UNPKG

1.05 MBJavaScriptView Raw
1/**
2 * Copyright (c) Tiny Technologies, Inc. All rights reserved.
3 * Licensed under the LGPL or a commercial license.
4 * For LGPL see License.txt in the project root for license information.
5 * For commercial licenses see https://www.tiny.cloud/
6 *
7 * Version: 5.0.12 (2019-07-18)
8 */
9(function (domGlobals) {
10 'use strict';
11
12 var noop = function () {
13 };
14 var compose = function (fa, fb) {
15 return function () {
16 var args = [];
17 for (var _i = 0; _i < arguments.length; _i++) {
18 args[_i] = arguments[_i];
19 }
20 return fa(fb.apply(null, args));
21 };
22 };
23 var constant = function (value) {
24 return function () {
25 return value;
26 };
27 };
28 var identity = function (x) {
29 return x;
30 };
31 function curry(fn) {
32 var initialArgs = [];
33 for (var _i = 1; _i < arguments.length; _i++) {
34 initialArgs[_i - 1] = arguments[_i];
35 }
36 return function () {
37 var restArgs = [];
38 for (var _i = 0; _i < arguments.length; _i++) {
39 restArgs[_i] = arguments[_i];
40 }
41 var all = initialArgs.concat(restArgs);
42 return fn.apply(null, all);
43 };
44 }
45 var not = function (f) {
46 return function () {
47 var args = [];
48 for (var _i = 0; _i < arguments.length; _i++) {
49 args[_i] = arguments[_i];
50 }
51 return !f.apply(null, args);
52 };
53 };
54 var die = function (msg) {
55 return function () {
56 throw new Error(msg);
57 };
58 };
59 var never = constant(false);
60 var always = constant(true);
61
62 var never$1 = never;
63 var always$1 = always;
64 var none = function () {
65 return NONE;
66 };
67 var NONE = function () {
68 var eq = function (o) {
69 return o.isNone();
70 };
71 var call = function (thunk) {
72 return thunk();
73 };
74 var id = function (n) {
75 return n;
76 };
77 var noop = function () {
78 };
79 var nul = function () {
80 return null;
81 };
82 var undef = function () {
83 return undefined;
84 };
85 var me = {
86 fold: function (n, s) {
87 return n();
88 },
89 is: never$1,
90 isSome: never$1,
91 isNone: always$1,
92 getOr: id,
93 getOrThunk: call,
94 getOrDie: function (msg) {
95 throw new Error(msg || 'error: getOrDie called on none.');
96 },
97 getOrNull: nul,
98 getOrUndefined: undef,
99 or: id,
100 orThunk: call,
101 map: none,
102 ap: none,
103 each: noop,
104 bind: none,
105 flatten: none,
106 exists: never$1,
107 forall: always$1,
108 filter: none,
109 equals: eq,
110 equals_: eq,
111 toArray: function () {
112 return [];
113 },
114 toString: constant('none()')
115 };
116 if (Object.freeze) {
117 Object.freeze(me);
118 }
119 return me;
120 }();
121 var some = function (a) {
122 var constant_a = function () {
123 return a;
124 };
125 var self = function () {
126 return me;
127 };
128 var map = function (f) {
129 return some(f(a));
130 };
131 var bind = function (f) {
132 return f(a);
133 };
134 var me = {
135 fold: function (n, s) {
136 return s(a);
137 },
138 is: function (v) {
139 return a === v;
140 },
141 isSome: always$1,
142 isNone: never$1,
143 getOr: constant_a,
144 getOrThunk: constant_a,
145 getOrDie: constant_a,
146 getOrNull: constant_a,
147 getOrUndefined: constant_a,
148 or: self,
149 orThunk: self,
150 map: map,
151 ap: function (optfab) {
152 return optfab.fold(none, function (fab) {
153 return some(fab(a));
154 });
155 },
156 each: function (f) {
157 f(a);
158 },
159 bind: bind,
160 flatten: constant_a,
161 exists: bind,
162 forall: bind,
163 filter: function (f) {
164 return f(a) ? me : NONE;
165 },
166 equals: function (o) {
167 return o.is(a);
168 },
169 equals_: function (o, elementEq) {
170 return o.fold(never$1, function (b) {
171 return elementEq(a, b);
172 });
173 },
174 toArray: function () {
175 return [a];
176 },
177 toString: function () {
178 return 'some(' + a + ')';
179 }
180 };
181 return me;
182 };
183 var from = function (value) {
184 return value === null || value === undefined ? NONE : some(value);
185 };
186 var Option = {
187 some: some,
188 none: none,
189 from: from
190 };
191
192 var typeOf = function (x) {
193 if (x === null) {
194 return 'null';
195 }
196 var t = typeof x;
197 if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) {
198 return 'array';
199 }
200 if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) {
201 return 'string';
202 }
203 return t;
204 };
205 var isType = function (type) {
206 return function (value) {
207 return typeOf(value) === type;
208 };
209 };
210 var isString = isType('string');
211 var isObject = isType('object');
212 var isArray = isType('array');
213 var isNull = isType('null');
214 var isBoolean = isType('boolean');
215 var isFunction = isType('function');
216 var isNumber = isType('number');
217
218 var slice = Array.prototype.slice;
219 var rawIndexOf = function () {
220 var pIndexOf = Array.prototype.indexOf;
221 var fastIndex = function (xs, x) {
222 return pIndexOf.call(xs, x);
223 };
224 var slowIndex = function (xs, x) {
225 return slowIndexOf(xs, x);
226 };
227 return pIndexOf === undefined ? slowIndex : fastIndex;
228 }();
229 var indexOf = function (xs, x) {
230 var r = rawIndexOf(xs, x);
231 return r === -1 ? Option.none() : Option.some(r);
232 };
233 var contains = function (xs, x) {
234 return rawIndexOf(xs, x) > -1;
235 };
236 var exists = function (xs, pred) {
237 return findIndex(xs, pred).isSome();
238 };
239 var map = function (xs, f) {
240 var len = xs.length;
241 var r = new Array(len);
242 for (var i = 0; i < len; i++) {
243 var x = xs[i];
244 r[i] = f(x, i, xs);
245 }
246 return r;
247 };
248 var each = function (xs, f) {
249 for (var i = 0, len = xs.length; i < len; i++) {
250 var x = xs[i];
251 f(x, i, xs);
252 }
253 };
254 var eachr = function (xs, f) {
255 for (var i = xs.length - 1; i >= 0; i--) {
256 var x = xs[i];
257 f(x, i, xs);
258 }
259 };
260 var partition = function (xs, pred) {
261 var pass = [];
262 var fail = [];
263 for (var i = 0, len = xs.length; i < len; i++) {
264 var x = xs[i];
265 var arr = pred(x, i, xs) ? pass : fail;
266 arr.push(x);
267 }
268 return {
269 pass: pass,
270 fail: fail
271 };
272 };
273 var filter = function (xs, pred) {
274 var r = [];
275 for (var i = 0, len = xs.length; i < len; i++) {
276 var x = xs[i];
277 if (pred(x, i, xs)) {
278 r.push(x);
279 }
280 }
281 return r;
282 };
283 var foldr = function (xs, f, acc) {
284 eachr(xs, function (x) {
285 acc = f(acc, x);
286 });
287 return acc;
288 };
289 var foldl = function (xs, f, acc) {
290 each(xs, function (x) {
291 acc = f(acc, x);
292 });
293 return acc;
294 };
295 var find = function (xs, pred) {
296 for (var i = 0, len = xs.length; i < len; i++) {
297 var x = xs[i];
298 if (pred(x, i, xs)) {
299 return Option.some(x);
300 }
301 }
302 return Option.none();
303 };
304 var findIndex = function (xs, pred) {
305 for (var i = 0, len = xs.length; i < len; i++) {
306 var x = xs[i];
307 if (pred(x, i, xs)) {
308 return Option.some(i);
309 }
310 }
311 return Option.none();
312 };
313 var slowIndexOf = function (xs, x) {
314 for (var i = 0, len = xs.length; i < len; ++i) {
315 if (xs[i] === x) {
316 return i;
317 }
318 }
319 return -1;
320 };
321 var push = Array.prototype.push;
322 var flatten = function (xs) {
323 var r = [];
324 for (var i = 0, len = xs.length; i < len; ++i) {
325 if (!isArray(xs[i])) {
326 throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
327 }
328 push.apply(r, xs[i]);
329 }
330 return r;
331 };
332 var bind = function (xs, f) {
333 var output = map(xs, f);
334 return flatten(output);
335 };
336 var forall = function (xs, pred) {
337 for (var i = 0, len = xs.length; i < len; ++i) {
338 var x = xs[i];
339 if (pred(x, i, xs) !== true) {
340 return false;
341 }
342 }
343 return true;
344 };
345 var reverse = function (xs) {
346 var r = slice.call(xs, 0);
347 r.reverse();
348 return r;
349 };
350 var difference = function (a1, a2) {
351 return filter(a1, function (x) {
352 return !contains(a2, x);
353 });
354 };
355 var mapToObject = function (xs, f) {
356 var r = {};
357 for (var i = 0, len = xs.length; i < len; i++) {
358 var x = xs[i];
359 r[String(x)] = f(x, i);
360 }
361 return r;
362 };
363 var sort = function (xs, comparator) {
364 var copy = slice.call(xs, 0);
365 copy.sort(comparator);
366 return copy;
367 };
368 var head = function (xs) {
369 return xs.length === 0 ? Option.none() : Option.some(xs[0]);
370 };
371 var last = function (xs) {
372 return xs.length === 0 ? Option.none() : Option.some(xs[xs.length - 1]);
373 };
374 var from$1 = isFunction(Array.from) ? Array.from : function (x) {
375 return slice.call(x);
376 };
377
378 var __assign = function () {
379 __assign = Object.assign || function __assign(t) {
380 for (var s, i = 1, n = arguments.length; i < n; i++) {
381 s = arguments[i];
382 for (var p in s)
383 if (Object.prototype.hasOwnProperty.call(s, p))
384 t[p] = s[p];
385 }
386 return t;
387 };
388 return __assign.apply(this, arguments);
389 };
390 function __rest(s, e) {
391 var t = {};
392 for (var p in s)
393 if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
394 t[p] = s[p];
395 if (s != null && typeof Object.getOwnPropertySymbols === 'function')
396 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
397 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
398 t[p[i]] = s[p[i]];
399 }
400 return t;
401 }
402
403 var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')();
404
405 var path = function (parts, scope) {
406 var o = scope !== undefined && scope !== null ? scope : Global;
407 for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i) {
408 o = o[parts[i]];
409 }
410 return o;
411 };
412 var resolve = function (p, scope) {
413 var parts = p.split('.');
414 return path(parts, scope);
415 };
416
417 var unsafe = function (name, scope) {
418 return resolve(name, scope);
419 };
420 var getOrDie = function (name, scope) {
421 var actual = unsafe(name, scope);
422 if (actual === undefined || actual === null) {
423 throw new Error(name + ' not available on this browser');
424 }
425 return actual;
426 };
427 var Global$1 = { getOrDie: getOrDie };
428
429 var url = function () {
430 return Global$1.getOrDie('URL');
431 };
432 var createObjectURL = function (blob) {
433 return url().createObjectURL(blob);
434 };
435 var revokeObjectURL = function (u) {
436 url().revokeObjectURL(u);
437 };
438 var URL = {
439 createObjectURL: createObjectURL,
440 revokeObjectURL: revokeObjectURL
441 };
442
443 var nav = domGlobals.navigator, userAgent = nav.userAgent;
444 var opera, webkit, ie, ie11, ie12, gecko, mac, iDevice, android, fileApi, phone, tablet, windowsPhone;
445 var matchMediaQuery = function (query) {
446 return 'matchMedia' in domGlobals.window ? domGlobals.matchMedia(query).matches : false;
447 };
448 opera = false;
449 android = /Android/.test(userAgent);
450 webkit = /WebKit/.test(userAgent);
451 ie = !webkit && !opera && /MSIE/gi.test(userAgent) && /Explorer/gi.test(nav.appName);
452 ie = ie && /MSIE (\w+)\./.exec(userAgent)[1];
453 ie11 = userAgent.indexOf('Trident/') !== -1 && (userAgent.indexOf('rv:') !== -1 || nav.appName.indexOf('Netscape') !== -1) ? 11 : false;
454 ie12 = userAgent.indexOf('Edge/') !== -1 && !ie && !ie11 ? 12 : false;
455 ie = ie || ie11 || ie12;
456 gecko = !webkit && !ie11 && /Gecko/.test(userAgent);
457 mac = userAgent.indexOf('Mac') !== -1;
458 iDevice = /(iPad|iPhone)/.test(userAgent);
459 fileApi = 'FormData' in domGlobals.window && 'FileReader' in domGlobals.window && 'URL' in domGlobals.window && !!URL.createObjectURL;
460 phone = matchMediaQuery('only screen and (max-device-width: 480px)') && (android || iDevice);
461 tablet = matchMediaQuery('only screen and (min-width: 800px)') && (android || iDevice);
462 windowsPhone = userAgent.indexOf('Windows Phone') !== -1;
463 if (ie12) {
464 webkit = false;
465 }
466 var contentEditable = !iDevice || fileApi || parseInt(userAgent.match(/AppleWebKit\/(\d*)/)[1], 10) >= 534;
467 var Env = {
468 opera: opera,
469 webkit: webkit,
470 ie: ie,
471 gecko: gecko,
472 mac: mac,
473 iOS: iDevice,
474 android: android,
475 contentEditable: contentEditable,
476 transparentSrc: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
477 caretAfter: ie !== 8,
478 range: domGlobals.window.getSelection && 'Range' in domGlobals.window,
479 documentMode: ie && !ie12 ? domGlobals.document.documentMode || 7 : 10,
480 fileApi: fileApi,
481 ceFalse: ie === false || ie > 8,
482 cacheSuffix: null,
483 container: null,
484 experimentalShadowDom: false,
485 canHaveCSP: ie === false || ie > 11,
486 desktop: !phone && !tablet,
487 windowsPhone: windowsPhone
488 };
489
490 var promise = function () {
491 function bind(fn, thisArg) {
492 return function () {
493 fn.apply(thisArg, arguments);
494 };
495 }
496 var isArray = Array.isArray || function (value) {
497 return Object.prototype.toString.call(value) === '[object Array]';
498 };
499 var Promise = function (fn) {
500 if (typeof this !== 'object') {
501 throw new TypeError('Promises must be constructed via new');
502 }
503 if (typeof fn !== 'function') {
504 throw new TypeError('not a function');
505 }
506 this._state = null;
507 this._value = null;
508 this._deferreds = [];
509 doResolve(fn, bind(resolve, this), bind(reject, this));
510 };
511 var asap = Promise.immediateFn || typeof domGlobals.setImmediate === 'function' && domGlobals.setImmediate || function (fn) {
512 domGlobals.setTimeout(fn, 1);
513 };
514 function handle(deferred) {
515 var me = this;
516 if (this._state === null) {
517 this._deferreds.push(deferred);
518 return;
519 }
520 asap(function () {
521 var cb = me._state ? deferred.onFulfilled : deferred.onRejected;
522 if (cb === null) {
523 (me._state ? deferred.resolve : deferred.reject)(me._value);
524 return;
525 }
526 var ret;
527 try {
528 ret = cb(me._value);
529 } catch (e) {
530 deferred.reject(e);
531 return;
532 }
533 deferred.resolve(ret);
534 });
535 }
536 function resolve(newValue) {
537 try {
538 if (newValue === this) {
539 throw new TypeError('A promise cannot be resolved with itself.');
540 }
541 if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
542 var then = newValue.then;
543 if (typeof then === 'function') {
544 doResolve(bind(then, newValue), bind(resolve, this), bind(reject, this));
545 return;
546 }
547 }
548 this._state = true;
549 this._value = newValue;
550 finale.call(this);
551 } catch (e) {
552 reject.call(this, e);
553 }
554 }
555 function reject(newValue) {
556 this._state = false;
557 this._value = newValue;
558 finale.call(this);
559 }
560 function finale() {
561 for (var i = 0, len = this._deferreds.length; i < len; i++) {
562 handle.call(this, this._deferreds[i]);
563 }
564 this._deferreds = null;
565 }
566 function Handler(onFulfilled, onRejected, resolve, reject) {
567 this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
568 this.onRejected = typeof onRejected === 'function' ? onRejected : null;
569 this.resolve = resolve;
570 this.reject = reject;
571 }
572 function doResolve(fn, onFulfilled, onRejected) {
573 var done = false;
574 try {
575 fn(function (value) {
576 if (done) {
577 return;
578 }
579 done = true;
580 onFulfilled(value);
581 }, function (reason) {
582 if (done) {
583 return;
584 }
585 done = true;
586 onRejected(reason);
587 });
588 } catch (ex) {
589 if (done) {
590 return;
591 }
592 done = true;
593 onRejected(ex);
594 }
595 }
596 Promise.prototype.catch = function (onRejected) {
597 return this.then(null, onRejected);
598 };
599 Promise.prototype.then = function (onFulfilled, onRejected) {
600 var me = this;
601 return new Promise(function (resolve, reject) {
602 handle.call(me, new Handler(onFulfilled, onRejected, resolve, reject));
603 });
604 };
605 Promise.all = function () {
606 var args = Array.prototype.slice.call(arguments.length === 1 && isArray(arguments[0]) ? arguments[0] : arguments);
607 return new Promise(function (resolve, reject) {
608 if (args.length === 0) {
609 return resolve([]);
610 }
611 var remaining = args.length;
612 function res(i, val) {
613 try {
614 if (val && (typeof val === 'object' || typeof val === 'function')) {
615 var then = val.then;
616 if (typeof then === 'function') {
617 then.call(val, function (val) {
618 res(i, val);
619 }, reject);
620 return;
621 }
622 }
623 args[i] = val;
624 if (--remaining === 0) {
625 resolve(args);
626 }
627 } catch (ex) {
628 reject(ex);
629 }
630 }
631 for (var i = 0; i < args.length; i++) {
632 res(i, args[i]);
633 }
634 });
635 };
636 Promise.resolve = function (value) {
637 if (value && typeof value === 'object' && value.constructor === Promise) {
638 return value;
639 }
640 return new Promise(function (resolve) {
641 resolve(value);
642 });
643 };
644 Promise.reject = function (value) {
645 return new Promise(function (resolve, reject) {
646 reject(value);
647 });
648 };
649 Promise.race = function (values) {
650 return new Promise(function (resolve, reject) {
651 for (var i = 0, len = values.length; i < len; i++) {
652 values[i].then(resolve, reject);
653 }
654 });
655 };
656 return Promise;
657 };
658 var promiseObj = window.Promise ? window.Promise : promise();
659
660 var requestAnimationFramePromise;
661 var requestAnimationFrame = function (callback, element) {
662 var i, requestAnimationFrameFunc = domGlobals.window.requestAnimationFrame;
663 var vendors = [
664 'ms',
665 'moz',
666 'webkit'
667 ];
668 var featurefill = function (callback) {
669 domGlobals.window.setTimeout(callback, 0);
670 };
671 for (i = 0; i < vendors.length && !requestAnimationFrameFunc; i++) {
672 requestAnimationFrameFunc = domGlobals.window[vendors[i] + 'RequestAnimationFrame'];
673 }
674 if (!requestAnimationFrameFunc) {
675 requestAnimationFrameFunc = featurefill;
676 }
677 requestAnimationFrameFunc(callback, element);
678 };
679 var wrappedSetTimeout = function (callback, time) {
680 if (typeof time !== 'number') {
681 time = 0;
682 }
683 return domGlobals.setTimeout(callback, time);
684 };
685 var wrappedSetInterval = function (callback, time) {
686 if (typeof time !== 'number') {
687 time = 1;
688 }
689 return domGlobals.setInterval(callback, time);
690 };
691 var wrappedClearTimeout = function (id) {
692 return domGlobals.clearTimeout(id);
693 };
694 var wrappedClearInterval = function (id) {
695 return domGlobals.clearInterval(id);
696 };
697 var debounce = function (callback, time) {
698 var timer, func;
699 func = function () {
700 var args = [];
701 for (var _i = 0; _i < arguments.length; _i++) {
702 args[_i] = arguments[_i];
703 }
704 domGlobals.clearTimeout(timer);
705 timer = wrappedSetTimeout(function () {
706 callback.apply(this, args);
707 }, time);
708 };
709 func.stop = function () {
710 domGlobals.clearTimeout(timer);
711 };
712 return func;
713 };
714 var Delay = {
715 requestAnimationFrame: function (callback, element) {
716 if (requestAnimationFramePromise) {
717 requestAnimationFramePromise.then(callback);
718 return;
719 }
720 requestAnimationFramePromise = new promiseObj(function (resolve) {
721 if (!element) {
722 element = domGlobals.document.body;
723 }
724 requestAnimationFrame(resolve, element);
725 }).then(callback);
726 },
727 setTimeout: wrappedSetTimeout,
728 setInterval: wrappedSetInterval,
729 setEditorTimeout: function (editor, callback, time) {
730 return wrappedSetTimeout(function () {
731 if (!editor.removed) {
732 callback();
733 }
734 }, time);
735 },
736 setEditorInterval: function (editor, callback, time) {
737 var timer;
738 timer = wrappedSetInterval(function () {
739 if (!editor.removed) {
740 callback();
741 } else {
742 domGlobals.clearInterval(timer);
743 }
744 }, time);
745 return timer;
746 },
747 debounce: debounce,
748 throttle: debounce,
749 clearInterval: wrappedClearInterval,
750 clearTimeout: wrappedClearTimeout
751 };
752
753 var eventExpandoPrefix = 'mce-data-';
754 var mouseEventRe = /^(?:mouse|contextmenu)|click/;
755 var deprecated = {
756 keyLocation: 1,
757 layerX: 1,
758 layerY: 1,
759 returnValue: 1,
760 webkitMovementX: 1,
761 webkitMovementY: 1,
762 keyIdentifier: 1
763 };
764 var hasIsDefaultPrevented = function (event) {
765 return event.isDefaultPrevented === returnTrue || event.isDefaultPrevented === returnFalse;
766 };
767 var returnFalse = function () {
768 return false;
769 };
770 var returnTrue = function () {
771 return true;
772 };
773 var addEvent = function (target, name, callback, capture) {
774 if (target.addEventListener) {
775 target.addEventListener(name, callback, capture || false);
776 } else if (target.attachEvent) {
777 target.attachEvent('on' + name, callback);
778 }
779 };
780 var removeEvent = function (target, name, callback, capture) {
781 if (target.removeEventListener) {
782 target.removeEventListener(name, callback, capture || false);
783 } else if (target.detachEvent) {
784 target.detachEvent('on' + name, callback);
785 }
786 };
787 var getTargetFromShadowDom = function (event, defaultTarget) {
788 if (event.composedPath) {
789 var composedPath = event.composedPath();
790 if (composedPath && composedPath.length > 0) {
791 return composedPath[0];
792 }
793 }
794 return defaultTarget;
795 };
796 var fix = function (originalEvent, data) {
797 var name;
798 var event = data || {};
799 for (name in originalEvent) {
800 if (!deprecated[name]) {
801 event[name] = originalEvent[name];
802 }
803 }
804 if (!event.target) {
805 event.target = event.srcElement || domGlobals.document;
806 }
807 if (Env.experimentalShadowDom) {
808 event.target = getTargetFromShadowDom(originalEvent, event.target);
809 }
810 if (originalEvent && mouseEventRe.test(originalEvent.type) && originalEvent.pageX === undefined && originalEvent.clientX !== undefined) {
811 var eventDoc = event.target.ownerDocument || domGlobals.document;
812 var doc = eventDoc.documentElement;
813 var body = eventDoc.body;
814 event.pageX = originalEvent.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
815 event.pageY = originalEvent.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
816 }
817 event.preventDefault = function () {
818 event.isDefaultPrevented = returnTrue;
819 if (originalEvent) {
820 if (originalEvent.preventDefault) {
821 originalEvent.preventDefault();
822 } else {
823 originalEvent.returnValue = false;
824 }
825 }
826 };
827 event.stopPropagation = function () {
828 event.isPropagationStopped = returnTrue;
829 if (originalEvent) {
830 if (originalEvent.stopPropagation) {
831 originalEvent.stopPropagation();
832 } else {
833 originalEvent.cancelBubble = true;
834 }
835 }
836 };
837 event.stopImmediatePropagation = function () {
838 event.isImmediatePropagationStopped = returnTrue;
839 event.stopPropagation();
840 };
841 if (hasIsDefaultPrevented(event) === false) {
842 event.isDefaultPrevented = returnFalse;
843 event.isPropagationStopped = returnFalse;
844 event.isImmediatePropagationStopped = returnFalse;
845 }
846 if (typeof event.metaKey === 'undefined') {
847 event.metaKey = false;
848 }
849 return event;
850 };
851 var bindOnReady = function (win, callback, eventUtils) {
852 var doc = win.document, event = { type: 'ready' };
853 if (eventUtils.domLoaded) {
854 callback(event);
855 return;
856 }
857 var isDocReady = function () {
858 return doc.readyState === 'complete' || doc.readyState === 'interactive' && doc.body;
859 };
860 var readyHandler = function () {
861 removeEvent(win, 'DOMContentLoaded', readyHandler);
862 removeEvent(win, 'load', readyHandler);
863 if (!eventUtils.domLoaded) {
864 eventUtils.domLoaded = true;
865 callback(event);
866 }
867 };
868 var waitForDomLoaded = function () {
869 if (isDocReady()) {
870 removeEvent(doc, 'readystatechange', waitForDomLoaded);
871 readyHandler();
872 }
873 };
874 var tryScroll = function () {
875 try {
876 doc.documentElement.doScroll('left');
877 } catch (ex) {
878 Delay.setTimeout(tryScroll);
879 return;
880 }
881 readyHandler();
882 };
883 if (doc.addEventListener && !(Env.ie && Env.ie < 11)) {
884 if (isDocReady()) {
885 readyHandler();
886 } else {
887 addEvent(win, 'DOMContentLoaded', readyHandler);
888 }
889 } else {
890 addEvent(doc, 'readystatechange', waitForDomLoaded);
891 if (doc.documentElement.doScroll && win.self === win.top) {
892 tryScroll();
893 }
894 }
895 addEvent(win, 'load', readyHandler);
896 };
897 var EventUtils = function () {
898 function EventUtils() {
899 this.domLoaded = false;
900 this.events = {};
901 this.count = 1;
902 this.expando = eventExpandoPrefix + (+new Date()).toString(32);
903 this.hasMouseEnterLeave = 'onmouseenter' in domGlobals.document.documentElement;
904 this.hasFocusIn = 'onfocusin' in domGlobals.document.documentElement;
905 this.count = 1;
906 }
907 EventUtils.prototype.bind = function (target, names, callback, scope) {
908 var self = this;
909 var id, callbackList, i, name, fakeName, nativeHandler, capture;
910 var win = domGlobals.window;
911 var defaultNativeHandler = function (evt) {
912 self.executeHandlers(fix(evt || win.event), id);
913 };
914 if (!target || target.nodeType === 3 || target.nodeType === 8) {
915 return;
916 }
917 if (!target[self.expando]) {
918 id = self.count++;
919 target[self.expando] = id;
920 self.events[id] = {};
921 } else {
922 id = target[self.expando];
923 }
924 scope = scope || target;
925 var namesList = names.split(' ');
926 i = namesList.length;
927 while (i--) {
928 name = namesList[i];
929 nativeHandler = defaultNativeHandler;
930 fakeName = capture = false;
931 if (name === 'DOMContentLoaded') {
932 name = 'ready';
933 }
934 if (self.domLoaded && name === 'ready' && target.readyState === 'complete') {
935 callback.call(scope, fix({ type: name }));
936 continue;
937 }
938 if (!self.hasMouseEnterLeave) {
939 fakeName = self.mouseEnterLeave[name];
940 if (fakeName) {
941 nativeHandler = function (evt) {
942 var current, related;
943 current = evt.currentTarget;
944 related = evt.relatedTarget;
945 if (related && current.contains) {
946 related = current.contains(related);
947 } else {
948 while (related && related !== current) {
949 related = related.parentNode;
950 }
951 }
952 if (!related) {
953 evt = fix(evt || win.event);
954 evt.type = evt.type === 'mouseout' ? 'mouseleave' : 'mouseenter';
955 evt.target = current;
956 self.executeHandlers(evt, id);
957 }
958 };
959 }
960 }
961 if (!self.hasFocusIn && (name === 'focusin' || name === 'focusout')) {
962 capture = true;
963 fakeName = name === 'focusin' ? 'focus' : 'blur';
964 nativeHandler = function (evt) {
965 evt = fix(evt || win.event);
966 evt.type = evt.type === 'focus' ? 'focusin' : 'focusout';
967 self.executeHandlers(evt, id);
968 };
969 }
970 callbackList = self.events[id][name];
971 if (!callbackList) {
972 self.events[id][name] = callbackList = [{
973 func: callback,
974 scope: scope
975 }];
976 callbackList.fakeName = fakeName;
977 callbackList.capture = capture;
978 callbackList.nativeHandler = nativeHandler;
979 if (name === 'ready') {
980 bindOnReady(target, nativeHandler, self);
981 } else {
982 addEvent(target, fakeName || name, nativeHandler, capture);
983 }
984 } else {
985 if (name === 'ready' && self.domLoaded) {
986 callback(fix({ type: name }));
987 } else {
988 callbackList.push({
989 func: callback,
990 scope: scope
991 });
992 }
993 }
994 }
995 target = callbackList = 0;
996 return callback;
997 };
998 EventUtils.prototype.unbind = function (target, names, callback) {
999 var id, callbackList, i, ci, name, eventMap;
1000 if (!target || target.nodeType === 3 || target.nodeType === 8) {
1001 return this;
1002 }
1003 id = target[this.expando];
1004 if (id) {
1005 eventMap = this.events[id];
1006 if (names) {
1007 var namesList = names.split(' ');
1008 i = namesList.length;
1009 while (i--) {
1010 name = namesList[i];
1011 callbackList = eventMap[name];
1012 if (callbackList) {
1013 if (callback) {
1014 ci = callbackList.length;
1015 while (ci--) {
1016 if (callbackList[ci].func === callback) {
1017 var nativeHandler = callbackList.nativeHandler;
1018 var fakeName = callbackList.fakeName, capture = callbackList.capture;
1019 callbackList = callbackList.slice(0, ci).concat(callbackList.slice(ci + 1));
1020 callbackList.nativeHandler = nativeHandler;
1021 callbackList.fakeName = fakeName;
1022 callbackList.capture = capture;
1023 eventMap[name] = callbackList;
1024 }
1025 }
1026 }
1027 if (!callback || callbackList.length === 0) {
1028 delete eventMap[name];
1029 removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture);
1030 }
1031 }
1032 }
1033 } else {
1034 for (name in eventMap) {
1035 callbackList = eventMap[name];
1036 removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture);
1037 }
1038 eventMap = {};
1039 }
1040 for (name in eventMap) {
1041 return this;
1042 }
1043 delete this.events[id];
1044 try {
1045 delete target[this.expando];
1046 } catch (ex) {
1047 target[this.expando] = null;
1048 }
1049 }
1050 return this;
1051 };
1052 EventUtils.prototype.fire = function (target, name, args) {
1053 var id;
1054 if (!target || target.nodeType === 3 || target.nodeType === 8) {
1055 return this;
1056 }
1057 var event = fix(null, args);
1058 event.type = name;
1059 event.target = target;
1060 do {
1061 id = target[this.expando];
1062 if (id) {
1063 this.executeHandlers(event, id);
1064 }
1065 target = target.parentNode || target.ownerDocument || target.defaultView || target.parentWindow;
1066 } while (target && !event.isPropagationStopped());
1067 return this;
1068 };
1069 EventUtils.prototype.clean = function (target) {
1070 var i, children;
1071 if (!target || target.nodeType === 3 || target.nodeType === 8) {
1072 return this;
1073 }
1074 if (target[this.expando]) {
1075 this.unbind(target);
1076 }
1077 if (!target.getElementsByTagName) {
1078 target = target.document;
1079 }
1080 if (target && target.getElementsByTagName) {
1081 this.unbind(target);
1082 children = target.getElementsByTagName('*');
1083 i = children.length;
1084 while (i--) {
1085 target = children[i];
1086 if (target[this.expando]) {
1087 this.unbind(target);
1088 }
1089 }
1090 }
1091 return this;
1092 };
1093 EventUtils.prototype.destroy = function () {
1094 this.events = {};
1095 };
1096 EventUtils.prototype.cancel = function (e) {
1097 if (e) {
1098 e.preventDefault();
1099 e.stopImmediatePropagation();
1100 }
1101 return false;
1102 };
1103 EventUtils.prototype.executeHandlers = function (evt, id) {
1104 var callbackList, i, l, callback;
1105 var container = this.events[id];
1106 callbackList = container && container[evt.type];
1107 if (callbackList) {
1108 for (i = 0, l = callbackList.length; i < l; i++) {
1109 callback = callbackList[i];
1110 if (callback && callback.func.call(callback.scope, evt) === false) {
1111 evt.preventDefault();
1112 }
1113 if (evt.isImmediatePropagationStopped()) {
1114 return;
1115 }
1116 }
1117 }
1118 };
1119 EventUtils.Event = new EventUtils();
1120 return EventUtils;
1121 }();
1122
1123 var i, support, Expr, getText, isXML, tokenize, compile, select, outermostContext, sortInput, hasDuplicate, setDocument, document, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains$1, expando = 'sizzle' + -new Date(), preferredDoc = domGlobals.window.document, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), sortOrder = function (a, b) {
1124 if (a === b) {
1125 hasDuplicate = true;
1126 }
1127 return 0;
1128 }, strundefined = typeof undefined, MAX_NEGATIVE = 1 << 31, hasOwn = {}.hasOwnProperty, arr = [], pop = arr.pop, push_native = arr.push, push$1 = arr.push, slice$1 = arr.slice, indexOf$1 = arr.indexOf || function (elem) {
1129 var i = 0, len = this.length;
1130 for (; i < len; i++) {
1131 if (this[i] === elem) {
1132 return i;
1133 }
1134 }
1135 return -1;
1136 }, booleans = 'checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped', whitespace = '[\\x20\\t\\r\\n\\f]', identifier = '(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+', attributes = '\\[' + whitespace + '*(' + identifier + ')(?:' + whitespace + '*([*^$|!~]?=)' + whitespace + '*(?:\'((?:\\\\.|[^\\\\\'])*)\'|"((?:\\\\.|[^\\\\"])*)"|(' + identifier + '))|)' + whitespace + '*\\]', pseudos = ':(' + identifier + ')(?:\\((' + '(\'((?:\\\\.|[^\\\\\'])*)\'|"((?:\\\\.|[^\\\\"])*)")|' + '((?:\\\\.|[^\\\\()[\\]]|' + attributes + ')*)|' + '.*' + ')\\)|)', rtrim = new RegExp('^' + whitespace + '+|((?:^|[^\\\\])(?:\\\\.)*)' + whitespace + '+$', 'g'), rcomma = new RegExp('^' + whitespace + '*,' + whitespace + '*'), rcombinators = new RegExp('^' + whitespace + '*([>+~]|' + whitespace + ')' + whitespace + '*'), rattributeQuotes = new RegExp('=' + whitespace + '*([^\\]\'"]*?)' + whitespace + '*\\]', 'g'), rpseudo = new RegExp(pseudos), ridentifier = new RegExp('^' + identifier + '$'), matchExpr = {
1137 ID: new RegExp('^#(' + identifier + ')'),
1138 CLASS: new RegExp('^\\.(' + identifier + ')'),
1139 TAG: new RegExp('^(' + identifier + '|[*])'),
1140 ATTR: new RegExp('^' + attributes),
1141 PSEUDO: new RegExp('^' + pseudos),
1142 CHILD: new RegExp('^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(' + whitespace + '*(even|odd|(([+-]|)(\\d*)n|)' + whitespace + '*(?:([+-]|)' + whitespace + '*(\\d+)|))' + whitespace + '*\\)|)', 'i'),
1143 bool: new RegExp('^(?:' + booleans + ')$', 'i'),
1144 needsContext: new RegExp('^' + whitespace + '*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(' + whitespace + '*((?:-\\d)?\\d*)' + whitespace + '*\\)|)(?=[^-]|$)', 'i')
1145 }, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, rescape = /'|\\/g, runescape = new RegExp('\\\\([\\da-f]{1,6}' + whitespace + '?|(' + whitespace + ')|.)', 'ig'), funescape = function (_, escaped, escapedWhitespace) {
1146 var high = '0x' + escaped - 65536;
1147 return high !== high || escapedWhitespace ? escaped : high < 0 ? String.fromCharCode(high + 65536) : String.fromCharCode(high >> 10 | 55296, high & 1023 | 56320);
1148 };
1149 try {
1150 push$1.apply(arr = slice$1.call(preferredDoc.childNodes), preferredDoc.childNodes);
1151 arr[preferredDoc.childNodes.length].nodeType;
1152 } catch (e) {
1153 push$1 = {
1154 apply: arr.length ? function (target, els) {
1155 push_native.apply(target, slice$1.call(els));
1156 } : function (target, els) {
1157 var j = target.length, i = 0;
1158 while (target[j++] = els[i++]) {
1159 }
1160 target.length = j - 1;
1161 }
1162 };
1163 }
1164 var Sizzle = function (selector, context, results, seed) {
1165 var match, elem, m, nodeType, i, groups, old, nid, newContext, newSelector;
1166 if ((context ? context.ownerDocument || context : preferredDoc) !== document) {
1167 setDocument(context);
1168 }
1169 context = context || document;
1170 results = results || [];
1171 if (!selector || typeof selector !== 'string') {
1172 return results;
1173 }
1174 if ((nodeType = context.nodeType) !== 1 && nodeType !== 9) {
1175 return [];
1176 }
1177 if (documentIsHTML && !seed) {
1178 if (match = rquickExpr.exec(selector)) {
1179 if (m = match[1]) {
1180 if (nodeType === 9) {
1181 elem = context.getElementById(m);
1182 if (elem && elem.parentNode) {
1183 if (elem.id === m) {
1184 results.push(elem);
1185 return results;
1186 }
1187 } else {
1188 return results;
1189 }
1190 } else {
1191 if (context.ownerDocument && (elem = context.ownerDocument.getElementById(m)) && contains$1(context, elem) && elem.id === m) {
1192 results.push(elem);
1193 return results;
1194 }
1195 }
1196 } else if (match[2]) {
1197 push$1.apply(results, context.getElementsByTagName(selector));
1198 return results;
1199 } else if ((m = match[3]) && support.getElementsByClassName) {
1200 push$1.apply(results, context.getElementsByClassName(m));
1201 return results;
1202 }
1203 }
1204 if (support.qsa && (!rbuggyQSA || !rbuggyQSA.test(selector))) {
1205 nid = old = expando;
1206 newContext = context;
1207 newSelector = nodeType === 9 && selector;
1208 if (nodeType === 1 && context.nodeName.toLowerCase() !== 'object') {
1209 groups = tokenize(selector);
1210 if (old = context.getAttribute('id')) {
1211 nid = old.replace(rescape, '\\$&');
1212 } else {
1213 context.setAttribute('id', nid);
1214 }
1215 nid = '[id=\'' + nid + '\'] ';
1216 i = groups.length;
1217 while (i--) {
1218 groups[i] = nid + toSelector(groups[i]);
1219 }
1220 newContext = rsibling.test(selector) && testContext(context.parentNode) || context;
1221 newSelector = groups.join(',');
1222 }
1223 if (newSelector) {
1224 try {
1225 push$1.apply(results, newContext.querySelectorAll(newSelector));
1226 return results;
1227 } catch (qsaError) {
1228 } finally {
1229 if (!old) {
1230 context.removeAttribute('id');
1231 }
1232 }
1233 }
1234 }
1235 }
1236 return select(selector.replace(rtrim, '$1'), context, results, seed);
1237 };
1238 function createCache() {
1239 var keys = [];
1240 function cache(key, value) {
1241 if (keys.push(key + ' ') > Expr.cacheLength) {
1242 delete cache[keys.shift()];
1243 }
1244 return cache[key + ' '] = value;
1245 }
1246 return cache;
1247 }
1248 function markFunction(fn) {
1249 fn[expando] = true;
1250 return fn;
1251 }
1252 function siblingCheck(a, b) {
1253 var cur = b && a, diff = cur && a.nodeType === 1 && b.nodeType === 1 && (~b.sourceIndex || MAX_NEGATIVE) - (~a.sourceIndex || MAX_NEGATIVE);
1254 if (diff) {
1255 return diff;
1256 }
1257 if (cur) {
1258 while (cur = cur.nextSibling) {
1259 if (cur === b) {
1260 return -1;
1261 }
1262 }
1263 }
1264 return a ? 1 : -1;
1265 }
1266 function createInputPseudo(type) {
1267 return function (elem) {
1268 var name = elem.nodeName.toLowerCase();
1269 return name === 'input' && elem.type === type;
1270 };
1271 }
1272 function createButtonPseudo(type) {
1273 return function (elem) {
1274 var name = elem.nodeName.toLowerCase();
1275 return (name === 'input' || name === 'button') && elem.type === type;
1276 };
1277 }
1278 function createPositionalPseudo(fn) {
1279 return markFunction(function (argument) {
1280 argument = +argument;
1281 return markFunction(function (seed, matches) {
1282 var j, matchIndexes = fn([], seed.length, argument), i = matchIndexes.length;
1283 while (i--) {
1284 if (seed[j = matchIndexes[i]]) {
1285 seed[j] = !(matches[j] = seed[j]);
1286 }
1287 }
1288 });
1289 });
1290 }
1291 function testContext(context) {
1292 return context && typeof context.getElementsByTagName !== strundefined && context;
1293 }
1294 support = Sizzle.support = {};
1295 isXML = Sizzle.isXML = function (elem) {
1296 var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1297 return documentElement ? documentElement.nodeName !== 'HTML' : false;
1298 };
1299 setDocument = Sizzle.setDocument = function (node) {
1300 var hasCompare, doc = node ? node.ownerDocument || node : preferredDoc, parent = doc.defaultView;
1301 function getTop(win) {
1302 try {
1303 return win.top;
1304 } catch (ex) {
1305 }
1306 return null;
1307 }
1308 if (doc === document || doc.nodeType !== 9 || !doc.documentElement) {
1309 return document;
1310 }
1311 document = doc;
1312 docElem = doc.documentElement;
1313 documentIsHTML = !isXML(doc);
1314 if (parent && parent !== getTop(parent)) {
1315 if (parent.addEventListener) {
1316 parent.addEventListener('unload', function () {
1317 setDocument();
1318 }, false);
1319 } else if (parent.attachEvent) {
1320 parent.attachEvent('onunload', function () {
1321 setDocument();
1322 });
1323 }
1324 }
1325 support.attributes = true;
1326 support.getElementsByTagName = true;
1327 support.getElementsByClassName = rnative.test(doc.getElementsByClassName);
1328 support.getById = true;
1329 Expr.find.ID = function (id, context) {
1330 if (typeof context.getElementById !== strundefined && documentIsHTML) {
1331 var m = context.getElementById(id);
1332 return m && m.parentNode ? [m] : [];
1333 }
1334 };
1335 Expr.filter.ID = function (id) {
1336 var attrId = id.replace(runescape, funescape);
1337 return function (elem) {
1338 return elem.getAttribute('id') === attrId;
1339 };
1340 };
1341 Expr.find.TAG = support.getElementsByTagName ? function (tag, context) {
1342 if (typeof context.getElementsByTagName !== strundefined) {
1343 return context.getElementsByTagName(tag);
1344 }
1345 } : function (tag, context) {
1346 var elem, tmp = [], i = 0, results = context.getElementsByTagName(tag);
1347 if (tag === '*') {
1348 while (elem = results[i++]) {
1349 if (elem.nodeType === 1) {
1350 tmp.push(elem);
1351 }
1352 }
1353 return tmp;
1354 }
1355 return results;
1356 };
1357 Expr.find.CLASS = support.getElementsByClassName && function (className, context) {
1358 if (documentIsHTML) {
1359 return context.getElementsByClassName(className);
1360 }
1361 };
1362 rbuggyMatches = [];
1363 rbuggyQSA = [];
1364 support.disconnectedMatch = true;
1365 rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join('|'));
1366 rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join('|'));
1367 hasCompare = rnative.test(docElem.compareDocumentPosition);
1368 contains$1 = hasCompare || rnative.test(docElem.contains) ? function (a, b) {
1369 var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode;
1370 return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16));
1371 } : function (a, b) {
1372 if (b) {
1373 while (b = b.parentNode) {
1374 if (b === a) {
1375 return true;
1376 }
1377 }
1378 }
1379 return false;
1380 };
1381 sortOrder = hasCompare ? function (a, b) {
1382 if (a === b) {
1383 hasDuplicate = true;
1384 return 0;
1385 }
1386 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1387 if (compare) {
1388 return compare;
1389 }
1390 compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1;
1391 if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) {
1392 if (a === doc || a.ownerDocument === preferredDoc && contains$1(preferredDoc, a)) {
1393 return -1;
1394 }
1395 if (b === doc || b.ownerDocument === preferredDoc && contains$1(preferredDoc, b)) {
1396 return 1;
1397 }
1398 return sortInput ? indexOf$1.call(sortInput, a) - indexOf$1.call(sortInput, b) : 0;
1399 }
1400 return compare & 4 ? -1 : 1;
1401 } : function (a, b) {
1402 if (a === b) {
1403 hasDuplicate = true;
1404 return 0;
1405 }
1406 var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [a], bp = [b];
1407 if (!aup || !bup) {
1408 return a === doc ? -1 : b === doc ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf$1.call(sortInput, a) - indexOf$1.call(sortInput, b) : 0;
1409 } else if (aup === bup) {
1410 return siblingCheck(a, b);
1411 }
1412 cur = a;
1413 while (cur = cur.parentNode) {
1414 ap.unshift(cur);
1415 }
1416 cur = b;
1417 while (cur = cur.parentNode) {
1418 bp.unshift(cur);
1419 }
1420 while (ap[i] === bp[i]) {
1421 i++;
1422 }
1423 return i ? siblingCheck(ap[i], bp[i]) : ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0;
1424 };
1425 return doc;
1426 };
1427 Sizzle.matches = function (expr, elements) {
1428 return Sizzle(expr, null, null, elements);
1429 };
1430 Sizzle.matchesSelector = function (elem, expr) {
1431 if ((elem.ownerDocument || elem) !== document) {
1432 setDocument(elem);
1433 }
1434 expr = expr.replace(rattributeQuotes, '=\'$1\']');
1435 if (support.matchesSelector && documentIsHTML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) {
1436 try {
1437 var ret = matches.call(elem, expr);
1438 if (ret || support.disconnectedMatch || elem.document && elem.document.nodeType !== 11) {
1439 return ret;
1440 }
1441 } catch (e) {
1442 }
1443 }
1444 return Sizzle(expr, document, null, [elem]).length > 0;
1445 };
1446 Sizzle.contains = function (context, elem) {
1447 if ((context.ownerDocument || context) !== document) {
1448 setDocument(context);
1449 }
1450 return contains$1(context, elem);
1451 };
1452 Sizzle.attr = function (elem, name) {
1453 if ((elem.ownerDocument || elem) !== document) {
1454 setDocument(elem);
1455 }
1456 var fn = Expr.attrHandle[name.toLowerCase()], val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined;
1457 return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null;
1458 };
1459 Sizzle.error = function (msg) {
1460 throw new Error('Syntax error, unrecognized expression: ' + msg);
1461 };
1462 Sizzle.uniqueSort = function (results) {
1463 var elem, duplicates = [], j = 0, i = 0;
1464 hasDuplicate = !support.detectDuplicates;
1465 sortInput = !support.sortStable && results.slice(0);
1466 results.sort(sortOrder);
1467 if (hasDuplicate) {
1468 while (elem = results[i++]) {
1469 if (elem === results[i]) {
1470 j = duplicates.push(i);
1471 }
1472 }
1473 while (j--) {
1474 results.splice(duplicates[j], 1);
1475 }
1476 }
1477 sortInput = null;
1478 return results;
1479 };
1480 getText = Sizzle.getText = function (elem) {
1481 var node, ret = '', i = 0, nodeType = elem.nodeType;
1482 if (!nodeType) {
1483 while (node = elem[i++]) {
1484 ret += getText(node);
1485 }
1486 } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
1487 if (typeof elem.textContent === 'string') {
1488 return elem.textContent;
1489 } else {
1490 for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
1491 ret += getText(elem);
1492 }
1493 }
1494 } else if (nodeType === 3 || nodeType === 4) {
1495 return elem.nodeValue;
1496 }
1497 return ret;
1498 };
1499 Expr = Sizzle.selectors = {
1500 cacheLength: 50,
1501 createPseudo: markFunction,
1502 match: matchExpr,
1503 attrHandle: {},
1504 find: {},
1505 relative: {
1506 '>': {
1507 dir: 'parentNode',
1508 first: true
1509 },
1510 ' ': { dir: 'parentNode' },
1511 '+': {
1512 dir: 'previousSibling',
1513 first: true
1514 },
1515 '~': { dir: 'previousSibling' }
1516 },
1517 preFilter: {
1518 ATTR: function (match) {
1519 match[1] = match[1].replace(runescape, funescape);
1520 match[3] = (match[3] || match[4] || match[5] || '').replace(runescape, funescape);
1521 if (match[2] === '~=') {
1522 match[3] = ' ' + match[3] + ' ';
1523 }
1524 return match.slice(0, 4);
1525 },
1526 CHILD: function (match) {
1527 match[1] = match[1].toLowerCase();
1528 if (match[1].slice(0, 3) === 'nth') {
1529 if (!match[3]) {
1530 Sizzle.error(match[0]);
1531 }
1532 match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === 'even' || match[3] === 'odd'));
1533 match[5] = +(match[7] + match[8] || match[3] === 'odd');
1534 } else if (match[3]) {
1535 Sizzle.error(match[0]);
1536 }
1537 return match;
1538 },
1539 PSEUDO: function (match) {
1540 var excess, unquoted = !match[6] && match[2];
1541 if (matchExpr.CHILD.test(match[0])) {
1542 return null;
1543 }
1544 if (match[3]) {
1545 match[2] = match[4] || match[5] || '';
1546 } else if (unquoted && rpseudo.test(unquoted) && (excess = tokenize(unquoted, true)) && (excess = unquoted.indexOf(')', unquoted.length - excess) - unquoted.length)) {
1547 match[0] = match[0].slice(0, excess);
1548 match[2] = unquoted.slice(0, excess);
1549 }
1550 return match.slice(0, 3);
1551 }
1552 },
1553 filter: {
1554 TAG: function (nodeNameSelector) {
1555 var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
1556 return nodeNameSelector === '*' ? function () {
1557 return true;
1558 } : function (elem) {
1559 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1560 };
1561 },
1562 CLASS: function (className) {
1563 var pattern = classCache[className + ' '];
1564 return pattern || (pattern = new RegExp('(^|' + whitespace + ')' + className + '(' + whitespace + '|$)')) && classCache(className, function (elem) {
1565 return pattern.test(typeof elem.className === 'string' && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute('class') || '');
1566 });
1567 },
1568 ATTR: function (name, operator, check) {
1569 return function (elem) {
1570 var result = Sizzle.attr(elem, name);
1571 if (result == null) {
1572 return operator === '!=';
1573 }
1574 if (!operator) {
1575 return true;
1576 }
1577 result += '';
1578 return operator === '=' ? result === check : operator === '!=' ? result !== check : operator === '^=' ? check && result.indexOf(check) === 0 : operator === '*=' ? check && result.indexOf(check) > -1 : operator === '$=' ? check && result.slice(-check.length) === check : operator === '~=' ? (' ' + result + ' ').indexOf(check) > -1 : operator === '|=' ? result === check || result.slice(0, check.length + 1) === check + '-' : false;
1579 };
1580 },
1581 CHILD: function (type, what, argument, first, last) {
1582 var simple = type.slice(0, 3) !== 'nth', forward = type.slice(-4) !== 'last', ofType = what === 'of-type';
1583 return first === 1 && last === 0 ? function (elem) {
1584 return !!elem.parentNode;
1585 } : function (elem, context, xml) {
1586 var cache, outerCache, node, diff, nodeIndex, start, dir = simple !== forward ? 'nextSibling' : 'previousSibling', parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType;
1587 if (parent) {
1588 if (simple) {
1589 while (dir) {
1590 node = elem;
1591 while (node = node[dir]) {
1592 if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) {
1593 return false;
1594 }
1595 }
1596 start = dir = type === 'only' && !start && 'nextSibling';
1597 }
1598 return true;
1599 }
1600 start = [forward ? parent.firstChild : parent.lastChild];
1601 if (forward && useCache) {
1602 outerCache = parent[expando] || (parent[expando] = {});
1603 cache = outerCache[type] || [];
1604 nodeIndex = cache[0] === dirruns && cache[1];
1605 diff = cache[0] === dirruns && cache[2];
1606 node = nodeIndex && parent.childNodes[nodeIndex];
1607 while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
1608 if (node.nodeType === 1 && ++diff && node === elem) {
1609 outerCache[type] = [
1610 dirruns,
1611 nodeIndex,
1612 diff
1613 ];
1614 break;
1615 }
1616 }
1617 } else if (useCache && (cache = (elem[expando] || (elem[expando] = {}))[type]) && cache[0] === dirruns) {
1618 diff = cache[1];
1619 } else {
1620 while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
1621 if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) {
1622 if (useCache) {
1623 (node[expando] || (node[expando] = {}))[type] = [
1624 dirruns,
1625 diff
1626 ];
1627 }
1628 if (node === elem) {
1629 break;
1630 }
1631 }
1632 }
1633 }
1634 diff -= last;
1635 return diff === first || diff % first === 0 && diff / first >= 0;
1636 }
1637 };
1638 },
1639 PSEUDO: function (pseudo, argument) {
1640 var args, fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error('unsupported pseudo: ' + pseudo);
1641 if (fn[expando]) {
1642 return fn(argument);
1643 }
1644 if (fn.length > 1) {
1645 args = [
1646 pseudo,
1647 pseudo,
1648 '',
1649 argument
1650 ];
1651 return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) {
1652 var idx, matched = fn(seed, argument), i = matched.length;
1653 while (i--) {
1654 idx = indexOf$1.call(seed, matched[i]);
1655 seed[idx] = !(matches[idx] = matched[i]);
1656 }
1657 }) : function (elem) {
1658 return fn(elem, 0, args);
1659 };
1660 }
1661 return fn;
1662 }
1663 },
1664 pseudos: {
1665 not: markFunction(function (selector) {
1666 var input = [], results = [], matcher = compile(selector.replace(rtrim, '$1'));
1667 return matcher[expando] ? markFunction(function (seed, matches, context, xml) {
1668 var elem, unmatched = matcher(seed, null, xml, []), i = seed.length;
1669 while (i--) {
1670 if (elem = unmatched[i]) {
1671 seed[i] = !(matches[i] = elem);
1672 }
1673 }
1674 }) : function (elem, context, xml) {
1675 input[0] = elem;
1676 matcher(input, null, xml, results);
1677 return !results.pop();
1678 };
1679 }),
1680 has: markFunction(function (selector) {
1681 return function (elem) {
1682 return Sizzle(selector, elem).length > 0;
1683 };
1684 }),
1685 contains: markFunction(function (text) {
1686 text = text.replace(runescape, funescape);
1687 return function (elem) {
1688 return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1;
1689 };
1690 }),
1691 lang: markFunction(function (lang) {
1692 if (!ridentifier.test(lang || '')) {
1693 Sizzle.error('unsupported lang: ' + lang);
1694 }
1695 lang = lang.replace(runescape, funescape).toLowerCase();
1696 return function (elem) {
1697 var elemLang;
1698 do {
1699 if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute('xml:lang') || elem.getAttribute('lang')) {
1700 elemLang = elemLang.toLowerCase();
1701 return elemLang === lang || elemLang.indexOf(lang + '-') === 0;
1702 }
1703 } while ((elem = elem.parentNode) && elem.nodeType === 1);
1704 return false;
1705 };
1706 }),
1707 target: function (elem) {
1708 var hash = domGlobals.window.location && domGlobals.window.location.hash;
1709 return hash && hash.slice(1) === elem.id;
1710 },
1711 root: function (elem) {
1712 return elem === docElem;
1713 },
1714 focus: function (elem) {
1715 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1716 },
1717 enabled: function (elem) {
1718 return elem.disabled === false;
1719 },
1720 disabled: function (elem) {
1721 return elem.disabled === true;
1722 },
1723 checked: function (elem) {
1724 var nodeName = elem.nodeName.toLowerCase();
1725 return nodeName === 'input' && !!elem.checked || nodeName === 'option' && !!elem.selected;
1726 },
1727 selected: function (elem) {
1728 if (elem.parentNode) {
1729 elem.parentNode.selectedIndex;
1730 }
1731 return elem.selected === true;
1732 },
1733 empty: function (elem) {
1734 for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
1735 if (elem.nodeType < 6) {
1736 return false;
1737 }
1738 }
1739 return true;
1740 },
1741 parent: function (elem) {
1742 return !Expr.pseudos.empty(elem);
1743 },
1744 header: function (elem) {
1745 return rheader.test(elem.nodeName);
1746 },
1747 input: function (elem) {
1748 return rinputs.test(elem.nodeName);
1749 },
1750 button: function (elem) {
1751 var name = elem.nodeName.toLowerCase();
1752 return name === 'input' && elem.type === 'button' || name === 'button';
1753 },
1754 text: function (elem) {
1755 var attr;
1756 return elem.nodeName.toLowerCase() === 'input' && elem.type === 'text' && ((attr = elem.getAttribute('type')) == null || attr.toLowerCase() === 'text');
1757 },
1758 first: createPositionalPseudo(function () {
1759 return [0];
1760 }),
1761 last: createPositionalPseudo(function (matchIndexes, length) {
1762 return [length - 1];
1763 }),
1764 eq: createPositionalPseudo(function (matchIndexes, length, argument) {
1765 return [argument < 0 ? argument + length : argument];
1766 }),
1767 even: createPositionalPseudo(function (matchIndexes, length) {
1768 var i = 0;
1769 for (; i < length; i += 2) {
1770 matchIndexes.push(i);
1771 }
1772 return matchIndexes;
1773 }),
1774 odd: createPositionalPseudo(function (matchIndexes, length) {
1775 var i = 1;
1776 for (; i < length; i += 2) {
1777 matchIndexes.push(i);
1778 }
1779 return matchIndexes;
1780 }),
1781 lt: createPositionalPseudo(function (matchIndexes, length, argument) {
1782 var i = argument < 0 ? argument + length : argument;
1783 for (; --i >= 0;) {
1784 matchIndexes.push(i);
1785 }
1786 return matchIndexes;
1787 }),
1788 gt: createPositionalPseudo(function (matchIndexes, length, argument) {
1789 var i = argument < 0 ? argument + length : argument;
1790 for (; ++i < length;) {
1791 matchIndexes.push(i);
1792 }
1793 return matchIndexes;
1794 })
1795 }
1796 };
1797 Expr.pseudos.nth = Expr.pseudos.eq;
1798 for (i in {
1799 radio: true,
1800 checkbox: true,
1801 file: true,
1802 password: true,
1803 image: true
1804 }) {
1805 Expr.pseudos[i] = createInputPseudo(i);
1806 }
1807 for (i in {
1808 submit: true,
1809 reset: true
1810 }) {
1811 Expr.pseudos[i] = createButtonPseudo(i);
1812 }
1813 function setFilters() {
1814 }
1815 setFilters.prototype = Expr.filters = Expr.pseudos;
1816 Expr.setFilters = new setFilters();
1817 tokenize = Sizzle.tokenize = function (selector, parseOnly) {
1818 var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[selector + ' '];
1819 if (cached) {
1820 return parseOnly ? 0 : cached.slice(0);
1821 }
1822 soFar = selector;
1823 groups = [];
1824 preFilters = Expr.preFilter;
1825 while (soFar) {
1826 if (!matched || (match = rcomma.exec(soFar))) {
1827 if (match) {
1828 soFar = soFar.slice(match[0].length) || soFar;
1829 }
1830 groups.push(tokens = []);
1831 }
1832 matched = false;
1833 if (match = rcombinators.exec(soFar)) {
1834 matched = match.shift();
1835 tokens.push({
1836 value: matched,
1837 type: match[0].replace(rtrim, ' ')
1838 });
1839 soFar = soFar.slice(matched.length);
1840 }
1841 for (type in Expr.filter) {
1842 if (!Expr.filter.hasOwnProperty(type))
1843 continue;
1844 if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) {
1845 matched = match.shift();
1846 tokens.push({
1847 value: matched,
1848 type: type,
1849 matches: match
1850 });
1851 soFar = soFar.slice(matched.length);
1852 }
1853 }
1854 if (!matched) {
1855 break;
1856 }
1857 }
1858 return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) : tokenCache(selector, groups).slice(0);
1859 };
1860 function toSelector(tokens) {
1861 var i = 0, len = tokens.length, selector = '';
1862 for (; i < len; i++) {
1863 selector += tokens[i].value;
1864 }
1865 return selector;
1866 }
1867 function addCombinator(matcher, combinator, base) {
1868 var dir = combinator.dir, checkNonElements = base && dir === 'parentNode', doneName = done++;
1869 return combinator.first ? function (elem, context, xml) {
1870 while (elem = elem[dir]) {
1871 if (elem.nodeType === 1 || checkNonElements) {
1872 return matcher(elem, context, xml);
1873 }
1874 }
1875 } : function (elem, context, xml) {
1876 var oldCache, outerCache, newCache = [
1877 dirruns,
1878 doneName
1879 ];
1880 if (xml) {
1881 while (elem = elem[dir]) {
1882 if (elem.nodeType === 1 || checkNonElements) {
1883 if (matcher(elem, context, xml)) {
1884 return true;
1885 }
1886 }
1887 }
1888 } else {
1889 while (elem = elem[dir]) {
1890 if (elem.nodeType === 1 || checkNonElements) {
1891 outerCache = elem[expando] || (elem[expando] = {});
1892 if ((oldCache = outerCache[dir]) && oldCache[0] === dirruns && oldCache[1] === doneName) {
1893 return newCache[2] = oldCache[2];
1894 } else {
1895 outerCache[dir] = newCache;
1896 if (newCache[2] = matcher(elem, context, xml)) {
1897 return true;
1898 }
1899 }
1900 }
1901 }
1902 }
1903 };
1904 }
1905 function elementMatcher(matchers) {
1906 return matchers.length > 1 ? function (elem, context, xml) {
1907 var i = matchers.length;
1908 while (i--) {
1909 if (!matchers[i](elem, context, xml)) {
1910 return false;
1911 }
1912 }
1913 return true;
1914 } : matchers[0];
1915 }
1916 function multipleContexts(selector, contexts, results) {
1917 var i = 0, len = contexts.length;
1918 for (; i < len; i++) {
1919 Sizzle(selector, contexts[i], results);
1920 }
1921 return results;
1922 }
1923 function condense(unmatched, map, filter, context, xml) {
1924 var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null;
1925 for (; i < len; i++) {
1926 if (elem = unmatched[i]) {
1927 if (!filter || filter(elem, context, xml)) {
1928 newUnmatched.push(elem);
1929 if (mapped) {
1930 map.push(i);
1931 }
1932 }
1933 }
1934 }
1935 return newUnmatched;
1936 }
1937 function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
1938 if (postFilter && !postFilter[expando]) {
1939 postFilter = setMatcher(postFilter);
1940 }
1941 if (postFinder && !postFinder[expando]) {
1942 postFinder = setMatcher(postFinder, postSelector);
1943 }
1944 return markFunction(function (seed, results, context, xml) {
1945 var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, elems = seed || multipleContexts(selector || '*', context.nodeType ? [context] : context, []), matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems, matcherOut = matcher ? postFinder || (seed ? preFilter : preexisting || postFilter) ? [] : results : matcherIn;
1946 if (matcher) {
1947 matcher(matcherIn, matcherOut, context, xml);
1948 }
1949 if (postFilter) {
1950 temp = condense(matcherOut, postMap);
1951 postFilter(temp, [], context, xml);
1952 i = temp.length;
1953 while (i--) {
1954 if (elem = temp[i]) {
1955 matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
1956 }
1957 }
1958 }
1959 if (seed) {
1960 if (postFinder || preFilter) {
1961 if (postFinder) {
1962 temp = [];
1963 i = matcherOut.length;
1964 while (i--) {
1965 if (elem = matcherOut[i]) {
1966 temp.push(matcherIn[i] = elem);
1967 }
1968 }
1969 postFinder(null, matcherOut = [], temp, xml);
1970 }
1971 i = matcherOut.length;
1972 while (i--) {
1973 if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf$1.call(seed, elem) : preMap[i]) > -1) {
1974 seed[temp] = !(results[temp] = elem);
1975 }
1976 }
1977 }
1978 } else {
1979 matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut);
1980 if (postFinder) {
1981 postFinder(null, results, matcherOut, xml);
1982 } else {
1983 push$1.apply(results, matcherOut);
1984 }
1985 }
1986 });
1987 }
1988 function matcherFromTokens(tokens) {
1989 var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[tokens[0].type], implicitRelative = leadingRelative || Expr.relative[' '], i = leadingRelative ? 1 : 0, matchContext = addCombinator(function (elem) {
1990 return elem === checkContext;
1991 }, implicitRelative, true), matchAnyContext = addCombinator(function (elem) {
1992 return indexOf$1.call(checkContext, elem) > -1;
1993 }, implicitRelative, true), matchers = [function (elem, context, xml) {
1994 return !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml));
1995 }];
1996 for (; i < len; i++) {
1997 if (matcher = Expr.relative[tokens[i].type]) {
1998 matchers = [addCombinator(elementMatcher(matchers), matcher)];
1999 } else {
2000 matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);
2001 if (matcher[expando]) {
2002 j = ++i;
2003 for (; j < len; j++) {
2004 if (Expr.relative[tokens[j].type]) {
2005 break;
2006 }
2007 }
2008 return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector(tokens.slice(0, i - 1).concat({ value: tokens[i - 2].type === ' ' ? '*' : '' })).replace(rtrim, '$1'), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens));
2009 }
2010 matchers.push(matcher);
2011 }
2012 }
2013 return elementMatcher(matchers);
2014 }
2015 function matcherFromGroupMatchers(elementMatchers, setMatchers) {
2016 var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function (seed, context, xml, results, outermost) {
2017 var elem, j, matcher, matchedCount = 0, i = '0', unmatched = seed && [], setMatched = [], contextBackup = outermostContext, elems = seed || byElement && Expr.find.TAG('*', outermost), dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1, len = elems.length;
2018 if (outermost) {
2019 outermostContext = context !== document && context;
2020 }
2021 for (; i !== len && (elem = elems[i]) != null; i++) {
2022 if (byElement && elem) {
2023 j = 0;
2024 while (matcher = elementMatchers[j++]) {
2025 if (matcher(elem, context, xml)) {
2026 results.push(elem);
2027 break;
2028 }
2029 }
2030 if (outermost) {
2031 dirruns = dirrunsUnique;
2032 }
2033 }
2034 if (bySet) {
2035 if (elem = !matcher && elem) {
2036 matchedCount--;
2037 }
2038 if (seed) {
2039 unmatched.push(elem);
2040 }
2041 }
2042 }
2043 matchedCount += i;
2044 if (bySet && i !== matchedCount) {
2045 j = 0;
2046 while (matcher = setMatchers[j++]) {
2047 matcher(unmatched, setMatched, context, xml);
2048 }
2049 if (seed) {
2050 if (matchedCount > 0) {
2051 while (i--) {
2052 if (!(unmatched[i] || setMatched[i])) {
2053 setMatched[i] = pop.call(results);
2054 }
2055 }
2056 }
2057 setMatched = condense(setMatched);
2058 }
2059 push$1.apply(results, setMatched);
2060 if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) {
2061 Sizzle.uniqueSort(results);
2062 }
2063 }
2064 if (outermost) {
2065 dirruns = dirrunsUnique;
2066 outermostContext = contextBackup;
2067 }
2068 return unmatched;
2069 };
2070 return bySet ? markFunction(superMatcher) : superMatcher;
2071 }
2072 compile = Sizzle.compile = function (selector, match) {
2073 var i, setMatchers = [], elementMatchers = [], cached = compilerCache[selector + ' '];
2074 if (!cached) {
2075 if (!match) {
2076 match = tokenize(selector);
2077 }
2078 i = match.length;
2079 while (i--) {
2080 cached = matcherFromTokens(match[i]);
2081 if (cached[expando]) {
2082 setMatchers.push(cached);
2083 } else {
2084 elementMatchers.push(cached);
2085 }
2086 }
2087 cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers));
2088 cached.selector = selector;
2089 }
2090 return cached;
2091 };
2092 select = Sizzle.select = function (selector, context, results, seed) {
2093 var i, tokens, token, type, find, compiled = typeof selector === 'function' && selector, match = !seed && tokenize(selector = compiled.selector || selector);
2094 results = results || [];
2095 if (match.length === 1) {
2096 tokens = match[0] = match[0].slice(0);
2097 if (tokens.length > 2 && (token = tokens[0]).type === 'ID' && support.getById && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {
2098 context = (Expr.find.ID(token.matches[0].replace(runescape, funescape), context) || [])[0];
2099 if (!context) {
2100 return results;
2101 } else if (compiled) {
2102 context = context.parentNode;
2103 }
2104 selector = selector.slice(tokens.shift().value.length);
2105 }
2106 i = matchExpr.needsContext.test(selector) ? 0 : tokens.length;
2107 while (i--) {
2108 token = tokens[i];
2109 if (Expr.relative[type = token.type]) {
2110 break;
2111 }
2112 if (find = Expr.find[type]) {
2113 if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testContext(context.parentNode) || context)) {
2114 tokens.splice(i, 1);
2115 selector = seed.length && toSelector(tokens);
2116 if (!selector) {
2117 push$1.apply(results, seed);
2118 return results;
2119 }
2120 break;
2121 }
2122 }
2123 }
2124 }
2125 (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, rsibling.test(selector) && testContext(context.parentNode) || context);
2126 return results;
2127 };
2128 support.sortStable = expando.split('').sort(sortOrder).join('') === expando;
2129 support.detectDuplicates = !!hasDuplicate;
2130 setDocument();
2131 support.sortDetached = true;
2132
2133 var isArray$1 = Array.isArray;
2134 var toArray = function (obj) {
2135 var array = obj, i, l;
2136 if (!isArray$1(obj)) {
2137 array = [];
2138 for (i = 0, l = obj.length; i < l; i++) {
2139 array[i] = obj[i];
2140 }
2141 }
2142 return array;
2143 };
2144 var each$1 = function (o, cb, s) {
2145 var n, l;
2146 if (!o) {
2147 return 0;
2148 }
2149 s = s || o;
2150 if (o.length !== undefined) {
2151 for (n = 0, l = o.length; n < l; n++) {
2152 if (cb.call(s, o[n], n, o) === false) {
2153 return 0;
2154 }
2155 }
2156 } else {
2157 for (n in o) {
2158 if (o.hasOwnProperty(n)) {
2159 if (cb.call(s, o[n], n, o) === false) {
2160 return 0;
2161 }
2162 }
2163 }
2164 }
2165 return 1;
2166 };
2167 var map$1 = function (array, callback) {
2168 var out = [];
2169 each$1(array, function (item, index) {
2170 out.push(callback(item, index, array));
2171 });
2172 return out;
2173 };
2174 var filter$1 = function (a, f) {
2175 var o = [];
2176 each$1(a, function (v, index) {
2177 if (!f || f(v, index, a)) {
2178 o.push(v);
2179 }
2180 });
2181 return o;
2182 };
2183 var indexOf$2 = function (a, v) {
2184 var i, l;
2185 if (a) {
2186 for (i = 0, l = a.length; i < l; i++) {
2187 if (a[i] === v) {
2188 return i;
2189 }
2190 }
2191 }
2192 return -1;
2193 };
2194 var reduce = function (collection, iteratee, accumulator, thisArg) {
2195 var i = 0;
2196 if (arguments.length < 3) {
2197 accumulator = collection[0];
2198 }
2199 for (; i < collection.length; i++) {
2200 accumulator = iteratee.call(thisArg, accumulator, collection[i], i);
2201 }
2202 return accumulator;
2203 };
2204 var findIndex$1 = function (array, predicate, thisArg) {
2205 var i, l;
2206 for (i = 0, l = array.length; i < l; i++) {
2207 if (predicate.call(thisArg, array[i], i, array)) {
2208 return i;
2209 }
2210 }
2211 return -1;
2212 };
2213 var find$1 = function (array, predicate, thisArg) {
2214 var idx = findIndex$1(array, predicate, thisArg);
2215 if (idx !== -1) {
2216 return array[idx];
2217 }
2218 return undefined;
2219 };
2220 var last$1 = function (collection) {
2221 return collection[collection.length - 1];
2222 };
2223 var ArrUtils = {
2224 isArray: isArray$1,
2225 toArray: toArray,
2226 each: each$1,
2227 map: map$1,
2228 filter: filter$1,
2229 indexOf: indexOf$2,
2230 reduce: reduce,
2231 findIndex: findIndex$1,
2232 find: find$1,
2233 last: last$1
2234 };
2235
2236 var whiteSpaceRegExp = /^\s*|\s*$/g;
2237 var trim = function (str) {
2238 return str === null || str === undefined ? '' : ('' + str).replace(whiteSpaceRegExp, '');
2239 };
2240 var is = function (obj, type) {
2241 if (!type) {
2242 return obj !== undefined;
2243 }
2244 if (type === 'array' && ArrUtils.isArray(obj)) {
2245 return true;
2246 }
2247 return typeof obj === type;
2248 };
2249 var makeMap = function (items, delim, map) {
2250 var i;
2251 items = items || [];
2252 delim = delim || ',';
2253 if (typeof items === 'string') {
2254 items = items.split(delim);
2255 }
2256 map = map || {};
2257 i = items.length;
2258 while (i--) {
2259 map[items[i]] = {};
2260 }
2261 return map;
2262 };
2263 var hasOwnProperty = function (obj, prop) {
2264 return Object.prototype.hasOwnProperty.call(obj, prop);
2265 };
2266 var create = function (s, p, root) {
2267 var self = this;
2268 var sp, ns, cn, scn, c, de = 0;
2269 s = /^((static) )?([\w.]+)(:([\w.]+))?/.exec(s);
2270 cn = s[3].match(/(^|\.)(\w+)$/i)[2];
2271 ns = self.createNS(s[3].replace(/\.\w+$/, ''), root);
2272 if (ns[cn]) {
2273 return;
2274 }
2275 if (s[2] === 'static') {
2276 ns[cn] = p;
2277 if (this.onCreate) {
2278 this.onCreate(s[2], s[3], ns[cn]);
2279 }
2280 return;
2281 }
2282 if (!p[cn]) {
2283 p[cn] = function () {
2284 };
2285 de = 1;
2286 }
2287 ns[cn] = p[cn];
2288 self.extend(ns[cn].prototype, p);
2289 if (s[5]) {
2290 sp = self.resolve(s[5]).prototype;
2291 scn = s[5].match(/\.(\w+)$/i)[1];
2292 c = ns[cn];
2293 if (de) {
2294 ns[cn] = function () {
2295 return sp[scn].apply(this, arguments);
2296 };
2297 } else {
2298 ns[cn] = function () {
2299 this.parent = sp[scn];
2300 return c.apply(this, arguments);
2301 };
2302 }
2303 ns[cn].prototype[cn] = ns[cn];
2304 self.each(sp, function (f, n) {
2305 ns[cn].prototype[n] = sp[n];
2306 });
2307 self.each(p, function (f, n) {
2308 if (sp[n]) {
2309 ns[cn].prototype[n] = function () {
2310 this.parent = sp[n];
2311 return f.apply(this, arguments);
2312 };
2313 } else {
2314 if (n !== cn) {
2315 ns[cn].prototype[n] = f;
2316 }
2317 }
2318 });
2319 }
2320 self.each(p.static, function (f, n) {
2321 ns[cn][n] = f;
2322 });
2323 };
2324 var extend = function (obj, ext) {
2325 var x = [];
2326 for (var _i = 2; _i < arguments.length; _i++) {
2327 x[_i - 2] = arguments[_i];
2328 }
2329 var i, l, name;
2330 var args = arguments;
2331 var value;
2332 for (i = 1, l = args.length; i < l; i++) {
2333 ext = args[i];
2334 for (name in ext) {
2335 if (ext.hasOwnProperty(name)) {
2336 value = ext[name];
2337 if (value !== undefined) {
2338 obj[name] = value;
2339 }
2340 }
2341 }
2342 }
2343 return obj;
2344 };
2345 var walk = function (o, f, n, s) {
2346 s = s || this;
2347 if (o) {
2348 if (n) {
2349 o = o[n];
2350 }
2351 ArrUtils.each(o, function (o, i) {
2352 if (f.call(s, o, i, n) === false) {
2353 return false;
2354 }
2355 walk(o, f, n, s);
2356 });
2357 }
2358 };
2359 var createNS = function (n, o) {
2360 var i, v;
2361 o = o || domGlobals.window;
2362 n = n.split('.');
2363 for (i = 0; i < n.length; i++) {
2364 v = n[i];
2365 if (!o[v]) {
2366 o[v] = {};
2367 }
2368 o = o[v];
2369 }
2370 return o;
2371 };
2372 var resolve$1 = function (n, o) {
2373 var i, l;
2374 o = o || domGlobals.window;
2375 n = n.split('.');
2376 for (i = 0, l = n.length; i < l; i++) {
2377 o = o[n[i]];
2378 if (!o) {
2379 break;
2380 }
2381 }
2382 return o;
2383 };
2384 var explode = function (s, d) {
2385 if (!s || is(s, 'array')) {
2386 return s;
2387 }
2388 return ArrUtils.map(s.split(d || ','), trim);
2389 };
2390 var _addCacheSuffix = function (url) {
2391 var cacheSuffix = Env.cacheSuffix;
2392 if (cacheSuffix) {
2393 url += (url.indexOf('?') === -1 ? '?' : '&') + cacheSuffix;
2394 }
2395 return url;
2396 };
2397 var Tools = {
2398 trim: trim,
2399 isArray: ArrUtils.isArray,
2400 is: is,
2401 toArray: ArrUtils.toArray,
2402 makeMap: makeMap,
2403 each: ArrUtils.each,
2404 map: ArrUtils.map,
2405 grep: ArrUtils.filter,
2406 inArray: ArrUtils.indexOf,
2407 hasOwn: hasOwnProperty,
2408 extend: extend,
2409 create: create,
2410 walk: walk,
2411 createNS: createNS,
2412 resolve: resolve$1,
2413 explode: explode,
2414 _addCacheSuffix: _addCacheSuffix
2415 };
2416
2417 var doc = domGlobals.document, push$2 = Array.prototype.push, slice$2 = Array.prototype.slice;
2418 var rquickExpr$1 = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/;
2419 var Event = EventUtils.Event;
2420 var skipUniques = Tools.makeMap('children,contents,next,prev');
2421 var isDefined = function (obj) {
2422 return typeof obj !== 'undefined';
2423 };
2424 var isString$1 = function (obj) {
2425 return typeof obj === 'string';
2426 };
2427 var isWindow = function (obj) {
2428 return obj && obj === obj.window;
2429 };
2430 var createFragment = function (html, fragDoc) {
2431 var frag, node, container;
2432 fragDoc = fragDoc || doc;
2433 container = fragDoc.createElement('div');
2434 frag = fragDoc.createDocumentFragment();
2435 container.innerHTML = html;
2436 while (node = container.firstChild) {
2437 frag.appendChild(node);
2438 }
2439 return frag;
2440 };
2441 var domManipulate = function (targetNodes, sourceItem, callback, reverse) {
2442 var i;
2443 if (isString$1(sourceItem)) {
2444 sourceItem = createFragment(sourceItem, getElementDocument(targetNodes[0]));
2445 } else if (sourceItem.length && !sourceItem.nodeType) {
2446 sourceItem = DomQuery.makeArray(sourceItem);
2447 if (reverse) {
2448 for (i = sourceItem.length - 1; i >= 0; i--) {
2449 domManipulate(targetNodes, sourceItem[i], callback, reverse);
2450 }
2451 } else {
2452 for (i = 0; i < sourceItem.length; i++) {
2453 domManipulate(targetNodes, sourceItem[i], callback, reverse);
2454 }
2455 }
2456 return targetNodes;
2457 }
2458 if (sourceItem.nodeType) {
2459 i = targetNodes.length;
2460 while (i--) {
2461 callback.call(targetNodes[i], sourceItem);
2462 }
2463 }
2464 return targetNodes;
2465 };
2466 var hasClass = function (node, className) {
2467 return node && className && (' ' + node.className + ' ').indexOf(' ' + className + ' ') !== -1;
2468 };
2469 var wrap = function (elements, wrapper, all) {
2470 var lastParent, newWrapper;
2471 wrapper = DomQuery(wrapper)[0];
2472 elements.each(function () {
2473 var self = this;
2474 if (!all || lastParent !== self.parentNode) {
2475 lastParent = self.parentNode;
2476 newWrapper = wrapper.cloneNode(false);
2477 self.parentNode.insertBefore(newWrapper, self);
2478 newWrapper.appendChild(self);
2479 } else {
2480 newWrapper.appendChild(self);
2481 }
2482 });
2483 return elements;
2484 };
2485 var numericCssMap = Tools.makeMap('fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom', ' ');
2486 var booleanMap = Tools.makeMap('checked compact declare defer disabled ismap multiple nohref noshade nowrap readonly selected', ' ');
2487 var propFix = {
2488 for: 'htmlFor',
2489 class: 'className',
2490 readonly: 'readOnly'
2491 };
2492 var cssFix = { float: 'cssFloat' };
2493 var attrHooks = {}, cssHooks = {};
2494 var DomQueryConstructor = function (selector, context) {
2495 return new DomQuery.fn.init(selector, context);
2496 };
2497 var inArray = function (item, array) {
2498 var i;
2499 if (array.indexOf) {
2500 return array.indexOf(item);
2501 }
2502 i = array.length;
2503 while (i--) {
2504 if (array[i] === item) {
2505 return i;
2506 }
2507 }
2508 return -1;
2509 };
2510 var whiteSpaceRegExp$1 = /^\s*|\s*$/g;
2511 var trim$1 = function (str) {
2512 return str === null || str === undefined ? '' : ('' + str).replace(whiteSpaceRegExp$1, '');
2513 };
2514 var each$2 = function (obj, callback) {
2515 var length, key, i, value;
2516 if (obj) {
2517 length = obj.length;
2518 if (length === undefined) {
2519 for (key in obj) {
2520 if (obj.hasOwnProperty(key)) {
2521 value = obj[key];
2522 if (callback.call(value, key, value) === false) {
2523 break;
2524 }
2525 }
2526 }
2527 } else {
2528 for (i = 0; i < length; i++) {
2529 value = obj[i];
2530 if (callback.call(value, i, value) === false) {
2531 break;
2532 }
2533 }
2534 }
2535 }
2536 return obj;
2537 };
2538 var grep = function (array, callback) {
2539 var out = [];
2540 each$2(array, function (i, item) {
2541 if (callback(item, i)) {
2542 out.push(item);
2543 }
2544 });
2545 return out;
2546 };
2547 var getElementDocument = function (element) {
2548 if (!element) {
2549 return doc;
2550 }
2551 if (element.nodeType === 9) {
2552 return element;
2553 }
2554 return element.ownerDocument;
2555 };
2556 DomQueryConstructor.fn = DomQueryConstructor.prototype = {
2557 constructor: DomQueryConstructor,
2558 selector: '',
2559 context: null,
2560 length: 0,
2561 init: function (selector, context) {
2562 var self = this;
2563 var match, node;
2564 if (!selector) {
2565 return self;
2566 }
2567 if (selector.nodeType) {
2568 self.context = self[0] = selector;
2569 self.length = 1;
2570 return self;
2571 }
2572 if (context && context.nodeType) {
2573 self.context = context;
2574 } else {
2575 if (context) {
2576 return DomQuery(selector).attr(context);
2577 }
2578 self.context = context = domGlobals.document;
2579 }
2580 if (isString$1(selector)) {
2581 self.selector = selector;
2582 if (selector.charAt(0) === '<' && selector.charAt(selector.length - 1) === '>' && selector.length >= 3) {
2583 match = [
2584 null,
2585 selector,
2586 null
2587 ];
2588 } else {
2589 match = rquickExpr$1.exec(selector);
2590 }
2591 if (match) {
2592 if (match[1]) {
2593 node = createFragment(selector, getElementDocument(context)).firstChild;
2594 while (node) {
2595 push$2.call(self, node);
2596 node = node.nextSibling;
2597 }
2598 } else {
2599 node = getElementDocument(context).getElementById(match[2]);
2600 if (!node) {
2601 return self;
2602 }
2603 if (node.id !== match[2]) {
2604 return self.find(selector);
2605 }
2606 self.length = 1;
2607 self[0] = node;
2608 }
2609 } else {
2610 return DomQuery(context).find(selector);
2611 }
2612 } else {
2613 this.add(selector, false);
2614 }
2615 return self;
2616 },
2617 toArray: function () {
2618 return Tools.toArray(this);
2619 },
2620 add: function (items, sort) {
2621 var self = this;
2622 var nodes, i;
2623 if (isString$1(items)) {
2624 return self.add(DomQuery(items));
2625 }
2626 if (sort !== false) {
2627 nodes = DomQuery.unique(self.toArray().concat(DomQuery.makeArray(items)));
2628 self.length = nodes.length;
2629 for (i = 0; i < nodes.length; i++) {
2630 self[i] = nodes[i];
2631 }
2632 } else {
2633 push$2.apply(self, DomQuery.makeArray(items));
2634 }
2635 return self;
2636 },
2637 attr: function (name, value) {
2638 var self = this;
2639 var hook;
2640 if (typeof name === 'object') {
2641 each$2(name, function (name, value) {
2642 self.attr(name, value);
2643 });
2644 } else if (isDefined(value)) {
2645 this.each(function () {
2646 var hook;
2647 if (this.nodeType === 1) {
2648 hook = attrHooks[name];
2649 if (hook && hook.set) {
2650 hook.set(this, value);
2651 return;
2652 }
2653 if (value === null) {
2654 this.removeAttribute(name, 2);
2655 } else {
2656 this.setAttribute(name, value, 2);
2657 }
2658 }
2659 });
2660 } else {
2661 if (self[0] && self[0].nodeType === 1) {
2662 hook = attrHooks[name];
2663 if (hook && hook.get) {
2664 return hook.get(self[0], name);
2665 }
2666 if (booleanMap[name]) {
2667 return self.prop(name) ? name : undefined;
2668 }
2669 value = self[0].getAttribute(name, 2);
2670 if (value === null) {
2671 value = undefined;
2672 }
2673 }
2674 return value;
2675 }
2676 return self;
2677 },
2678 removeAttr: function (name) {
2679 return this.attr(name, null);
2680 },
2681 prop: function (name, value) {
2682 var self = this;
2683 name = propFix[name] || name;
2684 if (typeof name === 'object') {
2685 each$2(name, function (name, value) {
2686 self.prop(name, value);
2687 });
2688 } else if (isDefined(value)) {
2689 this.each(function () {
2690 if (this.nodeType === 1) {
2691 this[name] = value;
2692 }
2693 });
2694 } else {
2695 if (self[0] && self[0].nodeType && name in self[0]) {
2696 return self[0][name];
2697 }
2698 return value;
2699 }
2700 return self;
2701 },
2702 css: function (name, value) {
2703 var self = this;
2704 var elm, hook;
2705 var camel = function (name) {
2706 return name.replace(/-(\D)/g, function (a, b) {
2707 return b.toUpperCase();
2708 });
2709 };
2710 var dashed = function (name) {
2711 return name.replace(/[A-Z]/g, function (a) {
2712 return '-' + a;
2713 });
2714 };
2715 if (typeof name === 'object') {
2716 each$2(name, function (name, value) {
2717 self.css(name, value);
2718 });
2719 } else {
2720 if (isDefined(value)) {
2721 name = camel(name);
2722 if (typeof value === 'number' && !numericCssMap[name]) {
2723 value = value.toString() + 'px';
2724 }
2725 self.each(function () {
2726 var style = this.style;
2727 hook = cssHooks[name];
2728 if (hook && hook.set) {
2729 hook.set(this, value);
2730 return;
2731 }
2732 try {
2733 this.style[cssFix[name] || name] = value;
2734 } catch (ex) {
2735 }
2736 if (value === null || value === '') {
2737 if (style.removeProperty) {
2738 style.removeProperty(dashed(name));
2739 } else {
2740 style.removeAttribute(name);
2741 }
2742 }
2743 });
2744 } else {
2745 elm = self[0];
2746 hook = cssHooks[name];
2747 if (hook && hook.get) {
2748 return hook.get(elm);
2749 }
2750 if (elm.ownerDocument.defaultView) {
2751 try {
2752 return elm.ownerDocument.defaultView.getComputedStyle(elm, null).getPropertyValue(dashed(name));
2753 } catch (ex) {
2754 return undefined;
2755 }
2756 } else if (elm.currentStyle) {
2757 return elm.currentStyle[camel(name)];
2758 } else {
2759 return '';
2760 }
2761 }
2762 }
2763 return self;
2764 },
2765 remove: function () {
2766 var self = this;
2767 var node, i = this.length;
2768 while (i--) {
2769 node = self[i];
2770 Event.clean(node);
2771 if (node.parentNode) {
2772 node.parentNode.removeChild(node);
2773 }
2774 }
2775 return this;
2776 },
2777 empty: function () {
2778 var self = this;
2779 var node, i = this.length;
2780 while (i--) {
2781 node = self[i];
2782 while (node.firstChild) {
2783 node.removeChild(node.firstChild);
2784 }
2785 }
2786 return this;
2787 },
2788 html: function (value) {
2789 var self = this;
2790 var i;
2791 if (isDefined(value)) {
2792 i = self.length;
2793 try {
2794 while (i--) {
2795 self[i].innerHTML = value;
2796 }
2797 } catch (ex) {
2798 DomQuery(self[i]).empty().append(value);
2799 }
2800 return self;
2801 }
2802 return self[0] ? self[0].innerHTML : '';
2803 },
2804 text: function (value) {
2805 var self = this;
2806 var i;
2807 if (isDefined(value)) {
2808 i = self.length;
2809 while (i--) {
2810 if ('innerText' in self[i]) {
2811 self[i].innerText = value;
2812 } else {
2813 self[0].textContent = value;
2814 }
2815 }
2816 return self;
2817 }
2818 return self[0] ? self[0].innerText || self[0].textContent : '';
2819 },
2820 append: function () {
2821 return domManipulate(this, arguments, function (node) {
2822 if (this.nodeType === 1 || this.host && this.host.nodeType === 1) {
2823 this.appendChild(node);
2824 }
2825 });
2826 },
2827 prepend: function () {
2828 return domManipulate(this, arguments, function (node) {
2829 if (this.nodeType === 1 || this.host && this.host.nodeType === 1) {
2830 this.insertBefore(node, this.firstChild);
2831 }
2832 }, true);
2833 },
2834 before: function () {
2835 var self = this;
2836 if (self[0] && self[0].parentNode) {
2837 return domManipulate(self, arguments, function (node) {
2838 this.parentNode.insertBefore(node, this);
2839 });
2840 }
2841 return self;
2842 },
2843 after: function () {
2844 var self = this;
2845 if (self[0] && self[0].parentNode) {
2846 return domManipulate(self, arguments, function (node) {
2847 this.parentNode.insertBefore(node, this.nextSibling);
2848 }, true);
2849 }
2850 return self;
2851 },
2852 appendTo: function (val) {
2853 DomQuery(val).append(this);
2854 return this;
2855 },
2856 prependTo: function (val) {
2857 DomQuery(val).prepend(this);
2858 return this;
2859 },
2860 replaceWith: function (content) {
2861 return this.before(content).remove();
2862 },
2863 wrap: function (content) {
2864 return wrap(this, content);
2865 },
2866 wrapAll: function (content) {
2867 return wrap(this, content, true);
2868 },
2869 wrapInner: function (content) {
2870 this.each(function () {
2871 DomQuery(this).contents().wrapAll(content);
2872 });
2873 return this;
2874 },
2875 unwrap: function () {
2876 return this.parent().each(function () {
2877 DomQuery(this).replaceWith(this.childNodes);
2878 });
2879 },
2880 clone: function () {
2881 var result = [];
2882 this.each(function () {
2883 result.push(this.cloneNode(true));
2884 });
2885 return DomQuery(result);
2886 },
2887 addClass: function (className) {
2888 return this.toggleClass(className, true);
2889 },
2890 removeClass: function (className) {
2891 return this.toggleClass(className, false);
2892 },
2893 toggleClass: function (className, state) {
2894 var self = this;
2895 if (typeof className !== 'string') {
2896 return self;
2897 }
2898 if (className.indexOf(' ') !== -1) {
2899 each$2(className.split(' '), function () {
2900 self.toggleClass(this, state);
2901 });
2902 } else {
2903 self.each(function (index, node) {
2904 var existingClassName, classState;
2905 classState = hasClass(node, className);
2906 if (classState !== state) {
2907 existingClassName = node.className;
2908 if (classState) {
2909 node.className = trim$1((' ' + existingClassName + ' ').replace(' ' + className + ' ', ' '));
2910 } else {
2911 node.className += existingClassName ? ' ' + className : className;
2912 }
2913 }
2914 });
2915 }
2916 return self;
2917 },
2918 hasClass: function (className) {
2919 return hasClass(this[0], className);
2920 },
2921 each: function (callback) {
2922 return each$2(this, callback);
2923 },
2924 on: function (name, callback) {
2925 return this.each(function () {
2926 Event.bind(this, name, callback);
2927 });
2928 },
2929 off: function (name, callback) {
2930 return this.each(function () {
2931 Event.unbind(this, name, callback);
2932 });
2933 },
2934 trigger: function (name) {
2935 return this.each(function () {
2936 if (typeof name === 'object') {
2937 Event.fire(this, name.type, name);
2938 } else {
2939 Event.fire(this, name);
2940 }
2941 });
2942 },
2943 show: function () {
2944 return this.css('display', '');
2945 },
2946 hide: function () {
2947 return this.css('display', 'none');
2948 },
2949 slice: function () {
2950 return new DomQuery(slice$2.apply(this, arguments));
2951 },
2952 eq: function (index) {
2953 return index === -1 ? this.slice(index) : this.slice(index, +index + 1);
2954 },
2955 first: function () {
2956 return this.eq(0);
2957 },
2958 last: function () {
2959 return this.eq(-1);
2960 },
2961 find: function (selector) {
2962 var i, l;
2963 var ret = [];
2964 for (i = 0, l = this.length; i < l; i++) {
2965 DomQuery.find(selector, this[i], ret);
2966 }
2967 return DomQuery(ret);
2968 },
2969 filter: function (selector) {
2970 if (typeof selector === 'function') {
2971 return DomQuery(grep(this.toArray(), function (item, i) {
2972 return selector(i, item);
2973 }));
2974 }
2975 return DomQuery(DomQuery.filter(selector, this.toArray()));
2976 },
2977 closest: function (selector) {
2978 var result = [];
2979 if (selector instanceof DomQuery) {
2980 selector = selector[0];
2981 }
2982 this.each(function (i, node) {
2983 while (node) {
2984 if (typeof selector === 'string' && DomQuery(node).is(selector)) {
2985 result.push(node);
2986 break;
2987 } else if (node === selector) {
2988 result.push(node);
2989 break;
2990 }
2991 node = node.parentNode;
2992 }
2993 });
2994 return DomQuery(result);
2995 },
2996 offset: function (offset) {
2997 var elm, doc, docElm;
2998 var x = 0, y = 0, pos;
2999 if (!offset) {
3000 elm = this[0];
3001 if (elm) {
3002 doc = elm.ownerDocument;
3003 docElm = doc.documentElement;
3004 if (elm.getBoundingClientRect) {
3005 pos = elm.getBoundingClientRect();
3006 x = pos.left + (docElm.scrollLeft || doc.body.scrollLeft) - docElm.clientLeft;
3007 y = pos.top + (docElm.scrollTop || doc.body.scrollTop) - docElm.clientTop;
3008 }
3009 }
3010 return {
3011 left: x,
3012 top: y
3013 };
3014 }
3015 return this.css(offset);
3016 },
3017 push: push$2,
3018 sort: Array.prototype.sort,
3019 splice: Array.prototype.splice
3020 };
3021 Tools.extend(DomQueryConstructor, {
3022 extend: Tools.extend,
3023 makeArray: function (object) {
3024 if (isWindow(object) || object.nodeType) {
3025 return [object];
3026 }
3027 return Tools.toArray(object);
3028 },
3029 inArray: inArray,
3030 isArray: Tools.isArray,
3031 each: each$2,
3032 trim: trim$1,
3033 grep: grep,
3034 find: Sizzle,
3035 expr: Sizzle.selectors,
3036 unique: Sizzle.uniqueSort,
3037 text: Sizzle.getText,
3038 contains: Sizzle.contains,
3039 filter: function (expr, elems, not) {
3040 var i = elems.length;
3041 if (not) {
3042 expr = ':not(' + expr + ')';
3043 }
3044 while (i--) {
3045 if (elems[i].nodeType !== 1) {
3046 elems.splice(i, 1);
3047 }
3048 }
3049 if (elems.length === 1) {
3050 elems = DomQuery.find.matchesSelector(elems[0], expr) ? [elems[0]] : [];
3051 } else {
3052 elems = DomQuery.find.matches(expr, elems);
3053 }
3054 return elems;
3055 }
3056 });
3057 var dir = function (el, prop, until) {
3058 var matched = [];
3059 var cur = el[prop];
3060 if (typeof until !== 'string' && until instanceof DomQuery) {
3061 until = until[0];
3062 }
3063 while (cur && cur.nodeType !== 9) {
3064 if (until !== undefined) {
3065 if (cur === until) {
3066 break;
3067 }
3068 if (typeof until === 'string' && DomQuery(cur).is(until)) {
3069 break;
3070 }
3071 }
3072 if (cur.nodeType === 1) {
3073 matched.push(cur);
3074 }
3075 cur = cur[prop];
3076 }
3077 return matched;
3078 };
3079 var sibling = function (node, siblingName, nodeType, until) {
3080 var result = [];
3081 if (until instanceof DomQuery) {
3082 until = until[0];
3083 }
3084 for (; node; node = node[siblingName]) {
3085 if (nodeType && node.nodeType !== nodeType) {
3086 continue;
3087 }
3088 if (until !== undefined) {
3089 if (node === until) {
3090 break;
3091 }
3092 if (typeof until === 'string' && DomQuery(node).is(until)) {
3093 break;
3094 }
3095 }
3096 result.push(node);
3097 }
3098 return result;
3099 };
3100 var firstSibling = function (node, siblingName, nodeType) {
3101 for (node = node[siblingName]; node; node = node[siblingName]) {
3102 if (node.nodeType === nodeType) {
3103 return node;
3104 }
3105 }
3106 return null;
3107 };
3108 each$2({
3109 parent: function (node) {
3110 var parent = node.parentNode;
3111 return parent && parent.nodeType !== 11 ? parent : null;
3112 },
3113 parents: function (node) {
3114 return dir(node, 'parentNode');
3115 },
3116 next: function (node) {
3117 return firstSibling(node, 'nextSibling', 1);
3118 },
3119 prev: function (node) {
3120 return firstSibling(node, 'previousSibling', 1);
3121 },
3122 children: function (node) {
3123 return sibling(node.firstChild, 'nextSibling', 1);
3124 },
3125 contents: function (node) {
3126 return Tools.toArray((node.nodeName === 'iframe' ? node.contentDocument || node.contentWindow.document : node).childNodes);
3127 }
3128 }, function (name, fn) {
3129 DomQueryConstructor.fn[name] = function (selector) {
3130 var self = this;
3131 var result = [];
3132 self.each(function () {
3133 var nodes = fn.call(result, this, selector, result);
3134 if (nodes) {
3135 if (DomQuery.isArray(nodes)) {
3136 result.push.apply(result, nodes);
3137 } else {
3138 result.push(nodes);
3139 }
3140 }
3141 });
3142 if (this.length > 1) {
3143 if (!skipUniques[name]) {
3144 result = DomQuery.unique(result);
3145 }
3146 if (name.indexOf('parents') === 0) {
3147 result = result.reverse();
3148 }
3149 }
3150 var wrappedResult = DomQuery(result);
3151 if (selector) {
3152 return wrappedResult.filter(selector);
3153 }
3154 return wrappedResult;
3155 };
3156 });
3157 each$2({
3158 parentsUntil: function (node, until) {
3159 return dir(node, 'parentNode', until);
3160 },
3161 nextUntil: function (node, until) {
3162 return sibling(node, 'nextSibling', 1, until).slice(1);
3163 },
3164 prevUntil: function (node, until) {
3165 return sibling(node, 'previousSibling', 1, until).slice(1);
3166 }
3167 }, function (name, fn) {
3168 DomQueryConstructor.fn[name] = function (selector, filter) {
3169 var self = this;
3170 var result = [];
3171 self.each(function () {
3172 var nodes = fn.call(result, this, selector, result);
3173 if (nodes) {
3174 if (DomQuery.isArray(nodes)) {
3175 result.push.apply(result, nodes);
3176 } else {
3177 result.push(nodes);
3178 }
3179 }
3180 });
3181 if (this.length > 1) {
3182 result = DomQuery.unique(result);
3183 if (name.indexOf('parents') === 0 || name === 'prevUntil') {
3184 result = result.reverse();
3185 }
3186 }
3187 var wrappedResult = DomQuery(result);
3188 if (filter) {
3189 return wrappedResult.filter(filter);
3190 }
3191 return wrappedResult;
3192 };
3193 });
3194 DomQueryConstructor.fn.is = function (selector) {
3195 return !!selector && this.filter(selector).length > 0;
3196 };
3197 DomQueryConstructor.fn.init.prototype = DomQueryConstructor.fn;
3198 DomQueryConstructor.overrideDefaults = function (callback) {
3199 var defaults;
3200 var sub = function (selector, context) {
3201 defaults = defaults || callback();
3202 if (arguments.length === 0) {
3203 selector = defaults.element;
3204 }
3205 if (!context) {
3206 context = defaults.context;
3207 }
3208 return new sub.fn.init(selector, context);
3209 };
3210 DomQuery.extend(sub, this);
3211 return sub;
3212 };
3213 var appendHooks = function (targetHooks, prop, hooks) {
3214 each$2(hooks, function (name, func) {
3215 targetHooks[name] = targetHooks[name] || {};
3216 targetHooks[name][prop] = func;
3217 });
3218 };
3219 if (Env.ie && Env.ie < 8) {
3220 appendHooks(attrHooks, 'get', {
3221 maxlength: function (elm) {
3222 var value = elm.maxLength;
3223 if (value === 2147483647) {
3224 return undefined;
3225 }
3226 return value;
3227 },
3228 size: function (elm) {
3229 var value = elm.size;
3230 if (value === 20) {
3231 return undefined;
3232 }
3233 return value;
3234 },
3235 class: function (elm) {
3236 return elm.className;
3237 },
3238 style: function (elm) {
3239 var value = elm.style.cssText;
3240 if (value.length === 0) {
3241 return undefined;
3242 }
3243 return value;
3244 }
3245 });
3246 appendHooks(attrHooks, 'set', {
3247 class: function (elm, value) {
3248 elm.className = value;
3249 },
3250 style: function (elm, value) {
3251 elm.style.cssText = value;
3252 }
3253 });
3254 }
3255 if (Env.ie && Env.ie < 9) {
3256 cssFix.float = 'styleFloat';
3257 appendHooks(cssHooks, 'set', {
3258 opacity: function (elm, value) {
3259 var style = elm.style;
3260 if (value === null || value === '') {
3261 style.removeAttribute('filter');
3262 } else {
3263 style.zoom = 1;
3264 style.filter = 'alpha(opacity=' + value * 100 + ')';
3265 }
3266 }
3267 });
3268 }
3269 DomQueryConstructor.attrHooks = attrHooks;
3270 DomQueryConstructor.cssHooks = cssHooks;
3271 var DomQuery = DomQueryConstructor;
3272
3273 var cached = function (f) {
3274 var called = false;
3275 var r;
3276 return function () {
3277 var args = [];
3278 for (var _i = 0; _i < arguments.length; _i++) {
3279 args[_i] = arguments[_i];
3280 }
3281 if (!called) {
3282 called = true;
3283 r = f.apply(null, args);
3284 }
3285 return r;
3286 };
3287 };
3288
3289 var firstMatch = function (regexes, s) {
3290 for (var i = 0; i < regexes.length; i++) {
3291 var x = regexes[i];
3292 if (x.test(s)) {
3293 return x;
3294 }
3295 }
3296 return undefined;
3297 };
3298 var find$2 = function (regexes, agent) {
3299 var r = firstMatch(regexes, agent);
3300 if (!r) {
3301 return {
3302 major: 0,
3303 minor: 0
3304 };
3305 }
3306 var group = function (i) {
3307 return Number(agent.replace(r, '$' + i));
3308 };
3309 return nu(group(1), group(2));
3310 };
3311 var detect = function (versionRegexes, agent) {
3312 var cleanedAgent = String(agent).toLowerCase();
3313 if (versionRegexes.length === 0) {
3314 return unknown();
3315 }
3316 return find$2(versionRegexes, cleanedAgent);
3317 };
3318 var unknown = function () {
3319 return nu(0, 0);
3320 };
3321 var nu = function (major, minor) {
3322 return {
3323 major: major,
3324 minor: minor
3325 };
3326 };
3327 var Version = {
3328 nu: nu,
3329 detect: detect,
3330 unknown: unknown
3331 };
3332
3333 var edge = 'Edge';
3334 var chrome = 'Chrome';
3335 var ie$1 = 'IE';
3336 var opera$1 = 'Opera';
3337 var firefox = 'Firefox';
3338 var safari = 'Safari';
3339 var isBrowser = function (name, current) {
3340 return function () {
3341 return current === name;
3342 };
3343 };
3344 var unknown$1 = function () {
3345 return nu$1({
3346 current: undefined,
3347 version: Version.unknown()
3348 });
3349 };
3350 var nu$1 = function (info) {
3351 var current = info.current;
3352 var version = info.version;
3353 return {
3354 current: current,
3355 version: version,
3356 isEdge: isBrowser(edge, current),
3357 isChrome: isBrowser(chrome, current),
3358 isIE: isBrowser(ie$1, current),
3359 isOpera: isBrowser(opera$1, current),
3360 isFirefox: isBrowser(firefox, current),
3361 isSafari: isBrowser(safari, current)
3362 };
3363 };
3364 var Browser = {
3365 unknown: unknown$1,
3366 nu: nu$1,
3367 edge: constant(edge),
3368 chrome: constant(chrome),
3369 ie: constant(ie$1),
3370 opera: constant(opera$1),
3371 firefox: constant(firefox),
3372 safari: constant(safari)
3373 };
3374
3375 var windows = 'Windows';
3376 var ios = 'iOS';
3377 var android$1 = 'Android';
3378 var linux = 'Linux';
3379 var osx = 'OSX';
3380 var solaris = 'Solaris';
3381 var freebsd = 'FreeBSD';
3382 var isOS = function (name, current) {
3383 return function () {
3384 return current === name;
3385 };
3386 };
3387 var unknown$2 = function () {
3388 return nu$2({
3389 current: undefined,
3390 version: Version.unknown()
3391 });
3392 };
3393 var nu$2 = function (info) {
3394 var current = info.current;
3395 var version = info.version;
3396 return {
3397 current: current,
3398 version: version,
3399 isWindows: isOS(windows, current),
3400 isiOS: isOS(ios, current),
3401 isAndroid: isOS(android$1, current),
3402 isOSX: isOS(osx, current),
3403 isLinux: isOS(linux, current),
3404 isSolaris: isOS(solaris, current),
3405 isFreeBSD: isOS(freebsd, current)
3406 };
3407 };
3408 var OperatingSystem = {
3409 unknown: unknown$2,
3410 nu: nu$2,
3411 windows: constant(windows),
3412 ios: constant(ios),
3413 android: constant(android$1),
3414 linux: constant(linux),
3415 osx: constant(osx),
3416 solaris: constant(solaris),
3417 freebsd: constant(freebsd)
3418 };
3419
3420 var DeviceType = function (os, browser, userAgent) {
3421 var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true;
3422 var isiPhone = os.isiOS() && !isiPad;
3423 var isAndroid3 = os.isAndroid() && os.version.major === 3;
3424 var isAndroid4 = os.isAndroid() && os.version.major === 4;
3425 var isTablet = isiPad || isAndroid3 || isAndroid4 && /mobile/i.test(userAgent) === true;
3426 var isTouch = os.isiOS() || os.isAndroid();
3427 var isPhone = isTouch && !isTablet;
3428 var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false;
3429 return {
3430 isiPad: constant(isiPad),
3431 isiPhone: constant(isiPhone),
3432 isTablet: constant(isTablet),
3433 isPhone: constant(isPhone),
3434 isTouch: constant(isTouch),
3435 isAndroid: os.isAndroid,
3436 isiOS: os.isiOS,
3437 isWebView: constant(iOSwebview)
3438 };
3439 };
3440
3441 var detect$1 = function (candidates, userAgent) {
3442 var agent = String(userAgent).toLowerCase();
3443 return find(candidates, function (candidate) {
3444 return candidate.search(agent);
3445 });
3446 };
3447 var detectBrowser = function (browsers, userAgent) {
3448 return detect$1(browsers, userAgent).map(function (browser) {
3449 var version = Version.detect(browser.versionRegexes, userAgent);
3450 return {
3451 current: browser.name,
3452 version: version
3453 };
3454 });
3455 };
3456 var detectOs = function (oses, userAgent) {
3457 return detect$1(oses, userAgent).map(function (os) {
3458 var version = Version.detect(os.versionRegexes, userAgent);
3459 return {
3460 current: os.name,
3461 version: version
3462 };
3463 });
3464 };
3465 var UaString = {
3466 detectBrowser: detectBrowser,
3467 detectOs: detectOs
3468 };
3469
3470 var checkRange = function (str, substr, start) {
3471 if (substr === '') {
3472 return true;
3473 }
3474 if (str.length < substr.length) {
3475 return false;
3476 }
3477 var x = str.substr(start, start + substr.length);
3478 return x === substr;
3479 };
3480 var contains$2 = function (str, substr) {
3481 return str.indexOf(substr) !== -1;
3482 };
3483 var startsWith = function (str, prefix) {
3484 return checkRange(str, prefix, 0);
3485 };
3486 var trim$2 = function (str) {
3487 return str.replace(/^\s+|\s+$/g, '');
3488 };
3489 var lTrim = function (str) {
3490 return str.replace(/^\s+/g, '');
3491 };
3492 var rTrim = function (str) {
3493 return str.replace(/\s+$/g, '');
3494 };
3495
3496 var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/;
3497 var checkContains = function (target) {
3498 return function (uastring) {
3499 return contains$2(uastring, target);
3500 };
3501 };
3502 var browsers = [
3503 {
3504 name: 'Edge',
3505 versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/],
3506 search: function (uastring) {
3507 return contains$2(uastring, 'edge/') && contains$2(uastring, 'chrome') && contains$2(uastring, 'safari') && contains$2(uastring, 'applewebkit');
3508 }
3509 },
3510 {
3511 name: 'Chrome',
3512 versionRegexes: [
3513 /.*?chrome\/([0-9]+)\.([0-9]+).*/,
3514 normalVersionRegex
3515 ],
3516 search: function (uastring) {
3517 return contains$2(uastring, 'chrome') && !contains$2(uastring, 'chromeframe');
3518 }
3519 },
3520 {
3521 name: 'IE',
3522 versionRegexes: [
3523 /.*?msie\ ?([0-9]+)\.([0-9]+).*/,
3524 /.*?rv:([0-9]+)\.([0-9]+).*/
3525 ],
3526 search: function (uastring) {
3527 return contains$2(uastring, 'msie') || contains$2(uastring, 'trident');
3528 }
3529 },
3530 {
3531 name: 'Opera',
3532 versionRegexes: [
3533 normalVersionRegex,
3534 /.*?opera\/([0-9]+)\.([0-9]+).*/
3535 ],
3536 search: checkContains('opera')
3537 },
3538 {
3539 name: 'Firefox',
3540 versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/],
3541 search: checkContains('firefox')
3542 },
3543 {
3544 name: 'Safari',
3545 versionRegexes: [
3546 normalVersionRegex,
3547 /.*?cpu os ([0-9]+)_([0-9]+).*/
3548 ],
3549 search: function (uastring) {
3550 return (contains$2(uastring, 'safari') || contains$2(uastring, 'mobile/')) && contains$2(uastring, 'applewebkit');
3551 }
3552 }
3553 ];
3554 var oses = [
3555 {
3556 name: 'Windows',
3557 search: checkContains('win'),
3558 versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/]
3559 },
3560 {
3561 name: 'iOS',
3562 search: function (uastring) {
3563 return contains$2(uastring, 'iphone') || contains$2(uastring, 'ipad');
3564 },
3565 versionRegexes: [
3566 /.*?version\/\ ?([0-9]+)\.([0-9]+).*/,
3567 /.*cpu os ([0-9]+)_([0-9]+).*/,
3568 /.*cpu iphone os ([0-9]+)_([0-9]+).*/
3569 ]
3570 },
3571 {
3572 name: 'Android',
3573 search: checkContains('android'),
3574 versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/]
3575 },
3576 {
3577 name: 'OSX',
3578 search: checkContains('os x'),
3579 versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/]
3580 },
3581 {
3582 name: 'Linux',
3583 search: checkContains('linux'),
3584 versionRegexes: []
3585 },
3586 {
3587 name: 'Solaris',
3588 search: checkContains('sunos'),
3589 versionRegexes: []
3590 },
3591 {
3592 name: 'FreeBSD',
3593 search: checkContains('freebsd'),
3594 versionRegexes: []
3595 }
3596 ];
3597 var PlatformInfo = {
3598 browsers: constant(browsers),
3599 oses: constant(oses)
3600 };
3601
3602 var detect$2 = function (userAgent) {
3603 var browsers = PlatformInfo.browsers();
3604 var oses = PlatformInfo.oses();
3605 var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu);
3606 var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu);
3607 var deviceType = DeviceType(os, browser, userAgent);
3608 return {
3609 browser: browser,
3610 os: os,
3611 deviceType: deviceType
3612 };
3613 };
3614 var PlatformDetection = { detect: detect$2 };
3615
3616 var detect$3 = cached(function () {
3617 var userAgent = domGlobals.navigator.userAgent;
3618 return PlatformDetection.detect(userAgent);
3619 });
3620 var PlatformDetection$1 = { detect: detect$3 };
3621
3622 var fromHtml = function (html, scope) {
3623 var doc = scope || domGlobals.document;
3624 var div = doc.createElement('div');
3625 div.innerHTML = html;
3626 if (!div.hasChildNodes() || div.childNodes.length > 1) {
3627 domGlobals.console.error('HTML does not have a single root node', html);
3628 throw new Error('HTML must have a single root node');
3629 }
3630 return fromDom(div.childNodes[0]);
3631 };
3632 var fromTag = function (tag, scope) {
3633 var doc = scope || domGlobals.document;
3634 var node = doc.createElement(tag);
3635 return fromDom(node);
3636 };
3637 var fromText = function (text, scope) {
3638 var doc = scope || domGlobals.document;
3639 var node = doc.createTextNode(text);
3640 return fromDom(node);
3641 };
3642 var fromDom = function (node) {
3643 if (node === null || node === undefined) {
3644 throw new Error('Node cannot be null or undefined');
3645 }
3646 return { dom: constant(node) };
3647 };
3648 var fromPoint = function (docElm, x, y) {
3649 var doc = docElm.dom();
3650 return Option.from(doc.elementFromPoint(x, y)).map(fromDom);
3651 };
3652 var Element = {
3653 fromHtml: fromHtml,
3654 fromTag: fromTag,
3655 fromText: fromText,
3656 fromDom: fromDom,
3657 fromPoint: fromPoint
3658 };
3659
3660 var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE;
3661 var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE;
3662 var COMMENT = domGlobals.Node.COMMENT_NODE;
3663 var DOCUMENT = domGlobals.Node.DOCUMENT_NODE;
3664 var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE;
3665 var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE;
3666 var ELEMENT = domGlobals.Node.ELEMENT_NODE;
3667 var TEXT = domGlobals.Node.TEXT_NODE;
3668 var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE;
3669 var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE;
3670 var ENTITY = domGlobals.Node.ENTITY_NODE;
3671 var NOTATION = domGlobals.Node.NOTATION_NODE;
3672
3673 var name = function (element) {
3674 var r = element.dom().nodeName;
3675 return r.toLowerCase();
3676 };
3677 var type = function (element) {
3678 return element.dom().nodeType;
3679 };
3680 var isType$1 = function (t) {
3681 return function (element) {
3682 return type(element) === t;
3683 };
3684 };
3685 var isElement = isType$1(ELEMENT);
3686 var isText = isType$1(TEXT);
3687 var isDocument = isType$1(DOCUMENT);
3688
3689 var keys = Object.keys;
3690 var hasOwnProperty$1 = Object.hasOwnProperty;
3691 var each$3 = function (obj, f) {
3692 var props = keys(obj);
3693 for (var k = 0, len = props.length; k < len; k++) {
3694 var i = props[k];
3695 var x = obj[i];
3696 f(x, i, obj);
3697 }
3698 };
3699 var map$2 = function (obj, f) {
3700 return tupleMap(obj, function (x, i, obj) {
3701 return {
3702 k: i,
3703 v: f(x, i, obj)
3704 };
3705 });
3706 };
3707 var tupleMap = function (obj, f) {
3708 var r = {};
3709 each$3(obj, function (x, i) {
3710 var tuple = f(x, i, obj);
3711 r[tuple.k] = tuple.v;
3712 });
3713 return r;
3714 };
3715 var bifilter = function (obj, pred) {
3716 var t = {};
3717 var f = {};
3718 each$3(obj, function (x, i) {
3719 var branch = pred(x, i) ? t : f;
3720 branch[i] = x;
3721 });
3722 return {
3723 t: t,
3724 f: f
3725 };
3726 };
3727 var get = function (obj, key) {
3728 return has(obj, key) ? Option.from(obj[key]) : Option.none();
3729 };
3730 var has = function (obj, key) {
3731 return hasOwnProperty$1.call(obj, key);
3732 };
3733
3734 var isSupported = function (dom) {
3735 return dom.style !== undefined && isFunction(dom.style.getPropertyValue);
3736 };
3737
3738 var inBody = function (element) {
3739 var dom = isText(element) ? element.dom().parentNode : element.dom();
3740 return dom !== undefined && dom !== null && dom.ownerDocument.body.contains(dom);
3741 };
3742
3743 var rawSet = function (dom, key, value) {
3744 if (isString(value) || isBoolean(value) || isNumber(value)) {
3745 dom.setAttribute(key, value + '');
3746 } else {
3747 domGlobals.console.error('Invalid call to Attr.set. Key ', key, ':: Value ', value, ':: Element ', dom);
3748 throw new Error('Attribute value was not simple');
3749 }
3750 };
3751 var set = function (element, key, value) {
3752 rawSet(element.dom(), key, value);
3753 };
3754 var setAll = function (element, attrs) {
3755 var dom = element.dom();
3756 each$3(attrs, function (v, k) {
3757 rawSet(dom, k, v);
3758 });
3759 };
3760 var get$1 = function (element, key) {
3761 var v = element.dom().getAttribute(key);
3762 return v === null ? undefined : v;
3763 };
3764 var has$1 = function (element, key) {
3765 var dom = element.dom();
3766 return dom && dom.hasAttribute ? dom.hasAttribute(key) : false;
3767 };
3768 var remove = function (element, key) {
3769 element.dom().removeAttribute(key);
3770 };
3771
3772 var get$2 = function (element, property) {
3773 var dom = element.dom();
3774 var styles = domGlobals.window.getComputedStyle(dom);
3775 var r = styles.getPropertyValue(property);
3776 var v = r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r;
3777 return v === null ? undefined : v;
3778 };
3779 var getUnsafeProperty = function (dom, property) {
3780 return isSupported(dom) ? dom.style.getPropertyValue(property) : '';
3781 };
3782 var getRaw = function (element, property) {
3783 var dom = element.dom();
3784 var raw = getUnsafeProperty(dom, property);
3785 return Option.from(raw).filter(function (r) {
3786 return r.length > 0;
3787 });
3788 };
3789 var reflow = function (e) {
3790 return e.dom().offsetWidth;
3791 };
3792
3793 var Immutable = function () {
3794 var fields = [];
3795 for (var _i = 0; _i < arguments.length; _i++) {
3796 fields[_i] = arguments[_i];
3797 }
3798 return function () {
3799 var values = [];
3800 for (var _i = 0; _i < arguments.length; _i++) {
3801 values[_i] = arguments[_i];
3802 }
3803 if (fields.length !== values.length) {
3804 throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments');
3805 }
3806 var struct = {};
3807 each(fields, function (name, i) {
3808 struct[name] = constant(values[i]);
3809 });
3810 return struct;
3811 };
3812 };
3813
3814 var toArray$1 = function (target, f) {
3815 var r = [];
3816 var recurse = function (e) {
3817 r.push(e);
3818 return f(e);
3819 };
3820 var cur = f(target);
3821 do {
3822 cur = cur.bind(recurse);
3823 } while (cur.isSome());
3824 return r;
3825 };
3826 var Recurse = { toArray: toArray$1 };
3827
3828 var node = function () {
3829 var f = Global$1.getOrDie('Node');
3830 return f;
3831 };
3832 var compareDocumentPosition = function (a, b, match) {
3833 return (a.compareDocumentPosition(b) & match) !== 0;
3834 };
3835 var documentPositionPreceding = function (a, b) {
3836 return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_PRECEDING);
3837 };
3838 var documentPositionContainedBy = function (a, b) {
3839 return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_CONTAINED_BY);
3840 };
3841 var Node = {
3842 documentPositionPreceding: documentPositionPreceding,
3843 documentPositionContainedBy: documentPositionContainedBy
3844 };
3845
3846 var ELEMENT$1 = ELEMENT;
3847 var DOCUMENT$1 = DOCUMENT;
3848 var is$1 = function (element, selector) {
3849 var elem = element.dom();
3850 if (elem.nodeType !== ELEMENT$1) {
3851 return false;
3852 } else if (elem.matches !== undefined) {
3853 return elem.matches(selector);
3854 } else if (elem.msMatchesSelector !== undefined) {
3855 return elem.msMatchesSelector(selector);
3856 } else if (elem.webkitMatchesSelector !== undefined) {
3857 return elem.webkitMatchesSelector(selector);
3858 } else if (elem.mozMatchesSelector !== undefined) {
3859 return elem.mozMatchesSelector(selector);
3860 } else {
3861 throw new Error('Browser lacks native selectors');
3862 }
3863 };
3864 var bypassSelector = function (dom) {
3865 return dom.nodeType !== ELEMENT$1 && dom.nodeType !== DOCUMENT$1 || dom.childElementCount === 0;
3866 };
3867 var all = function (selector, scope) {
3868 var base = scope === undefined ? domGlobals.document : scope.dom();
3869 return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), Element.fromDom);
3870 };
3871 var one = function (selector, scope) {
3872 var base = scope === undefined ? domGlobals.document : scope.dom();
3873 return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom);
3874 };
3875
3876 var eq = function (e1, e2) {
3877 return e1.dom() === e2.dom();
3878 };
3879 var regularContains = function (e1, e2) {
3880 var d1 = e1.dom();
3881 var d2 = e2.dom();
3882 return d1 === d2 ? false : d1.contains(d2);
3883 };
3884 var ieContains = function (e1, e2) {
3885 return Node.documentPositionContainedBy(e1.dom(), e2.dom());
3886 };
3887 var browser = PlatformDetection$1.detect().browser;
3888 var contains$3 = browser.isIE() ? ieContains : regularContains;
3889
3890 var owner = function (element) {
3891 return Element.fromDom(element.dom().ownerDocument);
3892 };
3893 var documentElement = function (element) {
3894 return Element.fromDom(element.dom().ownerDocument.documentElement);
3895 };
3896 var defaultView = function (element) {
3897 var el = element.dom();
3898 var defView = el.ownerDocument.defaultView;
3899 return Element.fromDom(defView);
3900 };
3901 var parent = function (element) {
3902 var dom = element.dom();
3903 return Option.from(dom.parentNode).map(Element.fromDom);
3904 };
3905 var parents = function (element, isRoot) {
3906 var stop = isFunction(isRoot) ? isRoot : constant(false);
3907 var dom = element.dom();
3908 var ret = [];
3909 while (dom.parentNode !== null && dom.parentNode !== undefined) {
3910 var rawParent = dom.parentNode;
3911 var p = Element.fromDom(rawParent);
3912 ret.push(p);
3913 if (stop(p) === true) {
3914 break;
3915 } else {
3916 dom = rawParent;
3917 }
3918 }
3919 return ret;
3920 };
3921 var prevSibling = function (element) {
3922 var dom = element.dom();
3923 return Option.from(dom.previousSibling).map(Element.fromDom);
3924 };
3925 var nextSibling = function (element) {
3926 var dom = element.dom();
3927 return Option.from(dom.nextSibling).map(Element.fromDom);
3928 };
3929 var prevSiblings = function (element) {
3930 return reverse(Recurse.toArray(element, prevSibling));
3931 };
3932 var nextSiblings = function (element) {
3933 return Recurse.toArray(element, nextSibling);
3934 };
3935 var children = function (element) {
3936 var dom = element.dom();
3937 return map(dom.childNodes, Element.fromDom);
3938 };
3939 var child = function (element, index) {
3940 var cs = element.dom().childNodes;
3941 return Option.from(cs[index]).map(Element.fromDom);
3942 };
3943 var firstChild = function (element) {
3944 return child(element, 0);
3945 };
3946 var lastChild = function (element) {
3947 return child(element, element.dom().childNodes.length - 1);
3948 };
3949 var childNodesCount = function (element) {
3950 return element.dom().childNodes.length;
3951 };
3952 var spot = Immutable('element', 'offset');
3953
3954 var browser$1 = PlatformDetection$1.detect().browser;
3955 var firstElement = function (nodes) {
3956 return find(nodes, isElement);
3957 };
3958 var getTableCaptionDeltaY = function (elm) {
3959 if (browser$1.isFirefox() && name(elm) === 'table') {
3960 return firstElement(children(elm)).filter(function (elm) {
3961 return name(elm) === 'caption';
3962 }).bind(function (caption) {
3963 return firstElement(nextSiblings(caption)).map(function (body) {
3964 var bodyTop = body.dom().offsetTop;
3965 var captionTop = caption.dom().offsetTop;
3966 var captionHeight = caption.dom().offsetHeight;
3967 return bodyTop <= captionTop ? -captionHeight : 0;
3968 });
3969 }).getOr(0);
3970 } else {
3971 return 0;
3972 }
3973 };
3974 var hasChild = function (elm, child) {
3975 return elm.children && contains(elm.children, child);
3976 };
3977 var getPos = function (body, elm, rootElm) {
3978 var x = 0, y = 0, offsetParent;
3979 var doc = body.ownerDocument;
3980 var pos;
3981 rootElm = rootElm ? rootElm : body;
3982 if (elm) {
3983 if (rootElm === body && elm.getBoundingClientRect && get$2(Element.fromDom(body), 'position') === 'static') {
3984 pos = elm.getBoundingClientRect();
3985 x = pos.left + (doc.documentElement.scrollLeft || body.scrollLeft) - doc.documentElement.clientLeft;
3986 y = pos.top + (doc.documentElement.scrollTop || body.scrollTop) - doc.documentElement.clientTop;
3987 return {
3988 x: x,
3989 y: y
3990 };
3991 }
3992 offsetParent = elm;
3993 while (offsetParent && offsetParent !== rootElm && offsetParent.nodeType && !hasChild(offsetParent, rootElm)) {
3994 x += offsetParent.offsetLeft || 0;
3995 y += offsetParent.offsetTop || 0;
3996 offsetParent = offsetParent.offsetParent;
3997 }
3998 offsetParent = elm.parentNode;
3999 while (offsetParent && offsetParent !== rootElm && offsetParent.nodeType && !hasChild(offsetParent, rootElm)) {
4000 x -= offsetParent.scrollLeft || 0;
4001 y -= offsetParent.scrollTop || 0;
4002 offsetParent = offsetParent.parentNode;
4003 }
4004 y += getTableCaptionDeltaY(Element.fromDom(elm));
4005 }
4006 return {
4007 x: x,
4008 y: y
4009 };
4010 };
4011 var Position = { getPos: getPos };
4012
4013 var nu$3 = function (baseFn) {
4014 var data = Option.none();
4015 var callbacks = [];
4016 var map = function (f) {
4017 return nu$3(function (nCallback) {
4018 get(function (data) {
4019 nCallback(f(data));
4020 });
4021 });
4022 };
4023 var get = function (nCallback) {
4024 if (isReady()) {
4025 call(nCallback);
4026 } else {
4027 callbacks.push(nCallback);
4028 }
4029 };
4030 var set = function (x) {
4031 data = Option.some(x);
4032 run(callbacks);
4033 callbacks = [];
4034 };
4035 var isReady = function () {
4036 return data.isSome();
4037 };
4038 var run = function (cbs) {
4039 each(cbs, call);
4040 };
4041 var call = function (cb) {
4042 data.each(function (x) {
4043 domGlobals.setTimeout(function () {
4044 cb(x);
4045 }, 0);
4046 });
4047 };
4048 baseFn(set);
4049 return {
4050 get: get,
4051 map: map,
4052 isReady: isReady
4053 };
4054 };
4055 var pure = function (a) {
4056 return nu$3(function (callback) {
4057 callback(a);
4058 });
4059 };
4060 var LazyValue = {
4061 nu: nu$3,
4062 pure: pure
4063 };
4064
4065 var bounce = function (f) {
4066 return function () {
4067 var args = [];
4068 for (var _i = 0; _i < arguments.length; _i++) {
4069 args[_i] = arguments[_i];
4070 }
4071 var me = this;
4072 domGlobals.setTimeout(function () {
4073 f.apply(me, args);
4074 }, 0);
4075 };
4076 };
4077
4078 var nu$4 = function (baseFn) {
4079 var get = function (callback) {
4080 baseFn(bounce(callback));
4081 };
4082 var map = function (fab) {
4083 return nu$4(function (callback) {
4084 get(function (a) {
4085 var value = fab(a);
4086 callback(value);
4087 });
4088 });
4089 };
4090 var bind = function (aFutureB) {
4091 return nu$4(function (callback) {
4092 get(function (a) {
4093 aFutureB(a).get(callback);
4094 });
4095 });
4096 };
4097 var anonBind = function (futureB) {
4098 return nu$4(function (callback) {
4099 get(function (a) {
4100 futureB.get(callback);
4101 });
4102 });
4103 };
4104 var toLazy = function () {
4105 return LazyValue.nu(get);
4106 };
4107 var toCached = function () {
4108 var cache = null;
4109 return nu$4(function (callback) {
4110 if (cache === null) {
4111 cache = toLazy();
4112 }
4113 cache.get(callback);
4114 });
4115 };
4116 return {
4117 map: map,
4118 bind: bind,
4119 anonBind: anonBind,
4120 toLazy: toLazy,
4121 toCached: toCached,
4122 get: get
4123 };
4124 };
4125 var pure$1 = function (a) {
4126 return nu$4(function (callback) {
4127 callback(a);
4128 });
4129 };
4130 var Future = {
4131 nu: nu$4,
4132 pure: pure$1
4133 };
4134
4135 var par = function (asyncValues, nu) {
4136 return nu(function (callback) {
4137 var r = [];
4138 var count = 0;
4139 var cb = function (i) {
4140 return function (value) {
4141 r[i] = value;
4142 count++;
4143 if (count >= asyncValues.length) {
4144 callback(r);
4145 }
4146 };
4147 };
4148 if (asyncValues.length === 0) {
4149 callback([]);
4150 } else {
4151 each(asyncValues, function (asyncValue, i) {
4152 asyncValue.get(cb(i));
4153 });
4154 }
4155 });
4156 };
4157
4158 var par$1 = function (futures) {
4159 return par(futures, Future.nu);
4160 };
4161
4162 var value = function (o) {
4163 var is = function (v) {
4164 return o === v;
4165 };
4166 var or = function (opt) {
4167 return value(o);
4168 };
4169 var orThunk = function (f) {
4170 return value(o);
4171 };
4172 var map = function (f) {
4173 return value(f(o));
4174 };
4175 var mapError = function (f) {
4176 return value(o);
4177 };
4178 var each = function (f) {
4179 f(o);
4180 };
4181 var bind = function (f) {
4182 return f(o);
4183 };
4184 var fold = function (_, onValue) {
4185 return onValue(o);
4186 };
4187 var exists = function (f) {
4188 return f(o);
4189 };
4190 var forall = function (f) {
4191 return f(o);
4192 };
4193 var toOption = function () {
4194 return Option.some(o);
4195 };
4196 return {
4197 is: is,
4198 isValue: always,
4199 isError: never,
4200 getOr: constant(o),
4201 getOrThunk: constant(o),
4202 getOrDie: constant(o),
4203 or: or,
4204 orThunk: orThunk,
4205 fold: fold,
4206 map: map,
4207 mapError: mapError,
4208 each: each,
4209 bind: bind,
4210 exists: exists,
4211 forall: forall,
4212 toOption: toOption
4213 };
4214 };
4215 var error = function (message) {
4216 var getOrThunk = function (f) {
4217 return f();
4218 };
4219 var getOrDie = function () {
4220 return die(String(message))();
4221 };
4222 var or = function (opt) {
4223 return opt;
4224 };
4225 var orThunk = function (f) {
4226 return f();
4227 };
4228 var map = function (f) {
4229 return error(message);
4230 };
4231 var mapError = function (f) {
4232 return error(f(message));
4233 };
4234 var bind = function (f) {
4235 return error(message);
4236 };
4237 var fold = function (onError, _) {
4238 return onError(message);
4239 };
4240 return {
4241 is: never,
4242 isValue: never,
4243 isError: always,
4244 getOr: identity,
4245 getOrThunk: getOrThunk,
4246 getOrDie: getOrDie,
4247 or: or,
4248 orThunk: orThunk,
4249 fold: fold,
4250 map: map,
4251 mapError: mapError,
4252 each: noop,
4253 bind: bind,
4254 exists: never,
4255 forall: always,
4256 toOption: Option.none
4257 };
4258 };
4259 var fromOption = function (opt, err) {
4260 return opt.fold(function () {
4261 return error(err);
4262 }, value);
4263 };
4264 var Result = {
4265 value: value,
4266 error: error,
4267 fromOption: fromOption
4268 };
4269
4270 function StyleSheetLoader(document, settings) {
4271 if (settings === void 0) {
4272 settings = {};
4273 }
4274 var idCount = 0;
4275 var loadedStates = {};
4276 var maxLoadTime;
4277 maxLoadTime = settings.maxLoadTime || 5000;
4278 var appendToHead = function (node) {
4279 document.getElementsByTagName('head')[0].appendChild(node);
4280 };
4281 var load = function (url, loadedCallback, errorCallback) {
4282 var link, style, startTime, state;
4283 var resolve = function (status) {
4284 state.status = status;
4285 state.passed = [];
4286 state.failed = [];
4287 if (link) {
4288 link.onload = null;
4289 link.onerror = null;
4290 link = null;
4291 }
4292 };
4293 var passed = function () {
4294 var callbacks = state.passed;
4295 var i = callbacks.length;
4296 while (i--) {
4297 callbacks[i]();
4298 }
4299 resolve(2);
4300 };
4301 var failed = function () {
4302 var callbacks = state.failed;
4303 var i = callbacks.length;
4304 while (i--) {
4305 callbacks[i]();
4306 }
4307 resolve(3);
4308 };
4309 var isOldWebKit = function () {
4310 var webKitChunks = domGlobals.navigator.userAgent.match(/WebKit\/(\d*)/);
4311 return !!(webKitChunks && parseInt(webKitChunks[1], 10) < 536);
4312 };
4313 var wait = function (testCallback, waitCallback) {
4314 if (!testCallback()) {
4315 if (new Date().getTime() - startTime < maxLoadTime) {
4316 Delay.setTimeout(waitCallback);
4317 } else {
4318 failed();
4319 }
4320 }
4321 };
4322 var waitForWebKitLinkLoaded = function () {
4323 wait(function () {
4324 var styleSheets = document.styleSheets;
4325 var styleSheet, i = styleSheets.length, owner;
4326 while (i--) {
4327 styleSheet = styleSheets[i];
4328 owner = styleSheet.ownerNode ? styleSheet.ownerNode : styleSheet.owningElement;
4329 if (owner && owner.id === link.id) {
4330 passed();
4331 return true;
4332 }
4333 }
4334 }, waitForWebKitLinkLoaded);
4335 };
4336 var waitForGeckoLinkLoaded = function () {
4337 wait(function () {
4338 try {
4339 var cssRules = style.sheet.cssRules;
4340 passed();
4341 return !!cssRules;
4342 } catch (ex) {
4343 }
4344 }, waitForGeckoLinkLoaded);
4345 };
4346 url = Tools._addCacheSuffix(url);
4347 if (!loadedStates[url]) {
4348 state = {
4349 passed: [],
4350 failed: []
4351 };
4352 loadedStates[url] = state;
4353 } else {
4354 state = loadedStates[url];
4355 }
4356 if (loadedCallback) {
4357 state.passed.push(loadedCallback);
4358 }
4359 if (errorCallback) {
4360 state.failed.push(errorCallback);
4361 }
4362 if (state.status === 1) {
4363 return;
4364 }
4365 if (state.status === 2) {
4366 passed();
4367 return;
4368 }
4369 if (state.status === 3) {
4370 failed();
4371 return;
4372 }
4373 state.status = 1;
4374 link = document.createElement('link');
4375 link.rel = 'stylesheet';
4376 link.type = 'text/css';
4377 link.id = 'u' + idCount++;
4378 link.async = false;
4379 link.defer = false;
4380 startTime = new Date().getTime();
4381 if (settings.contentCssCors) {
4382 link.crossOrigin = 'anonymous';
4383 }
4384 if ('onload' in link && !isOldWebKit()) {
4385 link.onload = waitForWebKitLinkLoaded;
4386 link.onerror = failed;
4387 } else {
4388 if (domGlobals.navigator.userAgent.indexOf('Firefox') > 0) {
4389 style = document.createElement('style');
4390 style.textContent = '@import "' + url + '"';
4391 waitForGeckoLinkLoaded();
4392 appendToHead(style);
4393 return;
4394 }
4395 waitForWebKitLinkLoaded();
4396 }
4397 appendToHead(link);
4398 link.href = url;
4399 };
4400 var loadF = function (url) {
4401 return Future.nu(function (resolve) {
4402 load(url, compose(resolve, constant(Result.value(url))), compose(resolve, constant(Result.error(url))));
4403 });
4404 };
4405 var unbox = function (result) {
4406 return result.fold(identity, identity);
4407 };
4408 var loadAll = function (urls, success, failure) {
4409 par$1(map(urls, loadF)).get(function (result) {
4410 var parts = partition(result, function (r) {
4411 return r.isValue();
4412 });
4413 if (parts.fail.length > 0) {
4414 failure(parts.fail.map(unbox));
4415 } else {
4416 success(parts.pass.map(unbox));
4417 }
4418 });
4419 };
4420 return {
4421 load: load,
4422 loadAll: loadAll
4423 };
4424 }
4425
4426 var isNodeType = function (type) {
4427 return function (node) {
4428 return !!node && node.nodeType === type;
4429 };
4430 };
4431 var isRestrictedNode = function (node) {
4432 return !!node && !Object.getPrototypeOf(node);
4433 };
4434 var isElement$1 = isNodeType(1);
4435 var matchNodeNames = function (names) {
4436 var lowercasedNames = names.map(function (s) {
4437 return s.toLowerCase();
4438 });
4439 return function (node) {
4440 if (node && node.nodeName) {
4441 var nodeName = node.nodeName.toLowerCase();
4442 return contains(lowercasedNames, nodeName);
4443 }
4444 return false;
4445 };
4446 };
4447 var matchStyleValues = function (name, values) {
4448 var items = values.toLowerCase().split(' ');
4449 return function (node) {
4450 var i, cssValue;
4451 if (isElement$1(node)) {
4452 for (i = 0; i < items.length; i++) {
4453 var computed = node.ownerDocument.defaultView.getComputedStyle(node, null);
4454 cssValue = computed ? computed.getPropertyValue(name) : null;
4455 if (cssValue === items[i]) {
4456 return true;
4457 }
4458 }
4459 }
4460 return false;
4461 };
4462 };
4463 var hasPropValue = function (propName, propValue) {
4464 return function (node) {
4465 return isElement$1(node) && node[propName] === propValue;
4466 };
4467 };
4468 var hasAttribute = function (attrName, attrValue) {
4469 return function (node) {
4470 return isElement$1(node) && node.hasAttribute(attrName);
4471 };
4472 };
4473 var hasAttributeValue = function (attrName, attrValue) {
4474 return function (node) {
4475 return isElement$1(node) && node.getAttribute(attrName) === attrValue;
4476 };
4477 };
4478 var isBogus = function (node) {
4479 return isElement$1(node) && node.hasAttribute('data-mce-bogus');
4480 };
4481 var isBogusAll = function (node) {
4482 return isElement$1(node) && node.getAttribute('data-mce-bogus') === 'all';
4483 };
4484 var isTable = function (node) {
4485 return isElement$1(node) && node.tagName === 'TABLE';
4486 };
4487 var hasContentEditableState = function (value) {
4488 return function (node) {
4489 if (isElement$1(node)) {
4490 if (node.contentEditable === value) {
4491 return true;
4492 }
4493 if (node.getAttribute('data-mce-contenteditable') === value) {
4494 return true;
4495 }
4496 }
4497 return false;
4498 };
4499 };
4500 var isTextareaOrInput = matchNodeNames([
4501 'textarea',
4502 'input'
4503 ]);
4504 var isText$1 = isNodeType(3);
4505 var isComment = isNodeType(8);
4506 var isDocument$1 = isNodeType(9);
4507 var isDocumentFragment = isNodeType(11);
4508 var isBr = matchNodeNames(['br']);
4509 var isContentEditableTrue = hasContentEditableState('true');
4510 var isContentEditableFalse = hasContentEditableState('false');
4511 var NodeType = {
4512 isText: isText$1,
4513 isElement: isElement$1,
4514 isComment: isComment,
4515 isDocument: isDocument$1,
4516 isDocumentFragment: isDocumentFragment,
4517 isBr: isBr,
4518 isContentEditableTrue: isContentEditableTrue,
4519 isContentEditableFalse: isContentEditableFalse,
4520 isRestrictedNode: isRestrictedNode,
4521 matchNodeNames: matchNodeNames,
4522 hasPropValue: hasPropValue,
4523 hasAttribute: hasAttribute,
4524 hasAttributeValue: hasAttributeValue,
4525 matchStyleValues: matchStyleValues,
4526 isBogus: isBogus,
4527 isBogusAll: isBogusAll,
4528 isTable: isTable,
4529 isTextareaOrInput: isTextareaOrInput
4530 };
4531
4532 var TreeWalker = function () {
4533 function TreeWalker(startNode, rootNode) {
4534 this.node = startNode;
4535 this.rootNode = rootNode;
4536 this.current = this.current.bind(this);
4537 this.next = this.next.bind(this);
4538 this.prev = this.prev.bind(this);
4539 this.prev2 = this.prev2.bind(this);
4540 }
4541 TreeWalker.prototype.current = function () {
4542 return this.node;
4543 };
4544 TreeWalker.prototype.next = function (shallow) {
4545 this.node = this.findSibling(this.node, 'firstChild', 'nextSibling', shallow);
4546 return this.node;
4547 };
4548 TreeWalker.prototype.prev = function (shallow) {
4549 this.node = this.findSibling(this.node, 'lastChild', 'previousSibling', shallow);
4550 return this.node;
4551 };
4552 TreeWalker.prototype.prev2 = function (shallow) {
4553 this.node = this.findPreviousNode(this.node, 'lastChild', 'previousSibling', shallow);
4554 return this.node;
4555 };
4556 TreeWalker.prototype.findSibling = function (node, startName, siblingName, shallow) {
4557 var sibling, parent;
4558 if (node) {
4559 if (!shallow && node[startName]) {
4560 return node[startName];
4561 }
4562 if (node !== this.rootNode) {
4563 sibling = node[siblingName];
4564 if (sibling) {
4565 return sibling;
4566 }
4567 for (parent = node.parentNode; parent && parent !== this.rootNode; parent = parent.parentNode) {
4568 sibling = parent[siblingName];
4569 if (sibling) {
4570 return sibling;
4571 }
4572 }
4573 }
4574 }
4575 };
4576 TreeWalker.prototype.findPreviousNode = function (node, startName, siblingName, shallow) {
4577 var sibling, parent, child;
4578 if (node) {
4579 sibling = node[siblingName];
4580 if (this.rootNode && sibling === this.rootNode) {
4581 return;
4582 }
4583 if (sibling) {
4584 if (!shallow) {
4585 for (child = sibling[startName]; child; child = child[startName]) {
4586 if (!child[startName]) {
4587 return child;
4588 }
4589 }
4590 }
4591 return sibling;
4592 }
4593 parent = node.parentNode;
4594 if (parent && parent !== this.rootNode) {
4595 return parent;
4596 }
4597 }
4598 };
4599 return TreeWalker;
4600 }();
4601
4602 var blocks = [
4603 'article',
4604 'aside',
4605 'details',
4606 'div',
4607 'dt',
4608 'figcaption',
4609 'footer',
4610 'form',
4611 'fieldset',
4612 'header',
4613 'hgroup',
4614 'html',
4615 'main',
4616 'nav',
4617 'section',
4618 'summary',
4619 'body',
4620 'p',
4621 'dl',
4622 'multicol',
4623 'dd',
4624 'figure',
4625 'address',
4626 'center',
4627 'blockquote',
4628 'h1',
4629 'h2',
4630 'h3',
4631 'h4',
4632 'h5',
4633 'h6',
4634 'listing',
4635 'xmp',
4636 'pre',
4637 'plaintext',
4638 'menu',
4639 'dir',
4640 'ul',
4641 'ol',
4642 'li',
4643 'hr',
4644 'table',
4645 'tbody',
4646 'thead',
4647 'tfoot',
4648 'th',
4649 'tr',
4650 'td',
4651 'caption'
4652 ];
4653 var voids = [
4654 'area',
4655 'base',
4656 'basefont',
4657 'br',
4658 'col',
4659 'frame',
4660 'hr',
4661 'img',
4662 'input',
4663 'isindex',
4664 'link',
4665 'meta',
4666 'param',
4667 'embed',
4668 'source',
4669 'wbr',
4670 'track'
4671 ];
4672 var tableCells = [
4673 'td',
4674 'th'
4675 ];
4676 var tableSections = [
4677 'thead',
4678 'tbody',
4679 'tfoot'
4680 ];
4681 var textBlocks = [
4682 'h1',
4683 'h2',
4684 'h3',
4685 'h4',
4686 'h5',
4687 'h6',
4688 'p',
4689 'div',
4690 'address',
4691 'pre',
4692 'form',
4693 'blockquote',
4694 'center',
4695 'dir',
4696 'fieldset',
4697 'header',
4698 'footer',
4699 'article',
4700 'section',
4701 'hgroup',
4702 'aside',
4703 'nav',
4704 'figure'
4705 ];
4706 var headings = [
4707 'h1',
4708 'h2',
4709 'h3',
4710 'h4',
4711 'h5',
4712 'h6'
4713 ];
4714 var listItems = [
4715 'li',
4716 'dd',
4717 'dt'
4718 ];
4719 var lists = [
4720 'ul',
4721 'ol',
4722 'dl'
4723 ];
4724 var wsElements = [
4725 'pre',
4726 'script',
4727 'textarea',
4728 'style'
4729 ];
4730 var lazyLookup = function (items) {
4731 var lookup;
4732 return function (node) {
4733 lookup = lookup ? lookup : mapToObject(items, constant(true));
4734 return lookup.hasOwnProperty(name(node));
4735 };
4736 };
4737 var isHeading = lazyLookup(headings);
4738 var isBlock = lazyLookup(blocks);
4739 var isTable$1 = function (node) {
4740 return name(node) === 'table';
4741 };
4742 var isInline = function (node) {
4743 return isElement(node) && !isBlock(node);
4744 };
4745 var isBr$1 = function (node) {
4746 return isElement(node) && name(node) === 'br';
4747 };
4748 var isTextBlock = lazyLookup(textBlocks);
4749 var isList = lazyLookup(lists);
4750 var isListItem = lazyLookup(listItems);
4751 var isVoid = lazyLookup(voids);
4752 var isTableSection = lazyLookup(tableSections);
4753 var isTableCell = lazyLookup(tableCells);
4754 var isWsPreserveElement = lazyLookup(wsElements);
4755
4756 var surroundedBySpans = function (node) {
4757 var previousIsSpan = node.previousSibling && node.previousSibling.nodeName === 'SPAN';
4758 var nextIsSpan = node.nextSibling && node.nextSibling.nodeName === 'SPAN';
4759 return previousIsSpan && nextIsSpan;
4760 };
4761 var isBookmarkNode = function (node) {
4762 return node && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark';
4763 };
4764 var trimNode = function (dom, node) {
4765 var i, children = node.childNodes;
4766 if (NodeType.isElement(node) && isBookmarkNode(node)) {
4767 return;
4768 }
4769 for (i = children.length - 1; i >= 0; i--) {
4770 trimNode(dom, children[i]);
4771 }
4772 if (NodeType.isDocument(node) === false) {
4773 if (NodeType.isText(node) && node.nodeValue.length > 0) {
4774 var trimmedLength = Tools.trim(node.nodeValue).length;
4775 if (dom.isBlock(node.parentNode) || trimmedLength > 0) {
4776 return;
4777 }
4778 if (trimmedLength === 0 && surroundedBySpans(node)) {
4779 return;
4780 }
4781 } else if (NodeType.isElement(node)) {
4782 children = node.childNodes;
4783 if (children.length === 1 && isBookmarkNode(children[0])) {
4784 node.parentNode.insertBefore(children[0], node);
4785 }
4786 if (children.length || isVoid(Element.fromDom(node))) {
4787 return;
4788 }
4789 }
4790 dom.remove(node);
4791 }
4792 return node;
4793 };
4794 var TrimNode = { trimNode: trimNode };
4795
4796 var makeMap$1 = Tools.makeMap;
4797 var namedEntities, baseEntities, reverseEntities;
4798 var attrsCharsRegExp = /[&<>\"\u0060\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
4799 var textCharsRegExp = /[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
4800 var rawCharsRegExp = /[<>&\"\']/g;
4801 var entityRegExp = /&#([a-z0-9]+);?|&([a-z0-9]+);/gi;
4802 var asciiMap = {
4803 128: '\u20AC',
4804 130: '\u201A',
4805 131: '\u0192',
4806 132: '\u201E',
4807 133: '\u2026',
4808 134: '\u2020',
4809 135: '\u2021',
4810 136: '\u02c6',
4811 137: '\u2030',
4812 138: '\u0160',
4813 139: '\u2039',
4814 140: '\u0152',
4815 142: '\u017d',
4816 145: '\u2018',
4817 146: '\u2019',
4818 147: '\u201C',
4819 148: '\u201D',
4820 149: '\u2022',
4821 150: '\u2013',
4822 151: '\u2014',
4823 152: '\u02DC',
4824 153: '\u2122',
4825 154: '\u0161',
4826 155: '\u203A',
4827 156: '\u0153',
4828 158: '\u017e',
4829 159: '\u0178'
4830 };
4831 baseEntities = {
4832 '"': '&quot;',
4833 '\'': '&#39;',
4834 '<': '&lt;',
4835 '>': '&gt;',
4836 '&': '&amp;',
4837 '`': '&#96;'
4838 };
4839 reverseEntities = {
4840 '&lt;': '<',
4841 '&gt;': '>',
4842 '&amp;': '&',
4843 '&quot;': '"',
4844 '&apos;': '\''
4845 };
4846 var nativeDecode = function (text) {
4847 var elm;
4848 elm = Element.fromTag('div').dom();
4849 elm.innerHTML = text;
4850 return elm.textContent || elm.innerText || text;
4851 };
4852 var buildEntitiesLookup = function (items, radix) {
4853 var i, chr, entity;
4854 var lookup = {};
4855 if (items) {
4856 items = items.split(',');
4857 radix = radix || 10;
4858 for (i = 0; i < items.length; i += 2) {
4859 chr = String.fromCharCode(parseInt(items[i], radix));
4860 if (!baseEntities[chr]) {
4861 entity = '&' + items[i + 1] + ';';
4862 lookup[chr] = entity;
4863 lookup[entity] = chr;
4864 }
4865 }
4866 return lookup;
4867 }
4868 };
4869 namedEntities = buildEntitiesLookup('50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,' + '5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,' + '5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,' + '5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,' + '68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,' + '6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,' + '6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,' + '75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,' + '7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,' + '7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,' + 'sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,' + 'st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,' + 't9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,' + 'tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,' + 'u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,' + '81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,' + '8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,' + '8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,' + '8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,' + '8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,' + 'nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,' + 'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' + 'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' + '80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' + '811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro', 32);
4870 var encodeRaw = function (text, attr) {
4871 return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {
4872 return baseEntities[chr] || chr;
4873 });
4874 };
4875 var encodeAllRaw = function (text) {
4876 return ('' + text).replace(rawCharsRegExp, function (chr) {
4877 return baseEntities[chr] || chr;
4878 });
4879 };
4880 var encodeNumeric = function (text, attr) {
4881 return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {
4882 if (chr.length > 1) {
4883 return '&#' + ((chr.charCodeAt(0) - 55296) * 1024 + (chr.charCodeAt(1) - 56320) + 65536) + ';';
4884 }
4885 return baseEntities[chr] || '&#' + chr.charCodeAt(0) + ';';
4886 });
4887 };
4888 var encodeNamed = function (text, attr, entities) {
4889 entities = entities || namedEntities;
4890 return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {
4891 return baseEntities[chr] || entities[chr] || chr;
4892 });
4893 };
4894 var getEncodeFunc = function (name, entities) {
4895 var entitiesMap = buildEntitiesLookup(entities) || namedEntities;
4896 var encodeNamedAndNumeric = function (text, attr) {
4897 return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {
4898 if (baseEntities[chr] !== undefined) {
4899 return baseEntities[chr];
4900 }
4901 if (entitiesMap[chr] !== undefined) {
4902 return entitiesMap[chr];
4903 }
4904 if (chr.length > 1) {
4905 return '&#' + ((chr.charCodeAt(0) - 55296) * 1024 + (chr.charCodeAt(1) - 56320) + 65536) + ';';
4906 }
4907 return '&#' + chr.charCodeAt(0) + ';';
4908 });
4909 };
4910 var encodeCustomNamed = function (text, attr) {
4911 return encodeNamed(text, attr, entitiesMap);
4912 };
4913 var nameMap = makeMap$1(name.replace(/\+/g, ','));
4914 if (nameMap.named && nameMap.numeric) {
4915 return encodeNamedAndNumeric;
4916 }
4917 if (nameMap.named) {
4918 if (entities) {
4919 return encodeCustomNamed;
4920 }
4921 return encodeNamed;
4922 }
4923 if (nameMap.numeric) {
4924 return encodeNumeric;
4925 }
4926 return encodeRaw;
4927 };
4928 var decode = function (text) {
4929 return text.replace(entityRegExp, function (all, numeric) {
4930 if (numeric) {
4931 if (numeric.charAt(0).toLowerCase() === 'x') {
4932 numeric = parseInt(numeric.substr(1), 16);
4933 } else {
4934 numeric = parseInt(numeric, 10);
4935 }
4936 if (numeric > 65535) {
4937 numeric -= 65536;
4938 return String.fromCharCode(55296 + (numeric >> 10), 56320 + (numeric & 1023));
4939 }
4940 return asciiMap[numeric] || String.fromCharCode(numeric);
4941 }
4942 return reverseEntities[all] || namedEntities[all] || nativeDecode(all);
4943 });
4944 };
4945 var Entities = {
4946 encodeRaw: encodeRaw,
4947 encodeAllRaw: encodeAllRaw,
4948 encodeNumeric: encodeNumeric,
4949 encodeNamed: encodeNamed,
4950 getEncodeFunc: getEncodeFunc,
4951 decode: decode
4952 };
4953
4954 var mapCache = {}, dummyObj = {};
4955 var makeMap$2 = Tools.makeMap, each$4 = Tools.each, extend$1 = Tools.extend, explode$1 = Tools.explode, inArray$1 = Tools.inArray;
4956 var split = function (items, delim) {
4957 items = Tools.trim(items);
4958 return items ? items.split(delim || ' ') : [];
4959 };
4960 var compileSchema = function (type) {
4961 var schema = {};
4962 var globalAttributes, blockContent;
4963 var phrasingContent, flowContent, html4BlockContent, html4PhrasingContent;
4964 var add = function (name, attributes, children) {
4965 var ni, attributesOrder, element;
4966 var arrayToMap = function (array, obj) {
4967 var map = {};
4968 var i, l;
4969 for (i = 0, l = array.length; i < l; i++) {
4970 map[array[i]] = obj || {};
4971 }
4972 return map;
4973 };
4974 children = children || [];
4975 attributes = attributes || '';
4976 if (typeof children === 'string') {
4977 children = split(children);
4978 }
4979 name = split(name);
4980 ni = name.length;
4981 while (ni--) {
4982 attributesOrder = split([
4983 globalAttributes,
4984 attributes
4985 ].join(' '));
4986 element = {
4987 attributes: arrayToMap(attributesOrder),
4988 attributesOrder: attributesOrder,
4989 children: arrayToMap(children, dummyObj)
4990 };
4991 schema[name[ni]] = element;
4992 }
4993 };
4994 var addAttrs = function (name, attributes) {
4995 var ni, schemaItem, i, l;
4996 name = split(name);
4997 ni = name.length;
4998 attributes = split(attributes);
4999 while (ni--) {
5000 schemaItem = schema[name[ni]];
5001 for (i = 0, l = attributes.length; i < l; i++) {
5002 schemaItem.attributes[attributes[i]] = {};
5003 schemaItem.attributesOrder.push(attributes[i]);
5004 }
5005 }
5006 };
5007 if (mapCache[type]) {
5008 return mapCache[type];
5009 }
5010 globalAttributes = 'id accesskey class dir lang style tabindex title role';
5011 blockContent = 'address blockquote div dl fieldset form h1 h2 h3 h4 h5 h6 hr menu ol p pre table ul';
5012 phrasingContent = 'a abbr b bdo br button cite code del dfn em embed i iframe img input ins kbd ' + 'label map noscript object q s samp script select small span strong sub sup ' + 'textarea u var #text #comment';
5013 if (type !== 'html4') {
5014 globalAttributes += ' contenteditable contextmenu draggable dropzone ' + 'hidden spellcheck translate';
5015 blockContent += ' article aside details dialog figure main header footer hgroup section nav';
5016 phrasingContent += ' audio canvas command datalist mark meter output picture ' + 'progress time wbr video ruby bdi keygen';
5017 }
5018 if (type !== 'html5-strict') {
5019 globalAttributes += ' xml:lang';
5020 html4PhrasingContent = 'acronym applet basefont big font strike tt';
5021 phrasingContent = [
5022 phrasingContent,
5023 html4PhrasingContent
5024 ].join(' ');
5025 each$4(split(html4PhrasingContent), function (name) {
5026 add(name, '', phrasingContent);
5027 });
5028 html4BlockContent = 'center dir isindex noframes';
5029 blockContent = [
5030 blockContent,
5031 html4BlockContent
5032 ].join(' ');
5033 flowContent = [
5034 blockContent,
5035 phrasingContent
5036 ].join(' ');
5037 each$4(split(html4BlockContent), function (name) {
5038 add(name, '', flowContent);
5039 });
5040 }
5041 flowContent = flowContent || [
5042 blockContent,
5043 phrasingContent
5044 ].join(' ');
5045 add('html', 'manifest', 'head body');
5046 add('head', '', 'base command link meta noscript script style title');
5047 add('title hr noscript br');
5048 add('base', 'href target');
5049 add('link', 'href rel media hreflang type sizes hreflang');
5050 add('meta', 'name http-equiv content charset');
5051 add('style', 'media type scoped');
5052 add('script', 'src async defer type charset');
5053 add('body', 'onafterprint onbeforeprint onbeforeunload onblur onerror onfocus ' + 'onhashchange onload onmessage onoffline ononline onpagehide onpageshow ' + 'onpopstate onresize onscroll onstorage onunload', flowContent);
5054 add('address dt dd div caption', '', flowContent);
5055 add('h1 h2 h3 h4 h5 h6 pre p abbr code var samp kbd sub sup i b u bdo span legend em strong small s cite dfn', '', phrasingContent);
5056 add('blockquote', 'cite', flowContent);
5057 add('ol', 'reversed start type', 'li');
5058 add('ul', '', 'li');
5059 add('li', 'value', flowContent);
5060 add('dl', '', 'dt dd');
5061 add('a', 'href target rel media hreflang type', phrasingContent);
5062 add('q', 'cite', phrasingContent);
5063 add('ins del', 'cite datetime', flowContent);
5064 add('img', 'src sizes srcset alt usemap ismap width height');
5065 add('iframe', 'src name width height', flowContent);
5066 add('embed', 'src type width height');
5067 add('object', 'data type typemustmatch name usemap form width height', [
5068 flowContent,
5069 'param'
5070 ].join(' '));
5071 add('param', 'name value');
5072 add('map', 'name', [
5073 flowContent,
5074 'area'
5075 ].join(' '));
5076 add('area', 'alt coords shape href target rel media hreflang type');
5077 add('table', 'border', 'caption colgroup thead tfoot tbody tr' + (type === 'html4' ? ' col' : ''));
5078 add('colgroup', 'span', 'col');
5079 add('col', 'span');
5080 add('tbody thead tfoot', '', 'tr');
5081 add('tr', '', 'td th');
5082 add('td', 'colspan rowspan headers', flowContent);
5083 add('th', 'colspan rowspan headers scope abbr', flowContent);
5084 add('form', 'accept-charset action autocomplete enctype method name novalidate target', flowContent);
5085 add('fieldset', 'disabled form name', [
5086 flowContent,
5087 'legend'
5088 ].join(' '));
5089 add('label', 'form for', phrasingContent);
5090 add('input', 'accept alt autocomplete checked dirname disabled form formaction formenctype formmethod formnovalidate ' + 'formtarget height list max maxlength min multiple name pattern readonly required size src step type value width');
5091 add('button', 'disabled form formaction formenctype formmethod formnovalidate formtarget name type value', type === 'html4' ? flowContent : phrasingContent);
5092 add('select', 'disabled form multiple name required size', 'option optgroup');
5093 add('optgroup', 'disabled label', 'option');
5094 add('option', 'disabled label selected value');
5095 add('textarea', 'cols dirname disabled form maxlength name readonly required rows wrap');
5096 add('menu', 'type label', [
5097 flowContent,
5098 'li'
5099 ].join(' '));
5100 add('noscript', '', flowContent);
5101 if (type !== 'html4') {
5102 add('wbr');
5103 add('ruby', '', [
5104 phrasingContent,
5105 'rt rp'
5106 ].join(' '));
5107 add('figcaption', '', flowContent);
5108 add('mark rt rp summary bdi', '', phrasingContent);
5109 add('canvas', 'width height', flowContent);
5110 add('video', 'src crossorigin poster preload autoplay mediagroup loop ' + 'muted controls width height buffered', [
5111 flowContent,
5112 'track source'
5113 ].join(' '));
5114 add('audio', 'src crossorigin preload autoplay mediagroup loop muted controls ' + 'buffered volume', [
5115 flowContent,
5116 'track source'
5117 ].join(' '));
5118 add('picture', '', 'img source');
5119 add('source', 'src srcset type media sizes');
5120 add('track', 'kind src srclang label default');
5121 add('datalist', '', [
5122 phrasingContent,
5123 'option'
5124 ].join(' '));
5125 add('article section nav aside main header footer', '', flowContent);
5126 add('hgroup', '', 'h1 h2 h3 h4 h5 h6');
5127 add('figure', '', [
5128 flowContent,
5129 'figcaption'
5130 ].join(' '));
5131 add('time', 'datetime', phrasingContent);
5132 add('dialog', 'open', flowContent);
5133 add('command', 'type label icon disabled checked radiogroup command');
5134 add('output', 'for form name', phrasingContent);
5135 add('progress', 'value max', phrasingContent);
5136 add('meter', 'value min max low high optimum', phrasingContent);
5137 add('details', 'open', [
5138 flowContent,
5139 'summary'
5140 ].join(' '));
5141 add('keygen', 'autofocus challenge disabled form keytype name');
5142 }
5143 if (type !== 'html5-strict') {
5144 addAttrs('script', 'language xml:space');
5145 addAttrs('style', 'xml:space');
5146 addAttrs('object', 'declare classid code codebase codetype archive standby align border hspace vspace');
5147 addAttrs('embed', 'align name hspace vspace');
5148 addAttrs('param', 'valuetype type');
5149 addAttrs('a', 'charset name rev shape coords');
5150 addAttrs('br', 'clear');
5151 addAttrs('applet', 'codebase archive code object alt name width height align hspace vspace');
5152 addAttrs('img', 'name longdesc align border hspace vspace');
5153 addAttrs('iframe', 'longdesc frameborder marginwidth marginheight scrolling align');
5154 addAttrs('font basefont', 'size color face');
5155 addAttrs('input', 'usemap align');
5156 addAttrs('select', 'onchange');
5157 addAttrs('textarea');
5158 addAttrs('h1 h2 h3 h4 h5 h6 div p legend caption', 'align');
5159 addAttrs('ul', 'type compact');
5160 addAttrs('li', 'type');
5161 addAttrs('ol dl menu dir', 'compact');
5162 addAttrs('pre', 'width xml:space');
5163 addAttrs('hr', 'align noshade size width');
5164 addAttrs('isindex', 'prompt');
5165 addAttrs('table', 'summary width frame rules cellspacing cellpadding align bgcolor');
5166 addAttrs('col', 'width align char charoff valign');
5167 addAttrs('colgroup', 'width align char charoff valign');
5168 addAttrs('thead', 'align char charoff valign');
5169 addAttrs('tr', 'align char charoff valign bgcolor');
5170 addAttrs('th', 'axis align char charoff valign nowrap bgcolor width height');
5171 addAttrs('form', 'accept');
5172 addAttrs('td', 'abbr axis scope align char charoff valign nowrap bgcolor width height');
5173 addAttrs('tfoot', 'align char charoff valign');
5174 addAttrs('tbody', 'align char charoff valign');
5175 addAttrs('area', 'nohref');
5176 addAttrs('body', 'background bgcolor text link vlink alink');
5177 }
5178 if (type !== 'html4') {
5179 addAttrs('input button select textarea', 'autofocus');
5180 addAttrs('input textarea', 'placeholder');
5181 addAttrs('a', 'download');
5182 addAttrs('link script img', 'crossorigin');
5183 addAttrs('iframe', 'sandbox seamless allowfullscreen');
5184 }
5185 each$4(split('a form meter progress dfn'), function (name) {
5186 if (schema[name]) {
5187 delete schema[name].children[name];
5188 }
5189 });
5190 delete schema.caption.children.table;
5191 delete schema.script;
5192 mapCache[type] = schema;
5193 return schema;
5194 };
5195 var compileElementMap = function (value, mode) {
5196 var styles;
5197 if (value) {
5198 styles = {};
5199 if (typeof value === 'string') {
5200 value = { '*': value };
5201 }
5202 each$4(value, function (value, key) {
5203 styles[key] = styles[key.toUpperCase()] = mode === 'map' ? makeMap$2(value, /[, ]/) : explode$1(value, /[, ]/);
5204 });
5205 }
5206 return styles;
5207 };
5208 function Schema(settings) {
5209 var elements = {};
5210 var children = {};
5211 var patternElements = [];
5212 var validStyles;
5213 var invalidStyles;
5214 var schemaItems;
5215 var whiteSpaceElementsMap, selfClosingElementsMap, shortEndedElementsMap, boolAttrMap, validClasses;
5216 var blockElementsMap, nonEmptyElementsMap, moveCaretBeforeOnEnterElementsMap, textBlockElementsMap, textInlineElementsMap;
5217 var customElementsMap = {}, specialElements = {};
5218 var createLookupTable = function (option, defaultValue, extendWith) {
5219 var value = settings[option];
5220 if (!value) {
5221 value = mapCache[option];
5222 if (!value) {
5223 value = makeMap$2(defaultValue, ' ', makeMap$2(defaultValue.toUpperCase(), ' '));
5224 value = extend$1(value, extendWith);
5225 mapCache[option] = value;
5226 }
5227 } else {
5228 value = makeMap$2(value, /[, ]/, makeMap$2(value.toUpperCase(), /[, ]/));
5229 }
5230 return value;
5231 };
5232 settings = settings || {};
5233 schemaItems = compileSchema(settings.schema);
5234 if (settings.verify_html === false) {
5235 settings.valid_elements = '*[*]';
5236 }
5237 validStyles = compileElementMap(settings.valid_styles);
5238 invalidStyles = compileElementMap(settings.invalid_styles, 'map');
5239 validClasses = compileElementMap(settings.valid_classes, 'map');
5240 whiteSpaceElementsMap = createLookupTable('whitespace_elements', 'pre script noscript style textarea video audio iframe object code');
5241 selfClosingElementsMap = createLookupTable('self_closing_elements', 'colgroup dd dt li option p td tfoot th thead tr');
5242 shortEndedElementsMap = createLookupTable('short_ended_elements', 'area base basefont br col frame hr img input isindex link ' + 'meta param embed source wbr track');
5243 boolAttrMap = createLookupTable('boolean_attributes', 'checked compact declare defer disabled ismap multiple nohref noresize ' + 'noshade nowrap readonly selected autoplay loop controls');
5244 nonEmptyElementsMap = createLookupTable('non_empty_elements', 'td th iframe video audio object ' + 'script pre code', shortEndedElementsMap);
5245 moveCaretBeforeOnEnterElementsMap = createLookupTable('move_caret_before_on_enter_elements', 'table', nonEmptyElementsMap);
5246 textBlockElementsMap = createLookupTable('text_block_elements', 'h1 h2 h3 h4 h5 h6 p div address pre form ' + 'blockquote center dir fieldset header footer article section hgroup aside main nav figure');
5247 blockElementsMap = createLookupTable('block_elements', 'hr table tbody thead tfoot ' + 'th tr td li ol ul caption dl dt dd noscript menu isindex option ' + 'datalist select optgroup figcaption details summary', textBlockElementsMap);
5248 textInlineElementsMap = createLookupTable('text_inline_elements', 'span strong b em i font strike u var cite ' + 'dfn code mark q sup sub samp');
5249 each$4((settings.special || 'script noscript noframes noembed title style textarea xmp').split(' '), function (name) {
5250 specialElements[name] = new RegExp('</' + name + '[^>]*>', 'gi');
5251 });
5252 var patternToRegExp = function (str) {
5253 return new RegExp('^' + str.replace(/([?+*])/g, '.$1') + '$');
5254 };
5255 var addValidElements = function (validElements) {
5256 var ei, el, ai, al, matches, element, attr, attrData, elementName, attrName, attrType, attributes, attributesOrder, prefix, outputName, globalAttributes, globalAttributesOrder, key, value;
5257 var elementRuleRegExp = /^([#+\-])?([^\[!\/]+)(?:\/([^\[!]+))?(?:(!?)\[([^\]]+)\])?$/, attrRuleRegExp = /^([!\-])?(\w+[\\:]:\w+|[^=:<]+)?(?:([=:<])(.*))?$/, hasPatternsRegExp = /[*?+]/;
5258 if (validElements) {
5259 validElements = split(validElements, ',');
5260 if (elements['@']) {
5261 globalAttributes = elements['@'].attributes;
5262 globalAttributesOrder = elements['@'].attributesOrder;
5263 }
5264 for (ei = 0, el = validElements.length; ei < el; ei++) {
5265 matches = elementRuleRegExp.exec(validElements[ei]);
5266 if (matches) {
5267 prefix = matches[1];
5268 elementName = matches[2];
5269 outputName = matches[3];
5270 attrData = matches[5];
5271 attributes = {};
5272 attributesOrder = [];
5273 element = {
5274 attributes: attributes,
5275 attributesOrder: attributesOrder
5276 };
5277 if (prefix === '#') {
5278 element.paddEmpty = true;
5279 }
5280 if (prefix === '-') {
5281 element.removeEmpty = true;
5282 }
5283 if (matches[4] === '!') {
5284 element.removeEmptyAttrs = true;
5285 }
5286 if (globalAttributes) {
5287 for (key in globalAttributes) {
5288 attributes[key] = globalAttributes[key];
5289 }
5290 attributesOrder.push.apply(attributesOrder, globalAttributesOrder);
5291 }
5292 if (attrData) {
5293 attrData = split(attrData, '|');
5294 for (ai = 0, al = attrData.length; ai < al; ai++) {
5295 matches = attrRuleRegExp.exec(attrData[ai]);
5296 if (matches) {
5297 attr = {};
5298 attrType = matches[1];
5299 attrName = matches[2].replace(/[\\:]:/g, ':');
5300 prefix = matches[3];
5301 value = matches[4];
5302 if (attrType === '!') {
5303 element.attributesRequired = element.attributesRequired || [];
5304 element.attributesRequired.push(attrName);
5305 attr.required = true;
5306 }
5307 if (attrType === '-') {
5308 delete attributes[attrName];
5309 attributesOrder.splice(inArray$1(attributesOrder, attrName), 1);
5310 continue;
5311 }
5312 if (prefix) {
5313 if (prefix === '=') {
5314 element.attributesDefault = element.attributesDefault || [];
5315 element.attributesDefault.push({
5316 name: attrName,
5317 value: value
5318 });
5319 attr.defaultValue = value;
5320 }
5321 if (prefix === ':') {
5322 element.attributesForced = element.attributesForced || [];
5323 element.attributesForced.push({
5324 name: attrName,
5325 value: value
5326 });
5327 attr.forcedValue = value;
5328 }
5329 if (prefix === '<') {
5330 attr.validValues = makeMap$2(value, '?');
5331 }
5332 }
5333 if (hasPatternsRegExp.test(attrName)) {
5334 element.attributePatterns = element.attributePatterns || [];
5335 attr.pattern = patternToRegExp(attrName);
5336 element.attributePatterns.push(attr);
5337 } else {
5338 if (!attributes[attrName]) {
5339 attributesOrder.push(attrName);
5340 }
5341 attributes[attrName] = attr;
5342 }
5343 }
5344 }
5345 }
5346 if (!globalAttributes && elementName === '@') {
5347 globalAttributes = attributes;
5348 globalAttributesOrder = attributesOrder;
5349 }
5350 if (outputName) {
5351 element.outputName = elementName;
5352 elements[outputName] = element;
5353 }
5354 if (hasPatternsRegExp.test(elementName)) {
5355 element.pattern = patternToRegExp(elementName);
5356 patternElements.push(element);
5357 } else {
5358 elements[elementName] = element;
5359 }
5360 }
5361 }
5362 }
5363 };
5364 var setValidElements = function (validElements) {
5365 elements = {};
5366 patternElements = [];
5367 addValidElements(validElements);
5368 each$4(schemaItems, function (element, name) {
5369 children[name] = element.children;
5370 });
5371 };
5372 var addCustomElements = function (customElements) {
5373 var customElementRegExp = /^(~)?(.+)$/;
5374 if (customElements) {
5375 mapCache.text_block_elements = mapCache.block_elements = null;
5376 each$4(split(customElements, ','), function (rule) {
5377 var matches = customElementRegExp.exec(rule), inline = matches[1] === '~', cloneName = inline ? 'span' : 'div', name = matches[2];
5378 children[name] = children[cloneName];
5379 customElementsMap[name] = cloneName;
5380 if (!inline) {
5381 blockElementsMap[name.toUpperCase()] = {};
5382 blockElementsMap[name] = {};
5383 }
5384 if (!elements[name]) {
5385 var customRule = elements[cloneName];
5386 customRule = extend$1({}, customRule);
5387 delete customRule.removeEmptyAttrs;
5388 delete customRule.removeEmpty;
5389 elements[name] = customRule;
5390 }
5391 each$4(children, function (element, elmName) {
5392 if (element[cloneName]) {
5393 children[elmName] = element = extend$1({}, children[elmName]);
5394 element[name] = element[cloneName];
5395 }
5396 });
5397 });
5398 }
5399 };
5400 var addValidChildren = function (validChildren) {
5401 var childRuleRegExp = /^([+\-]?)(\w+)\[([^\]]+)\]$/;
5402 mapCache[settings.schema] = null;
5403 if (validChildren) {
5404 each$4(split(validChildren, ','), function (rule) {
5405 var matches = childRuleRegExp.exec(rule);
5406 var parent, prefix;
5407 if (matches) {
5408 prefix = matches[1];
5409 if (prefix) {
5410 parent = children[matches[2]];
5411 } else {
5412 parent = children[matches[2]] = { '#comment': {} };
5413 }
5414 parent = children[matches[2]];
5415 each$4(split(matches[3], '|'), function (child) {
5416 if (prefix === '-') {
5417 delete parent[child];
5418 } else {
5419 parent[child] = {};
5420 }
5421 });
5422 }
5423 });
5424 }
5425 };
5426 var getElementRule = function (name) {
5427 var element = elements[name], i;
5428 if (element) {
5429 return element;
5430 }
5431 i = patternElements.length;
5432 while (i--) {
5433 element = patternElements[i];
5434 if (element.pattern.test(name)) {
5435 return element;
5436 }
5437 }
5438 };
5439 if (!settings.valid_elements) {
5440 each$4(schemaItems, function (element, name) {
5441 elements[name] = {
5442 attributes: element.attributes,
5443 attributesOrder: element.attributesOrder
5444 };
5445 children[name] = element.children;
5446 });
5447 if (settings.schema !== 'html5') {
5448 each$4(split('strong/b em/i'), function (item) {
5449 item = split(item, '/');
5450 elements[item[1]].outputName = item[0];
5451 });
5452 }
5453 each$4(split('ol ul sub sup blockquote span font a table tbody tr strong em b i'), function (name) {
5454 if (elements[name]) {
5455 elements[name].removeEmpty = true;
5456 }
5457 });
5458 each$4(split('p h1 h2 h3 h4 h5 h6 th td pre div address caption li'), function (name) {
5459 elements[name].paddEmpty = true;
5460 });
5461 each$4(split('span'), function (name) {
5462 elements[name].removeEmptyAttrs = true;
5463 });
5464 } else {
5465 setValidElements(settings.valid_elements);
5466 }
5467 addCustomElements(settings.custom_elements);
5468 addValidChildren(settings.valid_children);
5469 addValidElements(settings.extended_valid_elements);
5470 addValidChildren('+ol[ul|ol],+ul[ul|ol]');
5471 each$4({
5472 dd: 'dl',
5473 dt: 'dl',
5474 li: 'ul ol',
5475 td: 'tr',
5476 th: 'tr',
5477 tr: 'tbody thead tfoot',
5478 tbody: 'table',
5479 thead: 'table',
5480 tfoot: 'table',
5481 legend: 'fieldset',
5482 area: 'map',
5483 param: 'video audio object'
5484 }, function (parents, item) {
5485 if (elements[item]) {
5486 elements[item].parentsRequired = split(parents);
5487 }
5488 });
5489 if (settings.invalid_elements) {
5490 each$4(explode$1(settings.invalid_elements), function (item) {
5491 if (elements[item]) {
5492 delete elements[item];
5493 }
5494 });
5495 }
5496 if (!getElementRule('span')) {
5497 addValidElements('span[!data-mce-type|*]');
5498 }
5499 var getValidStyles = function () {
5500 return validStyles;
5501 };
5502 var getInvalidStyles = function () {
5503 return invalidStyles;
5504 };
5505 var getValidClasses = function () {
5506 return validClasses;
5507 };
5508 var getBoolAttrs = function () {
5509 return boolAttrMap;
5510 };
5511 var getBlockElements = function () {
5512 return blockElementsMap;
5513 };
5514 var getTextBlockElements = function () {
5515 return textBlockElementsMap;
5516 };
5517 var getTextInlineElements = function () {
5518 return textInlineElementsMap;
5519 };
5520 var getShortEndedElements = function () {
5521 return shortEndedElementsMap;
5522 };
5523 var getSelfClosingElements = function () {
5524 return selfClosingElementsMap;
5525 };
5526 var getNonEmptyElements = function () {
5527 return nonEmptyElementsMap;
5528 };
5529 var getMoveCaretBeforeOnEnterElements = function () {
5530 return moveCaretBeforeOnEnterElementsMap;
5531 };
5532 var getWhiteSpaceElements = function () {
5533 return whiteSpaceElementsMap;
5534 };
5535 var getSpecialElements = function () {
5536 return specialElements;
5537 };
5538 var isValidChild = function (name, child) {
5539 var parent = children[name.toLowerCase()];
5540 return !!(parent && parent[child.toLowerCase()]);
5541 };
5542 var isValid = function (name, attr) {
5543 var attrPatterns, i;
5544 var rule = getElementRule(name);
5545 if (rule) {
5546 if (attr) {
5547 if (rule.attributes[attr]) {
5548 return true;
5549 }
5550 attrPatterns = rule.attributePatterns;
5551 if (attrPatterns) {
5552 i = attrPatterns.length;
5553 while (i--) {
5554 if (attrPatterns[i].pattern.test(name)) {
5555 return true;
5556 }
5557 }
5558 }
5559 } else {
5560 return true;
5561 }
5562 }
5563 return false;
5564 };
5565 var getCustomElements = function () {
5566 return customElementsMap;
5567 };
5568 return {
5569 children: children,
5570 elements: elements,
5571 getValidStyles: getValidStyles,
5572 getValidClasses: getValidClasses,
5573 getBlockElements: getBlockElements,
5574 getInvalidStyles: getInvalidStyles,
5575 getShortEndedElements: getShortEndedElements,
5576 getTextBlockElements: getTextBlockElements,
5577 getTextInlineElements: getTextInlineElements,
5578 getBoolAttrs: getBoolAttrs,
5579 getElementRule: getElementRule,
5580 getSelfClosingElements: getSelfClosingElements,
5581 getNonEmptyElements: getNonEmptyElements,
5582 getMoveCaretBeforeOnEnterElements: getMoveCaretBeforeOnEnterElements,
5583 getWhiteSpaceElements: getWhiteSpaceElements,
5584 getSpecialElements: getSpecialElements,
5585 isValidChild: isValidChild,
5586 isValid: isValid,
5587 getCustomElements: getCustomElements,
5588 addValidElements: addValidElements,
5589 setValidElements: setValidElements,
5590 addCustomElements: addCustomElements,
5591 addValidChildren: addValidChildren
5592 };
5593 }
5594
5595 var toHex = function (match, r, g, b) {
5596 var hex = function (val) {
5597 val = parseInt(val, 10).toString(16);
5598 return val.length > 1 ? val : '0' + val;
5599 };
5600 return '#' + hex(r) + hex(g) + hex(b);
5601 };
5602 var Styles = function (settings, schema) {
5603 var rgbRegExp = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi;
5604 var urlOrStrRegExp = /(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi;
5605 var styleRegExp = /\s*([^:]+):\s*([^;]+);?/g;
5606 var trimRightRegExp = /\s+$/;
5607 var i;
5608 var encodingLookup = {};
5609 var encodingItems;
5610 var validStyles;
5611 var invalidStyles;
5612 var invisibleChar = '\uFEFF';
5613 settings = settings || {};
5614 if (schema) {
5615 validStyles = schema.getValidStyles();
5616 invalidStyles = schema.getInvalidStyles();
5617 }
5618 encodingItems = ('\\" \\\' \\; \\: ; : ' + invisibleChar).split(' ');
5619 for (i = 0; i < encodingItems.length; i++) {
5620 encodingLookup[encodingItems[i]] = invisibleChar + i;
5621 encodingLookup[invisibleChar + i] = encodingItems[i];
5622 }
5623 return {
5624 toHex: function (color) {
5625 return color.replace(rgbRegExp, toHex);
5626 },
5627 parse: function (css) {
5628 var styles = {};
5629 var matches, name, value, isEncoded;
5630 var urlConverter = settings.url_converter;
5631 var urlConverterScope = settings.url_converter_scope || this;
5632 var compress = function (prefix, suffix, noJoin) {
5633 var top, right, bottom, left;
5634 top = styles[prefix + '-top' + suffix];
5635 if (!top) {
5636 return;
5637 }
5638 right = styles[prefix + '-right' + suffix];
5639 if (!right) {
5640 return;
5641 }
5642 bottom = styles[prefix + '-bottom' + suffix];
5643 if (!bottom) {
5644 return;
5645 }
5646 left = styles[prefix + '-left' + suffix];
5647 if (!left) {
5648 return;
5649 }
5650 var box = [
5651 top,
5652 right,
5653 bottom,
5654 left
5655 ];
5656 i = box.length - 1;
5657 while (i--) {
5658 if (box[i] !== box[i + 1]) {
5659 break;
5660 }
5661 }
5662 if (i > -1 && noJoin) {
5663 return;
5664 }
5665 styles[prefix + suffix] = i === -1 ? box[0] : box.join(' ');
5666 delete styles[prefix + '-top' + suffix];
5667 delete styles[prefix + '-right' + suffix];
5668 delete styles[prefix + '-bottom' + suffix];
5669 delete styles[prefix + '-left' + suffix];
5670 };
5671 var canCompress = function (key) {
5672 var value = styles[key], i;
5673 if (!value) {
5674 return;
5675 }
5676 value = value.split(' ');
5677 i = value.length;
5678 while (i--) {
5679 if (value[i] !== value[0]) {
5680 return false;
5681 }
5682 }
5683 styles[key] = value[0];
5684 return true;
5685 };
5686 var compress2 = function (target, a, b, c) {
5687 if (!canCompress(a)) {
5688 return;
5689 }
5690 if (!canCompress(b)) {
5691 return;
5692 }
5693 if (!canCompress(c)) {
5694 return;
5695 }
5696 styles[target] = styles[a] + ' ' + styles[b] + ' ' + styles[c];
5697 delete styles[a];
5698 delete styles[b];
5699 delete styles[c];
5700 };
5701 var encode = function (str) {
5702 isEncoded = true;
5703 return encodingLookup[str];
5704 };
5705 var decode = function (str, keepSlashes) {
5706 if (isEncoded) {
5707 str = str.replace(/\uFEFF[0-9]/g, function (str) {
5708 return encodingLookup[str];
5709 });
5710 }
5711 if (!keepSlashes) {
5712 str = str.replace(/\\([\'\";:])/g, '$1');
5713 }
5714 return str;
5715 };
5716 var decodeSingleHexSequence = function (escSeq) {
5717 return String.fromCharCode(parseInt(escSeq.slice(1), 16));
5718 };
5719 var decodeHexSequences = function (value) {
5720 return value.replace(/\\[0-9a-f]+/gi, decodeSingleHexSequence);
5721 };
5722 var processUrl = function (match, url, url2, url3, str, str2) {
5723 str = str || str2;
5724 if (str) {
5725 str = decode(str);
5726 return '\'' + str.replace(/\'/g, '\\\'') + '\'';
5727 }
5728 url = decode(url || url2 || url3);
5729 if (!settings.allow_script_urls) {
5730 var scriptUrl = url.replace(/[\s\r\n]+/g, '');
5731 if (/(java|vb)script:/i.test(scriptUrl)) {
5732 return '';
5733 }
5734 if (!settings.allow_svg_data_urls && /^data:image\/svg/i.test(scriptUrl)) {
5735 return '';
5736 }
5737 }
5738 if (urlConverter) {
5739 url = urlConverter.call(urlConverterScope, url, 'style');
5740 }
5741 return 'url(\'' + url.replace(/\'/g, '\\\'') + '\')';
5742 };
5743 if (css) {
5744 css = css.replace(/[\u0000-\u001F]/g, '');
5745 css = css.replace(/\\[\"\';:\uFEFF]/g, encode).replace(/\"[^\"]+\"|\'[^\']+\'/g, function (str) {
5746 return str.replace(/[;:]/g, encode);
5747 });
5748 while (matches = styleRegExp.exec(css)) {
5749 styleRegExp.lastIndex = matches.index + matches[0].length;
5750 name = matches[1].replace(trimRightRegExp, '').toLowerCase();
5751 value = matches[2].replace(trimRightRegExp, '');
5752 if (name && value) {
5753 name = decodeHexSequences(name);
5754 value = decodeHexSequences(value);
5755 if (name.indexOf(invisibleChar) !== -1 || name.indexOf('"') !== -1) {
5756 continue;
5757 }
5758 if (!settings.allow_script_urls && (name === 'behavior' || /expression\s*\(|\/\*|\*\//.test(value))) {
5759 continue;
5760 }
5761 if (name === 'font-weight' && value === '700') {
5762 value = 'bold';
5763 } else if (name === 'color' || name === 'background-color') {
5764 value = value.toLowerCase();
5765 }
5766 value = value.replace(rgbRegExp, toHex);
5767 value = value.replace(urlOrStrRegExp, processUrl);
5768 styles[name] = isEncoded ? decode(value, true) : value;
5769 }
5770 }
5771 compress('border', '', true);
5772 compress('border', '-width');
5773 compress('border', '-color');
5774 compress('border', '-style');
5775 compress('padding', '');
5776 compress('margin', '');
5777 compress2('border', 'border-width', 'border-style', 'border-color');
5778 if (styles.border === 'medium none') {
5779 delete styles.border;
5780 }
5781 if (styles['border-image'] === 'none') {
5782 delete styles['border-image'];
5783 }
5784 }
5785 return styles;
5786 },
5787 serialize: function (styles, elementName) {
5788 var css = '', name, value;
5789 var serializeStyles = function (name) {
5790 var styleList, i, l, value;
5791 styleList = validStyles[name];
5792 if (styleList) {
5793 for (i = 0, l = styleList.length; i < l; i++) {
5794 name = styleList[i];
5795 value = styles[name];
5796 if (value) {
5797 css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';
5798 }
5799 }
5800 }
5801 };
5802 var isValid = function (name, elementName) {
5803 var styleMap;
5804 styleMap = invalidStyles['*'];
5805 if (styleMap && styleMap[name]) {
5806 return false;
5807 }
5808 styleMap = invalidStyles[elementName];
5809 if (styleMap && styleMap[name]) {
5810 return false;
5811 }
5812 return true;
5813 };
5814 if (elementName && validStyles) {
5815 serializeStyles('*');
5816 serializeStyles(elementName);
5817 } else {
5818 for (name in styles) {
5819 value = styles[name];
5820 if (value && (!invalidStyles || isValid(name, elementName))) {
5821 css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';
5822 }
5823 }
5824 }
5825 return css;
5826 }
5827 };
5828 };
5829
5830 var each$5 = Tools.each;
5831 var grep$1 = Tools.grep;
5832 var isIE = Env.ie;
5833 var simpleSelectorRe = /^([a-z0-9],?)+$/i;
5834 var whiteSpaceRegExp$2 = /^[ \t\r\n]*$/;
5835 var setupAttrHooks = function (styles, settings, getContext) {
5836 var keepValues = settings.keep_values;
5837 var keepUrlHook = {
5838 set: function ($elm, value, name) {
5839 if (settings.url_converter) {
5840 value = settings.url_converter.call(settings.url_converter_scope || getContext(), value, name, $elm[0]);
5841 }
5842 $elm.attr('data-mce-' + name, value).attr(name, value);
5843 },
5844 get: function ($elm, name) {
5845 return $elm.attr('data-mce-' + name) || $elm.attr(name);
5846 }
5847 };
5848 var attrHooks = {
5849 style: {
5850 set: function ($elm, value) {
5851 if (value !== null && typeof value === 'object') {
5852 $elm.css(value);
5853 return;
5854 }
5855 if (keepValues) {
5856 $elm.attr('data-mce-style', value);
5857 }
5858 $elm.attr('style', value);
5859 },
5860 get: function ($elm) {
5861 var value = $elm.attr('data-mce-style') || $elm.attr('style');
5862 value = styles.serialize(styles.parse(value), $elm[0].nodeName);
5863 return value;
5864 }
5865 }
5866 };
5867 if (keepValues) {
5868 attrHooks.href = attrHooks.src = keepUrlHook;
5869 }
5870 return attrHooks;
5871 };
5872 var updateInternalStyleAttr = function (styles, $elm) {
5873 var rawValue = $elm.attr('style');
5874 var value = styles.serialize(styles.parse(rawValue), $elm[0].nodeName);
5875 if (!value) {
5876 value = null;
5877 }
5878 $elm.attr('data-mce-style', value);
5879 };
5880 var findNodeIndex = function (node, normalized) {
5881 var idx = 0, lastNodeType, nodeType;
5882 if (node) {
5883 for (lastNodeType = node.nodeType, node = node.previousSibling; node; node = node.previousSibling) {
5884 nodeType = node.nodeType;
5885 if (normalized && nodeType === 3) {
5886 if (nodeType === lastNodeType || !node.nodeValue.length) {
5887 continue;
5888 }
5889 }
5890 idx++;
5891 lastNodeType = nodeType;
5892 }
5893 }
5894 return idx;
5895 };
5896 function DOMUtils(doc, settings) {
5897 var _this = this;
5898 if (settings === void 0) {
5899 settings = {};
5900 }
5901 var attrHooks;
5902 var addedStyles = {};
5903 var win = domGlobals.window;
5904 var files = {};
5905 var counter = 0;
5906 var stdMode = true;
5907 var boxModel = true;
5908 var styleSheetLoader = StyleSheetLoader(doc, { contentCssCors: settings.contentCssCors });
5909 var boundEvents = [];
5910 var schema = settings.schema ? settings.schema : Schema({});
5911 var styles = Styles({
5912 url_converter: settings.url_converter,
5913 url_converter_scope: settings.url_converter_scope
5914 }, settings.schema);
5915 var events = settings.ownEvents ? new EventUtils() : EventUtils.Event;
5916 var blockElementsMap = schema.getBlockElements();
5917 var $ = DomQuery.overrideDefaults(function () {
5918 return {
5919 context: doc,
5920 element: self.getRoot()
5921 };
5922 });
5923 var isBlock = function (node) {
5924 if (typeof node === 'string') {
5925 return !!blockElementsMap[node];
5926 } else if (node) {
5927 var type = node.nodeType;
5928 if (type) {
5929 return !!(type === 1 && blockElementsMap[node.nodeName]);
5930 }
5931 }
5932 return false;
5933 };
5934 var get = function (elm) {
5935 if (elm && doc && typeof elm === 'string') {
5936 var node = doc.getElementById(elm);
5937 if (node && node.id !== elm) {
5938 return doc.getElementsByName(elm)[1];
5939 } else {
5940 return node;
5941 }
5942 }
5943 return elm;
5944 };
5945 var $$ = function (elm) {
5946 if (typeof elm === 'string') {
5947 elm = get(elm);
5948 }
5949 return $(elm);
5950 };
5951 var getAttrib = function (elm, name, defaultVal) {
5952 var hook, value;
5953 var $elm = $$(elm);
5954 if ($elm.length) {
5955 hook = attrHooks[name];
5956 if (hook && hook.get) {
5957 value = hook.get($elm, name);
5958 } else {
5959 value = $elm.attr(name);
5960 }
5961 }
5962 if (typeof value === 'undefined') {
5963 value = defaultVal || '';
5964 }
5965 return value;
5966 };
5967 var getAttribs = function (elm) {
5968 var node = get(elm);
5969 if (!node) {
5970 return [];
5971 }
5972 return node.attributes;
5973 };
5974 var setAttrib = function (elm, name, value) {
5975 var originalValue, hook;
5976 if (value === '') {
5977 value = null;
5978 }
5979 var $elm = $$(elm);
5980 originalValue = $elm.attr(name);
5981 if (!$elm.length) {
5982 return;
5983 }
5984 hook = attrHooks[name];
5985 if (hook && hook.set) {
5986 hook.set($elm, value, name);
5987 } else {
5988 $elm.attr(name, value);
5989 }
5990 if (originalValue !== value && settings.onSetAttrib) {
5991 settings.onSetAttrib({
5992 attrElm: $elm,
5993 attrName: name,
5994 attrValue: value
5995 });
5996 }
5997 };
5998 var clone = function (node, deep) {
5999 if (!isIE || node.nodeType !== 1 || deep) {
6000 return node.cloneNode(deep);
6001 }
6002 if (!deep) {
6003 var clone_1 = doc.createElement(node.nodeName);
6004 each$5(getAttribs(node), function (attr) {
6005 setAttrib(clone_1, attr.nodeName, getAttrib(node, attr.nodeName));
6006 });
6007 return clone_1;
6008 }
6009 return null;
6010 };
6011 var getRoot = function () {
6012 return settings.root_element || doc.body;
6013 };
6014 var getViewPort = function (argWin) {
6015 var actWin = !argWin ? win : argWin;
6016 var doc = actWin.document;
6017 var rootElm = doc.documentElement ;
6018 return {
6019 x: actWin.pageXOffset || rootElm.scrollLeft,
6020 y: actWin.pageYOffset || rootElm.scrollTop,
6021 w: actWin.innerWidth || rootElm.clientWidth,
6022 h: actWin.innerHeight || rootElm.clientHeight
6023 };
6024 };
6025 var getPos = function (elm, rootElm) {
6026 return Position.getPos(doc.body, get(elm), rootElm);
6027 };
6028 var setStyle = function (elm, name, value) {
6029 var $elm = isString(name) ? $$(elm).css(name, value) : $$(elm).css(name);
6030 if (settings.update_styles) {
6031 updateInternalStyleAttr(styles, $elm);
6032 }
6033 };
6034 var setStyles = function (elm, stylesArg) {
6035 var $elm = $$(elm).css(stylesArg);
6036 if (settings.update_styles) {
6037 updateInternalStyleAttr(styles, $elm);
6038 }
6039 };
6040 var getStyle = function (elm, name, computed) {
6041 var $elm = $$(elm);
6042 if (computed) {
6043 return $elm.css(name);
6044 }
6045 name = name.replace(/-(\D)/g, function (a, b) {
6046 return b.toUpperCase();
6047 });
6048 if (name === 'float') {
6049 name = Env.ie && Env.ie < 12 ? 'styleFloat' : 'cssFloat';
6050 }
6051 return $elm[0] && $elm[0].style ? $elm[0].style[name] : undefined;
6052 };
6053 var getSize = function (elm) {
6054 var w, h;
6055 elm = get(elm);
6056 w = getStyle(elm, 'width');
6057 h = getStyle(elm, 'height');
6058 if (w.indexOf('px') === -1) {
6059 w = 0;
6060 }
6061 if (h.indexOf('px') === -1) {
6062 h = 0;
6063 }
6064 return {
6065 w: parseInt(w, 10) || elm.offsetWidth || elm.clientWidth,
6066 h: parseInt(h, 10) || elm.offsetHeight || elm.clientHeight
6067 };
6068 };
6069 var getRect = function (elm) {
6070 var pos, size;
6071 elm = get(elm);
6072 pos = getPos(elm);
6073 size = getSize(elm);
6074 return {
6075 x: pos.x,
6076 y: pos.y,
6077 w: size.w,
6078 h: size.h
6079 };
6080 };
6081 var is = function (elm, selector) {
6082 var i;
6083 if (!elm) {
6084 return false;
6085 }
6086 if (!Array.isArray(elm)) {
6087 if (selector === '*') {
6088 return elm.nodeType === 1;
6089 }
6090 if (simpleSelectorRe.test(selector)) {
6091 var selectors = selector.toLowerCase().split(/,/);
6092 var elmName = elm.nodeName.toLowerCase();
6093 for (i = selectors.length - 1; i >= 0; i--) {
6094 if (selectors[i] === elmName) {
6095 return true;
6096 }
6097 }
6098 return false;
6099 }
6100 if (elm.nodeType && elm.nodeType !== 1) {
6101 return false;
6102 }
6103 }
6104 var elms = !Array.isArray(elm) ? [elm] : elm;
6105 return Sizzle(selector, elms[0].ownerDocument || elms[0], null, elms).length > 0;
6106 };
6107 var getParents = function (elm, selector, root, collect) {
6108 var result = [];
6109 var selectorVal;
6110 var node = get(elm);
6111 collect = collect === undefined;
6112 root = root || (getRoot().nodeName !== 'BODY' ? getRoot().parentNode : null);
6113 if (Tools.is(selector, 'string')) {
6114 selectorVal = selector;
6115 if (selector === '*') {
6116 selector = function (node) {
6117 return node.nodeType === 1;
6118 };
6119 } else {
6120 selector = function (node) {
6121 return is(node, selectorVal);
6122 };
6123 }
6124 }
6125 while (node) {
6126 if (node === root || !node.nodeType || node.nodeType === 9) {
6127 break;
6128 }
6129 if (!selector || typeof selector === 'function' && selector(node)) {
6130 if (collect) {
6131 result.push(node);
6132 } else {
6133 return [node];
6134 }
6135 }
6136 node = node.parentNode;
6137 }
6138 return collect ? result : null;
6139 };
6140 var getParent = function (node, selector, root) {
6141 var parents = getParents(node, selector, root, false);
6142 return parents && parents.length > 0 ? parents[0] : null;
6143 };
6144 var _findSib = function (node, selector, name) {
6145 var func = selector;
6146 if (node) {
6147 if (typeof selector === 'string') {
6148 func = function (node) {
6149 return is(node, selector);
6150 };
6151 }
6152 for (node = node[name]; node; node = node[name]) {
6153 if (typeof func === 'function' && func(node)) {
6154 return node;
6155 }
6156 }
6157 }
6158 return null;
6159 };
6160 var getNext = function (node, selector) {
6161 return _findSib(node, selector, 'nextSibling');
6162 };
6163 var getPrev = function (node, selector) {
6164 return _findSib(node, selector, 'previousSibling');
6165 };
6166 var select = function (selector, scope) {
6167 return Sizzle(selector, get(scope) || settings.root_element || doc, []);
6168 };
6169 var run = function (elm, func, scope) {
6170 var result;
6171 var node = typeof elm === 'string' ? get(elm) : elm;
6172 if (!node) {
6173 return false;
6174 }
6175 if (Tools.isArray(node) && (node.length || node.length === 0)) {
6176 result = [];
6177 each$5(node, function (elm, i) {
6178 if (elm) {
6179 if (typeof elm === 'string') {
6180 elm = get(elm);
6181 }
6182 result.push(func.call(scope, elm, i));
6183 }
6184 });
6185 return result;
6186 }
6187 var context = scope ? scope : _this;
6188 return func.call(context, node);
6189 };
6190 var setAttribs = function (elm, attrs) {
6191 $$(elm).each(function (i, node) {
6192 each$5(attrs, function (value, name) {
6193 setAttrib(node, name, value);
6194 });
6195 });
6196 };
6197 var setHTML = function (elm, html) {
6198 var $elm = $$(elm);
6199 if (isIE) {
6200 $elm.each(function (i, target) {
6201 if (target.canHaveHTML === false) {
6202 return;
6203 }
6204 while (target.firstChild) {
6205 target.removeChild(target.firstChild);
6206 }
6207 try {
6208 target.innerHTML = '<br>' + html;
6209 target.removeChild(target.firstChild);
6210 } catch (ex) {
6211 DomQuery('<div></div>').html('<br>' + html).contents().slice(1).appendTo(target);
6212 }
6213 return html;
6214 });
6215 } else {
6216 $elm.html(html);
6217 }
6218 };
6219 var add = function (parentElm, name, attrs, html, create) {
6220 return run(parentElm, function (parentElm) {
6221 var newElm = typeof name === 'string' ? doc.createElement(name) : name;
6222 setAttribs(newElm, attrs);
6223 if (html) {
6224 if (typeof html !== 'string' && html.nodeType) {
6225 newElm.appendChild(html);
6226 } else if (typeof html === 'string') {
6227 setHTML(newElm, html);
6228 }
6229 }
6230 return !create ? parentElm.appendChild(newElm) : newElm;
6231 });
6232 };
6233 var create = function (name, attrs, html) {
6234 return add(doc.createElement(name), name, attrs, html, true);
6235 };
6236 var decode = Entities.decode;
6237 var encode = Entities.encodeAllRaw;
6238 var createHTML = function (name, attrs, html) {
6239 var outHtml = '', key;
6240 outHtml += '<' + name;
6241 for (key in attrs) {
6242 if (attrs.hasOwnProperty(key) && attrs[key] !== null && typeof attrs[key] !== 'undefined') {
6243 outHtml += ' ' + key + '="' + encode(attrs[key]) + '"';
6244 }
6245 }
6246 if (typeof html !== 'undefined') {
6247 return outHtml + '>' + html + '</' + name + '>';
6248 }
6249 return outHtml + ' />';
6250 };
6251 var createFragment = function (html) {
6252 var node;
6253 var container = doc.createElement('div');
6254 var frag = doc.createDocumentFragment();
6255 if (html) {
6256 container.innerHTML = html;
6257 }
6258 while (node = container.firstChild) {
6259 frag.appendChild(node);
6260 }
6261 return frag;
6262 };
6263 var remove = function (node, keepChildren) {
6264 var $node = $$(node);
6265 if (keepChildren) {
6266 $node.each(function () {
6267 var child;
6268 while (child = this.firstChild) {
6269 if (child.nodeType === 3 && child.data.length === 0) {
6270 this.removeChild(child);
6271 } else {
6272 this.parentNode.insertBefore(child, this);
6273 }
6274 }
6275 }).remove();
6276 } else {
6277 $node.remove();
6278 }
6279 return $node.length > 1 ? $node.toArray() : $node[0];
6280 };
6281 var removeAllAttribs = function (e) {
6282 return run(e, function (e) {
6283 var i;
6284 var attrs = e.attributes;
6285 for (i = attrs.length - 1; i >= 0; i--) {
6286 e.removeAttributeNode(attrs.item(i));
6287 }
6288 });
6289 };
6290 var parseStyle = function (cssText) {
6291 return styles.parse(cssText);
6292 };
6293 var serializeStyle = function (stylesArg, name) {
6294 return styles.serialize(stylesArg, name);
6295 };
6296 var addStyle = function (cssText) {
6297 var head, styleElm;
6298 if (self !== DOMUtils.DOM && doc === domGlobals.document) {
6299 if (addedStyles[cssText]) {
6300 return;
6301 }
6302 addedStyles[cssText] = true;
6303 }
6304 styleElm = doc.getElementById('mceDefaultStyles');
6305 if (!styleElm) {
6306 styleElm = doc.createElement('style');
6307 styleElm.id = 'mceDefaultStyles';
6308 styleElm.type = 'text/css';
6309 head = doc.getElementsByTagName('head')[0];
6310 if (head.firstChild) {
6311 head.insertBefore(styleElm, head.firstChild);
6312 } else {
6313 head.appendChild(styleElm);
6314 }
6315 }
6316 if (styleElm.styleSheet) {
6317 styleElm.styleSheet.cssText += cssText;
6318 } else {
6319 styleElm.appendChild(doc.createTextNode(cssText));
6320 }
6321 };
6322 var loadCSS = function (url) {
6323 var head;
6324 if (self !== DOMUtils.DOM && doc === domGlobals.document) {
6325 DOMUtils.DOM.loadCSS(url);
6326 return;
6327 }
6328 if (!url) {
6329 url = '';
6330 }
6331 head = doc.getElementsByTagName('head')[0];
6332 each$5(url.split(','), function (url) {
6333 var link;
6334 url = Tools._addCacheSuffix(url);
6335 if (files[url]) {
6336 return;
6337 }
6338 files[url] = true;
6339 link = create('link', __assign({
6340 rel: 'stylesheet',
6341 type: 'text/css',
6342 href: url
6343 }, settings.contentCssCors ? { crossOrigin: 'anonymous' } : {}));
6344 head.appendChild(link);
6345 });
6346 };
6347 var toggleClass = function (elm, cls, state) {
6348 $$(elm).toggleClass(cls, state).each(function () {
6349 if (this.className === '') {
6350 DomQuery(this).attr('class', null);
6351 }
6352 });
6353 };
6354 var addClass = function (elm, cls) {
6355 $$(elm).addClass(cls);
6356 };
6357 var removeClass = function (elm, cls) {
6358 toggleClass(elm, cls, false);
6359 };
6360 var hasClass = function (elm, cls) {
6361 return $$(elm).hasClass(cls);
6362 };
6363 var show = function (elm) {
6364 $$(elm).show();
6365 };
6366 var hide = function (elm) {
6367 $$(elm).hide();
6368 };
6369 var isHidden = function (elm) {
6370 return $$(elm).css('display') === 'none';
6371 };
6372 var uniqueId = function (prefix) {
6373 return (!prefix ? 'mce_' : prefix) + counter++;
6374 };
6375 var getOuterHTML = function (elm) {
6376 var node = typeof elm === 'string' ? get(elm) : elm;
6377 return NodeType.isElement(node) ? node.outerHTML : DomQuery('<div></div>').append(DomQuery(node).clone()).html();
6378 };
6379 var setOuterHTML = function (elm, html) {
6380 $$(elm).each(function () {
6381 try {
6382 if ('outerHTML' in this) {
6383 this.outerHTML = html;
6384 return;
6385 }
6386 } catch (ex) {
6387 }
6388 remove(DomQuery(this).html(html), true);
6389 });
6390 };
6391 var insertAfter = function (node, reference) {
6392 var referenceNode = get(reference);
6393 return run(node, function (node) {
6394 var parent, nextSibling;
6395 parent = referenceNode.parentNode;
6396 nextSibling = referenceNode.nextSibling;
6397 if (nextSibling) {
6398 parent.insertBefore(node, nextSibling);
6399 } else {
6400 parent.appendChild(node);
6401 }
6402 return node;
6403 });
6404 };
6405 var replace = function (newElm, oldElm, keepChildren) {
6406 return run(oldElm, function (oldElm) {
6407 if (Tools.is(oldElm, 'array')) {
6408 newElm = newElm.cloneNode(true);
6409 }
6410 if (keepChildren) {
6411 each$5(grep$1(oldElm.childNodes), function (node) {
6412 newElm.appendChild(node);
6413 });
6414 }
6415 return oldElm.parentNode.replaceChild(newElm, oldElm);
6416 });
6417 };
6418 var rename = function (elm, name) {
6419 var newElm;
6420 if (elm.nodeName !== name.toUpperCase()) {
6421 newElm = create(name);
6422 each$5(getAttribs(elm), function (attrNode) {
6423 setAttrib(newElm, attrNode.nodeName, getAttrib(elm, attrNode.nodeName));
6424 });
6425 replace(newElm, elm, true);
6426 }
6427 return newElm || elm;
6428 };
6429 var findCommonAncestor = function (a, b) {
6430 var ps = a, pe;
6431 while (ps) {
6432 pe = b;
6433 while (pe && ps !== pe) {
6434 pe = pe.parentNode;
6435 }
6436 if (ps === pe) {
6437 break;
6438 }
6439 ps = ps.parentNode;
6440 }
6441 if (!ps && a.ownerDocument) {
6442 return a.ownerDocument.documentElement;
6443 }
6444 return ps;
6445 };
6446 var toHex = function (rgbVal) {
6447 return styles.toHex(Tools.trim(rgbVal));
6448 };
6449 var isEmpty = function (node, elements) {
6450 var i, attributes, type, name, brCount = 0;
6451 node = node.firstChild;
6452 if (node) {
6453 var walker = new TreeWalker(node, node.parentNode);
6454 var whitespace = schema ? schema.getWhiteSpaceElements() : {};
6455 elements = elements || (schema ? schema.getNonEmptyElements() : null);
6456 do {
6457 type = node.nodeType;
6458 if (NodeType.isElement(node)) {
6459 var bogusVal = node.getAttribute('data-mce-bogus');
6460 if (bogusVal) {
6461 node = walker.next(bogusVal === 'all');
6462 continue;
6463 }
6464 name = node.nodeName.toLowerCase();
6465 if (elements && elements[name]) {
6466 if (name === 'br') {
6467 brCount++;
6468 node = walker.next();
6469 continue;
6470 }
6471 return false;
6472 }
6473 attributes = getAttribs(node);
6474 i = attributes.length;
6475 while (i--) {
6476 name = attributes[i].nodeName;
6477 if (name === 'name' || name === 'data-mce-bookmark') {
6478 return false;
6479 }
6480 }
6481 }
6482 if (type === 8) {
6483 return false;
6484 }
6485 if (type === 3 && !whiteSpaceRegExp$2.test(node.nodeValue)) {
6486 return false;
6487 }
6488 if (type === 3 && node.parentNode && whitespace[node.parentNode.nodeName] && whiteSpaceRegExp$2.test(node.nodeValue)) {
6489 return false;
6490 }
6491 node = walker.next();
6492 } while (node);
6493 }
6494 return brCount <= 1;
6495 };
6496 var createRng = function () {
6497 return doc.createRange();
6498 };
6499 var split = function (parentElm, splitElm, replacementElm) {
6500 var r = createRng(), bef, aft, pa;
6501 if (parentElm && splitElm) {
6502 r.setStart(parentElm.parentNode, findNodeIndex(parentElm));
6503 r.setEnd(splitElm.parentNode, findNodeIndex(splitElm));
6504 bef = r.extractContents();
6505 r = createRng();
6506 r.setStart(splitElm.parentNode, findNodeIndex(splitElm) + 1);
6507 r.setEnd(parentElm.parentNode, findNodeIndex(parentElm) + 1);
6508 aft = r.extractContents();
6509 pa = parentElm.parentNode;
6510 pa.insertBefore(TrimNode.trimNode(self, bef), parentElm);
6511 if (replacementElm) {
6512 pa.insertBefore(replacementElm, parentElm);
6513 } else {
6514 pa.insertBefore(splitElm, parentElm);
6515 }
6516 pa.insertBefore(TrimNode.trimNode(self, aft), parentElm);
6517 remove(parentElm);
6518 return replacementElm || splitElm;
6519 }
6520 };
6521 var bind = function (target, name, func, scope) {
6522 if (Tools.isArray(target)) {
6523 var i = target.length;
6524 var rv = [];
6525 while (i--) {
6526 rv[i] = bind(target[i], name, func, scope);
6527 }
6528 return rv;
6529 }
6530 if (settings.collect && (target === doc || target === win)) {
6531 boundEvents.push([
6532 target,
6533 name,
6534 func,
6535 scope
6536 ]);
6537 }
6538 return events.bind(target, name, func, scope || self);
6539 };
6540 var unbind = function (target, name, func) {
6541 var i;
6542 if (Tools.isArray(target)) {
6543 i = target.length;
6544 var rv = [];
6545 while (i--) {
6546 rv[i] = unbind(target[i], name, func);
6547 }
6548 return rv;
6549 }
6550 if (boundEvents && (target === doc || target === win)) {
6551 i = boundEvents.length;
6552 while (i--) {
6553 var item = boundEvents[i];
6554 if (target === item[0] && (!name || name === item[1]) && (!func || func === item[2])) {
6555 events.unbind(item[0], item[1], item[2]);
6556 }
6557 }
6558 }
6559 return events.unbind(target, name, func);
6560 };
6561 var fire = function (target, name, evt) {
6562 return events.fire(target, name, evt);
6563 };
6564 var getContentEditable = function (node) {
6565 if (node && NodeType.isElement(node)) {
6566 var contentEditable = node.getAttribute('data-mce-contenteditable');
6567 if (contentEditable && contentEditable !== 'inherit') {
6568 return contentEditable;
6569 }
6570 return node.contentEditable !== 'inherit' ? node.contentEditable : null;
6571 } else {
6572 return null;
6573 }
6574 };
6575 var getContentEditableParent = function (node) {
6576 var root = getRoot();
6577 var state = null;
6578 for (; node && node !== root; node = node.parentNode) {
6579 state = getContentEditable(node);
6580 if (state !== null) {
6581 break;
6582 }
6583 }
6584 return state;
6585 };
6586 var destroy = function () {
6587 if (boundEvents) {
6588 var i = boundEvents.length;
6589 while (i--) {
6590 var item = boundEvents[i];
6591 events.unbind(item[0], item[1], item[2]);
6592 }
6593 }
6594 if (Sizzle.setDocument) {
6595 Sizzle.setDocument();
6596 }
6597 };
6598 var isChildOf = function (node, parent) {
6599 while (node) {
6600 if (parent === node) {
6601 return true;
6602 }
6603 node = node.parentNode;
6604 }
6605 return false;
6606 };
6607 var dumpRng = function (r) {
6608 return 'startContainer: ' + r.startContainer.nodeName + ', startOffset: ' + r.startOffset + ', endContainer: ' + r.endContainer.nodeName + ', endOffset: ' + r.endOffset;
6609 };
6610 var self = {
6611 doc: doc,
6612 settings: settings,
6613 win: win,
6614 files: files,
6615 stdMode: stdMode,
6616 boxModel: boxModel,
6617 styleSheetLoader: styleSheetLoader,
6618 boundEvents: boundEvents,
6619 styles: styles,
6620 schema: schema,
6621 events: events,
6622 isBlock: isBlock,
6623 $: $,
6624 $$: $$,
6625 root: null,
6626 clone: clone,
6627 getRoot: getRoot,
6628 getViewPort: getViewPort,
6629 getRect: getRect,
6630 getSize: getSize,
6631 getParent: getParent,
6632 getParents: getParents,
6633 get: get,
6634 getNext: getNext,
6635 getPrev: getPrev,
6636 select: select,
6637 is: is,
6638 add: add,
6639 create: create,
6640 createHTML: createHTML,
6641 createFragment: createFragment,
6642 remove: remove,
6643 setStyle: setStyle,
6644 getStyle: getStyle,
6645 setStyles: setStyles,
6646 removeAllAttribs: removeAllAttribs,
6647 setAttrib: setAttrib,
6648 setAttribs: setAttribs,
6649 getAttrib: getAttrib,
6650 getPos: getPos,
6651 parseStyle: parseStyle,
6652 serializeStyle: serializeStyle,
6653 addStyle: addStyle,
6654 loadCSS: loadCSS,
6655 addClass: addClass,
6656 removeClass: removeClass,
6657 hasClass: hasClass,
6658 toggleClass: toggleClass,
6659 show: show,
6660 hide: hide,
6661 isHidden: isHidden,
6662 uniqueId: uniqueId,
6663 setHTML: setHTML,
6664 getOuterHTML: getOuterHTML,
6665 setOuterHTML: setOuterHTML,
6666 decode: decode,
6667 encode: encode,
6668 insertAfter: insertAfter,
6669 replace: replace,
6670 rename: rename,
6671 findCommonAncestor: findCommonAncestor,
6672 toHex: toHex,
6673 run: run,
6674 getAttribs: getAttribs,
6675 isEmpty: isEmpty,
6676 createRng: createRng,
6677 nodeIndex: findNodeIndex,
6678 split: split,
6679 bind: bind,
6680 unbind: unbind,
6681 fire: fire,
6682 getContentEditable: getContentEditable,
6683 getContentEditableParent: getContentEditableParent,
6684 destroy: destroy,
6685 isChildOf: isChildOf,
6686 dumpRng: dumpRng
6687 };
6688 attrHooks = setupAttrHooks(styles, settings, function () {
6689 return self;
6690 });
6691 return self;
6692 }
6693 (function (DOMUtils) {
6694 DOMUtils.DOM = DOMUtils(domGlobals.document);
6695 DOMUtils.nodeIndex = findNodeIndex;
6696 }(DOMUtils || (DOMUtils = {})));
6697 var DOMUtils$1 = DOMUtils;
6698
6699 var DOM = DOMUtils$1.DOM;
6700 var each$6 = Tools.each, grep$2 = Tools.grep;
6701 var QUEUED = 0;
6702 var LOADING = 1;
6703 var LOADED = 2;
6704 var FAILED = 3;
6705 var ScriptLoader = function () {
6706 function ScriptLoader() {
6707 this.states = {};
6708 this.queue = [];
6709 this.scriptLoadedCallbacks = {};
6710 this.queueLoadedCallbacks = [];
6711 this.loading = 0;
6712 }
6713 ScriptLoader.prototype.loadScript = function (url, success, failure) {
6714 var dom = DOM;
6715 var elm, id;
6716 var done = function () {
6717 dom.remove(id);
6718 if (elm) {
6719 elm.onreadystatechange = elm.onload = elm = null;
6720 }
6721 success();
6722 };
6723 var error = function () {
6724 if (isFunction(failure)) {
6725 failure();
6726 } else {
6727 if (typeof domGlobals.console !== 'undefined' && domGlobals.console.log) {
6728 domGlobals.console.log('Failed to load script: ' + url);
6729 }
6730 }
6731 };
6732 id = dom.uniqueId();
6733 elm = domGlobals.document.createElement('script');
6734 elm.id = id;
6735 elm.type = 'text/javascript';
6736 elm.src = Tools._addCacheSuffix(url);
6737 elm.onload = done;
6738 elm.onerror = error;
6739 (domGlobals.document.getElementsByTagName('head')[0] || domGlobals.document.body).appendChild(elm);
6740 };
6741 ScriptLoader.prototype.isDone = function (url) {
6742 return this.states[url] === LOADED;
6743 };
6744 ScriptLoader.prototype.markDone = function (url) {
6745 this.states[url] = LOADED;
6746 };
6747 ScriptLoader.prototype.add = function (url, success, scope, failure) {
6748 var state = this.states[url];
6749 if (state === undefined) {
6750 this.queue.push(url);
6751 this.states[url] = QUEUED;
6752 }
6753 if (success) {
6754 if (!this.scriptLoadedCallbacks[url]) {
6755 this.scriptLoadedCallbacks[url] = [];
6756 }
6757 this.scriptLoadedCallbacks[url].push({
6758 success: success,
6759 failure: failure,
6760 scope: scope || this
6761 });
6762 }
6763 };
6764 ScriptLoader.prototype.load = function (url, success, scope, failure) {
6765 return this.add(url, success, scope, failure);
6766 };
6767 ScriptLoader.prototype.remove = function (url) {
6768 delete this.states[url];
6769 delete this.scriptLoadedCallbacks[url];
6770 };
6771 ScriptLoader.prototype.loadQueue = function (success, scope, failure) {
6772 this.loadScripts(this.queue, success, scope, failure);
6773 };
6774 ScriptLoader.prototype.loadScripts = function (scripts, success, scope, failure) {
6775 var self = this;
6776 var loadScripts;
6777 var failures = [];
6778 var execCallbacks = function (name, url) {
6779 each$6(self.scriptLoadedCallbacks[url], function (callback) {
6780 if (isFunction(callback[name])) {
6781 callback[name].call(callback.scope);
6782 }
6783 });
6784 self.scriptLoadedCallbacks[url] = undefined;
6785 };
6786 self.queueLoadedCallbacks.push({
6787 success: success,
6788 failure: failure,
6789 scope: scope || this
6790 });
6791 loadScripts = function () {
6792 var loadingScripts = grep$2(scripts);
6793 scripts.length = 0;
6794 each$6(loadingScripts, function (url) {
6795 if (self.states[url] === LOADED) {
6796 execCallbacks('success', url);
6797 return;
6798 }
6799 if (self.states[url] === FAILED) {
6800 execCallbacks('failure', url);
6801 return;
6802 }
6803 if (self.states[url] !== LOADING) {
6804 self.states[url] = LOADING;
6805 self.loading++;
6806 self.loadScript(url, function () {
6807 self.states[url] = LOADED;
6808 self.loading--;
6809 execCallbacks('success', url);
6810 loadScripts();
6811 }, function () {
6812 self.states[url] = FAILED;
6813 self.loading--;
6814 failures.push(url);
6815 execCallbacks('failure', url);
6816 loadScripts();
6817 });
6818 }
6819 });
6820 if (!self.loading) {
6821 var notifyCallbacks = self.queueLoadedCallbacks.slice(0);
6822 self.queueLoadedCallbacks.length = 0;
6823 each$6(notifyCallbacks, function (callback) {
6824 if (failures.length === 0) {
6825 if (isFunction(callback.success)) {
6826 callback.success.call(callback.scope);
6827 }
6828 } else {
6829 if (isFunction(callback.failure)) {
6830 callback.failure.call(callback.scope, failures);
6831 }
6832 }
6833 });
6834 }
6835 };
6836 loadScripts();
6837 };
6838 ScriptLoader.ScriptLoader = new ScriptLoader();
6839 return ScriptLoader;
6840 }();
6841
6842 var Cell = function (initial) {
6843 var value = initial;
6844 var get = function () {
6845 return value;
6846 };
6847 var set = function (v) {
6848 value = v;
6849 };
6850 var clone = function () {
6851 return Cell(get());
6852 };
6853 return {
6854 get: get,
6855 set: set,
6856 clone: clone
6857 };
6858 };
6859
6860 var isRaw = function (str) {
6861 return isObject(str) && has(str, 'raw');
6862 };
6863 var isTokenised = function (str) {
6864 return isArray(str) && str.length > 1;
6865 };
6866 var data = {};
6867 var currentCode = Cell('en');
6868 var getData = function () {
6869 return map$2(data, function (value) {
6870 return __assign({}, value);
6871 });
6872 };
6873 var setCode = function (newCode) {
6874 if (newCode) {
6875 currentCode.set(newCode);
6876 }
6877 };
6878 var getCode = function () {
6879 return currentCode.get();
6880 };
6881 var add = function (code, items) {
6882 var langData = data[code];
6883 if (!langData) {
6884 data[code] = langData = {};
6885 }
6886 for (var name in items) {
6887 langData[name.toLowerCase()] = items[name];
6888 }
6889 };
6890 var translate = function (text) {
6891 var langData = data[currentCode.get()] || {};
6892 var toString = function (obj) {
6893 if (isFunction(obj)) {
6894 return Object.prototype.toString.call(obj);
6895 }
6896 return !isEmpty(obj) ? '' + obj : '';
6897 };
6898 var isEmpty = function (text) {
6899 return text === '' || text === null || text === undefined;
6900 };
6901 var getLangData = function (text) {
6902 var textstr = toString(text);
6903 var lowercaseTextstr = textstr.toLowerCase();
6904 return has(langData, lowercaseTextstr) ? toString(langData[lowercaseTextstr]) : textstr;
6905 };
6906 var removeContext = function (str) {
6907 return str.replace(/{context:\w+}$/, '');
6908 };
6909 var translated = function (text) {
6910 return text;
6911 };
6912 if (isEmpty(text)) {
6913 return translated('');
6914 }
6915 if (isRaw(text)) {
6916 return translated(toString(text.raw));
6917 }
6918 if (isTokenised(text)) {
6919 var values_1 = text.slice(1);
6920 var substitued = getLangData(text[0]).replace(/\{([0-9]+)\}/g, function ($1, $2) {
6921 return has(values_1, $2) ? toString(values_1[$2]) : $1;
6922 });
6923 return translated(removeContext(substitued));
6924 }
6925 return translated(removeContext(getLangData(text)));
6926 };
6927 var isRtl = function () {
6928 return get(data, currentCode.get()).bind(function (items) {
6929 return get(items, '_dir');
6930 }).exists(function (dir) {
6931 return dir === 'rtl';
6932 });
6933 };
6934 var hasCode = function (code) {
6935 return has(data, code);
6936 };
6937 var I18n = {
6938 getData: getData,
6939 setCode: setCode,
6940 getCode: getCode,
6941 add: add,
6942 translate: translate,
6943 isRtl: isRtl,
6944 hasCode: hasCode
6945 };
6946
6947 var each$7 = Tools.each;
6948 function AddOnManager() {
6949 var _this = this;
6950 var items = [];
6951 var urls = {};
6952 var lookup = {};
6953 var _listeners = [];
6954 var get = function (name) {
6955 if (lookup[name]) {
6956 return lookup[name].instance;
6957 }
6958 return undefined;
6959 };
6960 var dependencies = function (name) {
6961 var result;
6962 if (lookup[name]) {
6963 result = lookup[name].dependencies;
6964 }
6965 return result || [];
6966 };
6967 var requireLangPack = function (name, languages) {
6968 var language = I18n.getCode();
6969 if (language && AddOnManager.languageLoad !== false) {
6970 if (languages) {
6971 languages = ',' + languages + ',';
6972 if (languages.indexOf(',' + language.substr(0, 2) + ',') !== -1) {
6973 language = language.substr(0, 2);
6974 } else if (languages.indexOf(',' + language + ',') === -1) {
6975 return;
6976 }
6977 }
6978 ScriptLoader.ScriptLoader.add(urls[name] + '/langs/' + language + '.js');
6979 }
6980 };
6981 var add = function (id, addOn, dependencies) {
6982 items.push(addOn);
6983 lookup[id] = {
6984 instance: addOn,
6985 dependencies: dependencies
6986 };
6987 var result = partition(_listeners, function (listener) {
6988 return listener.name === id;
6989 });
6990 _listeners = result.fail;
6991 each$7(result.pass, function (listener) {
6992 listener.callback();
6993 });
6994 return addOn;
6995 };
6996 var remove = function (name) {
6997 delete urls[name];
6998 delete lookup[name];
6999 };
7000 var createUrl = function (baseUrl, dep) {
7001 if (typeof dep === 'object') {
7002 return dep;
7003 }
7004 return typeof baseUrl === 'string' ? {
7005 prefix: '',
7006 resource: dep,
7007 suffix: ''
7008 } : {
7009 prefix: baseUrl.prefix,
7010 resource: dep,
7011 suffix: baseUrl.suffix
7012 };
7013 };
7014 var addComponents = function (pluginName, scripts) {
7015 var pluginUrl = _this.urls[pluginName];
7016 each$7(scripts, function (script) {
7017 ScriptLoader.ScriptLoader.add(pluginUrl + '/' + script);
7018 });
7019 };
7020 var loadDependencies = function (name, addOnUrl, success, scope) {
7021 var deps = dependencies(name);
7022 each$7(deps, function (dep) {
7023 var newUrl = createUrl(addOnUrl, dep);
7024 load(newUrl.resource, newUrl, undefined, undefined);
7025 });
7026 if (success) {
7027 if (scope) {
7028 success.call(scope);
7029 } else {
7030 success.call(ScriptLoader);
7031 }
7032 }
7033 };
7034 var load = function (name, addOnUrl, success, scope, failure) {
7035 if (urls[name]) {
7036 return;
7037 }
7038 var urlString = typeof addOnUrl === 'string' ? addOnUrl : addOnUrl.prefix + addOnUrl.resource + addOnUrl.suffix;
7039 if (urlString.indexOf('/') !== 0 && urlString.indexOf('://') === -1) {
7040 urlString = AddOnManager.baseURL + '/' + urlString;
7041 }
7042 urls[name] = urlString.substring(0, urlString.lastIndexOf('/'));
7043 if (lookup[name]) {
7044 loadDependencies(name, addOnUrl, success, scope);
7045 } else {
7046 ScriptLoader.ScriptLoader.add(urlString, function () {
7047 return loadDependencies(name, addOnUrl, success, scope);
7048 }, scope, failure);
7049 }
7050 };
7051 var waitFor = function (name, callback) {
7052 if (lookup.hasOwnProperty(name)) {
7053 callback();
7054 } else {
7055 _listeners.push({
7056 name: name,
7057 callback: callback
7058 });
7059 }
7060 };
7061 return {
7062 items: items,
7063 urls: urls,
7064 lookup: lookup,
7065 _listeners: _listeners,
7066 get: get,
7067 dependencies: dependencies,
7068 requireLangPack: requireLangPack,
7069 add: add,
7070 remove: remove,
7071 createUrl: createUrl,
7072 addComponents: addComponents,
7073 load: load,
7074 waitFor: waitFor
7075 };
7076 }
7077 (function (AddOnManager) {
7078 AddOnManager.PluginManager = AddOnManager();
7079 AddOnManager.ThemeManager = AddOnManager();
7080 }(AddOnManager || (AddOnManager = {})));
7081 var AddOnManager$1 = AddOnManager;
7082
7083 var before = function (marker, element) {
7084 var parent$1 = parent(marker);
7085 parent$1.each(function (v) {
7086 v.dom().insertBefore(element.dom(), marker.dom());
7087 });
7088 };
7089 var after = function (marker, element) {
7090 var sibling = nextSibling(marker);
7091 sibling.fold(function () {
7092 var parent$1 = parent(marker);
7093 parent$1.each(function (v) {
7094 append(v, element);
7095 });
7096 }, function (v) {
7097 before(v, element);
7098 });
7099 };
7100 var prepend = function (parent, element) {
7101 var firstChild$1 = firstChild(parent);
7102 firstChild$1.fold(function () {
7103 append(parent, element);
7104 }, function (v) {
7105 parent.dom().insertBefore(element.dom(), v.dom());
7106 });
7107 };
7108 var append = function (parent, element) {
7109 parent.dom().appendChild(element.dom());
7110 };
7111 var wrap$1 = function (element, wrapper) {
7112 before(element, wrapper);
7113 append(wrapper, element);
7114 };
7115
7116 var before$1 = function (marker, elements) {
7117 each(elements, function (x) {
7118 before(marker, x);
7119 });
7120 };
7121 var append$1 = function (parent, elements) {
7122 each(elements, function (x) {
7123 append(parent, x);
7124 });
7125 };
7126
7127 var empty = function (element) {
7128 element.dom().textContent = '';
7129 each(children(element), function (rogue) {
7130 remove$1(rogue);
7131 });
7132 };
7133 var remove$1 = function (element) {
7134 var dom = element.dom();
7135 if (dom.parentNode !== null) {
7136 dom.parentNode.removeChild(dom);
7137 }
7138 };
7139 var unwrap = function (wrapper) {
7140 var children$1 = children(wrapper);
7141 if (children$1.length > 0) {
7142 before$1(wrapper, children$1);
7143 }
7144 remove$1(wrapper);
7145 };
7146
7147 var first = function (fn, rate) {
7148 var timer = null;
7149 var cancel = function () {
7150 if (timer !== null) {
7151 domGlobals.clearTimeout(timer);
7152 timer = null;
7153 }
7154 };
7155 var throttle = function () {
7156 var args = [];
7157 for (var _i = 0; _i < arguments.length; _i++) {
7158 args[_i] = arguments[_i];
7159 }
7160 if (timer === null) {
7161 timer = domGlobals.setTimeout(function () {
7162 fn.apply(null, args);
7163 timer = null;
7164 }, rate);
7165 }
7166 };
7167 return {
7168 cancel: cancel,
7169 throttle: throttle
7170 };
7171 };
7172 var last$2 = function (fn, rate) {
7173 var timer = null;
7174 var cancel = function () {
7175 if (timer !== null) {
7176 domGlobals.clearTimeout(timer);
7177 timer = null;
7178 }
7179 };
7180 var throttle = function () {
7181 var args = [];
7182 for (var _i = 0; _i < arguments.length; _i++) {
7183 args[_i] = arguments[_i];
7184 }
7185 if (timer !== null) {
7186 domGlobals.clearTimeout(timer);
7187 }
7188 timer = domGlobals.setTimeout(function () {
7189 fn.apply(null, args);
7190 timer = null;
7191 }, rate);
7192 };
7193 return {
7194 cancel: cancel,
7195 throttle: throttle
7196 };
7197 };
7198
7199 var read = function (element, attr) {
7200 var value = get$1(element, attr);
7201 return value === undefined || value === '' ? [] : value.split(' ');
7202 };
7203 var add$1 = function (element, attr, id) {
7204 var old = read(element, attr);
7205 var nu = old.concat([id]);
7206 set(element, attr, nu.join(' '));
7207 return true;
7208 };
7209 var remove$2 = function (element, attr, id) {
7210 var nu = filter(read(element, attr), function (v) {
7211 return v !== id;
7212 });
7213 if (nu.length > 0) {
7214 set(element, attr, nu.join(' '));
7215 } else {
7216 remove(element, attr);
7217 }
7218 return false;
7219 };
7220
7221 var supports = function (element) {
7222 return element.dom().classList !== undefined;
7223 };
7224 var get$3 = function (element) {
7225 return read(element, 'class');
7226 };
7227 var add$2 = function (element, clazz) {
7228 return add$1(element, 'class', clazz);
7229 };
7230 var remove$3 = function (element, clazz) {
7231 return remove$2(element, 'class', clazz);
7232 };
7233
7234 var add$3 = function (element, clazz) {
7235 if (supports(element)) {
7236 element.dom().classList.add(clazz);
7237 } else {
7238 add$2(element, clazz);
7239 }
7240 };
7241 var cleanClass = function (element) {
7242 var classList = supports(element) ? element.dom().classList : get$3(element);
7243 if (classList.length === 0) {
7244 remove(element, 'class');
7245 }
7246 };
7247 var remove$4 = function (element, clazz) {
7248 if (supports(element)) {
7249 var classList = element.dom().classList;
7250 classList.remove(clazz);
7251 } else {
7252 remove$3(element, clazz);
7253 }
7254 cleanClass(element);
7255 };
7256 var has$2 = function (element, clazz) {
7257 return supports(element) && element.dom().classList.contains(clazz);
7258 };
7259
7260 var descendants = function (scope, predicate) {
7261 var result = [];
7262 each(children(scope), function (x) {
7263 if (predicate(x)) {
7264 result = result.concat([x]);
7265 }
7266 result = result.concat(descendants(x, predicate));
7267 });
7268 return result;
7269 };
7270
7271 var descendants$1 = function (scope, selector) {
7272 return all(selector, scope);
7273 };
7274
7275 function ClosestOrAncestor (is, ancestor, scope, a, isRoot) {
7276 return is(scope, a) ? Option.some(scope) : isFunction(isRoot) && isRoot(scope) ? Option.none() : ancestor(scope, a, isRoot);
7277 }
7278
7279 var ancestor = function (scope, predicate, isRoot) {
7280 var element = scope.dom();
7281 var stop = isFunction(isRoot) ? isRoot : constant(false);
7282 while (element.parentNode) {
7283 element = element.parentNode;
7284 var el = Element.fromDom(element);
7285 if (predicate(el)) {
7286 return Option.some(el);
7287 } else if (stop(el)) {
7288 break;
7289 }
7290 }
7291 return Option.none();
7292 };
7293 var closest = function (scope, predicate, isRoot) {
7294 var is = function (s) {
7295 return predicate(s);
7296 };
7297 return ClosestOrAncestor(is, ancestor, scope, predicate, isRoot);
7298 };
7299
7300 var ancestor$1 = function (scope, selector, isRoot) {
7301 return ancestor(scope, function (e) {
7302 return is$1(e, selector);
7303 }, isRoot);
7304 };
7305 var descendant = function (scope, selector) {
7306 return one(selector, scope);
7307 };
7308 var closest$1 = function (scope, selector, isRoot) {
7309 return ClosestOrAncestor(is$1, ancestor$1, scope, selector, isRoot);
7310 };
7311
7312 var annotation = constant('mce-annotation');
7313 var dataAnnotation = constant('data-mce-annotation');
7314 var dataAnnotationId = constant('data-mce-annotation-uid');
7315
7316 var identify = function (editor, annotationName) {
7317 var rng = editor.selection.getRng();
7318 var start = Element.fromDom(rng.startContainer);
7319 var root = Element.fromDom(editor.getBody());
7320 var selector = annotationName.fold(function () {
7321 return '.' + annotation();
7322 }, function (an) {
7323 return '[' + dataAnnotation() + '="' + an + '"]';
7324 });
7325 var newStart = child(start, rng.startOffset).getOr(start);
7326 var closest = closest$1(newStart, selector, function (n) {
7327 return eq(n, root);
7328 });
7329 var getAttr = function (c, property) {
7330 if (has$1(c, property)) {
7331 return Option.some(get$1(c, property));
7332 } else {
7333 return Option.none();
7334 }
7335 };
7336 return closest.bind(function (c) {
7337 return getAttr(c, '' + dataAnnotationId()).bind(function (uid) {
7338 return getAttr(c, '' + dataAnnotation()).map(function (name) {
7339 var elements = findMarkers(editor, uid);
7340 return {
7341 uid: uid,
7342 name: name,
7343 elements: elements
7344 };
7345 });
7346 });
7347 });
7348 };
7349 var isAnnotation = function (elem) {
7350 return isElement(elem) && has$2(elem, annotation());
7351 };
7352 var findMarkers = function (editor, uid) {
7353 var body = Element.fromDom(editor.getBody());
7354 return descendants$1(body, '[' + dataAnnotationId() + '="' + uid + '"]');
7355 };
7356 var findAll = function (editor, name) {
7357 var body = Element.fromDom(editor.getBody());
7358 var markers = descendants$1(body, '[' + dataAnnotation() + '="' + name + '"]');
7359 var directory = {};
7360 each(markers, function (m) {
7361 var uid = get$1(m, dataAnnotationId());
7362 var nodesAlready = directory.hasOwnProperty(uid) ? directory[uid] : [];
7363 directory[uid] = nodesAlready.concat([m]);
7364 });
7365 return directory;
7366 };
7367
7368 var setup = function (editor, registry) {
7369 var changeCallbacks = Cell({});
7370 var initData = function () {
7371 return {
7372 listeners: [],
7373 previous: Cell(Option.none())
7374 };
7375 };
7376 var withCallbacks = function (name, f) {
7377 updateCallbacks(name, function (data) {
7378 f(data);
7379 return data;
7380 });
7381 };
7382 var updateCallbacks = function (name, f) {
7383 var callbackMap = changeCallbacks.get();
7384 var data = callbackMap.hasOwnProperty(name) ? callbackMap[name] : initData();
7385 var outputData = f(data);
7386 callbackMap[name] = outputData;
7387 changeCallbacks.set(callbackMap);
7388 };
7389 var fireCallbacks = function (name, uid, elements) {
7390 withCallbacks(name, function (data) {
7391 each(data.listeners, function (f) {
7392 return f(true, name, {
7393 uid: uid,
7394 nodes: map(elements, function (elem) {
7395 return elem.dom();
7396 })
7397 });
7398 });
7399 });
7400 };
7401 var fireNoAnnotation = function (name) {
7402 withCallbacks(name, function (data) {
7403 each(data.listeners, function (f) {
7404 return f(false, name);
7405 });
7406 });
7407 };
7408 var onNodeChange = last$2(function () {
7409 var callbackMap = changeCallbacks.get();
7410 var annotations = sort(keys(callbackMap));
7411 each(annotations, function (name) {
7412 updateCallbacks(name, function (data) {
7413 var prev = data.previous.get();
7414 identify(editor, Option.some(name)).fold(function () {
7415 if (prev.isSome()) {
7416 fireNoAnnotation(name);
7417 data.previous.set(Option.none());
7418 }
7419 }, function (_a) {
7420 var uid = _a.uid, name = _a.name, elements = _a.elements;
7421 if (!prev.is(uid)) {
7422 fireCallbacks(name, uid, elements);
7423 data.previous.set(Option.some(uid));
7424 }
7425 });
7426 return {
7427 previous: data.previous,
7428 listeners: data.listeners
7429 };
7430 });
7431 });
7432 }, 30);
7433 editor.on('remove', function () {
7434 onNodeChange.cancel();
7435 });
7436 editor.on('NodeChange', function () {
7437 onNodeChange.throttle();
7438 });
7439 var addListener = function (name, f) {
7440 updateCallbacks(name, function (data) {
7441 return {
7442 previous: data.previous,
7443 listeners: data.listeners.concat([f])
7444 };
7445 });
7446 };
7447 return { addListener: addListener };
7448 };
7449
7450 var setup$1 = function (editor, registry) {
7451 var identifyParserNode = function (span) {
7452 return Option.from(span.attr(dataAnnotation())).bind(registry.lookup);
7453 };
7454 editor.on('init', function () {
7455 editor.serializer.addNodeFilter('span', function (spans) {
7456 each(spans, function (span) {
7457 identifyParserNode(span).each(function (settings) {
7458 if (settings.persistent === false) {
7459 span.unwrap();
7460 }
7461 });
7462 });
7463 });
7464 });
7465 };
7466
7467 var create$1 = function () {
7468 var annotations = {};
7469 var register = function (name, settings) {
7470 annotations[name] = {
7471 name: name,
7472 settings: settings
7473 };
7474 };
7475 var lookup = function (name) {
7476 return annotations.hasOwnProperty(name) ? Option.from(annotations[name]).map(function (a) {
7477 return a.settings;
7478 }) : Option.none();
7479 };
7480 return {
7481 register: register,
7482 lookup: lookup
7483 };
7484 };
7485
7486 var unique = 0;
7487 var generate = function (prefix) {
7488 var date = new Date();
7489 var time = date.getTime();
7490 var random = Math.floor(Math.random() * 1000000000);
7491 unique++;
7492 return prefix + '_' + random + unique + String(time);
7493 };
7494
7495 var add$4 = function (element, classes) {
7496 each(classes, function (x) {
7497 add$3(element, x);
7498 });
7499 };
7500
7501 var clone = function (original, isDeep) {
7502 return Element.fromDom(original.dom().cloneNode(isDeep));
7503 };
7504 var shallow = function (original) {
7505 return clone(original, false);
7506 };
7507 var deep = function (original) {
7508 return clone(original, true);
7509 };
7510
7511 var fromHtml$1 = function (html, scope) {
7512 var doc = scope || domGlobals.document;
7513 var div = doc.createElement('div');
7514 div.innerHTML = html;
7515 return children(Element.fromDom(div));
7516 };
7517
7518 var get$4 = function (element) {
7519 return element.dom().innerHTML;
7520 };
7521 var set$1 = function (element, content) {
7522 var owner$1 = owner(element);
7523 var docDom = owner$1.dom();
7524 var fragment = Element.fromDom(docDom.createDocumentFragment());
7525 var contentElements = fromHtml$1(content, docDom);
7526 append$1(fragment, contentElements);
7527 empty(element);
7528 append(element, fragment);
7529 };
7530
7531 var ZWSP = '\uFEFF';
7532 var isZwsp = function (chr) {
7533 return chr === ZWSP;
7534 };
7535 var trim$3 = function (text) {
7536 return text.replace(new RegExp(ZWSP, 'g'), '');
7537 };
7538 var Zwsp = {
7539 isZwsp: isZwsp,
7540 ZWSP: ZWSP,
7541 trim: trim$3
7542 };
7543
7544 var isElement$2 = NodeType.isElement;
7545 var isText$2 = NodeType.isText;
7546 var isCaretContainerBlock = function (node) {
7547 if (isText$2(node)) {
7548 node = node.parentNode;
7549 }
7550 return isElement$2(node) && node.hasAttribute('data-mce-caret');
7551 };
7552 var isCaretContainerInline = function (node) {
7553 return isText$2(node) && Zwsp.isZwsp(node.data);
7554 };
7555 var isCaretContainer = function (node) {
7556 return isCaretContainerBlock(node) || isCaretContainerInline(node);
7557 };
7558 var hasContent = function (node) {
7559 return node.firstChild !== node.lastChild || !NodeType.isBr(node.firstChild);
7560 };
7561 var insertInline = function (node, before) {
7562 var doc, sibling, textNode, parentNode;
7563 doc = node.ownerDocument;
7564 textNode = doc.createTextNode(Zwsp.ZWSP);
7565 parentNode = node.parentNode;
7566 if (!before) {
7567 sibling = node.nextSibling;
7568 if (isText$2(sibling)) {
7569 if (isCaretContainer(sibling)) {
7570 return sibling;
7571 }
7572 if (startsWithCaretContainer(sibling)) {
7573 sibling.splitText(1);
7574 return sibling;
7575 }
7576 }
7577 if (node.nextSibling) {
7578 parentNode.insertBefore(textNode, node.nextSibling);
7579 } else {
7580 parentNode.appendChild(textNode);
7581 }
7582 } else {
7583 sibling = node.previousSibling;
7584 if (isText$2(sibling)) {
7585 if (isCaretContainer(sibling)) {
7586 return sibling;
7587 }
7588 if (endsWithCaretContainer(sibling)) {
7589 return sibling.splitText(sibling.data.length - 1);
7590 }
7591 }
7592 parentNode.insertBefore(textNode, node);
7593 }
7594 return textNode;
7595 };
7596 var isBeforeInline = function (pos) {
7597 var container = pos.container();
7598 if (!pos || !NodeType.isText(container)) {
7599 return false;
7600 }
7601 return container.data.charAt(pos.offset()) === Zwsp.ZWSP || pos.isAtStart() && isCaretContainerInline(container.previousSibling);
7602 };
7603 var isAfterInline = function (pos) {
7604 var container = pos.container();
7605 if (!pos || !NodeType.isText(container)) {
7606 return false;
7607 }
7608 return container.data.charAt(pos.offset() - 1) === Zwsp.ZWSP || pos.isAtEnd() && isCaretContainerInline(container.nextSibling);
7609 };
7610 var createBogusBr = function () {
7611 var br = domGlobals.document.createElement('br');
7612 br.setAttribute('data-mce-bogus', '1');
7613 return br;
7614 };
7615 var insertBlock = function (blockName, node, before) {
7616 var doc, blockNode, parentNode;
7617 doc = node.ownerDocument;
7618 blockNode = doc.createElement(blockName);
7619 blockNode.setAttribute('data-mce-caret', before ? 'before' : 'after');
7620 blockNode.setAttribute('data-mce-bogus', 'all');
7621 blockNode.appendChild(createBogusBr());
7622 parentNode = node.parentNode;
7623 if (!before) {
7624 if (node.nextSibling) {
7625 parentNode.insertBefore(blockNode, node.nextSibling);
7626 } else {
7627 parentNode.appendChild(blockNode);
7628 }
7629 } else {
7630 parentNode.insertBefore(blockNode, node);
7631 }
7632 return blockNode;
7633 };
7634 var startsWithCaretContainer = function (node) {
7635 return isText$2(node) && node.data[0] === Zwsp.ZWSP;
7636 };
7637 var endsWithCaretContainer = function (node) {
7638 return isText$2(node) && node.data[node.data.length - 1] === Zwsp.ZWSP;
7639 };
7640 var trimBogusBr = function (elm) {
7641 var brs = elm.getElementsByTagName('br');
7642 var lastBr = brs[brs.length - 1];
7643 if (NodeType.isBogus(lastBr)) {
7644 lastBr.parentNode.removeChild(lastBr);
7645 }
7646 };
7647 var showCaretContainerBlock = function (caretContainer) {
7648 if (caretContainer && caretContainer.hasAttribute('data-mce-caret')) {
7649 trimBogusBr(caretContainer);
7650 caretContainer.removeAttribute('data-mce-caret');
7651 caretContainer.removeAttribute('data-mce-bogus');
7652 caretContainer.removeAttribute('style');
7653 caretContainer.removeAttribute('_moz_abspos');
7654 return caretContainer;
7655 }
7656 return null;
7657 };
7658 var isRangeInCaretContainerBlock = function (range) {
7659 return isCaretContainerBlock(range.startContainer);
7660 };
7661
7662 var isContentEditableTrue$1 = NodeType.isContentEditableTrue;
7663 var isContentEditableFalse$1 = NodeType.isContentEditableFalse;
7664 var isBr$2 = NodeType.isBr;
7665 var isText$3 = NodeType.isText;
7666 var isInvalidTextElement = NodeType.matchNodeNames([
7667 'script',
7668 'style',
7669 'textarea'
7670 ]);
7671 var isAtomicInline = NodeType.matchNodeNames([
7672 'img',
7673 'input',
7674 'textarea',
7675 'hr',
7676 'iframe',
7677 'video',
7678 'audio',
7679 'object'
7680 ]);
7681 var isTable$2 = NodeType.matchNodeNames(['table']);
7682 var isCaretContainer$1 = isCaretContainer;
7683 var isCaretCandidate = function (node) {
7684 if (isCaretContainer$1(node)) {
7685 return false;
7686 }
7687 if (isText$3(node)) {
7688 if (isInvalidTextElement(node.parentNode)) {
7689 return false;
7690 }
7691 return true;
7692 }
7693 return isAtomicInline(node) || isBr$2(node) || isTable$2(node) || isNonUiContentEditableFalse(node);
7694 };
7695 var isUnselectable = function (node) {
7696 return NodeType.isElement(node) && node.getAttribute('unselectable') === 'true';
7697 };
7698 var isNonUiContentEditableFalse = function (node) {
7699 return isUnselectable(node) === false && isContentEditableFalse$1(node);
7700 };
7701 var isInEditable = function (node, root) {
7702 for (node = node.parentNode; node && node !== root; node = node.parentNode) {
7703 if (isNonUiContentEditableFalse(node)) {
7704 return false;
7705 }
7706 if (isContentEditableTrue$1(node)) {
7707 return true;
7708 }
7709 }
7710 return true;
7711 };
7712 var isAtomicContentEditableFalse = function (node) {
7713 if (!isNonUiContentEditableFalse(node)) {
7714 return false;
7715 }
7716 return foldl(from$1(node.getElementsByTagName('*')), function (result, elm) {
7717 return result || isContentEditableTrue$1(elm);
7718 }, false) !== true;
7719 };
7720 var isAtomic = function (node) {
7721 return isAtomicInline(node) || isAtomicContentEditableFalse(node);
7722 };
7723 var isEditableCaretCandidate = function (node, root) {
7724 return isCaretCandidate(node) && isInEditable(node, root);
7725 };
7726
7727 var round = Math.round;
7728 var clone$1 = function (rect) {
7729 if (!rect) {
7730 return {
7731 left: 0,
7732 top: 0,
7733 bottom: 0,
7734 right: 0,
7735 width: 0,
7736 height: 0
7737 };
7738 }
7739 return {
7740 left: round(rect.left),
7741 top: round(rect.top),
7742 bottom: round(rect.bottom),
7743 right: round(rect.right),
7744 width: round(rect.width),
7745 height: round(rect.height)
7746 };
7747 };
7748 var collapse = function (rect, toStart) {
7749 rect = clone$1(rect);
7750 if (toStart) {
7751 rect.right = rect.left;
7752 } else {
7753 rect.left = rect.left + rect.width;
7754 rect.right = rect.left;
7755 }
7756 rect.width = 0;
7757 return rect;
7758 };
7759 var isEqual = function (rect1, rect2) {
7760 return rect1.left === rect2.left && rect1.top === rect2.top && rect1.bottom === rect2.bottom && rect1.right === rect2.right;
7761 };
7762 var isValidOverflow = function (overflowY, rect1, rect2) {
7763 return overflowY >= 0 && overflowY <= Math.min(rect1.height, rect2.height) / 2;
7764 };
7765 var isAbove = function (rect1, rect2) {
7766 if (rect1.bottom - rect1.height / 2 < rect2.top) {
7767 return true;
7768 }
7769 if (rect1.top > rect2.bottom) {
7770 return false;
7771 }
7772 return isValidOverflow(rect2.top - rect1.bottom, rect1, rect2);
7773 };
7774 var isBelow = function (rect1, rect2) {
7775 if (rect1.top > rect2.bottom) {
7776 return true;
7777 }
7778 if (rect1.bottom < rect2.top) {
7779 return false;
7780 }
7781 return isValidOverflow(rect2.bottom - rect1.top, rect1, rect2);
7782 };
7783 var containsXY = function (rect, clientX, clientY) {
7784 return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
7785 };
7786
7787 var getSelectedNode = function (range) {
7788 var startContainer = range.startContainer, startOffset = range.startOffset;
7789 if (startContainer.hasChildNodes() && range.endOffset === startOffset + 1) {
7790 return startContainer.childNodes[startOffset];
7791 }
7792 return null;
7793 };
7794 var getNode = function (container, offset) {
7795 if (container.nodeType === 1 && container.hasChildNodes()) {
7796 if (offset >= container.childNodes.length) {
7797 offset = container.childNodes.length - 1;
7798 }
7799 container = container.childNodes[offset];
7800 }
7801 return container;
7802 };
7803
7804 var extendingChars = new RegExp('[\u0300-\u036f\u0483-\u0487\u0488-\u0489\u0591-\u05bd\u05bf\u05c1-\u05c2\u05c4-\u05c5\u05c7\u0610-\u061a' + '\u064b-\u065f\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7-\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0' + '\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08E3-\u0902\u093a\u093c' + '\u0941-\u0948\u094d\u0951-\u0957\u0962-\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2-\u09e3' + '\u0a01-\u0a02\u0a3c\u0a41-\u0a42\u0a47-\u0a48\u0a4b-\u0a4d\u0a51\u0a70-\u0a71\u0a75\u0a81-\u0a82\u0abc' + '\u0ac1-\u0ac5\u0ac7-\u0ac8\u0acd\u0ae2-\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57' + '\u0b62-\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c00\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55-\u0c56' + '\u0c62-\u0c63\u0c81\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc-\u0ccd\u0cd5-\u0cd6\u0ce2-\u0ce3\u0d01\u0d3e\u0d41-\u0d44' + '\u0d4d\u0d57\u0d62-\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9' + '\u0ebb-\u0ebc\u0ec8-\u0ecd\u0f18-\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86-\u0f87\u0f8d-\u0f97' + '\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039-\u103a\u103d-\u103e\u1058-\u1059\u105e-\u1060\u1071-\u1074' + '\u1082\u1085-\u1086\u108d\u109d\u135d-\u135f\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17b4-\u17b5' + '\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927-\u1928\u1932\u1939-\u193b\u1a17-\u1a18' + '\u1a1b\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1ab0-\u1abd\u1ABE\u1b00-\u1b03\u1b34' + '\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80-\u1b81\u1ba2-\u1ba5\u1ba8-\u1ba9\u1bab-\u1bad\u1be6\u1be8-\u1be9' + '\u1bed\u1bef-\u1bf1\u1c2c-\u1c33\u1c36-\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1cf4\u1cf8-\u1cf9' + '\u1dc0-\u1df5\u1dfc-\u1dff\u200c-\u200d\u20d0-\u20dc\u20DD-\u20E0\u20e1\u20E2-\u20E4\u20e5-\u20f0\u2cef-\u2cf1' + '\u2d7f\u2de0-\u2dff\u302a-\u302d\u302e-\u302f\u3099-\u309a\ua66f\uA670-\uA672\ua674-\ua67d\uA69E-\ua69f\ua6f0-\ua6f1' + '\ua802\ua806\ua80b\ua825-\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc' + '\ua9e5\uaa29-\uaa2e\uaa31-\uaa32\uaa35-\uaa36\uaa43\uaa4c\uaa7c\uaab0\uaab2-\uaab4\uaab7-\uaab8\uaabe-\uaabf\uaac1' + '\uaaec-\uaaed\uaaf6\uabe5\uabe8\uabed\ufb1e\ufe00-\ufe0f\ufe20-\uFE2F\uff9e-\uff9f]');
7805 var isExtendingChar = function (ch) {
7806 return typeof ch === 'string' && ch.charCodeAt(0) >= 768 && extendingChars.test(ch);
7807 };
7808
7809 var liftN = function (arr, f) {
7810 var r = [];
7811 for (var i = 0; i < arr.length; i++) {
7812 var x = arr[i];
7813 if (x.isSome()) {
7814 r.push(x.getOrDie());
7815 } else {
7816 return Option.none();
7817 }
7818 }
7819 return Option.some(f.apply(null, r));
7820 };
7821
7822 var slice$3 = [].slice;
7823 var or = function () {
7824 var x = [];
7825 for (var _i = 0; _i < arguments.length; _i++) {
7826 x[_i] = arguments[_i];
7827 }
7828 var args = slice$3.call(arguments);
7829 return function (x) {
7830 for (var i = 0; i < args.length; i++) {
7831 if (args[i](x)) {
7832 return true;
7833 }
7834 }
7835 return false;
7836 };
7837 };
7838 var and = function () {
7839 var x = [];
7840 for (var _i = 0; _i < arguments.length; _i++) {
7841 x[_i] = arguments[_i];
7842 }
7843 var args = slice$3.call(arguments);
7844 return function (x) {
7845 for (var i = 0; i < args.length; i++) {
7846 if (!args[i](x)) {
7847 return false;
7848 }
7849 }
7850 return true;
7851 };
7852 };
7853 var Predicate = {
7854 and: and,
7855 or: or
7856 };
7857
7858 var isElement$3 = NodeType.isElement;
7859 var isCaretCandidate$1 = isCaretCandidate;
7860 var isBlock$1 = NodeType.matchStyleValues('display', 'block table');
7861 var isFloated = NodeType.matchStyleValues('float', 'left right');
7862 var isValidElementCaretCandidate = Predicate.and(isElement$3, isCaretCandidate$1, not(isFloated));
7863 var isNotPre = not(NodeType.matchStyleValues('white-space', 'pre pre-line pre-wrap'));
7864 var isText$4 = NodeType.isText;
7865 var isBr$3 = NodeType.isBr;
7866 var nodeIndex = DOMUtils$1.nodeIndex;
7867 var resolveIndex = getNode;
7868 var createRange = function (doc) {
7869 return 'createRange' in doc ? doc.createRange() : DOMUtils$1.DOM.createRng();
7870 };
7871 var isWhiteSpace = function (chr) {
7872 return chr && /[\r\n\t ]/.test(chr);
7873 };
7874 var isRange = function (rng) {
7875 return !!rng.setStart && !!rng.setEnd;
7876 };
7877 var isHiddenWhiteSpaceRange = function (range) {
7878 var container = range.startContainer;
7879 var offset = range.startOffset;
7880 var text;
7881 if (isWhiteSpace(range.toString()) && isNotPre(container.parentNode) && NodeType.isText(container)) {
7882 text = container.data;
7883 if (isWhiteSpace(text[offset - 1]) || isWhiteSpace(text[offset + 1])) {
7884 return true;
7885 }
7886 }
7887 return false;
7888 };
7889 var getBrClientRect = function (brNode) {
7890 var doc = brNode.ownerDocument;
7891 var rng = createRange(doc);
7892 var nbsp = doc.createTextNode('\xA0');
7893 var parentNode = brNode.parentNode;
7894 var clientRect;
7895 parentNode.insertBefore(nbsp, brNode);
7896 rng.setStart(nbsp, 0);
7897 rng.setEnd(nbsp, 1);
7898 clientRect = clone$1(rng.getBoundingClientRect());
7899 parentNode.removeChild(nbsp);
7900 return clientRect;
7901 };
7902 var getBoundingClientRectWebKitText = function (rng) {
7903 var sc = rng.startContainer;
7904 var ec = rng.endContainer;
7905 var so = rng.startOffset;
7906 var eo = rng.endOffset;
7907 if (sc === ec && NodeType.isText(ec) && so === 0 && eo === 1) {
7908 var newRng = rng.cloneRange();
7909 newRng.setEndAfter(ec);
7910 return getBoundingClientRect(newRng);
7911 } else {
7912 return null;
7913 }
7914 };
7915 var isZeroRect = function (r) {
7916 return r.left === 0 && r.right === 0 && r.top === 0 && r.bottom === 0;
7917 };
7918 var getBoundingClientRect = function (item) {
7919 var clientRect, clientRects;
7920 clientRects = item.getClientRects();
7921 if (clientRects.length > 0) {
7922 clientRect = clone$1(clientRects[0]);
7923 } else {
7924 clientRect = clone$1(item.getBoundingClientRect());
7925 }
7926 if (!isRange(item) && isBr$3(item) && isZeroRect(clientRect)) {
7927 return getBrClientRect(item);
7928 }
7929 if (isZeroRect(clientRect) && isRange(item)) {
7930 return getBoundingClientRectWebKitText(item);
7931 }
7932 return clientRect;
7933 };
7934 var collapseAndInflateWidth = function (clientRect, toStart) {
7935 var newClientRect = collapse(clientRect, toStart);
7936 newClientRect.width = 1;
7937 newClientRect.right = newClientRect.left + 1;
7938 return newClientRect;
7939 };
7940 var getCaretPositionClientRects = function (caretPosition) {
7941 var clientRects = [];
7942 var beforeNode, node;
7943 var addUniqueAndValidRect = function (clientRect) {
7944 if (clientRect.height === 0) {
7945 return;
7946 }
7947 if (clientRects.length > 0) {
7948 if (isEqual(clientRect, clientRects[clientRects.length - 1])) {
7949 return;
7950 }
7951 }
7952 clientRects.push(clientRect);
7953 };
7954 var addCharacterOffset = function (container, offset) {
7955 var range = createRange(container.ownerDocument);
7956 if (offset < container.data.length) {
7957 if (isExtendingChar(container.data[offset])) {
7958 return clientRects;
7959 }
7960 if (isExtendingChar(container.data[offset - 1])) {
7961 range.setStart(container, offset);
7962 range.setEnd(container, offset + 1);
7963 if (!isHiddenWhiteSpaceRange(range)) {
7964 addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), false));
7965 return clientRects;
7966 }
7967 }
7968 }
7969 if (offset > 0) {
7970 range.setStart(container, offset - 1);
7971 range.setEnd(container, offset);
7972 if (!isHiddenWhiteSpaceRange(range)) {
7973 addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), false));
7974 }
7975 }
7976 if (offset < container.data.length) {
7977 range.setStart(container, offset);
7978 range.setEnd(container, offset + 1);
7979 if (!isHiddenWhiteSpaceRange(range)) {
7980 addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), true));
7981 }
7982 }
7983 };
7984 if (isText$4(caretPosition.container())) {
7985 addCharacterOffset(caretPosition.container(), caretPosition.offset());
7986 return clientRects;
7987 }
7988 if (isElement$3(caretPosition.container())) {
7989 if (caretPosition.isAtEnd()) {
7990 node = resolveIndex(caretPosition.container(), caretPosition.offset());
7991 if (isText$4(node)) {
7992 addCharacterOffset(node, node.data.length);
7993 }
7994 if (isValidElementCaretCandidate(node) && !isBr$3(node)) {
7995 addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), false));
7996 }
7997 } else {
7998 node = resolveIndex(caretPosition.container(), caretPosition.offset());
7999 if (isText$4(node)) {
8000 addCharacterOffset(node, 0);
8001 }
8002 if (isValidElementCaretCandidate(node) && caretPosition.isAtEnd()) {
8003 addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), false));
8004 return clientRects;
8005 }
8006 beforeNode = resolveIndex(caretPosition.container(), caretPosition.offset() - 1);
8007 if (isValidElementCaretCandidate(beforeNode) && !isBr$3(beforeNode)) {
8008 if (isBlock$1(beforeNode) || isBlock$1(node) || !isValidElementCaretCandidate(node)) {
8009 addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(beforeNode), false));
8010 }
8011 }
8012 if (isValidElementCaretCandidate(node)) {
8013 addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), true));
8014 }
8015 }
8016 }
8017 return clientRects;
8018 };
8019 function CaretPosition(container, offset, clientRects) {
8020 var isAtStart = function () {
8021 if (isText$4(container)) {
8022 return offset === 0;
8023 }
8024 return offset === 0;
8025 };
8026 var isAtEnd = function () {
8027 if (isText$4(container)) {
8028 return offset >= container.data.length;
8029 }
8030 return offset >= container.childNodes.length;
8031 };
8032 var toRange = function () {
8033 var range;
8034 range = createRange(container.ownerDocument);
8035 range.setStart(container, offset);
8036 range.setEnd(container, offset);
8037 return range;
8038 };
8039 var getClientRects = function () {
8040 if (!clientRects) {
8041 clientRects = getCaretPositionClientRects(CaretPosition(container, offset));
8042 }
8043 return clientRects;
8044 };
8045 var isVisible = function () {
8046 return getClientRects().length > 0;
8047 };
8048 var isEqual = function (caretPosition) {
8049 return caretPosition && container === caretPosition.container() && offset === caretPosition.offset();
8050 };
8051 var getNode = function (before) {
8052 return resolveIndex(container, before ? offset - 1 : offset);
8053 };
8054 return {
8055 container: constant(container),
8056 offset: constant(offset),
8057 toRange: toRange,
8058 getClientRects: getClientRects,
8059 isVisible: isVisible,
8060 isAtStart: isAtStart,
8061 isAtEnd: isAtEnd,
8062 isEqual: isEqual,
8063 getNode: getNode
8064 };
8065 }
8066 (function (CaretPosition) {
8067 CaretPosition.fromRangeStart = function (range) {
8068 return CaretPosition(range.startContainer, range.startOffset);
8069 };
8070 CaretPosition.fromRangeEnd = function (range) {
8071 return CaretPosition(range.endContainer, range.endOffset);
8072 };
8073 CaretPosition.after = function (node) {
8074 return CaretPosition(node.parentNode, nodeIndex(node) + 1);
8075 };
8076 CaretPosition.before = function (node) {
8077 return CaretPosition(node.parentNode, nodeIndex(node));
8078 };
8079 CaretPosition.isAbove = function (pos1, pos2) {
8080 return liftN([
8081 head(pos2.getClientRects()),
8082 last(pos1.getClientRects())
8083 ], isAbove).getOr(false);
8084 };
8085 CaretPosition.isBelow = function (pos1, pos2) {
8086 return liftN([
8087 last(pos2.getClientRects()),
8088 head(pos1.getClientRects())
8089 ], isBelow).getOr(false);
8090 };
8091 CaretPosition.isAtStart = function (pos) {
8092 return pos ? pos.isAtStart() : false;
8093 };
8094 CaretPosition.isAtEnd = function (pos) {
8095 return pos ? pos.isAtEnd() : false;
8096 };
8097 CaretPosition.isTextPosition = function (pos) {
8098 return pos ? NodeType.isText(pos.container()) : false;
8099 };
8100 CaretPosition.isElementPosition = function (pos) {
8101 return CaretPosition.isTextPosition(pos) === false;
8102 };
8103 }(CaretPosition || (CaretPosition = {})));
8104 var CaretPosition$1 = CaretPosition;
8105
8106 var isText$5 = NodeType.isText;
8107 var isBogus$1 = NodeType.isBogus;
8108 var nodeIndex$1 = DOMUtils$1.nodeIndex;
8109 var normalizedParent = function (node) {
8110 var parentNode = node.parentNode;
8111 if (isBogus$1(parentNode)) {
8112 return normalizedParent(parentNode);
8113 }
8114 return parentNode;
8115 };
8116 var getChildNodes = function (node) {
8117 if (!node) {
8118 return [];
8119 }
8120 return ArrUtils.reduce(node.childNodes, function (result, node) {
8121 if (isBogus$1(node) && node.nodeName !== 'BR') {
8122 result = result.concat(getChildNodes(node));
8123 } else {
8124 result.push(node);
8125 }
8126 return result;
8127 }, []);
8128 };
8129 var normalizedTextOffset = function (node, offset) {
8130 while (node = node.previousSibling) {
8131 if (!isText$5(node)) {
8132 break;
8133 }
8134 offset += node.data.length;
8135 }
8136 return offset;
8137 };
8138 var equal = function (a) {
8139 return function (b) {
8140 return a === b;
8141 };
8142 };
8143 var normalizedNodeIndex = function (node) {
8144 var nodes, index, numTextFragments;
8145 nodes = getChildNodes(normalizedParent(node));
8146 index = ArrUtils.findIndex(nodes, equal(node), node);
8147 nodes = nodes.slice(0, index + 1);
8148 numTextFragments = ArrUtils.reduce(nodes, function (result, node, i) {
8149 if (isText$5(node) && isText$5(nodes[i - 1])) {
8150 result++;
8151 }
8152 return result;
8153 }, 0);
8154 nodes = ArrUtils.filter(nodes, NodeType.matchNodeNames([node.nodeName]));
8155 index = ArrUtils.findIndex(nodes, equal(node), node);
8156 return index - numTextFragments;
8157 };
8158 var createPathItem = function (node) {
8159 var name;
8160 if (isText$5(node)) {
8161 name = 'text()';
8162 } else {
8163 name = node.nodeName.toLowerCase();
8164 }
8165 return name + '[' + normalizedNodeIndex(node) + ']';
8166 };
8167 var parentsUntil = function (root, node, predicate) {
8168 var parents = [];
8169 for (node = node.parentNode; node !== root; node = node.parentNode) {
8170 if (predicate && predicate(node)) {
8171 break;
8172 }
8173 parents.push(node);
8174 }
8175 return parents;
8176 };
8177 var create$2 = function (root, caretPosition) {
8178 var container, offset, path = [], outputOffset, childNodes, parents;
8179 container = caretPosition.container();
8180 offset = caretPosition.offset();
8181 if (isText$5(container)) {
8182 outputOffset = normalizedTextOffset(container, offset);
8183 } else {
8184 childNodes = container.childNodes;
8185 if (offset >= childNodes.length) {
8186 outputOffset = 'after';
8187 offset = childNodes.length - 1;
8188 } else {
8189 outputOffset = 'before';
8190 }
8191 container = childNodes[offset];
8192 }
8193 path.push(createPathItem(container));
8194 parents = parentsUntil(root, container);
8195 parents = ArrUtils.filter(parents, not(NodeType.isBogus));
8196 path = path.concat(ArrUtils.map(parents, function (node) {
8197 return createPathItem(node);
8198 }));
8199 return path.reverse().join('/') + ',' + outputOffset;
8200 };
8201 var resolvePathItem = function (node, name, index) {
8202 var nodes = getChildNodes(node);
8203 nodes = ArrUtils.filter(nodes, function (node, index) {
8204 return !isText$5(node) || !isText$5(nodes[index - 1]);
8205 });
8206 nodes = ArrUtils.filter(nodes, NodeType.matchNodeNames([name]));
8207 return nodes[index];
8208 };
8209 var findTextPosition = function (container, offset) {
8210 var node = container, targetOffset = 0, dataLen;
8211 while (isText$5(node)) {
8212 dataLen = node.data.length;
8213 if (offset >= targetOffset && offset <= targetOffset + dataLen) {
8214 container = node;
8215 offset = offset - targetOffset;
8216 break;
8217 }
8218 if (!isText$5(node.nextSibling)) {
8219 container = node;
8220 offset = dataLen;
8221 break;
8222 }
8223 targetOffset += dataLen;
8224 node = node.nextSibling;
8225 }
8226 if (isText$5(container) && offset > container.data.length) {
8227 offset = container.data.length;
8228 }
8229 return CaretPosition$1(container, offset);
8230 };
8231 var resolve$2 = function (root, path) {
8232 var parts, container, offset;
8233 if (!path) {
8234 return null;
8235 }
8236 parts = path.split(',');
8237 path = parts[0].split('/');
8238 offset = parts.length > 1 ? parts[1] : 'before';
8239 container = ArrUtils.reduce(path, function (result, value) {
8240 value = /([\w\-\(\)]+)\[([0-9]+)\]/.exec(value);
8241 if (!value) {
8242 return null;
8243 }
8244 if (value[1] === 'text()') {
8245 value[1] = '#text';
8246 }
8247 return resolvePathItem(result, value[1], parseInt(value[2], 10));
8248 }, root);
8249 if (!container) {
8250 return null;
8251 }
8252 if (!isText$5(container)) {
8253 if (offset === 'after') {
8254 offset = nodeIndex$1(container) + 1;
8255 } else {
8256 offset = nodeIndex$1(container);
8257 }
8258 return CaretPosition$1(container.parentNode, offset);
8259 }
8260 return findTextPosition(container, parseInt(offset, 10));
8261 };
8262
8263 var trimEmptyTextNode = function (dom, node) {
8264 if (NodeType.isText(node) && node.data.length === 0) {
8265 dom.remove(node);
8266 }
8267 };
8268 var insertNode = function (dom, rng, node) {
8269 rng.insertNode(node);
8270 trimEmptyTextNode(dom, node.previousSibling);
8271 trimEmptyTextNode(dom, node.nextSibling);
8272 };
8273 var insertFragment = function (dom, rng, frag) {
8274 var firstChild = Option.from(frag.firstChild);
8275 var lastChild = Option.from(frag.lastChild);
8276 rng.insertNode(frag);
8277 firstChild.each(function (child) {
8278 return trimEmptyTextNode(dom, child.previousSibling);
8279 });
8280 lastChild.each(function (child) {
8281 return trimEmptyTextNode(dom, child.nextSibling);
8282 });
8283 };
8284 var rangeInsertNode = function (dom, rng, node) {
8285 if (NodeType.isDocumentFragment(node)) {
8286 insertFragment(dom, rng, node);
8287 } else {
8288 insertNode(dom, rng, node);
8289 }
8290 };
8291
8292 var isContentEditableFalse$2 = NodeType.isContentEditableFalse;
8293 var getNormalizedTextOffset = function (trim, container, offset) {
8294 var node, trimmedOffset;
8295 trimmedOffset = trim(container.data.slice(0, offset)).length;
8296 for (node = container.previousSibling; node && NodeType.isText(node); node = node.previousSibling) {
8297 trimmedOffset += trim(node.data).length;
8298 }
8299 return trimmedOffset;
8300 };
8301 var getPoint = function (dom, trim, normalized, rng, start) {
8302 var container = rng[start ? 'startContainer' : 'endContainer'];
8303 var offset = rng[start ? 'startOffset' : 'endOffset'];
8304 var point = [];
8305 var childNodes, after = 0;
8306 var root = dom.getRoot();
8307 if (NodeType.isText(container)) {
8308 point.push(normalized ? getNormalizedTextOffset(trim, container, offset) : offset);
8309 } else {
8310 childNodes = container.childNodes;
8311 if (offset >= childNodes.length && childNodes.length) {
8312 after = 1;
8313 offset = Math.max(0, childNodes.length - 1);
8314 }
8315 point.push(dom.nodeIndex(childNodes[offset], normalized) + after);
8316 }
8317 for (; container && container !== root; container = container.parentNode) {
8318 point.push(dom.nodeIndex(container, normalized));
8319 }
8320 return point;
8321 };
8322 var getLocation = function (trim, selection, normalized, rng) {
8323 var dom = selection.dom, bookmark = {};
8324 bookmark.start = getPoint(dom, trim, normalized, rng, true);
8325 if (!selection.isCollapsed()) {
8326 bookmark.end = getPoint(dom, trim, normalized, rng, false);
8327 }
8328 return bookmark;
8329 };
8330 var findIndex$2 = function (dom, name, element) {
8331 var count = 0;
8332 Tools.each(dom.select(name), function (node) {
8333 if (node.getAttribute('data-mce-bogus') === 'all') {
8334 return;
8335 }
8336 if (node === element) {
8337 return false;
8338 }
8339 count++;
8340 });
8341 return count;
8342 };
8343 var moveEndPoint = function (rng, start) {
8344 var container, offset, childNodes;
8345 var prefix = start ? 'start' : 'end';
8346 container = rng[prefix + 'Container'];
8347 offset = rng[prefix + 'Offset'];
8348 if (NodeType.isElement(container) && container.nodeName === 'TR') {
8349 childNodes = container.childNodes;
8350 container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];
8351 if (container) {
8352 offset = start ? 0 : container.childNodes.length;
8353 rng['set' + (start ? 'Start' : 'End')](container, offset);
8354 }
8355 }
8356 };
8357 var normalizeTableCellSelection = function (rng) {
8358 moveEndPoint(rng, true);
8359 moveEndPoint(rng, false);
8360 return rng;
8361 };
8362 var findSibling = function (node, offset) {
8363 var sibling;
8364 if (NodeType.isElement(node)) {
8365 node = getNode(node, offset);
8366 if (isContentEditableFalse$2(node)) {
8367 return node;
8368 }
8369 }
8370 if (isCaretContainer(node)) {
8371 if (NodeType.isText(node) && isCaretContainerBlock(node)) {
8372 node = node.parentNode;
8373 }
8374 sibling = node.previousSibling;
8375 if (isContentEditableFalse$2(sibling)) {
8376 return sibling;
8377 }
8378 sibling = node.nextSibling;
8379 if (isContentEditableFalse$2(sibling)) {
8380 return sibling;
8381 }
8382 }
8383 };
8384 var findAdjacentContentEditableFalseElm = function (rng) {
8385 return findSibling(rng.startContainer, rng.startOffset) || findSibling(rng.endContainer, rng.endOffset);
8386 };
8387 var getOffsetBookmark = function (trim, normalized, selection) {
8388 var element = selection.getNode();
8389 var name = element ? element.nodeName : null;
8390 var rng = selection.getRng();
8391 if (isContentEditableFalse$2(element) || name === 'IMG') {
8392 return {
8393 name: name,
8394 index: findIndex$2(selection.dom, name, element)
8395 };
8396 }
8397 var sibling = findAdjacentContentEditableFalseElm(rng);
8398 if (sibling) {
8399 name = sibling.tagName;
8400 return {
8401 name: name,
8402 index: findIndex$2(selection.dom, name, sibling)
8403 };
8404 }
8405 return getLocation(trim, selection, normalized, rng);
8406 };
8407 var getCaretBookmark = function (selection) {
8408 var rng = selection.getRng();
8409 return {
8410 start: create$2(selection.dom.getRoot(), CaretPosition$1.fromRangeStart(rng)),
8411 end: create$2(selection.dom.getRoot(), CaretPosition$1.fromRangeEnd(rng))
8412 };
8413 };
8414 var getRangeBookmark = function (selection) {
8415 return { rng: selection.getRng() };
8416 };
8417 var createBookmarkSpan = function (dom, id, filled) {
8418 var args = {
8419 'data-mce-type': 'bookmark',
8420 'id': id,
8421 'style': 'overflow:hidden;line-height:0px'
8422 };
8423 return filled ? dom.create('span', args, '&#xFEFF;') : dom.create('span', args);
8424 };
8425 var getPersistentBookmark = function (selection, filled) {
8426 var dom = selection.dom;
8427 var rng = selection.getRng();
8428 var id = dom.uniqueId();
8429 var collapsed = selection.isCollapsed();
8430 var element = selection.getNode();
8431 var name = element.nodeName;
8432 if (name === 'IMG') {
8433 return {
8434 name: name,
8435 index: findIndex$2(dom, name, element)
8436 };
8437 }
8438 var rng2 = normalizeTableCellSelection(rng.cloneRange());
8439 if (!collapsed) {
8440 rng2.collapse(false);
8441 var endBookmarkNode = createBookmarkSpan(dom, id + '_end', filled);
8442 rangeInsertNode(dom, rng2, endBookmarkNode);
8443 }
8444 rng = normalizeTableCellSelection(rng);
8445 rng.collapse(true);
8446 var startBookmarkNode = createBookmarkSpan(dom, id + '_start', filled);
8447 rangeInsertNode(dom, rng, startBookmarkNode);
8448 selection.moveToBookmark({
8449 id: id,
8450 keep: 1
8451 });
8452 return { id: id };
8453 };
8454 var getBookmark = function (selection, type, normalized) {
8455 if (type === 2) {
8456 return getOffsetBookmark(Zwsp.trim, normalized, selection);
8457 } else if (type === 3) {
8458 return getCaretBookmark(selection);
8459 } else if (type) {
8460 return getRangeBookmark(selection);
8461 } else {
8462 return getPersistentBookmark(selection, false);
8463 }
8464 };
8465 var GetBookmark = {
8466 getBookmark: getBookmark,
8467 getUndoBookmark: curry(getOffsetBookmark, identity, true),
8468 getPersistentBookmark: getPersistentBookmark
8469 };
8470
8471 var CARET_ID = '_mce_caret';
8472 var isCaretNode = function (node) {
8473 return NodeType.isElement(node) && node.id === CARET_ID;
8474 };
8475 var getParentCaretContainer = function (body, node) {
8476 while (node && node !== body) {
8477 if (node.id === CARET_ID) {
8478 return node;
8479 }
8480 node = node.parentNode;
8481 }
8482 return null;
8483 };
8484
8485 var isElement$4 = NodeType.isElement;
8486 var isText$6 = NodeType.isText;
8487 var removeNode = function (node) {
8488 var parentNode = node.parentNode;
8489 if (parentNode) {
8490 parentNode.removeChild(node);
8491 }
8492 };
8493 var getNodeValue = function (node) {
8494 try {
8495 return node.nodeValue;
8496 } catch (ex) {
8497 return '';
8498 }
8499 };
8500 var setNodeValue = function (node, text) {
8501 if (text.length === 0) {
8502 removeNode(node);
8503 } else {
8504 node.nodeValue = text;
8505 }
8506 };
8507 var trimCount = function (text) {
8508 var trimmedText = Zwsp.trim(text);
8509 return {
8510 count: text.length - trimmedText.length,
8511 text: trimmedText
8512 };
8513 };
8514 var removeUnchanged = function (caretContainer, pos) {
8515 remove$5(caretContainer);
8516 return pos;
8517 };
8518 var removeTextAndReposition = function (caretContainer, pos) {
8519 var before = trimCount(caretContainer.data.substr(0, pos.offset()));
8520 var after = trimCount(caretContainer.data.substr(pos.offset()));
8521 var text = before.text + after.text;
8522 if (text.length > 0) {
8523 setNodeValue(caretContainer, text);
8524 return CaretPosition$1(caretContainer, pos.offset() - before.count);
8525 } else {
8526 return pos;
8527 }
8528 };
8529 var removeElementAndReposition = function (caretContainer, pos) {
8530 var parentNode = pos.container();
8531 var newPosition = indexOf(from$1(parentNode.childNodes), caretContainer).map(function (index) {
8532 return index < pos.offset() ? CaretPosition$1(parentNode, pos.offset() - 1) : pos;
8533 }).getOr(pos);
8534 remove$5(caretContainer);
8535 return newPosition;
8536 };
8537 var removeTextCaretContainer = function (caretContainer, pos) {
8538 return isText$6(caretContainer) && pos.container() === caretContainer ? removeTextAndReposition(caretContainer, pos) : removeUnchanged(caretContainer, pos);
8539 };
8540 var removeElementCaretContainer = function (caretContainer, pos) {
8541 return pos.container() === caretContainer.parentNode ? removeElementAndReposition(caretContainer, pos) : removeUnchanged(caretContainer, pos);
8542 };
8543 var removeAndReposition = function (container, pos) {
8544 return CaretPosition$1.isTextPosition(pos) ? removeTextCaretContainer(container, pos) : removeElementCaretContainer(container, pos);
8545 };
8546 var remove$5 = function (caretContainerNode) {
8547 if (isElement$4(caretContainerNode) && isCaretContainer(caretContainerNode)) {
8548 if (hasContent(caretContainerNode)) {
8549 caretContainerNode.removeAttribute('data-mce-caret');
8550 } else {
8551 removeNode(caretContainerNode);
8552 }
8553 }
8554 if (isText$6(caretContainerNode)) {
8555 var text = Zwsp.trim(getNodeValue(caretContainerNode));
8556 setNodeValue(caretContainerNode, text);
8557 }
8558 };
8559 var CaretContainerRemove = {
8560 removeAndReposition: removeAndReposition,
8561 remove: remove$5
8562 };
8563
8564 var browser$2 = PlatformDetection$1.detect().browser;
8565 var isContentEditableFalse$3 = NodeType.isContentEditableFalse;
8566 var isTableCell$1 = function (node) {
8567 return NodeType.isElement(node) && /^(TD|TH)$/i.test(node.tagName);
8568 };
8569 var getAbsoluteClientRect = function (root, element, before) {
8570 var clientRect = collapse(element.getBoundingClientRect(), before);
8571 var docElm, scrollX, scrollY, margin, rootRect;
8572 if (root.tagName === 'BODY') {
8573 docElm = root.ownerDocument.documentElement;
8574 scrollX = root.scrollLeft || docElm.scrollLeft;
8575 scrollY = root.scrollTop || docElm.scrollTop;
8576 } else {
8577 rootRect = root.getBoundingClientRect();
8578 scrollX = root.scrollLeft - rootRect.left;
8579 scrollY = root.scrollTop - rootRect.top;
8580 }
8581 clientRect.left += scrollX;
8582 clientRect.right += scrollX;
8583 clientRect.top += scrollY;
8584 clientRect.bottom += scrollY;
8585 clientRect.width = 1;
8586 margin = element.offsetWidth - element.clientWidth;
8587 if (margin > 0) {
8588 if (before) {
8589 margin *= -1;
8590 }
8591 clientRect.left += margin;
8592 clientRect.right += margin;
8593 }
8594 return clientRect;
8595 };
8596 var trimInlineCaretContainers = function (root) {
8597 var contentEditableFalseNodes, node, sibling, i, data;
8598 contentEditableFalseNodes = DomQuery('*[contentEditable=false]', root);
8599 for (i = 0; i < contentEditableFalseNodes.length; i++) {
8600 node = contentEditableFalseNodes[i];
8601 sibling = node.previousSibling;
8602 if (endsWithCaretContainer(sibling)) {
8603 data = sibling.data;
8604 if (data.length === 1) {
8605 sibling.parentNode.removeChild(sibling);
8606 } else {
8607 sibling.deleteData(data.length - 1, 1);
8608 }
8609 }
8610 sibling = node.nextSibling;
8611 if (startsWithCaretContainer(sibling)) {
8612 data = sibling.data;
8613 if (data.length === 1) {
8614 sibling.parentNode.removeChild(sibling);
8615 } else {
8616 sibling.deleteData(0, 1);
8617 }
8618 }
8619 }
8620 };
8621 var FakeCaret = function (root, isBlock, hasFocus) {
8622 var lastVisualCaret = Cell(Option.none());
8623 var cursorInterval, caretContainerNode;
8624 var show = function (before, element) {
8625 var clientRect, rng;
8626 hide();
8627 if (isTableCell$1(element)) {
8628 return null;
8629 }
8630 if (isBlock(element)) {
8631 caretContainerNode = insertBlock('p', element, before);
8632 clientRect = getAbsoluteClientRect(root, element, before);
8633 DomQuery(caretContainerNode).css('top', clientRect.top);
8634 var caret = DomQuery('<div class="mce-visual-caret" data-mce-bogus="all"></div>').css(clientRect).appendTo(root)[0];
8635 lastVisualCaret.set(Option.some({
8636 caret: caret,
8637 element: element,
8638 before: before
8639 }));
8640 lastVisualCaret.get().each(function (caretState) {
8641 if (before) {
8642 DomQuery(caretState.caret).addClass('mce-visual-caret-before');
8643 }
8644 });
8645 startBlink();
8646 rng = element.ownerDocument.createRange();
8647 rng.setStart(caretContainerNode, 0);
8648 rng.setEnd(caretContainerNode, 0);
8649 } else {
8650 caretContainerNode = insertInline(element, before);
8651 rng = element.ownerDocument.createRange();
8652 if (isContentEditableFalse$3(caretContainerNode.nextSibling)) {
8653 rng.setStart(caretContainerNode, 0);
8654 rng.setEnd(caretContainerNode, 0);
8655 } else {
8656 rng.setStart(caretContainerNode, 1);
8657 rng.setEnd(caretContainerNode, 1);
8658 }
8659 return rng;
8660 }
8661 return rng;
8662 };
8663 var hide = function () {
8664 trimInlineCaretContainers(root);
8665 if (caretContainerNode) {
8666 CaretContainerRemove.remove(caretContainerNode);
8667 caretContainerNode = null;
8668 }
8669 lastVisualCaret.get().each(function (caretState) {
8670 DomQuery(caretState.caret).remove();
8671 lastVisualCaret.set(Option.none());
8672 });
8673 Delay.clearInterval(cursorInterval);
8674 };
8675 var startBlink = function () {
8676 cursorInterval = Delay.setInterval(function () {
8677 if (hasFocus()) {
8678 DomQuery('div.mce-visual-caret', root).toggleClass('mce-visual-caret-hidden');
8679 } else {
8680 DomQuery('div.mce-visual-caret', root).addClass('mce-visual-caret-hidden');
8681 }
8682 }, 500);
8683 };
8684 var reposition = function () {
8685 lastVisualCaret.get().each(function (caretState) {
8686 var clientRect = getAbsoluteClientRect(root, caretState.element, caretState.before);
8687 DomQuery(caretState.caret).css(__assign({}, clientRect));
8688 });
8689 };
8690 var destroy = function () {
8691 return Delay.clearInterval(cursorInterval);
8692 };
8693 var getCss = function () {
8694 return '.mce-visual-caret {' + 'position: absolute;' + 'background-color: black;' + 'background-color: currentcolor;' + '}' + '.mce-visual-caret-hidden {' + 'display: none;' + '}' + '*[data-mce-caret] {' + 'position: absolute;' + 'left: -1000px;' + 'right: auto;' + 'top: 0;' + 'margin: 0;' + 'padding: 0;' + '}';
8695 };
8696 return {
8697 show: show,
8698 hide: hide,
8699 getCss: getCss,
8700 reposition: reposition,
8701 destroy: destroy
8702 };
8703 };
8704 var isFakeCaretTableBrowser = function () {
8705 return browser$2.isIE() || browser$2.isEdge() || browser$2.isFirefox();
8706 };
8707 var isFakeCaretTarget = function (node) {
8708 return isContentEditableFalse$3(node) || NodeType.isTable(node) && isFakeCaretTableBrowser();
8709 };
8710
8711 var isContentEditableFalse$4 = NodeType.isContentEditableFalse;
8712 var isBlockLike = NodeType.matchStyleValues('display', 'block table table-cell table-caption list-item');
8713 var isCaretContainer$2 = isCaretContainer;
8714 var isCaretContainerBlock$1 = isCaretContainerBlock;
8715 var isElement$5 = NodeType.isElement;
8716 var isCaretCandidate$2 = isCaretCandidate;
8717 var isForwards = function (direction) {
8718 return direction > 0;
8719 };
8720 var isBackwards = function (direction) {
8721 return direction < 0;
8722 };
8723 var skipCaretContainers = function (walk, shallow) {
8724 var node;
8725 while (node = walk(shallow)) {
8726 if (!isCaretContainerBlock$1(node)) {
8727 return node;
8728 }
8729 }
8730 return null;
8731 };
8732 var findNode = function (node, direction, predicateFn, rootNode, shallow) {
8733 var walker = new TreeWalker(node, rootNode);
8734 if (isBackwards(direction)) {
8735 if (isContentEditableFalse$4(node) || isCaretContainerBlock$1(node)) {
8736 node = skipCaretContainers(walker.prev, true);
8737 if (predicateFn(node)) {
8738 return node;
8739 }
8740 }
8741 while (node = skipCaretContainers(walker.prev, shallow)) {
8742 if (predicateFn(node)) {
8743 return node;
8744 }
8745 }
8746 }
8747 if (isForwards(direction)) {
8748 if (isContentEditableFalse$4(node) || isCaretContainerBlock$1(node)) {
8749 node = skipCaretContainers(walker.next, true);
8750 if (predicateFn(node)) {
8751 return node;
8752 }
8753 }
8754 while (node = skipCaretContainers(walker.next, shallow)) {
8755 if (predicateFn(node)) {
8756 return node;
8757 }
8758 }
8759 }
8760 return null;
8761 };
8762 var getParentBlock = function (node, rootNode) {
8763 while (node && node !== rootNode) {
8764 if (isBlockLike(node)) {
8765 return node;
8766 }
8767 node = node.parentNode;
8768 }
8769 return null;
8770 };
8771 var isInSameBlock = function (caretPosition1, caretPosition2, rootNode) {
8772 return getParentBlock(caretPosition1.container(), rootNode) === getParentBlock(caretPosition2.container(), rootNode);
8773 };
8774 var getChildNodeAtRelativeOffset = function (relativeOffset, caretPosition) {
8775 var container, offset;
8776 if (!caretPosition) {
8777 return null;
8778 }
8779 container = caretPosition.container();
8780 offset = caretPosition.offset();
8781 if (!isElement$5(container)) {
8782 return null;
8783 }
8784 return container.childNodes[offset + relativeOffset];
8785 };
8786 var beforeAfter = function (before, node) {
8787 var range = node.ownerDocument.createRange();
8788 if (before) {
8789 range.setStartBefore(node);
8790 range.setEndBefore(node);
8791 } else {
8792 range.setStartAfter(node);
8793 range.setEndAfter(node);
8794 }
8795 return range;
8796 };
8797 var isNodesInSameBlock = function (root, node1, node2) {
8798 return getParentBlock(node1, root) === getParentBlock(node2, root);
8799 };
8800 var lean = function (left, root, node) {
8801 var sibling, siblingName;
8802 if (left) {
8803 siblingName = 'previousSibling';
8804 } else {
8805 siblingName = 'nextSibling';
8806 }
8807 while (node && node !== root) {
8808 sibling = node[siblingName];
8809 if (isCaretContainer$2(sibling)) {
8810 sibling = sibling[siblingName];
8811 }
8812 if (isContentEditableFalse$4(sibling)) {
8813 if (isNodesInSameBlock(root, sibling, node)) {
8814 return sibling;
8815 }
8816 break;
8817 }
8818 if (isCaretCandidate$2(sibling)) {
8819 break;
8820 }
8821 node = node.parentNode;
8822 }
8823 return null;
8824 };
8825 var before$2 = curry(beforeAfter, true);
8826 var after$1 = curry(beforeAfter, false);
8827 var normalizeRange = function (direction, root, range) {
8828 var node, container, offset, location;
8829 var leanLeft = curry(lean, true, root);
8830 var leanRight = curry(lean, false, root);
8831 container = range.startContainer;
8832 offset = range.startOffset;
8833 if (isCaretContainerBlock(container)) {
8834 if (!isElement$5(container)) {
8835 container = container.parentNode;
8836 }
8837 location = container.getAttribute('data-mce-caret');
8838 if (location === 'before') {
8839 node = container.nextSibling;
8840 if (isFakeCaretTarget(node)) {
8841 return before$2(node);
8842 }
8843 }
8844 if (location === 'after') {
8845 node = container.previousSibling;
8846 if (isFakeCaretTarget(node)) {
8847 return after$1(node);
8848 }
8849 }
8850 }
8851 if (!range.collapsed) {
8852 return range;
8853 }
8854 if (NodeType.isText(container)) {
8855 if (isCaretContainer$2(container)) {
8856 if (direction === 1) {
8857 node = leanRight(container);
8858 if (node) {
8859 return before$2(node);
8860 }
8861 node = leanLeft(container);
8862 if (node) {
8863 return after$1(node);
8864 }
8865 }
8866 if (direction === -1) {
8867 node = leanLeft(container);
8868 if (node) {
8869 return after$1(node);
8870 }
8871 node = leanRight(container);
8872 if (node) {
8873 return before$2(node);
8874 }
8875 }
8876 return range;
8877 }
8878 if (endsWithCaretContainer(container) && offset >= container.data.length - 1) {
8879 if (direction === 1) {
8880 node = leanRight(container);
8881 if (node) {
8882 return before$2(node);
8883 }
8884 }
8885 return range;
8886 }
8887 if (startsWithCaretContainer(container) && offset <= 1) {
8888 if (direction === -1) {
8889 node = leanLeft(container);
8890 if (node) {
8891 return after$1(node);
8892 }
8893 }
8894 return range;
8895 }
8896 if (offset === container.data.length) {
8897 node = leanRight(container);
8898 if (node) {
8899 return before$2(node);
8900 }
8901 return range;
8902 }
8903 if (offset === 0) {
8904 node = leanLeft(container);
8905 if (node) {
8906 return after$1(node);
8907 }
8908 return range;
8909 }
8910 }
8911 return range;
8912 };
8913 var getRelativeCefElm = function (forward, caretPosition) {
8914 return Option.from(getChildNodeAtRelativeOffset(forward ? 0 : -1, caretPosition)).filter(isContentEditableFalse$4);
8915 };
8916 var getNormalizedRangeEndPoint = function (direction, root, range) {
8917 var normalizedRange = normalizeRange(direction, root, range);
8918 if (direction === -1) {
8919 return CaretPosition.fromRangeStart(normalizedRange);
8920 }
8921 return CaretPosition.fromRangeEnd(normalizedRange);
8922 };
8923 var getElementFromPosition = function (pos) {
8924 return Option.from(pos.getNode()).map(Element.fromDom);
8925 };
8926 var getElementFromPrevPosition = function (pos) {
8927 return Option.from(pos.getNode(true)).map(Element.fromDom);
8928 };
8929 var getVisualCaretPosition = function (walkFn, caretPosition) {
8930 while (caretPosition = walkFn(caretPosition)) {
8931 if (caretPosition.isVisible()) {
8932 return caretPosition;
8933 }
8934 }
8935 return caretPosition;
8936 };
8937 var isMoveInsideSameBlock = function (from, to) {
8938 var inSameBlock = isInSameBlock(from, to);
8939 if (!inSameBlock && NodeType.isBr(from.getNode())) {
8940 return true;
8941 }
8942 return inSameBlock;
8943 };
8944
8945 var HDirection;
8946 (function (HDirection) {
8947 HDirection[HDirection['Backwards'] = -1] = 'Backwards';
8948 HDirection[HDirection['Forwards'] = 1] = 'Forwards';
8949 }(HDirection || (HDirection = {})));
8950 var isContentEditableFalse$5 = NodeType.isContentEditableFalse;
8951 var isText$7 = NodeType.isText;
8952 var isElement$6 = NodeType.isElement;
8953 var isBr$4 = NodeType.isBr;
8954 var isCaretCandidate$3 = isCaretCandidate;
8955 var isAtomic$1 = isAtomic;
8956 var isEditableCaretCandidate$1 = isEditableCaretCandidate;
8957 var getParents = function (node, root) {
8958 var parents = [];
8959 while (node && node !== root) {
8960 parents.push(node);
8961 node = node.parentNode;
8962 }
8963 return parents;
8964 };
8965 var nodeAtIndex = function (container, offset) {
8966 if (container.hasChildNodes() && offset < container.childNodes.length) {
8967 return container.childNodes[offset];
8968 }
8969 return null;
8970 };
8971 var getCaretCandidatePosition = function (direction, node) {
8972 if (isForwards(direction)) {
8973 if (isCaretCandidate$3(node.previousSibling) && !isText$7(node.previousSibling)) {
8974 return CaretPosition$1.before(node);
8975 }
8976 if (isText$7(node)) {
8977 return CaretPosition$1(node, 0);
8978 }
8979 }
8980 if (isBackwards(direction)) {
8981 if (isCaretCandidate$3(node.nextSibling) && !isText$7(node.nextSibling)) {
8982 return CaretPosition$1.after(node);
8983 }
8984 if (isText$7(node)) {
8985 return CaretPosition$1(node, node.data.length);
8986 }
8987 }
8988 if (isBackwards(direction)) {
8989 if (isBr$4(node)) {
8990 return CaretPosition$1.before(node);
8991 }
8992 return CaretPosition$1.after(node);
8993 }
8994 return CaretPosition$1.before(node);
8995 };
8996 var moveForwardFromBr = function (root, nextNode) {
8997 var nextSibling = nextNode.nextSibling;
8998 if (nextSibling && isCaretCandidate$3(nextSibling)) {
8999 if (isText$7(nextSibling)) {
9000 return CaretPosition$1(nextSibling, 0);
9001 } else {
9002 return CaretPosition$1.before(nextSibling);
9003 }
9004 } else {
9005 return findCaretPosition(HDirection.Forwards, CaretPosition$1.after(nextNode), root);
9006 }
9007 };
9008 var findCaretPosition = function (direction, startPos, root) {
9009 var node, nextNode, innerNode;
9010 var rootContentEditableFalseElm, caretPosition;
9011 if (!isElement$6(root) || !startPos) {
9012 return null;
9013 }
9014 if (startPos.isEqual(CaretPosition$1.after(root)) && root.lastChild) {
9015 caretPosition = CaretPosition$1.after(root.lastChild);
9016 if (isBackwards(direction) && isCaretCandidate$3(root.lastChild) && isElement$6(root.lastChild)) {
9017 return isBr$4(root.lastChild) ? CaretPosition$1.before(root.lastChild) : caretPosition;
9018 }
9019 } else {
9020 caretPosition = startPos;
9021 }
9022 var container = caretPosition.container();
9023 var offset = caretPosition.offset();
9024 if (isText$7(container)) {
9025 if (isBackwards(direction) && offset > 0) {
9026 return CaretPosition$1(container, --offset);
9027 }
9028 if (isForwards(direction) && offset < container.length) {
9029 return CaretPosition$1(container, ++offset);
9030 }
9031 node = container;
9032 } else {
9033 if (isBackwards(direction) && offset > 0) {
9034 nextNode = nodeAtIndex(container, offset - 1);
9035 if (isCaretCandidate$3(nextNode)) {
9036 if (!isAtomic$1(nextNode)) {
9037 innerNode = findNode(nextNode, direction, isEditableCaretCandidate$1, nextNode);
9038 if (innerNode) {
9039 if (isText$7(innerNode)) {
9040 return CaretPosition$1(innerNode, innerNode.data.length);
9041 }
9042 return CaretPosition$1.after(innerNode);
9043 }
9044 }
9045 if (isText$7(nextNode)) {
9046 return CaretPosition$1(nextNode, nextNode.data.length);
9047 }
9048 return CaretPosition$1.before(nextNode);
9049 }
9050 }
9051 if (isForwards(direction) && offset < container.childNodes.length) {
9052 nextNode = nodeAtIndex(container, offset);
9053 if (isCaretCandidate$3(nextNode)) {
9054 if (isBr$4(nextNode)) {
9055 return moveForwardFromBr(root, nextNode);
9056 }
9057 if (!isAtomic$1(nextNode)) {
9058 innerNode = findNode(nextNode, direction, isEditableCaretCandidate$1, nextNode);
9059 if (innerNode) {
9060 if (isText$7(innerNode)) {
9061 return CaretPosition$1(innerNode, 0);
9062 }
9063 return CaretPosition$1.before(innerNode);
9064 }
9065 }
9066 if (isText$7(nextNode)) {
9067 return CaretPosition$1(nextNode, 0);
9068 }
9069 return CaretPosition$1.after(nextNode);
9070 }
9071 }
9072 node = nextNode ? nextNode : caretPosition.getNode();
9073 }
9074 if (isForwards(direction) && caretPosition.isAtEnd() || isBackwards(direction) && caretPosition.isAtStart()) {
9075 node = findNode(node, direction, constant(true), root, true);
9076 if (isEditableCaretCandidate$1(node, root)) {
9077 return getCaretCandidatePosition(direction, node);
9078 }
9079 }
9080 nextNode = findNode(node, direction, isEditableCaretCandidate$1, root);
9081 rootContentEditableFalseElm = ArrUtils.last(filter(getParents(container, root), isContentEditableFalse$5));
9082 if (rootContentEditableFalseElm && (!nextNode || !rootContentEditableFalseElm.contains(nextNode))) {
9083 if (isForwards(direction)) {
9084 caretPosition = CaretPosition$1.after(rootContentEditableFalseElm);
9085 } else {
9086 caretPosition = CaretPosition$1.before(rootContentEditableFalseElm);
9087 }
9088 return caretPosition;
9089 }
9090 if (nextNode) {
9091 return getCaretCandidatePosition(direction, nextNode);
9092 }
9093 return null;
9094 };
9095 var CaretWalker = function (root) {
9096 return {
9097 next: function (caretPosition) {
9098 return findCaretPosition(HDirection.Forwards, caretPosition, root);
9099 },
9100 prev: function (caretPosition) {
9101 return findCaretPosition(HDirection.Backwards, caretPosition, root);
9102 }
9103 };
9104 };
9105
9106 var walkToPositionIn = function (forward, root, start) {
9107 var position = forward ? CaretPosition$1.before(start) : CaretPosition$1.after(start);
9108 return fromPosition(forward, root, position);
9109 };
9110 var afterElement = function (node) {
9111 return NodeType.isBr(node) ? CaretPosition$1.before(node) : CaretPosition$1.after(node);
9112 };
9113 var isBeforeOrStart = function (position) {
9114 if (CaretPosition$1.isTextPosition(position)) {
9115 return position.offset() === 0;
9116 } else {
9117 return isCaretCandidate(position.getNode());
9118 }
9119 };
9120 var isAfterOrEnd = function (position) {
9121 if (CaretPosition$1.isTextPosition(position)) {
9122 var container = position.container();
9123 return position.offset() === container.data.length;
9124 } else {
9125 return isCaretCandidate(position.getNode(true));
9126 }
9127 };
9128 var isBeforeAfterSameElement = function (from, to) {
9129 return !CaretPosition$1.isTextPosition(from) && !CaretPosition$1.isTextPosition(to) && from.getNode() === to.getNode(true);
9130 };
9131 var isAtBr = function (position) {
9132 return !CaretPosition$1.isTextPosition(position) && NodeType.isBr(position.getNode());
9133 };
9134 var shouldSkipPosition = function (forward, from, to) {
9135 if (forward) {
9136 return !isBeforeAfterSameElement(from, to) && !isAtBr(from) && isAfterOrEnd(from) && isBeforeOrStart(to);
9137 } else {
9138 return !isBeforeAfterSameElement(to, from) && isBeforeOrStart(from) && isAfterOrEnd(to);
9139 }
9140 };
9141 var fromPosition = function (forward, root, pos) {
9142 var walker = CaretWalker(root);
9143 return Option.from(forward ? walker.next(pos) : walker.prev(pos));
9144 };
9145 var navigate = function (forward, root, from) {
9146 return fromPosition(forward, root, from).bind(function (to) {
9147 if (isInSameBlock(from, to, root) && shouldSkipPosition(forward, from, to)) {
9148 return fromPosition(forward, root, to);
9149 } else {
9150 return Option.some(to);
9151 }
9152 });
9153 };
9154 var navigateIgnore = function (forward, root, from, ignoreFilter) {
9155 return navigate(forward, root, from).bind(function (pos) {
9156 return ignoreFilter(pos) ? navigateIgnore(forward, root, pos, ignoreFilter) : Option.some(pos);
9157 });
9158 };
9159 var positionIn = function (forward, element) {
9160 var startNode = forward ? element.firstChild : element.lastChild;
9161 if (NodeType.isText(startNode)) {
9162 return Option.some(CaretPosition$1(startNode, forward ? 0 : startNode.data.length));
9163 } else if (startNode) {
9164 if (isCaretCandidate(startNode)) {
9165 return Option.some(forward ? CaretPosition$1.before(startNode) : afterElement(startNode));
9166 } else {
9167 return walkToPositionIn(forward, element, startNode);
9168 }
9169 } else {
9170 return Option.none();
9171 }
9172 };
9173 var nextPosition = curry(fromPosition, true);
9174 var prevPosition = curry(fromPosition, false);
9175 var CaretFinder = {
9176 fromPosition: fromPosition,
9177 nextPosition: nextPosition,
9178 prevPosition: prevPosition,
9179 navigate: navigate,
9180 navigateIgnore: navigateIgnore,
9181 positionIn: positionIn,
9182 firstPositionIn: curry(positionIn, true),
9183 lastPositionIn: curry(positionIn, false)
9184 };
9185
9186 var isStringPathBookmark = function (bookmark) {
9187 return typeof bookmark.start === 'string';
9188 };
9189 var isRangeBookmark = function (bookmark) {
9190 return bookmark.hasOwnProperty('rng');
9191 };
9192 var isIdBookmark = function (bookmark) {
9193 return bookmark.hasOwnProperty('id');
9194 };
9195 var isIndexBookmark = function (bookmark) {
9196 return bookmark.hasOwnProperty('name');
9197 };
9198 var isPathBookmark = function (bookmark) {
9199 return Tools.isArray(bookmark.start);
9200 };
9201
9202 var addBogus = function (dom, node) {
9203 if (dom.isBlock(node) && !node.innerHTML && !Env.ie) {
9204 node.innerHTML = '<br data-mce-bogus="1" />';
9205 }
9206 return node;
9207 };
9208 var resolveCaretPositionBookmark = function (dom, bookmark) {
9209 var rng, pos;
9210 rng = dom.createRng();
9211 pos = resolve$2(dom.getRoot(), bookmark.start);
9212 rng.setStart(pos.container(), pos.offset());
9213 pos = resolve$2(dom.getRoot(), bookmark.end);
9214 rng.setEnd(pos.container(), pos.offset());
9215 return rng;
9216 };
9217 var insertZwsp = function (node, rng) {
9218 var textNode = node.ownerDocument.createTextNode(Zwsp.ZWSP);
9219 node.appendChild(textNode);
9220 rng.setStart(textNode, 0);
9221 rng.setEnd(textNode, 0);
9222 };
9223 var isEmpty = function (node) {
9224 return node.hasChildNodes() === false;
9225 };
9226 var tryFindRangePosition = function (node, rng) {
9227 return CaretFinder.lastPositionIn(node).fold(function () {
9228 return false;
9229 }, function (pos) {
9230 rng.setStart(pos.container(), pos.offset());
9231 rng.setEnd(pos.container(), pos.offset());
9232 return true;
9233 });
9234 };
9235 var padEmptyCaretContainer = function (root, node, rng) {
9236 if (isEmpty(node) && getParentCaretContainer(root, node)) {
9237 insertZwsp(node, rng);
9238 return true;
9239 } else {
9240 return false;
9241 }
9242 };
9243 var setEndPoint = function (dom, start, bookmark, rng) {
9244 var point = bookmark[start ? 'start' : 'end'];
9245 var i, node, offset, children;
9246 var root = dom.getRoot();
9247 if (point) {
9248 offset = point[0];
9249 for (node = root, i = point.length - 1; i >= 1; i--) {
9250 children = node.childNodes;
9251 if (padEmptyCaretContainer(root, node, rng)) {
9252 return true;
9253 }
9254 if (point[i] > children.length - 1) {
9255 if (padEmptyCaretContainer(root, node, rng)) {
9256 return true;
9257 }
9258 return tryFindRangePosition(node, rng);
9259 }
9260 node = children[point[i]];
9261 }
9262 if (node.nodeType === 3) {
9263 offset = Math.min(point[0], node.nodeValue.length);
9264 }
9265 if (node.nodeType === 1) {
9266 offset = Math.min(point[0], node.childNodes.length);
9267 }
9268 if (start) {
9269 rng.setStart(node, offset);
9270 } else {
9271 rng.setEnd(node, offset);
9272 }
9273 }
9274 return true;
9275 };
9276 var isValidTextNode = function (node) {
9277 return NodeType.isText(node) && node.data.length > 0;
9278 };
9279 var restoreEndPoint = function (dom, suffix, bookmark) {
9280 var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev;
9281 var keep = bookmark.keep;
9282 var container, offset;
9283 if (marker) {
9284 node = marker.parentNode;
9285 if (suffix === 'start') {
9286 if (!keep) {
9287 idx = dom.nodeIndex(marker);
9288 } else {
9289 if (marker.hasChildNodes()) {
9290 node = marker.firstChild;
9291 idx = 1;
9292 } else if (isValidTextNode(marker.nextSibling)) {
9293 node = marker.nextSibling;
9294 idx = 0;
9295 } else if (isValidTextNode(marker.previousSibling)) {
9296 node = marker.previousSibling;
9297 idx = marker.previousSibling.data.length;
9298 } else {
9299 node = marker.parentNode;
9300 idx = dom.nodeIndex(marker) + 1;
9301 }
9302 }
9303 container = node;
9304 offset = idx;
9305 } else {
9306 if (!keep) {
9307 idx = dom.nodeIndex(marker);
9308 } else {
9309 if (marker.hasChildNodes()) {
9310 node = marker.firstChild;
9311 idx = 1;
9312 } else if (isValidTextNode(marker.previousSibling)) {
9313 node = marker.previousSibling;
9314 idx = marker.previousSibling.data.length;
9315 } else {
9316 node = marker.parentNode;
9317 idx = dom.nodeIndex(marker);
9318 }
9319 }
9320 container = node;
9321 offset = idx;
9322 }
9323 if (!keep) {
9324 prev = marker.previousSibling;
9325 next = marker.nextSibling;
9326 Tools.each(Tools.grep(marker.childNodes), function (node) {
9327 if (NodeType.isText(node)) {
9328 node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');
9329 }
9330 });
9331 while (marker = dom.get(bookmark.id + '_' + suffix)) {
9332 dom.remove(marker, true);
9333 }
9334 if (prev && next && prev.nodeType === next.nodeType && NodeType.isText(prev) && !Env.opera) {
9335 idx = prev.nodeValue.length;
9336 prev.appendData(next.nodeValue);
9337 dom.remove(next);
9338 if (suffix === 'start') {
9339 container = prev;
9340 offset = idx;
9341 } else {
9342 container = prev;
9343 offset = idx;
9344 }
9345 }
9346 }
9347 return Option.some(CaretPosition$1(container, offset));
9348 } else {
9349 return Option.none();
9350 }
9351 };
9352 var alt = function (o1, o2) {
9353 return o1.isSome() ? o1 : o2;
9354 };
9355 var resolvePaths = function (dom, bookmark) {
9356 var rng = dom.createRng();
9357 if (setEndPoint(dom, true, bookmark, rng) && setEndPoint(dom, false, bookmark, rng)) {
9358 return Option.some(rng);
9359 } else {
9360 return Option.none();
9361 }
9362 };
9363 var resolveId = function (dom, bookmark) {
9364 var startPos = restoreEndPoint(dom, 'start', bookmark);
9365 var endPos = restoreEndPoint(dom, 'end', bookmark);
9366 return liftN([
9367 startPos,
9368 alt(endPos, startPos)
9369 ], function (spos, epos) {
9370 var rng = dom.createRng();
9371 rng.setStart(addBogus(dom, spos.container()), spos.offset());
9372 rng.setEnd(addBogus(dom, epos.container()), epos.offset());
9373 return rng;
9374 });
9375 };
9376 var resolveIndex$1 = function (dom, bookmark) {
9377 return Option.from(dom.select(bookmark.name)[bookmark.index]).map(function (elm) {
9378 var rng = dom.createRng();
9379 rng.selectNode(elm);
9380 return rng;
9381 });
9382 };
9383 var resolve$3 = function (selection, bookmark) {
9384 var dom = selection.dom;
9385 if (bookmark) {
9386 if (isPathBookmark(bookmark)) {
9387 return resolvePaths(dom, bookmark);
9388 } else if (isStringPathBookmark(bookmark)) {
9389 return Option.some(resolveCaretPositionBookmark(dom, bookmark));
9390 } else if (isIdBookmark(bookmark)) {
9391 return resolveId(dom, bookmark);
9392 } else if (isIndexBookmark(bookmark)) {
9393 return resolveIndex$1(dom, bookmark);
9394 } else if (isRangeBookmark(bookmark)) {
9395 return Option.some(bookmark.rng);
9396 }
9397 }
9398 return Option.none();
9399 };
9400 var ResolveBookmark = { resolve: resolve$3 };
9401
9402 var getBookmark$1 = function (selection, type, normalized) {
9403 return GetBookmark.getBookmark(selection, type, normalized);
9404 };
9405 var moveToBookmark = function (selection, bookmark) {
9406 ResolveBookmark.resolve(selection, bookmark).each(function (rng) {
9407 selection.setRng(rng);
9408 });
9409 };
9410 var isBookmarkNode$1 = function (node) {
9411 return NodeType.isElement(node) && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark';
9412 };
9413 var Bookmarks = {
9414 getBookmark: getBookmark$1,
9415 moveToBookmark: moveToBookmark,
9416 isBookmarkNode: isBookmarkNode$1
9417 };
9418
9419 var isInlineBlock = function (node) {
9420 return node && /^(IMG)$/.test(node.nodeName);
9421 };
9422 var moveStart = function (dom, selection, rng) {
9423 var offset = rng.startOffset;
9424 var container = rng.startContainer, walker, node, nodes;
9425 if (rng.startContainer === rng.endContainer) {
9426 if (isInlineBlock(rng.startContainer.childNodes[rng.startOffset])) {
9427 return;
9428 }
9429 }
9430 if (container.nodeType === 1) {
9431 nodes = container.childNodes;
9432 if (offset < nodes.length) {
9433 container = nodes[offset];
9434 walker = new TreeWalker(container, dom.getParent(container, dom.isBlock));
9435 } else {
9436 container = nodes[nodes.length - 1];
9437 walker = new TreeWalker(container, dom.getParent(container, dom.isBlock));
9438 walker.next(true);
9439 }
9440 for (node = walker.current(); node; node = walker.next()) {
9441 if (node.nodeType === 3 && !isWhiteSpaceNode(node)) {
9442 rng.setStart(node, 0);
9443 selection.setRng(rng);
9444 return;
9445 }
9446 }
9447 }
9448 };
9449 var getNonWhiteSpaceSibling = function (node, next, inc) {
9450 if (node) {
9451 next = next ? 'nextSibling' : 'previousSibling';
9452 for (node = inc ? node : node[next]; node; node = node[next]) {
9453 if (node.nodeType === 1 || !isWhiteSpaceNode(node)) {
9454 return node;
9455 }
9456 }
9457 }
9458 };
9459 var isTextBlock$1 = function (editor, name) {
9460 if (name.nodeType) {
9461 name = name.nodeName;
9462 }
9463 return !!editor.schema.getTextBlockElements()[name.toLowerCase()];
9464 };
9465 var isValid = function (ed, parent, child) {
9466 return ed.schema.isValidChild(parent, child);
9467 };
9468 var isWhiteSpaceNode = function (node) {
9469 return node && node.nodeType === 3 && /^([\t \r\n]+|)$/.test(node.nodeValue);
9470 };
9471 var replaceVars = function (value, vars) {
9472 if (typeof value !== 'string') {
9473 value = value(vars);
9474 } else if (vars) {
9475 value = value.replace(/%(\w+)/g, function (str, name) {
9476 return vars[name] || str;
9477 });
9478 }
9479 return value;
9480 };
9481 var isEq = function (str1, str2) {
9482 str1 = str1 || '';
9483 str2 = str2 || '';
9484 str1 = '' + (str1.nodeName || str1);
9485 str2 = '' + (str2.nodeName || str2);
9486 return str1.toLowerCase() === str2.toLowerCase();
9487 };
9488 var normalizeStyleValue = function (dom, value, name) {
9489 if (name === 'color' || name === 'backgroundColor') {
9490 value = dom.toHex(value);
9491 }
9492 if (name === 'fontWeight' && value === 700) {
9493 value = 'bold';
9494 }
9495 if (name === 'fontFamily') {
9496 value = value.replace(/[\'\"]/g, '').replace(/,\s+/g, ',');
9497 }
9498 return '' + value;
9499 };
9500 var getStyle = function (dom, node, name) {
9501 return normalizeStyleValue(dom, dom.getStyle(node, name), name);
9502 };
9503 var getTextDecoration = function (dom, node) {
9504 var decoration;
9505 dom.getParent(node, function (n) {
9506 decoration = dom.getStyle(n, 'text-decoration');
9507 return decoration && decoration !== 'none';
9508 });
9509 return decoration;
9510 };
9511 var getParents$1 = function (dom, node, selector) {
9512 return dom.getParents(node, selector, dom.getRoot());
9513 };
9514 var FormatUtils = {
9515 isInlineBlock: isInlineBlock,
9516 moveStart: moveStart,
9517 getNonWhiteSpaceSibling: getNonWhiteSpaceSibling,
9518 isTextBlock: isTextBlock$1,
9519 isValid: isValid,
9520 isWhiteSpaceNode: isWhiteSpaceNode,
9521 replaceVars: replaceVars,
9522 isEq: isEq,
9523 normalizeStyleValue: normalizeStyleValue,
9524 getStyle: getStyle,
9525 getTextDecoration: getTextDecoration,
9526 getParents: getParents$1
9527 };
9528
9529 var isBookmarkNode$2 = Bookmarks.isBookmarkNode;
9530 var getParents$2 = FormatUtils.getParents, isWhiteSpaceNode$1 = FormatUtils.isWhiteSpaceNode, isTextBlock$2 = FormatUtils.isTextBlock;
9531 var findLeaf = function (node, offset) {
9532 if (typeof offset === 'undefined') {
9533 offset = node.nodeType === 3 ? node.length : node.childNodes.length;
9534 }
9535 while (node && node.hasChildNodes()) {
9536 node = node.childNodes[offset];
9537 if (node) {
9538 offset = node.nodeType === 3 ? node.length : node.childNodes.length;
9539 }
9540 }
9541 return {
9542 node: node,
9543 offset: offset
9544 };
9545 };
9546 var excludeTrailingWhitespace = function (endContainer, endOffset) {
9547 var leaf = findLeaf(endContainer, endOffset);
9548 if (leaf.node) {
9549 while (leaf.node && leaf.offset === 0 && leaf.node.previousSibling) {
9550 leaf = findLeaf(leaf.node.previousSibling);
9551 }
9552 if (leaf.node && leaf.offset > 0 && leaf.node.nodeType === 3 && leaf.node.nodeValue.charAt(leaf.offset - 1) === ' ') {
9553 if (leaf.offset > 1) {
9554 endContainer = leaf.node;
9555 endContainer.splitText(leaf.offset - 1);
9556 }
9557 }
9558 }
9559 return endContainer;
9560 };
9561 var isBogusBr = function (node) {
9562 return node.nodeName === 'BR' && node.getAttribute('data-mce-bogus') && !node.nextSibling;
9563 };
9564 var findParentContentEditable = function (dom, node) {
9565 var parent = node;
9566 while (parent) {
9567 if (parent.nodeType === 1 && dom.getContentEditable(parent)) {
9568 return dom.getContentEditable(parent) === 'false' ? parent : node;
9569 }
9570 parent = parent.parentNode;
9571 }
9572 return node;
9573 };
9574 var findSpace = function (start, remove, node, offset) {
9575 var pos, pos2;
9576 var str = node.nodeValue;
9577 if (typeof offset === 'undefined') {
9578 offset = start ? str.length : 0;
9579 }
9580 if (start) {
9581 pos = str.lastIndexOf(' ', offset);
9582 pos2 = str.lastIndexOf('\xA0', offset);
9583 pos = pos > pos2 ? pos : pos2;
9584 if (pos !== -1 && !remove && (pos < offset || !start) && pos <= str.length) {
9585 pos++;
9586 }
9587 } else {
9588 pos = str.indexOf(' ', offset);
9589 pos2 = str.indexOf('\xA0', offset);
9590 pos = pos !== -1 && (pos2 === -1 || pos < pos2) ? pos : pos2;
9591 }
9592 return pos;
9593 };
9594 var findWordEndPoint = function (dom, body, container, offset, start, remove) {
9595 var node, pos, lastTextNode;
9596 if (container.nodeType === 3) {
9597 pos = findSpace(start, remove, container, offset);
9598 if (pos !== -1) {
9599 return {
9600 container: container,
9601 offset: pos
9602 };
9603 }
9604 lastTextNode = container;
9605 }
9606 var walker = new TreeWalker(container, dom.getParent(container, dom.isBlock) || body);
9607 while (node = walker[start ? 'prev' : 'next']()) {
9608 if (node.nodeType === 3 && !isBookmarkNode$2(node.parentNode)) {
9609 lastTextNode = node;
9610 pos = findSpace(start, remove, node);
9611 if (pos !== -1) {
9612 return {
9613 container: node,
9614 offset: pos
9615 };
9616 }
9617 } else if (dom.isBlock(node) || FormatUtils.isEq(node, 'BR')) {
9618 break;
9619 }
9620 }
9621 if (lastTextNode) {
9622 if (start) {
9623 offset = 0;
9624 } else {
9625 offset = lastTextNode.length;
9626 }
9627 return {
9628 container: lastTextNode,
9629 offset: offset
9630 };
9631 }
9632 };
9633 var findSelectorEndPoint = function (dom, format, rng, container, siblingName) {
9634 var parents, i, y, curFormat;
9635 if (container.nodeType === 3 && container.nodeValue.length === 0 && container[siblingName]) {
9636 container = container[siblingName];
9637 }
9638 parents = getParents$2(dom, container);
9639 for (i = 0; i < parents.length; i++) {
9640 for (y = 0; y < format.length; y++) {
9641 curFormat = format[y];
9642 if ('collapsed' in curFormat && curFormat.collapsed !== rng.collapsed) {
9643 continue;
9644 }
9645 if (dom.is(parents[i], curFormat.selector)) {
9646 return parents[i];
9647 }
9648 }
9649 }
9650 return container;
9651 };
9652 var findBlockEndPoint = function (editor, format, container, siblingName) {
9653 var node;
9654 var dom = editor.dom;
9655 var root = dom.getRoot();
9656 if (!format[0].wrapper) {
9657 node = dom.getParent(container, format[0].block, root);
9658 }
9659 if (!node) {
9660 var scopeRoot = dom.getParent(container, 'LI,TD,TH');
9661 node = dom.getParent(container.nodeType === 3 ? container.parentNode : container, function (node) {
9662 return node !== root && isTextBlock$2(editor, node);
9663 }, scopeRoot);
9664 }
9665 if (node && format[0].wrapper) {
9666 node = getParents$2(dom, node, 'ul,ol').reverse()[0] || node;
9667 }
9668 if (!node) {
9669 node = container;
9670 while (node[siblingName] && !dom.isBlock(node[siblingName])) {
9671 node = node[siblingName];
9672 if (FormatUtils.isEq(node, 'br')) {
9673 break;
9674 }
9675 }
9676 }
9677 return node || container;
9678 };
9679 var findParentContainer = function (dom, format, startContainer, startOffset, endContainer, endOffset, start) {
9680 var container, parent, sibling, siblingName, root;
9681 container = parent = start ? startContainer : endContainer;
9682 siblingName = start ? 'previousSibling' : 'nextSibling';
9683 root = dom.getRoot();
9684 if (container.nodeType === 3 && !isWhiteSpaceNode$1(container)) {
9685 if (start ? startOffset > 0 : endOffset < container.nodeValue.length) {
9686 return container;
9687 }
9688 }
9689 while (true) {
9690 if (!format[0].block_expand && dom.isBlock(parent)) {
9691 return parent;
9692 }
9693 for (sibling = parent[siblingName]; sibling; sibling = sibling[siblingName]) {
9694 if (!isBookmarkNode$2(sibling) && !isWhiteSpaceNode$1(sibling) && !isBogusBr(sibling)) {
9695 return parent;
9696 }
9697 }
9698 if (parent === root || parent.parentNode === root) {
9699 container = parent;
9700 break;
9701 }
9702 parent = parent.parentNode;
9703 }
9704 return container;
9705 };
9706 var expandRng = function (editor, rng, format, remove) {
9707 var endPoint, startContainer = rng.startContainer, startOffset = rng.startOffset, endContainer = rng.endContainer, endOffset = rng.endOffset;
9708 var dom = editor.dom;
9709 if (startContainer.nodeType === 1 && startContainer.hasChildNodes()) {
9710 startContainer = getNode(startContainer, startOffset);
9711 if (startContainer.nodeType === 3) {
9712 startOffset = 0;
9713 }
9714 }
9715 if (endContainer.nodeType === 1 && endContainer.hasChildNodes()) {
9716 endContainer = getNode(endContainer, rng.collapsed ? endOffset : endOffset - 1);
9717 if (endContainer.nodeType === 3) {
9718 endOffset = endContainer.nodeValue.length;
9719 }
9720 }
9721 startContainer = findParentContentEditable(dom, startContainer);
9722 endContainer = findParentContentEditable(dom, endContainer);
9723 if (isBookmarkNode$2(startContainer.parentNode) || isBookmarkNode$2(startContainer)) {
9724 startContainer = isBookmarkNode$2(startContainer) ? startContainer : startContainer.parentNode;
9725 if (rng.collapsed) {
9726 startContainer = startContainer.previousSibling || startContainer;
9727 } else {
9728 startContainer = startContainer.nextSibling || startContainer;
9729 }
9730 if (startContainer.nodeType === 3) {
9731 startOffset = rng.collapsed ? startContainer.length : 0;
9732 }
9733 }
9734 if (isBookmarkNode$2(endContainer.parentNode) || isBookmarkNode$2(endContainer)) {
9735 endContainer = isBookmarkNode$2(endContainer) ? endContainer : endContainer.parentNode;
9736 if (rng.collapsed) {
9737 endContainer = endContainer.nextSibling || endContainer;
9738 } else {
9739 endContainer = endContainer.previousSibling || endContainer;
9740 }
9741 if (endContainer.nodeType === 3) {
9742 endOffset = rng.collapsed ? 0 : endContainer.length;
9743 }
9744 }
9745 if (rng.collapsed) {
9746 endPoint = findWordEndPoint(dom, editor.getBody(), startContainer, startOffset, true, remove);
9747 if (endPoint) {
9748 startContainer = endPoint.container;
9749 startOffset = endPoint.offset;
9750 }
9751 endPoint = findWordEndPoint(dom, editor.getBody(), endContainer, endOffset, false, remove);
9752 if (endPoint) {
9753 endContainer = endPoint.container;
9754 endOffset = endPoint.offset;
9755 }
9756 }
9757 if (format[0].inline) {
9758 endContainer = remove ? endContainer : excludeTrailingWhitespace(endContainer, endOffset);
9759 }
9760 if (format[0].inline || format[0].block_expand) {
9761 if (!format[0].inline || (startContainer.nodeType !== 3 || startOffset === 0)) {
9762 startContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, true);
9763 }
9764 if (!format[0].inline || (endContainer.nodeType !== 3 || endOffset === endContainer.nodeValue.length)) {
9765 endContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, false);
9766 }
9767 }
9768 if (format[0].selector && format[0].expand !== false && !format[0].inline) {
9769 startContainer = findSelectorEndPoint(dom, format, rng, startContainer, 'previousSibling');
9770 endContainer = findSelectorEndPoint(dom, format, rng, endContainer, 'nextSibling');
9771 }
9772 if (format[0].block || format[0].selector) {
9773 startContainer = findBlockEndPoint(editor, format, startContainer, 'previousSibling');
9774 endContainer = findBlockEndPoint(editor, format, endContainer, 'nextSibling');
9775 if (format[0].block) {
9776 if (!dom.isBlock(startContainer)) {
9777 startContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, true);
9778 }
9779 if (!dom.isBlock(endContainer)) {
9780 endContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, false);
9781 }
9782 }
9783 }
9784 if (startContainer.nodeType === 1) {
9785 startOffset = dom.nodeIndex(startContainer);
9786 startContainer = startContainer.parentNode;
9787 }
9788 if (endContainer.nodeType === 1) {
9789 endOffset = dom.nodeIndex(endContainer) + 1;
9790 endContainer = endContainer.parentNode;
9791 }
9792 return {
9793 startContainer: startContainer,
9794 startOffset: startOffset,
9795 endContainer: endContainer,
9796 endOffset: endOffset
9797 };
9798 };
9799 var ExpandRange = { expandRng: expandRng };
9800
9801 var each$8 = Tools.each;
9802 var getEndChild = function (container, index) {
9803 var childNodes = container.childNodes;
9804 index--;
9805 if (index > childNodes.length - 1) {
9806 index = childNodes.length - 1;
9807 } else if (index < 0) {
9808 index = 0;
9809 }
9810 return childNodes[index] || container;
9811 };
9812 var walk$1 = function (dom, rng, callback) {
9813 var startContainer = rng.startContainer;
9814 var startOffset = rng.startOffset;
9815 var endContainer = rng.endContainer;
9816 var endOffset = rng.endOffset;
9817 var ancestor;
9818 var startPoint;
9819 var endPoint;
9820 var node;
9821 var parent;
9822 var siblings;
9823 var nodes;
9824 nodes = dom.select('td[data-mce-selected],th[data-mce-selected]');
9825 if (nodes.length > 0) {
9826 each$8(nodes, function (node) {
9827 callback([node]);
9828 });
9829 return;
9830 }
9831 var exclude = function (nodes) {
9832 var node;
9833 node = nodes[0];
9834 if (node.nodeType === 3 && node === startContainer && startOffset >= node.nodeValue.length) {
9835 nodes.splice(0, 1);
9836 }
9837 node = nodes[nodes.length - 1];
9838 if (endOffset === 0 && nodes.length > 0 && node === endContainer && node.nodeType === 3) {
9839 nodes.splice(nodes.length - 1, 1);
9840 }
9841 return nodes;
9842 };
9843 var collectSiblings = function (node, name, endNode) {
9844 var siblings = [];
9845 for (; node && node !== endNode; node = node[name]) {
9846 siblings.push(node);
9847 }
9848 return siblings;
9849 };
9850 var findEndPoint = function (node, root) {
9851 do {
9852 if (node.parentNode === root) {
9853 return node;
9854 }
9855 node = node.parentNode;
9856 } while (node);
9857 };
9858 var walkBoundary = function (startNode, endNode, next) {
9859 var siblingName = next ? 'nextSibling' : 'previousSibling';
9860 for (node = startNode, parent = node.parentNode; node && node !== endNode; node = parent) {
9861 parent = node.parentNode;
9862 siblings = collectSiblings(node === startNode ? node : node[siblingName], siblingName);
9863 if (siblings.length) {
9864 if (!next) {
9865 siblings.reverse();
9866 }
9867 callback(exclude(siblings));
9868 }
9869 }
9870 };
9871 if (startContainer.nodeType === 1 && startContainer.hasChildNodes()) {
9872 startContainer = startContainer.childNodes[startOffset];
9873 }
9874 if (endContainer.nodeType === 1 && endContainer.hasChildNodes()) {
9875 endContainer = getEndChild(endContainer, endOffset);
9876 }
9877 if (startContainer === endContainer) {
9878 return callback(exclude([startContainer]));
9879 }
9880 ancestor = dom.findCommonAncestor(startContainer, endContainer);
9881 for (node = startContainer; node; node = node.parentNode) {
9882 if (node === endContainer) {
9883 return walkBoundary(startContainer, ancestor, true);
9884 }
9885 if (node === ancestor) {
9886 break;
9887 }
9888 }
9889 for (node = endContainer; node; node = node.parentNode) {
9890 if (node === startContainer) {
9891 return walkBoundary(endContainer, ancestor);
9892 }
9893 if (node === ancestor) {
9894 break;
9895 }
9896 }
9897 startPoint = findEndPoint(startContainer, ancestor) || startContainer;
9898 endPoint = findEndPoint(endContainer, ancestor) || endContainer;
9899 walkBoundary(startContainer, startPoint, true);
9900 siblings = collectSiblings(startPoint === startContainer ? startPoint : startPoint.nextSibling, 'nextSibling', endPoint === endContainer ? endPoint.nextSibling : endPoint);
9901 if (siblings.length) {
9902 callback(exclude(siblings));
9903 }
9904 walkBoundary(endContainer, endPoint);
9905 };
9906 var RangeWalk = { walk: walk$1 };
9907
9908 var zeroWidth = function () {
9909 return '\uFEFF';
9910 };
9911
9912 function NodeValue (is, name) {
9913 var get = function (element) {
9914 if (!is(element)) {
9915 throw new Error('Can only get ' + name + ' value of a ' + name + ' node');
9916 }
9917 return getOption(element).getOr('');
9918 };
9919 var getOptionIE10 = function (element) {
9920 try {
9921 return getOptionSafe(element);
9922 } catch (e) {
9923 return Option.none();
9924 }
9925 };
9926 var getOptionSafe = function (element) {
9927 return is(element) ? Option.from(element.dom().nodeValue) : Option.none();
9928 };
9929 var browser = PlatformDetection$1.detect().browser;
9930 var getOption = browser.isIE() && browser.version.major === 10 ? getOptionIE10 : getOptionSafe;
9931 var set = function (element, value) {
9932 if (!is(element)) {
9933 throw new Error('Can only set raw ' + name + ' value of a ' + name + ' node');
9934 }
9935 element.dom().nodeValue = value;
9936 };
9937 return {
9938 get: get,
9939 getOption: getOption,
9940 set: set
9941 };
9942 }
9943
9944 var api = NodeValue(isText, 'text');
9945 var get$5 = function (element) {
9946 return api.get(element);
9947 };
9948
9949 var isZeroWidth = function (elem) {
9950 return isText(elem) && get$5(elem) === zeroWidth();
9951 };
9952 var context = function (editor, elem, wrapName, nodeName) {
9953 return parent(elem).fold(function () {
9954 return 'skipping';
9955 }, function (parent) {
9956 if (nodeName === 'br' || isZeroWidth(elem)) {
9957 return 'valid';
9958 } else if (isAnnotation(elem)) {
9959 return 'existing';
9960 } else if (isCaretNode(elem)) {
9961 return 'caret';
9962 } else if (!FormatUtils.isValid(editor, wrapName, nodeName) || !FormatUtils.isValid(editor, name(parent), wrapName)) {
9963 return 'invalid-child';
9964 } else {
9965 return 'valid';
9966 }
9967 });
9968 };
9969
9970 var shouldApplyToTrailingSpaces = function (rng) {
9971 return rng.startContainer.nodeType === 3 && rng.startContainer.nodeValue.length >= rng.startOffset && rng.startContainer.nodeValue[rng.startOffset] === '\xA0';
9972 };
9973 var applyWordGrab = function (editor, rng) {
9974 var r = ExpandRange.expandRng(editor, rng, [{ inline: true }], shouldApplyToTrailingSpaces(rng));
9975 rng.setStart(r.startContainer, r.startOffset);
9976 rng.setEnd(r.endContainer, r.endOffset);
9977 editor.selection.setRng(rng);
9978 };
9979 var makeAnnotation = function (eDoc, _a, annotationName, decorate) {
9980 var _b = _a.uid, uid = _b === void 0 ? generate('mce-annotation') : _b, data = __rest(_a, ['uid']);
9981 var master = Element.fromTag('span', eDoc);
9982 add$3(master, annotation());
9983 set(master, '' + dataAnnotationId(), uid);
9984 set(master, '' + dataAnnotation(), annotationName);
9985 var _c = decorate(uid, data), _d = _c.attributes, attributes = _d === void 0 ? {} : _d, _e = _c.classes, classes = _e === void 0 ? [] : _e;
9986 setAll(master, attributes);
9987 add$4(master, classes);
9988 return master;
9989 };
9990 var annotate = function (editor, rng, annotationName, decorate, data) {
9991 var newWrappers = [];
9992 var master = makeAnnotation(editor.getDoc(), data, annotationName, decorate);
9993 var wrapper = Cell(Option.none());
9994 var finishWrapper = function () {
9995 wrapper.set(Option.none());
9996 };
9997 var getOrOpenWrapper = function () {
9998 return wrapper.get().getOrThunk(function () {
9999 var nu = shallow(master);
10000 newWrappers.push(nu);
10001 wrapper.set(Option.some(nu));
10002 return nu;
10003 });
10004 };
10005 var processElements = function (elems) {
10006 each(elems, processElement);
10007 };
10008 var processElement = function (elem) {
10009 var ctx = context(editor, elem, 'span', name(elem));
10010 switch (ctx) {
10011 case 'invalid-child': {
10012 finishWrapper();
10013 var children$1 = children(elem);
10014 processElements(children$1);
10015 finishWrapper();
10016 break;
10017 }
10018 case 'valid': {
10019 var w = getOrOpenWrapper();
10020 wrap$1(elem, w);
10021 break;
10022 }
10023 case 'skipping':
10024 case 'existing':
10025 case 'caret':
10026 }
10027 };
10028 var processNodes = function (nodes) {
10029 var elems = map(nodes, Element.fromDom);
10030 processElements(elems);
10031 };
10032 RangeWalk.walk(editor.dom, rng, function (nodes) {
10033 finishWrapper();
10034 processNodes(nodes);
10035 });
10036 return newWrappers;
10037 };
10038 var annotateWithBookmark = function (editor, name, settings, data) {
10039 editor.undoManager.transact(function () {
10040 var initialRng = editor.selection.getRng();
10041 if (initialRng.collapsed) {
10042 applyWordGrab(editor, initialRng);
10043 }
10044 if (editor.selection.getRng().collapsed) {
10045 var wrapper = makeAnnotation(editor.getDoc(), data, name, settings.decorate);
10046 set$1(wrapper, '\xA0');
10047 editor.selection.getRng().insertNode(wrapper.dom());
10048 editor.selection.select(wrapper.dom());
10049 } else {
10050 var bookmark = GetBookmark.getPersistentBookmark(editor.selection, false);
10051 var rng = editor.selection.getRng();
10052 annotate(editor, rng, name, settings.decorate, data);
10053 editor.selection.moveToBookmark(bookmark);
10054 }
10055 });
10056 };
10057
10058 var Annotator = function (editor) {
10059 var registry = create$1();
10060 setup$1(editor, registry);
10061 var changes = setup(editor);
10062 return {
10063 register: function (name, settings) {
10064 registry.register(name, settings);
10065 },
10066 annotate: function (name, data) {
10067 registry.lookup(name).each(function (settings) {
10068 annotateWithBookmark(editor, name, settings, data);
10069 });
10070 },
10071 annotationChanged: function (name, callback) {
10072 changes.addListener(name, callback);
10073 },
10074 remove: function (name) {
10075 identify(editor, Option.some(name)).each(function (_a) {
10076 var elements = _a.elements;
10077 each(elements, unwrap);
10078 });
10079 },
10080 getAll: function (name) {
10081 var directory = findAll(editor, name);
10082 return map$2(directory, function (elems) {
10083 return map(elems, function (elem) {
10084 return elem.dom();
10085 });
10086 });
10087 }
10088 };
10089 };
10090
10091 var whiteSpaceRegExp$3 = /^[ \t\r\n]*$/;
10092 var typeLookup = {
10093 '#text': 3,
10094 '#comment': 8,
10095 '#cdata': 4,
10096 '#pi': 7,
10097 '#doctype': 10,
10098 '#document-fragment': 11
10099 };
10100 var walk$2 = function (node, root, prev) {
10101 var sibling;
10102 var parent;
10103 var startName = prev ? 'lastChild' : 'firstChild';
10104 var siblingName = prev ? 'prev' : 'next';
10105 if (node[startName]) {
10106 return node[startName];
10107 }
10108 if (node !== root) {
10109 sibling = node[siblingName];
10110 if (sibling) {
10111 return sibling;
10112 }
10113 for (parent = node.parent; parent && parent !== root; parent = parent.parent) {
10114 sibling = parent[siblingName];
10115 if (sibling) {
10116 return sibling;
10117 }
10118 }
10119 }
10120 };
10121 var Node$1 = function () {
10122 function Node(name, type) {
10123 this.name = name;
10124 this.type = type;
10125 if (type === 1) {
10126 this.attributes = [];
10127 this.attributes.map = {};
10128 }
10129 }
10130 Node.create = function (name, attrs) {
10131 var node, attrName;
10132 node = new Node(name, typeLookup[name] || 1);
10133 if (attrs) {
10134 for (attrName in attrs) {
10135 node.attr(attrName, attrs[attrName]);
10136 }
10137 }
10138 return node;
10139 };
10140 Node.prototype.replace = function (node) {
10141 var self = this;
10142 if (node.parent) {
10143 node.remove();
10144 }
10145 self.insert(node, self);
10146 self.remove();
10147 return self;
10148 };
10149 Node.prototype.attr = function (name, value) {
10150 var self = this;
10151 var attrs, i;
10152 if (typeof name !== 'string') {
10153 for (i in name) {
10154 self.attr(i, name[i]);
10155 }
10156 return self;
10157 }
10158 if (attrs = self.attributes) {
10159 if (value !== undefined) {
10160 if (value === null) {
10161 if (name in attrs.map) {
10162 delete attrs.map[name];
10163 i = attrs.length;
10164 while (i--) {
10165 if (attrs[i].name === name) {
10166 attrs = attrs.splice(i, 1);
10167 return self;
10168 }
10169 }
10170 }
10171 return self;
10172 }
10173 if (name in attrs.map) {
10174 i = attrs.length;
10175 while (i--) {
10176 if (attrs[i].name === name) {
10177 attrs[i].value = value;
10178 break;
10179 }
10180 }
10181 } else {
10182 attrs.push({
10183 name: name,
10184 value: value
10185 });
10186 }
10187 attrs.map[name] = value;
10188 return self;
10189 }
10190 return attrs.map[name];
10191 }
10192 };
10193 Node.prototype.clone = function () {
10194 var self = this;
10195 var clone = new Node(self.name, self.type);
10196 var i, l, selfAttrs, selfAttr, cloneAttrs;
10197 if (selfAttrs = self.attributes) {
10198 cloneAttrs = [];
10199 cloneAttrs.map = {};
10200 for (i = 0, l = selfAttrs.length; i < l; i++) {
10201 selfAttr = selfAttrs[i];
10202 if (selfAttr.name !== 'id') {
10203 cloneAttrs[cloneAttrs.length] = {
10204 name: selfAttr.name,
10205 value: selfAttr.value
10206 };
10207 cloneAttrs.map[selfAttr.name] = selfAttr.value;
10208 }
10209 }
10210 clone.attributes = cloneAttrs;
10211 }
10212 clone.value = self.value;
10213 clone.shortEnded = self.shortEnded;
10214 return clone;
10215 };
10216 Node.prototype.wrap = function (wrapper) {
10217 var self = this;
10218 self.parent.insert(wrapper, self);
10219 wrapper.append(self);
10220 return self;
10221 };
10222 Node.prototype.unwrap = function () {
10223 var self = this;
10224 var node, next;
10225 for (node = self.firstChild; node;) {
10226 next = node.next;
10227 self.insert(node, self, true);
10228 node = next;
10229 }
10230 self.remove();
10231 };
10232 Node.prototype.remove = function () {
10233 var self = this, parent = self.parent, next = self.next, prev = self.prev;
10234 if (parent) {
10235 if (parent.firstChild === self) {
10236 parent.firstChild = next;
10237 if (next) {
10238 next.prev = null;
10239 }
10240 } else {
10241 prev.next = next;
10242 }
10243 if (parent.lastChild === self) {
10244 parent.lastChild = prev;
10245 if (prev) {
10246 prev.next = null;
10247 }
10248 } else {
10249 next.prev = prev;
10250 }
10251 self.parent = self.next = self.prev = null;
10252 }
10253 return self;
10254 };
10255 Node.prototype.append = function (node) {
10256 var self = this;
10257 var last;
10258 if (node.parent) {
10259 node.remove();
10260 }
10261 last = self.lastChild;
10262 if (last) {
10263 last.next = node;
10264 node.prev = last;
10265 self.lastChild = node;
10266 } else {
10267 self.lastChild = self.firstChild = node;
10268 }
10269 node.parent = self;
10270 return node;
10271 };
10272 Node.prototype.insert = function (node, refNode, before) {
10273 var parent;
10274 if (node.parent) {
10275 node.remove();
10276 }
10277 parent = refNode.parent || this;
10278 if (before) {
10279 if (refNode === parent.firstChild) {
10280 parent.firstChild = node;
10281 } else {
10282 refNode.prev.next = node;
10283 }
10284 node.prev = refNode.prev;
10285 node.next = refNode;
10286 refNode.prev = node;
10287 } else {
10288 if (refNode === parent.lastChild) {
10289 parent.lastChild = node;
10290 } else {
10291 refNode.next.prev = node;
10292 }
10293 node.next = refNode.next;
10294 node.prev = refNode;
10295 refNode.next = node;
10296 }
10297 node.parent = parent;
10298 return node;
10299 };
10300 Node.prototype.getAll = function (name) {
10301 var self = this;
10302 var node;
10303 var collection = [];
10304 for (node = self.firstChild; node; node = walk$2(node, self)) {
10305 if (node.name === name) {
10306 collection.push(node);
10307 }
10308 }
10309 return collection;
10310 };
10311 Node.prototype.empty = function () {
10312 var self = this;
10313 var nodes, i, node;
10314 if (self.firstChild) {
10315 nodes = [];
10316 for (node = self.firstChild; node; node = walk$2(node, self)) {
10317 nodes.push(node);
10318 }
10319 i = nodes.length;
10320 while (i--) {
10321 node = nodes[i];
10322 node.parent = node.firstChild = node.lastChild = node.next = node.prev = null;
10323 }
10324 }
10325 self.firstChild = self.lastChild = null;
10326 return self;
10327 };
10328 Node.prototype.isEmpty = function (elements, whitespace, predicate) {
10329 var self = this;
10330 var node = self.firstChild, i, name;
10331 whitespace = whitespace || {};
10332 if (node) {
10333 do {
10334 if (node.type === 1) {
10335 if (node.attr('data-mce-bogus')) {
10336 continue;
10337 }
10338 if (elements[node.name]) {
10339 return false;
10340 }
10341 i = node.attributes.length;
10342 while (i--) {
10343 name = node.attributes[i].name;
10344 if (name === 'name' || name.indexOf('data-mce-bookmark') === 0) {
10345 return false;
10346 }
10347 }
10348 }
10349 if (node.type === 8) {
10350 return false;
10351 }
10352 if (node.type === 3 && !whiteSpaceRegExp$3.test(node.value)) {
10353 return false;
10354 }
10355 if (node.type === 3 && node.parent && whitespace[node.parent.name] && whiteSpaceRegExp$3.test(node.value)) {
10356 return false;
10357 }
10358 if (predicate && predicate(node)) {
10359 return false;
10360 }
10361 } while (node = walk$2(node, self));
10362 }
10363 return true;
10364 };
10365 Node.prototype.walk = function (prev) {
10366 return walk$2(this, null, prev);
10367 };
10368 return Node;
10369 }();
10370
10371 var isValidPrefixAttrName = function (name) {
10372 return name.indexOf('data-') === 0 || name.indexOf('aria-') === 0;
10373 };
10374 var trimComments = function (text) {
10375 return text.replace(/<!--|-->/g, '');
10376 };
10377 var isInvalidUri = function (settings, uri) {
10378 if (settings.allow_html_data_urls) {
10379 return false;
10380 } else if (/^data:image\//i.test(uri)) {
10381 return settings.allow_svg_data_urls === false && /^data:image\/svg\+xml/i.test(uri);
10382 } else {
10383 return /^data:/i.test(uri);
10384 }
10385 };
10386 var findEndTagIndex = function (schema, html, startIndex) {
10387 var count = 1, index, matches, tokenRegExp, shortEndedElements;
10388 shortEndedElements = schema.getShortEndedElements();
10389 tokenRegExp = /<([!?\/])?([A-Za-z0-9\-_\:\.]+)((?:\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\/|\s+)>/g;
10390 tokenRegExp.lastIndex = index = startIndex;
10391 while (matches = tokenRegExp.exec(html)) {
10392 index = tokenRegExp.lastIndex;
10393 if (matches[1] === '/') {
10394 count--;
10395 } else if (!matches[1]) {
10396 if (matches[2] in shortEndedElements) {
10397 continue;
10398 }
10399 count++;
10400 }
10401 if (count === 0) {
10402 break;
10403 }
10404 }
10405 return index;
10406 };
10407 var checkBogusAttribute = function (regExp, attrString) {
10408 var matches = regExp.exec(attrString);
10409 if (matches) {
10410 var name = matches[1];
10411 var value = matches[2];
10412 return typeof name === 'string' && name.toLowerCase() === 'data-mce-bogus' ? value : null;
10413 } else {
10414 return null;
10415 }
10416 };
10417 function SaxParser(settings, schema) {
10418 if (schema === void 0) {
10419 schema = Schema();
10420 }
10421 var noop = function () {
10422 };
10423 settings = settings || {};
10424 if (settings.fix_self_closing !== false) {
10425 settings.fix_self_closing = true;
10426 }
10427 var comment = settings.comment ? settings.comment : noop;
10428 var cdata = settings.cdata ? settings.cdata : noop;
10429 var text = settings.text ? settings.text : noop;
10430 var start = settings.start ? settings.start : noop;
10431 var end = settings.end ? settings.end : noop;
10432 var pi = settings.pi ? settings.pi : noop;
10433 var doctype = settings.doctype ? settings.doctype : noop;
10434 var parse = function (html) {
10435 var matches, index = 0, value, endRegExp;
10436 var stack = [];
10437 var attrList, i, textData, name;
10438 var isInternalElement, removeInternalElements, shortEndedElements, fillAttrsMap, isShortEnded;
10439 var validate, elementRule, isValidElement, attr, attribsValue, validAttributesMap, validAttributePatterns;
10440 var attributesRequired, attributesDefault, attributesForced, processHtml;
10441 var anyAttributesRequired, selfClosing, tokenRegExp, attrRegExp, specialElements, attrValue, idCount = 0;
10442 var decode = Entities.decode;
10443 var fixSelfClosing;
10444 var filteredUrlAttrs = Tools.makeMap('src,href,data,background,formaction,poster,xlink:href');
10445 var scriptUriRegExp = /((java|vb)script|mhtml):/i;
10446 var processEndTag = function (name) {
10447 var pos, i;
10448 pos = stack.length;
10449 while (pos--) {
10450 if (stack[pos].name === name) {
10451 break;
10452 }
10453 }
10454 if (pos >= 0) {
10455 for (i = stack.length - 1; i >= pos; i--) {
10456 name = stack[i];
10457 if (name.valid) {
10458 end(name.name);
10459 }
10460 }
10461 stack.length = pos;
10462 }
10463 };
10464 var parseAttribute = function (match, name, value, val2, val3) {
10465 var attrRule, i;
10466 var trimRegExp = /[\s\u0000-\u001F]+/g;
10467 name = name.toLowerCase();
10468 value = name in fillAttrsMap ? name : decode(value || val2 || val3 || '');
10469 if (validate && !isInternalElement && isValidPrefixAttrName(name) === false) {
10470 attrRule = validAttributesMap[name];
10471 if (!attrRule && validAttributePatterns) {
10472 i = validAttributePatterns.length;
10473 while (i--) {
10474 attrRule = validAttributePatterns[i];
10475 if (attrRule.pattern.test(name)) {
10476 break;
10477 }
10478 }
10479 if (i === -1) {
10480 attrRule = null;
10481 }
10482 }
10483 if (!attrRule) {
10484 return;
10485 }
10486 if (attrRule.validValues && !(value in attrRule.validValues)) {
10487 return;
10488 }
10489 }
10490 if (filteredUrlAttrs[name] && !settings.allow_script_urls) {
10491 var uri = value.replace(trimRegExp, '');
10492 try {
10493 uri = decodeURIComponent(uri);
10494 } catch (ex) {
10495 uri = unescape(uri);
10496 }
10497 if (scriptUriRegExp.test(uri)) {
10498 return;
10499 }
10500 if (isInvalidUri(settings, uri)) {
10501 return;
10502 }
10503 }
10504 if (isInternalElement && (name in filteredUrlAttrs || name.indexOf('on') === 0)) {
10505 return;
10506 }
10507 attrList.map[name] = value;
10508 attrList.push({
10509 name: name,
10510 value: value
10511 });
10512 };
10513 tokenRegExp = new RegExp('<(?:' + '(?:!--([\\w\\W]*?)-->)|' + '(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|' + '(?:!DOCTYPE([\\w\\W]*?)>)|' + '(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|' + '(?:\\/([A-Za-z][A-Za-z0-9\\-_\\:\\.]*)>)|' + '(?:([A-Za-z][A-Za-z0-9\\-_\\:\\.]*)((?:\\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\\/|\\s+)>)' + ')', 'g');
10514 attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:[^\"])*)\")|(?:\'((?:[^\'])*)\')|([^>\s]+)))?/g;
10515 shortEndedElements = schema.getShortEndedElements();
10516 selfClosing = settings.self_closing_elements || schema.getSelfClosingElements();
10517 fillAttrsMap = schema.getBoolAttrs();
10518 validate = settings.validate;
10519 removeInternalElements = settings.remove_internals;
10520 fixSelfClosing = settings.fix_self_closing;
10521 specialElements = schema.getSpecialElements();
10522 processHtml = html + '>';
10523 while (matches = tokenRegExp.exec(processHtml)) {
10524 if (index < matches.index) {
10525 text(decode(html.substr(index, matches.index - index)));
10526 }
10527 if (value = matches[6]) {
10528 value = value.toLowerCase();
10529 if (value.charAt(0) === ':') {
10530 value = value.substr(1);
10531 }
10532 processEndTag(value);
10533 } else if (value = matches[7]) {
10534 if (matches.index + matches[0].length > html.length) {
10535 text(decode(html.substr(matches.index)));
10536 index = matches.index + matches[0].length;
10537 continue;
10538 }
10539 value = value.toLowerCase();
10540 if (value.charAt(0) === ':') {
10541 value = value.substr(1);
10542 }
10543 isShortEnded = value in shortEndedElements;
10544 if (fixSelfClosing && selfClosing[value] && stack.length > 0 && stack[stack.length - 1].name === value) {
10545 processEndTag(value);
10546 }
10547 var bogusValue = checkBogusAttribute(attrRegExp, matches[8]);
10548 if (bogusValue !== null) {
10549 if (bogusValue === 'all') {
10550 index = findEndTagIndex(schema, html, tokenRegExp.lastIndex);
10551 tokenRegExp.lastIndex = index;
10552 continue;
10553 }
10554 isValidElement = false;
10555 }
10556 if (!validate || (elementRule = schema.getElementRule(value))) {
10557 isValidElement = true;
10558 if (validate) {
10559 validAttributesMap = elementRule.attributes;
10560 validAttributePatterns = elementRule.attributePatterns;
10561 }
10562 if (attribsValue = matches[8]) {
10563 isInternalElement = attribsValue.indexOf('data-mce-type') !== -1;
10564 if (isInternalElement && removeInternalElements) {
10565 isValidElement = false;
10566 }
10567 attrList = [];
10568 attrList.map = {};
10569 attribsValue.replace(attrRegExp, parseAttribute);
10570 } else {
10571 attrList = [];
10572 attrList.map = {};
10573 }
10574 if (validate && !isInternalElement) {
10575 attributesRequired = elementRule.attributesRequired;
10576 attributesDefault = elementRule.attributesDefault;
10577 attributesForced = elementRule.attributesForced;
10578 anyAttributesRequired = elementRule.removeEmptyAttrs;
10579 if (anyAttributesRequired && !attrList.length) {
10580 isValidElement = false;
10581 }
10582 if (attributesForced) {
10583 i = attributesForced.length;
10584 while (i--) {
10585 attr = attributesForced[i];
10586 name = attr.name;
10587 attrValue = attr.value;
10588 if (attrValue === '{$uid}') {
10589 attrValue = 'mce_' + idCount++;
10590 }
10591 attrList.map[name] = attrValue;
10592 attrList.push({
10593 name: name,
10594 value: attrValue
10595 });
10596 }
10597 }
10598 if (attributesDefault) {
10599 i = attributesDefault.length;
10600 while (i--) {
10601 attr = attributesDefault[i];
10602 name = attr.name;
10603 if (!(name in attrList.map)) {
10604 attrValue = attr.value;
10605 if (attrValue === '{$uid}') {
10606 attrValue = 'mce_' + idCount++;
10607 }
10608 attrList.map[name] = attrValue;
10609 attrList.push({
10610 name: name,
10611 value: attrValue
10612 });
10613 }
10614 }
10615 }
10616 if (attributesRequired) {
10617 i = attributesRequired.length;
10618 while (i--) {
10619 if (attributesRequired[i] in attrList.map) {
10620 break;
10621 }
10622 }
10623 if (i === -1) {
10624 isValidElement = false;
10625 }
10626 }
10627 if (attr = attrList.map['data-mce-bogus']) {
10628 if (attr === 'all') {
10629 index = findEndTagIndex(schema, html, tokenRegExp.lastIndex);
10630 tokenRegExp.lastIndex = index;
10631 continue;
10632 }
10633 isValidElement = false;
10634 }
10635 }
10636 if (isValidElement) {
10637 start(value, attrList, isShortEnded);
10638 }
10639 } else {
10640 isValidElement = false;
10641 }
10642 if (endRegExp = specialElements[value]) {
10643 endRegExp.lastIndex = index = matches.index + matches[0].length;
10644 if (matches = endRegExp.exec(html)) {
10645 if (isValidElement) {
10646 textData = html.substr(index, matches.index - index);
10647 }
10648 index = matches.index + matches[0].length;
10649 } else {
10650 textData = html.substr(index);
10651 index = html.length;
10652 }
10653 if (isValidElement) {
10654 if (textData.length > 0) {
10655 text(textData, true);
10656 }
10657 end(value);
10658 }
10659 tokenRegExp.lastIndex = index;
10660 continue;
10661 }
10662 if (!isShortEnded) {
10663 if (!attribsValue || attribsValue.indexOf('/') !== attribsValue.length - 1) {
10664 stack.push({
10665 name: value,
10666 valid: isValidElement
10667 });
10668 } else if (isValidElement) {
10669 end(value);
10670 }
10671 }
10672 } else if (value = matches[1]) {
10673 if (value.charAt(0) === '>') {
10674 value = ' ' + value;
10675 }
10676 if (!settings.allow_conditional_comments && value.substr(0, 3).toLowerCase() === '[if') {
10677 value = ' ' + value;
10678 }
10679 comment(value);
10680 } else if (value = matches[2]) {
10681 cdata(trimComments(value));
10682 } else if (value = matches[3]) {
10683 doctype(value);
10684 } else if (value = matches[4]) {
10685 pi(value, matches[5]);
10686 }
10687 index = matches.index + matches[0].length;
10688 }
10689 if (index < html.length) {
10690 text(decode(html.substr(index)));
10691 }
10692 for (i = stack.length - 1; i >= 0; i--) {
10693 value = stack[i];
10694 if (value.valid) {
10695 end(value.name);
10696 }
10697 }
10698 };
10699 return { parse: parse };
10700 }
10701 (function (SaxParser) {
10702 SaxParser.findEndTag = findEndTagIndex;
10703 }(SaxParser || (SaxParser = {})));
10704 var SaxParser$1 = SaxParser;
10705
10706 var trimHtml = function (tempAttrs, html) {
10707 var trimContentRegExp = new RegExp(['\\s?(' + tempAttrs.join('|') + ')="[^"]+"'].join('|'), 'gi');
10708 return html.replace(trimContentRegExp, '');
10709 };
10710 var trimInternal = function (serializer, html) {
10711 var content = html;
10712 var bogusAllRegExp = /<(\w+) [^>]*data-mce-bogus="all"[^>]*>/g;
10713 var endTagIndex, index, matchLength, matches, shortEndedElements;
10714 var schema = serializer.schema;
10715 content = trimHtml(serializer.getTempAttrs(), content);
10716 shortEndedElements = schema.getShortEndedElements();
10717 while (matches = bogusAllRegExp.exec(content)) {
10718 index = bogusAllRegExp.lastIndex;
10719 matchLength = matches[0].length;
10720 if (shortEndedElements[matches[1]]) {
10721 endTagIndex = index;
10722 } else {
10723 endTagIndex = SaxParser$1.findEndTag(schema, content, index);
10724 }
10725 content = content.substring(0, index - matchLength) + content.substring(endTagIndex);
10726 bogusAllRegExp.lastIndex = index - matchLength;
10727 }
10728 return Zwsp.trim(content);
10729 };
10730 var trimExternal = trimInternal;
10731 var TrimHtml = {
10732 trimExternal: trimExternal,
10733 trimInternal: trimInternal
10734 };
10735
10736 var getBodySetting = function (editor, name, defaultValue) {
10737 var value = editor.getParam(name, defaultValue);
10738 if (value.indexOf('=') !== -1) {
10739 var bodyObj = editor.getParam(name, '', 'hash');
10740 return bodyObj.hasOwnProperty(editor.id) ? bodyObj[editor.id] : defaultValue;
10741 } else {
10742 return value;
10743 }
10744 };
10745 var getIframeAttrs = function (editor) {
10746 return editor.getParam('iframe_attrs', {});
10747 };
10748 var getDocType = function (editor) {
10749 return editor.getParam('doctype', '<!DOCTYPE html>');
10750 };
10751 var getDocumentBaseUrl = function (editor) {
10752 return editor.getParam('document_base_url', '');
10753 };
10754 var getBodyId = function (editor) {
10755 return getBodySetting(editor, 'body_id', 'tinymce');
10756 };
10757 var getBodyClass = function (editor) {
10758 return getBodySetting(editor, 'body_class', '');
10759 };
10760 var getContentSecurityPolicy = function (editor) {
10761 return editor.getParam('content_security_policy', '');
10762 };
10763 var shouldPutBrInPre = function (editor) {
10764 return editor.getParam('br_in_pre', true);
10765 };
10766 var getForcedRootBlock = function (editor) {
10767 if (editor.getParam('force_p_newlines', false)) {
10768 return 'p';
10769 }
10770 var block = editor.getParam('forced_root_block', 'p');
10771 if (block === false) {
10772 return '';
10773 } else if (block === true) {
10774 return 'p';
10775 } else {
10776 return block;
10777 }
10778 };
10779 var getForcedRootBlockAttrs = function (editor) {
10780 return editor.getParam('forced_root_block_attrs', {});
10781 };
10782 var getBrNewLineSelector = function (editor) {
10783 return editor.getParam('br_newline_selector', '.mce-toc h2,figcaption,caption');
10784 };
10785 var getNoNewLineSelector = function (editor) {
10786 return editor.getParam('no_newline_selector', '');
10787 };
10788 var shouldKeepStyles = function (editor) {
10789 return editor.getParam('keep_styles', true);
10790 };
10791 var shouldEndContainerOnEmptyBlock = function (editor) {
10792 return editor.getParam('end_container_on_empty_block', false);
10793 };
10794 var getFontStyleValues = function (editor) {
10795 return Tools.explode(editor.getParam('font_size_style_values', 'xx-small,x-small,small,medium,large,x-large,xx-large'));
10796 };
10797 var getFontSizeClasses = function (editor) {
10798 return Tools.explode(editor.getParam('font_size_classes', ''));
10799 };
10800 var getImagesDataImgFilter = function (editor) {
10801 return editor.getParam('images_dataimg_filter', constant(true), 'function');
10802 };
10803 var isAutomaticUploadsEnabled = function (editor) {
10804 return editor.getParam('automatic_uploads', true, 'boolean');
10805 };
10806 var shouldReuseFileName = function (editor) {
10807 return editor.getParam('images_reuse_filename', false, 'boolean');
10808 };
10809 var shouldReplaceBlobUris = function (editor) {
10810 return editor.getParam('images_replace_blob_uris', true, 'boolean');
10811 };
10812 var getIconPackName = function (editor) {
10813 return editor.getParam('icons', '', 'string');
10814 };
10815 var getIconsUrl = function (editor) {
10816 return editor.getParam('icons_url', '', 'string');
10817 };
10818 var getImageUploadUrl = function (editor) {
10819 return editor.getParam('images_upload_url', '', 'string');
10820 };
10821 var getImageUploadBasePath = function (editor) {
10822 return editor.getParam('images_upload_base_path', '', 'string');
10823 };
10824 var getImagesUploadCredentials = function (editor) {
10825 return editor.getParam('images_upload_credentials', false, 'boolean');
10826 };
10827 var getImagesUploadHandler = function (editor) {
10828 return editor.getParam('images_upload_handler', null, 'function');
10829 };
10830 var shouldUseContentCssCors = function (editor) {
10831 return editor.getParam('content_css_cors', false, 'boolean');
10832 };
10833 var getLanguageCode = function (editor) {
10834 return editor.getParam('language', 'en', 'string');
10835 };
10836 var getLanguageUrl = function (editor) {
10837 return editor.getParam('language_url', '', 'string');
10838 };
10839 var shouldIndentUseMargin = function (editor) {
10840 return editor.getParam('indent_use_margin', false);
10841 };
10842 var getIndentation = function (editor) {
10843 return editor.getParam('indentation', '40px', 'string');
10844 };
10845 var getContentCss = function (editor) {
10846 var contentCss = editor.settings.content_css;
10847 if (isString(contentCss)) {
10848 return map(contentCss.split(','), trim$2);
10849 } else if (isArray(contentCss)) {
10850 return contentCss;
10851 } else if (contentCss === false || editor.inline) {
10852 return [];
10853 } else {
10854 return ['default'];
10855 }
10856 };
10857 var getDirectionality = function (editor) {
10858 return editor.getParam('directionality', I18n.isRtl() ? 'rtl' : undefined);
10859 };
10860 var getInlineBoundarySelector = function (editor) {
10861 return editor.getParam('inline_boundaries_selector', 'a[href],code,.mce-annotation', 'string');
10862 };
10863 var Settings = {
10864 getIframeAttrs: getIframeAttrs,
10865 getDocType: getDocType,
10866 getDocumentBaseUrl: getDocumentBaseUrl,
10867 getBodyId: getBodyId,
10868 getBodyClass: getBodyClass,
10869 getContentSecurityPolicy: getContentSecurityPolicy,
10870 shouldPutBrInPre: shouldPutBrInPre,
10871 getForcedRootBlock: getForcedRootBlock,
10872 getForcedRootBlockAttrs: getForcedRootBlockAttrs,
10873 getBrNewLineSelector: getBrNewLineSelector,
10874 getNoNewLineSelector: getNoNewLineSelector,
10875 shouldKeepStyles: shouldKeepStyles,
10876 shouldEndContainerOnEmptyBlock: shouldEndContainerOnEmptyBlock,
10877 getFontStyleValues: getFontStyleValues,
10878 getFontSizeClasses: getFontSizeClasses,
10879 getIconPackName: getIconPackName,
10880 getIconsUrl: getIconsUrl,
10881 getImagesDataImgFilter: getImagesDataImgFilter,
10882 isAutomaticUploadsEnabled: isAutomaticUploadsEnabled,
10883 shouldReuseFileName: shouldReuseFileName,
10884 shouldReplaceBlobUris: shouldReplaceBlobUris,
10885 getImageUploadUrl: getImageUploadUrl,
10886 getImageUploadBasePath: getImageUploadBasePath,
10887 getImagesUploadCredentials: getImagesUploadCredentials,
10888 getImagesUploadHandler: getImagesUploadHandler,
10889 shouldUseContentCssCors: shouldUseContentCssCors,
10890 getLanguageCode: getLanguageCode,
10891 getLanguageUrl: getLanguageUrl,
10892 shouldIndentUseMargin: shouldIndentUseMargin,
10893 getIndentation: getIndentation,
10894 getContentCss: getContentCss,
10895 getDirectionality: getDirectionality,
10896 getInlineBoundarySelector: getInlineBoundarySelector
10897 };
10898
10899 var defaultFormat = 'html';
10900 var trimEmptyContents = function (editor, html) {
10901 var blockName = Settings.getForcedRootBlock(editor);
10902 var emptyRegExp = new RegExp('^(<' + blockName + '[^>]*>(&nbsp;|&#160;|\\s|\xA0|<br \\/>|)<\\/' + blockName + '>[\r\n]*|<br \\/>[\r\n]*)$');
10903 return html.replace(emptyRegExp, '');
10904 };
10905 var getContentFromBody = function (editor, args, body) {
10906 var content;
10907 args.format = args.format ? args.format : defaultFormat;
10908 args.get = true;
10909 args.getInner = true;
10910 if (!args.no_events) {
10911 editor.fire('BeforeGetContent', args);
10912 }
10913 if (args.format === 'raw') {
10914 content = Tools.trim(TrimHtml.trimExternal(editor.serializer, body.innerHTML));
10915 } else if (args.format === 'text') {
10916 content = Zwsp.trim(body.innerText || body.textContent);
10917 } else if (args.format === 'tree') {
10918 return editor.serializer.serialize(body, args);
10919 } else {
10920 content = trimEmptyContents(editor, editor.serializer.serialize(body, args));
10921 }
10922 if (args.format !== 'text' && !isWsPreserveElement(Element.fromDom(body))) {
10923 args.content = Tools.trim(content);
10924 } else {
10925 args.content = content;
10926 }
10927 if (!args.no_events) {
10928 editor.fire('GetContent', args);
10929 }
10930 return args.content;
10931 };
10932 var getContent = function (editor, args) {
10933 if (args === void 0) {
10934 args = {};
10935 }
10936 return Option.from(editor.getBody()).fold(constant(args.format === 'tree' ? new Node$1('body', 11) : ''), function (body) {
10937 return getContentFromBody(editor, args, body);
10938 });
10939 };
10940
10941 var makeMap$3 = Tools.makeMap;
10942 var Writer = function (settings) {
10943 var html = [];
10944 var indent, indentBefore, indentAfter, encode, htmlOutput;
10945 settings = settings || {};
10946 indent = settings.indent;
10947 indentBefore = makeMap$3(settings.indent_before || '');
10948 indentAfter = makeMap$3(settings.indent_after || '');
10949 encode = Entities.getEncodeFunc(settings.entity_encoding || 'raw', settings.entities);
10950 htmlOutput = settings.element_format === 'html';
10951 return {
10952 start: function (name, attrs, empty) {
10953 var i, l, attr, value;
10954 if (indent && indentBefore[name] && html.length > 0) {
10955 value = html[html.length - 1];
10956 if (value.length > 0 && value !== '\n') {
10957 html.push('\n');
10958 }
10959 }
10960 html.push('<', name);
10961 if (attrs) {
10962 for (i = 0, l = attrs.length; i < l; i++) {
10963 attr = attrs[i];
10964 html.push(' ', attr.name, '="', encode(attr.value, true), '"');
10965 }
10966 }
10967 if (!empty || htmlOutput) {
10968 html[html.length] = '>';
10969 } else {
10970 html[html.length] = ' />';
10971 }
10972 if (empty && indent && indentAfter[name] && html.length > 0) {
10973 value = html[html.length - 1];
10974 if (value.length > 0 && value !== '\n') {
10975 html.push('\n');
10976 }
10977 }
10978 },
10979 end: function (name) {
10980 var value;
10981 html.push('</', name, '>');
10982 if (indent && indentAfter[name] && html.length > 0) {
10983 value = html[html.length - 1];
10984 if (value.length > 0 && value !== '\n') {
10985 html.push('\n');
10986 }
10987 }
10988 },
10989 text: function (text, raw) {
10990 if (text.length > 0) {
10991 html[html.length] = raw ? text : encode(text);
10992 }
10993 },
10994 cdata: function (text) {
10995 html.push('<![CDATA[', text, ']]>');
10996 },
10997 comment: function (text) {
10998 html.push('<!--', text, '-->');
10999 },
11000 pi: function (name, text) {
11001 if (text) {
11002 html.push('<?', name, ' ', encode(text), '?>');
11003 } else {
11004 html.push('<?', name, '?>');
11005 }
11006 if (indent) {
11007 html.push('\n');
11008 }
11009 },
11010 doctype: function (text) {
11011 html.push('<!DOCTYPE', text, '>', indent ? '\n' : '');
11012 },
11013 reset: function () {
11014 html.length = 0;
11015 },
11016 getContent: function () {
11017 return html.join('').replace(/\n$/, '');
11018 }
11019 };
11020 };
11021
11022 var Serializer = function (settings, schema) {
11023 if (schema === void 0) {
11024 schema = Schema();
11025 }
11026 var writer = Writer(settings);
11027 settings = settings || {};
11028 settings.validate = 'validate' in settings ? settings.validate : true;
11029 var serialize = function (node) {
11030 var handlers, validate;
11031 validate = settings.validate;
11032 handlers = {
11033 3: function (node) {
11034 writer.text(node.value, node.raw);
11035 },
11036 8: function (node) {
11037 writer.comment(node.value);
11038 },
11039 7: function (node) {
11040 writer.pi(node.name, node.value);
11041 },
11042 10: function (node) {
11043 writer.doctype(node.value);
11044 },
11045 4: function (node) {
11046 writer.cdata(node.value);
11047 },
11048 11: function (node) {
11049 if (node = node.firstChild) {
11050 do {
11051 walk(node);
11052 } while (node = node.next);
11053 }
11054 }
11055 };
11056 writer.reset();
11057 var walk = function (node) {
11058 var handler = handlers[node.type];
11059 var name, isEmpty, attrs, attrName, attrValue, sortedAttrs, i, l, elementRule;
11060 if (!handler) {
11061 name = node.name;
11062 isEmpty = node.shortEnded;
11063 attrs = node.attributes;
11064 if (validate && attrs && attrs.length > 1) {
11065 sortedAttrs = [];
11066 sortedAttrs.map = {};
11067 elementRule = schema.getElementRule(node.name);
11068 if (elementRule) {
11069 for (i = 0, l = elementRule.attributesOrder.length; i < l; i++) {
11070 attrName = elementRule.attributesOrder[i];
11071 if (attrName in attrs.map) {
11072 attrValue = attrs.map[attrName];
11073 sortedAttrs.map[attrName] = attrValue;
11074 sortedAttrs.push({
11075 name: attrName,
11076 value: attrValue
11077 });
11078 }
11079 }
11080 for (i = 0, l = attrs.length; i < l; i++) {
11081 attrName = attrs[i].name;
11082 if (!(attrName in sortedAttrs.map)) {
11083 attrValue = attrs.map[attrName];
11084 sortedAttrs.map[attrName] = attrValue;
11085 sortedAttrs.push({
11086 name: attrName,
11087 value: attrValue
11088 });
11089 }
11090 }
11091 attrs = sortedAttrs;
11092 }
11093 }
11094 writer.start(node.name, attrs, isEmpty);
11095 if (!isEmpty) {
11096 if (node = node.firstChild) {
11097 do {
11098 walk(node);
11099 } while (node = node.next);
11100 }
11101 writer.end(name);
11102 }
11103 } else {
11104 handler(node);
11105 }
11106 };
11107 if (node.type === 1 && !settings.inner) {
11108 walk(node);
11109 } else {
11110 handlers[11](node);
11111 }
11112 return writer.getContent();
11113 };
11114 return { serialize: serialize };
11115 };
11116
11117 var traverse = function (node, fn) {
11118 fn(node);
11119 if (node.firstChild) {
11120 traverse(node.firstChild, fn);
11121 }
11122 if (node.next) {
11123 traverse(node.next, fn);
11124 }
11125 };
11126 var findMatchingNodes = function (nodeFilters, attributeFilters, node) {
11127 var nodeMatches = {};
11128 var attrMatches = {};
11129 var matches = [];
11130 if (node.firstChild) {
11131 traverse(node.firstChild, function (node) {
11132 each(nodeFilters, function (filter) {
11133 if (filter.name === node.name) {
11134 if (nodeMatches[filter.name]) {
11135 nodeMatches[filter.name].nodes.push(node);
11136 } else {
11137 nodeMatches[filter.name] = {
11138 filter: filter,
11139 nodes: [node]
11140 };
11141 }
11142 }
11143 });
11144 each(attributeFilters, function (filter) {
11145 if (typeof node.attr(filter.name) === 'string') {
11146 if (attrMatches[filter.name]) {
11147 attrMatches[filter.name].nodes.push(node);
11148 } else {
11149 attrMatches[filter.name] = {
11150 filter: filter,
11151 nodes: [node]
11152 };
11153 }
11154 }
11155 });
11156 });
11157 }
11158 for (var name in nodeMatches) {
11159 if (nodeMatches.hasOwnProperty(name)) {
11160 matches.push(nodeMatches[name]);
11161 }
11162 }
11163 for (var name in attrMatches) {
11164 if (attrMatches.hasOwnProperty(name)) {
11165 matches.push(attrMatches[name]);
11166 }
11167 }
11168 return matches;
11169 };
11170 var filter$2 = function (nodeFilters, attributeFilters, node) {
11171 var matches = findMatchingNodes(nodeFilters, attributeFilters, node);
11172 each(matches, function (match) {
11173 each(match.filter.callbacks, function (callback) {
11174 callback(match.nodes, match.filter.name, {});
11175 });
11176 });
11177 };
11178
11179 var hasFocus = function (element) {
11180 var doc = owner(element).dom();
11181 return element.dom() === doc.activeElement;
11182 };
11183 var active = function (_DOC) {
11184 var doc = _DOC !== undefined ? _DOC.dom() : domGlobals.document;
11185 return Option.from(doc.activeElement).map(Element.fromDom);
11186 };
11187 var search = function (element) {
11188 return active(owner(element)).filter(function (e) {
11189 return element.dom().contains(e.dom());
11190 });
11191 };
11192
11193 var generate$1 = function (cases) {
11194 if (!isArray(cases)) {
11195 throw new Error('cases must be an array');
11196 }
11197 if (cases.length === 0) {
11198 throw new Error('there must be at least one case');
11199 }
11200 var constructors = [];
11201 var adt = {};
11202 each(cases, function (acase, count) {
11203 var keys$1 = keys(acase);
11204 if (keys$1.length !== 1) {
11205 throw new Error('one and only one name per case');
11206 }
11207 var key = keys$1[0];
11208 var value = acase[key];
11209 if (adt[key] !== undefined) {
11210 throw new Error('duplicate key detected:' + key);
11211 } else if (key === 'cata') {
11212 throw new Error('cannot have a case named cata (sorry)');
11213 } else if (!isArray(value)) {
11214 throw new Error('case arguments must be an array');
11215 }
11216 constructors.push(key);
11217 adt[key] = function () {
11218 var argLength = arguments.length;
11219 if (argLength !== value.length) {
11220 throw new Error('Wrong number of arguments to case ' + key + '. Expected ' + value.length + ' (' + value + '), got ' + argLength);
11221 }
11222 var args = new Array(argLength);
11223 for (var i = 0; i < args.length; i++) {
11224 args[i] = arguments[i];
11225 }
11226 var match = function (branches) {
11227 var branchKeys = keys(branches);
11228 if (constructors.length !== branchKeys.length) {
11229 throw new Error('Wrong number of arguments to match. Expected: ' + constructors.join(',') + '\nActual: ' + branchKeys.join(','));
11230 }
11231 var allReqd = forall(constructors, function (reqKey) {
11232 return contains(branchKeys, reqKey);
11233 });
11234 if (!allReqd) {
11235 throw new Error('Not all branches were specified when using match. Specified: ' + branchKeys.join(', ') + '\nRequired: ' + constructors.join(', '));
11236 }
11237 return branches[key].apply(null, args);
11238 };
11239 return {
11240 fold: function () {
11241 if (arguments.length !== cases.length) {
11242 throw new Error('Wrong number of arguments to fold. Expected ' + cases.length + ', got ' + arguments.length);
11243 }
11244 var target = arguments[count];
11245 return target.apply(null, args);
11246 },
11247 match: match,
11248 log: function (label) {
11249 domGlobals.console.log(label, {
11250 constructors: constructors,
11251 constructor: key,
11252 params: args
11253 });
11254 }
11255 };
11256 };
11257 });
11258 return adt;
11259 };
11260 var Adt = { generate: generate$1 };
11261
11262 var create$3 = Immutable('start', 'soffset', 'finish', 'foffset');
11263 var SimRange = { create: create$3 };
11264
11265 var adt = Adt.generate([
11266 { before: ['element'] },
11267 {
11268 on: [
11269 'element',
11270 'offset'
11271 ]
11272 },
11273 { after: ['element'] }
11274 ]);
11275 var cata = function (subject, onBefore, onOn, onAfter) {
11276 return subject.fold(onBefore, onOn, onAfter);
11277 };
11278 var getStart = function (situ) {
11279 return situ.fold(identity, identity, identity);
11280 };
11281 var before$3 = adt.before;
11282 var on = adt.on;
11283 var after$2 = adt.after;
11284 var Situ = {
11285 before: before$3,
11286 on: on,
11287 after: after$2,
11288 cata: cata,
11289 getStart: getStart
11290 };
11291
11292 var adt$1 = Adt.generate([
11293 { domRange: ['rng'] },
11294 {
11295 relative: [
11296 'startSitu',
11297 'finishSitu'
11298 ]
11299 },
11300 {
11301 exact: [
11302 'start',
11303 'soffset',
11304 'finish',
11305 'foffset'
11306 ]
11307 }
11308 ]);
11309 var exactFromRange = function (simRange) {
11310 return adt$1.exact(simRange.start(), simRange.soffset(), simRange.finish(), simRange.foffset());
11311 };
11312 var getStart$1 = function (selection) {
11313 return selection.match({
11314 domRange: function (rng) {
11315 return Element.fromDom(rng.startContainer);
11316 },
11317 relative: function (startSitu, finishSitu) {
11318 return Situ.getStart(startSitu);
11319 },
11320 exact: function (start, soffset, finish, foffset) {
11321 return start;
11322 }
11323 });
11324 };
11325 var domRange = adt$1.domRange;
11326 var relative = adt$1.relative;
11327 var exact = adt$1.exact;
11328 var getWin = function (selection) {
11329 var start = getStart$1(selection);
11330 return defaultView(start);
11331 };
11332 var range = SimRange.create;
11333 var Selection = {
11334 domRange: domRange,
11335 relative: relative,
11336 exact: exact,
11337 exactFromRange: exactFromRange,
11338 getWin: getWin,
11339 range: range
11340 };
11341
11342 var browser$3 = PlatformDetection$1.detect().browser;
11343 var clamp = function (offset, element) {
11344 var max = isText(element) ? get$5(element).length : children(element).length + 1;
11345 if (offset > max) {
11346 return max;
11347 } else if (offset < 0) {
11348 return 0;
11349 }
11350 return offset;
11351 };
11352 var normalizeRng = function (rng) {
11353 return Selection.range(rng.start(), clamp(rng.soffset(), rng.start()), rng.finish(), clamp(rng.foffset(), rng.finish()));
11354 };
11355 var isOrContains = function (root, elm) {
11356 return !NodeType.isRestrictedNode(elm.dom()) && (contains$3(root, elm) || eq(root, elm));
11357 };
11358 var isRngInRoot = function (root) {
11359 return function (rng) {
11360 return isOrContains(root, rng.start()) && isOrContains(root, rng.finish());
11361 };
11362 };
11363 var shouldStore = function (editor) {
11364 return editor.inline === true || browser$3.isIE();
11365 };
11366 var nativeRangeToSelectionRange = function (r) {
11367 return Selection.range(Element.fromDom(r.startContainer), r.startOffset, Element.fromDom(r.endContainer), r.endOffset);
11368 };
11369 var readRange = function (win) {
11370 var selection = win.getSelection();
11371 var rng = !selection || selection.rangeCount === 0 ? Option.none() : Option.from(selection.getRangeAt(0));
11372 return rng.map(nativeRangeToSelectionRange);
11373 };
11374 var getBookmark$2 = function (root) {
11375 var win = defaultView(root);
11376 return readRange(win.dom()).filter(isRngInRoot(root));
11377 };
11378 var validate = function (root, bookmark) {
11379 return Option.from(bookmark).filter(isRngInRoot(root)).map(normalizeRng);
11380 };
11381 var bookmarkToNativeRng = function (bookmark) {
11382 var rng = domGlobals.document.createRange();
11383 try {
11384 rng.setStart(bookmark.start().dom(), bookmark.soffset());
11385 rng.setEnd(bookmark.finish().dom(), bookmark.foffset());
11386 return Option.some(rng);
11387 } catch (_) {
11388 return Option.none();
11389 }
11390 };
11391 var store = function (editor) {
11392 var newBookmark = shouldStore(editor) ? getBookmark$2(Element.fromDom(editor.getBody())) : Option.none();
11393 editor.bookmark = newBookmark.isSome() ? newBookmark : editor.bookmark;
11394 };
11395 var storeNative = function (editor, rng) {
11396 var root = Element.fromDom(editor.getBody());
11397 var range = shouldStore(editor) ? Option.from(rng) : Option.none();
11398 var newBookmark = range.map(nativeRangeToSelectionRange).filter(isRngInRoot(root));
11399 editor.bookmark = newBookmark.isSome() ? newBookmark : editor.bookmark;
11400 };
11401 var getRng = function (editor) {
11402 var bookmark = editor.bookmark ? editor.bookmark : Option.none();
11403 return bookmark.bind(curry(validate, Element.fromDom(editor.getBody()))).bind(bookmarkToNativeRng);
11404 };
11405 var restore = function (editor) {
11406 getRng(editor).each(function (rng) {
11407 editor.selection.setRng(rng);
11408 });
11409 };
11410 var SelectionBookmark = {
11411 store: store,
11412 storeNative: storeNative,
11413 readRange: readRange,
11414 restore: restore,
11415 getRng: getRng,
11416 getBookmark: getBookmark$2,
11417 validate: validate
11418 };
11419
11420 var isEditorUIElement = function (elm) {
11421 return elm.className.toString().indexOf('tox-') !== -1 || elm.className.toString().indexOf('mce-') !== -1;
11422 };
11423 var FocusManager = { isEditorUIElement: isEditorUIElement };
11424
11425 var isManualNodeChange = function (e) {
11426 return e.type === 'nodechange' && e.selectionChange;
11427 };
11428 var registerPageMouseUp = function (editor, throttledStore) {
11429 var mouseUpPage = function () {
11430 throttledStore.throttle();
11431 };
11432 DOMUtils$1.DOM.bind(domGlobals.document, 'mouseup', mouseUpPage);
11433 editor.on('remove', function () {
11434 DOMUtils$1.DOM.unbind(domGlobals.document, 'mouseup', mouseUpPage);
11435 });
11436 };
11437 var registerFocusOut = function (editor) {
11438 editor.on('focusout', function () {
11439 SelectionBookmark.store(editor);
11440 });
11441 };
11442 var registerMouseUp = function (editor, throttledStore) {
11443 editor.on('mouseup touchend', function (e) {
11444 throttledStore.throttle();
11445 });
11446 };
11447 var registerEditorEvents = function (editor, throttledStore) {
11448 var browser = PlatformDetection$1.detect().browser;
11449 if (browser.isIE()) {
11450 registerFocusOut(editor);
11451 } else {
11452 registerMouseUp(editor, throttledStore);
11453 }
11454 editor.on('keyup NodeChange', function (e) {
11455 if (!isManualNodeChange(e)) {
11456 SelectionBookmark.store(editor);
11457 }
11458 });
11459 };
11460 var register = function (editor) {
11461 var throttledStore = first(function () {
11462 SelectionBookmark.store(editor);
11463 }, 0);
11464 if (editor.inline) {
11465 registerPageMouseUp(editor, throttledStore);
11466 }
11467 editor.on('init', function () {
11468 registerEditorEvents(editor, throttledStore);
11469 });
11470 editor.on('remove', function () {
11471 throttledStore.cancel();
11472 });
11473 };
11474 var SelectionRestore = { register: register };
11475
11476 var documentFocusInHandler;
11477 var DOM$1 = DOMUtils$1.DOM;
11478 var isEditorUIElement$1 = function (elm) {
11479 return FocusManager.isEditorUIElement(elm);
11480 };
11481 var isUIElement = function (editor, elm) {
11482 var customSelector = editor ? editor.settings.custom_ui_selector : '';
11483 var parent = DOM$1.getParent(elm, function (elm) {
11484 return isEditorUIElement$1(elm) || (customSelector ? editor.dom.is(elm, customSelector) : false);
11485 });
11486 return parent !== null;
11487 };
11488 var getActiveElement = function () {
11489 try {
11490 return domGlobals.document.activeElement;
11491 } catch (ex) {
11492 return domGlobals.document.body;
11493 }
11494 };
11495 var registerEvents = function (editorManager, e) {
11496 var editor = e.editor;
11497 SelectionRestore.register(editor);
11498 editor.on('focusin', function () {
11499 var self = this;
11500 var focusedEditor = editorManager.focusedEditor;
11501 if (focusedEditor !== self) {
11502 if (focusedEditor) {
11503 focusedEditor.fire('blur', { focusedEditor: self });
11504 }
11505 editorManager.setActive(self);
11506 editorManager.focusedEditor = self;
11507 self.fire('focus', { blurredEditor: focusedEditor });
11508 self.focus(true);
11509 }
11510 });
11511 editor.on('focusout', function () {
11512 var self = this;
11513 Delay.setEditorTimeout(self, function () {
11514 var focusedEditor = editorManager.focusedEditor;
11515 if (!isUIElement(self, getActiveElement()) && focusedEditor === self) {
11516 self.fire('blur', { focusedEditor: null });
11517 editorManager.focusedEditor = null;
11518 }
11519 });
11520 });
11521 if (!documentFocusInHandler) {
11522 documentFocusInHandler = function (e) {
11523 var activeEditor = editorManager.activeEditor;
11524 var target;
11525 target = e.target;
11526 if (activeEditor && target.ownerDocument === domGlobals.document) {
11527 if (target !== domGlobals.document.body && !isUIElement(activeEditor, target) && editorManager.focusedEditor === activeEditor) {
11528 activeEditor.fire('blur', { focusedEditor: null });
11529 editorManager.focusedEditor = null;
11530 }
11531 }
11532 };
11533 DOM$1.bind(domGlobals.document, 'focusin', documentFocusInHandler);
11534 }
11535 };
11536 var unregisterDocumentEvents = function (editorManager, e) {
11537 if (editorManager.focusedEditor === e.editor) {
11538 editorManager.focusedEditor = null;
11539 }
11540 if (!editorManager.activeEditor) {
11541 DOM$1.unbind(domGlobals.document, 'focusin', documentFocusInHandler);
11542 documentFocusInHandler = null;
11543 }
11544 };
11545 var setup$2 = function (editorManager) {
11546 editorManager.on('AddEditor', curry(registerEvents, editorManager));
11547 editorManager.on('RemoveEditor', curry(unregisterDocumentEvents, editorManager));
11548 };
11549 var FocusController = {
11550 setup: setup$2,
11551 isEditorUIElement: isEditorUIElement$1,
11552 isUIElement: isUIElement
11553 };
11554
11555 var getContentEditableHost = function (editor, node) {
11556 return editor.dom.getParent(node, function (node) {
11557 return editor.dom.getContentEditable(node) === 'true';
11558 });
11559 };
11560 var getCollapsedNode = function (rng) {
11561 return rng.collapsed ? Option.from(getNode(rng.startContainer, rng.startOffset)).map(Element.fromDom) : Option.none();
11562 };
11563 var getFocusInElement = function (root, rng) {
11564 return getCollapsedNode(rng).bind(function (node) {
11565 if (isTableSection(node)) {
11566 return Option.some(node);
11567 } else if (contains$3(root, node) === false) {
11568 return Option.some(root);
11569 } else {
11570 return Option.none();
11571 }
11572 });
11573 };
11574 var normalizeSelection = function (editor, rng) {
11575 getFocusInElement(Element.fromDom(editor.getBody()), rng).bind(function (elm) {
11576 return CaretFinder.firstPositionIn(elm.dom());
11577 }).fold(function () {
11578 editor.selection.normalize();
11579 return;
11580 }, function (caretPos) {
11581 return editor.selection.setRng(caretPos.toRange());
11582 });
11583 };
11584 var focusBody = function (body) {
11585 if (body.setActive) {
11586 try {
11587 body.setActive();
11588 } catch (ex) {
11589 body.focus();
11590 }
11591 } else {
11592 body.focus();
11593 }
11594 };
11595 var hasElementFocus = function (elm) {
11596 return hasFocus(elm) || search(elm).isSome();
11597 };
11598 var hasIframeFocus = function (editor) {
11599 return editor.iframeElement && hasFocus(Element.fromDom(editor.iframeElement));
11600 };
11601 var hasInlineFocus = function (editor) {
11602 var rawBody = editor.getBody();
11603 return rawBody && hasElementFocus(Element.fromDom(rawBody));
11604 };
11605 var hasUiFocus = function (editor) {
11606 return hasElementFocus(Element.fromDom(editor.getContainer())) || active().filter(function (elem) {
11607 return FocusController.isUIElement(editor, elem.dom());
11608 }).isSome();
11609 };
11610 var hasFocus$1 = function (editor) {
11611 return editor.inline ? hasInlineFocus(editor) : hasIframeFocus(editor);
11612 };
11613 var hasEditorOrUiFocus = function (editor) {
11614 return hasFocus$1(editor) || hasUiFocus(editor);
11615 };
11616 var focusEditor = function (editor) {
11617 var selection = editor.selection;
11618 var body = editor.getBody();
11619 var rng = selection.getRng();
11620 editor.quirks.refreshContentEditable();
11621 if (editor.bookmark !== undefined && hasFocus$1(editor) === false) {
11622 SelectionBookmark.getRng(editor).each(function (bookmarkRng) {
11623 editor.selection.setRng(bookmarkRng);
11624 rng = bookmarkRng;
11625 });
11626 }
11627 var contentEditableHost = getContentEditableHost(editor, selection.getNode());
11628 if (editor.$.contains(body, contentEditableHost)) {
11629 focusBody(contentEditableHost);
11630 normalizeSelection(editor, rng);
11631 activateEditor(editor);
11632 return;
11633 }
11634 if (!editor.inline) {
11635 if (!Env.opera) {
11636 focusBody(body);
11637 }
11638 editor.getWin().focus();
11639 }
11640 if (Env.gecko || editor.inline) {
11641 focusBody(body);
11642 normalizeSelection(editor, rng);
11643 }
11644 activateEditor(editor);
11645 };
11646 var activateEditor = function (editor) {
11647 return editor.editorManager.setActive(editor);
11648 };
11649 var focus = function (editor, skipFocus) {
11650 if (editor.removed) {
11651 return;
11652 }
11653 skipFocus ? activateEditor(editor) : focusEditor(editor);
11654 };
11655 var EditorFocus = {
11656 focus: focus,
11657 hasFocus: hasFocus$1,
11658 hasEditorOrUiFocus: hasEditorOrUiFocus
11659 };
11660
11661 var defaultFormat$1 = 'html';
11662 var isTreeNode = function (content) {
11663 return content instanceof Node$1;
11664 };
11665 var moveSelection = function (editor) {
11666 if (EditorFocus.hasFocus(editor)) {
11667 CaretFinder.firstPositionIn(editor.getBody()).each(function (pos) {
11668 var node = pos.getNode();
11669 var caretPos = NodeType.isTable(node) ? CaretFinder.firstPositionIn(node).getOr(pos) : pos;
11670 editor.selection.setRng(caretPos.toRange());
11671 });
11672 }
11673 };
11674 var setEditorHtml = function (editor, html) {
11675 editor.dom.setHTML(editor.getBody(), html);
11676 moveSelection(editor);
11677 };
11678 var setContentString = function (editor, body, content, args) {
11679 var forcedRootBlockName, padd;
11680 if (content.length === 0 || /^\s+$/.test(content)) {
11681 padd = '<br data-mce-bogus="1">';
11682 if (body.nodeName === 'TABLE') {
11683 content = '<tr><td>' + padd + '</td></tr>';
11684 } else if (/^(UL|OL)$/.test(body.nodeName)) {
11685 content = '<li>' + padd + '</li>';
11686 }
11687 forcedRootBlockName = Settings.getForcedRootBlock(editor);
11688 if (forcedRootBlockName && editor.schema.isValidChild(body.nodeName.toLowerCase(), forcedRootBlockName.toLowerCase())) {
11689 content = padd;
11690 content = editor.dom.createHTML(forcedRootBlockName, editor.settings.forced_root_block_attrs, content);
11691 } else if (!content) {
11692 content = '<br data-mce-bogus="1">';
11693 }
11694 setEditorHtml(editor, content);
11695 editor.fire('SetContent', args);
11696 } else {
11697 if (args.format !== 'raw') {
11698 content = Serializer({ validate: editor.validate }, editor.schema).serialize(editor.parser.parse(content, {
11699 isRootContent: true,
11700 insert: true
11701 }));
11702 }
11703 args.content = isWsPreserveElement(Element.fromDom(body)) ? content : Tools.trim(content);
11704 setEditorHtml(editor, args.content);
11705 if (!args.no_events) {
11706 editor.fire('SetContent', args);
11707 }
11708 }
11709 return args.content;
11710 };
11711 var setContentTree = function (editor, body, content, args) {
11712 filter$2(editor.parser.getNodeFilters(), editor.parser.getAttributeFilters(), content);
11713 var html = Serializer({ validate: editor.validate }, editor.schema).serialize(content);
11714 args.content = isWsPreserveElement(Element.fromDom(body)) ? html : Tools.trim(html);
11715 setEditorHtml(editor, args.content);
11716 if (!args.no_events) {
11717 editor.fire('SetContent', args);
11718 }
11719 return content;
11720 };
11721 var setContent = function (editor, content, args) {
11722 if (args === void 0) {
11723 args = {};
11724 }
11725 args.format = args.format ? args.format : defaultFormat$1;
11726 args.set = true;
11727 args.content = isTreeNode(content) ? '' : content;
11728 if (!isTreeNode(content) && !args.no_events) {
11729 editor.fire('BeforeSetContent', args);
11730 content = args.content;
11731 }
11732 return Option.from(editor.getBody()).fold(constant(content), function (body) {
11733 return isTreeNode(content) ? setContentTree(editor, body, content, args) : setContentString(editor, body, content, args);
11734 });
11735 };
11736
11737 var firePreProcess = function (editor, args) {
11738 return editor.fire('PreProcess', args);
11739 };
11740 var firePostProcess = function (editor, args) {
11741 return editor.fire('PostProcess', args);
11742 };
11743 var fireRemove = function (editor) {
11744 return editor.fire('remove');
11745 };
11746 var fireDetach = function (editor) {
11747 return editor.fire('detach');
11748 };
11749 var fireSwitchMode = function (editor, mode) {
11750 return editor.fire('SwitchMode', { mode: mode });
11751 };
11752 var fireObjectResizeStart = function (editor, target, width, height) {
11753 editor.fire('ObjectResizeStart', {
11754 target: target,
11755 width: width,
11756 height: height
11757 });
11758 };
11759 var fireObjectResized = function (editor, target, width, height) {
11760 editor.fire('ObjectResized', {
11761 target: target,
11762 width: width,
11763 height: height
11764 });
11765 };
11766 var Events = {
11767 firePreProcess: firePreProcess,
11768 firePostProcess: firePostProcess,
11769 fireRemove: fireRemove,
11770 fireDetach: fireDetach,
11771 fireSwitchMode: fireSwitchMode,
11772 fireObjectResizeStart: fireObjectResizeStart,
11773 fireObjectResized: fireObjectResized
11774 };
11775
11776 var DOM$2 = DOMUtils$1.DOM;
11777 var restoreOriginalStyles = function (editor) {
11778 DOM$2.setStyle(editor.id, 'display', editor.orgDisplay);
11779 };
11780 var safeDestroy = function (x) {
11781 return Option.from(x).each(function (x) {
11782 return x.destroy();
11783 });
11784 };
11785 var clearDomReferences = function (editor) {
11786 editor.contentAreaContainer = editor.formElement = editor.container = editor.editorContainer = null;
11787 editor.bodyElement = editor.contentDocument = editor.contentWindow = null;
11788 editor.iframeElement = editor.targetElm = null;
11789 if (editor.selection) {
11790 editor.selection = editor.selection.win = editor.selection.dom = editor.selection.dom.doc = null;
11791 }
11792 };
11793 var restoreForm = function (editor) {
11794 var form = editor.formElement;
11795 if (form) {
11796 if (form._mceOldSubmit) {
11797 form.submit = form._mceOldSubmit;
11798 form._mceOldSubmit = null;
11799 }
11800 DOM$2.unbind(form, 'submit reset', editor.formEventDelegate);
11801 }
11802 };
11803 var remove$6 = function (editor) {
11804 if (!editor.removed) {
11805 var _selectionOverrides = editor._selectionOverrides, editorUpload = editor.editorUpload;
11806 var body = editor.getBody();
11807 var element = editor.getElement();
11808 if (body) {
11809 editor.save({ is_removing: true });
11810 }
11811 editor.removed = true;
11812 editor.unbindAllNativeEvents();
11813 if (editor.hasHiddenInput && element) {
11814 DOM$2.remove(element.nextSibling);
11815 }
11816 Events.fireRemove(editor);
11817 editor.editorManager.remove(editor);
11818 if (!editor.inline && body) {
11819 restoreOriginalStyles(editor);
11820 }
11821 Events.fireDetach(editor);
11822 DOM$2.remove(editor.getContainer());
11823 safeDestroy(_selectionOverrides);
11824 safeDestroy(editorUpload);
11825 editor.destroy();
11826 }
11827 };
11828 var destroy = function (editor, automatic) {
11829 var selection = editor.selection, dom = editor.dom;
11830 if (editor.destroyed) {
11831 return;
11832 }
11833 if (!automatic && !editor.removed) {
11834 editor.remove();
11835 return;
11836 }
11837 if (!automatic) {
11838 editor.editorManager.off('beforeunload', editor._beforeUnload);
11839 if (editor.theme && editor.theme.destroy) {
11840 editor.theme.destroy();
11841 }
11842 safeDestroy(selection);
11843 safeDestroy(dom);
11844 }
11845 restoreForm(editor);
11846 clearDomReferences(editor);
11847 editor.destroyed = true;
11848 };
11849
11850 var sectionResult = Immutable('sections', 'settings');
11851 var detection = PlatformDetection$1.detect();
11852 var isTouch = detection.deviceType.isTouch();
11853 var isPhone = detection.deviceType.isPhone();
11854 var mobilePlugins = [
11855 'lists',
11856 'autolink',
11857 'autosave'
11858 ];
11859 var defaultMobileSettings = isPhone ? { theme: 'mobile' } : {};
11860 var normalizePlugins = function (plugins) {
11861 var pluginNames = isArray(plugins) ? plugins.join(' ') : plugins;
11862 var trimmedPlugins = map(isString(pluginNames) ? pluginNames.split(' ') : [], trim$2);
11863 return filter(trimmedPlugins, function (item) {
11864 return item.length > 0;
11865 });
11866 };
11867 var filterMobilePlugins = function (plugins) {
11868 return filter(plugins, curry(contains, mobilePlugins));
11869 };
11870 var extractSections = function (keys, settings) {
11871 var result = bifilter(settings, function (value, key) {
11872 return contains(keys, key);
11873 });
11874 return sectionResult(result.t, result.f);
11875 };
11876 var getSection = function (sectionResult, name, defaults) {
11877 var sections = sectionResult.sections();
11878 var sectionSettings = sections.hasOwnProperty(name) ? sections[name] : {};
11879 return Tools.extend({}, defaults, sectionSettings);
11880 };
11881 var hasSection = function (sectionResult, name) {
11882 return sectionResult.sections().hasOwnProperty(name);
11883 };
11884 var getDefaultSettings = function (id, documentBaseUrl, editor) {
11885 return {
11886 id: id,
11887 theme: 'silver',
11888 plugins: '',
11889 document_base_url: documentBaseUrl,
11890 add_form_submit_trigger: true,
11891 submit_patch: true,
11892 add_unload_trigger: true,
11893 convert_urls: true,
11894 relative_urls: true,
11895 remove_script_host: true,
11896 object_resizing: true,
11897 doctype: '<!DOCTYPE html>',
11898 visual: true,
11899 font_size_legacy_values: 'xx-small,small,medium,large,x-large,xx-large,300%',
11900 forced_root_block: 'p',
11901 hidden_input: true,
11902 inline_styles: true,
11903 convert_fonts_to_spans: true,
11904 indent: true,
11905 indent_before: 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,' + 'tfoot,tbody,tr,section,summary,article,hgroup,aside,figure,figcaption,option,optgroup,datalist',
11906 indent_after: 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,' + 'tfoot,tbody,tr,section,summary,article,hgroup,aside,figure,figcaption,option,optgroup,datalist',
11907 entity_encoding: 'named',
11908 url_converter: editor.convertURL,
11909 url_converter_scope: editor
11910 };
11911 };
11912 var getExternalPlugins = function (overrideSettings, settings) {
11913 var userDefinedExternalPlugins = settings.external_plugins ? settings.external_plugins : {};
11914 if (overrideSettings && overrideSettings.external_plugins) {
11915 return Tools.extend({}, overrideSettings.external_plugins, userDefinedExternalPlugins);
11916 } else {
11917 return userDefinedExternalPlugins;
11918 }
11919 };
11920 var combinePlugins = function (forcedPlugins, plugins) {
11921 return [].concat(normalizePlugins(forcedPlugins)).concat(normalizePlugins(plugins));
11922 };
11923 var processPlugins = function (isTouchDevice, sectionResult, defaultOverrideSettings, settings) {
11924 var forcedPlugins = normalizePlugins(defaultOverrideSettings.forced_plugins);
11925 var plugins = normalizePlugins(settings.plugins);
11926 var platformPlugins = isTouchDevice && hasSection(sectionResult, 'mobile') ? filterMobilePlugins(plugins) : plugins;
11927 var combinedPlugins = combinePlugins(forcedPlugins, platformPlugins);
11928 return Tools.extend(settings, { plugins: combinedPlugins.join(' ') });
11929 };
11930 var isOnMobile = function (isTouchDevice, sectionResult) {
11931 var isInline = sectionResult.settings().inline;
11932 return isTouchDevice && !isInline;
11933 };
11934 var combineSettings = function (isTouchDevice, defaultSettings, defaultOverrideSettings, settings) {
11935 var sectionResult = extractSections(['mobile'], settings);
11936 var extendedSettings = Tools.extend(defaultSettings, defaultOverrideSettings, sectionResult.settings(), isOnMobile(isTouchDevice, sectionResult) ? getSection(sectionResult, 'mobile', defaultMobileSettings) : {}, {
11937 validate: true,
11938 external_plugins: getExternalPlugins(defaultOverrideSettings, sectionResult.settings())
11939 });
11940 return processPlugins(isTouchDevice, sectionResult, defaultOverrideSettings, extendedSettings);
11941 };
11942 var getEditorSettings = function (editor, id, documentBaseUrl, defaultOverrideSettings, settings) {
11943 var defaultSettings = getDefaultSettings(id, documentBaseUrl, editor);
11944 return combineSettings(isTouch, defaultSettings, defaultOverrideSettings, settings);
11945 };
11946 var getFiltered = function (predicate, editor, name) {
11947 return Option.from(editor.settings[name]).filter(predicate);
11948 };
11949 var getParamObject = function (value) {
11950 var output = {};
11951 if (typeof value === 'string') {
11952 each(value.indexOf('=') > 0 ? value.split(/[;,](?![^=;,]*(?:[;,]|$))/) : value.split(','), function (val) {
11953 var arr = val.split('=');
11954 if (arr.length > 1) {
11955 output[Tools.trim(arr[0])] = Tools.trim(arr[1]);
11956 } else {
11957 output[Tools.trim(arr[0])] = Tools.trim(arr[0]);
11958 }
11959 });
11960 } else {
11961 output = value;
11962 }
11963 return output;
11964 };
11965 var isArrayOf = function (p) {
11966 return function (a) {
11967 return isArray(a) && forall(a, p);
11968 };
11969 };
11970 var getParam = function (editor, name, defaultVal, type) {
11971 var value = name in editor.settings ? editor.settings[name] : defaultVal;
11972 if (type === 'hash') {
11973 return getParamObject(value);
11974 } else if (type === 'string') {
11975 return getFiltered(isString, editor, name).getOr(defaultVal);
11976 } else if (type === 'number') {
11977 return getFiltered(isNumber, editor, name).getOr(defaultVal);
11978 } else if (type === 'boolean') {
11979 return getFiltered(isBoolean, editor, name).getOr(defaultVal);
11980 } else if (type === 'object') {
11981 return getFiltered(isObject, editor, name).getOr(defaultVal);
11982 } else if (type === 'array') {
11983 return getFiltered(isArray, editor, name).getOr(defaultVal);
11984 } else if (type === 'string[]') {
11985 return getFiltered(isArrayOf(isString), editor, name).getOr(defaultVal);
11986 } else if (type === 'function') {
11987 return getFiltered(isFunction, editor, name).getOr(defaultVal);
11988 } else {
11989 return value;
11990 }
11991 };
11992
11993 var getProp = function (propName, elm) {
11994 var rawElm = elm.dom();
11995 return rawElm[propName];
11996 };
11997 var getComputedSizeProp = function (propName, elm) {
11998 return parseInt(get$2(elm, propName), 10);
11999 };
12000 var getClientWidth = curry(getProp, 'clientWidth');
12001 var getClientHeight = curry(getProp, 'clientHeight');
12002 var getMarginTop = curry(getComputedSizeProp, 'margin-top');
12003 var getMarginLeft = curry(getComputedSizeProp, 'margin-left');
12004 var getBoundingClientRect$1 = function (elm) {
12005 return elm.dom().getBoundingClientRect();
12006 };
12007 var isInsideElementContentArea = function (bodyElm, clientX, clientY) {
12008 var clientWidth = getClientWidth(bodyElm);
12009 var clientHeight = getClientHeight(bodyElm);
12010 return clientX >= 0 && clientY >= 0 && clientX <= clientWidth && clientY <= clientHeight;
12011 };
12012 var transpose = function (inline, elm, clientX, clientY) {
12013 var clientRect = getBoundingClientRect$1(elm);
12014 var deltaX = inline ? clientRect.left + elm.dom().clientLeft + getMarginLeft(elm) : 0;
12015 var deltaY = inline ? clientRect.top + elm.dom().clientTop + getMarginTop(elm) : 0;
12016 var x = clientX - deltaX;
12017 var y = clientY - deltaY;
12018 return {
12019 x: x,
12020 y: y
12021 };
12022 };
12023 var isXYInContentArea = function (editor, clientX, clientY) {
12024 var bodyElm = Element.fromDom(editor.getBody());
12025 var targetElm = editor.inline ? bodyElm : documentElement(bodyElm);
12026 var transposedPoint = transpose(editor.inline, targetElm, clientX, clientY);
12027 return isInsideElementContentArea(targetElm, transposedPoint.x, transposedPoint.y);
12028 };
12029 var fromDomSafe = function (node) {
12030 return Option.from(node).map(Element.fromDom);
12031 };
12032 var isEditorAttachedToDom = function (editor) {
12033 var rawContainer = editor.inline ? editor.getBody() : editor.getContentAreaContainer();
12034 return fromDomSafe(rawContainer).map(function (container) {
12035 return contains$3(owner(container), container);
12036 }).getOr(false);
12037 };
12038 var EditorView = {
12039 isXYInContentArea: isXYInContentArea,
12040 isEditorAttachedToDom: isEditorAttachedToDom
12041 };
12042
12043 function NotificationManagerImpl() {
12044 var unimplemented = function () {
12045 throw new Error('Theme did not provide a NotificationManager implementation.');
12046 };
12047 return {
12048 open: unimplemented,
12049 close: unimplemented,
12050 reposition: unimplemented,
12051 getArgs: unimplemented
12052 };
12053 }
12054
12055 function NotificationManager(editor) {
12056 var notifications = [];
12057 var getImplementation = function () {
12058 var theme = editor.theme;
12059 return theme && theme.getNotificationManagerImpl ? theme.getNotificationManagerImpl() : NotificationManagerImpl();
12060 };
12061 var getTopNotification = function () {
12062 return Option.from(notifications[0]);
12063 };
12064 var isEqual = function (a, b) {
12065 return a.type === b.type && a.text === b.text && !a.progressBar && !a.timeout && !b.progressBar && !b.timeout;
12066 };
12067 var reposition = function () {
12068 if (notifications.length > 0) {
12069 getImplementation().reposition(notifications);
12070 }
12071 };
12072 var addNotification = function (notification) {
12073 notifications.push(notification);
12074 };
12075 var closeNotification = function (notification) {
12076 findIndex(notifications, function (otherNotification) {
12077 return otherNotification === notification;
12078 }).each(function (index) {
12079 notifications.splice(index, 1);
12080 });
12081 };
12082 var open = function (spec) {
12083 if (editor.removed || !EditorView.isEditorAttachedToDom(editor)) {
12084 return;
12085 }
12086 return find(notifications, function (notification) {
12087 return isEqual(getImplementation().getArgs(notification), spec);
12088 }).getOrThunk(function () {
12089 editor.editorManager.setActive(editor);
12090 var notification = getImplementation().open(spec, function () {
12091 closeNotification(notification);
12092 reposition();
12093 });
12094 addNotification(notification);
12095 reposition();
12096 return notification;
12097 });
12098 };
12099 var close = function () {
12100 getTopNotification().each(function (notification) {
12101 getImplementation().close(notification);
12102 closeNotification(notification);
12103 reposition();
12104 });
12105 };
12106 var getNotifications = function () {
12107 return notifications;
12108 };
12109 var registerEvents = function (editor) {
12110 editor.on('SkinLoaded', function () {
12111 var serviceMessage = editor.settings.service_message;
12112 if (serviceMessage) {
12113 open({
12114 text: serviceMessage,
12115 type: 'warn',
12116 timeout: 0
12117 });
12118 }
12119 });
12120 editor.on('ResizeEditor ResizeWindow NodeChange', function () {
12121 Delay.requestAnimationFrame(reposition);
12122 });
12123 editor.on('remove', function () {
12124 each(notifications.slice(), function (notification) {
12125 getImplementation().close(notification);
12126 });
12127 });
12128 };
12129 registerEvents(editor);
12130 return {
12131 open: open,
12132 close: close,
12133 getNotifications: getNotifications
12134 };
12135 }
12136
12137 function WindowManagerImpl () {
12138 var unimplemented = function () {
12139 throw new Error('Theme did not provide a WindowManager implementation.');
12140 };
12141 return {
12142 open: unimplemented,
12143 openUrl: unimplemented,
12144 alert: unimplemented,
12145 confirm: unimplemented,
12146 close: unimplemented,
12147 getParams: unimplemented,
12148 setParams: unimplemented
12149 };
12150 }
12151
12152 var WindowManager = function (editor) {
12153 var dialogs = [];
12154 var getImplementation = function () {
12155 var theme = editor.theme;
12156 return theme && theme.getWindowManagerImpl ? theme.getWindowManagerImpl() : WindowManagerImpl();
12157 };
12158 var funcBind = function (scope, f) {
12159 return function () {
12160 return f ? f.apply(scope, arguments) : undefined;
12161 };
12162 };
12163 var fireOpenEvent = function (dialog) {
12164 editor.fire('OpenWindow', { dialog: dialog });
12165 };
12166 var fireCloseEvent = function (dialog) {
12167 editor.fire('CloseWindow', { dialog: dialog });
12168 };
12169 var addDialog = function (dialog) {
12170 dialogs.push(dialog);
12171 fireOpenEvent(dialog);
12172 };
12173 var closeDialog = function (dialog) {
12174 fireCloseEvent(dialog);
12175 dialogs = filter(dialogs, function (otherDialog) {
12176 return otherDialog !== dialog;
12177 });
12178 if (dialogs.length === 0) {
12179 editor.focus();
12180 }
12181 };
12182 var getTopDialog = function () {
12183 return Option.from(dialogs[dialogs.length - 1]);
12184 };
12185 var storeSelectionAndOpenDialog = function (openDialog) {
12186 editor.editorManager.setActive(editor);
12187 SelectionBookmark.store(editor);
12188 var dialog = openDialog();
12189 addDialog(dialog);
12190 return dialog;
12191 };
12192 var open = function (args, params) {
12193 return storeSelectionAndOpenDialog(function () {
12194 return getImplementation().open(args, params, closeDialog);
12195 });
12196 };
12197 var openUrl = function (args) {
12198 return storeSelectionAndOpenDialog(function () {
12199 return getImplementation().openUrl(args, closeDialog);
12200 });
12201 };
12202 var alert = function (message, callback, scope) {
12203 getImplementation().alert(message, funcBind(scope ? scope : this, callback));
12204 };
12205 var confirm = function (message, callback, scope) {
12206 getImplementation().confirm(message, funcBind(scope ? scope : this, callback));
12207 };
12208 var close = function () {
12209 getTopDialog().each(function (dialog) {
12210 getImplementation().close(dialog);
12211 closeDialog(dialog);
12212 });
12213 };
12214 editor.on('remove', function () {
12215 each(dialogs, function (dialog) {
12216 getImplementation().close(dialog);
12217 });
12218 });
12219 return {
12220 open: open,
12221 openUrl: openUrl,
12222 alert: alert,
12223 confirm: confirm,
12224 close: close
12225 };
12226 };
12227
12228 var displayNotification = function (editor, message) {
12229 editor.notificationManager.open({
12230 type: 'error',
12231 text: message
12232 });
12233 };
12234 var displayError = function (editor, message) {
12235 if (editor._skinLoaded) {
12236 displayNotification(editor, message);
12237 } else {
12238 editor.on('SkinLoaded', function () {
12239 displayNotification(editor, message);
12240 });
12241 }
12242 };
12243 var uploadError = function (editor, message) {
12244 displayError(editor, I18n.translate([
12245 'Failed to upload image: {0}',
12246 message
12247 ]));
12248 };
12249 var logError = function (msg) {
12250 domGlobals.console.error(msg);
12251 };
12252 var createLoadError = function (type, url, name) {
12253 return name ? 'Failed to load ' + type + ': ' + name + ' from url ' + url : 'Failed to load ' + type + ' url: ' + url;
12254 };
12255 var pluginLoadError = function (url, name) {
12256 logError(createLoadError('plugin', url, name));
12257 };
12258 var iconsLoadError = function (url, name) {
12259 logError(createLoadError('icons', url, name));
12260 };
12261 var languageLoadError = function (url, name) {
12262 logError(createLoadError('language', url, name));
12263 };
12264 var pluginInitError = function (editor, name, err) {
12265 var message = I18n.translate([
12266 'Failed to initialize plugin: {0}',
12267 name
12268 ]);
12269 initError(message, err);
12270 displayError(editor, message);
12271 };
12272 var initError = function (message) {
12273 var x = [];
12274 for (var _i = 1; _i < arguments.length; _i++) {
12275 x[_i - 1] = arguments[_i];
12276 }
12277 var console = domGlobals.window.console;
12278 if (console) {
12279 if (console.error) {
12280 console.error.apply(console, arguments);
12281 } else {
12282 console.log.apply(console, arguments);
12283 }
12284 }
12285 };
12286 var ErrorReporter = {
12287 pluginLoadError: pluginLoadError,
12288 iconsLoadError: iconsLoadError,
12289 languageLoadError: languageLoadError,
12290 pluginInitError: pluginInitError,
12291 uploadError: uploadError,
12292 displayError: displayError,
12293 initError: initError
12294 };
12295
12296 var getAll = function () {
12297 return {
12298 'accessibility-check': '<svg width="24" height="24"><path d="M12 2a2 2 0 0 1 2 2 2 2 0 0 1-2 2 2 2 0 0 1-2-2c0-1.1.9-2 2-2zm8 7h-5v12c0 .6-.4 1-1 1a1 1 0 0 1-1-1v-5c0-.6-.4-1-1-1a1 1 0 0 0-1 1v5c0 .6-.4 1-1 1a1 1 0 0 1-1-1V9H4a1 1 0 1 1 0-2h16c.6 0 1 .4 1 1s-.4 1-1 1z" fill-rule="nonzero"/></svg>',
12299 'action-next': '<svg width="24" height="24"><path fill-rule="nonzero" d="M5.7 7.3a1 1 0 0 0-1.4 1.4l7.7 7.7 7.7-7.7a1 1 0 1 0-1.4-1.4L12 13.6 5.7 7.3z"/></svg>',
12300 'action-prev': '<svg width="24" height="24"><path fill-rule="nonzero" d="M18.3 15.7a1 1 0 0 0 1.4-1.4L12 6.6l-7.7 7.7a1 1 0 0 0 1.4 1.4L12 9.4l6.3 6.3z"/></svg>',
12301 'align-center': '<svg width="24" height="24"><path d="M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm3 4h8c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 1 1 0-2zm0 8h8c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 0 1 0-2zm-3-4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2z" fill-rule="evenodd"/></svg>',
12302 'align-justify': '<svg width="24" height="24"><path d="M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm0 4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm0 4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2zm0 4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2z" fill-rule="evenodd"/></svg>',
12303 'align-left': '<svg width="24" height="24"><path d="M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm0 4h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm0 8h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2zm0-4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2z" fill-rule="evenodd"/></svg>',
12304 'align-none': '<svg width="24" height="24"><path d="M14.2 5L13 7H5a1 1 0 1 1 0-2h9.2zm4 0h.8a1 1 0 0 1 0 2h-2l1.2-2zm-6.4 4l-1.2 2H5a1 1 0 0 1 0-2h6.8zm4 0H19a1 1 0 0 1 0 2h-4.4l1.2-2zm-6.4 4l-1.2 2H5a1 1 0 0 1 0-2h4.4zm4 0H19a1 1 0 0 1 0 2h-6.8l1.2-2zM7 17l-1.2 2H5a1 1 0 0 1 0-2h2zm4 0h8a1 1 0 0 1 0 2H9.8l1.2-2zm5.2-13.5l1.3.7-9.7 16.3-1.3-.7 9.7-16.3z" fill-rule="evenodd"/></svg>',
12305 'align-right': '<svg width="24" height="24"><path d="M5 5h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm6 4h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0 8h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm-6-4h14c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2z" fill-rule="evenodd"/></svg>',
12306 'arrow-left': '<svg width="24" height="24"><path d="M5.6 13l12 6a1 1 0 0 0 1.4-1V6a1 1 0 0 0-1.4-.9l-12 6a1 1 0 0 0 0 1.8z" fill-rule="evenodd"/></svg>',
12307 'arrow-right': '<svg width="24" height="24"><path d="M18.5 13l-12 6A1 1 0 0 1 5 18V6a1 1 0 0 1 1.4-.9l12 6a1 1 0 0 1 0 1.8z" fill-rule="evenodd"/></svg>',
12308 'bold': '<svg width="24" height="24"><path d="M7.8 19c-.3 0-.5 0-.6-.2l-.2-.5V5.7c0-.2 0-.4.2-.5l.6-.2h5c1.5 0 2.7.3 3.5 1 .7.6 1.1 1.4 1.1 2.5a3 3 0 0 1-.6 1.9c-.4.6-1 1-1.6 1.2.4.1.9.3 1.3.6s.8.7 1 1.2c.4.4.5 1 .5 1.6 0 1.3-.4 2.3-1.3 3-.8.7-2.1 1-3.8 1H7.8zm5-8.3c.6 0 1.2-.1 1.6-.5.4-.3.6-.7.6-1.3 0-1.1-.8-1.7-2.3-1.7H9.3v3.5h3.4zm.5 6c.7 0 1.3-.1 1.7-.4.4-.4.6-.9.6-1.5s-.2-1-.7-1.4c-.4-.3-1-.4-2-.4H9.4v3.8h4z" fill-rule="evenodd"/></svg>',
12309 'bookmark': '<svg width="24" height="24"><path d="M6 4v17l6-4 6 4V4c0-.6-.4-1-1-1H7a1 1 0 0 0-1 1z" fill-rule="nonzero"/></svg>',
12310 'border-width': '<svg width="24" height="24"><path d="M5 14.8h14a1 1 0 0 1 0 2H5a1 1 0 0 1 0-2zm-.5 3.7h15c.3 0 .5.2.5.5s-.2.5-.5.5h-15a.5.5 0 1 1 0-1zm.5-8.3h14c.6 0 1 .4 1 1v1c0 .5-.4 1-1 1H5a1 1 0 0 1-1-1v-1c0-.6.4-1 1-1zm0-5.7h14c.6 0 1 .4 1 1v2c0 .6-.4 1-1 1H5a1 1 0 0 1-1-1v-2c0-.6.4-1 1-1z" fill-rule="evenodd"/></svg>',
12311 'brightness': '<svg width="24" height="24"><path d="M12 17c.3 0 .5.1.7.3.2.2.3.4.3.7v1c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3 1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7v-1c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3zm0-10a1 1 0 0 1-.7-.3A1 1 0 0 1 11 6V5c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3.3 0 .5.1.7.3.2.2.3.4.3.7v1c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3zm7 4c.3 0 .5.1.7.3.2.2.3.4.3.7 0 .3-.1.5-.3.7a1 1 0 0 1-.7.3h-1a1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h1zM7 12c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3H5a1 1 0 0 1-.7-.3A1 1 0 0 1 4 12c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h1c.3 0 .5.1.7.3.2.2.3.4.3.7zm10 3.5l.7.8c.2.1.3.4.3.6 0 .3-.1.6-.3.8a1 1 0 0 1-.8.3 1 1 0 0 1-.6-.3l-.8-.7a1 1 0 0 1-.3-.8c0-.2.1-.5.3-.7a1 1 0 0 1 1.4 0zm-10-7l-.7-.8a1 1 0 0 1-.3-.6c0-.3.1-.6.3-.8.2-.2.5-.3.8-.3.2 0 .5.1.7.3l.7.7c.2.2.3.5.3.8 0 .2-.1.5-.3.7a1 1 0 0 1-.7.3 1 1 0 0 1-.8-.3zm10 0a1 1 0 0 1-.8.3 1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7c0-.3.1-.6.3-.8l.8-.7c.1-.2.4-.3.6-.3.3 0 .6.1.8.3.2.2.3.5.3.8 0 .2-.1.5-.3.7l-.7.7zm-10 7c.2-.2.5-.3.8-.3.2 0 .5.1.7.3a1 1 0 0 1 0 1.4l-.8.8a1 1 0 0 1-.6.3 1 1 0 0 1-.8-.3 1 1 0 0 1-.3-.8c0-.2.1-.5.3-.6l.7-.8zM12 8a4 4 0 0 1 3.7 2.4 4 4 0 0 1 0 3.2A4 4 0 0 1 12 16a4 4 0 0 1-3.7-2.4 4 4 0 0 1 0-3.2A4 4 0 0 1 12 8zm0 6.5c.7 0 1.3-.2 1.8-.7.5-.5.7-1.1.7-1.8s-.2-1.3-.7-1.8c-.5-.5-1.1-.7-1.8-.7s-1.3.2-1.8.7c-.5.5-.7 1.1-.7 1.8s.2 1.3.7 1.8c.5.5 1.1.7 1.8.7z" fill-rule="evenodd"/></svg>',
12312 'browse': '<svg width="24" height="24"><path d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-4v-2h4V8H5v10h4v2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14zm-8 9.4l-2.3 2.3a1 1 0 1 1-1.4-1.4l4-4a1 1 0 0 1 1.4 0l4 4a1 1 0 0 1-1.4 1.4L13 13.4V20a1 1 0 0 1-2 0v-6.6z" fill-rule="nonzero"/></svg>',
12313 'cancel': '<svg width="24" height="24"><path d="M12 4.6a7.4 7.4 0 1 1 0 14.8 7.4 7.4 0 0 1 0-14.8zM12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18zm0 8L14.8 8l1 1.1-2.7 2.8 2.7 2.7-1.1 1.1-2.7-2.7-2.7 2.7-1-1.1 2.6-2.7-2.7-2.7 1-1.1 2.8 2.7z" fill-rule="nonzero"/></svg>',
12314 'change-case': '<svg width="24" height="24"><path d="M18.4 18.2v-.6c-.5.8-1.3 1.2-2.4 1.2-2.2 0-3.3-1.6-3.3-4.8 0-3.1 1-4.7 3.3-4.7 1.1 0 1.8.3 2.4 1.1v-.6c0-.5.4-.8.8-.8s.8.3.8.8v8.4c0 .5-.4.8-.8.8a.8.8 0 0 1-.8-.8zm-2-7.4c-1.3 0-1.8.9-1.8 3.2 0 2.4.5 3.3 1.7 3.3 1.3 0 1.8-.9 1.8-3.2 0-2.4-.5-3.3-1.7-3.3zM10 15.7H5.5l-.8 2.6a1 1 0 0 1-1 .7h-.2a.7.7 0 0 1-.7-1l4-12a1 1 0 1 1 2 0l4 12a.7.7 0 0 1-.8 1h-.2a1 1 0 0 1-1-.7l-.8-2.6zm-.3-1.5l-2-6.5-1.9 6.5h3.9z" fill-rule="evenodd"/></svg>',
12315 'character-count': '<svg width="24" height="24"><path d="M4 11.5h16v1H4v-1zm4.8-6.8V10H7.7V5.8h-1v-1h2zM11 8.3V9h2v1h-3V7.7l2-1v-.9h-2v-1h3v2.4l-2 1zm6.3-3.4V10h-3.1V9h2.1V8h-2.1V6.8h2.1v-1h-2.1v-1h3.1zM5.8 16.4c0-.5.2-.8.5-1 .2-.2.6-.3 1.2-.3l.8.1c.2 0 .4.2.5.3l.4.4v2.8l.2.3H8.2v-.1-.2l-.6.3H7c-.4 0-.7 0-1-.2a1 1 0 0 1-.3-.9c0-.3 0-.6.3-.8.3-.2.7-.4 1.2-.4l.6-.2h.3v-.2l-.1-.2a.8.8 0 0 0-.5-.1 1 1 0 0 0-.4 0l-.3.4h-1zm2.3.8h-.2l-.2.1-.4.1a1 1 0 0 0-.4.2l-.2.2.1.3.5.1h.4l.4-.4v-.6zm2-3.4h1.2v1.7l.5-.3h.5c.5 0 .9.1 1.2.5.3.4.5.8.5 1.4 0 .6-.2 1.1-.5 1.5-.3.4-.7.6-1.3.6l-.6-.1-.4-.4v.4h-1.1v-5.4zm1.1 3.3c0 .3 0 .6.2.8a.7.7 0 0 0 1.2 0l.2-.8c0-.4 0-.6-.2-.8a.7.7 0 0 0-.6-.3l-.6.3-.2.8zm6.1-.5c0-.2 0-.3-.2-.4a.8.8 0 0 0-.5-.2c-.3 0-.5.1-.6.3l-.2.9c0 .3 0 .6.2.8.1.2.3.3.6.3.2 0 .4 0 .5-.2l.2-.4h1.1c0 .5-.3.8-.6 1.1a2 2 0 0 1-1.3.4c-.5 0-1-.2-1.3-.6a2 2 0 0 1-.5-1.4c0-.6.1-1.1.5-1.5.3-.4.8-.5 1.4-.5.5 0 1 0 1.2.3.4.3.5.7.5 1.2h-1v-.1z" fill-rule="evenodd"/></svg>',
12316 'checklist-rtl': '<svg width="24" height="24"><path d="M5 17h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1H5a1 1 0 1 1 0-2zm14.2 11c.2-.4.6-.5.9-.3.3.2.4.6.2 1L18 20c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8zm0-6c.2-.4.6-.5.9-.3.3.2.4.6.2 1L18 14c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8zm0-6c.2-.4.6-.5.9-.3.3.2.4.6.2 1L18 8c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8z" fill-rule="evenodd"/></svg>',
12317 'checklist': '<svg width="24" height="24"><path d="M11 17h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0-6h8a1 1 0 0 1 0 2h-8a1 1 0 0 1 0-2zM7.2 16c.2-.4.6-.5.9-.3.3.2.4.6.2 1L6 20c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8zm0-6c.2-.4.6-.5.9-.3.3.2.4.6.2 1L6 14c-.2.3-.7.4-1 0l-1.3-1.3a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8zm0-6c.2-.4.6-.5.9-.3.3.2.4.6.2 1L6 8c-.2.3-.7.4-1 0L3.8 6.9a.7.7 0 0 1 0-1c.3-.2.7-.2 1 0l.7.9 1.7-2.8z" fill-rule="evenodd"/></svg>',
12318 'checkmark': '<svg width="24" height="24"><path d="M18.2 5.4a1 1 0 0 1 1.6 1.2l-8 12a1 1 0 0 1-1.5.1l-5-5a1 1 0 1 1 1.4-1.4l4.1 4.1 7.4-11z" fill-rule="nonzero"/></svg>',
12319 'chevron-down': '<svg width="10" height="10"><path d="M8.7 2.2c.3-.3.8-.3 1 0 .4.4.4.9 0 1.2L5.7 7.8c-.3.3-.9.3-1.2 0L.2 3.4a.8.8 0 0 1 0-1.2c.3-.3.8-.3 1.1 0L5 6l3.7-3.8z" fill-rule="nonzero"/></svg>',
12320 'chevron-left': '<svg width="10" height="10"><path d="M7.8 1.3L4 5l3.8 3.7c.3.3.3.8 0 1-.4.4-.9.4-1.2 0L2.2 5.7a.8.8 0 0 1 0-1.2L6.6.2C7 0 7.4 0 7.8.2c.3.3.3.8 0 1.1z" fill-rule="nonzero"/></svg>',
12321 'chevron-right': '<svg width="10" height="10"><path d="M2.2 1.3a.8.8 0 0 1 0-1c.4-.4.9-.4 1.2 0l4.4 4.1c.3.4.3.9 0 1.2L3.4 9.8c-.3.3-.8.3-1.2 0a.8.8 0 0 1 0-1.1L6 5 2.2 1.3z" fill-rule="nonzero"/></svg>',
12322 'chevron-up': '<svg width="10" height="10"><path d="M8.7 7.8L5 4 1.3 7.8c-.3.3-.8.3-1 0a.8.8 0 0 1 0-1.2l4.1-4.4c.3-.3.9-.3 1.2 0l4.2 4.4c.3.3.3.9 0 1.2-.3.3-.8.3-1.1 0z" fill-rule="nonzero"/></svg>',
12323 'close': '<svg width="24" height="24"><path d="M17.3 8.2L13.4 12l3.9 3.8a1 1 0 0 1-1.5 1.5L12 13.4l-3.8 3.9a1 1 0 0 1-1.5-1.5l3.9-3.8-3.9-3.8a1 1 0 0 1 1.5-1.5l3.8 3.9 3.8-3.9a1 1 0 0 1 1.5 1.5z" fill-rule="evenodd"/></svg>',
12324 'code-sample': '<svg width="24" height="26"><path d="M7.1 11a2.8 2.8 0 0 1-.8 2 2.8 2.8 0 0 1 .8 2v1.7c0 .3.1.6.4.8.2.3.5.4.8.4.3 0 .4.2.4.4v.8c0 .2-.1.4-.4.4-.7 0-1.4-.3-2-.8-.5-.6-.8-1.3-.8-2V15c0-.3-.1-.6-.4-.8-.2-.3-.5-.4-.8-.4a.4.4 0 0 1-.4-.4v-.8c0-.2.2-.4.4-.4.3 0 .6-.1.8-.4.3-.2.4-.5.4-.8V9.3c0-.7.3-1.4.8-2 .6-.5 1.3-.8 2-.8.3 0 .4.2.4.4v.8c0 .2-.1.4-.4.4-.3 0-.6.1-.8.4-.3.2-.4.5-.4.8V11zm9.8 0V9.3c0-.3-.1-.6-.4-.8-.2-.3-.5-.4-.8-.4a.4.4 0 0 1-.4-.4V7c0-.2.1-.4.4-.4.7 0 1.4.3 2 .8.5.6.8 1.3.8 2V11c0 .3.1.6.4.8.2.3.5.4.8.4.2 0 .4.2.4.4v.8c0 .2-.2.4-.4.4-.3 0-.6.1-.8.4-.3.2-.4.5-.4.8v1.7c0 .7-.3 1.4-.8 2-.6.5-1.3.8-2 .8a.4.4 0 0 1-.4-.4v-.8c0-.2.1-.4.4-.4.3 0 .6-.1.8-.4.3-.2.4-.5.4-.8V15a2.8 2.8 0 0 1 .8-2 2.8 2.8 0 0 1-.8-2zm-3.3-.4c0 .4-.1.8-.5 1.1-.3.3-.7.5-1.1.5-.4 0-.8-.2-1.1-.5-.4-.3-.5-.7-.5-1.1 0-.5.1-.9.5-1.2.3-.3.7-.4 1.1-.4.4 0 .8.1 1.1.4.4.3.5.7.5 1.2zM12 13c.4 0 .8.1 1.1.5.4.3.5.7.5 1.1 0 1-.1 1.6-.5 2a3 3 0 0 1-1.1 1c-.4.3-.8.4-1.1.4a.5.5 0 0 1-.5-.5V17a3 3 0 0 0 1-.2l.6-.6c-.6 0-1-.2-1.3-.5-.2-.3-.3-.7-.3-1 0-.5.1-1 .5-1.2.3-.4.7-.5 1.1-.5z" fill-rule="evenodd"/></svg>',
12325 'color-levels': '<svg width="24" height="24"><path d="M17.5 11.4A9 9 0 0 1 18 14c0 .5 0 1-.2 1.4 0 .4-.3.9-.5 1.3a6.2 6.2 0 0 1-3.7 3 5.7 5.7 0 0 1-3.2 0A5.9 5.9 0 0 1 7.6 18a6.2 6.2 0 0 1-1.4-2.6 6.7 6.7 0 0 1 0-2.8c0-.4.1-.9.3-1.3a13.6 13.6 0 0 1 2.3-4A20 20 0 0 1 12 4a26.4 26.4 0 0 1 3.2 3.4 18.2 18.2 0 0 1 2.3 4zm-2 4.5c.4-.7.5-1.4.5-2a7.3 7.3 0 0 0-1-3.2c.2.6.2 1.2.2 1.9a4.5 4.5 0 0 1-1.3 3 5.3 5.3 0 0 1-2.3 1.5 4.9 4.9 0 0 1-2 .1 4.3 4.3 0 0 0 2.4.8 4 4 0 0 0 2-.6 4 4 0 0 0 1.5-1.5z" fill-rule="evenodd"/></svg>',
12326 'color-picker': '<svg width="24" height="24"><path d="M12 3a9 9 0 0 0 0 18 1.5 1.5 0 0 0 1.1-2.5c-.2-.3-.4-.6-.4-1 0-.8.7-1.5 1.5-1.5H16a5 5 0 0 0 5-5c0-4.4-4-8-9-8zm-5.5 9a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm3-4a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm3 4a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z" fill-rule="nonzero"/></svg>',
12327 'color-swatch-remove-color': '<svg width="24" height="24"><path stroke="#000" stroke-width="2" d="M21 3L3 21" fill-rule="evenodd"/></svg>',
12328 'color-swatch': '<svg width="24" height="24"><rect x="3" y="3" width="18" height="18" rx="1" fill-rule="evenodd"/></svg>',
12329 'comment-add': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M9 19l3-2h7c.6 0 1-.4 1-1V6c0-.6-.4-1-1-1H5a1 1 0 0 0-1 1v10c0 .6.4 1 1 1h4v2zm-2 4v-4H5a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3h14a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3h-6.4L7 23z"/><path d="M13 10h2a1 1 0 0 1 0 2h-2v2a1 1 0 0 1-2 0v-2H9a1 1 0 0 1 0-2h2V8a1 1 0 0 1 2 0v2z"/></g></svg>',
12330 'comment': '<svg width="24" height="24"><path fill-rule="nonzero" d="M9 19l3-2h7c.6 0 1-.4 1-1V6c0-.6-.4-1-1-1H5a1 1 0 0 0-1 1v10c0 .6.4 1 1 1h4v2zm-2 4v-4H5a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3h14a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3h-6.4L7 23z"/></svg>',
12331 'contrast': '<svg width="24" height="24"><path d="M12 4a7.8 7.8 0 0 1 5.7 2.3A8 8 0 1 1 12 4zm-6 8a6 6 0 0 0 6 6V6a6 6 0 0 0-6 6z" fill-rule="evenodd"/></svg>',
12332 'copy': '<svg width="24" height="24"><path d="M16 3H6a2 2 0 0 0-2 2v11h2V5h10V3zm1 4a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-7a2 2 0 0 1-2-2V9c0-1.2.9-2 2-2h7zm0 12V9h-7v10h7z" fill-rule="nonzero"/></svg>',
12333 'crop': '<svg width="24" height="24"><path d="M17 8v7h2c.6 0 1 .4 1 1s-.4 1-1 1h-2v2c0 .6-.4 1-1 1a1 1 0 0 1-1-1v-2H7V9H5a1 1 0 1 1 0-2h2V5c0-.6.4-1 1-1s1 .4 1 1v2h7l3-3 1 1-3 3zM9 9v5l5-5H9zm1 6h5v-5l-5 5z" fill-rule="evenodd"/></svg>',
12334 'cut': '<svg width="24" height="24"><path d="M18 15c.6.7 1 1.4 1 2.3 0 .8-.2 1.5-.7 2l-.8.5-1 .2c-.4 0-.8 0-1.2-.3a3.9 3.9 0 0 1-2.1-2.2c-.2-.5-.3-1-.2-1.5l-1-1-1 1c0 .5 0 1-.2 1.5-.1.5-.4 1-.9 1.4-.3.4-.7.6-1.2.8l-1.2.3c-.4 0-.7 0-1-.2-.3 0-.6-.3-.8-.5-.5-.5-.8-1.2-.7-2 0-.9.4-1.6 1-2.2A3.7 3.7 0 0 1 8.6 14H9l1-1-4-4-.5-1a3.3 3.3 0 0 1 0-2c0-.4.3-.7.5-1l6 6 6-6 .5 1a3.3 3.3 0 0 1 0 2c0 .4-.3.7-.5 1l-4 4 1 1h.5c.4 0 .8 0 1.2.3.5.2.9.4 1.2.8zm-8.5 2.2l.1-.4v-.3-.4a1 1 0 0 0-.2-.5 1 1 0 0 0-.4-.2 1.6 1.6 0 0 0-.8 0 2.6 2.6 0 0 0-.8.3 2.5 2.5 0 0 0-.9 1.1l-.1.4v.7l.2.5.5.2h.7a2.5 2.5 0 0 0 .8-.3 2.8 2.8 0 0 0 1-1zm2.5-2.8c.4 0 .7-.1 1-.4.3-.3.4-.6.4-1s-.1-.7-.4-1c-.3-.3-.6-.4-1-.4s-.7.1-1 .4c-.3.3-.4.6-.4 1s.1.7.4 1c.3.3.6.4 1 .4zm5.4 4l.2-.5v-.4-.3a2.6 2.6 0 0 0-.3-.8 2.4 2.4 0 0 0-.7-.7 2.5 2.5 0 0 0-.8-.3 1.5 1.5 0 0 0-.8 0 1 1 0 0 0-.4.2 1 1 0 0 0-.2.5 1.5 1.5 0 0 0 0 .7v.4l.3.4.3.4a2.8 2.8 0 0 0 .8.5l.4.1h.7l.5-.2z" fill-rule="evenodd"/></svg>',
12335 'document-properties': '<svg width="24" height="24"><path d="M14.4 3H7a2 2 0 0 0-2 2v14c0 1.1.9 2 2 2h10a2 2 0 0 0 2-2V7.6L14.4 3zM17 19H7V5h6v4h4v10z" fill-rule="nonzero"/></svg>',
12336 'drag': '<svg width="24" height="24"><path d="M13 5h2v2h-2V5zm0 4h2v2h-2V9zM9 9h2v2H9V9zm4 4h2v2h-2v-2zm-4 0h2v2H9v-2zm0 4h2v2H9v-2zm4 0h2v2h-2v-2zM9 5h2v2H9V5z" fill-rule="evenodd"/></svg>',
12337 'duplicate': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M16 3v2H6v11H4V5c0-1.1.9-2 2-2h10zm3 8h-2V9h-7v10h9a2 2 0 0 1-2 2h-7a2 2 0 0 1-2-2V9c0-1.2.9-2 2-2h7a2 2 0 0 1 2 2v2z"/><path d="M17 14h1a1 1 0 0 1 0 2h-1v1a1 1 0 0 1-2 0v-1h-1a1 1 0 0 1 0-2h1v-1a1 1 0 0 1 2 0v1z"/></g></svg>',
12338 'edit-block': '<svg width="24" height="24"><path fill-rule="nonzero" d="M19.8 8.8l-9.4 9.4c-.2.2-.5.4-.9.4l-5.4 1.2 1.2-5.4.5-.8 9.4-9.4c.7-.7 1.8-.7 2.5 0l2.1 2.1c.7.7.7 1.8 0 2.5zm-2-.2l1-.9v-.3l-2.2-2.2a.3.3 0 0 0-.3 0l-1 1L18 8.5zm-1 1l-2.5-2.4-6 6 2.5 2.5 6-6zm-7 7.1l-2.6-2.4-.3.3-.1.2-.7 3 3.1-.6h.1l.4-.5z"/></svg>',
12339 'edit-image': '<svg width="24" height="24"><path d="M18 16h2V7a2 2 0 0 0-2-2H7v2h11v9zM6 17h15a1 1 0 0 1 0 2h-1v1a1 1 0 0 1-2 0v-1H6a2 2 0 0 1-2-2V7H3a1 1 0 1 1 0-2h1V4a1 1 0 1 1 2 0v13zm3-5.3l1.3 2 3-4.7 3.7 6H7l2-3.3z" fill-rule="nonzero"/></svg>',
12340 'embed-page': '<svg width="24" height="24"><path d="M19 6V5H5v14h2A13 13 0 0 1 19 6zm0 1.4c-.8.8-1.6 2.4-2.2 4.6H19V7.4zm0 5.6h-2.4c-.4 1.8-.6 3.8-.6 6h3v-6zm-4 6c0-2.2.2-4.2.6-6H13c-.7 1.8-1.1 3.8-1.1 6h3zm-4 0c0-2.2.4-4.2 1-6H9.6A12 12 0 0 0 8 19h3zM4 3h16c.6 0 1 .4 1 1v16c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1zm11.8 9c.4-1.9 1-3.4 1.8-4.5a9.2 9.2 0 0 0-4 4.5h2.2zm-3.4 0a12 12 0 0 1 2.8-4 12 12 0 0 0-5 4h2.2z" fill-rule="nonzero"/></svg>',
12341 'embed': '<svg width="24" height="24"><path d="M4 3h16c.6 0 1 .4 1 1v16c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1zm1 2v14h14V5H5zm4.8 2.6l5.6 4a.5.5 0 0 1 0 .8l-5.6 4A.5.5 0 0 1 9 16V8a.5.5 0 0 1 .8-.4z" fill-rule="nonzero"/></svg>',
12342 'emoji': '<svg width="24" height="24"><path d="M9 11c.6 0 1-.4 1-1s-.4-1-1-1a1 1 0 0 0-1 1c0 .6.4 1 1 1zm6 0c.6 0 1-.4 1-1s-.4-1-1-1a1 1 0 0 0-1 1c0 .6.4 1 1 1zm-3 5.5c2.1 0 4-1.5 4.4-3.5H7.6c.5 2 2.3 3.5 4.4 3.5zM12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16zm0 14.5a6.5 6.5 0 1 1 0-13 6.5 6.5 0 0 1 0 13z" fill-rule="nonzero"/></svg>',
12343 'fill': '<svg width="24" height="26"><path d="M16.6 12l-9-9-1.4 1.4 2.4 2.4-5.2 5.1c-.5.6-.5 1.6 0 2.2L9 19.6a1.5 1.5 0 0 0 2.2 0l5.5-5.5c.5-.6.5-1.6 0-2.2zM5.2 13L10 8.2l4.8 4.8H5.2zM19 14.5s-2 2.2-2 3.5c0 1.1.9 2 2 2a2 2 0 0 0 2-2c0-1.3-2-3.5-2-3.5z" fill-rule="nonzero"/></svg>',
12344 'flip-horizontally': '<svg width="24" height="24"><path d="M14 19h2v-2h-2v2zm4-8h2V9h-2v2zM4 7v10c0 1.1.9 2 2 2h3v-2H6V7h3V5H6a2 2 0 0 0-2 2zm14-2v2h2a2 2 0 0 0-2-2zm-7 16h2V3h-2v18zm7-6h2v-2h-2v2zm-4-8h2V5h-2v2zm4 12a2 2 0 0 0 2-2h-2v2z" fill-rule="nonzero"/></svg>',
12345 'flip-vertically': '<svg width="24" height="24"><path d="M5 14v2h2v-2H5zm8 4v2h2v-2h-2zm4-14H7a2 2 0 0 0-2 2v3h2V6h10v3h2V6a2 2 0 0 0-2-2zm2 14h-2v2a2 2 0 0 0 2-2zM3 11v2h18v-2H3zm6 7v2h2v-2H9zm8-4v2h2v-2h-2zM5 18c0 1.1.9 2 2 2v-2H5z" fill-rule="nonzero"/></svg>',
12346 'format-painter': '<svg width="24" height="24"><path d="M18 5V4c0-.5-.4-1-1-1H5a1 1 0 0 0-1 1v4c0 .6.5 1 1 1h12c.6 0 1-.4 1-1V7h1v4H9v9c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-7h8V5h-3z" fill-rule="nonzero"/></svg>',
12347 'fullscreen': '<svg width="24" height="24"><path d="M15.3 10l-1.2-1.3 2.9-3h-2.3a.9.9 0 1 1 0-1.7H19c.5 0 .9.4.9.9v4.4a.9.9 0 1 1-1.8 0V7l-2.9 3zm0 4l3 3v-2.3a.9.9 0 1 1 1.7 0V19c0 .5-.4.9-.9.9h-4.4a.9.9 0 1 1 0-1.8H17l-3-2.9 1.3-1.2zM10 15.4l-2.9 3h2.3a.9.9 0 1 1 0 1.7H5a.9.9 0 0 1-.9-.9v-4.4a.9.9 0 1 1 1.8 0V17l2.9-3 1.2 1.3zM8.7 10L5.7 7v2.3a.9.9 0 0 1-1.7 0V5c0-.5.4-.9.9-.9h4.4a.9.9 0 0 1 0 1.8H7l3 2.9-1.3 1.2z" fill-rule="nonzero"/></svg>',
12348 'gallery': '<svg width="24" height="24"><path fill-rule="nonzero" d="M5 15.7l2.3-2.2c.3-.3.7-.3 1 0L11 16l5.1-5c.3-.4.8-.4 1 0l2 1.9V8H5v7.7zM5 18V19h3l1.8-1.9-2-2L5 17.9zm14-3l-2.5-2.4-6.4 6.5H19v-4zM4 6h16c.6 0 1 .4 1 1v13c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V7c0-.6.4-1 1-1zm6 7a2 2 0 1 1 0-4 2 2 0 0 1 0 4zM4.5 4h15a.5.5 0 1 1 0 1h-15a.5.5 0 0 1 0-1zm2-2h11a.5.5 0 1 1 0 1h-11a.5.5 0 0 1 0-1z"/></svg>',
12349 'gamma': '<svg width="24" height="24"><path d="M4 3h16c.6 0 1 .4 1 1v16c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1zm1 2v14h14V5H5zm6.5 11.8V14L9.2 8.7a5.1 5.1 0 0 0-.4-.8l-.1-.2H8 8v-1l.3-.1.3-.1h.7a1 1 0 0 1 .6.5l.1.3a8.5 8.5 0 0 1 .3.6l1.9 4.6 2-5.2a1 1 0 0 1 1-.6.5.5 0 0 1 .5.6L13 14v2.8a.7.7 0 0 1-1.4 0z" fill-rule="nonzero"/></svg>',
12350 'help': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M12 5.5a6.5 6.5 0 0 0-6 9 6.3 6.3 0 0 0 1.4 2l1 1a6.3 6.3 0 0 0 3.6 1 6.5 6.5 0 0 0 6-9 6.3 6.3 0 0 0-1.4-2l-1-1a6.3 6.3 0 0 0-3.6-1zM12 4a7.8 7.8 0 0 1 5.7 2.3A8 8 0 1 1 12 4z"/><path d="M9.6 9.7a.7.7 0 0 1-.7-.8c0-1.1 1.5-1.8 3.2-1.8 1.8 0 3.2.8 3.2 2.4 0 1.4-.4 2.1-1.5 2.8-.2 0-.3.1-.3.2a2 2 0 0 0-.8.8.8.8 0 0 1-1.4-.6c.3-.7.8-1 1.3-1.5l.4-.2c.7-.4.8-.6.8-1.5 0-.5-.6-.9-1.7-.9-.5 0-1 .1-1.4.3-.2 0-.3.1-.3.2v-.2c0 .4-.4.8-.8.8z" fill-rule="nonzero"/><circle cx="12" cy="16" r="1"/></g></svg>',
12351 'highlight-bg-color': '<svg width="24" height="24"><g fill-rule="evenodd"><path id="tox-icon-highlight-bg-color__color" d="M3 18h18v3H3z"/><path fill-rule="nonzero" d="M7.7 16.7H3l3.3-3.3-.7-.8L10.2 8l4 4.1-4 4.2c-.2.2-.6.2-.8 0l-.6-.7-1.1 1.1zm5-7.5L11 7.4l3-2.9a2 2 0 0 1 2.6 0L18 6c.7.7.7 2 0 2.7l-2.9 2.9-1.8-1.8-.5-.6"/></g></svg>',
12352 'home': '<svg width="24" height="24"><path fill-rule="nonzero" d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>',
12353 'horizontal-rule': '<svg width="24" height="24"><path d="M4 11h16v2H4z" fill-rule="evenodd"/></svg>',
12354 'image-options': '<svg width="24" height="24"><path d="M6 10a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2zm12 0a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2zm-6 0a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2z" fill-rule="nonzero"/></svg>',
12355 'image': '<svg width="24" height="24"><path d="M5 15.7l3.3-3.2c.3-.3.7-.3 1 0L12 15l4.1-4c.3-.4.8-.4 1 0l2 1.9V5H5v10.7zM5 18V19h3l2.8-2.9-2-2L5 17.9zm14-3l-2.5-2.4-6.4 6.5H19v-4zM4 3h16c.6 0 1 .4 1 1v16c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V4c0-.6.4-1 1-1zm6 8a2 2 0 1 0 0-4 2 2 0 0 0 0 4z" fill-rule="nonzero"/></svg>',
12356 'indent': '<svg width="24" height="24"><path d="M7 5h12c.6 0 1 .4 1 1s-.4 1-1 1H7a1 1 0 1 1 0-2zm5 4h7c.6 0 1 .4 1 1s-.4 1-1 1h-7a1 1 0 0 1 0-2zm0 4h7c.6 0 1 .4 1 1s-.4 1-1 1h-7a1 1 0 0 1 0-2zm-5 4h12a1 1 0 0 1 0 2H7a1 1 0 0 1 0-2zm-2.6-3.8L6.2 12l-1.8-1.2a1 1 0 0 1 1.2-1.6l3 2a1 1 0 0 1 0 1.6l-3 2a1 1 0 1 1-1.2-1.6z" fill-rule="evenodd"/></svg>',
12357 'info': '<svg width="24" height="24"><path d="M12 4a7.8 7.8 0 0 1 5.7 2.3A8 8 0 1 1 12 4zm-1 3v2h2V7h-2zm3 10v-1h-1v-5h-3v1h1v4h-1v1h4z" fill-rule="evenodd"/></svg>',
12358 'insert-character': '<svg width="24" height="24"><path d="M15 18h4l1-2v4h-6v-3.3l1.4-1a6 6 0 0 0 1.8-2.9 6.3 6.3 0 0 0-.1-4.1 5.8 5.8 0 0 0-3-3.2c-.6-.3-1.3-.5-2.1-.5a5.1 5.1 0 0 0-3.9 1.8 6.3 6.3 0 0 0-1.3 6 6.2 6.2 0 0 0 1.8 3l1.4.9V20H4v-4l1 2h4v-.5l-2-1L5.4 15A6.5 6.5 0 0 1 4 11c0-1 .2-1.9.6-2.7A7 7 0 0 1 6.3 6C7.1 5.4 8 5 9 4.5c1-.3 2-.5 3.1-.5a8.8 8.8 0 0 1 5.7 2 7 7 0 0 1 1.7 2.3 6 6 0 0 1 .2 4.8c-.2.7-.6 1.3-1 1.9a7.6 7.6 0 0 1-3.6 2.5v.5z" fill-rule="evenodd"/></svg>',
12359 'insert-time': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M12 19a7 7 0 1 0 0-14 7 7 0 0 0 0 14zm0 2a9 9 0 1 1 0-18 9 9 0 0 1 0 18z"/><path d="M16 12h-3V7c0-.6-.4-1-1-1a1 1 0 0 0-1 1v7h5c.6 0 1-.4 1-1s-.4-1-1-1z"/></g></svg>',
12360 'invert': '<svg width="24" height="24"><path d="M18 19.3L16.5 18a5.8 5.8 0 0 1-3.1 1.9 6.1 6.1 0 0 1-5.5-1.6A5.8 5.8 0 0 1 6 14v-.3l.1-1.2A13.9 13.9 0 0 1 7.7 9l-3-3 .7-.8 2.8 2.9 9 8.9 1.5 1.6-.7.6zm0-5.5v.3l-.1 1.1-.4 1-1.2-1.2a4.3 4.3 0 0 0 .2-1v-.2c0-.4 0-.8-.2-1.3l-.5-1.4a14.8 14.8 0 0 0-3-4.2L12 6a26.1 26.1 0 0 0-2.2 2.5l-1-1a20.9 20.9 0 0 1 2.9-3.3L12 4l1 .8a22.2 22.2 0 0 1 4 5.4c.6 1.2 1 2.4 1 3.6z" fill-rule="evenodd"/></svg>',
12361 'italic': '<svg width="24" height="24"><path d="M16.7 4.7l-.1.9h-.3c-.6 0-1 0-1.4.3-.3.3-.4.6-.5 1.1l-2.1 9.8v.6c0 .5.4.8 1.4.8h.2l-.2.8H8l.2-.8h.2c1.1 0 1.8-.5 2-1.5l2-9.8.1-.5c0-.6-.4-.8-1.4-.8h-.3l.2-.9h5.8z" fill-rule="evenodd"/></svg>',
12362 'line': '<svg width="24" height="24"><path d="M15 9l-8 8H4v-3l8-8 3 3zm1-1l-3-3 1-1h1c-.2 0 0 0 0 0l2 2s0 .2 0 0v1l-1 1zM4 18h16v2H4v-2z" fill-rule="evenodd"/></svg>',
12363 'link': '<svg width="24" height="24"><path d="M6.2 12.3a1 1 0 0 1 1.4 1.4l-2.1 2a2 2 0 1 0 2.7 2.8l4.8-4.8a1 1 0 0 0 0-1.4 1 1 0 1 1 1.4-1.3 2.9 2.9 0 0 1 0 4L9.6 20a3.9 3.9 0 0 1-5.5-5.5l2-2zm11.6-.6a1 1 0 0 1-1.4-1.4l2-2a2 2 0 1 0-2.6-2.8L11 10.3a1 1 0 0 0 0 1.4A1 1 0 1 1 9.6 13a2.9 2.9 0 0 1 0-4L14.4 4a3.9 3.9 0 0 1 5.5 5.5l-2 2z" fill-rule="nonzero"/></svg>',
12364 'list-bull-circle': '<svg width="48" height="48"><g fill-rule="evenodd"><path d="M11 16a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 1a3 3 0 1 1 0-6 3 3 0 0 1 0 6zM11 26a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 1a3 3 0 1 1 0-6 3 3 0 0 1 0 6zM11 36a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 1a3 3 0 1 1 0-6 3 3 0 0 1 0 6z" fill-rule="nonzero"/><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/></g></svg>',
12365 'list-bull-default': '<svg width="48" height="48"><g fill-rule="evenodd"><circle cx="11" cy="14" r="3"/><circle cx="11" cy="24" r="3"/><circle cx="11" cy="34" r="3"/><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/></g></svg>',
12366 'list-bull-square': '<svg width="48" height="48"><g fill-rule="evenodd"><path d="M8 11h6v6H8zM8 21h6v6H8zM8 31h6v6H8z"/><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/></g></svg>',
12367 'list-num-default-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M37.4 17v-4.8l-1.6 1v-1.1l1.6-1h1.2V17zM33.3 17.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm1.7 5.7c0-1.2 1-2 2.2-2 1.3 0 2.1.8 2.1 1.8 0 .7-.3 1.2-1.3 2.2l-1.2 1v.2h2.6v1h-4.3v-.9l2-1.9c.8-.8 1-1.1 1-1.5 0-.5-.4-.8-1-.8-.5 0-.9.3-.9.9H35zm-1.7 4.3c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm3.2 7.3v-1h.7c.6 0 1-.3 1-.8 0-.4-.4-.7-1-.7s-1 .3-1 .8H35c0-1.1 1-1.8 2.2-1.8 1.2 0 2.1.6 2.1 1.6 0 .7-.4 1.2-1 1.3v.1c.7.1 1.3.7 1.3 1.4 0 1-1 1.9-2.4 1.9-1.3 0-2.2-.8-2.3-2h1.2c0 .6.5 1 1.1 1 .6 0 1-.4 1-1 0-.5-.3-.8-1-.8h-.7zm-3.3 2.7c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7z"/></g></svg>',
12368 'list-num-default': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M10 17v-4.8l-1.5 1v-1.1l1.6-1h1.2V17h-1.2zm3.6.1c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .7.3.7.7 0 .4-.2.7-.7.7zm-5 5.7c0-1.2.8-2 2.1-2s2.1.8 2.1 1.8c0 .7-.3 1.2-1.4 2.2l-1.1 1v.2h2.6v1H8.6v-.9l2-1.9c.8-.8 1-1.1 1-1.5 0-.5-.4-.8-1-.8-.5 0-.9.3-.9.9H8.5zm6.3 4.3c-.5 0-.7-.3-.7-.7 0-.4.2-.7.7-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zM10 34.4v-1h.7c.6 0 1-.3 1-.8 0-.4-.4-.7-1-.7s-1 .3-1 .8H8.6c0-1.1 1-1.8 2.2-1.8 1.3 0 2.1.6 2.1 1.6 0 .7-.4 1.2-1 1.3v.1c.8.1 1.3.7 1.3 1.4 0 1-1 1.9-2.4 1.9-1.3 0-2.2-.8-2.3-2h1.2c0 .6.5 1 1.1 1 .7 0 1-.4 1-1 0-.5-.3-.8-1-.8h-.7zm4.7 2.7c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7z"/></g></svg>',
12369 'list-num-lower-alpha-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M36.5 16c-.9 0-1.5-.5-1.5-1.3s.6-1.3 1.8-1.4h1v-.4c0-.4-.2-.6-.7-.6-.4 0-.7.1-.8.4h-1.1c0-.8.8-1.4 2-1.4S39 12 39 13V16h-1.2v-.6c-.3.4-.8.7-1.4.7zm.4-.8c.6 0 1-.4 1-.9V14h-1c-.5.1-.7.3-.7.6 0 .4.3.6.7.6zM33.1 16.1c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7zM37.7 26c-.7 0-1.2-.2-1.5-.7v.7H35v-6.3h1.2v2.5c.3-.5.8-.9 1.5-.9 1.1 0 1.8 1 1.8 2.4 0 1.5-.7 2.4-1.8 2.4zm-.5-3.6c-.6 0-1 .5-1 1.3s.4 1.4 1 1.4c.7 0 1-.6 1-1.4 0-.8-.3-1.3-1-1.3zM33.2 26.1c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7zm6 7h-1c-.1-.5-.4-.8-1-.8s-1 .5-1 1.4c0 1 .4 1.4 1 1.4.5 0 .9-.2 1-.7h1c0 1-.8 1.7-2 1.7-1.4 0-2.2-.9-2.2-2.4s.8-2.4 2.2-2.4c1.2 0 2 .7 2 1.7zm-6.1 3c-.5 0-.7-.3-.7-.7 0-.4.2-.7.7-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z"/></g></svg>',
12370 'list-num-lower-alpha': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M10.3 15.2c.5 0 1-.4 1-.9V14h-1c-.5.1-.8.3-.8.6 0 .4.3.6.8.6zm-.4.9c-1 0-1.5-.6-1.5-1.4 0-.8.6-1.3 1.7-1.4h1.1v-.4c0-.4-.2-.6-.7-.6-.5 0-.8.1-.9.4h-1c0-.8.8-1.4 2-1.4 1.1 0 1.8.6 1.8 1.6V16h-1.1v-.6h-.1c-.2.4-.7.7-1.3.7zm4.6 0c-.5 0-.7-.3-.7-.7 0-.4.2-.7.7-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm-3.2 10c-.6 0-1.2-.3-1.4-.8v.7H8.5v-6.3H10v2.5c.3-.5.8-.9 1.4-.9 1.2 0 1.9 1 1.9 2.4 0 1.5-.7 2.4-1.9 2.4zm-.4-3.7c-.7 0-1 .5-1 1.3s.3 1.4 1 1.4c.6 0 1-.6 1-1.4 0-.8-.4-1.3-1-1.3zm4 3.7c-.5 0-.7-.3-.7-.7 0-.4.2-.7.7-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm-2.2 7h-1.2c0-.5-.4-.8-.9-.8-.6 0-1 .5-1 1.4 0 1 .4 1.4 1 1.4.5 0 .8-.2 1-.7h1c0 1-.8 1.7-2 1.7-1.4 0-2.2-.9-2.2-2.4s.8-2.4 2.2-2.4c1.2 0 2 .7 2 1.7zm1.8 3c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z"/></g></svg>',
12371 'list-num-lower-greek-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M37.4 16c-1.2 0-2-.8-2-2.3 0-1.5.8-2.4 2-2.4.6 0 1 .4 1.3 1v-.9H40v3.2c0 .4.1.5.4.5h.2v.9h-.6c-.6 0-1-.2-1-.7h-.2c-.2.4-.7.8-1.3.8zm.3-1c.6 0 1-.5 1-1.3s-.4-1.3-1-1.3-1 .5-1 1.3.4 1.4 1 1.4zM33.3 16.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zM36 21.9c0-1.5.8-2.3 2.1-2.3 1.2 0 2 .6 2 1.6 0 .6-.3 1-.9 1.3.9.3 1.3.8 1.3 1.7 0 1.2-.7 1.9-1.8 1.9-.6 0-1.1-.3-1.4-.8v2.2H36V22zm1.8 1.2v-1h.3c.5 0 .9-.2.9-.7 0-.5-.3-.8-.9-.8-.5 0-.8.3-.8 1v2.2c0 .8.4 1.3 1 1.3s1-.4 1-1-.4-1-1.2-1h-.3zM33.3 26.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zM37.1 34.6L34.8 30h1.4l1.7 3.5 1.7-3.5h1.1l-2.2 4.6v.1c.5.8.7 1.4.7 1.8 0 .4-.2.8-.4 1-.2.2-.6.3-1 .3-.9 0-1.3-.4-1.3-1.2 0-.5.2-1 .5-1.7l.1-.2zm.7 1a2 2 0 0 0-.4.9c0 .3.1.4.4.4.3 0 .4-.1.4-.4 0-.2-.1-.6-.4-1zM33.3 36.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z"/></g></svg>',
12372 'list-num-lower-greek': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M10.5 15c.7 0 1-.5 1-1.3s-.3-1.3-1-1.3c-.5 0-.9.5-.9 1.3s.4 1.4 1 1.4zm-.3 1c-1.1 0-1.8-.8-1.8-2.3 0-1.5.7-2.4 1.8-2.4.7 0 1.1.4 1.3 1h.1v-.9h1.2v3.2c0 .4.1.5.4.5h.2v.9h-.6c-.6 0-1-.2-1.1-.7h-.1c-.2.4-.7.8-1.4.8zm5 .1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.7-.7.5 0 .8.3.8.7 0 .4-.3.7-.8.7zm-4.9 7v-1h.3c.6 0 1-.2 1-.7 0-.5-.4-.8-1-.8-.5 0-.8.3-.8 1v2.2c0 .8.4 1.3 1.1 1.3.6 0 1-.4 1-1s-.5-1-1.3-1h-.3zM8.6 22c0-1.5.7-2.3 2-2.3 1.2 0 2 .6 2 1.6 0 .6-.3 1-.8 1.3.8.3 1.3.8 1.3 1.7 0 1.2-.8 1.9-1.9 1.9-.6 0-1.1-.3-1.3-.8v2.2H8.5V22zm6.2 4.2c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .7.3.7.7 0 .4-.2.7-.7.7zm-4.5 8.5L8 30h1.4l1.7 3.5 1.7-3.5h1.1l-2.2 4.6v.1c.5.8.7 1.4.7 1.8 0 .4-.1.8-.4 1-.2.2-.6.3-1 .3-.9 0-1.3-.4-1.3-1.2 0-.5.2-1 .5-1.7l.1-.2zm.7 1a2 2 0 0 0-.4.9c0 .3.1.4.4.4.3 0 .4-.1.4-.4 0-.2-.1-.6-.4-1zm4.5.5c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z"/></g></svg>',
12373 'list-num-lower-roman-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M32.9 16v-1.2h-1.3V16H33zm0 10v-1.2h-1.3V26H33zm0 10v-1.2h-1.3V36H33z"/><path fill-rule="nonzero" d="M36 21h-1.5v5H36zM36 31h-1.5v5H36zM39 21h-1.5v5H39zM39 31h-1.5v5H39zM42 31h-1.5v5H42zM36 11h-1.5v5H36zM36 19h-1.5v1H36zM36 29h-1.5v1H36zM39 19h-1.5v1H39zM39 29h-1.5v1H39zM42 29h-1.5v1H42zM36 9h-1.5v1H36z"/></g></svg>',
12374 'list-num-lower-roman': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M15.1 16v-1.2h1.3V16H15zm0 10v-1.2h1.3V26H15zm0 10v-1.2h1.3V36H15z"/><path fill-rule="nonzero" d="M12 21h1.5v5H12zM12 31h1.5v5H12zM9 21h1.5v5H9zM9 31h1.5v5H9zM6 31h1.5v5H6zM12 11h1.5v5H12zM12 19h1.5v1H12zM12 29h1.5v1H12zM9 19h1.5v1H9zM9 29h1.5v1H9zM6 29h1.5v1H6zM12 9h1.5v1H12z"/></g></svg>',
12375 'list-num-upper-alpha-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M39.3 17l-.5-1.4h-2l-.5 1.4H35l2-6h1.6l2 6h-1.3zm-1.6-4.7l-.7 2.3h1.6l-.8-2.3zM33.4 17c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .7.3.7.7 0 .4-.2.7-.7.7zm4.7 9.9h-2.7v-6H38c1.2 0 1.9.6 1.9 1.5 0 .6-.5 1.2-1 1.3.7.1 1.3.7 1.3 1.5 0 1-.8 1.7-2 1.7zm-1.4-5v1.5h1c.6 0 1-.3 1-.8 0-.4-.4-.7-1-.7h-1zm0 4h1.1c.7 0 1.1-.3 1.1-.8 0-.6-.4-.9-1.1-.9h-1.1V26zM33 27.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm4.9 10c-1.8 0-2.8-1.1-2.8-3.1s1-3.1 2.8-3.1c1.4 0 2.5.9 2.6 2.2h-1.3c0-.7-.6-1.1-1.3-1.1-1 0-1.6.7-1.6 2s.6 2 1.6 2c.7 0 1.2-.4 1.4-1h1.2c-.1 1.3-1.2 2.2-2.6 2.2zm-4.5 0c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z"/></g></svg>',
12376 'list-num-upper-alpha': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M12.6 17l-.5-1.4h-2L9.5 17H8.3l2-6H12l2 6h-1.3zM11 12.3l-.7 2.3h1.6l-.8-2.3zm4.7 4.8c-.4 0-.7-.3-.7-.7 0-.4.3-.7.7-.7.5 0 .7.3.7.7 0 .4-.2.7-.7.7zM11.4 27H8.7v-6h2.6c1.2 0 1.9.6 1.9 1.5 0 .6-.5 1.2-1 1.3.7.1 1.3.7 1.3 1.5 0 1-.8 1.7-2 1.7zM10 22v1.5h1c.6 0 1-.3 1-.8 0-.4-.4-.7-1-.7h-1zm0 4H11c.7 0 1.1-.3 1.1-.8 0-.6-.4-.9-1.1-.9H10V26zm5.4 1.1c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7zm-4.1 10c-1.8 0-2.8-1.1-2.8-3.1s1-3.1 2.8-3.1c1.4 0 2.5.9 2.6 2.2h-1.3c0-.7-.6-1.1-1.3-1.1-1 0-1.6.7-1.6 2s.6 2 1.6 2c.7 0 1.2-.4 1.4-1h1.2c-.1 1.3-1.2 2.2-2.6 2.2zm4.5 0c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7.4 0 .7.3.7.7 0 .4-.3.7-.7.7z"/></g></svg>',
12377 'list-num-upper-roman-rtl': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M8 12h22v4H8zM8 22h22v4H8zM8 32h22v4H8z"/><path d="M31.6 17v-1.2H33V17h-1.3zm0 10v-1.2H33V27h-1.3zm0 10v-1.2H33V37h-1.3z"/><path fill-rule="nonzero" d="M34.5 20H36v7h-1.5zM34.5 30H36v7h-1.5zM37.5 20H39v7h-1.5zM37.5 30H39v7h-1.5zM40.5 30H42v7h-1.5zM34.5 10H36v7h-1.5z"/></g></svg>',
12378 'list-num-upper-roman': '<svg width="48" height="48"><g fill-rule="evenodd"><path opacity=".2" d="M18 12h22v4H18zM18 22h22v4H18zM18 32h22v4H18z"/><path d="M15.1 17v-1.2h1.3V17H15zm0 10v-1.2h1.3V27H15zm0 10v-1.2h1.3V37H15z"/><path fill-rule="nonzero" d="M12 20h1.5v7H12zM12 30h1.5v7H12zM9 20h1.5v7H9zM9 30h1.5v7H9zM6 30h1.5v7H6zM12 10h1.5v7H12z"/></g></svg>',
12379 'lock': '<svg width="24" height="24"><path d="M16.3 11c.2 0 .3 0 .5.2l.2.6v7.4c0 .3 0 .4-.2.6l-.6.2H7.8c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6v-7.4c0-.3 0-.4.2-.6l.5-.2H8V8c0-.8.3-1.5.9-2.1.6-.6 1.3-.9 2.1-.9h2c.8 0 1.5.3 2.1.9.6.6.9 1.3.9 2.1v3h.3zM10 8v3h4V8a1 1 0 0 0-.3-.7A1 1 0 0 0 13 7h-2a1 1 0 0 0-.7.3 1 1 0 0 0-.3.7z" fill-rule="evenodd"/></svg>',
12380 'ltr': '<svg width="24" height="24"><path d="M11 5h7a1 1 0 0 1 0 2h-1v11a1 1 0 0 1-2 0V7h-2v11a1 1 0 0 1-2 0v-6c-.5 0-1 0-1.4-.3A3.4 3.4 0 0 1 7.8 10a3.3 3.3 0 0 1 0-2.8 3.4 3.4 0 0 1 1.8-1.8L11 5zM4.4 16.2L6.2 15l-1.8-1.2a1 1 0 0 1 1.2-1.6l3 2a1 1 0 0 1 0 1.6l-3 2a1 1 0 1 1-1.2-1.6z" fill-rule="evenodd"/></svg>',
12381 'more-drawer': '<svg width="24" height="24"><path d="M6 10a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2zm12 0a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2zm-6 0a2 2 0 0 0-2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2 2 2 0 0 0-2-2z" fill-rule="nonzero"/></svg>',
12382 'new-document': '<svg width="24" height="24"><path d="M14.4 3H7a2 2 0 0 0-2 2v14c0 1.1.9 2 2 2h10a2 2 0 0 0 2-2V7.6L14.4 3zM17 19H7V5h6v4h4v10z" fill-rule="nonzero"/></svg>',
12383 'new-tab': '<svg width="24" height="24"><path d="M15 13l2-2v8H5V7h8l-2 2H7v8h8v-4zm4-8v5.5l-2-2-5.6 5.5H10v-1.4L15.5 7l-2-2H19z" fill-rule="evenodd"/></svg>',
12384 'non-breaking': '<svg width="24" height="24"><path d="M11 11H8a1 1 0 1 1 0-2h3V6c0-.6.4-1 1-1s1 .4 1 1v3h3c.6 0 1 .4 1 1s-.4 1-1 1h-3v3c0 .6-.4 1-1 1a1 1 0 0 1-1-1v-3zm10 4v5H3v-5c0-.6.4-1 1-1s1 .4 1 1v3h14v-3c0-.6.4-1 1-1s1 .4 1 1z" fill-rule="evenodd"/></svg>',
12385 'notice': '<svg width="24" height="24"><path d="M17.8 9.8L15.4 4 20 8.5v7L15.5 20h-7L4 15.5v-7L8.5 4h7l2.3 5.8zm0 0l2.2 5.7-2.3-5.8zM13 17v-2h-2v2h2zm0-4V7h-2v6h2z" fill-rule="evenodd"/></svg>',
12386 'ordered-list-rtl': '<svg width="24" height="24"><path d="M6 17h8a1 1 0 0 1 0 2H6a1 1 0 0 1 0-2zm0-6h8a1 1 0 0 1 0 2H6a1 1 0 0 1 0-2zm0-6h8a1 1 0 0 1 0 2H6a1 1 0 1 1 0-2zm13-1v3.5a.5.5 0 1 1-1 0V5h-.5a.5.5 0 1 1 0-1H19zm-1 8.8l.2.2h1.3a.5.5 0 1 1 0 1h-1.6a1 1 0 0 1-.9-1V13c0-.4.3-.8.6-1l1.2-.4.2-.3a.2.2 0 0 0-.2-.2h-1.3a.5.5 0 0 1-.5-.5c0-.3.2-.5.5-.5h1.6c.5 0 .9.4.9 1v.1c0 .4-.3.8-.6 1l-1.2.4-.2.3zm2 4.2v2c0 .6-.4 1-1 1h-1.5a.5.5 0 0 1 0-1h1.2a.3.3 0 1 0 0-.6h-1.3a.4.4 0 1 1 0-.8h1.3a.3.3 0 0 0 0-.6h-1.2a.5.5 0 1 1 0-1H19c.6 0 1 .4 1 1z" fill-rule="evenodd"/></svg>',
12387 'ordered-list': '<svg width="24" height="24"><path d="M10 17h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0-6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 1 1 0-2zM6 4v3.5c0 .3-.2.5-.5.5a.5.5 0 0 1-.5-.5V5h-.5a.5.5 0 0 1 0-1H6zm-1 8.8l.2.2h1.3c.3 0 .5.2.5.5s-.2.5-.5.5H4.9a1 1 0 0 1-.9-1V13c0-.4.3-.8.6-1l1.2-.4.2-.3a.2.2 0 0 0-.2-.2H4.5a.5.5 0 0 1-.5-.5c0-.3.2-.5.5-.5h1.6c.5 0 .9.4.9 1v.1c0 .4-.3.8-.6 1l-1.2.4-.2.3zM7 17v2c0 .6-.4 1-1 1H4.5a.5.5 0 0 1 0-1h1.2c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3H4.4a.4.4 0 1 1 0-.8h1.3c.2 0 .3-.1.3-.3 0-.2-.1-.3-.3-.3H4.5a.5.5 0 1 1 0-1H6c.6 0 1 .4 1 1z" fill-rule="evenodd"/></svg>',
12388 'orientation': '<svg width="24" height="24"><path d="M7.3 6.4L1 13l6.4 6.5 6.5-6.5-6.5-6.5zM3.7 13l3.6-3.7L11 13l-3.7 3.7-3.6-3.7zM12 6l2.8 2.7c.3.3.3.8 0 1-.3.4-.9.4-1.2 0L9.2 5.7a.8.8 0 0 1 0-1.2L13.6.2c.3-.3.9-.3 1.2 0 .3.3.3.8 0 1.1L12 4h1a9 9 0 1 1-4.3 16.9l1.5-1.5A7 7 0 1 0 13 6h-1z" fill-rule="nonzero"/></svg>',
12389 'outdent': '<svg width="24" height="24"><path d="M7 5h12c.6 0 1 .4 1 1s-.4 1-1 1H7a1 1 0 1 1 0-2zm5 4h7c.6 0 1 .4 1 1s-.4 1-1 1h-7a1 1 0 0 1 0-2zm0 4h7c.6 0 1 .4 1 1s-.4 1-1 1h-7a1 1 0 0 1 0-2zm-5 4h12a1 1 0 0 1 0 2H7a1 1 0 0 1 0-2zm1.6-3.8a1 1 0 0 1-1.2 1.6l-3-2a1 1 0 0 1 0-1.6l3-2a1 1 0 0 1 1.2 1.6L6.8 12l1.8 1.2z" fill-rule="evenodd"/></svg>',
12390 'page-break': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M5 11c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2zm3 0h1c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 0 1 0-2zm4 0c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2zm3 0h1c.6 0 1 .4 1 1s-.4 1-1 1h-1a1 1 0 0 1 0-2zm4 0c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2zM7 3v5h10V3c0-.6.4-1 1-1s1 .4 1 1v7H5V3c0-.6.4-1 1-1s1 .4 1 1zM6 22a1 1 0 0 1-1-1v-7h14v7c0 .6-.4 1-1 1a1 1 0 0 1-1-1v-5H7v5c0 .6-.4 1-1 1z"/></g></svg>',
12391 'paragraph': '<svg width="24" height="24"><path d="M10 5h7a1 1 0 0 1 0 2h-1v11a1 1 0 0 1-2 0V7h-2v11a1 1 0 0 1-2 0v-6c-.5 0-1 0-1.4-.3A3.4 3.4 0 0 1 6.8 10a3.3 3.3 0 0 1 0-2.8 3.4 3.4 0 0 1 1.8-1.8L10 5z" fill-rule="evenodd"/></svg>',
12392 'paste-text': '<svg width="24" height="24"><path d="M18 9V5h-2v1c0 .6-.4 1-1 1H9a1 1 0 0 1-1-1V5H6v13h3V9h9zM9 20H6a2 2 0 0 1-2-2V5c0-1.1.9-2 2-2h3.2A3 3 0 0 1 12 1a3 3 0 0 1 2.8 2H18a2 2 0 0 1 2 2v4h1v12H9v-1zm1.5-9.5v9h9v-9h-9zM12 3a1 1 0 0 0-1 1c0 .5.4 1 1 1s1-.5 1-1-.4-1-1-1zm0 9h6v2h-.5l-.5-1h-1v4h.8v1h-3.6v-1h.8v-4h-1l-.5 1H12v-2z" fill-rule="nonzero"/></svg>',
12393 'paste': '<svg width="24" height="24"><path d="M18 9V5h-2v1c0 .6-.4 1-1 1H9a1 1 0 0 1-1-1V5H6v13h3V9h9zM9 20H6a2 2 0 0 1-2-2V5c0-1.1.9-2 2-2h3.2A3 3 0 0 1 12 1a3 3 0 0 1 2.8 2H18a2 2 0 0 1 2 2v4h1v12H9v-1zm1.5-9.5v9h9v-9h-9zM12 3a1 1 0 0 0-1 1c0 .5.4 1 1 1s1-.5 1-1-.4-1-1-1z" fill-rule="nonzero"/></svg>',
12394 'permanent-pen': '<svg width="24" height="24"><path d="M10.5 17.5L8 20H3v-3l3.5-3.5a2 2 0 0 1 0-3L14 3l1 1-7.3 7.3a1 1 0 0 0 0 1.4l3.6 3.6c.4.4 1 .4 1.4 0L20 9l1 1-7.6 7.6a2 2 0 0 1-2.8 0l-.1-.1z" fill-rule="nonzero"/></svg>',
12395 'plus': '<svg width="24" height="24"><g fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke="#000" stroke-width="2"><path d="M12 5v14M5 12h14"/></g></svg>',
12396 'preferences': '<svg width="24" height="24"><path d="M20.1 13.5l-1.9.2a5.8 5.8 0 0 1-.6 1.5l1.2 1.5c.4.4.3 1 0 1.4l-.7.7a1 1 0 0 1-1.4 0l-1.5-1.2a6.2 6.2 0 0 1-1.5.6l-.2 1.9c0 .5-.5.9-1 .9h-1a1 1 0 0 1-1-.9l-.2-1.9a5.8 5.8 0 0 1-1.5-.6l-1.5 1.2a1 1 0 0 1-1.4 0l-.7-.7a1 1 0 0 1 0-1.4l1.2-1.5a6.2 6.2 0 0 1-.6-1.5l-1.9-.2a1 1 0 0 1-.9-1v-1c0-.5.4-1 .9-1l1.9-.2a5.8 5.8 0 0 1 .6-1.5L5.2 7.3a1 1 0 0 1 0-1.4l.7-.7a1 1 0 0 1 1.4 0l1.5 1.2a6.2 6.2 0 0 1 1.5-.6l.2-1.9c0-.5.5-.9 1-.9h1c.5 0 1 .4 1 .9l.2 1.9a5.8 5.8 0 0 1 1.5.6l1.5-1.2a1 1 0 0 1 1.4 0l.7.7c.3.4.4 1 0 1.4l-1.2 1.5a6.2 6.2 0 0 1 .6 1.5l1.9.2c.5 0 .9.5.9 1v1c0 .5-.4 1-.9 1zM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" fill-rule="evenodd"/></svg>',
12397 'preview': '<svg width="24" height="24"><path d="M3.5 12.5c.5.8 1.1 1.6 1.8 2.3 2 2 4.2 3.2 6.7 3.2s4.7-1.2 6.7-3.2a16.2 16.2 0 0 0 2.1-2.8 15.7 15.7 0 0 0-2.1-2.8c-2-2-4.2-3.2-6.7-3.2a9.3 9.3 0 0 0-6.7 3.2A16.2 16.2 0 0 0 3.2 12c0 .2.2.3.3.5zm-2.4-1l.7-1.2L4 7.8C6.2 5.4 8.9 4 12 4c3 0 5.8 1.4 8.1 3.8a18.2 18.2 0 0 1 2.8 3.7v1l-.7 1.2-2.1 2.5c-2.3 2.4-5 3.8-8.1 3.8-3 0-5.8-1.4-8.1-3.8a18.2 18.2 0 0 1-2.8-3.7 1 1 0 0 1 0-1zm12-3.3a2 2 0 1 0 2.7 2.6 4 4 0 1 1-2.6-2.6z" fill-rule="nonzero"/></svg>',
12398 'print': '<svg width="24" height="24"><path d="M18 8H6a3 3 0 0 0-3 3v6h2v3h14v-3h2v-6a3 3 0 0 0-3-3zm-1 10H7v-4h10v4zm.5-5c-.8 0-1.5-.7-1.5-1.5s.7-1.5 1.5-1.5 1.5.7 1.5 1.5-.7 1.5-1.5 1.5zm.5-8H6v2h12V5z" fill-rule="nonzero"/></svg>',
12399 'quote': '<svg width="24" height="24"><path d="M7.5 17h.9c.4 0 .7-.2.9-.6L11 13V8c0-.6-.4-1-1-1H6a1 1 0 0 0-1 1v4c0 .6.4 1 1 1h2l-1.3 2.7a1 1 0 0 0 .8 1.3zm8 0h.9c.4 0 .7-.2.9-.6L19 13V8c0-.6-.4-1-1-1h-4a1 1 0 0 0-1 1v4c0 .6.4 1 1 1h2l-1.3 2.7a1 1 0 0 0 .8 1.3z" fill-rule="nonzero"/></svg>',
12400 'redo': '<svg width="24" height="24"><path d="M17.6 10H12c-2.8 0-4.4 1.4-4.9 3.5-.4 2 .3 4 1.4 4.6a1 1 0 1 1-1 1.8c-2-1.2-2.9-4.1-2.3-6.8.6-3 3-5.1 6.8-5.1h5.6l-3.3-3.3a1 1 0 1 1 1.4-1.4l5 5a1 1 0 0 1 0 1.4l-5 5a1 1 0 0 1-1.4-1.4l3.3-3.3z" fill-rule="nonzero"/></svg>',
12401 'reload': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M5 22.1l-1.2-4.7v-.2a1 1 0 0 1 1-1l5 .4a1 1 0 1 1-.2 2l-2.2-.2a7.8 7.8 0 0 0 8.4.2 7.5 7.5 0 0 0 3.5-6.4 1 1 0 1 1 2 0 9.5 9.5 0 0 1-4.5 8 9.9 9.9 0 0 1-10.2 0l.4 1.4a1 1 0 1 1-2 .5zM13.6 7.4c0-.5.5-1 1-.9l2.8.2a8 8 0 0 0-9.5-1 7.5 7.5 0 0 0-3.6 7 1 1 0 0 1-2 0 9.5 9.5 0 0 1 4.5-8.6 10 10 0 0 1 10.9.3l-.3-1a1 1 0 0 1 2-.5l1.1 4.8a1 1 0 0 1-1 1.2l-5-.4a1 1 0 0 1-.9-1z"/></g></svg>',
12402 'remove-formatting': '<svg width="24" height="24"><path d="M13.2 6a1 1 0 0 1 0 .2l-2.6 10a1 1 0 0 1-1 .8h-.2a.8.8 0 0 1-.8-1l2.6-10H8a1 1 0 1 1 0-2h9a1 1 0 0 1 0 2h-3.8zM5 18h7a1 1 0 0 1 0 2H5a1 1 0 0 1 0-2zm13 1.5L16.5 18 15 19.5a.7.7 0 0 1-1-1l1.5-1.5-1.5-1.5a.7.7 0 0 1 1-1l1.5 1.5 1.5-1.5a.7.7 0 0 1 1 1L17.5 17l1.5 1.5a.7.7 0 0 1-1 1z" fill-rule="evenodd"/></svg>',
12403 'remove': '<svg width="24" height="24"><path d="M16 7h3a1 1 0 0 1 0 2h-1v9a3 3 0 0 1-3 3H9a3 3 0 0 1-3-3V9H5a1 1 0 1 1 0-2h3V6a3 3 0 0 1 3-3h2a3 3 0 0 1 3 3v1zm-2 0V6c0-.6-.4-1-1-1h-2a1 1 0 0 0-1 1v1h4zm2 2H8v9c0 .6.4 1 1 1h6c.6 0 1-.4 1-1V9zm-7 3a1 1 0 0 1 2 0v4a1 1 0 0 1-2 0v-4zm4 0a1 1 0 0 1 2 0v4a1 1 0 0 1-2 0v-4z" fill-rule="nonzero"/></svg>',
12404 'resize-handle': '<svg width="10" height="10"><g fill-rule="nonzero"><path d="M8.1 1.1A.5.5 0 1 1 9 2l-7 7A.5.5 0 1 1 1 8l7-7zM8.1 5.1A.5.5 0 1 1 9 6l-3 3A.5.5 0 1 1 5 8l3-3z"/></g></svg>',
12405 'resize': '<svg width="24" height="24"><path d="M4 5c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h6c.3 0 .5.1.7.3.2.2.3.4.3.7 0 .3-.1.5-.3.7a1 1 0 0 1-.7.3H7.4L18 16.6V13c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3.3 0 .5.1.7.3.2.2.3.4.3.7v6c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3h-6a1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h3.6L6 7.4V11c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3 1 1 0 0 1-.7-.3A1 1 0 0 1 4 11V5z" fill-rule="evenodd"/></svg>',
12406 'restore-draft': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M17 13c0 .6-.4 1-1 1h-4V8c0-.6.4-1 1-1s1 .4 1 1v4h2c.6 0 1 .4 1 1z"/><path d="M4.7 10H9a1 1 0 0 1 0 2H3a1 1 0 0 1-1-1V5a1 1 0 1 1 2 0v3l2.5-2.4a9.2 9.2 0 0 1 10.8-1.5A9 9 0 0 1 13.4 21c-2.4.1-4.7-.7-6.5-2.2a1 1 0 1 1 1.3-1.5 7.2 7.2 0 0 0 11.6-3.7 7 7 0 0 0-3.5-7.7A7.2 7.2 0 0 0 8 7L4.7 10z" fill-rule="nonzero"/></g></svg>',
12407 'rotate-left': '<svg width="24" height="24"><path d="M4.7 10H9a1 1 0 0 1 0 2H3a1 1 0 0 1-1-1V5a1 1 0 1 1 2 0v3l2.5-2.4a9.2 9.2 0 0 1 10.8-1.5A9 9 0 0 1 13.4 21c-2.4.1-4.7-.7-6.5-2.2a1 1 0 1 1 1.3-1.5 7.2 7.2 0 0 0 11.6-3.7 7 7 0 0 0-3.5-7.7A7.2 7.2 0 0 0 8 7L4.7 10z" fill-rule="nonzero"/></svg>',
12408 'rotate-right': '<svg width="24" height="24"><path d="M20 8V5a1 1 0 0 1 2 0v6c0 .6-.4 1-1 1h-6a1 1 0 0 1 0-2h4.3L16 7A7.2 7.2 0 0 0 7.7 6a7 7 0 0 0 3 13.1c1.9.1 3.7-.5 5-1.7a1 1 0 0 1 1.4 1.5A9.2 9.2 0 0 1 2.2 14c-.9-3.9 1-8 4.5-9.9 3.5-1.9 8-1.3 10.8 1.5L20 8z" fill-rule="nonzero"/></svg>',
12409 'rtl': '<svg width="24" height="24"><path d="M8 5h8v2h-2v12h-2V7h-2v12H8v-7c-.5 0-1 0-1.4-.3A3.4 3.4 0 0 1 4.8 10a3.3 3.3 0 0 1 0-2.8 3.4 3.4 0 0 1 1.8-1.8L8 5zm12 11.2a1 1 0 1 1-1 1.6l-3-2a1 1 0 0 1 0-1.6l3-2a1 1 0 1 1 1 1.6L18.4 15l1.8 1.2z" fill-rule="evenodd"/></svg>',
12410 'save': '<svg width="24" height="24"><path d="M5 16h14a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2c0-1.1.9-2 2-2zm0 2v2h14v-2H5zm10 0h2v2h-2v-2zm-4-6.4L8.7 9.3a1 1 0 1 0-1.4 1.4l4 4c.4.4 1 .4 1.4 0l4-4a1 1 0 1 0-1.4-1.4L13 11.6V4a1 1 0 0 0-2 0v7.6z" fill-rule="nonzero"/></svg>',
12411 'search': '<svg width="24" height="24"><path d="M16 17.3a8 8 0 1 1 1.4-1.4l4.3 4.4a1 1 0 0 1-1.4 1.4l-4.4-4.3zm-5-.3a6 6 0 1 0 0-12 6 6 0 0 0 0 12z" fill-rule="nonzero"/></svg>',
12412 'select-all': '<svg width="24" height="24"><path d="M3 5h2V3a2 2 0 0 0-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2a2 2 0 0 0-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8a2 2 0 0 0 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2zM7 17h10V7H7v10zm2-8h6v6H9V9z" fill-rule="nonzero"/></svg>',
12413 'selected': '<svg width="24" height="24"><path fill-rule="nonzero" d="M6 4h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2zm3.6 10.9L7 12.3a.7.7 0 0 0-1 1L9.6 17 18 8.6a.7.7 0 0 0 0-1 .7.7 0 0 0-1 0l-7.4 7.3z"/></svg>',
12414 'settings': '<svg width="24" height="24"><path d="M11 6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8v.3c0 .2 0 .3-.2.5l-.6.2H7.8c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6V8H5a1 1 0 1 1 0-2h2v-.3c0-.2 0-.3.2-.5l.5-.2h2.5c.3 0 .4 0 .6.2l.2.5V6zM8 8h2V6H8v2zm9 2.8v.2h2c.6 0 1 .4 1 1s-.4 1-1 1h-2v.3c0 .2 0 .3-.2.5l-.6.2h-2.4c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6V13H5a1 1 0 0 1 0-2h8v-.3c0-.2 0-.3.2-.5l.6-.2h2.4c.3 0 .4 0 .6.2l.2.6zM14 13h2v-2h-2v2zm-3 2.8v.2h8c.6 0 1 .4 1 1s-.4 1-1 1h-8v.3c0 .2 0 .3-.2.5l-.6.2H7.8c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6V18H5a1 1 0 0 1 0-2h2v-.3c0-.2 0-.3.2-.5l.5-.2h2.5c.3 0 .4 0 .6.2l.2.6zM8 18h2v-2H8v2z" fill-rule="evenodd"/></svg>',
12415 'sharpen': '<svg width="24" height="24"><path d="M16 6l4 4-8 9-8-9 4-4h8zm-4 10.2l5.5-6.2-.1-.1H12v-.3h5.1l-.2-.2H12V9h4.6l-.2-.2H12v-.3h4.1l-.2-.2H12V8h3.6l-.2-.2H8.7L6.5 10l.1.1H12v.3H6.9l.2.2H12v.3H7.3l.2.2H12v.3H7.7l.3.2h4v.3H8.2l.2.2H12v.3H8.6l.3.2H12v.3H9l.3.2H12v.3H9.5l.2.2H12v.3h-2l.2.2H12v.3h-1.6l.2.2H12v.3h-1.1l.2.2h.9v.3h-.7l.2.2h.5v.3h-.3l.3.2z" fill-rule="evenodd"/></svg>',
12416 'sourcecode': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M9.8 15.7c.3.3.3.8 0 1-.3.4-.9.4-1.2 0l-4.4-4.1a.8.8 0 0 1 0-1.2l4.4-4.2c.3-.3.9-.3 1.2 0 .3.3.3.8 0 1.1L6 12l3.8 3.7zM14.2 15.7c-.3.3-.3.8 0 1 .4.4.9.4 1.2 0l4.4-4.1c.3-.3.3-.9 0-1.2l-4.4-4.2a.8.8 0 0 0-1.2 0c-.3.3-.3.8 0 1.1L18 12l-3.8 3.7z"/></g></svg>',
12417 'spell-check': '<svg width="24" height="24"><path d="M6 8v3H5V5c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h2c.3 0 .5.1.7.3.2.2.3.4.3.7v6H8V8H6zm0-3v2h2V5H6zm13 0h-3v5h3v1h-3a1 1 0 0 1-.7-.3 1 1 0 0 1-.3-.7V5c0-.3.1-.5.3-.7.2-.2.4-.3.7-.3h3v1zm-5 1.5l-.1.7c-.1.2-.3.3-.6.3.3 0 .5.1.6.3l.1.7V10c0 .3-.1.5-.3.7a1 1 0 0 1-.7.3h-3V4h3c.3 0 .5.1.7.3.2.2.3.4.3.7v1.5zM13 10V8h-2v2h2zm0-3V5h-2v2h2zm3 5l1 1-6.5 7L7 15.5l1.3-1 2.2 2.2L16 12z" fill-rule="evenodd"/></svg>',
12418 'strike-through': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M15.6 8.5c-.5-.7-1-1.1-1.3-1.3-.6-.4-1.3-.6-2-.6-2.7 0-2.8 1.7-2.8 2.1 0 1.6 1.8 2 3.2 2.3 4.4.9 4.6 2.8 4.6 3.9 0 1.4-.7 4.1-5 4.1A6.2 6.2 0 0 1 7 16.4l1.5-1.1c.4.6 1.6 2 3.7 2 1.6 0 2.5-.4 3-1.2.4-.8.3-2-.8-2.6-.7-.4-1.6-.7-2.9-1-1-.2-3.9-.8-3.9-3.6C7.6 6 10.3 5 12.4 5c2.9 0 4.2 1.6 4.7 2.4l-1.5 1.1z"/><path d="M5 11h14a1 1 0 0 1 0 2H5a1 1 0 0 1 0-2z" fill-rule="nonzero"/></g></svg>',
12419 'subscript': '<svg width="24" height="24"><path d="M10.4 10l4.6 4.6-1.4 1.4L9 11.4 4.4 16 3 14.6 7.6 10 3 5.4 4.4 4 9 8.6 13.6 4 15 5.4 10.4 10zM21 19h-5v-1l1-.8 1.7-1.6c.3-.4.5-.8.5-1.2 0-.3 0-.6-.2-.7-.2-.2-.5-.3-.9-.3a2 2 0 0 0-.8.2l-.7.3-.4-1.1 1-.6 1.2-.2c.8 0 1.4.3 1.8.7.4.4.6.9.6 1.5s-.2 1.1-.5 1.6a8 8 0 0 1-1.3 1.3l-.6.6h2.6V19z" fill-rule="nonzero"/></svg>',
12420 'superscript': '<svg width="24" height="24"><path d="M15 9.4L10.4 14l4.6 4.6-1.4 1.4L9 15.4 4.4 20 3 18.6 7.6 14 3 9.4 4.4 8 9 12.6 13.6 8 15 9.4zm5.9 1.6h-5v-1l1-.8 1.7-1.6c.3-.5.5-.9.5-1.3 0-.3 0-.5-.2-.7-.2-.2-.5-.3-.9-.3l-.8.2-.7.4-.4-1.2c.2-.2.5-.4 1-.5.3-.2.8-.2 1.2-.2.8 0 1.4.2 1.8.6.4.4.6 1 .6 1.6 0 .5-.2 1-.5 1.5l-1.3 1.4-.6.5h2.6V11z" fill-rule="nonzero"/></svg>',
12421 'table-cell-properties': '<svg width="24" height="24"><path d="M4 5h16v14H4V5zm10 10h-4v3h4v-3zm0-8h-4v3h4V7zM9 7H5v3h4V7zm-4 4v3h4v-3H5zm10 0v3h4v-3h-4zm0-1h4V7h-4v3zM5 15v3h4v-3H5zm10 3h4v-3h-4v3z" fill-rule="evenodd"/></svg>',
12422 'table-cell-select-all': '<svg width="24" height="24"><path d="M12.5 5.5v6h6v-6h-6zm-1 0h-6v6h6v-6zm1 13h6v-6h-6v6zm-1 0v-6h-6v6h6zm-7-14h15v15h-15v-15z" fill-rule="nonzero"/></svg>',
12423 'table-cell-select-inner': '<svg width="24" height="24"><g fill-rule="nonzero"><path d="M5.5 5.5v13h13v-13h-13zm-1-1h15v15h-15v-15z" opacity=".2"/><path d="M11.5 11.5v-7h1v7h7v1h-7v7h-1v-7h-7v-1h7z"/></g></svg>',
12424 'table-delete-column': '<svg width="24" height="24"><path d="M9 11.2l1 1v.2l-1 1v-2.2zm5 1l1-1v2.2l-1-1v-.2zM20 5v14H4V5h16zm-1 2h-4v.8l-.2-.2-.8.8V7h-4v1.4l-.8-.8-.2.2V7H5v11h4v-1.8l.5.5.5-.4V18h4v-1.8l.8.8.2-.3V18h4V7zm-3.9 3.4l-1.8 1.9 1.8 1.9c.4.3.4.9 0 1.2-.3.3-.8.3-1.2 0L12 13.5l-1.8 1.9a.8.8 0 0 1-1.2 0 .9.9 0 0 1 0-1.2l1.8-1.9-1.9-2a.9.9 0 0 1 1.2-1.2l2 2 1.8-1.8c.3-.4.9-.4 1.2 0a.8.8 0 0 1 0 1.1z" fill-rule="evenodd"/></svg>',
12425 'table-delete-row': '<svg width="24" height="24"><path d="M16.7 8.8l1.1 1.2-2.4 2.5L18 15l-1.2 1.2-2.5-2.5-2.4 2.5-1.3-1.2 2.5-2.5-2.5-2.5 1.2-1.3 2.6 2.6 2.4-2.5zM4 5h16v14H4V5zm15 5V7H5v3h4.8l1 1H5v3h5.8l-1 1H5v3h14v-3h-.4l-1-1H19v-3h-1.3l1-1h.3z" fill-rule="evenodd"/></svg>',
12426 'table-delete-table': '<svg width="24" height="26"><path d="M4 6h16v14H4V6zm1 2v11h14V8H5zm11.7 8.7l-1.5 1.5L12 15l-3.3 3.2-1.4-1.5 3.2-3.2-3.3-3.2 1.5-1.5L12 12l3.2-3.2 1.5 1.5-3.2 3.2 3.2 3.2z" fill-rule="evenodd"/></svg>',
12427 'table-insert-column-after': '<svg width="24" height="24"><path d="M14.3 9c.4 0 .7.3.7.6v2.2h2.1c.4 0 .7.3.7.7 0 .4-.3.7-.7.7H15v2.2c0 .3-.3.6-.7.6a.7.7 0 0 1-.6-.6v-2.2h-2.2a.7.7 0 0 1 0-1.4h2.2V9.6c0-.3.3-.6.6-.6zM4 5h16v14H4V5zm5 13v-3H5v3h4zm0-4v-3H5v3h4zm0-4V7H5v3h4zm10 8V7h-9v11h9z" fill-rule="evenodd"/></svg>',
12428 'table-insert-column-before': '<svg width="24" height="24"><path d="M9.7 16a.7.7 0 0 1-.7-.6v-2.2H6.9a.7.7 0 0 1 0-1.4H9V9.6c0-.3.3-.6.7-.6.3 0 .6.3.6.6v2.2h2.2c.4 0 .8.3.8.7 0 .4-.4.7-.8.7h-2.2v2.2c0 .3-.3.6-.6.6zM4 5h16v14H4V5zm10 13V7H5v11h9zm5 0v-3h-4v3h4zm0-4v-3h-4v3h4zm0-4V7h-4v3h4z" fill-rule="evenodd"/></svg>',
12429 'table-insert-row-above': '<svg width="24" height="24"><path d="M14.8 10.5c0 .3-.2.5-.5.5h-1.8v1.8c0 .3-.2.5-.5.5a.5.5 0 0 1-.5-.6V11H9.7a.5.5 0 0 1 0-1h1.8V8.3c0-.3.2-.6.5-.6s.5.3.5.6V10h1.8c.3 0 .5.2.5.5zM4 5h16v14H4V5zm5 13v-3H5v3h4zm5 0v-3h-4v3h4zm5 0v-3h-4v3h4zm0-4V7H5v7h14z" fill-rule="evenodd"/></svg>',
12430 'table-insert-row-after': '<svg width="24" height="24"><path d="M9.2 14.5c0-.3.2-.5.5-.5h1.8v-1.8c0-.3.2-.5.5-.5s.5.2.5.6V14h1.8c.3 0 .5.2.5.5s-.2.5-.5.5h-1.8v1.7c0 .3-.2.6-.5.6a.5.5 0 0 1-.5-.6V15H9.7a.5.5 0 0 1-.5-.5zM4 5h16v14H4V5zm6 2v3h4V7h-4zM5 7v3h4V7H5zm14 11v-7H5v7h14zm0-8V7h-4v3h4z" fill-rule="evenodd"/></svg>',
12431 'table-left-header': '<svg width="24" height="24"><path d="M4 5h16v13H4V5zm10 12v-3h-4v3h4zm0-4v-3h-4v3h4zm0-4V6h-4v3h4zm5 8v-3h-4v3h4zm0-4v-3h-4v3h4zm0-4V6h-4v3h4z" fill-rule="evenodd"/></svg>',
12432 'table-merge-cells': '<svg width="24" height="24"><path d="M4 5h16v14H4V5zm6 13h9v-7h-9v7zm4-11h-4v3h4V7zM9 7H5v3h4V7zm-4 4v3h4v-3H5zm10-1h4V7h-4v3zM5 15v3h4v-3H5z" fill-rule="evenodd"/></svg>',
12433 'table-row-properties': '<svg width="24" height="24"><path d="M4 5h16v14H4V5zm10 10h-4v3h4v-3zm0-8h-4v3h4V7zM9 7H5v3h4V7zm6 3h4V7h-4v3zM5 15v3h4v-3H5zm10 3h4v-3h-4v3z" fill-rule="evenodd"/></svg>',
12434 'table-split-cells': '<svg width="24" height="24"><path d="M4 5h16v14H4V5zm6 2v3h4V7h-4zM9 18v-3H5v3h4zm0-4v-3H5v3h4zm0-4V7H5v3h4zm10 8v-7h-9v7h9zm0-8V7h-4v3h4zm-3.5 4.5l1.5 1.6c.3.2.3.7 0 1-.2.2-.7.2-1 0l-1.5-1.6-1.6 1.5c-.2.3-.7.3-1 0a.7.7 0 0 1 0-1l1.6-1.5-1.5-1.6a.7.7 0 0 1 1-1l1.5 1.6 1.6-1.5c.2-.3.7-.3 1 0 .2.2.2.7 0 1l-1.6 1.5z" fill-rule="evenodd"/></svg>',
12435 'table-top-header': '<svg width="24" height="24"><path d="M4 5h16v13H4V5zm5 12v-3H5v3h4zm0-4v-3H5v3h4zm5 4v-3h-4v3h4zm0-4v-3h-4v3h4zm5 4v-3h-4v3h4zm0-4v-3h-4v3h4z" fill-rule="evenodd"/></svg>',
12436 'table': '<svg width="24" height="24"><path d="M4 5h16v14H4V5zm6 9h4v-3h-4v3zm4 1h-4v3h4v-3zm0-8h-4v3h4V7zM9 7H5v3h4V7zm-4 4v3h4v-3H5zm10 0v3h4v-3h-4zm0-1h4V7h-4v3zM5 15v3h4v-3H5zm10 3h4v-3h-4v3z" fill-rule="evenodd"/></svg>',
12437 'template': '<svg width="24" height="24"><path d="M19 19v-1H5v1h14zM9 16v-4a5 5 0 1 1 6 0v4h4a2 2 0 0 1 2 2v3H3v-3c0-1.1.9-2 2-2h4zm4 0v-5l.8-.6a3 3 0 1 0-3.6 0l.8.6v5h2z" fill-rule="nonzero"/></svg>',
12438 'temporary-placeholder': '<svg width="24" height="24"><g fill-rule="evenodd"><path d="M9 7.6V6h2.5V4.5a.5.5 0 1 1 1 0V6H15v1.6a8 8 0 1 1-6 0zm-2.6 5.3a.5.5 0 0 0 .3.6c.3 0 .6 0 .6-.3l.1-.2a5 5 0 0 1 3.3-2.8c.3-.1.4-.4.4-.6-.1-.3-.4-.5-.6-.4a6 6 0 0 0-4.1 3.7z"/><circle cx="14" cy="4" r="1"/><circle cx="12" cy="2" r="1"/><circle cx="10" cy="4" r="1"/></g></svg>',
12439 'text-color': '<svg width="24" height="24"><g fill-rule="evenodd"><path id="tox-icon-text-color__color" d="M3 18h18v3H3z"/><path d="M8.7 16h-.8a.5.5 0 0 1-.5-.6l2.7-9c.1-.3.3-.4.5-.4h2.8c.2 0 .4.1.5.4l2.7 9a.5.5 0 0 1-.5.6h-.8a.5.5 0 0 1-.4-.4l-.7-2.2c0-.3-.3-.4-.5-.4h-3.4c-.2 0-.4.1-.5.4l-.7 2.2c0 .3-.2.4-.4.4zm2.6-7.6l-.6 2a.5.5 0 0 0 .5.6h1.6a.5.5 0 0 0 .5-.6l-.6-2c0-.3-.3-.4-.5-.4h-.4c-.2 0-.4.1-.5.4z"/></g></svg>',
12440 'toc': '<svg width="24" height="24"><path d="M5 5c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 1 1 0-2zm3 0h11c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 1 1 0-2zm-3 8c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2zm3 0h11c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 0 1 0-2zm0-4c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 1 1 0-2zm3 0h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm-3 8c.6 0 1 .4 1 1s-.4 1-1 1a1 1 0 0 1 0-2zm3 0h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2z" fill-rule="evenodd"/></svg>',
12441 'translate': '<svg width="24" height="24"><path d="M12.7 14.3l-.3.7-.4.7-2.2-2.2-3.1 3c-.3.4-.8.4-1 0a.7.7 0 0 1 0-1l3.1-3A12.4 12.4 0 0 1 6.7 9H8a10.1 10.1 0 0 0 1.7 2.4c.5-.5 1-1.1 1.4-1.8l.9-2H4.7a.7.7 0 1 1 0-1.5h4.4v-.7c0-.4.3-.8.7-.8.4 0 .7.4.7.8v.7H15c.4 0 .8.3.8.7 0 .4-.4.8-.8.8h-1.4a12.3 12.3 0 0 1-1 2.4 13.5 13.5 0 0 1-1.7 2.3l1.9 1.8zm4.3-3l2.7 7.3a.5.5 0 0 1-.4.7 1 1 0 0 1-1-.7l-.6-1.5h-3.4l-.6 1.5a1 1 0 0 1-1 .7.5.5 0 0 1-.4-.7l2.7-7.4a1 1 0 1 1 2 0zm-2.2 4.4h2.4L16 12.5l-1.2 3.2z" fill-rule="evenodd"/></svg>',
12442 'underline': '<svg width="24" height="24"><path d="M16 5c.6 0 1 .4 1 1v5.5a4 4 0 0 1-.4 1.8l-1 1.4a5.3 5.3 0 0 1-5.5 1 5 5 0 0 1-1.6-1c-.5-.4-.8-.9-1.1-1.4a4 4 0 0 1-.4-1.8V6c0-.6.4-1 1-1s1 .4 1 1v5.5c0 .3 0 .6.2 1l.6.7a3.3 3.3 0 0 0 2.2.8 3.4 3.4 0 0 0 2.2-.8c.3-.2.4-.5.6-.8l.2-.9V6c0-.6.4-1 1-1zM8 17h8c.6 0 1 .4 1 1s-.4 1-1 1H8a1 1 0 0 1 0-2z" fill-rule="evenodd"/></svg>',
12443 'undo': '<svg width="24" height="24"><path d="M6.4 8H12c3.7 0 6.2 2 6.8 5.1.6 2.7-.4 5.6-2.3 6.8a1 1 0 0 1-1-1.8c1.1-.6 1.8-2.7 1.4-4.6-.5-2.1-2.1-3.5-4.9-3.5H6.4l3.3 3.3a1 1 0 1 1-1.4 1.4l-5-5a1 1 0 0 1 0-1.4l5-5a1 1 0 0 1 1.4 1.4L6.4 8z" fill-rule="nonzero"/></svg>',
12444 'unlink': '<svg width="24" height="24"><path d="M6.2 12.3a1 1 0 0 1 1.4 1.4l-2 2a2 2 0 1 0 2.6 2.8l4.8-4.8a1 1 0 0 0 0-1.4 1 1 0 1 1 1.4-1.3 2.9 2.9 0 0 1 0 4L9.6 20a3.9 3.9 0 0 1-5.5-5.5l2-2zm11.6-.6a1 1 0 0 1-1.4-1.4l2.1-2a2 2 0 1 0-2.7-2.8L11 10.3a1 1 0 0 0 0 1.4A1 1 0 1 1 9.6 13a2.9 2.9 0 0 1 0-4L14.4 4a3.9 3.9 0 0 1 5.5 5.5l-2 2zM7.6 6.3a.8.8 0 0 1-1 1.1L3.3 4.2a.7.7 0 1 1 1-1l3.2 3.1zM5.1 8.6a.8.8 0 0 1 0 1.5H3a.8.8 0 0 1 0-1.5H5zm5-3.5a.8.8 0 0 1-1.5 0V3a.8.8 0 0 1 1.5 0V5zm6 11.8a.8.8 0 0 1 1-1l3.2 3.2a.8.8 0 0 1-1 1L16 17zm-2.2 2a.8.8 0 0 1 1.5 0V21a.8.8 0 0 1-1.5 0V19zm5-3.5a.7.7 0 1 1 0-1.5H21a.8.8 0 0 1 0 1.5H19z" fill-rule="nonzero"/></svg>',
12445 'unlock': '<svg width="24" height="24"><path d="M16 5c.8 0 1.5.3 2.1.9.6.6.9 1.3.9 2.1v3h-2V8a1 1 0 0 0-.3-.7A1 1 0 0 0 16 7h-2a1 1 0 0 0-.7.3 1 1 0 0 0-.3.7v3h.3c.2 0 .3 0 .5.2l.2.6v7.4c0 .3 0 .4-.2.6l-.6.2H4.8c-.3 0-.4 0-.6-.2a.7.7 0 0 1-.2-.6v-7.4c0-.3 0-.4.2-.6l.5-.2H11V8c0-.8.3-1.5.9-2.1.6-.6 1.3-.9 2.1-.9h2z" fill-rule="evenodd"/></svg>',
12446 'unordered-list': '<svg width="24" height="24"><path d="M11 5h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0 6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zm0 6h8c.6 0 1 .4 1 1s-.4 1-1 1h-8a1 1 0 0 1 0-2zM4.5 6c0-.4.1-.8.4-1 .3-.4.7-.5 1.1-.5.4 0 .8.1 1 .4.4.3.5.7.5 1.1 0 .4-.1.8-.4 1-.3.4-.7.5-1.1.5-.4 0-.8-.1-1-.4-.4-.3-.5-.7-.5-1.1zm0 6c0-.4.1-.8.4-1 .3-.4.7-.5 1.1-.5.4 0 .8.1 1 .4.4.3.5.7.5 1.1 0 .4-.1.8-.4 1-.3.4-.7.5-1.1.5-.4 0-.8-.1-1-.4-.4-.3-.5-.7-.5-1.1zm0 6c0-.4.1-.8.4-1 .3-.4.7-.5 1.1-.5.4 0 .8.1 1 .4.4.3.5.7.5 1.1 0 .4-.1.8-.4 1-.3.4-.7.5-1.1.5-.4 0-.8-.1-1-.4-.4-.3-.5-.7-.5-1.1z" fill-rule="evenodd"/></svg>',
12447 'unselected': '<svg width="24" height="24"><path fill-rule="nonzero" d="M6 4h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2zm0 1a1 1 0 0 0-1 1v12c0 .6.4 1 1 1h12c.6 0 1-.4 1-1V6c0-.6-.4-1-1-1H6z"/></svg>',
12448 'upload': '<svg width="24" height="24"><path d="M18 19v-2a1 1 0 0 1 2 0v3c0 .6-.4 1-1 1H5a1 1 0 0 1-1-1v-3a1 1 0 0 1 2 0v2h12zM11 6.4L8.7 8.7a1 1 0 0 1-1.4-1.4l4-4a1 1 0 0 1 1.4 0l4 4a1 1 0 1 1-1.4 1.4L13 6.4V16a1 1 0 0 1-2 0V6.4z" fill-rule="nonzero"/></svg>',
12449 'user': '<svg width="24" height="24"><path d="M12 24a12 12 0 1 1 0-24 12 12 0 0 1 0 24zm-8.7-5.3a11 11 0 0 0 17.4 0C19.4 16.3 14.6 15 12 15c-2.6 0-7.4 1.3-8.7 3.7zM12 13c2.2 0 4-2 4-4.5S14.2 4 12 4 8 6 8 8.5 9.8 13 12 13z" fill-rule="nonzero"/></svg>',
12450 'warning': '<svg width="24" height="24"><path d="M19.8 18.3c.2.5.3.9 0 1.2-.1.3-.5.5-1 .5H5.2c-.5 0-.9-.2-1-.5-.3-.3-.2-.7 0-1.2L11 4.7l.5-.5.5-.2c.2 0 .3 0 .5.2.2 0 .3.3.5.5l6.8 13.6zM12 18c.3 0 .5-.1.7-.3.2-.2.3-.4.3-.7a1 1 0 0 0-.3-.7 1 1 0 0 0-.7-.3 1 1 0 0 0-.7.3 1 1 0 0 0-.3.7c0 .3.1.5.3.7.2.2.4.3.7.3zm.7-3l.3-4a1 1 0 0 0-.3-.7 1 1 0 0 0-.7-.3 1 1 0 0 0-.7.3 1 1 0 0 0-.3.7l.3 4h1.4z" fill-rule="evenodd"/></svg>',
12451 'zoom-in': '<svg width="24" height="24"><path d="M16 17.3a8 8 0 1 1 1.4-1.4l4.3 4.4a1 1 0 0 1-1.4 1.4l-4.4-4.3zm-5-.3a6 6 0 1 0 0-12 6 6 0 0 0 0 12zm-1-9a1 1 0 0 1 2 0v6a1 1 0 0 1-2 0V8zm-2 4a1 1 0 0 1 0-2h6a1 1 0 0 1 0 2H8z" fill-rule="nonzero"/></svg>',
12452 'zoom-out': '<svg width="24" height="24"><path d="M16 17.3a8 8 0 1 1 1.4-1.4l4.3 4.4a1 1 0 0 1-1.4 1.4l-4.4-4.3zm-5-.3a6 6 0 1 0 0-12 6 6 0 0 0 0 12zm-3-5a1 1 0 0 1 0-2h6a1 1 0 0 1 0 2H8z" fill-rule="nonzero"/></svg>'
12453 };
12454 };
12455
12456 var CreateIconManager = function () {
12457 var lookup = {};
12458 var add = function (id, iconPack) {
12459 lookup[id] = iconPack;
12460 };
12461 var get = function (id) {
12462 if (lookup[id]) {
12463 return lookup[id];
12464 }
12465 return { icons: {} };
12466 };
12467 var has$1 = function (id) {
12468 return has(lookup, id);
12469 };
12470 return {
12471 add: add,
12472 get: get,
12473 has: has$1
12474 };
12475 };
12476 var IconManager = CreateIconManager();
12477
12478 var PluginManager = AddOnManager$1.PluginManager;
12479
12480 var ThemeManager = AddOnManager$1.ThemeManager;
12481
12482 function XMLHttpRequest () {
12483 var f = Global$1.getOrDie('XMLHttpRequest');
12484 return new f();
12485 }
12486
12487 function Uploader(uploadStatus, settings) {
12488 var pendingPromises = {};
12489 var pathJoin = function (path1, path2) {
12490 if (path1) {
12491 return path1.replace(/\/$/, '') + '/' + path2.replace(/^\//, '');
12492 }
12493 return path2;
12494 };
12495 var defaultHandler = function (blobInfo, success, failure, progress) {
12496 var xhr, formData;
12497 xhr = XMLHttpRequest();
12498 xhr.open('POST', settings.url);
12499 xhr.withCredentials = settings.credentials;
12500 xhr.upload.onprogress = function (e) {
12501 progress(e.loaded / e.total * 100);
12502 };
12503 xhr.onerror = function () {
12504 failure('Image upload failed due to a XHR Transport error. Code: ' + xhr.status);
12505 };
12506 xhr.onload = function () {
12507 var json;
12508 if (xhr.status < 200 || xhr.status >= 300) {
12509 failure('HTTP Error: ' + xhr.status);
12510 return;
12511 }
12512 json = JSON.parse(xhr.responseText);
12513 if (!json || typeof json.location !== 'string') {
12514 failure('Invalid JSON: ' + xhr.responseText);
12515 return;
12516 }
12517 success(pathJoin(settings.basePath, json.location));
12518 };
12519 formData = new domGlobals.FormData();
12520 formData.append('file', blobInfo.blob(), blobInfo.filename());
12521 xhr.send(formData);
12522 };
12523 var noUpload = function () {
12524 return new promiseObj(function (resolve) {
12525 resolve([]);
12526 });
12527 };
12528 var handlerSuccess = function (blobInfo, url) {
12529 return {
12530 url: url,
12531 blobInfo: blobInfo,
12532 status: true
12533 };
12534 };
12535 var handlerFailure = function (blobInfo, error) {
12536 return {
12537 url: '',
12538 blobInfo: blobInfo,
12539 status: false,
12540 error: error
12541 };
12542 };
12543 var resolvePending = function (blobUri, result) {
12544 Tools.each(pendingPromises[blobUri], function (resolve) {
12545 resolve(result);
12546 });
12547 delete pendingPromises[blobUri];
12548 };
12549 var uploadBlobInfo = function (blobInfo, handler, openNotification) {
12550 uploadStatus.markPending(blobInfo.blobUri());
12551 return new promiseObj(function (resolve) {
12552 var notification, progress;
12553 var noop = function () {
12554 };
12555 try {
12556 var closeNotification_1 = function () {
12557 if (notification) {
12558 notification.close();
12559 progress = noop;
12560 }
12561 };
12562 var success = function (url) {
12563 closeNotification_1();
12564 uploadStatus.markUploaded(blobInfo.blobUri(), url);
12565 resolvePending(blobInfo.blobUri(), handlerSuccess(blobInfo, url));
12566 resolve(handlerSuccess(blobInfo, url));
12567 };
12568 var failure = function (error) {
12569 closeNotification_1();
12570 uploadStatus.removeFailed(blobInfo.blobUri());
12571 resolvePending(blobInfo.blobUri(), handlerFailure(blobInfo, error));
12572 resolve(handlerFailure(blobInfo, error));
12573 };
12574 progress = function (percent) {
12575 if (percent < 0 || percent > 100) {
12576 return;
12577 }
12578 if (!notification) {
12579 notification = openNotification();
12580 }
12581 notification.progressBar.value(percent);
12582 };
12583 handler(blobInfo, success, failure, progress);
12584 } catch (ex) {
12585 resolve(handlerFailure(blobInfo, ex.message));
12586 }
12587 });
12588 };
12589 var isDefaultHandler = function (handler) {
12590 return handler === defaultHandler;
12591 };
12592 var pendingUploadBlobInfo = function (blobInfo) {
12593 var blobUri = blobInfo.blobUri();
12594 return new promiseObj(function (resolve) {
12595 pendingPromises[blobUri] = pendingPromises[blobUri] || [];
12596 pendingPromises[blobUri].push(resolve);
12597 });
12598 };
12599 var uploadBlobs = function (blobInfos, openNotification) {
12600 blobInfos = Tools.grep(blobInfos, function (blobInfo) {
12601 return !uploadStatus.isUploaded(blobInfo.blobUri());
12602 });
12603 return promiseObj.all(Tools.map(blobInfos, function (blobInfo) {
12604 return uploadStatus.isPending(blobInfo.blobUri()) ? pendingUploadBlobInfo(blobInfo) : uploadBlobInfo(blobInfo, settings.handler, openNotification);
12605 }));
12606 };
12607 var upload = function (blobInfos, openNotification) {
12608 return !settings.url && isDefaultHandler(settings.handler) ? noUpload() : uploadBlobs(blobInfos, openNotification);
12609 };
12610 if (isFunction(settings.handler) === false) {
12611 settings.handler = defaultHandler;
12612 }
12613 return { upload: upload };
12614 }
12615
12616 function FileReader () {
12617 var f = Global$1.getOrDie('FileReader');
12618 return new f();
12619 }
12620
12621 function Uint8Array (arr) {
12622 var f = Global$1.getOrDie('Uint8Array');
12623 return new f(arr);
12624 }
12625
12626 var requestAnimationFrame$1 = function (callback) {
12627 var f = Global$1.getOrDie('requestAnimationFrame');
12628 f(callback);
12629 };
12630 var atob = function (base64) {
12631 var f = Global$1.getOrDie('atob');
12632 return f(base64);
12633 };
12634 var Window = {
12635 atob: atob,
12636 requestAnimationFrame: requestAnimationFrame$1
12637 };
12638
12639 var blobUriToBlob = function (url) {
12640 return new promiseObj(function (resolve, reject) {
12641 var rejectWithError = function () {
12642 reject('Cannot convert ' + url + ' to Blob. Resource might not exist or is inaccessible.');
12643 };
12644 try {
12645 var xhr = XMLHttpRequest();
12646 xhr.open('GET', url, true);
12647 xhr.responseType = 'blob';
12648 xhr.onload = function () {
12649 if (this.status === 200) {
12650 resolve(this.response);
12651 } else {
12652 rejectWithError();
12653 }
12654 };
12655 xhr.onerror = rejectWithError;
12656 xhr.send();
12657 } catch (ex) {
12658 rejectWithError();
12659 }
12660 });
12661 };
12662 var parseDataUri = function (uri) {
12663 var type, matches;
12664 var uriParts = decodeURIComponent(uri).split(',');
12665 matches = /data:([^;]+)/.exec(uriParts[0]);
12666 if (matches) {
12667 type = matches[1];
12668 }
12669 return {
12670 type: type,
12671 data: uriParts[1]
12672 };
12673 };
12674 var dataUriToBlob = function (uri) {
12675 return new promiseObj(function (resolve) {
12676 var str, arr, i;
12677 var uriParts = parseDataUri(uri);
12678 try {
12679 str = Window.atob(uriParts.data);
12680 } catch (e) {
12681 resolve(new domGlobals.Blob([]));
12682 return;
12683 }
12684 arr = Uint8Array(str.length);
12685 for (i = 0; i < arr.length; i++) {
12686 arr[i] = str.charCodeAt(i);
12687 }
12688 resolve(new domGlobals.Blob([arr], { type: uriParts.type }));
12689 });
12690 };
12691 var uriToBlob = function (url) {
12692 if (url.indexOf('blob:') === 0) {
12693 return blobUriToBlob(url);
12694 }
12695 if (url.indexOf('data:') === 0) {
12696 return dataUriToBlob(url);
12697 }
12698 return null;
12699 };
12700 var blobToDataUri = function (blob) {
12701 return new promiseObj(function (resolve) {
12702 var reader = FileReader();
12703 reader.onloadend = function () {
12704 resolve(reader.result);
12705 };
12706 reader.readAsDataURL(blob);
12707 });
12708 };
12709 var Conversions = {
12710 uriToBlob: uriToBlob,
12711 blobToDataUri: blobToDataUri,
12712 parseDataUri: parseDataUri
12713 };
12714
12715 var count = 0;
12716 var uniqueId = function (prefix) {
12717 return (prefix || 'blobid') + count++;
12718 };
12719 var imageToBlobInfo = function (blobCache, img, resolve, reject) {
12720 var base64, blobInfo;
12721 if (img.src.indexOf('blob:') === 0) {
12722 blobInfo = blobCache.getByUri(img.src);
12723 if (blobInfo) {
12724 resolve({
12725 image: img,
12726 blobInfo: blobInfo
12727 });
12728 } else {
12729 Conversions.uriToBlob(img.src).then(function (blob) {
12730 Conversions.blobToDataUri(blob).then(function (dataUri) {
12731 base64 = Conversions.parseDataUri(dataUri).data;
12732 blobInfo = blobCache.create(uniqueId(), blob, base64);
12733 blobCache.add(blobInfo);
12734 resolve({
12735 image: img,
12736 blobInfo: blobInfo
12737 });
12738 });
12739 }, function (err) {
12740 reject(err);
12741 });
12742 }
12743 return;
12744 }
12745 base64 = Conversions.parseDataUri(img.src).data;
12746 blobInfo = blobCache.findFirst(function (cachedBlobInfo) {
12747 return cachedBlobInfo.base64() === base64;
12748 });
12749 if (blobInfo) {
12750 resolve({
12751 image: img,
12752 blobInfo: blobInfo
12753 });
12754 } else {
12755 Conversions.uriToBlob(img.src).then(function (blob) {
12756 blobInfo = blobCache.create(uniqueId(), blob, base64);
12757 blobCache.add(blobInfo);
12758 resolve({
12759 image: img,
12760 blobInfo: blobInfo
12761 });
12762 }, function (err) {
12763 reject(err);
12764 });
12765 }
12766 };
12767 var getAllImages = function (elm) {
12768 return elm ? from$1(elm.getElementsByTagName('img')) : [];
12769 };
12770 function ImageScanner(uploadStatus, blobCache) {
12771 var cachedPromises = {};
12772 var findAll = function (elm, predicate) {
12773 var images;
12774 if (!predicate) {
12775 predicate = constant(true);
12776 }
12777 images = filter(getAllImages(elm), function (img) {
12778 var src = img.src;
12779 if (!Env.fileApi) {
12780 return false;
12781 }
12782 if (img.hasAttribute('data-mce-bogus')) {
12783 return false;
12784 }
12785 if (img.hasAttribute('data-mce-placeholder')) {
12786 return false;
12787 }
12788 if (!src || src === Env.transparentSrc) {
12789 return false;
12790 }
12791 if (src.indexOf('blob:') === 0) {
12792 return !uploadStatus.isUploaded(src) && predicate(img);
12793 }
12794 if (src.indexOf('data:') === 0) {
12795 return predicate(img);
12796 }
12797 return false;
12798 });
12799 var promises = map(images, function (img) {
12800 if (cachedPromises[img.src]) {
12801 return new promiseObj(function (resolve) {
12802 cachedPromises[img.src].then(function (imageInfo) {
12803 if (typeof imageInfo === 'string') {
12804 return imageInfo;
12805 }
12806 resolve({
12807 image: img,
12808 blobInfo: imageInfo.blobInfo
12809 });
12810 });
12811 });
12812 }
12813 var newPromise = new promiseObj(function (resolve, reject) {
12814 imageToBlobInfo(blobCache, img, resolve, reject);
12815 }).then(function (result) {
12816 delete cachedPromises[result.image.src];
12817 return result;
12818 }).catch(function (error) {
12819 delete cachedPromises[img.src];
12820 return error;
12821 });
12822 cachedPromises[img.src] = newPromise;
12823 return newPromise;
12824 });
12825 return promiseObj.all(promises);
12826 };
12827 return { findAll: findAll };
12828 }
12829
12830 var count$1 = 0;
12831 var seed = function () {
12832 var rnd = function () {
12833 return Math.round(Math.random() * 4294967295).toString(36);
12834 };
12835 var now = new Date().getTime();
12836 return 's' + now.toString(36) + rnd() + rnd() + rnd();
12837 };
12838 var uuid = function (prefix) {
12839 return prefix + count$1++ + seed();
12840 };
12841 var Uuid = { uuid: uuid };
12842
12843 var BlobCache = function () {
12844 var cache = [];
12845 var mimeToExt = function (mime) {
12846 var mimes = {
12847 'image/jpeg': 'jpg',
12848 'image/jpg': 'jpg',
12849 'image/gif': 'gif',
12850 'image/png': 'png'
12851 };
12852 return mimes[mime.toLowerCase()] || 'dat';
12853 };
12854 var create = function (o, blob, base64, filename) {
12855 if (isString(o)) {
12856 var id = o;
12857 return toBlobInfo({
12858 id: id,
12859 name: filename,
12860 blob: blob,
12861 base64: base64
12862 });
12863 } else if (isObject(o)) {
12864 return toBlobInfo(o);
12865 } else {
12866 throw new Error('Unknown input type');
12867 }
12868 };
12869 var toBlobInfo = function (o) {
12870 var id, name;
12871 if (!o.blob || !o.base64) {
12872 throw new Error('blob and base64 representations of the image are required for BlobInfo to be created');
12873 }
12874 id = o.id || Uuid.uuid('blobid');
12875 name = o.name || id;
12876 return {
12877 id: constant(id),
12878 name: constant(name),
12879 filename: constant(name + '.' + mimeToExt(o.blob.type)),
12880 blob: constant(o.blob),
12881 base64: constant(o.base64),
12882 blobUri: constant(o.blobUri || URL.createObjectURL(o.blob)),
12883 uri: constant(o.uri)
12884 };
12885 };
12886 var add = function (blobInfo) {
12887 if (!get(blobInfo.id())) {
12888 cache.push(blobInfo);
12889 }
12890 };
12891 var get = function (id) {
12892 return findFirst(function (cachedBlobInfo) {
12893 return cachedBlobInfo.id() === id;
12894 });
12895 };
12896 var findFirst = function (predicate) {
12897 return filter(cache, predicate)[0];
12898 };
12899 var getByUri = function (blobUri) {
12900 return findFirst(function (blobInfo) {
12901 return blobInfo.blobUri() === blobUri;
12902 });
12903 };
12904 var removeByUri = function (blobUri) {
12905 cache = filter(cache, function (blobInfo) {
12906 if (blobInfo.blobUri() === blobUri) {
12907 URL.revokeObjectURL(blobInfo.blobUri());
12908 return false;
12909 }
12910 return true;
12911 });
12912 };
12913 var destroy = function () {
12914 each(cache, function (cachedBlobInfo) {
12915 URL.revokeObjectURL(cachedBlobInfo.blobUri());
12916 });
12917 cache = [];
12918 };
12919 return {
12920 create: create,
12921 add: add,
12922 get: get,
12923 getByUri: getByUri,
12924 findFirst: findFirst,
12925 removeByUri: removeByUri,
12926 destroy: destroy
12927 };
12928 };
12929
12930 function UploadStatus () {
12931 var PENDING = 1, UPLOADED = 2;
12932 var blobUriStatuses = {};
12933 var createStatus = function (status, resultUri) {
12934 return {
12935 status: status,
12936 resultUri: resultUri
12937 };
12938 };
12939 var hasBlobUri = function (blobUri) {
12940 return blobUri in blobUriStatuses;
12941 };
12942 var getResultUri = function (blobUri) {
12943 var result = blobUriStatuses[blobUri];
12944 return result ? result.resultUri : null;
12945 };
12946 var isPending = function (blobUri) {
12947 return hasBlobUri(blobUri) ? blobUriStatuses[blobUri].status === PENDING : false;
12948 };
12949 var isUploaded = function (blobUri) {
12950 return hasBlobUri(blobUri) ? blobUriStatuses[blobUri].status === UPLOADED : false;
12951 };
12952 var markPending = function (blobUri) {
12953 blobUriStatuses[blobUri] = createStatus(PENDING, null);
12954 };
12955 var markUploaded = function (blobUri, resultUri) {
12956 blobUriStatuses[blobUri] = createStatus(UPLOADED, resultUri);
12957 };
12958 var removeFailed = function (blobUri) {
12959 delete blobUriStatuses[blobUri];
12960 };
12961 var destroy = function () {
12962 blobUriStatuses = {};
12963 };
12964 return {
12965 hasBlobUri: hasBlobUri,
12966 getResultUri: getResultUri,
12967 isPending: isPending,
12968 isUploaded: isUploaded,
12969 markPending: markPending,
12970 markUploaded: markUploaded,
12971 removeFailed: removeFailed,
12972 destroy: destroy
12973 };
12974 }
12975
12976 var EditorUpload = function (editor) {
12977 var blobCache = BlobCache();
12978 var uploader, imageScanner;
12979 var uploadStatus = UploadStatus();
12980 var urlFilters = [];
12981 var aliveGuard = function (callback) {
12982 return function (result) {
12983 if (editor.selection) {
12984 return callback(result);
12985 }
12986 return [];
12987 };
12988 };
12989 var cacheInvalidator = function () {
12990 return '?' + new Date().getTime();
12991 };
12992 var replaceString = function (content, search, replace) {
12993 var index = 0;
12994 do {
12995 index = content.indexOf(search, index);
12996 if (index !== -1) {
12997 content = content.substring(0, index) + replace + content.substr(index + search.length);
12998 index += replace.length - search.length + 1;
12999 }
13000 } while (index !== -1);
13001 return content;
13002 };
13003 var replaceImageUrl = function (content, targetUrl, replacementUrl) {
13004 content = replaceString(content, 'src="' + targetUrl + '"', 'src="' + replacementUrl + '"');
13005 content = replaceString(content, 'data-mce-src="' + targetUrl + '"', 'data-mce-src="' + replacementUrl + '"');
13006 return content;
13007 };
13008 var replaceUrlInUndoStack = function (targetUrl, replacementUrl) {
13009 each(editor.undoManager.data, function (level) {
13010 if (level.type === 'fragmented') {
13011 level.fragments = map(level.fragments, function (fragment) {
13012 return replaceImageUrl(fragment, targetUrl, replacementUrl);
13013 });
13014 } else {
13015 level.content = replaceImageUrl(level.content, targetUrl, replacementUrl);
13016 }
13017 });
13018 };
13019 var openNotification = function () {
13020 return editor.notificationManager.open({
13021 text: editor.translate('Image uploading...'),
13022 type: 'info',
13023 timeout: -1,
13024 progressBar: true
13025 });
13026 };
13027 var replaceImageUri = function (image, resultUri) {
13028 blobCache.removeByUri(image.src);
13029 replaceUrlInUndoStack(image.src, resultUri);
13030 editor.$(image).attr({
13031 'src': Settings.shouldReuseFileName(editor) ? resultUri + cacheInvalidator() : resultUri,
13032 'data-mce-src': editor.convertURL(resultUri, 'src')
13033 });
13034 };
13035 var uploadImages = function (callback) {
13036 if (!uploader) {
13037 uploader = Uploader(uploadStatus, {
13038 url: Settings.getImageUploadUrl(editor),
13039 basePath: Settings.getImageUploadBasePath(editor),
13040 credentials: Settings.getImagesUploadCredentials(editor),
13041 handler: Settings.getImagesUploadHandler(editor)
13042 });
13043 }
13044 return scanForImages().then(aliveGuard(function (imageInfos) {
13045 var blobInfos;
13046 blobInfos = map(imageInfos, function (imageInfo) {
13047 return imageInfo.blobInfo;
13048 });
13049 return uploader.upload(blobInfos, openNotification).then(aliveGuard(function (result) {
13050 var filteredResult = map(result, function (uploadInfo, index) {
13051 var image = imageInfos[index].image;
13052 if (uploadInfo.status && Settings.shouldReplaceBlobUris(editor)) {
13053 replaceImageUri(image, uploadInfo.url);
13054 } else if (uploadInfo.error) {
13055 ErrorReporter.uploadError(editor, uploadInfo.error);
13056 }
13057 return {
13058 element: image,
13059 status: uploadInfo.status
13060 };
13061 });
13062 if (callback) {
13063 callback(filteredResult);
13064 }
13065 return filteredResult;
13066 }));
13067 }));
13068 };
13069 var uploadImagesAuto = function (callback) {
13070 if (Settings.isAutomaticUploadsEnabled(editor)) {
13071 return uploadImages(callback);
13072 }
13073 };
13074 var isValidDataUriImage = function (imgElm) {
13075 if (forall(urlFilters, function (filter) {
13076 return filter(imgElm);
13077 }) === false) {
13078 return false;
13079 }
13080 if (imgElm.getAttribute('src').indexOf('data:') === 0) {
13081 var dataImgFilter = Settings.getImagesDataImgFilter(editor);
13082 return dataImgFilter(imgElm);
13083 }
13084 return true;
13085 };
13086 var addFilter = function (filter) {
13087 urlFilters.push(filter);
13088 };
13089 var scanForImages = function () {
13090 if (!imageScanner) {
13091 imageScanner = ImageScanner(uploadStatus, blobCache);
13092 }
13093 return imageScanner.findAll(editor.getBody(), isValidDataUriImage).then(aliveGuard(function (result) {
13094 result = filter(result, function (resultItem) {
13095 if (typeof resultItem === 'string') {
13096 ErrorReporter.displayError(editor, resultItem);
13097 return false;
13098 }
13099 return true;
13100 });
13101 each(result, function (resultItem) {
13102 replaceUrlInUndoStack(resultItem.image.src, resultItem.blobInfo.blobUri());
13103 resultItem.image.src = resultItem.blobInfo.blobUri();
13104 resultItem.image.removeAttribute('data-mce-src');
13105 });
13106 return result;
13107 }));
13108 };
13109 var destroy = function () {
13110 blobCache.destroy();
13111 uploadStatus.destroy();
13112 imageScanner = uploader = null;
13113 };
13114 var replaceBlobUris = function (content) {
13115 return content.replace(/src="(blob:[^"]+)"/g, function (match, blobUri) {
13116 var resultUri = uploadStatus.getResultUri(blobUri);
13117 if (resultUri) {
13118 return 'src="' + resultUri + '"';
13119 }
13120 var blobInfo = blobCache.getByUri(blobUri);
13121 if (!blobInfo) {
13122 blobInfo = foldl(editor.editorManager.get(), function (result, editor) {
13123 return result || editor.editorUpload && editor.editorUpload.blobCache.getByUri(blobUri);
13124 }, null);
13125 }
13126 if (blobInfo) {
13127 var blob = blobInfo.blob();
13128 return 'src="data:' + blob.type + ';base64,' + blobInfo.base64() + '"';
13129 }
13130 return match;
13131 });
13132 };
13133 editor.on('SetContent', function () {
13134 if (Settings.isAutomaticUploadsEnabled(editor)) {
13135 uploadImagesAuto();
13136 } else {
13137 scanForImages();
13138 }
13139 });
13140 editor.on('RawSaveContent', function (e) {
13141 e.content = replaceBlobUris(e.content);
13142 });
13143 editor.on('GetContent', function (e) {
13144 if (e.source_view || e.format === 'raw') {
13145 return;
13146 }
13147 e.content = replaceBlobUris(e.content);
13148 });
13149 editor.on('PostRender', function () {
13150 editor.parser.addNodeFilter('img', function (images) {
13151 each(images, function (img) {
13152 var src = img.attr('src');
13153 if (blobCache.getByUri(src)) {
13154 return;
13155 }
13156 var resultUri = uploadStatus.getResultUri(src);
13157 if (resultUri) {
13158 img.attr('src', resultUri);
13159 }
13160 });
13161 });
13162 });
13163 return {
13164 blobCache: blobCache,
13165 addFilter: addFilter,
13166 uploadImages: uploadImages,
13167 uploadImagesAuto: uploadImagesAuto,
13168 scanForImages: scanForImages,
13169 destroy: destroy
13170 };
13171 };
13172
13173 var dropLast = function (xs) {
13174 return xs.slice(0, -1);
13175 };
13176 var parentsUntil$1 = function (start, root, predicate) {
13177 if (contains$3(root, start)) {
13178 return dropLast(parents(start, function (elm) {
13179 return predicate(elm) || eq(elm, root);
13180 }));
13181 } else {
13182 return [];
13183 }
13184 };
13185 var parents$1 = function (start, root) {
13186 return parentsUntil$1(start, root, constant(false));
13187 };
13188 var parentsAndSelf = function (start, root) {
13189 return [start].concat(parents$1(start, root));
13190 };
13191 var Parents = {
13192 parentsUntil: parentsUntil$1,
13193 parents: parents$1,
13194 parentsAndSelf: parentsAndSelf
13195 };
13196
13197 var isBlockElement = function (blockElements, node) {
13198 return blockElements.hasOwnProperty(node.nodeName);
13199 };
13200 var isValidTarget = function (blockElements, node) {
13201 if (NodeType.isText(node)) {
13202 return true;
13203 } else if (NodeType.isElement(node)) {
13204 return !isBlockElement(blockElements, node) && !Bookmarks.isBookmarkNode(node);
13205 } else {
13206 return false;
13207 }
13208 };
13209 var hasBlockParent = function (blockElements, root, node) {
13210 return exists(Parents.parents(Element.fromDom(node), Element.fromDom(root)), function (elm) {
13211 return isBlockElement(blockElements, elm.dom());
13212 });
13213 };
13214 var shouldRemoveTextNode = function (blockElements, node) {
13215 if (NodeType.isText(node)) {
13216 if (node.nodeValue.length === 0) {
13217 return true;
13218 } else if (/^\s+$/.test(node.nodeValue) && (!node.nextSibling || isBlockElement(blockElements, node.nextSibling))) {
13219 return true;
13220 }
13221 }
13222 return false;
13223 };
13224 var addRootBlocks = function (editor) {
13225 var dom = editor.dom, selection = editor.selection;
13226 var schema = editor.schema, blockElements = schema.getBlockElements();
13227 var node = selection.getStart();
13228 var rootNode = editor.getBody();
13229 var rng;
13230 var startContainer, startOffset, endContainer, endOffset, rootBlockNode;
13231 var tempNode, wrapped, restoreSelection;
13232 var rootNodeName;
13233 var forcedRootBlock = Settings.getForcedRootBlock(editor);
13234 if (!node || !NodeType.isElement(node) || !forcedRootBlock) {
13235 return;
13236 }
13237 rootNodeName = rootNode.nodeName.toLowerCase();
13238 if (!schema.isValidChild(rootNodeName, forcedRootBlock.toLowerCase()) || hasBlockParent(blockElements, rootNode, node)) {
13239 return;
13240 }
13241 rng = selection.getRng();
13242 startContainer = rng.startContainer;
13243 startOffset = rng.startOffset;
13244 endContainer = rng.endContainer;
13245 endOffset = rng.endOffset;
13246 restoreSelection = EditorFocus.hasFocus(editor);
13247 node = rootNode.firstChild;
13248 while (node) {
13249 if (isValidTarget(blockElements, node)) {
13250 if (shouldRemoveTextNode(blockElements, node)) {
13251 tempNode = node;
13252 node = node.nextSibling;
13253 dom.remove(tempNode);
13254 continue;
13255 }
13256 if (!rootBlockNode) {
13257 rootBlockNode = dom.create(forcedRootBlock, Settings.getForcedRootBlockAttrs(editor));
13258 node.parentNode.insertBefore(rootBlockNode, node);
13259 wrapped = true;
13260 }
13261 tempNode = node;
13262 node = node.nextSibling;
13263 rootBlockNode.appendChild(tempNode);
13264 } else {
13265 rootBlockNode = null;
13266 node = node.nextSibling;
13267 }
13268 }
13269 if (wrapped && restoreSelection) {
13270 rng.setStart(startContainer, startOffset);
13271 rng.setEnd(endContainer, endOffset);
13272 selection.setRng(rng);
13273 editor.nodeChanged();
13274 }
13275 };
13276 var setup$3 = function (editor) {
13277 if (Settings.getForcedRootBlock(editor)) {
13278 editor.on('NodeChange', curry(addRootBlocks, editor));
13279 }
13280 };
13281 var ForceBlocks = { setup: setup$3 };
13282
13283 var isEq$1 = function (rng1, rng2) {
13284 return rng1 && rng2 && (rng1.startContainer === rng2.startContainer && rng1.startOffset === rng2.startOffset) && (rng1.endContainer === rng2.endContainer && rng1.endOffset === rng2.endOffset);
13285 };
13286 var RangeCompare = { isEq: isEq$1 };
13287
13288 var getStartNode = function (rng) {
13289 var sc = rng.startContainer, so = rng.startOffset;
13290 if (NodeType.isText(sc)) {
13291 return so === 0 ? Option.some(Element.fromDom(sc)) : Option.none();
13292 } else {
13293 return Option.from(sc.childNodes[so]).map(Element.fromDom);
13294 }
13295 };
13296 var getEndNode = function (rng) {
13297 var ec = rng.endContainer, eo = rng.endOffset;
13298 if (NodeType.isText(ec)) {
13299 return eo === ec.data.length ? Option.some(Element.fromDom(ec)) : Option.none();
13300 } else {
13301 return Option.from(ec.childNodes[eo - 1]).map(Element.fromDom);
13302 }
13303 };
13304 var getFirstChildren = function (node) {
13305 return firstChild(node).fold(constant([node]), function (child) {
13306 return [node].concat(getFirstChildren(child));
13307 });
13308 };
13309 var getLastChildren = function (node) {
13310 return lastChild(node).fold(constant([node]), function (child) {
13311 if (name(child) === 'br') {
13312 return prevSibling(child).map(function (sibling) {
13313 return [node].concat(getLastChildren(sibling));
13314 }).getOr([]);
13315 } else {
13316 return [node].concat(getLastChildren(child));
13317 }
13318 });
13319 };
13320 var hasAllContentsSelected = function (elm, rng) {
13321 return liftN([
13322 getStartNode(rng),
13323 getEndNode(rng)
13324 ], function (startNode, endNode) {
13325 var start = find(getFirstChildren(elm), curry(eq, startNode));
13326 var end = find(getLastChildren(elm), curry(eq, endNode));
13327 return start.isSome() && end.isSome();
13328 }).getOr(false);
13329 };
13330 var moveEndPoint$1 = function (dom, rng, node, start) {
13331 var root = node, walker = new TreeWalker(node, root);
13332 var nonEmptyElementsMap = dom.schema.getNonEmptyElements();
13333 do {
13334 if (node.nodeType === 3 && Tools.trim(node.nodeValue).length !== 0) {
13335 if (start) {
13336 rng.setStart(node, 0);
13337 } else {
13338 rng.setEnd(node, node.nodeValue.length);
13339 }
13340 return;
13341 }
13342 if (nonEmptyElementsMap[node.nodeName] && !/^(TD|TH)$/.test(node.nodeName)) {
13343 if (start) {
13344 rng.setStartBefore(node);
13345 } else {
13346 if (node.nodeName === 'BR') {
13347 rng.setEndBefore(node);
13348 } else {
13349 rng.setEndAfter(node);
13350 }
13351 }
13352 return;
13353 }
13354 if (Env.ie && Env.ie < 11 && dom.isBlock(node) && dom.isEmpty(node)) {
13355 if (start) {
13356 rng.setStart(node, 0);
13357 } else {
13358 rng.setEnd(node, 0);
13359 }
13360 return;
13361 }
13362 } while (node = start ? walker.next() : walker.prev());
13363 if (root.nodeName === 'BODY') {
13364 if (start) {
13365 rng.setStart(root, 0);
13366 } else {
13367 rng.setEnd(root, root.childNodes.length);
13368 }
13369 }
13370 };
13371 var hasAnyRanges = function (editor) {
13372 var sel = editor.selection.getSel();
13373 return sel && sel.rangeCount > 0;
13374 };
13375
13376 var NodeChange = function () {
13377 function NodeChange(editor) {
13378 this.lastPath = [];
13379 this.editor = editor;
13380 var lastRng;
13381 var self = this;
13382 if (!('onselectionchange' in editor.getDoc())) {
13383 editor.on('NodeChange click mouseup keyup focus', function (e) {
13384 var nativeRng, fakeRng;
13385 nativeRng = editor.selection.getRng();
13386 fakeRng = {
13387 startContainer: nativeRng.startContainer,
13388 startOffset: nativeRng.startOffset,
13389 endContainer: nativeRng.endContainer,
13390 endOffset: nativeRng.endOffset
13391 };
13392 if (e.type === 'nodechange' || !RangeCompare.isEq(fakeRng, lastRng)) {
13393 editor.fire('SelectionChange');
13394 }
13395 lastRng = fakeRng;
13396 });
13397 }
13398 editor.on('contextmenu', function () {
13399 editor.fire('SelectionChange');
13400 });
13401 editor.on('SelectionChange', function () {
13402 var startElm = editor.selection.getStart(true);
13403 if (!startElm || !Env.range && editor.selection.isCollapsed()) {
13404 return;
13405 }
13406 if (hasAnyRanges(editor) && !self.isSameElementPath(startElm) && editor.dom.isChildOf(startElm, editor.getBody())) {
13407 editor.nodeChanged({ selectionChange: true });
13408 }
13409 });
13410 editor.on('mouseup', function (e) {
13411 if (!e.isDefaultPrevented() && hasAnyRanges(editor)) {
13412 if (editor.selection.getNode().nodeName === 'IMG') {
13413 Delay.setEditorTimeout(editor, function () {
13414 editor.nodeChanged();
13415 });
13416 } else {
13417 editor.nodeChanged();
13418 }
13419 }
13420 });
13421 }
13422 NodeChange.prototype.nodeChanged = function (args) {
13423 var selection = this.editor.selection;
13424 var node, parents, root;
13425 if (this.editor.initialized && selection && !this.editor.settings.disable_nodechange && !this.editor.readonly) {
13426 root = this.editor.getBody();
13427 node = selection.getStart(true) || root;
13428 if (node.ownerDocument !== this.editor.getDoc() || !this.editor.dom.isChildOf(node, root)) {
13429 node = root;
13430 }
13431 parents = [];
13432 this.editor.dom.getParent(node, function (node) {
13433 if (node === root) {
13434 return true;
13435 }
13436 parents.push(node);
13437 });
13438 args = args || {};
13439 args.element = node;
13440 args.parents = parents;
13441 this.editor.fire('NodeChange', args);
13442 }
13443 };
13444 NodeChange.prototype.isSameElementPath = function (startElm) {
13445 var i, currentPath;
13446 currentPath = this.editor.$(startElm).parentsUntil(this.editor.getBody()).add(startElm);
13447 if (currentPath.length === this.lastPath.length) {
13448 for (i = currentPath.length; i >= 0; i--) {
13449 if (currentPath[i] !== this.lastPath[i]) {
13450 break;
13451 }
13452 }
13453 if (i === -1) {
13454 this.lastPath = currentPath;
13455 return true;
13456 }
13457 }
13458 this.lastPath = currentPath;
13459 return false;
13460 };
13461 return NodeChange;
13462 }();
13463
13464 var getAbsolutePosition = function (elm) {
13465 var doc, docElem, win, clientRect;
13466 clientRect = elm.getBoundingClientRect();
13467 doc = elm.ownerDocument;
13468 docElem = doc.documentElement;
13469 win = doc.defaultView;
13470 return {
13471 top: clientRect.top + win.pageYOffset - docElem.clientTop,
13472 left: clientRect.left + win.pageXOffset - docElem.clientLeft
13473 };
13474 };
13475 var getBodyPosition = function (editor) {
13476 return editor.inline ? getAbsolutePosition(editor.getBody()) : {
13477 left: 0,
13478 top: 0
13479 };
13480 };
13481 var getScrollPosition = function (editor) {
13482 var body = editor.getBody();
13483 return editor.inline ? {
13484 left: body.scrollLeft,
13485 top: body.scrollTop
13486 } : {
13487 left: 0,
13488 top: 0
13489 };
13490 };
13491 var getBodyScroll = function (editor) {
13492 var body = editor.getBody(), docElm = editor.getDoc().documentElement;
13493 var inlineScroll = {
13494 left: body.scrollLeft,
13495 top: body.scrollTop
13496 };
13497 var iframeScroll = {
13498 left: body.scrollLeft || docElm.scrollLeft,
13499 top: body.scrollTop || docElm.scrollTop
13500 };
13501 return editor.inline ? inlineScroll : iframeScroll;
13502 };
13503 var getMousePosition = function (editor, event) {
13504 if (event.target.ownerDocument !== editor.getDoc()) {
13505 var iframePosition = getAbsolutePosition(editor.getContentAreaContainer());
13506 var scrollPosition = getBodyScroll(editor);
13507 return {
13508 left: event.pageX - iframePosition.left + scrollPosition.left,
13509 top: event.pageY - iframePosition.top + scrollPosition.top
13510 };
13511 }
13512 return {
13513 left: event.pageX,
13514 top: event.pageY
13515 };
13516 };
13517 var calculatePosition = function (bodyPosition, scrollPosition, mousePosition) {
13518 return {
13519 pageX: mousePosition.left - bodyPosition.left + scrollPosition.left,
13520 pageY: mousePosition.top - bodyPosition.top + scrollPosition.top
13521 };
13522 };
13523 var calc = function (editor, event) {
13524 return calculatePosition(getBodyPosition(editor), getScrollPosition(editor), getMousePosition(editor, event));
13525 };
13526 var MousePosition = { calc: calc };
13527
13528 var isContentEditableFalse$6 = NodeType.isContentEditableFalse, isContentEditableTrue$2 = NodeType.isContentEditableTrue;
13529 var isDraggable = function (rootElm, elm) {
13530 return isContentEditableFalse$6(elm) && elm !== rootElm;
13531 };
13532 var isValidDropTarget = function (editor, targetElement, dragElement) {
13533 if (targetElement === dragElement || editor.dom.isChildOf(targetElement, dragElement)) {
13534 return false;
13535 }
13536 return !isContentEditableFalse$6(targetElement);
13537 };
13538 var cloneElement = function (elm) {
13539 var cloneElm = elm.cloneNode(true);
13540 cloneElm.removeAttribute('data-mce-selected');
13541 return cloneElm;
13542 };
13543 var createGhost = function (editor, elm, width, height) {
13544 var clonedElm = elm.cloneNode(true);
13545 editor.dom.setStyles(clonedElm, {
13546 width: width,
13547 height: height
13548 });
13549 editor.dom.setAttrib(clonedElm, 'data-mce-selected', null);
13550 var ghostElm = editor.dom.create('div', {
13551 'class': 'mce-drag-container',
13552 'data-mce-bogus': 'all',
13553 'unselectable': 'on',
13554 'contenteditable': 'false'
13555 });
13556 editor.dom.setStyles(ghostElm, {
13557 position: 'absolute',
13558 opacity: 0.5,
13559 overflow: 'hidden',
13560 border: 0,
13561 padding: 0,
13562 margin: 0,
13563 width: width,
13564 height: height
13565 });
13566 editor.dom.setStyles(clonedElm, {
13567 margin: 0,
13568 boxSizing: 'border-box'
13569 });
13570 ghostElm.appendChild(clonedElm);
13571 return ghostElm;
13572 };
13573 var appendGhostToBody = function (ghostElm, bodyElm) {
13574 if (ghostElm.parentNode !== bodyElm) {
13575 bodyElm.appendChild(ghostElm);
13576 }
13577 };
13578 var moveGhost = function (ghostElm, position, width, height, maxX, maxY) {
13579 var overflowX = 0, overflowY = 0;
13580 ghostElm.style.left = position.pageX + 'px';
13581 ghostElm.style.top = position.pageY + 'px';
13582 if (position.pageX + width > maxX) {
13583 overflowX = position.pageX + width - maxX;
13584 }
13585 if (position.pageY + height > maxY) {
13586 overflowY = position.pageY + height - maxY;
13587 }
13588 ghostElm.style.width = width - overflowX + 'px';
13589 ghostElm.style.height = height - overflowY + 'px';
13590 };
13591 var removeElement = function (elm) {
13592 if (elm && elm.parentNode) {
13593 elm.parentNode.removeChild(elm);
13594 }
13595 };
13596 var isLeftMouseButtonPressed = function (e) {
13597 return e.button === 0;
13598 };
13599 var hasDraggableElement = function (state) {
13600 return state.element;
13601 };
13602 var applyRelPos = function (state, position) {
13603 return {
13604 pageX: position.pageX - state.relX,
13605 pageY: position.pageY + 5
13606 };
13607 };
13608 var start = function (state, editor) {
13609 return function (e) {
13610 if (isLeftMouseButtonPressed(e)) {
13611 var ceElm = find(editor.dom.getParents(e.target), Predicate.or(isContentEditableFalse$6, isContentEditableTrue$2)).getOr(null);
13612 if (isDraggable(editor.getBody(), ceElm)) {
13613 var elmPos = editor.dom.getPos(ceElm);
13614 var bodyElm = editor.getBody();
13615 var docElm = editor.getDoc().documentElement;
13616 state.element = ceElm;
13617 state.screenX = e.screenX;
13618 state.screenY = e.screenY;
13619 state.maxX = (editor.inline ? bodyElm.scrollWidth : docElm.offsetWidth) - 2;
13620 state.maxY = (editor.inline ? bodyElm.scrollHeight : docElm.offsetHeight) - 2;
13621 state.relX = e.pageX - elmPos.x;
13622 state.relY = e.pageY - elmPos.y;
13623 state.width = ceElm.offsetWidth;
13624 state.height = ceElm.offsetHeight;
13625 state.ghost = createGhost(editor, ceElm, state.width, state.height);
13626 }
13627 }
13628 };
13629 };
13630 var move = function (state, editor) {
13631 var throttledPlaceCaretAt = Delay.throttle(function (clientX, clientY) {
13632 editor._selectionOverrides.hideFakeCaret();
13633 editor.selection.placeCaretAt(clientX, clientY);
13634 }, 0);
13635 return function (e) {
13636 var movement = Math.max(Math.abs(e.screenX - state.screenX), Math.abs(e.screenY - state.screenY));
13637 if (hasDraggableElement(state) && !state.dragging && movement > 10) {
13638 var args = editor.fire('dragstart', { target: state.element });
13639 if (args.isDefaultPrevented()) {
13640 return;
13641 }
13642 state.dragging = true;
13643 editor.focus();
13644 }
13645 if (state.dragging) {
13646 var targetPos = applyRelPos(state, MousePosition.calc(editor, e));
13647 appendGhostToBody(state.ghost, editor.getBody());
13648 moveGhost(state.ghost, targetPos, state.width, state.height, state.maxX, state.maxY);
13649 throttledPlaceCaretAt(e.clientX, e.clientY);
13650 }
13651 };
13652 };
13653 var getRawTarget = function (selection) {
13654 var rng = selection.getSel().getRangeAt(0);
13655 var startContainer = rng.startContainer;
13656 return startContainer.nodeType === 3 ? startContainer.parentNode : startContainer;
13657 };
13658 var drop = function (state, editor) {
13659 return function (e) {
13660 if (state.dragging) {
13661 if (isValidDropTarget(editor, getRawTarget(editor.selection), state.element)) {
13662 var targetClone_1 = cloneElement(state.element);
13663 var args = editor.fire('drop', {
13664 targetClone: targetClone_1,
13665 clientX: e.clientX,
13666 clientY: e.clientY
13667 });
13668 if (!args.isDefaultPrevented()) {
13669 targetClone_1 = args.targetClone;
13670 editor.undoManager.transact(function () {
13671 removeElement(state.element);
13672 editor.insertContent(editor.dom.getOuterHTML(targetClone_1));
13673 editor._selectionOverrides.hideFakeCaret();
13674 });
13675 }
13676 }
13677 }
13678 removeDragState(state);
13679 };
13680 };
13681 var stop = function (state, editor) {
13682 return function () {
13683 if (state.dragging) {
13684 editor.fire('dragend');
13685 }
13686 removeDragState(state);
13687 };
13688 };
13689 var removeDragState = function (state) {
13690 state.dragging = false;
13691 state.element = null;
13692 removeElement(state.ghost);
13693 };
13694 var bindFakeDragEvents = function (editor) {
13695 var state = {};
13696 var pageDom, dragStartHandler, dragHandler, dropHandler, dragEndHandler, rootDocument;
13697 pageDom = DOMUtils$1.DOM;
13698 rootDocument = domGlobals.document;
13699 dragStartHandler = start(state, editor);
13700 dragHandler = move(state, editor);
13701 dropHandler = drop(state, editor);
13702 dragEndHandler = stop(state, editor);
13703 editor.on('mousedown', dragStartHandler);
13704 editor.on('mousemove', dragHandler);
13705 editor.on('mouseup', dropHandler);
13706 pageDom.bind(rootDocument, 'mousemove', dragHandler);
13707 pageDom.bind(rootDocument, 'mouseup', dragEndHandler);
13708 editor.on('remove', function () {
13709 pageDom.unbind(rootDocument, 'mousemove', dragHandler);
13710 pageDom.unbind(rootDocument, 'mouseup', dragEndHandler);
13711 });
13712 };
13713 var blockIeDrop = function (editor) {
13714 editor.on('drop', function (e) {
13715 var realTarget = typeof e.clientX !== 'undefined' ? editor.getDoc().elementFromPoint(e.clientX, e.clientY) : null;
13716 if (isContentEditableFalse$6(realTarget) || isContentEditableFalse$6(editor.dom.getContentEditableParent(realTarget))) {
13717 e.preventDefault();
13718 }
13719 });
13720 };
13721 var init = function (editor) {
13722 bindFakeDragEvents(editor);
13723 blockIeDrop(editor);
13724 };
13725 var DragDropOverrides = { init: init };
13726
13727 var getNodeClientRects = function (node) {
13728 var toArrayWithNode = function (clientRects) {
13729 return map(clientRects, function (clientRect) {
13730 clientRect = clone$1(clientRect);
13731 clientRect.node = node;
13732 return clientRect;
13733 });
13734 };
13735 if (NodeType.isElement(node)) {
13736 return toArrayWithNode(node.getClientRects());
13737 }
13738 if (NodeType.isText(node)) {
13739 var rng = node.ownerDocument.createRange();
13740 rng.setStart(node, 0);
13741 rng.setEnd(node, node.data.length);
13742 return toArrayWithNode(rng.getClientRects());
13743 }
13744 };
13745 var getClientRects = function (node) {
13746 return foldl(node, function (result, node) {
13747 return result.concat(getNodeClientRects(node));
13748 }, []);
13749 };
13750
13751 var VDirection;
13752 (function (VDirection) {
13753 VDirection[VDirection['Up'] = -1] = 'Up';
13754 VDirection[VDirection['Down'] = 1] = 'Down';
13755 }(VDirection || (VDirection = {})));
13756 var findUntil = function (direction, root, predicateFn, node) {
13757 while (node = findNode(node, direction, isEditableCaretCandidate, root)) {
13758 if (predicateFn(node)) {
13759 return;
13760 }
13761 }
13762 };
13763 var walkUntil = function (direction, isAboveFn, isBeflowFn, root, predicateFn, caretPosition) {
13764 var line = 0, node;
13765 var result = [];
13766 var targetClientRect;
13767 var add = function (node) {
13768 var i, clientRect, clientRects;
13769 clientRects = getClientRects([node]);
13770 if (direction === -1) {
13771 clientRects = clientRects.reverse();
13772 }
13773 for (i = 0; i < clientRects.length; i++) {
13774 clientRect = clientRects[i];
13775 if (isBeflowFn(clientRect, targetClientRect)) {
13776 continue;
13777 }
13778 if (result.length > 0 && isAboveFn(clientRect, ArrUtils.last(result))) {
13779 line++;
13780 }
13781 clientRect.line = line;
13782 if (predicateFn(clientRect)) {
13783 return true;
13784 }
13785 result.push(clientRect);
13786 }
13787 };
13788 targetClientRect = ArrUtils.last(caretPosition.getClientRects());
13789 if (!targetClientRect) {
13790 return result;
13791 }
13792 node = caretPosition.getNode();
13793 add(node);
13794 findUntil(direction, root, add, node);
13795 return result;
13796 };
13797 var aboveLineNumber = function (lineNumber, clientRect) {
13798 return clientRect.line > lineNumber;
13799 };
13800 var isLineNumber = function (lineNumber, clientRect) {
13801 return clientRect.line === lineNumber;
13802 };
13803 var upUntil = curry(walkUntil, VDirection.Up, isAbove, isBelow);
13804 var downUntil = curry(walkUntil, VDirection.Down, isBelow, isAbove);
13805 var positionsUntil = function (direction, root, predicateFn, node) {
13806 var caretWalker = CaretWalker(root);
13807 var walkFn, isBelowFn, isAboveFn, caretPosition;
13808 var result = [];
13809 var line = 0, clientRect, targetClientRect;
13810 var getClientRect = function (caretPosition) {
13811 if (direction === 1) {
13812 return ArrUtils.last(caretPosition.getClientRects());
13813 }
13814 return ArrUtils.last(caretPosition.getClientRects());
13815 };
13816 if (direction === 1) {
13817 walkFn = caretWalker.next;
13818 isBelowFn = isBelow;
13819 isAboveFn = isAbove;
13820 caretPosition = CaretPosition$1.after(node);
13821 } else {
13822 walkFn = caretWalker.prev;
13823 isBelowFn = isAbove;
13824 isAboveFn = isBelow;
13825 caretPosition = CaretPosition$1.before(node);
13826 }
13827 targetClientRect = getClientRect(caretPosition);
13828 do {
13829 if (!caretPosition.isVisible()) {
13830 continue;
13831 }
13832 clientRect = getClientRect(caretPosition);
13833 if (isAboveFn(clientRect, targetClientRect)) {
13834 continue;
13835 }
13836 if (result.length > 0 && isBelowFn(clientRect, ArrUtils.last(result))) {
13837 line++;
13838 }
13839 clientRect = clone$1(clientRect);
13840 clientRect.position = caretPosition;
13841 clientRect.line = line;
13842 if (predicateFn(clientRect)) {
13843 return result;
13844 }
13845 result.push(clientRect);
13846 } while (caretPosition = walkFn(caretPosition));
13847 return result;
13848 };
13849 var isAboveLine = function (lineNumber) {
13850 return function (clientRect) {
13851 return aboveLineNumber(lineNumber, clientRect);
13852 };
13853 };
13854 var isLine = function (lineNumber) {
13855 return function (clientRect) {
13856 return isLineNumber(lineNumber, clientRect);
13857 };
13858 };
13859
13860 var isContentEditableFalse$7 = NodeType.isContentEditableFalse;
13861 var findNode$1 = findNode;
13862 var distanceToRectLeft = function (clientRect, clientX) {
13863 return Math.abs(clientRect.left - clientX);
13864 };
13865 var distanceToRectRight = function (clientRect, clientX) {
13866 return Math.abs(clientRect.right - clientX);
13867 };
13868 var isInside = function (clientX, clientRect) {
13869 return clientX >= clientRect.left && clientX <= clientRect.right;
13870 };
13871 var findClosestClientRect = function (clientRects, clientX) {
13872 return ArrUtils.reduce(clientRects, function (oldClientRect, clientRect) {
13873 var oldDistance, newDistance;
13874 oldDistance = Math.min(distanceToRectLeft(oldClientRect, clientX), distanceToRectRight(oldClientRect, clientX));
13875 newDistance = Math.min(distanceToRectLeft(clientRect, clientX), distanceToRectRight(clientRect, clientX));
13876 if (isInside(clientX, clientRect)) {
13877 return clientRect;
13878 }
13879 if (isInside(clientX, oldClientRect)) {
13880 return oldClientRect;
13881 }
13882 if (newDistance === oldDistance && isContentEditableFalse$7(clientRect.node)) {
13883 return clientRect;
13884 }
13885 if (newDistance < oldDistance) {
13886 return clientRect;
13887 }
13888 return oldClientRect;
13889 });
13890 };
13891 var walkUntil$1 = function (direction, root, predicateFn, node) {
13892 while (node = findNode$1(node, direction, isEditableCaretCandidate, root)) {
13893 if (predicateFn(node)) {
13894 return;
13895 }
13896 }
13897 };
13898 var findLineNodeRects = function (root, targetNodeRect) {
13899 var clientRects = [];
13900 var collect = function (checkPosFn, node) {
13901 var lineRects;
13902 lineRects = filter(getClientRects([node]), function (clientRect) {
13903 return !checkPosFn(clientRect, targetNodeRect);
13904 });
13905 clientRects = clientRects.concat(lineRects);
13906 return lineRects.length === 0;
13907 };
13908 clientRects.push(targetNodeRect);
13909 walkUntil$1(VDirection.Up, root, curry(collect, isAbove), targetNodeRect.node);
13910 walkUntil$1(VDirection.Down, root, curry(collect, isBelow), targetNodeRect.node);
13911 return clientRects;
13912 };
13913 var getFakeCaretTargets = function (root) {
13914 return filter(from$1(root.getElementsByTagName('*')), isFakeCaretTarget);
13915 };
13916 var caretInfo = function (clientRect, clientX) {
13917 return {
13918 node: clientRect.node,
13919 before: distanceToRectLeft(clientRect, clientX) < distanceToRectRight(clientRect, clientX)
13920 };
13921 };
13922 var closestCaret = function (root, clientX, clientY) {
13923 var closestNodeRect;
13924 var contentEditableFalseNodeRects = getClientRects(getFakeCaretTargets(root));
13925 var targetNodeRects = filter(contentEditableFalseNodeRects, function (rect) {
13926 return clientY >= rect.top && clientY <= rect.bottom;
13927 });
13928 closestNodeRect = findClosestClientRect(targetNodeRects, clientX);
13929 if (closestNodeRect) {
13930 closestNodeRect = findClosestClientRect(findLineNodeRects(root, closestNodeRect), clientX);
13931 if (closestNodeRect && isFakeCaretTarget(closestNodeRect.node)) {
13932 return caretInfo(closestNodeRect, clientX);
13933 }
13934 }
13935 return null;
13936 };
13937
13938 var isXYWithinRange = function (clientX, clientY, range) {
13939 if (range.collapsed) {
13940 return false;
13941 }
13942 if (Env.ie && Env.ie <= 11 && range.startOffset === range.endOffset - 1 && range.startContainer === range.endContainer) {
13943 var elm = range.startContainer.childNodes[range.startOffset];
13944 if (NodeType.isElement(elm)) {
13945 return exists(elm.getClientRects(), function (rect) {
13946 return containsXY(rect, clientX, clientY);
13947 });
13948 }
13949 }
13950 return exists(range.getClientRects(), function (rect) {
13951 return containsXY(rect, clientX, clientY);
13952 });
13953 };
13954 var RangePoint = { isXYWithinRange: isXYWithinRange };
13955
13956 var isContentEditableTrue$3 = NodeType.isContentEditableTrue;
13957 var isContentEditableFalse$8 = NodeType.isContentEditableFalse;
13958 var showCaret = function (direction, editor, node, before, scrollIntoView) {
13959 return editor._selectionOverrides.showCaret(direction, node, before, scrollIntoView);
13960 };
13961 var getNodeRange = function (node) {
13962 var rng = node.ownerDocument.createRange();
13963 rng.selectNode(node);
13964 return rng;
13965 };
13966 var selectNode = function (editor, node) {
13967 var e = editor.fire('BeforeObjectSelected', { target: node });
13968 if (e.isDefaultPrevented()) {
13969 return null;
13970 }
13971 return getNodeRange(node);
13972 };
13973 var renderCaretAtRange = function (editor, range, scrollIntoView) {
13974 var normalizedRange = normalizeRange(1, editor.getBody(), range);
13975 var caretPosition = CaretPosition$1.fromRangeStart(normalizedRange);
13976 var caretPositionNode = caretPosition.getNode();
13977 if (isContentEditableFalse$8(caretPositionNode)) {
13978 return showCaret(1, editor, caretPositionNode, !caretPosition.isAtEnd(), false);
13979 }
13980 var caretPositionBeforeNode = caretPosition.getNode(true);
13981 if (isContentEditableFalse$8(caretPositionBeforeNode)) {
13982 return showCaret(1, editor, caretPositionBeforeNode, false, false);
13983 }
13984 var ceRoot = editor.dom.getParent(caretPosition.getNode(), function (node) {
13985 return isContentEditableFalse$8(node) || isContentEditableTrue$3(node);
13986 });
13987 if (isContentEditableFalse$8(ceRoot)) {
13988 return showCaret(1, editor, ceRoot, false, scrollIntoView);
13989 }
13990 return null;
13991 };
13992 var renderRangeCaret = function (editor, range, scrollIntoView) {
13993 if (!range || !range.collapsed) {
13994 return range;
13995 }
13996 var caretRange = renderCaretAtRange(editor, range, scrollIntoView);
13997 if (caretRange) {
13998 return caretRange;
13999 }
14000 return range;
14001 };
14002
14003 var setup$4 = function (editor) {
14004 var renderFocusCaret = first(function () {
14005 if (!editor.removed && editor.getBody().contains(domGlobals.document.activeElement)) {
14006 var rng = editor.selection.getRng();
14007 if (rng.collapsed) {
14008 var caretRange = renderRangeCaret(editor, editor.selection.getRng(), false);
14009 editor.selection.setRng(caretRange);
14010 }
14011 }
14012 }, 0);
14013 editor.on('focus', function () {
14014 renderFocusCaret.throttle();
14015 });
14016 editor.on('blur', function () {
14017 renderFocusCaret.cancel();
14018 });
14019 };
14020 var CefFocus = { setup: setup$4 };
14021
14022 var VK = {
14023 BACKSPACE: 8,
14024 DELETE: 46,
14025 DOWN: 40,
14026 ENTER: 13,
14027 LEFT: 37,
14028 RIGHT: 39,
14029 SPACEBAR: 32,
14030 TAB: 9,
14031 UP: 38,
14032 END: 35,
14033 HOME: 36,
14034 modifierPressed: function (e) {
14035 return e.shiftKey || e.ctrlKey || e.altKey || this.metaKeyPressed(e);
14036 },
14037 metaKeyPressed: function (e) {
14038 return Env.mac ? e.metaKey : e.ctrlKey && !e.altKey;
14039 }
14040 };
14041
14042 var is$2 = function (expected) {
14043 return function (actual) {
14044 return expected === actual;
14045 };
14046 };
14047 var isNbsp = is$2('\xA0');
14048 var isWhiteSpace$1 = function (chr) {
14049 return /^[\r\n\t ]$/.test(chr);
14050 };
14051 var isContent = function (chr) {
14052 return !isWhiteSpace$1(chr) && !isNbsp(chr);
14053 };
14054
14055 var isChar = function (forward, predicate, pos) {
14056 return Option.from(pos.container()).filter(NodeType.isText).exists(function (text) {
14057 var delta = forward ? 0 : -1;
14058 return predicate(text.data.charAt(pos.offset() + delta));
14059 });
14060 };
14061 var isBeforeSpace = curry(isChar, true, isWhiteSpace$1);
14062 var isAfterSpace = curry(isChar, false, isWhiteSpace$1);
14063 var isEmptyText = function (pos) {
14064 var container = pos.container();
14065 return NodeType.isText(container) && container.data.length === 0;
14066 };
14067 var matchesElementPosition = function (before, predicate) {
14068 return function (pos) {
14069 return Option.from(getChildNodeAtRelativeOffset(before ? 0 : -1, pos)).filter(predicate).isSome();
14070 };
14071 };
14072 var isImageBlock = function (node) {
14073 return node.nodeName === 'IMG' && get$2(Element.fromDom(node), 'display') === 'block';
14074 };
14075 var isCefNode = function (node) {
14076 return NodeType.isContentEditableFalse(node) && !NodeType.isBogusAll(node);
14077 };
14078 var isBeforeImageBlock = matchesElementPosition(true, isImageBlock);
14079 var isAfterImageBlock = matchesElementPosition(false, isImageBlock);
14080 var isBeforeTable = matchesElementPosition(true, NodeType.isTable);
14081 var isAfterTable = matchesElementPosition(false, NodeType.isTable);
14082 var isBeforeContentEditableFalse = matchesElementPosition(true, isCefNode);
14083 var isAfterContentEditableFalse = matchesElementPosition(false, isCefNode);
14084
14085 var isContentEditableTrue$4 = NodeType.isContentEditableTrue;
14086 var isContentEditableFalse$9 = NodeType.isContentEditableFalse;
14087 var getContentEditableRoot = function (editor, node) {
14088 var root = editor.getBody();
14089 while (node && node !== root) {
14090 if (isContentEditableTrue$4(node) || isContentEditableFalse$9(node)) {
14091 return node;
14092 }
14093 node = node.parentNode;
14094 }
14095 return null;
14096 };
14097 var SelectionOverrides = function (editor) {
14098 var isBlock = function (node) {
14099 return editor.dom.isBlock(node);
14100 };
14101 var rootNode = editor.getBody();
14102 var fakeCaret = FakeCaret(editor.getBody(), isBlock, function () {
14103 return EditorFocus.hasFocus(editor);
14104 });
14105 var realSelectionId = 'sel-' + editor.dom.uniqueId();
14106 var selectedContentEditableNode;
14107 var isFakeSelectionElement = function (elm) {
14108 return editor.dom.hasClass(elm, 'mce-offscreen-selection');
14109 };
14110 var getRealSelectionElement = function () {
14111 var container = editor.dom.get(realSelectionId);
14112 return container ? container.getElementsByTagName('*')[0] : container;
14113 };
14114 var setRange = function (range) {
14115 if (range) {
14116 editor.selection.setRng(range);
14117 }
14118 };
14119 var getRange = function () {
14120 return editor.selection.getRng();
14121 };
14122 var showCaret = function (direction, node, before, scrollIntoView) {
14123 if (scrollIntoView === void 0) {
14124 scrollIntoView = true;
14125 }
14126 var e;
14127 e = editor.fire('ShowCaret', {
14128 target: node,
14129 direction: direction,
14130 before: before
14131 });
14132 if (e.isDefaultPrevented()) {
14133 return null;
14134 }
14135 if (scrollIntoView) {
14136 editor.selection.scrollIntoView(node, direction === -1);
14137 }
14138 return fakeCaret.show(before, node);
14139 };
14140 var getNormalizedRangeEndPoint = function (direction, range) {
14141 range = normalizeRange(direction, rootNode, range);
14142 if (direction === -1) {
14143 return CaretPosition$1.fromRangeStart(range);
14144 }
14145 return CaretPosition$1.fromRangeEnd(range);
14146 };
14147 var showBlockCaretContainer = function (blockCaretContainer) {
14148 if (blockCaretContainer.hasAttribute('data-mce-caret')) {
14149 showCaretContainerBlock(blockCaretContainer);
14150 setRange(getRange());
14151 editor.selection.scrollIntoView(blockCaretContainer[0]);
14152 }
14153 };
14154 var registerEvents = function () {
14155 editor.on('mouseup', function (e) {
14156 var range = getRange();
14157 if (range.collapsed && EditorView.isXYInContentArea(editor, e.clientX, e.clientY)) {
14158 setRange(renderCaretAtRange(editor, range, false));
14159 }
14160 });
14161 editor.on('click', function (e) {
14162 var contentEditableRoot;
14163 contentEditableRoot = getContentEditableRoot(editor, e.target);
14164 if (contentEditableRoot) {
14165 if (isContentEditableFalse$9(contentEditableRoot)) {
14166 e.preventDefault();
14167 editor.focus();
14168 }
14169 if (isContentEditableTrue$4(contentEditableRoot)) {
14170 if (editor.dom.isChildOf(contentEditableRoot, editor.selection.getNode())) {
14171 removeContentEditableSelection();
14172 }
14173 }
14174 }
14175 });
14176 editor.on('blur NewBlock', function () {
14177 removeContentEditableSelection();
14178 });
14179 editor.on('ResizeWindow FullscreenStateChanged', function () {
14180 return fakeCaret.reposition();
14181 });
14182 var handleTouchSelect = function (editor) {
14183 var moved = false;
14184 editor.on('touchstart', function () {
14185 moved = false;
14186 });
14187 editor.on('touchmove', function () {
14188 moved = true;
14189 });
14190 editor.on('touchend', function (e) {
14191 var contentEditableRoot = getContentEditableRoot(editor, e.target);
14192 if (isContentEditableFalse$9(contentEditableRoot)) {
14193 if (!moved) {
14194 e.preventDefault();
14195 setContentEditableSelection(selectNode(editor, contentEditableRoot));
14196 }
14197 }
14198 });
14199 };
14200 var hasNormalCaretPosition = function (elm) {
14201 var caretWalker = CaretWalker(elm);
14202 if (!elm.firstChild) {
14203 return false;
14204 }
14205 var startPos = CaretPosition$1.before(elm.firstChild);
14206 var newPos = caretWalker.next(startPos);
14207 return newPos && !isBeforeContentEditableFalse(newPos) && !isAfterContentEditableFalse(newPos);
14208 };
14209 var isInSameBlock = function (node1, node2) {
14210 var block1 = editor.dom.getParent(node1, editor.dom.isBlock);
14211 var block2 = editor.dom.getParent(node2, editor.dom.isBlock);
14212 return block1 === block2;
14213 };
14214 var hasBetterMouseTarget = function (targetNode, caretNode) {
14215 var targetBlock = editor.dom.getParent(targetNode, editor.dom.isBlock);
14216 var caretBlock = editor.dom.getParent(caretNode, editor.dom.isBlock);
14217 if (targetBlock && editor.dom.isChildOf(targetBlock, caretBlock) && isContentEditableFalse$9(getContentEditableRoot(editor, targetBlock)) === false) {
14218 return true;
14219 }
14220 return targetBlock && !isInSameBlock(targetBlock, caretBlock) && hasNormalCaretPosition(targetBlock);
14221 };
14222 handleTouchSelect(editor);
14223 editor.on('mousedown', function (e) {
14224 var contentEditableRoot;
14225 var targetElm = e.target;
14226 if (targetElm !== rootNode && targetElm.nodeName !== 'HTML' && !editor.dom.isChildOf(targetElm, rootNode)) {
14227 return;
14228 }
14229 if (EditorView.isXYInContentArea(editor, e.clientX, e.clientY) === false) {
14230 return;
14231 }
14232 contentEditableRoot = getContentEditableRoot(editor, targetElm);
14233 if (contentEditableRoot) {
14234 if (isContentEditableFalse$9(contentEditableRoot)) {
14235 e.preventDefault();
14236 setContentEditableSelection(selectNode(editor, contentEditableRoot));
14237 } else {
14238 removeContentEditableSelection();
14239 if (!(isContentEditableTrue$4(contentEditableRoot) && e.shiftKey) && !RangePoint.isXYWithinRange(e.clientX, e.clientY, editor.selection.getRng())) {
14240 hideFakeCaret();
14241 editor.selection.placeCaretAt(e.clientX, e.clientY);
14242 }
14243 }
14244 } else if (isFakeCaretTarget(targetElm) === false) {
14245 removeContentEditableSelection();
14246 hideFakeCaret();
14247 var caretInfo = closestCaret(rootNode, e.clientX, e.clientY);
14248 if (caretInfo) {
14249 if (!hasBetterMouseTarget(e.target, caretInfo.node)) {
14250 e.preventDefault();
14251 var range = showCaret(1, caretInfo.node, caretInfo.before, false);
14252 editor.getBody().focus();
14253 setRange(range);
14254 }
14255 }
14256 }
14257 });
14258 editor.on('keypress', function (e) {
14259 if (VK.modifierPressed(e)) {
14260 return;
14261 }
14262 switch (e.keyCode) {
14263 default:
14264 if (isContentEditableFalse$9(editor.selection.getNode())) {
14265 e.preventDefault();
14266 }
14267 break;
14268 }
14269 });
14270 editor.on('GetSelectionRange', function (e) {
14271 var rng = e.range;
14272 if (selectedContentEditableNode) {
14273 if (!selectedContentEditableNode.parentNode) {
14274 selectedContentEditableNode = null;
14275 return;
14276 }
14277 rng = rng.cloneRange();
14278 rng.selectNode(selectedContentEditableNode);
14279 e.range = rng;
14280 }
14281 });
14282 editor.on('SetSelectionRange', function (e) {
14283 var rng;
14284 rng = setContentEditableSelection(e.range, e.forward);
14285 if (rng) {
14286 e.range = rng;
14287 }
14288 });
14289 var isPasteBin = function (node) {
14290 return node.id === 'mcepastebin';
14291 };
14292 editor.on('AfterSetSelectionRange', function (e) {
14293 var rng = e.range;
14294 if (!isRangeInCaretContainer(rng) && !isPasteBin(rng.startContainer.parentNode)) {
14295 hideFakeCaret();
14296 }
14297 if (!isFakeSelectionElement(rng.startContainer.parentNode)) {
14298 removeContentEditableSelection();
14299 }
14300 });
14301 editor.on('copy', function (e) {
14302 var clipboardData = e.clipboardData;
14303 if (!e.isDefaultPrevented() && e.clipboardData && !Env.ie) {
14304 var realSelectionElement = getRealSelectionElement();
14305 if (realSelectionElement) {
14306 e.preventDefault();
14307 clipboardData.clearData();
14308 clipboardData.setData('text/html', realSelectionElement.outerHTML);
14309 clipboardData.setData('text/plain', realSelectionElement.outerText);
14310 }
14311 }
14312 });
14313 DragDropOverrides.init(editor);
14314 CefFocus.setup(editor);
14315 };
14316 var isWithinCaretContainer = function (node) {
14317 return isCaretContainer(node) || startsWithCaretContainer(node) || endsWithCaretContainer(node);
14318 };
14319 var isRangeInCaretContainer = function (rng) {
14320 return isWithinCaretContainer(rng.startContainer) || isWithinCaretContainer(rng.endContainer);
14321 };
14322 var setContentEditableSelection = function (range, forward) {
14323 var node;
14324 var $ = editor.$;
14325 var dom = editor.dom;
14326 var $realSelectionContainer, sel, startContainer, startOffset, endOffset, e, caretPosition, targetClone, origTargetClone;
14327 if (!range) {
14328 return null;
14329 }
14330 if (range.collapsed) {
14331 if (!isRangeInCaretContainer(range)) {
14332 if (forward === false) {
14333 caretPosition = getNormalizedRangeEndPoint(-1, range);
14334 if (isFakeCaretTarget(caretPosition.getNode(true))) {
14335 return showCaret(-1, caretPosition.getNode(true), false, false);
14336 }
14337 if (isFakeCaretTarget(caretPosition.getNode())) {
14338 return showCaret(-1, caretPosition.getNode(), !caretPosition.isAtEnd(), false);
14339 }
14340 } else {
14341 caretPosition = getNormalizedRangeEndPoint(1, range);
14342 if (isFakeCaretTarget(caretPosition.getNode())) {
14343 return showCaret(1, caretPosition.getNode(), !caretPosition.isAtEnd(), false);
14344 }
14345 if (isFakeCaretTarget(caretPosition.getNode(true))) {
14346 return showCaret(1, caretPosition.getNode(true), false, false);
14347 }
14348 }
14349 }
14350 return null;
14351 }
14352 startContainer = range.startContainer;
14353 startOffset = range.startOffset;
14354 endOffset = range.endOffset;
14355 if (startContainer.nodeType === 3 && startOffset === 0 && isContentEditableFalse$9(startContainer.parentNode)) {
14356 startContainer = startContainer.parentNode;
14357 startOffset = dom.nodeIndex(startContainer);
14358 startContainer = startContainer.parentNode;
14359 }
14360 if (startContainer.nodeType !== 1) {
14361 return null;
14362 }
14363 if (endOffset === startOffset + 1 && startContainer === range.endContainer) {
14364 node = startContainer.childNodes[startOffset];
14365 }
14366 if (!isContentEditableFalse$9(node)) {
14367 return null;
14368 }
14369 targetClone = origTargetClone = node.cloneNode(true);
14370 e = editor.fire('ObjectSelected', {
14371 target: node,
14372 targetClone: targetClone
14373 });
14374 if (e.isDefaultPrevented()) {
14375 return null;
14376 }
14377 $realSelectionContainer = descendant(Element.fromDom(editor.getBody()), '#' + realSelectionId).fold(function () {
14378 return $([]);
14379 }, function (elm) {
14380 return $([elm.dom()]);
14381 });
14382 targetClone = e.targetClone;
14383 if ($realSelectionContainer.length === 0) {
14384 $realSelectionContainer = $('<div data-mce-bogus="all" class="mce-offscreen-selection"></div>').attr('id', realSelectionId);
14385 $realSelectionContainer.appendTo(editor.getBody());
14386 }
14387 range = editor.dom.createRng();
14388 if (targetClone === origTargetClone && Env.ie) {
14389 $realSelectionContainer.empty().append('<p style="font-size: 0" data-mce-bogus="all">\xA0</p>').append(targetClone);
14390 range.setStartAfter($realSelectionContainer[0].firstChild.firstChild);
14391 range.setEndAfter(targetClone);
14392 } else {
14393 $realSelectionContainer.empty().append('\xA0').append(targetClone).append('\xA0');
14394 range.setStart($realSelectionContainer[0].firstChild, 1);
14395 range.setEnd($realSelectionContainer[0].lastChild, 0);
14396 }
14397 $realSelectionContainer.css({ top: dom.getPos(node, editor.getBody()).y });
14398 $realSelectionContainer[0].focus();
14399 sel = editor.selection.getSel();
14400 sel.removeAllRanges();
14401 sel.addRange(range);
14402 each(descendants$1(Element.fromDom(editor.getBody()), '*[data-mce-selected]'), function (elm) {
14403 remove(elm, 'data-mce-selected');
14404 });
14405 node.setAttribute('data-mce-selected', '1');
14406 selectedContentEditableNode = node;
14407 hideFakeCaret();
14408 return range;
14409 };
14410 var removeContentEditableSelection = function () {
14411 if (selectedContentEditableNode) {
14412 selectedContentEditableNode.removeAttribute('data-mce-selected');
14413 descendant(Element.fromDom(editor.getBody()), '#' + realSelectionId).each(remove$1);
14414 selectedContentEditableNode = null;
14415 }
14416 descendant(Element.fromDom(editor.getBody()), '#' + realSelectionId).each(remove$1);
14417 selectedContentEditableNode = null;
14418 };
14419 var destroy = function () {
14420 fakeCaret.destroy();
14421 selectedContentEditableNode = null;
14422 };
14423 var hideFakeCaret = function () {
14424 fakeCaret.hide();
14425 };
14426 if (Env.ceFalse) {
14427 registerEvents();
14428 }
14429 return {
14430 showCaret: showCaret,
14431 showBlockCaretContainer: showBlockCaretContainer,
14432 hideFakeCaret: hideFakeCaret,
14433 destroy: destroy
14434 };
14435 };
14436
14437 var KEEP = 0, INSERT = 1, DELETE = 2;
14438 var diff = function (left, right) {
14439 var size = left.length + right.length + 2;
14440 var vDown = new Array(size);
14441 var vUp = new Array(size);
14442 var snake = function (start, end, diag) {
14443 return {
14444 start: start,
14445 end: end,
14446 diag: diag
14447 };
14448 };
14449 var buildScript = function (start1, end1, start2, end2, script) {
14450 var middle = getMiddleSnake(start1, end1, start2, end2);
14451 if (middle === null || middle.start === end1 && middle.diag === end1 - end2 || middle.end === start1 && middle.diag === start1 - start2) {
14452 var i = start1;
14453 var j = start2;
14454 while (i < end1 || j < end2) {
14455 if (i < end1 && j < end2 && left[i] === right[j]) {
14456 script.push([
14457 KEEP,
14458 left[i]
14459 ]);
14460 ++i;
14461 ++j;
14462 } else {
14463 if (end1 - start1 > end2 - start2) {
14464 script.push([
14465 DELETE,
14466 left[i]
14467 ]);
14468 ++i;
14469 } else {
14470 script.push([
14471 INSERT,
14472 right[j]
14473 ]);
14474 ++j;
14475 }
14476 }
14477 }
14478 } else {
14479 buildScript(start1, middle.start, start2, middle.start - middle.diag, script);
14480 for (var i2 = middle.start; i2 < middle.end; ++i2) {
14481 script.push([
14482 KEEP,
14483 left[i2]
14484 ]);
14485 }
14486 buildScript(middle.end, end1, middle.end - middle.diag, end2, script);
14487 }
14488 };
14489 var buildSnake = function (start, diag, end1, end2) {
14490 var end = start;
14491 while (end - diag < end2 && end < end1 && left[end] === right[end - diag]) {
14492 ++end;
14493 }
14494 return snake(start, end, diag);
14495 };
14496 var getMiddleSnake = function (start1, end1, start2, end2) {
14497 var m = end1 - start1;
14498 var n = end2 - start2;
14499 if (m === 0 || n === 0) {
14500 return null;
14501 }
14502 var delta = m - n;
14503 var sum = n + m;
14504 var offset = (sum % 2 === 0 ? sum : sum + 1) / 2;
14505 vDown[1 + offset] = start1;
14506 vUp[1 + offset] = end1 + 1;
14507 var d, k, i, x, y;
14508 for (d = 0; d <= offset; ++d) {
14509 for (k = -d; k <= d; k += 2) {
14510 i = k + offset;
14511 if (k === -d || k !== d && vDown[i - 1] < vDown[i + 1]) {
14512 vDown[i] = vDown[i + 1];
14513 } else {
14514 vDown[i] = vDown[i - 1] + 1;
14515 }
14516 x = vDown[i];
14517 y = x - start1 + start2 - k;
14518 while (x < end1 && y < end2 && left[x] === right[y]) {
14519 vDown[i] = ++x;
14520 ++y;
14521 }
14522 if (delta % 2 !== 0 && delta - d <= k && k <= delta + d) {
14523 if (vUp[i - delta] <= vDown[i]) {
14524 return buildSnake(vUp[i - delta], k + start1 - start2, end1, end2);
14525 }
14526 }
14527 }
14528 for (k = delta - d; k <= delta + d; k += 2) {
14529 i = k + offset - delta;
14530 if (k === delta - d || k !== delta + d && vUp[i + 1] <= vUp[i - 1]) {
14531 vUp[i] = vUp[i + 1] - 1;
14532 } else {
14533 vUp[i] = vUp[i - 1];
14534 }
14535 x = vUp[i] - 1;
14536 y = x - start1 + start2 - k;
14537 while (x >= start1 && y >= start2 && left[x] === right[y]) {
14538 vUp[i] = x--;
14539 y--;
14540 }
14541 if (delta % 2 === 0 && -d <= k && k <= d) {
14542 if (vUp[i] <= vDown[i + delta]) {
14543 return buildSnake(vUp[i], k + start1 - start2, end1, end2);
14544 }
14545 }
14546 }
14547 }
14548 };
14549 var script = [];
14550 buildScript(0, left.length, 0, right.length, script);
14551 return script;
14552 };
14553 var Diff = {
14554 KEEP: KEEP,
14555 DELETE: DELETE,
14556 INSERT: INSERT,
14557 diff: diff
14558 };
14559
14560 var getOuterHtml = function (elm) {
14561 if (NodeType.isElement(elm)) {
14562 return elm.outerHTML;
14563 } else if (NodeType.isText(elm)) {
14564 return Entities.encodeRaw(elm.data, false);
14565 } else if (NodeType.isComment(elm)) {
14566 return '<!--' + elm.data + '-->';
14567 }
14568 return '';
14569 };
14570 var createFragment$1 = function (html) {
14571 var frag, node, container;
14572 container = domGlobals.document.createElement('div');
14573 frag = domGlobals.document.createDocumentFragment();
14574 if (html) {
14575 container.innerHTML = html;
14576 }
14577 while (node = container.firstChild) {
14578 frag.appendChild(node);
14579 }
14580 return frag;
14581 };
14582 var insertAt = function (elm, html, index) {
14583 var fragment = createFragment$1(html);
14584 if (elm.hasChildNodes() && index < elm.childNodes.length) {
14585 var target = elm.childNodes[index];
14586 target.parentNode.insertBefore(fragment, target);
14587 } else {
14588 elm.appendChild(fragment);
14589 }
14590 };
14591 var removeAt = function (elm, index) {
14592 if (elm.hasChildNodes() && index < elm.childNodes.length) {
14593 var target = elm.childNodes[index];
14594 target.parentNode.removeChild(target);
14595 }
14596 };
14597 var applyDiff = function (diff, elm) {
14598 var index = 0;
14599 each(diff, function (action) {
14600 if (action[0] === Diff.KEEP) {
14601 index++;
14602 } else if (action[0] === Diff.INSERT) {
14603 insertAt(elm, action[1], index);
14604 index++;
14605 } else if (action[0] === Diff.DELETE) {
14606 removeAt(elm, index);
14607 }
14608 });
14609 };
14610 var read$1 = function (elm) {
14611 return filter(map(from$1(elm.childNodes), getOuterHtml), function (item) {
14612 return item.length > 0;
14613 });
14614 };
14615 var write = function (fragments, elm) {
14616 var currentFragments = map(from$1(elm.childNodes), getOuterHtml);
14617 applyDiff(Diff.diff(currentFragments, fragments), elm);
14618 return elm;
14619 };
14620 var Fragments = {
14621 read: read$1,
14622 write: write
14623 };
14624
14625 var undoLevelDocument = Cell(Option.none());
14626 var lazyTempDocument = function () {
14627 return undoLevelDocument.get().getOrThunk(function () {
14628 var doc = domGlobals.document.implementation.createHTMLDocument('undo');
14629 undoLevelDocument.set(Option.some(doc));
14630 return doc;
14631 });
14632 };
14633 var hasIframes = function (html) {
14634 return html.indexOf('</iframe>') !== -1;
14635 };
14636 var createFragmentedLevel = function (fragments) {
14637 return {
14638 type: 'fragmented',
14639 fragments: fragments,
14640 content: '',
14641 bookmark: null,
14642 beforeBookmark: null
14643 };
14644 };
14645 var createCompleteLevel = function (content) {
14646 return {
14647 type: 'complete',
14648 fragments: null,
14649 content: content,
14650 bookmark: null,
14651 beforeBookmark: null
14652 };
14653 };
14654 var createFromEditor = function (editor) {
14655 var fragments, content, trimmedFragments;
14656 fragments = Fragments.read(editor.getBody());
14657 trimmedFragments = bind(fragments, function (html) {
14658 var trimmed = TrimHtml.trimInternal(editor.serializer, html);
14659 return trimmed.length > 0 ? [trimmed] : [];
14660 });
14661 content = trimmedFragments.join('');
14662 return hasIframes(content) ? createFragmentedLevel(trimmedFragments) : createCompleteLevel(content);
14663 };
14664 var applyToEditor = function (editor, level, before) {
14665 if (level.type === 'fragmented') {
14666 Fragments.write(level.fragments, editor.getBody());
14667 } else {
14668 editor.setContent(level.content, { format: 'raw' });
14669 }
14670 editor.selection.moveToBookmark(before ? level.beforeBookmark : level.bookmark);
14671 };
14672 var getLevelContent = function (level) {
14673 return level.type === 'fragmented' ? level.fragments.join('') : level.content;
14674 };
14675 var getCleanLevelContent = function (level) {
14676 var elm = Element.fromTag('body', lazyTempDocument());
14677 set$1(elm, getLevelContent(level));
14678 each(descendants$1(elm, '*[data-mce-bogus]'), unwrap);
14679 return get$4(elm);
14680 };
14681 var hasEqualContent = function (level1, level2) {
14682 return getLevelContent(level1) === getLevelContent(level2);
14683 };
14684 var hasEqualCleanedContent = function (level1, level2) {
14685 return getCleanLevelContent(level1) === getCleanLevelContent(level2);
14686 };
14687 var isEq$2 = function (level1, level2) {
14688 if (!level1 || !level2) {
14689 return false;
14690 } else if (hasEqualContent(level1, level2)) {
14691 return true;
14692 } else {
14693 return hasEqualCleanedContent(level1, level2);
14694 }
14695 };
14696 var Levels = {
14697 createFragmentedLevel: createFragmentedLevel,
14698 createCompleteLevel: createCompleteLevel,
14699 createFromEditor: createFromEditor,
14700 applyToEditor: applyToEditor,
14701 isEq: isEq$2
14702 };
14703
14704 var UndoManager = function (editor) {
14705 var self = this, index = 0, data = [], beforeBookmark, isFirstTypedCharacter, locks = 0;
14706 var isUnlocked = function () {
14707 return locks === 0;
14708 };
14709 var setTyping = function (typing) {
14710 if (isUnlocked()) {
14711 self.typing = typing;
14712 }
14713 };
14714 var setDirty = function (state) {
14715 editor.setDirty(state);
14716 };
14717 var addNonTypingUndoLevel = function (e) {
14718 setTyping(false);
14719 self.add({}, e);
14720 };
14721 var endTyping = function () {
14722 if (self.typing) {
14723 setTyping(false);
14724 self.add();
14725 }
14726 };
14727 editor.on('init', function () {
14728 self.add();
14729 });
14730 editor.on('BeforeExecCommand', function (e) {
14731 var cmd = e.command;
14732 if (cmd !== 'Undo' && cmd !== 'Redo' && cmd !== 'mceRepaint') {
14733 endTyping();
14734 self.beforeChange();
14735 }
14736 });
14737 editor.on('ExecCommand', function (e) {
14738 var cmd = e.command;
14739 if (cmd !== 'Undo' && cmd !== 'Redo' && cmd !== 'mceRepaint') {
14740 addNonTypingUndoLevel(e);
14741 }
14742 });
14743 editor.on('ObjectResizeStart cut', function () {
14744 self.beforeChange();
14745 });
14746 editor.on('SaveContent ObjectResized blur', addNonTypingUndoLevel);
14747 editor.on('dragend', addNonTypingUndoLevel);
14748 editor.on('keyup', function (e) {
14749 var keyCode = e.keyCode;
14750 if (e.isDefaultPrevented()) {
14751 return;
14752 }
14753 if (keyCode >= 33 && keyCode <= 36 || keyCode >= 37 && keyCode <= 40 || keyCode === 45 || e.ctrlKey) {
14754 addNonTypingUndoLevel();
14755 editor.nodeChanged();
14756 }
14757 if (keyCode === 46 || keyCode === 8) {
14758 editor.nodeChanged();
14759 }
14760 if (isFirstTypedCharacter && self.typing && Levels.isEq(Levels.createFromEditor(editor), data[0]) === false) {
14761 if (editor.isDirty() === false) {
14762 setDirty(true);
14763 editor.fire('change', {
14764 level: data[0],
14765 lastLevel: null
14766 });
14767 }
14768 editor.fire('TypingUndo');
14769 isFirstTypedCharacter = false;
14770 editor.nodeChanged();
14771 }
14772 });
14773 editor.on('keydown', function (e) {
14774 var keyCode = e.keyCode;
14775 if (e.isDefaultPrevented()) {
14776 return;
14777 }
14778 if (keyCode >= 33 && keyCode <= 36 || keyCode >= 37 && keyCode <= 40 || keyCode === 45) {
14779 if (self.typing) {
14780 addNonTypingUndoLevel(e);
14781 }
14782 return;
14783 }
14784 var modKey = e.ctrlKey && !e.altKey || e.metaKey;
14785 if ((keyCode < 16 || keyCode > 20) && keyCode !== 224 && keyCode !== 91 && !self.typing && !modKey) {
14786 self.beforeChange();
14787 setTyping(true);
14788 self.add({}, e);
14789 isFirstTypedCharacter = true;
14790 }
14791 });
14792 editor.on('mousedown', function (e) {
14793 if (self.typing) {
14794 addNonTypingUndoLevel(e);
14795 }
14796 });
14797 var isInsertReplacementText = function (event) {
14798 return event.inputType === 'insertReplacementText';
14799 };
14800 var isInsertTextDataNull = function (event) {
14801 return event.inputType === 'insertText' && event.data === null;
14802 };
14803 editor.on('input', function (e) {
14804 if (e.inputType && (isInsertReplacementText(e) || isInsertTextDataNull(e))) {
14805 addNonTypingUndoLevel(e);
14806 }
14807 });
14808 editor.addShortcut('meta+z', '', 'Undo');
14809 editor.addShortcut('meta+y,meta+shift+z', '', 'Redo');
14810 editor.on('AddUndo Undo Redo ClearUndos', function (e) {
14811 if (!e.isDefaultPrevented()) {
14812 editor.nodeChanged();
14813 }
14814 });
14815 self = {
14816 data: data,
14817 typing: false,
14818 beforeChange: function () {
14819 if (isUnlocked()) {
14820 beforeBookmark = GetBookmark.getUndoBookmark(editor.selection);
14821 }
14822 },
14823 add: function (level, event) {
14824 var i;
14825 var settings = editor.settings;
14826 var lastLevel, currentLevel;
14827 currentLevel = Levels.createFromEditor(editor);
14828 level = level || {};
14829 level = Tools.extend(level, currentLevel);
14830 if (isUnlocked() === false || editor.removed) {
14831 return null;
14832 }
14833 lastLevel = data[index];
14834 if (editor.fire('BeforeAddUndo', {
14835 level: level,
14836 lastLevel: lastLevel,
14837 originalEvent: event
14838 }).isDefaultPrevented()) {
14839 return null;
14840 }
14841 if (lastLevel && Levels.isEq(lastLevel, level)) {
14842 return null;
14843 }
14844 if (data[index]) {
14845 data[index].beforeBookmark = beforeBookmark;
14846 }
14847 if (settings.custom_undo_redo_levels) {
14848 if (data.length > settings.custom_undo_redo_levels) {
14849 for (i = 0; i < data.length - 1; i++) {
14850 data[i] = data[i + 1];
14851 }
14852 data.length--;
14853 index = data.length;
14854 }
14855 }
14856 level.bookmark = GetBookmark.getUndoBookmark(editor.selection);
14857 if (index < data.length - 1) {
14858 data.length = index + 1;
14859 }
14860 data.push(level);
14861 index = data.length - 1;
14862 var args = {
14863 level: level,
14864 lastLevel: lastLevel,
14865 originalEvent: event
14866 };
14867 editor.fire('AddUndo', args);
14868 if (index > 0) {
14869 setDirty(true);
14870 editor.fire('change', args);
14871 }
14872 return level;
14873 },
14874 undo: function () {
14875 var level;
14876 if (self.typing) {
14877 self.add();
14878 self.typing = false;
14879 setTyping(false);
14880 }
14881 if (index > 0) {
14882 level = data[--index];
14883 Levels.applyToEditor(editor, level, true);
14884 setDirty(true);
14885 editor.fire('Undo', { level: level });
14886 }
14887 return level;
14888 },
14889 redo: function () {
14890 var level;
14891 if (index < data.length - 1) {
14892 level = data[++index];
14893 Levels.applyToEditor(editor, level, false);
14894 setDirty(true);
14895 editor.fire('Redo', { level: level });
14896 }
14897 return level;
14898 },
14899 clear: function () {
14900 data = [];
14901 index = 0;
14902 self.typing = false;
14903 self.data = data;
14904 editor.fire('ClearUndos');
14905 },
14906 reset: function () {
14907 self.clear();
14908 self.add();
14909 },
14910 hasUndo: function () {
14911 return index > 0 || self.typing && data[0] && !Levels.isEq(Levels.createFromEditor(editor), data[0]);
14912 },
14913 hasRedo: function () {
14914 return index < data.length - 1 && !self.typing;
14915 },
14916 transact: function (callback) {
14917 endTyping();
14918 self.beforeChange();
14919 self.ignore(callback);
14920 return self.add();
14921 },
14922 ignore: function (callback) {
14923 try {
14924 locks++;
14925 callback();
14926 } finally {
14927 locks--;
14928 }
14929 },
14930 extra: function (callback1, callback2) {
14931 var lastLevel, bookmark;
14932 if (self.transact(callback1)) {
14933 bookmark = data[index].bookmark;
14934 lastLevel = data[index - 1];
14935 Levels.applyToEditor(editor, lastLevel, true);
14936 if (self.transact(callback2)) {
14937 data[index - 1].beforeBookmark = bookmark;
14938 }
14939 }
14940 }
14941 };
14942 return self;
14943 };
14944
14945 var getLastChildren$1 = function (elm) {
14946 var children = [];
14947 var rawNode = elm.dom();
14948 while (rawNode) {
14949 children.push(Element.fromDom(rawNode));
14950 rawNode = rawNode.lastChild;
14951 }
14952 return children;
14953 };
14954 var removeTrailingBr = function (elm) {
14955 var allBrs = descendants$1(elm, 'br');
14956 var brs = filter(getLastChildren$1(elm).slice(-1), isBr$1);
14957 if (allBrs.length === brs.length) {
14958 each(brs, remove$1);
14959 }
14960 };
14961 var fillWithPaddingBr = function (elm) {
14962 empty(elm);
14963 append(elm, Element.fromHtml('<br data-mce-bogus="1">'));
14964 };
14965 var isPaddingContents = function (elm) {
14966 return isText(elm) ? get$5(elm) === '\xA0' : isBr$1(elm);
14967 };
14968 var isPaddedElement = function (elm) {
14969 return filter(children(elm), isPaddingContents).length === 1;
14970 };
14971 var trimBlockTrailingBr = function (elm) {
14972 lastChild(elm).each(function (lastChild) {
14973 prevSibling(lastChild).each(function (lastChildPrevSibling) {
14974 if (isBlock(elm) && isBr$1(lastChild) && isBlock(lastChildPrevSibling)) {
14975 remove$1(lastChild);
14976 }
14977 });
14978 });
14979 };
14980 var PaddingBr = {
14981 removeTrailingBr: removeTrailingBr,
14982 fillWithPaddingBr: fillWithPaddingBr,
14983 isPaddedElement: isPaddedElement,
14984 trimBlockTrailingBr: trimBlockTrailingBr
14985 };
14986
14987 var isEq$3 = FormatUtils.isEq;
14988 var matchesUnInheritedFormatSelector = function (ed, node, name) {
14989 var formatList = ed.formatter.get(name);
14990 if (formatList) {
14991 for (var i = 0; i < formatList.length; i++) {
14992 if (formatList[i].inherit === false && ed.dom.is(node, formatList[i].selector)) {
14993 return true;
14994 }
14995 }
14996 }
14997 return false;
14998 };
14999 var matchParents = function (editor, node, name, vars) {
15000 var root = editor.dom.getRoot();
15001 if (node === root) {
15002 return false;
15003 }
15004 node = editor.dom.getParent(node, function (node) {
15005 if (matchesUnInheritedFormatSelector(editor, node, name)) {
15006 return true;
15007 }
15008 return node.parentNode === root || !!matchNode(editor, node, name, vars, true);
15009 });
15010 return matchNode(editor, node, name, vars);
15011 };
15012 var matchName = function (dom, node, format) {
15013 if (isEq$3(node, format.inline)) {
15014 return true;
15015 }
15016 if (isEq$3(node, format.block)) {
15017 return true;
15018 }
15019 if (format.selector) {
15020 return node.nodeType === 1 && dom.is(node, format.selector);
15021 }
15022 };
15023 var matchItems = function (dom, node, format, itemName, similar, vars) {
15024 var key, value;
15025 var items = format[itemName];
15026 var i;
15027 if (format.onmatch) {
15028 return format.onmatch(node, format, itemName);
15029 }
15030 if (items) {
15031 if (typeof items.length === 'undefined') {
15032 for (key in items) {
15033 if (items.hasOwnProperty(key)) {
15034 if (itemName === 'attributes') {
15035 value = dom.getAttrib(node, key);
15036 } else {
15037 value = FormatUtils.getStyle(dom, node, key);
15038 }
15039 if (similar && !value && !format.exact) {
15040 return;
15041 }
15042 if ((!similar || format.exact) && !isEq$3(value, FormatUtils.normalizeStyleValue(dom, FormatUtils.replaceVars(items[key], vars), key))) {
15043 return;
15044 }
15045 }
15046 }
15047 } else {
15048 for (i = 0; i < items.length; i++) {
15049 if (itemName === 'attributes' ? dom.getAttrib(node, items[i]) : FormatUtils.getStyle(dom, node, items[i])) {
15050 return format;
15051 }
15052 }
15053 }
15054 }
15055 return format;
15056 };
15057 var matchNode = function (ed, node, name, vars, similar) {
15058 var formatList = ed.formatter.get(name);
15059 var format, i, x, classes;
15060 var dom = ed.dom;
15061 if (formatList && node) {
15062 for (i = 0; i < formatList.length; i++) {
15063 format = formatList[i];
15064 if (matchName(ed.dom, node, format) && matchItems(dom, node, format, 'attributes', similar, vars) && matchItems(dom, node, format, 'styles', similar, vars)) {
15065 if (classes = format.classes) {
15066 for (x = 0; x < classes.length; x++) {
15067 if (!ed.dom.hasClass(node, classes[x])) {
15068 return;
15069 }
15070 }
15071 }
15072 return format;
15073 }
15074 }
15075 }
15076 };
15077 var match = function (editor, name, vars, node) {
15078 var startNode;
15079 if (node) {
15080 return matchParents(editor, node, name, vars);
15081 }
15082 node = editor.selection.getNode();
15083 if (matchParents(editor, node, name, vars)) {
15084 return true;
15085 }
15086 startNode = editor.selection.getStart();
15087 if (startNode !== node) {
15088 if (matchParents(editor, startNode, name, vars)) {
15089 return true;
15090 }
15091 }
15092 return false;
15093 };
15094 var matchAll = function (editor, names, vars) {
15095 var startElement;
15096 var matchedFormatNames = [];
15097 var checkedMap = {};
15098 startElement = editor.selection.getStart();
15099 editor.dom.getParent(startElement, function (node) {
15100 var i, name;
15101 for (i = 0; i < names.length; i++) {
15102 name = names[i];
15103 if (!checkedMap[name] && matchNode(editor, node, name, vars)) {
15104 checkedMap[name] = true;
15105 matchedFormatNames.push(name);
15106 }
15107 }
15108 }, editor.dom.getRoot());
15109 return matchedFormatNames;
15110 };
15111 var canApply = function (editor, name) {
15112 var formatList = editor.formatter.get(name);
15113 var startNode, parents, i, x, selector;
15114 var dom = editor.dom;
15115 if (formatList) {
15116 startNode = editor.selection.getStart();
15117 parents = FormatUtils.getParents(dom, startNode);
15118 for (x = formatList.length - 1; x >= 0; x--) {
15119 selector = formatList[x].selector;
15120 if (!selector || formatList[x].defaultBlock) {
15121 return true;
15122 }
15123 for (i = parents.length - 1; i >= 0; i--) {
15124 if (dom.is(parents[i], selector)) {
15125 return true;
15126 }
15127 }
15128 }
15129 }
15130 return false;
15131 };
15132 var MatchFormat = {
15133 matchNode: matchNode,
15134 matchName: matchName,
15135 match: match,
15136 matchAll: matchAll,
15137 canApply: canApply,
15138 matchesUnInheritedFormatSelector: matchesUnInheritedFormatSelector
15139 };
15140
15141 var splitText = function (node, offset) {
15142 return node.splitText(offset);
15143 };
15144 var split$1 = function (rng) {
15145 var startContainer = rng.startContainer, startOffset = rng.startOffset, endContainer = rng.endContainer, endOffset = rng.endOffset;
15146 if (startContainer === endContainer && NodeType.isText(startContainer)) {
15147 if (startOffset > 0 && startOffset < startContainer.nodeValue.length) {
15148 endContainer = splitText(startContainer, startOffset);
15149 startContainer = endContainer.previousSibling;
15150 if (endOffset > startOffset) {
15151 endOffset = endOffset - startOffset;
15152 startContainer = endContainer = splitText(endContainer, endOffset).previousSibling;
15153 endOffset = endContainer.nodeValue.length;
15154 startOffset = 0;
15155 } else {
15156 endOffset = 0;
15157 }
15158 }
15159 } else {
15160 if (NodeType.isText(startContainer) && startOffset > 0 && startOffset < startContainer.nodeValue.length) {
15161 startContainer = splitText(startContainer, startOffset);
15162 startOffset = 0;
15163 }
15164 if (NodeType.isText(endContainer) && endOffset > 0 && endOffset < endContainer.nodeValue.length) {
15165 endContainer = splitText(endContainer, endOffset).previousSibling;
15166 endOffset = endContainer.nodeValue.length;
15167 }
15168 }
15169 return {
15170 startContainer: startContainer,
15171 startOffset: startOffset,
15172 endContainer: endContainer,
15173 endOffset: endOffset
15174 };
15175 };
15176
15177 var isCollapsibleWhitespace = function (c) {
15178 return ' \f\n\r\t\x0B'.indexOf(c) !== -1;
15179 };
15180 var normalizeContent = function (content, isStartOfContent, isEndOfContent) {
15181 var result = foldl(content, function (acc, c) {
15182 if (isCollapsibleWhitespace(c) || c === '\xA0') {
15183 if (acc.previousCharIsSpace || acc.str === '' && isStartOfContent || acc.str.length === content.length - 1 && isEndOfContent) {
15184 return {
15185 previousCharIsSpace: false,
15186 str: acc.str + '\xA0'
15187 };
15188 } else {
15189 return {
15190 previousCharIsSpace: true,
15191 str: acc.str + ' '
15192 };
15193 }
15194 } else {
15195 return {
15196 previousCharIsSpace: false,
15197 str: acc.str + c
15198 };
15199 }
15200 }, {
15201 previousCharIsSpace: false,
15202 str: ''
15203 });
15204 return result.str;
15205 };
15206 var normalize = function (node, offset, count) {
15207 if (count === 0) {
15208 return;
15209 }
15210 var whitespace = node.data.slice(offset, offset + count);
15211 var isEndOfContent = offset + count >= node.data.length;
15212 var isStartOfContent = offset === 0;
15213 node.replaceData(offset, count, normalizeContent(whitespace, isStartOfContent, isEndOfContent));
15214 };
15215 var normalizeWhitespaceAfter = function (node, offset) {
15216 var content = node.data.slice(offset);
15217 var whitespaceCount = content.length - lTrim(content).length;
15218 return normalize(node, offset, whitespaceCount);
15219 };
15220 var normalizeWhitespaceBefore = function (node, offset) {
15221 var content = node.data.slice(0, offset);
15222 var whitespaceCount = content.length - rTrim(content).length;
15223 return normalize(node, offset - whitespaceCount, whitespaceCount);
15224 };
15225 var mergeTextNodes = function (prevNode, nextNode, normalizeWhitespace) {
15226 var whitespaceOffset = rTrim(prevNode.data).length;
15227 prevNode.appendData(nextNode.data);
15228 remove$1(Element.fromDom(nextNode));
15229 if (normalizeWhitespace) {
15230 normalizeWhitespaceAfter(prevNode, whitespaceOffset);
15231 }
15232 return prevNode;
15233 };
15234
15235 var ancestor$2 = function (scope, selector, isRoot) {
15236 return ancestor$1(scope, selector, isRoot).isSome();
15237 };
15238
15239 var hasWhitespacePreserveParent = function (rootNode, node) {
15240 var rootElement = Element.fromDom(rootNode);
15241 var startNode = Element.fromDom(node);
15242 return ancestor$2(startNode, 'pre,code', curry(eq, rootElement));
15243 };
15244 var isWhitespace = function (rootNode, node) {
15245 return NodeType.isText(node) && /^[ \t\r\n]*$/.test(node.data) && hasWhitespacePreserveParent(rootNode, node) === false;
15246 };
15247 var isNamedAnchor = function (node) {
15248 return NodeType.isElement(node) && node.nodeName === 'A' && node.hasAttribute('name');
15249 };
15250 var isContent$1 = function (rootNode, node) {
15251 return isCaretCandidate(node) && isWhitespace(rootNode, node) === false || isNamedAnchor(node) || isBookmark(node);
15252 };
15253 var isBookmark = NodeType.hasAttribute('data-mce-bookmark');
15254 var isBogus$2 = NodeType.hasAttribute('data-mce-bogus');
15255 var isBogusAll$1 = NodeType.hasAttributeValue('data-mce-bogus', 'all');
15256 var isEmptyNode = function (targetNode) {
15257 var node, brCount = 0;
15258 if (isContent$1(targetNode, targetNode)) {
15259 return false;
15260 } else {
15261 node = targetNode.firstChild;
15262 if (!node) {
15263 return true;
15264 }
15265 var walker = new TreeWalker(node, targetNode);
15266 do {
15267 if (isBogusAll$1(node)) {
15268 node = walker.next(true);
15269 continue;
15270 }
15271 if (isBogus$2(node)) {
15272 node = walker.next();
15273 continue;
15274 }
15275 if (NodeType.isBr(node)) {
15276 brCount++;
15277 node = walker.next();
15278 continue;
15279 }
15280 if (isContent$1(targetNode, node)) {
15281 return false;
15282 }
15283 node = walker.next();
15284 } while (node);
15285 return brCount <= 1;
15286 }
15287 };
15288 var isEmpty$1 = function (elm) {
15289 return isEmptyNode(elm.dom());
15290 };
15291 var Empty = { isEmpty: isEmpty$1 };
15292
15293 var needsReposition = function (pos, elm) {
15294 var container = pos.container();
15295 var offset = pos.offset();
15296 return CaretPosition$1.isTextPosition(pos) === false && container === elm.parentNode && offset > CaretPosition$1.before(elm).offset();
15297 };
15298 var reposition = function (elm, pos) {
15299 return needsReposition(pos, elm) ? CaretPosition$1(pos.container(), pos.offset() - 1) : pos;
15300 };
15301 var beforeOrStartOf = function (node) {
15302 return NodeType.isText(node) ? CaretPosition$1(node, 0) : CaretPosition$1.before(node);
15303 };
15304 var afterOrEndOf = function (node) {
15305 return NodeType.isText(node) ? CaretPosition$1(node, node.data.length) : CaretPosition$1.after(node);
15306 };
15307 var getPreviousSiblingCaretPosition = function (elm) {
15308 if (isCaretCandidate(elm.previousSibling)) {
15309 return Option.some(afterOrEndOf(elm.previousSibling));
15310 } else {
15311 return elm.previousSibling ? CaretFinder.lastPositionIn(elm.previousSibling) : Option.none();
15312 }
15313 };
15314 var getNextSiblingCaretPosition = function (elm) {
15315 if (isCaretCandidate(elm.nextSibling)) {
15316 return Option.some(beforeOrStartOf(elm.nextSibling));
15317 } else {
15318 return elm.nextSibling ? CaretFinder.firstPositionIn(elm.nextSibling) : Option.none();
15319 }
15320 };
15321 var findCaretPositionBackwardsFromElm = function (rootElement, elm) {
15322 var startPosition = CaretPosition$1.before(elm.previousSibling ? elm.previousSibling : elm.parentNode);
15323 return CaretFinder.prevPosition(rootElement, startPosition).fold(function () {
15324 return CaretFinder.nextPosition(rootElement, CaretPosition$1.after(elm));
15325 }, Option.some);
15326 };
15327 var findCaretPositionForwardsFromElm = function (rootElement, elm) {
15328 return CaretFinder.nextPosition(rootElement, CaretPosition$1.after(elm)).fold(function () {
15329 return CaretFinder.prevPosition(rootElement, CaretPosition$1.before(elm));
15330 }, Option.some);
15331 };
15332 var findCaretPositionBackwards = function (rootElement, elm) {
15333 return getPreviousSiblingCaretPosition(elm).orThunk(function () {
15334 return getNextSiblingCaretPosition(elm);
15335 }).orThunk(function () {
15336 return findCaretPositionBackwardsFromElm(rootElement, elm);
15337 });
15338 };
15339 var findCaretPositionForward = function (rootElement, elm) {
15340 return getNextSiblingCaretPosition(elm).orThunk(function () {
15341 return getPreviousSiblingCaretPosition(elm);
15342 }).orThunk(function () {
15343 return findCaretPositionForwardsFromElm(rootElement, elm);
15344 });
15345 };
15346 var findCaretPosition$1 = function (forward, rootElement, elm) {
15347 return forward ? findCaretPositionForward(rootElement, elm) : findCaretPositionBackwards(rootElement, elm);
15348 };
15349 var findCaretPosOutsideElmAfterDelete = function (forward, rootElement, elm) {
15350 return findCaretPosition$1(forward, rootElement, elm).map(curry(reposition, elm));
15351 };
15352 var setSelection = function (editor, forward, pos) {
15353 pos.fold(function () {
15354 editor.focus();
15355 }, function (pos) {
15356 editor.selection.setRng(pos.toRange(), forward);
15357 });
15358 };
15359 var eqRawNode = function (rawNode) {
15360 return function (elm) {
15361 return elm.dom() === rawNode;
15362 };
15363 };
15364 var isBlock$2 = function (editor, elm) {
15365 return elm && editor.schema.getBlockElements().hasOwnProperty(name(elm));
15366 };
15367 var paddEmptyBlock = function (elm) {
15368 if (Empty.isEmpty(elm)) {
15369 var br = Element.fromHtml('<br data-mce-bogus="1">');
15370 empty(elm);
15371 append(elm, br);
15372 return Option.some(CaretPosition$1.before(br.dom()));
15373 } else {
15374 return Option.none();
15375 }
15376 };
15377 var deleteNormalized = function (elm, afterDeletePosOpt, normalizeWhitespace) {
15378 var prevTextOpt = prevSibling(elm).filter(function (e) {
15379 return NodeType.isText(e.dom());
15380 });
15381 var nextTextOpt = nextSibling(elm).filter(function (e) {
15382 return NodeType.isText(e.dom());
15383 });
15384 remove$1(elm);
15385 return liftN([
15386 prevTextOpt,
15387 nextTextOpt,
15388 afterDeletePosOpt
15389 ], function (prev, next, pos) {
15390 var prevNode = prev.dom(), nextNode = next.dom();
15391 var offset = prevNode.data.length;
15392 mergeTextNodes(prevNode, nextNode, normalizeWhitespace);
15393 return pos.container() === nextNode ? CaretPosition$1(prevNode, offset) : pos;
15394 }).orThunk(function () {
15395 if (normalizeWhitespace) {
15396 prevTextOpt.each(function (elm) {
15397 return normalizeWhitespaceBefore(elm.dom(), elm.dom().length);
15398 });
15399 nextTextOpt.each(function (elm) {
15400 return normalizeWhitespaceAfter(elm.dom(), 0);
15401 });
15402 }
15403 return afterDeletePosOpt;
15404 });
15405 };
15406 var isInlineElement = function (editor, element) {
15407 return has(editor.schema.getTextInlineElements(), name(element));
15408 };
15409 var deleteElement = function (editor, forward, elm, moveCaret) {
15410 if (moveCaret === void 0) {
15411 moveCaret = true;
15412 }
15413 var afterDeletePos = findCaretPosOutsideElmAfterDelete(forward, editor.getBody(), elm.dom());
15414 var parentBlock = ancestor(elm, curry(isBlock$2, editor), eqRawNode(editor.getBody()));
15415 var normalizedAfterDeletePos = deleteNormalized(elm, afterDeletePos, isInlineElement(editor, elm));
15416 if (editor.dom.isEmpty(editor.getBody())) {
15417 editor.setContent('');
15418 editor.selection.setCursorLocation();
15419 } else {
15420 parentBlock.bind(paddEmptyBlock).fold(function () {
15421 if (moveCaret) {
15422 setSelection(editor, forward, normalizedAfterDeletePos);
15423 }
15424 }, function (paddPos) {
15425 if (moveCaret) {
15426 setSelection(editor, forward, Option.some(paddPos));
15427 }
15428 });
15429 }
15430 };
15431 var DeleteElement = { deleteElement: deleteElement };
15432
15433 var ZWSP$1 = Zwsp.ZWSP, CARET_ID$1 = '_mce_caret';
15434 var importNode = function (ownerDocument, node) {
15435 return ownerDocument.importNode(node, true);
15436 };
15437 var getEmptyCaretContainers = function (node) {
15438 var nodes = [];
15439 while (node) {
15440 if (node.nodeType === 3 && node.nodeValue !== ZWSP$1 || node.childNodes.length > 1) {
15441 return [];
15442 }
15443 if (node.nodeType === 1) {
15444 nodes.push(node);
15445 }
15446 node = node.firstChild;
15447 }
15448 return nodes;
15449 };
15450 var isCaretContainerEmpty = function (node) {
15451 return getEmptyCaretContainers(node).length > 0;
15452 };
15453 var findFirstTextNode = function (node) {
15454 if (node) {
15455 var walker = new TreeWalker(node, node);
15456 for (node = walker.current(); node; node = walker.next()) {
15457 if (node.nodeType === 3) {
15458 return node;
15459 }
15460 }
15461 }
15462 return null;
15463 };
15464 var createCaretContainer = function (fill) {
15465 var caretContainer = Element.fromTag('span');
15466 setAll(caretContainer, {
15467 'id': CARET_ID$1,
15468 'data-mce-bogus': '1',
15469 'data-mce-type': 'format-caret'
15470 });
15471 if (fill) {
15472 append(caretContainer, Element.fromText(ZWSP$1));
15473 }
15474 return caretContainer;
15475 };
15476 var trimZwspFromCaretContainer = function (caretContainerNode) {
15477 var textNode = findFirstTextNode(caretContainerNode);
15478 if (textNode && textNode.nodeValue.charAt(0) === ZWSP$1) {
15479 textNode.deleteData(0, 1);
15480 }
15481 return textNode;
15482 };
15483 var removeCaretContainerNode = function (editor, node, moveCaret) {
15484 if (moveCaret === void 0) {
15485 moveCaret = true;
15486 }
15487 var dom = editor.dom, selection = editor.selection;
15488 if (isCaretContainerEmpty(node)) {
15489 DeleteElement.deleteElement(editor, false, Element.fromDom(node), moveCaret);
15490 } else {
15491 var rng = selection.getRng();
15492 var block = dom.getParent(node, dom.isBlock);
15493 var textNode = trimZwspFromCaretContainer(node);
15494 if (rng.startContainer === textNode && rng.startOffset > 0) {
15495 rng.setStart(textNode, rng.startOffset - 1);
15496 }
15497 if (rng.endContainer === textNode && rng.endOffset > 0) {
15498 rng.setEnd(textNode, rng.endOffset - 1);
15499 }
15500 dom.remove(node, true);
15501 if (block && dom.isEmpty(block)) {
15502 PaddingBr.fillWithPaddingBr(Element.fromDom(block));
15503 }
15504 selection.setRng(rng);
15505 }
15506 };
15507 var removeCaretContainer = function (editor, node, moveCaret) {
15508 if (moveCaret === void 0) {
15509 moveCaret = true;
15510 }
15511 var dom = editor.dom, selection = editor.selection;
15512 if (!node) {
15513 node = getParentCaretContainer(editor.getBody(), selection.getStart());
15514 if (!node) {
15515 while (node = dom.get(CARET_ID$1)) {
15516 removeCaretContainerNode(editor, node, false);
15517 }
15518 }
15519 } else {
15520 removeCaretContainerNode(editor, node, moveCaret);
15521 }
15522 };
15523 var insertCaretContainerNode = function (editor, caretContainer, formatNode) {
15524 var dom = editor.dom, block = dom.getParent(formatNode, curry(FormatUtils.isTextBlock, editor));
15525 if (block && dom.isEmpty(block)) {
15526 formatNode.parentNode.replaceChild(caretContainer, formatNode);
15527 } else {
15528 PaddingBr.removeTrailingBr(Element.fromDom(formatNode));
15529 if (dom.isEmpty(formatNode)) {
15530 formatNode.parentNode.replaceChild(caretContainer, formatNode);
15531 } else {
15532 dom.insertAfter(caretContainer, formatNode);
15533 }
15534 }
15535 };
15536 var appendNode = function (parentNode, node) {
15537 parentNode.appendChild(node);
15538 return node;
15539 };
15540 var insertFormatNodesIntoCaretContainer = function (formatNodes, caretContainer) {
15541 var innerMostFormatNode = foldr(formatNodes, function (parentNode, formatNode) {
15542 return appendNode(parentNode, formatNode.cloneNode(false));
15543 }, caretContainer);
15544 return appendNode(innerMostFormatNode, innerMostFormatNode.ownerDocument.createTextNode(ZWSP$1));
15545 };
15546 var applyCaretFormat = function (editor, name, vars) {
15547 var rng, caretContainer, textNode, offset, bookmark, container, text;
15548 var selection = editor.selection;
15549 rng = selection.getRng();
15550 offset = rng.startOffset;
15551 container = rng.startContainer;
15552 text = container.nodeValue;
15553 caretContainer = getParentCaretContainer(editor.getBody(), selection.getStart());
15554 if (caretContainer) {
15555 textNode = findFirstTextNode(caretContainer);
15556 }
15557 var wordcharRegex = /[^\s\u00a0\u00ad\u200b\ufeff]/;
15558 if (text && offset > 0 && offset < text.length && wordcharRegex.test(text.charAt(offset)) && wordcharRegex.test(text.charAt(offset - 1))) {
15559 bookmark = selection.getBookmark();
15560 rng.collapse(true);
15561 rng = ExpandRange.expandRng(editor, rng, editor.formatter.get(name));
15562 rng = split$1(rng);
15563 editor.formatter.apply(name, vars, rng);
15564 selection.moveToBookmark(bookmark);
15565 } else {
15566 if (!caretContainer || textNode.nodeValue !== ZWSP$1) {
15567 caretContainer = importNode(editor.getDoc(), createCaretContainer(true).dom());
15568 textNode = caretContainer.firstChild;
15569 rng.insertNode(caretContainer);
15570 offset = 1;
15571 editor.formatter.apply(name, vars, caretContainer);
15572 } else {
15573 editor.formatter.apply(name, vars, caretContainer);
15574 }
15575 selection.setCursorLocation(textNode, offset);
15576 }
15577 };
15578 var removeCaretFormat = function (editor, name, vars, similar) {
15579 var dom = editor.dom, selection = editor.selection;
15580 var container, offset, bookmark;
15581 var hasContentAfter, node, formatNode;
15582 var parents = [], rng = selection.getRng();
15583 var caretContainer;
15584 container = rng.startContainer;
15585 offset = rng.startOffset;
15586 node = container;
15587 if (container.nodeType === 3) {
15588 if (offset !== container.nodeValue.length) {
15589 hasContentAfter = true;
15590 }
15591 node = node.parentNode;
15592 }
15593 while (node) {
15594 if (MatchFormat.matchNode(editor, node, name, vars, similar)) {
15595 formatNode = node;
15596 break;
15597 }
15598 if (node.nextSibling) {
15599 hasContentAfter = true;
15600 }
15601 parents.push(node);
15602 node = node.parentNode;
15603 }
15604 if (!formatNode) {
15605 return;
15606 }
15607 if (hasContentAfter) {
15608 bookmark = selection.getBookmark();
15609 rng.collapse(true);
15610 var expandedRng = ExpandRange.expandRng(editor, rng, editor.formatter.get(name), true);
15611 expandedRng = split$1(expandedRng);
15612 editor.formatter.remove(name, vars, expandedRng);
15613 selection.moveToBookmark(bookmark);
15614 } else {
15615 caretContainer = getParentCaretContainer(editor.getBody(), formatNode);
15616 var newCaretContainer = createCaretContainer(false).dom();
15617 var caretNode = insertFormatNodesIntoCaretContainer(parents, newCaretContainer);
15618 if (caretContainer) {
15619 insertCaretContainerNode(editor, newCaretContainer, caretContainer);
15620 } else {
15621 insertCaretContainerNode(editor, newCaretContainer, formatNode);
15622 }
15623 removeCaretContainerNode(editor, caretContainer, false);
15624 selection.setCursorLocation(caretNode, 1);
15625 if (dom.isEmpty(formatNode)) {
15626 dom.remove(formatNode);
15627 }
15628 }
15629 };
15630 var disableCaretContainer = function (editor, keyCode) {
15631 var selection = editor.selection, body = editor.getBody();
15632 removeCaretContainer(editor, null, false);
15633 if ((keyCode === 8 || keyCode === 46) && selection.isCollapsed() && selection.getStart().innerHTML === ZWSP$1) {
15634 removeCaretContainer(editor, getParentCaretContainer(body, selection.getStart()));
15635 }
15636 if (keyCode === 37 || keyCode === 39) {
15637 removeCaretContainer(editor, getParentCaretContainer(body, selection.getStart()));
15638 }
15639 };
15640 var setup$5 = function (editor) {
15641 editor.on('mouseup keydown', function (e) {
15642 disableCaretContainer(editor, e.keyCode);
15643 });
15644 };
15645 var replaceWithCaretFormat = function (targetNode, formatNodes) {
15646 var caretContainer = createCaretContainer(false);
15647 var innerMost = insertFormatNodesIntoCaretContainer(formatNodes, caretContainer.dom());
15648 before(Element.fromDom(targetNode), caretContainer);
15649 remove$1(Element.fromDom(targetNode));
15650 return CaretPosition$1(innerMost, 0);
15651 };
15652 var isFormatElement = function (editor, element) {
15653 var inlineElements = editor.schema.getTextInlineElements();
15654 return inlineElements.hasOwnProperty(name(element)) && !isCaretNode(element.dom()) && !NodeType.isBogus(element.dom());
15655 };
15656 var isEmptyCaretFormatElement = function (element) {
15657 return isCaretNode(element.dom()) && isCaretContainerEmpty(element.dom());
15658 };
15659
15660 var postProcessHooks = {}, filter$3 = ArrUtils.filter, each$9 = ArrUtils.each;
15661 var addPostProcessHook = function (name, hook) {
15662 var hooks = postProcessHooks[name];
15663 if (!hooks) {
15664 postProcessHooks[name] = hooks = [];
15665 }
15666 postProcessHooks[name].push(hook);
15667 };
15668 var postProcess = function (name, editor) {
15669 each$9(postProcessHooks[name], function (hook) {
15670 hook(editor);
15671 });
15672 };
15673 addPostProcessHook('pre', function (editor) {
15674 var rng = editor.selection.getRng();
15675 var isPre, blocks;
15676 var hasPreSibling = function (pre) {
15677 return isPre(pre.previousSibling) && ArrUtils.indexOf(blocks, pre.previousSibling) !== -1;
15678 };
15679 var joinPre = function (pre1, pre2) {
15680 DomQuery(pre2).remove();
15681 DomQuery(pre1).append('<br><br>').append(pre2.childNodes);
15682 };
15683 isPre = NodeType.matchNodeNames(['pre']);
15684 if (!rng.collapsed) {
15685 blocks = editor.selection.getSelectedBlocks();
15686 each$9(filter$3(filter$3(blocks, isPre), hasPreSibling), function (pre) {
15687 joinPre(pre.previousSibling, pre);
15688 });
15689 }
15690 });
15691 var Hooks = { postProcess: postProcess };
15692
15693 var each$a = Tools.each;
15694 var ElementUtils = function (dom) {
15695 this.compare = function (node1, node2) {
15696 if (node1.nodeName !== node2.nodeName) {
15697 return false;
15698 }
15699 var getAttribs = function (node) {
15700 var attribs = {};
15701 each$a(dom.getAttribs(node), function (attr) {
15702 var name = attr.nodeName.toLowerCase();
15703 if (name.indexOf('_') !== 0 && name !== 'style' && name.indexOf('data-') !== 0) {
15704 attribs[name] = dom.getAttrib(node, name);
15705 }
15706 });
15707 return attribs;
15708 };
15709 var compareObjects = function (obj1, obj2) {
15710 var value, name;
15711 for (name in obj1) {
15712 if (obj1.hasOwnProperty(name)) {
15713 value = obj2[name];
15714 if (typeof value === 'undefined') {
15715 return false;
15716 }
15717 if (obj1[name] !== value) {
15718 return false;
15719 }
15720 delete obj2[name];
15721 }
15722 }
15723 for (name in obj2) {
15724 if (obj2.hasOwnProperty(name)) {
15725 return false;
15726 }
15727 }
15728 return true;
15729 };
15730 if (!compareObjects(getAttribs(node1), getAttribs(node2))) {
15731 return false;
15732 }
15733 if (!compareObjects(dom.parseStyle(dom.getAttrib(node1, 'style')), dom.parseStyle(dom.getAttrib(node2, 'style')))) {
15734 return false;
15735 }
15736 return !Bookmarks.isBookmarkNode(node1) && !Bookmarks.isBookmarkNode(node2);
15737 };
15738 };
15739
15740 var MCE_ATTR_RE = /^(src|href|style)$/;
15741 var each$b = Tools.each;
15742 var isEq$4 = FormatUtils.isEq;
15743 var isTableCell$2 = function (node) {
15744 return /^(TH|TD)$/.test(node.nodeName);
15745 };
15746 var isChildOfInlineParent = function (dom, node, parent) {
15747 return dom.isChildOf(node, parent) && node !== parent && !dom.isBlock(parent);
15748 };
15749 var getContainer = function (ed, rng, start) {
15750 var container, offset, lastIdx;
15751 container = rng[start ? 'startContainer' : 'endContainer'];
15752 offset = rng[start ? 'startOffset' : 'endOffset'];
15753 if (NodeType.isElement(container)) {
15754 lastIdx = container.childNodes.length - 1;
15755 if (!start && offset) {
15756 offset--;
15757 }
15758 container = container.childNodes[offset > lastIdx ? lastIdx : offset];
15759 }
15760 if (NodeType.isText(container) && start && offset >= container.nodeValue.length) {
15761 container = new TreeWalker(container, ed.getBody()).next() || container;
15762 }
15763 if (NodeType.isText(container) && !start && offset === 0) {
15764 container = new TreeWalker(container, ed.getBody()).prev() || container;
15765 }
15766 return container;
15767 };
15768 var wrap$2 = function (dom, node, name, attrs) {
15769 var wrapper = dom.create(name, attrs);
15770 node.parentNode.insertBefore(wrapper, node);
15771 wrapper.appendChild(node);
15772 return wrapper;
15773 };
15774 var wrapWithSiblings = function (dom, node, next, name, attrs) {
15775 var start = Element.fromDom(node);
15776 var wrapper = Element.fromDom(dom.create(name, attrs));
15777 var siblings = next ? nextSiblings(start) : prevSiblings(start);
15778 append$1(wrapper, siblings);
15779 if (next) {
15780 before(start, wrapper);
15781 prepend(wrapper, start);
15782 } else {
15783 after(start, wrapper);
15784 append(wrapper, start);
15785 }
15786 return wrapper.dom();
15787 };
15788 var matchName$1 = function (dom, node, format) {
15789 if (isEq$4(node, format.inline)) {
15790 return true;
15791 }
15792 if (isEq$4(node, format.block)) {
15793 return true;
15794 }
15795 if (format.selector) {
15796 return NodeType.isElement(node) && dom.is(node, format.selector);
15797 }
15798 };
15799 var isColorFormatAndAnchor = function (node, format) {
15800 return format.links && node.tagName === 'A';
15801 };
15802 var find$3 = function (dom, node, next, inc) {
15803 node = FormatUtils.getNonWhiteSpaceSibling(node, next, inc);
15804 return !node || (node.nodeName === 'BR' || dom.isBlock(node));
15805 };
15806 var removeNode$1 = function (ed, node, format) {
15807 var parentNode = node.parentNode;
15808 var rootBlockElm;
15809 var dom = ed.dom, forcedRootBlock = Settings.getForcedRootBlock(ed);
15810 if (format.block) {
15811 if (!forcedRootBlock) {
15812 if (dom.isBlock(node) && !dom.isBlock(parentNode)) {
15813 if (!find$3(dom, node, false) && !find$3(dom, node.firstChild, true, 1)) {
15814 node.insertBefore(dom.create('br'), node.firstChild);
15815 }
15816 if (!find$3(dom, node, true) && !find$3(dom, node.lastChild, false, 1)) {
15817 node.appendChild(dom.create('br'));
15818 }
15819 }
15820 } else {
15821 if (parentNode === dom.getRoot()) {
15822 if (!format.list_block || !isEq$4(node, format.list_block)) {
15823 each$b(Tools.grep(node.childNodes), function (node) {
15824 if (FormatUtils.isValid(ed, forcedRootBlock, node.nodeName.toLowerCase())) {
15825 if (!rootBlockElm) {
15826 rootBlockElm = wrap$2(dom, node, forcedRootBlock);
15827 dom.setAttribs(rootBlockElm, ed.settings.forced_root_block_attrs);
15828 } else {
15829 rootBlockElm.appendChild(node);
15830 }
15831 } else {
15832 rootBlockElm = 0;
15833 }
15834 });
15835 }
15836 }
15837 }
15838 }
15839 if (format.selector && format.inline && !isEq$4(format.inline, node)) {
15840 return;
15841 }
15842 dom.remove(node, 1);
15843 };
15844 var removeFormat = function (ed, format, vars, node, compareNode) {
15845 var i, attrs, stylesModified;
15846 var dom = ed.dom;
15847 if (!matchName$1(dom, node, format) && !isColorFormatAndAnchor(node, format)) {
15848 return false;
15849 }
15850 if (format.remove !== 'all') {
15851 each$b(format.styles, function (value, name) {
15852 value = FormatUtils.normalizeStyleValue(dom, FormatUtils.replaceVars(value, vars), name);
15853 if (typeof name === 'number') {
15854 name = value;
15855 compareNode = 0;
15856 }
15857 if (format.remove_similar || (!compareNode || isEq$4(FormatUtils.getStyle(dom, compareNode, name), value))) {
15858 dom.setStyle(node, name, '');
15859 }
15860 stylesModified = 1;
15861 });
15862 if (stylesModified && dom.getAttrib(node, 'style') === '') {
15863 node.removeAttribute('style');
15864 node.removeAttribute('data-mce-style');
15865 }
15866 each$b(format.attributes, function (value, name) {
15867 var valueOut;
15868 value = FormatUtils.replaceVars(value, vars);
15869 if (typeof name === 'number') {
15870 name = value;
15871 compareNode = 0;
15872 }
15873 if (format.remove_similar || (!compareNode || isEq$4(dom.getAttrib(compareNode, name), value))) {
15874 if (name === 'class') {
15875 value = dom.getAttrib(node, name);
15876 if (value) {
15877 valueOut = '';
15878 each$b(value.split(/\s+/), function (cls) {
15879 if (/mce\-\w+/.test(cls)) {
15880 valueOut += (valueOut ? ' ' : '') + cls;
15881 }
15882 });
15883 if (valueOut) {
15884 dom.setAttrib(node, name, valueOut);
15885 return;
15886 }
15887 }
15888 }
15889 if (name === 'class') {
15890 node.removeAttribute('className');
15891 }
15892 if (MCE_ATTR_RE.test(name)) {
15893 node.removeAttribute('data-mce-' + name);
15894 }
15895 node.removeAttribute(name);
15896 }
15897 });
15898 each$b(format.classes, function (value) {
15899 value = FormatUtils.replaceVars(value, vars);
15900 if (!compareNode || dom.hasClass(compareNode, value)) {
15901 dom.removeClass(node, value);
15902 }
15903 });
15904 attrs = dom.getAttribs(node);
15905 for (i = 0; i < attrs.length; i++) {
15906 var attrName = attrs[i].nodeName;
15907 if (attrName.indexOf('_') !== 0 && attrName.indexOf('data-') !== 0) {
15908 return false;
15909 }
15910 }
15911 }
15912 if (format.remove !== 'none') {
15913 removeNode$1(ed, node, format);
15914 return true;
15915 }
15916 };
15917 var findFormatRoot = function (editor, container, name, vars, similar) {
15918 var formatRoot;
15919 each$b(FormatUtils.getParents(editor.dom, container.parentNode).reverse(), function (parent) {
15920 var format;
15921 if (!formatRoot && parent.id !== '_start' && parent.id !== '_end') {
15922 format = MatchFormat.matchNode(editor, parent, name, vars, similar);
15923 if (format && format.split !== false) {
15924 formatRoot = parent;
15925 }
15926 }
15927 });
15928 return formatRoot;
15929 };
15930 var wrapAndSplit = function (editor, formatList, formatRoot, container, target, split, format, vars) {
15931 var parent, clone, lastClone, firstClone, i, formatRootParent;
15932 var dom = editor.dom;
15933 if (formatRoot) {
15934 formatRootParent = formatRoot.parentNode;
15935 for (parent = container.parentNode; parent && parent !== formatRootParent; parent = parent.parentNode) {
15936 clone = dom.clone(parent, false);
15937 for (i = 0; i < formatList.length; i++) {
15938 if (removeFormat(editor, formatList[i], vars, clone, clone)) {
15939 clone = 0;
15940 break;
15941 }
15942 }
15943 if (clone) {
15944 if (lastClone) {
15945 clone.appendChild(lastClone);
15946 }
15947 if (!firstClone) {
15948 firstClone = clone;
15949 }
15950 lastClone = clone;
15951 }
15952 }
15953 if (split && (!format.mixed || !dom.isBlock(formatRoot))) {
15954 container = dom.split(formatRoot, container);
15955 }
15956 if (lastClone) {
15957 target.parentNode.insertBefore(lastClone, target);
15958 firstClone.appendChild(target);
15959 }
15960 }
15961 return container;
15962 };
15963 var remove$7 = function (ed, name, vars, node, similar) {
15964 var formatList = ed.formatter.get(name), format = formatList[0];
15965 var bookmark, rng, contentEditable = true;
15966 var dom = ed.dom;
15967 var selection = ed.selection;
15968 var splitToFormatRoot = function (container) {
15969 var formatRoot = findFormatRoot(ed, container, name, vars, similar);
15970 return wrapAndSplit(ed, formatList, formatRoot, container, container, true, format, vars);
15971 };
15972 var isRemoveBookmarkNode = function (node) {
15973 return Bookmarks.isBookmarkNode(node) && NodeType.isElement(node) && (node.id === '_start' || node.id === '_end');
15974 };
15975 var process = function (node) {
15976 var children, i, l, lastContentEditable, hasContentEditableState;
15977 if (NodeType.isElement(node) && dom.getContentEditable(node)) {
15978 lastContentEditable = contentEditable;
15979 contentEditable = dom.getContentEditable(node) === 'true';
15980 hasContentEditableState = true;
15981 }
15982 children = Tools.grep(node.childNodes);
15983 if (contentEditable && !hasContentEditableState) {
15984 for (i = 0, l = formatList.length; i < l; i++) {
15985 if (removeFormat(ed, formatList[i], vars, node, node)) {
15986 break;
15987 }
15988 }
15989 }
15990 if (format.deep) {
15991 if (children.length) {
15992 for (i = 0, l = children.length; i < l; i++) {
15993 process(children[i]);
15994 }
15995 if (hasContentEditableState) {
15996 contentEditable = lastContentEditable;
15997 }
15998 }
15999 }
16000 };
16001 var unwrap = function (start) {
16002 var node = dom.get(start ? '_start' : '_end');
16003 var out = node[start ? 'firstChild' : 'lastChild'];
16004 if (isRemoveBookmarkNode(out)) {
16005 out = out[start ? 'firstChild' : 'lastChild'];
16006 }
16007 if (NodeType.isText(out) && out.data.length === 0) {
16008 out = start ? node.previousSibling || node.nextSibling : node.nextSibling || node.previousSibling;
16009 }
16010 dom.remove(node, true);
16011 return out;
16012 };
16013 var removeRngStyle = function (rng) {
16014 var startContainer, endContainer;
16015 var commonAncestorContainer = rng.commonAncestorContainer;
16016 rng = ExpandRange.expandRng(ed, rng, formatList, true);
16017 if (format.split) {
16018 rng = split$1(rng);
16019 startContainer = getContainer(ed, rng, true);
16020 endContainer = getContainer(ed, rng);
16021 if (startContainer !== endContainer) {
16022 if (/^(TR|TH|TD)$/.test(startContainer.nodeName) && startContainer.firstChild) {
16023 if (startContainer.nodeName === 'TR') {
16024 startContainer = startContainer.firstChild.firstChild || startContainer;
16025 } else {
16026 startContainer = startContainer.firstChild || startContainer;
16027 }
16028 }
16029 if (commonAncestorContainer && /^T(HEAD|BODY|FOOT|R)$/.test(commonAncestorContainer.nodeName) && isTableCell$2(endContainer) && endContainer.firstChild) {
16030 endContainer = endContainer.firstChild || endContainer;
16031 }
16032 if (isChildOfInlineParent(dom, startContainer, endContainer)) {
16033 var marker = Option.from(startContainer.firstChild).getOr(startContainer);
16034 splitToFormatRoot(wrapWithSiblings(dom, marker, true, 'span', {
16035 'id': '_start',
16036 'data-mce-type': 'bookmark'
16037 }));
16038 unwrap(true);
16039 return;
16040 }
16041 if (isChildOfInlineParent(dom, endContainer, startContainer)) {
16042 var marker = Option.from(endContainer.lastChild).getOr(endContainer);
16043 splitToFormatRoot(wrapWithSiblings(dom, marker, false, 'span', {
16044 'id': '_end',
16045 'data-mce-type': 'bookmark'
16046 }));
16047 unwrap(false);
16048 return;
16049 }
16050 startContainer = wrap$2(dom, startContainer, 'span', {
16051 'id': '_start',
16052 'data-mce-type': 'bookmark'
16053 });
16054 endContainer = wrap$2(dom, endContainer, 'span', {
16055 'id': '_end',
16056 'data-mce-type': 'bookmark'
16057 });
16058 splitToFormatRoot(startContainer);
16059 splitToFormatRoot(endContainer);
16060 startContainer = unwrap(true);
16061 endContainer = unwrap();
16062 } else {
16063 startContainer = endContainer = splitToFormatRoot(startContainer);
16064 }
16065 rng.startContainer = startContainer.parentNode ? startContainer.parentNode : startContainer;
16066 rng.startOffset = dom.nodeIndex(startContainer);
16067 rng.endContainer = endContainer.parentNode ? endContainer.parentNode : endContainer;
16068 rng.endOffset = dom.nodeIndex(endContainer) + 1;
16069 }
16070 RangeWalk.walk(dom, rng, function (nodes) {
16071 each$b(nodes, function (node) {
16072 process(node);
16073 if (NodeType.isElement(node) && ed.dom.getStyle(node, 'text-decoration') === 'underline' && node.parentNode && FormatUtils.getTextDecoration(dom, node.parentNode) === 'underline') {
16074 removeFormat(ed, {
16075 deep: false,
16076 exact: true,
16077 inline: 'span',
16078 styles: { textDecoration: 'underline' }
16079 }, null, node);
16080 }
16081 });
16082 });
16083 };
16084 if (node) {
16085 if (node.nodeType) {
16086 rng = dom.createRng();
16087 rng.setStartBefore(node);
16088 rng.setEndAfter(node);
16089 removeRngStyle(rng);
16090 } else {
16091 removeRngStyle(node);
16092 }
16093 return;
16094 }
16095 if (dom.getContentEditable(selection.getNode()) === 'false') {
16096 node = selection.getNode();
16097 for (var i = 0, l = formatList.length; i < l; i++) {
16098 if (formatList[i].ceFalseOverride) {
16099 if (removeFormat(ed, formatList[i], vars, node, node)) {
16100 break;
16101 }
16102 }
16103 }
16104 return;
16105 }
16106 if (!selection.isCollapsed() || !format.inline || dom.select('td[data-mce-selected],th[data-mce-selected]').length) {
16107 bookmark = GetBookmark.getPersistentBookmark(ed.selection, true);
16108 removeRngStyle(selection.getRng());
16109 selection.moveToBookmark(bookmark);
16110 if (format.inline && MatchFormat.match(ed, name, vars, selection.getStart())) {
16111 FormatUtils.moveStart(dom, selection, selection.getRng());
16112 }
16113 ed.nodeChanged();
16114 } else {
16115 removeCaretFormat(ed, name, vars, similar);
16116 }
16117 };
16118 var RemoveFormat = {
16119 removeFormat: removeFormat,
16120 remove: remove$7
16121 };
16122
16123 var each$c = Tools.each;
16124 var isElementNode = function (node) {
16125 return node && node.nodeType === 1 && !Bookmarks.isBookmarkNode(node) && !isCaretNode(node) && !NodeType.isBogus(node);
16126 };
16127 var findElementSibling = function (node, siblingName) {
16128 var sibling;
16129 for (sibling = node; sibling; sibling = sibling[siblingName]) {
16130 if (sibling.nodeType === 3 && sibling.nodeValue.length !== 0) {
16131 return node;
16132 }
16133 if (sibling.nodeType === 1 && !Bookmarks.isBookmarkNode(sibling)) {
16134 return sibling;
16135 }
16136 }
16137 return node;
16138 };
16139 var mergeSiblingsNodes = function (dom, prev, next) {
16140 var sibling, tmpSibling;
16141 var elementUtils = new ElementUtils(dom);
16142 if (prev && next) {
16143 prev = findElementSibling(prev, 'previousSibling');
16144 next = findElementSibling(next, 'nextSibling');
16145 if (elementUtils.compare(prev, next)) {
16146 for (sibling = prev.nextSibling; sibling && sibling !== next;) {
16147 tmpSibling = sibling;
16148 sibling = sibling.nextSibling;
16149 prev.appendChild(tmpSibling);
16150 }
16151 dom.remove(next);
16152 Tools.each(Tools.grep(next.childNodes), function (node) {
16153 prev.appendChild(node);
16154 });
16155 return prev;
16156 }
16157 }
16158 return next;
16159 };
16160 var processChildElements = function (node, filter, process) {
16161 each$c(node.childNodes, function (node) {
16162 if (isElementNode(node)) {
16163 if (filter(node)) {
16164 process(node);
16165 }
16166 if (node.hasChildNodes()) {
16167 processChildElements(node, filter, process);
16168 }
16169 }
16170 });
16171 };
16172 var hasStyle = function (dom, name) {
16173 return curry(function (name, node) {
16174 return !!(node && FormatUtils.getStyle(dom, node, name));
16175 }, name);
16176 };
16177 var applyStyle = function (dom, name, value) {
16178 return curry(function (name, value, node) {
16179 dom.setStyle(node, name, value);
16180 if (node.getAttribute('style') === '') {
16181 node.removeAttribute('style');
16182 }
16183 unwrapEmptySpan(dom, node);
16184 }, name, value);
16185 };
16186 var unwrapEmptySpan = function (dom, node) {
16187 if (node.nodeName === 'SPAN' && dom.getAttribs(node).length === 0) {
16188 dom.remove(node, true);
16189 }
16190 };
16191 var processUnderlineAndColor = function (dom, node) {
16192 var textDecoration;
16193 if (node.nodeType === 1 && node.parentNode && node.parentNode.nodeType === 1) {
16194 textDecoration = FormatUtils.getTextDecoration(dom, node.parentNode);
16195 if (dom.getStyle(node, 'color') && textDecoration) {
16196 dom.setStyle(node, 'text-decoration', textDecoration);
16197 } else if (dom.getStyle(node, 'text-decoration') === textDecoration) {
16198 dom.setStyle(node, 'text-decoration', null);
16199 }
16200 }
16201 };
16202 var mergeUnderlineAndColor = function (dom, format, vars, node) {
16203 if (format.styles.color || format.styles.textDecoration) {
16204 Tools.walk(node, curry(processUnderlineAndColor, dom), 'childNodes');
16205 processUnderlineAndColor(dom, node);
16206 }
16207 };
16208 var mergeBackgroundColorAndFontSize = function (dom, format, vars, node) {
16209 if (format.styles && format.styles.backgroundColor) {
16210 processChildElements(node, hasStyle(dom, 'fontSize'), applyStyle(dom, 'backgroundColor', FormatUtils.replaceVars(format.styles.backgroundColor, vars)));
16211 }
16212 };
16213 var mergeSubSup = function (dom, format, vars, node) {
16214 if (format.inline === 'sub' || format.inline === 'sup') {
16215 processChildElements(node, hasStyle(dom, 'fontSize'), applyStyle(dom, 'fontSize', ''));
16216 dom.remove(dom.select(format.inline === 'sup' ? 'sub' : 'sup', node), true);
16217 }
16218 };
16219 var mergeSiblings = function (dom, format, vars, node) {
16220 if (node && format.merge_siblings !== false) {
16221 node = mergeSiblingsNodes(dom, FormatUtils.getNonWhiteSpaceSibling(node), node);
16222 node = mergeSiblingsNodes(dom, node, FormatUtils.getNonWhiteSpaceSibling(node, true));
16223 }
16224 };
16225 var clearChildStyles = function (dom, format, node) {
16226 if (format.clear_child_styles) {
16227 var selector = format.links ? '*:not(a)' : '*';
16228 each$c(dom.select(selector, node), function (node) {
16229 if (isElementNode(node)) {
16230 each$c(format.styles, function (value, name) {
16231 dom.setStyle(node, name, '');
16232 });
16233 }
16234 });
16235 }
16236 };
16237 var mergeWithChildren = function (editor, formatList, vars, node) {
16238 each$c(formatList, function (format) {
16239 each$c(editor.dom.select(format.inline, node), function (child) {
16240 if (!isElementNode(child)) {
16241 return;
16242 }
16243 RemoveFormat.removeFormat(editor, format, vars, child, format.exact ? child : null);
16244 });
16245 clearChildStyles(editor.dom, format, node);
16246 });
16247 };
16248 var mergeWithParents = function (editor, format, name, vars, node) {
16249 if (MatchFormat.matchNode(editor, node.parentNode, name, vars)) {
16250 if (RemoveFormat.removeFormat(editor, format, vars, node)) {
16251 return;
16252 }
16253 }
16254 if (format.merge_with_parents) {
16255 editor.dom.getParent(node.parentNode, function (parent) {
16256 if (MatchFormat.matchNode(editor, parent, name, vars)) {
16257 RemoveFormat.removeFormat(editor, format, vars, node);
16258 return true;
16259 }
16260 });
16261 }
16262 };
16263 var MergeFormats = {
16264 mergeWithChildren: mergeWithChildren,
16265 mergeUnderlineAndColor: mergeUnderlineAndColor,
16266 mergeBackgroundColorAndFontSize: mergeBackgroundColorAndFontSize,
16267 mergeSubSup: mergeSubSup,
16268 mergeSiblings: mergeSiblings,
16269 mergeWithParents: mergeWithParents
16270 };
16271
16272 var createRange$1 = function (sc, so, ec, eo) {
16273 var rng = domGlobals.document.createRange();
16274 rng.setStart(sc, so);
16275 rng.setEnd(ec, eo);
16276 return rng;
16277 };
16278 var normalizeBlockSelectionRange = function (rng) {
16279 var startPos = CaretPosition$1.fromRangeStart(rng);
16280 var endPos = CaretPosition$1.fromRangeEnd(rng);
16281 var rootNode = rng.commonAncestorContainer;
16282 return CaretFinder.fromPosition(false, rootNode, endPos).map(function (newEndPos) {
16283 if (!isInSameBlock(startPos, endPos, rootNode) && isInSameBlock(startPos, newEndPos, rootNode)) {
16284 return createRange$1(startPos.container(), startPos.offset(), newEndPos.container(), newEndPos.offset());
16285 } else {
16286 return rng;
16287 }
16288 }).getOr(rng);
16289 };
16290 var normalize$1 = function (rng) {
16291 return rng.collapsed ? rng : normalizeBlockSelectionRange(rng);
16292 };
16293 var RangeNormalizer = { normalize: normalize$1 };
16294
16295 var each$d = Tools.each;
16296 var isElementNode$1 = function (node) {
16297 return node && node.nodeType === 1 && !Bookmarks.isBookmarkNode(node) && !isCaretNode(node) && !NodeType.isBogus(node);
16298 };
16299 var applyFormat = function (ed, name, vars, node) {
16300 var formatList = ed.formatter.get(name);
16301 var format = formatList[0];
16302 var bookmark, rng;
16303 var isCollapsed = !node && ed.selection.isCollapsed();
16304 var dom = ed.dom, selection = ed.selection;
16305 var setElementFormat = function (elm, fmt) {
16306 fmt = fmt || format;
16307 if (elm) {
16308 if (fmt.onformat) {
16309 fmt.onformat(elm, fmt, vars, node);
16310 }
16311 each$d(fmt.styles, function (value, name) {
16312 dom.setStyle(elm, name, FormatUtils.replaceVars(value, vars));
16313 });
16314 if (fmt.styles) {
16315 var styleVal = dom.getAttrib(elm, 'style');
16316 if (styleVal) {
16317 elm.setAttribute('data-mce-style', styleVal);
16318 }
16319 }
16320 each$d(fmt.attributes, function (value, name) {
16321 dom.setAttrib(elm, name, FormatUtils.replaceVars(value, vars));
16322 });
16323 each$d(fmt.classes, function (value) {
16324 value = FormatUtils.replaceVars(value, vars);
16325 if (!dom.hasClass(elm, value)) {
16326 dom.addClass(elm, value);
16327 }
16328 });
16329 }
16330 };
16331 var applyNodeStyle = function (formatList, node) {
16332 var found = false;
16333 if (!format.selector) {
16334 return false;
16335 }
16336 each$d(formatList, function (format) {
16337 if ('collapsed' in format && format.collapsed !== isCollapsed) {
16338 return;
16339 }
16340 if (dom.is(node, format.selector) && !isCaretNode(node)) {
16341 setElementFormat(node, format);
16342 found = true;
16343 return false;
16344 }
16345 });
16346 return found;
16347 };
16348 var applyRngStyle = function (dom, rng, bookmark, nodeSpecific) {
16349 var newWrappers = [];
16350 var wrapName, wrapElm, contentEditable = true;
16351 wrapName = format.inline || format.block;
16352 wrapElm = dom.create(wrapName);
16353 setElementFormat(wrapElm);
16354 RangeWalk.walk(dom, rng, function (nodes) {
16355 var currentWrapElm;
16356 var process = function (node) {
16357 var nodeName, parentName, hasContentEditableState, lastContentEditable;
16358 lastContentEditable = contentEditable;
16359 nodeName = node.nodeName.toLowerCase();
16360 parentName = node.parentNode.nodeName.toLowerCase();
16361 if (node.nodeType === 1 && dom.getContentEditable(node)) {
16362 lastContentEditable = contentEditable;
16363 contentEditable = dom.getContentEditable(node) === 'true';
16364 hasContentEditableState = true;
16365 }
16366 if (FormatUtils.isEq(nodeName, 'br')) {
16367 currentWrapElm = 0;
16368 if (format.block) {
16369 dom.remove(node);
16370 }
16371 return;
16372 }
16373 if (format.wrapper && MatchFormat.matchNode(ed, node, name, vars)) {
16374 currentWrapElm = 0;
16375 return;
16376 }
16377 if (contentEditable && !hasContentEditableState && format.block && !format.wrapper && FormatUtils.isTextBlock(ed, nodeName) && FormatUtils.isValid(ed, parentName, wrapName)) {
16378 node = dom.rename(node, wrapName);
16379 setElementFormat(node);
16380 newWrappers.push(node);
16381 currentWrapElm = 0;
16382 return;
16383 }
16384 if (format.selector) {
16385 var found = applyNodeStyle(formatList, node);
16386 if (!format.inline || found) {
16387 currentWrapElm = 0;
16388 return;
16389 }
16390 }
16391 if (contentEditable && !hasContentEditableState && FormatUtils.isValid(ed, wrapName, nodeName) && FormatUtils.isValid(ed, parentName, wrapName) && !(!nodeSpecific && node.nodeType === 3 && node.nodeValue.length === 1 && node.nodeValue.charCodeAt(0) === 65279) && !isCaretNode(node) && (!format.inline || !dom.isBlock(node))) {
16392 if (!currentWrapElm) {
16393 currentWrapElm = dom.clone(wrapElm, false);
16394 node.parentNode.insertBefore(currentWrapElm, node);
16395 newWrappers.push(currentWrapElm);
16396 }
16397 currentWrapElm.appendChild(node);
16398 } else {
16399 currentWrapElm = 0;
16400 each$d(Tools.grep(node.childNodes), process);
16401 if (hasContentEditableState) {
16402 contentEditable = lastContentEditable;
16403 }
16404 currentWrapElm = 0;
16405 }
16406 };
16407 each$d(nodes, process);
16408 });
16409 if (format.links === true) {
16410 each$d(newWrappers, function (node) {
16411 var process = function (node) {
16412 if (node.nodeName === 'A') {
16413 setElementFormat(node, format);
16414 }
16415 each$d(Tools.grep(node.childNodes), process);
16416 };
16417 process(node);
16418 });
16419 }
16420 each$d(newWrappers, function (node) {
16421 var childCount;
16422 var getChildCount = function (node) {
16423 var count = 0;
16424 each$d(node.childNodes, function (node) {
16425 if (!FormatUtils.isWhiteSpaceNode(node) && !Bookmarks.isBookmarkNode(node)) {
16426 count++;
16427 }
16428 });
16429 return count;
16430 };
16431 var getChildElementNode = function (root) {
16432 var child = false;
16433 each$d(root.childNodes, function (node) {
16434 if (isElementNode$1(node)) {
16435 child = node;
16436 return false;
16437 }
16438 });
16439 return child;
16440 };
16441 var mergeStyles = function (node) {
16442 var child, clone;
16443 child = getChildElementNode(node);
16444 if (child && !Bookmarks.isBookmarkNode(child) && MatchFormat.matchName(dom, child, format)) {
16445 clone = dom.clone(child, false);
16446 setElementFormat(clone);
16447 dom.replace(clone, node, true);
16448 dom.remove(child, 1);
16449 }
16450 return clone || node;
16451 };
16452 childCount = getChildCount(node);
16453 if ((newWrappers.length > 1 || !dom.isBlock(node)) && childCount === 0) {
16454 dom.remove(node, 1);
16455 return;
16456 }
16457 if (format.inline || format.wrapper) {
16458 if (!format.exact && childCount === 1) {
16459 node = mergeStyles(node);
16460 }
16461 MergeFormats.mergeWithChildren(ed, formatList, vars, node);
16462 MergeFormats.mergeWithParents(ed, format, name, vars, node);
16463 MergeFormats.mergeBackgroundColorAndFontSize(dom, format, vars, node);
16464 MergeFormats.mergeSubSup(dom, format, vars, node);
16465 MergeFormats.mergeSiblings(dom, format, vars, node);
16466 }
16467 });
16468 };
16469 if (dom.getContentEditable(selection.getNode()) === 'false') {
16470 node = selection.getNode();
16471 for (var i = 0, l = formatList.length; i < l; i++) {
16472 if (formatList[i].ceFalseOverride && dom.is(node, formatList[i].selector)) {
16473 setElementFormat(node, formatList[i]);
16474 return;
16475 }
16476 }
16477 return;
16478 }
16479 if (format) {
16480 if (node) {
16481 if (node.nodeType) {
16482 if (!applyNodeStyle(formatList, node)) {
16483 rng = dom.createRng();
16484 rng.setStartBefore(node);
16485 rng.setEndAfter(node);
16486 applyRngStyle(dom, ExpandRange.expandRng(ed, rng, formatList), null, true);
16487 }
16488 } else {
16489 applyRngStyle(dom, node, null, true);
16490 }
16491 } else {
16492 if (!isCollapsed || !format.inline || dom.select('td[data-mce-selected],th[data-mce-selected]').length) {
16493 var curSelNode = ed.selection.getNode();
16494 if (!ed.settings.forced_root_block && formatList[0].defaultBlock && !dom.getParent(curSelNode, dom.isBlock)) {
16495 applyFormat(ed, formatList[0].defaultBlock);
16496 }
16497 ed.selection.setRng(RangeNormalizer.normalize(ed.selection.getRng()));
16498 bookmark = GetBookmark.getPersistentBookmark(ed.selection, true);
16499 applyRngStyle(dom, ExpandRange.expandRng(ed, selection.getRng(), formatList));
16500 if (format.styles) {
16501 MergeFormats.mergeUnderlineAndColor(dom, format, vars, curSelNode);
16502 }
16503 selection.moveToBookmark(bookmark);
16504 FormatUtils.moveStart(dom, selection, selection.getRng());
16505 ed.nodeChanged();
16506 } else {
16507 applyCaretFormat(ed, name, vars);
16508 }
16509 }
16510 Hooks.postProcess(name, ed);
16511 }
16512 };
16513 var ApplyFormat = { applyFormat: applyFormat };
16514
16515 var setup$6 = function (registeredFormatListeners, editor) {
16516 var currentFormats = Cell({});
16517 registeredFormatListeners.set({});
16518 editor.on('NodeChange', function (e) {
16519 updateAndFireChangeCallbacks(editor, e.element, currentFormats, registeredFormatListeners.get());
16520 });
16521 };
16522 var updateAndFireChangeCallbacks = function (editor, elm, currentFormats, formatChangeData) {
16523 var formatsList = keys(currentFormats.get());
16524 var newFormats = {};
16525 var matchedFormats = {};
16526 var parents = filter(FormatUtils.getParents(editor.dom, elm), function (node) {
16527 return node.nodeType === 1 && !node.getAttribute('data-mce-bogus');
16528 });
16529 each$3(formatChangeData, function (data, format) {
16530 Tools.each(parents, function (node) {
16531 if (editor.formatter.matchNode(node, format, {}, data.similar)) {
16532 if (formatsList.indexOf(format) === -1) {
16533 each(data.callbacks, function (callback) {
16534 callback(true, {
16535 node: node,
16536 format: format,
16537 parents: parents
16538 });
16539 });
16540 newFormats[format] = data.callbacks;
16541 }
16542 matchedFormats[format] = data.callbacks;
16543 return false;
16544 }
16545 if (MatchFormat.matchesUnInheritedFormatSelector(editor, node, format)) {
16546 return false;
16547 }
16548 });
16549 });
16550 var remainingFormats = filterRemainingFormats(currentFormats.get(), matchedFormats, elm, parents);
16551 currentFormats.set(__assign({}, newFormats, remainingFormats));
16552 };
16553 var filterRemainingFormats = function (currentFormats, matchedFormats, elm, parents) {
16554 return bifilter(currentFormats, function (callbacks, format) {
16555 if (!has(matchedFormats, format)) {
16556 each(callbacks, function (callback) {
16557 callback(false, {
16558 node: elm,
16559 format: format,
16560 parents: parents
16561 });
16562 });
16563 return false;
16564 } else {
16565 return true;
16566 }
16567 }).t;
16568 };
16569 var addListeners = function (registeredFormatListeners, formats, callback, similar) {
16570 var formatChangeItems = registeredFormatListeners.get();
16571 each(formats.split(','), function (format) {
16572 if (!formatChangeItems[format]) {
16573 formatChangeItems[format] = {
16574 similar: similar,
16575 callbacks: []
16576 };
16577 }
16578 formatChangeItems[format].callbacks.push(callback);
16579 });
16580 registeredFormatListeners.set(formatChangeItems);
16581 };
16582 var removeListeners = function (registeredFormatListeners, formats, callback) {
16583 var formatChangeItems = registeredFormatListeners.get();
16584 each(formats.split(','), function (format) {
16585 formatChangeItems[format].callbacks = filter(formatChangeItems[format].callbacks, function (c) {
16586 return c !== callback;
16587 });
16588 if (formatChangeItems[format].callbacks.length === 0) {
16589 delete formatChangeItems[format];
16590 }
16591 });
16592 registeredFormatListeners.set(formatChangeItems);
16593 };
16594 var formatChanged = function (editor, registeredFormatListeners, formats, callback, similar) {
16595 if (registeredFormatListeners.get() === null) {
16596 setup$6(registeredFormatListeners, editor);
16597 }
16598 addListeners(registeredFormatListeners, formats, callback, similar);
16599 return {
16600 unbind: function () {
16601 return removeListeners(registeredFormatListeners, formats, callback);
16602 }
16603 };
16604 };
16605
16606 var get$6 = function (dom) {
16607 var formats = {
16608 valigntop: [{
16609 selector: 'td,th',
16610 styles: { verticalAlign: 'top' }
16611 }],
16612 valignmiddle: [{
16613 selector: 'td,th',
16614 styles: { verticalAlign: 'middle' }
16615 }],
16616 valignbottom: [{
16617 selector: 'td,th',
16618 styles: { verticalAlign: 'bottom' }
16619 }],
16620 alignleft: [
16621 {
16622 selector: 'figure.image',
16623 collapsed: false,
16624 classes: 'align-left',
16625 ceFalseOverride: true,
16626 preview: 'font-family font-size'
16627 },
16628 {
16629 selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
16630 styles: { textAlign: 'left' },
16631 inherit: false,
16632 preview: false,
16633 defaultBlock: 'div'
16634 },
16635 {
16636 selector: 'img,table',
16637 collapsed: false,
16638 styles: { float: 'left' },
16639 preview: 'font-family font-size'
16640 }
16641 ],
16642 aligncenter: [
16643 {
16644 selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
16645 styles: { textAlign: 'center' },
16646 inherit: false,
16647 preview: 'font-family font-size',
16648 defaultBlock: 'div'
16649 },
16650 {
16651 selector: 'figure.image',
16652 collapsed: false,
16653 classes: 'align-center',
16654 ceFalseOverride: true,
16655 preview: 'font-family font-size'
16656 },
16657 {
16658 selector: 'img',
16659 collapsed: false,
16660 styles: {
16661 display: 'block',
16662 marginLeft: 'auto',
16663 marginRight: 'auto'
16664 },
16665 preview: false
16666 },
16667 {
16668 selector: 'table',
16669 collapsed: false,
16670 styles: {
16671 marginLeft: 'auto',
16672 marginRight: 'auto'
16673 },
16674 preview: 'font-family font-size'
16675 }
16676 ],
16677 alignright: [
16678 {
16679 selector: 'figure.image',
16680 collapsed: false,
16681 classes: 'align-right',
16682 ceFalseOverride: true,
16683 preview: 'font-family font-size'
16684 },
16685 {
16686 selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
16687 styles: { textAlign: 'right' },
16688 inherit: false,
16689 preview: 'font-family font-size',
16690 defaultBlock: 'div'
16691 },
16692 {
16693 selector: 'img,table',
16694 collapsed: false,
16695 styles: { float: 'right' },
16696 preview: 'font-family font-size'
16697 }
16698 ],
16699 alignjustify: [{
16700 selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
16701 styles: { textAlign: 'justify' },
16702 inherit: false,
16703 defaultBlock: 'div',
16704 preview: 'font-family font-size'
16705 }],
16706 bold: [
16707 {
16708 inline: 'strong',
16709 remove: 'all'
16710 },
16711 {
16712 inline: 'span',
16713 styles: { fontWeight: 'bold' }
16714 },
16715 {
16716 inline: 'b',
16717 remove: 'all'
16718 }
16719 ],
16720 italic: [
16721 {
16722 inline: 'em',
16723 remove: 'all'
16724 },
16725 {
16726 inline: 'span',
16727 styles: { fontStyle: 'italic' }
16728 },
16729 {
16730 inline: 'i',
16731 remove: 'all'
16732 }
16733 ],
16734 underline: [
16735 {
16736 inline: 'span',
16737 styles: { textDecoration: 'underline' },
16738 exact: true
16739 },
16740 {
16741 inline: 'u',
16742 remove: 'all'
16743 }
16744 ],
16745 strikethrough: [
16746 {
16747 inline: 'span',
16748 styles: { textDecoration: 'line-through' },
16749 exact: true
16750 },
16751 {
16752 inline: 'strike',
16753 remove: 'all'
16754 }
16755 ],
16756 forecolor: {
16757 inline: 'span',
16758 styles: { color: '%value' },
16759 links: true,
16760 remove_similar: true,
16761 clear_child_styles: true
16762 },
16763 hilitecolor: {
16764 inline: 'span',
16765 styles: { backgroundColor: '%value' },
16766 links: true,
16767 remove_similar: true,
16768 clear_child_styles: true
16769 },
16770 fontname: {
16771 inline: 'span',
16772 toggle: false,
16773 styles: { fontFamily: '%value' },
16774 clear_child_styles: true
16775 },
16776 fontsize: {
16777 inline: 'span',
16778 toggle: false,
16779 styles: { fontSize: '%value' },
16780 clear_child_styles: true
16781 },
16782 fontsize_class: {
16783 inline: 'span',
16784 attributes: { class: '%value' }
16785 },
16786 blockquote: {
16787 block: 'blockquote',
16788 wrapper: true,
16789 remove: 'all'
16790 },
16791 subscript: { inline: 'sub' },
16792 superscript: { inline: 'sup' },
16793 code: { inline: 'code' },
16794 link: {
16795 inline: 'a',
16796 selector: 'a',
16797 remove: 'all',
16798 split: true,
16799 deep: true,
16800 onmatch: function () {
16801 return true;
16802 },
16803 onformat: function (elm, fmt, vars) {
16804 Tools.each(vars, function (value, key) {
16805 dom.setAttrib(elm, key, value);
16806 });
16807 }
16808 },
16809 removeformat: [
16810 {
16811 selector: 'b,strong,em,i,font,u,strike,sub,sup,dfn,code,samp,kbd,var,cite,mark,q,del,ins',
16812 remove: 'all',
16813 split: true,
16814 expand: false,
16815 block_expand: true,
16816 deep: true
16817 },
16818 {
16819 selector: 'span',
16820 attributes: [
16821 'style',
16822 'class'
16823 ],
16824 remove: 'empty',
16825 split: true,
16826 expand: false,
16827 deep: true
16828 },
16829 {
16830 selector: '*',
16831 attributes: [
16832 'style',
16833 'class'
16834 ],
16835 split: false,
16836 expand: false,
16837 deep: true
16838 }
16839 ]
16840 };
16841 Tools.each('p h1 h2 h3 h4 h5 h6 div address pre div dt dd samp'.split(/\s/), function (name) {
16842 formats[name] = {
16843 block: name,
16844 remove: 'all'
16845 };
16846 });
16847 return formats;
16848 };
16849 var DefaultFormats = { get: get$6 };
16850
16851 function FormatRegistry(editor) {
16852 var formats = {};
16853 var get = function (name) {
16854 return name ? formats[name] : formats;
16855 };
16856 var has$1 = function (name) {
16857 return has(formats, name);
16858 };
16859 var register = function (name, format) {
16860 if (name) {
16861 if (typeof name !== 'string') {
16862 Tools.each(name, function (format, name) {
16863 register(name, format);
16864 });
16865 } else {
16866 if (!isArray(format)) {
16867 format = [format];
16868 }
16869 Tools.each(format, function (format) {
16870 if (typeof format.deep === 'undefined') {
16871 format.deep = !format.selector;
16872 }
16873 if (typeof format.split === 'undefined') {
16874 format.split = !format.selector || format.inline;
16875 }
16876 if (typeof format.remove === 'undefined' && format.selector && !format.inline) {
16877 format.remove = 'none';
16878 }
16879 if (format.selector && format.inline) {
16880 format.mixed = true;
16881 format.block_expand = true;
16882 }
16883 if (typeof format.classes === 'string') {
16884 format.classes = format.classes.split(/\s+/);
16885 }
16886 });
16887 formats[name] = format;
16888 }
16889 }
16890 };
16891 var unregister = function (name) {
16892 if (name && formats[name]) {
16893 delete formats[name];
16894 }
16895 return formats;
16896 };
16897 register(DefaultFormats.get(editor.dom));
16898 register(editor.settings.formats);
16899 return {
16900 get: get,
16901 has: has$1,
16902 register: register,
16903 unregister: unregister
16904 };
16905 }
16906
16907 var each$e = Tools.each;
16908 var dom = DOMUtils$1.DOM;
16909 var parsedSelectorToHtml = function (ancestry, editor) {
16910 var elm, item, fragment;
16911 var schema = editor && editor.schema || Schema({});
16912 var decorate = function (elm, item) {
16913 if (item.classes.length) {
16914 dom.addClass(elm, item.classes.join(' '));
16915 }
16916 dom.setAttribs(elm, item.attrs);
16917 };
16918 var createElement = function (sItem) {
16919 var elm;
16920 item = typeof sItem === 'string' ? {
16921 name: sItem,
16922 classes: [],
16923 attrs: {}
16924 } : sItem;
16925 elm = dom.create(item.name);
16926 decorate(elm, item);
16927 return elm;
16928 };
16929 var getRequiredParent = function (elm, candidate) {
16930 var name = typeof elm !== 'string' ? elm.nodeName.toLowerCase() : elm;
16931 var elmRule = schema.getElementRule(name);
16932 var parentsRequired = elmRule && elmRule.parentsRequired;
16933 if (parentsRequired && parentsRequired.length) {
16934 return candidate && Tools.inArray(parentsRequired, candidate) !== -1 ? candidate : parentsRequired[0];
16935 } else {
16936 return false;
16937 }
16938 };
16939 var wrapInHtml = function (elm, ancestry, siblings) {
16940 var parent, parentCandidate, parentRequired;
16941 var ancestor = ancestry.length > 0 && ancestry[0];
16942 var ancestorName = ancestor && ancestor.name;
16943 parentRequired = getRequiredParent(elm, ancestorName);
16944 if (parentRequired) {
16945 if (ancestorName === parentRequired) {
16946 parentCandidate = ancestry[0];
16947 ancestry = ancestry.slice(1);
16948 } else {
16949 parentCandidate = parentRequired;
16950 }
16951 } else if (ancestor) {
16952 parentCandidate = ancestry[0];
16953 ancestry = ancestry.slice(1);
16954 } else if (!siblings) {
16955 return elm;
16956 }
16957 if (parentCandidate) {
16958 parent = createElement(parentCandidate);
16959 parent.appendChild(elm);
16960 }
16961 if (siblings) {
16962 if (!parent) {
16963 parent = dom.create('div');
16964 parent.appendChild(elm);
16965 }
16966 Tools.each(siblings, function (sibling) {
16967 var siblingElm = createElement(sibling);
16968 parent.insertBefore(siblingElm, elm);
16969 });
16970 }
16971 return wrapInHtml(parent, ancestry, parentCandidate && parentCandidate.siblings);
16972 };
16973 if (ancestry && ancestry.length) {
16974 item = ancestry[0];
16975 elm = createElement(item);
16976 fragment = dom.create('div');
16977 fragment.appendChild(wrapInHtml(elm, ancestry.slice(1), item.siblings));
16978 return fragment;
16979 } else {
16980 return '';
16981 }
16982 };
16983 var selectorToHtml = function (selector, editor) {
16984 return parsedSelectorToHtml(parseSelector(selector), editor);
16985 };
16986 var parseSelectorItem = function (item) {
16987 var tagName;
16988 var obj = {
16989 classes: [],
16990 attrs: {}
16991 };
16992 item = obj.selector = Tools.trim(item);
16993 if (item !== '*') {
16994 tagName = item.replace(/(?:([#\.]|::?)([\w\-]+)|(\[)([^\]]+)\]?)/g, function ($0, $1, $2, $3, $4) {
16995 switch ($1) {
16996 case '#':
16997 obj.attrs.id = $2;
16998 break;
16999 case '.':
17000 obj.classes.push($2);
17001 break;
17002 case ':':
17003 if (Tools.inArray('checked disabled enabled read-only required'.split(' '), $2) !== -1) {
17004 obj.attrs[$2] = $2;
17005 }
17006 break;
17007 }
17008 if ($3 === '[') {
17009 var m = $4.match(/([\w\-]+)(?:\=\"([^\"]+))?/);
17010 if (m) {
17011 obj.attrs[m[1]] = m[2];
17012 }
17013 }
17014 return '';
17015 });
17016 }
17017 obj.name = tagName || 'div';
17018 return obj;
17019 };
17020 var parseSelector = function (selector) {
17021 if (!selector || typeof selector !== 'string') {
17022 return [];
17023 }
17024 selector = selector.split(/\s*,\s*/)[0];
17025 selector = selector.replace(/\s*(~\+|~|\+|>)\s*/g, '$1');
17026 return Tools.map(selector.split(/(?:>|\s+(?![^\[\]]+\]))/), function (item) {
17027 var siblings = Tools.map(item.split(/(?:~\+|~|\+)/), parseSelectorItem);
17028 var obj = siblings.pop();
17029 if (siblings.length) {
17030 obj.siblings = siblings;
17031 }
17032 return obj;
17033 }).reverse();
17034 };
17035 var getCssText = function (editor, format) {
17036 var name, previewFrag, previewElm, items;
17037 var previewCss = '', parentFontSize, previewStyles;
17038 previewStyles = editor.settings.preview_styles;
17039 if (previewStyles === false) {
17040 return '';
17041 }
17042 if (typeof previewStyles !== 'string') {
17043 previewStyles = 'font-family font-size font-weight font-style text-decoration ' + 'text-transform color background-color border border-radius outline text-shadow';
17044 }
17045 var removeVars = function (val) {
17046 return val.replace(/%(\w+)/g, '');
17047 };
17048 if (typeof format === 'string') {
17049 format = editor.formatter.get(format);
17050 if (!format) {
17051 return;
17052 }
17053 format = format[0];
17054 }
17055 if ('preview' in format) {
17056 previewStyles = format.preview;
17057 if (previewStyles === false) {
17058 return '';
17059 }
17060 }
17061 name = format.block || format.inline || 'span';
17062 items = parseSelector(format.selector);
17063 if (items.length) {
17064 if (!items[0].name) {
17065 items[0].name = name;
17066 }
17067 name = format.selector;
17068 previewFrag = parsedSelectorToHtml(items, editor);
17069 } else {
17070 previewFrag = parsedSelectorToHtml([name], editor);
17071 }
17072 previewElm = dom.select(name, previewFrag)[0] || previewFrag.firstChild;
17073 each$e(format.styles, function (value, name) {
17074 value = removeVars(value);
17075 if (value) {
17076 dom.setStyle(previewElm, name, value);
17077 }
17078 });
17079 each$e(format.attributes, function (value, name) {
17080 value = removeVars(value);
17081 if (value) {
17082 dom.setAttrib(previewElm, name, value);
17083 }
17084 });
17085 each$e(format.classes, function (value) {
17086 value = removeVars(value);
17087 if (!dom.hasClass(previewElm, value)) {
17088 dom.addClass(previewElm, value);
17089 }
17090 });
17091 editor.fire('PreviewFormats');
17092 dom.setStyles(previewFrag, {
17093 position: 'absolute',
17094 left: -65535
17095 });
17096 editor.getBody().appendChild(previewFrag);
17097 parentFontSize = dom.getStyle(editor.getBody(), 'fontSize', true);
17098 parentFontSize = /px$/.test(parentFontSize) ? parseInt(parentFontSize, 10) : 0;
17099 each$e(previewStyles.split(' '), function (name) {
17100 var value = dom.getStyle(previewElm, name, true);
17101 if (name === 'background-color' && /transparent|rgba\s*\([^)]+,\s*0\)/.test(value)) {
17102 value = dom.getStyle(editor.getBody(), name, true);
17103 if (dom.toHex(value).toLowerCase() === '#ffffff') {
17104 return;
17105 }
17106 }
17107 if (name === 'color') {
17108 if (dom.toHex(value).toLowerCase() === '#000000') {
17109 return;
17110 }
17111 }
17112 if (name === 'font-size') {
17113 if (/em|%$/.test(value)) {
17114 if (parentFontSize === 0) {
17115 return;
17116 }
17117 var numValue = parseFloat(value) / (/%$/.test(value) ? 100 : 1);
17118 value = numValue * parentFontSize + 'px';
17119 }
17120 }
17121 if (name === 'border' && value) {
17122 previewCss += 'padding:0 2px;';
17123 }
17124 previewCss += name + ':' + value + ';';
17125 });
17126 editor.fire('AfterPreviewFormats');
17127 dom.remove(previewFrag);
17128 return previewCss;
17129 };
17130 var Preview = {
17131 getCssText: getCssText,
17132 parseSelector: parseSelector,
17133 selectorToHtml: selectorToHtml
17134 };
17135
17136 var toggle = function (editor, formats, name, vars, node) {
17137 var fmt = formats.get(name);
17138 if (MatchFormat.match(editor, name, vars, node) && (!('toggle' in fmt[0]) || fmt[0].toggle)) {
17139 RemoveFormat.remove(editor, name, vars, node);
17140 } else {
17141 ApplyFormat.applyFormat(editor, name, vars, node);
17142 }
17143 };
17144 var ToggleFormat = { toggle: toggle };
17145
17146 var setup$7 = function (editor) {
17147 editor.addShortcut('meta+b', '', 'Bold');
17148 editor.addShortcut('meta+i', '', 'Italic');
17149 editor.addShortcut('meta+u', '', 'Underline');
17150 for (var i = 1; i <= 6; i++) {
17151 editor.addShortcut('access+' + i, '', [
17152 'FormatBlock',
17153 false,
17154 'h' + i
17155 ]);
17156 }
17157 editor.addShortcut('access+7', '', [
17158 'FormatBlock',
17159 false,
17160 'p'
17161 ]);
17162 editor.addShortcut('access+8', '', [
17163 'FormatBlock',
17164 false,
17165 'div'
17166 ]);
17167 editor.addShortcut('access+9', '', [
17168 'FormatBlock',
17169 false,
17170 'address'
17171 ]);
17172 };
17173 var FormatShortcuts = { setup: setup$7 };
17174
17175 var Formatter = function (editor) {
17176 var formats = FormatRegistry(editor);
17177 var formatChangeState = Cell(null);
17178 FormatShortcuts.setup(editor);
17179 setup$5(editor);
17180 return {
17181 get: formats.get,
17182 has: formats.has,
17183 register: formats.register,
17184 unregister: formats.unregister,
17185 apply: curry(ApplyFormat.applyFormat, editor),
17186 remove: curry(RemoveFormat.remove, editor),
17187 toggle: curry(ToggleFormat.toggle, editor, formats),
17188 match: curry(MatchFormat.match, editor),
17189 matchAll: curry(MatchFormat.matchAll, editor),
17190 matchNode: curry(MatchFormat.matchNode, editor),
17191 canApply: curry(MatchFormat.canApply, editor),
17192 formatChanged: curry(formatChanged, editor, formatChangeState),
17193 getCssText: curry(Preview.getCssText, editor)
17194 };
17195 };
17196
17197 var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
17198 var shallow$1 = function (old, nu) {
17199 return nu;
17200 };
17201 var baseMerge = function (merger) {
17202 return function () {
17203 var objects = new Array(arguments.length);
17204 for (var i = 0; i < objects.length; i++) {
17205 objects[i] = arguments[i];
17206 }
17207 if (objects.length === 0) {
17208 throw new Error('Can\'t merge zero objects');
17209 }
17210 var ret = {};
17211 for (var j = 0; j < objects.length; j++) {
17212 var curObject = objects[j];
17213 for (var key in curObject) {
17214 if (hasOwnProperty$2.call(curObject, key)) {
17215 ret[key] = merger(ret[key], curObject[key]);
17216 }
17217 }
17218 }
17219 return ret;
17220 };
17221 };
17222 var merge = baseMerge(shallow$1);
17223
17224 var register$1 = function (htmlParser, settings, dom) {
17225 htmlParser.addAttributeFilter('data-mce-tabindex', function (nodes, name) {
17226 var i = nodes.length, node;
17227 while (i--) {
17228 node = nodes[i];
17229 node.attr('tabindex', node.attr('data-mce-tabindex'));
17230 node.attr(name, null);
17231 }
17232 });
17233 htmlParser.addAttributeFilter('src,href,style', function (nodes, name) {
17234 var i = nodes.length, node, value;
17235 var internalName = 'data-mce-' + name;
17236 var urlConverter = settings.url_converter;
17237 var urlConverterScope = settings.url_converter_scope;
17238 while (i--) {
17239 node = nodes[i];
17240 value = node.attr(internalName);
17241 if (value !== undefined) {
17242 node.attr(name, value.length > 0 ? value : null);
17243 node.attr(internalName, null);
17244 } else {
17245 value = node.attr(name);
17246 if (name === 'style') {
17247 value = dom.serializeStyle(dom.parseStyle(value), node.name);
17248 } else if (urlConverter) {
17249 value = urlConverter.call(urlConverterScope, value, name, node.name);
17250 }
17251 node.attr(name, value.length > 0 ? value : null);
17252 }
17253 }
17254 });
17255 htmlParser.addAttributeFilter('class', function (nodes) {
17256 var i = nodes.length, node, value;
17257 while (i--) {
17258 node = nodes[i];
17259 value = node.attr('class');
17260 if (value) {
17261 value = node.attr('class').replace(/(?:^|\s)mce-item-\w+(?!\S)/g, '');
17262 node.attr('class', value.length > 0 ? value : null);
17263 }
17264 }
17265 });
17266 htmlParser.addAttributeFilter('data-mce-type', function (nodes, name, args) {
17267 var i = nodes.length, node;
17268 while (i--) {
17269 node = nodes[i];
17270 if (node.attr('data-mce-type') === 'bookmark' && !args.cleanup) {
17271 var hasChildren = Option.from(node.firstChild).exists(function (firstChild) {
17272 return !Zwsp.isZwsp(firstChild.value);
17273 });
17274 if (hasChildren) {
17275 node.unwrap();
17276 } else {
17277 node.remove();
17278 }
17279 }
17280 }
17281 });
17282 htmlParser.addNodeFilter('noscript', function (nodes) {
17283 var i = nodes.length, node;
17284 while (i--) {
17285 node = nodes[i].firstChild;
17286 if (node) {
17287 node.value = Entities.decode(node.value);
17288 }
17289 }
17290 });
17291 htmlParser.addNodeFilter('script,style', function (nodes, name) {
17292 var i = nodes.length, node, value, type;
17293 var trim = function (value) {
17294 return value.replace(/(<!--\[CDATA\[|\]\]-->)/g, '\n').replace(/^[\r\n]*|[\r\n]*$/g, '').replace(/^\s*((<!--)?(\s*\/\/)?\s*<!\[CDATA\[|(<!--\s*)?\/\*\s*<!\[CDATA\[\s*\*\/|(\/\/)?\s*<!--|\/\*\s*<!--\s*\*\/)\s*[\r\n]*/gi, '').replace(/\s*(\/\*\s*\]\]>\s*\*\/(-->)?|\s*\/\/\s*\]\]>(-->)?|\/\/\s*(-->)?|\]\]>|\/\*\s*-->\s*\*\/|\s*-->\s*)\s*$/g, '');
17295 };
17296 while (i--) {
17297 node = nodes[i];
17298 value = node.firstChild ? node.firstChild.value : '';
17299 if (name === 'script') {
17300 type = node.attr('type');
17301 if (type) {
17302 node.attr('type', type === 'mce-no/type' ? null : type.replace(/^mce\-/, ''));
17303 }
17304 if (settings.element_format === 'xhtml' && value.length > 0) {
17305 node.firstChild.value = '// <![CDATA[\n' + trim(value) + '\n// ]]>';
17306 }
17307 } else {
17308 if (settings.element_format === 'xhtml' && value.length > 0) {
17309 node.firstChild.value = '<!--\n' + trim(value) + '\n-->';
17310 }
17311 }
17312 }
17313 });
17314 htmlParser.addNodeFilter('#comment', function (nodes) {
17315 var i = nodes.length, node;
17316 while (i--) {
17317 node = nodes[i];
17318 if (node.value.indexOf('[CDATA[') === 0) {
17319 node.name = '#cdata';
17320 node.type = 4;
17321 node.value = node.value.replace(/^\[CDATA\[|\]\]$/g, '');
17322 } else if (node.value.indexOf('mce:protected ') === 0) {
17323 node.name = '#text';
17324 node.type = 3;
17325 node.raw = true;
17326 node.value = unescape(node.value).substr(14);
17327 }
17328 }
17329 });
17330 htmlParser.addNodeFilter('xml:namespace,input', function (nodes, name) {
17331 var i = nodes.length, node;
17332 while (i--) {
17333 node = nodes[i];
17334 if (node.type === 7) {
17335 node.remove();
17336 } else if (node.type === 1) {
17337 if (name === 'input' && !node.attr('type')) {
17338 node.attr('type', 'text');
17339 }
17340 }
17341 }
17342 });
17343 htmlParser.addAttributeFilter('data-mce-type', function (nodes) {
17344 each(nodes, function (node) {
17345 if (node.attr('data-mce-type') === 'format-caret') {
17346 if (node.isEmpty(htmlParser.schema.getNonEmptyElements())) {
17347 node.remove();
17348 } else {
17349 node.unwrap();
17350 }
17351 }
17352 });
17353 });
17354 htmlParser.addAttributeFilter('data-mce-src,data-mce-href,data-mce-style,' + 'data-mce-selected,data-mce-expando,' + 'data-mce-type,data-mce-resize', function (nodes, name) {
17355 var i = nodes.length;
17356 while (i--) {
17357 nodes[i].attr(name, null);
17358 }
17359 });
17360 };
17361 var trimTrailingBr = function (rootNode) {
17362 var brNode1, brNode2;
17363 var isBr = function (node) {
17364 return node && node.name === 'br';
17365 };
17366 brNode1 = rootNode.lastChild;
17367 if (isBr(brNode1)) {
17368 brNode2 = brNode1.prev;
17369 if (isBr(brNode2)) {
17370 brNode1.remove();
17371 brNode2.remove();
17372 }
17373 }
17374 };
17375 var DomSerializerFilters = {
17376 register: register$1,
17377 trimTrailingBr: trimTrailingBr
17378 };
17379
17380 var preProcess = function (editor, node, args) {
17381 var impl, doc, oldDoc;
17382 var dom = editor.dom;
17383 node = node.cloneNode(true);
17384 impl = domGlobals.document.implementation;
17385 if (impl.createHTMLDocument) {
17386 doc = impl.createHTMLDocument('');
17387 Tools.each(node.nodeName === 'BODY' ? node.childNodes : [node], function (node) {
17388 doc.body.appendChild(doc.importNode(node, true));
17389 });
17390 if (node.nodeName !== 'BODY') {
17391 node = doc.body.firstChild;
17392 } else {
17393 node = doc.body;
17394 }
17395 oldDoc = dom.doc;
17396 dom.doc = doc;
17397 }
17398 Events.firePreProcess(editor, merge(args, { node: node }));
17399 if (oldDoc) {
17400 dom.doc = oldDoc;
17401 }
17402 return node;
17403 };
17404 var shouldFireEvent = function (editor, args) {
17405 return editor && editor.hasEventListeners('PreProcess') && !args.no_events;
17406 };
17407 var process = function (editor, node, args) {
17408 return shouldFireEvent(editor, args) ? preProcess(editor, node, args) : node;
17409 };
17410 var DomSerializerPreProcess = { process: process };
17411
17412 var removeAttrs = function (node, names) {
17413 each(names, function (name) {
17414 node.attr(name, null);
17415 });
17416 };
17417 var addFontToSpansFilter = function (domParser, styles, fontSizes) {
17418 domParser.addNodeFilter('font', function (nodes) {
17419 each(nodes, function (node) {
17420 var props = styles.parse(node.attr('style'));
17421 var color = node.attr('color');
17422 var face = node.attr('face');
17423 var size = node.attr('size');
17424 if (color) {
17425 props.color = color;
17426 }
17427 if (face) {
17428 props['font-family'] = face;
17429 }
17430 if (size) {
17431 props['font-size'] = fontSizes[parseInt(node.attr('size'), 10) - 1];
17432 }
17433 node.name = 'span';
17434 node.attr('style', styles.serialize(props));
17435 removeAttrs(node, [
17436 'color',
17437 'face',
17438 'size'
17439 ]);
17440 });
17441 });
17442 };
17443 var addStrikeToSpanFilter = function (domParser, styles) {
17444 domParser.addNodeFilter('strike', function (nodes) {
17445 each(nodes, function (node) {
17446 var props = styles.parse(node.attr('style'));
17447 props['text-decoration'] = 'line-through';
17448 node.name = 'span';
17449 node.attr('style', styles.serialize(props));
17450 });
17451 });
17452 };
17453 var addFilters = function (domParser, settings) {
17454 var styles = Styles();
17455 if (settings.convert_fonts_to_spans) {
17456 addFontToSpansFilter(domParser, styles, Tools.explode(settings.font_size_legacy_values));
17457 }
17458 addStrikeToSpanFilter(domParser, styles);
17459 };
17460 var register$2 = function (domParser, settings) {
17461 if (settings.inline_styles) {
17462 addFilters(domParser, settings);
17463 }
17464 };
17465 var LegacyFilter = { register: register$2 };
17466
17467 var paddEmptyNode = function (settings, args, blockElements, node) {
17468 var brPreferred = settings.padd_empty_with_br || args.insert;
17469 if (brPreferred && blockElements[node.name]) {
17470 node.empty().append(new Node$1('br', 1)).shortEnded = true;
17471 } else {
17472 node.empty().append(new Node$1('#text', 3)).value = '\xA0';
17473 }
17474 };
17475 var isPaddedWithNbsp = function (node) {
17476 return hasOnlyChild(node, '#text') && node.firstChild.value === '\xA0';
17477 };
17478 var hasOnlyChild = function (node, name) {
17479 return node && node.firstChild && node.firstChild === node.lastChild && node.firstChild.name === name;
17480 };
17481 var isPadded = function (schema, node) {
17482 var rule = schema.getElementRule(node.name);
17483 return rule && rule.paddEmpty;
17484 };
17485 var isEmpty$2 = function (schema, nonEmptyElements, whitespaceElements, node) {
17486 return node.isEmpty(nonEmptyElements, whitespaceElements, function (node) {
17487 return isPadded(schema, node);
17488 });
17489 };
17490 var isLineBreakNode = function (node, blockElements) {
17491 return node && (blockElements[node.name] || node.name === 'br');
17492 };
17493
17494 var register$3 = function (parser, settings) {
17495 var schema = parser.schema;
17496 if (settings.remove_trailing_brs) {
17497 parser.addNodeFilter('br', function (nodes, _, args) {
17498 var i;
17499 var l = nodes.length;
17500 var node;
17501 var blockElements = Tools.extend({}, schema.getBlockElements());
17502 var nonEmptyElements = schema.getNonEmptyElements();
17503 var parent, lastParent, prev, prevName;
17504 var whiteSpaceElements = schema.getNonEmptyElements();
17505 var elementRule, textNode;
17506 blockElements.body = 1;
17507 for (i = 0; i < l; i++) {
17508 node = nodes[i];
17509 parent = node.parent;
17510 if (blockElements[node.parent.name] && node === parent.lastChild) {
17511 prev = node.prev;
17512 while (prev) {
17513 prevName = prev.name;
17514 if (prevName !== 'span' || prev.attr('data-mce-type') !== 'bookmark') {
17515 if (prevName !== 'br') {
17516 break;
17517 }
17518 if (prevName === 'br') {
17519 node = null;
17520 break;
17521 }
17522 }
17523 prev = prev.prev;
17524 }
17525 if (node) {
17526 node.remove();
17527 if (isEmpty$2(schema, nonEmptyElements, whiteSpaceElements, parent)) {
17528 elementRule = schema.getElementRule(parent.name);
17529 if (elementRule) {
17530 if (elementRule.removeEmpty) {
17531 parent.remove();
17532 } else if (elementRule.paddEmpty) {
17533 paddEmptyNode(settings, args, blockElements, parent);
17534 }
17535 }
17536 }
17537 }
17538 } else {
17539 lastParent = node;
17540 while (parent && parent.firstChild === lastParent && parent.lastChild === lastParent) {
17541 lastParent = parent;
17542 if (blockElements[parent.name]) {
17543 break;
17544 }
17545 parent = parent.parent;
17546 }
17547 if (lastParent === parent && settings.padd_empty_with_br !== true) {
17548 textNode = new Node$1('#text', 3);
17549 textNode.value = '\xA0';
17550 node.replace(textNode);
17551 }
17552 }
17553 }
17554 });
17555 }
17556 parser.addAttributeFilter('href', function (nodes) {
17557 var i = nodes.length, node;
17558 var appendRel = function (rel) {
17559 var parts = rel.split(' ').filter(function (p) {
17560 return p.length > 0;
17561 });
17562 return parts.concat(['noopener']).sort().join(' ');
17563 };
17564 var addNoOpener = function (rel) {
17565 var newRel = rel ? Tools.trim(rel) : '';
17566 if (!/\b(noopener)\b/g.test(newRel)) {
17567 return appendRel(newRel);
17568 } else {
17569 return newRel;
17570 }
17571 };
17572 if (!settings.allow_unsafe_link_target) {
17573 while (i--) {
17574 node = nodes[i];
17575 if (node.name === 'a' && node.attr('target') === '_blank') {
17576 node.attr('rel', addNoOpener(node.attr('rel')));
17577 }
17578 }
17579 }
17580 });
17581 if (!settings.allow_html_in_named_anchor) {
17582 parser.addAttributeFilter('id,name', function (nodes) {
17583 var i = nodes.length, sibling, prevSibling, parent, node;
17584 while (i--) {
17585 node = nodes[i];
17586 if (node.name === 'a' && node.firstChild && !node.attr('href')) {
17587 parent = node.parent;
17588 sibling = node.lastChild;
17589 do {
17590 prevSibling = sibling.prev;
17591 parent.insert(sibling, node);
17592 sibling = prevSibling;
17593 } while (sibling);
17594 }
17595 }
17596 });
17597 }
17598 if (settings.fix_list_elements) {
17599 parser.addNodeFilter('ul,ol', function (nodes) {
17600 var i = nodes.length, node, parentNode;
17601 while (i--) {
17602 node = nodes[i];
17603 parentNode = node.parent;
17604 if (parentNode.name === 'ul' || parentNode.name === 'ol') {
17605 if (node.prev && node.prev.name === 'li') {
17606 node.prev.append(node);
17607 } else {
17608 var li = new Node$1('li', 1);
17609 li.attr('style', 'list-style-type: none');
17610 node.wrap(li);
17611 }
17612 }
17613 }
17614 });
17615 }
17616 if (settings.validate && schema.getValidClasses()) {
17617 parser.addAttributeFilter('class', function (nodes) {
17618 var i = nodes.length, node, classList, ci, className, classValue;
17619 var validClasses = schema.getValidClasses();
17620 var validClassesMap, valid;
17621 while (i--) {
17622 node = nodes[i];
17623 classList = node.attr('class').split(' ');
17624 classValue = '';
17625 for (ci = 0; ci < classList.length; ci++) {
17626 className = classList[ci];
17627 valid = false;
17628 validClassesMap = validClasses['*'];
17629 if (validClassesMap && validClassesMap[className]) {
17630 valid = true;
17631 }
17632 validClassesMap = validClasses[node.name];
17633 if (!valid && validClassesMap && validClassesMap[className]) {
17634 valid = true;
17635 }
17636 if (valid) {
17637 if (classValue) {
17638 classValue += ' ';
17639 }
17640 classValue += className;
17641 }
17642 }
17643 if (!classValue.length) {
17644 classValue = null;
17645 }
17646 node.attr('class', classValue);
17647 }
17648 });
17649 }
17650 };
17651
17652 var makeMap$4 = Tools.makeMap, each$f = Tools.each, explode$2 = Tools.explode, extend$2 = Tools.extend;
17653 var DomParser = function (settings, schema) {
17654 if (schema === void 0) {
17655 schema = Schema();
17656 }
17657 var nodeFilters = {};
17658 var attributeFilters = [];
17659 var matchedNodes = {};
17660 var matchedAttributes = {};
17661 settings = settings || {};
17662 settings.validate = 'validate' in settings ? settings.validate : true;
17663 settings.root_name = settings.root_name || 'body';
17664 var fixInvalidChildren = function (nodes) {
17665 var ni, node, parent, parents, newParent, currentNode, tempNode, childNode, i;
17666 var nonEmptyElements, whitespaceElements, nonSplitableElements, textBlockElements, specialElements, sibling, nextNode;
17667 nonSplitableElements = makeMap$4('tr,td,th,tbody,thead,tfoot,table');
17668 nonEmptyElements = schema.getNonEmptyElements();
17669 whitespaceElements = schema.getWhiteSpaceElements();
17670 textBlockElements = schema.getTextBlockElements();
17671 specialElements = schema.getSpecialElements();
17672 for (ni = 0; ni < nodes.length; ni++) {
17673 node = nodes[ni];
17674 if (!node.parent || node.fixed) {
17675 continue;
17676 }
17677 if (textBlockElements[node.name] && node.parent.name === 'li') {
17678 sibling = node.next;
17679 while (sibling) {
17680 if (textBlockElements[sibling.name]) {
17681 sibling.name = 'li';
17682 sibling.fixed = true;
17683 node.parent.insert(sibling, node.parent);
17684 } else {
17685 break;
17686 }
17687 sibling = sibling.next;
17688 }
17689 node.unwrap(node);
17690 continue;
17691 }
17692 parents = [node];
17693 for (parent = node.parent; parent && !schema.isValidChild(parent.name, node.name) && !nonSplitableElements[parent.name]; parent = parent.parent) {
17694 parents.push(parent);
17695 }
17696 if (parent && parents.length > 1) {
17697 parents.reverse();
17698 newParent = currentNode = filterNode(parents[0].clone());
17699 for (i = 0; i < parents.length - 1; i++) {
17700 if (schema.isValidChild(currentNode.name, parents[i].name)) {
17701 tempNode = filterNode(parents[i].clone());
17702 currentNode.append(tempNode);
17703 } else {
17704 tempNode = currentNode;
17705 }
17706 for (childNode = parents[i].firstChild; childNode && childNode !== parents[i + 1];) {
17707 nextNode = childNode.next;
17708 tempNode.append(childNode);
17709 childNode = nextNode;
17710 }
17711 currentNode = tempNode;
17712 }
17713 if (!isEmpty$2(schema, nonEmptyElements, whitespaceElements, newParent)) {
17714 parent.insert(newParent, parents[0], true);
17715 parent.insert(node, newParent);
17716 } else {
17717 parent.insert(node, parents[0], true);
17718 }
17719 parent = parents[0];
17720 if (isEmpty$2(schema, nonEmptyElements, whitespaceElements, parent) || hasOnlyChild(parent, 'br')) {
17721 parent.empty().remove();
17722 }
17723 } else if (node.parent) {
17724 if (node.name === 'li') {
17725 sibling = node.prev;
17726 if (sibling && (sibling.name === 'ul' || sibling.name === 'ul')) {
17727 sibling.append(node);
17728 continue;
17729 }
17730 sibling = node.next;
17731 if (sibling && (sibling.name === 'ul' || sibling.name === 'ul')) {
17732 sibling.insert(node, sibling.firstChild, true);
17733 continue;
17734 }
17735 node.wrap(filterNode(new Node$1('ul', 1)));
17736 continue;
17737 }
17738 if (schema.isValidChild(node.parent.name, 'div') && schema.isValidChild('div', node.name)) {
17739 node.wrap(filterNode(new Node$1('div', 1)));
17740 } else {
17741 if (specialElements[node.name]) {
17742 node.empty().remove();
17743 } else {
17744 node.unwrap();
17745 }
17746 }
17747 }
17748 }
17749 };
17750 var filterNode = function (node) {
17751 var i, name, list;
17752 name = node.name;
17753 if (name in nodeFilters) {
17754 list = matchedNodes[name];
17755 if (list) {
17756 list.push(node);
17757 } else {
17758 matchedNodes[name] = [node];
17759 }
17760 }
17761 i = attributeFilters.length;
17762 while (i--) {
17763 name = attributeFilters[i].name;
17764 if (name in node.attributes.map) {
17765 list = matchedAttributes[name];
17766 if (list) {
17767 list.push(node);
17768 } else {
17769 matchedAttributes[name] = [node];
17770 }
17771 }
17772 }
17773 return node;
17774 };
17775 var addNodeFilter = function (name, callback) {
17776 each$f(explode$2(name), function (name) {
17777 var list = nodeFilters[name];
17778 if (!list) {
17779 nodeFilters[name] = list = [];
17780 }
17781 list.push(callback);
17782 });
17783 };
17784 var getNodeFilters = function () {
17785 var out = [];
17786 for (var name in nodeFilters) {
17787 if (nodeFilters.hasOwnProperty(name)) {
17788 out.push({
17789 name: name,
17790 callbacks: nodeFilters[name]
17791 });
17792 }
17793 }
17794 return out;
17795 };
17796 var addAttributeFilter = function (name, callback) {
17797 each$f(explode$2(name), function (name) {
17798 var i;
17799 for (i = 0; i < attributeFilters.length; i++) {
17800 if (attributeFilters[i].name === name) {
17801 attributeFilters[i].callbacks.push(callback);
17802 return;
17803 }
17804 }
17805 attributeFilters.push({
17806 name: name,
17807 callbacks: [callback]
17808 });
17809 });
17810 };
17811 var getAttributeFilters = function () {
17812 return [].concat(attributeFilters);
17813 };
17814 var parse = function (html, args) {
17815 var parser, nodes, i, l, fi, fl, list, name;
17816 var blockElements;
17817 var invalidChildren = [];
17818 var isInWhiteSpacePreservedElement;
17819 var node;
17820 var getRootBlockName = function (name) {
17821 if (name === false) {
17822 return '';
17823 } else if (name === true) {
17824 return 'p';
17825 } else {
17826 return name;
17827 }
17828 };
17829 args = args || {};
17830 matchedNodes = {};
17831 matchedAttributes = {};
17832 blockElements = extend$2(makeMap$4('script,style,head,html,body,title,meta,param'), schema.getBlockElements());
17833 var nonEmptyElements = schema.getNonEmptyElements();
17834 var children = schema.children;
17835 var validate = settings.validate;
17836 var forcedRootBlockName = 'forced_root_block' in args ? args.forced_root_block : settings.forced_root_block;
17837 var rootBlockName = getRootBlockName(forcedRootBlockName);
17838 var whiteSpaceElements = schema.getWhiteSpaceElements();
17839 var startWhiteSpaceRegExp = /^[ \t\r\n]+/;
17840 var endWhiteSpaceRegExp = /[ \t\r\n]+$/;
17841 var allWhiteSpaceRegExp = /[ \t\r\n]+/g;
17842 var isAllWhiteSpaceRegExp = /^[ \t\r\n]+$/;
17843 isInWhiteSpacePreservedElement = whiteSpaceElements.hasOwnProperty(args.context) || whiteSpaceElements.hasOwnProperty(settings.root_name);
17844 var addRootBlocks = function () {
17845 var node = rootNode.firstChild, next, rootBlockNode;
17846 var trim = function (rootBlockNode) {
17847 if (rootBlockNode) {
17848 node = rootBlockNode.firstChild;
17849 if (node && node.type === 3) {
17850 node.value = node.value.replace(startWhiteSpaceRegExp, '');
17851 }
17852 node = rootBlockNode.lastChild;
17853 if (node && node.type === 3) {
17854 node.value = node.value.replace(endWhiteSpaceRegExp, '');
17855 }
17856 }
17857 };
17858 if (!schema.isValidChild(rootNode.name, rootBlockName.toLowerCase())) {
17859 return;
17860 }
17861 while (node) {
17862 next = node.next;
17863 if (node.type === 3 || node.type === 1 && node.name !== 'p' && !blockElements[node.name] && !node.attr('data-mce-type')) {
17864 if (!rootBlockNode) {
17865 rootBlockNode = createNode(rootBlockName, 1);
17866 rootBlockNode.attr(settings.forced_root_block_attrs);
17867 rootNode.insert(rootBlockNode, node);
17868 rootBlockNode.append(node);
17869 } else {
17870 rootBlockNode.append(node);
17871 }
17872 } else {
17873 trim(rootBlockNode);
17874 rootBlockNode = null;
17875 }
17876 node = next;
17877 }
17878 trim(rootBlockNode);
17879 };
17880 var createNode = function (name, type) {
17881 var node = new Node$1(name, type);
17882 var list;
17883 if (name in nodeFilters) {
17884 list = matchedNodes[name];
17885 if (list) {
17886 list.push(node);
17887 } else {
17888 matchedNodes[name] = [node];
17889 }
17890 }
17891 return node;
17892 };
17893 var removeWhitespaceBefore = function (node) {
17894 var textNode, textNodeNext, textVal, sibling;
17895 var blockElements = schema.getBlockElements();
17896 for (textNode = node.prev; textNode && textNode.type === 3;) {
17897 textVal = textNode.value.replace(endWhiteSpaceRegExp, '');
17898 if (textVal.length > 0) {
17899 textNode.value = textVal;
17900 return;
17901 }
17902 textNodeNext = textNode.next;
17903 if (textNodeNext) {
17904 if (textNodeNext.type === 3 && textNodeNext.value.length) {
17905 textNode = textNode.prev;
17906 continue;
17907 }
17908 if (!blockElements[textNodeNext.name] && textNodeNext.name !== 'script' && textNodeNext.name !== 'style') {
17909 textNode = textNode.prev;
17910 continue;
17911 }
17912 }
17913 sibling = textNode.prev;
17914 textNode.remove();
17915 textNode = sibling;
17916 }
17917 };
17918 var cloneAndExcludeBlocks = function (input) {
17919 var name;
17920 var output = {};
17921 for (name in input) {
17922 if (name !== 'li' && name !== 'p') {
17923 output[name] = input[name];
17924 }
17925 }
17926 return output;
17927 };
17928 parser = SaxParser$1({
17929 validate: validate,
17930 allow_script_urls: settings.allow_script_urls,
17931 allow_conditional_comments: settings.allow_conditional_comments,
17932 self_closing_elements: cloneAndExcludeBlocks(schema.getSelfClosingElements()),
17933 cdata: function (text) {
17934 node.append(createNode('#cdata', 4)).value = text;
17935 },
17936 text: function (text, raw) {
17937 var textNode;
17938 if (!isInWhiteSpacePreservedElement) {
17939 text = text.replace(allWhiteSpaceRegExp, ' ');
17940 if (isLineBreakNode(node.lastChild, blockElements)) {
17941 text = text.replace(startWhiteSpaceRegExp, '');
17942 }
17943 }
17944 if (text.length !== 0) {
17945 textNode = createNode('#text', 3);
17946 textNode.raw = !!raw;
17947 node.append(textNode).value = text;
17948 }
17949 },
17950 comment: function (text) {
17951 node.append(createNode('#comment', 8)).value = text;
17952 },
17953 pi: function (name, text) {
17954 node.append(createNode(name, 7)).value = text;
17955 removeWhitespaceBefore(node);
17956 },
17957 doctype: function (text) {
17958 var newNode;
17959 newNode = node.append(createNode('#doctype', 10));
17960 newNode.value = text;
17961 removeWhitespaceBefore(node);
17962 },
17963 start: function (name, attrs, empty) {
17964 var newNode, attrFiltersLen, elementRule, attrName, parent;
17965 elementRule = validate ? schema.getElementRule(name) : {};
17966 if (elementRule) {
17967 newNode = createNode(elementRule.outputName || name, 1);
17968 newNode.attributes = attrs;
17969 newNode.shortEnded = empty;
17970 node.append(newNode);
17971 parent = children[node.name];
17972 if (parent && children[newNode.name] && !parent[newNode.name]) {
17973 invalidChildren.push(newNode);
17974 }
17975 attrFiltersLen = attributeFilters.length;
17976 while (attrFiltersLen--) {
17977 attrName = attributeFilters[attrFiltersLen].name;
17978 if (attrName in attrs.map) {
17979 list = matchedAttributes[attrName];
17980 if (list) {
17981 list.push(newNode);
17982 } else {
17983 matchedAttributes[attrName] = [newNode];
17984 }
17985 }
17986 }
17987 if (blockElements[name]) {
17988 removeWhitespaceBefore(newNode);
17989 }
17990 if (!empty) {
17991 node = newNode;
17992 }
17993 if (!isInWhiteSpacePreservedElement && whiteSpaceElements[name]) {
17994 isInWhiteSpacePreservedElement = true;
17995 }
17996 }
17997 },
17998 end: function (name) {
17999 var textNode, elementRule, text, sibling, tempNode;
18000 elementRule = validate ? schema.getElementRule(name) : {};
18001 if (elementRule) {
18002 if (blockElements[name]) {
18003 if (!isInWhiteSpacePreservedElement) {
18004 textNode = node.firstChild;
18005 if (textNode && textNode.type === 3) {
18006 text = textNode.value.replace(startWhiteSpaceRegExp, '');
18007 if (text.length > 0) {
18008 textNode.value = text;
18009 textNode = textNode.next;
18010 } else {
18011 sibling = textNode.next;
18012 textNode.remove();
18013 textNode = sibling;
18014 while (textNode && textNode.type === 3) {
18015 text = textNode.value;
18016 sibling = textNode.next;
18017 if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) {
18018 textNode.remove();
18019 textNode = sibling;
18020 }
18021 textNode = sibling;
18022 }
18023 }
18024 }
18025 textNode = node.lastChild;
18026 if (textNode && textNode.type === 3) {
18027 text = textNode.value.replace(endWhiteSpaceRegExp, '');
18028 if (text.length > 0) {
18029 textNode.value = text;
18030 textNode = textNode.prev;
18031 } else {
18032 sibling = textNode.prev;
18033 textNode.remove();
18034 textNode = sibling;
18035 while (textNode && textNode.type === 3) {
18036 text = textNode.value;
18037 sibling = textNode.prev;
18038 if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) {
18039 textNode.remove();
18040 textNode = sibling;
18041 }
18042 textNode = sibling;
18043 }
18044 }
18045 }
18046 }
18047 }
18048 if (isInWhiteSpacePreservedElement && whiteSpaceElements[name]) {
18049 isInWhiteSpacePreservedElement = false;
18050 }
18051 if (elementRule.removeEmpty && isEmpty$2(schema, nonEmptyElements, whiteSpaceElements, node)) {
18052 if (!node.attr('name') && !node.attr('id')) {
18053 tempNode = node.parent;
18054 if (blockElements[node.name]) {
18055 node.empty().remove();
18056 } else {
18057 node.unwrap();
18058 }
18059 node = tempNode;
18060 return;
18061 }
18062 }
18063 if (elementRule.paddEmpty && (isPaddedWithNbsp(node) || isEmpty$2(schema, nonEmptyElements, whiteSpaceElements, node))) {
18064 paddEmptyNode(settings, args, blockElements, node);
18065 }
18066 node = node.parent;
18067 }
18068 }
18069 }, schema);
18070 var rootNode = node = new Node$1(args.context || settings.root_name, 11);
18071 parser.parse(html);
18072 if (validate && invalidChildren.length) {
18073 if (!args.context) {
18074 fixInvalidChildren(invalidChildren);
18075 } else {
18076 args.invalid = true;
18077 }
18078 }
18079 if (rootBlockName && (rootNode.name === 'body' || args.isRootContent)) {
18080 addRootBlocks();
18081 }
18082 if (!args.invalid) {
18083 for (name in matchedNodes) {
18084 if (!matchedNodes.hasOwnProperty(name)) {
18085 continue;
18086 }
18087 list = nodeFilters[name];
18088 nodes = matchedNodes[name];
18089 fi = nodes.length;
18090 while (fi--) {
18091 if (!nodes[fi].parent) {
18092 nodes.splice(fi, 1);
18093 }
18094 }
18095 for (i = 0, l = list.length; i < l; i++) {
18096 list[i](nodes, name, args);
18097 }
18098 }
18099 for (i = 0, l = attributeFilters.length; i < l; i++) {
18100 list = attributeFilters[i];
18101 if (list.name in matchedAttributes) {
18102 nodes = matchedAttributes[list.name];
18103 fi = nodes.length;
18104 while (fi--) {
18105 if (!nodes[fi].parent) {
18106 nodes.splice(fi, 1);
18107 }
18108 }
18109 for (fi = 0, fl = list.callbacks.length; fi < fl; fi++) {
18110 list.callbacks[fi](nodes, list.name, args);
18111 }
18112 }
18113 }
18114 }
18115 return rootNode;
18116 };
18117 var exports = {
18118 schema: schema,
18119 addAttributeFilter: addAttributeFilter,
18120 getAttributeFilters: getAttributeFilters,
18121 addNodeFilter: addNodeFilter,
18122 getNodeFilters: getNodeFilters,
18123 filterNode: filterNode,
18124 parse: parse
18125 };
18126 register$3(exports, settings);
18127 LegacyFilter.register(exports, settings);
18128 return exports;
18129 };
18130
18131 var addTempAttr = function (htmlParser, tempAttrs, name) {
18132 if (Tools.inArray(tempAttrs, name) === -1) {
18133 htmlParser.addAttributeFilter(name, function (nodes, name) {
18134 var i = nodes.length;
18135 while (i--) {
18136 nodes[i].attr(name, null);
18137 }
18138 });
18139 tempAttrs.push(name);
18140 }
18141 };
18142 var postProcess$1 = function (editor, args, content) {
18143 if (!args.no_events && editor) {
18144 var outArgs = Events.firePostProcess(editor, merge(args, { content: content }));
18145 return outArgs.content;
18146 } else {
18147 return content;
18148 }
18149 };
18150 var getHtmlFromNode = function (dom, node, args) {
18151 var html = Zwsp.trim(args.getInner ? node.innerHTML : dom.getOuterHTML(node));
18152 return args.selection || isWsPreserveElement(Element.fromDom(node)) ? html : Tools.trim(html);
18153 };
18154 var parseHtml = function (htmlParser, html, args) {
18155 var parserArgs = args.selection ? merge({ forced_root_block: false }, args) : args;
18156 var rootNode = htmlParser.parse(html, parserArgs);
18157 DomSerializerFilters.trimTrailingBr(rootNode);
18158 return rootNode;
18159 };
18160 var serializeNode = function (settings, schema, node) {
18161 var htmlSerializer = Serializer(settings, schema);
18162 return htmlSerializer.serialize(node);
18163 };
18164 var toHtml = function (editor, settings, schema, rootNode, args) {
18165 var content = serializeNode(settings, schema, rootNode);
18166 return postProcess$1(editor, args, content);
18167 };
18168 var DomSerializer = function (settings, editor) {
18169 var dom, schema, htmlParser;
18170 var tempAttrs = ['data-mce-selected'];
18171 dom = editor && editor.dom ? editor.dom : DOMUtils$1.DOM;
18172 schema = editor && editor.schema ? editor.schema : Schema(settings);
18173 settings.entity_encoding = settings.entity_encoding || 'named';
18174 settings.remove_trailing_brs = 'remove_trailing_brs' in settings ? settings.remove_trailing_brs : true;
18175 htmlParser = DomParser(settings, schema);
18176 DomSerializerFilters.register(htmlParser, settings, dom);
18177 var serialize = function (node, parserArgs) {
18178 var args = merge({ format: 'html' }, parserArgs ? parserArgs : {});
18179 var targetNode = DomSerializerPreProcess.process(editor, node, args);
18180 var html = getHtmlFromNode(dom, targetNode, args);
18181 var rootNode = parseHtml(htmlParser, html, args);
18182 return args.format === 'tree' ? rootNode : toHtml(editor, settings, schema, rootNode, args);
18183 };
18184 return {
18185 schema: schema,
18186 addNodeFilter: htmlParser.addNodeFilter,
18187 addAttributeFilter: htmlParser.addAttributeFilter,
18188 serialize: serialize,
18189 addRules: function (rules) {
18190 schema.addValidElements(rules);
18191 },
18192 setRules: function (rules) {
18193 schema.setValidElements(rules);
18194 },
18195 addTempAttr: curry(addTempAttr, htmlParser, tempAttrs),
18196 getTempAttrs: function () {
18197 return tempAttrs;
18198 }
18199 };
18200 };
18201
18202 var Serializer$1 = function (settings, editor) {
18203 var domSerializer = DomSerializer(settings, editor);
18204 return {
18205 schema: domSerializer.schema,
18206 addNodeFilter: domSerializer.addNodeFilter,
18207 addAttributeFilter: domSerializer.addAttributeFilter,
18208 serialize: domSerializer.serialize,
18209 addRules: domSerializer.addRules,
18210 setRules: domSerializer.setRules,
18211 addTempAttr: domSerializer.addTempAttr,
18212 getTempAttrs: domSerializer.getTempAttrs
18213 };
18214 };
18215
18216 function BookmarkManager(selection) {
18217 return {
18218 getBookmark: curry(Bookmarks.getBookmark, selection),
18219 moveToBookmark: curry(Bookmarks.moveToBookmark, selection)
18220 };
18221 }
18222 (function (BookmarkManager) {
18223 BookmarkManager.isBookmarkNode = Bookmarks.isBookmarkNode;
18224 }(BookmarkManager || (BookmarkManager = {})));
18225 var BookmarkManager$1 = BookmarkManager;
18226
18227 var isContentEditableFalse$a = NodeType.isContentEditableFalse;
18228 var isContentEditableTrue$5 = NodeType.isContentEditableTrue;
18229 var getContentEditableRoot$1 = function (root, node) {
18230 while (node && node !== root) {
18231 if (isContentEditableTrue$5(node) || isContentEditableFalse$a(node)) {
18232 return node;
18233 }
18234 node = node.parentNode;
18235 }
18236 return null;
18237 };
18238 var ControlSelection = function (selection, editor) {
18239 var dom = editor.dom, each = Tools.each;
18240 var selectedElm, selectedElmGhost, resizeHelper, resizeHandles, selectedHandle;
18241 var startX, startY, selectedElmX, selectedElmY, startW, startH, ratio, resizeStarted;
18242 var width, height;
18243 var editableDoc = editor.getDoc(), rootDocument = domGlobals.document;
18244 var abs = Math.abs, round = Math.round, rootElement = editor.getBody();
18245 var startScrollWidth, startScrollHeight;
18246 resizeHandles = {
18247 nw: [
18248 0,
18249 0,
18250 -1,
18251 -1
18252 ],
18253 ne: [
18254 1,
18255 0,
18256 1,
18257 -1
18258 ],
18259 se: [
18260 1,
18261 1,
18262 1,
18263 1
18264 ],
18265 sw: [
18266 0,
18267 1,
18268 -1,
18269 1
18270 ]
18271 };
18272 var isImage = function (elm) {
18273 return elm && (elm.nodeName === 'IMG' || editor.dom.is(elm, 'figure.image'));
18274 };
18275 var isEventOnImageOutsideRange = function (evt, range) {
18276 return isImage(evt.target) && !RangePoint.isXYWithinRange(evt.clientX, evt.clientY, range);
18277 };
18278 var contextMenuSelectImage = function (evt) {
18279 var target = evt.target;
18280 if (isEventOnImageOutsideRange(evt, editor.selection.getRng()) && !evt.isDefaultPrevented()) {
18281 editor.selection.select(target);
18282 }
18283 };
18284 var getResizeTarget = function (elm) {
18285 return editor.dom.is(elm, 'figure.image') ? elm.querySelector('img') : elm;
18286 };
18287 var isResizable = function (elm) {
18288 var selector = editor.settings.object_resizing;
18289 if (selector === false || Env.iOS) {
18290 return false;
18291 }
18292 if (typeof selector !== 'string') {
18293 selector = 'table,img,figure.image,div';
18294 }
18295 if (elm.getAttribute('data-mce-resize') === 'false') {
18296 return false;
18297 }
18298 if (elm === editor.getBody()) {
18299 return false;
18300 }
18301 return is$1(Element.fromDom(elm), selector);
18302 };
18303 var resizeGhostElement = function (e) {
18304 var deltaX, deltaY, proportional;
18305 var resizeHelperX, resizeHelperY;
18306 deltaX = e.screenX - startX;
18307 deltaY = e.screenY - startY;
18308 width = deltaX * selectedHandle[2] + startW;
18309 height = deltaY * selectedHandle[3] + startH;
18310 width = width < 5 ? 5 : width;
18311 height = height < 5 ? 5 : height;
18312 if (isImage(selectedElm) && editor.settings.resize_img_proportional !== false) {
18313 proportional = !VK.modifierPressed(e);
18314 } else {
18315 proportional = VK.modifierPressed(e) || isImage(selectedElm) && selectedHandle[2] * selectedHandle[3] !== 0;
18316 }
18317 if (proportional) {
18318 if (abs(deltaX) > abs(deltaY)) {
18319 height = round(width * ratio);
18320 width = round(height / ratio);
18321 } else {
18322 width = round(height / ratio);
18323 height = round(width * ratio);
18324 }
18325 }
18326 dom.setStyles(getResizeTarget(selectedElmGhost), {
18327 width: width,
18328 height: height
18329 });
18330 resizeHelperX = selectedHandle.startPos.x + deltaX;
18331 resizeHelperY = selectedHandle.startPos.y + deltaY;
18332 resizeHelperX = resizeHelperX > 0 ? resizeHelperX : 0;
18333 resizeHelperY = resizeHelperY > 0 ? resizeHelperY : 0;
18334 dom.setStyles(resizeHelper, {
18335 left: resizeHelperX,
18336 top: resizeHelperY,
18337 display: 'block'
18338 });
18339 resizeHelper.innerHTML = width + ' &times; ' + height;
18340 if (selectedHandle[2] < 0 && selectedElmGhost.clientWidth <= width) {
18341 dom.setStyle(selectedElmGhost, 'left', selectedElmX + (startW - width));
18342 }
18343 if (selectedHandle[3] < 0 && selectedElmGhost.clientHeight <= height) {
18344 dom.setStyle(selectedElmGhost, 'top', selectedElmY + (startH - height));
18345 }
18346 deltaX = rootElement.scrollWidth - startScrollWidth;
18347 deltaY = rootElement.scrollHeight - startScrollHeight;
18348 if (deltaX + deltaY !== 0) {
18349 dom.setStyles(resizeHelper, {
18350 left: resizeHelperX - deltaX,
18351 top: resizeHelperY - deltaY
18352 });
18353 }
18354 if (!resizeStarted) {
18355 Events.fireObjectResizeStart(editor, selectedElm, startW, startH);
18356 resizeStarted = true;
18357 }
18358 };
18359 var endGhostResize = function () {
18360 resizeStarted = false;
18361 var setSizeProp = function (name, value) {
18362 if (value) {
18363 if (selectedElm.style[name] || !editor.schema.isValid(selectedElm.nodeName.toLowerCase(), name)) {
18364 dom.setStyle(getResizeTarget(selectedElm), name, value);
18365 } else {
18366 dom.setAttrib(getResizeTarget(selectedElm), name, value);
18367 }
18368 }
18369 };
18370 setSizeProp('width', width);
18371 setSizeProp('height', height);
18372 dom.unbind(editableDoc, 'mousemove', resizeGhostElement);
18373 dom.unbind(editableDoc, 'mouseup', endGhostResize);
18374 if (rootDocument !== editableDoc) {
18375 dom.unbind(rootDocument, 'mousemove', resizeGhostElement);
18376 dom.unbind(rootDocument, 'mouseup', endGhostResize);
18377 }
18378 dom.remove(selectedElmGhost);
18379 dom.remove(resizeHelper);
18380 showResizeRect(selectedElm);
18381 Events.fireObjectResized(editor, selectedElm, width, height);
18382 dom.setAttrib(selectedElm, 'style', dom.getAttrib(selectedElm, 'style'));
18383 editor.nodeChanged();
18384 };
18385 var showResizeRect = function (targetElm) {
18386 var position, targetWidth, targetHeight, e, rect;
18387 hideResizeRect();
18388 unbindResizeHandleEvents();
18389 position = dom.getPos(targetElm, rootElement);
18390 selectedElmX = position.x;
18391 selectedElmY = position.y;
18392 rect = targetElm.getBoundingClientRect();
18393 targetWidth = rect.width || rect.right - rect.left;
18394 targetHeight = rect.height || rect.bottom - rect.top;
18395 if (selectedElm !== targetElm) {
18396 selectedElm = targetElm;
18397 width = height = 0;
18398 }
18399 e = editor.fire('ObjectSelected', { target: targetElm });
18400 if (isResizable(targetElm) && !e.isDefaultPrevented()) {
18401 each(resizeHandles, function (handle, name) {
18402 var handleElm;
18403 var startDrag = function (e) {
18404 startX = e.screenX;
18405 startY = e.screenY;
18406 startW = getResizeTarget(selectedElm).clientWidth;
18407 startH = getResizeTarget(selectedElm).clientHeight;
18408 ratio = startH / startW;
18409 selectedHandle = handle;
18410 handle.startPos = {
18411 x: targetWidth * handle[0] + selectedElmX,
18412 y: targetHeight * handle[1] + selectedElmY
18413 };
18414 startScrollWidth = rootElement.scrollWidth;
18415 startScrollHeight = rootElement.scrollHeight;
18416 selectedElmGhost = selectedElm.cloneNode(true);
18417 dom.addClass(selectedElmGhost, 'mce-clonedresizable');
18418 dom.setAttrib(selectedElmGhost, 'data-mce-bogus', 'all');
18419 selectedElmGhost.contentEditable = false;
18420 selectedElmGhost.unSelectabe = true;
18421 dom.setStyles(selectedElmGhost, {
18422 left: selectedElmX,
18423 top: selectedElmY,
18424 margin: 0
18425 });
18426 selectedElmGhost.removeAttribute('data-mce-selected');
18427 rootElement.appendChild(selectedElmGhost);
18428 dom.bind(editableDoc, 'mousemove', resizeGhostElement);
18429 dom.bind(editableDoc, 'mouseup', endGhostResize);
18430 if (rootDocument !== editableDoc) {
18431 dom.bind(rootDocument, 'mousemove', resizeGhostElement);
18432 dom.bind(rootDocument, 'mouseup', endGhostResize);
18433 }
18434 resizeHelper = dom.add(rootElement, 'div', {
18435 'class': 'mce-resize-helper',
18436 'data-mce-bogus': 'all'
18437 }, startW + ' &times; ' + startH);
18438 };
18439 handleElm = dom.get('mceResizeHandle' + name);
18440 if (handleElm) {
18441 dom.remove(handleElm);
18442 }
18443 handleElm = dom.add(rootElement, 'div', {
18444 'id': 'mceResizeHandle' + name,
18445 'data-mce-bogus': 'all',
18446 'class': 'mce-resizehandle',
18447 'unselectable': true,
18448 'style': 'cursor:' + name + '-resize; margin:0; padding:0'
18449 });
18450 if (Env.ie === 11) {
18451 handleElm.contentEditable = false;
18452 }
18453 dom.bind(handleElm, 'mousedown', function (e) {
18454 e.stopImmediatePropagation();
18455 e.preventDefault();
18456 startDrag(e);
18457 });
18458 handle.elm = handleElm;
18459 dom.setStyles(handleElm, {
18460 left: targetWidth * handle[0] + selectedElmX - handleElm.offsetWidth / 2,
18461 top: targetHeight * handle[1] + selectedElmY - handleElm.offsetHeight / 2
18462 });
18463 });
18464 } else {
18465 hideResizeRect();
18466 }
18467 selectedElm.setAttribute('data-mce-selected', '1');
18468 };
18469 var hideResizeRect = function () {
18470 var name, handleElm;
18471 unbindResizeHandleEvents();
18472 if (selectedElm) {
18473 selectedElm.removeAttribute('data-mce-selected');
18474 }
18475 for (name in resizeHandles) {
18476 handleElm = dom.get('mceResizeHandle' + name);
18477 if (handleElm) {
18478 dom.unbind(handleElm);
18479 dom.remove(handleElm);
18480 }
18481 }
18482 };
18483 var updateResizeRect = function (e) {
18484 var startElm, controlElm;
18485 var isChildOrEqual = function (node, parent) {
18486 if (node) {
18487 do {
18488 if (node === parent) {
18489 return true;
18490 }
18491 } while (node = node.parentNode);
18492 }
18493 };
18494 if (resizeStarted || editor.removed) {
18495 return;
18496 }
18497 each(dom.select('img[data-mce-selected],hr[data-mce-selected]'), function (img) {
18498 img.removeAttribute('data-mce-selected');
18499 });
18500 controlElm = e.type === 'mousedown' ? e.target : selection.getNode();
18501 controlElm = dom.$(controlElm).closest('table,img,figure.image,hr')[0];
18502 if (isChildOrEqual(controlElm, rootElement)) {
18503 disableGeckoResize();
18504 startElm = selection.getStart(true);
18505 if (isChildOrEqual(startElm, controlElm) && isChildOrEqual(selection.getEnd(true), controlElm)) {
18506 showResizeRect(controlElm);
18507 return;
18508 }
18509 }
18510 hideResizeRect();
18511 };
18512 var isWithinContentEditableFalse = function (elm) {
18513 return isContentEditableFalse$a(getContentEditableRoot$1(editor.getBody(), elm));
18514 };
18515 var unbindResizeHandleEvents = function () {
18516 for (var name in resizeHandles) {
18517 var handle = resizeHandles[name];
18518 if (handle.elm) {
18519 dom.unbind(handle.elm);
18520 delete handle.elm;
18521 }
18522 }
18523 };
18524 var disableGeckoResize = function () {
18525 try {
18526 editor.getDoc().execCommand('enableObjectResizing', false, false);
18527 } catch (ex) {
18528 }
18529 };
18530 editor.on('init', function () {
18531 disableGeckoResize();
18532 if (Env.ie && Env.ie >= 11) {
18533 editor.on('mousedown click', function (e) {
18534 var target = e.target, nodeName = target.nodeName;
18535 if (!resizeStarted && /^(TABLE|IMG|HR)$/.test(nodeName) && !isWithinContentEditableFalse(target)) {
18536 if (e.button !== 2) {
18537 editor.selection.select(target, nodeName === 'TABLE');
18538 }
18539 if (e.type === 'mousedown') {
18540 editor.nodeChanged();
18541 }
18542 }
18543 });
18544 editor.dom.bind(rootElement, 'mscontrolselect', function (e) {
18545 var delayedSelect = function (node) {
18546 Delay.setEditorTimeout(editor, function () {
18547 editor.selection.select(node);
18548 });
18549 };
18550 if (isWithinContentEditableFalse(e.target)) {
18551 e.preventDefault();
18552 delayedSelect(e.target);
18553 return;
18554 }
18555 if (/^(TABLE|IMG|HR)$/.test(e.target.nodeName)) {
18556 e.preventDefault();
18557 if (e.target.tagName === 'IMG') {
18558 delayedSelect(e.target);
18559 }
18560 }
18561 });
18562 }
18563 var throttledUpdateResizeRect = Delay.throttle(function (e) {
18564 if (!editor.composing) {
18565 updateResizeRect(e);
18566 }
18567 });
18568 editor.on('nodechange ResizeEditor ResizeWindow drop FullscreenStateChanged', throttledUpdateResizeRect);
18569 editor.on('keyup compositionend', function (e) {
18570 if (selectedElm && selectedElm.nodeName === 'TABLE') {
18571 throttledUpdateResizeRect(e);
18572 }
18573 });
18574 editor.on('hide blur', hideResizeRect);
18575 editor.on('contextmenu', contextMenuSelectImage, true);
18576 });
18577 editor.on('remove', unbindResizeHandleEvents);
18578 var destroy = function () {
18579 selectedElm = selectedElmGhost = null;
18580 };
18581 return {
18582 isResizable: isResizable,
18583 showResizeRect: showResizeRect,
18584 hideResizeRect: hideResizeRect,
18585 updateResizeRect: updateResizeRect,
18586 destroy: destroy
18587 };
18588 };
18589
18590 function Dimension (name, getOffset) {
18591 var set = function (element, h) {
18592 if (!isNumber(h) && !h.match(/^[0-9]+$/)) {
18593 throw new Error(name + '.set accepts only positive integer values. Value was ' + h);
18594 }
18595 var dom = element.dom();
18596 if (isSupported(dom)) {
18597 dom.style[name] = h + 'px';
18598 }
18599 };
18600 var get = function (element) {
18601 var r = getOffset(element);
18602 if (r <= 0 || r === null) {
18603 var css = get$2(element, name);
18604 return parseFloat(css) || 0;
18605 }
18606 return r;
18607 };
18608 var getOuter = get;
18609 var aggregate = function (element, properties) {
18610 return foldl(properties, function (acc, property) {
18611 var val = get$2(element, property);
18612 var value = val === undefined ? 0 : parseInt(val, 10);
18613 return isNaN(value) ? acc : acc + value;
18614 }, 0);
18615 };
18616 var max = function (element, value, properties) {
18617 var cumulativeInclusions = aggregate(element, properties);
18618 var absoluteMax = value > cumulativeInclusions ? value - cumulativeInclusions : 0;
18619 return absoluteMax;
18620 };
18621 return {
18622 set: set,
18623 get: get,
18624 getOuter: getOuter,
18625 aggregate: aggregate,
18626 max: max
18627 };
18628 }
18629
18630 var api$1 = Dimension('height', function (element) {
18631 var dom = element.dom();
18632 return inBody(element) ? dom.getBoundingClientRect().height : dom.offsetHeight;
18633 });
18634 var get$7 = function (element) {
18635 return api$1.get(element);
18636 };
18637
18638 var attached = function (element, scope) {
18639 var doc = scope || Element.fromDom(domGlobals.document.documentElement);
18640 return ancestor(element, curry(eq, doc)).isSome();
18641 };
18642 var windowOf = function (element) {
18643 var dom = element.dom();
18644 if (dom === dom.window && element instanceof domGlobals.Window) {
18645 return element;
18646 }
18647 return isDocument(element) ? dom.defaultView || dom.parentWindow : null;
18648 };
18649
18650 var r = function (left, top) {
18651 var translate = function (x, y) {
18652 return r(left + x, top + y);
18653 };
18654 return {
18655 left: constant(left),
18656 top: constant(top),
18657 translate: translate
18658 };
18659 };
18660 var Position$1 = r;
18661
18662 var boxPosition = function (dom) {
18663 var box = dom.getBoundingClientRect();
18664 return Position$1(box.left, box.top);
18665 };
18666 var firstDefinedOrZero = function (a, b) {
18667 return a !== undefined ? a : b !== undefined ? b : 0;
18668 };
18669 var absolute = function (element) {
18670 var doc = element.dom().ownerDocument;
18671 var body = doc.body;
18672 var win = windowOf(Element.fromDom(doc));
18673 var html = doc.documentElement;
18674 var scrollTop = firstDefinedOrZero(win.pageYOffset, html.scrollTop);
18675 var scrollLeft = firstDefinedOrZero(win.pageXOffset, html.scrollLeft);
18676 var clientTop = firstDefinedOrZero(html.clientTop, body.clientTop);
18677 var clientLeft = firstDefinedOrZero(html.clientLeft, body.clientLeft);
18678 return viewport(element).translate(scrollLeft - clientLeft, scrollTop - clientTop);
18679 };
18680 var viewport = function (element) {
18681 var dom = element.dom();
18682 var doc = dom.ownerDocument;
18683 var body = doc.body;
18684 var html = Element.fromDom(doc.documentElement);
18685 if (body === dom) {
18686 return Position$1(body.offsetLeft, body.offsetTop);
18687 }
18688 if (!attached(element, html)) {
18689 return Position$1(0, 0);
18690 }
18691 return boxPosition(dom);
18692 };
18693
18694 var isSafari = PlatformDetection$1.detect().browser.isSafari();
18695 var get$8 = function (_DOC) {
18696 var doc = _DOC !== undefined ? _DOC.dom() : domGlobals.document;
18697 var x = doc.body.scrollLeft || doc.documentElement.scrollLeft;
18698 var y = doc.body.scrollTop || doc.documentElement.scrollTop;
18699 return Position$1(x, y);
18700 };
18701 var to = function (x, y, _DOC) {
18702 var doc = _DOC !== undefined ? _DOC.dom() : domGlobals.document;
18703 var win = doc.defaultView;
18704 win.scrollTo(x, y);
18705 };
18706 var intoView = function (element, alignToTop) {
18707 if (isSafari && isFunction(element.dom().scrollIntoViewIfNeeded)) {
18708 element.dom().scrollIntoViewIfNeeded(false);
18709 } else {
18710 element.dom().scrollIntoView(alignToTop);
18711 }
18712 };
18713
18714 var walkUp = function (navigation, doc) {
18715 var frame = navigation.view(doc);
18716 return frame.fold(constant([]), function (f) {
18717 var parent = navigation.owner(f);
18718 var rest = walkUp(navigation, parent);
18719 return [f].concat(rest);
18720 });
18721 };
18722 var pathTo = function (element, navigation) {
18723 var d = navigation.owner(element);
18724 return walkUp(navigation, d);
18725 };
18726
18727 var view = function (doc) {
18728 var element = doc.dom() === domGlobals.document ? Option.none() : Option.from(doc.dom().defaultView.frameElement);
18729 return element.map(Element.fromDom);
18730 };
18731 var owner$1 = function (element) {
18732 return owner(element);
18733 };
18734
18735 var Navigation = /*#__PURE__*/Object.freeze({
18736 view: view,
18737 owner: owner$1
18738 });
18739
18740 var find$4 = function (element) {
18741 var doc = Element.fromDom(domGlobals.document);
18742 var scroll = get$8(doc);
18743 var frames = pathTo(element, Navigation);
18744 var offset = viewport(element);
18745 var r = foldr(frames, function (b, a) {
18746 var loc = viewport(a);
18747 return {
18748 left: b.left + loc.left(),
18749 top: b.top + loc.top()
18750 };
18751 }, {
18752 left: 0,
18753 top: 0
18754 });
18755 return Position$1(r.left + offset.left() + scroll.left(), r.top + offset.top() + scroll.top());
18756 };
18757
18758 var excludeFromDescend = function (element) {
18759 return name(element) === 'textarea';
18760 };
18761 var descend = function (element, offset) {
18762 var children$1 = children(element);
18763 if (children$1.length === 0 || excludeFromDescend(element)) {
18764 return {
18765 element: element,
18766 offset: offset
18767 };
18768 } else if (offset < children$1.length && !excludeFromDescend(children$1[offset])) {
18769 return {
18770 element: children$1[offset],
18771 offset: 0
18772 };
18773 } else {
18774 var last = children$1[children$1.length - 1];
18775 if (excludeFromDescend(last)) {
18776 return {
18777 element: element,
18778 offset: offset
18779 };
18780 } else {
18781 if (name(last) === 'img') {
18782 return {
18783 element: last,
18784 offset: 1
18785 };
18786 } else if (isText(last)) {
18787 return {
18788 element: last,
18789 offset: get$5(last).length
18790 };
18791 } else {
18792 return {
18793 element: last,
18794 offset: children(last).length
18795 };
18796 }
18797 }
18798 }
18799 };
18800 var markerInfo = function (element, cleanupFun) {
18801 var pos = absolute(element);
18802 var height = get$7(element);
18803 return {
18804 element: element,
18805 bottom: pos.top() + height,
18806 pos: pos,
18807 cleanup: cleanupFun
18808 };
18809 };
18810 var createMarker = function (element, offset) {
18811 var startPoint = descend(element, offset);
18812 var span = Element.fromHtml('<span data-mce-bogus="all">' + Zwsp.ZWSP + '</span>');
18813 before(startPoint.element, span);
18814 return markerInfo(span, function () {
18815 return remove$1(span);
18816 });
18817 };
18818 var elementMarker = function (element) {
18819 return markerInfo(Element.fromDom(element), noop);
18820 };
18821 var withMarker = function (editor, f, rng, alignToTop) {
18822 preserveWith(editor, function (_s, _e) {
18823 return applyWithMarker(editor, f, rng, alignToTop);
18824 }, rng);
18825 };
18826 var applyWithMarker = function (editor, f, rng, alignToTop) {
18827 var body = Element.fromDom(editor.getBody());
18828 var doc = Element.fromDom(editor.getDoc());
18829 reflow(body);
18830 var scrollTop = get$8(doc).top();
18831 var marker = createMarker(Element.fromDom(rng.startContainer), rng.startOffset);
18832 f(doc, scrollTop, marker, alignToTop);
18833 marker.cleanup();
18834 };
18835 var withElement = function (editor, element, f, alignToTop) {
18836 var doc = Element.fromDom(editor.getDoc());
18837 var scrollTop = get$8(doc).top();
18838 f(doc, scrollTop, element, alignToTop);
18839 };
18840 var preserveWith = function (editor, f, rng) {
18841 var startElement = rng.startContainer;
18842 var startOffset = rng.startOffset;
18843 var endElement = rng.endContainer;
18844 var endOffset = rng.endOffset;
18845 f(Element.fromDom(startElement), Element.fromDom(endElement));
18846 var newRng = editor.dom.createRng();
18847 newRng.setStart(startElement, startOffset);
18848 newRng.setEnd(endElement, endOffset);
18849 editor.selection.setRng(rng);
18850 };
18851 var fireScrollIntoViewEvent = function (editor, elm, alignToTop) {
18852 var scrollEvent = editor.fire('ScrollIntoView', {
18853 elm: elm,
18854 alignToTop: alignToTop
18855 });
18856 return scrollEvent.isDefaultPrevented();
18857 };
18858 var scrollTo = function (marker, viewHeight, alignToTop, doc) {
18859 var pos = marker.pos;
18860 if (alignToTop) {
18861 to(pos.left(), pos.top(), doc);
18862 } else {
18863 var y = pos.top() - viewHeight + (marker.bottom - pos.top());
18864 to(pos.left(), y, doc);
18865 }
18866 };
18867 var intoWindowIfNeeded = function (doc, scrollTop, viewHeight, marker, alignToTop) {
18868 if (marker.pos.top() < scrollTop) {
18869 scrollTo(marker, viewHeight, alignToTop !== false, doc);
18870 } else if (marker.bottom > viewHeight + scrollTop) {
18871 scrollTo(marker, viewHeight, alignToTop === true, doc);
18872 }
18873 };
18874 var intoWindow = function (doc, scrollTop, marker, alignToTop) {
18875 var viewHeight = doc.dom().defaultView.innerHeight;
18876 intoWindowIfNeeded(doc, scrollTop, viewHeight, marker, alignToTop);
18877 };
18878 var intoFrame = function (editor, doc, scrollTop, marker, alignToTop) {
18879 var frameViewHeight = doc.dom().defaultView.innerHeight;
18880 intoWindowIfNeeded(doc, scrollTop, frameViewHeight, marker, alignToTop);
18881 var op = find$4(marker.element);
18882 var viewTop = get$8().top();
18883 var viewBot = domGlobals.window.innerHeight + viewTop;
18884 if (op.top() < viewTop) {
18885 intoView(marker.element, alignToTop !== false);
18886 } else if (op.top() > viewBot) {
18887 intoView(marker.element, alignToTop === true);
18888 }
18889 };
18890 var rangeIntoWindow = function (editor, rng, alignToTop) {
18891 return withMarker(editor, curry(intoWindow), rng, alignToTop);
18892 };
18893 var elementIntoWindow = function (editor, element, alignToTop) {
18894 return withElement(editor, elementMarker(element), curry(intoWindow), alignToTop);
18895 };
18896 var rangeIntoFrame = function (editor, rng, alignToTop) {
18897 return withMarker(editor, curry(intoFrame, editor), rng, alignToTop);
18898 };
18899 var elementIntoFrame = function (editor, element, alignToTop) {
18900 return withElement(editor, elementMarker(element), curry(intoFrame, editor), alignToTop);
18901 };
18902 var elementIntoView = function (editor, element, alignToTop) {
18903 if (fireScrollIntoViewEvent(editor, element, alignToTop)) {
18904 return;
18905 }
18906 var scroller = editor.inline ? elementIntoWindow : elementIntoFrame;
18907 scroller(editor, element, alignToTop);
18908 };
18909 var rangeIntoView = function (editor, rng, alignToTop) {
18910 var scroller = editor.inline ? rangeIntoWindow : rangeIntoFrame;
18911 scroller(editor, rng, alignToTop);
18912 };
18913 var ScrollIntoView = {
18914 scrollElementIntoView: elementIntoView,
18915 scrollRangeIntoView: rangeIntoView
18916 };
18917
18918 var hasCeProperty = function (node) {
18919 return NodeType.isContentEditableTrue(node) || NodeType.isContentEditableFalse(node);
18920 };
18921 var findParent = function (node, rootNode, predicate) {
18922 while (node && node !== rootNode) {
18923 if (predicate(node)) {
18924 return node;
18925 }
18926 node = node.parentNode;
18927 }
18928 return null;
18929 };
18930 var findClosestIeRange = function (clientX, clientY, doc) {
18931 var element, rng, rects;
18932 element = doc.elementFromPoint(clientX, clientY);
18933 rng = doc.body.createTextRange();
18934 if (!element || element.tagName === 'HTML') {
18935 element = doc.body;
18936 }
18937 rng.moveToElementText(element);
18938 rects = Tools.toArray(rng.getClientRects());
18939 rects = rects.sort(function (a, b) {
18940 a = Math.abs(Math.max(a.top - clientY, a.bottom - clientY));
18941 b = Math.abs(Math.max(b.top - clientY, b.bottom - clientY));
18942 return a - b;
18943 });
18944 if (rects.length > 0) {
18945 clientY = (rects[0].bottom + rects[0].top) / 2;
18946 try {
18947 rng.moveToPoint(clientX, clientY);
18948 rng.collapse(true);
18949 return rng;
18950 } catch (ex) {
18951 }
18952 }
18953 return null;
18954 };
18955 var moveOutOfContentEditableFalse = function (rng, rootNode) {
18956 var parentElement = rng && rng.parentElement ? rng.parentElement() : null;
18957 return NodeType.isContentEditableFalse(findParent(parentElement, rootNode, hasCeProperty)) ? null : rng;
18958 };
18959 var fromPoint$1 = function (clientX, clientY, doc) {
18960 var rng, point;
18961 var pointDoc = doc;
18962 if (pointDoc.caretPositionFromPoint) {
18963 point = pointDoc.caretPositionFromPoint(clientX, clientY);
18964 if (point) {
18965 rng = doc.createRange();
18966 rng.setStart(point.offsetNode, point.offset);
18967 rng.collapse(true);
18968 }
18969 } else if (doc.caretRangeFromPoint) {
18970 rng = doc.caretRangeFromPoint(clientX, clientY);
18971 } else if (pointDoc.body.createTextRange) {
18972 rng = pointDoc.body.createTextRange();
18973 try {
18974 rng.moveToPoint(clientX, clientY);
18975 rng.collapse(true);
18976 } catch (ex) {
18977 rng = findClosestIeRange(clientX, clientY, doc);
18978 }
18979 return moveOutOfContentEditableFalse(rng, doc.body);
18980 }
18981 return rng;
18982 };
18983 var CaretRangeFromPoint = { fromPoint: fromPoint$1 };
18984
18985 var processRanges = function (editor, ranges) {
18986 return map(ranges, function (range) {
18987 var evt = editor.fire('GetSelectionRange', { range: range });
18988 return evt.range !== range ? evt.range : range;
18989 });
18990 };
18991 var EventProcessRanges = { processRanges: processRanges };
18992
18993 var fromElements = function (elements, scope) {
18994 var doc = scope || domGlobals.document;
18995 var fragment = doc.createDocumentFragment();
18996 each(elements, function (element) {
18997 fragment.appendChild(element.dom());
18998 });
18999 return Element.fromDom(fragment);
19000 };
19001
19002 var tableModel = Immutable('element', 'width', 'rows');
19003 var tableRow = Immutable('element', 'cells');
19004 var cellPosition = Immutable('x', 'y');
19005 var getSpan = function (td, key) {
19006 var value = parseInt(get$1(td, key), 10);
19007 return isNaN(value) ? 1 : value;
19008 };
19009 var fillout = function (table, x, y, tr, td) {
19010 var rowspan = getSpan(td, 'rowspan');
19011 var colspan = getSpan(td, 'colspan');
19012 var rows = table.rows();
19013 for (var y2 = y; y2 < y + rowspan; y2++) {
19014 if (!rows[y2]) {
19015 rows[y2] = tableRow(deep(tr), []);
19016 }
19017 for (var x2 = x; x2 < x + colspan; x2++) {
19018 var cells = rows[y2].cells();
19019 cells[x2] = y2 === y && x2 === x ? td : shallow(td);
19020 }
19021 }
19022 };
19023 var cellExists = function (table, x, y) {
19024 var rows = table.rows();
19025 var cells = rows[y] ? rows[y].cells() : [];
19026 return !!cells[x];
19027 };
19028 var skipCellsX = function (table, x, y) {
19029 while (cellExists(table, x, y)) {
19030 x++;
19031 }
19032 return x;
19033 };
19034 var getWidth = function (rows) {
19035 return foldl(rows, function (acc, row) {
19036 return row.cells().length > acc ? row.cells().length : acc;
19037 }, 0);
19038 };
19039 var findElementPos = function (table, element) {
19040 var rows = table.rows();
19041 for (var y = 0; y < rows.length; y++) {
19042 var cells = rows[y].cells();
19043 for (var x = 0; x < cells.length; x++) {
19044 if (eq(cells[x], element)) {
19045 return Option.some(cellPosition(x, y));
19046 }
19047 }
19048 }
19049 return Option.none();
19050 };
19051 var extractRows = function (table, sx, sy, ex, ey) {
19052 var newRows = [];
19053 var rows = table.rows();
19054 for (var y = sy; y <= ey; y++) {
19055 var cells = rows[y].cells();
19056 var slice = sx < ex ? cells.slice(sx, ex + 1) : cells.slice(ex, sx + 1);
19057 newRows.push(tableRow(rows[y].element(), slice));
19058 }
19059 return newRows;
19060 };
19061 var subTable = function (table, startPos, endPos) {
19062 var sx = startPos.x(), sy = startPos.y();
19063 var ex = endPos.x(), ey = endPos.y();
19064 var newRows = sy < ey ? extractRows(table, sx, sy, ex, ey) : extractRows(table, sx, ey, ex, sy);
19065 return tableModel(table.element(), getWidth(newRows), newRows);
19066 };
19067 var createDomTable = function (table, rows) {
19068 var tableElement = shallow(table.element());
19069 var tableBody = Element.fromTag('tbody');
19070 append$1(tableBody, rows);
19071 append(tableElement, tableBody);
19072 return tableElement;
19073 };
19074 var modelRowsToDomRows = function (table) {
19075 return map(table.rows(), function (row) {
19076 var cells = map(row.cells(), function (cell) {
19077 var td = deep(cell);
19078 remove(td, 'colspan');
19079 remove(td, 'rowspan');
19080 return td;
19081 });
19082 var tr = shallow(row.element());
19083 append$1(tr, cells);
19084 return tr;
19085 });
19086 };
19087 var fromDom$1 = function (tableElm) {
19088 var table = tableModel(shallow(tableElm), 0, []);
19089 each(descendants$1(tableElm, 'tr'), function (tr, y) {
19090 each(descendants$1(tr, 'td,th'), function (td, x) {
19091 fillout(table, skipCellsX(table, x, y), y, tr, td);
19092 });
19093 });
19094 return tableModel(table.element(), getWidth(table.rows()), table.rows());
19095 };
19096 var toDom = function (table) {
19097 return createDomTable(table, modelRowsToDomRows(table));
19098 };
19099 var subsection = function (table, startElement, endElement) {
19100 return findElementPos(table, startElement).bind(function (startPos) {
19101 return findElementPos(table, endElement).map(function (endPos) {
19102 return subTable(table, startPos, endPos);
19103 });
19104 });
19105 };
19106 var SimpleTableModel = {
19107 fromDom: fromDom$1,
19108 toDom: toDom,
19109 subsection: subsection
19110 };
19111
19112 var getRanges = function (selection) {
19113 var ranges = [];
19114 if (selection) {
19115 for (var i = 0; i < selection.rangeCount; i++) {
19116 ranges.push(selection.getRangeAt(i));
19117 }
19118 }
19119 return ranges;
19120 };
19121 var getSelectedNodes = function (ranges) {
19122 return bind(ranges, function (range) {
19123 var node = getSelectedNode(range);
19124 return node ? [Element.fromDom(node)] : [];
19125 });
19126 };
19127 var hasMultipleRanges = function (selection) {
19128 return getRanges(selection).length > 1;
19129 };
19130 var MultiRange = {
19131 getRanges: getRanges,
19132 getSelectedNodes: getSelectedNodes,
19133 hasMultipleRanges: hasMultipleRanges
19134 };
19135
19136 var getCellsFromRanges = function (ranges) {
19137 return filter(MultiRange.getSelectedNodes(ranges), isTableCell);
19138 };
19139 var getCellsFromElement = function (elm) {
19140 return descendants$1(elm, 'td[data-mce-selected],th[data-mce-selected]');
19141 };
19142 var getCellsFromElementOrRanges = function (ranges, element) {
19143 var selectedCells = getCellsFromElement(element);
19144 var rangeCells = getCellsFromRanges(ranges);
19145 return selectedCells.length > 0 ? selectedCells : rangeCells;
19146 };
19147 var getCellsFromEditor = function (editor) {
19148 return getCellsFromElementOrRanges(MultiRange.getRanges(editor.selection.getSel()), Element.fromDom(editor.getBody()));
19149 };
19150 var TableCellSelection = {
19151 getCellsFromRanges: getCellsFromRanges,
19152 getCellsFromElement: getCellsFromElement,
19153 getCellsFromElementOrRanges: getCellsFromElementOrRanges,
19154 getCellsFromEditor: getCellsFromEditor
19155 };
19156
19157 var findParentListContainer = function (parents) {
19158 return find(parents, function (elm) {
19159 return name(elm) === 'ul' || name(elm) === 'ol';
19160 });
19161 };
19162 var getFullySelectedListWrappers = function (parents, rng) {
19163 return find(parents, function (elm) {
19164 return name(elm) === 'li' && hasAllContentsSelected(elm, rng);
19165 }).fold(constant([]), function (li) {
19166 return findParentListContainer(parents).map(function (listCont) {
19167 return [
19168 Element.fromTag('li'),
19169 Element.fromTag(name(listCont))
19170 ];
19171 }).getOr([]);
19172 });
19173 };
19174 var wrap$3 = function (innerElm, elms) {
19175 var wrapped = foldl(elms, function (acc, elm) {
19176 append(elm, acc);
19177 return elm;
19178 }, innerElm);
19179 return elms.length > 0 ? fromElements([wrapped]) : wrapped;
19180 };
19181 var directListWrappers = function (commonAnchorContainer) {
19182 if (isListItem(commonAnchorContainer)) {
19183 return parent(commonAnchorContainer).filter(isList).fold(constant([]), function (listElm) {
19184 return [
19185 commonAnchorContainer,
19186 listElm
19187 ];
19188 });
19189 } else {
19190 return isList(commonAnchorContainer) ? [commonAnchorContainer] : [];
19191 }
19192 };
19193 var getWrapElements = function (rootNode, rng) {
19194 var commonAnchorContainer = Element.fromDom(rng.commonAncestorContainer);
19195 var parents = Parents.parentsAndSelf(commonAnchorContainer, rootNode);
19196 var wrapElements = filter(parents, function (elm) {
19197 return isInline(elm) || isHeading(elm);
19198 });
19199 var listWrappers = getFullySelectedListWrappers(parents, rng);
19200 var allWrappers = wrapElements.concat(listWrappers.length ? listWrappers : directListWrappers(commonAnchorContainer));
19201 return map(allWrappers, shallow);
19202 };
19203 var emptyFragment = function () {
19204 return fromElements([]);
19205 };
19206 var getFragmentFromRange = function (rootNode, rng) {
19207 return wrap$3(Element.fromDom(rng.cloneContents()), getWrapElements(rootNode, rng));
19208 };
19209 var getParentTable = function (rootElm, cell) {
19210 return ancestor$1(cell, 'table', curry(eq, rootElm));
19211 };
19212 var getTableFragment = function (rootNode, selectedTableCells) {
19213 return getParentTable(rootNode, selectedTableCells[0]).bind(function (tableElm) {
19214 var firstCell = selectedTableCells[0];
19215 var lastCell = selectedTableCells[selectedTableCells.length - 1];
19216 var fullTableModel = SimpleTableModel.fromDom(tableElm);
19217 return SimpleTableModel.subsection(fullTableModel, firstCell, lastCell).map(function (sectionedTableModel) {
19218 return fromElements([SimpleTableModel.toDom(sectionedTableModel)]);
19219 });
19220 }).getOrThunk(emptyFragment);
19221 };
19222 var getSelectionFragment = function (rootNode, ranges) {
19223 return ranges.length > 0 && ranges[0].collapsed ? emptyFragment() : getFragmentFromRange(rootNode, ranges[0]);
19224 };
19225 var read$2 = function (rootNode, ranges) {
19226 var selectedCells = TableCellSelection.getCellsFromElementOrRanges(ranges, rootNode);
19227 return selectedCells.length > 0 ? getTableFragment(rootNode, selectedCells) : getSelectionFragment(rootNode, ranges);
19228 };
19229 var FragmentReader = { read: read$2 };
19230
19231 var getTextContent = function (editor) {
19232 return Option.from(editor.selection.getRng()).map(function (rng) {
19233 var bin = editor.dom.add(editor.getBody(), 'div', {
19234 'data-mce-bogus': 'all',
19235 'style': 'overflow: hidden; opacity: 0;'
19236 }, rng.cloneContents());
19237 var text = Zwsp.trim(bin.innerText);
19238 editor.dom.remove(bin);
19239 return text;
19240 }).getOr('');
19241 };
19242 var getHtmlContent = function (editor, args) {
19243 var rng = editor.selection.getRng(), tmpElm = editor.dom.create('body');
19244 var sel = editor.selection.getSel();
19245 var fragment;
19246 var ranges = EventProcessRanges.processRanges(editor, MultiRange.getRanges(sel));
19247 fragment = args.contextual ? FragmentReader.read(Element.fromDom(editor.getBody()), ranges).dom() : rng.cloneContents();
19248 if (fragment) {
19249 tmpElm.appendChild(fragment);
19250 }
19251 return editor.selection.serializer.serialize(tmpElm, args);
19252 };
19253 var getContent$1 = function (editor, args) {
19254 if (args === void 0) {
19255 args = {};
19256 }
19257 args.get = true;
19258 args.format = args.format || 'html';
19259 args.selection = true;
19260 args = editor.fire('BeforeGetContent', args);
19261 if (args.isDefaultPrevented()) {
19262 editor.fire('GetContent', args);
19263 return args.content;
19264 }
19265 if (args.format === 'text') {
19266 return getTextContent(editor);
19267 } else {
19268 args.getInner = true;
19269 var content = getHtmlContent(editor, args);
19270 if (args.format === 'tree') {
19271 return content;
19272 } else {
19273 args.content = editor.selection.isCollapsed() ? '' : content;
19274 editor.fire('GetContent', args);
19275 return args.content;
19276 }
19277 }
19278 };
19279 var GetSelectionContent = { getContent: getContent$1 };
19280
19281 var findParent$1 = function (node, rootNode, predicate) {
19282 while (node && node !== rootNode) {
19283 if (predicate(node)) {
19284 return node;
19285 }
19286 node = node.parentNode;
19287 }
19288 return null;
19289 };
19290 var hasParent = function (node, rootNode, predicate) {
19291 return findParent$1(node, rootNode, predicate) !== null;
19292 };
19293 var hasParentWithName = function (node, rootNode, name) {
19294 return hasParent(node, rootNode, function (node) {
19295 return node.nodeName === name;
19296 });
19297 };
19298 var isTable$3 = function (node) {
19299 return node && node.nodeName === 'TABLE';
19300 };
19301 var isTableCell$3 = function (node) {
19302 return node && /^(TD|TH|CAPTION)$/.test(node.nodeName);
19303 };
19304 var isCeFalseCaretContainer = function (node, rootNode) {
19305 return isCaretContainer(node) && hasParent(node, rootNode, isCaretNode) === false;
19306 };
19307 var hasBrBeforeAfter = function (dom, node, left) {
19308 var walker = new TreeWalker(node, dom.getParent(node.parentNode, dom.isBlock) || dom.getRoot());
19309 while (node = walker[left ? 'prev' : 'next']()) {
19310 if (NodeType.isBr(node)) {
19311 return true;
19312 }
19313 }
19314 };
19315 var isPrevNode = function (node, name) {
19316 return node.previousSibling && node.previousSibling.nodeName === name;
19317 };
19318 var hasContentEditableFalseParent = function (body, node) {
19319 while (node && node !== body) {
19320 if (NodeType.isContentEditableFalse(node)) {
19321 return true;
19322 }
19323 node = node.parentNode;
19324 }
19325 return false;
19326 };
19327 var findTextNodeRelative = function (dom, isAfterNode, collapsed, left, startNode) {
19328 var lastInlineElement;
19329 var body = dom.getRoot();
19330 var node;
19331 var nonEmptyElementsMap = dom.schema.getNonEmptyElements();
19332 var parentBlockContainer = dom.getParent(startNode.parentNode, dom.isBlock) || body;
19333 if (left && NodeType.isBr(startNode) && isAfterNode && dom.isEmpty(parentBlockContainer)) {
19334 return Option.some(CaretPosition(startNode.parentNode, dom.nodeIndex(startNode)));
19335 }
19336 var walker = new TreeWalker(startNode, parentBlockContainer);
19337 while (node = walker[left ? 'prev' : 'next']()) {
19338 if (dom.getContentEditableParent(node) === 'false' || isCeFalseCaretContainer(node, body)) {
19339 return Option.none();
19340 }
19341 if (NodeType.isText(node) && node.nodeValue.length > 0) {
19342 if (hasParentWithName(node, body, 'A') === false) {
19343 return Option.some(CaretPosition(node, left ? node.nodeValue.length : 0));
19344 }
19345 return Option.none();
19346 }
19347 if (dom.isBlock(node) || nonEmptyElementsMap[node.nodeName.toLowerCase()]) {
19348 return Option.none();
19349 }
19350 lastInlineElement = node;
19351 }
19352 if (collapsed && lastInlineElement) {
19353 return Option.some(CaretPosition(lastInlineElement, 0));
19354 }
19355 return Option.none();
19356 };
19357 var normalizeEndPoint = function (dom, collapsed, start, rng) {
19358 var container, offset;
19359 var body = dom.getRoot();
19360 var node, nonEmptyElementsMap;
19361 var directionLeft, isAfterNode, normalized = false;
19362 container = rng[(start ? 'start' : 'end') + 'Container'];
19363 offset = rng[(start ? 'start' : 'end') + 'Offset'];
19364 isAfterNode = NodeType.isElement(container) && offset === container.childNodes.length;
19365 nonEmptyElementsMap = dom.schema.getNonEmptyElements();
19366 directionLeft = start;
19367 if (isCaretContainer(container)) {
19368 return Option.none();
19369 }
19370 if (NodeType.isElement(container) && offset > container.childNodes.length - 1) {
19371 directionLeft = false;
19372 }
19373 if (NodeType.isDocument(container)) {
19374 container = body;
19375 offset = 0;
19376 }
19377 if (container === body) {
19378 if (directionLeft) {
19379 node = container.childNodes[offset > 0 ? offset - 1 : 0];
19380 if (node) {
19381 if (isCaretContainer(node)) {
19382 return Option.none();
19383 }
19384 if (nonEmptyElementsMap[node.nodeName] || isTable$3(node)) {
19385 return Option.none();
19386 }
19387 }
19388 }
19389 if (container.hasChildNodes()) {
19390 offset = Math.min(!directionLeft && offset > 0 ? offset - 1 : offset, container.childNodes.length - 1);
19391 container = container.childNodes[offset];
19392 offset = NodeType.isText(container) && isAfterNode ? container.data.length : 0;
19393 if (!collapsed && container === body.lastChild && isTable$3(container)) {
19394 return Option.none();
19395 }
19396 if (hasContentEditableFalseParent(body, container) || isCaretContainer(container)) {
19397 return Option.none();
19398 }
19399 if (container.hasChildNodes() && isTable$3(container) === false) {
19400 node = container;
19401 var walker = new TreeWalker(container, body);
19402 do {
19403 if (NodeType.isContentEditableFalse(node) || isCaretContainer(node)) {
19404 normalized = false;
19405 break;
19406 }
19407 if (NodeType.isText(node) && node.nodeValue.length > 0) {
19408 offset = directionLeft ? 0 : node.nodeValue.length;
19409 container = node;
19410 normalized = true;
19411 break;
19412 }
19413 if (nonEmptyElementsMap[node.nodeName.toLowerCase()] && !isTableCell$3(node)) {
19414 offset = dom.nodeIndex(node);
19415 container = node.parentNode;
19416 if (!directionLeft) {
19417 offset++;
19418 }
19419 normalized = true;
19420 break;
19421 }
19422 } while (node = directionLeft ? walker.next() : walker.prev());
19423 }
19424 }
19425 }
19426 if (collapsed) {
19427 if (NodeType.isText(container) && offset === 0) {
19428 findTextNodeRelative(dom, isAfterNode, collapsed, true, container).each(function (pos) {
19429 container = pos.container();
19430 offset = pos.offset();
19431 normalized = true;
19432 });
19433 }
19434 if (NodeType.isElement(container)) {
19435 node = container.childNodes[offset];
19436 if (!node) {
19437 node = container.childNodes[offset - 1];
19438 }
19439 if (node && NodeType.isBr(node) && !isPrevNode(node, 'A') && !hasBrBeforeAfter(dom, node, false) && !hasBrBeforeAfter(dom, node, true)) {
19440 findTextNodeRelative(dom, isAfterNode, collapsed, true, node).each(function (pos) {
19441 container = pos.container();
19442 offset = pos.offset();
19443 normalized = true;
19444 });
19445 }
19446 }
19447 }
19448 if (directionLeft && !collapsed && NodeType.isText(container) && offset === container.nodeValue.length) {
19449 findTextNodeRelative(dom, isAfterNode, collapsed, false, container).each(function (pos) {
19450 container = pos.container();
19451 offset = pos.offset();
19452 normalized = true;
19453 });
19454 }
19455 return normalized ? Option.some(CaretPosition(container, offset)) : Option.none();
19456 };
19457 var normalize$2 = function (dom, rng) {
19458 var collapsed = rng.collapsed, normRng = rng.cloneRange();
19459 var startPos = CaretPosition.fromRangeStart(rng);
19460 normalizeEndPoint(dom, collapsed, true, normRng).each(function (pos) {
19461 if (!collapsed || !CaretPosition.isAbove(startPos, pos)) {
19462 normRng.setStart(pos.container(), pos.offset());
19463 }
19464 });
19465 if (!collapsed) {
19466 normalizeEndPoint(dom, collapsed, false, normRng).each(function (pos) {
19467 normRng.setEnd(pos.container(), pos.offset());
19468 });
19469 }
19470 if (collapsed) {
19471 normRng.collapse(true);
19472 }
19473 return RangeCompare.isEq(rng, normRng) ? Option.none() : Option.some(normRng);
19474 };
19475 var NormalizeRange = { normalize: normalize$2 };
19476
19477 var prependData = function (target, data) {
19478 target.insertData(0, data);
19479 };
19480 var removeEmpty = function (text) {
19481 if (text.dom().length === 0) {
19482 remove$1(text);
19483 return Option.none();
19484 }
19485 return Option.some(text);
19486 };
19487 var rngSetContent = function (rng, fragment) {
19488 var firstChild = Option.from(fragment.firstChild).map(Element.fromDom);
19489 var lastChild = Option.from(fragment.lastChild).map(Element.fromDom);
19490 rng.deleteContents();
19491 rng.insertNode(fragment);
19492 var prevText = firstChild.bind(prevSibling).filter(isText).bind(removeEmpty);
19493 var nextText = lastChild.bind(nextSibling).filter(isText).bind(removeEmpty);
19494 liftN([
19495 prevText,
19496 firstChild.filter(isText)
19497 ], function (prev, start) {
19498 prependData(start.dom(), prev.dom().data);
19499 remove$1(prev);
19500 });
19501 liftN([
19502 nextText,
19503 lastChild.filter(isText)
19504 ], function (next, end) {
19505 var oldLength = end.dom().length;
19506 end.dom().appendData(next.dom().data);
19507 rng.setEnd(end.dom(), oldLength);
19508 remove$1(next);
19509 });
19510 rng.collapse(false);
19511 };
19512 var setupArgs = function (args, content) {
19513 args = args || { format: 'html' };
19514 args.set = true;
19515 args.selection = true;
19516 args.content = content;
19517 return args;
19518 };
19519 var setContent$1 = function (editor, content, args) {
19520 args = setupArgs(args, content);
19521 if (!args.no_events) {
19522 args = editor.fire('BeforeSetContent', args);
19523 if (args.isDefaultPrevented()) {
19524 editor.fire('SetContent', args);
19525 return;
19526 }
19527 }
19528 var rng = editor.selection.getRng();
19529 rngSetContent(rng, rng.createContextualFragment(args.content));
19530 editor.selection.setRng(rng);
19531 ScrollIntoView.scrollRangeIntoView(editor, rng);
19532 if (!args.no_events) {
19533 editor.fire('SetContent', args);
19534 }
19535 };
19536 var SetSelectionContent = { setContent: setContent$1 };
19537
19538 var getEndpointElement = function (root, rng, start, real, resolve) {
19539 var container = start ? rng.startContainer : rng.endContainer;
19540 var offset = start ? rng.startOffset : rng.endOffset;
19541 return Option.from(container).map(Element.fromDom).map(function (elm) {
19542 return !real || !rng.collapsed ? child(elm, resolve(elm, offset)).getOr(elm) : elm;
19543 }).bind(function (elm) {
19544 return isElement(elm) ? Option.some(elm) : parent(elm);
19545 }).map(function (elm) {
19546 return elm.dom();
19547 }).getOr(root);
19548 };
19549 var getStart$2 = function (root, rng, real) {
19550 return getEndpointElement(root, rng, true, real, function (elm, offset) {
19551 return Math.min(childNodesCount(elm), offset);
19552 });
19553 };
19554 var getEnd = function (root, rng, real) {
19555 return getEndpointElement(root, rng, false, real, function (elm, offset) {
19556 return offset > 0 ? offset - 1 : offset;
19557 });
19558 };
19559 var skipEmptyTextNodes = function (node, forwards) {
19560 var orig = node;
19561 while (node && NodeType.isText(node) && node.length === 0) {
19562 node = forwards ? node.nextSibling : node.previousSibling;
19563 }
19564 return node || orig;
19565 };
19566 var getNode$1 = function (root, rng) {
19567 var elm, startContainer, endContainer, startOffset, endOffset;
19568 if (!rng) {
19569 return root;
19570 }
19571 startContainer = rng.startContainer;
19572 endContainer = rng.endContainer;
19573 startOffset = rng.startOffset;
19574 endOffset = rng.endOffset;
19575 elm = rng.commonAncestorContainer;
19576 if (!rng.collapsed) {
19577 if (startContainer === endContainer) {
19578 if (endOffset - startOffset < 2) {
19579 if (startContainer.hasChildNodes()) {
19580 elm = startContainer.childNodes[startOffset];
19581 }
19582 }
19583 }
19584 if (startContainer.nodeType === 3 && endContainer.nodeType === 3) {
19585 if (startContainer.length === startOffset) {
19586 startContainer = skipEmptyTextNodes(startContainer.nextSibling, true);
19587 } else {
19588 startContainer = startContainer.parentNode;
19589 }
19590 if (endOffset === 0) {
19591 endContainer = skipEmptyTextNodes(endContainer.previousSibling, false);
19592 } else {
19593 endContainer = endContainer.parentNode;
19594 }
19595 if (startContainer && startContainer === endContainer) {
19596 return startContainer;
19597 }
19598 }
19599 }
19600 if (elm && elm.nodeType === 3) {
19601 return elm.parentNode;
19602 }
19603 return elm;
19604 };
19605 var getSelectedBlocks = function (dom, rng, startElm, endElm) {
19606 var node, root;
19607 var selectedBlocks = [];
19608 root = dom.getRoot();
19609 startElm = dom.getParent(startElm || getStart$2(root, rng, rng.collapsed), dom.isBlock);
19610 endElm = dom.getParent(endElm || getEnd(root, rng, rng.collapsed), dom.isBlock);
19611 if (startElm && startElm !== root) {
19612 selectedBlocks.push(startElm);
19613 }
19614 if (startElm && endElm && startElm !== endElm) {
19615 node = startElm;
19616 var walker = new TreeWalker(startElm, root);
19617 while ((node = walker.next()) && node !== endElm) {
19618 if (dom.isBlock(node)) {
19619 selectedBlocks.push(node);
19620 }
19621 }
19622 }
19623 if (endElm && startElm !== endElm && endElm !== root) {
19624 selectedBlocks.push(endElm);
19625 }
19626 return selectedBlocks;
19627 };
19628 var select$1 = function (dom, node, content) {
19629 return Option.from(node).map(function (node) {
19630 var idx = dom.nodeIndex(node);
19631 var rng = dom.createRng();
19632 rng.setStart(node.parentNode, idx);
19633 rng.setEnd(node.parentNode, idx + 1);
19634 if (content) {
19635 moveEndPoint$1(dom, rng, node, true);
19636 moveEndPoint$1(dom, rng, node, false);
19637 }
19638 return rng;
19639 });
19640 };
19641
19642 var deleteFromCallbackMap = function (callbackMap, selector, callback) {
19643 if (callbackMap && callbackMap.hasOwnProperty(selector)) {
19644 var newCallbacks = filter(callbackMap[selector], function (cb) {
19645 return cb !== callback;
19646 });
19647 if (newCallbacks.length === 0) {
19648 delete callbackMap[selector];
19649 } else {
19650 callbackMap[selector] = newCallbacks;
19651 }
19652 }
19653 };
19654 function SelectorChanged (dom, editor) {
19655 var selectorChangedData, currentSelectors;
19656 return {
19657 selectorChangedWithUnbind: function (selector, callback) {
19658 if (!selectorChangedData) {
19659 selectorChangedData = {};
19660 currentSelectors = {};
19661 editor.on('NodeChange', function (e) {
19662 var node = e.element, parents = dom.getParents(node, null, dom.getRoot()), matchedSelectors = {};
19663 Tools.each(selectorChangedData, function (callbacks, selector) {
19664 Tools.each(parents, function (node) {
19665 if (dom.is(node, selector)) {
19666 if (!currentSelectors[selector]) {
19667 Tools.each(callbacks, function (callback) {
19668 callback(true, {
19669 node: node,
19670 selector: selector,
19671 parents: parents
19672 });
19673 });
19674 currentSelectors[selector] = callbacks;
19675 }
19676 matchedSelectors[selector] = callbacks;
19677 return false;
19678 }
19679 });
19680 });
19681 Tools.each(currentSelectors, function (callbacks, selector) {
19682 if (!matchedSelectors[selector]) {
19683 delete currentSelectors[selector];
19684 Tools.each(callbacks, function (callback) {
19685 callback(false, {
19686 node: node,
19687 selector: selector,
19688 parents: parents
19689 });
19690 });
19691 }
19692 });
19693 });
19694 }
19695 if (!selectorChangedData[selector]) {
19696 selectorChangedData[selector] = [];
19697 }
19698 selectorChangedData[selector].push(callback);
19699 return {
19700 unbind: function () {
19701 deleteFromCallbackMap(selectorChangedData, selector, callback);
19702 deleteFromCallbackMap(currentSelectors, selector, callback);
19703 }
19704 };
19705 }
19706 };
19707 }
19708
19709 var isNativeIeSelection = function (rng) {
19710 return !!rng.select;
19711 };
19712 var isAttachedToDom = function (node) {
19713 return !!(node && node.ownerDocument) && contains$3(Element.fromDom(node.ownerDocument), Element.fromDom(node));
19714 };
19715 var isValidRange = function (rng) {
19716 if (!rng) {
19717 return false;
19718 } else if (isNativeIeSelection(rng)) {
19719 return true;
19720 } else {
19721 return isAttachedToDom(rng.startContainer) && isAttachedToDom(rng.endContainer);
19722 }
19723 };
19724 var Selection$1 = function (dom, win, serializer, editor) {
19725 var bookmarkManager, controlSelection;
19726 var selectedRange, explicitRange;
19727 var selectorChangedWithUnbind = SelectorChanged(dom, editor).selectorChangedWithUnbind;
19728 var setCursorLocation = function (node, offset) {
19729 var rng = dom.createRng();
19730 if (!node) {
19731 moveEndPoint$1(dom, rng, editor.getBody(), true);
19732 setRng(rng);
19733 } else {
19734 rng.setStart(node, offset);
19735 rng.setEnd(node, offset);
19736 setRng(rng);
19737 collapse(false);
19738 }
19739 };
19740 var getContent = function (args) {
19741 return GetSelectionContent.getContent(editor, args);
19742 };
19743 var setContent = function (content, args) {
19744 return SetSelectionContent.setContent(editor, content, args);
19745 };
19746 var getStart = function (real) {
19747 return getStart$2(editor.getBody(), getRng(), real);
19748 };
19749 var getEnd$1 = function (real) {
19750 return getEnd(editor.getBody(), getRng(), real);
19751 };
19752 var getBookmark = function (type, normalized) {
19753 return bookmarkManager.getBookmark(type, normalized);
19754 };
19755 var moveToBookmark = function (bookmark) {
19756 return bookmarkManager.moveToBookmark(bookmark);
19757 };
19758 var select = function (node, content) {
19759 select$1(dom, node, content).each(setRng);
19760 return node;
19761 };
19762 var isCollapsed = function () {
19763 var rng = getRng(), sel = getSel();
19764 if (!rng || rng.item) {
19765 return false;
19766 }
19767 if (rng.compareEndPoints) {
19768 return rng.compareEndPoints('StartToEnd', rng) === 0;
19769 }
19770 return !sel || rng.collapsed;
19771 };
19772 var collapse = function (toStart) {
19773 var rng = getRng();
19774 rng.collapse(!!toStart);
19775 setRng(rng);
19776 };
19777 var getSel = function () {
19778 return win.getSelection ? win.getSelection() : win.document.selection;
19779 };
19780 var getRng = function () {
19781 var selection, rng, elm, doc;
19782 var tryCompareBoundaryPoints = function (how, sourceRange, destinationRange) {
19783 try {
19784 return sourceRange.compareBoundaryPoints(how, destinationRange);
19785 } catch (ex) {
19786 return -1;
19787 }
19788 };
19789 if (!win) {
19790 return null;
19791 }
19792 doc = win.document;
19793 if (typeof doc === 'undefined' || doc === null) {
19794 return null;
19795 }
19796 if (editor.bookmark !== undefined && EditorFocus.hasFocus(editor) === false) {
19797 var bookmark = SelectionBookmark.getRng(editor);
19798 if (bookmark.isSome()) {
19799 return bookmark.map(function (r) {
19800 return EventProcessRanges.processRanges(editor, [r])[0];
19801 }).getOr(doc.createRange());
19802 }
19803 }
19804 try {
19805 if ((selection = getSel()) && !NodeType.isRestrictedNode(selection.anchorNode)) {
19806 if (selection.rangeCount > 0) {
19807 rng = selection.getRangeAt(0);
19808 } else {
19809 rng = selection.createRange ? selection.createRange() : doc.createRange();
19810 }
19811 }
19812 } catch (ex) {
19813 }
19814 rng = EventProcessRanges.processRanges(editor, [rng])[0];
19815 if (!rng) {
19816 rng = doc.createRange ? doc.createRange() : doc.body.createTextRange();
19817 }
19818 if (rng.setStart && rng.startContainer.nodeType === 9 && rng.collapsed) {
19819 elm = dom.getRoot();
19820 rng.setStart(elm, 0);
19821 rng.setEnd(elm, 0);
19822 }
19823 if (selectedRange && explicitRange) {
19824 if (tryCompareBoundaryPoints(rng.START_TO_START, rng, selectedRange) === 0 && tryCompareBoundaryPoints(rng.END_TO_END, rng, selectedRange) === 0) {
19825 rng = explicitRange;
19826 } else {
19827 selectedRange = null;
19828 explicitRange = null;
19829 }
19830 }
19831 return rng;
19832 };
19833 var setRng = function (rng, forward) {
19834 var sel, node, evt;
19835 if (!isValidRange(rng)) {
19836 return;
19837 }
19838 var ieRange = isNativeIeSelection(rng) ? rng : null;
19839 if (ieRange) {
19840 explicitRange = null;
19841 try {
19842 ieRange.select();
19843 } catch (ex) {
19844 }
19845 return;
19846 }
19847 sel = getSel();
19848 evt = editor.fire('SetSelectionRange', {
19849 range: rng,
19850 forward: forward
19851 });
19852 rng = evt.range;
19853 if (sel) {
19854 explicitRange = rng;
19855 try {
19856 sel.removeAllRanges();
19857 sel.addRange(rng);
19858 } catch (ex) {
19859 }
19860 if (forward === false && sel.extend) {
19861 sel.collapse(rng.endContainer, rng.endOffset);
19862 sel.extend(rng.startContainer, rng.startOffset);
19863 }
19864 selectedRange = sel.rangeCount > 0 ? sel.getRangeAt(0) : null;
19865 }
19866 if (!rng.collapsed && rng.startContainer === rng.endContainer && sel.setBaseAndExtent && !Env.ie) {
19867 if (rng.endOffset - rng.startOffset < 2) {
19868 if (rng.startContainer.hasChildNodes()) {
19869 node = rng.startContainer.childNodes[rng.startOffset];
19870 if (node && node.tagName === 'IMG') {
19871 sel.setBaseAndExtent(rng.startContainer, rng.startOffset, rng.endContainer, rng.endOffset);
19872 if (sel.anchorNode !== rng.startContainer || sel.focusNode !== rng.endContainer) {
19873 sel.setBaseAndExtent(node, 0, node, 1);
19874 }
19875 }
19876 }
19877 }
19878 }
19879 editor.fire('AfterSetSelectionRange', {
19880 range: rng,
19881 forward: forward
19882 });
19883 };
19884 var setNode = function (elm) {
19885 setContent(dom.getOuterHTML(elm));
19886 return elm;
19887 };
19888 var getNode = function () {
19889 return getNode$1(editor.getBody(), getRng());
19890 };
19891 var getSelectedBlocks$1 = function (startElm, endElm) {
19892 return getSelectedBlocks(dom, getRng(), startElm, endElm);
19893 };
19894 var isForward = function () {
19895 var sel = getSel();
19896 var anchorRange, focusRange;
19897 if (!sel || !sel.anchorNode || !sel.focusNode) {
19898 return true;
19899 }
19900 anchorRange = dom.createRng();
19901 anchorRange.setStart(sel.anchorNode, sel.anchorOffset);
19902 anchorRange.collapse(true);
19903 focusRange = dom.createRng();
19904 focusRange.setStart(sel.focusNode, sel.focusOffset);
19905 focusRange.collapse(true);
19906 return anchorRange.compareBoundaryPoints(anchorRange.START_TO_START, focusRange) <= 0;
19907 };
19908 var normalize = function () {
19909 var rng = getRng();
19910 var sel = getSel();
19911 if (!MultiRange.hasMultipleRanges(sel) && hasAnyRanges(editor)) {
19912 var normRng = NormalizeRange.normalize(dom, rng);
19913 normRng.each(function (normRng) {
19914 setRng(normRng, isForward());
19915 });
19916 return normRng.getOr(rng);
19917 }
19918 return rng;
19919 };
19920 var selectorChanged = function (selector, callback) {
19921 selectorChangedWithUnbind(selector, callback);
19922 return exports;
19923 };
19924 var getScrollContainer = function () {
19925 var scrollContainer;
19926 var node = dom.getRoot();
19927 while (node && node.nodeName !== 'BODY') {
19928 if (node.scrollHeight > node.clientHeight) {
19929 scrollContainer = node;
19930 break;
19931 }
19932 node = node.parentNode;
19933 }
19934 return scrollContainer;
19935 };
19936 var scrollIntoView = function (elm, alignToTop) {
19937 return ScrollIntoView.scrollElementIntoView(editor, elm, alignToTop);
19938 };
19939 var placeCaretAt = function (clientX, clientY) {
19940 return setRng(CaretRangeFromPoint.fromPoint(clientX, clientY, editor.getDoc()));
19941 };
19942 var getBoundingClientRect = function () {
19943 var rng = getRng();
19944 return rng.collapsed ? CaretPosition$1.fromRangeStart(rng).getClientRects()[0] : rng.getBoundingClientRect();
19945 };
19946 var destroy = function () {
19947 win = selectedRange = explicitRange = null;
19948 controlSelection.destroy();
19949 };
19950 var exports = {
19951 bookmarkManager: null,
19952 controlSelection: null,
19953 dom: dom,
19954 win: win,
19955 serializer: serializer,
19956 editor: editor,
19957 collapse: collapse,
19958 setCursorLocation: setCursorLocation,
19959 getContent: getContent,
19960 setContent: setContent,
19961 getBookmark: getBookmark,
19962 moveToBookmark: moveToBookmark,
19963 select: select,
19964 isCollapsed: isCollapsed,
19965 isForward: isForward,
19966 setNode: setNode,
19967 getNode: getNode,
19968 getSel: getSel,
19969 setRng: setRng,
19970 getRng: getRng,
19971 getStart: getStart,
19972 getEnd: getEnd$1,
19973 getSelectedBlocks: getSelectedBlocks$1,
19974 normalize: normalize,
19975 selectorChanged: selectorChanged,
19976 selectorChangedWithUnbind: selectorChangedWithUnbind,
19977 getScrollContainer: getScrollContainer,
19978 scrollIntoView: scrollIntoView,
19979 placeCaretAt: placeCaretAt,
19980 getBoundingClientRect: getBoundingClientRect,
19981 destroy: destroy
19982 };
19983 bookmarkManager = BookmarkManager$1(exports);
19984 controlSelection = ControlSelection(exports, editor);
19985 exports.bookmarkManager = bookmarkManager;
19986 exports.controlSelection = controlSelection;
19987 return exports;
19988 };
19989
19990 var isText$8 = NodeType.isText;
19991 var startsWithCaretContainer$1 = function (node) {
19992 return isText$8(node) && node.data[0] === Zwsp.ZWSP;
19993 };
19994 var endsWithCaretContainer$1 = function (node) {
19995 return isText$8(node) && node.data[node.data.length - 1] === Zwsp.ZWSP;
19996 };
19997 var createZwsp = function (node) {
19998 return node.ownerDocument.createTextNode(Zwsp.ZWSP);
19999 };
20000 var insertBefore = function (node) {
20001 if (isText$8(node.previousSibling)) {
20002 if (endsWithCaretContainer$1(node.previousSibling)) {
20003 return node.previousSibling;
20004 } else {
20005 node.previousSibling.appendData(Zwsp.ZWSP);
20006 return node.previousSibling;
20007 }
20008 } else if (isText$8(node)) {
20009 if (startsWithCaretContainer$1(node)) {
20010 return node;
20011 } else {
20012 node.insertData(0, Zwsp.ZWSP);
20013 return node;
20014 }
20015 } else {
20016 var newNode = createZwsp(node);
20017 node.parentNode.insertBefore(newNode, node);
20018 return newNode;
20019 }
20020 };
20021 var insertAfter = function (node) {
20022 if (isText$8(node.nextSibling)) {
20023 if (startsWithCaretContainer$1(node.nextSibling)) {
20024 return node.nextSibling;
20025 } else {
20026 node.nextSibling.insertData(0, Zwsp.ZWSP);
20027 return node.nextSibling;
20028 }
20029 } else if (isText$8(node)) {
20030 if (endsWithCaretContainer$1(node)) {
20031 return node;
20032 } else {
20033 node.appendData(Zwsp.ZWSP);
20034 return node;
20035 }
20036 } else {
20037 var newNode = createZwsp(node);
20038 if (node.nextSibling) {
20039 node.parentNode.insertBefore(newNode, node.nextSibling);
20040 } else {
20041 node.parentNode.appendChild(newNode);
20042 }
20043 return newNode;
20044 }
20045 };
20046 var insertInline$1 = function (before, node) {
20047 return before ? insertBefore(node) : insertAfter(node);
20048 };
20049 var insertInlineBefore = curry(insertInline$1, true);
20050 var insertInlineAfter = curry(insertInline$1, false);
20051
20052 var insertInlinePos = function (pos, before) {
20053 if (NodeType.isText(pos.container())) {
20054 return insertInline$1(before, pos.container());
20055 } else {
20056 return insertInline$1(before, pos.getNode());
20057 }
20058 };
20059 var isPosCaretContainer = function (pos, caret) {
20060 var caretNode = caret.get();
20061 return caretNode && pos.container() === caretNode && isCaretContainerInline(caretNode);
20062 };
20063 var renderCaret = function (caret, location) {
20064 return location.fold(function (element) {
20065 CaretContainerRemove.remove(caret.get());
20066 var text = insertInlineBefore(element);
20067 caret.set(text);
20068 return Option.some(CaretPosition$1(text, text.length - 1));
20069 }, function (element) {
20070 return CaretFinder.firstPositionIn(element).map(function (pos) {
20071 if (!isPosCaretContainer(pos, caret)) {
20072 CaretContainerRemove.remove(caret.get());
20073 var text = insertInlinePos(pos, true);
20074 caret.set(text);
20075 return CaretPosition$1(text, 1);
20076 } else {
20077 return CaretPosition$1(caret.get(), 1);
20078 }
20079 });
20080 }, function (element) {
20081 return CaretFinder.lastPositionIn(element).map(function (pos) {
20082 if (!isPosCaretContainer(pos, caret)) {
20083 CaretContainerRemove.remove(caret.get());
20084 var text = insertInlinePos(pos, false);
20085 caret.set(text);
20086 return CaretPosition$1(text, text.length - 1);
20087 } else {
20088 return CaretPosition$1(caret.get(), caret.get().length - 1);
20089 }
20090 });
20091 }, function (element) {
20092 CaretContainerRemove.remove(caret.get());
20093 var text = insertInlineAfter(element);
20094 caret.set(text);
20095 return Option.some(CaretPosition$1(text, 1));
20096 });
20097 };
20098 var BoundaryCaret = { renderCaret: renderCaret };
20099
20100 var strongRtl = /[\u0591-\u07FF\uFB1D-\uFDFF\uFE70-\uFEFC]/;
20101 var hasStrongRtl = function (text) {
20102 return strongRtl.test(text);
20103 };
20104
20105 var isInlineTarget = function (editor, elm) {
20106 return is$1(Element.fromDom(elm), Settings.getInlineBoundarySelector(editor));
20107 };
20108 var isRtl$1 = function (element) {
20109 return DOMUtils$1.DOM.getStyle(element, 'direction', true) === 'rtl' || hasStrongRtl(element.textContent);
20110 };
20111 var findInlineParents = function (isInlineTarget, rootNode, pos) {
20112 return filter(DOMUtils$1.DOM.getParents(pos.container(), '*', rootNode), isInlineTarget);
20113 };
20114 var findRootInline = function (isInlineTarget, rootNode, pos) {
20115 var parents = findInlineParents(isInlineTarget, rootNode, pos);
20116 return Option.from(parents[parents.length - 1]);
20117 };
20118 var hasSameParentBlock = function (rootNode, node1, node2) {
20119 var block1 = getParentBlock(node1, rootNode);
20120 var block2 = getParentBlock(node2, rootNode);
20121 return block1 && block1 === block2;
20122 };
20123 var isAtZwsp = function (pos) {
20124 return isBeforeInline(pos) || isAfterInline(pos);
20125 };
20126 var normalizePosition = function (forward, pos) {
20127 if (!pos) {
20128 return pos;
20129 }
20130 var container = pos.container(), offset = pos.offset();
20131 if (forward) {
20132 if (isCaretContainerInline(container)) {
20133 if (NodeType.isText(container.nextSibling)) {
20134 return CaretPosition$1(container.nextSibling, 0);
20135 } else {
20136 return CaretPosition$1.after(container);
20137 }
20138 } else {
20139 return isBeforeInline(pos) ? CaretPosition$1(container, offset + 1) : pos;
20140 }
20141 } else {
20142 if (isCaretContainerInline(container)) {
20143 if (NodeType.isText(container.previousSibling)) {
20144 return CaretPosition$1(container.previousSibling, container.previousSibling.data.length);
20145 } else {
20146 return CaretPosition$1.before(container);
20147 }
20148 } else {
20149 return isAfterInline(pos) ? CaretPosition$1(container, offset - 1) : pos;
20150 }
20151 }
20152 };
20153 var normalizeForwards = curry(normalizePosition, true);
20154 var normalizeBackwards = curry(normalizePosition, false);
20155 var InlineUtils = {
20156 isInlineTarget: isInlineTarget,
20157 findRootInline: findRootInline,
20158 isRtl: isRtl$1,
20159 isAtZwsp: isAtZwsp,
20160 normalizePosition: normalizePosition,
20161 normalizeForwards: normalizeForwards,
20162 normalizeBackwards: normalizeBackwards,
20163 hasSameParentBlock: hasSameParentBlock
20164 };
20165
20166 var evaluateUntil = function (fns, args) {
20167 for (var i = 0; i < fns.length; i++) {
20168 var result = fns[i].apply(null, args);
20169 if (result.isSome()) {
20170 return result;
20171 }
20172 }
20173 return Option.none();
20174 };
20175 var LazyEvaluator = { evaluateUntil: evaluateUntil };
20176
20177 var Location = Adt.generate([
20178 { before: ['element'] },
20179 { start: ['element'] },
20180 { end: ['element'] },
20181 { after: ['element'] }
20182 ]);
20183 var rescope = function (rootNode, node) {
20184 var parentBlock = getParentBlock(node, rootNode);
20185 return parentBlock ? parentBlock : rootNode;
20186 };
20187 var before$4 = function (isInlineTarget, rootNode, pos) {
20188 var nPos = InlineUtils.normalizeForwards(pos);
20189 var scope = rescope(rootNode, nPos.container());
20190 return InlineUtils.findRootInline(isInlineTarget, scope, nPos).fold(function () {
20191 return CaretFinder.nextPosition(scope, nPos).bind(curry(InlineUtils.findRootInline, isInlineTarget, scope)).map(function (inline) {
20192 return Location.before(inline);
20193 });
20194 }, Option.none);
20195 };
20196 var isNotInsideFormatCaretContainer = function (rootNode, elm) {
20197 return getParentCaretContainer(rootNode, elm) === null;
20198 };
20199 var findInsideRootInline = function (isInlineTarget, rootNode, pos) {
20200 return InlineUtils.findRootInline(isInlineTarget, rootNode, pos).filter(curry(isNotInsideFormatCaretContainer, rootNode));
20201 };
20202 var start$1 = function (isInlineTarget, rootNode, pos) {
20203 var nPos = InlineUtils.normalizeBackwards(pos);
20204 return findInsideRootInline(isInlineTarget, rootNode, nPos).bind(function (inline) {
20205 var prevPos = CaretFinder.prevPosition(inline, nPos);
20206 return prevPos.isNone() ? Option.some(Location.start(inline)) : Option.none();
20207 });
20208 };
20209 var end = function (isInlineTarget, rootNode, pos) {
20210 var nPos = InlineUtils.normalizeForwards(pos);
20211 return findInsideRootInline(isInlineTarget, rootNode, nPos).bind(function (inline) {
20212 var nextPos = CaretFinder.nextPosition(inline, nPos);
20213 return nextPos.isNone() ? Option.some(Location.end(inline)) : Option.none();
20214 });
20215 };
20216 var after$3 = function (isInlineTarget, rootNode, pos) {
20217 var nPos = InlineUtils.normalizeBackwards(pos);
20218 var scope = rescope(rootNode, nPos.container());
20219 return InlineUtils.findRootInline(isInlineTarget, scope, nPos).fold(function () {
20220 return CaretFinder.prevPosition(scope, nPos).bind(curry(InlineUtils.findRootInline, isInlineTarget, scope)).map(function (inline) {
20221 return Location.after(inline);
20222 });
20223 }, Option.none);
20224 };
20225 var isValidLocation = function (location) {
20226 return InlineUtils.isRtl(getElement(location)) === false;
20227 };
20228 var readLocation = function (isInlineTarget, rootNode, pos) {
20229 var location = LazyEvaluator.evaluateUntil([
20230 before$4,
20231 start$1,
20232 end,
20233 after$3
20234 ], [
20235 isInlineTarget,
20236 rootNode,
20237 pos
20238 ]);
20239 return location.filter(isValidLocation);
20240 };
20241 var getElement = function (location) {
20242 return location.fold(identity, identity, identity, identity);
20243 };
20244 var getName = function (location) {
20245 return location.fold(constant('before'), constant('start'), constant('end'), constant('after'));
20246 };
20247 var outside = function (location) {
20248 return location.fold(Location.before, Location.before, Location.after, Location.after);
20249 };
20250 var inside = function (location) {
20251 return location.fold(Location.start, Location.start, Location.end, Location.end);
20252 };
20253 var isEq$5 = function (location1, location2) {
20254 return getName(location1) === getName(location2) && getElement(location1) === getElement(location2);
20255 };
20256 var betweenInlines = function (forward, isInlineTarget, rootNode, from, to, location) {
20257 return liftN([
20258 InlineUtils.findRootInline(isInlineTarget, rootNode, from),
20259 InlineUtils.findRootInline(isInlineTarget, rootNode, to)
20260 ], function (fromInline, toInline) {
20261 if (fromInline !== toInline && InlineUtils.hasSameParentBlock(rootNode, fromInline, toInline)) {
20262 return Location.after(forward ? fromInline : toInline);
20263 } else {
20264 return location;
20265 }
20266 }).getOr(location);
20267 };
20268 var skipNoMovement = function (fromLocation, toLocation) {
20269 return fromLocation.fold(constant(true), function (fromLocation) {
20270 return !isEq$5(fromLocation, toLocation);
20271 });
20272 };
20273 var findLocationTraverse = function (forward, isInlineTarget, rootNode, fromLocation, pos) {
20274 var from = InlineUtils.normalizePosition(forward, pos);
20275 var to = CaretFinder.fromPosition(forward, rootNode, from).map(curry(InlineUtils.normalizePosition, forward));
20276 var location = to.fold(function () {
20277 return fromLocation.map(outside);
20278 }, function (to) {
20279 return readLocation(isInlineTarget, rootNode, to).map(curry(betweenInlines, forward, isInlineTarget, rootNode, from, to)).filter(curry(skipNoMovement, fromLocation));
20280 });
20281 return location.filter(isValidLocation);
20282 };
20283 var findLocationSimple = function (forward, location) {
20284 if (forward) {
20285 return location.fold(compose(Option.some, Location.start), Option.none, compose(Option.some, Location.after), Option.none);
20286 } else {
20287 return location.fold(Option.none, compose(Option.some, Location.before), Option.none, compose(Option.some, Location.end));
20288 }
20289 };
20290 var findLocation = function (forward, isInlineTarget, rootNode, pos) {
20291 var from = InlineUtils.normalizePosition(forward, pos);
20292 var fromLocation = readLocation(isInlineTarget, rootNode, from);
20293 return readLocation(isInlineTarget, rootNode, from).bind(curry(findLocationSimple, forward)).orThunk(function () {
20294 return findLocationTraverse(forward, isInlineTarget, rootNode, fromLocation, pos);
20295 });
20296 };
20297 var BoundaryLocation = {
20298 readLocation: readLocation,
20299 findLocation: findLocation,
20300 prevLocation: curry(findLocation, false),
20301 nextLocation: curry(findLocation, true),
20302 getElement: getElement,
20303 outside: outside,
20304 inside: inside
20305 };
20306
20307 var hasSelectionModifyApi = function (editor) {
20308 return isFunction(editor.selection.getSel().modify);
20309 };
20310 var moveRel = function (forward, selection, pos) {
20311 var delta = forward ? 1 : -1;
20312 selection.setRng(CaretPosition$1(pos.container(), pos.offset() + delta).toRange());
20313 selection.getSel().modify('move', forward ? 'forward' : 'backward', 'word');
20314 return true;
20315 };
20316 var moveByWord = function (forward, editor) {
20317 var rng = editor.selection.getRng();
20318 var pos = forward ? CaretPosition$1.fromRangeEnd(rng) : CaretPosition$1.fromRangeStart(rng);
20319 if (!hasSelectionModifyApi(editor)) {
20320 return false;
20321 } else if (forward && isBeforeInline(pos)) {
20322 return moveRel(true, editor.selection, pos);
20323 } else if (!forward && isAfterInline(pos)) {
20324 return moveRel(false, editor.selection, pos);
20325 } else {
20326 return false;
20327 }
20328 };
20329 var WordSelection = {
20330 hasSelectionModifyApi: hasSelectionModifyApi,
20331 moveByWord: moveByWord
20332 };
20333
20334 var setCaretPosition = function (editor, pos) {
20335 var rng = editor.dom.createRng();
20336 rng.setStart(pos.container(), pos.offset());
20337 rng.setEnd(pos.container(), pos.offset());
20338 editor.selection.setRng(rng);
20339 };
20340 var isFeatureEnabled = function (editor) {
20341 return editor.settings.inline_boundaries !== false;
20342 };
20343 var setSelected = function (state, elm) {
20344 if (state) {
20345 elm.setAttribute('data-mce-selected', 'inline-boundary');
20346 } else {
20347 elm.removeAttribute('data-mce-selected');
20348 }
20349 };
20350 var renderCaretLocation = function (editor, caret, location) {
20351 return BoundaryCaret.renderCaret(caret, location).map(function (pos) {
20352 setCaretPosition(editor, pos);
20353 return location;
20354 });
20355 };
20356 var findLocation$1 = function (editor, caret, forward) {
20357 var rootNode = editor.getBody();
20358 var from = CaretPosition$1.fromRangeStart(editor.selection.getRng());
20359 var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);
20360 var location = BoundaryLocation.findLocation(forward, isInlineTarget, rootNode, from);
20361 return location.bind(function (location) {
20362 return renderCaretLocation(editor, caret, location);
20363 });
20364 };
20365 var toggleInlines = function (isInlineTarget, dom, elms) {
20366 var selectedInlines = filter(dom.select('*[data-mce-selected="inline-boundary"]'), isInlineTarget);
20367 var targetInlines = filter(elms, isInlineTarget);
20368 each(difference(selectedInlines, targetInlines), curry(setSelected, false));
20369 each(difference(targetInlines, selectedInlines), curry(setSelected, true));
20370 };
20371 var safeRemoveCaretContainer = function (editor, caret) {
20372 if (editor.selection.isCollapsed() && editor.composing !== true && caret.get()) {
20373 var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
20374 if (CaretPosition$1.isTextPosition(pos) && InlineUtils.isAtZwsp(pos) === false) {
20375 setCaretPosition(editor, CaretContainerRemove.removeAndReposition(caret.get(), pos));
20376 caret.set(null);
20377 }
20378 }
20379 };
20380 var renderInsideInlineCaret = function (isInlineTarget, editor, caret, elms) {
20381 if (editor.selection.isCollapsed()) {
20382 var inlines = filter(elms, isInlineTarget);
20383 each(inlines, function (inline) {
20384 var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
20385 BoundaryLocation.readLocation(isInlineTarget, editor.getBody(), pos).bind(function (location) {
20386 return renderCaretLocation(editor, caret, location);
20387 });
20388 });
20389 }
20390 };
20391 var move$1 = function (editor, caret, forward) {
20392 return function () {
20393 return isFeatureEnabled(editor) ? findLocation$1(editor, caret, forward).isSome() : false;
20394 };
20395 };
20396 var moveWord = function (forward, editor, caret) {
20397 return function () {
20398 return isFeatureEnabled(editor) ? WordSelection.moveByWord(forward, editor) : false;
20399 };
20400 };
20401 var setupSelectedState = function (editor) {
20402 var caret = Cell(null);
20403 var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);
20404 editor.on('NodeChange', function (e) {
20405 if (isFeatureEnabled(editor)) {
20406 toggleInlines(isInlineTarget, editor.dom, e.parents);
20407 safeRemoveCaretContainer(editor, caret);
20408 renderInsideInlineCaret(isInlineTarget, editor, caret, e.parents);
20409 }
20410 });
20411 return caret;
20412 };
20413 var moveNextWord = curry(moveWord, true);
20414 var movePrevWord = curry(moveWord, false);
20415 var BoundarySelection = {
20416 move: move$1,
20417 moveNextWord: moveNextWord,
20418 movePrevWord: movePrevWord,
20419 setupSelectedState: setupSelectedState,
20420 setCaretPosition: setCaretPosition
20421 };
20422
20423 var BreakType;
20424 (function (BreakType) {
20425 BreakType[BreakType['Br'] = 0] = 'Br';
20426 BreakType[BreakType['Block'] = 1] = 'Block';
20427 BreakType[BreakType['Wrap'] = 2] = 'Wrap';
20428 BreakType[BreakType['Eol'] = 3] = 'Eol';
20429 }(BreakType || (BreakType = {})));
20430 var flip = function (direction, positions) {
20431 return direction === HDirection.Backwards ? positions.reverse() : positions;
20432 };
20433 var walk$3 = function (direction, caretWalker, pos) {
20434 return direction === HDirection.Forwards ? caretWalker.next(pos) : caretWalker.prev(pos);
20435 };
20436 var getBreakType = function (scope, direction, currentPos, nextPos) {
20437 if (NodeType.isBr(nextPos.getNode(direction === HDirection.Forwards))) {
20438 return BreakType.Br;
20439 } else if (isInSameBlock(currentPos, nextPos) === false) {
20440 return BreakType.Block;
20441 } else {
20442 return BreakType.Wrap;
20443 }
20444 };
20445 var getPositionsUntil = function (predicate, direction, scope, start) {
20446 var caretWalker = CaretWalker(scope);
20447 var currentPos = start, nextPos;
20448 var positions = [];
20449 while (currentPos) {
20450 nextPos = walk$3(direction, caretWalker, currentPos);
20451 if (!nextPos) {
20452 break;
20453 }
20454 if (NodeType.isBr(nextPos.getNode(false))) {
20455 if (direction === HDirection.Forwards) {
20456 return {
20457 positions: flip(direction, positions).concat([nextPos]),
20458 breakType: BreakType.Br,
20459 breakAt: Option.some(nextPos)
20460 };
20461 } else {
20462 return {
20463 positions: flip(direction, positions),
20464 breakType: BreakType.Br,
20465 breakAt: Option.some(nextPos)
20466 };
20467 }
20468 }
20469 if (!nextPos.isVisible()) {
20470 currentPos = nextPos;
20471 continue;
20472 }
20473 if (predicate(currentPos, nextPos)) {
20474 var breakType = getBreakType(scope, direction, currentPos, nextPos);
20475 return {
20476 positions: flip(direction, positions),
20477 breakType: breakType,
20478 breakAt: Option.some(nextPos)
20479 };
20480 }
20481 positions.push(nextPos);
20482 currentPos = nextPos;
20483 }
20484 return {
20485 positions: flip(direction, positions),
20486 breakType: BreakType.Eol,
20487 breakAt: Option.none()
20488 };
20489 };
20490 var getAdjacentLinePositions = function (direction, getPositionsUntilBreak, scope, start) {
20491 return getPositionsUntilBreak(scope, start).breakAt.map(function (pos) {
20492 var positions = getPositionsUntilBreak(scope, pos).positions;
20493 return direction === HDirection.Backwards ? positions.concat(pos) : [pos].concat(positions);
20494 }).getOr([]);
20495 };
20496 var findClosestHorizontalPositionFromPoint = function (positions, x) {
20497 return foldl(positions, function (acc, newPos) {
20498 return acc.fold(function () {
20499 return Option.some(newPos);
20500 }, function (lastPos) {
20501 return liftN([
20502 head(lastPos.getClientRects()),
20503 head(newPos.getClientRects())
20504 ], function (lastRect, newRect) {
20505 var lastDist = Math.abs(x - lastRect.left);
20506 var newDist = Math.abs(x - newRect.left);
20507 return newDist <= lastDist ? newPos : lastPos;
20508 }).or(acc);
20509 });
20510 }, Option.none());
20511 };
20512 var findClosestHorizontalPosition = function (positions, pos) {
20513 return head(pos.getClientRects()).bind(function (targetRect) {
20514 return findClosestHorizontalPositionFromPoint(positions, targetRect.left);
20515 });
20516 };
20517 var getPositionsUntilPreviousLine = curry(getPositionsUntil, CaretPosition.isAbove, -1);
20518 var getPositionsUntilNextLine = curry(getPositionsUntil, CaretPosition.isBelow, 1);
20519 var isAtFirstLine = function (scope, pos) {
20520 return getPositionsUntilPreviousLine(scope, pos).breakAt.isNone();
20521 };
20522 var isAtLastLine = function (scope, pos) {
20523 return getPositionsUntilNextLine(scope, pos).breakAt.isNone();
20524 };
20525 var getPositionsAbove = curry(getAdjacentLinePositions, -1, getPositionsUntilPreviousLine);
20526 var getPositionsBelow = curry(getAdjacentLinePositions, 1, getPositionsUntilNextLine);
20527 var getFirstLinePositions = function (scope) {
20528 return CaretFinder.firstPositionIn(scope).map(function (pos) {
20529 return [pos].concat(getPositionsUntilNextLine(scope, pos).positions);
20530 }).getOr([]);
20531 };
20532 var getLastLinePositions = function (scope) {
20533 return CaretFinder.lastPositionIn(scope).map(function (pos) {
20534 return getPositionsUntilPreviousLine(scope, pos).positions.concat(pos);
20535 }).getOr([]);
20536 };
20537
20538 var isContentEditableFalse$b = NodeType.isContentEditableFalse;
20539 var getSelectedNode$1 = getSelectedNode;
20540 var moveToCeFalseHorizontally = function (direction, editor, getNextPosFn, range) {
20541 var forwards = direction === HDirection.Forwards;
20542 var isBeforeContentEditableFalseFn = forwards ? isBeforeContentEditableFalse : isAfterContentEditableFalse;
20543 if (!range.collapsed) {
20544 var node = getSelectedNode$1(range);
20545 if (isContentEditableFalse$b(node)) {
20546 return showCaret(direction, editor, node, direction === HDirection.Backwards, true);
20547 }
20548 }
20549 var rangeIsInContainerBlock = isRangeInCaretContainerBlock(range);
20550 var caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range);
20551 if (isBeforeContentEditableFalseFn(caretPosition)) {
20552 return selectNode(editor, caretPosition.getNode(!forwards));
20553 }
20554 var nextCaretPosition = InlineUtils.normalizePosition(forwards, getNextPosFn(caretPosition));
20555 if (!nextCaretPosition) {
20556 if (rangeIsInContainerBlock) {
20557 return range;
20558 }
20559 return null;
20560 }
20561 if (isBeforeContentEditableFalseFn(nextCaretPosition)) {
20562 return showCaret(direction, editor, nextCaretPosition.getNode(!forwards), forwards, true);
20563 }
20564 var peekCaretPosition = getNextPosFn(nextCaretPosition);
20565 if (peekCaretPosition && isBeforeContentEditableFalseFn(peekCaretPosition)) {
20566 if (isMoveInsideSameBlock(nextCaretPosition, peekCaretPosition)) {
20567 return showCaret(direction, editor, peekCaretPosition.getNode(!forwards), forwards, true);
20568 }
20569 }
20570 if (rangeIsInContainerBlock) {
20571 return renderRangeCaret(editor, nextCaretPosition.toRange(), true);
20572 }
20573 return null;
20574 };
20575 var moveToCeFalseVertically = function (direction, editor, walkerFn, range) {
20576 var caretPosition, linePositions, nextLinePositions;
20577 var closestNextLineRect, caretClientRect, clientX;
20578 var dist1, dist2, contentEditableFalseNode;
20579 contentEditableFalseNode = getSelectedNode$1(range);
20580 caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range);
20581 linePositions = walkerFn(editor.getBody(), isAboveLine(1), caretPosition);
20582 nextLinePositions = filter(linePositions, isLine(1));
20583 caretClientRect = ArrUtils.last(caretPosition.getClientRects());
20584 if (isBeforeContentEditableFalse(caretPosition) || isBeforeTable(caretPosition)) {
20585 contentEditableFalseNode = caretPosition.getNode();
20586 }
20587 if (isAfterContentEditableFalse(caretPosition) || isAfterTable(caretPosition)) {
20588 contentEditableFalseNode = caretPosition.getNode(true);
20589 }
20590 if (!caretClientRect) {
20591 return null;
20592 }
20593 clientX = caretClientRect.left;
20594 closestNextLineRect = findClosestClientRect(nextLinePositions, clientX);
20595 if (closestNextLineRect) {
20596 if (isContentEditableFalse$b(closestNextLineRect.node)) {
20597 dist1 = Math.abs(clientX - closestNextLineRect.left);
20598 dist2 = Math.abs(clientX - closestNextLineRect.right);
20599 return showCaret(direction, editor, closestNextLineRect.node, dist1 < dist2, true);
20600 }
20601 }
20602 if (contentEditableFalseNode) {
20603 var caretPositions = positionsUntil(direction, editor.getBody(), isAboveLine(1), contentEditableFalseNode);
20604 closestNextLineRect = findClosestClientRect(filter(caretPositions, isLine(1)), clientX);
20605 if (closestNextLineRect) {
20606 return renderRangeCaret(editor, closestNextLineRect.position.toRange(), true);
20607 }
20608 closestNextLineRect = ArrUtils.last(filter(caretPositions, isLine(0)));
20609 if (closestNextLineRect) {
20610 return renderRangeCaret(editor, closestNextLineRect.position.toRange(), true);
20611 }
20612 }
20613 };
20614 var createTextBlock = function (editor) {
20615 var textBlock = editor.dom.create(Settings.getForcedRootBlock(editor));
20616 if (!Env.ie || Env.ie >= 11) {
20617 textBlock.innerHTML = '<br data-mce-bogus="1">';
20618 }
20619 return textBlock;
20620 };
20621 var exitPreBlock = function (editor, direction, range) {
20622 var pre, caretPos, newBlock;
20623 var caretWalker = CaretWalker(editor.getBody());
20624 var getNextVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.next);
20625 var getPrevVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.prev);
20626 if (range.collapsed && editor.settings.forced_root_block) {
20627 pre = editor.dom.getParent(range.startContainer, 'PRE');
20628 if (!pre) {
20629 return;
20630 }
20631 if (direction === 1) {
20632 caretPos = getNextVisualCaretPosition(CaretPosition$1.fromRangeStart(range));
20633 } else {
20634 caretPos = getPrevVisualCaretPosition(CaretPosition$1.fromRangeStart(range));
20635 }
20636 if (!caretPos) {
20637 newBlock = createTextBlock(editor);
20638 if (direction === 1) {
20639 editor.$(pre).after(newBlock);
20640 } else {
20641 editor.$(pre).before(newBlock);
20642 }
20643 editor.selection.select(newBlock, true);
20644 editor.selection.collapse();
20645 }
20646 }
20647 };
20648 var getHorizontalRange = function (editor, forward) {
20649 var caretWalker = CaretWalker(editor.getBody());
20650 var getNextVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.next);
20651 var getPrevVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.prev);
20652 var newRange;
20653 var direction = forward ? HDirection.Forwards : HDirection.Backwards;
20654 var getNextPosFn = forward ? getNextVisualCaretPosition : getPrevVisualCaretPosition;
20655 var range = editor.selection.getRng();
20656 newRange = moveToCeFalseHorizontally(direction, editor, getNextPosFn, range);
20657 if (newRange) {
20658 return newRange;
20659 }
20660 newRange = exitPreBlock(editor, direction, range);
20661 if (newRange) {
20662 return newRange;
20663 }
20664 return null;
20665 };
20666 var getVerticalRange = function (editor, down) {
20667 var newRange;
20668 var direction = down ? 1 : -1;
20669 var walkerFn = down ? downUntil : upUntil;
20670 var range = editor.selection.getRng();
20671 newRange = moveToCeFalseVertically(direction, editor, walkerFn, range);
20672 if (newRange) {
20673 return newRange;
20674 }
20675 newRange = exitPreBlock(editor, direction, range);
20676 if (newRange) {
20677 return newRange;
20678 }
20679 return null;
20680 };
20681 var moveH = function (editor, forward) {
20682 return function () {
20683 var newRng = getHorizontalRange(editor, forward);
20684 if (newRng) {
20685 editor.selection.setRng(newRng);
20686 return true;
20687 } else {
20688 return false;
20689 }
20690 };
20691 };
20692 var moveV = function (editor, down) {
20693 return function () {
20694 var newRng = getVerticalRange(editor, down);
20695 if (newRng) {
20696 editor.selection.setRng(newRng);
20697 return true;
20698 } else {
20699 return false;
20700 }
20701 };
20702 };
20703 var isCefPosition = function (forward) {
20704 return function (pos) {
20705 return forward ? isAfterContentEditableFalse(pos) : isBeforeContentEditableFalse(pos);
20706 };
20707 };
20708 var moveToLineEndPoint = function (editor, forward) {
20709 return function () {
20710 var from = forward ? CaretPosition$1.fromRangeEnd(editor.selection.getRng()) : CaretPosition$1.fromRangeStart(editor.selection.getRng());
20711 var result = forward ? getPositionsUntilNextLine(editor.getBody(), from) : getPositionsUntilPreviousLine(editor.getBody(), from);
20712 var to = forward ? last(result.positions) : head(result.positions);
20713 return to.filter(isCefPosition(forward)).fold(constant(false), function (pos) {
20714 editor.selection.setRng(pos.toRange());
20715 return true;
20716 });
20717 };
20718 };
20719
20720 var deflate = function (rect, delta) {
20721 return {
20722 left: rect.left - delta,
20723 top: rect.top - delta,
20724 right: rect.right + delta * 2,
20725 bottom: rect.bottom + delta * 2,
20726 width: rect.width + delta,
20727 height: rect.height + delta
20728 };
20729 };
20730 var getCorners = function (getYAxisValue, tds) {
20731 return bind(tds, function (td) {
20732 var rect = deflate(clone$1(td.getBoundingClientRect()), -1);
20733 return [
20734 {
20735 x: rect.left,
20736 y: getYAxisValue(rect),
20737 cell: td
20738 },
20739 {
20740 x: rect.right,
20741 y: getYAxisValue(rect),
20742 cell: td
20743 }
20744 ];
20745 });
20746 };
20747 var findClosestCorner = function (corners, x, y) {
20748 return foldl(corners, function (acc, newCorner) {
20749 return acc.fold(function () {
20750 return Option.some(newCorner);
20751 }, function (oldCorner) {
20752 var oldDist = Math.sqrt(Math.abs(oldCorner.x - x) + Math.abs(oldCorner.y - y));
20753 var newDist = Math.sqrt(Math.abs(newCorner.x - x) + Math.abs(newCorner.y - y));
20754 return Option.some(newDist < oldDist ? newCorner : oldCorner);
20755 });
20756 }, Option.none());
20757 };
20758 var getClosestCell = function (getYAxisValue, isTargetCorner, table, x, y) {
20759 var cells = descendants$1(Element.fromDom(table), 'td,th,caption').map(function (e) {
20760 return e.dom();
20761 });
20762 var corners = filter(getCorners(getYAxisValue, cells), function (corner) {
20763 return isTargetCorner(corner, y);
20764 });
20765 return findClosestCorner(corners, x, y).map(function (corner) {
20766 return corner.cell;
20767 });
20768 };
20769 var getBottomValue = function (rect) {
20770 return rect.bottom;
20771 };
20772 var getTopValue = function (rect) {
20773 return rect.top;
20774 };
20775 var isAbove$1 = function (corner, y) {
20776 return corner.y < y;
20777 };
20778 var isBelow$1 = function (corner, y) {
20779 return corner.y > y;
20780 };
20781 var getClosestCellAbove = curry(getClosestCell, getBottomValue, isAbove$1);
20782 var getClosestCellBelow = curry(getClosestCell, getTopValue, isBelow$1);
20783 var findClosestPositionInAboveCell = function (table, pos) {
20784 return head(pos.getClientRects()).bind(function (rect) {
20785 return getClosestCellAbove(table, rect.left, rect.top);
20786 }).bind(function (cell) {
20787 return findClosestHorizontalPosition(getLastLinePositions(cell), pos);
20788 });
20789 };
20790 var findClosestPositionInBelowCell = function (table, pos) {
20791 return last(pos.getClientRects()).bind(function (rect) {
20792 return getClosestCellBelow(table, rect.left, rect.top);
20793 }).bind(function (cell) {
20794 return findClosestHorizontalPosition(getFirstLinePositions(cell), pos);
20795 });
20796 };
20797
20798 var moveToRange = function (editor, rng) {
20799 editor.selection.setRng(rng);
20800 ScrollIntoView.scrollRangeIntoView(editor, rng);
20801 };
20802 var hasNextBreak = function (getPositionsUntil, scope, lineInfo) {
20803 return lineInfo.breakAt.map(function (breakPos) {
20804 return getPositionsUntil(scope, breakPos).breakAt.isSome();
20805 }).getOr(false);
20806 };
20807 var startsWithWrapBreak = function (lineInfo) {
20808 return lineInfo.breakType === BreakType.Wrap && lineInfo.positions.length === 0;
20809 };
20810 var startsWithBrBreak = function (lineInfo) {
20811 return lineInfo.breakType === BreakType.Br && lineInfo.positions.length === 1;
20812 };
20813 var isAtTableCellLine = function (getPositionsUntil, scope, pos) {
20814 var lineInfo = getPositionsUntil(scope, pos);
20815 if (startsWithWrapBreak(lineInfo) || !NodeType.isBr(pos.getNode()) && startsWithBrBreak(lineInfo)) {
20816 return !hasNextBreak(getPositionsUntil, scope, lineInfo);
20817 } else {
20818 return lineInfo.breakAt.isNone();
20819 }
20820 };
20821 var isAtFirstTableCellLine = curry(isAtTableCellLine, getPositionsUntilPreviousLine);
20822 var isAtLastTableCellLine = curry(isAtTableCellLine, getPositionsUntilNextLine);
20823 var isCaretAtStartOrEndOfTable = function (forward, rng, table) {
20824 var caretPos = CaretPosition$1.fromRangeStart(rng);
20825 return CaretFinder.positionIn(!forward, table).map(function (pos) {
20826 return pos.isEqual(caretPos);
20827 }).getOr(false);
20828 };
20829 var navigateHorizontally = function (editor, forward, table, td) {
20830 var rng = editor.selection.getRng();
20831 var direction = forward ? 1 : -1;
20832 if (isFakeCaretTableBrowser() && isCaretAtStartOrEndOfTable(forward, rng, table)) {
20833 var newRng = showCaret(direction, editor, table, !forward, true);
20834 moveToRange(editor, newRng);
20835 return true;
20836 }
20837 return false;
20838 };
20839 var getClosestAbovePosition = function (root, table, start) {
20840 return findClosestPositionInAboveCell(table, start).orThunk(function () {
20841 return head(start.getClientRects()).bind(function (rect) {
20842 return findClosestHorizontalPositionFromPoint(getPositionsAbove(root, CaretPosition$1.before(table)), rect.left);
20843 });
20844 }).getOr(CaretPosition$1.before(table));
20845 };
20846 var getClosestBelowPosition = function (root, table, start) {
20847 return findClosestPositionInBelowCell(table, start).orThunk(function () {
20848 return head(start.getClientRects()).bind(function (rect) {
20849 return findClosestHorizontalPositionFromPoint(getPositionsBelow(root, CaretPosition$1.after(table)), rect.left);
20850 });
20851 }).getOr(CaretPosition$1.after(table));
20852 };
20853 var getTable = function (previous, pos) {
20854 var node = pos.getNode(previous);
20855 return NodeType.isElement(node) && node.nodeName === 'TABLE' ? Option.some(node) : Option.none();
20856 };
20857 var renderBlock = function (down, editor, table, pos) {
20858 var forcedRootBlock = Settings.getForcedRootBlock(editor);
20859 if (forcedRootBlock) {
20860 editor.undoManager.transact(function () {
20861 var element = Element.fromTag(forcedRootBlock);
20862 setAll(element, Settings.getForcedRootBlockAttrs(editor));
20863 append(element, Element.fromTag('br'));
20864 if (down) {
20865 after(Element.fromDom(table), element);
20866 } else {
20867 before(Element.fromDom(table), element);
20868 }
20869 var rng = editor.dom.createRng();
20870 rng.setStart(element.dom(), 0);
20871 rng.setEnd(element.dom(), 0);
20872 moveToRange(editor, rng);
20873 });
20874 } else {
20875 moveToRange(editor, pos.toRange());
20876 }
20877 };
20878 var moveCaret = function (editor, down, pos) {
20879 var table = down ? getTable(true, pos) : getTable(false, pos);
20880 var last = down === false;
20881 table.fold(function () {
20882 return moveToRange(editor, pos.toRange());
20883 }, function (table) {
20884 return CaretFinder.positionIn(last, editor.getBody()).filter(function (lastPos) {
20885 return lastPos.isEqual(pos);
20886 }).fold(function () {
20887 return moveToRange(editor, pos.toRange());
20888 }, function (_) {
20889 return renderBlock(down, editor, table, pos);
20890 });
20891 });
20892 };
20893 var navigateVertically = function (editor, down, table, td) {
20894 var rng = editor.selection.getRng();
20895 var pos = CaretPosition$1.fromRangeStart(rng);
20896 var root = editor.getBody();
20897 if (!down && isAtFirstTableCellLine(td, pos)) {
20898 var newPos = getClosestAbovePosition(root, table, pos);
20899 moveCaret(editor, down, newPos);
20900 return true;
20901 } else if (down && isAtLastTableCellLine(td, pos)) {
20902 var newPos = getClosestBelowPosition(root, table, pos);
20903 moveCaret(editor, down, newPos);
20904 return true;
20905 } else {
20906 return false;
20907 }
20908 };
20909 var moveH$1 = function (editor, forward) {
20910 return function () {
20911 return Option.from(editor.dom.getParent(editor.selection.getNode(), 'td,th')).bind(function (td) {
20912 return Option.from(editor.dom.getParent(td, 'table')).map(function (table) {
20913 return navigateHorizontally(editor, forward, table);
20914 });
20915 }).getOr(false);
20916 };
20917 };
20918 var moveV$1 = function (editor, forward) {
20919 return function () {
20920 return Option.from(editor.dom.getParent(editor.selection.getNode(), 'td,th')).bind(function (td) {
20921 return Option.from(editor.dom.getParent(td, 'table')).map(function (table) {
20922 return navigateVertically(editor, forward, table, td);
20923 });
20924 }).getOr(false);
20925 };
20926 };
20927
20928 var isTarget = function (node) {
20929 return contains(['figcaption'], name(node));
20930 };
20931 var rangeBefore = function (target) {
20932 var rng = domGlobals.document.createRange();
20933 rng.setStartBefore(target.dom());
20934 rng.setEndBefore(target.dom());
20935 return rng;
20936 };
20937 var insertElement = function (root, elm, forward) {
20938 if (forward) {
20939 append(root, elm);
20940 } else {
20941 prepend(root, elm);
20942 }
20943 };
20944 var insertBr = function (root, forward) {
20945 var br = Element.fromTag('br');
20946 insertElement(root, br, forward);
20947 return rangeBefore(br);
20948 };
20949 var insertBlock$1 = function (root, forward, blockName, attrs) {
20950 var block = Element.fromTag(blockName);
20951 var br = Element.fromTag('br');
20952 setAll(block, attrs);
20953 append(block, br);
20954 insertElement(root, block, forward);
20955 return rangeBefore(br);
20956 };
20957 var insertEmptyLine = function (root, rootBlockName, attrs, forward) {
20958 if (rootBlockName === '') {
20959 return insertBr(root, forward);
20960 } else {
20961 return insertBlock$1(root, forward, rootBlockName, attrs);
20962 }
20963 };
20964 var getClosestTargetBlock = function (pos, root) {
20965 var isRoot = curry(eq, root);
20966 return closest(Element.fromDom(pos.container()), isBlock, isRoot).filter(isTarget);
20967 };
20968 var isAtFirstOrLastLine = function (root, forward, pos) {
20969 return forward ? isAtLastLine(root.dom(), pos) : isAtFirstLine(root.dom(), pos);
20970 };
20971 var moveCaretToNewEmptyLine = function (editor, forward) {
20972 var root = Element.fromDom(editor.getBody());
20973 var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
20974 var rootBlock = Settings.getForcedRootBlock(editor);
20975 var rootBlockAttrs = Settings.getForcedRootBlockAttrs(editor);
20976 return getClosestTargetBlock(pos, root).exists(function () {
20977 if (isAtFirstOrLastLine(root, forward, pos)) {
20978 var rng = insertEmptyLine(root, rootBlock, rootBlockAttrs, forward);
20979 editor.selection.setRng(rng);
20980 return true;
20981 } else {
20982 return false;
20983 }
20984 });
20985 };
20986 var moveV$2 = function (editor, forward) {
20987 return function () {
20988 if (editor.selection.isCollapsed()) {
20989 return moveCaretToNewEmptyLine(editor, forward);
20990 } else {
20991 return false;
20992 }
20993 };
20994 };
20995
20996 var defaultPatterns = function (patterns) {
20997 return map(patterns, function (pattern) {
20998 return merge({
20999 shiftKey: false,
21000 altKey: false,
21001 ctrlKey: false,
21002 metaKey: false,
21003 keyCode: 0,
21004 action: noop
21005 }, pattern);
21006 });
21007 };
21008 var matchesEvent = function (pattern, evt) {
21009 return evt.keyCode === pattern.keyCode && evt.shiftKey === pattern.shiftKey && evt.altKey === pattern.altKey && evt.ctrlKey === pattern.ctrlKey && evt.metaKey === pattern.metaKey;
21010 };
21011 var match$1 = function (patterns, evt) {
21012 return bind(defaultPatterns(patterns), function (pattern) {
21013 return matchesEvent(pattern, evt) ? [pattern] : [];
21014 });
21015 };
21016 var action = function (f) {
21017 var x = [];
21018 for (var _i = 1; _i < arguments.length; _i++) {
21019 x[_i - 1] = arguments[_i];
21020 }
21021 var args = Array.prototype.slice.call(arguments, 1);
21022 return function () {
21023 return f.apply(null, args);
21024 };
21025 };
21026 var execute = function (patterns, evt) {
21027 return find(match$1(patterns, evt), function (pattern) {
21028 return pattern.action();
21029 });
21030 };
21031 var MatchKeys = {
21032 match: match$1,
21033 action: action,
21034 execute: execute
21035 };
21036
21037 var executeKeydownOverride = function (editor, caret, evt) {
21038 var os = PlatformDetection$1.detect().os;
21039 MatchKeys.execute([
21040 {
21041 keyCode: VK.RIGHT,
21042 action: moveH(editor, true)
21043 },
21044 {
21045 keyCode: VK.LEFT,
21046 action: moveH(editor, false)
21047 },
21048 {
21049 keyCode: VK.UP,
21050 action: moveV(editor, false)
21051 },
21052 {
21053 keyCode: VK.DOWN,
21054 action: moveV(editor, true)
21055 },
21056 {
21057 keyCode: VK.RIGHT,
21058 action: moveH$1(editor, true)
21059 },
21060 {
21061 keyCode: VK.LEFT,
21062 action: moveH$1(editor, false)
21063 },
21064 {
21065 keyCode: VK.UP,
21066 action: moveV$1(editor, false)
21067 },
21068 {
21069 keyCode: VK.DOWN,
21070 action: moveV$1(editor, true)
21071 },
21072 {
21073 keyCode: VK.RIGHT,
21074 action: BoundarySelection.move(editor, caret, true)
21075 },
21076 {
21077 keyCode: VK.LEFT,
21078 action: BoundarySelection.move(editor, caret, false)
21079 },
21080 {
21081 keyCode: VK.RIGHT,
21082 ctrlKey: !os.isOSX(),
21083 altKey: os.isOSX(),
21084 action: BoundarySelection.moveNextWord(editor, caret)
21085 },
21086 {
21087 keyCode: VK.LEFT,
21088 ctrlKey: !os.isOSX(),
21089 altKey: os.isOSX(),
21090 action: BoundarySelection.movePrevWord(editor, caret)
21091 },
21092 {
21093 keyCode: VK.UP,
21094 action: moveV$2(editor, false)
21095 },
21096 {
21097 keyCode: VK.DOWN,
21098 action: moveV$2(editor, true)
21099 }
21100 ], evt).each(function (_) {
21101 evt.preventDefault();
21102 });
21103 };
21104 var setup$8 = function (editor, caret) {
21105 editor.on('keydown', function (evt) {
21106 if (evt.isDefaultPrevented() === false) {
21107 executeKeydownOverride(editor, caret, evt);
21108 }
21109 });
21110 };
21111 var ArrowKeys = { setup: setup$8 };
21112
21113 var isBeforeRoot = function (rootNode) {
21114 return function (elm) {
21115 return eq(rootNode, Element.fromDom(elm.dom().parentNode));
21116 };
21117 };
21118 var getParentBlock$1 = function (rootNode, elm) {
21119 return contains$3(rootNode, elm) ? closest(elm, function (element) {
21120 return isTextBlock(element) || isListItem(element);
21121 }, isBeforeRoot(rootNode)) : Option.none();
21122 };
21123 var placeCaretInEmptyBody = function (editor) {
21124 var body = editor.getBody();
21125 var node = body.firstChild && editor.dom.isBlock(body.firstChild) ? body.firstChild : body;
21126 editor.selection.setCursorLocation(node, 0);
21127 };
21128 var paddEmptyBody = function (editor) {
21129 if (editor.dom.isEmpty(editor.getBody())) {
21130 editor.setContent('');
21131 placeCaretInEmptyBody(editor);
21132 }
21133 };
21134 var willDeleteLastPositionInElement = function (forward, fromPos, elm) {
21135 return liftN([
21136 CaretFinder.firstPositionIn(elm),
21137 CaretFinder.lastPositionIn(elm)
21138 ], function (firstPos, lastPos) {
21139 var normalizedFirstPos = InlineUtils.normalizePosition(true, firstPos);
21140 var normalizedLastPos = InlineUtils.normalizePosition(false, lastPos);
21141 var normalizedFromPos = InlineUtils.normalizePosition(false, fromPos);
21142 if (forward) {
21143 return CaretFinder.nextPosition(elm, normalizedFromPos).map(function (nextPos) {
21144 return nextPos.isEqual(normalizedLastPos) && fromPos.isEqual(normalizedFirstPos);
21145 }).getOr(false);
21146 } else {
21147 return CaretFinder.prevPosition(elm, normalizedFromPos).map(function (prevPos) {
21148 return prevPos.isEqual(normalizedFirstPos) && fromPos.isEqual(normalizedLastPos);
21149 }).getOr(false);
21150 }
21151 }).getOr(true);
21152 };
21153 var DeleteUtils = {
21154 getParentBlock: getParentBlock$1,
21155 paddEmptyBody: paddEmptyBody,
21156 willDeleteLastPositionInElement: willDeleteLastPositionInElement
21157 };
21158
21159 var BlockPosition = Immutable('block', 'position');
21160 var BlockBoundary = Immutable('from', 'to');
21161 var getBlockPosition = function (rootNode, pos) {
21162 var rootElm = Element.fromDom(rootNode);
21163 var containerElm = Element.fromDom(pos.container());
21164 return DeleteUtils.getParentBlock(rootElm, containerElm).map(function (block) {
21165 return BlockPosition(block, pos);
21166 });
21167 };
21168 var isDifferentBlocks = function (blockBoundary) {
21169 return eq(blockBoundary.from().block(), blockBoundary.to().block()) === false;
21170 };
21171 var hasSameParent = function (blockBoundary) {
21172 return parent(blockBoundary.from().block()).bind(function (parent1) {
21173 return parent(blockBoundary.to().block()).filter(function (parent2) {
21174 return eq(parent1, parent2);
21175 });
21176 }).isSome();
21177 };
21178 var isEditable = function (blockBoundary) {
21179 return NodeType.isContentEditableFalse(blockBoundary.from().block()) === false && NodeType.isContentEditableFalse(blockBoundary.to().block()) === false;
21180 };
21181 var skipLastBr = function (rootNode, forward, blockPosition) {
21182 if (NodeType.isBr(blockPosition.position().getNode()) && Empty.isEmpty(blockPosition.block()) === false) {
21183 return CaretFinder.positionIn(false, blockPosition.block().dom()).bind(function (lastPositionInBlock) {
21184 if (lastPositionInBlock.isEqual(blockPosition.position())) {
21185 return CaretFinder.fromPosition(forward, rootNode, lastPositionInBlock).bind(function (to) {
21186 return getBlockPosition(rootNode, to);
21187 });
21188 } else {
21189 return Option.some(blockPosition);
21190 }
21191 }).getOr(blockPosition);
21192 } else {
21193 return blockPosition;
21194 }
21195 };
21196 var readFromRange = function (rootNode, forward, rng) {
21197 var fromBlockPos = getBlockPosition(rootNode, CaretPosition$1.fromRangeStart(rng));
21198 var toBlockPos = fromBlockPos.bind(function (blockPos) {
21199 return CaretFinder.fromPosition(forward, rootNode, blockPos.position()).bind(function (to) {
21200 return getBlockPosition(rootNode, to).map(function (blockPos) {
21201 return skipLastBr(rootNode, forward, blockPos);
21202 });
21203 });
21204 });
21205 return liftN([
21206 fromBlockPos,
21207 toBlockPos
21208 ], BlockBoundary).filter(function (blockBoundary) {
21209 return isDifferentBlocks(blockBoundary) && hasSameParent(blockBoundary) && isEditable(blockBoundary);
21210 });
21211 };
21212 var read$3 = function (rootNode, forward, rng) {
21213 return rng.collapsed ? readFromRange(rootNode, forward, rng) : Option.none();
21214 };
21215 var BlockMergeBoundary = { read: read$3 };
21216
21217 var getChildrenUntilBlockBoundary = function (block) {
21218 var children$1 = children(block);
21219 return findIndex(children$1, isBlock).fold(function () {
21220 return children$1;
21221 }, function (index) {
21222 return children$1.slice(0, index);
21223 });
21224 };
21225 var extractChildren = function (block) {
21226 var children = getChildrenUntilBlockBoundary(block);
21227 each(children, remove$1);
21228 return children;
21229 };
21230 var removeEmptyRoot = function (rootNode, block) {
21231 var parents = Parents.parentsAndSelf(block, rootNode);
21232 return find(parents.reverse(), Empty.isEmpty).each(remove$1);
21233 };
21234 var isEmptyBefore = function (el) {
21235 return filter(prevSiblings(el), function (el) {
21236 return !Empty.isEmpty(el);
21237 }).length === 0;
21238 };
21239 var nestedBlockMerge = function (rootNode, fromBlock, toBlock, insertionPoint) {
21240 if (Empty.isEmpty(toBlock)) {
21241 PaddingBr.fillWithPaddingBr(toBlock);
21242 return CaretFinder.firstPositionIn(toBlock.dom());
21243 }
21244 if (isEmptyBefore(insertionPoint) && Empty.isEmpty(fromBlock)) {
21245 before(insertionPoint, Element.fromTag('br'));
21246 }
21247 var position = CaretFinder.prevPosition(toBlock.dom(), CaretPosition$1.before(insertionPoint.dom()));
21248 each(extractChildren(fromBlock), function (child) {
21249 before(insertionPoint, child);
21250 });
21251 removeEmptyRoot(rootNode, fromBlock);
21252 return position;
21253 };
21254 var sidelongBlockMerge = function (rootNode, fromBlock, toBlock) {
21255 if (Empty.isEmpty(toBlock)) {
21256 remove$1(toBlock);
21257 if (Empty.isEmpty(fromBlock)) {
21258 PaddingBr.fillWithPaddingBr(fromBlock);
21259 }
21260 return CaretFinder.firstPositionIn(fromBlock.dom());
21261 }
21262 var position = CaretFinder.lastPositionIn(toBlock.dom());
21263 each(extractChildren(fromBlock), function (child) {
21264 append(toBlock, child);
21265 });
21266 removeEmptyRoot(rootNode, fromBlock);
21267 return position;
21268 };
21269 var findInsertionPoint = function (toBlock, block) {
21270 var parentsAndSelf = Parents.parentsAndSelf(block, toBlock);
21271 return Option.from(parentsAndSelf[parentsAndSelf.length - 1]);
21272 };
21273 var getInsertionPoint = function (fromBlock, toBlock) {
21274 return contains$3(toBlock, fromBlock) ? findInsertionPoint(toBlock, fromBlock) : Option.none();
21275 };
21276 var trimBr = function (first, block) {
21277 CaretFinder.positionIn(first, block.dom()).map(function (position) {
21278 return position.getNode();
21279 }).map(Element.fromDom).filter(isBr$1).each(remove$1);
21280 };
21281 var mergeBlockInto = function (rootNode, fromBlock, toBlock) {
21282 trimBr(true, fromBlock);
21283 trimBr(false, toBlock);
21284 return getInsertionPoint(fromBlock, toBlock).fold(curry(sidelongBlockMerge, rootNode, fromBlock, toBlock), curry(nestedBlockMerge, rootNode, fromBlock, toBlock));
21285 };
21286 var mergeBlocks = function (rootNode, forward, block1, block2) {
21287 return forward ? mergeBlockInto(rootNode, block2, block1) : mergeBlockInto(rootNode, block1, block2);
21288 };
21289 var MergeBlocks = { mergeBlocks: mergeBlocks };
21290
21291 var backspaceDelete = function (editor, forward) {
21292 var position;
21293 var rootNode = Element.fromDom(editor.getBody());
21294 position = BlockMergeBoundary.read(rootNode.dom(), forward, editor.selection.getRng()).bind(function (blockBoundary) {
21295 return MergeBlocks.mergeBlocks(rootNode, forward, blockBoundary.from().block(), blockBoundary.to().block());
21296 });
21297 position.each(function (pos) {
21298 editor.selection.setRng(pos.toRange());
21299 });
21300 return position.isSome();
21301 };
21302 var BlockBoundaryDelete = { backspaceDelete: backspaceDelete };
21303
21304 var deleteRangeMergeBlocks = function (rootNode, selection) {
21305 var rng = selection.getRng();
21306 return liftN([
21307 DeleteUtils.getParentBlock(rootNode, Element.fromDom(rng.startContainer)),
21308 DeleteUtils.getParentBlock(rootNode, Element.fromDom(rng.endContainer))
21309 ], function (block1, block2) {
21310 if (eq(block1, block2) === false) {
21311 rng.deleteContents();
21312 MergeBlocks.mergeBlocks(rootNode, true, block1, block2).each(function (pos) {
21313 selection.setRng(pos.toRange());
21314 });
21315 return true;
21316 } else {
21317 return false;
21318 }
21319 }).getOr(false);
21320 };
21321 var isRawNodeInTable = function (root, rawNode) {
21322 var node = Element.fromDom(rawNode);
21323 var isRoot = curry(eq, root);
21324 return ancestor(node, isTableCell, isRoot).isSome();
21325 };
21326 var isSelectionInTable = function (root, rng) {
21327 return isRawNodeInTable(root, rng.startContainer) || isRawNodeInTable(root, rng.endContainer);
21328 };
21329 var isEverythingSelected = function (root, rng) {
21330 var noPrevious = CaretFinder.prevPosition(root.dom(), CaretPosition$1.fromRangeStart(rng)).isNone();
21331 var noNext = CaretFinder.nextPosition(root.dom(), CaretPosition$1.fromRangeEnd(rng)).isNone();
21332 return !isSelectionInTable(root, rng) && noPrevious && noNext;
21333 };
21334 var emptyEditor = function (editor) {
21335 editor.setContent('');
21336 editor.selection.setCursorLocation();
21337 return true;
21338 };
21339 var deleteRange = function (editor) {
21340 var rootNode = Element.fromDom(editor.getBody());
21341 var rng = editor.selection.getRng();
21342 return isEverythingSelected(rootNode, rng) ? emptyEditor(editor) : deleteRangeMergeBlocks(rootNode, editor.selection);
21343 };
21344 var backspaceDelete$1 = function (editor, forward) {
21345 return editor.selection.isCollapsed() ? false : deleteRange(editor);
21346 };
21347 var BlockRangeDelete = { backspaceDelete: backspaceDelete$1 };
21348
21349 var isBr$5 = function (pos) {
21350 return getElementFromPosition(pos).exists(isBr$1);
21351 };
21352 var findBr = function (forward, root, pos) {
21353 var parentBlocks = filter(Parents.parentsAndSelf(Element.fromDom(pos.container()), root), isBlock);
21354 var scope = head(parentBlocks).getOr(root);
21355 return CaretFinder.fromPosition(forward, scope.dom(), pos).filter(isBr$5);
21356 };
21357 var isBeforeBr = function (root, pos) {
21358 return getElementFromPosition(pos).exists(isBr$1) || findBr(true, root, pos).isSome();
21359 };
21360 var isAfterBr = function (root, pos) {
21361 return getElementFromPrevPosition(pos).exists(isBr$1) || findBr(false, root, pos).isSome();
21362 };
21363 var findPreviousBr = curry(findBr, false);
21364 var findNextBr = curry(findBr, true);
21365
21366 var isCompoundElement = function (node) {
21367 return isTableCell(Element.fromDom(node)) || isListItem(Element.fromDom(node));
21368 };
21369 var DeleteAction = Adt.generate([
21370 { remove: ['element'] },
21371 { moveToElement: ['element'] },
21372 { moveToPosition: ['position'] }
21373 ]);
21374 var isAtContentEditableBlockCaret = function (forward, from) {
21375 var elm = from.getNode(forward === false);
21376 var caretLocation = forward ? 'after' : 'before';
21377 return NodeType.isElement(elm) && elm.getAttribute('data-mce-caret') === caretLocation;
21378 };
21379 var isDeleteFromCefDifferentBlocks = function (root, forward, from, to) {
21380 var inSameBlock = function (elm) {
21381 return isInline(Element.fromDom(elm)) && !isInSameBlock(from, to, root);
21382 };
21383 return getRelativeCefElm(!forward, from).fold(function () {
21384 return getRelativeCefElm(forward, to).fold(constant(false), inSameBlock);
21385 }, inSameBlock);
21386 };
21387 var deleteEmptyBlockOrMoveToCef = function (root, forward, from, to) {
21388 var toCefElm = to.getNode(forward === false);
21389 return DeleteUtils.getParentBlock(Element.fromDom(root), Element.fromDom(from.getNode())).map(function (blockElm) {
21390 return Empty.isEmpty(blockElm) ? DeleteAction.remove(blockElm.dom()) : DeleteAction.moveToElement(toCefElm);
21391 }).orThunk(function () {
21392 return Option.some(DeleteAction.moveToElement(toCefElm));
21393 });
21394 };
21395 var findCefPosition = function (root, forward, from) {
21396 return CaretFinder.fromPosition(forward, root, from).bind(function (to) {
21397 if (isCompoundElement(to.getNode())) {
21398 return Option.none();
21399 } else if (isDeleteFromCefDifferentBlocks(root, forward, from, to)) {
21400 return Option.none();
21401 } else if (forward && NodeType.isContentEditableFalse(to.getNode())) {
21402 return deleteEmptyBlockOrMoveToCef(root, forward, from, to);
21403 } else if (forward === false && NodeType.isContentEditableFalse(to.getNode(true))) {
21404 return deleteEmptyBlockOrMoveToCef(root, forward, from, to);
21405 } else if (forward && isAfterContentEditableFalse(from)) {
21406 return Option.some(DeleteAction.moveToPosition(to));
21407 } else if (forward === false && isBeforeContentEditableFalse(from)) {
21408 return Option.some(DeleteAction.moveToPosition(to));
21409 } else {
21410 return Option.none();
21411 }
21412 });
21413 };
21414 var getContentEditableBlockAction = function (forward, elm) {
21415 if (forward && NodeType.isContentEditableFalse(elm.nextSibling)) {
21416 return Option.some(DeleteAction.moveToElement(elm.nextSibling));
21417 } else if (forward === false && NodeType.isContentEditableFalse(elm.previousSibling)) {
21418 return Option.some(DeleteAction.moveToElement(elm.previousSibling));
21419 } else {
21420 return Option.none();
21421 }
21422 };
21423 var skipMoveToActionFromInlineCefToContent = function (root, from, deleteAction) {
21424 return deleteAction.fold(function (elm) {
21425 return Option.some(DeleteAction.remove(elm));
21426 }, function (elm) {
21427 return Option.some(DeleteAction.moveToElement(elm));
21428 }, function (to) {
21429 if (isInSameBlock(from, to, root)) {
21430 return Option.none();
21431 } else {
21432 return Option.some(DeleteAction.moveToPosition(to));
21433 }
21434 });
21435 };
21436 var getContentEditableAction = function (root, forward, from) {
21437 if (isAtContentEditableBlockCaret(forward, from)) {
21438 return getContentEditableBlockAction(forward, from.getNode(forward === false)).fold(function () {
21439 return findCefPosition(root, forward, from);
21440 }, Option.some);
21441 } else {
21442 return findCefPosition(root, forward, from).bind(function (deleteAction) {
21443 return skipMoveToActionFromInlineCefToContent(root, from, deleteAction);
21444 });
21445 }
21446 };
21447 var read$4 = function (root, forward, rng) {
21448 var normalizedRange = normalizeRange(forward ? 1 : -1, root, rng);
21449 var from = CaretPosition$1.fromRangeStart(normalizedRange);
21450 var rootElement = Element.fromDom(root);
21451 if (forward === false && isAfterContentEditableFalse(from)) {
21452 return Option.some(DeleteAction.remove(from.getNode(true)));
21453 } else if (forward && isBeforeContentEditableFalse(from)) {
21454 return Option.some(DeleteAction.remove(from.getNode()));
21455 } else if (forward === false && isBeforeContentEditableFalse(from) && isAfterBr(rootElement, from)) {
21456 return findPreviousBr(rootElement, from).map(function (br) {
21457 return DeleteAction.remove(br.getNode());
21458 });
21459 } else if (forward && isAfterContentEditableFalse(from) && isBeforeBr(rootElement, from)) {
21460 return findNextBr(rootElement, from).map(function (br) {
21461 return DeleteAction.remove(br.getNode());
21462 });
21463 } else {
21464 return getContentEditableAction(root, forward, from);
21465 }
21466 };
21467
21468 var deleteElement$1 = function (editor, forward) {
21469 return function (element) {
21470 editor._selectionOverrides.hideFakeCaret();
21471 DeleteElement.deleteElement(editor, forward, Element.fromDom(element));
21472 return true;
21473 };
21474 };
21475 var moveToElement = function (editor, forward) {
21476 return function (element) {
21477 var pos = forward ? CaretPosition$1.before(element) : CaretPosition$1.after(element);
21478 editor.selection.setRng(pos.toRange());
21479 return true;
21480 };
21481 };
21482 var moveToPosition = function (editor) {
21483 return function (pos) {
21484 editor.selection.setRng(pos.toRange());
21485 return true;
21486 };
21487 };
21488 var backspaceDeleteCaret = function (editor, forward) {
21489 var result = read$4(editor.getBody(), forward, editor.selection.getRng()).map(function (deleteAction) {
21490 return deleteAction.fold(deleteElement$1(editor, forward), moveToElement(editor, forward), moveToPosition(editor));
21491 });
21492 return result.getOr(false);
21493 };
21494 var deleteOffscreenSelection = function (rootElement) {
21495 each(descendants$1(rootElement, '.mce-offscreen-selection'), remove$1);
21496 };
21497 var backspaceDeleteRange = function (editor, forward) {
21498 var selectedElement = editor.selection.getNode();
21499 if (NodeType.isContentEditableFalse(selectedElement)) {
21500 deleteOffscreenSelection(Element.fromDom(editor.getBody()));
21501 DeleteElement.deleteElement(editor, forward, Element.fromDom(editor.selection.getNode()));
21502 DeleteUtils.paddEmptyBody(editor);
21503 return true;
21504 } else {
21505 return false;
21506 }
21507 };
21508 var getContentEditableRoot$2 = function (root, node) {
21509 while (node && node !== root) {
21510 if (NodeType.isContentEditableTrue(node) || NodeType.isContentEditableFalse(node)) {
21511 return node;
21512 }
21513 node = node.parentNode;
21514 }
21515 return null;
21516 };
21517 var paddEmptyElement = function (editor) {
21518 var br;
21519 var ceRoot = getContentEditableRoot$2(editor.getBody(), editor.selection.getNode());
21520 if (NodeType.isContentEditableTrue(ceRoot) && editor.dom.isBlock(ceRoot) && editor.dom.isEmpty(ceRoot)) {
21521 br = editor.dom.create('br', { 'data-mce-bogus': '1' });
21522 editor.dom.setHTML(ceRoot, '');
21523 ceRoot.appendChild(br);
21524 editor.selection.setRng(CaretPosition$1.before(br).toRange());
21525 }
21526 return true;
21527 };
21528 var backspaceDelete$2 = function (editor, forward) {
21529 if (editor.selection.isCollapsed()) {
21530 return backspaceDeleteCaret(editor, forward);
21531 } else {
21532 return backspaceDeleteRange(editor, forward);
21533 }
21534 };
21535 var CefDelete = {
21536 backspaceDelete: backspaceDelete$2,
21537 paddEmptyElement: paddEmptyElement
21538 };
21539
21540 var trimEmptyTextNode$1 = function (dom, node) {
21541 if (NodeType.isText(node) && node.data.length === 0) {
21542 dom.remove(node);
21543 }
21544 };
21545 var deleteContentAndShowCaret = function (editor, range, node, direction, forward, peekCaretPosition) {
21546 var caretRange = showCaret(direction, editor, peekCaretPosition.getNode(!forward), forward, true);
21547 if (range.collapsed) {
21548 var deleteRange = range.cloneRange();
21549 if (forward) {
21550 deleteRange.setEnd(caretRange.startContainer, caretRange.startOffset);
21551 } else {
21552 deleteRange.setStart(caretRange.endContainer, caretRange.endOffset);
21553 }
21554 deleteRange.deleteContents();
21555 } else {
21556 range.deleteContents();
21557 }
21558 editor.selection.setRng(caretRange);
21559 trimEmptyTextNode$1(editor.dom, node);
21560 return true;
21561 };
21562 var deleteCefBoundaryText = function (editor, forward) {
21563 var range = editor.selection.getRng();
21564 if (!NodeType.isText(range.commonAncestorContainer)) {
21565 return false;
21566 }
21567 var direction = forward ? HDirection.Forwards : HDirection.Backwards;
21568 var caretWalker = CaretWalker(editor.getBody());
21569 var getNextVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.next);
21570 var getPrevVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.prev);
21571 var getNextPosFn = forward ? getNextVisualCaretPosition : getPrevVisualCaretPosition;
21572 var isBeforeContentEditableFalseFn = forward ? isBeforeContentEditableFalse : isAfterContentEditableFalse;
21573 var caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range);
21574 var nextCaretPosition = InlineUtils.normalizePosition(forward, getNextPosFn(caretPosition));
21575 if (!nextCaretPosition) {
21576 return false;
21577 } else if (isBeforeContentEditableFalseFn(nextCaretPosition)) {
21578 return deleteContentAndShowCaret(editor, range, caretPosition.getNode(), direction, forward, nextCaretPosition);
21579 }
21580 var peekCaretPosition = getNextPosFn(nextCaretPosition);
21581 if (peekCaretPosition && isBeforeContentEditableFalseFn(peekCaretPosition)) {
21582 if (isMoveInsideSameBlock(nextCaretPosition, peekCaretPosition)) {
21583 return deleteContentAndShowCaret(editor, range, caretPosition.getNode(), direction, forward, peekCaretPosition);
21584 }
21585 }
21586 return false;
21587 };
21588 var backspaceDelete$3 = function (editor, forward) {
21589 return deleteCefBoundaryText(editor, forward);
21590 };
21591 var CefBoundaryDelete = { backspaceDelete: backspaceDelete$3 };
21592
21593 var isFeatureEnabled$1 = function (editor) {
21594 return editor.settings.inline_boundaries !== false;
21595 };
21596 var rangeFromPositions = function (from, to) {
21597 var range = domGlobals.document.createRange();
21598 range.setStart(from.container(), from.offset());
21599 range.setEnd(to.container(), to.offset());
21600 return range;
21601 };
21602 var hasOnlyTwoOrLessPositionsLeft = function (elm) {
21603 return liftN([
21604 CaretFinder.firstPositionIn(elm),
21605 CaretFinder.lastPositionIn(elm)
21606 ], function (firstPos, lastPos) {
21607 var normalizedFirstPos = InlineUtils.normalizePosition(true, firstPos);
21608 var normalizedLastPos = InlineUtils.normalizePosition(false, lastPos);
21609 return CaretFinder.nextPosition(elm, normalizedFirstPos).map(function (pos) {
21610 return pos.isEqual(normalizedLastPos);
21611 }).getOr(true);
21612 }).getOr(true);
21613 };
21614 var setCaretLocation = function (editor, caret) {
21615 return function (location) {
21616 return BoundaryCaret.renderCaret(caret, location).map(function (pos) {
21617 BoundarySelection.setCaretPosition(editor, pos);
21618 return true;
21619 }).getOr(false);
21620 };
21621 };
21622 var deleteFromTo = function (editor, caret, from, to) {
21623 var rootNode = editor.getBody();
21624 var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);
21625 editor.undoManager.ignore(function () {
21626 editor.selection.setRng(rangeFromPositions(from, to));
21627 editor.execCommand('Delete');
21628 BoundaryLocation.readLocation(isInlineTarget, rootNode, CaretPosition$1.fromRangeStart(editor.selection.getRng())).map(BoundaryLocation.inside).map(setCaretLocation(editor, caret));
21629 });
21630 editor.nodeChanged();
21631 };
21632 var rescope$1 = function (rootNode, node) {
21633 var parentBlock = getParentBlock(node, rootNode);
21634 return parentBlock ? parentBlock : rootNode;
21635 };
21636 var backspaceDeleteCollapsed = function (editor, caret, forward, from) {
21637 var rootNode = rescope$1(editor.getBody(), from.container());
21638 var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);
21639 var fromLocation = BoundaryLocation.readLocation(isInlineTarget, rootNode, from);
21640 return fromLocation.bind(function (location) {
21641 if (forward) {
21642 return location.fold(constant(Option.some(BoundaryLocation.inside(location))), Option.none, constant(Option.some(BoundaryLocation.outside(location))), Option.none);
21643 } else {
21644 return location.fold(Option.none, constant(Option.some(BoundaryLocation.outside(location))), Option.none, constant(Option.some(BoundaryLocation.inside(location))));
21645 }
21646 }).map(setCaretLocation(editor, caret)).getOrThunk(function () {
21647 var toPosition = CaretFinder.navigate(forward, rootNode, from);
21648 var toLocation = toPosition.bind(function (pos) {
21649 return BoundaryLocation.readLocation(isInlineTarget, rootNode, pos);
21650 });
21651 if (fromLocation.isSome() && toLocation.isSome()) {
21652 return InlineUtils.findRootInline(isInlineTarget, rootNode, from).map(function (elm) {
21653 if (hasOnlyTwoOrLessPositionsLeft(elm)) {
21654 DeleteElement.deleteElement(editor, forward, Element.fromDom(elm));
21655 return true;
21656 } else {
21657 return false;
21658 }
21659 }).getOr(false);
21660 } else {
21661 return toLocation.bind(function (_) {
21662 return toPosition.map(function (to) {
21663 if (forward) {
21664 deleteFromTo(editor, caret, from, to);
21665 } else {
21666 deleteFromTo(editor, caret, to, from);
21667 }
21668 return true;
21669 });
21670 }).getOr(false);
21671 }
21672 });
21673 };
21674 var backspaceDelete$4 = function (editor, caret, forward) {
21675 if (editor.selection.isCollapsed() && isFeatureEnabled$1(editor)) {
21676 var from = CaretPosition$1.fromRangeStart(editor.selection.getRng());
21677 return backspaceDeleteCollapsed(editor, caret, forward, from);
21678 }
21679 return false;
21680 };
21681 var BoundaryDelete = { backspaceDelete: backspaceDelete$4 };
21682
21683 var getParentInlines = function (rootElm, startElm) {
21684 var parents = Parents.parentsAndSelf(startElm, rootElm);
21685 return findIndex(parents, isBlock).fold(constant(parents), function (index) {
21686 return parents.slice(0, index);
21687 });
21688 };
21689 var hasOnlyOneChild = function (elm) {
21690 return children(elm).length === 1;
21691 };
21692 var deleteLastPosition = function (forward, editor, target, parentInlines) {
21693 var isFormatElement$1 = curry(isFormatElement, editor);
21694 var formatNodes = map(filter(parentInlines, isFormatElement$1), function (elm) {
21695 return elm.dom();
21696 });
21697 if (formatNodes.length === 0) {
21698 DeleteElement.deleteElement(editor, forward, target);
21699 } else {
21700 var pos = replaceWithCaretFormat(target.dom(), formatNodes);
21701 editor.selection.setRng(pos.toRange());
21702 }
21703 };
21704 var deleteCaret = function (editor, forward) {
21705 var rootElm = Element.fromDom(editor.getBody());
21706 var startElm = Element.fromDom(editor.selection.getStart());
21707 var parentInlines = filter(getParentInlines(rootElm, startElm), hasOnlyOneChild);
21708 return last(parentInlines).map(function (target) {
21709 var fromPos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
21710 if (DeleteUtils.willDeleteLastPositionInElement(forward, fromPos, target.dom()) && !isEmptyCaretFormatElement(target)) {
21711 deleteLastPosition(forward, editor, target, parentInlines);
21712 return true;
21713 } else {
21714 return false;
21715 }
21716 }).getOr(false);
21717 };
21718 var backspaceDelete$5 = function (editor, forward) {
21719 return editor.selection.isCollapsed() ? deleteCaret(editor, forward) : false;
21720 };
21721 var InlineFormatDelete = { backspaceDelete: backspaceDelete$5 };
21722
21723 var tableCellRng = Immutable('start', 'end');
21724 var tableSelection = Immutable('rng', 'table', 'cells');
21725 var deleteAction = Adt.generate([
21726 { removeTable: ['element'] },
21727 { emptyCells: ['cells'] }
21728 ]);
21729 var isRootFromElement = function (root) {
21730 return curry(eq, root);
21731 };
21732 var getClosestCell$1 = function (container, isRoot) {
21733 return closest$1(Element.fromDom(container), 'td,th', isRoot);
21734 };
21735 var getClosestTable = function (cell, isRoot) {
21736 return ancestor$1(cell, 'table', isRoot);
21737 };
21738 var isExpandedCellRng = function (cellRng) {
21739 return eq(cellRng.start(), cellRng.end()) === false;
21740 };
21741 var getTableFromCellRng = function (cellRng, isRoot) {
21742 return getClosestTable(cellRng.start(), isRoot).bind(function (startParentTable) {
21743 return getClosestTable(cellRng.end(), isRoot).bind(function (endParentTable) {
21744 return eq(startParentTable, endParentTable) ? Option.some(startParentTable) : Option.none();
21745 });
21746 });
21747 };
21748 var getTableCells = function (table) {
21749 return descendants$1(table, 'td,th');
21750 };
21751 var getCellRangeFromStartTable = function (cellRng, isRoot) {
21752 return getClosestTable(cellRng.start(), isRoot).bind(function (table) {
21753 return last(getTableCells(table)).map(function (endCell) {
21754 return tableCellRng(cellRng.start(), endCell);
21755 });
21756 });
21757 };
21758 var partialSelection = function (isRoot, rng) {
21759 var startCell = getClosestCell$1(rng.startContainer, isRoot);
21760 var endCell = getClosestCell$1(rng.endContainer, isRoot);
21761 return rng.collapsed ? Option.none() : liftN([
21762 startCell,
21763 endCell
21764 ], tableCellRng).fold(function () {
21765 return startCell.fold(function () {
21766 return endCell.bind(function (endCell) {
21767 return getClosestTable(endCell, isRoot).bind(function (table) {
21768 return head(getTableCells(table)).map(function (startCell) {
21769 return tableCellRng(startCell, endCell);
21770 });
21771 });
21772 });
21773 }, function (startCell) {
21774 return getClosestTable(startCell, isRoot).bind(function (table) {
21775 return last(getTableCells(table)).map(function (endCell) {
21776 return tableCellRng(startCell, endCell);
21777 });
21778 });
21779 });
21780 }, function (cellRng) {
21781 return isWithinSameTable(isRoot, cellRng) ? Option.none() : getCellRangeFromStartTable(cellRng, isRoot);
21782 });
21783 };
21784 var isWithinSameTable = function (isRoot, cellRng) {
21785 return getTableFromCellRng(cellRng, isRoot).isSome();
21786 };
21787 var getCellRng = function (rng, isRoot) {
21788 var startCell = getClosestCell$1(rng.startContainer, isRoot);
21789 var endCell = getClosestCell$1(rng.endContainer, isRoot);
21790 return liftN([
21791 startCell,
21792 endCell
21793 ], tableCellRng).filter(isExpandedCellRng).filter(function (cellRng) {
21794 return isWithinSameTable(isRoot, cellRng);
21795 }).orThunk(function () {
21796 return partialSelection(isRoot, rng);
21797 });
21798 };
21799 var getTableSelectionFromCellRng = function (cellRng, isRoot) {
21800 return getTableFromCellRng(cellRng, isRoot).map(function (table) {
21801 return tableSelection(cellRng, table, getTableCells(table));
21802 });
21803 };
21804 var getTableSelectionFromRng = function (root, rng) {
21805 var isRoot = isRootFromElement(root);
21806 return getCellRng(rng, isRoot).bind(function (cellRng) {
21807 return getTableSelectionFromCellRng(cellRng, isRoot);
21808 });
21809 };
21810 var getCellIndex = function (cells, cell) {
21811 return findIndex(cells, function (x) {
21812 return eq(x, cell);
21813 });
21814 };
21815 var getSelectedCells = function (tableSelection) {
21816 return liftN([
21817 getCellIndex(tableSelection.cells(), tableSelection.rng().start()),
21818 getCellIndex(tableSelection.cells(), tableSelection.rng().end())
21819 ], function (startIndex, endIndex) {
21820 return tableSelection.cells().slice(startIndex, endIndex + 1);
21821 });
21822 };
21823 var getAction = function (tableSelection) {
21824 return getSelectedCells(tableSelection).map(function (selected) {
21825 var cells = tableSelection.cells();
21826 return selected.length === cells.length ? deleteAction.removeTable(tableSelection.table()) : deleteAction.emptyCells(selected);
21827 });
21828 };
21829 var getActionFromCells = function (cells) {
21830 return deleteAction.emptyCells(cells);
21831 };
21832 var getActionFromRange = function (root, rng) {
21833 return getTableSelectionFromRng(root, rng).bind(getAction);
21834 };
21835 var TableDeleteAction = {
21836 getActionFromRange: getActionFromRange,
21837 getActionFromCells: getActionFromCells
21838 };
21839
21840 var emptyCells = function (editor, cells) {
21841 each(cells, PaddingBr.fillWithPaddingBr);
21842 editor.selection.setCursorLocation(cells[0].dom(), 0);
21843 return true;
21844 };
21845 var deleteTableElement = function (editor, table) {
21846 DeleteElement.deleteElement(editor, false, table);
21847 return true;
21848 };
21849 var deleteCellRange = function (editor, rootElm, rng) {
21850 return TableDeleteAction.getActionFromRange(rootElm, rng).map(function (action) {
21851 return action.fold(curry(deleteTableElement, editor), curry(emptyCells, editor));
21852 });
21853 };
21854 var deleteCaptionRange = function (editor, caption) {
21855 return emptyElement(editor, caption);
21856 };
21857 var deleteTableRange = function (editor, rootElm, rng, startElm) {
21858 return getParentCaption(rootElm, startElm).fold(function () {
21859 return deleteCellRange(editor, rootElm, rng);
21860 }, function (caption) {
21861 return deleteCaptionRange(editor, caption);
21862 }).getOr(false);
21863 };
21864 var deleteRange$1 = function (editor, startElm) {
21865 var rootNode = Element.fromDom(editor.getBody());
21866 var rng = editor.selection.getRng();
21867 var selectedCells = TableCellSelection.getCellsFromEditor(editor);
21868 return selectedCells.length !== 0 ? emptyCells(editor, selectedCells) : deleteTableRange(editor, rootNode, rng, startElm);
21869 };
21870 var getParentCell = function (rootElm, elm) {
21871 return find(Parents.parentsAndSelf(elm, rootElm), isTableCell);
21872 };
21873 var getParentCaption = function (rootElm, elm) {
21874 return find(Parents.parentsAndSelf(elm, rootElm), function (elm) {
21875 return name(elm) === 'caption';
21876 });
21877 };
21878 var deleteBetweenCells = function (editor, rootElm, forward, fromCell, from) {
21879 return CaretFinder.navigate(forward, editor.getBody(), from).bind(function (to) {
21880 return getParentCell(rootElm, Element.fromDom(to.getNode())).map(function (toCell) {
21881 return eq(toCell, fromCell) === false;
21882 });
21883 });
21884 };
21885 var emptyElement = function (editor, elm) {
21886 PaddingBr.fillWithPaddingBr(elm);
21887 editor.selection.setCursorLocation(elm.dom(), 0);
21888 return Option.some(true);
21889 };
21890 var isDeleteOfLastCharPos = function (fromCaption, forward, from, to) {
21891 return CaretFinder.firstPositionIn(fromCaption.dom()).bind(function (first) {
21892 return CaretFinder.lastPositionIn(fromCaption.dom()).map(function (last) {
21893 return forward ? from.isEqual(first) && to.isEqual(last) : from.isEqual(last) && to.isEqual(first);
21894 });
21895 }).getOr(true);
21896 };
21897 var emptyCaretCaption = function (editor, elm) {
21898 return emptyElement(editor, elm);
21899 };
21900 var validateCaretCaption = function (rootElm, fromCaption, to) {
21901 return getParentCaption(rootElm, Element.fromDom(to.getNode())).map(function (toCaption) {
21902 return eq(toCaption, fromCaption) === false;
21903 });
21904 };
21905 var deleteCaretInsideCaption = function (editor, rootElm, forward, fromCaption, from) {
21906 return CaretFinder.navigate(forward, editor.getBody(), from).bind(function (to) {
21907 return isDeleteOfLastCharPos(fromCaption, forward, from, to) ? emptyCaretCaption(editor, fromCaption) : validateCaretCaption(rootElm, fromCaption, to);
21908 }).or(Option.some(true));
21909 };
21910 var deleteCaretCells = function (editor, forward, rootElm, startElm) {
21911 var from = CaretPosition$1.fromRangeStart(editor.selection.getRng());
21912 return getParentCell(rootElm, startElm).bind(function (fromCell) {
21913 return Empty.isEmpty(fromCell) ? emptyElement(editor, fromCell) : deleteBetweenCells(editor, rootElm, forward, fromCell, from);
21914 }).getOr(false);
21915 };
21916 var deleteCaretCaption = function (editor, forward, rootElm, fromCaption) {
21917 var from = CaretPosition$1.fromRangeStart(editor.selection.getRng());
21918 return Empty.isEmpty(fromCaption) ? emptyElement(editor, fromCaption) : deleteCaretInsideCaption(editor, rootElm, forward, fromCaption, from);
21919 };
21920 var isNearTable = function (forward, pos) {
21921 return forward ? isBeforeTable(pos) : isAfterTable(pos);
21922 };
21923 var isBeforeOrAfterTable = function (editor, forward) {
21924 var fromPos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
21925 return isNearTable(forward, fromPos) || CaretFinder.fromPosition(forward, editor.getBody(), fromPos).map(function (pos) {
21926 return isNearTable(forward, pos);
21927 }).getOr(false);
21928 };
21929 var deleteCaret$1 = function (editor, forward, startElm) {
21930 var rootElm = Element.fromDom(editor.getBody());
21931 return getParentCaption(rootElm, startElm).fold(function () {
21932 return deleteCaretCells(editor, forward, rootElm, startElm) || isBeforeOrAfterTable(editor, forward);
21933 }, function (fromCaption) {
21934 return deleteCaretCaption(editor, forward, rootElm, fromCaption).getOr(false);
21935 });
21936 };
21937 var backspaceDelete$6 = function (editor, forward) {
21938 var startElm = Element.fromDom(editor.selection.getStart(true));
21939 var cells = TableCellSelection.getCellsFromEditor(editor);
21940 return editor.selection.isCollapsed() && cells.length === 0 ? deleteCaret$1(editor, forward, startElm) : deleteRange$1(editor, startElm);
21941 };
21942 var TableDelete = { backspaceDelete: backspaceDelete$6 };
21943
21944 var deleteCaret$2 = function (editor, forward) {
21945 var fromPos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
21946 return CaretFinder.fromPosition(forward, editor.getBody(), fromPos).filter(function (pos) {
21947 return forward ? isBeforeImageBlock(pos) : isAfterImageBlock(pos);
21948 }).bind(function (pos) {
21949 return Option.from(getChildNodeAtRelativeOffset(forward ? 0 : -1, pos));
21950 }).map(function (elm) {
21951 editor.selection.select(elm);
21952 return true;
21953 }).getOr(false);
21954 };
21955 var backspaceDelete$7 = function (editor, forward) {
21956 return editor.selection.isCollapsed() ? deleteCaret$2(editor, forward) : false;
21957 };
21958 var PageBreakDelete = { backspaceDelete: backspaceDelete$7 };
21959
21960 var isEditable$1 = function (target) {
21961 return closest(target, function (elm) {
21962 return NodeType.isContentEditableTrue(elm.dom()) || NodeType.isContentEditableFalse(elm.dom());
21963 }).exists(function (elm) {
21964 return NodeType.isContentEditableTrue(elm.dom());
21965 });
21966 };
21967 var parseIndentValue = function (value) {
21968 var number = parseInt(value, 10);
21969 return isNaN(number) ? 0 : number;
21970 };
21971 var getIndentStyleName = function (useMargin, element) {
21972 var indentStyleName = useMargin || isTable$1(element) ? 'margin' : 'padding';
21973 var suffix = get$2(element, 'direction') === 'rtl' ? '-right' : '-left';
21974 return indentStyleName + suffix;
21975 };
21976 var indentElement = function (dom, command, useMargin, value, unit, element) {
21977 var indentStyleName = getIndentStyleName(useMargin, Element.fromDom(element));
21978 if (command === 'outdent') {
21979 var styleValue = Math.max(0, parseIndentValue(element.style[indentStyleName]) - value);
21980 dom.setStyle(element, indentStyleName, styleValue ? styleValue + unit : '');
21981 } else {
21982 var styleValue = parseIndentValue(element.style[indentStyleName]) + value + unit;
21983 dom.setStyle(element, indentStyleName, styleValue);
21984 }
21985 };
21986 var validateBlocks = function (editor, blocks) {
21987 return forall(blocks, function (block) {
21988 var indentStyleName = getIndentStyleName(Settings.shouldIndentUseMargin(editor), block);
21989 var intentValue = getRaw(block, indentStyleName).map(parseIndentValue).getOr(0);
21990 var contentEditable = editor.dom.getContentEditable(block.dom());
21991 return contentEditable !== 'false' && intentValue > 0;
21992 });
21993 };
21994 var canOutdent = function (editor) {
21995 var blocks = getBlocksToIndent(editor);
21996 return editor.readonly !== true && (blocks.length > 1 || validateBlocks(editor, blocks));
21997 };
21998 var isListComponent = function (el) {
21999 return isList(el) || isListItem(el);
22000 };
22001 var parentIsListComponent = function (el) {
22002 return parent(el).map(isListComponent).getOr(false);
22003 };
22004 var getBlocksToIndent = function (editor) {
22005 return filter(map(editor.selection.getSelectedBlocks(), Element.fromDom), function (el) {
22006 return !isListComponent(el) && !parentIsListComponent(el) && isEditable$1(el);
22007 });
22008 };
22009 var handle = function (editor, command) {
22010 var dom = editor.dom, selection = editor.selection, formatter = editor.formatter;
22011 var indentation = Settings.getIndentation(editor);
22012 var indentUnit = /[a-z%]+$/i.exec(indentation)[0];
22013 var indentValue = parseInt(indentation, 10);
22014 var useMargin = Settings.shouldIndentUseMargin(editor);
22015 var forcedRootBlock = Settings.getForcedRootBlock(editor);
22016 if (!editor.queryCommandState('InsertUnorderedList') && !editor.queryCommandState('InsertOrderedList')) {
22017 if (forcedRootBlock === '' && !dom.getParent(selection.getNode(), dom.isBlock)) {
22018 formatter.apply('div');
22019 }
22020 }
22021 each(getBlocksToIndent(editor), function (block) {
22022 indentElement(dom, command, useMargin, indentValue, indentUnit, block.dom());
22023 });
22024 };
22025
22026 var navigateIgnoreEmptyTextNodes = function (forward, root, from) {
22027 return CaretFinder.navigateIgnore(forward, root, from, isEmptyText);
22028 };
22029 var getClosestBlock = function (root, pos) {
22030 return find(Parents.parentsAndSelf(Element.fromDom(pos.container()), root), isBlock);
22031 };
22032 var isAtBeforeAfterBlockBoundary = function (forward, root, pos) {
22033 return navigateIgnoreEmptyTextNodes(forward, root.dom(), pos).forall(function (newPos) {
22034 return getClosestBlock(root, pos).fold(function () {
22035 return isInSameBlock(newPos, pos, root.dom()) === false;
22036 }, function (fromBlock) {
22037 return isInSameBlock(newPos, pos, root.dom()) === false && contains$3(fromBlock, Element.fromDom(newPos.container()));
22038 });
22039 });
22040 };
22041 var isAtBlockBoundary = function (forward, root, pos) {
22042 return getClosestBlock(root, pos).fold(function () {
22043 return navigateIgnoreEmptyTextNodes(forward, root.dom(), pos).forall(function (newPos) {
22044 return isInSameBlock(newPos, pos, root.dom()) === false;
22045 });
22046 }, function (parent) {
22047 return navigateIgnoreEmptyTextNodes(forward, parent.dom(), pos).isNone();
22048 });
22049 };
22050 var isAtStartOfBlock = curry(isAtBlockBoundary, false);
22051 var isAtEndOfBlock = curry(isAtBlockBoundary, true);
22052 var isBeforeBlock = curry(isAtBeforeAfterBlockBoundary, false);
22053 var isAfterBlock = curry(isAtBeforeAfterBlockBoundary, true);
22054
22055 var backspaceDelete$8 = function (editor, _caret, _forward) {
22056 if (editor.selection.isCollapsed() && canOutdent(editor)) {
22057 var dom = editor.dom;
22058 var rng = editor.selection.getRng();
22059 var pos = CaretPosition$1.fromRangeStart(rng);
22060 var block = Element.fromDom(dom.getParent(rng.startContainer, dom.isBlock));
22061 if (isAtStartOfBlock(block, pos)) {
22062 handle(editor, 'outdent');
22063 return true;
22064 }
22065 }
22066 return false;
22067 };
22068 var Outdent = { backspaceDelete: backspaceDelete$8 };
22069
22070 var executeKeydownOverride$1 = function (editor, caret, evt) {
22071 MatchKeys.execute([
22072 {
22073 keyCode: VK.BACKSPACE,
22074 action: MatchKeys.action(Outdent.backspaceDelete, editor, false)
22075 },
22076 {
22077 keyCode: VK.BACKSPACE,
22078 action: MatchKeys.action(CefDelete.backspaceDelete, editor, false)
22079 },
22080 {
22081 keyCode: VK.DELETE,
22082 action: MatchKeys.action(CefDelete.backspaceDelete, editor, true)
22083 },
22084 {
22085 keyCode: VK.BACKSPACE,
22086 action: MatchKeys.action(CefBoundaryDelete.backspaceDelete, editor, false)
22087 },
22088 {
22089 keyCode: VK.DELETE,
22090 action: MatchKeys.action(CefBoundaryDelete.backspaceDelete, editor, true)
22091 },
22092 {
22093 keyCode: VK.BACKSPACE,
22094 action: MatchKeys.action(BoundaryDelete.backspaceDelete, editor, caret, false)
22095 },
22096 {
22097 keyCode: VK.DELETE,
22098 action: MatchKeys.action(BoundaryDelete.backspaceDelete, editor, caret, true)
22099 },
22100 {
22101 keyCode: VK.BACKSPACE,
22102 action: MatchKeys.action(TableDelete.backspaceDelete, editor, false)
22103 },
22104 {
22105 keyCode: VK.DELETE,
22106 action: MatchKeys.action(TableDelete.backspaceDelete, editor, true)
22107 },
22108 {
22109 keyCode: VK.BACKSPACE,
22110 action: MatchKeys.action(PageBreakDelete.backspaceDelete, editor, false)
22111 },
22112 {
22113 keyCode: VK.DELETE,
22114 action: MatchKeys.action(PageBreakDelete.backspaceDelete, editor, true)
22115 },
22116 {
22117 keyCode: VK.BACKSPACE,
22118 action: MatchKeys.action(BlockRangeDelete.backspaceDelete, editor, false)
22119 },
22120 {
22121 keyCode: VK.DELETE,
22122 action: MatchKeys.action(BlockRangeDelete.backspaceDelete, editor, true)
22123 },
22124 {
22125 keyCode: VK.BACKSPACE,
22126 action: MatchKeys.action(BlockBoundaryDelete.backspaceDelete, editor, false)
22127 },
22128 {
22129 keyCode: VK.DELETE,
22130 action: MatchKeys.action(BlockBoundaryDelete.backspaceDelete, editor, true)
22131 },
22132 {
22133 keyCode: VK.BACKSPACE,
22134 action: MatchKeys.action(InlineFormatDelete.backspaceDelete, editor, false)
22135 },
22136 {
22137 keyCode: VK.DELETE,
22138 action: MatchKeys.action(InlineFormatDelete.backspaceDelete, editor, true)
22139 }
22140 ], evt).each(function (_) {
22141 evt.preventDefault();
22142 });
22143 };
22144 var executeKeyupOverride = function (editor, evt) {
22145 MatchKeys.execute([
22146 {
22147 keyCode: VK.BACKSPACE,
22148 action: MatchKeys.action(CefDelete.paddEmptyElement, editor)
22149 },
22150 {
22151 keyCode: VK.DELETE,
22152 action: MatchKeys.action(CefDelete.paddEmptyElement, editor)
22153 }
22154 ], evt);
22155 };
22156 var setup$9 = function (editor, caret) {
22157 editor.on('keydown', function (evt) {
22158 if (evt.isDefaultPrevented() === false) {
22159 executeKeydownOverride$1(editor, caret, evt);
22160 }
22161 });
22162 editor.on('keyup', function (evt) {
22163 if (evt.isDefaultPrevented() === false) {
22164 executeKeyupOverride(editor, evt);
22165 }
22166 });
22167 };
22168 var DeleteBackspaceKeys = { setup: setup$9 };
22169
22170 var firstNonWhiteSpaceNodeSibling = function (node) {
22171 while (node) {
22172 if (node.nodeType === 1 || node.nodeType === 3 && node.data && /[\r\n\s]/.test(node.data)) {
22173 return node;
22174 }
22175 node = node.nextSibling;
22176 }
22177 };
22178 var moveToCaretPosition = function (editor, root) {
22179 var node, rng, lastNode = root;
22180 var dom = editor.dom;
22181 var moveCaretBeforeOnEnterElementsMap = editor.schema.getMoveCaretBeforeOnEnterElements();
22182 if (!root) {
22183 return;
22184 }
22185 if (/^(LI|DT|DD)$/.test(root.nodeName)) {
22186 var firstChild = firstNonWhiteSpaceNodeSibling(root.firstChild);
22187 if (firstChild && /^(UL|OL|DL)$/.test(firstChild.nodeName)) {
22188 root.insertBefore(dom.doc.createTextNode('\xA0'), root.firstChild);
22189 }
22190 }
22191 rng = dom.createRng();
22192 root.normalize();
22193 if (root.hasChildNodes()) {
22194 var walker = new TreeWalker(root, root);
22195 while (node = walker.current()) {
22196 if (NodeType.isText(node)) {
22197 rng.setStart(node, 0);
22198 rng.setEnd(node, 0);
22199 break;
22200 }
22201 if (moveCaretBeforeOnEnterElementsMap[node.nodeName.toLowerCase()]) {
22202 rng.setStartBefore(node);
22203 rng.setEndBefore(node);
22204 break;
22205 }
22206 lastNode = node;
22207 node = walker.next();
22208 }
22209 if (!node) {
22210 rng.setStart(lastNode, 0);
22211 rng.setEnd(lastNode, 0);
22212 }
22213 } else {
22214 if (NodeType.isBr(root)) {
22215 if (root.nextSibling && dom.isBlock(root.nextSibling)) {
22216 rng.setStartBefore(root);
22217 rng.setEndBefore(root);
22218 } else {
22219 rng.setStartAfter(root);
22220 rng.setEndAfter(root);
22221 }
22222 } else {
22223 rng.setStart(root, 0);
22224 rng.setEnd(root, 0);
22225 }
22226 }
22227 editor.selection.setRng(rng);
22228 editor.selection.scrollIntoView(root);
22229 };
22230 var getEditableRoot = function (dom, node) {
22231 var root = dom.getRoot();
22232 var parent, editableRoot;
22233 parent = node;
22234 while (parent !== root && dom.getContentEditable(parent) !== 'false') {
22235 if (dom.getContentEditable(parent) === 'true') {
22236 editableRoot = parent;
22237 }
22238 parent = parent.parentNode;
22239 }
22240 return parent !== root ? editableRoot : root;
22241 };
22242 var getParentBlock$2 = function (editor) {
22243 return Option.from(editor.dom.getParent(editor.selection.getStart(true), editor.dom.isBlock));
22244 };
22245 var getParentBlockName = function (editor) {
22246 return getParentBlock$2(editor).fold(constant(''), function (parentBlock) {
22247 return parentBlock.nodeName.toUpperCase();
22248 });
22249 };
22250 var isListItemParentBlock = function (editor) {
22251 return getParentBlock$2(editor).filter(function (elm) {
22252 return isListItem(Element.fromDom(elm));
22253 }).isSome();
22254 };
22255 var NewLineUtils = {
22256 moveToCaretPosition: moveToCaretPosition,
22257 getEditableRoot: getEditableRoot,
22258 getParentBlock: getParentBlock$2,
22259 getParentBlockName: getParentBlockName,
22260 isListItemParentBlock: isListItemParentBlock
22261 };
22262
22263 var hasFirstChild = function (elm, name) {
22264 return elm.firstChild && elm.firstChild.nodeName === name;
22265 };
22266 var hasParent$1 = function (elm, parentName) {
22267 return elm && elm.parentNode && elm.parentNode.nodeName === parentName;
22268 };
22269 var isListBlock = function (elm) {
22270 return elm && /^(OL|UL|LI)$/.test(elm.nodeName);
22271 };
22272 var isNestedList = function (elm) {
22273 return isListBlock(elm) && isListBlock(elm.parentNode);
22274 };
22275 var getContainerBlock = function (containerBlock) {
22276 var containerBlockParent = containerBlock.parentNode;
22277 if (/^(LI|DT|DD)$/.test(containerBlockParent.nodeName)) {
22278 return containerBlockParent;
22279 }
22280 return containerBlock;
22281 };
22282 var isFirstOrLastLi = function (containerBlock, parentBlock, first) {
22283 var node = containerBlock[first ? 'firstChild' : 'lastChild'];
22284 while (node) {
22285 if (NodeType.isElement(node)) {
22286 break;
22287 }
22288 node = node[first ? 'nextSibling' : 'previousSibling'];
22289 }
22290 return node === parentBlock;
22291 };
22292 var insert = function (editor, createNewBlock, containerBlock, parentBlock, newBlockName) {
22293 var dom = editor.dom;
22294 var rng = editor.selection.getRng();
22295 if (containerBlock === editor.getBody()) {
22296 return;
22297 }
22298 if (isNestedList(containerBlock)) {
22299 newBlockName = 'LI';
22300 }
22301 var newBlock = newBlockName ? createNewBlock(newBlockName) : dom.create('BR');
22302 if (isFirstOrLastLi(containerBlock, parentBlock, true) && isFirstOrLastLi(containerBlock, parentBlock, false)) {
22303 if (hasParent$1(containerBlock, 'LI')) {
22304 dom.insertAfter(newBlock, getContainerBlock(containerBlock));
22305 } else {
22306 dom.replace(newBlock, containerBlock);
22307 }
22308 } else if (isFirstOrLastLi(containerBlock, parentBlock, true)) {
22309 if (hasParent$1(containerBlock, 'LI')) {
22310 dom.insertAfter(newBlock, getContainerBlock(containerBlock));
22311 newBlock.appendChild(dom.doc.createTextNode(' '));
22312 newBlock.appendChild(containerBlock);
22313 } else {
22314 containerBlock.parentNode.insertBefore(newBlock, containerBlock);
22315 }
22316 } else if (isFirstOrLastLi(containerBlock, parentBlock, false)) {
22317 dom.insertAfter(newBlock, getContainerBlock(containerBlock));
22318 } else {
22319 containerBlock = getContainerBlock(containerBlock);
22320 var tmpRng = rng.cloneRange();
22321 tmpRng.setStartAfter(parentBlock);
22322 tmpRng.setEndAfter(containerBlock);
22323 var fragment = tmpRng.extractContents();
22324 if (newBlockName === 'LI' && hasFirstChild(fragment, 'LI')) {
22325 newBlock = fragment.firstChild;
22326 dom.insertAfter(fragment, containerBlock);
22327 } else {
22328 dom.insertAfter(fragment, containerBlock);
22329 dom.insertAfter(newBlock, containerBlock);
22330 }
22331 }
22332 dom.remove(parentBlock);
22333 NewLineUtils.moveToCaretPosition(editor, newBlock);
22334 };
22335 var InsertLi = { insert: insert };
22336
22337 var trimZwsp = function (fragment) {
22338 each(descendants(Element.fromDom(fragment), isText), function (text) {
22339 var rawNode = text.dom();
22340 rawNode.nodeValue = Zwsp.trim(rawNode.nodeValue);
22341 });
22342 };
22343 var isEmptyAnchor = function (dom, elm) {
22344 return elm && elm.nodeName === 'A' && dom.isEmpty(elm);
22345 };
22346 var isTableCell$4 = function (node) {
22347 return node && /^(TD|TH|CAPTION)$/.test(node.nodeName);
22348 };
22349 var emptyBlock = function (elm) {
22350 elm.innerHTML = '<br data-mce-bogus="1">';
22351 };
22352 var containerAndSiblingName = function (container, nodeName) {
22353 return container.nodeName === nodeName || container.previousSibling && container.previousSibling.nodeName === nodeName;
22354 };
22355 var canSplitBlock = function (dom, node) {
22356 return node && dom.isBlock(node) && !/^(TD|TH|CAPTION|FORM)$/.test(node.nodeName) && !/^(fixed|absolute)/i.test(node.style.position) && dom.getContentEditable(node) !== 'true';
22357 };
22358 var trimInlineElementsOnLeftSideOfBlock = function (dom, nonEmptyElementsMap, block) {
22359 var node = block;
22360 var firstChilds = [];
22361 var i;
22362 if (!node) {
22363 return;
22364 }
22365 while (node = node.firstChild) {
22366 if (dom.isBlock(node)) {
22367 return;
22368 }
22369 if (NodeType.isElement(node) && !nonEmptyElementsMap[node.nodeName.toLowerCase()]) {
22370 firstChilds.push(node);
22371 }
22372 }
22373 i = firstChilds.length;
22374 while (i--) {
22375 node = firstChilds[i];
22376 if (!node.hasChildNodes() || node.firstChild === node.lastChild && node.firstChild.nodeValue === '') {
22377 dom.remove(node);
22378 } else {
22379 if (isEmptyAnchor(dom, node)) {
22380 dom.remove(node);
22381 }
22382 }
22383 }
22384 };
22385 var normalizeZwspOffset = function (start, container, offset) {
22386 if (NodeType.isText(container) === false) {
22387 return offset;
22388 } else if (start) {
22389 return offset === 1 && container.data.charAt(offset - 1) === Zwsp.ZWSP ? 0 : offset;
22390 } else {
22391 return offset === container.data.length - 1 && container.data.charAt(offset) === Zwsp.ZWSP ? container.data.length : offset;
22392 }
22393 };
22394 var includeZwspInRange = function (rng) {
22395 var newRng = rng.cloneRange();
22396 newRng.setStart(rng.startContainer, normalizeZwspOffset(true, rng.startContainer, rng.startOffset));
22397 newRng.setEnd(rng.endContainer, normalizeZwspOffset(false, rng.endContainer, rng.endOffset));
22398 return newRng;
22399 };
22400 var trimLeadingLineBreaks = function (node) {
22401 do {
22402 if (NodeType.isText(node)) {
22403 node.nodeValue = node.nodeValue.replace(/^[\r\n]+/, '');
22404 }
22405 node = node.firstChild;
22406 } while (node);
22407 };
22408 var getEditableRoot$1 = function (dom, node) {
22409 var root = dom.getRoot();
22410 var parent, editableRoot;
22411 parent = node;
22412 while (parent !== root && dom.getContentEditable(parent) !== 'false') {
22413 if (dom.getContentEditable(parent) === 'true') {
22414 editableRoot = parent;
22415 }
22416 parent = parent.parentNode;
22417 }
22418 return parent !== root ? editableRoot : root;
22419 };
22420 var setForcedBlockAttrs = function (editor, node) {
22421 var forcedRootBlockName = Settings.getForcedRootBlock(editor);
22422 if (forcedRootBlockName && forcedRootBlockName.toLowerCase() === node.tagName.toLowerCase()) {
22423 editor.dom.setAttribs(node, Settings.getForcedRootBlockAttrs(editor));
22424 }
22425 };
22426 var wrapSelfAndSiblingsInDefaultBlock = function (editor, newBlockName, rng, container, offset) {
22427 var newBlock, parentBlock, startNode, node, next, rootBlockName;
22428 var blockName = newBlockName || 'P';
22429 var dom = editor.dom, editableRoot = getEditableRoot$1(dom, container);
22430 parentBlock = dom.getParent(container, dom.isBlock);
22431 if (!parentBlock || !canSplitBlock(dom, parentBlock)) {
22432 parentBlock = parentBlock || editableRoot;
22433 if (parentBlock === editor.getBody() || isTableCell$4(parentBlock)) {
22434 rootBlockName = parentBlock.nodeName.toLowerCase();
22435 } else {
22436 rootBlockName = parentBlock.parentNode.nodeName.toLowerCase();
22437 }
22438 if (!parentBlock.hasChildNodes()) {
22439 newBlock = dom.create(blockName);
22440 setForcedBlockAttrs(editor, newBlock);
22441 parentBlock.appendChild(newBlock);
22442 rng.setStart(newBlock, 0);
22443 rng.setEnd(newBlock, 0);
22444 return newBlock;
22445 }
22446 node = container;
22447 while (node.parentNode !== parentBlock) {
22448 node = node.parentNode;
22449 }
22450 while (node && !dom.isBlock(node)) {
22451 startNode = node;
22452 node = node.previousSibling;
22453 }
22454 if (startNode && editor.schema.isValidChild(rootBlockName, blockName.toLowerCase())) {
22455 newBlock = dom.create(blockName);
22456 setForcedBlockAttrs(editor, newBlock);
22457 startNode.parentNode.insertBefore(newBlock, startNode);
22458 node = startNode;
22459 while (node && !dom.isBlock(node)) {
22460 next = node.nextSibling;
22461 newBlock.appendChild(node);
22462 node = next;
22463 }
22464 rng.setStart(container, offset);
22465 rng.setEnd(container, offset);
22466 }
22467 }
22468 return container;
22469 };
22470 var addBrToBlockIfNeeded = function (dom, block) {
22471 var lastChild;
22472 block.normalize();
22473 lastChild = block.lastChild;
22474 if (!lastChild || /^(left|right)$/gi.test(dom.getStyle(lastChild, 'float', true))) {
22475 dom.add(block, 'br');
22476 }
22477 };
22478 var insert$1 = function (editor, evt) {
22479 var tmpRng, editableRoot, container, offset, parentBlock, shiftKey;
22480 var newBlock, fragment, containerBlock, parentBlockName, containerBlockName, newBlockName, isAfterLastNodeInContainer;
22481 var dom = editor.dom;
22482 var schema = editor.schema, nonEmptyElementsMap = schema.getNonEmptyElements();
22483 var rng = editor.selection.getRng();
22484 var createNewBlock = function (name) {
22485 var node = container, block, clonedNode, caretNode;
22486 var textInlineElements = schema.getTextInlineElements();
22487 if (name || parentBlockName === 'TABLE' || parentBlockName === 'HR') {
22488 block = dom.create(name || newBlockName);
22489 setForcedBlockAttrs(editor, block);
22490 } else {
22491 block = parentBlock.cloneNode(false);
22492 }
22493 caretNode = block;
22494 if (Settings.shouldKeepStyles(editor) === false) {
22495 dom.setAttrib(block, 'style', null);
22496 dom.setAttrib(block, 'class', null);
22497 } else {
22498 do {
22499 if (textInlineElements[node.nodeName]) {
22500 if (isCaretNode(node) || Bookmarks.isBookmarkNode(node)) {
22501 continue;
22502 }
22503 clonedNode = node.cloneNode(false);
22504 dom.setAttrib(clonedNode, 'id', '');
22505 if (block.hasChildNodes()) {
22506 clonedNode.appendChild(block.firstChild);
22507 block.appendChild(clonedNode);
22508 } else {
22509 caretNode = clonedNode;
22510 block.appendChild(clonedNode);
22511 }
22512 }
22513 } while ((node = node.parentNode) && node !== editableRoot);
22514 }
22515 emptyBlock(caretNode);
22516 return block;
22517 };
22518 var isCaretAtStartOrEndOfBlock = function (start) {
22519 var node, name;
22520 var normalizedOffset = normalizeZwspOffset(start, container, offset);
22521 if (NodeType.isText(container) && (start ? normalizedOffset > 0 : normalizedOffset < container.nodeValue.length)) {
22522 return false;
22523 }
22524 if (container.parentNode === parentBlock && isAfterLastNodeInContainer && !start) {
22525 return true;
22526 }
22527 if (start && NodeType.isElement(container) && container === parentBlock.firstChild) {
22528 return true;
22529 }
22530 if (containerAndSiblingName(container, 'TABLE') || containerAndSiblingName(container, 'HR')) {
22531 return isAfterLastNodeInContainer && !start || !isAfterLastNodeInContainer && start;
22532 }
22533 var walker = new TreeWalker(container, parentBlock);
22534 if (NodeType.isText(container)) {
22535 if (start && normalizedOffset === 0) {
22536 walker.prev();
22537 } else if (!start && normalizedOffset === container.nodeValue.length) {
22538 walker.next();
22539 }
22540 }
22541 while (node = walker.current()) {
22542 if (NodeType.isElement(node)) {
22543 if (!node.getAttribute('data-mce-bogus')) {
22544 name = node.nodeName.toLowerCase();
22545 if (nonEmptyElementsMap[name] && name !== 'br') {
22546 return false;
22547 }
22548 }
22549 } else if (NodeType.isText(node) && !/^[ \t\r\n]*$/.test(node.nodeValue)) {
22550 return false;
22551 }
22552 if (start) {
22553 walker.prev();
22554 } else {
22555 walker.next();
22556 }
22557 }
22558 return true;
22559 };
22560 var insertNewBlockAfter = function () {
22561 if (/^(H[1-6]|PRE|FIGURE)$/.test(parentBlockName) && containerBlockName !== 'HGROUP') {
22562 newBlock = createNewBlock(newBlockName);
22563 } else {
22564 newBlock = createNewBlock();
22565 }
22566 if (Settings.shouldEndContainerOnEmptyBlock(editor) && canSplitBlock(dom, containerBlock) && dom.isEmpty(parentBlock)) {
22567 newBlock = dom.split(containerBlock, parentBlock);
22568 } else {
22569 dom.insertAfter(newBlock, parentBlock);
22570 }
22571 NewLineUtils.moveToCaretPosition(editor, newBlock);
22572 };
22573 NormalizeRange.normalize(dom, rng).each(function (normRng) {
22574 rng.setStart(normRng.startContainer, normRng.startOffset);
22575 rng.setEnd(normRng.endContainer, normRng.endOffset);
22576 });
22577 container = rng.startContainer;
22578 offset = rng.startOffset;
22579 newBlockName = Settings.getForcedRootBlock(editor);
22580 shiftKey = !!(evt && evt.shiftKey);
22581 var ctrlKey = !!(evt && evt.ctrlKey);
22582 if (NodeType.isElement(container) && container.hasChildNodes()) {
22583 isAfterLastNodeInContainer = offset > container.childNodes.length - 1;
22584 container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
22585 if (isAfterLastNodeInContainer && NodeType.isText(container)) {
22586 offset = container.nodeValue.length;
22587 } else {
22588 offset = 0;
22589 }
22590 }
22591 editableRoot = getEditableRoot$1(dom, container);
22592 if (!editableRoot) {
22593 return;
22594 }
22595 if (newBlockName && !shiftKey || !newBlockName && shiftKey) {
22596 container = wrapSelfAndSiblingsInDefaultBlock(editor, newBlockName, rng, container, offset);
22597 }
22598 parentBlock = dom.getParent(container, dom.isBlock);
22599 containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null;
22600 parentBlockName = parentBlock ? parentBlock.nodeName.toUpperCase() : '';
22601 containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : '';
22602 if (containerBlockName === 'LI' && !ctrlKey) {
22603 parentBlock = containerBlock;
22604 containerBlock = containerBlock.parentNode;
22605 parentBlockName = containerBlockName;
22606 }
22607 if (/^(LI|DT|DD)$/.test(parentBlockName)) {
22608 if (dom.isEmpty(parentBlock)) {
22609 InsertLi.insert(editor, createNewBlock, containerBlock, parentBlock, newBlockName);
22610 return;
22611 }
22612 }
22613 if (newBlockName && parentBlock === editor.getBody()) {
22614 return;
22615 }
22616 newBlockName = newBlockName || 'P';
22617 if (isCaretContainerBlock(parentBlock)) {
22618 newBlock = showCaretContainerBlock(parentBlock);
22619 if (dom.isEmpty(parentBlock)) {
22620 emptyBlock(parentBlock);
22621 }
22622 NewLineUtils.moveToCaretPosition(editor, newBlock);
22623 } else if (isCaretAtStartOrEndOfBlock()) {
22624 insertNewBlockAfter();
22625 } else if (isCaretAtStartOrEndOfBlock(true)) {
22626 newBlock = parentBlock.parentNode.insertBefore(createNewBlock(), parentBlock);
22627 NewLineUtils.moveToCaretPosition(editor, containerAndSiblingName(parentBlock, 'HR') ? newBlock : parentBlock);
22628 } else {
22629 tmpRng = includeZwspInRange(rng).cloneRange();
22630 tmpRng.setEndAfter(parentBlock);
22631 fragment = tmpRng.extractContents();
22632 trimZwsp(fragment);
22633 trimLeadingLineBreaks(fragment);
22634 newBlock = fragment.firstChild;
22635 dom.insertAfter(fragment, parentBlock);
22636 trimInlineElementsOnLeftSideOfBlock(dom, nonEmptyElementsMap, newBlock);
22637 addBrToBlockIfNeeded(dom, parentBlock);
22638 if (dom.isEmpty(parentBlock)) {
22639 emptyBlock(parentBlock);
22640 }
22641 newBlock.normalize();
22642 if (dom.isEmpty(newBlock)) {
22643 dom.remove(newBlock);
22644 insertNewBlockAfter();
22645 } else {
22646 NewLineUtils.moveToCaretPosition(editor, newBlock);
22647 }
22648 }
22649 dom.setAttrib(newBlock, 'id', '');
22650 editor.fire('NewBlock', { newBlock: newBlock });
22651 };
22652 var InsertBlock = { insert: insert$1 };
22653
22654 var hasRightSideContent = function (schema, container, parentBlock) {
22655 var walker = new TreeWalker(container, parentBlock);
22656 var node;
22657 var nonEmptyElementsMap = schema.getNonEmptyElements();
22658 while (node = walker.next()) {
22659 if (nonEmptyElementsMap[node.nodeName.toLowerCase()] || node.length > 0) {
22660 return true;
22661 }
22662 }
22663 };
22664 var scrollToBr = function (dom, selection, brElm) {
22665 var marker = dom.create('span', {}, '&nbsp;');
22666 brElm.parentNode.insertBefore(marker, brElm);
22667 selection.scrollIntoView(marker);
22668 dom.remove(marker);
22669 };
22670 var moveSelectionToBr = function (dom, selection, brElm, extraBr) {
22671 var rng = dom.createRng();
22672 if (!extraBr) {
22673 rng.setStartAfter(brElm);
22674 rng.setEndAfter(brElm);
22675 } else {
22676 rng.setStartBefore(brElm);
22677 rng.setEndBefore(brElm);
22678 }
22679 selection.setRng(rng);
22680 };
22681 var insertBrAtCaret = function (editor, evt) {
22682 var selection = editor.selection;
22683 var dom = editor.dom;
22684 var rng = selection.getRng();
22685 var brElm;
22686 var extraBr;
22687 NormalizeRange.normalize(dom, rng).each(function (normRng) {
22688 rng.setStart(normRng.startContainer, normRng.startOffset);
22689 rng.setEnd(normRng.endContainer, normRng.endOffset);
22690 });
22691 var offset = rng.startOffset;
22692 var container = rng.startContainer;
22693 if (container.nodeType === 1 && container.hasChildNodes()) {
22694 var isAfterLastNodeInContainer = offset > container.childNodes.length - 1;
22695 container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
22696 if (isAfterLastNodeInContainer && container.nodeType === 3) {
22697 offset = container.nodeValue.length;
22698 } else {
22699 offset = 0;
22700 }
22701 }
22702 var parentBlock = dom.getParent(container, dom.isBlock);
22703 var containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null;
22704 var containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : '';
22705 var isControlKey = !!(evt && evt.ctrlKey);
22706 if (containerBlockName === 'LI' && !isControlKey) {
22707 parentBlock = containerBlock;
22708 }
22709 if (container && container.nodeType === 3 && offset >= container.nodeValue.length) {
22710 if (!hasRightSideContent(editor.schema, container, parentBlock)) {
22711 brElm = dom.create('br');
22712 rng.insertNode(brElm);
22713 rng.setStartAfter(brElm);
22714 rng.setEndAfter(brElm);
22715 extraBr = true;
22716 }
22717 }
22718 brElm = dom.create('br');
22719 rangeInsertNode(dom, rng, brElm);
22720 scrollToBr(dom, selection, brElm);
22721 moveSelectionToBr(dom, selection, brElm, extraBr);
22722 editor.undoManager.add();
22723 };
22724 var insertBrBefore = function (editor, inline) {
22725 var br = Element.fromTag('br');
22726 before(Element.fromDom(inline), br);
22727 editor.undoManager.add();
22728 };
22729 var insertBrAfter = function (editor, inline) {
22730 if (!hasBrAfter(editor.getBody(), inline)) {
22731 after(Element.fromDom(inline), Element.fromTag('br'));
22732 }
22733 var br = Element.fromTag('br');
22734 after(Element.fromDom(inline), br);
22735 scrollToBr(editor.dom, editor.selection, br.dom());
22736 moveSelectionToBr(editor.dom, editor.selection, br.dom(), false);
22737 editor.undoManager.add();
22738 };
22739 var isBeforeBr$1 = function (pos) {
22740 return NodeType.isBr(pos.getNode());
22741 };
22742 var hasBrAfter = function (rootNode, startNode) {
22743 if (isBeforeBr$1(CaretPosition$1.after(startNode))) {
22744 return true;
22745 } else {
22746 return CaretFinder.nextPosition(rootNode, CaretPosition$1.after(startNode)).map(function (pos) {
22747 return NodeType.isBr(pos.getNode());
22748 }).getOr(false);
22749 }
22750 };
22751 var isAnchorLink = function (elm) {
22752 return elm && elm.nodeName === 'A' && 'href' in elm;
22753 };
22754 var isInsideAnchor = function (location) {
22755 return location.fold(constant(false), isAnchorLink, isAnchorLink, constant(false));
22756 };
22757 var readInlineAnchorLocation = function (editor) {
22758 var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);
22759 var position = CaretPosition$1.fromRangeStart(editor.selection.getRng());
22760 return BoundaryLocation.readLocation(isInlineTarget, editor.getBody(), position).filter(isInsideAnchor);
22761 };
22762 var insertBrOutsideAnchor = function (editor, location) {
22763 location.fold(noop, curry(insertBrBefore, editor), curry(insertBrAfter, editor), noop);
22764 };
22765 var insert$2 = function (editor, evt) {
22766 var anchorLocation = readInlineAnchorLocation(editor);
22767 if (anchorLocation.isSome()) {
22768 anchorLocation.each(curry(insertBrOutsideAnchor, editor));
22769 } else {
22770 insertBrAtCaret(editor, evt);
22771 }
22772 };
22773 var InsertBr = { insert: insert$2 };
22774
22775 var matchesSelector = function (editor, selector) {
22776 return NewLineUtils.getParentBlock(editor).filter(function (parentBlock) {
22777 return selector.length > 0 && is$1(Element.fromDom(parentBlock), selector);
22778 }).isSome();
22779 };
22780 var shouldInsertBr = function (editor) {
22781 return matchesSelector(editor, Settings.getBrNewLineSelector(editor));
22782 };
22783 var shouldBlockNewLine = function (editor) {
22784 return matchesSelector(editor, Settings.getNoNewLineSelector(editor));
22785 };
22786 var ContextSelectors = {
22787 shouldInsertBr: shouldInsertBr,
22788 shouldBlockNewLine: shouldBlockNewLine
22789 };
22790
22791 var newLineAction = Adt.generate([
22792 { br: [] },
22793 { block: [] },
22794 { none: [] }
22795 ]);
22796 var shouldBlockNewLine$1 = function (editor, shiftKey) {
22797 return ContextSelectors.shouldBlockNewLine(editor);
22798 };
22799 var isBrMode = function (requiredState) {
22800 return function (editor, shiftKey) {
22801 var brMode = Settings.getForcedRootBlock(editor) === '';
22802 return brMode === requiredState;
22803 };
22804 };
22805 var inListBlock = function (requiredState) {
22806 return function (editor, shiftKey) {
22807 return NewLineUtils.isListItemParentBlock(editor) === requiredState;
22808 };
22809 };
22810 var inBlock = function (blockName, requiredState) {
22811 return function (editor, shiftKey) {
22812 var state = NewLineUtils.getParentBlockName(editor) === blockName.toUpperCase();
22813 return state === requiredState;
22814 };
22815 };
22816 var inPreBlock = function (requiredState) {
22817 return inBlock('pre', requiredState);
22818 };
22819 var inSummaryBlock = function () {
22820 return inBlock('summary', true);
22821 };
22822 var shouldPutBrInPre$1 = function (requiredState) {
22823 return function (editor, shiftKey) {
22824 return Settings.shouldPutBrInPre(editor) === requiredState;
22825 };
22826 };
22827 var inBrContext = function (editor, shiftKey) {
22828 return ContextSelectors.shouldInsertBr(editor);
22829 };
22830 var hasShiftKey = function (editor, shiftKey) {
22831 return shiftKey;
22832 };
22833 var canInsertIntoEditableRoot = function (editor) {
22834 var forcedRootBlock = Settings.getForcedRootBlock(editor);
22835 var rootEditable = NewLineUtils.getEditableRoot(editor.dom, editor.selection.getStart());
22836 return rootEditable && editor.schema.isValidChild(rootEditable.nodeName, forcedRootBlock ? forcedRootBlock : 'P');
22837 };
22838 var match$2 = function (predicates, action) {
22839 return function (editor, shiftKey) {
22840 var isMatch = foldl(predicates, function (res, p) {
22841 return res && p(editor, shiftKey);
22842 }, true);
22843 return isMatch ? Option.some(action) : Option.none();
22844 };
22845 };
22846 var getAction$1 = function (editor, evt) {
22847 return LazyEvaluator.evaluateUntil([
22848 match$2([shouldBlockNewLine$1], newLineAction.none()),
22849 match$2([inSummaryBlock()], newLineAction.br()),
22850 match$2([
22851 inPreBlock(true),
22852 shouldPutBrInPre$1(false),
22853 hasShiftKey
22854 ], newLineAction.br()),
22855 match$2([
22856 inPreBlock(true),
22857 shouldPutBrInPre$1(false)
22858 ], newLineAction.block()),
22859 match$2([
22860 inPreBlock(true),
22861 shouldPutBrInPre$1(true),
22862 hasShiftKey
22863 ], newLineAction.block()),
22864 match$2([
22865 inPreBlock(true),
22866 shouldPutBrInPre$1(true)
22867 ], newLineAction.br()),
22868 match$2([
22869 inListBlock(true),
22870 hasShiftKey
22871 ], newLineAction.br()),
22872 match$2([inListBlock(true)], newLineAction.block()),
22873 match$2([
22874 isBrMode(true),
22875 hasShiftKey,
22876 canInsertIntoEditableRoot
22877 ], newLineAction.block()),
22878 match$2([isBrMode(true)], newLineAction.br()),
22879 match$2([inBrContext], newLineAction.br()),
22880 match$2([
22881 isBrMode(false),
22882 hasShiftKey
22883 ], newLineAction.br()),
22884 match$2([canInsertIntoEditableRoot], newLineAction.block())
22885 ], [
22886 editor,
22887 !!(evt && evt.shiftKey)
22888 ]).getOr(newLineAction.none());
22889 };
22890 var NewLineAction = { getAction: getAction$1 };
22891
22892 var insert$3 = function (editor, evt) {
22893 NewLineAction.getAction(editor, evt).fold(function () {
22894 InsertBr.insert(editor, evt);
22895 }, function () {
22896 InsertBlock.insert(editor, evt);
22897 }, noop);
22898 };
22899 var InsertNewLine = { insert: insert$3 };
22900
22901 var endTypingLevel = function (undoManager) {
22902 if (undoManager.typing) {
22903 undoManager.typing = false;
22904 undoManager.add();
22905 }
22906 };
22907 var handleEnterKeyEvent = function (editor, event) {
22908 if (event.isDefaultPrevented()) {
22909 return;
22910 }
22911 event.preventDefault();
22912 endTypingLevel(editor.undoManager);
22913 editor.undoManager.transact(function () {
22914 if (editor.selection.isCollapsed() === false) {
22915 editor.execCommand('Delete');
22916 }
22917 InsertNewLine.insert(editor, event);
22918 });
22919 };
22920 var setup$a = function (editor) {
22921 editor.on('keydown', function (event) {
22922 if (event.keyCode === VK.ENTER) {
22923 handleEnterKeyEvent(editor, event);
22924 }
22925 });
22926 };
22927 var EnterKey = { setup: setup$a };
22928
22929 var insertTextAtPosition = function (text, pos) {
22930 var container = pos.container();
22931 var offset = pos.offset();
22932 if (NodeType.isText(container)) {
22933 container.insertData(offset, text);
22934 return Option.some(CaretPosition(container, offset + text.length));
22935 } else {
22936 return getElementFromPosition(pos).map(function (elm) {
22937 var textNode = Element.fromText(text);
22938 if (pos.isAtEnd()) {
22939 after(elm, textNode);
22940 } else {
22941 before(elm, textNode);
22942 }
22943 return CaretPosition(textNode.dom(), text.length);
22944 });
22945 }
22946 };
22947 var insertNbspAtPosition = curry(insertTextAtPosition, '\xA0');
22948 var insertSpaceAtPosition = curry(insertTextAtPosition, ' ');
22949
22950 var nbsp = '\xA0';
22951 var isInMiddleOfText = function (pos) {
22952 return CaretPosition.isTextPosition(pos) && !pos.isAtStart() && !pos.isAtEnd();
22953 };
22954 var getClosestBlock$1 = function (root, pos) {
22955 var parentBlocks = filter(Parents.parentsAndSelf(Element.fromDom(pos.container()), root), isBlock);
22956 return head(parentBlocks).getOr(root);
22957 };
22958 var hasSpaceBefore = function (root, pos) {
22959 if (isInMiddleOfText(pos)) {
22960 return isAfterSpace(pos);
22961 } else {
22962 return isAfterSpace(pos) || CaretFinder.prevPosition(getClosestBlock$1(root, pos).dom(), pos).exists(isAfterSpace);
22963 }
22964 };
22965 var hasSpaceAfter = function (root, pos) {
22966 if (isInMiddleOfText(pos)) {
22967 return isBeforeSpace(pos);
22968 } else {
22969 return isBeforeSpace(pos) || CaretFinder.nextPosition(getClosestBlock$1(root, pos).dom(), pos).exists(isBeforeSpace);
22970 }
22971 };
22972 var isPreValue = function (value) {
22973 return contains([
22974 'pre',
22975 'pre-wrap'
22976 ], value);
22977 };
22978 var isInPre = function (pos) {
22979 return getElementFromPosition(pos).bind(function (elm) {
22980 return closest(elm, isElement);
22981 }).exists(function (elm) {
22982 return isPreValue(get$2(elm, 'white-space'));
22983 });
22984 };
22985 var isAtBeginningOfBody = function (root, pos) {
22986 return CaretFinder.prevPosition(root.dom(), pos).isNone();
22987 };
22988 var isAtEndOfBody = function (root, pos) {
22989 return CaretFinder.nextPosition(root.dom(), pos).isNone();
22990 };
22991 var isAtLineBoundary = function (root, pos) {
22992 return isAtBeginningOfBody(root, pos) || isAtEndOfBody(root, pos) || isAtStartOfBlock(root, pos) || isAtEndOfBlock(root, pos) || isAfterBr(root, pos) || isBeforeBr(root, pos);
22993 };
22994 var needsToHaveNbsp = function (root, pos) {
22995 if (isInPre(pos)) {
22996 return false;
22997 } else {
22998 return isAtLineBoundary(root, pos) || hasSpaceBefore(root, pos) || hasSpaceAfter(root, pos);
22999 }
23000 };
23001 var needsToBeNbspLeft = function (root, pos) {
23002 if (isInPre(pos)) {
23003 return false;
23004 } else {
23005 return isAtStartOfBlock(root, pos) || isBeforeBlock(root, pos) || isAfterBr(root, pos) || hasSpaceBefore(root, pos);
23006 }
23007 };
23008 var leanRight = function (pos) {
23009 var container = pos.container();
23010 var offset = pos.offset();
23011 if (NodeType.isText(container) && offset < container.data.length) {
23012 return CaretPosition(container, offset + 1);
23013 } else {
23014 return pos;
23015 }
23016 };
23017 var needsToBeNbspRight = function (root, pos) {
23018 var afterPos = leanRight(pos);
23019 if (isInPre(afterPos)) {
23020 return false;
23021 } else {
23022 return isAtEndOfBlock(root, afterPos) || isAfterBlock(root, afterPos) || isBeforeBr(root, afterPos) || hasSpaceAfter(root, afterPos);
23023 }
23024 };
23025 var needsToBeNbsp = function (root, pos) {
23026 return needsToBeNbspLeft(root, pos) || needsToBeNbspRight(root, pos);
23027 };
23028 var isNbspAt = function (text, offset) {
23029 return isNbsp(text.charAt(offset));
23030 };
23031 var hasNbsp = function (pos) {
23032 var container = pos.container();
23033 return NodeType.isText(container) && contains$2(container.data, nbsp);
23034 };
23035 var normalizeNbspMiddle = function (text) {
23036 return map(text.split(''), function (chr, i, chars) {
23037 if (isNbsp(chr) && i > 0 && i < chars.length - 1 && isContent(chars[i - 1]) && isContent(chars[i + 1])) {
23038 return ' ';
23039 } else {
23040 return chr;
23041 }
23042 }).join('');
23043 };
23044 var normalizeNbspAtStart = function (root, node) {
23045 var text = node.data;
23046 var firstPos = CaretPosition(node, 0);
23047 if (isNbspAt(text, 0) && !needsToBeNbsp(root, firstPos)) {
23048 node.data = ' ' + text.slice(1);
23049 return true;
23050 } else {
23051 return false;
23052 }
23053 };
23054 var normalizeNbspInMiddleOfTextNode = function (node) {
23055 var text = node.data;
23056 var newText = normalizeNbspMiddle(text);
23057 if (newText !== text) {
23058 node.data = newText;
23059 return true;
23060 } else {
23061 return false;
23062 }
23063 };
23064 var normalizeNbspAtEnd = function (root, node) {
23065 var text = node.data;
23066 var lastPos = CaretPosition(node, text.length - 1);
23067 if (isNbspAt(text, text.length - 1) && !needsToBeNbsp(root, lastPos)) {
23068 node.data = text.slice(0, -1) + ' ';
23069 return true;
23070 } else {
23071 return false;
23072 }
23073 };
23074 var normalizeNbsps = function (root, pos) {
23075 return Option.some(pos).filter(hasNbsp).bind(function (pos) {
23076 var container = pos.container();
23077 var normalized = normalizeNbspAtStart(root, container) || normalizeNbspInMiddleOfTextNode(container) || normalizeNbspAtEnd(root, container);
23078 return normalized ? Option.some(pos) : Option.none();
23079 });
23080 };
23081 var normalizeNbspsInEditor = function (editor) {
23082 var root = Element.fromDom(editor.getBody());
23083 if (editor.selection.isCollapsed()) {
23084 normalizeNbsps(root, CaretPosition.fromRangeStart(editor.selection.getRng())).each(function (pos) {
23085 editor.selection.setRng(pos.toRange());
23086 });
23087 }
23088 };
23089
23090 var locationToCaretPosition = function (root) {
23091 return function (location) {
23092 return location.fold(function (element) {
23093 return CaretFinder.prevPosition(root.dom(), CaretPosition$1.before(element));
23094 }, function (element) {
23095 return CaretFinder.firstPositionIn(element);
23096 }, function (element) {
23097 return CaretFinder.lastPositionIn(element);
23098 }, function (element) {
23099 return CaretFinder.nextPosition(root.dom(), CaretPosition$1.after(element));
23100 });
23101 };
23102 };
23103 var insertInlineBoundarySpaceOrNbsp = function (root, pos) {
23104 return function (checkPos) {
23105 return needsToHaveNbsp(root, checkPos) ? insertNbspAtPosition(pos) : insertSpaceAtPosition(pos);
23106 };
23107 };
23108 var setSelection$1 = function (editor) {
23109 return function (pos) {
23110 editor.selection.setRng(pos.toRange());
23111 editor.nodeChanged();
23112 return true;
23113 };
23114 };
23115 var insertSpaceOrNbspAtSelection = function (editor) {
23116 var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
23117 var root = Element.fromDom(editor.getBody());
23118 if (editor.selection.isCollapsed()) {
23119 var isInlineTarget = curry(InlineUtils.isInlineTarget, editor);
23120 var caretPosition = CaretPosition$1.fromRangeStart(editor.selection.getRng());
23121 return BoundaryLocation.readLocation(isInlineTarget, editor.getBody(), caretPosition).bind(locationToCaretPosition(root)).bind(insertInlineBoundarySpaceOrNbsp(root, pos)).exists(setSelection$1(editor));
23122 } else {
23123 return false;
23124 }
23125 };
23126
23127 var executeKeydownOverride$2 = function (editor, evt) {
23128 MatchKeys.execute([{
23129 keyCode: VK.SPACEBAR,
23130 action: MatchKeys.action(insertSpaceOrNbspAtSelection, editor)
23131 }], evt).each(function (_) {
23132 evt.preventDefault();
23133 });
23134 };
23135 var setup$b = function (editor) {
23136 editor.on('keydown', function (evt) {
23137 if (evt.isDefaultPrevented() === false) {
23138 executeKeydownOverride$2(editor, evt);
23139 }
23140 });
23141 };
23142 var SpaceKey = { setup: setup$b };
23143
23144 var findBlockCaretContainer = function (editor) {
23145 return descendant(Element.fromDom(editor.getBody()), '*[data-mce-caret]').fold(constant(null), function (elm) {
23146 return elm.dom();
23147 });
23148 };
23149 var removeIeControlRect = function (editor) {
23150 editor.selection.setRng(editor.selection.getRng());
23151 };
23152 var showBlockCaretContainer = function (editor, blockCaretContainer) {
23153 if (blockCaretContainer.hasAttribute('data-mce-caret')) {
23154 showCaretContainerBlock(blockCaretContainer);
23155 removeIeControlRect(editor);
23156 editor.selection.scrollIntoView(blockCaretContainer);
23157 }
23158 };
23159 var handleBlockContainer = function (editor, e) {
23160 var blockCaretContainer = findBlockCaretContainer(editor);
23161 if (!blockCaretContainer) {
23162 return;
23163 }
23164 if (e.type === 'compositionstart') {
23165 e.preventDefault();
23166 e.stopPropagation();
23167 showBlockCaretContainer(editor, blockCaretContainer);
23168 return;
23169 }
23170 if (hasContent(blockCaretContainer)) {
23171 showBlockCaretContainer(editor, blockCaretContainer);
23172 editor.undoManager.add();
23173 }
23174 };
23175 var setup$c = function (editor) {
23176 editor.on('keyup compositionstart', curry(handleBlockContainer, editor));
23177 };
23178 var CaretContainerInput = { setup: setup$c };
23179
23180 var browser$4 = PlatformDetection$1.detect().browser;
23181 var setupIeInput = function (editor) {
23182 var keypressThrotter = first(function () {
23183 if (!editor.composing) {
23184 normalizeNbspsInEditor(editor);
23185 }
23186 }, 0);
23187 if (browser$4.isIE()) {
23188 editor.on('keypress', function (e) {
23189 keypressThrotter.throttle();
23190 });
23191 editor.on('remove', function (e) {
23192 keypressThrotter.cancel();
23193 });
23194 }
23195 };
23196 var setup$d = function (editor) {
23197 setupIeInput(editor);
23198 editor.on('input', function (e) {
23199 if (e.isComposing === false) {
23200 normalizeNbspsInEditor(editor);
23201 }
23202 });
23203 };
23204
23205 var executeKeydownOverride$3 = function (editor, evt) {
23206 MatchKeys.execute([
23207 {
23208 keyCode: VK.END,
23209 action: moveToLineEndPoint(editor, true)
23210 },
23211 {
23212 keyCode: VK.HOME,
23213 action: moveToLineEndPoint(editor, false)
23214 }
23215 ], evt).each(function (_) {
23216 evt.preventDefault();
23217 });
23218 };
23219 var setup$e = function (editor) {
23220 editor.on('keydown', function (evt) {
23221 if (evt.isDefaultPrevented() === false) {
23222 executeKeydownOverride$3(editor, evt);
23223 }
23224 });
23225 };
23226 var HomeEndKeys = { setup: setup$e };
23227
23228 var setup$f = function (editor) {
23229 var caret = BoundarySelection.setupSelectedState(editor);
23230 CaretContainerInput.setup(editor);
23231 ArrowKeys.setup(editor, caret);
23232 DeleteBackspaceKeys.setup(editor, caret);
23233 EnterKey.setup(editor);
23234 SpaceKey.setup(editor);
23235 setup$d(editor);
23236 HomeEndKeys.setup(editor);
23237 };
23238 var KeyboardOverrides = { setup: setup$f };
23239
23240 var Quirks = function (editor) {
23241 var each = Tools.each;
23242 var BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE, dom = editor.dom, selection = editor.selection, settings = editor.settings, parser = editor.parser;
23243 var isGecko = Env.gecko, isIE = Env.ie, isWebKit = Env.webkit;
23244 var mceInternalUrlPrefix = 'data:text/mce-internal,';
23245 var mceInternalDataType = isIE ? 'Text' : 'URL';
23246 var setEditorCommandState = function (cmd, state) {
23247 try {
23248 editor.getDoc().execCommand(cmd, false, state);
23249 } catch (ex) {
23250 }
23251 };
23252 var isDefaultPrevented = function (e) {
23253 return e.isDefaultPrevented();
23254 };
23255 var setMceInternalContent = function (e) {
23256 var selectionHtml, internalContent;
23257 if (e.dataTransfer) {
23258 if (editor.selection.isCollapsed() && e.target.tagName === 'IMG') {
23259 selection.select(e.target);
23260 }
23261 selectionHtml = editor.selection.getContent();
23262 if (selectionHtml.length > 0) {
23263 internalContent = mceInternalUrlPrefix + escape(editor.id) + ',' + escape(selectionHtml);
23264 e.dataTransfer.setData(mceInternalDataType, internalContent);
23265 }
23266 }
23267 };
23268 var getMceInternalContent = function (e) {
23269 var internalContent;
23270 if (e.dataTransfer) {
23271 internalContent = e.dataTransfer.getData(mceInternalDataType);
23272 if (internalContent && internalContent.indexOf(mceInternalUrlPrefix) >= 0) {
23273 internalContent = internalContent.substr(mceInternalUrlPrefix.length).split(',');
23274 return {
23275 id: unescape(internalContent[0]),
23276 html: unescape(internalContent[1])
23277 };
23278 }
23279 }
23280 return null;
23281 };
23282 var insertClipboardContents = function (content, internal) {
23283 if (editor.queryCommandSupported('mceInsertClipboardContent')) {
23284 editor.execCommand('mceInsertClipboardContent', false, {
23285 content: content,
23286 internal: internal
23287 });
23288 } else {
23289 editor.execCommand('mceInsertContent', false, content);
23290 }
23291 };
23292 var emptyEditorWhenDeleting = function () {
23293 var serializeRng = function (rng) {
23294 var body = dom.create('body');
23295 var contents = rng.cloneContents();
23296 body.appendChild(contents);
23297 return selection.serializer.serialize(body, { format: 'html' });
23298 };
23299 var allContentsSelected = function (rng) {
23300 var selection = serializeRng(rng);
23301 var allRng = dom.createRng();
23302 allRng.selectNode(editor.getBody());
23303 var allSelection = serializeRng(allRng);
23304 return selection === allSelection;
23305 };
23306 editor.on('keydown', function (e) {
23307 var keyCode = e.keyCode;
23308 var isCollapsed, body;
23309 if (!isDefaultPrevented(e) && (keyCode === DELETE || keyCode === BACKSPACE)) {
23310 isCollapsed = editor.selection.isCollapsed();
23311 body = editor.getBody();
23312 if (isCollapsed && !dom.isEmpty(body)) {
23313 return;
23314 }
23315 if (!isCollapsed && !allContentsSelected(editor.selection.getRng())) {
23316 return;
23317 }
23318 e.preventDefault();
23319 editor.setContent('');
23320 if (body.firstChild && dom.isBlock(body.firstChild)) {
23321 editor.selection.setCursorLocation(body.firstChild, 0);
23322 } else {
23323 editor.selection.setCursorLocation(body, 0);
23324 }
23325 editor.nodeChanged();
23326 }
23327 });
23328 };
23329 var selectAll = function () {
23330 editor.shortcuts.add('meta+a', null, 'SelectAll');
23331 };
23332 var inputMethodFocus = function () {
23333 if (!editor.inline) {
23334 dom.bind(editor.getDoc(), 'mousedown mouseup', function (e) {
23335 var rng;
23336 if (e.target === editor.getDoc().documentElement) {
23337 rng = selection.getRng();
23338 editor.getBody().focus();
23339 if (e.type === 'mousedown') {
23340 if (isCaretContainer(rng.startContainer)) {
23341 return;
23342 }
23343 selection.placeCaretAt(e.clientX, e.clientY);
23344 } else {
23345 selection.setRng(rng);
23346 }
23347 }
23348 });
23349 }
23350 };
23351 var removeHrOnBackspace = function () {
23352 editor.on('keydown', function (e) {
23353 if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {
23354 if (!editor.getBody().getElementsByTagName('hr').length) {
23355 return;
23356 }
23357 if (selection.isCollapsed() && selection.getRng().startOffset === 0) {
23358 var node = selection.getNode();
23359 var previousSibling = node.previousSibling;
23360 if (node.nodeName === 'HR') {
23361 dom.remove(node);
23362 e.preventDefault();
23363 return;
23364 }
23365 if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === 'hr') {
23366 dom.remove(previousSibling);
23367 e.preventDefault();
23368 }
23369 }
23370 }
23371 });
23372 };
23373 var focusBody = function () {
23374 if (!domGlobals.Range.prototype.getClientRects) {
23375 editor.on('mousedown', function (e) {
23376 if (!isDefaultPrevented(e) && e.target.nodeName === 'HTML') {
23377 var body_1 = editor.getBody();
23378 body_1.blur();
23379 Delay.setEditorTimeout(editor, function () {
23380 body_1.focus();
23381 });
23382 }
23383 });
23384 }
23385 };
23386 var selectControlElements = function () {
23387 editor.on('click', function (e) {
23388 var target = e.target;
23389 if (/^(IMG|HR)$/.test(target.nodeName) && dom.getContentEditableParent(target) !== 'false') {
23390 e.preventDefault();
23391 editor.selection.select(target);
23392 editor.nodeChanged();
23393 }
23394 if (target.nodeName === 'A' && dom.hasClass(target, 'mce-item-anchor')) {
23395 e.preventDefault();
23396 selection.select(target);
23397 }
23398 });
23399 };
23400 var removeStylesWhenDeletingAcrossBlockElements = function () {
23401 var getAttributeApplyFunction = function () {
23402 var template = dom.getAttribs(selection.getStart().cloneNode(false));
23403 return function () {
23404 var target = selection.getStart();
23405 if (target !== editor.getBody()) {
23406 dom.setAttrib(target, 'style', null);
23407 each(template, function (attr) {
23408 target.setAttributeNode(attr.cloneNode(true));
23409 });
23410 }
23411 };
23412 };
23413 var isSelectionAcrossElements = function () {
23414 return !selection.isCollapsed() && dom.getParent(selection.getStart(), dom.isBlock) !== dom.getParent(selection.getEnd(), dom.isBlock);
23415 };
23416 editor.on('keypress', function (e) {
23417 var applyAttributes;
23418 if (!isDefaultPrevented(e) && (e.keyCode === 8 || e.keyCode === 46) && isSelectionAcrossElements()) {
23419 applyAttributes = getAttributeApplyFunction();
23420 editor.getDoc().execCommand('delete', false, null);
23421 applyAttributes();
23422 e.preventDefault();
23423 return false;
23424 }
23425 });
23426 dom.bind(editor.getDoc(), 'cut', function (e) {
23427 var applyAttributes;
23428 if (!isDefaultPrevented(e) && isSelectionAcrossElements()) {
23429 applyAttributes = getAttributeApplyFunction();
23430 Delay.setEditorTimeout(editor, function () {
23431 applyAttributes();
23432 });
23433 }
23434 });
23435 };
23436 var disableBackspaceIntoATable = function () {
23437 editor.on('keydown', function (e) {
23438 if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {
23439 if (selection.isCollapsed() && selection.getRng().startOffset === 0) {
23440 var previousSibling = selection.getNode().previousSibling;
23441 if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === 'table') {
23442 e.preventDefault();
23443 return false;
23444 }
23445 }
23446 }
23447 });
23448 };
23449 var removeBlockQuoteOnBackSpace = function () {
23450 editor.on('keydown', function (e) {
23451 var rng, container, offset, root, parent;
23452 if (isDefaultPrevented(e) || e.keyCode !== VK.BACKSPACE) {
23453 return;
23454 }
23455 rng = selection.getRng();
23456 container = rng.startContainer;
23457 offset = rng.startOffset;
23458 root = dom.getRoot();
23459 parent = container;
23460 if (!rng.collapsed || offset !== 0) {
23461 return;
23462 }
23463 while (parent && parent.parentNode && parent.parentNode.firstChild === parent && parent.parentNode !== root) {
23464 parent = parent.parentNode;
23465 }
23466 if (parent.tagName === 'BLOCKQUOTE') {
23467 editor.formatter.toggle('blockquote', null, parent);
23468 rng = dom.createRng();
23469 rng.setStart(container, 0);
23470 rng.setEnd(container, 0);
23471 selection.setRng(rng);
23472 }
23473 });
23474 };
23475 var setGeckoEditingOptions = function () {
23476 var setOpts = function () {
23477 setEditorCommandState('StyleWithCSS', false);
23478 setEditorCommandState('enableInlineTableEditing', false);
23479 if (!settings.object_resizing) {
23480 setEditorCommandState('enableObjectResizing', false);
23481 }
23482 };
23483 if (!settings.readonly) {
23484 editor.on('BeforeExecCommand mousedown', setOpts);
23485 }
23486 };
23487 var addBrAfterLastLinks = function () {
23488 var fixLinks = function () {
23489 each(dom.select('a'), function (node) {
23490 var parentNode = node.parentNode;
23491 var root = dom.getRoot();
23492 if (parentNode.lastChild === node) {
23493 while (parentNode && !dom.isBlock(parentNode)) {
23494 if (parentNode.parentNode.lastChild !== parentNode || parentNode === root) {
23495 return;
23496 }
23497 parentNode = parentNode.parentNode;
23498 }
23499 dom.add(parentNode, 'br', { 'data-mce-bogus': 1 });
23500 }
23501 });
23502 };
23503 editor.on('SetContent ExecCommand', function (e) {
23504 if (e.type === 'setcontent' || e.command === 'mceInsertLink') {
23505 fixLinks();
23506 }
23507 });
23508 };
23509 var setDefaultBlockType = function () {
23510 if (settings.forced_root_block) {
23511 editor.on('init', function () {
23512 setEditorCommandState('DefaultParagraphSeparator', Settings.getForcedRootBlock(editor));
23513 });
23514 }
23515 };
23516 var normalizeSelection = function () {
23517 editor.on('keyup focusin mouseup', function (e) {
23518 if (!VK.modifierPressed(e)) {
23519 selection.normalize();
23520 }
23521 }, true);
23522 };
23523 var showBrokenImageIcon = function () {
23524 editor.contentStyles.push('img:-moz-broken {' + '-moz-force-broken-image-icon:1;' + 'min-width:24px;' + 'min-height:24px' + '}');
23525 };
23526 var restoreFocusOnKeyDown = function () {
23527 if (!editor.inline) {
23528 editor.on('keydown', function () {
23529 if (domGlobals.document.activeElement === domGlobals.document.body) {
23530 editor.getWin().focus();
23531 }
23532 });
23533 }
23534 };
23535 var bodyHeight = function () {
23536 if (!editor.inline) {
23537 editor.contentStyles.push('body {min-height: 150px}');
23538 editor.on('click', function (e) {
23539 var rng;
23540 if (e.target.nodeName === 'HTML') {
23541 if (Env.ie > 11) {
23542 editor.getBody().focus();
23543 return;
23544 }
23545 rng = editor.selection.getRng();
23546 editor.getBody().focus();
23547 editor.selection.setRng(rng);
23548 editor.selection.normalize();
23549 editor.nodeChanged();
23550 }
23551 });
23552 }
23553 };
23554 var blockCmdArrowNavigation = function () {
23555 if (Env.mac) {
23556 editor.on('keydown', function (e) {
23557 if (VK.metaKeyPressed(e) && !e.shiftKey && (e.keyCode === 37 || e.keyCode === 39)) {
23558 e.preventDefault();
23559 var selection_1 = editor.selection.getSel();
23560 selection_1.modify('move', e.keyCode === 37 ? 'backward' : 'forward', 'lineboundary');
23561 }
23562 });
23563 }
23564 };
23565 var disableAutoUrlDetect = function () {
23566 setEditorCommandState('AutoUrlDetect', false);
23567 };
23568 var tapLinksAndImages = function () {
23569 editor.on('click', function (e) {
23570 var elm = e.target;
23571 do {
23572 if (elm.tagName === 'A') {
23573 e.preventDefault();
23574 return;
23575 }
23576 } while (elm = elm.parentNode);
23577 });
23578 editor.contentStyles.push('.mce-content-body {-webkit-touch-callout: none}');
23579 };
23580 var blockFormSubmitInsideEditor = function () {
23581 editor.on('init', function () {
23582 editor.dom.bind(editor.getBody(), 'submit', function (e) {
23583 e.preventDefault();
23584 });
23585 });
23586 };
23587 var removeAppleInterchangeBrs = function () {
23588 parser.addNodeFilter('br', function (nodes) {
23589 var i = nodes.length;
23590 while (i--) {
23591 if (nodes[i].attr('class') === 'Apple-interchange-newline') {
23592 nodes[i].remove();
23593 }
23594 }
23595 });
23596 };
23597 var ieInternalDragAndDrop = function () {
23598 editor.on('dragstart', function (e) {
23599 setMceInternalContent(e);
23600 });
23601 editor.on('drop', function (e) {
23602 if (!isDefaultPrevented(e)) {
23603 var internalContent = getMceInternalContent(e);
23604 if (internalContent && internalContent.id !== editor.id) {
23605 e.preventDefault();
23606 var rng = CaretRangeFromPoint.fromPoint(e.x, e.y, editor.getDoc());
23607 selection.setRng(rng);
23608 insertClipboardContents(internalContent.html, true);
23609 }
23610 }
23611 });
23612 };
23613 var refreshContentEditable = function () {
23614 };
23615 var isHidden = function () {
23616 var sel;
23617 if (!isGecko || editor.removed) {
23618 return false;
23619 }
23620 sel = editor.selection.getSel();
23621 return !sel || !sel.rangeCount || sel.rangeCount === 0;
23622 };
23623 removeBlockQuoteOnBackSpace();
23624 emptyEditorWhenDeleting();
23625 if (!Env.windowsPhone) {
23626 normalizeSelection();
23627 }
23628 if (isWebKit) {
23629 inputMethodFocus();
23630 selectControlElements();
23631 setDefaultBlockType();
23632 blockFormSubmitInsideEditor();
23633 disableBackspaceIntoATable();
23634 removeAppleInterchangeBrs();
23635 if (Env.iOS) {
23636 restoreFocusOnKeyDown();
23637 bodyHeight();
23638 tapLinksAndImages();
23639 } else {
23640 selectAll();
23641 }
23642 }
23643 if (Env.ie >= 11) {
23644 bodyHeight();
23645 disableBackspaceIntoATable();
23646 }
23647 if (Env.ie) {
23648 selectAll();
23649 disableAutoUrlDetect();
23650 ieInternalDragAndDrop();
23651 }
23652 if (isGecko) {
23653 removeHrOnBackspace();
23654 focusBody();
23655 removeStylesWhenDeletingAcrossBlockElements();
23656 setGeckoEditingOptions();
23657 addBrAfterLastLinks();
23658 showBrokenImageIcon();
23659 blockCmdArrowNavigation();
23660 disableBackspaceIntoATable();
23661 }
23662 return {
23663 refreshContentEditable: refreshContentEditable,
23664 isHidden: isHidden
23665 };
23666 };
23667
23668 var isTextBlockNode = function (node) {
23669 return NodeType.isElement(node) && isTextBlock(Element.fromDom(node));
23670 };
23671 var normalizeSelection$1 = function (editor) {
23672 var rng = editor.selection.getRng();
23673 var startPos = CaretPosition.fromRangeStart(rng);
23674 var endPos = CaretPosition.fromRangeEnd(rng);
23675 if (CaretPosition.isElementPosition(startPos)) {
23676 var container = startPos.container();
23677 if (isTextBlockNode(container)) {
23678 CaretFinder.firstPositionIn(container).each(function (pos) {
23679 return rng.setStart(pos.container(), pos.offset());
23680 });
23681 }
23682 }
23683 if (CaretPosition.isElementPosition(endPos)) {
23684 var container = startPos.container();
23685 if (isTextBlockNode(container)) {
23686 CaretFinder.lastPositionIn(container).each(function (pos) {
23687 return rng.setEnd(pos.container(), pos.offset());
23688 });
23689 }
23690 }
23691 editor.selection.setRng(RangeNormalizer.normalize(rng));
23692 };
23693 var setup$g = function (editor) {
23694 editor.on('click', function (e) {
23695 if (e.detail >= 3) {
23696 normalizeSelection$1(editor);
23697 }
23698 });
23699 };
23700
23701 var preventSummaryToggle = function (editor) {
23702 editor.on('click', function (e) {
23703 if (editor.dom.getParent(e.target, 'details')) {
23704 e.preventDefault();
23705 }
23706 });
23707 };
23708 var filterDetails = function (editor) {
23709 editor.parser.addNodeFilter('details', function (elms) {
23710 each(elms, function (details) {
23711 details.attr('data-mce-open', details.attr('open'));
23712 details.attr('open', 'open');
23713 });
23714 });
23715 editor.serializer.addNodeFilter('details', function (elms) {
23716 each(elms, function (details) {
23717 var open = details.attr('data-mce-open');
23718 details.attr('open', isString(open) ? open : null);
23719 details.attr('data-mce-open', null);
23720 });
23721 });
23722 };
23723 var setup$h = function (editor) {
23724 preventSummaryToggle(editor);
23725 filterDetails(editor);
23726 };
23727
23728 var DOM$3 = DOMUtils$1.DOM;
23729 var appendStyle = function (editor, text) {
23730 var head = Element.fromDom(editor.getDoc().head);
23731 var tag = Element.fromTag('style');
23732 set(tag, 'type', 'text/css');
23733 append(tag, Element.fromText(text));
23734 append(head, tag);
23735 };
23736 var createParser = function (editor) {
23737 var parser = DomParser(editor.settings, editor.schema);
23738 parser.addAttributeFilter('src,href,style,tabindex', function (nodes, name) {
23739 var i = nodes.length, node;
23740 var dom = editor.dom;
23741 var value, internalName;
23742 while (i--) {
23743 node = nodes[i];
23744 value = node.attr(name);
23745 internalName = 'data-mce-' + name;
23746 if (!node.attr(internalName)) {
23747 if (value.indexOf('data:') === 0 || value.indexOf('blob:') === 0) {
23748 continue;
23749 }
23750 if (name === 'style') {
23751 value = dom.serializeStyle(dom.parseStyle(value), node.name);
23752 if (!value.length) {
23753 value = null;
23754 }
23755 node.attr(internalName, value);
23756 node.attr(name, value);
23757 } else if (name === 'tabindex') {
23758 node.attr(internalName, value);
23759 node.attr(name, null);
23760 } else {
23761 node.attr(internalName, editor.convertURL(value, name, node.name));
23762 }
23763 }
23764 }
23765 });
23766 parser.addNodeFilter('script', function (nodes) {
23767 var i = nodes.length, node, type;
23768 while (i--) {
23769 node = nodes[i];
23770 type = node.attr('type') || 'no/type';
23771 if (type.indexOf('mce-') !== 0) {
23772 node.attr('type', 'mce-' + type);
23773 }
23774 }
23775 });
23776 parser.addNodeFilter('#cdata', function (nodes) {
23777 var i = nodes.length, node;
23778 while (i--) {
23779 node = nodes[i];
23780 node.type = 8;
23781 node.name = '#comment';
23782 node.value = '[CDATA[' + node.value + ']]';
23783 }
23784 });
23785 parser.addNodeFilter('p,h1,h2,h3,h4,h5,h6,div', function (nodes) {
23786 var i = nodes.length, node;
23787 var nonEmptyElements = editor.schema.getNonEmptyElements();
23788 while (i--) {
23789 node = nodes[i];
23790 if (node.isEmpty(nonEmptyElements) && node.getAll('br').length === 0) {
23791 node.append(new Node$1('br', 1)).shortEnded = true;
23792 }
23793 }
23794 });
23795 return parser;
23796 };
23797 var autoFocus = function (editor) {
23798 if (editor.settings.auto_focus) {
23799 Delay.setEditorTimeout(editor, function () {
23800 var focusEditor;
23801 if (editor.settings.auto_focus === true) {
23802 focusEditor = editor;
23803 } else {
23804 focusEditor = editor.editorManager.get(editor.settings.auto_focus);
23805 }
23806 if (!focusEditor.destroyed) {
23807 focusEditor.focus();
23808 }
23809 }, 100);
23810 }
23811 };
23812 var initEditor = function (editor) {
23813 editor.bindPendingEventDelegates();
23814 editor.initialized = true;
23815 editor.fire('init');
23816 editor.focus(true);
23817 editor.nodeChanged({ initial: true });
23818 editor.execCallback('init_instance_callback', editor);
23819 autoFocus(editor);
23820 };
23821 var getStyleSheetLoader = function (editor) {
23822 return editor.inline ? DOM$3.styleSheetLoader : editor.dom.styleSheetLoader;
23823 };
23824 var initContentBody = function (editor, skipWrite) {
23825 var settings = editor.settings;
23826 var targetElm = editor.getElement();
23827 var doc = editor.getDoc(), body, contentCssText;
23828 if (!settings.inline) {
23829 editor.getElement().style.visibility = editor.orgVisibility;
23830 }
23831 if (!skipWrite && !editor.inline) {
23832 doc.open();
23833 doc.write(editor.iframeHTML);
23834 doc.close();
23835 }
23836 if (editor.inline) {
23837 editor.on('remove', function () {
23838 var bodyEl = this.getBody();
23839 DOM$3.removeClass(bodyEl, 'mce-content-body');
23840 DOM$3.removeClass(bodyEl, 'mce-edit-focus');
23841 DOM$3.setAttrib(bodyEl, 'contentEditable', null);
23842 });
23843 DOM$3.addClass(targetElm, 'mce-content-body');
23844 editor.contentDocument = doc = domGlobals.document;
23845 editor.contentWindow = domGlobals.window;
23846 editor.bodyElement = targetElm;
23847 editor.contentAreaContainer = targetElm;
23848 settings.root_name = targetElm.nodeName.toLowerCase();
23849 }
23850 body = editor.getBody();
23851 body.disabled = true;
23852 editor.readonly = settings.readonly;
23853 if (!editor.readonly) {
23854 if (editor.inline && DOM$3.getStyle(body, 'position', true) === 'static') {
23855 body.style.position = 'relative';
23856 }
23857 body.contentEditable = editor.getParam('content_editable_state', true);
23858 }
23859 body.disabled = false;
23860 editor.editorUpload = EditorUpload(editor);
23861 editor.schema = Schema(settings);
23862 editor.dom = DOMUtils$1(doc, {
23863 keep_values: true,
23864 url_converter: editor.convertURL,
23865 url_converter_scope: editor,
23866 hex_colors: settings.force_hex_style_colors,
23867 update_styles: true,
23868 root_element: editor.inline ? editor.getBody() : null,
23869 collect: function () {
23870 return editor.inline;
23871 },
23872 schema: editor.schema,
23873 contentCssCors: Settings.shouldUseContentCssCors(editor),
23874 onSetAttrib: function (e) {
23875 editor.fire('SetAttrib', e);
23876 }
23877 });
23878 editor.parser = createParser(editor);
23879 editor.serializer = Serializer$1(settings, editor);
23880 editor.selection = Selection$1(editor.dom, editor.getWin(), editor.serializer, editor);
23881 editor.annotator = Annotator(editor);
23882 editor.formatter = Formatter(editor);
23883 editor.undoManager = UndoManager(editor);
23884 editor._nodeChangeDispatcher = new NodeChange(editor);
23885 editor._selectionOverrides = SelectionOverrides(editor);
23886 setup$h(editor);
23887 setup$g(editor);
23888 KeyboardOverrides.setup(editor);
23889 ForceBlocks.setup(editor);
23890 editor.fire('PreInit');
23891 if (!settings.browser_spellcheck && !settings.gecko_spellcheck) {
23892 doc.body.spellcheck = false;
23893 DOM$3.setAttrib(body, 'spellcheck', 'false');
23894 }
23895 editor.quirks = Quirks(editor);
23896 editor.fire('PostRender');
23897 var directionality = Settings.getDirectionality(editor);
23898 if (directionality !== undefined) {
23899 body.dir = directionality;
23900 }
23901 if (settings.protect) {
23902 editor.on('BeforeSetContent', function (e) {
23903 Tools.each(settings.protect, function (pattern) {
23904 e.content = e.content.replace(pattern, function (str) {
23905 return '<!--mce:protected ' + escape(str) + '-->';
23906 });
23907 });
23908 });
23909 }
23910 editor.on('SetContent', function () {
23911 editor.addVisual(editor.getBody());
23912 });
23913 editor.load({
23914 initial: true,
23915 format: 'html'
23916 });
23917 editor.startContent = editor.getContent({ format: 'raw' });
23918 editor.on('compositionstart compositionend', function (e) {
23919 editor.composing = e.type === 'compositionstart';
23920 });
23921 if (editor.contentStyles.length > 0) {
23922 contentCssText = '';
23923 Tools.each(editor.contentStyles, function (style) {
23924 contentCssText += style + '\r\n';
23925 });
23926 editor.dom.addStyle(contentCssText);
23927 }
23928 getStyleSheetLoader(editor).loadAll(editor.contentCSS, function (_) {
23929 initEditor(editor);
23930 }, function (urls) {
23931 initEditor(editor);
23932 });
23933 if (settings.content_style) {
23934 appendStyle(editor, settings.content_style);
23935 }
23936 };
23937 var InitContentBody = { initContentBody: initContentBody };
23938
23939 var DOM$4 = DOMUtils$1.DOM;
23940 var relaxDomain = function (editor, ifr) {
23941 if (domGlobals.document.domain !== domGlobals.window.location.hostname && Env.ie && Env.ie < 12) {
23942 var bodyUuid = Uuid.uuid('mce');
23943 editor[bodyUuid] = function () {
23944 InitContentBody.initContentBody(editor);
23945 };
23946 var domainRelaxUrl = 'javascript:(function(){' + 'document.open();document.domain="' + domGlobals.document.domain + '";' + 'var ed = window.parent.tinymce.get("' + editor.id + '");document.write(ed.iframeHTML);' + 'document.close();ed.' + bodyUuid + '(true);})()';
23947 DOM$4.setAttrib(ifr, 'src', domainRelaxUrl);
23948 return true;
23949 }
23950 return false;
23951 };
23952 var createIframeElement = function (id, title, height, customAttrs) {
23953 var iframe = Element.fromTag('iframe');
23954 setAll(iframe, customAttrs);
23955 setAll(iframe, {
23956 id: id + '_ifr',
23957 frameBorder: '0',
23958 allowTransparency: 'true',
23959 title: title
23960 });
23961 add$3(iframe, 'tox-edit-area__iframe');
23962 return iframe;
23963 };
23964 var getIframeHtml = function (editor) {
23965 var bodyId, bodyClass, iframeHTML;
23966 iframeHTML = Settings.getDocType(editor) + '<html><head>';
23967 if (Settings.getDocumentBaseUrl(editor) !== editor.documentBaseUrl) {
23968 iframeHTML += '<base href="' + editor.documentBaseURI.getURI() + '" />';
23969 }
23970 iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
23971 bodyId = Settings.getBodyId(editor);
23972 bodyClass = Settings.getBodyClass(editor);
23973 if (Settings.getContentSecurityPolicy(editor)) {
23974 iframeHTML += '<meta http-equiv="Content-Security-Policy" content="' + Settings.getContentSecurityPolicy(editor) + '" />';
23975 }
23976 iframeHTML += '</head><body id="' + bodyId + '" class="mce-content-body ' + bodyClass + '" data-id="' + editor.id + '"><br></body></html>';
23977 return iframeHTML;
23978 };
23979 var createIframe = function (editor, o) {
23980 var title = editor.editorManager.translate('Rich Text Area. Press ALT-0 for help.');
23981 var ifr = createIframeElement(editor.id, title, o.height, Settings.getIframeAttrs(editor)).dom();
23982 ifr.onload = function () {
23983 ifr.onload = null;
23984 editor.fire('load');
23985 };
23986 var isDomainRelaxed = relaxDomain(editor, ifr);
23987 editor.contentAreaContainer = o.iframeContainer;
23988 editor.iframeElement = ifr;
23989 editor.iframeHTML = getIframeHtml(editor);
23990 DOM$4.add(o.iframeContainer, ifr);
23991 return isDomainRelaxed;
23992 };
23993 var init$1 = function (editor, boxInfo) {
23994 var isDomainRelaxed = createIframe(editor, boxInfo);
23995 if (boxInfo.editorContainer) {
23996 DOM$4.get(boxInfo.editorContainer).style.display = editor.orgDisplay;
23997 editor.hidden = DOM$4.isHidden(boxInfo.editorContainer);
23998 }
23999 editor.getElement().style.display = 'none';
24000 DOM$4.setAttrib(editor.id, 'aria-hidden', 'true');
24001 if (!isDomainRelaxed) {
24002 InitContentBody.initContentBody(editor);
24003 }
24004 };
24005 var InitIframe = { init: init$1 };
24006
24007 var isContentCssSkinName = function (url) {
24008 return /^[a-z0-9\-]+$/i.test(url);
24009 };
24010 var getContentCssUrls = function (editor) {
24011 var contentCss = Settings.getContentCss(editor);
24012 var skinUrl = editor.editorManager.baseURL + '/skins/content';
24013 var suffix = editor.editorManager.suffix;
24014 var contentCssFile = 'content' + suffix + '.css';
24015 var inline = editor.inline === true;
24016 return map(contentCss, function (url) {
24017 if (isContentCssSkinName(url) && !inline) {
24018 return skinUrl + '/' + url + '/' + contentCssFile;
24019 } else {
24020 return editor.documentBaseURI.toAbsolute(url);
24021 }
24022 });
24023 };
24024 var appendContentCssFromSettings = function (editor) {
24025 editor.contentCSS = editor.contentCSS.concat(getContentCssUrls(editor));
24026 };
24027
24028 var DOM$5 = DOMUtils$1.DOM;
24029 var initPlugin = function (editor, initializedPlugins, plugin) {
24030 var Plugin = PluginManager.get(plugin);
24031 var pluginUrl = PluginManager.urls[plugin] || editor.documentBaseUrl.replace(/\/$/, '');
24032 plugin = Tools.trim(plugin);
24033 if (Plugin && Tools.inArray(initializedPlugins, plugin) === -1) {
24034 Tools.each(PluginManager.dependencies(plugin), function (dep) {
24035 initPlugin(editor, initializedPlugins, dep);
24036 });
24037 if (editor.plugins[plugin]) {
24038 return;
24039 }
24040 try {
24041 var pluginInstance = new Plugin(editor, pluginUrl, editor.$);
24042 editor.plugins[plugin] = pluginInstance;
24043 if (pluginInstance.init) {
24044 pluginInstance.init(editor, pluginUrl);
24045 initializedPlugins.push(plugin);
24046 }
24047 } catch (e) {
24048 ErrorReporter.pluginInitError(editor, plugin, e);
24049 }
24050 }
24051 };
24052 var trimLegacyPrefix = function (name) {
24053 return name.replace(/^\-/, '');
24054 };
24055 var initPlugins = function (editor) {
24056 var initializedPlugins = [];
24057 Tools.each(editor.settings.plugins.split(/[ ,]/), function (name) {
24058 initPlugin(editor, initializedPlugins, trimLegacyPrefix(name));
24059 });
24060 };
24061 var initIcons = function (editor) {
24062 var iconPackName = Tools.trim(editor.settings.icons);
24063 var currentIcons = editor.ui.registry.getAll().icons;
24064 var defaultIcons = getAll();
24065 var loadIcons = __assign({}, defaultIcons, IconManager.get(iconPackName).icons);
24066 each$3(loadIcons, function (svgData, icon) {
24067 if (!has(currentIcons, icon)) {
24068 editor.ui.registry.addIcon(icon, svgData);
24069 }
24070 });
24071 };
24072 var initTheme = function (editor) {
24073 var theme = editor.settings.theme;
24074 if (isString(theme)) {
24075 editor.settings.theme = trimLegacyPrefix(theme);
24076 var Theme = ThemeManager.get(theme);
24077 editor.theme = new Theme(editor, ThemeManager.urls[theme]);
24078 if (editor.theme.init) {
24079 editor.theme.init(editor, ThemeManager.urls[theme] || editor.documentBaseUrl.replace(/\/$/, ''), editor.$);
24080 }
24081 } else {
24082 editor.theme = {};
24083 }
24084 };
24085 var renderFromLoadedTheme = function (editor) {
24086 return editor.theme.renderUI();
24087 };
24088 var renderFromThemeFunc = function (editor) {
24089 var elm = editor.getElement();
24090 var theme = editor.settings.theme;
24091 var info = theme(editor, elm);
24092 if (info.editorContainer.nodeType) {
24093 info.editorContainer.id = info.editorContainer.id || editor.id + '_parent';
24094 }
24095 if (info.iframeContainer && info.iframeContainer.nodeType) {
24096 info.iframeContainer.id = info.iframeContainer.id || editor.id + '_iframecontainer';
24097 }
24098 info.height = info.iframeHeight ? info.iframeHeight : elm.offsetHeight;
24099 return info;
24100 };
24101 var createThemeFalseResult = function (element) {
24102 return {
24103 editorContainer: element,
24104 iframeContainer: element
24105 };
24106 };
24107 var renderThemeFalseIframe = function (targetElement) {
24108 var iframeContainer = DOM$5.create('div');
24109 DOM$5.insertAfter(iframeContainer, targetElement);
24110 return createThemeFalseResult(iframeContainer);
24111 };
24112 var renderThemeFalse = function (editor) {
24113 var targetElement = editor.getElement();
24114 return editor.inline ? createThemeFalseResult(null) : renderThemeFalseIframe(targetElement);
24115 };
24116 var renderThemeUi = function (editor) {
24117 var elm = editor.getElement();
24118 editor.orgDisplay = elm.style.display;
24119 if (isString(editor.settings.theme)) {
24120 return renderFromLoadedTheme(editor);
24121 } else if (isFunction(editor.settings.theme)) {
24122 return renderFromThemeFunc(editor);
24123 } else {
24124 return renderThemeFalse(editor);
24125 }
24126 };
24127 var init$2 = function (editor) {
24128 editor.fire('ScriptsLoaded');
24129 initIcons(editor);
24130 initTheme(editor);
24131 initPlugins(editor);
24132 var boxInfo = renderThemeUi(editor);
24133 editor.editorContainer = boxInfo.editorContainer ? boxInfo.editorContainer : null;
24134 appendContentCssFromSettings(editor);
24135 if (editor.inline) {
24136 return InitContentBody.initContentBody(editor);
24137 } else {
24138 return InitIframe.init(editor, boxInfo);
24139 }
24140 };
24141 var Init = { init: init$2 };
24142
24143 var DOM$6 = DOMUtils$1.DOM;
24144 var hasSkipLoadPrefix = function (name) {
24145 return name.charAt(0) === '-';
24146 };
24147 var loadLanguage = function (scriptLoader, editor) {
24148 var languageCode = Settings.getLanguageCode(editor);
24149 var languageUrl = Settings.getLanguageUrl(editor);
24150 if (I18n.hasCode(languageCode) === false && languageCode !== 'en') {
24151 var url_1 = languageUrl !== '' ? languageUrl : editor.editorManager.baseURL + '/langs/' + languageCode + '.js';
24152 scriptLoader.add(url_1, noop, undefined, function () {
24153 ErrorReporter.languageLoadError(url_1, languageCode);
24154 });
24155 }
24156 };
24157 var loadTheme = function (scriptLoader, editor, suffix, callback) {
24158 var settings = editor.settings, theme = settings.theme;
24159 if (isString(theme)) {
24160 if (!hasSkipLoadPrefix(theme) && !ThemeManager.urls.hasOwnProperty(theme)) {
24161 var themeUrl = settings.theme_url;
24162 if (themeUrl) {
24163 ThemeManager.load(theme, editor.documentBaseURI.toAbsolute(themeUrl));
24164 } else {
24165 ThemeManager.load(theme, 'themes/' + theme + '/theme' + suffix + '.js');
24166 }
24167 }
24168 scriptLoader.loadQueue(function () {
24169 ThemeManager.waitFor(theme, callback);
24170 });
24171 } else {
24172 callback();
24173 }
24174 };
24175 var getIconsUrlMetaFromUrl = function (editor) {
24176 return Option.from(Settings.getIconsUrl(editor)).filter(function (url) {
24177 return url.length > 0;
24178 }).map(function (url) {
24179 return {
24180 url: url,
24181 name: Option.none()
24182 };
24183 });
24184 };
24185 var getIconsUrlMetaFromName = function (editor) {
24186 return Option.from(Settings.getIconPackName(editor)).filter(function (name) {
24187 return name.length > 0 && !IconManager.has(name);
24188 }).map(function (name) {
24189 return {
24190 url: editor.editorManager.baseURL + '/icons/' + name + '/icons.js',
24191 name: Option.some(name)
24192 };
24193 });
24194 };
24195 var loadIcons = function (scriptLoader, editor) {
24196 getIconsUrlMetaFromUrl(editor).orThunk(function () {
24197 return getIconsUrlMetaFromName(editor);
24198 }).each(function (urlMeta) {
24199 scriptLoader.add(urlMeta.url, noop, undefined, function () {
24200 ErrorReporter.iconsLoadError(urlMeta.url, urlMeta.name.getOrUndefined());
24201 });
24202 });
24203 };
24204 var loadPlugins = function (settings, suffix) {
24205 if (isArray(settings.plugins)) {
24206 settings.plugins = settings.plugins.join(' ');
24207 }
24208 Tools.each(settings.external_plugins, function (url, name) {
24209 PluginManager.load(name, url, noop, undefined, function () {
24210 ErrorReporter.pluginLoadError(name, url);
24211 });
24212 settings.plugins += ' ' + name;
24213 });
24214 Tools.each(settings.plugins.split(/[ ,]/), function (plugin) {
24215 plugin = Tools.trim(plugin);
24216 if (plugin && !PluginManager.urls[plugin]) {
24217 if (hasSkipLoadPrefix(plugin)) {
24218 plugin = plugin.substr(1, plugin.length);
24219 var dependencies = PluginManager.dependencies(plugin);
24220 Tools.each(dependencies, function (dep) {
24221 var defaultSettings = {
24222 prefix: 'plugins/',
24223 resource: dep,
24224 suffix: '/plugin' + suffix + '.js'
24225 };
24226 dep = PluginManager.createUrl(defaultSettings, dep);
24227 PluginManager.load(dep.resource, dep, noop, undefined, function () {
24228 ErrorReporter.pluginLoadError(dep.prefix + dep.resource + dep.suffix, dep.resource);
24229 });
24230 });
24231 } else {
24232 var url_2 = {
24233 prefix: 'plugins/',
24234 resource: plugin,
24235 suffix: '/plugin' + suffix + '.js'
24236 };
24237 PluginManager.load(plugin, url_2, noop, undefined, function () {
24238 ErrorReporter.pluginLoadError(url_2.prefix + url_2.resource + url_2.suffix, plugin);
24239 });
24240 }
24241 }
24242 });
24243 };
24244 var loadScripts = function (editor, suffix) {
24245 var scriptLoader = ScriptLoader.ScriptLoader;
24246 loadTheme(scriptLoader, editor, suffix, function () {
24247 loadLanguage(scriptLoader, editor);
24248 loadIcons(scriptLoader, editor);
24249 loadPlugins(editor.settings, suffix);
24250 scriptLoader.loadQueue(function () {
24251 if (!editor.removed) {
24252 Init.init(editor);
24253 }
24254 }, editor, function () {
24255 if (!editor.removed) {
24256 Init.init(editor);
24257 }
24258 });
24259 });
24260 };
24261 var render = function (editor) {
24262 var settings = editor.settings, id = editor.id;
24263 I18n.setCode(Settings.getLanguageCode(editor));
24264 var readyHandler = function () {
24265 DOM$6.unbind(domGlobals.window, 'ready', readyHandler);
24266 editor.render();
24267 };
24268 if (!EventUtils.Event.domLoaded) {
24269 DOM$6.bind(domGlobals.window, 'ready', readyHandler);
24270 return;
24271 }
24272 if (!editor.getElement()) {
24273 return;
24274 }
24275 if (!Env.contentEditable) {
24276 return;
24277 }
24278 if (!settings.inline) {
24279 editor.orgVisibility = editor.getElement().style.visibility;
24280 editor.getElement().style.visibility = 'hidden';
24281 } else {
24282 editor.inline = true;
24283 }
24284 var form = editor.getElement().form || DOM$6.getParent(id, 'form');
24285 if (form) {
24286 editor.formElement = form;
24287 if (settings.hidden_input && !NodeType.isTextareaOrInput(editor.getElement())) {
24288 DOM$6.insertAfter(DOM$6.create('input', {
24289 type: 'hidden',
24290 name: id
24291 }), id);
24292 editor.hasHiddenInput = true;
24293 }
24294 editor.formEventDelegate = function (e) {
24295 editor.fire(e.type, e);
24296 };
24297 DOM$6.bind(form, 'submit reset', editor.formEventDelegate);
24298 editor.on('reset', function () {
24299 editor.resetContent();
24300 });
24301 if (settings.submit_patch && !form.submit.nodeType && !form.submit.length && !form._mceOldSubmit) {
24302 form._mceOldSubmit = form.submit;
24303 form.submit = function () {
24304 editor.editorManager.triggerSave();
24305 editor.setDirty(false);
24306 return form._mceOldSubmit(form);
24307 };
24308 }
24309 }
24310 editor.windowManager = WindowManager(editor);
24311 editor.notificationManager = NotificationManager(editor);
24312 if (settings.encoding === 'xml') {
24313 editor.on('GetContent', function (e) {
24314 if (e.save) {
24315 e.content = DOM$6.encode(e.content);
24316 }
24317 });
24318 }
24319 if (settings.add_form_submit_trigger) {
24320 editor.on('submit', function () {
24321 if (editor.initialized) {
24322 editor.save();
24323 }
24324 });
24325 }
24326 if (settings.add_unload_trigger) {
24327 editor._beforeUnload = function () {
24328 if (editor.initialized && !editor.destroyed && !editor.isHidden()) {
24329 editor.save({
24330 format: 'raw',
24331 no_events: true,
24332 set_dirty: false
24333 });
24334 }
24335 };
24336 editor.editorManager.on('BeforeUnload', editor._beforeUnload);
24337 }
24338 editor.editorManager.add(editor);
24339 loadScripts(editor, editor.suffix);
24340 };
24341 var Render = { render: render };
24342
24343 var internalContentEditableAttr = 'data-mce-contenteditable';
24344 var toggleClass = function (elm, cls, state) {
24345 if (has$2(elm, cls) && state === false) {
24346 remove$4(elm, cls);
24347 } else if (state) {
24348 add$3(elm, cls);
24349 }
24350 };
24351 var setEditorCommandState = function (editor, cmd, state) {
24352 try {
24353 editor.getDoc().execCommand(cmd, false, state);
24354 } catch (ex) {
24355 }
24356 };
24357 var setContentEditable = function (elm, state) {
24358 elm.dom().contentEditable = state ? 'true' : 'false';
24359 };
24360 var switchOffContentEditableTrue = function (elm) {
24361 each(descendants$1(elm, '*[contenteditable="true"]'), function (elm) {
24362 set(elm, internalContentEditableAttr, 'true');
24363 setContentEditable(elm, false);
24364 });
24365 };
24366 var switchOnContentEditableTrue = function (elm) {
24367 each(descendants$1(elm, '*[' + internalContentEditableAttr + '="true"]'), function (elm) {
24368 remove(elm, internalContentEditableAttr);
24369 setContentEditable(elm, true);
24370 });
24371 };
24372 var removeFakeSelection = function (editor) {
24373 Option.from(editor.selection.getNode()).each(function (elm) {
24374 elm.removeAttribute('data-mce-selected');
24375 });
24376 };
24377 var restoreFakeSelection = function (editor) {
24378 editor.selection.setRng(editor.selection.getRng());
24379 };
24380 var toggleReadOnly = function (editor, state) {
24381 var body = Element.fromDom(editor.getBody());
24382 toggleClass(body, 'mce-content-readonly', state);
24383 if (state) {
24384 editor.selection.controlSelection.hideResizeRect();
24385 editor._selectionOverrides.hideFakeCaret();
24386 removeFakeSelection(editor);
24387 editor.readonly = true;
24388 setContentEditable(body, false);
24389 switchOffContentEditableTrue(body);
24390 } else {
24391 editor.readonly = false;
24392 setContentEditable(body, true);
24393 switchOnContentEditableTrue(body);
24394 setEditorCommandState(editor, 'StyleWithCSS', false);
24395 setEditorCommandState(editor, 'enableInlineTableEditing', false);
24396 setEditorCommandState(editor, 'enableObjectResizing', false);
24397 if (EditorFocus.hasEditorOrUiFocus(editor)) {
24398 editor.focus();
24399 }
24400 restoreFakeSelection(editor);
24401 editor.nodeChanged();
24402 }
24403 };
24404 var isReadOnly = function (editor) {
24405 return editor.readonly === true;
24406 };
24407 var registerFilters = function (editor) {
24408 editor.parser.addAttributeFilter('contenteditable', function (nodes) {
24409 if (isReadOnly(editor)) {
24410 each(nodes, function (node) {
24411 node.attr(internalContentEditableAttr, node.attr('contenteditable'));
24412 node.attr('contenteditable', 'false');
24413 });
24414 }
24415 });
24416 editor.serializer.addAttributeFilter(internalContentEditableAttr, function (nodes) {
24417 if (isReadOnly(editor)) {
24418 each(nodes, function (node) {
24419 node.attr('contenteditable', node.attr(internalContentEditableAttr));
24420 });
24421 }
24422 });
24423 editor.serializer.addTempAttr(internalContentEditableAttr);
24424 };
24425 var registerReadOnlyContentFilters = function (editor) {
24426 if (editor.serializer) {
24427 registerFilters(editor);
24428 } else {
24429 editor.on('PreInit', function () {
24430 registerFilters(editor);
24431 });
24432 }
24433 };
24434 var preventReadOnlyEvents = function (e) {
24435 var target = e.target;
24436 if (e.type === 'click' && target.tagName === 'A') {
24437 e.preventDefault();
24438 }
24439 };
24440 var registerReadOnlySelectionBlockers = function (editor) {
24441 editor.on('ShowCaret', function (e) {
24442 if (isReadOnly(editor)) {
24443 e.preventDefault();
24444 }
24445 });
24446 editor.on('ObjectSelected', function (e) {
24447 if (isReadOnly(editor)) {
24448 e.preventDefault();
24449 }
24450 });
24451 };
24452
24453 var defaultModes = [
24454 'design',
24455 'readonly'
24456 ];
24457 var switchToMode = function (editor, activeMode, availableModes, mode) {
24458 var oldMode = availableModes[activeMode.get()];
24459 var newMode = availableModes[mode];
24460 try {
24461 newMode.activate();
24462 } catch (e) {
24463 domGlobals.console.error('problem while activating editor mode ' + mode + ':', e);
24464 return;
24465 }
24466 oldMode.deactivate();
24467 if (oldMode.editorReadOnly !== newMode.editorReadOnly) {
24468 toggleReadOnly(editor, newMode.editorReadOnly);
24469 }
24470 activeMode.set(mode);
24471 Events.fireSwitchMode(editor, mode);
24472 };
24473 var setMode = function (editor, availableModes, activeMode, mode) {
24474 if (mode === activeMode.get()) {
24475 return;
24476 } else if (!has(availableModes, mode)) {
24477 throw new Error('Editor mode \'' + mode + '\' is invalid');
24478 }
24479 if (editor.initialized) {
24480 switchToMode(editor, activeMode, availableModes, mode);
24481 } else {
24482 editor.on('init', function () {
24483 return switchToMode(editor, activeMode, availableModes, mode);
24484 });
24485 }
24486 };
24487 var registerMode = function (availableModes, mode, api) {
24488 var _a;
24489 if (contains(defaultModes, mode)) {
24490 throw new Error('Cannot override default mode ' + mode);
24491 }
24492 return __assign({}, availableModes, (_a = {}, _a[mode] = __assign({}, api, {
24493 deactivate: function () {
24494 try {
24495 api.deactivate();
24496 } catch (e) {
24497 domGlobals.console.error('problem while deactivating editor mode ' + mode + ':', e);
24498 }
24499 }
24500 }), _a));
24501 };
24502
24503 var create$4 = function (editor) {
24504 var activeMode = Cell('design');
24505 var availableModes = Cell({
24506 design: {
24507 activate: noop,
24508 deactivate: noop,
24509 editorReadOnly: false
24510 },
24511 readonly: {
24512 activate: noop,
24513 deactivate: noop,
24514 editorReadOnly: true
24515 }
24516 });
24517 registerReadOnlyContentFilters(editor);
24518 registerReadOnlySelectionBlockers(editor);
24519 return {
24520 isReadOnly: function () {
24521 return isReadOnly(editor);
24522 },
24523 set: function (mode) {
24524 return setMode(editor, availableModes.get(), activeMode, mode);
24525 },
24526 get: function () {
24527 return activeMode.get();
24528 },
24529 register: function (mode, api) {
24530 availableModes.set(registerMode(availableModes.get(), mode, api));
24531 }
24532 };
24533 };
24534
24535 var hasOnlyOneChild$1 = function (node) {
24536 return node.firstChild && node.firstChild === node.lastChild;
24537 };
24538 var isPaddingNode = function (node) {
24539 return node.name === 'br' || node.value === '\xA0';
24540 };
24541 var isPaddedEmptyBlock = function (schema, node) {
24542 var blockElements = schema.getBlockElements();
24543 return blockElements[node.name] && hasOnlyOneChild$1(node) && isPaddingNode(node.firstChild);
24544 };
24545 var isEmptyFragmentElement = function (schema, node) {
24546 var nonEmptyElements = schema.getNonEmptyElements();
24547 return node && (node.isEmpty(nonEmptyElements) || isPaddedEmptyBlock(schema, node));
24548 };
24549 var isListFragment = function (schema, fragment) {
24550 var firstChild = fragment.firstChild;
24551 var lastChild = fragment.lastChild;
24552 if (firstChild && firstChild.name === 'meta') {
24553 firstChild = firstChild.next;
24554 }
24555 if (lastChild && lastChild.attr('id') === 'mce_marker') {
24556 lastChild = lastChild.prev;
24557 }
24558 if (isEmptyFragmentElement(schema, lastChild)) {
24559 lastChild = lastChild.prev;
24560 }
24561 if (!firstChild || firstChild !== lastChild) {
24562 return false;
24563 }
24564 return firstChild.name === 'ul' || firstChild.name === 'ol';
24565 };
24566 var cleanupDomFragment = function (domFragment) {
24567 var firstChild = domFragment.firstChild;
24568 var lastChild = domFragment.lastChild;
24569 if (firstChild && firstChild.nodeName === 'META') {
24570 firstChild.parentNode.removeChild(firstChild);
24571 }
24572 if (lastChild && lastChild.id === 'mce_marker') {
24573 lastChild.parentNode.removeChild(lastChild);
24574 }
24575 return domFragment;
24576 };
24577 var toDomFragment = function (dom, serializer, fragment) {
24578 var html = serializer.serialize(fragment);
24579 var domFragment = dom.createFragment(html);
24580 return cleanupDomFragment(domFragment);
24581 };
24582 var listItems$1 = function (elm) {
24583 return Tools.grep(elm.childNodes, function (child) {
24584 return child.nodeName === 'LI';
24585 });
24586 };
24587 var isPadding = function (node) {
24588 return node.data === '\xA0' || NodeType.isBr(node);
24589 };
24590 var isListItemPadded = function (node) {
24591 return node && node.firstChild && node.firstChild === node.lastChild && isPadding(node.firstChild);
24592 };
24593 var isEmptyOrPadded = function (elm) {
24594 return !elm.firstChild || isListItemPadded(elm);
24595 };
24596 var trimListItems = function (elms) {
24597 return elms.length > 0 && isEmptyOrPadded(elms[elms.length - 1]) ? elms.slice(0, -1) : elms;
24598 };
24599 var getParentLi = function (dom, node) {
24600 var parentBlock = dom.getParent(node, dom.isBlock);
24601 return parentBlock && parentBlock.nodeName === 'LI' ? parentBlock : null;
24602 };
24603 var isParentBlockLi = function (dom, node) {
24604 return !!getParentLi(dom, node);
24605 };
24606 var getSplit = function (parentNode, rng) {
24607 var beforeRng = rng.cloneRange();
24608 var afterRng = rng.cloneRange();
24609 beforeRng.setStartBefore(parentNode);
24610 afterRng.setEndAfter(parentNode);
24611 return [
24612 beforeRng.cloneContents(),
24613 afterRng.cloneContents()
24614 ];
24615 };
24616 var findFirstIn = function (node, rootNode) {
24617 var caretPos = CaretPosition$1.before(node);
24618 var caretWalker = CaretWalker(rootNode);
24619 var newCaretPos = caretWalker.next(caretPos);
24620 return newCaretPos ? newCaretPos.toRange() : null;
24621 };
24622 var findLastOf = function (node, rootNode) {
24623 var caretPos = CaretPosition$1.after(node);
24624 var caretWalker = CaretWalker(rootNode);
24625 var newCaretPos = caretWalker.prev(caretPos);
24626 return newCaretPos ? newCaretPos.toRange() : null;
24627 };
24628 var insertMiddle = function (target, elms, rootNode, rng) {
24629 var parts = getSplit(target, rng);
24630 var parentElm = target.parentNode;
24631 parentElm.insertBefore(parts[0], target);
24632 Tools.each(elms, function (li) {
24633 parentElm.insertBefore(li, target);
24634 });
24635 parentElm.insertBefore(parts[1], target);
24636 parentElm.removeChild(target);
24637 return findLastOf(elms[elms.length - 1], rootNode);
24638 };
24639 var insertBefore$1 = function (target, elms, rootNode) {
24640 var parentElm = target.parentNode;
24641 Tools.each(elms, function (elm) {
24642 parentElm.insertBefore(elm, target);
24643 });
24644 return findFirstIn(target, rootNode);
24645 };
24646 var insertAfter$1 = function (target, elms, rootNode, dom) {
24647 dom.insertAfter(elms.reverse(), target);
24648 return findLastOf(elms[0], rootNode);
24649 };
24650 var insertAtCaret = function (serializer, dom, rng, fragment) {
24651 var domFragment = toDomFragment(dom, serializer, fragment);
24652 var liTarget = getParentLi(dom, rng.startContainer);
24653 var liElms = trimListItems(listItems$1(domFragment.firstChild));
24654 var BEGINNING = 1, END = 2;
24655 var rootNode = dom.getRoot();
24656 var isAt = function (location) {
24657 var caretPos = CaretPosition$1.fromRangeStart(rng);
24658 var caretWalker = CaretWalker(dom.getRoot());
24659 var newPos = location === BEGINNING ? caretWalker.prev(caretPos) : caretWalker.next(caretPos);
24660 return newPos ? getParentLi(dom, newPos.getNode()) !== liTarget : true;
24661 };
24662 if (isAt(BEGINNING)) {
24663 return insertBefore$1(liTarget, liElms, rootNode);
24664 } else if (isAt(END)) {
24665 return insertAfter$1(liTarget, liElms, rootNode, dom);
24666 }
24667 return insertMiddle(liTarget, liElms, rootNode, rng);
24668 };
24669 var InsertList = {
24670 isListFragment: isListFragment,
24671 insertAtCaret: insertAtCaret,
24672 isParentBlockLi: isParentBlockLi,
24673 trimListItems: trimListItems,
24674 listItems: listItems$1
24675 };
24676
24677 var isAfterNbsp = function (container, offset) {
24678 return NodeType.isText(container) && container.nodeValue[offset - 1] === '\xA0';
24679 };
24680 var trimOrPadLeftRight = function (rng, html) {
24681 var container, offset;
24682 container = rng.startContainer;
24683 offset = rng.startOffset;
24684 var hasSiblingText = function (siblingName) {
24685 return container[siblingName] && container[siblingName].nodeType === 3;
24686 };
24687 if (container.nodeType === 3) {
24688 if (offset > 0) {
24689 html = html.replace(/^&nbsp;/, ' ');
24690 } else if (!hasSiblingText('previousSibling')) {
24691 html = html.replace(/^ /, '&nbsp;');
24692 }
24693 if (offset < container.length) {
24694 html = html.replace(/&nbsp;(<br>|)$/, ' ');
24695 } else if (!hasSiblingText('nextSibling')) {
24696 html = html.replace(/(&nbsp;| )(<br>|)$/, '&nbsp;');
24697 }
24698 }
24699 return html;
24700 };
24701 var trimNbspAfterDeleteAndPadValue = function (rng, value) {
24702 var container, offset;
24703 container = rng.startContainer;
24704 offset = rng.startOffset;
24705 if (container.nodeType === 3 && rng.collapsed) {
24706 if (container.data[offset] === '\xA0') {
24707 container.deleteData(offset, 1);
24708 if (!/[\u00a0| ]$/.test(value)) {
24709 value += ' ';
24710 }
24711 } else if (container.data[offset - 1] === '\xA0') {
24712 container.deleteData(offset - 1, 1);
24713 if (!/[\u00a0| ]$/.test(value)) {
24714 value = ' ' + value;
24715 }
24716 }
24717 }
24718 return value;
24719 };
24720
24721 var isTableCell$5 = NodeType.matchNodeNames([
24722 'td',
24723 'th'
24724 ]);
24725 var selectionSetContent = function (editor, content) {
24726 var rng = editor.selection.getRng();
24727 var container = rng.startContainer;
24728 var offset = rng.startOffset;
24729 if (rng.collapsed && isAfterNbsp(container, offset) && NodeType.isText(container)) {
24730 container.insertData(offset - 1, ' ');
24731 container.deleteData(offset, 1);
24732 rng.setStart(container, offset);
24733 rng.setEnd(container, offset);
24734 editor.selection.setRng(rng);
24735 }
24736 editor.selection.setContent(content);
24737 };
24738 var validInsertion = function (editor, value, parentNode) {
24739 if (parentNode.getAttribute('data-mce-bogus') === 'all') {
24740 parentNode.parentNode.insertBefore(editor.dom.createFragment(value), parentNode);
24741 } else {
24742 var node = parentNode.firstChild;
24743 var node2 = parentNode.lastChild;
24744 if (!node || node === node2 && node.nodeName === 'BR') {
24745 editor.dom.setHTML(parentNode, value);
24746 } else {
24747 selectionSetContent(editor, value);
24748 }
24749 }
24750 };
24751 var trimBrsFromTableCell = function (dom, elm) {
24752 Option.from(dom.getParent(elm, 'td,th')).map(Element.fromDom).each(PaddingBr.trimBlockTrailingBr);
24753 };
24754 var reduceInlineTextElements = function (editor, merge) {
24755 var textInlineElements = editor.schema.getTextInlineElements();
24756 var dom = editor.dom;
24757 if (merge) {
24758 var root_1 = editor.getBody(), elementUtils_1 = new ElementUtils(dom);
24759 Tools.each(dom.select('*[data-mce-fragment]'), function (node) {
24760 for (var testNode = node.parentNode; testNode && testNode !== root_1; testNode = testNode.parentNode) {
24761 if (textInlineElements[node.nodeName.toLowerCase()] && elementUtils_1.compare(testNode, node)) {
24762 dom.remove(node, true);
24763 }
24764 }
24765 });
24766 }
24767 };
24768 var markFragmentElements = function (fragment) {
24769 var node = fragment;
24770 while (node = node.walk()) {
24771 if (node.type === 1) {
24772 node.attr('data-mce-fragment', '1');
24773 }
24774 }
24775 };
24776 var umarkFragmentElements = function (elm) {
24777 Tools.each(elm.getElementsByTagName('*'), function (elm) {
24778 elm.removeAttribute('data-mce-fragment');
24779 });
24780 };
24781 var isPartOfFragment = function (node) {
24782 return !!node.getAttribute('data-mce-fragment');
24783 };
24784 var canHaveChildren = function (editor, node) {
24785 return node && !editor.schema.getShortEndedElements()[node.nodeName];
24786 };
24787 var moveSelectionToMarker = function (editor, marker) {
24788 var parentEditableFalseElm, parentBlock, nextRng;
24789 var dom = editor.dom, selection = editor.selection;
24790 var node, node2;
24791 var getContentEditableFalseParent = function (node) {
24792 var root = editor.getBody();
24793 for (; node && node !== root; node = node.parentNode) {
24794 if (editor.dom.getContentEditable(node) === 'false') {
24795 return node;
24796 }
24797 }
24798 return null;
24799 };
24800 if (!marker) {
24801 return;
24802 }
24803 editor.selection.scrollIntoView(marker);
24804 parentEditableFalseElm = getContentEditableFalseParent(marker);
24805 if (parentEditableFalseElm) {
24806 dom.remove(marker);
24807 selection.select(parentEditableFalseElm);
24808 return;
24809 }
24810 var rng = dom.createRng();
24811 node = marker.previousSibling;
24812 if (node && node.nodeType === 3) {
24813 rng.setStart(node, node.nodeValue.length);
24814 if (!Env.ie) {
24815 node2 = marker.nextSibling;
24816 if (node2 && node2.nodeType === 3) {
24817 node.appendData(node2.data);
24818 node2.parentNode.removeChild(node2);
24819 }
24820 }
24821 } else {
24822 rng.setStartBefore(marker);
24823 rng.setEndBefore(marker);
24824 }
24825 var findNextCaretRng = function (rng) {
24826 var caretPos = CaretPosition$1.fromRangeStart(rng);
24827 var caretWalker = CaretWalker(editor.getBody());
24828 caretPos = caretWalker.next(caretPos);
24829 if (caretPos) {
24830 return caretPos.toRange();
24831 }
24832 };
24833 parentBlock = dom.getParent(marker, dom.isBlock);
24834 dom.remove(marker);
24835 if (parentBlock && dom.isEmpty(parentBlock)) {
24836 editor.$(parentBlock).empty();
24837 rng.setStart(parentBlock, 0);
24838 rng.setEnd(parentBlock, 0);
24839 if (!isTableCell$5(parentBlock) && !isPartOfFragment(parentBlock) && (nextRng = findNextCaretRng(rng))) {
24840 rng = nextRng;
24841 dom.remove(parentBlock);
24842 } else {
24843 dom.add(parentBlock, dom.create('br', { 'data-mce-bogus': '1' }));
24844 }
24845 }
24846 selection.setRng(rng);
24847 };
24848 var insertHtmlAtCaret = function (editor, value, details) {
24849 var parser, serializer, parentNode, rootNode, fragment, args;
24850 var marker, rng, node, bookmarkHtml, merge;
24851 var selection = editor.selection, dom = editor.dom;
24852 if (/^ | $/.test(value)) {
24853 value = trimOrPadLeftRight(selection.getRng(), value);
24854 }
24855 parser = editor.parser;
24856 merge = details.merge;
24857 serializer = Serializer({ validate: editor.settings.validate }, editor.schema);
24858 bookmarkHtml = '<span id="mce_marker" data-mce-type="bookmark">&#xFEFF;&#x200B;</span>';
24859 args = {
24860 content: value,
24861 format: 'html',
24862 selection: true,
24863 paste: details.paste
24864 };
24865 args = editor.fire('BeforeSetContent', args);
24866 if (args.isDefaultPrevented()) {
24867 editor.fire('SetContent', {
24868 content: args.content,
24869 format: 'html',
24870 selection: true,
24871 paste: details.paste
24872 });
24873 return;
24874 }
24875 value = args.content;
24876 if (value.indexOf('{$caret}') === -1) {
24877 value += '{$caret}';
24878 }
24879 value = value.replace(/\{\$caret\}/, bookmarkHtml);
24880 rng = selection.getRng();
24881 var caretElement = rng.startContainer || (rng.parentElement ? rng.parentElement() : null);
24882 var body = editor.getBody();
24883 if (caretElement === body && selection.isCollapsed()) {
24884 if (dom.isBlock(body.firstChild) && canHaveChildren(editor, body.firstChild) && dom.isEmpty(body.firstChild)) {
24885 rng = dom.createRng();
24886 rng.setStart(body.firstChild, 0);
24887 rng.setEnd(body.firstChild, 0);
24888 selection.setRng(rng);
24889 }
24890 }
24891 if (!selection.isCollapsed()) {
24892 editor.selection.setRng(RangeNormalizer.normalize(editor.selection.getRng()));
24893 editor.getDoc().execCommand('Delete', false, null);
24894 value = trimNbspAfterDeleteAndPadValue(editor.selection.getRng(), value);
24895 }
24896 parentNode = selection.getNode();
24897 var parserArgs = {
24898 context: parentNode.nodeName.toLowerCase(),
24899 data: details.data,
24900 insert: true
24901 };
24902 fragment = parser.parse(value, parserArgs);
24903 if (details.paste === true && InsertList.isListFragment(editor.schema, fragment) && InsertList.isParentBlockLi(dom, parentNode)) {
24904 rng = InsertList.insertAtCaret(serializer, dom, editor.selection.getRng(), fragment);
24905 editor.selection.setRng(rng);
24906 editor.fire('SetContent', args);
24907 return;
24908 }
24909 markFragmentElements(fragment);
24910 node = fragment.lastChild;
24911 if (node.attr('id') === 'mce_marker') {
24912 marker = node;
24913 for (node = node.prev; node; node = node.walk(true)) {
24914 if (node.type === 3 || !dom.isBlock(node.name)) {
24915 if (editor.schema.isValidChild(node.parent.name, 'span')) {
24916 node.parent.insert(marker, node, node.name === 'br');
24917 }
24918 break;
24919 }
24920 }
24921 }
24922 editor._selectionOverrides.showBlockCaretContainer(parentNode);
24923 if (!parserArgs.invalid) {
24924 value = serializer.serialize(fragment);
24925 validInsertion(editor, value, parentNode);
24926 } else {
24927 selectionSetContent(editor, bookmarkHtml);
24928 parentNode = selection.getNode();
24929 rootNode = editor.getBody();
24930 if (parentNode.nodeType === 9) {
24931 parentNode = node = rootNode;
24932 } else {
24933 node = parentNode;
24934 }
24935 while (node !== rootNode) {
24936 parentNode = node;
24937 node = node.parentNode;
24938 }
24939 value = parentNode === rootNode ? rootNode.innerHTML : dom.getOuterHTML(parentNode);
24940 value = serializer.serialize(parser.parse(value.replace(/<span (id="mce_marker"|id=mce_marker).+?<\/span>/i, function () {
24941 return serializer.serialize(fragment);
24942 })));
24943 if (parentNode === rootNode) {
24944 dom.setHTML(rootNode, value);
24945 } else {
24946 dom.setOuterHTML(parentNode, value);
24947 }
24948 }
24949 reduceInlineTextElements(editor, merge);
24950 moveSelectionToMarker(editor, dom.get('mce_marker'));
24951 umarkFragmentElements(editor.getBody());
24952 trimBrsFromTableCell(editor.dom, editor.selection.getStart());
24953 editor.fire('SetContent', args);
24954 editor.addVisual();
24955 };
24956 var processValue = function (value) {
24957 var details;
24958 if (typeof value !== 'string') {
24959 details = Tools.extend({
24960 paste: value.paste,
24961 data: { paste: value.paste }
24962 }, value);
24963 return {
24964 content: value.content,
24965 details: details
24966 };
24967 }
24968 return {
24969 content: value,
24970 details: {}
24971 };
24972 };
24973 var insertAtCaret$1 = function (editor, value) {
24974 var result = processValue(value);
24975 insertHtmlAtCaret(editor, result.content, result.details);
24976 };
24977 var InsertContent = { insertAtCaret: insertAtCaret$1 };
24978
24979 var nativeCommand = function (editor, command) {
24980 editor.getDoc().execCommand(command, false, null);
24981 };
24982 var deleteCommand = function (editor) {
24983 if (Outdent.backspaceDelete(editor, false)) {
24984 return;
24985 } else if (CefDelete.backspaceDelete(editor, false)) {
24986 return;
24987 } else if (CefBoundaryDelete.backspaceDelete(editor, false)) {
24988 return;
24989 } else if (BoundaryDelete.backspaceDelete(editor, false)) {
24990 return;
24991 } else if (BlockBoundaryDelete.backspaceDelete(editor, false)) {
24992 return;
24993 } else if (TableDelete.backspaceDelete(editor)) {
24994 return;
24995 } else if (BlockRangeDelete.backspaceDelete(editor, false)) {
24996 return;
24997 } else if (InlineFormatDelete.backspaceDelete(editor, false)) {
24998 return;
24999 } else {
25000 nativeCommand(editor, 'Delete');
25001 DeleteUtils.paddEmptyBody(editor);
25002 }
25003 };
25004 var forwardDeleteCommand = function (editor) {
25005 if (CefDelete.backspaceDelete(editor, true)) {
25006 return;
25007 } else if (CefBoundaryDelete.backspaceDelete(editor, true)) {
25008 return;
25009 } else if (BoundaryDelete.backspaceDelete(editor, true)) {
25010 return;
25011 } else if (BlockBoundaryDelete.backspaceDelete(editor, true)) {
25012 return;
25013 } else if (TableDelete.backspaceDelete(editor)) {
25014 return;
25015 } else if (BlockRangeDelete.backspaceDelete(editor, true)) {
25016 return;
25017 } else if (InlineFormatDelete.backspaceDelete(editor, true)) {
25018 return;
25019 } else {
25020 nativeCommand(editor, 'ForwardDelete');
25021 }
25022 };
25023 var DeleteCommands = {
25024 deleteCommand: deleteCommand,
25025 forwardDeleteCommand: forwardDeleteCommand
25026 };
25027
25028 var getSpecifiedFontProp = function (propName, rootElm, elm) {
25029 var getProperty = function (elm) {
25030 return getRaw(elm, propName);
25031 };
25032 var isRoot = function (elm) {
25033 return eq(Element.fromDom(rootElm), elm);
25034 };
25035 return closest(Element.fromDom(elm), function (elm) {
25036 return getProperty(elm).isSome();
25037 }, isRoot).bind(getProperty);
25038 };
25039 var round$1 = function (number, precision) {
25040 var factor = Math.pow(10, precision);
25041 return Math.round(number * factor) / factor;
25042 };
25043 var toPt = function (fontSize, precision) {
25044 if (/[0-9.]+px$/.test(fontSize)) {
25045 return round$1(parseInt(fontSize, 10) * 72 / 96, precision || 0) + 'pt';
25046 }
25047 return fontSize;
25048 };
25049 var normalizeFontFamily = function (fontFamily) {
25050 return fontFamily.replace(/[\'\"\\]/g, '').replace(/,\s+/g, ',');
25051 };
25052 var getComputedFontProp = function (propName, elm) {
25053 return Option.from(DOMUtils$1.DOM.getStyle(elm, propName, true));
25054 };
25055 var getFontProp = function (propName) {
25056 return function (rootElm, elm) {
25057 return Option.from(elm).map(Element.fromDom).filter(isElement).bind(function (element) {
25058 return getSpecifiedFontProp(propName, rootElm, element.dom()).or(getComputedFontProp(propName, element.dom()));
25059 }).getOr('');
25060 };
25061 };
25062 var FontInfo = {
25063 getFontSize: getFontProp('font-size'),
25064 getFontFamily: compose(normalizeFontFamily, getFontProp('font-family')),
25065 toPt: toPt
25066 };
25067
25068 var findFirstCaretElement = function (editor) {
25069 return CaretFinder.firstPositionIn(editor.getBody()).map(function (caret) {
25070 var container = caret.container();
25071 return NodeType.isText(container) ? container.parentNode : container;
25072 });
25073 };
25074 var isRangeAtStartOfNode = function (rng, root) {
25075 return rng.startContainer === root && rng.startOffset === 0;
25076 };
25077 var getCaretElement = function (editor) {
25078 return Option.from(editor.selection.getRng()).bind(function (rng) {
25079 var root = editor.getBody();
25080 return isRangeAtStartOfNode(rng, root) ? Option.none() : Option.from(editor.selection.getStart(true));
25081 });
25082 };
25083 var fromFontSizeNumber = function (editor, value) {
25084 if (/^[0-9\.]+$/.test(value)) {
25085 var fontSizeNumber = parseInt(value, 10);
25086 if (fontSizeNumber >= 1 && fontSizeNumber <= 7) {
25087 var fontSizes = Settings.getFontStyleValues(editor);
25088 var fontClasses = Settings.getFontSizeClasses(editor);
25089 if (fontClasses) {
25090 return fontClasses[fontSizeNumber - 1] || value;
25091 } else {
25092 return fontSizes[fontSizeNumber - 1] || value;
25093 }
25094 } else {
25095 return value;
25096 }
25097 } else {
25098 return value;
25099 }
25100 };
25101 var normalizeFontNames = function (font) {
25102 var fonts = font.split(/\s*,\s*/);
25103 return map(fonts, function (font) {
25104 if (font.indexOf(' ') !== -1 && !(startsWith(font, '"') || startsWith(font, '\''))) {
25105 return '"' + font + '"';
25106 } else {
25107 return font;
25108 }
25109 }).join(',');
25110 };
25111 var fontNameAction = function (editor, value) {
25112 var font = fromFontSizeNumber(editor, value);
25113 editor.formatter.toggle('fontname', { value: normalizeFontNames(font) });
25114 editor.nodeChanged();
25115 };
25116 var fontNameQuery = function (editor) {
25117 return getCaretElement(editor).fold(function () {
25118 return findFirstCaretElement(editor).map(function (caretElement) {
25119 return FontInfo.getFontFamily(editor.getBody(), caretElement);
25120 }).getOr('');
25121 }, function (caretElement) {
25122 return FontInfo.getFontFamily(editor.getBody(), caretElement);
25123 });
25124 };
25125 var fontSizeAction = function (editor, value) {
25126 editor.formatter.toggle('fontsize', { value: fromFontSizeNumber(editor, value) });
25127 editor.nodeChanged();
25128 };
25129 var fontSizeQuery = function (editor) {
25130 return getCaretElement(editor).fold(function () {
25131 return findFirstCaretElement(editor).map(function (caretElement) {
25132 return FontInfo.getFontSize(editor.getBody(), caretElement);
25133 }).getOr('');
25134 }, function (caretElement) {
25135 return FontInfo.getFontSize(editor.getBody(), caretElement);
25136 });
25137 };
25138
25139 var each$g = Tools.each;
25140 var map$3 = Tools.map, inArray$2 = Tools.inArray;
25141 var EditorCommands = function () {
25142 function EditorCommands(editor) {
25143 this.commands = {
25144 state: {},
25145 exec: {},
25146 value: {}
25147 };
25148 this.editor = editor;
25149 this.setupCommands(editor);
25150 }
25151 EditorCommands.prototype.execCommand = function (command, ui, value, args) {
25152 var func, customCommand, state = false;
25153 var self = this;
25154 if (self.editor.removed) {
25155 return;
25156 }
25157 if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(command) && (!args || !args.skip_focus)) {
25158 self.editor.focus();
25159 } else {
25160 SelectionBookmark.restore(self.editor);
25161 }
25162 args = self.editor.fire('BeforeExecCommand', {
25163 command: command,
25164 ui: ui,
25165 value: value
25166 });
25167 if (args.isDefaultPrevented()) {
25168 return false;
25169 }
25170 customCommand = command.toLowerCase();
25171 if (func = self.commands.exec[customCommand]) {
25172 func(customCommand, ui, value);
25173 self.editor.fire('ExecCommand', {
25174 command: command,
25175 ui: ui,
25176 value: value
25177 });
25178 return true;
25179 }
25180 each$g(this.editor.plugins, function (p) {
25181 if (p.execCommand && p.execCommand(command, ui, value)) {
25182 self.editor.fire('ExecCommand', {
25183 command: command,
25184 ui: ui,
25185 value: value
25186 });
25187 state = true;
25188 return false;
25189 }
25190 });
25191 if (state) {
25192 return state;
25193 }
25194 if (self.editor.theme && self.editor.theme.execCommand && self.editor.theme.execCommand(command, ui, value)) {
25195 self.editor.fire('ExecCommand', {
25196 command: command,
25197 ui: ui,
25198 value: value
25199 });
25200 return true;
25201 }
25202 try {
25203 state = self.editor.getDoc().execCommand(command, ui, value);
25204 } catch (ex) {
25205 }
25206 if (state) {
25207 self.editor.fire('ExecCommand', {
25208 command: command,
25209 ui: ui,
25210 value: value
25211 });
25212 return true;
25213 }
25214 return false;
25215 };
25216 EditorCommands.prototype.queryCommandState = function (command) {
25217 var func;
25218 if (this.editor.quirks.isHidden() || this.editor.removed) {
25219 return;
25220 }
25221 command = command.toLowerCase();
25222 if (func = this.commands.state[command]) {
25223 return func(command);
25224 }
25225 try {
25226 return this.editor.getDoc().queryCommandState(command);
25227 } catch (ex) {
25228 }
25229 return false;
25230 };
25231 EditorCommands.prototype.queryCommandValue = function (command) {
25232 var func;
25233 if (this.editor.quirks.isHidden() || this.editor.removed) {
25234 return;
25235 }
25236 command = command.toLowerCase();
25237 if (func = this.commands.value[command]) {
25238 return func(command);
25239 }
25240 try {
25241 return this.editor.getDoc().queryCommandValue(command);
25242 } catch (ex) {
25243 }
25244 };
25245 EditorCommands.prototype.addCommands = function (commandList, type) {
25246 var self = this;
25247 type = type || 'exec';
25248 each$g(commandList, function (callback, command) {
25249 each$g(command.toLowerCase().split(','), function (command) {
25250 self.commands[type][command] = callback;
25251 });
25252 });
25253 };
25254 EditorCommands.prototype.addCommand = function (command, callback, scope) {
25255 var _this = this;
25256 command = command.toLowerCase();
25257 this.commands.exec[command] = function (command, ui, value, args) {
25258 return callback.call(scope || _this.editor, ui, value, args);
25259 };
25260 };
25261 EditorCommands.prototype.queryCommandSupported = function (command) {
25262 command = command.toLowerCase();
25263 if (this.commands.exec[command]) {
25264 return true;
25265 }
25266 try {
25267 return this.editor.getDoc().queryCommandSupported(command);
25268 } catch (ex) {
25269 }
25270 return false;
25271 };
25272 EditorCommands.prototype.addQueryStateHandler = function (command, callback, scope) {
25273 var _this = this;
25274 command = command.toLowerCase();
25275 this.commands.state[command] = function () {
25276 return callback.call(scope || _this.editor);
25277 };
25278 };
25279 EditorCommands.prototype.addQueryValueHandler = function (command, callback, scope) {
25280 var _this = this;
25281 command = command.toLowerCase();
25282 this.commands.value[command] = function () {
25283 return callback.call(scope || _this.editor);
25284 };
25285 };
25286 EditorCommands.prototype.hasCustomCommand = function (command) {
25287 command = command.toLowerCase();
25288 return !!this.commands.exec[command];
25289 };
25290 EditorCommands.prototype.execNativeCommand = function (command, ui, value) {
25291 if (ui === undefined) {
25292 ui = false;
25293 }
25294 if (value === undefined) {
25295 value = null;
25296 }
25297 return this.editor.getDoc().execCommand(command, ui, value);
25298 };
25299 EditorCommands.prototype.isFormatMatch = function (name) {
25300 return this.editor.formatter.match(name);
25301 };
25302 EditorCommands.prototype.toggleFormat = function (name, value) {
25303 this.editor.formatter.toggle(name, value ? { value: value } : undefined);
25304 this.editor.nodeChanged();
25305 };
25306 EditorCommands.prototype.storeSelection = function (type) {
25307 this.selectionBookmark = this.editor.selection.getBookmark(type);
25308 };
25309 EditorCommands.prototype.restoreSelection = function () {
25310 this.editor.selection.moveToBookmark(this.selectionBookmark);
25311 };
25312 EditorCommands.prototype.setupCommands = function (editor) {
25313 var self = this;
25314 this.addCommands({
25315 'mceResetDesignMode,mceBeginUndoLevel': function () {
25316 },
25317 'mceEndUndoLevel,mceAddUndoLevel': function () {
25318 editor.undoManager.add();
25319 },
25320 'Cut,Copy,Paste': function (command) {
25321 var doc = editor.getDoc();
25322 var failed;
25323 try {
25324 self.execNativeCommand(command);
25325 } catch (ex) {
25326 failed = true;
25327 }
25328 if (command === 'paste' && !doc.queryCommandEnabled(command)) {
25329 failed = true;
25330 }
25331 if (failed || !doc.queryCommandSupported(command)) {
25332 var msg = editor.translate('Your browser doesn\'t support direct access to the clipboard. ' + 'Please use the Ctrl+X/C/V keyboard shortcuts instead.');
25333 if (Env.mac) {
25334 msg = msg.replace(/Ctrl\+/g, '\u2318+');
25335 }
25336 editor.notificationManager.open({
25337 text: msg,
25338 type: 'error'
25339 });
25340 }
25341 },
25342 'unlink': function () {
25343 if (editor.selection.isCollapsed()) {
25344 var elm = editor.dom.getParent(editor.selection.getStart(), 'a');
25345 if (elm) {
25346 editor.dom.remove(elm, true);
25347 }
25348 return;
25349 }
25350 editor.formatter.remove('link');
25351 },
25352 'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull,JustifyNone': function (command) {
25353 var align = command.substring(7);
25354 if (align === 'full') {
25355 align = 'justify';
25356 }
25357 each$g('left,center,right,justify'.split(','), function (name) {
25358 if (align !== name) {
25359 editor.formatter.remove('align' + name);
25360 }
25361 });
25362 if (align !== 'none') {
25363 self.toggleFormat('align' + align);
25364 }
25365 },
25366 'InsertUnorderedList,InsertOrderedList': function (command) {
25367 var listElm, listParent;
25368 self.execNativeCommand(command);
25369 listElm = editor.dom.getParent(editor.selection.getNode(), 'ol,ul');
25370 if (listElm) {
25371 listParent = listElm.parentNode;
25372 if (/^(H[1-6]|P|ADDRESS|PRE)$/.test(listParent.nodeName)) {
25373 self.storeSelection();
25374 editor.dom.split(listParent, listElm);
25375 self.restoreSelection();
25376 }
25377 }
25378 },
25379 'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function (command) {
25380 self.toggleFormat(command);
25381 },
25382 'ForeColor,HiliteColor': function (command, ui, value) {
25383 self.toggleFormat(command, value);
25384 },
25385 'FontName': function (command, ui, value) {
25386 fontNameAction(editor, value);
25387 },
25388 'FontSize': function (command, ui, value) {
25389 fontSizeAction(editor, value);
25390 },
25391 'RemoveFormat': function (command) {
25392 editor.formatter.remove(command);
25393 },
25394 'mceBlockQuote': function () {
25395 self.toggleFormat('blockquote');
25396 },
25397 'FormatBlock': function (command, ui, value) {
25398 return self.toggleFormat(value || 'p');
25399 },
25400 'mceCleanup': function () {
25401 var bookmark = editor.selection.getBookmark();
25402 editor.setContent(editor.getContent());
25403 editor.selection.moveToBookmark(bookmark);
25404 },
25405 'mceRemoveNode': function (command, ui, value) {
25406 var node = value || editor.selection.getNode();
25407 if (node !== editor.getBody()) {
25408 self.storeSelection();
25409 editor.dom.remove(node, true);
25410 self.restoreSelection();
25411 }
25412 },
25413 'mceSelectNodeDepth': function (command, ui, value) {
25414 var counter = 0;
25415 editor.dom.getParent(editor.selection.getNode(), function (node) {
25416 if (node.nodeType === 1 && counter++ === value) {
25417 editor.selection.select(node);
25418 return false;
25419 }
25420 }, editor.getBody());
25421 },
25422 'mceSelectNode': function (command, ui, value) {
25423 editor.selection.select(value);
25424 },
25425 'mceInsertContent': function (command, ui, value) {
25426 InsertContent.insertAtCaret(editor, value);
25427 },
25428 'mceInsertRawHTML': function (command, ui, value) {
25429 editor.selection.setContent('tiny_mce_marker');
25430 var content = editor.getContent();
25431 editor.setContent(content.replace(/tiny_mce_marker/g, function () {
25432 return value;
25433 }));
25434 },
25435 'mceInsertNewLine': function (command, ui, value) {
25436 InsertNewLine.insert(editor, value);
25437 },
25438 'mceToggleFormat': function (command, ui, value) {
25439 self.toggleFormat(value);
25440 },
25441 'mceSetContent': function (command, ui, value) {
25442 editor.setContent(value);
25443 },
25444 'Indent,Outdent': function (command) {
25445 handle(editor, command);
25446 },
25447 'mceRepaint': function () {
25448 },
25449 'InsertHorizontalRule': function () {
25450 editor.execCommand('mceInsertContent', false, '<hr />');
25451 },
25452 'mceToggleVisualAid': function () {
25453 editor.hasVisual = !editor.hasVisual;
25454 editor.addVisual();
25455 },
25456 'mceReplaceContent': function (command, ui, value) {
25457 editor.execCommand('mceInsertContent', false, value.replace(/\{\$selection\}/g, editor.selection.getContent({ format: 'text' })));
25458 },
25459 'mceInsertLink': function (command, ui, value) {
25460 var anchor;
25461 if (typeof value === 'string') {
25462 value = { href: value };
25463 }
25464 anchor = editor.dom.getParent(editor.selection.getNode(), 'a');
25465 value.href = value.href.replace(/ /g, '%20');
25466 if (!anchor || !value.href) {
25467 editor.formatter.remove('link');
25468 }
25469 if (value.href) {
25470 editor.formatter.apply('link', value, anchor);
25471 }
25472 },
25473 'selectAll': function () {
25474 var editingHost = editor.dom.getParent(editor.selection.getStart(), NodeType.isContentEditableTrue);
25475 if (editingHost) {
25476 var rng = editor.dom.createRng();
25477 rng.selectNodeContents(editingHost);
25478 editor.selection.setRng(rng);
25479 }
25480 },
25481 'delete': function () {
25482 DeleteCommands.deleteCommand(editor);
25483 },
25484 'forwardDelete': function () {
25485 DeleteCommands.forwardDeleteCommand(editor);
25486 },
25487 'mceNewDocument': function () {
25488 editor.setContent('');
25489 },
25490 'InsertLineBreak': function (command, ui, value) {
25491 InsertBr.insert(editor, value);
25492 return true;
25493 }
25494 });
25495 var alignStates = function (name) {
25496 return function () {
25497 var nodes = editor.selection.isCollapsed() ? [editor.dom.getParent(editor.selection.getNode(), editor.dom.isBlock)] : editor.selection.getSelectedBlocks();
25498 var matches = map$3(nodes, function (node) {
25499 return !!editor.formatter.matchNode(node, name);
25500 });
25501 return inArray$2(matches, true) !== -1;
25502 };
25503 };
25504 self.addCommands({
25505 'JustifyLeft': alignStates('alignleft'),
25506 'JustifyCenter': alignStates('aligncenter'),
25507 'JustifyRight': alignStates('alignright'),
25508 'JustifyFull': alignStates('alignjustify'),
25509 'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function (command) {
25510 return self.isFormatMatch(command);
25511 },
25512 'mceBlockQuote': function () {
25513 return self.isFormatMatch('blockquote');
25514 },
25515 'Outdent': function () {
25516 return canOutdent(editor);
25517 },
25518 'InsertUnorderedList,InsertOrderedList': function (command) {
25519 var list = editor.dom.getParent(editor.selection.getNode(), 'ul,ol');
25520 return list && (command === 'insertunorderedlist' && list.tagName === 'UL' || command === 'insertorderedlist' && list.tagName === 'OL');
25521 }
25522 }, 'state');
25523 self.addCommands({
25524 Undo: function () {
25525 editor.undoManager.undo();
25526 },
25527 Redo: function () {
25528 editor.undoManager.redo();
25529 }
25530 });
25531 self.addQueryValueHandler('FontName', function () {
25532 return fontNameQuery(editor);
25533 }, this);
25534 self.addQueryValueHandler('FontSize', function () {
25535 return fontSizeQuery(editor);
25536 }, this);
25537 };
25538 return EditorCommands;
25539 }();
25540
25541 var nativeEvents = Tools.makeMap('focus blur focusin focusout click dblclick mousedown mouseup mousemove mouseover beforepaste paste cut copy selectionchange ' + 'mouseout mouseenter mouseleave wheel keydown keypress keyup input contextmenu dragstart dragend dragover ' + 'draggesture dragdrop drop drag submit ' + 'compositionstart compositionend compositionupdate touchstart touchmove touchend', ' ');
25542 var EventDispatcher = function () {
25543 function EventDispatcher(settings) {
25544 this.bindings = {};
25545 this.settings = settings || {};
25546 this.scope = this.settings.scope || this;
25547 this.toggleEvent = this.settings.toggleEvent || never;
25548 }
25549 EventDispatcher.isNative = function (name) {
25550 return !!nativeEvents[name.toLowerCase()];
25551 };
25552 EventDispatcher.prototype.fire = function (name, args) {
25553 var handlers, i, l, callback;
25554 name = name.toLowerCase();
25555 args = args || {};
25556 args.type = name;
25557 if (!args.target) {
25558 args.target = this.scope;
25559 }
25560 if (!args.preventDefault) {
25561 args.preventDefault = function () {
25562 args.isDefaultPrevented = always;
25563 };
25564 args.stopPropagation = function () {
25565 args.isPropagationStopped = always;
25566 };
25567 args.stopImmediatePropagation = function () {
25568 args.isImmediatePropagationStopped = always;
25569 };
25570 args.isDefaultPrevented = never;
25571 args.isPropagationStopped = never;
25572 args.isImmediatePropagationStopped = never;
25573 }
25574 if (this.settings.beforeFire) {
25575 this.settings.beforeFire(args);
25576 }
25577 handlers = this.bindings[name];
25578 if (handlers) {
25579 for (i = 0, l = handlers.length; i < l; i++) {
25580 callback = handlers[i];
25581 if (callback.once) {
25582 this.off(name, callback.func);
25583 }
25584 if (args.isImmediatePropagationStopped()) {
25585 args.stopPropagation();
25586 return args;
25587 }
25588 if (callback.func.call(this.scope, args) === false) {
25589 args.preventDefault();
25590 return args;
25591 }
25592 }
25593 }
25594 return args;
25595 };
25596 EventDispatcher.prototype.on = function (name, callback, prepend, extra) {
25597 var handlers, names, i;
25598 if (callback === false) {
25599 callback = never;
25600 }
25601 if (callback) {
25602 var wrappedCallback = { func: callback };
25603 if (extra) {
25604 Tools.extend(wrappedCallback, extra);
25605 }
25606 names = name.toLowerCase().split(' ');
25607 i = names.length;
25608 while (i--) {
25609 name = names[i];
25610 handlers = this.bindings[name];
25611 if (!handlers) {
25612 handlers = this.bindings[name] = [];
25613 this.toggleEvent(name, true);
25614 }
25615 if (prepend) {
25616 handlers.unshift(wrappedCallback);
25617 } else {
25618 handlers.push(wrappedCallback);
25619 }
25620 }
25621 }
25622 return this;
25623 };
25624 EventDispatcher.prototype.off = function (name, callback) {
25625 var i, handlers, bindingName, names, hi;
25626 if (name) {
25627 names = name.toLowerCase().split(' ');
25628 i = names.length;
25629 while (i--) {
25630 name = names[i];
25631 handlers = this.bindings[name];
25632 if (!name) {
25633 for (bindingName in this.bindings) {
25634 this.toggleEvent(bindingName, false);
25635 delete this.bindings[bindingName];
25636 }
25637 return this;
25638 }
25639 if (handlers) {
25640 if (!callback) {
25641 handlers.length = 0;
25642 } else {
25643 hi = handlers.length;
25644 while (hi--) {
25645 if (handlers[hi].func === callback) {
25646 handlers = handlers.slice(0, hi).concat(handlers.slice(hi + 1));
25647 this.bindings[name] = handlers;
25648 }
25649 }
25650 }
25651 if (!handlers.length) {
25652 this.toggleEvent(name, false);
25653 delete this.bindings[name];
25654 }
25655 }
25656 }
25657 } else {
25658 for (name in this.bindings) {
25659 this.toggleEvent(name, false);
25660 }
25661 this.bindings = {};
25662 }
25663 return this;
25664 };
25665 EventDispatcher.prototype.once = function (name, callback, prepend) {
25666 return this.on(name, callback, prepend, { once: true });
25667 };
25668 EventDispatcher.prototype.has = function (name) {
25669 name = name.toLowerCase();
25670 return !(!this.bindings[name] || this.bindings[name].length === 0);
25671 };
25672 return EventDispatcher;
25673 }();
25674
25675 var getEventDispatcher = function (obj) {
25676 if (!obj._eventDispatcher) {
25677 obj._eventDispatcher = new EventDispatcher({
25678 scope: obj,
25679 toggleEvent: function (name, state) {
25680 if (EventDispatcher.isNative(name) && obj.toggleNativeEvent) {
25681 obj.toggleNativeEvent(name, state);
25682 }
25683 }
25684 });
25685 }
25686 return obj._eventDispatcher;
25687 };
25688 var Observable = {
25689 fire: function (name, args, bubble) {
25690 var self = this;
25691 if (self.removed && name !== 'remove' && name !== 'detach') {
25692 return args;
25693 }
25694 var dispatcherArgs = getEventDispatcher(self).fire(name, args);
25695 if (bubble !== false && self.parent) {
25696 var parent = self.parent();
25697 while (parent && !dispatcherArgs.isPropagationStopped()) {
25698 parent.fire(name, dispatcherArgs, false);
25699 parent = parent.parent();
25700 }
25701 }
25702 return dispatcherArgs;
25703 },
25704 on: function (name, callback, prepend) {
25705 return getEventDispatcher(this).on(name, callback, prepend);
25706 },
25707 off: function (name, callback) {
25708 return getEventDispatcher(this).off(name, callback);
25709 },
25710 once: function (name, callback) {
25711 return getEventDispatcher(this).once(name, callback);
25712 },
25713 hasEventListeners: function (name) {
25714 return getEventDispatcher(this).has(name);
25715 }
25716 };
25717
25718 var DOM$7 = DOMUtils$1.DOM;
25719 var customEventRootDelegates;
25720 var getEventTarget = function (editor, eventName) {
25721 if (eventName === 'selectionchange') {
25722 return editor.getDoc();
25723 }
25724 if (!editor.inline && /^mouse|touch|click|contextmenu|drop|dragover|dragend/.test(eventName)) {
25725 return editor.getDoc().documentElement;
25726 }
25727 if (editor.settings.event_root) {
25728 if (!editor.eventRoot) {
25729 editor.eventRoot = DOM$7.select(editor.settings.event_root)[0];
25730 }
25731 return editor.eventRoot;
25732 }
25733 return editor.getBody();
25734 };
25735 var isListening = function (editor) {
25736 return !editor.hidden && !isReadOnly(editor);
25737 };
25738 var fireEvent = function (editor, eventName, e) {
25739 if (isListening(editor)) {
25740 editor.fire(eventName, e);
25741 } else if (isReadOnly(editor)) {
25742 preventReadOnlyEvents(e);
25743 }
25744 };
25745 var bindEventDelegate = function (editor, eventName) {
25746 var eventRootElm, delegate;
25747 if (!editor.delegates) {
25748 editor.delegates = {};
25749 }
25750 if (editor.delegates[eventName] || editor.removed) {
25751 return;
25752 }
25753 eventRootElm = getEventTarget(editor, eventName);
25754 if (editor.settings.event_root) {
25755 if (!customEventRootDelegates) {
25756 customEventRootDelegates = {};
25757 editor.editorManager.on('removeEditor', function () {
25758 var name;
25759 if (!editor.editorManager.activeEditor) {
25760 if (customEventRootDelegates) {
25761 for (name in customEventRootDelegates) {
25762 editor.dom.unbind(getEventTarget(editor, name));
25763 }
25764 customEventRootDelegates = null;
25765 }
25766 }
25767 });
25768 }
25769 if (customEventRootDelegates[eventName]) {
25770 return;
25771 }
25772 delegate = function (e) {
25773 var target = e.target;
25774 var editors = editor.editorManager.get();
25775 var i = editors.length;
25776 while (i--) {
25777 var body = editors[i].getBody();
25778 if (body === target || DOM$7.isChildOf(target, body)) {
25779 fireEvent(editors[i], eventName, e);
25780 }
25781 }
25782 };
25783 customEventRootDelegates[eventName] = delegate;
25784 DOM$7.bind(eventRootElm, eventName, delegate);
25785 } else {
25786 delegate = function (e) {
25787 fireEvent(editor, eventName, e);
25788 };
25789 DOM$7.bind(eventRootElm, eventName, delegate);
25790 editor.delegates[eventName] = delegate;
25791 }
25792 };
25793 var EditorObservable = __assign({}, Observable, {
25794 bindPendingEventDelegates: function () {
25795 var self = this;
25796 Tools.each(self._pendingNativeEvents, function (name) {
25797 bindEventDelegate(self, name);
25798 });
25799 },
25800 toggleNativeEvent: function (name, state) {
25801 var self = this;
25802 if (name === 'focus' || name === 'blur') {
25803 return;
25804 }
25805 if (state) {
25806 if (self.initialized) {
25807 bindEventDelegate(self, name);
25808 } else {
25809 if (!self._pendingNativeEvents) {
25810 self._pendingNativeEvents = [name];
25811 } else {
25812 self._pendingNativeEvents.push(name);
25813 }
25814 }
25815 } else if (self.initialized) {
25816 self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]);
25817 delete self.delegates[name];
25818 }
25819 },
25820 unbindAllNativeEvents: function () {
25821 var self = this;
25822 var body = self.getBody();
25823 var dom = self.dom;
25824 var name;
25825 if (self.delegates) {
25826 for (name in self.delegates) {
25827 self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]);
25828 }
25829 delete self.delegates;
25830 }
25831 if (!self.inline && body && dom) {
25832 body.onload = null;
25833 dom.unbind(self.getWin());
25834 dom.unbind(self.getDoc());
25835 }
25836 if (dom) {
25837 dom.unbind(body);
25838 dom.unbind(self.getContainer());
25839 }
25840 }
25841 });
25842
25843 var each$h = Tools.each, explode$3 = Tools.explode;
25844 var keyCodeLookup = {
25845 f1: 112,
25846 f2: 113,
25847 f3: 114,
25848 f4: 115,
25849 f5: 116,
25850 f6: 117,
25851 f7: 118,
25852 f8: 119,
25853 f9: 120,
25854 f10: 121,
25855 f11: 122,
25856 f12: 123
25857 };
25858 var modifierNames = Tools.makeMap('alt,ctrl,shift,meta,access');
25859 var Shortcuts = function () {
25860 function Shortcuts(editor) {
25861 this.shortcuts = {};
25862 this.pendingPatterns = [];
25863 this.editor = editor;
25864 var self = this;
25865 editor.on('keyup keypress keydown', function (e) {
25866 if ((self.hasModifier(e) || self.isFunctionKey(e)) && !e.isDefaultPrevented()) {
25867 each$h(self.shortcuts, function (shortcut) {
25868 if (self.matchShortcut(e, shortcut)) {
25869 self.pendingPatterns = shortcut.subpatterns.slice(0);
25870 if (e.type === 'keydown') {
25871 self.executeShortcutAction(shortcut);
25872 }
25873 return true;
25874 }
25875 });
25876 if (self.matchShortcut(e, self.pendingPatterns[0])) {
25877 if (self.pendingPatterns.length === 1) {
25878 if (e.type === 'keydown') {
25879 self.executeShortcutAction(self.pendingPatterns[0]);
25880 }
25881 }
25882 self.pendingPatterns.shift();
25883 }
25884 }
25885 });
25886 }
25887 Shortcuts.prototype.add = function (pattern, desc, cmdFunc, scope) {
25888 var self = this;
25889 var cmd;
25890 cmd = cmdFunc;
25891 if (typeof cmdFunc === 'string') {
25892 cmdFunc = function () {
25893 self.editor.execCommand(cmd, false, null);
25894 };
25895 } else if (Tools.isArray(cmd)) {
25896 cmdFunc = function () {
25897 self.editor.execCommand(cmd[0], cmd[1], cmd[2]);
25898 };
25899 }
25900 each$h(explode$3(Tools.trim(pattern)), function (pattern) {
25901 var shortcut = self.createShortcut(pattern, desc, cmdFunc, scope);
25902 self.shortcuts[shortcut.id] = shortcut;
25903 });
25904 return true;
25905 };
25906 Shortcuts.prototype.remove = function (pattern) {
25907 var shortcut = this.createShortcut(pattern);
25908 if (this.shortcuts[shortcut.id]) {
25909 delete this.shortcuts[shortcut.id];
25910 return true;
25911 }
25912 return false;
25913 };
25914 Shortcuts.prototype.parseShortcut = function (pattern) {
25915 var id, key;
25916 var shortcut = {};
25917 each$h(explode$3(pattern.toLowerCase(), '+'), function (value) {
25918 if (value in modifierNames) {
25919 shortcut[value] = true;
25920 } else {
25921 if (/^[0-9]{2,}$/.test(value)) {
25922 shortcut.keyCode = parseInt(value, 10);
25923 } else {
25924 shortcut.charCode = value.charCodeAt(0);
25925 shortcut.keyCode = keyCodeLookup[value] || value.toUpperCase().charCodeAt(0);
25926 }
25927 }
25928 });
25929 id = [shortcut.keyCode];
25930 for (key in modifierNames) {
25931 if (shortcut[key]) {
25932 id.push(key);
25933 } else {
25934 shortcut[key] = false;
25935 }
25936 }
25937 shortcut.id = id.join(',');
25938 if (shortcut.access) {
25939 shortcut.alt = true;
25940 if (Env.mac) {
25941 shortcut.ctrl = true;
25942 } else {
25943 shortcut.shift = true;
25944 }
25945 }
25946 if (shortcut.meta) {
25947 if (Env.mac) {
25948 shortcut.meta = true;
25949 } else {
25950 shortcut.ctrl = true;
25951 shortcut.meta = false;
25952 }
25953 }
25954 return shortcut;
25955 };
25956 Shortcuts.prototype.createShortcut = function (pattern, desc, cmdFunc, scope) {
25957 var shortcuts;
25958 shortcuts = Tools.map(explode$3(pattern, '>'), this.parseShortcut);
25959 shortcuts[shortcuts.length - 1] = Tools.extend(shortcuts[shortcuts.length - 1], {
25960 func: cmdFunc,
25961 scope: scope || this.editor
25962 });
25963 return Tools.extend(shortcuts[0], {
25964 desc: this.editor.translate(desc),
25965 subpatterns: shortcuts.slice(1)
25966 });
25967 };
25968 Shortcuts.prototype.hasModifier = function (e) {
25969 return e.altKey || e.ctrlKey || e.metaKey;
25970 };
25971 Shortcuts.prototype.isFunctionKey = function (e) {
25972 return e.type === 'keydown' && e.keyCode >= 112 && e.keyCode <= 123;
25973 };
25974 Shortcuts.prototype.matchShortcut = function (e, shortcut) {
25975 if (!shortcut) {
25976 return false;
25977 }
25978 if (shortcut.ctrl !== e.ctrlKey || shortcut.meta !== e.metaKey) {
25979 return false;
25980 }
25981 if (shortcut.alt !== e.altKey || shortcut.shift !== e.shiftKey) {
25982 return false;
25983 }
25984 if (e.keyCode === shortcut.keyCode || e.charCode && e.charCode === shortcut.charCode) {
25985 e.preventDefault();
25986 return true;
25987 }
25988 return false;
25989 };
25990 Shortcuts.prototype.executeShortcutAction = function (shortcut) {
25991 return shortcut.func ? shortcut.func.call(shortcut.scope) : null;
25992 };
25993 return Shortcuts;
25994 }();
25995
25996 var each$i = Tools.each, trim$4 = Tools.trim;
25997 var queryParts = 'source protocol authority userInfo user password host port relative path directory file query anchor'.split(' ');
25998 var DEFAULT_PORTS = {
25999 ftp: 21,
26000 http: 80,
26001 https: 443,
26002 mailto: 25
26003 };
26004 var URI = function () {
26005 function URI(url, settings) {
26006 url = trim$4(url);
26007 this.settings = settings || {};
26008 var baseUri = this.settings.base_uri;
26009 var self = this;
26010 if (/^([\w\-]+):([^\/]{2})/i.test(url) || /^\s*#/.test(url)) {
26011 self.source = url;
26012 return;
26013 }
26014 var isProtocolRelative = url.indexOf('//') === 0;
26015 if (url.indexOf('/') === 0 && !isProtocolRelative) {
26016 url = (baseUri ? baseUri.protocol || 'http' : 'http') + '://mce_host' + url;
26017 }
26018 if (!/^[\w\-]*:?\/\//.test(url)) {
26019 var baseUrl = this.settings.base_uri ? this.settings.base_uri.path : new URI(domGlobals.document.location.href).directory;
26020 if (this.settings.base_uri && this.settings.base_uri.protocol == '') {
26021 url = '//mce_host' + self.toAbsPath(baseUrl, url);
26022 } else {
26023 var match = /([^#?]*)([#?]?.*)/.exec(url);
26024 url = (baseUri && baseUri.protocol || 'http') + '://mce_host' + self.toAbsPath(baseUrl, match[1]) + match[2];
26025 }
26026 }
26027 url = url.replace(/@@/g, '(mce_at)');
26028 var urlMatch = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(url);
26029 each$i(queryParts, function (v, i) {
26030 var part = urlMatch[i];
26031 if (part) {
26032 part = part.replace(/\(mce_at\)/g, '@@');
26033 }
26034 self[v] = part;
26035 });
26036 if (baseUri) {
26037 if (!self.protocol) {
26038 self.protocol = baseUri.protocol;
26039 }
26040 if (!self.userInfo) {
26041 self.userInfo = baseUri.userInfo;
26042 }
26043 if (!self.port && self.host === 'mce_host') {
26044 self.port = baseUri.port;
26045 }
26046 if (!self.host || self.host === 'mce_host') {
26047 self.host = baseUri.host;
26048 }
26049 self.source = '';
26050 }
26051 if (isProtocolRelative) {
26052 self.protocol = '';
26053 }
26054 }
26055 URI.parseDataUri = function (uri) {
26056 var type;
26057 var uriComponents = decodeURIComponent(uri).split(',');
26058 var matches = /data:([^;]+)/.exec(uriComponents[0]);
26059 if (matches) {
26060 type = matches[1];
26061 }
26062 return {
26063 type: type,
26064 data: uriComponents[1]
26065 };
26066 };
26067 URI.getDocumentBaseUrl = function (loc) {
26068 var baseUrl;
26069 if (loc.protocol.indexOf('http') !== 0 && loc.protocol !== 'file:') {
26070 baseUrl = loc.href;
26071 } else {
26072 baseUrl = loc.protocol + '//' + loc.host + loc.pathname;
26073 }
26074 if (/^[^:]+:\/\/\/?[^\/]+\//.test(baseUrl)) {
26075 baseUrl = baseUrl.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');
26076 if (!/[\/\\]$/.test(baseUrl)) {
26077 baseUrl += '/';
26078 }
26079 }
26080 return baseUrl;
26081 };
26082 URI.prototype.setPath = function (path) {
26083 var pathMatch = /^(.*?)\/?(\w+)?$/.exec(path);
26084 this.path = pathMatch[0];
26085 this.directory = pathMatch[1];
26086 this.file = pathMatch[2];
26087 this.source = '';
26088 this.getURI();
26089 };
26090 URI.prototype.toRelative = function (uri) {
26091 var output;
26092 if (uri === './') {
26093 return uri;
26094 }
26095 var relativeUri = new URI(uri, { base_uri: this });
26096 if (relativeUri.host !== 'mce_host' && this.host !== relativeUri.host && relativeUri.host || this.port !== relativeUri.port || this.protocol !== relativeUri.protocol && relativeUri.protocol !== '') {
26097 return relativeUri.getURI();
26098 }
26099 var tu = this.getURI(), uu = relativeUri.getURI();
26100 if (tu === uu || tu.charAt(tu.length - 1) === '/' && tu.substr(0, tu.length - 1) === uu) {
26101 return tu;
26102 }
26103 output = this.toRelPath(this.path, relativeUri.path);
26104 if (relativeUri.query) {
26105 output += '?' + relativeUri.query;
26106 }
26107 if (relativeUri.anchor) {
26108 output += '#' + relativeUri.anchor;
26109 }
26110 return output;
26111 };
26112 URI.prototype.toAbsolute = function (uri, noHost) {
26113 var absoluteUri = new URI(uri, { base_uri: this });
26114 return absoluteUri.getURI(noHost && this.isSameOrigin(absoluteUri));
26115 };
26116 URI.prototype.isSameOrigin = function (uri) {
26117 if (this.host == uri.host && this.protocol == uri.protocol) {
26118 if (this.port == uri.port) {
26119 return true;
26120 }
26121 var defaultPort = DEFAULT_PORTS[this.protocol];
26122 if (defaultPort && (this.port || defaultPort) == (uri.port || defaultPort)) {
26123 return true;
26124 }
26125 }
26126 return false;
26127 };
26128 URI.prototype.toRelPath = function (base, path) {
26129 var items, breakPoint = 0, out = '', i, l;
26130 var normalizedBase = base.substring(0, base.lastIndexOf('/')).split('/');
26131 items = path.split('/');
26132 if (normalizedBase.length >= items.length) {
26133 for (i = 0, l = normalizedBase.length; i < l; i++) {
26134 if (i >= items.length || normalizedBase[i] !== items[i]) {
26135 breakPoint = i + 1;
26136 break;
26137 }
26138 }
26139 }
26140 if (normalizedBase.length < items.length) {
26141 for (i = 0, l = items.length; i < l; i++) {
26142 if (i >= normalizedBase.length || normalizedBase[i] !== items[i]) {
26143 breakPoint = i + 1;
26144 break;
26145 }
26146 }
26147 }
26148 if (breakPoint === 1) {
26149 return path;
26150 }
26151 for (i = 0, l = normalizedBase.length - (breakPoint - 1); i < l; i++) {
26152 out += '../';
26153 }
26154 for (i = breakPoint - 1, l = items.length; i < l; i++) {
26155 if (i !== breakPoint - 1) {
26156 out += '/' + items[i];
26157 } else {
26158 out += items[i];
26159 }
26160 }
26161 return out;
26162 };
26163 URI.prototype.toAbsPath = function (base, path) {
26164 var i, nb = 0, o = [], tr, outPath;
26165 tr = /\/$/.test(path) ? '/' : '';
26166 var normalizedBase = base.split('/');
26167 var normalizedPath = path.split('/');
26168 each$i(normalizedBase, function (k) {
26169 if (k) {
26170 o.push(k);
26171 }
26172 });
26173 normalizedBase = o;
26174 for (i = normalizedPath.length - 1, o = []; i >= 0; i--) {
26175 if (normalizedPath[i].length === 0 || normalizedPath[i] === '.') {
26176 continue;
26177 }
26178 if (normalizedPath[i] === '..') {
26179 nb++;
26180 continue;
26181 }
26182 if (nb > 0) {
26183 nb--;
26184 continue;
26185 }
26186 o.push(normalizedPath[i]);
26187 }
26188 i = normalizedBase.length - nb;
26189 if (i <= 0) {
26190 outPath = o.reverse().join('/');
26191 } else {
26192 outPath = normalizedBase.slice(0, i).join('/') + '/' + o.reverse().join('/');
26193 }
26194 if (outPath.indexOf('/') !== 0) {
26195 outPath = '/' + outPath;
26196 }
26197 if (tr && outPath.lastIndexOf('/') !== outPath.length - 1) {
26198 outPath += tr;
26199 }
26200 return outPath;
26201 };
26202 URI.prototype.getURI = function (noProtoHost) {
26203 if (noProtoHost === void 0) {
26204 noProtoHost = false;
26205 }
26206 var s;
26207 if (!this.source || noProtoHost) {
26208 s = '';
26209 if (!noProtoHost) {
26210 if (this.protocol) {
26211 s += this.protocol + '://';
26212 } else {
26213 s += '//';
26214 }
26215 if (this.userInfo) {
26216 s += this.userInfo + '@';
26217 }
26218 if (this.host) {
26219 s += this.host;
26220 }
26221 if (this.port) {
26222 s += ':' + this.port;
26223 }
26224 }
26225 if (this.path) {
26226 s += this.path;
26227 }
26228 if (this.query) {
26229 s += '?' + this.query;
26230 }
26231 if (this.anchor) {
26232 s += '#' + this.anchor;
26233 }
26234 this.source = s;
26235 }
26236 return this.source;
26237 };
26238 return URI;
26239 }();
26240
26241 var create$5 = function () {
26242 var buttons = {};
26243 var menuItems = {};
26244 var popups = {};
26245 var icons = {};
26246 var contextMenus = {};
26247 var contextToolbars = {};
26248 var sidebars = {};
26249 var add = function (collection, type) {
26250 return function (name, spec) {
26251 return collection[name.toLowerCase()] = __assign({}, spec, { type: type });
26252 };
26253 };
26254 var addIcon = function (name, svgData) {
26255 return icons[name.toLowerCase()] = svgData;
26256 };
26257 return {
26258 addButton: add(buttons, 'button'),
26259 addToggleButton: add(buttons, 'togglebutton'),
26260 addMenuButton: add(buttons, 'menubutton'),
26261 addSplitButton: add(buttons, 'splitbutton'),
26262 addMenuItem: add(menuItems, 'menuitem'),
26263 addNestedMenuItem: add(menuItems, 'nestedmenuitem'),
26264 addToggleMenuItem: add(menuItems, 'togglemenuitem'),
26265 addAutocompleter: add(popups, 'autocompleter'),
26266 addContextMenu: add(contextMenus, 'contextmenu'),
26267 addContextToolbar: add(contextToolbars, 'contexttoolbar'),
26268 addContextForm: add(contextToolbars, 'contextform'),
26269 addSidebar: add(sidebars, 'sidebar'),
26270 addIcon: addIcon,
26271 getAll: function () {
26272 return {
26273 buttons: buttons,
26274 menuItems: menuItems,
26275 icons: icons,
26276 popups: popups,
26277 contextMenus: contextMenus,
26278 contextToolbars: contextToolbars,
26279 sidebars: sidebars
26280 };
26281 }
26282 };
26283 };
26284
26285 var registry = function () {
26286 var bridge = create$5();
26287 return {
26288 addAutocompleter: bridge.addAutocompleter,
26289 addButton: bridge.addButton,
26290 addContextForm: bridge.addContextForm,
26291 addContextMenu: bridge.addContextMenu,
26292 addContextToolbar: bridge.addContextToolbar,
26293 addIcon: bridge.addIcon,
26294 addMenuButton: bridge.addMenuButton,
26295 addMenuItem: bridge.addMenuItem,
26296 addNestedMenuItem: bridge.addNestedMenuItem,
26297 addSidebar: bridge.addSidebar,
26298 addSplitButton: bridge.addSplitButton,
26299 addToggleButton: bridge.addToggleButton,
26300 addToggleMenuItem: bridge.addToggleMenuItem,
26301 getAll: bridge.getAll
26302 };
26303 };
26304
26305 var DOM$8 = DOMUtils$1.DOM;
26306 var extend$3 = Tools.extend, each$j = Tools.each;
26307 var resolve$4 = Tools.resolve;
26308 var ie$2 = Env.ie;
26309 var Editor = function () {
26310 function Editor(id, settings, editorManager) {
26311 var _this = this;
26312 this.plugins = {};
26313 this.contentCSS = [];
26314 this.contentStyles = [];
26315 this.loadedCSS = {};
26316 this.isNotDirty = false;
26317 this.editorManager = editorManager;
26318 this.documentBaseUrl = editorManager.documentBaseURL;
26319 extend$3(this, EditorObservable);
26320 this.settings = getEditorSettings(this, id, this.documentBaseUrl, editorManager.defaultSettings, settings);
26321 if (this.settings.suffix) {
26322 editorManager.suffix = this.settings.suffix;
26323 }
26324 this.suffix = editorManager.suffix;
26325 if (this.settings.base_url) {
26326 editorManager._setBaseUrl(this.settings.base_url);
26327 }
26328 this.baseUri = editorManager.baseURI;
26329 AddOnManager$1.languageLoad = this.settings.language_load;
26330 AddOnManager$1.baseURL = editorManager.baseURL;
26331 this.id = id;
26332 this.setDirty(false);
26333 this.documentBaseURI = new URI(this.settings.document_base_url, { base_uri: this.baseUri });
26334 this.baseURI = this.baseUri;
26335 this.inline = this.settings.inline;
26336 this.shortcuts = new Shortcuts(this);
26337 this.editorCommands = new EditorCommands(this);
26338 if (this.settings.cache_suffix) {
26339 Env.cacheSuffix = this.settings.cache_suffix.replace(/^[\?\&]+/, '');
26340 }
26341 this.ui = { registry: registry() };
26342 var self = this;
26343 var modeInstance = create$4(self);
26344 this.mode = modeInstance;
26345 this.setMode = modeInstance.set;
26346 editorManager.fire('SetupEditor', { editor: this });
26347 this.execCallback('setup', this);
26348 this.$ = DomQuery.overrideDefaults(function () {
26349 return {
26350 context: _this.inline ? _this.getBody() : _this.getDoc(),
26351 element: _this.getBody()
26352 };
26353 });
26354 }
26355 Editor.prototype.render = function () {
26356 Render.render(this);
26357 };
26358 Editor.prototype.focus = function (skipFocus) {
26359 EditorFocus.focus(this, skipFocus);
26360 };
26361 Editor.prototype.hasFocus = function () {
26362 return EditorFocus.hasFocus(this);
26363 };
26364 Editor.prototype.execCallback = function (name) {
26365 var x = [];
26366 for (var _i = 1; _i < arguments.length; _i++) {
26367 x[_i - 1] = arguments[_i];
26368 }
26369 var self = this;
26370 var callback = self.settings[name], scope;
26371 if (!callback) {
26372 return;
26373 }
26374 if (self.callbackLookup && (scope = self.callbackLookup[name])) {
26375 callback = scope.func;
26376 scope = scope.scope;
26377 }
26378 if (typeof callback === 'string') {
26379 scope = callback.replace(/\.\w+$/, '');
26380 scope = scope ? resolve$4(scope) : 0;
26381 callback = resolve$4(callback);
26382 self.callbackLookup = self.callbackLookup || {};
26383 self.callbackLookup[name] = {
26384 func: callback,
26385 scope: scope
26386 };
26387 }
26388 return callback.apply(scope || self, Array.prototype.slice.call(arguments, 1));
26389 };
26390 Editor.prototype.translate = function (text) {
26391 return I18n.translate(text);
26392 };
26393 Editor.prototype.getParam = function (name, defaultVal, type) {
26394 return getParam(this, name, defaultVal, type);
26395 };
26396 Editor.prototype.nodeChanged = function (args) {
26397 this._nodeChangeDispatcher.nodeChanged(args);
26398 };
26399 Editor.prototype.addCommand = function (name, callback, scope) {
26400 this.editorCommands.addCommand(name, callback, scope);
26401 };
26402 Editor.prototype.addQueryStateHandler = function (name, callback, scope) {
26403 this.editorCommands.addQueryStateHandler(name, callback, scope);
26404 };
26405 Editor.prototype.addQueryValueHandler = function (name, callback, scope) {
26406 this.editorCommands.addQueryValueHandler(name, callback, scope);
26407 };
26408 Editor.prototype.addShortcut = function (pattern, desc, cmdFunc, scope) {
26409 this.shortcuts.add(pattern, desc, cmdFunc, scope);
26410 };
26411 Editor.prototype.execCommand = function (cmd, ui, value, args) {
26412 return this.editorCommands.execCommand(cmd, ui, value, args);
26413 };
26414 Editor.prototype.queryCommandState = function (cmd) {
26415 return this.editorCommands.queryCommandState(cmd);
26416 };
26417 Editor.prototype.queryCommandValue = function (cmd) {
26418 return this.editorCommands.queryCommandValue(cmd);
26419 };
26420 Editor.prototype.queryCommandSupported = function (cmd) {
26421 return this.editorCommands.queryCommandSupported(cmd);
26422 };
26423 Editor.prototype.show = function () {
26424 var self = this;
26425 if (self.hidden) {
26426 self.hidden = false;
26427 if (self.inline) {
26428 self.getBody().contentEditable = 'true';
26429 } else {
26430 DOM$8.show(self.getContainer());
26431 DOM$8.hide(self.id);
26432 }
26433 self.load();
26434 self.fire('show');
26435 }
26436 };
26437 Editor.prototype.hide = function () {
26438 var self = this, doc = self.getDoc();
26439 if (!self.hidden) {
26440 if (ie$2 && doc && !self.inline) {
26441 doc.execCommand('SelectAll');
26442 }
26443 self.save();
26444 if (self.inline) {
26445 self.getBody().contentEditable = 'false';
26446 if (self === self.editorManager.focusedEditor) {
26447 self.editorManager.focusedEditor = null;
26448 }
26449 } else {
26450 DOM$8.hide(self.getContainer());
26451 DOM$8.setStyle(self.id, 'display', self.orgDisplay);
26452 }
26453 self.hidden = true;
26454 self.fire('hide');
26455 }
26456 };
26457 Editor.prototype.isHidden = function () {
26458 return !!this.hidden;
26459 };
26460 Editor.prototype.setProgressState = function (state, time) {
26461 this.fire('ProgressState', {
26462 state: state,
26463 time: time
26464 });
26465 };
26466 Editor.prototype.load = function (args) {
26467 var self = this;
26468 var elm = self.getElement(), html;
26469 if (self.removed) {
26470 return '';
26471 }
26472 if (elm) {
26473 args = args || {};
26474 args.load = true;
26475 var value = NodeType.isTextareaOrInput(elm) ? elm.value : elm.innerHTML;
26476 html = self.setContent(value, args);
26477 args.element = elm;
26478 if (!args.no_events) {
26479 self.fire('LoadContent', args);
26480 }
26481 args.element = elm = null;
26482 return html;
26483 }
26484 };
26485 Editor.prototype.save = function (args) {
26486 var self = this;
26487 var elm = self.getElement(), html, form;
26488 if (!elm || !self.initialized || self.removed) {
26489 return;
26490 }
26491 args = args || {};
26492 args.save = true;
26493 args.element = elm;
26494 html = args.content = self.getContent(args);
26495 if (!args.no_events) {
26496 self.fire('SaveContent', args);
26497 }
26498 if (args.format === 'raw') {
26499 self.fire('RawSaveContent', args);
26500 }
26501 html = args.content;
26502 if (!NodeType.isTextareaOrInput(elm)) {
26503 if (args.is_removing || !self.inline) {
26504 elm.innerHTML = html;
26505 }
26506 if (form = DOM$8.getParent(self.id, 'form')) {
26507 each$j(form.elements, function (elm) {
26508 if (elm.name === self.id) {
26509 elm.value = html;
26510 return false;
26511 }
26512 });
26513 }
26514 } else {
26515 elm.value = html;
26516 }
26517 args.element = elm = null;
26518 if (args.set_dirty !== false) {
26519 self.setDirty(false);
26520 }
26521 return html;
26522 };
26523 Editor.prototype.setContent = function (content, args) {
26524 return setContent(this, content, args);
26525 };
26526 Editor.prototype.getContent = function (args) {
26527 return getContent(this, args);
26528 };
26529 Editor.prototype.insertContent = function (content, args) {
26530 if (args) {
26531 content = extend$3({ content: content }, args);
26532 }
26533 this.execCommand('mceInsertContent', false, content);
26534 };
26535 Editor.prototype.resetContent = function (initialContent) {
26536 if (initialContent === undefined) {
26537 setContent(this, this.startContent, { format: 'raw' });
26538 } else {
26539 setContent(this, initialContent);
26540 }
26541 this.undoManager.reset();
26542 this.setDirty(false);
26543 this.nodeChanged();
26544 };
26545 Editor.prototype.isDirty = function () {
26546 return !this.isNotDirty;
26547 };
26548 Editor.prototype.setDirty = function (state) {
26549 var oldState = !this.isNotDirty;
26550 this.isNotDirty = !state;
26551 if (state && state !== oldState) {
26552 this.fire('dirty');
26553 }
26554 };
26555 Editor.prototype.getContainer = function () {
26556 var self = this;
26557 if (!self.container) {
26558 self.container = DOM$8.get(self.editorContainer || self.id + '_parent');
26559 }
26560 return self.container;
26561 };
26562 Editor.prototype.getContentAreaContainer = function () {
26563 return this.contentAreaContainer;
26564 };
26565 Editor.prototype.getElement = function () {
26566 if (!this.targetElm) {
26567 this.targetElm = DOM$8.get(this.id);
26568 }
26569 return this.targetElm;
26570 };
26571 Editor.prototype.getWin = function () {
26572 var self = this;
26573 var elm;
26574 if (!self.contentWindow) {
26575 elm = self.iframeElement;
26576 if (elm) {
26577 self.contentWindow = elm.contentWindow;
26578 }
26579 }
26580 return self.contentWindow;
26581 };
26582 Editor.prototype.getDoc = function () {
26583 var self = this;
26584 var win;
26585 if (!self.contentDocument) {
26586 win = self.getWin();
26587 if (win) {
26588 self.contentDocument = win.document;
26589 }
26590 }
26591 return self.contentDocument;
26592 };
26593 Editor.prototype.getBody = function () {
26594 var doc = this.getDoc();
26595 return this.bodyElement || (doc ? doc.body : null);
26596 };
26597 Editor.prototype.convertURL = function (url, name, elm) {
26598 var self = this, settings = self.settings;
26599 if (settings.urlconverter_callback) {
26600 return self.execCallback('urlconverter_callback', url, elm, true, name);
26601 }
26602 if (!settings.convert_urls || elm && elm.nodeName === 'LINK' || url.indexOf('file:') === 0 || url.length === 0) {
26603 return url;
26604 }
26605 if (settings.relative_urls) {
26606 return self.documentBaseURI.toRelative(url);
26607 }
26608 url = self.documentBaseURI.toAbsolute(url, settings.remove_script_host);
26609 return url;
26610 };
26611 Editor.prototype.addVisual = function (elm) {
26612 var self = this;
26613 var settings = self.settings;
26614 var dom = self.dom;
26615 var cls;
26616 elm = elm || self.getBody();
26617 if (self.hasVisual === undefined) {
26618 self.hasVisual = settings.visual;
26619 }
26620 each$j(dom.select('table,a', elm), function (elm) {
26621 var value;
26622 switch (elm.nodeName) {
26623 case 'TABLE':
26624 cls = settings.visual_table_class || 'mce-item-table';
26625 value = dom.getAttrib(elm, 'border');
26626 if ((!value || value === '0') && self.hasVisual) {
26627 dom.addClass(elm, cls);
26628 } else {
26629 dom.removeClass(elm, cls);
26630 }
26631 return;
26632 case 'A':
26633 if (!dom.getAttrib(elm, 'href')) {
26634 value = dom.getAttrib(elm, 'name') || elm.id;
26635 cls = settings.visual_anchor_class || 'mce-item-anchor';
26636 if (value && self.hasVisual) {
26637 dom.addClass(elm, cls);
26638 } else {
26639 dom.removeClass(elm, cls);
26640 }
26641 }
26642 return;
26643 }
26644 });
26645 self.fire('VisualAid', {
26646 element: elm,
26647 hasVisual: self.hasVisual
26648 });
26649 };
26650 Editor.prototype.remove = function () {
26651 remove$6(this);
26652 };
26653 Editor.prototype.destroy = function (automatic) {
26654 destroy(this, automatic);
26655 };
26656 Editor.prototype.uploadImages = function (callback) {
26657 return this.editorUpload.uploadImages(callback);
26658 };
26659 Editor.prototype._scanForImages = function () {
26660 return this.editorUpload.scanForImages();
26661 };
26662 Editor.prototype.addButton = function () {
26663 throw new Error('editor.addButton has been removed in tinymce 5x, use editor.ui.registry.addButton or editor.ui.registry.addToggleButton or editor.ui.registry.addSplitButton instead');
26664 };
26665 Editor.prototype.addSidebar = function () {
26666 throw new Error('editor.addSidebar has been removed in tinymce 5x, use editor.ui.registry.addSidebar instead');
26667 };
26668 Editor.prototype.addMenuItem = function () {
26669 throw new Error('editor.addMenuItem has been removed in tinymce 5x, use editor.ui.registry.addMenuItem instead');
26670 };
26671 Editor.prototype.addContextToolbar = function () {
26672 throw new Error('editor.addContextToolbar has been removed in tinymce 5x, use editor.ui.registry.addContextToolbar instead');
26673 };
26674 return Editor;
26675 }();
26676
26677 var DOM$9 = DOMUtils$1.DOM;
26678 var explode$4 = Tools.explode, each$k = Tools.each, extend$4 = Tools.extend;
26679 var instanceCounter = 0, boundGlobalEvents = false;
26680 var beforeUnloadDelegate;
26681 var legacyEditors = [];
26682 var editors = [];
26683 var isValidLegacyKey = function (id) {
26684 return id !== 'length';
26685 };
26686 var globalEventDelegate = function (e) {
26687 var type = e.type;
26688 each$k(EditorManager.get(), function (editor) {
26689 switch (type) {
26690 case 'scroll':
26691 editor.fire('ScrollWindow', e);
26692 break;
26693 case 'resize':
26694 editor.fire('ResizeWindow', e);
26695 break;
26696 }
26697 });
26698 };
26699 var toggleGlobalEvents = function (state) {
26700 if (state !== boundGlobalEvents) {
26701 if (state) {
26702 DomQuery(window).on('resize scroll', globalEventDelegate);
26703 } else {
26704 DomQuery(window).off('resize scroll', globalEventDelegate);
26705 }
26706 boundGlobalEvents = state;
26707 }
26708 };
26709 var removeEditorFromList = function (targetEditor) {
26710 var oldEditors = editors;
26711 delete legacyEditors[targetEditor.id];
26712 for (var i = 0; i < legacyEditors.length; i++) {
26713 if (legacyEditors[i] === targetEditor) {
26714 legacyEditors.splice(i, 1);
26715 break;
26716 }
26717 }
26718 editors = filter(editors, function (editor) {
26719 return targetEditor !== editor;
26720 });
26721 if (EditorManager.activeEditor === targetEditor) {
26722 EditorManager.activeEditor = editors.length > 0 ? editors[0] : null;
26723 }
26724 if (EditorManager.focusedEditor === targetEditor) {
26725 EditorManager.focusedEditor = null;
26726 }
26727 return oldEditors.length !== editors.length;
26728 };
26729 var purgeDestroyedEditor = function (editor) {
26730 if (editor && editor.initialized && !(editor.getContainer() || editor.getBody()).parentNode) {
26731 removeEditorFromList(editor);
26732 editor.unbindAllNativeEvents();
26733 editor.destroy(true);
26734 editor.removed = true;
26735 editor = null;
26736 }
26737 return editor;
26738 };
26739 var isQuirksMode = domGlobals.document.compatMode !== 'CSS1Compat';
26740 var EditorManager = __assign({}, Observable, {
26741 baseURI: null,
26742 baseURL: null,
26743 defaultSettings: {},
26744 documentBaseURL: null,
26745 suffix: null,
26746 $: DomQuery,
26747 majorVersion: '5',
26748 minorVersion: '0.12',
26749 releaseDate: '2019-07-18',
26750 editors: legacyEditors,
26751 i18n: I18n,
26752 activeEditor: null,
26753 focusedEditor: null,
26754 settings: {},
26755 setup: function () {
26756 var self = this;
26757 var baseURL, documentBaseURL, suffix = '', preInit, src;
26758 documentBaseURL = URI.getDocumentBaseUrl(domGlobals.document.location);
26759 if (/^[^:]+:\/\/\/?[^\/]+\//.test(documentBaseURL)) {
26760 documentBaseURL = documentBaseURL.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');
26761 if (!/[\/\\]$/.test(documentBaseURL)) {
26762 documentBaseURL += '/';
26763 }
26764 }
26765 preInit = window.tinymce || window.tinyMCEPreInit;
26766 if (preInit) {
26767 baseURL = preInit.base || preInit.baseURL;
26768 suffix = preInit.suffix;
26769 } else {
26770 var scripts = domGlobals.document.getElementsByTagName('script');
26771 for (var i = 0; i < scripts.length; i++) {
26772 src = scripts[i].src;
26773 var srcScript = src.substring(src.lastIndexOf('/'));
26774 if (/tinymce(\.full|\.jquery|)(\.min|\.dev|)\.js/.test(src)) {
26775 if (srcScript.indexOf('.min') !== -1) {
26776 suffix = '.min';
26777 }
26778 baseURL = src.substring(0, src.lastIndexOf('/'));
26779 break;
26780 }
26781 }
26782 if (!baseURL && domGlobals.document.currentScript) {
26783 src = domGlobals.document.currentScript.src;
26784 if (src.indexOf('.min') !== -1) {
26785 suffix = '.min';
26786 }
26787 baseURL = src.substring(0, src.lastIndexOf('/'));
26788 }
26789 }
26790 self.baseURL = new URI(documentBaseURL).toAbsolute(baseURL);
26791 self.documentBaseURL = documentBaseURL;
26792 self.baseURI = new URI(self.baseURL);
26793 self.suffix = suffix;
26794 FocusController.setup(self);
26795 },
26796 overrideDefaults: function (defaultSettings) {
26797 var baseUrl, suffix;
26798 baseUrl = defaultSettings.base_url;
26799 if (baseUrl) {
26800 this._setBaseUrl(baseUrl);
26801 }
26802 suffix = defaultSettings.suffix;
26803 if (defaultSettings.suffix) {
26804 this.suffix = suffix;
26805 }
26806 this.defaultSettings = defaultSettings;
26807 var pluginBaseUrls = defaultSettings.plugin_base_urls;
26808 for (var name in pluginBaseUrls) {
26809 AddOnManager$1.PluginManager.urls[name] = pluginBaseUrls[name];
26810 }
26811 },
26812 init: function (settings) {
26813 var self = this;
26814 var result, invalidInlineTargets;
26815 invalidInlineTargets = Tools.makeMap('area base basefont br col frame hr img input isindex link meta param embed source wbr track ' + 'colgroup option table tbody tfoot thead tr th td script noscript style textarea video audio iframe object menu', ' ');
26816 var isInvalidInlineTarget = function (settings, elm) {
26817 return settings.inline && elm.tagName.toLowerCase() in invalidInlineTargets;
26818 };
26819 var createId = function (elm) {
26820 var id = elm.id;
26821 if (!id) {
26822 id = elm.name;
26823 if (id && !DOM$9.get(id)) {
26824 id = elm.name;
26825 } else {
26826 id = DOM$9.uniqueId();
26827 }
26828 elm.setAttribute('id', id);
26829 }
26830 return id;
26831 };
26832 var execCallback = function (name) {
26833 var callback = settings[name];
26834 if (!callback) {
26835 return;
26836 }
26837 return callback.apply(self, Array.prototype.slice.call(arguments, 2));
26838 };
26839 var hasClass = function (elm, className) {
26840 return className.constructor === RegExp ? className.test(elm.className) : DOM$9.hasClass(elm, className);
26841 };
26842 var findTargets = function (settings) {
26843 var l, targets = [];
26844 if (Env.ie && Env.ie < 11) {
26845 ErrorReporter.initError('TinyMCE does not support the browser you are using. For a list of supported' + ' browsers please see: https://www.tinymce.com/docs/get-started/system-requirements/');
26846 return [];
26847 } else if (isQuirksMode) {
26848 ErrorReporter.initError('Failed to initialize the editor as the document is not in standards mode. ' + 'TinyMCE requires standards mode.');
26849 return [];
26850 }
26851 if (settings.types) {
26852 each$k(settings.types, function (type) {
26853 targets = targets.concat(DOM$9.select(type.selector));
26854 });
26855 return targets;
26856 } else if (settings.selector) {
26857 return DOM$9.select(settings.selector);
26858 } else if (settings.target) {
26859 return [settings.target];
26860 }
26861 switch (settings.mode) {
26862 case 'exact':
26863 l = settings.elements || '';
26864 if (l.length > 0) {
26865 each$k(explode$4(l), function (id) {
26866 var elm;
26867 if (elm = DOM$9.get(id)) {
26868 targets.push(elm);
26869 } else {
26870 each$k(domGlobals.document.forms, function (f) {
26871 each$k(f.elements, function (e) {
26872 if (e.name === id) {
26873 id = 'mce_editor_' + instanceCounter++;
26874 DOM$9.setAttrib(e, 'id', id);
26875 targets.push(e);
26876 }
26877 });
26878 });
26879 }
26880 });
26881 }
26882 break;
26883 case 'textareas':
26884 case 'specific_textareas':
26885 each$k(DOM$9.select('textarea'), function (elm) {
26886 if (settings.editor_deselector && hasClass(elm, settings.editor_deselector)) {
26887 return;
26888 }
26889 if (!settings.editor_selector || hasClass(elm, settings.editor_selector)) {
26890 targets.push(elm);
26891 }
26892 });
26893 break;
26894 }
26895 return targets;
26896 };
26897 var provideResults = function (editors) {
26898 result = editors;
26899 };
26900 var initEditors = function () {
26901 var initCount = 0;
26902 var editors = [];
26903 var targets;
26904 var createEditor = function (id, settings, targetElm) {
26905 var editor = new Editor(id, settings, self);
26906 editors.push(editor);
26907 editor.on('init', function () {
26908 if (++initCount === targets.length) {
26909 provideResults(editors);
26910 }
26911 });
26912 editor.targetElm = editor.targetElm || targetElm;
26913 editor.render();
26914 };
26915 DOM$9.unbind(window, 'ready', initEditors);
26916 execCallback('onpageload');
26917 targets = DomQuery.unique(findTargets(settings));
26918 if (settings.types) {
26919 each$k(settings.types, function (type) {
26920 Tools.each(targets, function (elm) {
26921 if (DOM$9.is(elm, type.selector)) {
26922 createEditor(createId(elm), extend$4({}, settings, type), elm);
26923 return false;
26924 }
26925 return true;
26926 });
26927 });
26928 return;
26929 }
26930 Tools.each(targets, function (elm) {
26931 purgeDestroyedEditor(self.get(elm.id));
26932 });
26933 targets = Tools.grep(targets, function (elm) {
26934 return !self.get(elm.id);
26935 });
26936 if (targets.length === 0) {
26937 provideResults([]);
26938 } else {
26939 each$k(targets, function (elm) {
26940 if (isInvalidInlineTarget(settings, elm)) {
26941 ErrorReporter.initError('Could not initialize inline editor on invalid inline target element', elm);
26942 } else {
26943 createEditor(createId(elm), settings, elm);
26944 }
26945 });
26946 }
26947 };
26948 self.settings = settings;
26949 DOM$9.bind(window, 'ready', initEditors);
26950 return new promiseObj(function (resolve) {
26951 if (result) {
26952 resolve(result);
26953 } else {
26954 provideResults = function (editors) {
26955 resolve(editors);
26956 };
26957 }
26958 });
26959 },
26960 get: function (id) {
26961 if (arguments.length === 0) {
26962 return editors.slice(0);
26963 } else if (isString(id)) {
26964 return find(editors, function (editor) {
26965 return editor.id === id;
26966 }).getOr(null);
26967 } else if (isNumber(id)) {
26968 return editors[id] ? editors[id] : null;
26969 } else {
26970 return null;
26971 }
26972 },
26973 add: function (editor) {
26974 var self = this;
26975 var existingEditor;
26976 existingEditor = legacyEditors[editor.id];
26977 if (existingEditor === editor) {
26978 return editor;
26979 }
26980 if (self.get(editor.id) === null) {
26981 if (isValidLegacyKey(editor.id)) {
26982 legacyEditors[editor.id] = editor;
26983 }
26984 legacyEditors.push(editor);
26985 editors.push(editor);
26986 }
26987 toggleGlobalEvents(true);
26988 self.activeEditor = editor;
26989 self.fire('AddEditor', { editor: editor });
26990 if (!beforeUnloadDelegate) {
26991 beforeUnloadDelegate = function (e) {
26992 var event = self.fire('BeforeUnload');
26993 if (event.returnValue) {
26994 e.preventDefault();
26995 e.returnValue = event.returnValue;
26996 return event.returnValue;
26997 }
26998 };
26999 window.addEventListener('beforeunload', beforeUnloadDelegate);
27000 }
27001 return editor;
27002 },
27003 createEditor: function (id, settings) {
27004 return this.add(new Editor(id, settings, this));
27005 },
27006 remove: function (selector) {
27007 var self = this;
27008 var i, editor;
27009 if (!selector) {
27010 for (i = editors.length - 1; i >= 0; i--) {
27011 self.remove(editors[i]);
27012 }
27013 return;
27014 }
27015 if (isString(selector)) {
27016 each$k(DOM$9.select(selector), function (elm) {
27017 editor = self.get(elm.id);
27018 if (editor) {
27019 self.remove(editor);
27020 }
27021 });
27022 return;
27023 }
27024 editor = selector;
27025 if (isNull(self.get(editor.id))) {
27026 return null;
27027 }
27028 if (removeEditorFromList(editor)) {
27029 self.fire('RemoveEditor', { editor: editor });
27030 }
27031 if (editors.length === 0) {
27032 window.removeEventListener('beforeunload', beforeUnloadDelegate);
27033 }
27034 editor.remove();
27035 toggleGlobalEvents(editors.length > 0);
27036 return editor;
27037 },
27038 execCommand: function (cmd, ui, value) {
27039 var self = this, editor = self.get(value);
27040 switch (cmd) {
27041 case 'mceAddEditor':
27042 if (!self.get(value)) {
27043 new Editor(value, self.settings, self).render();
27044 }
27045 return true;
27046 case 'mceRemoveEditor':
27047 if (editor) {
27048 editor.remove();
27049 }
27050 return true;
27051 case 'mceToggleEditor':
27052 if (!editor) {
27053 self.execCommand('mceAddEditor', 0, value);
27054 return true;
27055 }
27056 if (editor.isHidden()) {
27057 editor.show();
27058 } else {
27059 editor.hide();
27060 }
27061 return true;
27062 }
27063 if (self.activeEditor) {
27064 return self.activeEditor.execCommand(cmd, ui, value);
27065 }
27066 return false;
27067 },
27068 triggerSave: function () {
27069 each$k(editors, function (editor) {
27070 editor.save();
27071 });
27072 },
27073 addI18n: function (code, items) {
27074 I18n.add(code, items);
27075 },
27076 translate: function (text) {
27077 return I18n.translate(text);
27078 },
27079 setActive: function (editor) {
27080 var activeEditor = this.activeEditor;
27081 if (this.activeEditor !== editor) {
27082 if (activeEditor) {
27083 activeEditor.fire('deactivate', { relatedTarget: editor });
27084 }
27085 editor.fire('activate', { relatedTarget: activeEditor });
27086 }
27087 this.activeEditor = editor;
27088 },
27089 _setBaseUrl: function (baseUrl) {
27090 this.baseURL = new URI(this.documentBaseURL).toAbsolute(baseUrl.replace(/\/+$/, ''));
27091 this.baseURI = new URI(this.baseURL);
27092 }
27093 });
27094 EditorManager.setup();
27095
27096 function RangeUtils(dom) {
27097 var walk = function (rng, callback) {
27098 return RangeWalk.walk(dom, rng, callback);
27099 };
27100 var split = split$1;
27101 var normalize = function (rng) {
27102 return NormalizeRange.normalize(dom, rng).fold(constant(false), function (normalizedRng) {
27103 rng.setStart(normalizedRng.startContainer, normalizedRng.startOffset);
27104 rng.setEnd(normalizedRng.endContainer, normalizedRng.endOffset);
27105 return true;
27106 });
27107 };
27108 return {
27109 walk: walk,
27110 split: split,
27111 normalize: normalize
27112 };
27113 }
27114 (function (RangeUtils) {
27115 RangeUtils.compareRanges = RangeCompare.isEq;
27116 RangeUtils.getCaretRangeFromPoint = CaretRangeFromPoint.fromPoint;
27117 RangeUtils.getSelectedNode = getSelectedNode;
27118 RangeUtils.getNode = getNode;
27119 }(RangeUtils || (RangeUtils = {})));
27120 var RangeUtils$1 = RangeUtils;
27121
27122 var min = Math.min, max = Math.max, round$2 = Math.round;
27123 var relativePosition = function (rect, targetRect, rel) {
27124 var x, y, w, h, targetW, targetH;
27125 x = targetRect.x;
27126 y = targetRect.y;
27127 w = rect.w;
27128 h = rect.h;
27129 targetW = targetRect.w;
27130 targetH = targetRect.h;
27131 rel = (rel || '').split('');
27132 if (rel[0] === 'b') {
27133 y += targetH;
27134 }
27135 if (rel[1] === 'r') {
27136 x += targetW;
27137 }
27138 if (rel[0] === 'c') {
27139 y += round$2(targetH / 2);
27140 }
27141 if (rel[1] === 'c') {
27142 x += round$2(targetW / 2);
27143 }
27144 if (rel[3] === 'b') {
27145 y -= h;
27146 }
27147 if (rel[4] === 'r') {
27148 x -= w;
27149 }
27150 if (rel[3] === 'c') {
27151 y -= round$2(h / 2);
27152 }
27153 if (rel[4] === 'c') {
27154 x -= round$2(w / 2);
27155 }
27156 return create$6(x, y, w, h);
27157 };
27158 var findBestRelativePosition = function (rect, targetRect, constrainRect, rels) {
27159 var pos, i;
27160 for (i = 0; i < rels.length; i++) {
27161 pos = relativePosition(rect, targetRect, rels[i]);
27162 if (pos.x >= constrainRect.x && pos.x + pos.w <= constrainRect.w + constrainRect.x && pos.y >= constrainRect.y && pos.y + pos.h <= constrainRect.h + constrainRect.y) {
27163 return rels[i];
27164 }
27165 }
27166 return null;
27167 };
27168 var inflate = function (rect, w, h) {
27169 return create$6(rect.x - w, rect.y - h, rect.w + w * 2, rect.h + h * 2);
27170 };
27171 var intersect = function (rect, cropRect) {
27172 var x1, y1, x2, y2;
27173 x1 = max(rect.x, cropRect.x);
27174 y1 = max(rect.y, cropRect.y);
27175 x2 = min(rect.x + rect.w, cropRect.x + cropRect.w);
27176 y2 = min(rect.y + rect.h, cropRect.y + cropRect.h);
27177 if (x2 - x1 < 0 || y2 - y1 < 0) {
27178 return null;
27179 }
27180 return create$6(x1, y1, x2 - x1, y2 - y1);
27181 };
27182 var clamp$1 = function (rect, clampRect, fixedSize) {
27183 var underflowX1, underflowY1, overflowX2, overflowY2, x1, y1, x2, y2, cx2, cy2;
27184 x1 = rect.x;
27185 y1 = rect.y;
27186 x2 = rect.x + rect.w;
27187 y2 = rect.y + rect.h;
27188 cx2 = clampRect.x + clampRect.w;
27189 cy2 = clampRect.y + clampRect.h;
27190 underflowX1 = max(0, clampRect.x - x1);
27191 underflowY1 = max(0, clampRect.y - y1);
27192 overflowX2 = max(0, x2 - cx2);
27193 overflowY2 = max(0, y2 - cy2);
27194 x1 += underflowX1;
27195 y1 += underflowY1;
27196 if (fixedSize) {
27197 x2 += underflowX1;
27198 y2 += underflowY1;
27199 x1 -= overflowX2;
27200 y1 -= overflowY2;
27201 }
27202 x2 -= overflowX2;
27203 y2 -= overflowY2;
27204 return create$6(x1, y1, x2 - x1, y2 - y1);
27205 };
27206 var create$6 = function (x, y, w, h) {
27207 return {
27208 x: x,
27209 y: y,
27210 w: w,
27211 h: h
27212 };
27213 };
27214 var fromClientRect = function (clientRect) {
27215 return create$6(clientRect.left, clientRect.top, clientRect.width, clientRect.height);
27216 };
27217 var Rect = {
27218 inflate: inflate,
27219 relativePosition: relativePosition,
27220 findBestRelativePosition: findBestRelativePosition,
27221 intersect: intersect,
27222 clamp: clamp$1,
27223 create: create$6,
27224 fromClientRect: fromClientRect
27225 };
27226
27227 var each$l = Tools.each, extend$5 = Tools.extend;
27228 var extendClass, initializing;
27229 var Class = function () {
27230 };
27231 Class.extend = extendClass = function (prop) {
27232 var self = this;
27233 var _super = self.prototype;
27234 var prototype, name, member;
27235 var Class = function () {
27236 var i, mixins, mixin;
27237 var self = this;
27238 if (!initializing) {
27239 if (self.init) {
27240 self.init.apply(self, arguments);
27241 }
27242 mixins = self.Mixins;
27243 if (mixins) {
27244 i = mixins.length;
27245 while (i--) {
27246 mixin = mixins[i];
27247 if (mixin.init) {
27248 mixin.init.apply(self, arguments);
27249 }
27250 }
27251 }
27252 }
27253 };
27254 var dummy = function () {
27255 return this;
27256 };
27257 var createMethod = function (name, fn) {
27258 return function () {
27259 var self = this;
27260 var tmp = self._super;
27261 var ret;
27262 self._super = _super[name];
27263 ret = fn.apply(self, arguments);
27264 self._super = tmp;
27265 return ret;
27266 };
27267 };
27268 initializing = true;
27269 prototype = new self();
27270 initializing = false;
27271 if (prop.Mixins) {
27272 each$l(prop.Mixins, function (mixin) {
27273 for (var name_1 in mixin) {
27274 if (name_1 !== 'init') {
27275 prop[name_1] = mixin[name_1];
27276 }
27277 }
27278 });
27279 if (_super.Mixins) {
27280 prop.Mixins = _super.Mixins.concat(prop.Mixins);
27281 }
27282 }
27283 if (prop.Methods) {
27284 each$l(prop.Methods.split(','), function (name) {
27285 prop[name] = dummy;
27286 });
27287 }
27288 if (prop.Properties) {
27289 each$l(prop.Properties.split(','), function (name) {
27290 var fieldName = '_' + name;
27291 prop[name] = function (value) {
27292 var self = this;
27293 if (value !== undefined) {
27294 self[fieldName] = value;
27295 return self;
27296 }
27297 return self[fieldName];
27298 };
27299 });
27300 }
27301 if (prop.Statics) {
27302 each$l(prop.Statics, function (func, name) {
27303 Class[name] = func;
27304 });
27305 }
27306 if (prop.Defaults && _super.Defaults) {
27307 prop.Defaults = extend$5({}, _super.Defaults, prop.Defaults);
27308 }
27309 for (name in prop) {
27310 member = prop[name];
27311 if (typeof member === 'function' && _super[name]) {
27312 prototype[name] = createMethod(name, member);
27313 } else {
27314 prototype[name] = member;
27315 }
27316 }
27317 Class.prototype = prototype;
27318 Class.constructor = Class;
27319 Class.extend = extendClass;
27320 return Class;
27321 };
27322
27323 var min$1 = Math.min, max$1 = Math.max, round$3 = Math.round;
27324 var Color = function (value) {
27325 var self = {};
27326 var r = 0, g = 0, b = 0;
27327 var rgb2hsv = function (r, g, b) {
27328 var h, s, v, d, minRGB, maxRGB;
27329 h = 0;
27330 s = 0;
27331 v = 0;
27332 r = r / 255;
27333 g = g / 255;
27334 b = b / 255;
27335 minRGB = min$1(r, min$1(g, b));
27336 maxRGB = max$1(r, max$1(g, b));
27337 if (minRGB === maxRGB) {
27338 v = minRGB;
27339 return {
27340 h: 0,
27341 s: 0,
27342 v: v * 100
27343 };
27344 }
27345 d = r === minRGB ? g - b : b === minRGB ? r - g : b - r;
27346 h = r === minRGB ? 3 : b === minRGB ? 1 : 5;
27347 h = 60 * (h - d / (maxRGB - minRGB));
27348 s = (maxRGB - minRGB) / maxRGB;
27349 v = maxRGB;
27350 return {
27351 h: round$3(h),
27352 s: round$3(s * 100),
27353 v: round$3(v * 100)
27354 };
27355 };
27356 var hsvToRgb = function (hue, saturation, brightness) {
27357 var side, chroma, x, match;
27358 hue = (parseInt(hue, 10) || 0) % 360;
27359 saturation = parseInt(saturation, 10) / 100;
27360 brightness = parseInt(brightness, 10) / 100;
27361 saturation = max$1(0, min$1(saturation, 1));
27362 brightness = max$1(0, min$1(brightness, 1));
27363 if (saturation === 0) {
27364 r = g = b = round$3(255 * brightness);
27365 return;
27366 }
27367 side = hue / 60;
27368 chroma = brightness * saturation;
27369 x = chroma * (1 - Math.abs(side % 2 - 1));
27370 match = brightness - chroma;
27371 switch (Math.floor(side)) {
27372 case 0:
27373 r = chroma;
27374 g = x;
27375 b = 0;
27376 break;
27377 case 1:
27378 r = x;
27379 g = chroma;
27380 b = 0;
27381 break;
27382 case 2:
27383 r = 0;
27384 g = chroma;
27385 b = x;
27386 break;
27387 case 3:
27388 r = 0;
27389 g = x;
27390 b = chroma;
27391 break;
27392 case 4:
27393 r = x;
27394 g = 0;
27395 b = chroma;
27396 break;
27397 case 5:
27398 r = chroma;
27399 g = 0;
27400 b = x;
27401 break;
27402 default:
27403 r = g = b = 0;
27404 }
27405 r = round$3(255 * (r + match));
27406 g = round$3(255 * (g + match));
27407 b = round$3(255 * (b + match));
27408 };
27409 var toHex = function () {
27410 var hex = function (val) {
27411 val = parseInt(val, 10).toString(16);
27412 return val.length > 1 ? val : '0' + val;
27413 };
27414 return '#' + hex(r) + hex(g) + hex(b);
27415 };
27416 var toRgb = function () {
27417 return {
27418 r: r,
27419 g: g,
27420 b: b
27421 };
27422 };
27423 var toHsv = function () {
27424 return rgb2hsv(r, g, b);
27425 };
27426 var parse = function (value) {
27427 var matches;
27428 if (typeof value === 'object') {
27429 if ('r' in value) {
27430 r = value.r;
27431 g = value.g;
27432 b = value.b;
27433 } else if ('v' in value) {
27434 hsvToRgb(value.h, value.s, value.v);
27435 }
27436 } else {
27437 if (matches = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)[^\)]*\)/gi.exec(value)) {
27438 r = parseInt(matches[1], 10);
27439 g = parseInt(matches[2], 10);
27440 b = parseInt(matches[3], 10);
27441 } else if (matches = /#([0-F]{2})([0-F]{2})([0-F]{2})/gi.exec(value)) {
27442 r = parseInt(matches[1], 16);
27443 g = parseInt(matches[2], 16);
27444 b = parseInt(matches[3], 16);
27445 } else if (matches = /#([0-F])([0-F])([0-F])/gi.exec(value)) {
27446 r = parseInt(matches[1] + matches[1], 16);
27447 g = parseInt(matches[2] + matches[2], 16);
27448 b = parseInt(matches[3] + matches[3], 16);
27449 }
27450 }
27451 r = r < 0 ? 0 : r > 255 ? 255 : r;
27452 g = g < 0 ? 0 : g > 255 ? 255 : g;
27453 b = b < 0 ? 0 : b > 255 ? 255 : b;
27454 return self;
27455 };
27456 if (value) {
27457 parse(value);
27458 }
27459 self.toRgb = toRgb;
27460 self.toHsv = toHsv;
27461 self.toHex = toHex;
27462 self.parse = parse;
27463 return self;
27464 };
27465
27466 var serialize = function (obj) {
27467 var data = JSON.stringify(obj);
27468 if (!isString(data)) {
27469 return data;
27470 }
27471 return data.replace(/[\u0080-\uFFFF]/g, function (match) {
27472 var hexCode = match.charCodeAt(0).toString(16);
27473 return '\\u' + '0000'.substring(hexCode.length) + hexCode;
27474 });
27475 };
27476 var JSONUtils = {
27477 serialize: serialize,
27478 parse: function (text) {
27479 try {
27480 return JSON.parse(text);
27481 } catch (ex) {
27482 }
27483 }
27484 };
27485
27486 var JSONP = {
27487 callbacks: {},
27488 count: 0,
27489 send: function (settings) {
27490 var self = this, dom = DOMUtils$1.DOM, count = settings.count !== undefined ? settings.count : self.count;
27491 var id = 'tinymce_jsonp_' + count;
27492 self.callbacks[count] = function (json) {
27493 dom.remove(id);
27494 delete self.callbacks[count];
27495 settings.callback(json);
27496 };
27497 dom.add(dom.doc.body, 'script', {
27498 id: id,
27499 src: settings.url,
27500 type: 'text/javascript'
27501 });
27502 self.count++;
27503 }
27504 };
27505
27506 var XHR = __assign({}, Observable, {
27507 send: function (settings) {
27508 var xhr, count = 0;
27509 var ready = function () {
27510 if (!settings.async || xhr.readyState === 4 || count++ > 10000) {
27511 if (settings.success && count < 10000 && xhr.status === 200) {
27512 settings.success.call(settings.success_scope, '' + xhr.responseText, xhr, settings);
27513 } else if (settings.error) {
27514 settings.error.call(settings.error_scope, count > 10000 ? 'TIMED_OUT' : 'GENERAL', xhr, settings);
27515 }
27516 xhr = null;
27517 } else {
27518 Delay.setTimeout(ready, 10);
27519 }
27520 };
27521 settings.scope = settings.scope || this;
27522 settings.success_scope = settings.success_scope || settings.scope;
27523 settings.error_scope = settings.error_scope || settings.scope;
27524 settings.async = settings.async !== false;
27525 settings.data = settings.data || '';
27526 XHR.fire('beforeInitialize', { settings: settings });
27527 xhr = XMLHttpRequest();
27528 if (xhr) {
27529 if (xhr.overrideMimeType) {
27530 xhr.overrideMimeType(settings.content_type);
27531 }
27532 xhr.open(settings.type || (settings.data ? 'POST' : 'GET'), settings.url, settings.async);
27533 if (settings.crossDomain) {
27534 xhr.withCredentials = true;
27535 }
27536 if (settings.content_type) {
27537 xhr.setRequestHeader('Content-Type', settings.content_type);
27538 }
27539 if (settings.requestheaders) {
27540 Tools.each(settings.requestheaders, function (header) {
27541 xhr.setRequestHeader(header.key, header.value);
27542 });
27543 }
27544 xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
27545 xhr = XHR.fire('beforeSend', {
27546 xhr: xhr,
27547 settings: settings
27548 }).xhr;
27549 xhr.send(settings.data);
27550 if (!settings.async) {
27551 return ready();
27552 }
27553 Delay.setTimeout(ready, 10);
27554 }
27555 }
27556 });
27557
27558 var extend$6 = Tools.extend;
27559 var JSONRequest = function () {
27560 function JSONRequest(settings) {
27561 this.settings = extend$6({}, settings);
27562 this.count = 0;
27563 }
27564 JSONRequest.sendRPC = function (o) {
27565 return new JSONRequest().send(o);
27566 };
27567 JSONRequest.prototype.send = function (args) {
27568 var ecb = args.error, scb = args.success;
27569 var xhrArgs = extend$6(this.settings, args);
27570 xhrArgs.success = function (c, x) {
27571 c = JSONUtils.parse(c);
27572 if (typeof c === 'undefined') {
27573 c = { error: 'JSON Parse error.' };
27574 }
27575 if (c.error) {
27576 ecb.call(xhrArgs.error_scope || xhrArgs.scope, c.error, x);
27577 } else {
27578 scb.call(xhrArgs.success_scope || xhrArgs.scope, c.result);
27579 }
27580 };
27581 xhrArgs.error = function (ty, x) {
27582 if (ecb) {
27583 ecb.call(xhrArgs.error_scope || xhrArgs.scope, ty, x);
27584 }
27585 };
27586 xhrArgs.data = JSONUtils.serialize({
27587 id: args.id || 'c' + this.count++,
27588 method: args.method,
27589 params: args.params
27590 });
27591 xhrArgs.content_type = 'application/json';
27592 XHR.send(xhrArgs);
27593 };
27594 return JSONRequest;
27595 }();
27596
27597 var create$7 = function () {
27598 return function () {
27599 var data = {};
27600 var keys = [];
27601 var storage = {
27602 getItem: function (key) {
27603 var item = data[key];
27604 return item ? item : null;
27605 },
27606 setItem: function (key, value) {
27607 keys.push(key);
27608 data[key] = String(value);
27609 },
27610 key: function (index) {
27611 return keys[index];
27612 },
27613 removeItem: function (key) {
27614 keys = keys.filter(function (k) {
27615 return k === key;
27616 });
27617 delete data[key];
27618 },
27619 clear: function () {
27620 keys = [];
27621 data = {};
27622 },
27623 length: 0
27624 };
27625 Object.defineProperty(storage, 'length', {
27626 get: function () {
27627 return keys.length;
27628 },
27629 configurable: false,
27630 enumerable: false
27631 });
27632 return storage;
27633 }();
27634 };
27635
27636 var localStorage;
27637 try {
27638 localStorage = domGlobals.window.localStorage;
27639 } catch (e) {
27640 localStorage = create$7();
27641 }
27642 var LocalStorage = localStorage;
27643
27644 var publicApi = {
27645 geom: { Rect: Rect },
27646 util: {
27647 Promise: promiseObj,
27648 Delay: Delay,
27649 Tools: Tools,
27650 VK: VK,
27651 URI: URI,
27652 Class: Class,
27653 EventDispatcher: EventDispatcher,
27654 Observable: Observable,
27655 I18n: I18n,
27656 XHR: XHR,
27657 JSON: JSONUtils,
27658 JSONRequest: JSONRequest,
27659 JSONP: JSONP,
27660 LocalStorage: LocalStorage,
27661 Color: Color
27662 },
27663 dom: {
27664 EventUtils: EventUtils,
27665 Sizzle: Sizzle,
27666 DomQuery: DomQuery,
27667 TreeWalker: TreeWalker,
27668 DOMUtils: DOMUtils$1,
27669 ScriptLoader: ScriptLoader,
27670 RangeUtils: RangeUtils$1,
27671 Serializer: Serializer$1,
27672 ControlSelection: ControlSelection,
27673 BookmarkManager: BookmarkManager$1,
27674 Selection: Selection$1,
27675 Event: EventUtils.Event
27676 },
27677 html: {
27678 Styles: Styles,
27679 Entities: Entities,
27680 Node: Node$1,
27681 Schema: Schema,
27682 SaxParser: SaxParser$1,
27683 DomParser: DomParser,
27684 Writer: Writer,
27685 Serializer: Serializer
27686 },
27687 Env: Env,
27688 AddOnManager: AddOnManager$1,
27689 Annotator: Annotator,
27690 Formatter: Formatter,
27691 UndoManager: UndoManager,
27692 EditorCommands: EditorCommands,
27693 WindowManager: WindowManager,
27694 NotificationManager: NotificationManager,
27695 EditorObservable: EditorObservable,
27696 Shortcuts: Shortcuts,
27697 Editor: Editor,
27698 FocusManager: FocusManager,
27699 EditorManager: EditorManager,
27700 DOM: DOMUtils$1.DOM,
27701 ScriptLoader: ScriptLoader.ScriptLoader,
27702 PluginManager: AddOnManager$1.PluginManager,
27703 ThemeManager: AddOnManager$1.ThemeManager,
27704 IconManager: IconManager,
27705 trim: Tools.trim,
27706 isArray: Tools.isArray,
27707 is: Tools.is,
27708 toArray: Tools.toArray,
27709 makeMap: Tools.makeMap,
27710 each: Tools.each,
27711 map: Tools.map,
27712 grep: Tools.grep,
27713 inArray: Tools.inArray,
27714 extend: Tools.extend,
27715 create: Tools.create,
27716 walk: Tools.walk,
27717 createNS: Tools.createNS,
27718 resolve: Tools.resolve,
27719 explode: Tools.explode,
27720 _addCacheSuffix: Tools._addCacheSuffix,
27721 isOpera: Env.opera,
27722 isWebKit: Env.webkit,
27723 isIE: Env.ie,
27724 isGecko: Env.gecko,
27725 isMac: Env.mac
27726 };
27727 var tinymce = Tools.extend(EditorManager, publicApi);
27728
27729 var exportToModuleLoaders = function (tinymce) {
27730 if (typeof module === 'object') {
27731 try {
27732 module.exports = tinymce;
27733 } catch (_) {
27734 }
27735 }
27736 };
27737 var exportToWindowGlobal = function (tinymce) {
27738 window.tinymce = tinymce;
27739 window.tinyMCE = tinymce;
27740 };
27741 exportToWindowGlobal(tinymce);
27742 exportToModuleLoaders(tinymce);
27743
27744}(window));