選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

10235 行
317KB

  1. /*!
  2. *
  3. * Super simple WYSIWYG editor v0.8.20
  4. * https://summernote.org
  5. *
  6. *
  7. * Copyright 2013- Alan Hong and contributors
  8. * Summernote may be freely distributed under the MIT license.
  9. *
  10. * Date: 2021-10-14T21:15Z
  11. *
  12. */
  13. (function webpackUniversalModuleDefinition(root, factory) {
  14. if(typeof exports === 'object' && typeof module === 'object')
  15. module.exports = factory(require("jQuery"));
  16. else if(typeof define === 'function' && define.amd)
  17. define(["jQuery"], factory);
  18. else {
  19. var a = typeof exports === 'object' ? factory(require("jQuery")) : factory(root["jQuery"]);
  20. for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
  21. }
  22. })(self, function(__WEBPACK_EXTERNAL_MODULE__1145__) {
  23. return /******/ (() => { // webpackBootstrap
  24. /******/ "use strict";
  25. /******/ var __webpack_modules__ = ({
  26. /***/ 9770:
  27. /***/ ((__unused_webpack_module, __unused_webpack___webpack_exports__, __webpack_require__) => {
  28. /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1145);
  29. /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);
  30. (jquery__WEBPACK_IMPORTED_MODULE_0___default().summernote) = (jquery__WEBPACK_IMPORTED_MODULE_0___default().summernote) || {
  31. lang: {}
  32. };
  33. jquery__WEBPACK_IMPORTED_MODULE_0___default().extend((jquery__WEBPACK_IMPORTED_MODULE_0___default().summernote.lang), {
  34. 'en-US': {
  35. font: {
  36. bold: 'Bold',
  37. italic: 'Italic',
  38. underline: 'Underline',
  39. clear: 'Remove Font Style',
  40. height: 'Line Height',
  41. name: 'Font Family',
  42. strikethrough: 'Strikethrough',
  43. subscript: 'Subscript',
  44. superscript: 'Superscript',
  45. size: 'Font Size',
  46. sizeunit: 'Font Size Unit'
  47. },
  48. image: {
  49. image: 'Picture',
  50. insert: 'Insert Image',
  51. resizeFull: 'Resize full',
  52. resizeHalf: 'Resize half',
  53. resizeQuarter: 'Resize quarter',
  54. resizeNone: 'Original size',
  55. floatLeft: 'Float Left',
  56. floatRight: 'Float Right',
  57. floatNone: 'Remove float',
  58. shapeRounded: 'Shape: Rounded',
  59. shapeCircle: 'Shape: Circle',
  60. shapeThumbnail: 'Shape: Thumbnail',
  61. shapeNone: 'Shape: None',
  62. dragImageHere: 'Drag image or text here',
  63. dropImage: 'Drop image or Text',
  64. selectFromFiles: 'Select from files',
  65. maximumFileSize: 'Maximum file size',
  66. maximumFileSizeError: 'Maximum file size exceeded.',
  67. url: 'Image URL',
  68. remove: 'Remove Image',
  69. original: 'Original'
  70. },
  71. video: {
  72. video: 'Video',
  73. videoLink: 'Video Link',
  74. insert: 'Insert Video',
  75. url: 'Video URL',
  76. providers: '(YouTube, Google Drive, Vimeo, Vine, Instagram, DailyMotion, Youku, Peertube)'
  77. },
  78. link: {
  79. link: 'Link',
  80. insert: 'Insert Link',
  81. unlink: 'Unlink',
  82. edit: 'Edit',
  83. textToDisplay: 'Text to display',
  84. url: 'To what URL should this link go?',
  85. openInNewWindow: 'Open in new window',
  86. useProtocol: 'Use default protocol'
  87. },
  88. table: {
  89. table: 'Table',
  90. addRowAbove: 'Add row above',
  91. addRowBelow: 'Add row below',
  92. addColLeft: 'Add column left',
  93. addColRight: 'Add column right',
  94. delRow: 'Delete row',
  95. delCol: 'Delete column',
  96. delTable: 'Delete table'
  97. },
  98. hr: {
  99. insert: 'Insert Horizontal Rule'
  100. },
  101. style: {
  102. style: 'Style',
  103. p: 'Normal',
  104. blockquote: 'Quote',
  105. pre: 'Code',
  106. h1: 'Header 1',
  107. h2: 'Header 2',
  108. h3: 'Header 3',
  109. h4: 'Header 4',
  110. h5: 'Header 5',
  111. h6: 'Header 6'
  112. },
  113. lists: {
  114. unordered: 'Unordered list',
  115. ordered: 'Ordered list'
  116. },
  117. options: {
  118. help: 'Help',
  119. fullscreen: 'Full Screen',
  120. codeview: 'Code View'
  121. },
  122. paragraph: {
  123. paragraph: 'Paragraph',
  124. outdent: 'Outdent',
  125. indent: 'Indent',
  126. left: 'Align left',
  127. center: 'Align center',
  128. right: 'Align right',
  129. justify: 'Justify full'
  130. },
  131. color: {
  132. recent: 'Recent Color',
  133. more: 'More Color',
  134. background: 'Background Color',
  135. foreground: 'Text Color',
  136. transparent: 'Transparent',
  137. setTransparent: 'Set transparent',
  138. reset: 'Reset',
  139. resetToDefault: 'Reset to default',
  140. cpSelect: 'Select'
  141. },
  142. shortcut: {
  143. shortcuts: 'Keyboard shortcuts',
  144. close: 'Close',
  145. textFormatting: 'Text formatting',
  146. action: 'Action',
  147. paragraphFormatting: 'Paragraph formatting',
  148. documentStyle: 'Document Style',
  149. extraKeys: 'Extra keys'
  150. },
  151. help: {
  152. 'escape': 'Escape',
  153. 'insertParagraph': 'Insert Paragraph',
  154. 'undo': 'Undo the last command',
  155. 'redo': 'Redo the last command',
  156. 'tab': 'Tab',
  157. 'untab': 'Untab',
  158. 'bold': 'Set a bold style',
  159. 'italic': 'Set a italic style',
  160. 'underline': 'Set a underline style',
  161. 'strikethrough': 'Set a strikethrough style',
  162. 'removeFormat': 'Clean a style',
  163. 'justifyLeft': 'Set left align',
  164. 'justifyCenter': 'Set center align',
  165. 'justifyRight': 'Set right align',
  166. 'justifyFull': 'Set full align',
  167. 'insertUnorderedList': 'Toggle unordered list',
  168. 'insertOrderedList': 'Toggle ordered list',
  169. 'outdent': 'Outdent on current paragraph',
  170. 'indent': 'Indent on current paragraph',
  171. 'formatPara': 'Change current block\'s format as a paragraph(P tag)',
  172. 'formatH1': 'Change current block\'s format as H1',
  173. 'formatH2': 'Change current block\'s format as H2',
  174. 'formatH3': 'Change current block\'s format as H3',
  175. 'formatH4': 'Change current block\'s format as H4',
  176. 'formatH5': 'Change current block\'s format as H5',
  177. 'formatH6': 'Change current block\'s format as H6',
  178. 'insertHorizontalRule': 'Insert horizontal rule',
  179. 'linkDialog.show': 'Show Link Dialog'
  180. },
  181. history: {
  182. undo: 'Undo',
  183. redo: 'Redo'
  184. },
  185. specialChar: {
  186. specialChar: 'SPECIAL CHARACTERS',
  187. select: 'Select Special characters'
  188. },
  189. output: {
  190. noSelection: 'No Selection Made!'
  191. }
  192. }
  193. });
  194. /***/ }),
  195. /***/ 1145:
  196. /***/ ((module) => {
  197. module.exports = __WEBPACK_EXTERNAL_MODULE__1145__;
  198. /***/ })
  199. /******/ });
  200. /************************************************************************/
  201. /******/ // The module cache
  202. /******/ var __webpack_module_cache__ = {};
  203. /******/
  204. /******/ // The require function
  205. /******/ function __webpack_require__(moduleId) {
  206. /******/ // Check if module is in cache
  207. /******/ var cachedModule = __webpack_module_cache__[moduleId];
  208. /******/ if (cachedModule !== undefined) {
  209. /******/ return cachedModule.exports;
  210. /******/ }
  211. /******/ // Create a new module (and put it into the cache)
  212. /******/ var module = __webpack_module_cache__[moduleId] = {
  213. /******/ // no module.id needed
  214. /******/ // no module.loaded needed
  215. /******/ exports: {}
  216. /******/ };
  217. /******/
  218. /******/ // Execute the module function
  219. /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
  220. /******/
  221. /******/ // Return the exports of the module
  222. /******/ return module.exports;
  223. /******/ }
  224. /******/
  225. /************************************************************************/
  226. /******/ /* webpack/runtime/compat get default export */
  227. /******/ (() => {
  228. /******/ // getDefaultExport function for compatibility with non-harmony modules
  229. /******/ __webpack_require__.n = (module) => {
  230. /******/ var getter = module && module.__esModule ?
  231. /******/ () => (module['default']) :
  232. /******/ () => (module);
  233. /******/ __webpack_require__.d(getter, { a: getter });
  234. /******/ return getter;
  235. /******/ };
  236. /******/ })();
  237. /******/
  238. /******/ /* webpack/runtime/define property getters */
  239. /******/ (() => {
  240. /******/ // define getter functions for harmony exports
  241. /******/ __webpack_require__.d = (exports, definition) => {
  242. /******/ for(var key in definition) {
  243. /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
  244. /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
  245. /******/ }
  246. /******/ }
  247. /******/ };
  248. /******/ })();
  249. /******/
  250. /******/ /* webpack/runtime/hasOwnProperty shorthand */
  251. /******/ (() => {
  252. /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
  253. /******/ })();
  254. /******/
  255. /******/ /* webpack/runtime/make namespace object */
  256. /******/ (() => {
  257. /******/ // define __esModule on exports
  258. /******/ __webpack_require__.r = (exports) => {
  259. /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
  260. /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
  261. /******/ }
  262. /******/ Object.defineProperty(exports, '__esModule', { value: true });
  263. /******/ };
  264. /******/ })();
  265. /******/
  266. /************************************************************************/
  267. var __webpack_exports__ = {};
  268. // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
  269. (() => {
  270. // ESM COMPAT FLAG
  271. __webpack_require__.r(__webpack_exports__);
  272. // EXTERNAL MODULE: external "jQuery"
  273. var external_jQuery_ = __webpack_require__(1145);
  274. var external_jQuery_default = /*#__PURE__*/__webpack_require__.n(external_jQuery_);
  275. // EXTERNAL MODULE: ./src/lang/summernote-en-US.js
  276. var summernote_en_US = __webpack_require__(9770);
  277. ;// CONCATENATED MODULE: ./src/js/core/env.js
  278. /**
  279. * returns whether font is installed or not.
  280. *
  281. * @param {String} fontName
  282. * @return {Boolean}
  283. */
  284. var genericFontFamilies = ['sans-serif', 'serif', 'monospace', 'cursive', 'fantasy'];
  285. function validFontName(fontName) {
  286. return external_jQuery_default().inArray(fontName.toLowerCase(), genericFontFamilies) === -1 ? "'".concat(fontName, "'") : fontName;
  287. }
  288. function isFontInstalled(fontName) {
  289. var testFontName = fontName === 'Comic Sans MS' ? 'Courier New' : 'Comic Sans MS';
  290. var testText = 'mmmmmmmmmmwwwww';
  291. var testSize = '200px';
  292. var canvas = document.createElement('canvas');
  293. var context = canvas.getContext('2d');
  294. context.font = testSize + " '" + testFontName + "'";
  295. var originalWidth = context.measureText(testText).width;
  296. context.font = testSize + ' ' + validFontName(fontName) + ', "' + testFontName + '"';
  297. var width = context.measureText(testText).width;
  298. return originalWidth !== width;
  299. }
  300. var userAgent = navigator.userAgent;
  301. var isMSIE = /MSIE|Trident/i.test(userAgent);
  302. var browserVersion;
  303. if (isMSIE) {
  304. var matches = /MSIE (\d+[.]\d+)/.exec(userAgent);
  305. if (matches) {
  306. browserVersion = parseFloat(matches[1]);
  307. }
  308. matches = /Trident\/.*rv:([0-9]{1,}[.0-9]{0,})/.exec(userAgent);
  309. if (matches) {
  310. browserVersion = parseFloat(matches[1]);
  311. }
  312. }
  313. var isEdge = /Edge\/\d+/.test(userAgent);
  314. var isSupportTouch = 'ontouchstart' in window || navigator.MaxTouchPoints > 0 || navigator.msMaxTouchPoints > 0; // [workaround] IE doesn't have input events for contentEditable
  315. // - see: https://goo.gl/4bfIvA
  316. var inputEventName = isMSIE ? 'DOMCharacterDataModified DOMSubtreeModified DOMNodeInserted' : 'input';
  317. /**
  318. * @class core.env
  319. *
  320. * Object which check platform and agent
  321. *
  322. * @singleton
  323. * @alternateClassName env
  324. */
  325. /* harmony default export */ const env = ({
  326. isMac: navigator.appVersion.indexOf('Mac') > -1,
  327. isMSIE: isMSIE,
  328. isEdge: isEdge,
  329. isFF: !isEdge && /firefox/i.test(userAgent),
  330. isPhantom: /PhantomJS/i.test(userAgent),
  331. isWebkit: !isEdge && /webkit/i.test(userAgent),
  332. isChrome: !isEdge && /chrome/i.test(userAgent),
  333. isSafari: !isEdge && /safari/i.test(userAgent) && !/chrome/i.test(userAgent),
  334. browserVersion: browserVersion,
  335. isSupportTouch: isSupportTouch,
  336. isFontInstalled: isFontInstalled,
  337. isW3CRangeSupport: !!document.createRange,
  338. inputEventName: inputEventName,
  339. genericFontFamilies: genericFontFamilies,
  340. validFontName: validFontName
  341. });
  342. ;// CONCATENATED MODULE: ./src/js/core/func.js
  343. /**
  344. * @class core.func
  345. *
  346. * func utils (for high-order func's arg)
  347. *
  348. * @singleton
  349. * @alternateClassName func
  350. */
  351. function eq(itemA) {
  352. return function (itemB) {
  353. return itemA === itemB;
  354. };
  355. }
  356. function eq2(itemA, itemB) {
  357. return itemA === itemB;
  358. }
  359. function peq2(propName) {
  360. return function (itemA, itemB) {
  361. return itemA[propName] === itemB[propName];
  362. };
  363. }
  364. function ok() {
  365. return true;
  366. }
  367. function fail() {
  368. return false;
  369. }
  370. function not(f) {
  371. return function () {
  372. return !f.apply(f, arguments);
  373. };
  374. }
  375. function and(fA, fB) {
  376. return function (item) {
  377. return fA(item) && fB(item);
  378. };
  379. }
  380. function func_self(a) {
  381. return a;
  382. }
  383. function invoke(obj, method) {
  384. return function () {
  385. return obj[method].apply(obj, arguments);
  386. };
  387. }
  388. var idCounter = 0;
  389. /**
  390. * reset globally-unique id
  391. *
  392. */
  393. function resetUniqueId() {
  394. idCounter = 0;
  395. }
  396. /**
  397. * generate a globally-unique id
  398. *
  399. * @param {String} [prefix]
  400. */
  401. function uniqueId(prefix) {
  402. var id = ++idCounter + '';
  403. return prefix ? prefix + id : id;
  404. }
  405. /**
  406. * returns bnd (bounds) from rect
  407. *
  408. * - IE Compatibility Issue: http://goo.gl/sRLOAo
  409. * - Scroll Issue: http://goo.gl/sNjUc
  410. *
  411. * @param {Rect} rect
  412. * @return {Object} bounds
  413. * @return {Number} bounds.top
  414. * @return {Number} bounds.left
  415. * @return {Number} bounds.width
  416. * @return {Number} bounds.height
  417. */
  418. function rect2bnd(rect) {
  419. var $document = external_jQuery_default()(document);
  420. return {
  421. top: rect.top + $document.scrollTop(),
  422. left: rect.left + $document.scrollLeft(),
  423. width: rect.right - rect.left,
  424. height: rect.bottom - rect.top
  425. };
  426. }
  427. /**
  428. * returns a copy of the object where the keys have become the values and the values the keys.
  429. * @param {Object} obj
  430. * @return {Object}
  431. */
  432. function invertObject(obj) {
  433. var inverted = {};
  434. for (var key in obj) {
  435. if (Object.prototype.hasOwnProperty.call(obj, key)) {
  436. inverted[obj[key]] = key;
  437. }
  438. }
  439. return inverted;
  440. }
  441. /**
  442. * @param {String} namespace
  443. * @param {String} [prefix]
  444. * @return {String}
  445. */
  446. function namespaceToCamel(namespace, prefix) {
  447. prefix = prefix || '';
  448. return prefix + namespace.split('.').map(function (name) {
  449. return name.substring(0, 1).toUpperCase() + name.substring(1);
  450. }).join('');
  451. }
  452. /**
  453. * Returns a function, that, as long as it continues to be invoked, will not
  454. * be triggered. The function will be called after it stops being called for
  455. * N milliseconds. If `immediate` is passed, trigger the function on the
  456. * leading edge, instead of the trailing.
  457. * @param {Function} func
  458. * @param {Number} wait
  459. * @param {Boolean} immediate
  460. * @return {Function}
  461. */
  462. function debounce(func, wait, immediate) {
  463. var timeout;
  464. return function () {
  465. var context = this;
  466. var args = arguments;
  467. var later = function later() {
  468. timeout = null;
  469. if (!immediate) {
  470. func.apply(context, args);
  471. }
  472. };
  473. var callNow = immediate && !timeout;
  474. clearTimeout(timeout);
  475. timeout = setTimeout(later, wait);
  476. if (callNow) {
  477. func.apply(context, args);
  478. }
  479. };
  480. }
  481. /**
  482. *
  483. * @param {String} url
  484. * @return {Boolean}
  485. */
  486. function isValidUrl(url) {
  487. var expression = /[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/gi;
  488. return expression.test(url);
  489. }
  490. /* harmony default export */ const func = ({
  491. eq: eq,
  492. eq2: eq2,
  493. peq2: peq2,
  494. ok: ok,
  495. fail: fail,
  496. self: func_self,
  497. not: not,
  498. and: and,
  499. invoke: invoke,
  500. resetUniqueId: resetUniqueId,
  501. uniqueId: uniqueId,
  502. rect2bnd: rect2bnd,
  503. invertObject: invertObject,
  504. namespaceToCamel: namespaceToCamel,
  505. debounce: debounce,
  506. isValidUrl: isValidUrl
  507. });
  508. ;// CONCATENATED MODULE: ./src/js/core/lists.js
  509. /**
  510. * returns the first item of an array.
  511. *
  512. * @param {Array} array
  513. */
  514. function head(array) {
  515. return array[0];
  516. }
  517. /**
  518. * returns the last item of an array.
  519. *
  520. * @param {Array} array
  521. */
  522. function last(array) {
  523. return array[array.length - 1];
  524. }
  525. /**
  526. * returns everything but the last entry of the array.
  527. *
  528. * @param {Array} array
  529. */
  530. function initial(array) {
  531. return array.slice(0, array.length - 1);
  532. }
  533. /**
  534. * returns the rest of the items in an array.
  535. *
  536. * @param {Array} array
  537. */
  538. function tail(array) {
  539. return array.slice(1);
  540. }
  541. /**
  542. * returns item of array
  543. */
  544. function find(array, pred) {
  545. for (var idx = 0, len = array.length; idx < len; idx++) {
  546. var item = array[idx];
  547. if (pred(item)) {
  548. return item;
  549. }
  550. }
  551. }
  552. /**
  553. * returns true if all of the values in the array pass the predicate truth test.
  554. */
  555. function lists_all(array, pred) {
  556. for (var idx = 0, len = array.length; idx < len; idx++) {
  557. if (!pred(array[idx])) {
  558. return false;
  559. }
  560. }
  561. return true;
  562. }
  563. /**
  564. * returns true if the value is present in the list.
  565. */
  566. function contains(array, item) {
  567. if (array && array.length && item) {
  568. if (array.indexOf) {
  569. return array.indexOf(item) !== -1;
  570. } else if (array.contains) {
  571. // `DOMTokenList` doesn't implement `.indexOf`, but it implements `.contains`
  572. return array.contains(item);
  573. }
  574. }
  575. return false;
  576. }
  577. /**
  578. * get sum from a list
  579. *
  580. * @param {Array} array - array
  581. * @param {Function} fn - iterator
  582. */
  583. function sum(array, fn) {
  584. fn = fn || func.self;
  585. return array.reduce(function (memo, v) {
  586. return memo + fn(v);
  587. }, 0);
  588. }
  589. /**
  590. * returns a copy of the collection with array type.
  591. * @param {Collection} collection - collection eg) node.childNodes, ...
  592. */
  593. function from(collection) {
  594. var result = [];
  595. var length = collection.length;
  596. var idx = -1;
  597. while (++idx < length) {
  598. result[idx] = collection[idx];
  599. }
  600. return result;
  601. }
  602. /**
  603. * returns whether list is empty or not
  604. */
  605. function isEmpty(array) {
  606. return !array || !array.length;
  607. }
  608. /**
  609. * cluster elements by predicate function.
  610. *
  611. * @param {Array} array - array
  612. * @param {Function} fn - predicate function for cluster rule
  613. * @param {Array[]}
  614. */
  615. function clusterBy(array, fn) {
  616. if (!array.length) {
  617. return [];
  618. }
  619. var aTail = tail(array);
  620. return aTail.reduce(function (memo, v) {
  621. var aLast = last(memo);
  622. if (fn(last(aLast), v)) {
  623. aLast[aLast.length] = v;
  624. } else {
  625. memo[memo.length] = [v];
  626. }
  627. return memo;
  628. }, [[head(array)]]);
  629. }
  630. /**
  631. * returns a copy of the array with all false values removed
  632. *
  633. * @param {Array} array - array
  634. * @param {Function} fn - predicate function for cluster rule
  635. */
  636. function compact(array) {
  637. var aResult = [];
  638. for (var idx = 0, len = array.length; idx < len; idx++) {
  639. if (array[idx]) {
  640. aResult.push(array[idx]);
  641. }
  642. }
  643. return aResult;
  644. }
  645. /**
  646. * produces a duplicate-free version of the array
  647. *
  648. * @param {Array} array
  649. */
  650. function unique(array) {
  651. var results = [];
  652. for (var idx = 0, len = array.length; idx < len; idx++) {
  653. if (!contains(results, array[idx])) {
  654. results.push(array[idx]);
  655. }
  656. }
  657. return results;
  658. }
  659. /**
  660. * returns next item.
  661. * @param {Array} array
  662. */
  663. function next(array, item) {
  664. if (array && array.length && item) {
  665. var idx = array.indexOf(item);
  666. return idx === -1 ? null : array[idx + 1];
  667. }
  668. return null;
  669. }
  670. /**
  671. * returns prev item.
  672. * @param {Array} array
  673. */
  674. function prev(array, item) {
  675. if (array && array.length && item) {
  676. var idx = array.indexOf(item);
  677. return idx === -1 ? null : array[idx - 1];
  678. }
  679. return null;
  680. }
  681. /**
  682. * @class core.list
  683. *
  684. * list utils
  685. *
  686. * @singleton
  687. * @alternateClassName list
  688. */
  689. /* harmony default export */ const lists = ({
  690. head: head,
  691. last: last,
  692. initial: initial,
  693. tail: tail,
  694. prev: prev,
  695. next: next,
  696. find: find,
  697. contains: contains,
  698. all: lists_all,
  699. sum: sum,
  700. from: from,
  701. isEmpty: isEmpty,
  702. clusterBy: clusterBy,
  703. compact: compact,
  704. unique: unique
  705. });
  706. ;// CONCATENATED MODULE: ./src/js/core/dom.js
  707. var NBSP_CHAR = String.fromCharCode(160);
  708. var ZERO_WIDTH_NBSP_CHAR = "\uFEFF";
  709. /**
  710. * @method isEditable
  711. *
  712. * returns whether node is `note-editable` or not.
  713. *
  714. * @param {Node} node
  715. * @return {Boolean}
  716. */
  717. function isEditable(node) {
  718. return node && external_jQuery_default()(node).hasClass('note-editable');
  719. }
  720. /**
  721. * @method isControlSizing
  722. *
  723. * returns whether node is `note-control-sizing` or not.
  724. *
  725. * @param {Node} node
  726. * @return {Boolean}
  727. */
  728. function isControlSizing(node) {
  729. return node && external_jQuery_default()(node).hasClass('note-control-sizing');
  730. }
  731. /**
  732. * @method makePredByNodeName
  733. *
  734. * returns predicate which judge whether nodeName is same
  735. *
  736. * @param {String} nodeName
  737. * @return {Function}
  738. */
  739. function makePredByNodeName(nodeName) {
  740. nodeName = nodeName.toUpperCase();
  741. return function (node) {
  742. return node && node.nodeName.toUpperCase() === nodeName;
  743. };
  744. }
  745. /**
  746. * @method isText
  747. *
  748. *
  749. *
  750. * @param {Node} node
  751. * @return {Boolean} true if node's type is text(3)
  752. */
  753. function isText(node) {
  754. return node && node.nodeType === 3;
  755. }
  756. /**
  757. * @method isElement
  758. *
  759. *
  760. *
  761. * @param {Node} node
  762. * @return {Boolean} true if node's type is element(1)
  763. */
  764. function isElement(node) {
  765. return node && node.nodeType === 1;
  766. }
  767. /**
  768. * ex) br, col, embed, hr, img, input, ...
  769. * @see http://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements
  770. */
  771. function isVoid(node) {
  772. return node && /^BR|^IMG|^HR|^IFRAME|^BUTTON|^INPUT|^AUDIO|^VIDEO|^EMBED/.test(node.nodeName.toUpperCase());
  773. }
  774. function isPara(node) {
  775. if (isEditable(node)) {
  776. return false;
  777. } // Chrome(v31.0), FF(v25.0.1) use DIV for paragraph
  778. return node && /^DIV|^P|^LI|^H[1-7]/.test(node.nodeName.toUpperCase());
  779. }
  780. function isHeading(node) {
  781. return node && /^H[1-7]/.test(node.nodeName.toUpperCase());
  782. }
  783. var isPre = makePredByNodeName('PRE');
  784. var isLi = makePredByNodeName('LI');
  785. function isPurePara(node) {
  786. return isPara(node) && !isLi(node);
  787. }
  788. var isTable = makePredByNodeName('TABLE');
  789. var isData = makePredByNodeName('DATA');
  790. function isInline(node) {
  791. return !isBodyContainer(node) && !isList(node) && !isHr(node) && !isPara(node) && !isTable(node) && !isBlockquote(node) && !isData(node);
  792. }
  793. function isList(node) {
  794. return node && /^UL|^OL/.test(node.nodeName.toUpperCase());
  795. }
  796. var isHr = makePredByNodeName('HR');
  797. function isCell(node) {
  798. return node && /^TD|^TH/.test(node.nodeName.toUpperCase());
  799. }
  800. var isBlockquote = makePredByNodeName('BLOCKQUOTE');
  801. function isBodyContainer(node) {
  802. return isCell(node) || isBlockquote(node) || isEditable(node);
  803. }
  804. var isAnchor = makePredByNodeName('A');
  805. function isParaInline(node) {
  806. return isInline(node) && !!ancestor(node, isPara);
  807. }
  808. function isBodyInline(node) {
  809. return isInline(node) && !ancestor(node, isPara);
  810. }
  811. var isBody = makePredByNodeName('BODY');
  812. /**
  813. * returns whether nodeB is closest sibling of nodeA
  814. *
  815. * @param {Node} nodeA
  816. * @param {Node} nodeB
  817. * @return {Boolean}
  818. */
  819. function isClosestSibling(nodeA, nodeB) {
  820. return nodeA.nextSibling === nodeB || nodeA.previousSibling === nodeB;
  821. }
  822. /**
  823. * returns array of closest siblings with node
  824. *
  825. * @param {Node} node
  826. * @param {function} [pred] - predicate function
  827. * @return {Node[]}
  828. */
  829. function withClosestSiblings(node, pred) {
  830. pred = pred || func.ok;
  831. var siblings = [];
  832. if (node.previousSibling && pred(node.previousSibling)) {
  833. siblings.push(node.previousSibling);
  834. }
  835. siblings.push(node);
  836. if (node.nextSibling && pred(node.nextSibling)) {
  837. siblings.push(node.nextSibling);
  838. }
  839. return siblings;
  840. }
  841. /**
  842. * blank HTML for cursor position
  843. * - [workaround] old IE only works with &nbsp;
  844. * - [workaround] IE11 and other browser works with bogus br
  845. */
  846. var blankHTML = env.isMSIE && env.browserVersion < 11 ? '&nbsp;' : '<br>';
  847. /**
  848. * @method nodeLength
  849. *
  850. * returns #text's text size or element's childNodes size
  851. *
  852. * @param {Node} node
  853. */
  854. function nodeLength(node) {
  855. if (isText(node)) {
  856. return node.nodeValue.length;
  857. }
  858. if (node) {
  859. return node.childNodes.length;
  860. }
  861. return 0;
  862. }
  863. /**
  864. * returns whether deepest child node is empty or not.
  865. *
  866. * @param {Node} node
  867. * @return {Boolean}
  868. */
  869. function deepestChildIsEmpty(node) {
  870. do {
  871. if (node.firstElementChild === null || node.firstElementChild.innerHTML === '') break;
  872. } while (node = node.firstElementChild);
  873. return dom_isEmpty(node);
  874. }
  875. /**
  876. * returns whether node is empty or not.
  877. *
  878. * @param {Node} node
  879. * @return {Boolean}
  880. */
  881. function dom_isEmpty(node) {
  882. var len = nodeLength(node);
  883. if (len === 0) {
  884. return true;
  885. } else if (!isText(node) && len === 1 && node.innerHTML === blankHTML) {
  886. // ex) <p><br></p>, <span><br></span>
  887. return true;
  888. } else if (lists.all(node.childNodes, isText) && node.innerHTML === '') {
  889. // ex) <p></p>, <span></span>
  890. return true;
  891. }
  892. return false;
  893. }
  894. /**
  895. * padding blankHTML if node is empty (for cursor position)
  896. */
  897. function paddingBlankHTML(node) {
  898. if (!isVoid(node) && !nodeLength(node)) {
  899. node.innerHTML = blankHTML;
  900. }
  901. }
  902. /**
  903. * find nearest ancestor predicate hit
  904. *
  905. * @param {Node} node
  906. * @param {Function} pred - predicate function
  907. */
  908. function ancestor(node, pred) {
  909. while (node) {
  910. if (pred(node)) {
  911. return node;
  912. }
  913. if (isEditable(node)) {
  914. break;
  915. }
  916. node = node.parentNode;
  917. }
  918. return null;
  919. }
  920. /**
  921. * find nearest ancestor only single child blood line and predicate hit
  922. *
  923. * @param {Node} node
  924. * @param {Function} pred - predicate function
  925. */
  926. function singleChildAncestor(node, pred) {
  927. node = node.parentNode;
  928. while (node) {
  929. if (nodeLength(node) !== 1) {
  930. break;
  931. }
  932. if (pred(node)) {
  933. return node;
  934. }
  935. if (isEditable(node)) {
  936. break;
  937. }
  938. node = node.parentNode;
  939. }
  940. return null;
  941. }
  942. /**
  943. * returns new array of ancestor nodes (until predicate hit).
  944. *
  945. * @param {Node} node
  946. * @param {Function} [optional] pred - predicate function
  947. */
  948. function listAncestor(node, pred) {
  949. pred = pred || func.fail;
  950. var ancestors = [];
  951. ancestor(node, function (el) {
  952. if (!isEditable(el)) {
  953. ancestors.push(el);
  954. }
  955. return pred(el);
  956. });
  957. return ancestors;
  958. }
  959. /**
  960. * find farthest ancestor predicate hit
  961. */
  962. function lastAncestor(node, pred) {
  963. var ancestors = listAncestor(node);
  964. return lists.last(ancestors.filter(pred));
  965. }
  966. /**
  967. * returns common ancestor node between two nodes.
  968. *
  969. * @param {Node} nodeA
  970. * @param {Node} nodeB
  971. */
  972. function commonAncestor(nodeA, nodeB) {
  973. var ancestors = listAncestor(nodeA);
  974. for (var n = nodeB; n; n = n.parentNode) {
  975. if (ancestors.indexOf(n) > -1) return n;
  976. }
  977. return null; // difference document area
  978. }
  979. /**
  980. * listing all previous siblings (until predicate hit).
  981. *
  982. * @param {Node} node
  983. * @param {Function} [optional] pred - predicate function
  984. */
  985. function listPrev(node, pred) {
  986. pred = pred || func.fail;
  987. var nodes = [];
  988. while (node) {
  989. if (pred(node)) {
  990. break;
  991. }
  992. nodes.push(node);
  993. node = node.previousSibling;
  994. }
  995. return nodes;
  996. }
  997. /**
  998. * listing next siblings (until predicate hit).
  999. *
  1000. * @param {Node} node
  1001. * @param {Function} [pred] - predicate function
  1002. */
  1003. function listNext(node, pred) {
  1004. pred = pred || func.fail;
  1005. var nodes = [];
  1006. while (node) {
  1007. if (pred(node)) {
  1008. break;
  1009. }
  1010. nodes.push(node);
  1011. node = node.nextSibling;
  1012. }
  1013. return nodes;
  1014. }
  1015. /**
  1016. * listing descendant nodes
  1017. *
  1018. * @param {Node} node
  1019. * @param {Function} [pred] - predicate function
  1020. */
  1021. function listDescendant(node, pred) {
  1022. var descendants = [];
  1023. pred = pred || func.ok; // start DFS(depth first search) with node
  1024. (function fnWalk(current) {
  1025. if (node !== current && pred(current)) {
  1026. descendants.push(current);
  1027. }
  1028. for (var idx = 0, len = current.childNodes.length; idx < len; idx++) {
  1029. fnWalk(current.childNodes[idx]);
  1030. }
  1031. })(node);
  1032. return descendants;
  1033. }
  1034. /**
  1035. * wrap node with new tag.
  1036. *
  1037. * @param {Node} node
  1038. * @param {Node} tagName of wrapper
  1039. * @return {Node} - wrapper
  1040. */
  1041. function wrap(node, wrapperName) {
  1042. var parent = node.parentNode;
  1043. var wrapper = external_jQuery_default()('<' + wrapperName + '>')[0];
  1044. parent.insertBefore(wrapper, node);
  1045. wrapper.appendChild(node);
  1046. return wrapper;
  1047. }
  1048. /**
  1049. * insert node after preceding
  1050. *
  1051. * @param {Node} node
  1052. * @param {Node} preceding - predicate function
  1053. */
  1054. function insertAfter(node, preceding) {
  1055. var next = preceding.nextSibling;
  1056. var parent = preceding.parentNode;
  1057. if (next) {
  1058. parent.insertBefore(node, next);
  1059. } else {
  1060. parent.appendChild(node);
  1061. }
  1062. return node;
  1063. }
  1064. /**
  1065. * append elements.
  1066. *
  1067. * @param {Node} node
  1068. * @param {Collection} aChild
  1069. */
  1070. function appendChildNodes(node, aChild) {
  1071. external_jQuery_default().each(aChild, function (idx, child) {
  1072. node.appendChild(child);
  1073. });
  1074. return node;
  1075. }
  1076. /**
  1077. * returns whether boundaryPoint is left edge or not.
  1078. *
  1079. * @param {BoundaryPoint} point
  1080. * @return {Boolean}
  1081. */
  1082. function isLeftEdgePoint(point) {
  1083. return point.offset === 0;
  1084. }
  1085. /**
  1086. * returns whether boundaryPoint is right edge or not.
  1087. *
  1088. * @param {BoundaryPoint} point
  1089. * @return {Boolean}
  1090. */
  1091. function isRightEdgePoint(point) {
  1092. return point.offset === nodeLength(point.node);
  1093. }
  1094. /**
  1095. * returns whether boundaryPoint is edge or not.
  1096. *
  1097. * @param {BoundaryPoint} point
  1098. * @return {Boolean}
  1099. */
  1100. function isEdgePoint(point) {
  1101. return isLeftEdgePoint(point) || isRightEdgePoint(point);
  1102. }
  1103. /**
  1104. * returns whether node is left edge of ancestor or not.
  1105. *
  1106. * @param {Node} node
  1107. * @param {Node} ancestor
  1108. * @return {Boolean}
  1109. */
  1110. function isLeftEdgeOf(node, ancestor) {
  1111. while (node && node !== ancestor) {
  1112. if (position(node) !== 0) {
  1113. return false;
  1114. }
  1115. node = node.parentNode;
  1116. }
  1117. return true;
  1118. }
  1119. /**
  1120. * returns whether node is right edge of ancestor or not.
  1121. *
  1122. * @param {Node} node
  1123. * @param {Node} ancestor
  1124. * @return {Boolean}
  1125. */
  1126. function isRightEdgeOf(node, ancestor) {
  1127. if (!ancestor) {
  1128. return false;
  1129. }
  1130. while (node && node !== ancestor) {
  1131. if (position(node) !== nodeLength(node.parentNode) - 1) {
  1132. return false;
  1133. }
  1134. node = node.parentNode;
  1135. }
  1136. return true;
  1137. }
  1138. /**
  1139. * returns whether point is left edge of ancestor or not.
  1140. * @param {BoundaryPoint} point
  1141. * @param {Node} ancestor
  1142. * @return {Boolean}
  1143. */
  1144. function isLeftEdgePointOf(point, ancestor) {
  1145. return isLeftEdgePoint(point) && isLeftEdgeOf(point.node, ancestor);
  1146. }
  1147. /**
  1148. * returns whether point is right edge of ancestor or not.
  1149. * @param {BoundaryPoint} point
  1150. * @param {Node} ancestor
  1151. * @return {Boolean}
  1152. */
  1153. function isRightEdgePointOf(point, ancestor) {
  1154. return isRightEdgePoint(point) && isRightEdgeOf(point.node, ancestor);
  1155. }
  1156. /**
  1157. * returns offset from parent.
  1158. *
  1159. * @param {Node} node
  1160. */
  1161. function position(node) {
  1162. var offset = 0;
  1163. while (node = node.previousSibling) {
  1164. offset += 1;
  1165. }
  1166. return offset;
  1167. }
  1168. function hasChildren(node) {
  1169. return !!(node && node.childNodes && node.childNodes.length);
  1170. }
  1171. /**
  1172. * returns previous boundaryPoint
  1173. *
  1174. * @param {BoundaryPoint} point
  1175. * @param {Boolean} isSkipInnerOffset
  1176. * @return {BoundaryPoint}
  1177. */
  1178. function prevPoint(point, isSkipInnerOffset) {
  1179. var node;
  1180. var offset;
  1181. if (point.offset === 0) {
  1182. if (isEditable(point.node)) {
  1183. return null;
  1184. }
  1185. node = point.node.parentNode;
  1186. offset = position(point.node);
  1187. } else if (hasChildren(point.node)) {
  1188. node = point.node.childNodes[point.offset - 1];
  1189. offset = nodeLength(node);
  1190. } else {
  1191. node = point.node;
  1192. offset = isSkipInnerOffset ? 0 : point.offset - 1;
  1193. }
  1194. return {
  1195. node: node,
  1196. offset: offset
  1197. };
  1198. }
  1199. /**
  1200. * returns next boundaryPoint
  1201. *
  1202. * @param {BoundaryPoint} point
  1203. * @param {Boolean} isSkipInnerOffset
  1204. * @return {BoundaryPoint}
  1205. */
  1206. function nextPoint(point, isSkipInnerOffset) {
  1207. var node, offset;
  1208. if (nodeLength(point.node) === point.offset) {
  1209. if (isEditable(point.node)) {
  1210. return null;
  1211. }
  1212. var nextTextNode = getNextTextNode(point.node);
  1213. if (nextTextNode) {
  1214. node = nextTextNode;
  1215. offset = 0;
  1216. } else {
  1217. node = point.node.parentNode;
  1218. offset = position(point.node) + 1;
  1219. }
  1220. } else if (hasChildren(point.node)) {
  1221. node = point.node.childNodes[point.offset];
  1222. offset = 0;
  1223. } else {
  1224. node = point.node;
  1225. offset = isSkipInnerOffset ? nodeLength(point.node) : point.offset + 1;
  1226. }
  1227. return {
  1228. node: node,
  1229. offset: offset
  1230. };
  1231. }
  1232. /**
  1233. * returns next boundaryPoint with empty node
  1234. *
  1235. * @param {BoundaryPoint} point
  1236. * @param {Boolean} isSkipInnerOffset
  1237. * @return {BoundaryPoint}
  1238. */
  1239. function nextPointWithEmptyNode(point, isSkipInnerOffset) {
  1240. var node,
  1241. offset = 0; // if node is empty string node, return current node's sibling.
  1242. if (dom_isEmpty(point.node)) {
  1243. if (point.node === null) {
  1244. return null;
  1245. }
  1246. node = point.node.nextSibling;
  1247. offset = 0;
  1248. return {
  1249. node: node,
  1250. offset: offset
  1251. };
  1252. }
  1253. if (nodeLength(point.node) === point.offset) {
  1254. if (isEditable(point.node)) {
  1255. return null;
  1256. }
  1257. node = point.node.parentNode;
  1258. offset = position(point.node) + 1; // if next node is editable , return current node's sibling node.
  1259. if (isEditable(node)) {
  1260. node = point.node.nextSibling;
  1261. offset = 0;
  1262. }
  1263. } else if (hasChildren(point.node)) {
  1264. node = point.node.childNodes[point.offset];
  1265. offset = 0;
  1266. if (dom_isEmpty(node)) {
  1267. if (!dom_isEmpty(point.node.nextSibling)) {
  1268. return {
  1269. node: point.node.nextSibling,
  1270. offset: offset
  1271. };
  1272. }
  1273. return null;
  1274. }
  1275. } else {
  1276. node = point.node;
  1277. offset = isSkipInnerOffset ? nodeLength(point.node) : point.offset + 1;
  1278. if (dom_isEmpty(node)) {
  1279. return null;
  1280. }
  1281. }
  1282. return {
  1283. node: node,
  1284. offset: offset
  1285. };
  1286. }
  1287. /*
  1288. * returns the next Text node index or 0 if not found.
  1289. */
  1290. function getNextTextNode(actual) {
  1291. if (!actual.nextSibling) return undefined;
  1292. if (actual.parent !== actual.nextSibling.parent) return undefined;
  1293. if (isText(actual.nextSibling)) return actual.nextSibling;else return getNextTextNode(actual.nextSibling);
  1294. }
  1295. /**
  1296. * returns whether pointA and pointB is same or not.
  1297. *
  1298. * @param {BoundaryPoint} pointA
  1299. * @param {BoundaryPoint} pointB
  1300. * @return {Boolean}
  1301. */
  1302. function isSamePoint(pointA, pointB) {
  1303. return pointA.node === pointB.node && pointA.offset === pointB.offset;
  1304. }
  1305. /**
  1306. * returns whether point is visible (can set cursor) or not.
  1307. *
  1308. * @param {BoundaryPoint} point
  1309. * @return {Boolean}
  1310. */
  1311. function isVisiblePoint(point) {
  1312. if (isText(point.node) || !hasChildren(point.node) || dom_isEmpty(point.node)) {
  1313. return true;
  1314. }
  1315. var leftNode = point.node.childNodes[point.offset - 1];
  1316. var rightNode = point.node.childNodes[point.offset];
  1317. if ((!leftNode || isVoid(leftNode)) && (!rightNode || isVoid(rightNode)) || isTable(rightNode)) {
  1318. return true;
  1319. }
  1320. return false;
  1321. }
  1322. /**
  1323. * @method prevPointUtil
  1324. *
  1325. * @param {BoundaryPoint} point
  1326. * @param {Function} pred
  1327. * @return {BoundaryPoint}
  1328. */
  1329. function prevPointUntil(point, pred) {
  1330. while (point) {
  1331. if (pred(point)) {
  1332. return point;
  1333. }
  1334. point = prevPoint(point);
  1335. }
  1336. return null;
  1337. }
  1338. /**
  1339. * @method nextPointUntil
  1340. *
  1341. * @param {BoundaryPoint} point
  1342. * @param {Function} pred
  1343. * @return {BoundaryPoint}
  1344. */
  1345. function nextPointUntil(point, pred) {
  1346. while (point) {
  1347. if (pred(point)) {
  1348. return point;
  1349. }
  1350. point = nextPoint(point);
  1351. }
  1352. return null;
  1353. }
  1354. /**
  1355. * returns whether point has character or not.
  1356. *
  1357. * @param {Point} point
  1358. * @return {Boolean}
  1359. */
  1360. function isCharPoint(point) {
  1361. if (!isText(point.node)) {
  1362. return false;
  1363. }
  1364. var ch = point.node.nodeValue.charAt(point.offset - 1);
  1365. return ch && ch !== ' ' && ch !== NBSP_CHAR;
  1366. }
  1367. /**
  1368. * returns whether point has space or not.
  1369. *
  1370. * @param {Point} point
  1371. * @return {Boolean}
  1372. */
  1373. function isSpacePoint(point) {
  1374. if (!isText(point.node)) {
  1375. return false;
  1376. }
  1377. var ch = point.node.nodeValue.charAt(point.offset - 1);
  1378. return ch === ' ' || ch === NBSP_CHAR;
  1379. }
  1380. /**
  1381. * @method walkPoint
  1382. *
  1383. * @param {BoundaryPoint} startPoint
  1384. * @param {BoundaryPoint} endPoint
  1385. * @param {Function} handler
  1386. * @param {Boolean} isSkipInnerOffset
  1387. */
  1388. function walkPoint(startPoint, endPoint, handler, isSkipInnerOffset) {
  1389. var point = startPoint;
  1390. while (point) {
  1391. handler(point);
  1392. if (isSamePoint(point, endPoint)) {
  1393. break;
  1394. }
  1395. var isSkipOffset = isSkipInnerOffset && startPoint.node !== point.node && endPoint.node !== point.node;
  1396. point = nextPointWithEmptyNode(point, isSkipOffset);
  1397. }
  1398. }
  1399. /**
  1400. * @method makeOffsetPath
  1401. *
  1402. * return offsetPath(array of offset) from ancestor
  1403. *
  1404. * @param {Node} ancestor - ancestor node
  1405. * @param {Node} node
  1406. */
  1407. function makeOffsetPath(ancestor, node) {
  1408. var ancestors = listAncestor(node, func.eq(ancestor));
  1409. return ancestors.map(position).reverse();
  1410. }
  1411. /**
  1412. * @method fromOffsetPath
  1413. *
  1414. * return element from offsetPath(array of offset)
  1415. *
  1416. * @param {Node} ancestor - ancestor node
  1417. * @param {array} offsets - offsetPath
  1418. */
  1419. function fromOffsetPath(ancestor, offsets) {
  1420. var current = ancestor;
  1421. for (var i = 0, len = offsets.length; i < len; i++) {
  1422. if (current.childNodes.length <= offsets[i]) {
  1423. current = current.childNodes[current.childNodes.length - 1];
  1424. } else {
  1425. current = current.childNodes[offsets[i]];
  1426. }
  1427. }
  1428. return current;
  1429. }
  1430. /**
  1431. * @method splitNode
  1432. *
  1433. * split element or #text
  1434. *
  1435. * @param {BoundaryPoint} point
  1436. * @param {Object} [options]
  1437. * @param {Boolean} [options.isSkipPaddingBlankHTML] - default: false
  1438. * @param {Boolean} [options.isNotSplitEdgePoint] - default: false
  1439. * @param {Boolean} [options.isDiscardEmptySplits] - default: false
  1440. * @return {Node} right node of boundaryPoint
  1441. */
  1442. function splitNode(point, options) {
  1443. var isSkipPaddingBlankHTML = options && options.isSkipPaddingBlankHTML;
  1444. var isNotSplitEdgePoint = options && options.isNotSplitEdgePoint;
  1445. var isDiscardEmptySplits = options && options.isDiscardEmptySplits;
  1446. if (isDiscardEmptySplits) {
  1447. isSkipPaddingBlankHTML = true;
  1448. } // edge case
  1449. if (isEdgePoint(point) && (isText(point.node) || isNotSplitEdgePoint)) {
  1450. if (isLeftEdgePoint(point)) {
  1451. return point.node;
  1452. } else if (isRightEdgePoint(point)) {
  1453. return point.node.nextSibling;
  1454. }
  1455. } // split #text
  1456. if (isText(point.node)) {
  1457. return point.node.splitText(point.offset);
  1458. } else {
  1459. var childNode = point.node.childNodes[point.offset];
  1460. var clone = insertAfter(point.node.cloneNode(false), point.node);
  1461. appendChildNodes(clone, listNext(childNode));
  1462. if (!isSkipPaddingBlankHTML) {
  1463. paddingBlankHTML(point.node);
  1464. paddingBlankHTML(clone);
  1465. }
  1466. if (isDiscardEmptySplits) {
  1467. if (dom_isEmpty(point.node)) {
  1468. remove(point.node);
  1469. }
  1470. if (dom_isEmpty(clone)) {
  1471. remove(clone);
  1472. return point.node.nextSibling;
  1473. }
  1474. }
  1475. return clone;
  1476. }
  1477. }
  1478. /**
  1479. * @method splitTree
  1480. *
  1481. * split tree by point
  1482. *
  1483. * @param {Node} root - split root
  1484. * @param {BoundaryPoint} point
  1485. * @param {Object} [options]
  1486. * @param {Boolean} [options.isSkipPaddingBlankHTML] - default: false
  1487. * @param {Boolean} [options.isNotSplitEdgePoint] - default: false
  1488. * @return {Node} right node of boundaryPoint
  1489. */
  1490. function splitTree(root, point, options) {
  1491. // ex) [#text, <span>, <p>]
  1492. var ancestors = listAncestor(point.node, func.eq(root));
  1493. if (!ancestors.length) {
  1494. return null;
  1495. } else if (ancestors.length === 1) {
  1496. return splitNode(point, options);
  1497. }
  1498. return ancestors.reduce(function (node, parent) {
  1499. if (node === point.node) {
  1500. node = splitNode(point, options);
  1501. }
  1502. return splitNode({
  1503. node: parent,
  1504. offset: node ? position(node) : nodeLength(parent)
  1505. }, options);
  1506. });
  1507. }
  1508. /**
  1509. * split point
  1510. *
  1511. * @param {Point} point
  1512. * @param {Boolean} isInline
  1513. * @return {Object}
  1514. */
  1515. function splitPoint(point, isInline) {
  1516. // find splitRoot, container
  1517. // - inline: splitRoot is a child of paragraph
  1518. // - block: splitRoot is a child of bodyContainer
  1519. var pred = isInline ? isPara : isBodyContainer;
  1520. var ancestors = listAncestor(point.node, pred);
  1521. var topAncestor = lists.last(ancestors) || point.node;
  1522. var splitRoot, container;
  1523. if (pred(topAncestor)) {
  1524. splitRoot = ancestors[ancestors.length - 2];
  1525. container = topAncestor;
  1526. } else {
  1527. splitRoot = topAncestor;
  1528. container = splitRoot.parentNode;
  1529. } // if splitRoot is exists, split with splitTree
  1530. var pivot = splitRoot && splitTree(splitRoot, point, {
  1531. isSkipPaddingBlankHTML: isInline,
  1532. isNotSplitEdgePoint: isInline
  1533. }); // if container is point.node, find pivot with point.offset
  1534. if (!pivot && container === point.node) {
  1535. pivot = point.node.childNodes[point.offset];
  1536. }
  1537. return {
  1538. rightNode: pivot,
  1539. container: container
  1540. };
  1541. }
  1542. function create(nodeName) {
  1543. return document.createElement(nodeName);
  1544. }
  1545. function createText(text) {
  1546. return document.createTextNode(text);
  1547. }
  1548. /**
  1549. * @method remove
  1550. *
  1551. * remove node, (isRemoveChild: remove child or not)
  1552. *
  1553. * @param {Node} node
  1554. * @param {Boolean} isRemoveChild
  1555. */
  1556. function remove(node, isRemoveChild) {
  1557. if (!node || !node.parentNode) {
  1558. return;
  1559. }
  1560. if (node.removeNode) {
  1561. return node.removeNode(isRemoveChild);
  1562. }
  1563. var parent = node.parentNode;
  1564. if (!isRemoveChild) {
  1565. var nodes = [];
  1566. for (var i = 0, len = node.childNodes.length; i < len; i++) {
  1567. nodes.push(node.childNodes[i]);
  1568. }
  1569. for (var _i = 0, _len = nodes.length; _i < _len; _i++) {
  1570. parent.insertBefore(nodes[_i], node);
  1571. }
  1572. }
  1573. parent.removeChild(node);
  1574. }
  1575. /**
  1576. * @method removeWhile
  1577. *
  1578. * @param {Node} node
  1579. * @param {Function} pred
  1580. */
  1581. function removeWhile(node, pred) {
  1582. while (node) {
  1583. if (isEditable(node) || !pred(node)) {
  1584. break;
  1585. }
  1586. var parent = node.parentNode;
  1587. remove(node);
  1588. node = parent;
  1589. }
  1590. }
  1591. /**
  1592. * @method replace
  1593. *
  1594. * replace node with provided nodeName
  1595. *
  1596. * @param {Node} node
  1597. * @param {String} nodeName
  1598. * @return {Node} - new node
  1599. */
  1600. function replace(node, nodeName) {
  1601. if (node.nodeName.toUpperCase() === nodeName.toUpperCase()) {
  1602. return node;
  1603. }
  1604. var newNode = create(nodeName);
  1605. if (node.style.cssText) {
  1606. newNode.style.cssText = node.style.cssText;
  1607. }
  1608. appendChildNodes(newNode, lists.from(node.childNodes));
  1609. insertAfter(newNode, node);
  1610. remove(node);
  1611. return newNode;
  1612. }
  1613. var isTextarea = makePredByNodeName('TEXTAREA');
  1614. /**
  1615. * @param {jQuery} $node
  1616. * @param {Boolean} [stripLinebreaks] - default: false
  1617. */
  1618. function value($node, stripLinebreaks) {
  1619. var val = isTextarea($node[0]) ? $node.val() : $node.html();
  1620. if (stripLinebreaks) {
  1621. return val.replace(/[\n\r]/g, '');
  1622. }
  1623. return val;
  1624. }
  1625. /**
  1626. * @method html
  1627. *
  1628. * get the HTML contents of node
  1629. *
  1630. * @param {jQuery} $node
  1631. * @param {Boolean} [isNewlineOnBlock]
  1632. */
  1633. function html($node, isNewlineOnBlock) {
  1634. var markup = value($node);
  1635. if (isNewlineOnBlock) {
  1636. var regexTag = /<(\/?)(\b(?!!)[^>\s]*)(.*?)(\s*\/?>)/g;
  1637. markup = markup.replace(regexTag, function (match, endSlash, name) {
  1638. name = name.toUpperCase();
  1639. var isEndOfInlineContainer = /^DIV|^TD|^TH|^P|^LI|^H[1-7]/.test(name) && !!endSlash;
  1640. var isBlockNode = /^BLOCKQUOTE|^TABLE|^TBODY|^TR|^HR|^UL|^OL/.test(name);
  1641. return match + (isEndOfInlineContainer || isBlockNode ? '\n' : '');
  1642. });
  1643. markup = markup.trim();
  1644. }
  1645. return markup;
  1646. }
  1647. function posFromPlaceholder(placeholder) {
  1648. var $placeholder = external_jQuery_default()(placeholder);
  1649. var pos = $placeholder.offset();
  1650. var height = $placeholder.outerHeight(true); // include margin
  1651. return {
  1652. left: pos.left,
  1653. top: pos.top + height
  1654. };
  1655. }
  1656. function attachEvents($node, events) {
  1657. Object.keys(events).forEach(function (key) {
  1658. $node.on(key, events[key]);
  1659. });
  1660. }
  1661. function detachEvents($node, events) {
  1662. Object.keys(events).forEach(function (key) {
  1663. $node.off(key, events[key]);
  1664. });
  1665. }
  1666. /**
  1667. * @method isCustomStyleTag
  1668. *
  1669. * assert if a node contains a "note-styletag" class,
  1670. * which implies that's a custom-made style tag node
  1671. *
  1672. * @param {Node} an HTML DOM node
  1673. */
  1674. function isCustomStyleTag(node) {
  1675. return node && !isText(node) && lists.contains(node.classList, 'note-styletag');
  1676. }
  1677. /* harmony default export */ const dom = ({
  1678. /** @property {String} NBSP_CHAR */
  1679. NBSP_CHAR: NBSP_CHAR,
  1680. /** @property {String} ZERO_WIDTH_NBSP_CHAR */
  1681. ZERO_WIDTH_NBSP_CHAR: ZERO_WIDTH_NBSP_CHAR,
  1682. /** @property {String} blank */
  1683. blank: blankHTML,
  1684. /** @property {String} emptyPara */
  1685. emptyPara: "<p>".concat(blankHTML, "</p>"),
  1686. makePredByNodeName: makePredByNodeName,
  1687. isEditable: isEditable,
  1688. isControlSizing: isControlSizing,
  1689. isText: isText,
  1690. isElement: isElement,
  1691. isVoid: isVoid,
  1692. isPara: isPara,
  1693. isPurePara: isPurePara,
  1694. isHeading: isHeading,
  1695. isInline: isInline,
  1696. isBlock: func.not(isInline),
  1697. isBodyInline: isBodyInline,
  1698. isBody: isBody,
  1699. isParaInline: isParaInline,
  1700. isPre: isPre,
  1701. isList: isList,
  1702. isTable: isTable,
  1703. isData: isData,
  1704. isCell: isCell,
  1705. isBlockquote: isBlockquote,
  1706. isBodyContainer: isBodyContainer,
  1707. isAnchor: isAnchor,
  1708. isDiv: makePredByNodeName('DIV'),
  1709. isLi: isLi,
  1710. isBR: makePredByNodeName('BR'),
  1711. isSpan: makePredByNodeName('SPAN'),
  1712. isB: makePredByNodeName('B'),
  1713. isU: makePredByNodeName('U'),
  1714. isS: makePredByNodeName('S'),
  1715. isI: makePredByNodeName('I'),
  1716. isImg: makePredByNodeName('IMG'),
  1717. isTextarea: isTextarea,
  1718. deepestChildIsEmpty: deepestChildIsEmpty,
  1719. isEmpty: dom_isEmpty,
  1720. isEmptyAnchor: func.and(isAnchor, dom_isEmpty),
  1721. isClosestSibling: isClosestSibling,
  1722. withClosestSiblings: withClosestSiblings,
  1723. nodeLength: nodeLength,
  1724. isLeftEdgePoint: isLeftEdgePoint,
  1725. isRightEdgePoint: isRightEdgePoint,
  1726. isEdgePoint: isEdgePoint,
  1727. isLeftEdgeOf: isLeftEdgeOf,
  1728. isRightEdgeOf: isRightEdgeOf,
  1729. isLeftEdgePointOf: isLeftEdgePointOf,
  1730. isRightEdgePointOf: isRightEdgePointOf,
  1731. prevPoint: prevPoint,
  1732. nextPoint: nextPoint,
  1733. nextPointWithEmptyNode: nextPointWithEmptyNode,
  1734. isSamePoint: isSamePoint,
  1735. isVisiblePoint: isVisiblePoint,
  1736. prevPointUntil: prevPointUntil,
  1737. nextPointUntil: nextPointUntil,
  1738. isCharPoint: isCharPoint,
  1739. isSpacePoint: isSpacePoint,
  1740. walkPoint: walkPoint,
  1741. ancestor: ancestor,
  1742. singleChildAncestor: singleChildAncestor,
  1743. listAncestor: listAncestor,
  1744. lastAncestor: lastAncestor,
  1745. listNext: listNext,
  1746. listPrev: listPrev,
  1747. listDescendant: listDescendant,
  1748. commonAncestor: commonAncestor,
  1749. wrap: wrap,
  1750. insertAfter: insertAfter,
  1751. appendChildNodes: appendChildNodes,
  1752. position: position,
  1753. hasChildren: hasChildren,
  1754. makeOffsetPath: makeOffsetPath,
  1755. fromOffsetPath: fromOffsetPath,
  1756. splitTree: splitTree,
  1757. splitPoint: splitPoint,
  1758. create: create,
  1759. createText: createText,
  1760. remove: remove,
  1761. removeWhile: removeWhile,
  1762. replace: replace,
  1763. html: html,
  1764. value: value,
  1765. posFromPlaceholder: posFromPlaceholder,
  1766. attachEvents: attachEvents,
  1767. detachEvents: detachEvents,
  1768. isCustomStyleTag: isCustomStyleTag
  1769. });
  1770. ;// CONCATENATED MODULE: ./src/js/Context.js
  1771. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  1772. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  1773. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
  1774. var Context = /*#__PURE__*/function () {
  1775. /**
  1776. * @param {jQuery} $note
  1777. * @param {Object} options
  1778. */
  1779. function Context($note, options) {
  1780. _classCallCheck(this, Context);
  1781. this.$note = $note;
  1782. this.memos = {};
  1783. this.modules = {};
  1784. this.layoutInfo = {};
  1785. this.options = external_jQuery_default().extend(true, {}, options); // init ui with options
  1786. (external_jQuery_default()).summernote.ui = external_jQuery_default().summernote.ui_template(this.options);
  1787. this.ui = (external_jQuery_default()).summernote.ui;
  1788. this.initialize();
  1789. }
  1790. /**
  1791. * create layout and initialize modules and other resources
  1792. */
  1793. _createClass(Context, [{
  1794. key: "initialize",
  1795. value: function initialize() {
  1796. this.layoutInfo = this.ui.createLayout(this.$note);
  1797. this._initialize();
  1798. this.$note.hide();
  1799. return this;
  1800. }
  1801. /**
  1802. * destroy modules and other resources and remove layout
  1803. */
  1804. }, {
  1805. key: "destroy",
  1806. value: function destroy() {
  1807. this._destroy();
  1808. this.$note.removeData('summernote');
  1809. this.ui.removeLayout(this.$note, this.layoutInfo);
  1810. }
  1811. /**
  1812. * destory modules and other resources and initialize it again
  1813. */
  1814. }, {
  1815. key: "reset",
  1816. value: function reset() {
  1817. var disabled = this.isDisabled();
  1818. this.code(dom.emptyPara);
  1819. this._destroy();
  1820. this._initialize();
  1821. if (disabled) {
  1822. this.disable();
  1823. }
  1824. }
  1825. }, {
  1826. key: "_initialize",
  1827. value: function _initialize() {
  1828. var _this = this;
  1829. // set own id
  1830. this.options.id = func.uniqueId(external_jQuery_default().now()); // set default container for tooltips, popovers, and dialogs
  1831. this.options.container = this.options.container || this.layoutInfo.editor; // add optional buttons
  1832. var buttons = external_jQuery_default().extend({}, this.options.buttons);
  1833. Object.keys(buttons).forEach(function (key) {
  1834. _this.memo('button.' + key, buttons[key]);
  1835. });
  1836. var modules = external_jQuery_default().extend({}, this.options.modules, (external_jQuery_default()).summernote.plugins || {}); // add and initialize modules
  1837. Object.keys(modules).forEach(function (key) {
  1838. _this.module(key, modules[key], true);
  1839. });
  1840. Object.keys(this.modules).forEach(function (key) {
  1841. _this.initializeModule(key);
  1842. });
  1843. }
  1844. }, {
  1845. key: "_destroy",
  1846. value: function _destroy() {
  1847. var _this2 = this;
  1848. // destroy modules with reversed order
  1849. Object.keys(this.modules).reverse().forEach(function (key) {
  1850. _this2.removeModule(key);
  1851. });
  1852. Object.keys(this.memos).forEach(function (key) {
  1853. _this2.removeMemo(key);
  1854. }); // trigger custom onDestroy callback
  1855. this.triggerEvent('destroy', this);
  1856. }
  1857. }, {
  1858. key: "code",
  1859. value: function code(html) {
  1860. var isActivated = this.invoke('codeview.isActivated');
  1861. if (html === undefined) {
  1862. this.invoke('codeview.sync');
  1863. return isActivated ? this.layoutInfo.codable.val() : this.layoutInfo.editable.html();
  1864. } else {
  1865. if (isActivated) {
  1866. this.invoke('codeview.sync', html);
  1867. } else {
  1868. this.layoutInfo.editable.html(html);
  1869. }
  1870. this.$note.val(html);
  1871. this.triggerEvent('change', html, this.layoutInfo.editable);
  1872. }
  1873. }
  1874. }, {
  1875. key: "isDisabled",
  1876. value: function isDisabled() {
  1877. return this.layoutInfo.editable.attr('contenteditable') === 'false';
  1878. }
  1879. }, {
  1880. key: "enable",
  1881. value: function enable() {
  1882. this.layoutInfo.editable.attr('contenteditable', true);
  1883. this.invoke('toolbar.activate', true);
  1884. this.triggerEvent('disable', false);
  1885. this.options.editing = true;
  1886. }
  1887. }, {
  1888. key: "disable",
  1889. value: function disable() {
  1890. // close codeview if codeview is opend
  1891. if (this.invoke('codeview.isActivated')) {
  1892. this.invoke('codeview.deactivate');
  1893. }
  1894. this.layoutInfo.editable.attr('contenteditable', false);
  1895. this.options.editing = false;
  1896. this.invoke('toolbar.deactivate', true);
  1897. this.triggerEvent('disable', true);
  1898. }
  1899. }, {
  1900. key: "triggerEvent",
  1901. value: function triggerEvent() {
  1902. var namespace = lists.head(arguments);
  1903. var args = lists.tail(lists.from(arguments));
  1904. var callback = this.options.callbacks[func.namespaceToCamel(namespace, 'on')];
  1905. if (callback) {
  1906. callback.apply(this.$note[0], args);
  1907. }
  1908. this.$note.trigger('summernote.' + namespace, args);
  1909. }
  1910. }, {
  1911. key: "initializeModule",
  1912. value: function initializeModule(key) {
  1913. var module = this.modules[key];
  1914. module.shouldInitialize = module.shouldInitialize || func.ok;
  1915. if (!module.shouldInitialize()) {
  1916. return;
  1917. } // initialize module
  1918. if (module.initialize) {
  1919. module.initialize();
  1920. } // attach events
  1921. if (module.events) {
  1922. dom.attachEvents(this.$note, module.events);
  1923. }
  1924. }
  1925. }, {
  1926. key: "module",
  1927. value: function module(key, ModuleClass, withoutIntialize) {
  1928. if (arguments.length === 1) {
  1929. return this.modules[key];
  1930. }
  1931. this.modules[key] = new ModuleClass(this);
  1932. if (!withoutIntialize) {
  1933. this.initializeModule(key);
  1934. }
  1935. }
  1936. }, {
  1937. key: "removeModule",
  1938. value: function removeModule(key) {
  1939. var module = this.modules[key];
  1940. if (module.shouldInitialize()) {
  1941. if (module.events) {
  1942. dom.detachEvents(this.$note, module.events);
  1943. }
  1944. if (module.destroy) {
  1945. module.destroy();
  1946. }
  1947. }
  1948. delete this.modules[key];
  1949. }
  1950. }, {
  1951. key: "memo",
  1952. value: function memo(key, obj) {
  1953. if (arguments.length === 1) {
  1954. return this.memos[key];
  1955. }
  1956. this.memos[key] = obj;
  1957. }
  1958. }, {
  1959. key: "removeMemo",
  1960. value: function removeMemo(key) {
  1961. if (this.memos[key] && this.memos[key].destroy) {
  1962. this.memos[key].destroy();
  1963. }
  1964. delete this.memos[key];
  1965. }
  1966. /**
  1967. * Some buttons need to change their visual style immediately once they get pressed
  1968. */
  1969. }, {
  1970. key: "createInvokeHandlerAndUpdateState",
  1971. value: function createInvokeHandlerAndUpdateState(namespace, value) {
  1972. var _this3 = this;
  1973. return function (event) {
  1974. _this3.createInvokeHandler(namespace, value)(event);
  1975. _this3.invoke('buttons.updateCurrentStyle');
  1976. };
  1977. }
  1978. }, {
  1979. key: "createInvokeHandler",
  1980. value: function createInvokeHandler(namespace, value) {
  1981. var _this4 = this;
  1982. return function (event) {
  1983. event.preventDefault();
  1984. var $target = external_jQuery_default()(event.target);
  1985. _this4.invoke(namespace, value || $target.closest('[data-value]').data('value'), $target);
  1986. };
  1987. }
  1988. }, {
  1989. key: "invoke",
  1990. value: function invoke() {
  1991. var namespace = lists.head(arguments);
  1992. var args = lists.tail(lists.from(arguments));
  1993. var splits = namespace.split('.');
  1994. var hasSeparator = splits.length > 1;
  1995. var moduleName = hasSeparator && lists.head(splits);
  1996. var methodName = hasSeparator ? lists.last(splits) : lists.head(splits);
  1997. var module = this.modules[moduleName || 'editor'];
  1998. if (!moduleName && this[methodName]) {
  1999. return this[methodName].apply(this, args);
  2000. } else if (module && module[methodName] && module.shouldInitialize()) {
  2001. return module[methodName].apply(module, args);
  2002. }
  2003. }
  2004. }]);
  2005. return Context;
  2006. }();
  2007. ;// CONCATENATED MODULE: ./src/js/summernote.js
  2008. external_jQuery_default().fn.extend({
  2009. /**
  2010. * Summernote API
  2011. *
  2012. * @param {Object|String}
  2013. * @return {this}
  2014. */
  2015. summernote: function summernote() {
  2016. var type = external_jQuery_default().type(lists.head(arguments));
  2017. var isExternalAPICalled = type === 'string';
  2018. var hasInitOptions = type === 'object';
  2019. var options = external_jQuery_default().extend({}, (external_jQuery_default()).summernote.options, hasInitOptions ? lists.head(arguments) : {}); // Update options
  2020. options.langInfo = external_jQuery_default().extend(true, {}, (external_jQuery_default()).summernote.lang["en-US"], (external_jQuery_default()).summernote.lang[options.lang]);
  2021. options.icons = external_jQuery_default().extend(true, {}, (external_jQuery_default()).summernote.options.icons, options.icons);
  2022. options.tooltip = options.tooltip === 'auto' ? !env.isSupportTouch : options.tooltip;
  2023. this.each(function (idx, note) {
  2024. var $note = external_jQuery_default()(note);
  2025. if (!$note.data('summernote')) {
  2026. var context = new Context($note, options);
  2027. $note.data('summernote', context);
  2028. $note.data('summernote').triggerEvent('init', context.layoutInfo);
  2029. }
  2030. });
  2031. var $note = this.first();
  2032. if ($note.length) {
  2033. var context = $note.data('summernote');
  2034. if (isExternalAPICalled) {
  2035. return context.invoke.apply(context, lists.from(arguments));
  2036. } else if (options.focus) {
  2037. context.invoke('editor.focus');
  2038. }
  2039. }
  2040. return this;
  2041. }
  2042. });
  2043. ;// CONCATENATED MODULE: ./src/js/core/range.js
  2044. function range_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2045. function range_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  2046. function range_createClass(Constructor, protoProps, staticProps) { if (protoProps) range_defineProperties(Constructor.prototype, protoProps); if (staticProps) range_defineProperties(Constructor, staticProps); return Constructor; }
  2047. /**
  2048. * return boundaryPoint from TextRange, inspired by Andy Na's HuskyRange.js
  2049. *
  2050. * @param {TextRange} textRange
  2051. * @param {Boolean} isStart
  2052. * @return {BoundaryPoint}
  2053. *
  2054. * @see http://msdn.microsoft.com/en-us/library/ie/ms535872(v=vs.85).aspx
  2055. */
  2056. function textRangeToPoint(textRange, isStart) {
  2057. var container = textRange.parentElement();
  2058. var offset;
  2059. var tester = document.body.createTextRange();
  2060. var prevContainer;
  2061. var childNodes = lists.from(container.childNodes);
  2062. for (offset = 0; offset < childNodes.length; offset++) {
  2063. if (dom.isText(childNodes[offset])) {
  2064. continue;
  2065. }
  2066. tester.moveToElementText(childNodes[offset]);
  2067. if (tester.compareEndPoints('StartToStart', textRange) >= 0) {
  2068. break;
  2069. }
  2070. prevContainer = childNodes[offset];
  2071. }
  2072. if (offset !== 0 && dom.isText(childNodes[offset - 1])) {
  2073. var textRangeStart = document.body.createTextRange();
  2074. var curTextNode = null;
  2075. textRangeStart.moveToElementText(prevContainer || container);
  2076. textRangeStart.collapse(!prevContainer);
  2077. curTextNode = prevContainer ? prevContainer.nextSibling : container.firstChild;
  2078. var pointTester = textRange.duplicate();
  2079. pointTester.setEndPoint('StartToStart', textRangeStart);
  2080. var textCount = pointTester.text.replace(/[\r\n]/g, '').length;
  2081. while (textCount > curTextNode.nodeValue.length && curTextNode.nextSibling) {
  2082. textCount -= curTextNode.nodeValue.length;
  2083. curTextNode = curTextNode.nextSibling;
  2084. } // [workaround] enforce IE to re-reference curTextNode, hack
  2085. var dummy = curTextNode.nodeValue; // eslint-disable-line
  2086. if (isStart && curTextNode.nextSibling && dom.isText(curTextNode.nextSibling) && textCount === curTextNode.nodeValue.length) {
  2087. textCount -= curTextNode.nodeValue.length;
  2088. curTextNode = curTextNode.nextSibling;
  2089. }
  2090. container = curTextNode;
  2091. offset = textCount;
  2092. }
  2093. return {
  2094. cont: container,
  2095. offset: offset
  2096. };
  2097. }
  2098. /**
  2099. * return TextRange from boundary point (inspired by google closure-library)
  2100. * @param {BoundaryPoint} point
  2101. * @return {TextRange}
  2102. */
  2103. function pointToTextRange(point) {
  2104. var textRangeInfo = function textRangeInfo(container, offset) {
  2105. var node, isCollapseToStart;
  2106. if (dom.isText(container)) {
  2107. var prevTextNodes = dom.listPrev(container, func.not(dom.isText));
  2108. var prevContainer = lists.last(prevTextNodes).previousSibling;
  2109. node = prevContainer || container.parentNode;
  2110. offset += lists.sum(lists.tail(prevTextNodes), dom.nodeLength);
  2111. isCollapseToStart = !prevContainer;
  2112. } else {
  2113. node = container.childNodes[offset] || container;
  2114. if (dom.isText(node)) {
  2115. return textRangeInfo(node, 0);
  2116. }
  2117. offset = 0;
  2118. isCollapseToStart = false;
  2119. }
  2120. return {
  2121. node: node,
  2122. collapseToStart: isCollapseToStart,
  2123. offset: offset
  2124. };
  2125. };
  2126. var textRange = document.body.createTextRange();
  2127. var info = textRangeInfo(point.node, point.offset);
  2128. textRange.moveToElementText(info.node);
  2129. textRange.collapse(info.collapseToStart);
  2130. textRange.moveStart('character', info.offset);
  2131. return textRange;
  2132. }
  2133. /**
  2134. * Wrapped Range
  2135. *
  2136. * @constructor
  2137. * @param {Node} sc - start container
  2138. * @param {Number} so - start offset
  2139. * @param {Node} ec - end container
  2140. * @param {Number} eo - end offset
  2141. */
  2142. var WrappedRange = /*#__PURE__*/function () {
  2143. function WrappedRange(sc, so, ec, eo) {
  2144. range_classCallCheck(this, WrappedRange);
  2145. this.sc = sc;
  2146. this.so = so;
  2147. this.ec = ec;
  2148. this.eo = eo; // isOnEditable: judge whether range is on editable or not
  2149. this.isOnEditable = this.makeIsOn(dom.isEditable); // isOnList: judge whether range is on list node or not
  2150. this.isOnList = this.makeIsOn(dom.isList); // isOnAnchor: judge whether range is on anchor node or not
  2151. this.isOnAnchor = this.makeIsOn(dom.isAnchor); // isOnCell: judge whether range is on cell node or not
  2152. this.isOnCell = this.makeIsOn(dom.isCell); // isOnData: judge whether range is on data node or not
  2153. this.isOnData = this.makeIsOn(dom.isData);
  2154. } // nativeRange: get nativeRange from sc, so, ec, eo
  2155. range_createClass(WrappedRange, [{
  2156. key: "nativeRange",
  2157. value: function nativeRange() {
  2158. if (env.isW3CRangeSupport) {
  2159. var w3cRange = document.createRange();
  2160. w3cRange.setStart(this.sc, this.so);
  2161. w3cRange.setEnd(this.ec, this.eo);
  2162. return w3cRange;
  2163. } else {
  2164. var textRange = pointToTextRange({
  2165. node: this.sc,
  2166. offset: this.so
  2167. });
  2168. textRange.setEndPoint('EndToEnd', pointToTextRange({
  2169. node: this.ec,
  2170. offset: this.eo
  2171. }));
  2172. return textRange;
  2173. }
  2174. }
  2175. }, {
  2176. key: "getPoints",
  2177. value: function getPoints() {
  2178. return {
  2179. sc: this.sc,
  2180. so: this.so,
  2181. ec: this.ec,
  2182. eo: this.eo
  2183. };
  2184. }
  2185. }, {
  2186. key: "getStartPoint",
  2187. value: function getStartPoint() {
  2188. return {
  2189. node: this.sc,
  2190. offset: this.so
  2191. };
  2192. }
  2193. }, {
  2194. key: "getEndPoint",
  2195. value: function getEndPoint() {
  2196. return {
  2197. node: this.ec,
  2198. offset: this.eo
  2199. };
  2200. }
  2201. /**
  2202. * select update visible range
  2203. */
  2204. }, {
  2205. key: "select",
  2206. value: function select() {
  2207. var nativeRng = this.nativeRange();
  2208. if (env.isW3CRangeSupport) {
  2209. var selection = document.getSelection();
  2210. if (selection.rangeCount > 0) {
  2211. selection.removeAllRanges();
  2212. }
  2213. selection.addRange(nativeRng);
  2214. } else {
  2215. nativeRng.select();
  2216. }
  2217. return this;
  2218. }
  2219. /**
  2220. * Moves the scrollbar to start container(sc) of current range
  2221. *
  2222. * @return {WrappedRange}
  2223. */
  2224. }, {
  2225. key: "scrollIntoView",
  2226. value: function scrollIntoView(container) {
  2227. var height = external_jQuery_default()(container).height();
  2228. if (container.scrollTop + height < this.sc.offsetTop) {
  2229. container.scrollTop += Math.abs(container.scrollTop + height - this.sc.offsetTop);
  2230. }
  2231. return this;
  2232. }
  2233. /**
  2234. * @return {WrappedRange}
  2235. */
  2236. }, {
  2237. key: "normalize",
  2238. value: function normalize() {
  2239. /**
  2240. * @param {BoundaryPoint} point
  2241. * @param {Boolean} isLeftToRight - true: prefer to choose right node
  2242. * - false: prefer to choose left node
  2243. * @return {BoundaryPoint}
  2244. */
  2245. var getVisiblePoint = function getVisiblePoint(point, isLeftToRight) {
  2246. if (!point) {
  2247. return point;
  2248. } // Just use the given point [XXX:Adhoc]
  2249. // - case 01. if the point is on the middle of the node
  2250. // - case 02. if the point is on the right edge and prefer to choose left node
  2251. // - case 03. if the point is on the left edge and prefer to choose right node
  2252. // - case 04. if the point is on the right edge and prefer to choose right node but the node is void
  2253. // - case 05. if the point is on the left edge and prefer to choose left node but the node is void
  2254. // - case 06. if the point is on the block node and there is no children
  2255. if (dom.isVisiblePoint(point)) {
  2256. if (!dom.isEdgePoint(point) || dom.isRightEdgePoint(point) && !isLeftToRight || dom.isLeftEdgePoint(point) && isLeftToRight || dom.isRightEdgePoint(point) && isLeftToRight && dom.isVoid(point.node.nextSibling) || dom.isLeftEdgePoint(point) && !isLeftToRight && dom.isVoid(point.node.previousSibling) || dom.isBlock(point.node) && dom.isEmpty(point.node)) {
  2257. return point;
  2258. }
  2259. } // point on block's edge
  2260. var block = dom.ancestor(point.node, dom.isBlock);
  2261. var hasRightNode = false;
  2262. if (!hasRightNode) {
  2263. var prevPoint = dom.prevPoint(point) || {
  2264. node: null
  2265. };
  2266. hasRightNode = (dom.isLeftEdgePointOf(point, block) || dom.isVoid(prevPoint.node)) && !isLeftToRight;
  2267. }
  2268. var hasLeftNode = false;
  2269. if (!hasLeftNode) {
  2270. var _nextPoint = dom.nextPoint(point) || {
  2271. node: null
  2272. };
  2273. hasLeftNode = (dom.isRightEdgePointOf(point, block) || dom.isVoid(_nextPoint.node)) && isLeftToRight;
  2274. }
  2275. if (hasRightNode || hasLeftNode) {
  2276. // returns point already on visible point
  2277. if (dom.isVisiblePoint(point)) {
  2278. return point;
  2279. } // reverse direction
  2280. isLeftToRight = !isLeftToRight;
  2281. }
  2282. var nextPoint = isLeftToRight ? dom.nextPointUntil(dom.nextPoint(point), dom.isVisiblePoint) : dom.prevPointUntil(dom.prevPoint(point), dom.isVisiblePoint);
  2283. return nextPoint || point;
  2284. };
  2285. var endPoint = getVisiblePoint(this.getEndPoint(), false);
  2286. var startPoint = this.isCollapsed() ? endPoint : getVisiblePoint(this.getStartPoint(), true);
  2287. return new WrappedRange(startPoint.node, startPoint.offset, endPoint.node, endPoint.offset);
  2288. }
  2289. /**
  2290. * returns matched nodes on range
  2291. *
  2292. * @param {Function} [pred] - predicate function
  2293. * @param {Object} [options]
  2294. * @param {Boolean} [options.includeAncestor]
  2295. * @param {Boolean} [options.fullyContains]
  2296. * @return {Node[]}
  2297. */
  2298. }, {
  2299. key: "nodes",
  2300. value: function nodes(pred, options) {
  2301. pred = pred || func.ok;
  2302. var includeAncestor = options && options.includeAncestor;
  2303. var fullyContains = options && options.fullyContains; // TODO compare points and sort
  2304. var startPoint = this.getStartPoint();
  2305. var endPoint = this.getEndPoint();
  2306. var nodes = [];
  2307. var leftEdgeNodes = [];
  2308. dom.walkPoint(startPoint, endPoint, function (point) {
  2309. if (dom.isEditable(point.node)) {
  2310. return;
  2311. }
  2312. var node;
  2313. if (fullyContains) {
  2314. if (dom.isLeftEdgePoint(point)) {
  2315. leftEdgeNodes.push(point.node);
  2316. }
  2317. if (dom.isRightEdgePoint(point) && lists.contains(leftEdgeNodes, point.node)) {
  2318. node = point.node;
  2319. }
  2320. } else if (includeAncestor) {
  2321. node = dom.ancestor(point.node, pred);
  2322. } else {
  2323. node = point.node;
  2324. }
  2325. if (node && pred(node)) {
  2326. nodes.push(node);
  2327. }
  2328. }, true);
  2329. return lists.unique(nodes);
  2330. }
  2331. /**
  2332. * returns commonAncestor of range
  2333. * @return {Element} - commonAncestor
  2334. */
  2335. }, {
  2336. key: "commonAncestor",
  2337. value: function commonAncestor() {
  2338. return dom.commonAncestor(this.sc, this.ec);
  2339. }
  2340. /**
  2341. * returns expanded range by pred
  2342. *
  2343. * @param {Function} pred - predicate function
  2344. * @return {WrappedRange}
  2345. */
  2346. }, {
  2347. key: "expand",
  2348. value: function expand(pred) {
  2349. var startAncestor = dom.ancestor(this.sc, pred);
  2350. var endAncestor = dom.ancestor(this.ec, pred);
  2351. if (!startAncestor && !endAncestor) {
  2352. return new WrappedRange(this.sc, this.so, this.ec, this.eo);
  2353. }
  2354. var boundaryPoints = this.getPoints();
  2355. if (startAncestor) {
  2356. boundaryPoints.sc = startAncestor;
  2357. boundaryPoints.so = 0;
  2358. }
  2359. if (endAncestor) {
  2360. boundaryPoints.ec = endAncestor;
  2361. boundaryPoints.eo = dom.nodeLength(endAncestor);
  2362. }
  2363. return new WrappedRange(boundaryPoints.sc, boundaryPoints.so, boundaryPoints.ec, boundaryPoints.eo);
  2364. }
  2365. /**
  2366. * @param {Boolean} isCollapseToStart
  2367. * @return {WrappedRange}
  2368. */
  2369. }, {
  2370. key: "collapse",
  2371. value: function collapse(isCollapseToStart) {
  2372. if (isCollapseToStart) {
  2373. return new WrappedRange(this.sc, this.so, this.sc, this.so);
  2374. } else {
  2375. return new WrappedRange(this.ec, this.eo, this.ec, this.eo);
  2376. }
  2377. }
  2378. /**
  2379. * splitText on range
  2380. */
  2381. }, {
  2382. key: "splitText",
  2383. value: function splitText() {
  2384. var isSameContainer = this.sc === this.ec;
  2385. var boundaryPoints = this.getPoints();
  2386. if (dom.isText(this.ec) && !dom.isEdgePoint(this.getEndPoint())) {
  2387. this.ec.splitText(this.eo);
  2388. }
  2389. if (dom.isText(this.sc) && !dom.isEdgePoint(this.getStartPoint())) {
  2390. boundaryPoints.sc = this.sc.splitText(this.so);
  2391. boundaryPoints.so = 0;
  2392. if (isSameContainer) {
  2393. boundaryPoints.ec = boundaryPoints.sc;
  2394. boundaryPoints.eo = this.eo - this.so;
  2395. }
  2396. }
  2397. return new WrappedRange(boundaryPoints.sc, boundaryPoints.so, boundaryPoints.ec, boundaryPoints.eo);
  2398. }
  2399. /**
  2400. * delete contents on range
  2401. * @return {WrappedRange}
  2402. */
  2403. }, {
  2404. key: "deleteContents",
  2405. value: function deleteContents() {
  2406. if (this.isCollapsed()) {
  2407. return this;
  2408. }
  2409. var rng = this.splitText();
  2410. var nodes = rng.nodes(null, {
  2411. fullyContains: true
  2412. }); // find new cursor point
  2413. var point = dom.prevPointUntil(rng.getStartPoint(), function (point) {
  2414. return !lists.contains(nodes, point.node);
  2415. });
  2416. var emptyParents = [];
  2417. external_jQuery_default().each(nodes, function (idx, node) {
  2418. // find empty parents
  2419. var parent = node.parentNode;
  2420. if (point.node !== parent && dom.nodeLength(parent) === 1) {
  2421. emptyParents.push(parent);
  2422. }
  2423. dom.remove(node, false);
  2424. }); // remove empty parents
  2425. external_jQuery_default().each(emptyParents, function (idx, node) {
  2426. dom.remove(node, false);
  2427. });
  2428. return new WrappedRange(point.node, point.offset, point.node, point.offset).normalize();
  2429. }
  2430. /**
  2431. * makeIsOn: return isOn(pred) function
  2432. */
  2433. }, {
  2434. key: "makeIsOn",
  2435. value: function makeIsOn(pred) {
  2436. return function () {
  2437. var ancestor = dom.ancestor(this.sc, pred);
  2438. return !!ancestor && ancestor === dom.ancestor(this.ec, pred);
  2439. };
  2440. }
  2441. /**
  2442. * @param {Function} pred
  2443. * @return {Boolean}
  2444. */
  2445. }, {
  2446. key: "isLeftEdgeOf",
  2447. value: function isLeftEdgeOf(pred) {
  2448. if (!dom.isLeftEdgePoint(this.getStartPoint())) {
  2449. return false;
  2450. }
  2451. var node = dom.ancestor(this.sc, pred);
  2452. return node && dom.isLeftEdgeOf(this.sc, node);
  2453. }
  2454. /**
  2455. * returns whether range was collapsed or not
  2456. */
  2457. }, {
  2458. key: "isCollapsed",
  2459. value: function isCollapsed() {
  2460. return this.sc === this.ec && this.so === this.eo;
  2461. }
  2462. /**
  2463. * wrap inline nodes which children of body with paragraph
  2464. *
  2465. * @return {WrappedRange}
  2466. */
  2467. }, {
  2468. key: "wrapBodyInlineWithPara",
  2469. value: function wrapBodyInlineWithPara() {
  2470. if (dom.isBodyContainer(this.sc) && dom.isEmpty(this.sc)) {
  2471. this.sc.innerHTML = dom.emptyPara;
  2472. return new WrappedRange(this.sc.firstChild, 0, this.sc.firstChild, 0);
  2473. }
  2474. /**
  2475. * [workaround] firefox often create range on not visible point. so normalize here.
  2476. * - firefox: |<p>text</p>|
  2477. * - chrome: <p>|text|</p>
  2478. */
  2479. var rng = this.normalize();
  2480. if (dom.isParaInline(this.sc) || dom.isPara(this.sc)) {
  2481. return rng;
  2482. } // find inline top ancestor
  2483. var topAncestor;
  2484. if (dom.isInline(rng.sc)) {
  2485. var ancestors = dom.listAncestor(rng.sc, func.not(dom.isInline));
  2486. topAncestor = lists.last(ancestors);
  2487. if (!dom.isInline(topAncestor)) {
  2488. topAncestor = ancestors[ancestors.length - 2] || rng.sc.childNodes[rng.so];
  2489. }
  2490. } else {
  2491. topAncestor = rng.sc.childNodes[rng.so > 0 ? rng.so - 1 : 0];
  2492. }
  2493. if (topAncestor) {
  2494. // siblings not in paragraph
  2495. var inlineSiblings = dom.listPrev(topAncestor, dom.isParaInline).reverse();
  2496. inlineSiblings = inlineSiblings.concat(dom.listNext(topAncestor.nextSibling, dom.isParaInline)); // wrap with paragraph
  2497. if (inlineSiblings.length) {
  2498. var para = dom.wrap(lists.head(inlineSiblings), 'p');
  2499. dom.appendChildNodes(para, lists.tail(inlineSiblings));
  2500. }
  2501. }
  2502. return this.normalize();
  2503. }
  2504. /**
  2505. * insert node at current cursor
  2506. *
  2507. * @param {Node} node
  2508. * @return {Node}
  2509. */
  2510. }, {
  2511. key: "insertNode",
  2512. value: function insertNode(node) {
  2513. var rng = this;
  2514. if (dom.isText(node) || dom.isInline(node)) {
  2515. rng = this.wrapBodyInlineWithPara().deleteContents();
  2516. }
  2517. var info = dom.splitPoint(rng.getStartPoint(), dom.isInline(node));
  2518. if (info.rightNode) {
  2519. info.rightNode.parentNode.insertBefore(node, info.rightNode);
  2520. if (dom.isEmpty(info.rightNode) && dom.isPara(node)) {
  2521. info.rightNode.parentNode.removeChild(info.rightNode);
  2522. }
  2523. } else {
  2524. info.container.appendChild(node);
  2525. }
  2526. return node;
  2527. }
  2528. /**
  2529. * insert html at current cursor
  2530. */
  2531. }, {
  2532. key: "pasteHTML",
  2533. value: function pasteHTML(markup) {
  2534. markup = external_jQuery_default().trim(markup);
  2535. var contentsContainer = external_jQuery_default()('<div></div>').html(markup)[0];
  2536. var childNodes = lists.from(contentsContainer.childNodes); // const rng = this.wrapBodyInlineWithPara().deleteContents();
  2537. var rng = this;
  2538. var reversed = false;
  2539. if (rng.so >= 0) {
  2540. childNodes = childNodes.reverse();
  2541. reversed = true;
  2542. }
  2543. childNodes = childNodes.map(function (childNode) {
  2544. return rng.insertNode(childNode);
  2545. });
  2546. if (reversed) {
  2547. childNodes = childNodes.reverse();
  2548. }
  2549. return childNodes;
  2550. }
  2551. /**
  2552. * returns text in range
  2553. *
  2554. * @return {String}
  2555. */
  2556. }, {
  2557. key: "toString",
  2558. value: function toString() {
  2559. var nativeRng = this.nativeRange();
  2560. return env.isW3CRangeSupport ? nativeRng.toString() : nativeRng.text;
  2561. }
  2562. /**
  2563. * returns range for word before cursor
  2564. *
  2565. * @param {Boolean} [findAfter] - find after cursor, default: false
  2566. * @return {WrappedRange}
  2567. */
  2568. }, {
  2569. key: "getWordRange",
  2570. value: function getWordRange(findAfter) {
  2571. var endPoint = this.getEndPoint();
  2572. if (!dom.isCharPoint(endPoint)) {
  2573. return this;
  2574. }
  2575. var startPoint = dom.prevPointUntil(endPoint, function (point) {
  2576. return !dom.isCharPoint(point);
  2577. });
  2578. if (findAfter) {
  2579. endPoint = dom.nextPointUntil(endPoint, function (point) {
  2580. return !dom.isCharPoint(point);
  2581. });
  2582. }
  2583. return new WrappedRange(startPoint.node, startPoint.offset, endPoint.node, endPoint.offset);
  2584. }
  2585. /**
  2586. * returns range for words before cursor
  2587. *
  2588. * @param {Boolean} [findAfter] - find after cursor, default: false
  2589. * @return {WrappedRange}
  2590. */
  2591. }, {
  2592. key: "getWordsRange",
  2593. value: function getWordsRange(findAfter) {
  2594. var endPoint = this.getEndPoint();
  2595. var isNotTextPoint = function isNotTextPoint(point) {
  2596. return !dom.isCharPoint(point) && !dom.isSpacePoint(point);
  2597. };
  2598. if (isNotTextPoint(endPoint)) {
  2599. return this;
  2600. }
  2601. var startPoint = dom.prevPointUntil(endPoint, isNotTextPoint);
  2602. if (findAfter) {
  2603. endPoint = dom.nextPointUntil(endPoint, isNotTextPoint);
  2604. }
  2605. return new WrappedRange(startPoint.node, startPoint.offset, endPoint.node, endPoint.offset);
  2606. }
  2607. /**
  2608. * returns range for words before cursor that match with a Regex
  2609. *
  2610. * example:
  2611. * range: 'hi @Peter Pan'
  2612. * regex: '/@[a-z ]+/i'
  2613. * return range: '@Peter Pan'
  2614. *
  2615. * @param {RegExp} [regex]
  2616. * @return {WrappedRange|null}
  2617. */
  2618. }, {
  2619. key: "getWordsMatchRange",
  2620. value: function getWordsMatchRange(regex) {
  2621. var endPoint = this.getEndPoint();
  2622. var startPoint = dom.prevPointUntil(endPoint, function (point) {
  2623. if (!dom.isCharPoint(point) && !dom.isSpacePoint(point)) {
  2624. return true;
  2625. }
  2626. var rng = new WrappedRange(point.node, point.offset, endPoint.node, endPoint.offset);
  2627. var result = regex.exec(rng.toString());
  2628. return result && result.index === 0;
  2629. });
  2630. var rng = new WrappedRange(startPoint.node, startPoint.offset, endPoint.node, endPoint.offset);
  2631. var text = rng.toString();
  2632. var result = regex.exec(text);
  2633. if (result && result[0].length === text.length) {
  2634. return rng;
  2635. } else {
  2636. return null;
  2637. }
  2638. }
  2639. /**
  2640. * create offsetPath bookmark
  2641. *
  2642. * @param {Node} editable
  2643. */
  2644. }, {
  2645. key: "bookmark",
  2646. value: function bookmark(editable) {
  2647. return {
  2648. s: {
  2649. path: dom.makeOffsetPath(editable, this.sc),
  2650. offset: this.so
  2651. },
  2652. e: {
  2653. path: dom.makeOffsetPath(editable, this.ec),
  2654. offset: this.eo
  2655. }
  2656. };
  2657. }
  2658. /**
  2659. * create offsetPath bookmark base on paragraph
  2660. *
  2661. * @param {Node[]} paras
  2662. */
  2663. }, {
  2664. key: "paraBookmark",
  2665. value: function paraBookmark(paras) {
  2666. return {
  2667. s: {
  2668. path: lists.tail(dom.makeOffsetPath(lists.head(paras), this.sc)),
  2669. offset: this.so
  2670. },
  2671. e: {
  2672. path: lists.tail(dom.makeOffsetPath(lists.last(paras), this.ec)),
  2673. offset: this.eo
  2674. }
  2675. };
  2676. }
  2677. /**
  2678. * getClientRects
  2679. * @return {Rect[]}
  2680. */
  2681. }, {
  2682. key: "getClientRects",
  2683. value: function getClientRects() {
  2684. var nativeRng = this.nativeRange();
  2685. return nativeRng.getClientRects();
  2686. }
  2687. }]);
  2688. return WrappedRange;
  2689. }();
  2690. /**
  2691. * Data structure
  2692. * * BoundaryPoint: a point of dom tree
  2693. * * BoundaryPoints: two boundaryPoints corresponding to the start and the end of the Range
  2694. *
  2695. * See to http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Position
  2696. */
  2697. /* harmony default export */ const range = ({
  2698. /**
  2699. * create Range Object From arguments or Browser Selection
  2700. *
  2701. * @param {Node} sc - start container
  2702. * @param {Number} so - start offset
  2703. * @param {Node} ec - end container
  2704. * @param {Number} eo - end offset
  2705. * @return {WrappedRange}
  2706. */
  2707. create: function create(sc, so, ec, eo) {
  2708. if (arguments.length === 4) {
  2709. return new WrappedRange(sc, so, ec, eo);
  2710. } else if (arguments.length === 2) {
  2711. // collapsed
  2712. ec = sc;
  2713. eo = so;
  2714. return new WrappedRange(sc, so, ec, eo);
  2715. } else {
  2716. var wrappedRange = this.createFromSelection();
  2717. if (!wrappedRange && arguments.length === 1) {
  2718. var bodyElement = arguments[0];
  2719. if (dom.isEditable(bodyElement)) {
  2720. bodyElement = bodyElement.lastChild;
  2721. }
  2722. return this.createFromBodyElement(bodyElement, dom.emptyPara === arguments[0].innerHTML);
  2723. }
  2724. return wrappedRange;
  2725. }
  2726. },
  2727. createFromBodyElement: function createFromBodyElement(bodyElement) {
  2728. var isCollapseToStart = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  2729. var wrappedRange = this.createFromNode(bodyElement);
  2730. return wrappedRange.collapse(isCollapseToStart);
  2731. },
  2732. createFromSelection: function createFromSelection() {
  2733. var sc, so, ec, eo;
  2734. if (env.isW3CRangeSupport) {
  2735. var selection = document.getSelection();
  2736. if (!selection || selection.rangeCount === 0) {
  2737. return null;
  2738. } else if (dom.isBody(selection.anchorNode)) {
  2739. // Firefox: returns entire body as range on initialization.
  2740. // We won't never need it.
  2741. return null;
  2742. }
  2743. var nativeRng = selection.getRangeAt(0);
  2744. sc = nativeRng.startContainer;
  2745. so = nativeRng.startOffset;
  2746. ec = nativeRng.endContainer;
  2747. eo = nativeRng.endOffset;
  2748. } else {
  2749. // IE8: TextRange
  2750. var textRange = document.selection.createRange();
  2751. var textRangeEnd = textRange.duplicate();
  2752. textRangeEnd.collapse(false);
  2753. var textRangeStart = textRange;
  2754. textRangeStart.collapse(true);
  2755. var startPoint = textRangeToPoint(textRangeStart, true);
  2756. var endPoint = textRangeToPoint(textRangeEnd, false); // same visible point case: range was collapsed.
  2757. if (dom.isText(startPoint.node) && dom.isLeftEdgePoint(startPoint) && dom.isTextNode(endPoint.node) && dom.isRightEdgePoint(endPoint) && endPoint.node.nextSibling === startPoint.node) {
  2758. startPoint = endPoint;
  2759. }
  2760. sc = startPoint.cont;
  2761. so = startPoint.offset;
  2762. ec = endPoint.cont;
  2763. eo = endPoint.offset;
  2764. }
  2765. return new WrappedRange(sc, so, ec, eo);
  2766. },
  2767. /**
  2768. * @method
  2769. *
  2770. * create WrappedRange from node
  2771. *
  2772. * @param {Node} node
  2773. * @return {WrappedRange}
  2774. */
  2775. createFromNode: function createFromNode(node) {
  2776. var sc = node;
  2777. var so = 0;
  2778. var ec = node;
  2779. var eo = dom.nodeLength(ec); // browsers can't target a picture or void node
  2780. if (dom.isVoid(sc)) {
  2781. so = dom.listPrev(sc).length - 1;
  2782. sc = sc.parentNode;
  2783. }
  2784. if (dom.isBR(ec)) {
  2785. eo = dom.listPrev(ec).length - 1;
  2786. ec = ec.parentNode;
  2787. } else if (dom.isVoid(ec)) {
  2788. eo = dom.listPrev(ec).length;
  2789. ec = ec.parentNode;
  2790. }
  2791. return this.create(sc, so, ec, eo);
  2792. },
  2793. /**
  2794. * create WrappedRange from node after position
  2795. *
  2796. * @param {Node} node
  2797. * @return {WrappedRange}
  2798. */
  2799. createFromNodeBefore: function createFromNodeBefore(node) {
  2800. return this.createFromNode(node).collapse(true);
  2801. },
  2802. /**
  2803. * create WrappedRange from node after position
  2804. *
  2805. * @param {Node} node
  2806. * @return {WrappedRange}
  2807. */
  2808. createFromNodeAfter: function createFromNodeAfter(node) {
  2809. return this.createFromNode(node).collapse();
  2810. },
  2811. /**
  2812. * @method
  2813. *
  2814. * create WrappedRange from bookmark
  2815. *
  2816. * @param {Node} editable
  2817. * @param {Object} bookmark
  2818. * @return {WrappedRange}
  2819. */
  2820. createFromBookmark: function createFromBookmark(editable, bookmark) {
  2821. var sc = dom.fromOffsetPath(editable, bookmark.s.path);
  2822. var so = bookmark.s.offset;
  2823. var ec = dom.fromOffsetPath(editable, bookmark.e.path);
  2824. var eo = bookmark.e.offset;
  2825. return new WrappedRange(sc, so, ec, eo);
  2826. },
  2827. /**
  2828. * @method
  2829. *
  2830. * create WrappedRange from paraBookmark
  2831. *
  2832. * @param {Object} bookmark
  2833. * @param {Node[]} paras
  2834. * @return {WrappedRange}
  2835. */
  2836. createFromParaBookmark: function createFromParaBookmark(bookmark, paras) {
  2837. var so = bookmark.s.offset;
  2838. var eo = bookmark.e.offset;
  2839. var sc = dom.fromOffsetPath(lists.head(paras), bookmark.s.path);
  2840. var ec = dom.fromOffsetPath(lists.last(paras), bookmark.e.path);
  2841. return new WrappedRange(sc, so, ec, eo);
  2842. }
  2843. });
  2844. ;// CONCATENATED MODULE: ./src/js/core/key.js
  2845. var KEY_MAP = {
  2846. 'BACKSPACE': 8,
  2847. 'TAB': 9,
  2848. 'ENTER': 13,
  2849. 'ESCAPE': 27,
  2850. 'SPACE': 32,
  2851. 'DELETE': 46,
  2852. // Arrow
  2853. 'LEFT': 37,
  2854. 'UP': 38,
  2855. 'RIGHT': 39,
  2856. 'DOWN': 40,
  2857. // Number: 0-9
  2858. 'NUM0': 48,
  2859. 'NUM1': 49,
  2860. 'NUM2': 50,
  2861. 'NUM3': 51,
  2862. 'NUM4': 52,
  2863. 'NUM5': 53,
  2864. 'NUM6': 54,
  2865. 'NUM7': 55,
  2866. 'NUM8': 56,
  2867. // Alphabet: a-z
  2868. 'B': 66,
  2869. 'E': 69,
  2870. 'I': 73,
  2871. 'J': 74,
  2872. 'K': 75,
  2873. 'L': 76,
  2874. 'R': 82,
  2875. 'S': 83,
  2876. 'U': 85,
  2877. 'V': 86,
  2878. 'Y': 89,
  2879. 'Z': 90,
  2880. 'SLASH': 191,
  2881. 'LEFTBRACKET': 219,
  2882. 'BACKSLASH': 220,
  2883. 'RIGHTBRACKET': 221,
  2884. // Navigation
  2885. 'HOME': 36,
  2886. 'END': 35,
  2887. 'PAGEUP': 33,
  2888. 'PAGEDOWN': 34
  2889. };
  2890. /**
  2891. * @class core.key
  2892. *
  2893. * Object for keycodes.
  2894. *
  2895. * @singleton
  2896. * @alternateClassName key
  2897. */
  2898. /* harmony default export */ const key = ({
  2899. /**
  2900. * @method isEdit
  2901. *
  2902. * @param {Number} keyCode
  2903. * @return {Boolean}
  2904. */
  2905. isEdit: function isEdit(keyCode) {
  2906. return lists.contains([KEY_MAP.BACKSPACE, KEY_MAP.TAB, KEY_MAP.ENTER, KEY_MAP.SPACE, KEY_MAP.DELETE], keyCode);
  2907. },
  2908. /**
  2909. * @method isMove
  2910. *
  2911. * @param {Number} keyCode
  2912. * @return {Boolean}
  2913. */
  2914. isMove: function isMove(keyCode) {
  2915. return lists.contains([KEY_MAP.LEFT, KEY_MAP.UP, KEY_MAP.RIGHT, KEY_MAP.DOWN], keyCode);
  2916. },
  2917. /**
  2918. * @method isNavigation
  2919. *
  2920. * @param {Number} keyCode
  2921. * @return {Boolean}
  2922. */
  2923. isNavigation: function isNavigation(keyCode) {
  2924. return lists.contains([KEY_MAP.HOME, KEY_MAP.END, KEY_MAP.PAGEUP, KEY_MAP.PAGEDOWN], keyCode);
  2925. },
  2926. /**
  2927. * @property {Object} nameFromCode
  2928. * @property {String} nameFromCode.8 "BACKSPACE"
  2929. */
  2930. nameFromCode: func.invertObject(KEY_MAP),
  2931. code: KEY_MAP
  2932. });
  2933. ;// CONCATENATED MODULE: ./src/js/core/async.js
  2934. /**
  2935. * @method readFileAsDataURL
  2936. *
  2937. * read contents of file as representing URL
  2938. *
  2939. * @param {File} file
  2940. * @return {Promise} - then: dataUrl
  2941. */
  2942. function readFileAsDataURL(file) {
  2943. return external_jQuery_default().Deferred(function (deferred) {
  2944. external_jQuery_default().extend(new FileReader(), {
  2945. onload: function onload(e) {
  2946. var dataURL = e.target.result;
  2947. deferred.resolve(dataURL);
  2948. },
  2949. onerror: function onerror(err) {
  2950. deferred.reject(err);
  2951. }
  2952. }).readAsDataURL(file);
  2953. }).promise();
  2954. }
  2955. /**
  2956. * @method createImage
  2957. *
  2958. * create `<image>` from url string
  2959. *
  2960. * @param {String} url
  2961. * @return {Promise} - then: $image
  2962. */
  2963. function createImage(url) {
  2964. return external_jQuery_default().Deferred(function (deferred) {
  2965. var $img = external_jQuery_default()('<img>');
  2966. $img.one('load', function () {
  2967. $img.off('error abort');
  2968. deferred.resolve($img);
  2969. }).one('error abort', function () {
  2970. $img.off('load').detach();
  2971. deferred.reject($img);
  2972. }).css({
  2973. display: 'none'
  2974. }).appendTo(document.body).attr('src', url);
  2975. }).promise();
  2976. }
  2977. ;// CONCATENATED MODULE: ./src/js/editing/History.js
  2978. function History_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2979. function History_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  2980. function History_createClass(Constructor, protoProps, staticProps) { if (protoProps) History_defineProperties(Constructor.prototype, protoProps); if (staticProps) History_defineProperties(Constructor, staticProps); return Constructor; }
  2981. var History = /*#__PURE__*/function () {
  2982. function History(context) {
  2983. History_classCallCheck(this, History);
  2984. this.stack = [];
  2985. this.stackOffset = -1;
  2986. this.context = context;
  2987. this.$editable = context.layoutInfo.editable;
  2988. this.editable = this.$editable[0];
  2989. }
  2990. History_createClass(History, [{
  2991. key: "makeSnapshot",
  2992. value: function makeSnapshot() {
  2993. var rng = range.create(this.editable);
  2994. var emptyBookmark = {
  2995. s: {
  2996. path: [],
  2997. offset: 0
  2998. },
  2999. e: {
  3000. path: [],
  3001. offset: 0
  3002. }
  3003. };
  3004. return {
  3005. contents: this.$editable.html(),
  3006. bookmark: rng && rng.isOnEditable() ? rng.bookmark(this.editable) : emptyBookmark
  3007. };
  3008. }
  3009. }, {
  3010. key: "applySnapshot",
  3011. value: function applySnapshot(snapshot) {
  3012. if (snapshot.contents !== null) {
  3013. this.$editable.html(snapshot.contents);
  3014. }
  3015. if (snapshot.bookmark !== null) {
  3016. range.createFromBookmark(this.editable, snapshot.bookmark).select();
  3017. }
  3018. }
  3019. /**
  3020. * @method rewind
  3021. * Rewinds the history stack back to the first snapshot taken.
  3022. * Leaves the stack intact, so that "Redo" can still be used.
  3023. */
  3024. }, {
  3025. key: "rewind",
  3026. value: function rewind() {
  3027. // Create snap shot if not yet recorded
  3028. if (this.$editable.html() !== this.stack[this.stackOffset].contents) {
  3029. this.recordUndo();
  3030. } // Return to the first available snapshot.
  3031. this.stackOffset = 0; // Apply that snapshot.
  3032. this.applySnapshot(this.stack[this.stackOffset]);
  3033. }
  3034. /**
  3035. * @method commit
  3036. * Resets history stack, but keeps current editor's content.
  3037. */
  3038. }, {
  3039. key: "commit",
  3040. value: function commit() {
  3041. // Clear the stack.
  3042. this.stack = []; // Restore stackOffset to its original value.
  3043. this.stackOffset = -1; // Record our first snapshot (of nothing).
  3044. this.recordUndo();
  3045. }
  3046. /**
  3047. * @method reset
  3048. * Resets the history stack completely; reverting to an empty editor.
  3049. */
  3050. }, {
  3051. key: "reset",
  3052. value: function reset() {
  3053. // Clear the stack.
  3054. this.stack = []; // Restore stackOffset to its original value.
  3055. this.stackOffset = -1; // Clear the editable area.
  3056. this.$editable.html(''); // Record our first snapshot (of nothing).
  3057. this.recordUndo();
  3058. }
  3059. /**
  3060. * undo
  3061. */
  3062. }, {
  3063. key: "undo",
  3064. value: function undo() {
  3065. // Create snap shot if not yet recorded
  3066. if (this.$editable.html() !== this.stack[this.stackOffset].contents) {
  3067. this.recordUndo();
  3068. }
  3069. if (this.stackOffset > 0) {
  3070. this.stackOffset--;
  3071. this.applySnapshot(this.stack[this.stackOffset]);
  3072. }
  3073. }
  3074. /**
  3075. * redo
  3076. */
  3077. }, {
  3078. key: "redo",
  3079. value: function redo() {
  3080. if (this.stack.length - 1 > this.stackOffset) {
  3081. this.stackOffset++;
  3082. this.applySnapshot(this.stack[this.stackOffset]);
  3083. }
  3084. }
  3085. /**
  3086. * recorded undo
  3087. */
  3088. }, {
  3089. key: "recordUndo",
  3090. value: function recordUndo() {
  3091. this.stackOffset++; // Wash out stack after stackOffset
  3092. if (this.stack.length > this.stackOffset) {
  3093. this.stack = this.stack.slice(0, this.stackOffset);
  3094. } // Create new snapshot and push it to the end
  3095. this.stack.push(this.makeSnapshot()); // If the stack size reachs to the limit, then slice it
  3096. if (this.stack.length > this.context.options.historyLimit) {
  3097. this.stack.shift();
  3098. this.stackOffset -= 1;
  3099. }
  3100. }
  3101. }]);
  3102. return History;
  3103. }();
  3104. ;// CONCATENATED MODULE: ./src/js/editing/Style.js
  3105. function Style_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3106. function Style_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  3107. function Style_createClass(Constructor, protoProps, staticProps) { if (protoProps) Style_defineProperties(Constructor.prototype, protoProps); if (staticProps) Style_defineProperties(Constructor, staticProps); return Constructor; }
  3108. var Style = /*#__PURE__*/function () {
  3109. function Style() {
  3110. Style_classCallCheck(this, Style);
  3111. }
  3112. Style_createClass(Style, [{
  3113. key: "jQueryCSS",
  3114. value:
  3115. /**
  3116. * @method jQueryCSS
  3117. *
  3118. * [workaround] for old jQuery
  3119. * passing an array of style properties to .css()
  3120. * will result in an object of property-value pairs.
  3121. * (compability with version < 1.9)
  3122. *
  3123. * @private
  3124. * @param {jQuery} $obj
  3125. * @param {Array} propertyNames - An array of one or more CSS properties.
  3126. * @return {Object}
  3127. */
  3128. function jQueryCSS($obj, propertyNames) {
  3129. var result = {};
  3130. external_jQuery_default().each(propertyNames, function (idx, propertyName) {
  3131. result[propertyName] = $obj.css(propertyName);
  3132. });
  3133. return result;
  3134. }
  3135. /**
  3136. * returns style object from node
  3137. *
  3138. * @param {jQuery} $node
  3139. * @return {Object}
  3140. */
  3141. }, {
  3142. key: "fromNode",
  3143. value: function fromNode($node) {
  3144. var properties = ['font-family', 'font-size', 'text-align', 'list-style-type', 'line-height'];
  3145. var styleInfo = this.jQueryCSS($node, properties) || {};
  3146. var fontSize = $node[0].style.fontSize || styleInfo['font-size'];
  3147. styleInfo['font-size'] = parseInt(fontSize, 10);
  3148. styleInfo['font-size-unit'] = fontSize.match(/[a-z%]+$/);
  3149. return styleInfo;
  3150. }
  3151. /**
  3152. * paragraph level style
  3153. *
  3154. * @param {WrappedRange} rng
  3155. * @param {Object} styleInfo
  3156. */
  3157. }, {
  3158. key: "stylePara",
  3159. value: function stylePara(rng, styleInfo) {
  3160. external_jQuery_default().each(rng.nodes(dom.isPara, {
  3161. includeAncestor: true
  3162. }), function (idx, para) {
  3163. external_jQuery_default()(para).css(styleInfo);
  3164. });
  3165. }
  3166. /**
  3167. * insert and returns styleNodes on range.
  3168. *
  3169. * @param {WrappedRange} rng
  3170. * @param {Object} [options] - options for styleNodes
  3171. * @param {String} [options.nodeName] - default: `SPAN`
  3172. * @param {Boolean} [options.expandClosestSibling] - default: `false`
  3173. * @param {Boolean} [options.onlyPartialContains] - default: `false`
  3174. * @return {Node[]}
  3175. */
  3176. }, {
  3177. key: "styleNodes",
  3178. value: function styleNodes(rng, options) {
  3179. rng = rng.splitText();
  3180. var nodeName = options && options.nodeName || 'SPAN';
  3181. var expandClosestSibling = !!(options && options.expandClosestSibling);
  3182. var onlyPartialContains = !!(options && options.onlyPartialContains);
  3183. if (rng.isCollapsed()) {
  3184. return [rng.insertNode(dom.create(nodeName))];
  3185. }
  3186. var pred = dom.makePredByNodeName(nodeName);
  3187. var nodes = rng.nodes(dom.isText, {
  3188. fullyContains: true
  3189. }).map(function (text) {
  3190. return dom.singleChildAncestor(text, pred) || dom.wrap(text, nodeName);
  3191. });
  3192. if (expandClosestSibling) {
  3193. if (onlyPartialContains) {
  3194. var nodesInRange = rng.nodes(); // compose with partial contains predication
  3195. pred = func.and(pred, function (node) {
  3196. return lists.contains(nodesInRange, node);
  3197. });
  3198. }
  3199. return nodes.map(function (node) {
  3200. var siblings = dom.withClosestSiblings(node, pred);
  3201. var head = lists.head(siblings);
  3202. var tails = lists.tail(siblings);
  3203. external_jQuery_default().each(tails, function (idx, elem) {
  3204. dom.appendChildNodes(head, elem.childNodes);
  3205. dom.remove(elem);
  3206. });
  3207. return lists.head(siblings);
  3208. });
  3209. } else {
  3210. return nodes;
  3211. }
  3212. }
  3213. /**
  3214. * get current style on cursor
  3215. *
  3216. * @param {WrappedRange} rng
  3217. * @return {Object} - object contains style properties.
  3218. */
  3219. }, {
  3220. key: "current",
  3221. value: function current(rng) {
  3222. var $cont = external_jQuery_default()(!dom.isElement(rng.sc) ? rng.sc.parentNode : rng.sc);
  3223. var styleInfo = this.fromNode($cont); // document.queryCommandState for toggle state
  3224. // [workaround] prevent Firefox nsresult: "0x80004005 (NS_ERROR_FAILURE)"
  3225. try {
  3226. styleInfo = external_jQuery_default().extend(styleInfo, {
  3227. 'font-bold': document.queryCommandState('bold') ? 'bold' : 'normal',
  3228. 'font-italic': document.queryCommandState('italic') ? 'italic' : 'normal',
  3229. 'font-underline': document.queryCommandState('underline') ? 'underline' : 'normal',
  3230. 'font-subscript': document.queryCommandState('subscript') ? 'subscript' : 'normal',
  3231. 'font-superscript': document.queryCommandState('superscript') ? 'superscript' : 'normal',
  3232. 'font-strikethrough': document.queryCommandState('strikethrough') ? 'strikethrough' : 'normal',
  3233. 'font-family': document.queryCommandValue('fontname') || styleInfo['font-family']
  3234. });
  3235. } catch (e) {// eslint-disable-next-line
  3236. } // list-style-type to list-style(unordered, ordered)
  3237. if (!rng.isOnList()) {
  3238. styleInfo['list-style'] = 'none';
  3239. } else {
  3240. var orderedTypes = ['circle', 'disc', 'disc-leading-zero', 'square'];
  3241. var isUnordered = orderedTypes.indexOf(styleInfo['list-style-type']) > -1;
  3242. styleInfo['list-style'] = isUnordered ? 'unordered' : 'ordered';
  3243. }
  3244. var para = dom.ancestor(rng.sc, dom.isPara);
  3245. if (para && para.style['line-height']) {
  3246. styleInfo['line-height'] = para.style.lineHeight;
  3247. } else {
  3248. var lineHeight = parseInt(styleInfo['line-height'], 10) / parseInt(styleInfo['font-size'], 10);
  3249. styleInfo['line-height'] = lineHeight.toFixed(1);
  3250. }
  3251. styleInfo.anchor = rng.isOnAnchor() && dom.ancestor(rng.sc, dom.isAnchor);
  3252. styleInfo.ancestors = dom.listAncestor(rng.sc, dom.isEditable);
  3253. styleInfo.range = rng;
  3254. return styleInfo;
  3255. }
  3256. }]);
  3257. return Style;
  3258. }();
  3259. ;// CONCATENATED MODULE: ./src/js/editing/Bullet.js
  3260. function Bullet_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3261. function Bullet_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  3262. function Bullet_createClass(Constructor, protoProps, staticProps) { if (protoProps) Bullet_defineProperties(Constructor.prototype, protoProps); if (staticProps) Bullet_defineProperties(Constructor, staticProps); return Constructor; }
  3263. var Bullet = /*#__PURE__*/function () {
  3264. function Bullet() {
  3265. Bullet_classCallCheck(this, Bullet);
  3266. }
  3267. Bullet_createClass(Bullet, [{
  3268. key: "insertOrderedList",
  3269. value:
  3270. /**
  3271. * toggle ordered list
  3272. */
  3273. function insertOrderedList(editable) {
  3274. this.toggleList('OL', editable);
  3275. }
  3276. /**
  3277. * toggle unordered list
  3278. */
  3279. }, {
  3280. key: "insertUnorderedList",
  3281. value: function insertUnorderedList(editable) {
  3282. this.toggleList('UL', editable);
  3283. }
  3284. /**
  3285. * indent
  3286. */
  3287. }, {
  3288. key: "indent",
  3289. value: function indent(editable) {
  3290. var _this = this;
  3291. var rng = range.create(editable).wrapBodyInlineWithPara();
  3292. var paras = rng.nodes(dom.isPara, {
  3293. includeAncestor: true
  3294. });
  3295. var clustereds = lists.clusterBy(paras, func.peq2('parentNode'));
  3296. external_jQuery_default().each(clustereds, function (idx, paras) {
  3297. var head = lists.head(paras);
  3298. if (dom.isLi(head)) {
  3299. var previousList = _this.findList(head.previousSibling);
  3300. if (previousList) {
  3301. paras.map(function (para) {
  3302. return previousList.appendChild(para);
  3303. });
  3304. } else {
  3305. _this.wrapList(paras, head.parentNode.nodeName);
  3306. paras.map(function (para) {
  3307. return para.parentNode;
  3308. }).map(function (para) {
  3309. return _this.appendToPrevious(para);
  3310. });
  3311. }
  3312. } else {
  3313. external_jQuery_default().each(paras, function (idx, para) {
  3314. external_jQuery_default()(para).css('marginLeft', function (idx, val) {
  3315. return (parseInt(val, 10) || 0) + 25;
  3316. });
  3317. });
  3318. }
  3319. });
  3320. rng.select();
  3321. }
  3322. /**
  3323. * outdent
  3324. */
  3325. }, {
  3326. key: "outdent",
  3327. value: function outdent(editable) {
  3328. var _this2 = this;
  3329. var rng = range.create(editable).wrapBodyInlineWithPara();
  3330. var paras = rng.nodes(dom.isPara, {
  3331. includeAncestor: true
  3332. });
  3333. var clustereds = lists.clusterBy(paras, func.peq2('parentNode'));
  3334. external_jQuery_default().each(clustereds, function (idx, paras) {
  3335. var head = lists.head(paras);
  3336. if (dom.isLi(head)) {
  3337. _this2.releaseList([paras]);
  3338. } else {
  3339. external_jQuery_default().each(paras, function (idx, para) {
  3340. external_jQuery_default()(para).css('marginLeft', function (idx, val) {
  3341. val = parseInt(val, 10) || 0;
  3342. return val > 25 ? val - 25 : '';
  3343. });
  3344. });
  3345. }
  3346. });
  3347. rng.select();
  3348. }
  3349. /**
  3350. * toggle list
  3351. *
  3352. * @param {String} listName - OL or UL
  3353. */
  3354. }, {
  3355. key: "toggleList",
  3356. value: function toggleList(listName, editable) {
  3357. var _this3 = this;
  3358. var rng = range.create(editable).wrapBodyInlineWithPara();
  3359. var paras = rng.nodes(dom.isPara, {
  3360. includeAncestor: true
  3361. });
  3362. var bookmark = rng.paraBookmark(paras);
  3363. var clustereds = lists.clusterBy(paras, func.peq2('parentNode')); // paragraph to list
  3364. if (lists.find(paras, dom.isPurePara)) {
  3365. var wrappedParas = [];
  3366. external_jQuery_default().each(clustereds, function (idx, paras) {
  3367. wrappedParas = wrappedParas.concat(_this3.wrapList(paras, listName));
  3368. });
  3369. paras = wrappedParas; // list to paragraph or change list style
  3370. } else {
  3371. var diffLists = rng.nodes(dom.isList, {
  3372. includeAncestor: true
  3373. }).filter(function (listNode) {
  3374. return !external_jQuery_default().nodeName(listNode, listName);
  3375. });
  3376. if (diffLists.length) {
  3377. external_jQuery_default().each(diffLists, function (idx, listNode) {
  3378. dom.replace(listNode, listName);
  3379. });
  3380. } else {
  3381. paras = this.releaseList(clustereds, true);
  3382. }
  3383. }
  3384. range.createFromParaBookmark(bookmark, paras).select();
  3385. }
  3386. /**
  3387. * @param {Node[]} paras
  3388. * @param {String} listName
  3389. * @return {Node[]}
  3390. */
  3391. }, {
  3392. key: "wrapList",
  3393. value: function wrapList(paras, listName) {
  3394. var head = lists.head(paras);
  3395. var last = lists.last(paras);
  3396. var prevList = dom.isList(head.previousSibling) && head.previousSibling;
  3397. var nextList = dom.isList(last.nextSibling) && last.nextSibling;
  3398. var listNode = prevList || dom.insertAfter(dom.create(listName || 'UL'), last); // P to LI
  3399. paras = paras.map(function (para) {
  3400. return dom.isPurePara(para) ? dom.replace(para, 'LI') : para;
  3401. }); // append to list(<ul>, <ol>)
  3402. dom.appendChildNodes(listNode, paras);
  3403. if (nextList) {
  3404. dom.appendChildNodes(listNode, lists.from(nextList.childNodes));
  3405. dom.remove(nextList);
  3406. }
  3407. return paras;
  3408. }
  3409. /**
  3410. * @method releaseList
  3411. *
  3412. * @param {Array[]} clustereds
  3413. * @param {Boolean} isEscapseToBody
  3414. * @return {Node[]}
  3415. */
  3416. }, {
  3417. key: "releaseList",
  3418. value: function releaseList(clustereds, isEscapseToBody) {
  3419. var _this4 = this;
  3420. var releasedParas = [];
  3421. external_jQuery_default().each(clustereds, function (idx, paras) {
  3422. var head = lists.head(paras);
  3423. var last = lists.last(paras);
  3424. var headList = isEscapseToBody ? dom.lastAncestor(head, dom.isList) : head.parentNode;
  3425. var parentItem = headList.parentNode;
  3426. if (headList.parentNode.nodeName === 'LI') {
  3427. paras.map(function (para) {
  3428. var newList = _this4.findNextSiblings(para);
  3429. if (parentItem.nextSibling) {
  3430. parentItem.parentNode.insertBefore(para, parentItem.nextSibling);
  3431. } else {
  3432. parentItem.parentNode.appendChild(para);
  3433. }
  3434. if (newList.length) {
  3435. _this4.wrapList(newList, headList.nodeName);
  3436. para.appendChild(newList[0].parentNode);
  3437. }
  3438. });
  3439. if (headList.children.length === 0) {
  3440. parentItem.removeChild(headList);
  3441. }
  3442. if (parentItem.childNodes.length === 0) {
  3443. parentItem.parentNode.removeChild(parentItem);
  3444. }
  3445. } else {
  3446. var lastList = headList.childNodes.length > 1 ? dom.splitTree(headList, {
  3447. node: last.parentNode,
  3448. offset: dom.position(last) + 1
  3449. }, {
  3450. isSkipPaddingBlankHTML: true
  3451. }) : null;
  3452. var middleList = dom.splitTree(headList, {
  3453. node: head.parentNode,
  3454. offset: dom.position(head)
  3455. }, {
  3456. isSkipPaddingBlankHTML: true
  3457. });
  3458. paras = isEscapseToBody ? dom.listDescendant(middleList, dom.isLi) : lists.from(middleList.childNodes).filter(dom.isLi); // LI to P
  3459. if (isEscapseToBody || !dom.isList(headList.parentNode)) {
  3460. paras = paras.map(function (para) {
  3461. return dom.replace(para, 'P');
  3462. });
  3463. }
  3464. external_jQuery_default().each(lists.from(paras).reverse(), function (idx, para) {
  3465. dom.insertAfter(para, headList);
  3466. }); // remove empty lists
  3467. var rootLists = lists.compact([headList, middleList, lastList]);
  3468. external_jQuery_default().each(rootLists, function (idx, rootList) {
  3469. var listNodes = [rootList].concat(dom.listDescendant(rootList, dom.isList));
  3470. external_jQuery_default().each(listNodes.reverse(), function (idx, listNode) {
  3471. if (!dom.nodeLength(listNode)) {
  3472. dom.remove(listNode, true);
  3473. }
  3474. });
  3475. });
  3476. }
  3477. releasedParas = releasedParas.concat(paras);
  3478. });
  3479. return releasedParas;
  3480. }
  3481. /**
  3482. * @method appendToPrevious
  3483. *
  3484. * Appends list to previous list item, if
  3485. * none exist it wraps the list in a new list item.
  3486. *
  3487. * @param {HTMLNode} ListItem
  3488. * @return {HTMLNode}
  3489. */
  3490. }, {
  3491. key: "appendToPrevious",
  3492. value: function appendToPrevious(node) {
  3493. return node.previousSibling ? dom.appendChildNodes(node.previousSibling, [node]) : this.wrapList([node], 'LI');
  3494. }
  3495. /**
  3496. * @method findList
  3497. *
  3498. * Finds an existing list in list item
  3499. *
  3500. * @param {HTMLNode} ListItem
  3501. * @return {Array[]}
  3502. */
  3503. }, {
  3504. key: "findList",
  3505. value: function findList(node) {
  3506. return node ? lists.find(node.children, function (child) {
  3507. return ['OL', 'UL'].indexOf(child.nodeName) > -1;
  3508. }) : null;
  3509. }
  3510. /**
  3511. * @method findNextSiblings
  3512. *
  3513. * Finds all list item siblings that follow it
  3514. *
  3515. * @param {HTMLNode} ListItem
  3516. * @return {HTMLNode}
  3517. */
  3518. }, {
  3519. key: "findNextSiblings",
  3520. value: function findNextSiblings(node) {
  3521. var siblings = [];
  3522. while (node.nextSibling) {
  3523. siblings.push(node.nextSibling);
  3524. node = node.nextSibling;
  3525. }
  3526. return siblings;
  3527. }
  3528. }]);
  3529. return Bullet;
  3530. }();
  3531. ;// CONCATENATED MODULE: ./src/js/editing/Typing.js
  3532. function Typing_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3533. function Typing_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  3534. function Typing_createClass(Constructor, protoProps, staticProps) { if (protoProps) Typing_defineProperties(Constructor.prototype, protoProps); if (staticProps) Typing_defineProperties(Constructor, staticProps); return Constructor; }
  3535. /**
  3536. * @class editing.Typing
  3537. *
  3538. * Typing
  3539. *
  3540. */
  3541. var Typing = /*#__PURE__*/function () {
  3542. function Typing(context) {
  3543. Typing_classCallCheck(this, Typing);
  3544. // a Bullet instance to toggle lists off
  3545. this.bullet = new Bullet();
  3546. this.options = context.options;
  3547. }
  3548. /**
  3549. * insert tab
  3550. *
  3551. * @param {WrappedRange} rng
  3552. * @param {Number} tabsize
  3553. */
  3554. Typing_createClass(Typing, [{
  3555. key: "insertTab",
  3556. value: function insertTab(rng, tabsize) {
  3557. var tab = dom.createText(new Array(tabsize + 1).join(dom.NBSP_CHAR));
  3558. rng = rng.deleteContents();
  3559. rng.insertNode(tab, true);
  3560. rng = range.create(tab, tabsize);
  3561. rng.select();
  3562. }
  3563. /**
  3564. * insert paragraph
  3565. *
  3566. * @param {jQuery} $editable
  3567. * @param {WrappedRange} rng Can be used in unit tests to "mock" the range
  3568. *
  3569. * blockquoteBreakingLevel
  3570. * 0 - No break, the new paragraph remains inside the quote
  3571. * 1 - Break the first blockquote in the ancestors list
  3572. * 2 - Break all blockquotes, so that the new paragraph is not quoted (this is the default)
  3573. */
  3574. }, {
  3575. key: "insertParagraph",
  3576. value: function insertParagraph(editable, rng) {
  3577. rng = rng || range.create(editable); // deleteContents on range.
  3578. rng = rng.deleteContents(); // Wrap range if it needs to be wrapped by paragraph
  3579. rng = rng.wrapBodyInlineWithPara(); // finding paragraph
  3580. var splitRoot = dom.ancestor(rng.sc, dom.isPara);
  3581. var nextPara; // on paragraph: split paragraph
  3582. if (splitRoot) {
  3583. // if it is an empty line with li
  3584. if (dom.isLi(splitRoot) && (dom.isEmpty(splitRoot) || dom.deepestChildIsEmpty(splitRoot))) {
  3585. // toggle UL/OL and escape
  3586. this.bullet.toggleList(splitRoot.parentNode.nodeName);
  3587. return;
  3588. } else {
  3589. var blockquote = null;
  3590. if (this.options.blockquoteBreakingLevel === 1) {
  3591. blockquote = dom.ancestor(splitRoot, dom.isBlockquote);
  3592. } else if (this.options.blockquoteBreakingLevel === 2) {
  3593. blockquote = dom.lastAncestor(splitRoot, dom.isBlockquote);
  3594. }
  3595. if (blockquote) {
  3596. // We're inside a blockquote and options ask us to break it
  3597. nextPara = external_jQuery_default()(dom.emptyPara)[0]; // If the split is right before a <br>, remove it so that there's no "empty line"
  3598. // after the split in the new blockquote created
  3599. if (dom.isRightEdgePoint(rng.getStartPoint()) && dom.isBR(rng.sc.nextSibling)) {
  3600. external_jQuery_default()(rng.sc.nextSibling).remove();
  3601. }
  3602. var split = dom.splitTree(blockquote, rng.getStartPoint(), {
  3603. isDiscardEmptySplits: true
  3604. });
  3605. if (split) {
  3606. split.parentNode.insertBefore(nextPara, split);
  3607. } else {
  3608. dom.insertAfter(nextPara, blockquote); // There's no split if we were at the end of the blockquote
  3609. }
  3610. } else {
  3611. nextPara = dom.splitTree(splitRoot, rng.getStartPoint()); // not a blockquote, just insert the paragraph
  3612. var emptyAnchors = dom.listDescendant(splitRoot, dom.isEmptyAnchor);
  3613. emptyAnchors = emptyAnchors.concat(dom.listDescendant(nextPara, dom.isEmptyAnchor));
  3614. external_jQuery_default().each(emptyAnchors, function (idx, anchor) {
  3615. dom.remove(anchor);
  3616. }); // replace empty heading, pre or custom-made styleTag with P tag
  3617. if ((dom.isHeading(nextPara) || dom.isPre(nextPara) || dom.isCustomStyleTag(nextPara)) && dom.isEmpty(nextPara)) {
  3618. nextPara = dom.replace(nextPara, 'p');
  3619. }
  3620. }
  3621. } // no paragraph: insert empty paragraph
  3622. } else {
  3623. var next = rng.sc.childNodes[rng.so];
  3624. nextPara = external_jQuery_default()(dom.emptyPara)[0];
  3625. if (next) {
  3626. rng.sc.insertBefore(nextPara, next);
  3627. } else {
  3628. rng.sc.appendChild(nextPara);
  3629. }
  3630. }
  3631. range.create(nextPara, 0).normalize().select().scrollIntoView(editable);
  3632. }
  3633. }]);
  3634. return Typing;
  3635. }();
  3636. ;// CONCATENATED MODULE: ./src/js/editing/Table.js
  3637. function Table_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3638. function Table_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  3639. function Table_createClass(Constructor, protoProps, staticProps) { if (protoProps) Table_defineProperties(Constructor.prototype, protoProps); if (staticProps) Table_defineProperties(Constructor, staticProps); return Constructor; }
  3640. /**
  3641. * @class Create a virtual table to create what actions to do in change.
  3642. * @param {object} startPoint Cell selected to apply change.
  3643. * @param {enum} where Where change will be applied Row or Col. Use enum: TableResultAction.where
  3644. * @param {enum} action Action to be applied. Use enum: TableResultAction.requestAction
  3645. * @param {object} domTable Dom element of table to make changes.
  3646. */
  3647. var TableResultAction = function TableResultAction(startPoint, where, action, domTable) {
  3648. var _startPoint = {
  3649. 'colPos': 0,
  3650. 'rowPos': 0
  3651. };
  3652. var _virtualTable = [];
  3653. var _actionCellList = []; /// ///////////////////////////////////////////
  3654. // Private functions
  3655. /// ///////////////////////////////////////////
  3656. /**
  3657. * Set the startPoint of action.
  3658. */
  3659. function setStartPoint() {
  3660. if (!startPoint || !startPoint.tagName || startPoint.tagName.toLowerCase() !== 'td' && startPoint.tagName.toLowerCase() !== 'th') {
  3661. // Impossible to identify start Cell point
  3662. return;
  3663. }
  3664. _startPoint.colPos = startPoint.cellIndex;
  3665. if (!startPoint.parentElement || !startPoint.parentElement.tagName || startPoint.parentElement.tagName.toLowerCase() !== 'tr') {
  3666. // Impossible to identify start Row point
  3667. return;
  3668. }
  3669. _startPoint.rowPos = startPoint.parentElement.rowIndex;
  3670. }
  3671. /**
  3672. * Define virtual table position info object.
  3673. *
  3674. * @param {int} rowIndex Index position in line of virtual table.
  3675. * @param {int} cellIndex Index position in column of virtual table.
  3676. * @param {object} baseRow Row affected by this position.
  3677. * @param {object} baseCell Cell affected by this position.
  3678. * @param {bool} isSpan Inform if it is an span cell/row.
  3679. */
  3680. function setVirtualTablePosition(rowIndex, cellIndex, baseRow, baseCell, isRowSpan, isColSpan, isVirtualCell) {
  3681. var objPosition = {
  3682. 'baseRow': baseRow,
  3683. 'baseCell': baseCell,
  3684. 'isRowSpan': isRowSpan,
  3685. 'isColSpan': isColSpan,
  3686. 'isVirtual': isVirtualCell
  3687. };
  3688. if (!_virtualTable[rowIndex]) {
  3689. _virtualTable[rowIndex] = [];
  3690. }
  3691. _virtualTable[rowIndex][cellIndex] = objPosition;
  3692. }
  3693. /**
  3694. * Create action cell object.
  3695. *
  3696. * @param {object} virtualTableCellObj Object of specific position on virtual table.
  3697. * @param {enum} resultAction Action to be applied in that item.
  3698. */
  3699. function getActionCell(virtualTableCellObj, resultAction, virtualRowPosition, virtualColPosition) {
  3700. return {
  3701. 'baseCell': virtualTableCellObj.baseCell,
  3702. 'action': resultAction,
  3703. 'virtualTable': {
  3704. 'rowIndex': virtualRowPosition,
  3705. 'cellIndex': virtualColPosition
  3706. }
  3707. };
  3708. }
  3709. /**
  3710. * Recover free index of row to append Cell.
  3711. *
  3712. * @param {int} rowIndex Index of row to find free space.
  3713. * @param {int} cellIndex Index of cell to find free space in table.
  3714. */
  3715. function recoverCellIndex(rowIndex, cellIndex) {
  3716. if (!_virtualTable[rowIndex]) {
  3717. return cellIndex;
  3718. }
  3719. if (!_virtualTable[rowIndex][cellIndex]) {
  3720. return cellIndex;
  3721. }
  3722. var newCellIndex = cellIndex;
  3723. while (_virtualTable[rowIndex][newCellIndex]) {
  3724. newCellIndex++;
  3725. if (!_virtualTable[rowIndex][newCellIndex]) {
  3726. return newCellIndex;
  3727. }
  3728. }
  3729. }
  3730. /**
  3731. * Recover info about row and cell and add information to virtual table.
  3732. *
  3733. * @param {object} row Row to recover information.
  3734. * @param {object} cell Cell to recover information.
  3735. */
  3736. function addCellInfoToVirtual(row, cell) {
  3737. var cellIndex = recoverCellIndex(row.rowIndex, cell.cellIndex);
  3738. var cellHasColspan = cell.colSpan > 1;
  3739. var cellHasRowspan = cell.rowSpan > 1;
  3740. var isThisSelectedCell = row.rowIndex === _startPoint.rowPos && cell.cellIndex === _startPoint.colPos;
  3741. setVirtualTablePosition(row.rowIndex, cellIndex, row, cell, cellHasRowspan, cellHasColspan, false); // Add span rows to virtual Table.
  3742. var rowspanNumber = cell.attributes.rowSpan ? parseInt(cell.attributes.rowSpan.value, 10) : 0;
  3743. if (rowspanNumber > 1) {
  3744. for (var rp = 1; rp < rowspanNumber; rp++) {
  3745. var rowspanIndex = row.rowIndex + rp;
  3746. adjustStartPoint(rowspanIndex, cellIndex, cell, isThisSelectedCell);
  3747. setVirtualTablePosition(rowspanIndex, cellIndex, row, cell, true, cellHasColspan, true);
  3748. }
  3749. } // Add span cols to virtual table.
  3750. var colspanNumber = cell.attributes.colSpan ? parseInt(cell.attributes.colSpan.value, 10) : 0;
  3751. if (colspanNumber > 1) {
  3752. for (var cp = 1; cp < colspanNumber; cp++) {
  3753. var cellspanIndex = recoverCellIndex(row.rowIndex, cellIndex + cp);
  3754. adjustStartPoint(row.rowIndex, cellspanIndex, cell, isThisSelectedCell);
  3755. setVirtualTablePosition(row.rowIndex, cellspanIndex, row, cell, cellHasRowspan, true, true);
  3756. }
  3757. }
  3758. }
  3759. /**
  3760. * Process validation and adjust of start point if needed
  3761. *
  3762. * @param {int} rowIndex
  3763. * @param {int} cellIndex
  3764. * @param {object} cell
  3765. * @param {bool} isSelectedCell
  3766. */
  3767. function adjustStartPoint(rowIndex, cellIndex, cell, isSelectedCell) {
  3768. if (rowIndex === _startPoint.rowPos && _startPoint.colPos >= cell.cellIndex && cell.cellIndex <= cellIndex && !isSelectedCell) {
  3769. _startPoint.colPos++;
  3770. }
  3771. }
  3772. /**
  3773. * Create virtual table of cells with all cells, including span cells.
  3774. */
  3775. function createVirtualTable() {
  3776. var rows = domTable.rows;
  3777. for (var rowIndex = 0; rowIndex < rows.length; rowIndex++) {
  3778. var cells = rows[rowIndex].cells;
  3779. for (var cellIndex = 0; cellIndex < cells.length; cellIndex++) {
  3780. addCellInfoToVirtual(rows[rowIndex], cells[cellIndex]);
  3781. }
  3782. }
  3783. }
  3784. /**
  3785. * Get action to be applied on the cell.
  3786. *
  3787. * @param {object} cell virtual table cell to apply action
  3788. */
  3789. function getDeleteResultActionToCell(cell) {
  3790. switch (where) {
  3791. case TableResultAction.where.Column:
  3792. if (cell.isColSpan) {
  3793. return TableResultAction.resultAction.SubtractSpanCount;
  3794. }
  3795. break;
  3796. case TableResultAction.where.Row:
  3797. if (!cell.isVirtual && cell.isRowSpan) {
  3798. return TableResultAction.resultAction.AddCell;
  3799. } else if (cell.isRowSpan) {
  3800. return TableResultAction.resultAction.SubtractSpanCount;
  3801. }
  3802. break;
  3803. }
  3804. return TableResultAction.resultAction.RemoveCell;
  3805. }
  3806. /**
  3807. * Get action to be applied on the cell.
  3808. *
  3809. * @param {object} cell virtual table cell to apply action
  3810. */
  3811. function getAddResultActionToCell(cell) {
  3812. switch (where) {
  3813. case TableResultAction.where.Column:
  3814. if (cell.isColSpan) {
  3815. return TableResultAction.resultAction.SumSpanCount;
  3816. } else if (cell.isRowSpan && cell.isVirtual) {
  3817. return TableResultAction.resultAction.Ignore;
  3818. }
  3819. break;
  3820. case TableResultAction.where.Row:
  3821. if (cell.isRowSpan) {
  3822. return TableResultAction.resultAction.SumSpanCount;
  3823. } else if (cell.isColSpan && cell.isVirtual) {
  3824. return TableResultAction.resultAction.Ignore;
  3825. }
  3826. break;
  3827. }
  3828. return TableResultAction.resultAction.AddCell;
  3829. }
  3830. function init() {
  3831. setStartPoint();
  3832. createVirtualTable();
  3833. } /// ///////////////////////////////////////////
  3834. // Public functions
  3835. /// ///////////////////////////////////////////
  3836. /**
  3837. * Recover array os what to do in table.
  3838. */
  3839. this.getActionList = function () {
  3840. var fixedRow = where === TableResultAction.where.Row ? _startPoint.rowPos : -1;
  3841. var fixedCol = where === TableResultAction.where.Column ? _startPoint.colPos : -1;
  3842. var actualPosition = 0;
  3843. var canContinue = true;
  3844. while (canContinue) {
  3845. var rowPosition = fixedRow >= 0 ? fixedRow : actualPosition;
  3846. var colPosition = fixedCol >= 0 ? fixedCol : actualPosition;
  3847. var row = _virtualTable[rowPosition];
  3848. if (!row) {
  3849. canContinue = false;
  3850. return _actionCellList;
  3851. }
  3852. var cell = row[colPosition];
  3853. if (!cell) {
  3854. canContinue = false;
  3855. return _actionCellList;
  3856. } // Define action to be applied in this cell
  3857. var resultAction = TableResultAction.resultAction.Ignore;
  3858. switch (action) {
  3859. case TableResultAction.requestAction.Add:
  3860. resultAction = getAddResultActionToCell(cell);
  3861. break;
  3862. case TableResultAction.requestAction.Delete:
  3863. resultAction = getDeleteResultActionToCell(cell);
  3864. break;
  3865. }
  3866. _actionCellList.push(getActionCell(cell, resultAction, rowPosition, colPosition));
  3867. actualPosition++;
  3868. }
  3869. return _actionCellList;
  3870. };
  3871. init();
  3872. };
  3873. /**
  3874. *
  3875. * Where action occours enum.
  3876. */
  3877. TableResultAction.where = {
  3878. 'Row': 0,
  3879. 'Column': 1
  3880. };
  3881. /**
  3882. *
  3883. * Requested action to apply enum.
  3884. */
  3885. TableResultAction.requestAction = {
  3886. 'Add': 0,
  3887. 'Delete': 1
  3888. };
  3889. /**
  3890. *
  3891. * Result action to be executed enum.
  3892. */
  3893. TableResultAction.resultAction = {
  3894. 'Ignore': 0,
  3895. 'SubtractSpanCount': 1,
  3896. 'RemoveCell': 2,
  3897. 'AddCell': 3,
  3898. 'SumSpanCount': 4
  3899. };
  3900. /**
  3901. *
  3902. * @class editing.Table
  3903. *
  3904. * Table
  3905. *
  3906. */
  3907. var Table = /*#__PURE__*/function () {
  3908. function Table() {
  3909. Table_classCallCheck(this, Table);
  3910. }
  3911. Table_createClass(Table, [{
  3912. key: "tab",
  3913. value:
  3914. /**
  3915. * handle tab key
  3916. *
  3917. * @param {WrappedRange} rng
  3918. * @param {Boolean} isShift
  3919. */
  3920. function tab(rng, isShift) {
  3921. var cell = dom.ancestor(rng.commonAncestor(), dom.isCell);
  3922. var table = dom.ancestor(cell, dom.isTable);
  3923. var cells = dom.listDescendant(table, dom.isCell);
  3924. var nextCell = lists[isShift ? 'prev' : 'next'](cells, cell);
  3925. if (nextCell) {
  3926. range.create(nextCell, 0).select();
  3927. }
  3928. }
  3929. /**
  3930. * Add a new row
  3931. *
  3932. * @param {WrappedRange} rng
  3933. * @param {String} position (top/bottom)
  3934. * @return {Node}
  3935. */
  3936. }, {
  3937. key: "addRow",
  3938. value: function addRow(rng, position) {
  3939. var cell = dom.ancestor(rng.commonAncestor(), dom.isCell);
  3940. var currentTr = external_jQuery_default()(cell).closest('tr');
  3941. var trAttributes = this.recoverAttributes(currentTr);
  3942. var html = external_jQuery_default()('<tr' + trAttributes + '></tr>');
  3943. var vTable = new TableResultAction(cell, TableResultAction.where.Row, TableResultAction.requestAction.Add, external_jQuery_default()(currentTr).closest('table')[0]);
  3944. var actions = vTable.getActionList();
  3945. for (var idCell = 0; idCell < actions.length; idCell++) {
  3946. var currentCell = actions[idCell];
  3947. var tdAttributes = this.recoverAttributes(currentCell.baseCell);
  3948. switch (currentCell.action) {
  3949. case TableResultAction.resultAction.AddCell:
  3950. html.append('<td' + tdAttributes + '>' + dom.blank + '</td>');
  3951. break;
  3952. case TableResultAction.resultAction.SumSpanCount:
  3953. {
  3954. if (position === 'top') {
  3955. var baseCellTr = currentCell.baseCell.parent;
  3956. var isTopFromRowSpan = (!baseCellTr ? 0 : currentCell.baseCell.closest('tr').rowIndex) <= currentTr[0].rowIndex;
  3957. if (isTopFromRowSpan) {
  3958. var newTd = external_jQuery_default()('<div></div>').append(external_jQuery_default()('<td' + tdAttributes + '>' + dom.blank + '</td>').removeAttr('rowspan')).html();
  3959. html.append(newTd);
  3960. break;
  3961. }
  3962. }
  3963. var rowspanNumber = parseInt(currentCell.baseCell.rowSpan, 10);
  3964. rowspanNumber++;
  3965. currentCell.baseCell.setAttribute('rowSpan', rowspanNumber);
  3966. }
  3967. break;
  3968. }
  3969. }
  3970. if (position === 'top') {
  3971. currentTr.before(html);
  3972. } else {
  3973. var cellHasRowspan = cell.rowSpan > 1;
  3974. if (cellHasRowspan) {
  3975. var lastTrIndex = currentTr[0].rowIndex + (cell.rowSpan - 2);
  3976. external_jQuery_default()(external_jQuery_default()(currentTr).parent().find('tr')[lastTrIndex]).after(external_jQuery_default()(html));
  3977. return;
  3978. }
  3979. currentTr.after(html);
  3980. }
  3981. }
  3982. /**
  3983. * Add a new col
  3984. *
  3985. * @param {WrappedRange} rng
  3986. * @param {String} position (left/right)
  3987. * @return {Node}
  3988. */
  3989. }, {
  3990. key: "addCol",
  3991. value: function addCol(rng, position) {
  3992. var cell = dom.ancestor(rng.commonAncestor(), dom.isCell);
  3993. var row = external_jQuery_default()(cell).closest('tr');
  3994. var rowsGroup = external_jQuery_default()(row).siblings();
  3995. rowsGroup.push(row);
  3996. var vTable = new TableResultAction(cell, TableResultAction.where.Column, TableResultAction.requestAction.Add, external_jQuery_default()(row).closest('table')[0]);
  3997. var actions = vTable.getActionList();
  3998. for (var actionIndex = 0; actionIndex < actions.length; actionIndex++) {
  3999. var currentCell = actions[actionIndex];
  4000. var tdAttributes = this.recoverAttributes(currentCell.baseCell);
  4001. switch (currentCell.action) {
  4002. case TableResultAction.resultAction.AddCell:
  4003. if (position === 'right') {
  4004. external_jQuery_default()(currentCell.baseCell).after('<td' + tdAttributes + '>' + dom.blank + '</td>');
  4005. } else {
  4006. external_jQuery_default()(currentCell.baseCell).before('<td' + tdAttributes + '>' + dom.blank + '</td>');
  4007. }
  4008. break;
  4009. case TableResultAction.resultAction.SumSpanCount:
  4010. if (position === 'right') {
  4011. var colspanNumber = parseInt(currentCell.baseCell.colSpan, 10);
  4012. colspanNumber++;
  4013. currentCell.baseCell.setAttribute('colSpan', colspanNumber);
  4014. } else {
  4015. external_jQuery_default()(currentCell.baseCell).before('<td' + tdAttributes + '>' + dom.blank + '</td>');
  4016. }
  4017. break;
  4018. }
  4019. }
  4020. }
  4021. /*
  4022. * Copy attributes from element.
  4023. *
  4024. * @param {object} Element to recover attributes.
  4025. * @return {string} Copied string elements.
  4026. */
  4027. }, {
  4028. key: "recoverAttributes",
  4029. value: function recoverAttributes(el) {
  4030. var resultStr = '';
  4031. if (!el) {
  4032. return resultStr;
  4033. }
  4034. var attrList = el.attributes || [];
  4035. for (var i = 0; i < attrList.length; i++) {
  4036. if (attrList[i].name.toLowerCase() === 'id') {
  4037. continue;
  4038. }
  4039. if (attrList[i].specified) {
  4040. resultStr += ' ' + attrList[i].name + '=\'' + attrList[i].value + '\'';
  4041. }
  4042. }
  4043. return resultStr;
  4044. }
  4045. /**
  4046. * Delete current row
  4047. *
  4048. * @param {WrappedRange} rng
  4049. * @return {Node}
  4050. */
  4051. }, {
  4052. key: "deleteRow",
  4053. value: function deleteRow(rng) {
  4054. var cell = dom.ancestor(rng.commonAncestor(), dom.isCell);
  4055. var row = external_jQuery_default()(cell).closest('tr');
  4056. var cellPos = row.children('td, th').index(external_jQuery_default()(cell));
  4057. var rowPos = row[0].rowIndex;
  4058. var vTable = new TableResultAction(cell, TableResultAction.where.Row, TableResultAction.requestAction.Delete, external_jQuery_default()(row).closest('table')[0]);
  4059. var actions = vTable.getActionList();
  4060. for (var actionIndex = 0; actionIndex < actions.length; actionIndex++) {
  4061. if (!actions[actionIndex]) {
  4062. continue;
  4063. }
  4064. var baseCell = actions[actionIndex].baseCell;
  4065. var virtualPosition = actions[actionIndex].virtualTable;
  4066. var hasRowspan = baseCell.rowSpan && baseCell.rowSpan > 1;
  4067. var rowspanNumber = hasRowspan ? parseInt(baseCell.rowSpan, 10) : 0;
  4068. switch (actions[actionIndex].action) {
  4069. case TableResultAction.resultAction.Ignore:
  4070. continue;
  4071. case TableResultAction.resultAction.AddCell:
  4072. {
  4073. var nextRow = row.next('tr')[0];
  4074. if (!nextRow) {
  4075. continue;
  4076. }
  4077. var cloneRow = row[0].cells[cellPos];
  4078. if (hasRowspan) {
  4079. if (rowspanNumber > 2) {
  4080. rowspanNumber--;
  4081. nextRow.insertBefore(cloneRow, nextRow.cells[cellPos]);
  4082. nextRow.cells[cellPos].setAttribute('rowSpan', rowspanNumber);
  4083. nextRow.cells[cellPos].innerHTML = '';
  4084. } else if (rowspanNumber === 2) {
  4085. nextRow.insertBefore(cloneRow, nextRow.cells[cellPos]);
  4086. nextRow.cells[cellPos].removeAttribute('rowSpan');
  4087. nextRow.cells[cellPos].innerHTML = '';
  4088. }
  4089. }
  4090. }
  4091. continue;
  4092. case TableResultAction.resultAction.SubtractSpanCount:
  4093. if (hasRowspan) {
  4094. if (rowspanNumber > 2) {
  4095. rowspanNumber--;
  4096. baseCell.setAttribute('rowSpan', rowspanNumber);
  4097. if (virtualPosition.rowIndex !== rowPos && baseCell.cellIndex === cellPos) {
  4098. baseCell.innerHTML = '';
  4099. }
  4100. } else if (rowspanNumber === 2) {
  4101. baseCell.removeAttribute('rowSpan');
  4102. if (virtualPosition.rowIndex !== rowPos && baseCell.cellIndex === cellPos) {
  4103. baseCell.innerHTML = '';
  4104. }
  4105. }
  4106. }
  4107. continue;
  4108. case TableResultAction.resultAction.RemoveCell:
  4109. // Do not need remove cell because row will be deleted.
  4110. continue;
  4111. }
  4112. }
  4113. row.remove();
  4114. }
  4115. /**
  4116. * Delete current col
  4117. *
  4118. * @param {WrappedRange} rng
  4119. * @return {Node}
  4120. */
  4121. }, {
  4122. key: "deleteCol",
  4123. value: function deleteCol(rng) {
  4124. var cell = dom.ancestor(rng.commonAncestor(), dom.isCell);
  4125. var row = external_jQuery_default()(cell).closest('tr');
  4126. var cellPos = row.children('td, th').index(external_jQuery_default()(cell));
  4127. var vTable = new TableResultAction(cell, TableResultAction.where.Column, TableResultAction.requestAction.Delete, external_jQuery_default()(row).closest('table')[0]);
  4128. var actions = vTable.getActionList();
  4129. for (var actionIndex = 0; actionIndex < actions.length; actionIndex++) {
  4130. if (!actions[actionIndex]) {
  4131. continue;
  4132. }
  4133. switch (actions[actionIndex].action) {
  4134. case TableResultAction.resultAction.Ignore:
  4135. continue;
  4136. case TableResultAction.resultAction.SubtractSpanCount:
  4137. {
  4138. var baseCell = actions[actionIndex].baseCell;
  4139. var hasColspan = baseCell.colSpan && baseCell.colSpan > 1;
  4140. if (hasColspan) {
  4141. var colspanNumber = baseCell.colSpan ? parseInt(baseCell.colSpan, 10) : 0;
  4142. if (colspanNumber > 2) {
  4143. colspanNumber--;
  4144. baseCell.setAttribute('colSpan', colspanNumber);
  4145. if (baseCell.cellIndex === cellPos) {
  4146. baseCell.innerHTML = '';
  4147. }
  4148. } else if (colspanNumber === 2) {
  4149. baseCell.removeAttribute('colSpan');
  4150. if (baseCell.cellIndex === cellPos) {
  4151. baseCell.innerHTML = '';
  4152. }
  4153. }
  4154. }
  4155. }
  4156. continue;
  4157. case TableResultAction.resultAction.RemoveCell:
  4158. dom.remove(actions[actionIndex].baseCell, true);
  4159. continue;
  4160. }
  4161. }
  4162. }
  4163. /**
  4164. * create empty table element
  4165. *
  4166. * @param {Number} rowCount
  4167. * @param {Number} colCount
  4168. * @return {Node}
  4169. */
  4170. }, {
  4171. key: "createTable",
  4172. value: function createTable(colCount, rowCount, options) {
  4173. var tds = [];
  4174. var tdHTML;
  4175. for (var idxCol = 0; idxCol < colCount; idxCol++) {
  4176. tds.push('<td>' + dom.blank + '</td>');
  4177. }
  4178. tdHTML = tds.join('');
  4179. var trs = [];
  4180. var trHTML;
  4181. for (var idxRow = 0; idxRow < rowCount; idxRow++) {
  4182. trs.push('<tr>' + tdHTML + '</tr>');
  4183. }
  4184. trHTML = trs.join('');
  4185. var $table = external_jQuery_default()('<table>' + trHTML + '</table>');
  4186. if (options && options.tableClassName) {
  4187. $table.addClass(options.tableClassName);
  4188. }
  4189. return $table[0];
  4190. }
  4191. /**
  4192. * Delete current table
  4193. *
  4194. * @param {WrappedRange} rng
  4195. * @return {Node}
  4196. */
  4197. }, {
  4198. key: "deleteTable",
  4199. value: function deleteTable(rng) {
  4200. var cell = dom.ancestor(rng.commonAncestor(), dom.isCell);
  4201. external_jQuery_default()(cell).closest('table').remove();
  4202. }
  4203. }]);
  4204. return Table;
  4205. }();
  4206. ;// CONCATENATED MODULE: ./src/js/module/Editor.js
  4207. function Editor_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4208. function Editor_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  4209. function Editor_createClass(Constructor, protoProps, staticProps) { if (protoProps) Editor_defineProperties(Constructor.prototype, protoProps); if (staticProps) Editor_defineProperties(Constructor, staticProps); return Constructor; }
  4210. var KEY_BOGUS = 'bogus';
  4211. /**
  4212. * @class Editor
  4213. */
  4214. var Editor = /*#__PURE__*/function () {
  4215. function Editor(context) {
  4216. var _this = this;
  4217. Editor_classCallCheck(this, Editor);
  4218. this.context = context;
  4219. this.$note = context.layoutInfo.note;
  4220. this.$editor = context.layoutInfo.editor;
  4221. this.$editable = context.layoutInfo.editable;
  4222. this.options = context.options;
  4223. this.lang = this.options.langInfo;
  4224. this.editable = this.$editable[0];
  4225. this.lastRange = null;
  4226. this.snapshot = null;
  4227. this.style = new Style();
  4228. this.table = new Table();
  4229. this.typing = new Typing(context);
  4230. this.bullet = new Bullet();
  4231. this.history = new History(context);
  4232. this.context.memo('help.escape', this.lang.help.escape);
  4233. this.context.memo('help.undo', this.lang.help.undo);
  4234. this.context.memo('help.redo', this.lang.help.redo);
  4235. this.context.memo('help.tab', this.lang.help.tab);
  4236. this.context.memo('help.untab', this.lang.help.untab);
  4237. this.context.memo('help.insertParagraph', this.lang.help.insertParagraph);
  4238. this.context.memo('help.insertOrderedList', this.lang.help.insertOrderedList);
  4239. this.context.memo('help.insertUnorderedList', this.lang.help.insertUnorderedList);
  4240. this.context.memo('help.indent', this.lang.help.indent);
  4241. this.context.memo('help.outdent', this.lang.help.outdent);
  4242. this.context.memo('help.formatPara', this.lang.help.formatPara);
  4243. this.context.memo('help.insertHorizontalRule', this.lang.help.insertHorizontalRule);
  4244. this.context.memo('help.fontName', this.lang.help.fontName); // native commands(with execCommand), generate function for execCommand
  4245. var commands = ['bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript', 'justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull', 'formatBlock', 'removeFormat', 'backColor'];
  4246. for (var idx = 0, len = commands.length; idx < len; idx++) {
  4247. this[commands[idx]] = function (sCmd) {
  4248. return function (value) {
  4249. _this.beforeCommand();
  4250. document.execCommand(sCmd, false, value);
  4251. _this.afterCommand(true);
  4252. };
  4253. }(commands[idx]);
  4254. this.context.memo('help.' + commands[idx], this.lang.help[commands[idx]]);
  4255. }
  4256. this.fontName = this.wrapCommand(function (value) {
  4257. return _this.fontStyling('font-family', env.validFontName(value));
  4258. });
  4259. this.fontSize = this.wrapCommand(function (value) {
  4260. var unit = _this.currentStyle()['font-size-unit'];
  4261. return _this.fontStyling('font-size', value + unit);
  4262. });
  4263. this.fontSizeUnit = this.wrapCommand(function (value) {
  4264. var size = _this.currentStyle()['font-size'];
  4265. return _this.fontStyling('font-size', size + value);
  4266. });
  4267. for (var _idx = 1; _idx <= 6; _idx++) {
  4268. this['formatH' + _idx] = function (idx) {
  4269. return function () {
  4270. _this.formatBlock('H' + idx);
  4271. };
  4272. }(_idx);
  4273. this.context.memo('help.formatH' + _idx, this.lang.help['formatH' + _idx]);
  4274. }
  4275. this.insertParagraph = this.wrapCommand(function () {
  4276. _this.typing.insertParagraph(_this.editable);
  4277. });
  4278. this.insertOrderedList = this.wrapCommand(function () {
  4279. _this.bullet.insertOrderedList(_this.editable);
  4280. });
  4281. this.insertUnorderedList = this.wrapCommand(function () {
  4282. _this.bullet.insertUnorderedList(_this.editable);
  4283. });
  4284. this.indent = this.wrapCommand(function () {
  4285. _this.bullet.indent(_this.editable);
  4286. });
  4287. this.outdent = this.wrapCommand(function () {
  4288. _this.bullet.outdent(_this.editable);
  4289. });
  4290. /**
  4291. * insertNode
  4292. * insert node
  4293. * @param {Node} node
  4294. */
  4295. this.insertNode = this.wrapCommand(function (node) {
  4296. if (_this.isLimited(external_jQuery_default()(node).text().length)) {
  4297. return;
  4298. }
  4299. var rng = _this.getLastRange();
  4300. rng.insertNode(node);
  4301. _this.setLastRange(range.createFromNodeAfter(node).select());
  4302. });
  4303. /**
  4304. * insert text
  4305. * @param {String} text
  4306. */
  4307. this.insertText = this.wrapCommand(function (text) {
  4308. if (_this.isLimited(text.length)) {
  4309. return;
  4310. }
  4311. var rng = _this.getLastRange();
  4312. var textNode = rng.insertNode(dom.createText(text));
  4313. _this.setLastRange(range.create(textNode, dom.nodeLength(textNode)).select());
  4314. });
  4315. /**
  4316. * paste HTML
  4317. * @param {String} markup
  4318. */
  4319. this.pasteHTML = this.wrapCommand(function (markup) {
  4320. if (_this.isLimited(markup.length)) {
  4321. return;
  4322. }
  4323. markup = _this.context.invoke('codeview.purify', markup);
  4324. var contents = _this.getLastRange().pasteHTML(markup);
  4325. _this.setLastRange(range.createFromNodeAfter(lists.last(contents)).select());
  4326. });
  4327. /**
  4328. * formatBlock
  4329. *
  4330. * @param {String} tagName
  4331. */
  4332. this.formatBlock = this.wrapCommand(function (tagName, $target) {
  4333. var onApplyCustomStyle = _this.options.callbacks.onApplyCustomStyle;
  4334. if (onApplyCustomStyle) {
  4335. onApplyCustomStyle.call(_this, $target, _this.context, _this.onFormatBlock);
  4336. } else {
  4337. _this.onFormatBlock(tagName, $target);
  4338. }
  4339. });
  4340. /**
  4341. * insert horizontal rule
  4342. */
  4343. this.insertHorizontalRule = this.wrapCommand(function () {
  4344. var hrNode = _this.getLastRange().insertNode(dom.create('HR'));
  4345. if (hrNode.nextSibling) {
  4346. _this.setLastRange(range.create(hrNode.nextSibling, 0).normalize().select());
  4347. }
  4348. });
  4349. /**
  4350. * lineHeight
  4351. * @param {String} value
  4352. */
  4353. this.lineHeight = this.wrapCommand(function (value) {
  4354. _this.style.stylePara(_this.getLastRange(), {
  4355. lineHeight: value
  4356. });
  4357. });
  4358. /**
  4359. * create link (command)
  4360. *
  4361. * @param {Object} linkInfo
  4362. */
  4363. this.createLink = this.wrapCommand(function (linkInfo) {
  4364. var linkUrl = linkInfo.url;
  4365. var linkText = linkInfo.text;
  4366. var isNewWindow = linkInfo.isNewWindow;
  4367. var checkProtocol = linkInfo.checkProtocol;
  4368. var rng = linkInfo.range || _this.getLastRange();
  4369. var additionalTextLength = linkText.length - rng.toString().length;
  4370. if (additionalTextLength > 0 && _this.isLimited(additionalTextLength)) {
  4371. return;
  4372. }
  4373. var isTextChanged = rng.toString() !== linkText; // handle spaced urls from input
  4374. if (typeof linkUrl === 'string') {
  4375. linkUrl = linkUrl.trim();
  4376. }
  4377. if (_this.options.onCreateLink) {
  4378. linkUrl = _this.options.onCreateLink(linkUrl);
  4379. } else if (checkProtocol) {
  4380. // if url doesn't have any protocol and not even a relative or a label, use http:// as default
  4381. linkUrl = /^([A-Za-z][A-Za-z0-9+-.]*\:|#|\/)/.test(linkUrl) ? linkUrl : _this.options.defaultProtocol + linkUrl;
  4382. }
  4383. var anchors = [];
  4384. if (isTextChanged) {
  4385. rng = rng.deleteContents();
  4386. var anchor = rng.insertNode(external_jQuery_default()('<A>' + linkText + '</A>')[0]);
  4387. anchors.push(anchor);
  4388. } else {
  4389. anchors = _this.style.styleNodes(rng, {
  4390. nodeName: 'A',
  4391. expandClosestSibling: true,
  4392. onlyPartialContains: true
  4393. });
  4394. }
  4395. external_jQuery_default().each(anchors, function (idx, anchor) {
  4396. external_jQuery_default()(anchor).attr('href', linkUrl);
  4397. if (isNewWindow) {
  4398. external_jQuery_default()(anchor).attr('target', '_blank');
  4399. } else {
  4400. external_jQuery_default()(anchor).removeAttr('target');
  4401. }
  4402. });
  4403. _this.setLastRange(_this.createRangeFromList(anchors).select());
  4404. });
  4405. /**
  4406. * setting color
  4407. *
  4408. * @param {Object} sObjColor color code
  4409. * @param {String} sObjColor.foreColor foreground color
  4410. * @param {String} sObjColor.backColor background color
  4411. */
  4412. this.color = this.wrapCommand(function (colorInfo) {
  4413. var foreColor = colorInfo.foreColor;
  4414. var backColor = colorInfo.backColor;
  4415. if (foreColor) {
  4416. document.execCommand('foreColor', false, foreColor);
  4417. }
  4418. if (backColor) {
  4419. document.execCommand('backColor', false, backColor);
  4420. }
  4421. });
  4422. /**
  4423. * Set foreground color
  4424. *
  4425. * @param {String} colorCode foreground color code
  4426. */
  4427. this.foreColor = this.wrapCommand(function (colorInfo) {
  4428. document.execCommand('foreColor', false, colorInfo);
  4429. });
  4430. /**
  4431. * insert Table
  4432. *
  4433. * @param {String} dimension of table (ex : "5x5")
  4434. */
  4435. this.insertTable = this.wrapCommand(function (dim) {
  4436. var dimension = dim.split('x');
  4437. var rng = _this.getLastRange().deleteContents();
  4438. rng.insertNode(_this.table.createTable(dimension[0], dimension[1], _this.options));
  4439. });
  4440. /**
  4441. * remove media object and Figure Elements if media object is img with Figure.
  4442. */
  4443. this.removeMedia = this.wrapCommand(function () {
  4444. var $target = external_jQuery_default()(_this.restoreTarget()).parent();
  4445. if ($target.closest('figure').length) {
  4446. $target.closest('figure').remove();
  4447. } else {
  4448. $target = external_jQuery_default()(_this.restoreTarget()).detach();
  4449. }
  4450. _this.context.triggerEvent('media.delete', $target, _this.$editable);
  4451. });
  4452. /**
  4453. * float me
  4454. *
  4455. * @param {String} value
  4456. */
  4457. this.floatMe = this.wrapCommand(function (value) {
  4458. var $target = external_jQuery_default()(_this.restoreTarget());
  4459. $target.toggleClass('note-float-left', value === 'left');
  4460. $target.toggleClass('note-float-right', value === 'right');
  4461. $target.css('float', value === 'none' ? '' : value);
  4462. });
  4463. /**
  4464. * resize overlay element
  4465. * @param {String} value
  4466. */
  4467. this.resize = this.wrapCommand(function (value) {
  4468. var $target = external_jQuery_default()(_this.restoreTarget());
  4469. value = parseFloat(value);
  4470. if (value === 0) {
  4471. $target.css('width', '');
  4472. } else {
  4473. $target.css({
  4474. width: value * 100 + '%',
  4475. height: ''
  4476. });
  4477. }
  4478. });
  4479. }
  4480. Editor_createClass(Editor, [{
  4481. key: "initialize",
  4482. value: function initialize() {
  4483. var _this2 = this;
  4484. // bind custom events
  4485. this.$editable.on('keydown', function (event) {
  4486. if (event.keyCode === key.code.ENTER) {
  4487. _this2.context.triggerEvent('enter', event);
  4488. }
  4489. _this2.context.triggerEvent('keydown', event); // keep a snapshot to limit text on input event
  4490. _this2.snapshot = _this2.history.makeSnapshot();
  4491. _this2.hasKeyShortCut = false;
  4492. if (!event.isDefaultPrevented()) {
  4493. if (_this2.options.shortcuts) {
  4494. _this2.hasKeyShortCut = _this2.handleKeyMap(event);
  4495. } else {
  4496. _this2.preventDefaultEditableShortCuts(event);
  4497. }
  4498. }
  4499. if (_this2.isLimited(1, event)) {
  4500. var lastRange = _this2.getLastRange();
  4501. if (lastRange.eo - lastRange.so === 0) {
  4502. return false;
  4503. }
  4504. }
  4505. _this2.setLastRange(); // record undo in the key event except keyMap.
  4506. if (_this2.options.recordEveryKeystroke) {
  4507. if (_this2.hasKeyShortCut === false) {
  4508. _this2.history.recordUndo();
  4509. }
  4510. }
  4511. }).on('keyup', function (event) {
  4512. _this2.setLastRange();
  4513. _this2.context.triggerEvent('keyup', event);
  4514. }).on('focus', function (event) {
  4515. _this2.setLastRange();
  4516. _this2.context.triggerEvent('focus', event);
  4517. }).on('blur', function (event) {
  4518. _this2.context.triggerEvent('blur', event);
  4519. }).on('mousedown', function (event) {
  4520. _this2.context.triggerEvent('mousedown', event);
  4521. }).on('mouseup', function (event) {
  4522. _this2.setLastRange();
  4523. _this2.history.recordUndo();
  4524. _this2.context.triggerEvent('mouseup', event);
  4525. }).on('scroll', function (event) {
  4526. _this2.context.triggerEvent('scroll', event);
  4527. }).on('paste', function (event) {
  4528. _this2.setLastRange();
  4529. _this2.context.triggerEvent('paste', event);
  4530. }).on('input', function () {
  4531. // To limit composition characters (e.g. Korean)
  4532. if (_this2.isLimited(0) && _this2.snapshot) {
  4533. _this2.history.applySnapshot(_this2.snapshot);
  4534. }
  4535. });
  4536. this.$editable.attr('spellcheck', this.options.spellCheck);
  4537. this.$editable.attr('autocorrect', this.options.spellCheck);
  4538. if (this.options.disableGrammar) {
  4539. this.$editable.attr('data-gramm', false);
  4540. } // init content before set event
  4541. this.$editable.html(dom.html(this.$note) || dom.emptyPara);
  4542. this.$editable.on(env.inputEventName, func.debounce(function () {
  4543. _this2.context.triggerEvent('change', _this2.$editable.html(), _this2.$editable);
  4544. }, 10));
  4545. this.$editable.on('focusin', function (event) {
  4546. _this2.context.triggerEvent('focusin', event);
  4547. }).on('focusout', function (event) {
  4548. _this2.context.triggerEvent('focusout', event);
  4549. });
  4550. if (this.options.airMode) {
  4551. if (this.options.overrideContextMenu) {
  4552. this.$editor.on('contextmenu', function (event) {
  4553. _this2.context.triggerEvent('contextmenu', event);
  4554. return false;
  4555. });
  4556. }
  4557. } else {
  4558. if (this.options.width) {
  4559. this.$editor.outerWidth(this.options.width);
  4560. }
  4561. if (this.options.height) {
  4562. this.$editable.outerHeight(this.options.height);
  4563. }
  4564. if (this.options.maxHeight) {
  4565. this.$editable.css('max-height', this.options.maxHeight);
  4566. }
  4567. if (this.options.minHeight) {
  4568. this.$editable.css('min-height', this.options.minHeight);
  4569. }
  4570. }
  4571. this.history.recordUndo();
  4572. this.setLastRange();
  4573. }
  4574. }, {
  4575. key: "destroy",
  4576. value: function destroy() {
  4577. this.$editable.off();
  4578. }
  4579. }, {
  4580. key: "handleKeyMap",
  4581. value: function handleKeyMap(event) {
  4582. var keyMap = this.options.keyMap[env.isMac ? 'mac' : 'pc'];
  4583. var keys = [];
  4584. if (event.metaKey) {
  4585. keys.push('CMD');
  4586. }
  4587. if (event.ctrlKey && !event.altKey) {
  4588. keys.push('CTRL');
  4589. }
  4590. if (event.shiftKey) {
  4591. keys.push('SHIFT');
  4592. }
  4593. var keyName = key.nameFromCode[event.keyCode];
  4594. if (keyName) {
  4595. keys.push(keyName);
  4596. }
  4597. var eventName = keyMap[keys.join('+')];
  4598. if (keyName === 'TAB' && !this.options.tabDisable) {
  4599. this.afterCommand();
  4600. } else if (eventName) {
  4601. if (this.context.invoke(eventName) !== false) {
  4602. event.preventDefault(); // if keyMap action was invoked
  4603. return true;
  4604. }
  4605. } else if (key.isEdit(event.keyCode)) {
  4606. this.afterCommand();
  4607. }
  4608. return false;
  4609. }
  4610. }, {
  4611. key: "preventDefaultEditableShortCuts",
  4612. value: function preventDefaultEditableShortCuts(event) {
  4613. // B(Bold, 66) / I(Italic, 73) / U(Underline, 85)
  4614. if ((event.ctrlKey || event.metaKey) && lists.contains([66, 73, 85], event.keyCode)) {
  4615. event.preventDefault();
  4616. }
  4617. }
  4618. }, {
  4619. key: "isLimited",
  4620. value: function isLimited(pad, event) {
  4621. pad = pad || 0;
  4622. if (typeof event !== 'undefined') {
  4623. if (key.isMove(event.keyCode) || key.isNavigation(event.keyCode) || event.ctrlKey || event.metaKey || lists.contains([key.code.BACKSPACE, key.code.DELETE], event.keyCode)) {
  4624. return false;
  4625. }
  4626. }
  4627. if (this.options.maxTextLength > 0) {
  4628. if (this.$editable.text().length + pad > this.options.maxTextLength) {
  4629. return true;
  4630. }
  4631. }
  4632. return false;
  4633. }
  4634. /**
  4635. * create range
  4636. * @return {WrappedRange}
  4637. */
  4638. }, {
  4639. key: "createRange",
  4640. value: function createRange() {
  4641. this.focus();
  4642. this.setLastRange();
  4643. return this.getLastRange();
  4644. }
  4645. /**
  4646. * create a new range from the list of elements
  4647. *
  4648. * @param {list} dom element list
  4649. * @return {WrappedRange}
  4650. */
  4651. }, {
  4652. key: "createRangeFromList",
  4653. value: function createRangeFromList(lst) {
  4654. var startRange = range.createFromNodeBefore(lists.head(lst));
  4655. var startPoint = startRange.getStartPoint();
  4656. var endRange = range.createFromNodeAfter(lists.last(lst));
  4657. var endPoint = endRange.getEndPoint();
  4658. return range.create(startPoint.node, startPoint.offset, endPoint.node, endPoint.offset);
  4659. }
  4660. /**
  4661. * set the last range
  4662. *
  4663. * if given rng is exist, set rng as the last range
  4664. * or create a new range at the end of the document
  4665. *
  4666. * @param {WrappedRange} rng
  4667. */
  4668. }, {
  4669. key: "setLastRange",
  4670. value: function setLastRange(rng) {
  4671. if (rng) {
  4672. this.lastRange = rng;
  4673. } else {
  4674. this.lastRange = range.create(this.editable);
  4675. if (external_jQuery_default()(this.lastRange.sc).closest('.note-editable').length === 0) {
  4676. this.lastRange = range.createFromBodyElement(this.editable);
  4677. }
  4678. }
  4679. }
  4680. /**
  4681. * get the last range
  4682. *
  4683. * if there is a saved last range, return it
  4684. * or create a new range and return it
  4685. *
  4686. * @return {WrappedRange}
  4687. */
  4688. }, {
  4689. key: "getLastRange",
  4690. value: function getLastRange() {
  4691. if (!this.lastRange) {
  4692. this.setLastRange();
  4693. }
  4694. return this.lastRange;
  4695. }
  4696. /**
  4697. * saveRange
  4698. *
  4699. * save current range
  4700. *
  4701. * @param {Boolean} [thenCollapse=false]
  4702. */
  4703. }, {
  4704. key: "saveRange",
  4705. value: function saveRange(thenCollapse) {
  4706. if (thenCollapse) {
  4707. this.getLastRange().collapse().select();
  4708. }
  4709. }
  4710. /**
  4711. * restoreRange
  4712. *
  4713. * restore lately range
  4714. */
  4715. }, {
  4716. key: "restoreRange",
  4717. value: function restoreRange() {
  4718. if (this.lastRange) {
  4719. this.lastRange.select();
  4720. this.focus();
  4721. }
  4722. }
  4723. }, {
  4724. key: "saveTarget",
  4725. value: function saveTarget(node) {
  4726. this.$editable.data('target', node);
  4727. }
  4728. }, {
  4729. key: "clearTarget",
  4730. value: function clearTarget() {
  4731. this.$editable.removeData('target');
  4732. }
  4733. }, {
  4734. key: "restoreTarget",
  4735. value: function restoreTarget() {
  4736. return this.$editable.data('target');
  4737. }
  4738. /**
  4739. * currentStyle
  4740. *
  4741. * current style
  4742. * @return {Object|Boolean} unfocus
  4743. */
  4744. }, {
  4745. key: "currentStyle",
  4746. value: function currentStyle() {
  4747. var rng = range.create();
  4748. if (rng) {
  4749. rng = rng.normalize();
  4750. }
  4751. return rng ? this.style.current(rng) : this.style.fromNode(this.$editable);
  4752. }
  4753. /**
  4754. * style from node
  4755. *
  4756. * @param {jQuery} $node
  4757. * @return {Object}
  4758. */
  4759. }, {
  4760. key: "styleFromNode",
  4761. value: function styleFromNode($node) {
  4762. return this.style.fromNode($node);
  4763. }
  4764. /**
  4765. * undo
  4766. */
  4767. }, {
  4768. key: "undo",
  4769. value: function undo() {
  4770. this.context.triggerEvent('before.command', this.$editable.html());
  4771. this.history.undo();
  4772. this.context.triggerEvent('change', this.$editable.html(), this.$editable);
  4773. }
  4774. /*
  4775. * commit
  4776. */
  4777. }, {
  4778. key: "commit",
  4779. value: function commit() {
  4780. this.context.triggerEvent('before.command', this.$editable.html());
  4781. this.history.commit();
  4782. this.context.triggerEvent('change', this.$editable.html(), this.$editable);
  4783. }
  4784. /**
  4785. * redo
  4786. */
  4787. }, {
  4788. key: "redo",
  4789. value: function redo() {
  4790. this.context.triggerEvent('before.command', this.$editable.html());
  4791. this.history.redo();
  4792. this.context.triggerEvent('change', this.$editable.html(), this.$editable);
  4793. }
  4794. /**
  4795. * before command
  4796. */
  4797. }, {
  4798. key: "beforeCommand",
  4799. value: function beforeCommand() {
  4800. this.context.triggerEvent('before.command', this.$editable.html()); // Set styleWithCSS before run a command
  4801. document.execCommand('styleWithCSS', false, this.options.styleWithCSS); // keep focus on editable before command execution
  4802. this.focus();
  4803. }
  4804. /**
  4805. * after command
  4806. * @param {Boolean} isPreventTrigger
  4807. */
  4808. }, {
  4809. key: "afterCommand",
  4810. value: function afterCommand(isPreventTrigger) {
  4811. this.normalizeContent();
  4812. this.history.recordUndo();
  4813. if (!isPreventTrigger) {
  4814. this.context.triggerEvent('change', this.$editable.html(), this.$editable);
  4815. }
  4816. }
  4817. /**
  4818. * handle tab key
  4819. */
  4820. }, {
  4821. key: "tab",
  4822. value: function tab() {
  4823. var rng = this.getLastRange();
  4824. if (rng.isCollapsed() && rng.isOnCell()) {
  4825. this.table.tab(rng);
  4826. } else {
  4827. if (this.options.tabSize === 0) {
  4828. return false;
  4829. }
  4830. if (!this.isLimited(this.options.tabSize)) {
  4831. this.beforeCommand();
  4832. this.typing.insertTab(rng, this.options.tabSize);
  4833. this.afterCommand();
  4834. }
  4835. }
  4836. }
  4837. /**
  4838. * handle shift+tab key
  4839. */
  4840. }, {
  4841. key: "untab",
  4842. value: function untab() {
  4843. var rng = this.getLastRange();
  4844. if (rng.isCollapsed() && rng.isOnCell()) {
  4845. this.table.tab(rng, true);
  4846. } else {
  4847. if (this.options.tabSize === 0) {
  4848. return false;
  4849. }
  4850. }
  4851. }
  4852. /**
  4853. * run given function between beforeCommand and afterCommand
  4854. */
  4855. }, {
  4856. key: "wrapCommand",
  4857. value: function wrapCommand(fn) {
  4858. return function () {
  4859. this.beforeCommand();
  4860. fn.apply(this, arguments);
  4861. this.afterCommand();
  4862. };
  4863. }
  4864. /**
  4865. * insert image
  4866. *
  4867. * @param {String} src
  4868. * @param {String|Function} param
  4869. * @return {Promise}
  4870. */
  4871. }, {
  4872. key: "insertImage",
  4873. value: function insertImage(src, param) {
  4874. var _this3 = this;
  4875. return createImage(src, param).then(function ($image) {
  4876. _this3.beforeCommand();
  4877. if (typeof param === 'function') {
  4878. param($image);
  4879. } else {
  4880. if (typeof param === 'string') {
  4881. $image.attr('data-filename', param);
  4882. }
  4883. $image.css('width', Math.min(_this3.$editable.width(), $image.width()));
  4884. }
  4885. $image.show();
  4886. _this3.getLastRange().insertNode($image[0]);
  4887. _this3.setLastRange(range.createFromNodeAfter($image[0]).select());
  4888. _this3.afterCommand();
  4889. }).fail(function (e) {
  4890. _this3.context.triggerEvent('image.upload.error', e);
  4891. });
  4892. }
  4893. /**
  4894. * insertImages
  4895. * @param {File[]} files
  4896. */
  4897. }, {
  4898. key: "insertImagesAsDataURL",
  4899. value: function insertImagesAsDataURL(files) {
  4900. var _this4 = this;
  4901. external_jQuery_default().each(files, function (idx, file) {
  4902. var filename = file.name;
  4903. if (_this4.options.maximumImageFileSize && _this4.options.maximumImageFileSize < file.size) {
  4904. _this4.context.triggerEvent('image.upload.error', _this4.lang.image.maximumFileSizeError);
  4905. } else {
  4906. readFileAsDataURL(file).then(function (dataURL) {
  4907. return _this4.insertImage(dataURL, filename);
  4908. }).fail(function () {
  4909. _this4.context.triggerEvent('image.upload.error');
  4910. });
  4911. }
  4912. });
  4913. }
  4914. /**
  4915. * insertImagesOrCallback
  4916. * @param {File[]} files
  4917. */
  4918. }, {
  4919. key: "insertImagesOrCallback",
  4920. value: function insertImagesOrCallback(files) {
  4921. var callbacks = this.options.callbacks; // If onImageUpload set,
  4922. if (callbacks.onImageUpload) {
  4923. this.context.triggerEvent('image.upload', files); // else insert Image as dataURL
  4924. } else {
  4925. this.insertImagesAsDataURL(files);
  4926. }
  4927. }
  4928. /**
  4929. * return selected plain text
  4930. * @return {String} text
  4931. */
  4932. }, {
  4933. key: "getSelectedText",
  4934. value: function getSelectedText() {
  4935. var rng = this.getLastRange(); // if range on anchor, expand range with anchor
  4936. if (rng.isOnAnchor()) {
  4937. rng = range.createFromNode(dom.ancestor(rng.sc, dom.isAnchor));
  4938. }
  4939. return rng.toString();
  4940. }
  4941. }, {
  4942. key: "onFormatBlock",
  4943. value: function onFormatBlock(tagName, $target) {
  4944. // [workaround] for MSIE, IE need `<`
  4945. document.execCommand('FormatBlock', false, env.isMSIE ? '<' + tagName + '>' : tagName); // support custom class
  4946. if ($target && $target.length) {
  4947. // find the exact element has given tagName
  4948. if ($target[0].tagName.toUpperCase() !== tagName.toUpperCase()) {
  4949. $target = $target.find(tagName);
  4950. }
  4951. if ($target && $target.length) {
  4952. var currentRange = this.createRange();
  4953. var $parent = external_jQuery_default()([currentRange.sc, currentRange.ec]).closest(tagName); // remove class added for current block
  4954. $parent.removeClass();
  4955. var className = $target[0].className || '';
  4956. if (className) {
  4957. $parent.addClass(className);
  4958. }
  4959. }
  4960. }
  4961. }
  4962. }, {
  4963. key: "formatPara",
  4964. value: function formatPara() {
  4965. this.formatBlock('P');
  4966. }
  4967. }, {
  4968. key: "fontStyling",
  4969. value: function fontStyling(target, value) {
  4970. var rng = this.getLastRange();
  4971. if (rng !== '') {
  4972. var spans = this.style.styleNodes(rng);
  4973. this.$editor.find('.note-status-output').html('');
  4974. external_jQuery_default()(spans).css(target, value); // [workaround] added styled bogus span for style
  4975. // - also bogus character needed for cursor position
  4976. if (rng.isCollapsed()) {
  4977. var firstSpan = lists.head(spans);
  4978. if (firstSpan && !dom.nodeLength(firstSpan)) {
  4979. firstSpan.innerHTML = dom.ZERO_WIDTH_NBSP_CHAR;
  4980. range.createFromNode(firstSpan.firstChild).select();
  4981. this.setLastRange();
  4982. this.$editable.data(KEY_BOGUS, firstSpan);
  4983. }
  4984. } else {
  4985. this.setLastRange(this.createRangeFromList(spans).select());
  4986. }
  4987. } else {
  4988. var noteStatusOutput = external_jQuery_default().now();
  4989. this.$editor.find('.note-status-output').html('<div id="note-status-output-' + noteStatusOutput + '" class="alert alert-info">' + this.lang.output.noSelection + '</div>');
  4990. setTimeout(function () {
  4991. external_jQuery_default()('#note-status-output-' + noteStatusOutput).remove();
  4992. }, 5000);
  4993. }
  4994. }
  4995. /**
  4996. * unlink
  4997. *
  4998. * @type command
  4999. */
  5000. }, {
  5001. key: "unlink",
  5002. value: function unlink() {
  5003. var rng = this.getLastRange();
  5004. if (rng.isOnAnchor()) {
  5005. var anchor = dom.ancestor(rng.sc, dom.isAnchor);
  5006. rng = range.createFromNode(anchor);
  5007. rng.select();
  5008. this.setLastRange();
  5009. this.beforeCommand();
  5010. document.execCommand('unlink');
  5011. this.afterCommand();
  5012. }
  5013. }
  5014. /**
  5015. * returns link info
  5016. *
  5017. * @return {Object}
  5018. * @return {WrappedRange} return.range
  5019. * @return {String} return.text
  5020. * @return {Boolean} [return.isNewWindow=true]
  5021. * @return {String} [return.url=""]
  5022. */
  5023. }, {
  5024. key: "getLinkInfo",
  5025. value: function getLinkInfo() {
  5026. var rng = this.getLastRange().expand(dom.isAnchor); // Get the first anchor on range(for edit).
  5027. var $anchor = external_jQuery_default()(lists.head(rng.nodes(dom.isAnchor)));
  5028. var linkInfo = {
  5029. range: rng,
  5030. text: rng.toString(),
  5031. url: $anchor.length ? $anchor.attr('href') : ''
  5032. }; // When anchor exists,
  5033. if ($anchor.length) {
  5034. // Set isNewWindow by checking its target.
  5035. linkInfo.isNewWindow = $anchor.attr('target') === '_blank';
  5036. }
  5037. return linkInfo;
  5038. }
  5039. }, {
  5040. key: "addRow",
  5041. value: function addRow(position) {
  5042. var rng = this.getLastRange(this.$editable);
  5043. if (rng.isCollapsed() && rng.isOnCell()) {
  5044. this.beforeCommand();
  5045. this.table.addRow(rng, position);
  5046. this.afterCommand();
  5047. }
  5048. }
  5049. }, {
  5050. key: "addCol",
  5051. value: function addCol(position) {
  5052. var rng = this.getLastRange(this.$editable);
  5053. if (rng.isCollapsed() && rng.isOnCell()) {
  5054. this.beforeCommand();
  5055. this.table.addCol(rng, position);
  5056. this.afterCommand();
  5057. }
  5058. }
  5059. }, {
  5060. key: "deleteRow",
  5061. value: function deleteRow() {
  5062. var rng = this.getLastRange(this.$editable);
  5063. if (rng.isCollapsed() && rng.isOnCell()) {
  5064. this.beforeCommand();
  5065. this.table.deleteRow(rng);
  5066. this.afterCommand();
  5067. }
  5068. }
  5069. }, {
  5070. key: "deleteCol",
  5071. value: function deleteCol() {
  5072. var rng = this.getLastRange(this.$editable);
  5073. if (rng.isCollapsed() && rng.isOnCell()) {
  5074. this.beforeCommand();
  5075. this.table.deleteCol(rng);
  5076. this.afterCommand();
  5077. }
  5078. }
  5079. }, {
  5080. key: "deleteTable",
  5081. value: function deleteTable() {
  5082. var rng = this.getLastRange(this.$editable);
  5083. if (rng.isCollapsed() && rng.isOnCell()) {
  5084. this.beforeCommand();
  5085. this.table.deleteTable(rng);
  5086. this.afterCommand();
  5087. }
  5088. }
  5089. /**
  5090. * @param {Position} pos
  5091. * @param {jQuery} $target - target element
  5092. * @param {Boolean} [bKeepRatio] - keep ratio
  5093. */
  5094. }, {
  5095. key: "resizeTo",
  5096. value: function resizeTo(pos, $target, bKeepRatio) {
  5097. var imageSize;
  5098. if (bKeepRatio) {
  5099. var newRatio = pos.y / pos.x;
  5100. var ratio = $target.data('ratio');
  5101. imageSize = {
  5102. width: ratio > newRatio ? pos.x : pos.y / ratio,
  5103. height: ratio > newRatio ? pos.x * ratio : pos.y
  5104. };
  5105. } else {
  5106. imageSize = {
  5107. width: pos.x,
  5108. height: pos.y
  5109. };
  5110. }
  5111. $target.css(imageSize);
  5112. }
  5113. /**
  5114. * returns whether editable area has focus or not.
  5115. */
  5116. }, {
  5117. key: "hasFocus",
  5118. value: function hasFocus() {
  5119. return this.$editable.is(':focus');
  5120. }
  5121. /**
  5122. * set focus
  5123. */
  5124. }, {
  5125. key: "focus",
  5126. value: function focus() {
  5127. // [workaround] Screen will move when page is scolled in IE.
  5128. // - do focus when not focused
  5129. if (!this.hasFocus()) {
  5130. this.$editable.focus();
  5131. }
  5132. }
  5133. /**
  5134. * returns whether contents is empty or not.
  5135. * @return {Boolean}
  5136. */
  5137. }, {
  5138. key: "isEmpty",
  5139. value: function isEmpty() {
  5140. return dom.isEmpty(this.$editable[0]) || dom.emptyPara === this.$editable.html();
  5141. }
  5142. /**
  5143. * Removes all contents and restores the editable instance to an _emptyPara_.
  5144. */
  5145. }, {
  5146. key: "empty",
  5147. value: function empty() {
  5148. this.context.invoke('code', dom.emptyPara);
  5149. }
  5150. /**
  5151. * normalize content
  5152. */
  5153. }, {
  5154. key: "normalizeContent",
  5155. value: function normalizeContent() {
  5156. this.$editable[0].normalize();
  5157. }
  5158. }]);
  5159. return Editor;
  5160. }();
  5161. ;// CONCATENATED MODULE: ./src/js/module/Clipboard.js
  5162. function Clipboard_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5163. function Clipboard_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  5164. function Clipboard_createClass(Constructor, protoProps, staticProps) { if (protoProps) Clipboard_defineProperties(Constructor.prototype, protoProps); if (staticProps) Clipboard_defineProperties(Constructor, staticProps); return Constructor; }
  5165. var Clipboard = /*#__PURE__*/function () {
  5166. function Clipboard(context) {
  5167. Clipboard_classCallCheck(this, Clipboard);
  5168. this.context = context;
  5169. this.$editable = context.layoutInfo.editable;
  5170. }
  5171. Clipboard_createClass(Clipboard, [{
  5172. key: "initialize",
  5173. value: function initialize() {
  5174. this.$editable.on('paste', this.pasteByEvent.bind(this));
  5175. }
  5176. /**
  5177. * paste by clipboard event
  5178. *
  5179. * @param {Event} event
  5180. */
  5181. }, {
  5182. key: "pasteByEvent",
  5183. value: function pasteByEvent(event) {
  5184. var _this = this;
  5185. var clipboardData = event.originalEvent.clipboardData;
  5186. if (clipboardData && clipboardData.items && clipboardData.items.length) {
  5187. var item = clipboardData.items.length > 1 ? clipboardData.items[1] : lists.head(clipboardData.items);
  5188. if (item.kind === 'file' && item.type.indexOf('image/') !== -1) {
  5189. // paste img file
  5190. this.context.invoke('editor.insertImagesOrCallback', [item.getAsFile()]);
  5191. event.preventDefault();
  5192. } else if (item.kind === 'string') {
  5193. // paste text with maxTextLength check
  5194. if (this.context.invoke('editor.isLimited', clipboardData.getData('Text').length)) {
  5195. event.preventDefault();
  5196. }
  5197. }
  5198. } else if (window.clipboardData) {
  5199. // for IE
  5200. var text = window.clipboardData.getData('text');
  5201. if (this.context.invoke('editor.isLimited', text.length)) {
  5202. event.preventDefault();
  5203. }
  5204. } // Call editor.afterCommand after proceeding default event handler
  5205. setTimeout(function () {
  5206. _this.context.invoke('editor.afterCommand');
  5207. }, 10);
  5208. }
  5209. }]);
  5210. return Clipboard;
  5211. }();
  5212. ;// CONCATENATED MODULE: ./src/js/module/Dropzone.js
  5213. function Dropzone_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5214. function Dropzone_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  5215. function Dropzone_createClass(Constructor, protoProps, staticProps) { if (protoProps) Dropzone_defineProperties(Constructor.prototype, protoProps); if (staticProps) Dropzone_defineProperties(Constructor, staticProps); return Constructor; }
  5216. var Dropzone = /*#__PURE__*/function () {
  5217. function Dropzone(context) {
  5218. Dropzone_classCallCheck(this, Dropzone);
  5219. this.context = context;
  5220. this.$eventListener = external_jQuery_default()(document);
  5221. this.$editor = context.layoutInfo.editor;
  5222. this.$editable = context.layoutInfo.editable;
  5223. this.options = context.options;
  5224. this.lang = this.options.langInfo;
  5225. this.documentEventHandlers = {};
  5226. this.$dropzone = external_jQuery_default()(['<div class="note-dropzone">', '<div class="note-dropzone-message"></div>', '</div>'].join('')).prependTo(this.$editor);
  5227. }
  5228. /**
  5229. * attach Drag and Drop Events
  5230. */
  5231. Dropzone_createClass(Dropzone, [{
  5232. key: "initialize",
  5233. value: function initialize() {
  5234. if (this.options.disableDragAndDrop) {
  5235. // prevent default drop event
  5236. this.documentEventHandlers.onDrop = function (e) {
  5237. e.preventDefault();
  5238. }; // do not consider outside of dropzone
  5239. this.$eventListener = this.$dropzone;
  5240. this.$eventListener.on('drop', this.documentEventHandlers.onDrop);
  5241. } else {
  5242. this.attachDragAndDropEvent();
  5243. }
  5244. }
  5245. /**
  5246. * attach Drag and Drop Events
  5247. */
  5248. }, {
  5249. key: "attachDragAndDropEvent",
  5250. value: function attachDragAndDropEvent() {
  5251. var _this = this;
  5252. var collection = external_jQuery_default()();
  5253. var $dropzoneMessage = this.$dropzone.find('.note-dropzone-message');
  5254. this.documentEventHandlers.onDragenter = function (e) {
  5255. var isCodeview = _this.context.invoke('codeview.isActivated');
  5256. var hasEditorSize = _this.$editor.width() > 0 && _this.$editor.height() > 0;
  5257. if (!isCodeview && !collection.length && hasEditorSize) {
  5258. _this.$editor.addClass('dragover');
  5259. _this.$dropzone.width(_this.$editor.width());
  5260. _this.$dropzone.height(_this.$editor.height());
  5261. $dropzoneMessage.text(_this.lang.image.dragImageHere);
  5262. }
  5263. collection = collection.add(e.target);
  5264. };
  5265. this.documentEventHandlers.onDragleave = function (e) {
  5266. collection = collection.not(e.target); // If nodeName is BODY, then just make it over (fix for IE)
  5267. if (!collection.length || e.target.nodeName === 'BODY') {
  5268. collection = external_jQuery_default()();
  5269. _this.$editor.removeClass('dragover');
  5270. }
  5271. };
  5272. this.documentEventHandlers.onDrop = function () {
  5273. collection = external_jQuery_default()();
  5274. _this.$editor.removeClass('dragover');
  5275. }; // show dropzone on dragenter when dragging a object to document
  5276. // -but only if the editor is visible, i.e. has a positive width and height
  5277. this.$eventListener.on('dragenter', this.documentEventHandlers.onDragenter).on('dragleave', this.documentEventHandlers.onDragleave).on('drop', this.documentEventHandlers.onDrop); // change dropzone's message on hover.
  5278. this.$dropzone.on('dragenter', function () {
  5279. _this.$dropzone.addClass('hover');
  5280. $dropzoneMessage.text(_this.lang.image.dropImage);
  5281. }).on('dragleave', function () {
  5282. _this.$dropzone.removeClass('hover');
  5283. $dropzoneMessage.text(_this.lang.image.dragImageHere);
  5284. }); // attach dropImage
  5285. this.$dropzone.on('drop', function (event) {
  5286. var dataTransfer = event.originalEvent.dataTransfer; // stop the browser from opening the dropped content
  5287. event.preventDefault();
  5288. if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
  5289. _this.$editable.focus();
  5290. _this.context.invoke('editor.insertImagesOrCallback', dataTransfer.files);
  5291. } else {
  5292. external_jQuery_default().each(dataTransfer.types, function (idx, type) {
  5293. // skip moz-specific types
  5294. if (type.toLowerCase().indexOf('_moz_') > -1) {
  5295. return;
  5296. }
  5297. var content = dataTransfer.getData(type);
  5298. if (type.toLowerCase().indexOf('text') > -1) {
  5299. _this.context.invoke('editor.pasteHTML', content);
  5300. } else {
  5301. external_jQuery_default()(content).each(function (idx, item) {
  5302. _this.context.invoke('editor.insertNode', item);
  5303. });
  5304. }
  5305. });
  5306. }
  5307. }).on('dragover', false); // prevent default dragover event
  5308. }
  5309. }, {
  5310. key: "destroy",
  5311. value: function destroy() {
  5312. var _this2 = this;
  5313. Object.keys(this.documentEventHandlers).forEach(function (key) {
  5314. _this2.$eventListener.off(key.substr(2).toLowerCase(), _this2.documentEventHandlers[key]);
  5315. });
  5316. this.documentEventHandlers = {};
  5317. }
  5318. }]);
  5319. return Dropzone;
  5320. }();
  5321. ;// CONCATENATED MODULE: ./src/js/module/Codeview.js
  5322. function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
  5323. function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
  5324. function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
  5325. function Codeview_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5326. function Codeview_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  5327. function Codeview_createClass(Constructor, protoProps, staticProps) { if (protoProps) Codeview_defineProperties(Constructor.prototype, protoProps); if (staticProps) Codeview_defineProperties(Constructor, staticProps); return Constructor; }
  5328. /**
  5329. * @class Codeview
  5330. */
  5331. var CodeView = /*#__PURE__*/function () {
  5332. function CodeView(context) {
  5333. Codeview_classCallCheck(this, CodeView);
  5334. this.context = context;
  5335. this.$editor = context.layoutInfo.editor;
  5336. this.$editable = context.layoutInfo.editable;
  5337. this.$codable = context.layoutInfo.codable;
  5338. this.options = context.options;
  5339. this.CodeMirrorConstructor = window.CodeMirror;
  5340. if (this.options.codemirror.CodeMirrorConstructor) {
  5341. this.CodeMirrorConstructor = this.options.codemirror.CodeMirrorConstructor;
  5342. }
  5343. }
  5344. Codeview_createClass(CodeView, [{
  5345. key: "sync",
  5346. value: function sync(html) {
  5347. var isCodeview = this.isActivated();
  5348. var CodeMirror = this.CodeMirrorConstructor;
  5349. if (isCodeview) {
  5350. if (html) {
  5351. if (CodeMirror) {
  5352. this.$codable.data('cmEditor').getDoc().setValue(html);
  5353. } else {
  5354. this.$codable.val(html);
  5355. }
  5356. } else {
  5357. if (CodeMirror) {
  5358. this.$codable.data('cmEditor').save();
  5359. }
  5360. }
  5361. }
  5362. }
  5363. }, {
  5364. key: "initialize",
  5365. value: function initialize() {
  5366. var _this = this;
  5367. this.$codable.on('keyup', function (event) {
  5368. if (event.keyCode === key.code.ESCAPE) {
  5369. _this.deactivate();
  5370. }
  5371. });
  5372. }
  5373. /**
  5374. * @return {Boolean}
  5375. */
  5376. }, {
  5377. key: "isActivated",
  5378. value: function isActivated() {
  5379. return this.$editor.hasClass('codeview');
  5380. }
  5381. /**
  5382. * toggle codeview
  5383. */
  5384. }, {
  5385. key: "toggle",
  5386. value: function toggle() {
  5387. if (this.isActivated()) {
  5388. this.deactivate();
  5389. } else {
  5390. this.activate();
  5391. }
  5392. this.context.triggerEvent('codeview.toggled');
  5393. }
  5394. /**
  5395. * purify input value
  5396. * @param value
  5397. * @returns {*}
  5398. */
  5399. }, {
  5400. key: "purify",
  5401. value: function purify(value) {
  5402. if (this.options.codeviewFilter) {
  5403. // filter code view regex
  5404. value = value.replace(this.options.codeviewFilterRegex, ''); // allow specific iframe tag
  5405. if (this.options.codeviewIframeFilter) {
  5406. var whitelist = this.options.codeviewIframeWhitelistSrc.concat(this.options.codeviewIframeWhitelistSrcBase);
  5407. value = value.replace(/(<iframe.*?>.*?(?:<\/iframe>)?)/gi, function (tag) {
  5408. // remove if src attribute is duplicated
  5409. if (/<.+src(?==?('|"|\s)?)[\s\S]+src(?=('|"|\s)?)[^>]*?>/i.test(tag)) {
  5410. return '';
  5411. }
  5412. var _iterator = _createForOfIteratorHelper(whitelist),
  5413. _step;
  5414. try {
  5415. for (_iterator.s(); !(_step = _iterator.n()).done;) {
  5416. var src = _step.value;
  5417. // pass if src is trusted
  5418. if (new RegExp('src="(https?:)?\/\/' + src.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '\/(.+)"').test(tag)) {
  5419. return tag;
  5420. }
  5421. }
  5422. } catch (err) {
  5423. _iterator.e(err);
  5424. } finally {
  5425. _iterator.f();
  5426. }
  5427. return '';
  5428. });
  5429. }
  5430. }
  5431. return value;
  5432. }
  5433. /**
  5434. * activate code view
  5435. */
  5436. }, {
  5437. key: "activate",
  5438. value: function activate() {
  5439. var _this2 = this;
  5440. var CodeMirror = this.CodeMirrorConstructor;
  5441. this.$codable.val(dom.html(this.$editable, this.options.prettifyHtml));
  5442. this.$codable.height(this.$editable.height());
  5443. this.context.invoke('toolbar.updateCodeview', true);
  5444. this.context.invoke('airPopover.updateCodeview', true);
  5445. this.$editor.addClass('codeview');
  5446. this.$codable.focus(); // activate CodeMirror as codable
  5447. if (CodeMirror) {
  5448. var cmEditor = CodeMirror.fromTextArea(this.$codable[0], this.options.codemirror); // CodeMirror TernServer
  5449. if (this.options.codemirror.tern) {
  5450. var server = new CodeMirror.TernServer(this.options.codemirror.tern);
  5451. cmEditor.ternServer = server;
  5452. cmEditor.on('cursorActivity', function (cm) {
  5453. server.updateArgHints(cm);
  5454. });
  5455. }
  5456. cmEditor.on('blur', function (event) {
  5457. _this2.context.triggerEvent('blur.codeview', cmEditor.getValue(), event);
  5458. });
  5459. cmEditor.on('change', function () {
  5460. _this2.context.triggerEvent('change.codeview', cmEditor.getValue(), cmEditor);
  5461. }); // CodeMirror hasn't Padding.
  5462. cmEditor.setSize(null, this.$editable.outerHeight());
  5463. this.$codable.data('cmEditor', cmEditor);
  5464. } else {
  5465. this.$codable.on('blur', function (event) {
  5466. _this2.context.triggerEvent('blur.codeview', _this2.$codable.val(), event);
  5467. });
  5468. this.$codable.on('input', function () {
  5469. _this2.context.triggerEvent('change.codeview', _this2.$codable.val(), _this2.$codable);
  5470. });
  5471. }
  5472. }
  5473. /**
  5474. * deactivate code view
  5475. */
  5476. }, {
  5477. key: "deactivate",
  5478. value: function deactivate() {
  5479. var CodeMirror = this.CodeMirrorConstructor; // deactivate CodeMirror as codable
  5480. if (CodeMirror) {
  5481. var cmEditor = this.$codable.data('cmEditor');
  5482. this.$codable.val(cmEditor.getValue());
  5483. cmEditor.toTextArea();
  5484. }
  5485. var value = this.purify(dom.value(this.$codable, this.options.prettifyHtml) || dom.emptyPara);
  5486. var isChange = this.$editable.html() !== value;
  5487. this.$editable.html(value);
  5488. this.$editable.height(this.options.height ? this.$codable.height() : 'auto');
  5489. this.$editor.removeClass('codeview');
  5490. if (isChange) {
  5491. this.context.triggerEvent('change', this.$editable.html(), this.$editable);
  5492. }
  5493. this.$editable.focus();
  5494. this.context.invoke('toolbar.updateCodeview', false);
  5495. this.context.invoke('airPopover.updateCodeview', false);
  5496. }
  5497. }, {
  5498. key: "destroy",
  5499. value: function destroy() {
  5500. if (this.isActivated()) {
  5501. this.deactivate();
  5502. }
  5503. }
  5504. }]);
  5505. return CodeView;
  5506. }();
  5507. ;// CONCATENATED MODULE: ./src/js/module/Statusbar.js
  5508. function Statusbar_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5509. function Statusbar_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  5510. function Statusbar_createClass(Constructor, protoProps, staticProps) { if (protoProps) Statusbar_defineProperties(Constructor.prototype, protoProps); if (staticProps) Statusbar_defineProperties(Constructor, staticProps); return Constructor; }
  5511. var EDITABLE_PADDING = 24;
  5512. var Statusbar = /*#__PURE__*/function () {
  5513. function Statusbar(context) {
  5514. Statusbar_classCallCheck(this, Statusbar);
  5515. this.$document = external_jQuery_default()(document);
  5516. this.$statusbar = context.layoutInfo.statusbar;
  5517. this.$editable = context.layoutInfo.editable;
  5518. this.$codable = context.layoutInfo.codable;
  5519. this.options = context.options;
  5520. }
  5521. Statusbar_createClass(Statusbar, [{
  5522. key: "initialize",
  5523. value: function initialize() {
  5524. var _this = this;
  5525. if (this.options.airMode || this.options.disableResizeEditor) {
  5526. this.destroy();
  5527. return;
  5528. }
  5529. this.$statusbar.on('mousedown', function (event) {
  5530. event.preventDefault();
  5531. event.stopPropagation();
  5532. var editableTop = _this.$editable.offset().top - _this.$document.scrollTop();
  5533. var editableCodeTop = _this.$codable.offset().top - _this.$document.scrollTop();
  5534. var onMouseMove = function onMouseMove(event) {
  5535. var height = event.clientY - (editableTop + EDITABLE_PADDING);
  5536. var heightCode = event.clientY - (editableCodeTop + EDITABLE_PADDING);
  5537. height = _this.options.minheight > 0 ? Math.max(height, _this.options.minheight) : height;
  5538. height = _this.options.maxHeight > 0 ? Math.min(height, _this.options.maxHeight) : height;
  5539. heightCode = _this.options.minheight > 0 ? Math.max(heightCode, _this.options.minheight) : heightCode;
  5540. heightCode = _this.options.maxHeight > 0 ? Math.min(heightCode, _this.options.maxHeight) : heightCode;
  5541. _this.$editable.height(height);
  5542. _this.$codable.height(heightCode);
  5543. };
  5544. _this.$document.on('mousemove', onMouseMove).one('mouseup', function () {
  5545. _this.$document.off('mousemove', onMouseMove);
  5546. });
  5547. });
  5548. }
  5549. }, {
  5550. key: "destroy",
  5551. value: function destroy() {
  5552. this.$statusbar.off();
  5553. this.$statusbar.addClass('locked');
  5554. }
  5555. }]);
  5556. return Statusbar;
  5557. }();
  5558. ;// CONCATENATED MODULE: ./src/js/module/Fullscreen.js
  5559. function Fullscreen_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5560. function Fullscreen_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  5561. function Fullscreen_createClass(Constructor, protoProps, staticProps) { if (protoProps) Fullscreen_defineProperties(Constructor.prototype, protoProps); if (staticProps) Fullscreen_defineProperties(Constructor, staticProps); return Constructor; }
  5562. var Fullscreen = /*#__PURE__*/function () {
  5563. function Fullscreen(context) {
  5564. var _this = this;
  5565. Fullscreen_classCallCheck(this, Fullscreen);
  5566. this.context = context;
  5567. this.$editor = context.layoutInfo.editor;
  5568. this.$toolbar = context.layoutInfo.toolbar;
  5569. this.$editable = context.layoutInfo.editable;
  5570. this.$codable = context.layoutInfo.codable;
  5571. this.$window = external_jQuery_default()(window);
  5572. this.$scrollbar = external_jQuery_default()('html, body');
  5573. this.scrollbarClassName = 'note-fullscreen-body';
  5574. this.onResize = function () {
  5575. _this.resizeTo({
  5576. h: _this.$window.height() - _this.$toolbar.outerHeight()
  5577. });
  5578. };
  5579. }
  5580. Fullscreen_createClass(Fullscreen, [{
  5581. key: "resizeTo",
  5582. value: function resizeTo(size) {
  5583. this.$editable.css('height', size.h);
  5584. this.$codable.css('height', size.h);
  5585. if (this.$codable.data('cmeditor')) {
  5586. this.$codable.data('cmeditor').setsize(null, size.h);
  5587. }
  5588. }
  5589. /**
  5590. * toggle fullscreen
  5591. */
  5592. }, {
  5593. key: "toggle",
  5594. value: function toggle() {
  5595. this.$editor.toggleClass('fullscreen');
  5596. var isFullscreen = this.isFullscreen();
  5597. this.$scrollbar.toggleClass(this.scrollbarClassName, isFullscreen);
  5598. if (isFullscreen) {
  5599. this.$editable.data('orgHeight', this.$editable.css('height'));
  5600. this.$editable.data('orgMaxHeight', this.$editable.css('maxHeight'));
  5601. this.$editable.css('maxHeight', '');
  5602. this.$window.on('resize', this.onResize).trigger('resize');
  5603. } else {
  5604. this.$window.off('resize', this.onResize);
  5605. this.resizeTo({
  5606. h: this.$editable.data('orgHeight')
  5607. });
  5608. this.$editable.css('maxHeight', this.$editable.css('orgMaxHeight'));
  5609. }
  5610. this.context.invoke('toolbar.updateFullscreen', isFullscreen);
  5611. }
  5612. }, {
  5613. key: "isFullscreen",
  5614. value: function isFullscreen() {
  5615. return this.$editor.hasClass('fullscreen');
  5616. }
  5617. }, {
  5618. key: "destroy",
  5619. value: function destroy() {
  5620. this.$scrollbar.removeClass(this.scrollbarClassName);
  5621. }
  5622. }]);
  5623. return Fullscreen;
  5624. }();
  5625. ;// CONCATENATED MODULE: ./src/js/module/Handle.js
  5626. function Handle_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5627. function Handle_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  5628. function Handle_createClass(Constructor, protoProps, staticProps) { if (protoProps) Handle_defineProperties(Constructor.prototype, protoProps); if (staticProps) Handle_defineProperties(Constructor, staticProps); return Constructor; }
  5629. var Handle = /*#__PURE__*/function () {
  5630. function Handle(context) {
  5631. var _this = this;
  5632. Handle_classCallCheck(this, Handle);
  5633. this.context = context;
  5634. this.$document = external_jQuery_default()(document);
  5635. this.$editingArea = context.layoutInfo.editingArea;
  5636. this.options = context.options;
  5637. this.lang = this.options.langInfo;
  5638. this.events = {
  5639. 'summernote.mousedown': function summernoteMousedown(we, e) {
  5640. if (_this.update(e.target, e)) {
  5641. e.preventDefault();
  5642. }
  5643. },
  5644. 'summernote.keyup summernote.scroll summernote.change summernote.dialog.shown': function summernoteKeyupSummernoteScrollSummernoteChangeSummernoteDialogShown() {
  5645. _this.update();
  5646. },
  5647. 'summernote.disable summernote.blur': function summernoteDisableSummernoteBlur() {
  5648. _this.hide();
  5649. },
  5650. 'summernote.codeview.toggled': function summernoteCodeviewToggled() {
  5651. _this.update();
  5652. }
  5653. };
  5654. }
  5655. Handle_createClass(Handle, [{
  5656. key: "initialize",
  5657. value: function initialize() {
  5658. var _this2 = this;
  5659. this.$handle = external_jQuery_default()(['<div class="note-handle">', '<div class="note-control-selection">', '<div class="note-control-selection-bg"></div>', '<div class="note-control-holder note-control-nw"></div>', '<div class="note-control-holder note-control-ne"></div>', '<div class="note-control-holder note-control-sw"></div>', '<div class="', this.options.disableResizeImage ? 'note-control-holder' : 'note-control-sizing', ' note-control-se"></div>', this.options.disableResizeImage ? '' : '<div class="note-control-selection-info"></div>', '</div>', '</div>'].join('')).prependTo(this.$editingArea);
  5660. this.$handle.on('mousedown', function (event) {
  5661. if (dom.isControlSizing(event.target)) {
  5662. event.preventDefault();
  5663. event.stopPropagation();
  5664. var $target = _this2.$handle.find('.note-control-selection').data('target');
  5665. var posStart = $target.offset();
  5666. var scrollTop = _this2.$document.scrollTop();
  5667. var onMouseMove = function onMouseMove(event) {
  5668. _this2.context.invoke('editor.resizeTo', {
  5669. x: event.clientX - posStart.left,
  5670. y: event.clientY - (posStart.top - scrollTop)
  5671. }, $target, !event.shiftKey);
  5672. _this2.update($target[0], event);
  5673. };
  5674. _this2.$document.on('mousemove', onMouseMove).one('mouseup', function (e) {
  5675. e.preventDefault();
  5676. _this2.$document.off('mousemove', onMouseMove);
  5677. _this2.context.invoke('editor.afterCommand');
  5678. });
  5679. if (!$target.data('ratio')) {
  5680. // original ratio.
  5681. $target.data('ratio', $target.height() / $target.width());
  5682. }
  5683. }
  5684. }); // Listen for scrolling on the handle overlay.
  5685. this.$handle.on('wheel', function (e) {
  5686. e.preventDefault();
  5687. _this2.update();
  5688. });
  5689. }
  5690. }, {
  5691. key: "destroy",
  5692. value: function destroy() {
  5693. this.$handle.remove();
  5694. }
  5695. }, {
  5696. key: "update",
  5697. value: function update(target, event) {
  5698. if (this.context.isDisabled()) {
  5699. return false;
  5700. }
  5701. var isImage = dom.isImg(target);
  5702. var $selection = this.$handle.find('.note-control-selection');
  5703. this.context.invoke('imagePopover.update', target, event);
  5704. if (isImage) {
  5705. var $image = external_jQuery_default()(target);
  5706. var position = $image.position();
  5707. var pos = {
  5708. left: position.left + parseInt($image.css('marginLeft'), 10),
  5709. top: position.top + parseInt($image.css('marginTop'), 10)
  5710. }; // exclude margin
  5711. var imageSize = {
  5712. w: $image.outerWidth(false),
  5713. h: $image.outerHeight(false)
  5714. };
  5715. $selection.css({
  5716. display: 'block',
  5717. left: pos.left,
  5718. top: pos.top,
  5719. width: imageSize.w,
  5720. height: imageSize.h
  5721. }).data('target', $image); // save current image element.
  5722. var origImageObj = new Image();
  5723. origImageObj.src = $image.attr('src');
  5724. var sizingText = imageSize.w + 'x' + imageSize.h + ' (' + this.lang.image.original + ': ' + origImageObj.width + 'x' + origImageObj.height + ')';
  5725. $selection.find('.note-control-selection-info').text(sizingText);
  5726. this.context.invoke('editor.saveTarget', target);
  5727. } else {
  5728. this.hide();
  5729. }
  5730. return isImage;
  5731. }
  5732. /**
  5733. * hide
  5734. *
  5735. * @param {jQuery} $handle
  5736. */
  5737. }, {
  5738. key: "hide",
  5739. value: function hide() {
  5740. this.context.invoke('editor.clearTarget');
  5741. this.$handle.children().hide();
  5742. }
  5743. }]);
  5744. return Handle;
  5745. }();
  5746. ;// CONCATENATED MODULE: ./src/js/module/AutoLink.js
  5747. function AutoLink_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5748. function AutoLink_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  5749. function AutoLink_createClass(Constructor, protoProps, staticProps) { if (protoProps) AutoLink_defineProperties(Constructor.prototype, protoProps); if (staticProps) AutoLink_defineProperties(Constructor, staticProps); return Constructor; }
  5750. var defaultScheme = 'http://';
  5751. var linkPattern = /^([A-Za-z][A-Za-z0-9+-.]*\:[\/]{2}|tel:|mailto:[A-Z0-9._%+-]+@|xmpp:[A-Z0-9._%+-]+@)?(www\.)?(.+)$/i;
  5752. var AutoLink = /*#__PURE__*/function () {
  5753. function AutoLink(context) {
  5754. var _this = this;
  5755. AutoLink_classCallCheck(this, AutoLink);
  5756. this.context = context;
  5757. this.options = context.options;
  5758. this.events = {
  5759. 'summernote.keyup': function summernoteKeyup(we, e) {
  5760. if (!e.isDefaultPrevented()) {
  5761. _this.handleKeyup(e);
  5762. }
  5763. },
  5764. 'summernote.keydown': function summernoteKeydown(we, e) {
  5765. _this.handleKeydown(e);
  5766. }
  5767. };
  5768. }
  5769. AutoLink_createClass(AutoLink, [{
  5770. key: "initialize",
  5771. value: function initialize() {
  5772. this.lastWordRange = null;
  5773. }
  5774. }, {
  5775. key: "destroy",
  5776. value: function destroy() {
  5777. this.lastWordRange = null;
  5778. }
  5779. }, {
  5780. key: "replace",
  5781. value: function replace() {
  5782. if (!this.lastWordRange) {
  5783. return;
  5784. }
  5785. var keyword = this.lastWordRange.toString();
  5786. var match = keyword.match(linkPattern);
  5787. if (match && (match[1] || match[2])) {
  5788. var link = match[1] ? keyword : defaultScheme + keyword;
  5789. var urlText = this.options.showDomainOnlyForAutolink ? keyword.replace(/^(?:https?:\/\/)?(?:tel?:?)?(?:mailto?:?)?(?:xmpp?:?)?(?:www\.)?/i, '').split('/')[0] : keyword;
  5790. var node = external_jQuery_default()('<a></a>').html(urlText).attr('href', link)[0];
  5791. if (this.context.options.linkTargetBlank) {
  5792. external_jQuery_default()(node).attr('target', '_blank');
  5793. }
  5794. this.lastWordRange.insertNode(node);
  5795. this.lastWordRange = null;
  5796. this.context.invoke('editor.focus');
  5797. }
  5798. }
  5799. }, {
  5800. key: "handleKeydown",
  5801. value: function handleKeydown(e) {
  5802. if (lists.contains([key.code.ENTER, key.code.SPACE], e.keyCode)) {
  5803. var wordRange = this.context.invoke('editor.createRange').getWordRange();
  5804. this.lastWordRange = wordRange;
  5805. }
  5806. }
  5807. }, {
  5808. key: "handleKeyup",
  5809. value: function handleKeyup(e) {
  5810. if (lists.contains([key.code.ENTER, key.code.SPACE], e.keyCode)) {
  5811. this.replace();
  5812. }
  5813. }
  5814. }]);
  5815. return AutoLink;
  5816. }();
  5817. ;// CONCATENATED MODULE: ./src/js/module/AutoSync.js
  5818. function AutoSync_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5819. function AutoSync_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  5820. function AutoSync_createClass(Constructor, protoProps, staticProps) { if (protoProps) AutoSync_defineProperties(Constructor.prototype, protoProps); if (staticProps) AutoSync_defineProperties(Constructor, staticProps); return Constructor; }
  5821. /**
  5822. * textarea auto sync.
  5823. */
  5824. var AutoSync = /*#__PURE__*/function () {
  5825. function AutoSync(context) {
  5826. var _this = this;
  5827. AutoSync_classCallCheck(this, AutoSync);
  5828. this.$note = context.layoutInfo.note;
  5829. this.events = {
  5830. 'summernote.change': function summernoteChange() {
  5831. _this.$note.val(context.invoke('code'));
  5832. }
  5833. };
  5834. }
  5835. AutoSync_createClass(AutoSync, [{
  5836. key: "shouldInitialize",
  5837. value: function shouldInitialize() {
  5838. return dom.isTextarea(this.$note[0]);
  5839. }
  5840. }]);
  5841. return AutoSync;
  5842. }();
  5843. ;// CONCATENATED MODULE: ./src/js/module/AutoReplace.js
  5844. function AutoReplace_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5845. function AutoReplace_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  5846. function AutoReplace_createClass(Constructor, protoProps, staticProps) { if (protoProps) AutoReplace_defineProperties(Constructor.prototype, protoProps); if (staticProps) AutoReplace_defineProperties(Constructor, staticProps); return Constructor; }
  5847. var AutoReplace = /*#__PURE__*/function () {
  5848. function AutoReplace(context) {
  5849. var _this = this;
  5850. AutoReplace_classCallCheck(this, AutoReplace);
  5851. this.context = context;
  5852. this.options = context.options.replace || {};
  5853. this.keys = [key.code.ENTER, key.code.SPACE, key.code.PERIOD, key.code.COMMA, key.code.SEMICOLON, key.code.SLASH];
  5854. this.previousKeydownCode = null;
  5855. this.events = {
  5856. 'summernote.keyup': function summernoteKeyup(we, e) {
  5857. if (!e.isDefaultPrevented()) {
  5858. _this.handleKeyup(e);
  5859. }
  5860. },
  5861. 'summernote.keydown': function summernoteKeydown(we, e) {
  5862. _this.handleKeydown(e);
  5863. }
  5864. };
  5865. }
  5866. AutoReplace_createClass(AutoReplace, [{
  5867. key: "shouldInitialize",
  5868. value: function shouldInitialize() {
  5869. return !!this.options.match;
  5870. }
  5871. }, {
  5872. key: "initialize",
  5873. value: function initialize() {
  5874. this.lastWord = null;
  5875. }
  5876. }, {
  5877. key: "destroy",
  5878. value: function destroy() {
  5879. this.lastWord = null;
  5880. }
  5881. }, {
  5882. key: "replace",
  5883. value: function replace() {
  5884. if (!this.lastWord) {
  5885. return;
  5886. }
  5887. var self = this;
  5888. var keyword = this.lastWord.toString();
  5889. this.options.match(keyword, function (match) {
  5890. if (match) {
  5891. var node = '';
  5892. if (typeof match === 'string') {
  5893. node = dom.createText(match);
  5894. } else if (match instanceof jQuery) {
  5895. node = match[0];
  5896. } else if (match instanceof Node) {
  5897. node = match;
  5898. }
  5899. if (!node) return;
  5900. self.lastWord.insertNode(node);
  5901. self.lastWord = null;
  5902. self.context.invoke('editor.focus');
  5903. }
  5904. });
  5905. }
  5906. }, {
  5907. key: "handleKeydown",
  5908. value: function handleKeydown(e) {
  5909. // this forces it to remember the last whole word, even if multiple termination keys are pressed
  5910. // before the previous key is let go.
  5911. if (this.previousKeydownCode && lists.contains(this.keys, this.previousKeydownCode)) {
  5912. this.previousKeydownCode = e.keyCode;
  5913. return;
  5914. }
  5915. if (lists.contains(this.keys, e.keyCode)) {
  5916. var wordRange = this.context.invoke('editor.createRange').getWordRange();
  5917. this.lastWord = wordRange;
  5918. }
  5919. this.previousKeydownCode = e.keyCode;
  5920. }
  5921. }, {
  5922. key: "handleKeyup",
  5923. value: function handleKeyup(e) {
  5924. if (lists.contains(this.keys, e.keyCode)) {
  5925. this.replace();
  5926. }
  5927. }
  5928. }]);
  5929. return AutoReplace;
  5930. }();
  5931. ;// CONCATENATED MODULE: ./src/js/module/Placeholder.js
  5932. function Placeholder_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5933. function Placeholder_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  5934. function Placeholder_createClass(Constructor, protoProps, staticProps) { if (protoProps) Placeholder_defineProperties(Constructor.prototype, protoProps); if (staticProps) Placeholder_defineProperties(Constructor, staticProps); return Constructor; }
  5935. var Placeholder = /*#__PURE__*/function () {
  5936. function Placeholder(context) {
  5937. var _this = this;
  5938. Placeholder_classCallCheck(this, Placeholder);
  5939. this.context = context;
  5940. this.$editingArea = context.layoutInfo.editingArea;
  5941. this.options = context.options;
  5942. if (this.options.inheritPlaceholder === true) {
  5943. // get placeholder value from the original element
  5944. this.options.placeholder = this.context.$note.attr('placeholder') || this.options.placeholder;
  5945. }
  5946. this.events = {
  5947. 'summernote.init summernote.change': function summernoteInitSummernoteChange() {
  5948. _this.update();
  5949. },
  5950. 'summernote.codeview.toggled': function summernoteCodeviewToggled() {
  5951. _this.update();
  5952. }
  5953. };
  5954. }
  5955. Placeholder_createClass(Placeholder, [{
  5956. key: "shouldInitialize",
  5957. value: function shouldInitialize() {
  5958. return !!this.options.placeholder;
  5959. }
  5960. }, {
  5961. key: "initialize",
  5962. value: function initialize() {
  5963. var _this2 = this;
  5964. this.$placeholder = external_jQuery_default()('<div class="note-placeholder"></div>');
  5965. this.$placeholder.on('click', function () {
  5966. _this2.context.invoke('focus');
  5967. }).html(this.options.placeholder).prependTo(this.$editingArea);
  5968. this.update();
  5969. }
  5970. }, {
  5971. key: "destroy",
  5972. value: function destroy() {
  5973. this.$placeholder.remove();
  5974. }
  5975. }, {
  5976. key: "update",
  5977. value: function update() {
  5978. var isShow = !this.context.invoke('codeview.isActivated') && this.context.invoke('editor.isEmpty');
  5979. this.$placeholder.toggle(isShow);
  5980. }
  5981. }]);
  5982. return Placeholder;
  5983. }();
  5984. ;// CONCATENATED MODULE: ./src/js/module/Buttons.js
  5985. function Buttons_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5986. function Buttons_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  5987. function Buttons_createClass(Constructor, protoProps, staticProps) { if (protoProps) Buttons_defineProperties(Constructor.prototype, protoProps); if (staticProps) Buttons_defineProperties(Constructor, staticProps); return Constructor; }
  5988. var Buttons = /*#__PURE__*/function () {
  5989. function Buttons(context) {
  5990. Buttons_classCallCheck(this, Buttons);
  5991. this.ui = (external_jQuery_default()).summernote.ui;
  5992. this.context = context;
  5993. this.$toolbar = context.layoutInfo.toolbar;
  5994. this.options = context.options;
  5995. this.lang = this.options.langInfo;
  5996. this.invertedKeyMap = func.invertObject(this.options.keyMap[env.isMac ? 'mac' : 'pc']);
  5997. }
  5998. Buttons_createClass(Buttons, [{
  5999. key: "representShortcut",
  6000. value: function representShortcut(editorMethod) {
  6001. var shortcut = this.invertedKeyMap[editorMethod];
  6002. if (!this.options.shortcuts || !shortcut) {
  6003. return '';
  6004. }
  6005. if (env.isMac) {
  6006. shortcut = shortcut.replace('CMD', '⌘').replace('SHIFT', '⇧');
  6007. }
  6008. shortcut = shortcut.replace('BACKSLASH', '\\').replace('SLASH', '/').replace('LEFTBRACKET', '[').replace('RIGHTBRACKET', ']');
  6009. return ' (' + shortcut + ')';
  6010. }
  6011. }, {
  6012. key: "button",
  6013. value: function button(o) {
  6014. if (!this.options.tooltip && o.tooltip) {
  6015. delete o.tooltip;
  6016. }
  6017. o.container = this.options.container;
  6018. return this.ui.button(o);
  6019. }
  6020. }, {
  6021. key: "initialize",
  6022. value: function initialize() {
  6023. this.addToolbarButtons();
  6024. this.addImagePopoverButtons();
  6025. this.addLinkPopoverButtons();
  6026. this.addTablePopoverButtons();
  6027. this.fontInstalledMap = {};
  6028. }
  6029. }, {
  6030. key: "destroy",
  6031. value: function destroy() {
  6032. delete this.fontInstalledMap;
  6033. }
  6034. }, {
  6035. key: "isFontInstalled",
  6036. value: function isFontInstalled(name) {
  6037. if (!Object.prototype.hasOwnProperty.call(this.fontInstalledMap, name)) {
  6038. this.fontInstalledMap[name] = env.isFontInstalled(name) || lists.contains(this.options.fontNamesIgnoreCheck, name);
  6039. }
  6040. return this.fontInstalledMap[name];
  6041. }
  6042. }, {
  6043. key: "isFontDeservedToAdd",
  6044. value: function isFontDeservedToAdd(name) {
  6045. name = name.toLowerCase();
  6046. return name !== '' && this.isFontInstalled(name) && env.genericFontFamilies.indexOf(name) === -1;
  6047. }
  6048. }, {
  6049. key: "colorPalette",
  6050. value: function colorPalette(className, tooltip, backColor, foreColor) {
  6051. var _this = this;
  6052. return this.ui.buttonGroup({
  6053. className: 'note-color ' + className,
  6054. children: [this.button({
  6055. className: 'note-current-color-button',
  6056. contents: this.ui.icon(this.options.icons.font + ' note-recent-color'),
  6057. tooltip: tooltip,
  6058. click: function click(e) {
  6059. var $button = external_jQuery_default()(e.currentTarget);
  6060. if (backColor && foreColor) {
  6061. _this.context.invoke('editor.color', {
  6062. backColor: $button.attr('data-backColor'),
  6063. foreColor: $button.attr('data-foreColor')
  6064. });
  6065. } else if (backColor) {
  6066. _this.context.invoke('editor.color', {
  6067. backColor: $button.attr('data-backColor')
  6068. });
  6069. } else if (foreColor) {
  6070. _this.context.invoke('editor.color', {
  6071. foreColor: $button.attr('data-foreColor')
  6072. });
  6073. }
  6074. },
  6075. callback: function callback($button) {
  6076. var $recentColor = $button.find('.note-recent-color');
  6077. if (backColor) {
  6078. $recentColor.css('background-color', _this.options.colorButton.backColor);
  6079. $button.attr('data-backColor', _this.options.colorButton.backColor);
  6080. }
  6081. if (foreColor) {
  6082. $recentColor.css('color', _this.options.colorButton.foreColor);
  6083. $button.attr('data-foreColor', _this.options.colorButton.foreColor);
  6084. } else {
  6085. $recentColor.css('color', 'transparent');
  6086. }
  6087. }
  6088. }), this.button({
  6089. className: 'dropdown-toggle',
  6090. contents: this.ui.dropdownButtonContents('', this.options),
  6091. tooltip: this.lang.color.more,
  6092. data: {
  6093. toggle: 'dropdown'
  6094. }
  6095. }), this.ui.dropdown({
  6096. items: (backColor ? ['<div class="note-palette">', '<div class="note-palette-title">' + this.lang.color.background + '</div>', '<div>', '<button type="button" class="note-color-reset btn btn-light btn-default" data-event="backColor" data-value="transparent">', this.lang.color.transparent, '</button>', '</div>', '<div class="note-holder" data-event="backColor"><!-- back colors --></div>', '<div>', '<button type="button" class="note-color-select btn btn-light btn-default" data-event="openPalette" data-value="backColorPicker-' + this.options.id + '">', this.lang.color.cpSelect, '</button>', '<input type="color" id="backColorPicker-' + this.options.id + '" class="note-btn note-color-select-btn" value="' + this.options.colorButton.backColor + '" data-event="backColorPalette-' + this.options.id + '">', '</div>', '<div class="note-holder-custom" id="backColorPalette-' + this.options.id + '" data-event="backColor"></div>', '</div>'].join('') : '') + (foreColor ? ['<div class="note-palette">', '<div class="note-palette-title">' + this.lang.color.foreground + '</div>', '<div>', '<button type="button" class="note-color-reset btn btn-light btn-default" data-event="removeFormat" data-value="foreColor">', this.lang.color.resetToDefault, '</button>', '</div>', '<div class="note-holder" data-event="foreColor"><!-- fore colors --></div>', '<div>', '<button type="button" class="note-color-select btn btn-light btn-default" data-event="openPalette" data-value="foreColorPicker-' + this.options.id + '">', this.lang.color.cpSelect, '</button>', '<input type="color" id="foreColorPicker-' + this.options.id + '" class="note-btn note-color-select-btn" value="' + this.options.colorButton.foreColor + '" data-event="foreColorPalette-' + this.options.id + '">', '</div>', // Fix missing Div, Commented to find easily if it's wrong
  6097. '<div class="note-holder-custom" id="foreColorPalette-' + this.options.id + '" data-event="foreColor"></div>', '</div>'].join('') : ''),
  6098. callback: function callback($dropdown) {
  6099. $dropdown.find('.note-holder').each(function (idx, item) {
  6100. var $holder = external_jQuery_default()(item);
  6101. $holder.append(_this.ui.palette({
  6102. colors: _this.options.colors,
  6103. colorsName: _this.options.colorsName,
  6104. eventName: $holder.data('event'),
  6105. container: _this.options.container,
  6106. tooltip: _this.options.tooltip
  6107. }).render());
  6108. });
  6109. /* TODO: do we have to record recent custom colors within cookies? */
  6110. var customColors = [['#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF', '#FFFFFF']];
  6111. $dropdown.find('.note-holder-custom').each(function (idx, item) {
  6112. var $holder = external_jQuery_default()(item);
  6113. $holder.append(_this.ui.palette({
  6114. colors: customColors,
  6115. colorsName: customColors,
  6116. eventName: $holder.data('event'),
  6117. container: _this.options.container,
  6118. tooltip: _this.options.tooltip
  6119. }).render());
  6120. });
  6121. $dropdown.find('input[type=color]').each(function (idx, item) {
  6122. external_jQuery_default()(item).change(function () {
  6123. var $chip = $dropdown.find('#' + external_jQuery_default()(this).data('event')).find('.note-color-btn').first();
  6124. var color = this.value.toUpperCase();
  6125. $chip.css('background-color', color).attr('aria-label', color).attr('data-value', color).attr('data-original-title', color);
  6126. $chip.click();
  6127. });
  6128. });
  6129. },
  6130. click: function click(event) {
  6131. event.stopPropagation();
  6132. var $parent = external_jQuery_default()('.' + className).find('.note-dropdown-menu');
  6133. var $button = external_jQuery_default()(event.target);
  6134. var eventName = $button.data('event');
  6135. var value = $button.attr('data-value');
  6136. if (eventName === 'openPalette') {
  6137. var $picker = $parent.find('#' + value);
  6138. var $palette = external_jQuery_default()($parent.find('#' + $picker.data('event')).find('.note-color-row')[0]); // Shift palette chips
  6139. var $chip = $palette.find('.note-color-btn').last().detach(); // Set chip attributes
  6140. var color = $picker.val();
  6141. $chip.css('background-color', color).attr('aria-label', color).attr('data-value', color).attr('data-original-title', color);
  6142. $palette.prepend($chip);
  6143. $picker.click();
  6144. } else {
  6145. if (lists.contains(['backColor', 'foreColor'], eventName)) {
  6146. var key = eventName === 'backColor' ? 'background-color' : 'color';
  6147. var $color = $button.closest('.note-color').find('.note-recent-color');
  6148. var $currentButton = $button.closest('.note-color').find('.note-current-color-button');
  6149. $color.css(key, value);
  6150. $currentButton.attr('data-' + eventName, value);
  6151. }
  6152. _this.context.invoke('editor.' + eventName, value);
  6153. }
  6154. }
  6155. })]
  6156. }).render();
  6157. }
  6158. }, {
  6159. key: "addToolbarButtons",
  6160. value: function addToolbarButtons() {
  6161. var _this2 = this;
  6162. this.context.memo('button.style', function () {
  6163. return _this2.ui.buttonGroup([_this2.button({
  6164. className: 'dropdown-toggle',
  6165. contents: _this2.ui.dropdownButtonContents(_this2.ui.icon(_this2.options.icons.magic), _this2.options),
  6166. tooltip: _this2.lang.style.style,
  6167. data: {
  6168. toggle: 'dropdown'
  6169. }
  6170. }), _this2.ui.dropdown({
  6171. className: 'dropdown-style',
  6172. items: _this2.options.styleTags,
  6173. title: _this2.lang.style.style,
  6174. template: function template(item) {
  6175. // TBD: need to be simplified
  6176. if (typeof item === 'string') {
  6177. item = {
  6178. tag: item,
  6179. title: Object.prototype.hasOwnProperty.call(_this2.lang.style, item) ? _this2.lang.style[item] : item
  6180. };
  6181. }
  6182. var tag = item.tag;
  6183. var title = item.title;
  6184. var style = item.style ? ' style="' + item.style + '" ' : '';
  6185. var className = item.className ? ' class="' + item.className + '"' : '';
  6186. return '<' + tag + style + className + '>' + title + '</' + tag + '>';
  6187. },
  6188. click: _this2.context.createInvokeHandler('editor.formatBlock')
  6189. })]).render();
  6190. });
  6191. var _loop = function _loop(styleIdx, styleLen) {
  6192. var item = _this2.options.styleTags[styleIdx];
  6193. _this2.context.memo('button.style.' + item, function () {
  6194. return _this2.button({
  6195. className: 'note-btn-style-' + item,
  6196. contents: '<div data-value="' + item + '">' + item.toUpperCase() + '</div>',
  6197. tooltip: _this2.lang.style[item],
  6198. click: _this2.context.createInvokeHandler('editor.formatBlock')
  6199. }).render();
  6200. });
  6201. };
  6202. for (var styleIdx = 0, styleLen = this.options.styleTags.length; styleIdx < styleLen; styleIdx++) {
  6203. _loop(styleIdx, styleLen);
  6204. }
  6205. this.context.memo('button.bold', function () {
  6206. return _this2.button({
  6207. className: 'note-btn-bold',
  6208. contents: _this2.ui.icon(_this2.options.icons.bold),
  6209. tooltip: _this2.lang.font.bold + _this2.representShortcut('bold'),
  6210. click: _this2.context.createInvokeHandlerAndUpdateState('editor.bold')
  6211. }).render();
  6212. });
  6213. this.context.memo('button.italic', function () {
  6214. return _this2.button({
  6215. className: 'note-btn-italic',
  6216. contents: _this2.ui.icon(_this2.options.icons.italic),
  6217. tooltip: _this2.lang.font.italic + _this2.representShortcut('italic'),
  6218. click: _this2.context.createInvokeHandlerAndUpdateState('editor.italic')
  6219. }).render();
  6220. });
  6221. this.context.memo('button.underline', function () {
  6222. return _this2.button({
  6223. className: 'note-btn-underline',
  6224. contents: _this2.ui.icon(_this2.options.icons.underline),
  6225. tooltip: _this2.lang.font.underline + _this2.representShortcut('underline'),
  6226. click: _this2.context.createInvokeHandlerAndUpdateState('editor.underline')
  6227. }).render();
  6228. });
  6229. this.context.memo('button.clear', function () {
  6230. return _this2.button({
  6231. contents: _this2.ui.icon(_this2.options.icons.eraser),
  6232. tooltip: _this2.lang.font.clear + _this2.representShortcut('removeFormat'),
  6233. click: _this2.context.createInvokeHandler('editor.removeFormat')
  6234. }).render();
  6235. });
  6236. this.context.memo('button.strikethrough', function () {
  6237. return _this2.button({
  6238. className: 'note-btn-strikethrough',
  6239. contents: _this2.ui.icon(_this2.options.icons.strikethrough),
  6240. tooltip: _this2.lang.font.strikethrough + _this2.representShortcut('strikethrough'),
  6241. click: _this2.context.createInvokeHandlerAndUpdateState('editor.strikethrough')
  6242. }).render();
  6243. });
  6244. this.context.memo('button.superscript', function () {
  6245. return _this2.button({
  6246. className: 'note-btn-superscript',
  6247. contents: _this2.ui.icon(_this2.options.icons.superscript),
  6248. tooltip: _this2.lang.font.superscript,
  6249. click: _this2.context.createInvokeHandlerAndUpdateState('editor.superscript')
  6250. }).render();
  6251. });
  6252. this.context.memo('button.subscript', function () {
  6253. return _this2.button({
  6254. className: 'note-btn-subscript',
  6255. contents: _this2.ui.icon(_this2.options.icons.subscript),
  6256. tooltip: _this2.lang.font.subscript,
  6257. click: _this2.context.createInvokeHandlerAndUpdateState('editor.subscript')
  6258. }).render();
  6259. });
  6260. this.context.memo('button.fontname', function () {
  6261. var styleInfo = _this2.context.invoke('editor.currentStyle');
  6262. if (_this2.options.addDefaultFonts) {
  6263. // Add 'default' fonts into the fontnames array if not exist
  6264. external_jQuery_default().each(styleInfo['font-family'].split(','), function (idx, fontname) {
  6265. fontname = fontname.trim().replace(/['"]+/g, '');
  6266. if (_this2.isFontDeservedToAdd(fontname)) {
  6267. if (_this2.options.fontNames.indexOf(fontname) === -1) {
  6268. _this2.options.fontNames.push(fontname);
  6269. }
  6270. }
  6271. });
  6272. }
  6273. return _this2.ui.buttonGroup([_this2.button({
  6274. className: 'dropdown-toggle',
  6275. contents: _this2.ui.dropdownButtonContents('<span class="note-current-fontname"></span>', _this2.options),
  6276. tooltip: _this2.lang.font.name,
  6277. data: {
  6278. toggle: 'dropdown'
  6279. }
  6280. }), _this2.ui.dropdownCheck({
  6281. className: 'dropdown-fontname',
  6282. checkClassName: _this2.options.icons.menuCheck,
  6283. items: _this2.options.fontNames.filter(_this2.isFontInstalled.bind(_this2)),
  6284. title: _this2.lang.font.name,
  6285. template: function template(item) {
  6286. return '<span style="font-family: ' + env.validFontName(item) + '">' + item + '</span>';
  6287. },
  6288. click: _this2.context.createInvokeHandlerAndUpdateState('editor.fontName')
  6289. })]).render();
  6290. });
  6291. this.context.memo('button.fontsize', function () {
  6292. return _this2.ui.buttonGroup([_this2.button({
  6293. className: 'dropdown-toggle',
  6294. contents: _this2.ui.dropdownButtonContents('<span class="note-current-fontsize"></span>', _this2.options),
  6295. tooltip: _this2.lang.font.size,
  6296. data: {
  6297. toggle: 'dropdown'
  6298. }
  6299. }), _this2.ui.dropdownCheck({
  6300. className: 'dropdown-fontsize',
  6301. checkClassName: _this2.options.icons.menuCheck,
  6302. items: _this2.options.fontSizes,
  6303. title: _this2.lang.font.size,
  6304. click: _this2.context.createInvokeHandlerAndUpdateState('editor.fontSize')
  6305. })]).render();
  6306. });
  6307. this.context.memo('button.fontsizeunit', function () {
  6308. return _this2.ui.buttonGroup([_this2.button({
  6309. className: 'dropdown-toggle',
  6310. contents: _this2.ui.dropdownButtonContents('<span class="note-current-fontsizeunit"></span>', _this2.options),
  6311. tooltip: _this2.lang.font.sizeunit,
  6312. data: {
  6313. toggle: 'dropdown'
  6314. }
  6315. }), _this2.ui.dropdownCheck({
  6316. className: 'dropdown-fontsizeunit',
  6317. checkClassName: _this2.options.icons.menuCheck,
  6318. items: _this2.options.fontSizeUnits,
  6319. title: _this2.lang.font.sizeunit,
  6320. click: _this2.context.createInvokeHandlerAndUpdateState('editor.fontSizeUnit')
  6321. })]).render();
  6322. });
  6323. this.context.memo('button.color', function () {
  6324. return _this2.colorPalette('note-color-all', _this2.lang.color.recent, true, true);
  6325. });
  6326. this.context.memo('button.forecolor', function () {
  6327. return _this2.colorPalette('note-color-fore', _this2.lang.color.foreground, false, true);
  6328. });
  6329. this.context.memo('button.backcolor', function () {
  6330. return _this2.colorPalette('note-color-back', _this2.lang.color.background, true, false);
  6331. });
  6332. this.context.memo('button.ul', function () {
  6333. return _this2.button({
  6334. contents: _this2.ui.icon(_this2.options.icons.unorderedlist),
  6335. tooltip: _this2.lang.lists.unordered + _this2.representShortcut('insertUnorderedList'),
  6336. click: _this2.context.createInvokeHandler('editor.insertUnorderedList')
  6337. }).render();
  6338. });
  6339. this.context.memo('button.ol', function () {
  6340. return _this2.button({
  6341. contents: _this2.ui.icon(_this2.options.icons.orderedlist),
  6342. tooltip: _this2.lang.lists.ordered + _this2.representShortcut('insertOrderedList'),
  6343. click: _this2.context.createInvokeHandler('editor.insertOrderedList')
  6344. }).render();
  6345. });
  6346. var justifyLeft = this.button({
  6347. contents: this.ui.icon(this.options.icons.alignLeft),
  6348. tooltip: this.lang.paragraph.left + this.representShortcut('justifyLeft'),
  6349. click: this.context.createInvokeHandler('editor.justifyLeft')
  6350. });
  6351. var justifyCenter = this.button({
  6352. contents: this.ui.icon(this.options.icons.alignCenter),
  6353. tooltip: this.lang.paragraph.center + this.representShortcut('justifyCenter'),
  6354. click: this.context.createInvokeHandler('editor.justifyCenter')
  6355. });
  6356. var justifyRight = this.button({
  6357. contents: this.ui.icon(this.options.icons.alignRight),
  6358. tooltip: this.lang.paragraph.right + this.representShortcut('justifyRight'),
  6359. click: this.context.createInvokeHandler('editor.justifyRight')
  6360. });
  6361. var justifyFull = this.button({
  6362. contents: this.ui.icon(this.options.icons.alignJustify),
  6363. tooltip: this.lang.paragraph.justify + this.representShortcut('justifyFull'),
  6364. click: this.context.createInvokeHandler('editor.justifyFull')
  6365. });
  6366. var outdent = this.button({
  6367. contents: this.ui.icon(this.options.icons.outdent),
  6368. tooltip: this.lang.paragraph.outdent + this.representShortcut('outdent'),
  6369. click: this.context.createInvokeHandler('editor.outdent')
  6370. });
  6371. var indent = this.button({
  6372. contents: this.ui.icon(this.options.icons.indent),
  6373. tooltip: this.lang.paragraph.indent + this.representShortcut('indent'),
  6374. click: this.context.createInvokeHandler('editor.indent')
  6375. });
  6376. this.context.memo('button.justifyLeft', func.invoke(justifyLeft, 'render'));
  6377. this.context.memo('button.justifyCenter', func.invoke(justifyCenter, 'render'));
  6378. this.context.memo('button.justifyRight', func.invoke(justifyRight, 'render'));
  6379. this.context.memo('button.justifyFull', func.invoke(justifyFull, 'render'));
  6380. this.context.memo('button.outdent', func.invoke(outdent, 'render'));
  6381. this.context.memo('button.indent', func.invoke(indent, 'render'));
  6382. this.context.memo('button.paragraph', function () {
  6383. return _this2.ui.buttonGroup([_this2.button({
  6384. className: 'dropdown-toggle',
  6385. contents: _this2.ui.dropdownButtonContents(_this2.ui.icon(_this2.options.icons.alignLeft), _this2.options),
  6386. tooltip: _this2.lang.paragraph.paragraph,
  6387. data: {
  6388. toggle: 'dropdown'
  6389. }
  6390. }), _this2.ui.dropdown([_this2.ui.buttonGroup({
  6391. className: 'note-align',
  6392. children: [justifyLeft, justifyCenter, justifyRight, justifyFull]
  6393. }), _this2.ui.buttonGroup({
  6394. className: 'note-list',
  6395. children: [outdent, indent]
  6396. })])]).render();
  6397. });
  6398. this.context.memo('button.height', function () {
  6399. return _this2.ui.buttonGroup([_this2.button({
  6400. className: 'dropdown-toggle',
  6401. contents: _this2.ui.dropdownButtonContents(_this2.ui.icon(_this2.options.icons.textHeight), _this2.options),
  6402. tooltip: _this2.lang.font.height,
  6403. data: {
  6404. toggle: 'dropdown'
  6405. }
  6406. }), _this2.ui.dropdownCheck({
  6407. items: _this2.options.lineHeights,
  6408. checkClassName: _this2.options.icons.menuCheck,
  6409. className: 'dropdown-line-height',
  6410. title: _this2.lang.font.height,
  6411. click: _this2.context.createInvokeHandler('editor.lineHeight')
  6412. })]).render();
  6413. });
  6414. this.context.memo('button.table', function () {
  6415. return _this2.ui.buttonGroup([_this2.button({
  6416. className: 'dropdown-toggle',
  6417. contents: _this2.ui.dropdownButtonContents(_this2.ui.icon(_this2.options.icons.table), _this2.options),
  6418. tooltip: _this2.lang.table.table,
  6419. data: {
  6420. toggle: 'dropdown'
  6421. }
  6422. }), _this2.ui.dropdown({
  6423. title: _this2.lang.table.table,
  6424. className: 'note-table',
  6425. items: ['<div class="note-dimension-picker">', '<div class="note-dimension-picker-mousecatcher" data-event="insertTable" data-value="1x1"></div>', '<div class="note-dimension-picker-highlighted"></div>', '<div class="note-dimension-picker-unhighlighted"></div>', '</div>', '<div class="note-dimension-display">1 x 1</div>'].join('')
  6426. })], {
  6427. callback: function callback($node) {
  6428. var $catcher = $node.find('.note-dimension-picker-mousecatcher');
  6429. $catcher.css({
  6430. width: _this2.options.insertTableMaxSize.col + 'em',
  6431. height: _this2.options.insertTableMaxSize.row + 'em'
  6432. }).mouseup(_this2.context.createInvokeHandler('editor.insertTable')).on('mousemove', _this2.tableMoveHandler.bind(_this2));
  6433. }
  6434. }).render();
  6435. });
  6436. this.context.memo('button.link', function () {
  6437. return _this2.button({
  6438. contents: _this2.ui.icon(_this2.options.icons.link),
  6439. tooltip: _this2.lang.link.link + _this2.representShortcut('linkDialog.show'),
  6440. click: _this2.context.createInvokeHandler('linkDialog.show')
  6441. }).render();
  6442. });
  6443. this.context.memo('button.picture', function () {
  6444. return _this2.button({
  6445. contents: _this2.ui.icon(_this2.options.icons.picture),
  6446. tooltip: _this2.lang.image.image,
  6447. click: _this2.context.createInvokeHandler('imageDialog.show')
  6448. }).render();
  6449. });
  6450. this.context.memo('button.video', function () {
  6451. return _this2.button({
  6452. contents: _this2.ui.icon(_this2.options.icons.video),
  6453. tooltip: _this2.lang.video.video,
  6454. click: _this2.context.createInvokeHandler('videoDialog.show')
  6455. }).render();
  6456. });
  6457. this.context.memo('button.hr', function () {
  6458. return _this2.button({
  6459. contents: _this2.ui.icon(_this2.options.icons.minus),
  6460. tooltip: _this2.lang.hr.insert + _this2.representShortcut('insertHorizontalRule'),
  6461. click: _this2.context.createInvokeHandler('editor.insertHorizontalRule')
  6462. }).render();
  6463. });
  6464. this.context.memo('button.fullscreen', function () {
  6465. return _this2.button({
  6466. className: 'btn-fullscreen note-codeview-keep',
  6467. contents: _this2.ui.icon(_this2.options.icons.arrowsAlt),
  6468. tooltip: _this2.lang.options.fullscreen,
  6469. click: _this2.context.createInvokeHandler('fullscreen.toggle')
  6470. }).render();
  6471. });
  6472. this.context.memo('button.codeview', function () {
  6473. return _this2.button({
  6474. className: 'btn-codeview note-codeview-keep',
  6475. contents: _this2.ui.icon(_this2.options.icons.code),
  6476. tooltip: _this2.lang.options.codeview,
  6477. click: _this2.context.createInvokeHandler('codeview.toggle')
  6478. }).render();
  6479. });
  6480. this.context.memo('button.redo', function () {
  6481. return _this2.button({
  6482. contents: _this2.ui.icon(_this2.options.icons.redo),
  6483. tooltip: _this2.lang.history.redo + _this2.representShortcut('redo'),
  6484. click: _this2.context.createInvokeHandler('editor.redo')
  6485. }).render();
  6486. });
  6487. this.context.memo('button.undo', function () {
  6488. return _this2.button({
  6489. contents: _this2.ui.icon(_this2.options.icons.undo),
  6490. tooltip: _this2.lang.history.undo + _this2.representShortcut('undo'),
  6491. click: _this2.context.createInvokeHandler('editor.undo')
  6492. }).render();
  6493. });
  6494. this.context.memo('button.help', function () {
  6495. return _this2.button({
  6496. contents: _this2.ui.icon(_this2.options.icons.question),
  6497. tooltip: _this2.lang.options.help,
  6498. click: _this2.context.createInvokeHandler('helpDialog.show')
  6499. }).render();
  6500. });
  6501. }
  6502. /**
  6503. * image: [
  6504. * ['imageResize', ['resizeFull', 'resizeHalf', 'resizeQuarter', 'resizeNone']],
  6505. * ['float', ['floatLeft', 'floatRight', 'floatNone']],
  6506. * ['remove', ['removeMedia']],
  6507. * ],
  6508. */
  6509. }, {
  6510. key: "addImagePopoverButtons",
  6511. value: function addImagePopoverButtons() {
  6512. var _this3 = this;
  6513. // Image Size Buttons
  6514. this.context.memo('button.resizeFull', function () {
  6515. return _this3.button({
  6516. contents: '<span class="note-fontsize-10">100%</span>',
  6517. tooltip: _this3.lang.image.resizeFull,
  6518. click: _this3.context.createInvokeHandler('editor.resize', '1')
  6519. }).render();
  6520. });
  6521. this.context.memo('button.resizeHalf', function () {
  6522. return _this3.button({
  6523. contents: '<span class="note-fontsize-10">50%</span>',
  6524. tooltip: _this3.lang.image.resizeHalf,
  6525. click: _this3.context.createInvokeHandler('editor.resize', '0.5')
  6526. }).render();
  6527. });
  6528. this.context.memo('button.resizeQuarter', function () {
  6529. return _this3.button({
  6530. contents: '<span class="note-fontsize-10">25%</span>',
  6531. tooltip: _this3.lang.image.resizeQuarter,
  6532. click: _this3.context.createInvokeHandler('editor.resize', '0.25')
  6533. }).render();
  6534. });
  6535. this.context.memo('button.resizeNone', function () {
  6536. return _this3.button({
  6537. contents: _this3.ui.icon(_this3.options.icons.rollback),
  6538. tooltip: _this3.lang.image.resizeNone,
  6539. click: _this3.context.createInvokeHandler('editor.resize', '0')
  6540. }).render();
  6541. }); // Float Buttons
  6542. this.context.memo('button.floatLeft', function () {
  6543. return _this3.button({
  6544. contents: _this3.ui.icon(_this3.options.icons.floatLeft),
  6545. tooltip: _this3.lang.image.floatLeft,
  6546. click: _this3.context.createInvokeHandler('editor.floatMe', 'left')
  6547. }).render();
  6548. });
  6549. this.context.memo('button.floatRight', function () {
  6550. return _this3.button({
  6551. contents: _this3.ui.icon(_this3.options.icons.floatRight),
  6552. tooltip: _this3.lang.image.floatRight,
  6553. click: _this3.context.createInvokeHandler('editor.floatMe', 'right')
  6554. }).render();
  6555. });
  6556. this.context.memo('button.floatNone', function () {
  6557. return _this3.button({
  6558. contents: _this3.ui.icon(_this3.options.icons.rollback),
  6559. tooltip: _this3.lang.image.floatNone,
  6560. click: _this3.context.createInvokeHandler('editor.floatMe', 'none')
  6561. }).render();
  6562. }); // Remove Buttons
  6563. this.context.memo('button.removeMedia', function () {
  6564. return _this3.button({
  6565. contents: _this3.ui.icon(_this3.options.icons.trash),
  6566. tooltip: _this3.lang.image.remove,
  6567. click: _this3.context.createInvokeHandler('editor.removeMedia')
  6568. }).render();
  6569. });
  6570. }
  6571. }, {
  6572. key: "addLinkPopoverButtons",
  6573. value: function addLinkPopoverButtons() {
  6574. var _this4 = this;
  6575. this.context.memo('button.linkDialogShow', function () {
  6576. return _this4.button({
  6577. contents: _this4.ui.icon(_this4.options.icons.link),
  6578. tooltip: _this4.lang.link.edit,
  6579. click: _this4.context.createInvokeHandler('linkDialog.show')
  6580. }).render();
  6581. });
  6582. this.context.memo('button.unlink', function () {
  6583. return _this4.button({
  6584. contents: _this4.ui.icon(_this4.options.icons.unlink),
  6585. tooltip: _this4.lang.link.unlink,
  6586. click: _this4.context.createInvokeHandler('editor.unlink')
  6587. }).render();
  6588. });
  6589. }
  6590. /**
  6591. * table : [
  6592. * ['add', ['addRowDown', 'addRowUp', 'addColLeft', 'addColRight']],
  6593. * ['delete', ['deleteRow', 'deleteCol', 'deleteTable']]
  6594. * ],
  6595. */
  6596. }, {
  6597. key: "addTablePopoverButtons",
  6598. value: function addTablePopoverButtons() {
  6599. var _this5 = this;
  6600. this.context.memo('button.addRowUp', function () {
  6601. return _this5.button({
  6602. className: 'btn-md',
  6603. contents: _this5.ui.icon(_this5.options.icons.rowAbove),
  6604. tooltip: _this5.lang.table.addRowAbove,
  6605. click: _this5.context.createInvokeHandler('editor.addRow', 'top')
  6606. }).render();
  6607. });
  6608. this.context.memo('button.addRowDown', function () {
  6609. return _this5.button({
  6610. className: 'btn-md',
  6611. contents: _this5.ui.icon(_this5.options.icons.rowBelow),
  6612. tooltip: _this5.lang.table.addRowBelow,
  6613. click: _this5.context.createInvokeHandler('editor.addRow', 'bottom')
  6614. }).render();
  6615. });
  6616. this.context.memo('button.addColLeft', function () {
  6617. return _this5.button({
  6618. className: 'btn-md',
  6619. contents: _this5.ui.icon(_this5.options.icons.colBefore),
  6620. tooltip: _this5.lang.table.addColLeft,
  6621. click: _this5.context.createInvokeHandler('editor.addCol', 'left')
  6622. }).render();
  6623. });
  6624. this.context.memo('button.addColRight', function () {
  6625. return _this5.button({
  6626. className: 'btn-md',
  6627. contents: _this5.ui.icon(_this5.options.icons.colAfter),
  6628. tooltip: _this5.lang.table.addColRight,
  6629. click: _this5.context.createInvokeHandler('editor.addCol', 'right')
  6630. }).render();
  6631. });
  6632. this.context.memo('button.deleteRow', function () {
  6633. return _this5.button({
  6634. className: 'btn-md',
  6635. contents: _this5.ui.icon(_this5.options.icons.rowRemove),
  6636. tooltip: _this5.lang.table.delRow,
  6637. click: _this5.context.createInvokeHandler('editor.deleteRow')
  6638. }).render();
  6639. });
  6640. this.context.memo('button.deleteCol', function () {
  6641. return _this5.button({
  6642. className: 'btn-md',
  6643. contents: _this5.ui.icon(_this5.options.icons.colRemove),
  6644. tooltip: _this5.lang.table.delCol,
  6645. click: _this5.context.createInvokeHandler('editor.deleteCol')
  6646. }).render();
  6647. });
  6648. this.context.memo('button.deleteTable', function () {
  6649. return _this5.button({
  6650. className: 'btn-md',
  6651. contents: _this5.ui.icon(_this5.options.icons.trash),
  6652. tooltip: _this5.lang.table.delTable,
  6653. click: _this5.context.createInvokeHandler('editor.deleteTable')
  6654. }).render();
  6655. });
  6656. }
  6657. }, {
  6658. key: "build",
  6659. value: function build($container, groups) {
  6660. for (var groupIdx = 0, groupLen = groups.length; groupIdx < groupLen; groupIdx++) {
  6661. var group = groups[groupIdx];
  6662. var groupName = Array.isArray(group) ? group[0] : group;
  6663. var buttons = Array.isArray(group) ? group.length === 1 ? [group[0]] : group[1] : [group];
  6664. var $group = this.ui.buttonGroup({
  6665. className: 'note-' + groupName
  6666. }).render();
  6667. for (var idx = 0, len = buttons.length; idx < len; idx++) {
  6668. var btn = this.context.memo('button.' + buttons[idx]);
  6669. if (btn) {
  6670. $group.append(typeof btn === 'function' ? btn(this.context) : btn);
  6671. }
  6672. }
  6673. $group.appendTo($container);
  6674. }
  6675. }
  6676. /**
  6677. * @param {jQuery} [$container]
  6678. */
  6679. }, {
  6680. key: "updateCurrentStyle",
  6681. value: function updateCurrentStyle($container) {
  6682. var $cont = $container || this.$toolbar;
  6683. var styleInfo = this.context.invoke('editor.currentStyle');
  6684. this.updateBtnStates($cont, {
  6685. '.note-btn-bold': function noteBtnBold() {
  6686. return styleInfo['font-bold'] === 'bold';
  6687. },
  6688. '.note-btn-italic': function noteBtnItalic() {
  6689. return styleInfo['font-italic'] === 'italic';
  6690. },
  6691. '.note-btn-underline': function noteBtnUnderline() {
  6692. return styleInfo['font-underline'] === 'underline';
  6693. },
  6694. '.note-btn-subscript': function noteBtnSubscript() {
  6695. return styleInfo['font-subscript'] === 'subscript';
  6696. },
  6697. '.note-btn-superscript': function noteBtnSuperscript() {
  6698. return styleInfo['font-superscript'] === 'superscript';
  6699. },
  6700. '.note-btn-strikethrough': function noteBtnStrikethrough() {
  6701. return styleInfo['font-strikethrough'] === 'strikethrough';
  6702. }
  6703. });
  6704. if (styleInfo['font-family']) {
  6705. var fontNames = styleInfo['font-family'].split(',').map(function (name) {
  6706. return name.replace(/[\'\"]/g, '').replace(/\s+$/, '').replace(/^\s+/, '');
  6707. });
  6708. var fontName = lists.find(fontNames, this.isFontInstalled.bind(this));
  6709. $cont.find('.dropdown-fontname a').each(function (idx, item) {
  6710. var $item = external_jQuery_default()(item); // always compare string to avoid creating another func.
  6711. var isChecked = $item.data('value') + '' === fontName + '';
  6712. $item.toggleClass('checked', isChecked);
  6713. });
  6714. $cont.find('.note-current-fontname').text(fontName).css('font-family', fontName);
  6715. }
  6716. if (styleInfo['font-size']) {
  6717. var fontSize = styleInfo['font-size'];
  6718. $cont.find('.dropdown-fontsize a').each(function (idx, item) {
  6719. var $item = external_jQuery_default()(item); // always compare with string to avoid creating another func.
  6720. var isChecked = $item.data('value') + '' === fontSize + '';
  6721. $item.toggleClass('checked', isChecked);
  6722. });
  6723. $cont.find('.note-current-fontsize').text(fontSize);
  6724. var fontSizeUnit = styleInfo['font-size-unit'];
  6725. $cont.find('.dropdown-fontsizeunit a').each(function (idx, item) {
  6726. var $item = external_jQuery_default()(item);
  6727. var isChecked = $item.data('value') + '' === fontSizeUnit + '';
  6728. $item.toggleClass('checked', isChecked);
  6729. });
  6730. $cont.find('.note-current-fontsizeunit').text(fontSizeUnit);
  6731. }
  6732. if (styleInfo['line-height']) {
  6733. var lineHeight = styleInfo['line-height'];
  6734. $cont.find('.dropdown-line-height a').each(function (idx, item) {
  6735. var $item = external_jQuery_default()(item); // always compare with string to avoid creating another func.
  6736. var isChecked = external_jQuery_default()(item).data('value') + '' === lineHeight + '';
  6737. $item.toggleClass('checked', isChecked);
  6738. });
  6739. $cont.find('.note-current-line-height').text(lineHeight);
  6740. }
  6741. }
  6742. }, {
  6743. key: "updateBtnStates",
  6744. value: function updateBtnStates($container, infos) {
  6745. var _this6 = this;
  6746. external_jQuery_default().each(infos, function (selector, pred) {
  6747. _this6.ui.toggleBtnActive($container.find(selector), pred());
  6748. });
  6749. }
  6750. }, {
  6751. key: "tableMoveHandler",
  6752. value: function tableMoveHandler(event) {
  6753. var PX_PER_EM = 18;
  6754. var $picker = external_jQuery_default()(event.target.parentNode); // target is mousecatcher
  6755. var $dimensionDisplay = $picker.next();
  6756. var $catcher = $picker.find('.note-dimension-picker-mousecatcher');
  6757. var $highlighted = $picker.find('.note-dimension-picker-highlighted');
  6758. var $unhighlighted = $picker.find('.note-dimension-picker-unhighlighted');
  6759. var posOffset; // HTML5 with jQuery - e.offsetX is undefined in Firefox
  6760. if (event.offsetX === undefined) {
  6761. var posCatcher = external_jQuery_default()(event.target).offset();
  6762. posOffset = {
  6763. x: event.pageX - posCatcher.left,
  6764. y: event.pageY - posCatcher.top
  6765. };
  6766. } else {
  6767. posOffset = {
  6768. x: event.offsetX,
  6769. y: event.offsetY
  6770. };
  6771. }
  6772. var dim = {
  6773. c: Math.ceil(posOffset.x / PX_PER_EM) || 1,
  6774. r: Math.ceil(posOffset.y / PX_PER_EM) || 1
  6775. };
  6776. $highlighted.css({
  6777. width: dim.c + 'em',
  6778. height: dim.r + 'em'
  6779. });
  6780. $catcher.data('value', dim.c + 'x' + dim.r);
  6781. if (dim.c > 3 && dim.c < this.options.insertTableMaxSize.col) {
  6782. $unhighlighted.css({
  6783. width: dim.c + 1 + 'em'
  6784. });
  6785. }
  6786. if (dim.r > 3 && dim.r < this.options.insertTableMaxSize.row) {
  6787. $unhighlighted.css({
  6788. height: dim.r + 1 + 'em'
  6789. });
  6790. }
  6791. $dimensionDisplay.html(dim.c + ' x ' + dim.r);
  6792. }
  6793. }]);
  6794. return Buttons;
  6795. }();
  6796. ;// CONCATENATED MODULE: ./src/js/module/Toolbar.js
  6797. function Toolbar_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  6798. function Toolbar_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  6799. function Toolbar_createClass(Constructor, protoProps, staticProps) { if (protoProps) Toolbar_defineProperties(Constructor.prototype, protoProps); if (staticProps) Toolbar_defineProperties(Constructor, staticProps); return Constructor; }
  6800. var Toolbar = /*#__PURE__*/function () {
  6801. function Toolbar(context) {
  6802. Toolbar_classCallCheck(this, Toolbar);
  6803. this.context = context;
  6804. this.$window = external_jQuery_default()(window);
  6805. this.$document = external_jQuery_default()(document);
  6806. this.ui = (external_jQuery_default()).summernote.ui;
  6807. this.$note = context.layoutInfo.note;
  6808. this.$editor = context.layoutInfo.editor;
  6809. this.$toolbar = context.layoutInfo.toolbar;
  6810. this.$editable = context.layoutInfo.editable;
  6811. this.$statusbar = context.layoutInfo.statusbar;
  6812. this.options = context.options;
  6813. this.isFollowing = false;
  6814. this.followScroll = this.followScroll.bind(this);
  6815. }
  6816. Toolbar_createClass(Toolbar, [{
  6817. key: "shouldInitialize",
  6818. value: function shouldInitialize() {
  6819. return !this.options.airMode;
  6820. }
  6821. }, {
  6822. key: "initialize",
  6823. value: function initialize() {
  6824. var _this = this;
  6825. this.options.toolbar = this.options.toolbar || [];
  6826. if (!this.options.toolbar.length) {
  6827. this.$toolbar.hide();
  6828. } else {
  6829. this.context.invoke('buttons.build', this.$toolbar, this.options.toolbar);
  6830. }
  6831. if (this.options.toolbarContainer) {
  6832. this.$toolbar.appendTo(this.options.toolbarContainer);
  6833. }
  6834. this.changeContainer(false);
  6835. this.$note.on('summernote.keyup summernote.mouseup summernote.change', function () {
  6836. _this.context.invoke('buttons.updateCurrentStyle');
  6837. });
  6838. this.context.invoke('buttons.updateCurrentStyle');
  6839. if (this.options.followingToolbar) {
  6840. this.$window.on('scroll resize', this.followScroll);
  6841. }
  6842. }
  6843. }, {
  6844. key: "destroy",
  6845. value: function destroy() {
  6846. this.$toolbar.children().remove();
  6847. if (this.options.followingToolbar) {
  6848. this.$window.off('scroll resize', this.followScroll);
  6849. }
  6850. }
  6851. }, {
  6852. key: "followScroll",
  6853. value: function followScroll() {
  6854. if (this.$editor.hasClass('fullscreen')) {
  6855. return false;
  6856. }
  6857. var editorHeight = this.$editor.outerHeight();
  6858. var editorWidth = this.$editor.width();
  6859. var toolbarHeight = this.$toolbar.height();
  6860. var statusbarHeight = this.$statusbar.height(); // check if the web app is currently using another static bar
  6861. var otherBarHeight = 0;
  6862. if (this.options.otherStaticBar) {
  6863. otherBarHeight = external_jQuery_default()(this.options.otherStaticBar).outerHeight();
  6864. }
  6865. var currentOffset = this.$document.scrollTop();
  6866. var editorOffsetTop = this.$editor.offset().top;
  6867. var editorOffsetBottom = editorOffsetTop + editorHeight;
  6868. var activateOffset = editorOffsetTop - otherBarHeight;
  6869. var deactivateOffsetBottom = editorOffsetBottom - otherBarHeight - toolbarHeight - statusbarHeight;
  6870. if (!this.isFollowing && currentOffset > activateOffset && currentOffset < deactivateOffsetBottom - toolbarHeight) {
  6871. this.isFollowing = true;
  6872. this.$editable.css({
  6873. marginTop: this.$toolbar.outerHeight()
  6874. });
  6875. this.$toolbar.css({
  6876. position: 'fixed',
  6877. top: otherBarHeight,
  6878. width: editorWidth,
  6879. zIndex: 1000
  6880. });
  6881. } else if (this.isFollowing && (currentOffset < activateOffset || currentOffset > deactivateOffsetBottom)) {
  6882. this.isFollowing = false;
  6883. this.$toolbar.css({
  6884. position: 'relative',
  6885. top: 0,
  6886. width: '100%',
  6887. zIndex: 'auto'
  6888. });
  6889. this.$editable.css({
  6890. marginTop: ''
  6891. });
  6892. }
  6893. }
  6894. }, {
  6895. key: "changeContainer",
  6896. value: function changeContainer(isFullscreen) {
  6897. if (isFullscreen) {
  6898. this.$toolbar.prependTo(this.$editor);
  6899. } else {
  6900. if (this.options.toolbarContainer) {
  6901. this.$toolbar.appendTo(this.options.toolbarContainer);
  6902. }
  6903. }
  6904. if (this.options.followingToolbar) {
  6905. this.followScroll();
  6906. }
  6907. }
  6908. }, {
  6909. key: "updateFullscreen",
  6910. value: function updateFullscreen(isFullscreen) {
  6911. this.ui.toggleBtnActive(this.$toolbar.find('.btn-fullscreen'), isFullscreen);
  6912. this.changeContainer(isFullscreen);
  6913. }
  6914. }, {
  6915. key: "updateCodeview",
  6916. value: function updateCodeview(isCodeview) {
  6917. this.ui.toggleBtnActive(this.$toolbar.find('.btn-codeview'), isCodeview);
  6918. if (isCodeview) {
  6919. this.deactivate();
  6920. } else {
  6921. this.activate();
  6922. }
  6923. }
  6924. }, {
  6925. key: "activate",
  6926. value: function activate(isIncludeCodeview) {
  6927. var $btn = this.$toolbar.find('button');
  6928. if (!isIncludeCodeview) {
  6929. $btn = $btn.not('.note-codeview-keep');
  6930. }
  6931. this.ui.toggleBtn($btn, true);
  6932. }
  6933. }, {
  6934. key: "deactivate",
  6935. value: function deactivate(isIncludeCodeview) {
  6936. var $btn = this.$toolbar.find('button');
  6937. if (!isIncludeCodeview) {
  6938. $btn = $btn.not('.note-codeview-keep');
  6939. }
  6940. this.ui.toggleBtn($btn, false);
  6941. }
  6942. }]);
  6943. return Toolbar;
  6944. }();
  6945. ;// CONCATENATED MODULE: ./src/js/module/LinkDialog.js
  6946. function LinkDialog_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  6947. function LinkDialog_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  6948. function LinkDialog_createClass(Constructor, protoProps, staticProps) { if (protoProps) LinkDialog_defineProperties(Constructor.prototype, protoProps); if (staticProps) LinkDialog_defineProperties(Constructor, staticProps); return Constructor; }
  6949. var LinkDialog = /*#__PURE__*/function () {
  6950. function LinkDialog(context) {
  6951. LinkDialog_classCallCheck(this, LinkDialog);
  6952. this.context = context;
  6953. this.ui = (external_jQuery_default()).summernote.ui;
  6954. this.$body = external_jQuery_default()(document.body);
  6955. this.$editor = context.layoutInfo.editor;
  6956. this.options = context.options;
  6957. this.lang = this.options.langInfo;
  6958. context.memo('help.linkDialog.show', this.options.langInfo.help['linkDialog.show']);
  6959. }
  6960. LinkDialog_createClass(LinkDialog, [{
  6961. key: "initialize",
  6962. value: function initialize() {
  6963. var $container = this.options.dialogsInBody ? this.$body : this.options.container;
  6964. var body = ['<div class="form-group note-form-group">', "<label for=\"note-dialog-link-txt-".concat(this.options.id, "\" class=\"note-form-label\">").concat(this.lang.link.textToDisplay, "</label>"), "<input id=\"note-dialog-link-txt-".concat(this.options.id, "\" class=\"note-link-text form-control note-form-control note-input\" type=\"text\"/>"), '</div>', '<div class="form-group note-form-group">', "<label for=\"note-dialog-link-url-".concat(this.options.id, "\" class=\"note-form-label\">").concat(this.lang.link.url, "</label>"), "<input id=\"note-dialog-link-url-".concat(this.options.id, "\" class=\"note-link-url form-control note-form-control note-input\" type=\"text\" value=\"http://\"/>"), '</div>', !this.options.disableLinkTarget ? external_jQuery_default()('<div></div>').append(this.ui.checkbox({
  6965. className: 'sn-checkbox-open-in-new-window',
  6966. text: this.lang.link.openInNewWindow,
  6967. checked: true
  6968. }).render()).html() : '', external_jQuery_default()('<div></div>').append(this.ui.checkbox({
  6969. className: 'sn-checkbox-use-protocol',
  6970. text: this.lang.link.useProtocol,
  6971. checked: true
  6972. }).render()).html()].join('');
  6973. var buttonClass = 'btn btn-primary note-btn note-btn-primary note-link-btn';
  6974. var footer = "<input type=\"button\" href=\"#\" class=\"".concat(buttonClass, "\" value=\"").concat(this.lang.link.insert, "\" disabled>");
  6975. this.$dialog = this.ui.dialog({
  6976. className: 'link-dialog',
  6977. title: this.lang.link.insert,
  6978. fade: this.options.dialogsFade,
  6979. body: body,
  6980. footer: footer
  6981. }).render().appendTo($container);
  6982. }
  6983. }, {
  6984. key: "destroy",
  6985. value: function destroy() {
  6986. this.ui.hideDialog(this.$dialog);
  6987. this.$dialog.remove();
  6988. }
  6989. }, {
  6990. key: "bindEnterKey",
  6991. value: function bindEnterKey($input, $btn) {
  6992. $input.on('keypress', function (event) {
  6993. if (event.keyCode === key.code.ENTER) {
  6994. event.preventDefault();
  6995. $btn.trigger('click');
  6996. }
  6997. });
  6998. }
  6999. /**
  7000. * toggle update button
  7001. */
  7002. }, {
  7003. key: "toggleLinkBtn",
  7004. value: function toggleLinkBtn($linkBtn, $linkText, $linkUrl) {
  7005. this.ui.toggleBtn($linkBtn, $linkText.val() && $linkUrl.val());
  7006. }
  7007. /**
  7008. * Show link dialog and set event handlers on dialog controls.
  7009. *
  7010. * @param {Object} linkInfo
  7011. * @return {Promise}
  7012. */
  7013. }, {
  7014. key: "showLinkDialog",
  7015. value: function showLinkDialog(linkInfo) {
  7016. var _this = this;
  7017. return external_jQuery_default().Deferred(function (deferred) {
  7018. var $linkText = _this.$dialog.find('.note-link-text');
  7019. var $linkUrl = _this.$dialog.find('.note-link-url');
  7020. var $linkBtn = _this.$dialog.find('.note-link-btn');
  7021. var $openInNewWindow = _this.$dialog.find('.sn-checkbox-open-in-new-window input[type=checkbox]');
  7022. var $useProtocol = _this.$dialog.find('.sn-checkbox-use-protocol input[type=checkbox]');
  7023. _this.ui.onDialogShown(_this.$dialog, function () {
  7024. _this.context.triggerEvent('dialog.shown'); // If no url was given and given text is valid URL then copy that into URL Field
  7025. if (!linkInfo.url && func.isValidUrl(linkInfo.text)) {
  7026. linkInfo.url = linkInfo.text;
  7027. }
  7028. $linkText.on('input paste propertychange', function () {
  7029. // If linktext was modified by input events,
  7030. // cloning text from linkUrl will be stopped.
  7031. linkInfo.text = $linkText.val();
  7032. _this.toggleLinkBtn($linkBtn, $linkText, $linkUrl);
  7033. }).val(linkInfo.text);
  7034. $linkUrl.on('input paste propertychange', function () {
  7035. // Display same text on `Text to display` as default
  7036. // when linktext has no text
  7037. if (!linkInfo.text) {
  7038. $linkText.val($linkUrl.val());
  7039. }
  7040. _this.toggleLinkBtn($linkBtn, $linkText, $linkUrl);
  7041. }).val(linkInfo.url);
  7042. if (!env.isSupportTouch) {
  7043. $linkUrl.trigger('focus');
  7044. }
  7045. _this.toggleLinkBtn($linkBtn, $linkText, $linkUrl);
  7046. _this.bindEnterKey($linkUrl, $linkBtn);
  7047. _this.bindEnterKey($linkText, $linkBtn);
  7048. var isNewWindowChecked = linkInfo.isNewWindow !== undefined ? linkInfo.isNewWindow : _this.context.options.linkTargetBlank;
  7049. $openInNewWindow.prop('checked', isNewWindowChecked);
  7050. var useProtocolChecked = linkInfo.url ? false : _this.context.options.useProtocol;
  7051. $useProtocol.prop('checked', useProtocolChecked);
  7052. $linkBtn.one('click', function (event) {
  7053. event.preventDefault();
  7054. deferred.resolve({
  7055. range: linkInfo.range,
  7056. url: $linkUrl.val(),
  7057. text: $linkText.val(),
  7058. isNewWindow: $openInNewWindow.is(':checked'),
  7059. checkProtocol: $useProtocol.is(':checked')
  7060. });
  7061. _this.ui.hideDialog(_this.$dialog);
  7062. });
  7063. });
  7064. _this.ui.onDialogHidden(_this.$dialog, function () {
  7065. // detach events
  7066. $linkText.off();
  7067. $linkUrl.off();
  7068. $linkBtn.off();
  7069. if (deferred.state() === 'pending') {
  7070. deferred.reject();
  7071. }
  7072. });
  7073. _this.ui.showDialog(_this.$dialog);
  7074. }).promise();
  7075. }
  7076. /**
  7077. * @param {Object} layoutInfo
  7078. */
  7079. }, {
  7080. key: "show",
  7081. value: function show() {
  7082. var _this2 = this;
  7083. var linkInfo = this.context.invoke('editor.getLinkInfo');
  7084. this.context.invoke('editor.saveRange');
  7085. this.showLinkDialog(linkInfo).then(function (linkInfo) {
  7086. _this2.context.invoke('editor.restoreRange');
  7087. _this2.context.invoke('editor.createLink', linkInfo);
  7088. }).fail(function () {
  7089. _this2.context.invoke('editor.restoreRange');
  7090. });
  7091. }
  7092. }]);
  7093. return LinkDialog;
  7094. }();
  7095. ;// CONCATENATED MODULE: ./src/js/module/LinkPopover.js
  7096. function LinkPopover_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7097. function LinkPopover_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  7098. function LinkPopover_createClass(Constructor, protoProps, staticProps) { if (protoProps) LinkPopover_defineProperties(Constructor.prototype, protoProps); if (staticProps) LinkPopover_defineProperties(Constructor, staticProps); return Constructor; }
  7099. var LinkPopover = /*#__PURE__*/function () {
  7100. function LinkPopover(context) {
  7101. var _this = this;
  7102. LinkPopover_classCallCheck(this, LinkPopover);
  7103. this.context = context;
  7104. this.ui = (external_jQuery_default()).summernote.ui;
  7105. this.options = context.options;
  7106. this.events = {
  7107. 'summernote.keyup summernote.mouseup summernote.change summernote.scroll': function summernoteKeyupSummernoteMouseupSummernoteChangeSummernoteScroll() {
  7108. _this.update();
  7109. },
  7110. 'summernote.disable summernote.dialog.shown': function summernoteDisableSummernoteDialogShown() {
  7111. _this.hide();
  7112. },
  7113. 'summernote.blur': function summernoteBlur(we, e) {
  7114. if (e.originalEvent && e.originalEvent.relatedTarget) {
  7115. if (!_this.$popover[0].contains(e.originalEvent.relatedTarget)) {
  7116. _this.hide();
  7117. }
  7118. } else {
  7119. _this.hide();
  7120. }
  7121. }
  7122. };
  7123. }
  7124. LinkPopover_createClass(LinkPopover, [{
  7125. key: "shouldInitialize",
  7126. value: function shouldInitialize() {
  7127. return !lists.isEmpty(this.options.popover.link);
  7128. }
  7129. }, {
  7130. key: "initialize",
  7131. value: function initialize() {
  7132. this.$popover = this.ui.popover({
  7133. className: 'note-link-popover',
  7134. callback: function callback($node) {
  7135. var $content = $node.find('.popover-content,.note-popover-content');
  7136. $content.prepend('<span><a target="_blank"></a>&nbsp;</span>');
  7137. }
  7138. }).render().appendTo(this.options.container);
  7139. var $content = this.$popover.find('.popover-content,.note-popover-content');
  7140. this.context.invoke('buttons.build', $content, this.options.popover.link);
  7141. this.$popover.on('mousedown', function (e) {
  7142. e.preventDefault();
  7143. });
  7144. }
  7145. }, {
  7146. key: "destroy",
  7147. value: function destroy() {
  7148. this.$popover.remove();
  7149. }
  7150. }, {
  7151. key: "update",
  7152. value: function update() {
  7153. // Prevent focusing on editable when invoke('code') is executed
  7154. if (!this.context.invoke('editor.hasFocus')) {
  7155. this.hide();
  7156. return;
  7157. }
  7158. var rng = this.context.invoke('editor.getLastRange');
  7159. if (rng.isCollapsed() && rng.isOnAnchor()) {
  7160. var anchor = dom.ancestor(rng.sc, dom.isAnchor);
  7161. var href = external_jQuery_default()(anchor).attr('href');
  7162. this.$popover.find('a').attr('href', href).text(href);
  7163. var pos = dom.posFromPlaceholder(anchor);
  7164. var containerOffset = external_jQuery_default()(this.options.container).offset();
  7165. pos.top -= containerOffset.top;
  7166. pos.left -= containerOffset.left;
  7167. this.$popover.css({
  7168. display: 'block',
  7169. left: pos.left,
  7170. top: pos.top
  7171. });
  7172. } else {
  7173. this.hide();
  7174. }
  7175. }
  7176. }, {
  7177. key: "hide",
  7178. value: function hide() {
  7179. this.$popover.hide();
  7180. }
  7181. }]);
  7182. return LinkPopover;
  7183. }();
  7184. ;// CONCATENATED MODULE: ./src/js/module/ImageDialog.js
  7185. function ImageDialog_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7186. function ImageDialog_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  7187. function ImageDialog_createClass(Constructor, protoProps, staticProps) { if (protoProps) ImageDialog_defineProperties(Constructor.prototype, protoProps); if (staticProps) ImageDialog_defineProperties(Constructor, staticProps); return Constructor; }
  7188. var ImageDialog = /*#__PURE__*/function () {
  7189. function ImageDialog(context) {
  7190. ImageDialog_classCallCheck(this, ImageDialog);
  7191. this.context = context;
  7192. this.ui = (external_jQuery_default()).summernote.ui;
  7193. this.$body = external_jQuery_default()(document.body);
  7194. this.$editor = context.layoutInfo.editor;
  7195. this.options = context.options;
  7196. this.lang = this.options.langInfo;
  7197. }
  7198. ImageDialog_createClass(ImageDialog, [{
  7199. key: "initialize",
  7200. value: function initialize() {
  7201. var imageLimitation = '';
  7202. if (this.options.maximumImageFileSize) {
  7203. var unit = Math.floor(Math.log(this.options.maximumImageFileSize) / Math.log(1024));
  7204. var readableSize = (this.options.maximumImageFileSize / Math.pow(1024, unit)).toFixed(2) * 1 + ' ' + ' KMGTP'[unit] + 'B';
  7205. imageLimitation = "<small>".concat(this.lang.image.maximumFileSize + ' : ' + readableSize, "</small>");
  7206. }
  7207. var $container = this.options.dialogsInBody ? this.$body : this.options.container;
  7208. var body = ['<div class="form-group note-form-group note-group-select-from-files">', '<label for="note-dialog-image-file-' + this.options.id + '" class="note-form-label">' + this.lang.image.selectFromFiles + '</label>', '<input id="note-dialog-image-file-' + this.options.id + '" class="note-image-input form-control-file note-form-control note-input" ', ' type="file" name="files" accept="' + this.options.acceptImageFileTypes + '" multiple="multiple"/>', imageLimitation, '</div>', '<div class="form-group note-group-image-url">', '<label for="note-dialog-image-url-' + this.options.id + '" class="note-form-label">' + this.lang.image.url + '</label>', '<input id="note-dialog-image-url-' + this.options.id + '" class="note-image-url form-control note-form-control note-input" type="text"/>', '</div>'].join('');
  7209. var buttonClass = 'btn btn-primary note-btn note-btn-primary note-image-btn';
  7210. var footer = "<input type=\"button\" href=\"#\" class=\"".concat(buttonClass, "\" value=\"").concat(this.lang.image.insert, "\" disabled>");
  7211. this.$dialog = this.ui.dialog({
  7212. title: this.lang.image.insert,
  7213. fade: this.options.dialogsFade,
  7214. body: body,
  7215. footer: footer
  7216. }).render().appendTo($container);
  7217. }
  7218. }, {
  7219. key: "destroy",
  7220. value: function destroy() {
  7221. this.ui.hideDialog(this.$dialog);
  7222. this.$dialog.remove();
  7223. }
  7224. }, {
  7225. key: "bindEnterKey",
  7226. value: function bindEnterKey($input, $btn) {
  7227. $input.on('keypress', function (event) {
  7228. if (event.keyCode === key.code.ENTER) {
  7229. event.preventDefault();
  7230. $btn.trigger('click');
  7231. }
  7232. });
  7233. }
  7234. }, {
  7235. key: "show",
  7236. value: function show() {
  7237. var _this = this;
  7238. this.context.invoke('editor.saveRange');
  7239. this.showImageDialog().then(function (data) {
  7240. // [workaround] hide dialog before restore range for IE range focus
  7241. _this.ui.hideDialog(_this.$dialog);
  7242. _this.context.invoke('editor.restoreRange');
  7243. if (typeof data === 'string') {
  7244. // image url
  7245. // If onImageLinkInsert set,
  7246. if (_this.options.callbacks.onImageLinkInsert) {
  7247. _this.context.triggerEvent('image.link.insert', data);
  7248. } else {
  7249. _this.context.invoke('editor.insertImage', data);
  7250. }
  7251. } else {
  7252. // array of files
  7253. _this.context.invoke('editor.insertImagesOrCallback', data);
  7254. }
  7255. }).fail(function () {
  7256. _this.context.invoke('editor.restoreRange');
  7257. });
  7258. }
  7259. /**
  7260. * show image dialog
  7261. *
  7262. * @param {jQuery} $dialog
  7263. * @return {Promise}
  7264. */
  7265. }, {
  7266. key: "showImageDialog",
  7267. value: function showImageDialog() {
  7268. var _this2 = this;
  7269. return external_jQuery_default().Deferred(function (deferred) {
  7270. var $imageInput = _this2.$dialog.find('.note-image-input');
  7271. var $imageUrl = _this2.$dialog.find('.note-image-url');
  7272. var $imageBtn = _this2.$dialog.find('.note-image-btn');
  7273. _this2.ui.onDialogShown(_this2.$dialog, function () {
  7274. _this2.context.triggerEvent('dialog.shown'); // Cloning imageInput to clear element.
  7275. $imageInput.replaceWith($imageInput.clone().on('change', function (event) {
  7276. deferred.resolve(event.target.files || event.target.value);
  7277. }).val(''));
  7278. $imageUrl.on('input paste propertychange', function () {
  7279. _this2.ui.toggleBtn($imageBtn, $imageUrl.val());
  7280. }).val('');
  7281. if (!env.isSupportTouch) {
  7282. $imageUrl.trigger('focus');
  7283. }
  7284. $imageBtn.click(function (event) {
  7285. event.preventDefault();
  7286. deferred.resolve($imageUrl.val());
  7287. });
  7288. _this2.bindEnterKey($imageUrl, $imageBtn);
  7289. });
  7290. _this2.ui.onDialogHidden(_this2.$dialog, function () {
  7291. $imageInput.off();
  7292. $imageUrl.off();
  7293. $imageBtn.off();
  7294. if (deferred.state() === 'pending') {
  7295. deferred.reject();
  7296. }
  7297. });
  7298. _this2.ui.showDialog(_this2.$dialog);
  7299. });
  7300. }
  7301. }]);
  7302. return ImageDialog;
  7303. }();
  7304. ;// CONCATENATED MODULE: ./src/js/module/ImagePopover.js
  7305. function ImagePopover_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7306. function ImagePopover_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  7307. function ImagePopover_createClass(Constructor, protoProps, staticProps) { if (protoProps) ImagePopover_defineProperties(Constructor.prototype, protoProps); if (staticProps) ImagePopover_defineProperties(Constructor, staticProps); return Constructor; }
  7308. /**
  7309. * Image popover module
  7310. * mouse events that show/hide popover will be handled by Handle.js.
  7311. * Handle.js will receive the events and invoke 'imagePopover.update'.
  7312. */
  7313. var ImagePopover = /*#__PURE__*/function () {
  7314. function ImagePopover(context) {
  7315. var _this = this;
  7316. ImagePopover_classCallCheck(this, ImagePopover);
  7317. this.context = context;
  7318. this.ui = (external_jQuery_default()).summernote.ui;
  7319. this.editable = context.layoutInfo.editable[0];
  7320. this.options = context.options;
  7321. this.events = {
  7322. 'summernote.disable summernote.dialog.shown': function summernoteDisableSummernoteDialogShown() {
  7323. _this.hide();
  7324. },
  7325. 'summernote.blur': function summernoteBlur(we, e) {
  7326. if (e.originalEvent && e.originalEvent.relatedTarget) {
  7327. if (!_this.$popover[0].contains(e.originalEvent.relatedTarget)) {
  7328. _this.hide();
  7329. }
  7330. } else {
  7331. _this.hide();
  7332. }
  7333. }
  7334. };
  7335. }
  7336. ImagePopover_createClass(ImagePopover, [{
  7337. key: "shouldInitialize",
  7338. value: function shouldInitialize() {
  7339. return !lists.isEmpty(this.options.popover.image);
  7340. }
  7341. }, {
  7342. key: "initialize",
  7343. value: function initialize() {
  7344. this.$popover = this.ui.popover({
  7345. className: 'note-image-popover'
  7346. }).render().appendTo(this.options.container);
  7347. var $content = this.$popover.find('.popover-content,.note-popover-content');
  7348. this.context.invoke('buttons.build', $content, this.options.popover.image);
  7349. this.$popover.on('mousedown', function (e) {
  7350. e.preventDefault();
  7351. });
  7352. }
  7353. }, {
  7354. key: "destroy",
  7355. value: function destroy() {
  7356. this.$popover.remove();
  7357. }
  7358. }, {
  7359. key: "update",
  7360. value: function update(target, event) {
  7361. if (dom.isImg(target)) {
  7362. var position = external_jQuery_default()(target).offset();
  7363. var containerOffset = external_jQuery_default()(this.options.container).offset();
  7364. var pos = {};
  7365. if (this.options.popatmouse) {
  7366. pos.left = event.pageX - 20;
  7367. pos.top = event.pageY;
  7368. } else {
  7369. pos = position;
  7370. }
  7371. pos.top -= containerOffset.top;
  7372. pos.left -= containerOffset.left;
  7373. this.$popover.css({
  7374. display: 'block',
  7375. left: pos.left,
  7376. top: pos.top
  7377. });
  7378. } else {
  7379. this.hide();
  7380. }
  7381. }
  7382. }, {
  7383. key: "hide",
  7384. value: function hide() {
  7385. this.$popover.hide();
  7386. }
  7387. }]);
  7388. return ImagePopover;
  7389. }();
  7390. ;// CONCATENATED MODULE: ./src/js/module/TablePopover.js
  7391. function TablePopover_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7392. function TablePopover_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  7393. function TablePopover_createClass(Constructor, protoProps, staticProps) { if (protoProps) TablePopover_defineProperties(Constructor.prototype, protoProps); if (staticProps) TablePopover_defineProperties(Constructor, staticProps); return Constructor; }
  7394. var TablePopover = /*#__PURE__*/function () {
  7395. function TablePopover(context) {
  7396. var _this = this;
  7397. TablePopover_classCallCheck(this, TablePopover);
  7398. this.context = context;
  7399. this.ui = (external_jQuery_default()).summernote.ui;
  7400. this.options = context.options;
  7401. this.events = {
  7402. 'summernote.mousedown': function summernoteMousedown(we, e) {
  7403. _this.update(e.target);
  7404. },
  7405. 'summernote.keyup summernote.scroll summernote.change': function summernoteKeyupSummernoteScrollSummernoteChange() {
  7406. _this.update();
  7407. },
  7408. 'summernote.disable summernote.dialog.shown': function summernoteDisableSummernoteDialogShown() {
  7409. _this.hide();
  7410. },
  7411. 'summernote.blur': function summernoteBlur(we, e) {
  7412. if (e.originalEvent && e.originalEvent.relatedTarget) {
  7413. if (!_this.$popover[0].contains(e.originalEvent.relatedTarget)) {
  7414. _this.hide();
  7415. }
  7416. } else {
  7417. _this.hide();
  7418. }
  7419. }
  7420. };
  7421. }
  7422. TablePopover_createClass(TablePopover, [{
  7423. key: "shouldInitialize",
  7424. value: function shouldInitialize() {
  7425. return !lists.isEmpty(this.options.popover.table);
  7426. }
  7427. }, {
  7428. key: "initialize",
  7429. value: function initialize() {
  7430. this.$popover = this.ui.popover({
  7431. className: 'note-table-popover'
  7432. }).render().appendTo(this.options.container);
  7433. var $content = this.$popover.find('.popover-content,.note-popover-content');
  7434. this.context.invoke('buttons.build', $content, this.options.popover.table); // [workaround] Disable Firefox's default table editor
  7435. if (env.isFF) {
  7436. document.execCommand('enableInlineTableEditing', false, false);
  7437. }
  7438. this.$popover.on('mousedown', function (e) {
  7439. e.preventDefault();
  7440. });
  7441. }
  7442. }, {
  7443. key: "destroy",
  7444. value: function destroy() {
  7445. this.$popover.remove();
  7446. }
  7447. }, {
  7448. key: "update",
  7449. value: function update(target) {
  7450. if (this.context.isDisabled()) {
  7451. return false;
  7452. }
  7453. var isCell = dom.isCell(target) || dom.isCell(target === null || target === void 0 ? void 0 : target.parentElement);
  7454. if (isCell) {
  7455. var pos = dom.posFromPlaceholder(target);
  7456. var containerOffset = external_jQuery_default()(this.options.container).offset();
  7457. pos.top -= containerOffset.top;
  7458. pos.left -= containerOffset.left;
  7459. this.$popover.css({
  7460. display: 'block',
  7461. left: pos.left,
  7462. top: pos.top
  7463. });
  7464. } else {
  7465. this.hide();
  7466. }
  7467. return isCell;
  7468. }
  7469. }, {
  7470. key: "hide",
  7471. value: function hide() {
  7472. this.$popover.hide();
  7473. }
  7474. }]);
  7475. return TablePopover;
  7476. }();
  7477. ;// CONCATENATED MODULE: ./src/js/module/VideoDialog.js
  7478. function VideoDialog_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7479. function VideoDialog_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  7480. function VideoDialog_createClass(Constructor, protoProps, staticProps) { if (protoProps) VideoDialog_defineProperties(Constructor.prototype, protoProps); if (staticProps) VideoDialog_defineProperties(Constructor, staticProps); return Constructor; }
  7481. var VideoDialog = /*#__PURE__*/function () {
  7482. function VideoDialog(context) {
  7483. VideoDialog_classCallCheck(this, VideoDialog);
  7484. this.context = context;
  7485. this.ui = (external_jQuery_default()).summernote.ui;
  7486. this.$body = external_jQuery_default()(document.body);
  7487. this.$editor = context.layoutInfo.editor;
  7488. this.options = context.options;
  7489. this.lang = this.options.langInfo;
  7490. }
  7491. VideoDialog_createClass(VideoDialog, [{
  7492. key: "initialize",
  7493. value: function initialize() {
  7494. var $container = this.options.dialogsInBody ? this.$body : this.options.container;
  7495. var body = ['<div class="form-group note-form-group row-fluid">', "<label for=\"note-dialog-video-url-".concat(this.options.id, "\" class=\"note-form-label\">").concat(this.lang.video.url, " <small class=\"text-muted\">").concat(this.lang.video.providers, "</small></label>"), "<input id=\"note-dialog-video-url-".concat(this.options.id, "\" class=\"note-video-url form-control note-form-control note-input\" type=\"text\"/>"), '</div>'].join('');
  7496. var buttonClass = 'btn btn-primary note-btn note-btn-primary note-video-btn';
  7497. var footer = "<input type=\"button\" href=\"#\" class=\"".concat(buttonClass, "\" value=\"").concat(this.lang.video.insert, "\" disabled>");
  7498. this.$dialog = this.ui.dialog({
  7499. title: this.lang.video.insert,
  7500. fade: this.options.dialogsFade,
  7501. body: body,
  7502. footer: footer
  7503. }).render().appendTo($container);
  7504. }
  7505. }, {
  7506. key: "destroy",
  7507. value: function destroy() {
  7508. this.ui.hideDialog(this.$dialog);
  7509. this.$dialog.remove();
  7510. }
  7511. }, {
  7512. key: "bindEnterKey",
  7513. value: function bindEnterKey($input, $btn) {
  7514. $input.on('keypress', function (event) {
  7515. if (event.keyCode === key.code.ENTER) {
  7516. event.preventDefault();
  7517. $btn.trigger('click');
  7518. }
  7519. });
  7520. }
  7521. }, {
  7522. key: "createVideoNode",
  7523. value: function createVideoNode(url) {
  7524. // video url patterns(youtube, instagram, vimeo, dailymotion, youku, peertube, mp4, ogg, webm)
  7525. var ytRegExp = /\/\/(?:(?:www|m)\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))([\w|-]{11})(?:(?:[\?&]t=)(\S+))?$/;
  7526. var ytRegExpForStart = /^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/;
  7527. var ytMatch = url.match(ytRegExp);
  7528. var gdRegExp = /(?:\.|\/\/)drive\.google\.com\/file\/d\/(.[a-zA-Z0-9_-]*)\/view/;
  7529. var gdMatch = url.match(gdRegExp);
  7530. var igRegExp = /(?:www\.|\/\/)instagram\.com\/p\/(.[a-zA-Z0-9_-]*)/;
  7531. var igMatch = url.match(igRegExp);
  7532. var vRegExp = /\/\/vine\.co\/v\/([a-zA-Z0-9]+)/;
  7533. var vMatch = url.match(vRegExp);
  7534. var vimRegExp = /\/\/(player\.)?vimeo\.com\/([a-z]*\/)*(\d+)[?]?.*/;
  7535. var vimMatch = url.match(vimRegExp);
  7536. var dmRegExp = /.+dailymotion.com\/(video|hub)\/([^_]+)[^#]*(#video=([^_&]+))?/;
  7537. var dmMatch = url.match(dmRegExp);
  7538. var youkuRegExp = /\/\/v\.youku\.com\/v_show\/id_(\w+)=*\.html/;
  7539. var youkuMatch = url.match(youkuRegExp);
  7540. var peerTubeRegExp = /\/\/(.*)\/videos\/watch\/([^?]*)(?:\?(?:start=(\w*))?(?:&stop=(\w*))?(?:&loop=([10]))?(?:&autoplay=([10]))?(?:&muted=([10]))?)?/;
  7541. var peerTubeMatch = url.match(peerTubeRegExp);
  7542. var qqRegExp = /\/\/v\.qq\.com.*?vid=(.+)/;
  7543. var qqMatch = url.match(qqRegExp);
  7544. var qqRegExp2 = /\/\/v\.qq\.com\/x?\/?(page|cover).*?\/([^\/]+)\.html\??.*/;
  7545. var qqMatch2 = url.match(qqRegExp2);
  7546. var mp4RegExp = /^.+.(mp4|m4v)$/;
  7547. var mp4Match = url.match(mp4RegExp);
  7548. var oggRegExp = /^.+.(ogg|ogv)$/;
  7549. var oggMatch = url.match(oggRegExp);
  7550. var webmRegExp = /^.+.(webm)$/;
  7551. var webmMatch = url.match(webmRegExp);
  7552. var fbRegExp = /(?:www\.|\/\/)facebook\.com\/([^\/]+)\/videos\/([0-9]+)/;
  7553. var fbMatch = url.match(fbRegExp);
  7554. var $video;
  7555. if (ytMatch && ytMatch[1].length === 11) {
  7556. var youtubeId = ytMatch[1];
  7557. var start = 0;
  7558. if (typeof ytMatch[2] !== 'undefined') {
  7559. var ytMatchForStart = ytMatch[2].match(ytRegExpForStart);
  7560. if (ytMatchForStart) {
  7561. for (var n = [3600, 60, 1], i = 0, r = n.length; i < r; i++) {
  7562. start += typeof ytMatchForStart[i + 1] !== 'undefined' ? n[i] * parseInt(ytMatchForStart[i + 1], 10) : 0;
  7563. }
  7564. }
  7565. }
  7566. $video = external_jQuery_default()('<iframe>').attr('frameborder', 0).attr('src', '//www.youtube.com/embed/' + youtubeId + (start > 0 ? '?start=' + start : '')).attr('width', '640').attr('height', '360');
  7567. } else if (gdMatch && gdMatch[0].length) {
  7568. $video = external_jQuery_default()('<iframe>').attr('frameborder', 0).attr('src', 'https://drive.google.com/file/d/' + gdMatch[1] + '/preview').attr('width', '640').attr('height', '480');
  7569. } else if (igMatch && igMatch[0].length) {
  7570. $video = external_jQuery_default()('<iframe>').attr('frameborder', 0).attr('src', 'https://instagram.com/p/' + igMatch[1] + '/embed/').attr('width', '612').attr('height', '710').attr('scrolling', 'no').attr('allowtransparency', 'true');
  7571. } else if (vMatch && vMatch[0].length) {
  7572. $video = external_jQuery_default()('<iframe>').attr('frameborder', 0).attr('src', vMatch[0] + '/embed/simple').attr('width', '600').attr('height', '600').attr('class', 'vine-embed');
  7573. } else if (vimMatch && vimMatch[3].length) {
  7574. $video = external_jQuery_default()('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen>').attr('frameborder', 0).attr('src', '//player.vimeo.com/video/' + vimMatch[3]).attr('width', '640').attr('height', '360');
  7575. } else if (dmMatch && dmMatch[2].length) {
  7576. $video = external_jQuery_default()('<iframe>').attr('frameborder', 0).attr('src', '//www.dailymotion.com/embed/video/' + dmMatch[2]).attr('width', '640').attr('height', '360');
  7577. } else if (youkuMatch && youkuMatch[1].length) {
  7578. $video = external_jQuery_default()('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen>').attr('frameborder', 0).attr('height', '498').attr('width', '510').attr('src', '//player.youku.com/embed/' + youkuMatch[1]);
  7579. } else if (peerTubeMatch && peerTubeMatch[0].length) {
  7580. var begin = 0;
  7581. if (peerTubeMatch[2] !== 'undefined') begin = peerTubeMatch[2];
  7582. var end = 0;
  7583. if (peerTubeMatch[3] !== 'undefined') end = peerTubeMatch[3];
  7584. var loop = 0;
  7585. if (peerTubeMatch[4] !== 'undefined') loop = peerTubeMatch[4];
  7586. var autoplay = 0;
  7587. if (peerTubeMatch[5] !== 'undefined') autoplay = peerTubeMatch[5];
  7588. var muted = 0;
  7589. if (peerTubeMatch[6] !== 'undefined') muted = peerTubeMatch[6];
  7590. $video = external_jQuery_default()('<iframe allowfullscreen sandbox="allow-same-origin allow-scripts allow-popups">').attr('frameborder', 0).attr('src', '//' + peerTubeMatch[1] + '/videos/embed/' + peerTubeMatch[2] + "?loop=" + loop + "&autoplay=" + autoplay + "&muted=" + muted + (begin > 0 ? '&start=' + begin : '') + (end > 0 ? '&end=' + start : '')).attr('width', '560').attr('height', '315');
  7591. } else if (qqMatch && qqMatch[1].length || qqMatch2 && qqMatch2[2].length) {
  7592. var vid = qqMatch && qqMatch[1].length ? qqMatch[1] : qqMatch2[2];
  7593. $video = external_jQuery_default()('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen>').attr('frameborder', 0).attr('height', '310').attr('width', '500').attr('src', 'https://v.qq.com/txp/iframe/player.html?vid=' + vid + '&amp;auto=0');
  7594. } else if (mp4Match || oggMatch || webmMatch) {
  7595. $video = external_jQuery_default()('<video controls>').attr('src', url).attr('width', '640').attr('height', '360');
  7596. } else if (fbMatch && fbMatch[0].length) {
  7597. $video = external_jQuery_default()('<iframe>').attr('frameborder', 0).attr('src', 'https://www.facebook.com/plugins/video.php?href=' + encodeURIComponent(fbMatch[0]) + '&show_text=0&width=560').attr('width', '560').attr('height', '301').attr('scrolling', 'no').attr('allowtransparency', 'true');
  7598. } else {
  7599. // this is not a known video link. Now what, Cat? Now what?
  7600. return false;
  7601. }
  7602. $video.addClass('note-video-clip');
  7603. return $video[0];
  7604. }
  7605. }, {
  7606. key: "show",
  7607. value: function show() {
  7608. var _this = this;
  7609. var text = this.context.invoke('editor.getSelectedText');
  7610. this.context.invoke('editor.saveRange');
  7611. this.showVideoDialog(text).then(function (url) {
  7612. // [workaround] hide dialog before restore range for IE range focus
  7613. _this.ui.hideDialog(_this.$dialog);
  7614. _this.context.invoke('editor.restoreRange'); // build node
  7615. var $node = _this.createVideoNode(url);
  7616. if ($node) {
  7617. // insert video node
  7618. _this.context.invoke('editor.insertNode', $node);
  7619. }
  7620. }).fail(function () {
  7621. _this.context.invoke('editor.restoreRange');
  7622. });
  7623. }
  7624. /**
  7625. * show video dialog
  7626. *
  7627. * @param {jQuery} $dialog
  7628. * @return {Promise}
  7629. */
  7630. }, {
  7631. key: "showVideoDialog",
  7632. value: function showVideoDialog() {
  7633. var _this2 = this;
  7634. return external_jQuery_default().Deferred(function (deferred) {
  7635. var $videoUrl = _this2.$dialog.find('.note-video-url');
  7636. var $videoBtn = _this2.$dialog.find('.note-video-btn');
  7637. _this2.ui.onDialogShown(_this2.$dialog, function () {
  7638. _this2.context.triggerEvent('dialog.shown');
  7639. $videoUrl.on('input paste propertychange', function () {
  7640. _this2.ui.toggleBtn($videoBtn, $videoUrl.val());
  7641. });
  7642. if (!env.isSupportTouch) {
  7643. $videoUrl.trigger('focus');
  7644. }
  7645. $videoBtn.click(function (event) {
  7646. event.preventDefault();
  7647. deferred.resolve($videoUrl.val());
  7648. });
  7649. _this2.bindEnterKey($videoUrl, $videoBtn);
  7650. });
  7651. _this2.ui.onDialogHidden(_this2.$dialog, function () {
  7652. $videoUrl.off();
  7653. $videoBtn.off();
  7654. if (deferred.state() === 'pending') {
  7655. deferred.reject();
  7656. }
  7657. });
  7658. _this2.ui.showDialog(_this2.$dialog);
  7659. });
  7660. }
  7661. }]);
  7662. return VideoDialog;
  7663. }();
  7664. ;// CONCATENATED MODULE: ./src/js/module/HelpDialog.js
  7665. function HelpDialog_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7666. function HelpDialog_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  7667. function HelpDialog_createClass(Constructor, protoProps, staticProps) { if (protoProps) HelpDialog_defineProperties(Constructor.prototype, protoProps); if (staticProps) HelpDialog_defineProperties(Constructor, staticProps); return Constructor; }
  7668. var HelpDialog = /*#__PURE__*/function () {
  7669. function HelpDialog(context) {
  7670. HelpDialog_classCallCheck(this, HelpDialog);
  7671. this.context = context;
  7672. this.ui = (external_jQuery_default()).summernote.ui;
  7673. this.$body = external_jQuery_default()(document.body);
  7674. this.$editor = context.layoutInfo.editor;
  7675. this.options = context.options;
  7676. this.lang = this.options.langInfo;
  7677. }
  7678. HelpDialog_createClass(HelpDialog, [{
  7679. key: "initialize",
  7680. value: function initialize() {
  7681. var $container = this.options.dialogsInBody ? this.$body : this.options.container;
  7682. var body = ['<p class="text-center">', '<a href="http://summernote.org/" target="_blank" rel="noopener noreferrer">Summernote 0.8.20</a> · ', '<a href="https://github.com/summernote/summernote" target="_blank" rel="noopener noreferrer">Project</a> · ', '<a href="https://github.com/summernote/summernote/issues" target="_blank" rel="noopener noreferrer">Issues</a>', '</p>'].join('');
  7683. this.$dialog = this.ui.dialog({
  7684. title: this.lang.options.help,
  7685. fade: this.options.dialogsFade,
  7686. body: this.createShortcutList(),
  7687. footer: body,
  7688. callback: function callback($node) {
  7689. $node.find('.modal-body,.note-modal-body').css({
  7690. 'max-height': 300,
  7691. 'overflow': 'scroll'
  7692. });
  7693. }
  7694. }).render().appendTo($container);
  7695. }
  7696. }, {
  7697. key: "destroy",
  7698. value: function destroy() {
  7699. this.ui.hideDialog(this.$dialog);
  7700. this.$dialog.remove();
  7701. }
  7702. }, {
  7703. key: "createShortcutList",
  7704. value: function createShortcutList() {
  7705. var _this = this;
  7706. var keyMap = this.options.keyMap[env.isMac ? 'mac' : 'pc'];
  7707. return Object.keys(keyMap).map(function (key) {
  7708. var command = keyMap[key];
  7709. var $row = external_jQuery_default()('<div><div class="help-list-item"></div></div>');
  7710. $row.append(external_jQuery_default()('<label><kbd>' + key + '</kdb></label>').css({
  7711. 'width': 180,
  7712. 'margin-right': 10
  7713. })).append(external_jQuery_default()('<span></span>').html(_this.context.memo('help.' + command) || command));
  7714. return $row.html();
  7715. }).join('');
  7716. }
  7717. /**
  7718. * show help dialog
  7719. *
  7720. * @return {Promise}
  7721. */
  7722. }, {
  7723. key: "showHelpDialog",
  7724. value: function showHelpDialog() {
  7725. var _this2 = this;
  7726. return external_jQuery_default().Deferred(function (deferred) {
  7727. _this2.ui.onDialogShown(_this2.$dialog, function () {
  7728. _this2.context.triggerEvent('dialog.shown');
  7729. deferred.resolve();
  7730. });
  7731. _this2.ui.showDialog(_this2.$dialog);
  7732. }).promise();
  7733. }
  7734. }, {
  7735. key: "show",
  7736. value: function show() {
  7737. var _this3 = this;
  7738. this.context.invoke('editor.saveRange');
  7739. this.showHelpDialog().then(function () {
  7740. _this3.context.invoke('editor.restoreRange');
  7741. });
  7742. }
  7743. }]);
  7744. return HelpDialog;
  7745. }();
  7746. ;// CONCATENATED MODULE: ./src/js/module/AirPopover.js
  7747. function AirPopover_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7748. function AirPopover_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  7749. function AirPopover_createClass(Constructor, protoProps, staticProps) { if (protoProps) AirPopover_defineProperties(Constructor.prototype, protoProps); if (staticProps) AirPopover_defineProperties(Constructor, staticProps); return Constructor; }
  7750. var AIRMODE_POPOVER_X_OFFSET = -5;
  7751. var AIRMODE_POPOVER_Y_OFFSET = 5;
  7752. var AirPopover = /*#__PURE__*/function () {
  7753. function AirPopover(context) {
  7754. var _this = this;
  7755. AirPopover_classCallCheck(this, AirPopover);
  7756. this.context = context;
  7757. this.ui = (external_jQuery_default()).summernote.ui;
  7758. this.options = context.options;
  7759. this.hidable = true;
  7760. this.onContextmenu = false;
  7761. this.pageX = null;
  7762. this.pageY = null;
  7763. this.events = {
  7764. 'summernote.contextmenu': function summernoteContextmenu(e) {
  7765. if (_this.options.editing) {
  7766. e.preventDefault();
  7767. e.stopPropagation();
  7768. _this.onContextmenu = true;
  7769. _this.update(true);
  7770. }
  7771. },
  7772. 'summernote.mousedown': function summernoteMousedown(we, e) {
  7773. _this.pageX = e.pageX;
  7774. _this.pageY = e.pageY;
  7775. },
  7776. 'summernote.keyup summernote.mouseup summernote.scroll': function summernoteKeyupSummernoteMouseupSummernoteScroll(we, e) {
  7777. if (_this.options.editing && !_this.onContextmenu) {
  7778. _this.pageX = e.pageX;
  7779. _this.pageY = e.pageY;
  7780. _this.update();
  7781. }
  7782. _this.onContextmenu = false;
  7783. },
  7784. 'summernote.disable summernote.change summernote.dialog.shown summernote.blur': function summernoteDisableSummernoteChangeSummernoteDialogShownSummernoteBlur() {
  7785. _this.hide();
  7786. },
  7787. 'summernote.focusout': function summernoteFocusout() {
  7788. if (!_this.$popover.is(':active,:focus')) {
  7789. _this.hide();
  7790. }
  7791. }
  7792. };
  7793. }
  7794. AirPopover_createClass(AirPopover, [{
  7795. key: "shouldInitialize",
  7796. value: function shouldInitialize() {
  7797. return this.options.airMode && !lists.isEmpty(this.options.popover.air);
  7798. }
  7799. }, {
  7800. key: "initialize",
  7801. value: function initialize() {
  7802. var _this2 = this;
  7803. this.$popover = this.ui.popover({
  7804. className: 'note-air-popover'
  7805. }).render().appendTo(this.options.container);
  7806. var $content = this.$popover.find('.popover-content');
  7807. this.context.invoke('buttons.build', $content, this.options.popover.air); // disable hiding this popover preemptively by 'summernote.blur' event.
  7808. this.$popover.on('mousedown', function () {
  7809. _this2.hidable = false;
  7810. }); // (re-)enable hiding after 'summernote.blur' has been handled (aka. ignored).
  7811. this.$popover.on('mouseup', function () {
  7812. _this2.hidable = true;
  7813. });
  7814. }
  7815. }, {
  7816. key: "destroy",
  7817. value: function destroy() {
  7818. this.$popover.remove();
  7819. }
  7820. }, {
  7821. key: "update",
  7822. value: function update(forcelyOpen) {
  7823. var styleInfo = this.context.invoke('editor.currentStyle');
  7824. if (styleInfo.range && (!styleInfo.range.isCollapsed() || forcelyOpen)) {
  7825. var rect = {
  7826. left: this.pageX,
  7827. top: this.pageY
  7828. };
  7829. var containerOffset = external_jQuery_default()(this.options.container).offset();
  7830. rect.top -= containerOffset.top;
  7831. rect.left -= containerOffset.left;
  7832. this.$popover.css({
  7833. display: 'block',
  7834. left: Math.max(rect.left, 0) + AIRMODE_POPOVER_X_OFFSET,
  7835. top: rect.top + AIRMODE_POPOVER_Y_OFFSET
  7836. });
  7837. this.context.invoke('buttons.updateCurrentStyle', this.$popover);
  7838. } else {
  7839. this.hide();
  7840. }
  7841. }
  7842. }, {
  7843. key: "updateCodeview",
  7844. value: function updateCodeview(isCodeview) {
  7845. this.ui.toggleBtnActive(this.$popover.find('.btn-codeview'), isCodeview);
  7846. if (isCodeview) {
  7847. this.hide();
  7848. }
  7849. }
  7850. }, {
  7851. key: "hide",
  7852. value: function hide() {
  7853. if (this.hidable) {
  7854. this.$popover.hide();
  7855. }
  7856. }
  7857. }]);
  7858. return AirPopover;
  7859. }();
  7860. ;// CONCATENATED MODULE: ./src/js/module/HintPopover.js
  7861. function HintPopover_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7862. function HintPopover_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  7863. function HintPopover_createClass(Constructor, protoProps, staticProps) { if (protoProps) HintPopover_defineProperties(Constructor.prototype, protoProps); if (staticProps) HintPopover_defineProperties(Constructor, staticProps); return Constructor; }
  7864. var POPOVER_DIST = 5;
  7865. var HintPopover = /*#__PURE__*/function () {
  7866. function HintPopover(context) {
  7867. var _this = this;
  7868. HintPopover_classCallCheck(this, HintPopover);
  7869. this.context = context;
  7870. this.ui = (external_jQuery_default()).summernote.ui;
  7871. this.$editable = context.layoutInfo.editable;
  7872. this.options = context.options;
  7873. this.hint = this.options.hint || [];
  7874. this.direction = this.options.hintDirection || 'bottom';
  7875. this.hints = Array.isArray(this.hint) ? this.hint : [this.hint];
  7876. this.events = {
  7877. 'summernote.keyup': function summernoteKeyup(we, e) {
  7878. if (!e.isDefaultPrevented()) {
  7879. _this.handleKeyup(e);
  7880. }
  7881. },
  7882. 'summernote.keydown': function summernoteKeydown(we, e) {
  7883. _this.handleKeydown(e);
  7884. },
  7885. 'summernote.disable summernote.dialog.shown summernote.blur': function summernoteDisableSummernoteDialogShownSummernoteBlur() {
  7886. _this.hide();
  7887. }
  7888. };
  7889. }
  7890. HintPopover_createClass(HintPopover, [{
  7891. key: "shouldInitialize",
  7892. value: function shouldInitialize() {
  7893. return this.hints.length > 0;
  7894. }
  7895. }, {
  7896. key: "initialize",
  7897. value: function initialize() {
  7898. var _this2 = this;
  7899. this.lastWordRange = null;
  7900. this.matchingWord = null;
  7901. this.$popover = this.ui.popover({
  7902. className: 'note-hint-popover',
  7903. hideArrow: true,
  7904. direction: ''
  7905. }).render().appendTo(this.options.container);
  7906. this.$popover.hide();
  7907. this.$content = this.$popover.find('.popover-content,.note-popover-content');
  7908. this.$content.on('click', '.note-hint-item', function (e) {
  7909. _this2.$content.find('.active').removeClass('active');
  7910. external_jQuery_default()(e.currentTarget).addClass('active');
  7911. _this2.replace();
  7912. });
  7913. this.$popover.on('mousedown', function (e) {
  7914. e.preventDefault();
  7915. });
  7916. }
  7917. }, {
  7918. key: "destroy",
  7919. value: function destroy() {
  7920. this.$popover.remove();
  7921. }
  7922. }, {
  7923. key: "selectItem",
  7924. value: function selectItem($item) {
  7925. this.$content.find('.active').removeClass('active');
  7926. $item.addClass('active');
  7927. this.$content[0].scrollTop = $item[0].offsetTop - this.$content.innerHeight() / 2;
  7928. }
  7929. }, {
  7930. key: "moveDown",
  7931. value: function moveDown() {
  7932. var $current = this.$content.find('.note-hint-item.active');
  7933. var $next = $current.next();
  7934. if ($next.length) {
  7935. this.selectItem($next);
  7936. } else {
  7937. var $nextGroup = $current.parent().next();
  7938. if (!$nextGroup.length) {
  7939. $nextGroup = this.$content.find('.note-hint-group').first();
  7940. }
  7941. this.selectItem($nextGroup.find('.note-hint-item').first());
  7942. }
  7943. }
  7944. }, {
  7945. key: "moveUp",
  7946. value: function moveUp() {
  7947. var $current = this.$content.find('.note-hint-item.active');
  7948. var $prev = $current.prev();
  7949. if ($prev.length) {
  7950. this.selectItem($prev);
  7951. } else {
  7952. var $prevGroup = $current.parent().prev();
  7953. if (!$prevGroup.length) {
  7954. $prevGroup = this.$content.find('.note-hint-group').last();
  7955. }
  7956. this.selectItem($prevGroup.find('.note-hint-item').last());
  7957. }
  7958. }
  7959. }, {
  7960. key: "replace",
  7961. value: function replace() {
  7962. var $item = this.$content.find('.note-hint-item.active');
  7963. if ($item.length) {
  7964. var node = this.nodeFromItem($item); // If matchingWord length = 0 -> capture OK / open hint / but as mention capture "" (\w*)
  7965. if (this.matchingWord !== null && this.matchingWord.length === 0) {
  7966. this.lastWordRange.so = this.lastWordRange.eo; // Else si > 0 and normal case -> adjust range "before" for correct position of insertion
  7967. } else if (this.matchingWord !== null && this.matchingWord.length > 0 && !this.lastWordRange.isCollapsed()) {
  7968. var rangeCompute = this.lastWordRange.eo - this.lastWordRange.so - this.matchingWord.length;
  7969. if (rangeCompute > 0) {
  7970. this.lastWordRange.so += rangeCompute;
  7971. }
  7972. }
  7973. this.lastWordRange.insertNode(node);
  7974. if (this.options.hintSelect === 'next') {
  7975. var blank = document.createTextNode('');
  7976. external_jQuery_default()(node).after(blank);
  7977. range.createFromNodeBefore(blank).select();
  7978. } else {
  7979. range.createFromNodeAfter(node).select();
  7980. }
  7981. this.lastWordRange = null;
  7982. this.hide();
  7983. this.context.invoke('editor.focus');
  7984. this.context.triggerEvent('change', this.$editable.html(), this.$editable);
  7985. }
  7986. }
  7987. }, {
  7988. key: "nodeFromItem",
  7989. value: function nodeFromItem($item) {
  7990. var hint = this.hints[$item.data('index')];
  7991. var item = $item.data('item');
  7992. var node = hint.content ? hint.content(item) : item;
  7993. if (typeof node === 'string') {
  7994. node = dom.createText(node);
  7995. }
  7996. return node;
  7997. }
  7998. }, {
  7999. key: "createItemTemplates",
  8000. value: function createItemTemplates(hintIdx, items) {
  8001. var hint = this.hints[hintIdx];
  8002. return items.map(function (item
  8003. /*, idx */
  8004. ) {
  8005. var $item = external_jQuery_default()('<div class="note-hint-item"></div>');
  8006. $item.append(hint.template ? hint.template(item) : item + '');
  8007. $item.data({
  8008. 'index': hintIdx,
  8009. 'item': item
  8010. });
  8011. return $item;
  8012. });
  8013. }
  8014. }, {
  8015. key: "handleKeydown",
  8016. value: function handleKeydown(e) {
  8017. if (!this.$popover.is(':visible')) {
  8018. return;
  8019. }
  8020. if (e.keyCode === key.code.ENTER) {
  8021. e.preventDefault();
  8022. this.replace();
  8023. } else if (e.keyCode === key.code.UP) {
  8024. e.preventDefault();
  8025. this.moveUp();
  8026. } else if (e.keyCode === key.code.DOWN) {
  8027. e.preventDefault();
  8028. this.moveDown();
  8029. }
  8030. }
  8031. }, {
  8032. key: "searchKeyword",
  8033. value: function searchKeyword(index, keyword, callback) {
  8034. var hint = this.hints[index];
  8035. if (hint && hint.match.test(keyword) && hint.search) {
  8036. var matches = hint.match.exec(keyword);
  8037. this.matchingWord = matches[0];
  8038. hint.search(matches[1], callback);
  8039. } else {
  8040. callback();
  8041. }
  8042. }
  8043. }, {
  8044. key: "createGroup",
  8045. value: function createGroup(idx, keyword) {
  8046. var _this3 = this;
  8047. var $group = external_jQuery_default()('<div class="note-hint-group note-hint-group-' + idx + '"></div>');
  8048. this.searchKeyword(idx, keyword, function (items) {
  8049. items = items || [];
  8050. if (items.length) {
  8051. $group.html(_this3.createItemTemplates(idx, items));
  8052. _this3.show();
  8053. }
  8054. });
  8055. return $group;
  8056. }
  8057. }, {
  8058. key: "handleKeyup",
  8059. value: function handleKeyup(e) {
  8060. var _this4 = this;
  8061. if (!lists.contains([key.code.ENTER, key.code.UP, key.code.DOWN], e.keyCode)) {
  8062. var _range = this.context.invoke('editor.getLastRange');
  8063. var wordRange, keyword;
  8064. if (this.options.hintMode === 'words') {
  8065. wordRange = _range.getWordsRange(_range);
  8066. keyword = wordRange.toString();
  8067. this.hints.forEach(function (hint) {
  8068. if (hint.match.test(keyword)) {
  8069. wordRange = _range.getWordsMatchRange(hint.match);
  8070. return false;
  8071. }
  8072. });
  8073. if (!wordRange) {
  8074. this.hide();
  8075. return;
  8076. }
  8077. keyword = wordRange.toString();
  8078. } else {
  8079. wordRange = _range.getWordRange();
  8080. keyword = wordRange.toString();
  8081. }
  8082. if (this.hints.length && keyword) {
  8083. this.$content.empty();
  8084. var bnd = func.rect2bnd(lists.last(wordRange.getClientRects()));
  8085. var containerOffset = external_jQuery_default()(this.options.container).offset();
  8086. if (bnd) {
  8087. bnd.top -= containerOffset.top;
  8088. bnd.left -= containerOffset.left;
  8089. this.$popover.hide();
  8090. this.lastWordRange = wordRange;
  8091. this.hints.forEach(function (hint, idx) {
  8092. if (hint.match.test(keyword)) {
  8093. _this4.createGroup(idx, keyword).appendTo(_this4.$content);
  8094. }
  8095. }); // select first .note-hint-item
  8096. this.$content.find('.note-hint-item:first').addClass('active'); // set position for popover after group is created
  8097. if (this.direction === 'top') {
  8098. this.$popover.css({
  8099. left: bnd.left,
  8100. top: bnd.top - this.$popover.outerHeight() - POPOVER_DIST
  8101. });
  8102. } else {
  8103. this.$popover.css({
  8104. left: bnd.left,
  8105. top: bnd.top + bnd.height + POPOVER_DIST
  8106. });
  8107. }
  8108. }
  8109. } else {
  8110. this.hide();
  8111. }
  8112. }
  8113. }
  8114. }, {
  8115. key: "show",
  8116. value: function show() {
  8117. this.$popover.show();
  8118. }
  8119. }, {
  8120. key: "hide",
  8121. value: function hide() {
  8122. this.$popover.hide();
  8123. }
  8124. }]);
  8125. return HintPopover;
  8126. }();
  8127. ;// CONCATENATED MODULE: ./src/js/settings.js
  8128. (external_jQuery_default()).summernote = external_jQuery_default().extend((external_jQuery_default()).summernote, {
  8129. version: '0.8.20',
  8130. plugins: {},
  8131. dom: dom,
  8132. range: range,
  8133. lists: lists,
  8134. options: {
  8135. langInfo: (external_jQuery_default()).summernote.lang["en-US"],
  8136. editing: true,
  8137. modules: {
  8138. 'editor': Editor,
  8139. 'clipboard': Clipboard,
  8140. 'dropzone': Dropzone,
  8141. 'codeview': CodeView,
  8142. 'statusbar': Statusbar,
  8143. 'fullscreen': Fullscreen,
  8144. 'handle': Handle,
  8145. // FIXME: HintPopover must be front of autolink
  8146. // - Script error about range when Enter key is pressed on hint popover
  8147. 'hintPopover': HintPopover,
  8148. 'autoLink': AutoLink,
  8149. 'autoSync': AutoSync,
  8150. 'autoReplace': AutoReplace,
  8151. 'placeholder': Placeholder,
  8152. 'buttons': Buttons,
  8153. 'toolbar': Toolbar,
  8154. 'linkDialog': LinkDialog,
  8155. 'linkPopover': LinkPopover,
  8156. 'imageDialog': ImageDialog,
  8157. 'imagePopover': ImagePopover,
  8158. 'tablePopover': TablePopover,
  8159. 'videoDialog': VideoDialog,
  8160. 'helpDialog': HelpDialog,
  8161. 'airPopover': AirPopover
  8162. },
  8163. buttons: {},
  8164. lang: 'en-US',
  8165. followingToolbar: false,
  8166. toolbarPosition: 'top',
  8167. otherStaticBar: '',
  8168. // toolbar
  8169. codeviewKeepButton: false,
  8170. toolbar: [['style', ['style']], ['font', ['bold', 'underline', 'clear']], ['fontname', ['fontname']], ['color', ['color']], ['para', ['ul', 'ol', 'paragraph']], ['table', ['table']], ['insert', ['link', 'picture', 'video']], ['view', ['fullscreen', 'codeview', 'help']]],
  8171. // popover
  8172. popatmouse: true,
  8173. popover: {
  8174. image: [['resize', ['resizeFull', 'resizeHalf', 'resizeQuarter', 'resizeNone']], ['float', ['floatLeft', 'floatRight', 'floatNone']], ['remove', ['removeMedia']]],
  8175. link: [['link', ['linkDialogShow', 'unlink']]],
  8176. table: [['add', ['addRowDown', 'addRowUp', 'addColLeft', 'addColRight']], ['delete', ['deleteRow', 'deleteCol', 'deleteTable']]],
  8177. air: [['color', ['color']], ['font', ['bold', 'underline', 'clear']], ['para', ['ul', 'paragraph']], ['table', ['table']], ['insert', ['link', 'picture']], ['view', ['fullscreen', 'codeview']]]
  8178. },
  8179. // air mode: inline editor
  8180. airMode: false,
  8181. overrideContextMenu: false,
  8182. // TBD
  8183. width: null,
  8184. height: null,
  8185. linkTargetBlank: true,
  8186. useProtocol: true,
  8187. defaultProtocol: 'http://',
  8188. focus: false,
  8189. tabDisabled: false,
  8190. tabSize: 4,
  8191. styleWithCSS: false,
  8192. shortcuts: true,
  8193. textareaAutoSync: true,
  8194. tooltip: 'auto',
  8195. container: null,
  8196. maxTextLength: 0,
  8197. blockquoteBreakingLevel: 2,
  8198. spellCheck: true,
  8199. disableGrammar: false,
  8200. placeholder: null,
  8201. inheritPlaceholder: false,
  8202. // TODO: need to be documented
  8203. recordEveryKeystroke: false,
  8204. historyLimit: 200,
  8205. // TODO: need to be documented
  8206. showDomainOnlyForAutolink: false,
  8207. // TODO: need to be documented
  8208. hintMode: 'word',
  8209. hintSelect: 'after',
  8210. hintDirection: 'bottom',
  8211. styleTags: ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
  8212. fontNames: ['Arial', 'Arial Black', 'Comic Sans MS', 'Courier New', 'Helvetica Neue', 'Helvetica', 'Impact', 'Lucida Grande', 'Tahoma', 'Times New Roman', 'Verdana'],
  8213. fontNamesIgnoreCheck: [],
  8214. addDefaultFonts: true,
  8215. fontSizes: ['8', '9', '10', '11', '12', '14', '18', '24', '36'],
  8216. fontSizeUnits: ['px', 'pt'],
  8217. // pallete colors(n x n)
  8218. colors: [['#000000', '#424242', '#636363', '#9C9C94', '#CEC6CE', '#EFEFEF', '#F7F7F7', '#FFFFFF'], ['#FF0000', '#FF9C00', '#FFFF00', '#00FF00', '#00FFFF', '#0000FF', '#9C00FF', '#FF00FF'], ['#F7C6CE', '#FFE7CE', '#FFEFC6', '#D6EFD6', '#CEDEE7', '#CEE7F7', '#D6D6E7', '#E7D6DE'], ['#E79C9C', '#FFC69C', '#FFE79C', '#B5D6A5', '#A5C6CE', '#9CC6EF', '#B5A5D6', '#D6A5BD'], ['#E76363', '#F7AD6B', '#FFD663', '#94BD7B', '#73A5AD', '#6BADDE', '#8C7BC6', '#C67BA5'], ['#CE0000', '#E79439', '#EFC631', '#6BA54A', '#4A7B8C', '#3984C6', '#634AA5', '#A54A7B'], ['#9C0000', '#B56308', '#BD9400', '#397B21', '#104A5A', '#085294', '#311873', '#731842'], ['#630000', '#7B3900', '#846300', '#295218', '#083139', '#003163', '#21104A', '#4A1031']],
  8219. // http://chir.ag/projects/name-that-color/
  8220. colorsName: [['Black', 'Tundora', 'Dove Gray', 'Star Dust', 'Pale Slate', 'Gallery', 'Alabaster', 'White'], ['Red', 'Orange Peel', 'Yellow', 'Green', 'Cyan', 'Blue', 'Electric Violet', 'Magenta'], ['Azalea', 'Karry', 'Egg White', 'Zanah', 'Botticelli', 'Tropical Blue', 'Mischka', 'Twilight'], ['Tonys Pink', 'Peach Orange', 'Cream Brulee', 'Sprout', 'Casper', 'Perano', 'Cold Purple', 'Careys Pink'], ['Mandy', 'Rajah', 'Dandelion', 'Olivine', 'Gulf Stream', 'Viking', 'Blue Marguerite', 'Puce'], ['Guardsman Red', 'Fire Bush', 'Golden Dream', 'Chelsea Cucumber', 'Smalt Blue', 'Boston Blue', 'Butterfly Bush', 'Cadillac'], ['Sangria', 'Mai Tai', 'Buddha Gold', 'Forest Green', 'Eden', 'Venice Blue', 'Meteorite', 'Claret'], ['Rosewood', 'Cinnamon', 'Olive', 'Parsley', 'Tiber', 'Midnight Blue', 'Valentino', 'Loulou']],
  8221. colorButton: {
  8222. foreColor: '#000000',
  8223. backColor: '#FFFF00'
  8224. },
  8225. lineHeights: ['1.0', '1.2', '1.4', '1.5', '1.6', '1.8', '2.0', '3.0'],
  8226. tableClassName: 'table table-bordered',
  8227. insertTableMaxSize: {
  8228. col: 10,
  8229. row: 10
  8230. },
  8231. // By default, dialogs are attached in container.
  8232. dialogsInBody: false,
  8233. dialogsFade: false,
  8234. maximumImageFileSize: null,
  8235. acceptImageFileTypes: "image/*",
  8236. callbacks: {
  8237. onBeforeCommand: null,
  8238. onBlur: null,
  8239. onBlurCodeview: null,
  8240. onChange: null,
  8241. onChangeCodeview: null,
  8242. onDialogShown: null,
  8243. onEnter: null,
  8244. onFocus: null,
  8245. onImageLinkInsert: null,
  8246. onImageUpload: null,
  8247. onImageUploadError: null,
  8248. onInit: null,
  8249. onKeydown: null,
  8250. onKeyup: null,
  8251. onMousedown: null,
  8252. onMouseup: null,
  8253. onPaste: null,
  8254. onScroll: null
  8255. },
  8256. codemirror: {
  8257. mode: 'text/html',
  8258. htmlMode: true,
  8259. lineNumbers: true
  8260. },
  8261. codeviewFilter: true,
  8262. codeviewFilterRegex: /<\/*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|ilayer|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|t(?:itle|extarea)|xml)[^>]*?>/gi,
  8263. codeviewIframeFilter: true,
  8264. codeviewIframeWhitelistSrc: [],
  8265. codeviewIframeWhitelistSrcBase: ['www.youtube.com', 'www.youtube-nocookie.com', 'www.facebook.com', 'vine.co', 'instagram.com', 'player.vimeo.com', 'www.dailymotion.com', 'player.youku.com', 'jumpingbean.tv', 'v.qq.com'],
  8266. keyMap: {
  8267. pc: {
  8268. 'ESC': 'escape',
  8269. 'ENTER': 'insertParagraph',
  8270. 'CTRL+Z': 'undo',
  8271. 'CTRL+Y': 'redo',
  8272. 'TAB': 'tab',
  8273. 'SHIFT+TAB': 'untab',
  8274. 'CTRL+B': 'bold',
  8275. 'CTRL+I': 'italic',
  8276. 'CTRL+U': 'underline',
  8277. 'CTRL+SHIFT+S': 'strikethrough',
  8278. 'CTRL+BACKSLASH': 'removeFormat',
  8279. 'CTRL+SHIFT+L': 'justifyLeft',
  8280. 'CTRL+SHIFT+E': 'justifyCenter',
  8281. 'CTRL+SHIFT+R': 'justifyRight',
  8282. 'CTRL+SHIFT+J': 'justifyFull',
  8283. 'CTRL+SHIFT+NUM7': 'insertUnorderedList',
  8284. 'CTRL+SHIFT+NUM8': 'insertOrderedList',
  8285. 'CTRL+LEFTBRACKET': 'outdent',
  8286. 'CTRL+RIGHTBRACKET': 'indent',
  8287. 'CTRL+NUM0': 'formatPara',
  8288. 'CTRL+NUM1': 'formatH1',
  8289. 'CTRL+NUM2': 'formatH2',
  8290. 'CTRL+NUM3': 'formatH3',
  8291. 'CTRL+NUM4': 'formatH4',
  8292. 'CTRL+NUM5': 'formatH5',
  8293. 'CTRL+NUM6': 'formatH6',
  8294. 'CTRL+ENTER': 'insertHorizontalRule',
  8295. 'CTRL+K': 'linkDialog.show'
  8296. },
  8297. mac: {
  8298. 'ESC': 'escape',
  8299. 'ENTER': 'insertParagraph',
  8300. 'CMD+Z': 'undo',
  8301. 'CMD+SHIFT+Z': 'redo',
  8302. 'TAB': 'tab',
  8303. 'SHIFT+TAB': 'untab',
  8304. 'CMD+B': 'bold',
  8305. 'CMD+I': 'italic',
  8306. 'CMD+U': 'underline',
  8307. 'CMD+SHIFT+S': 'strikethrough',
  8308. 'CMD+BACKSLASH': 'removeFormat',
  8309. 'CMD+SHIFT+L': 'justifyLeft',
  8310. 'CMD+SHIFT+E': 'justifyCenter',
  8311. 'CMD+SHIFT+R': 'justifyRight',
  8312. 'CMD+SHIFT+J': 'justifyFull',
  8313. 'CMD+SHIFT+NUM7': 'insertUnorderedList',
  8314. 'CMD+SHIFT+NUM8': 'insertOrderedList',
  8315. 'CMD+LEFTBRACKET': 'outdent',
  8316. 'CMD+RIGHTBRACKET': 'indent',
  8317. 'CMD+NUM0': 'formatPara',
  8318. 'CMD+NUM1': 'formatH1',
  8319. 'CMD+NUM2': 'formatH2',
  8320. 'CMD+NUM3': 'formatH3',
  8321. 'CMD+NUM4': 'formatH4',
  8322. 'CMD+NUM5': 'formatH5',
  8323. 'CMD+NUM6': 'formatH6',
  8324. 'CMD+ENTER': 'insertHorizontalRule',
  8325. 'CMD+K': 'linkDialog.show'
  8326. }
  8327. },
  8328. icons: {
  8329. 'align': 'note-icon-align',
  8330. 'alignCenter': 'note-icon-align-center',
  8331. 'alignJustify': 'note-icon-align-justify',
  8332. 'alignLeft': 'note-icon-align-left',
  8333. 'alignRight': 'note-icon-align-right',
  8334. 'rowBelow': 'note-icon-row-below',
  8335. 'colBefore': 'note-icon-col-before',
  8336. 'colAfter': 'note-icon-col-after',
  8337. 'rowAbove': 'note-icon-row-above',
  8338. 'rowRemove': 'note-icon-row-remove',
  8339. 'colRemove': 'note-icon-col-remove',
  8340. 'indent': 'note-icon-align-indent',
  8341. 'outdent': 'note-icon-align-outdent',
  8342. 'arrowsAlt': 'note-icon-arrows-alt',
  8343. 'bold': 'note-icon-bold',
  8344. 'caret': 'note-icon-caret',
  8345. 'circle': 'note-icon-circle',
  8346. 'close': 'note-icon-close',
  8347. 'code': 'note-icon-code',
  8348. 'eraser': 'note-icon-eraser',
  8349. 'floatLeft': 'note-icon-float-left',
  8350. 'floatRight': 'note-icon-float-right',
  8351. 'font': 'note-icon-font',
  8352. 'frame': 'note-icon-frame',
  8353. 'italic': 'note-icon-italic',
  8354. 'link': 'note-icon-link',
  8355. 'unlink': 'note-icon-chain-broken',
  8356. 'magic': 'note-icon-magic',
  8357. 'menuCheck': 'note-icon-menu-check',
  8358. 'minus': 'note-icon-minus',
  8359. 'orderedlist': 'note-icon-orderedlist',
  8360. 'pencil': 'note-icon-pencil',
  8361. 'picture': 'note-icon-picture',
  8362. 'question': 'note-icon-question',
  8363. 'redo': 'note-icon-redo',
  8364. 'rollback': 'note-icon-rollback',
  8365. 'square': 'note-icon-square',
  8366. 'strikethrough': 'note-icon-strikethrough',
  8367. 'subscript': 'note-icon-subscript',
  8368. 'superscript': 'note-icon-superscript',
  8369. 'table': 'note-icon-table',
  8370. 'textHeight': 'note-icon-text-height',
  8371. 'trash': 'note-icon-trash',
  8372. 'underline': 'note-icon-underline',
  8373. 'undo': 'note-icon-undo',
  8374. 'unorderedlist': 'note-icon-unorderedlist',
  8375. 'video': 'note-icon-video'
  8376. }
  8377. }
  8378. });
  8379. ;// CONCATENATED MODULE: ./src/js/renderer.js
  8380. function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
  8381. function renderer_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  8382. function renderer_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  8383. function renderer_createClass(Constructor, protoProps, staticProps) { if (protoProps) renderer_defineProperties(Constructor.prototype, protoProps); if (staticProps) renderer_defineProperties(Constructor, staticProps); return Constructor; }
  8384. var Renderer = /*#__PURE__*/function () {
  8385. function Renderer(markup, children, options, callback) {
  8386. renderer_classCallCheck(this, Renderer);
  8387. this.markup = markup;
  8388. this.children = children;
  8389. this.options = options;
  8390. this.callback = callback;
  8391. }
  8392. renderer_createClass(Renderer, [{
  8393. key: "render",
  8394. value: function render($parent) {
  8395. var $node = external_jQuery_default()(this.markup);
  8396. if (this.options && this.options.contents) {
  8397. $node.html(this.options.contents);
  8398. }
  8399. if (this.options && this.options.className) {
  8400. $node.addClass(this.options.className);
  8401. }
  8402. if (this.options && this.options.data) {
  8403. external_jQuery_default().each(this.options.data, function (k, v) {
  8404. $node.attr('data-' + k, v);
  8405. });
  8406. }
  8407. if (this.options && this.options.click) {
  8408. $node.on('click', this.options.click);
  8409. }
  8410. if (this.children) {
  8411. var $container = $node.find('.note-children-container');
  8412. this.children.forEach(function (child) {
  8413. child.render($container.length ? $container : $node);
  8414. });
  8415. }
  8416. if (this.callback) {
  8417. this.callback($node, this.options);
  8418. }
  8419. if (this.options && this.options.callback) {
  8420. this.options.callback($node);
  8421. }
  8422. if ($parent) {
  8423. $parent.append($node);
  8424. }
  8425. return $node;
  8426. }
  8427. }]);
  8428. return Renderer;
  8429. }();
  8430. /* harmony default export */ const renderer = ({
  8431. create: function create(markup, callback) {
  8432. return function () {
  8433. var options = _typeof(arguments[1]) === 'object' ? arguments[1] : arguments[0];
  8434. var children = Array.isArray(arguments[0]) ? arguments[0] : [];
  8435. if (options && options.children) {
  8436. children = options.children;
  8437. }
  8438. return new Renderer(markup, children, options, callback);
  8439. };
  8440. }
  8441. });
  8442. ;// CONCATENATED MODULE: ./src/styles/bs4/summernote-bs4.js
  8443. function summernote_bs4_typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { summernote_bs4_typeof = function _typeof(obj) { return typeof obj; }; } else { summernote_bs4_typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return summernote_bs4_typeof(obj); }
  8444. var editor = renderer.create('<div class="note-editor note-frame card"></div>');
  8445. var toolbar = renderer.create('<div class="note-toolbar card-header" role="toolbar"></div>');
  8446. var editingArea = renderer.create('<div class="note-editing-area"></div>');
  8447. var codable = renderer.create('<textarea class="note-codable" aria-multiline="true"></textarea>');
  8448. var editable = renderer.create('<div class="note-editable card-block" contentEditable="true" role="textbox" aria-multiline="true"></div>');
  8449. var statusbar = renderer.create(['<output class="note-status-output" role="status" aria-live="polite"></output>', '<div class="note-statusbar" role="status">', '<div class="note-resizebar" aria-label="Resize">', '<div class="note-icon-bar"></div>', '<div class="note-icon-bar"></div>', '<div class="note-icon-bar"></div>', '</div>', '</div>'].join(''));
  8450. var airEditor = renderer.create('<div class="note-editor note-airframe"></div>');
  8451. var airEditable = renderer.create(['<div class="note-editable" contentEditable="true" role="textbox" aria-multiline="true"></div>', '<output class="note-status-output" role="status" aria-live="polite"></output>'].join(''));
  8452. var buttonGroup = renderer.create('<div class="note-btn-group btn-group"></div>');
  8453. var dropdown = renderer.create('<div class="note-dropdown-menu dropdown-menu" role="list"></div>', function ($node, options) {
  8454. var markup = Array.isArray(options.items) ? options.items.map(function (item) {
  8455. var value = typeof item === 'string' ? item : item.value || '';
  8456. var content = options.template ? options.template(item) : item;
  8457. var option = summernote_bs4_typeof(item) === 'object' ? item.option : undefined;
  8458. var dataValue = 'data-value="' + value + '"';
  8459. var dataOption = option !== undefined ? ' data-option="' + option + '"' : '';
  8460. return '<a class="dropdown-item" href="#" ' + (dataValue + dataOption) + ' role="listitem" aria-label="' + value + '">' + content + '</a>';
  8461. }).join('') : options.items;
  8462. $node.html(markup).attr({
  8463. 'aria-label': options.title
  8464. });
  8465. if (options && options.codeviewKeepButton) {
  8466. $node.addClass('note-codeview-keep');
  8467. }
  8468. });
  8469. var dropdownButtonContents = function dropdownButtonContents(contents) {
  8470. return contents;
  8471. };
  8472. var dropdownCheck = renderer.create('<div class="note-dropdown-menu dropdown-menu note-check" role="list"></div>', function ($node, options) {
  8473. var markup = Array.isArray(options.items) ? options.items.map(function (item) {
  8474. var value = typeof item === 'string' ? item : item.value || '';
  8475. var content = options.template ? options.template(item) : item;
  8476. return '<a class="dropdown-item" href="#" data-value="' + value + '" role="listitem" aria-label="' + item + '">' + icon(options.checkClassName) + ' ' + content + '</a>';
  8477. }).join('') : options.items;
  8478. $node.html(markup).attr({
  8479. 'aria-label': options.title
  8480. });
  8481. if (options && options.codeviewKeepButton) {
  8482. $node.addClass('note-codeview-keep');
  8483. }
  8484. });
  8485. var dialog = renderer.create('<div class="modal note-modal" aria-hidden="false" tabindex="-1" role="dialog"></div>', function ($node, options) {
  8486. if (options.fade) {
  8487. $node.addClass('fade');
  8488. }
  8489. $node.attr({
  8490. 'aria-label': options.title
  8491. });
  8492. $node.html(['<div class="modal-dialog">', '<div class="modal-content">', options.title ? '<div class="modal-header">' + '<h4 class="modal-title">' + options.title + '</h4>' + '<button type="button" class="close" data-dismiss="modal" aria-label="Close" aria-hidden="true">&times;</button>' + '</div>' : '', '<div class="modal-body">' + options.body + '</div>', options.footer ? '<div class="modal-footer">' + options.footer + '</div>' : '', '</div>', '</div>'].join(''));
  8493. });
  8494. var popover = renderer.create(['<div class="note-popover popover in">', '<div class="arrow"></div>', '<div class="popover-content note-children-container"></div>', '</div>'].join(''), function ($node, options) {
  8495. var direction = typeof options.direction !== 'undefined' ? options.direction : 'bottom';
  8496. $node.addClass(direction);
  8497. if (options.hideArrow) {
  8498. $node.find('.arrow').hide();
  8499. }
  8500. });
  8501. var summernote_bs4_checkbox = renderer.create('<div class="form-check"></div>', function ($node, options) {
  8502. $node.html(['<label class="form-check-label"' + (options.id ? ' for="note-' + options.id + '"' : '') + '>', '<input type="checkbox" class="form-check-input"' + (options.id ? ' id="note-' + options.id + '"' : ''), options.checked ? ' checked' : '', ' aria-label="' + (options.text ? options.text : '') + '"', ' aria-checked="' + (options.checked ? 'true' : 'false') + '"/>', ' ' + (options.text ? options.text : '') + '</label>'].join(''));
  8503. });
  8504. var icon = function icon(iconClassName, tagName) {
  8505. if (iconClassName.match(/^</)) {
  8506. return iconClassName;
  8507. }
  8508. tagName = tagName || 'i';
  8509. return '<' + tagName + ' class="' + iconClassName + '"></' + tagName + '>';
  8510. };
  8511. var ui = function ui(editorOptions) {
  8512. return {
  8513. editor: editor,
  8514. toolbar: toolbar,
  8515. editingArea: editingArea,
  8516. codable: codable,
  8517. editable: editable,
  8518. statusbar: statusbar,
  8519. airEditor: airEditor,
  8520. airEditable: airEditable,
  8521. buttonGroup: buttonGroup,
  8522. dropdown: dropdown,
  8523. dropdownButtonContents: dropdownButtonContents,
  8524. dropdownCheck: dropdownCheck,
  8525. dialog: dialog,
  8526. popover: popover,
  8527. icon: icon,
  8528. checkbox: summernote_bs4_checkbox,
  8529. options: editorOptions,
  8530. palette: function palette($node, options) {
  8531. return renderer.create('<div class="note-color-palette"></div>', function ($node, options) {
  8532. var contents = [];
  8533. for (var row = 0, rowSize = options.colors.length; row < rowSize; row++) {
  8534. var eventName = options.eventName;
  8535. var colors = options.colors[row];
  8536. var colorsName = options.colorsName[row];
  8537. var buttons = [];
  8538. for (var col = 0, colSize = colors.length; col < colSize; col++) {
  8539. var color = colors[col];
  8540. var colorName = colorsName[col];
  8541. buttons.push(['<button type="button" class="note-color-btn"', 'style="background-color:', color, '" ', 'data-event="', eventName, '" ', 'data-value="', color, '" ', 'title="', colorName, '" ', 'aria-label="', colorName, '" ', 'data-toggle="button" tabindex="-1"></button>'].join(''));
  8542. }
  8543. contents.push('<div class="note-color-row">' + buttons.join('') + '</div>');
  8544. }
  8545. $node.html(contents.join(''));
  8546. if (options.tooltip) {
  8547. $node.find('.note-color-btn').tooltip({
  8548. container: options.container || editorOptions.container,
  8549. trigger: 'hover',
  8550. placement: 'bottom'
  8551. });
  8552. }
  8553. })($node, options);
  8554. },
  8555. button: function button($node, options) {
  8556. return renderer.create('<button type="button" class="note-btn btn btn-light btn-sm" tabindex="-1"></button>', function ($node, options) {
  8557. if (options && options.tooltip) {
  8558. $node.attr({
  8559. title: options.tooltip,
  8560. 'aria-label': options.tooltip
  8561. }).tooltip({
  8562. container: options.container || editorOptions.container,
  8563. trigger: 'hover',
  8564. placement: 'bottom'
  8565. }).on('click', function (e) {
  8566. external_jQuery_default()(e.currentTarget).tooltip('hide');
  8567. });
  8568. }
  8569. if (options && options.codeviewButton) {
  8570. $node.addClass('note-codeview-keep');
  8571. }
  8572. })($node, options);
  8573. },
  8574. toggleBtn: function toggleBtn($btn, isEnable) {
  8575. $btn.toggleClass('disabled', !isEnable);
  8576. $btn.attr('disabled', !isEnable);
  8577. },
  8578. toggleBtnActive: function toggleBtnActive($btn, isActive) {
  8579. $btn.toggleClass('active', isActive);
  8580. },
  8581. onDialogShown: function onDialogShown($dialog, handler) {
  8582. $dialog.one('shown.bs.modal', handler);
  8583. },
  8584. onDialogHidden: function onDialogHidden($dialog, handler) {
  8585. $dialog.one('hidden.bs.modal', handler);
  8586. },
  8587. showDialog: function showDialog($dialog) {
  8588. $dialog.modal('show');
  8589. },
  8590. hideDialog: function hideDialog($dialog) {
  8591. $dialog.modal('hide');
  8592. },
  8593. createLayout: function createLayout($note) {
  8594. var $editor = (editorOptions.airMode ? airEditor([editingArea([codable(), airEditable()])]) : editorOptions.toolbarPosition === 'bottom' ? editor([editingArea([codable(), editable()]), toolbar(), statusbar()]) : editor([toolbar(), editingArea([codable(), editable()]), statusbar()])).render();
  8595. $editor.insertAfter($note);
  8596. return {
  8597. note: $note,
  8598. editor: $editor,
  8599. toolbar: $editor.find('.note-toolbar'),
  8600. editingArea: $editor.find('.note-editing-area'),
  8601. editable: $editor.find('.note-editable'),
  8602. codable: $editor.find('.note-codable'),
  8603. statusbar: $editor.find('.note-statusbar')
  8604. };
  8605. },
  8606. removeLayout: function removeLayout($note, layoutInfo) {
  8607. $note.html(layoutInfo.editable.html());
  8608. layoutInfo.editor.remove();
  8609. $note.show();
  8610. }
  8611. };
  8612. };
  8613. (external_jQuery_default()).summernote = external_jQuery_default().extend((external_jQuery_default()).summernote, {
  8614. ui_template: ui,
  8615. "interface": 'bs4'
  8616. });
  8617. (external_jQuery_default()).summernote.options.styleTags = ['p', {
  8618. title: 'Blockquote',
  8619. tag: 'blockquote',
  8620. className: 'blockquote',
  8621. value: 'blockquote'
  8622. }, 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
  8623. })();
  8624. /******/ return __webpack_exports__;
  8625. /******/ })()
  8626. ;
  8627. });
  8628. //# sourceMappingURL=summernote-bs4.js.map