[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 (function () { 2 var inlite = (function (domGlobals) { 3 'use strict'; 4 5 var global = tinymce.util.Tools.resolve('tinymce.ThemeManager'); 6 7 var global$1 = tinymce.util.Tools.resolve('tinymce.Env'); 8 9 var global$2 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); 10 11 var global$3 = tinymce.util.Tools.resolve('tinymce.util.Delay'); 12 13 var flatten = function (arr) { 14 return arr.reduce(function (results, item) { 15 return Array.isArray(item) ? results.concat(flatten(item)) : results.concat(item); 16 }, []); 17 }; 18 var DeepFlatten = { flatten: flatten }; 19 20 var result = function (id, rect) { 21 return { 22 id: id, 23 rect: rect 24 }; 25 }; 26 var match = function (editor, matchers) { 27 for (var i = 0; i < matchers.length; i++) { 28 var f = matchers[i]; 29 var result_1 = f(editor); 30 if (result_1) { 31 return result_1; 32 } 33 } 34 return null; 35 }; 36 var Matcher = { 37 match: match, 38 result: result 39 }; 40 41 var fromClientRect = function (clientRect) { 42 return { 43 x: clientRect.left, 44 y: clientRect.top, 45 w: clientRect.width, 46 h: clientRect.height 47 }; 48 }; 49 var toClientRect = function (geomRect) { 50 return { 51 left: geomRect.x, 52 top: geomRect.y, 53 width: geomRect.w, 54 height: geomRect.h, 55 right: geomRect.x + geomRect.w, 56 bottom: geomRect.y + geomRect.h 57 }; 58 }; 59 var Convert = { 60 fromClientRect: fromClientRect, 61 toClientRect: toClientRect 62 }; 63 64 var toAbsolute = function (rect) { 65 var vp = global$2.DOM.getViewPort(); 66 return { 67 x: rect.x + vp.x, 68 y: rect.y + vp.y, 69 w: rect.w, 70 h: rect.h 71 }; 72 }; 73 var measureElement = function (elm) { 74 var clientRect = elm.getBoundingClientRect(); 75 return toAbsolute({ 76 x: clientRect.left, 77 y: clientRect.top, 78 w: Math.max(elm.clientWidth, elm.offsetWidth), 79 h: Math.max(elm.clientHeight, elm.offsetHeight) 80 }); 81 }; 82 var getElementRect = function (editor, elm) { 83 return measureElement(elm); 84 }; 85 var getPageAreaRect = function (editor) { 86 return measureElement(editor.getElement().ownerDocument.body); 87 }; 88 var getContentAreaRect = function (editor) { 89 return measureElement(editor.getContentAreaContainer() || editor.getBody()); 90 }; 91 var getSelectionRect = function (editor) { 92 var clientRect = editor.selection.getBoundingClientRect(); 93 return clientRect ? toAbsolute(Convert.fromClientRect(clientRect)) : null; 94 }; 95 var Measure = { 96 getElementRect: getElementRect, 97 getPageAreaRect: getPageAreaRect, 98 getContentAreaRect: getContentAreaRect, 99 getSelectionRect: getSelectionRect 100 }; 101 102 var element = function (element, predicateIds) { 103 return function (editor) { 104 for (var i = 0; i < predicateIds.length; i++) { 105 if (predicateIds[i].predicate(element)) { 106 var result = Matcher.result(predicateIds[i].id, Measure.getElementRect(editor, element)); 107 return result; 108 } 109 } 110 return null; 111 }; 112 }; 113 var parent = function (elements, predicateIds) { 114 return function (editor) { 115 for (var i = 0; i < elements.length; i++) { 116 for (var x = 0; x < predicateIds.length; x++) { 117 if (predicateIds[x].predicate(elements[i])) { 118 return Matcher.result(predicateIds[x].id, Measure.getElementRect(editor, elements[i])); 119 } 120 } 121 } 122 return null; 123 }; 124 }; 125 var ElementMatcher = { 126 element: element, 127 parent: parent 128 }; 129 130 var global$4 = tinymce.util.Tools.resolve('tinymce.util.Tools'); 131 132 var create = function (id, predicate) { 133 return { 134 id: id, 135 predicate: predicate 136 }; 137 }; 138 var fromContextToolbars = function (toolbars) { 139 return global$4.map(toolbars, function (toolbar) { 140 return create(toolbar.id, toolbar.predicate); 141 }); 142 }; 143 var PredicateId = { 144 create: create, 145 fromContextToolbars: fromContextToolbars 146 }; 147 148 var textSelection = function (id) { 149 return function (editor) { 150 if (!editor.selection.isCollapsed()) { 151 var result = Matcher.result(id, Measure.getSelectionRect(editor)); 152 return result; 153 } 154 return null; 155 }; 156 }; 157 var emptyTextBlock = function (elements, id) { 158 return function (editor) { 159 var i; 160 var textBlockElementsMap = editor.schema.getTextBlockElements(); 161 for (i = 0; i < elements.length; i++) { 162 if (elements[i].nodeName === 'TABLE') { 163 return null; 164 } 165 } 166 for (i = 0; i < elements.length; i++) { 167 if (elements[i].nodeName in textBlockElementsMap) { 168 if (editor.dom.isEmpty(elements[i])) { 169 return Matcher.result(id, Measure.getSelectionRect(editor)); 170 } 171 return null; 172 } 173 } 174 return null; 175 }; 176 }; 177 var SelectionMatcher = { 178 textSelection: textSelection, 179 emptyTextBlock: emptyTextBlock 180 }; 181 182 var fireSkinLoaded = function (editor) { 183 editor.fire('SkinLoaded'); 184 }; 185 var fireBeforeRenderUI = function (editor) { 186 return editor.fire('BeforeRenderUI'); 187 }; 188 var Events = { 189 fireSkinLoaded: fireSkinLoaded, 190 fireBeforeRenderUI: fireBeforeRenderUI 191 }; 192 193 var global$5 = tinymce.util.Tools.resolve('tinymce.EditorManager'); 194 195 var isType = function (type) { 196 return function (value) { 197 return typeof value === type; 198 }; 199 }; 200 var isArray = function (value) { 201 return Array.isArray(value); 202 }; 203 var isNull = function (value) { 204 return value === null; 205 }; 206 var isObject = function (predicate) { 207 return function (value) { 208 return !isNull(value) && !isArray(value) && predicate(value); 209 }; 210 }; 211 var isString = function (value) { 212 return isType('string')(value); 213 }; 214 var isNumber = function (value) { 215 return isType('number')(value); 216 }; 217 var isFunction = function (value) { 218 return isType('function')(value); 219 }; 220 var isBoolean = function (value) { 221 return isType('boolean')(value); 222 }; 223 var Type = { 224 isString: isString, 225 isNumber: isNumber, 226 isBoolean: isBoolean, 227 isFunction: isFunction, 228 isObject: isObject(isType('object')), 229 isNull: isNull, 230 isArray: isArray 231 }; 232 233 var validDefaultOrDie = function (value, predicate) { 234 if (predicate(value)) { 235 return true; 236 } 237 throw new Error('Default value doesn\'t match requested type.'); 238 }; 239 var getByTypeOr = function (predicate) { 240 return function (editor, name, defaultValue) { 241 var settings = editor.settings; 242 validDefaultOrDie(defaultValue, predicate); 243 return name in settings && predicate(settings[name]) ? settings[name] : defaultValue; 244 }; 245 }; 246 var splitNoEmpty = function (str, delim) { 247 return str.split(delim).filter(function (item) { 248 return item.length > 0; 249 }); 250 }; 251 var itemsToArray = function (value, defaultValue) { 252 var stringToItemsArray = function (value) { 253 return typeof value === 'string' ? splitNoEmpty(value, /[ ,]/) : value; 254 }; 255 var boolToItemsArray = function (value, defaultValue) { 256 return value === false ? [] : defaultValue; 257 }; 258 if (Type.isArray(value)) { 259 return value; 260 } else if (Type.isString(value)) { 261 return stringToItemsArray(value); 262 } else if (Type.isBoolean(value)) { 263 return boolToItemsArray(value, defaultValue); 264 } 265 return defaultValue; 266 }; 267 var getToolbarItemsOr = function (predicate) { 268 return function (editor, name, defaultValue) { 269 var value = name in editor.settings ? editor.settings[name] : defaultValue; 270 validDefaultOrDie(defaultValue, predicate); 271 return itemsToArray(value, defaultValue); 272 }; 273 }; 274 var EditorSettings = { 275 getStringOr: getByTypeOr(Type.isString), 276 getBoolOr: getByTypeOr(Type.isBoolean), 277 getNumberOr: getByTypeOr(Type.isNumber), 278 getHandlerOr: getByTypeOr(Type.isFunction), 279 getToolbarItemsOr: getToolbarItemsOr(Type.isArray) 280 }; 281 282 var global$6 = tinymce.util.Tools.resolve('tinymce.geom.Rect'); 283 284 var result$1 = function (rect, position) { 285 return { 286 rect: rect, 287 position: position 288 }; 289 }; 290 var moveTo = function (rect, toRect) { 291 return { 292 x: toRect.x, 293 y: toRect.y, 294 w: rect.w, 295 h: rect.h 296 }; 297 }; 298 var calcByPositions = function (testPositions1, testPositions2, targetRect, contentAreaRect, panelRect) { 299 var relPos, relRect, outputPanelRect; 300 var paddedContentRect = { 301 x: contentAreaRect.x, 302 y: contentAreaRect.y, 303 w: contentAreaRect.w + (contentAreaRect.w < panelRect.w + targetRect.w ? panelRect.w : 0), 304 h: contentAreaRect.h + (contentAreaRect.h < panelRect.h + targetRect.h ? panelRect.h : 0) 305 }; 306 relPos = global$6.findBestRelativePosition(panelRect, targetRect, paddedContentRect, testPositions1); 307 targetRect = global$6.clamp(targetRect, paddedContentRect); 308 if (relPos) { 309 relRect = global$6.relativePosition(panelRect, targetRect, relPos); 310 outputPanelRect = moveTo(panelRect, relRect); 311 return result$1(outputPanelRect, relPos); 312 } 313 targetRect = global$6.intersect(paddedContentRect, targetRect); 314 if (targetRect) { 315 relPos = global$6.findBestRelativePosition(panelRect, targetRect, paddedContentRect, testPositions2); 316 if (relPos) { 317 relRect = global$6.relativePosition(panelRect, targetRect, relPos); 318 outputPanelRect = moveTo(panelRect, relRect); 319 return result$1(outputPanelRect, relPos); 320 } 321 outputPanelRect = moveTo(panelRect, targetRect); 322 return result$1(outputPanelRect, relPos); 323 } 324 return null; 325 }; 326 var calcInsert = function (targetRect, contentAreaRect, panelRect) { 327 return calcByPositions([ 328 'cr-cl', 329 'cl-cr' 330 ], [ 331 'bc-tc', 332 'bl-tl', 333 'br-tr' 334 ], targetRect, contentAreaRect, panelRect); 335 }; 336 var calc = function (targetRect, contentAreaRect, panelRect) { 337 return calcByPositions([ 338 'tc-bc', 339 'bc-tc', 340 'tl-bl', 341 'bl-tl', 342 'tr-br', 343 'br-tr', 344 'cr-cl', 345 'cl-cr' 346 ], [ 347 'bc-tc', 348 'bl-tl', 349 'br-tr', 350 'cr-cl' 351 ], targetRect, contentAreaRect, panelRect); 352 }; 353 var userConstrain = function (handler, targetRect, contentAreaRect, panelRect) { 354 var userConstrainedPanelRect; 355 if (typeof handler === 'function') { 356 userConstrainedPanelRect = handler({ 357 elementRect: Convert.toClientRect(targetRect), 358 contentAreaRect: Convert.toClientRect(contentAreaRect), 359 panelRect: Convert.toClientRect(panelRect) 360 }); 361 return Convert.fromClientRect(userConstrainedPanelRect); 362 } 363 return panelRect; 364 }; 365 var defaultHandler = function (rects) { 366 return rects.panelRect; 367 }; 368 var Layout = { 369 calcInsert: calcInsert, 370 calc: calc, 371 userConstrain: userConstrain, 372 defaultHandler: defaultHandler 373 }; 374 375 var toAbsoluteUrl = function (editor, url) { 376 return editor.documentBaseURI.toAbsolute(url); 377 }; 378 var urlFromName = function (name) { 379 var prefix = global$5.baseURL + '/skins/'; 380 return name ? prefix + name : prefix + 'lightgray'; 381 }; 382 var getTextSelectionToolbarItems = function (editor) { 383 return EditorSettings.getToolbarItemsOr(editor, 'selection_toolbar', [ 384 'bold', 385 'italic', 386 '|', 387 'quicklink', 388 'h2', 389 'h3', 390 'blockquote' 391 ]); 392 }; 393 var getInsertToolbarItems = function (editor) { 394 return EditorSettings.getToolbarItemsOr(editor, 'insert_toolbar', [ 395 'quickimage', 396 'quicktable' 397 ]); 398 }; 399 var getPositionHandler = function (editor) { 400 return EditorSettings.getHandlerOr(editor, 'inline_toolbar_position_handler', Layout.defaultHandler); 401 }; 402 var getSkinUrl = function (editor) { 403 var settings = editor.settings; 404 return settings.skin_url ? toAbsoluteUrl(editor, settings.skin_url) : urlFromName(settings.skin); 405 }; 406 var isSkinDisabled = function (editor) { 407 return editor.settings.skin === false; 408 }; 409 var Settings = { 410 getTextSelectionToolbarItems: getTextSelectionToolbarItems, 411 getInsertToolbarItems: getInsertToolbarItems, 412 getPositionHandler: getPositionHandler, 413 getSkinUrl: getSkinUrl, 414 isSkinDisabled: isSkinDisabled 415 }; 416 417 var fireSkinLoaded$1 = function (editor, callback) { 418 var done = function () { 419 editor._skinLoaded = true; 420 Events.fireSkinLoaded(editor); 421 callback(); 422 }; 423 if (editor.initialized) { 424 done(); 425 } else { 426 editor.on('init', done); 427 } 428 }; 429 var load = function (editor, callback) { 430 var skinUrl = Settings.getSkinUrl(editor); 431 var done = function () { 432 fireSkinLoaded$1(editor, callback); 433 }; 434 if (Settings.isSkinDisabled(editor)) { 435 done(); 436 } else { 437 global$2.DOM.styleSheetLoader.load(skinUrl + '/skin.min.css', done); 438 editor.contentCSS.push(skinUrl + '/content.inline.min.css'); 439 } 440 }; 441 var SkinLoader = { load: load }; 442 443 var getSelectionElements = function (editor) { 444 var node = editor.selection.getNode(); 445 var elms = editor.dom.getParents(node, '*'); 446 return elms; 447 }; 448 var createToolbar = function (editor, selector, id, items) { 449 var selectorPredicate = function (elm) { 450 return editor.dom.is(elm, selector); 451 }; 452 return { 453 predicate: selectorPredicate, 454 id: id, 455 items: items 456 }; 457 }; 458 var getToolbars = function (editor) { 459 var contextToolbars = editor.contextToolbars; 460 return DeepFlatten.flatten([ 461 contextToolbars ? contextToolbars : [], 462 createToolbar(editor, 'img', 'image', 'alignleft aligncenter alignright') 463 ]); 464 }; 465 var findMatchResult = function (editor, toolbars) { 466 var result, elements, contextToolbarsPredicateIds; 467 elements = getSelectionElements(editor); 468 contextToolbarsPredicateIds = PredicateId.fromContextToolbars(toolbars); 469 result = Matcher.match(editor, [ 470 ElementMatcher.element(elements[0], contextToolbarsPredicateIds), 471 SelectionMatcher.textSelection('text'), 472 SelectionMatcher.emptyTextBlock(elements, 'insert'), 473 ElementMatcher.parent(elements, contextToolbarsPredicateIds) 474 ]); 475 return result && result.rect ? result : null; 476 }; 477 var editorHasFocus = function (editor) { 478 return domGlobals.document.activeElement === editor.getBody(); 479 }; 480 var togglePanel = function (editor, panel) { 481 var toggle = function () { 482 var toolbars = getToolbars(editor); 483 var result = findMatchResult(editor, toolbars); 484 if (result) { 485 panel.show(editor, result.id, result.rect, toolbars); 486 } else { 487 panel.hide(); 488 } 489 }; 490 return function () { 491 if (!editor.removed && editorHasFocus(editor)) { 492 toggle(); 493 } 494 }; 495 }; 496 var repositionPanel = function (editor, panel) { 497 return function () { 498 var toolbars = getToolbars(editor); 499 var result = findMatchResult(editor, toolbars); 500 if (result) { 501 panel.reposition(editor, result.id, result.rect); 502 } 503 }; 504 }; 505 var ignoreWhenFormIsVisible = function (editor, panel, f) { 506 return function () { 507 if (!editor.removed && !panel.inForm()) { 508 f(); 509 } 510 }; 511 }; 512 var bindContextualToolbarsEvents = function (editor, panel) { 513 var throttledTogglePanel = global$3.throttle(togglePanel(editor, panel), 0); 514 var throttledTogglePanelWhenNotInForm = global$3.throttle(ignoreWhenFormIsVisible(editor, panel, togglePanel(editor, panel)), 0); 515 var reposition = repositionPanel(editor, panel); 516 editor.on('blur hide ObjectResizeStart', panel.hide); 517 editor.on('click', throttledTogglePanel); 518 editor.on('nodeChange mouseup', throttledTogglePanelWhenNotInForm); 519 editor.on('ResizeEditor keyup', throttledTogglePanel); 520 editor.on('ResizeWindow', reposition); 521 global$2.DOM.bind(global$1.container, 'scroll', reposition); 522 editor.on('remove', function () { 523 global$2.DOM.unbind(global$1.container, 'scroll', reposition); 524 panel.remove(); 525 }); 526 editor.shortcuts.add('Alt+F10,F10', '', panel.focus); 527 }; 528 var overrideLinkShortcut = function (editor, panel) { 529 editor.shortcuts.remove('meta+k'); 530 editor.shortcuts.add('meta+k', '', function () { 531 var toolbars = getToolbars(editor); 532 var result = Matcher.match(editor, [SelectionMatcher.textSelection('quicklink')]); 533 if (result) { 534 panel.show(editor, result.id, result.rect, toolbars); 535 } 536 }); 537 }; 538 var renderInlineUI = function (editor, panel) { 539 SkinLoader.load(editor, function () { 540 bindContextualToolbarsEvents(editor, panel); 541 overrideLinkShortcut(editor, panel); 542 }); 543 return {}; 544 }; 545 var fail = function (message) { 546 throw new Error(message); 547 }; 548 var renderUI = function (editor, panel) { 549 return editor.inline ? renderInlineUI(editor, panel) : fail('inlite theme only supports inline mode.'); 550 }; 551 var Render = { renderUI: renderUI }; 552 553 var noop = function () { 554 }; 555 var constant = function (value) { 556 return function () { 557 return value; 558 }; 559 }; 560 var never = constant(false); 561 var always = constant(true); 562 563 var none = function () { 564 return NONE; 565 }; 566 var NONE = function () { 567 var eq = function (o) { 568 return o.isNone(); 569 }; 570 var call = function (thunk) { 571 return thunk(); 572 }; 573 var id = function (n) { 574 return n; 575 }; 576 var me = { 577 fold: function (n, s) { 578 return n(); 579 }, 580 is: never, 581 isSome: never, 582 isNone: always, 583 getOr: id, 584 getOrThunk: call, 585 getOrDie: function (msg) { 586 throw new Error(msg || 'error: getOrDie called on none.'); 587 }, 588 getOrNull: constant(null), 589 getOrUndefined: constant(undefined), 590 or: id, 591 orThunk: call, 592 map: none, 593 each: noop, 594 bind: none, 595 exists: never, 596 forall: always, 597 filter: none, 598 equals: eq, 599 equals_: eq, 600 toArray: function () { 601 return []; 602 }, 603 toString: constant('none()') 604 }; 605 if (Object.freeze) { 606 Object.freeze(me); 607 } 608 return me; 609 }(); 610 var some = function (a) { 611 var constant_a = constant(a); 612 var self = function () { 613 return me; 614 }; 615 var bind = function (f) { 616 return f(a); 617 }; 618 var me = { 619 fold: function (n, s) { 620 return s(a); 621 }, 622 is: function (v) { 623 return a === v; 624 }, 625 isSome: always, 626 isNone: never, 627 getOr: constant_a, 628 getOrThunk: constant_a, 629 getOrDie: constant_a, 630 getOrNull: constant_a, 631 getOrUndefined: constant_a, 632 or: self, 633 orThunk: self, 634 map: function (f) { 635 return some(f(a)); 636 }, 637 each: function (f) { 638 f(a); 639 }, 640 bind: bind, 641 exists: bind, 642 forall: bind, 643 filter: function (f) { 644 return f(a) ? me : NONE; 645 }, 646 toArray: function () { 647 return [a]; 648 }, 649 toString: function () { 650 return 'some(' + a + ')'; 651 }, 652 equals: function (o) { 653 return o.is(a); 654 }, 655 equals_: function (o, elementEq) { 656 return o.fold(never, function (b) { 657 return elementEq(a, b); 658 }); 659 } 660 }; 661 return me; 662 }; 663 var from = function (value) { 664 return value === null || value === undefined ? NONE : some(value); 665 }; 666 var Option = { 667 some: some, 668 none: none, 669 from: from 670 }; 671 672 var typeOf = function (x) { 673 if (x === null) { 674 return 'null'; 675 } 676 var t = typeof x; 677 if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) { 678 return 'array'; 679 } 680 if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) { 681 return 'string'; 682 } 683 return t; 684 }; 685 var isType$1 = function (type) { 686 return function (value) { 687 return typeOf(value) === type; 688 }; 689 }; 690 var isArray$1 = isType$1('array'); 691 var isFunction$1 = isType$1('function'); 692 var isNumber$1 = isType$1('number'); 693 694 var nativeSlice = Array.prototype.slice; 695 var nativeIndexOf = Array.prototype.indexOf; 696 var nativePush = Array.prototype.push; 697 var rawIndexOf = function (ts, t) { 698 return nativeIndexOf.call(ts, t); 699 }; 700 var indexOf = function (xs, x) { 701 var r = rawIndexOf(xs, x); 702 return r === -1 ? Option.none() : Option.some(r); 703 }; 704 var exists = function (xs, pred) { 705 for (var i = 0, len = xs.length; i < len; i++) { 706 var x = xs[i]; 707 if (pred(x, i)) { 708 return true; 709 } 710 } 711 return false; 712 }; 713 var map = function (xs, f) { 714 var len = xs.length; 715 var r = new Array(len); 716 for (var i = 0; i < len; i++) { 717 var x = xs[i]; 718 r[i] = f(x, i); 719 } 720 return r; 721 }; 722 var each = function (xs, f) { 723 for (var i = 0, len = xs.length; i < len; i++) { 724 var x = xs[i]; 725 f(x, i); 726 } 727 }; 728 var filter = function (xs, pred) { 729 var r = []; 730 for (var i = 0, len = xs.length; i < len; i++) { 731 var x = xs[i]; 732 if (pred(x, i)) { 733 r.push(x); 734 } 735 } 736 return r; 737 }; 738 var foldl = function (xs, f, acc) { 739 each(xs, function (x) { 740 acc = f(acc, x); 741 }); 742 return acc; 743 }; 744 var find = function (xs, pred) { 745 for (var i = 0, len = xs.length; i < len; i++) { 746 var x = xs[i]; 747 if (pred(x, i)) { 748 return Option.some(x); 749 } 750 } 751 return Option.none(); 752 }; 753 var flatten$1 = function (xs) { 754 var r = []; 755 for (var i = 0, len = xs.length; i < len; ++i) { 756 if (!isArray$1(xs[i])) { 757 throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs); 758 } 759 nativePush.apply(r, xs[i]); 760 } 761 return r; 762 }; 763 var from$1 = isFunction$1(Array.from) ? Array.from : function (x) { 764 return nativeSlice.call(x); 765 }; 766 767 var count = 0; 768 var funcs = { 769 id: function () { 770 return 'mceu_' + count++; 771 }, 772 create: function (name, attrs, children) { 773 var elm = domGlobals.document.createElement(name); 774 global$2.DOM.setAttribs(elm, attrs); 775 if (typeof children === 'string') { 776 elm.innerHTML = children; 777 } else { 778 global$4.each(children, function (child) { 779 if (child.nodeType) { 780 elm.appendChild(child); 781 } 782 }); 783 } 784 return elm; 785 }, 786 createFragment: function (html) { 787 return global$2.DOM.createFragment(html); 788 }, 789 getWindowSize: function () { 790 return global$2.DOM.getViewPort(); 791 }, 792 getSize: function (elm) { 793 var width, height; 794 if (elm.getBoundingClientRect) { 795 var rect = elm.getBoundingClientRect(); 796 width = Math.max(rect.width || rect.right - rect.left, elm.offsetWidth); 797 height = Math.max(rect.height || rect.bottom - rect.bottom, elm.offsetHeight); 798 } else { 799 width = elm.offsetWidth; 800 height = elm.offsetHeight; 801 } 802 return { 803 width: width, 804 height: height 805 }; 806 }, 807 getPos: function (elm, root) { 808 return global$2.DOM.getPos(elm, root || funcs.getContainer()); 809 }, 810 getContainer: function () { 811 return global$1.container ? global$1.container : domGlobals.document.body; 812 }, 813 getViewPort: function (win) { 814 return global$2.DOM.getViewPort(win); 815 }, 816 get: function (id) { 817 return domGlobals.document.getElementById(id); 818 }, 819 addClass: function (elm, cls) { 820 return global$2.DOM.addClass(elm, cls); 821 }, 822 removeClass: function (elm, cls) { 823 return global$2.DOM.removeClass(elm, cls); 824 }, 825 hasClass: function (elm, cls) { 826 return global$2.DOM.hasClass(elm, cls); 827 }, 828 toggleClass: function (elm, cls, state) { 829 return global$2.DOM.toggleClass(elm, cls, state); 830 }, 831 css: function (elm, name, value) { 832 return global$2.DOM.setStyle(elm, name, value); 833 }, 834 getRuntimeStyle: function (elm, name) { 835 return global$2.DOM.getStyle(elm, name, true); 836 }, 837 on: function (target, name, callback, scope) { 838 return global$2.DOM.bind(target, name, callback, scope); 839 }, 840 off: function (target, name, callback) { 841 return global$2.DOM.unbind(target, name, callback); 842 }, 843 fire: function (target, name, args) { 844 return global$2.DOM.fire(target, name, args); 845 }, 846 innerHtml: function (elm, html) { 847 global$2.DOM.setHTML(elm, html); 848 } 849 }; 850 851 var global$7 = tinymce.util.Tools.resolve('tinymce.dom.DomQuery'); 852 853 var global$8 = tinymce.util.Tools.resolve('tinymce.util.Class'); 854 855 var global$9 = tinymce.util.Tools.resolve('tinymce.util.EventDispatcher'); 856 857 var BoxUtils = { 858 parseBox: function (value) { 859 var len; 860 var radix = 10; 861 if (!value) { 862 return; 863 } 864 if (typeof value === 'number') { 865 value = value || 0; 866 return { 867 top: value, 868 left: value, 869 bottom: value, 870 right: value 871 }; 872 } 873 value = value.split(' '); 874 len = value.length; 875 if (len === 1) { 876 value[1] = value[2] = value[3] = value[0]; 877 } else if (len === 2) { 878 value[2] = value[0]; 879 value[3] = value[1]; 880 } else if (len === 3) { 881 value[3] = value[1]; 882 } 883 return { 884 top: parseInt(value[0], radix) || 0, 885 right: parseInt(value[1], radix) || 0, 886 bottom: parseInt(value[2], radix) || 0, 887 left: parseInt(value[3], radix) || 0 888 }; 889 }, 890 measureBox: function (elm, prefix) { 891 function getStyle(name) { 892 var defaultView = elm.ownerDocument.defaultView; 893 if (defaultView) { 894 var computedStyle = defaultView.getComputedStyle(elm, null); 895 if (computedStyle) { 896 name = name.replace(/[A-Z]/g, function (a) { 897 return '-' + a; 898 }); 899 return computedStyle.getPropertyValue(name); 900 } else { 901 return null; 902 } 903 } 904 return elm.currentStyle[name]; 905 } 906 function getSide(name) { 907 var val = parseFloat(getStyle(name)); 908 return isNaN(val) ? 0 : val; 909 } 910 return { 911 top: getSide(prefix + 'TopWidth'), 912 right: getSide(prefix + 'RightWidth'), 913 bottom: getSide(prefix + 'BottomWidth'), 914 left: getSide(prefix + 'LeftWidth') 915 }; 916 } 917 }; 918 919 function noop$1() { 920 } 921 function ClassList(onchange) { 922 this.cls = []; 923 this.cls._map = {}; 924 this.onchange = onchange || noop$1; 925 this.prefix = ''; 926 } 927 global$4.extend(ClassList.prototype, { 928 add: function (cls) { 929 if (cls && !this.contains(cls)) { 930 this.cls._map[cls] = true; 931 this.cls.push(cls); 932 this._change(); 933 } 934 return this; 935 }, 936 remove: function (cls) { 937 if (this.contains(cls)) { 938 var i = void 0; 939 for (i = 0; i < this.cls.length; i++) { 940 if (this.cls[i] === cls) { 941 break; 942 } 943 } 944 this.cls.splice(i, 1); 945 delete this.cls._map[cls]; 946 this._change(); 947 } 948 return this; 949 }, 950 toggle: function (cls, state) { 951 var curState = this.contains(cls); 952 if (curState !== state) { 953 if (curState) { 954 this.remove(cls); 955 } else { 956 this.add(cls); 957 } 958 this._change(); 959 } 960 return this; 961 }, 962 contains: function (cls) { 963 return !!this.cls._map[cls]; 964 }, 965 _change: function () { 966 delete this.clsValue; 967 this.onchange.call(this); 968 } 969 }); 970 ClassList.prototype.toString = function () { 971 var value; 972 if (this.clsValue) { 973 return this.clsValue; 974 } 975 value = ''; 976 for (var i = 0; i < this.cls.length; i++) { 977 if (i > 0) { 978 value += ' '; 979 } 980 value += this.prefix + this.cls[i]; 981 } 982 return value; 983 }; 984 985 function unique(array) { 986 var uniqueItems = []; 987 var i = array.length, item; 988 while (i--) { 989 item = array[i]; 990 if (!item.__checked) { 991 uniqueItems.push(item); 992 item.__checked = 1; 993 } 994 } 995 i = uniqueItems.length; 996 while (i--) { 997 delete uniqueItems[i].__checked; 998 } 999 return uniqueItems; 1000 } 1001 var expression = /^([\w\\*]+)?(?:#([\w\-\\]+))?(?:\.([\w\\\.]+))?(?:\[\@?([\w\\]+)([\^\$\*!~]?=)([\w\\]+)\])?(?:\:(.+))?/i; 1002 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g; 1003 var whiteSpace = /^\s*|\s*$/g; 1004 var Collection; 1005 var Selector = global$8.extend({ 1006 init: function (selector) { 1007 var match = this.match; 1008 function compileNameFilter(name) { 1009 if (name) { 1010 name = name.toLowerCase(); 1011 return function (item) { 1012 return name === '*' || item.type === name; 1013 }; 1014 } 1015 } 1016 function compileIdFilter(id) { 1017 if (id) { 1018 return function (item) { 1019 return item._name === id; 1020 }; 1021 } 1022 } 1023 function compileClassesFilter(classes) { 1024 if (classes) { 1025 classes = classes.split('.'); 1026 return function (item) { 1027 var i = classes.length; 1028 while (i--) { 1029 if (!item.classes.contains(classes[i])) { 1030 return false; 1031 } 1032 } 1033 return true; 1034 }; 1035 } 1036 } 1037 function compileAttrFilter(name, cmp, check) { 1038 if (name) { 1039 return function (item) { 1040 var value = item[name] ? item[name]() : ''; 1041 return !cmp ? !!check : cmp === '=' ? value === check : cmp === '*=' ? value.indexOf(check) >= 0 : cmp === '~=' ? (' ' + value + ' ').indexOf(' ' + check + ' ') >= 0 : cmp === '!=' ? value !== check : cmp === '^=' ? value.indexOf(check) === 0 : cmp === '$=' ? value.substr(value.length - check.length) === check : false; 1042 }; 1043 } 1044 } 1045 function compilePsuedoFilter(name) { 1046 var notSelectors; 1047 if (name) { 1048 name = /(?:not\((.+)\))|(.+)/i.exec(name); 1049 if (!name[1]) { 1050 name = name[2]; 1051 return function (item, index, length) { 1052 return name === 'first' ? index === 0 : name === 'last' ? index === length - 1 : name === 'even' ? index % 2 === 0 : name === 'odd' ? index % 2 === 1 : item[name] ? item[name]() : false; 1053 }; 1054 } 1055 notSelectors = parseChunks(name[1], []); 1056 return function (item) { 1057 return !match(item, notSelectors); 1058 }; 1059 } 1060 } 1061 function compile(selector, filters, direct) { 1062 var parts; 1063 function add(filter) { 1064 if (filter) { 1065 filters.push(filter); 1066 } 1067 } 1068 parts = expression.exec(selector.replace(whiteSpace, '')); 1069 add(compileNameFilter(parts[1])); 1070 add(compileIdFilter(parts[2])); 1071 add(compileClassesFilter(parts[3])); 1072 add(compileAttrFilter(parts[4], parts[5], parts[6])); 1073 add(compilePsuedoFilter(parts[7])); 1074 filters.pseudo = !!parts[7]; 1075 filters.direct = direct; 1076 return filters; 1077 } 1078 function parseChunks(selector, selectors) { 1079 var parts = []; 1080 var extra, matches, i; 1081 do { 1082 chunker.exec(''); 1083 matches = chunker.exec(selector); 1084 if (matches) { 1085 selector = matches[3]; 1086 parts.push(matches[1]); 1087 if (matches[2]) { 1088 extra = matches[3]; 1089 break; 1090 } 1091 } 1092 } while (matches); 1093 if (extra) { 1094 parseChunks(extra, selectors); 1095 } 1096 selector = []; 1097 for (i = 0; i < parts.length; i++) { 1098 if (parts[i] !== '>') { 1099 selector.push(compile(parts[i], [], parts[i - 1] === '>')); 1100 } 1101 } 1102 selectors.push(selector); 1103 return selectors; 1104 } 1105 this._selectors = parseChunks(selector, []); 1106 }, 1107 match: function (control, selectors) { 1108 var i, l, si, sl, selector, fi, fl, filters, index, length, siblings, count, item; 1109 selectors = selectors || this._selectors; 1110 for (i = 0, l = selectors.length; i < l; i++) { 1111 selector = selectors[i]; 1112 sl = selector.length; 1113 item = control; 1114 count = 0; 1115 for (si = sl - 1; si >= 0; si--) { 1116 filters = selector[si]; 1117 while (item) { 1118 if (filters.pseudo) { 1119 siblings = item.parent().items(); 1120 index = length = siblings.length; 1121 while (index--) { 1122 if (siblings[index] === item) { 1123 break; 1124 } 1125 } 1126 } 1127 for (fi = 0, fl = filters.length; fi < fl; fi++) { 1128 if (!filters[fi](item, index, length)) { 1129 fi = fl + 1; 1130 break; 1131 } 1132 } 1133 if (fi === fl) { 1134 count++; 1135 break; 1136 } else { 1137 if (si === sl - 1) { 1138 break; 1139 } 1140 } 1141 item = item.parent(); 1142 } 1143 } 1144 if (count === sl) { 1145 return true; 1146 } 1147 } 1148 return false; 1149 }, 1150 find: function (container) { 1151 var matches = [], i, l; 1152 var selectors = this._selectors; 1153 function collect(items, selector, index) { 1154 var i, l, fi, fl, item; 1155 var filters = selector[index]; 1156 for (i = 0, l = items.length; i < l; i++) { 1157 item = items[i]; 1158 for (fi = 0, fl = filters.length; fi < fl; fi++) { 1159 if (!filters[fi](item, i, l)) { 1160 fi = fl + 1; 1161 break; 1162 } 1163 } 1164 if (fi === fl) { 1165 if (index === selector.length - 1) { 1166 matches.push(item); 1167 } else { 1168 if (item.items) { 1169 collect(item.items(), selector, index + 1); 1170 } 1171 } 1172 } else if (filters.direct) { 1173 return; 1174 } 1175 if (item.items) { 1176 collect(item.items(), selector, index); 1177 } 1178 } 1179 } 1180 if (container.items) { 1181 for (i = 0, l = selectors.length; i < l; i++) { 1182 collect(container.items(), selectors[i], 0); 1183 } 1184 if (l > 1) { 1185 matches = unique(matches); 1186 } 1187 } 1188 if (!Collection) { 1189 Collection = Selector.Collection; 1190 } 1191 return new Collection(matches); 1192 } 1193 }); 1194 1195 var Collection$1, proto; 1196 var push = Array.prototype.push, slice = Array.prototype.slice; 1197 proto = { 1198 length: 0, 1199 init: function (items) { 1200 if (items) { 1201 this.add(items); 1202 } 1203 }, 1204 add: function (items) { 1205 var self = this; 1206 if (!global$4.isArray(items)) { 1207 if (items instanceof Collection$1) { 1208 self.add(items.toArray()); 1209 } else { 1210 push.call(self, items); 1211 } 1212 } else { 1213 push.apply(self, items); 1214 } 1215 return self; 1216 }, 1217 set: function (items) { 1218 var self = this; 1219 var len = self.length; 1220 var i; 1221 self.length = 0; 1222 self.add(items); 1223 for (i = self.length; i < len; i++) { 1224 delete self[i]; 1225 } 1226 return self; 1227 }, 1228 filter: function (selector) { 1229 var self = this; 1230 var i, l; 1231 var matches = []; 1232 var item, match; 1233 if (typeof selector === 'string') { 1234 selector = new Selector(selector); 1235 match = function (item) { 1236 return selector.match(item); 1237 }; 1238 } else { 1239 match = selector; 1240 } 1241 for (i = 0, l = self.length; i < l; i++) { 1242 item = self[i]; 1243 if (match(item)) { 1244 matches.push(item); 1245 } 1246 } 1247 return new Collection$1(matches); 1248 }, 1249 slice: function () { 1250 return new Collection$1(slice.apply(this, arguments)); 1251 }, 1252 eq: function (index) { 1253 return index === -1 ? this.slice(index) : this.slice(index, +index + 1); 1254 }, 1255 each: function (callback) { 1256 global$4.each(this, callback); 1257 return this; 1258 }, 1259 toArray: function () { 1260 return global$4.toArray(this); 1261 }, 1262 indexOf: function (ctrl) { 1263 var self = this; 1264 var i = self.length; 1265 while (i--) { 1266 if (self[i] === ctrl) { 1267 break; 1268 } 1269 } 1270 return i; 1271 }, 1272 reverse: function () { 1273 return new Collection$1(global$4.toArray(this).reverse()); 1274 }, 1275 hasClass: function (cls) { 1276 return this[0] ? this[0].classes.contains(cls) : false; 1277 }, 1278 prop: function (name, value) { 1279 var self = this; 1280 var item; 1281 if (value !== undefined) { 1282 self.each(function (item) { 1283 if (item[name]) { 1284 item[name](value); 1285 } 1286 }); 1287 return self; 1288 } 1289 item = self[0]; 1290 if (item && item[name]) { 1291 return item[name](); 1292 } 1293 }, 1294 exec: function (name) { 1295 var self = this, args = global$4.toArray(arguments).slice(1); 1296 self.each(function (item) { 1297 if (item[name]) { 1298 item[name].apply(item, args); 1299 } 1300 }); 1301 return self; 1302 }, 1303 remove: function () { 1304 var i = this.length; 1305 while (i--) { 1306 this[i].remove(); 1307 } 1308 return this; 1309 }, 1310 addClass: function (cls) { 1311 return this.each(function (item) { 1312 item.classes.add(cls); 1313 }); 1314 }, 1315 removeClass: function (cls) { 1316 return this.each(function (item) { 1317 item.classes.remove(cls); 1318 }); 1319 } 1320 }; 1321 global$4.each('fire on off show hide append prepend before after reflow'.split(' '), function (name) { 1322 proto[name] = function () { 1323 var args = global$4.toArray(arguments); 1324 this.each(function (ctrl) { 1325 if (name in ctrl) { 1326 ctrl[name].apply(ctrl, args); 1327 } 1328 }); 1329 return this; 1330 }; 1331 }); 1332 global$4.each('text name disabled active selected checked visible parent value data'.split(' '), function (name) { 1333 proto[name] = function (value) { 1334 return this.prop(name, value); 1335 }; 1336 }); 1337 Collection$1 = global$8.extend(proto); 1338 Selector.Collection = Collection$1; 1339 var Collection$2 = Collection$1; 1340 1341 var Binding = function (settings) { 1342 this.create = settings.create; 1343 }; 1344 Binding.create = function (model, name) { 1345 return new Binding({ 1346 create: function (otherModel, otherName) { 1347 var bindings; 1348 var fromSelfToOther = function (e) { 1349 otherModel.set(otherName, e.value); 1350 }; 1351 var fromOtherToSelf = function (e) { 1352 model.set(name, e.value); 1353 }; 1354 otherModel.on('change:' + otherName, fromOtherToSelf); 1355 model.on('change:' + name, fromSelfToOther); 1356 bindings = otherModel._bindings; 1357 if (!bindings) { 1358 bindings = otherModel._bindings = []; 1359 otherModel.on('destroy', function () { 1360 var i = bindings.length; 1361 while (i--) { 1362 bindings[i](); 1363 } 1364 }); 1365 } 1366 bindings.push(function () { 1367 model.off('change:' + name, fromSelfToOther); 1368 }); 1369 return model.get(name); 1370 } 1371 }); 1372 }; 1373 1374 var global$a = tinymce.util.Tools.resolve('tinymce.util.Observable'); 1375 1376 function isNode(node) { 1377 return node.nodeType > 0; 1378 } 1379 function isEqual(a, b) { 1380 var k, checked; 1381 if (a === b) { 1382 return true; 1383 } 1384 if (a === null || b === null) { 1385 return a === b; 1386 } 1387 if (typeof a !== 'object' || typeof b !== 'object') { 1388 return a === b; 1389 } 1390 if (global$4.isArray(b)) { 1391 if (a.length !== b.length) { 1392 return false; 1393 } 1394 k = a.length; 1395 while (k--) { 1396 if (!isEqual(a[k], b[k])) { 1397 return false; 1398 } 1399 } 1400 } 1401 if (isNode(a) || isNode(b)) { 1402 return a === b; 1403 } 1404 checked = {}; 1405 for (k in b) { 1406 if (!isEqual(a[k], b[k])) { 1407 return false; 1408 } 1409 checked[k] = true; 1410 } 1411 for (k in a) { 1412 if (!checked[k] && !isEqual(a[k], b[k])) { 1413 return false; 1414 } 1415 } 1416 return true; 1417 } 1418 var ObservableObject = global$8.extend({ 1419 Mixins: [global$a], 1420 init: function (data) { 1421 var name, value; 1422 data = data || {}; 1423 for (name in data) { 1424 value = data[name]; 1425 if (value instanceof Binding) { 1426 data[name] = value.create(this, name); 1427 } 1428 } 1429 this.data = data; 1430 }, 1431 set: function (name, value) { 1432 var key, args; 1433 var oldValue = this.data[name]; 1434 if (value instanceof Binding) { 1435 value = value.create(this, name); 1436 } 1437 if (typeof name === 'object') { 1438 for (key in name) { 1439 this.set(key, name[key]); 1440 } 1441 return this; 1442 } 1443 if (!isEqual(oldValue, value)) { 1444 this.data[name] = value; 1445 args = { 1446 target: this, 1447 name: name, 1448 value: value, 1449 oldValue: oldValue 1450 }; 1451 this.fire('change:' + name, args); 1452 this.fire('change', args); 1453 } 1454 return this; 1455 }, 1456 get: function (name) { 1457 return this.data[name]; 1458 }, 1459 has: function (name) { 1460 return name in this.data; 1461 }, 1462 bind: function (name) { 1463 return Binding.create(this, name); 1464 }, 1465 destroy: function () { 1466 this.fire('destroy'); 1467 } 1468 }); 1469 1470 var dirtyCtrls = {}, animationFrameRequested; 1471 var ReflowQueue = { 1472 add: function (ctrl) { 1473 var parent = ctrl.parent(); 1474 if (parent) { 1475 if (!parent._layout || parent._layout.isNative()) { 1476 return; 1477 } 1478 if (!dirtyCtrls[parent._id]) { 1479 dirtyCtrls[parent._id] = parent; 1480 } 1481 if (!animationFrameRequested) { 1482 animationFrameRequested = true; 1483 global$3.requestAnimationFrame(function () { 1484 var id, ctrl; 1485 animationFrameRequested = false; 1486 for (id in dirtyCtrls) { 1487 ctrl = dirtyCtrls[id]; 1488 if (ctrl.state.get('rendered')) { 1489 ctrl.reflow(); 1490 } 1491 } 1492 dirtyCtrls = {}; 1493 }, domGlobals.document.body); 1494 } 1495 } 1496 }, 1497 remove: function (ctrl) { 1498 if (dirtyCtrls[ctrl._id]) { 1499 delete dirtyCtrls[ctrl._id]; 1500 } 1501 } 1502 }; 1503 1504 var getUiContainerDelta = function (ctrl) { 1505 var uiContainer = getUiContainer(ctrl); 1506 if (uiContainer && global$2.DOM.getStyle(uiContainer, 'position', true) !== 'static') { 1507 var containerPos = global$2.DOM.getPos(uiContainer); 1508 var dx = uiContainer.scrollLeft - containerPos.x; 1509 var dy = uiContainer.scrollTop - containerPos.y; 1510 return Option.some({ 1511 x: dx, 1512 y: dy 1513 }); 1514 } else { 1515 return Option.none(); 1516 } 1517 }; 1518 var setUiContainer = function (editor, ctrl) { 1519 var uiContainer = global$2.DOM.select(editor.settings.ui_container)[0]; 1520 ctrl.getRoot().uiContainer = uiContainer; 1521 }; 1522 var getUiContainer = function (ctrl) { 1523 return ctrl ? ctrl.getRoot().uiContainer : null; 1524 }; 1525 var inheritUiContainer = function (fromCtrl, toCtrl) { 1526 return toCtrl.uiContainer = getUiContainer(fromCtrl); 1527 }; 1528 var UiContainer = { 1529 getUiContainerDelta: getUiContainerDelta, 1530 setUiContainer: setUiContainer, 1531 getUiContainer: getUiContainer, 1532 inheritUiContainer: inheritUiContainer 1533 }; 1534 1535 var hasMouseWheelEventSupport = 'onmousewheel' in domGlobals.document; 1536 var hasWheelEventSupport = false; 1537 var classPrefix = 'mce-'; 1538 var Control, idCounter = 0; 1539 var proto$1 = { 1540 Statics: { classPrefix: classPrefix }, 1541 isRtl: function () { 1542 return Control.rtl; 1543 }, 1544 classPrefix: classPrefix, 1545 init: function (settings) { 1546 var self = this; 1547 var classes, defaultClasses; 1548 function applyClasses(classes) { 1549 var i; 1550 classes = classes.split(' '); 1551 for (i = 0; i < classes.length; i++) { 1552 self.classes.add(classes[i]); 1553 } 1554 } 1555 self.settings = settings = global$4.extend({}, self.Defaults, settings); 1556 self._id = settings.id || 'mceu_' + idCounter++; 1557 self._aria = { role: settings.role }; 1558 self._elmCache = {}; 1559 self.$ = global$7; 1560 self.state = new ObservableObject({ 1561 visible: true, 1562 active: false, 1563 disabled: false, 1564 value: '' 1565 }); 1566 self.data = new ObservableObject(settings.data); 1567 self.classes = new ClassList(function () { 1568 if (self.state.get('rendered')) { 1569 self.getEl().className = this.toString(); 1570 } 1571 }); 1572 self.classes.prefix = self.classPrefix; 1573 classes = settings.classes; 1574 if (classes) { 1575 if (self.Defaults) { 1576 defaultClasses = self.Defaults.classes; 1577 if (defaultClasses && classes !== defaultClasses) { 1578 applyClasses(defaultClasses); 1579 } 1580 } 1581 applyClasses(classes); 1582 } 1583 global$4.each('title text name visible disabled active value'.split(' '), function (name) { 1584 if (name in settings) { 1585 self[name](settings[name]); 1586 } 1587 }); 1588 self.on('click', function () { 1589 if (self.disabled()) { 1590 return false; 1591 } 1592 }); 1593 self.settings = settings; 1594 self.borderBox = BoxUtils.parseBox(settings.border); 1595 self.paddingBox = BoxUtils.parseBox(settings.padding); 1596 self.marginBox = BoxUtils.parseBox(settings.margin); 1597 if (settings.hidden) { 1598 self.hide(); 1599 } 1600 }, 1601 Properties: 'parent,name', 1602 getContainerElm: function () { 1603 var uiContainer = UiContainer.getUiContainer(this); 1604 return uiContainer ? uiContainer : funcs.getContainer(); 1605 }, 1606 getParentCtrl: function (elm) { 1607 var ctrl; 1608 var lookup = this.getRoot().controlIdLookup; 1609 while (elm && lookup) { 1610 ctrl = lookup[elm.id]; 1611 if (ctrl) { 1612 break; 1613 } 1614 elm = elm.parentNode; 1615 } 1616 return ctrl; 1617 }, 1618 initLayoutRect: function () { 1619 var self = this; 1620 var settings = self.settings; 1621 var borderBox, layoutRect; 1622 var elm = self.getEl(); 1623 var width, height, minWidth, minHeight, autoResize; 1624 var startMinWidth, startMinHeight, initialSize; 1625 borderBox = self.borderBox = self.borderBox || BoxUtils.measureBox(elm, 'border'); 1626 self.paddingBox = self.paddingBox || BoxUtils.measureBox(elm, 'padding'); 1627 self.marginBox = self.marginBox || BoxUtils.measureBox(elm, 'margin'); 1628 initialSize = funcs.getSize(elm); 1629 startMinWidth = settings.minWidth; 1630 startMinHeight = settings.minHeight; 1631 minWidth = startMinWidth || initialSize.width; 1632 minHeight = startMinHeight || initialSize.height; 1633 width = settings.width; 1634 height = settings.height; 1635 autoResize = settings.autoResize; 1636 autoResize = typeof autoResize !== 'undefined' ? autoResize : !width && !height; 1637 width = width || minWidth; 1638 height = height || minHeight; 1639 var deltaW = borderBox.left + borderBox.right; 1640 var deltaH = borderBox.top + borderBox.bottom; 1641 var maxW = settings.maxWidth || 65535; 1642 var maxH = settings.maxHeight || 65535; 1643 self._layoutRect = layoutRect = { 1644 x: settings.x || 0, 1645 y: settings.y || 0, 1646 w: width, 1647 h: height, 1648 deltaW: deltaW, 1649 deltaH: deltaH, 1650 contentW: width - deltaW, 1651 contentH: height - deltaH, 1652 innerW: width - deltaW, 1653 innerH: height - deltaH, 1654 startMinWidth: startMinWidth || 0, 1655 startMinHeight: startMinHeight || 0, 1656 minW: Math.min(minWidth, maxW), 1657 minH: Math.min(minHeight, maxH), 1658 maxW: maxW, 1659 maxH: maxH, 1660 autoResize: autoResize, 1661 scrollW: 0 1662 }; 1663 self._lastLayoutRect = {}; 1664 return layoutRect; 1665 }, 1666 layoutRect: function (newRect) { 1667 var self = this; 1668 var curRect = self._layoutRect, lastLayoutRect, size, deltaWidth, deltaHeight, repaintControls; 1669 if (!curRect) { 1670 curRect = self.initLayoutRect(); 1671 } 1672 if (newRect) { 1673 deltaWidth = curRect.deltaW; 1674 deltaHeight = curRect.deltaH; 1675 if (newRect.x !== undefined) { 1676 curRect.x = newRect.x; 1677 } 1678 if (newRect.y !== undefined) { 1679 curRect.y = newRect.y; 1680 } 1681 if (newRect.minW !== undefined) { 1682 curRect.minW = newRect.minW; 1683 } 1684 if (newRect.minH !== undefined) { 1685 curRect.minH = newRect.minH; 1686 } 1687 size = newRect.w; 1688 if (size !== undefined) { 1689 size = size < curRect.minW ? curRect.minW : size; 1690 size = size > curRect.maxW ? curRect.maxW : size; 1691 curRect.w = size; 1692 curRect.innerW = size - deltaWidth; 1693 } 1694 size = newRect.h; 1695 if (size !== undefined) { 1696 size = size < curRect.minH ? curRect.minH : size; 1697 size = size > curRect.maxH ? curRect.maxH : size; 1698 curRect.h = size; 1699 curRect.innerH = size - deltaHeight; 1700 } 1701 size = newRect.innerW; 1702 if (size !== undefined) { 1703 size = size < curRect.minW - deltaWidth ? curRect.minW - deltaWidth : size; 1704 size = size > curRect.maxW - deltaWidth ? curRect.maxW - deltaWidth : size; 1705 curRect.innerW = size; 1706 curRect.w = size + deltaWidth; 1707 } 1708 size = newRect.innerH; 1709 if (size !== undefined) { 1710 size = size < curRect.minH - deltaHeight ? curRect.minH - deltaHeight : size; 1711 size = size > curRect.maxH - deltaHeight ? curRect.maxH - deltaHeight : size; 1712 curRect.innerH = size; 1713 curRect.h = size + deltaHeight; 1714 } 1715 if (newRect.contentW !== undefined) { 1716 curRect.contentW = newRect.contentW; 1717 } 1718 if (newRect.contentH !== undefined) { 1719 curRect.contentH = newRect.contentH; 1720 } 1721 lastLayoutRect = self._lastLayoutRect; 1722 if (lastLayoutRect.x !== curRect.x || lastLayoutRect.y !== curRect.y || lastLayoutRect.w !== curRect.w || lastLayoutRect.h !== curRect.h) { 1723 repaintControls = Control.repaintControls; 1724 if (repaintControls) { 1725 if (repaintControls.map && !repaintControls.map[self._id]) { 1726 repaintControls.push(self); 1727 repaintControls.map[self._id] = true; 1728 } 1729 } 1730 lastLayoutRect.x = curRect.x; 1731 lastLayoutRect.y = curRect.y; 1732 lastLayoutRect.w = curRect.w; 1733 lastLayoutRect.h = curRect.h; 1734 } 1735 return self; 1736 } 1737 return curRect; 1738 }, 1739 repaint: function () { 1740 var self = this; 1741 var style, bodyStyle, bodyElm, rect, borderBox; 1742 var borderW, borderH, lastRepaintRect, round, value; 1743 round = !domGlobals.document.createRange ? Math.round : function (value) { 1744 return value; 1745 }; 1746 style = self.getEl().style; 1747 rect = self._layoutRect; 1748 lastRepaintRect = self._lastRepaintRect || {}; 1749 borderBox = self.borderBox; 1750 borderW = borderBox.left + borderBox.right; 1751 borderH = borderBox.top + borderBox.bottom; 1752 if (rect.x !== lastRepaintRect.x) { 1753 style.left = round(rect.x) + 'px'; 1754 lastRepaintRect.x = rect.x; 1755 } 1756 if (rect.y !== lastRepaintRect.y) { 1757 style.top = round(rect.y) + 'px'; 1758 lastRepaintRect.y = rect.y; 1759 } 1760 if (rect.w !== lastRepaintRect.w) { 1761 value = round(rect.w - borderW); 1762 style.width = (value >= 0 ? value : 0) + 'px'; 1763 lastRepaintRect.w = rect.w; 1764 } 1765 if (rect.h !== lastRepaintRect.h) { 1766 value = round(rect.h - borderH); 1767 style.height = (value >= 0 ? value : 0) + 'px'; 1768 lastRepaintRect.h = rect.h; 1769 } 1770 if (self._hasBody && rect.innerW !== lastRepaintRect.innerW) { 1771 value = round(rect.innerW); 1772 bodyElm = self.getEl('body'); 1773 if (bodyElm) { 1774 bodyStyle = bodyElm.style; 1775 bodyStyle.width = (value >= 0 ? value : 0) + 'px'; 1776 } 1777 lastRepaintRect.innerW = rect.innerW; 1778 } 1779 if (self._hasBody && rect.innerH !== lastRepaintRect.innerH) { 1780 value = round(rect.innerH); 1781 bodyElm = bodyElm || self.getEl('body'); 1782 if (bodyElm) { 1783 bodyStyle = bodyStyle || bodyElm.style; 1784 bodyStyle.height = (value >= 0 ? value : 0) + 'px'; 1785 } 1786 lastRepaintRect.innerH = rect.innerH; 1787 } 1788 self._lastRepaintRect = lastRepaintRect; 1789 self.fire('repaint', {}, false); 1790 }, 1791 updateLayoutRect: function () { 1792 var self = this; 1793 self.parent()._lastRect = null; 1794 funcs.css(self.getEl(), { 1795 width: '', 1796 height: '' 1797 }); 1798 self._layoutRect = self._lastRepaintRect = self._lastLayoutRect = null; 1799 self.initLayoutRect(); 1800 }, 1801 on: function (name, callback) { 1802 var self = this; 1803 function resolveCallbackName(name) { 1804 var callback, scope; 1805 if (typeof name !== 'string') { 1806 return name; 1807 } 1808 return function (e) { 1809 if (!callback) { 1810 self.parentsAndSelf().each(function (ctrl) { 1811 var callbacks = ctrl.settings.callbacks; 1812 if (callbacks && (callback = callbacks[name])) { 1813 scope = ctrl; 1814 return false; 1815 } 1816 }); 1817 } 1818 if (!callback) { 1819 e.action = name; 1820 this.fire('execute', e); 1821 return; 1822 } 1823 return callback.call(scope, e); 1824 }; 1825 } 1826 getEventDispatcher(self).on(name, resolveCallbackName(callback)); 1827 return self; 1828 }, 1829 off: function (name, callback) { 1830 getEventDispatcher(this).off(name, callback); 1831 return this; 1832 }, 1833 fire: function (name, args, bubble) { 1834 var self = this; 1835 args = args || {}; 1836 if (!args.control) { 1837 args.control = self; 1838 } 1839 args = getEventDispatcher(self).fire(name, args); 1840 if (bubble !== false && self.parent) { 1841 var parent = self.parent(); 1842 while (parent && !args.isPropagationStopped()) { 1843 parent.fire(name, args, false); 1844 parent = parent.parent(); 1845 } 1846 } 1847 return args; 1848 }, 1849 hasEventListeners: function (name) { 1850 return getEventDispatcher(this).has(name); 1851 }, 1852 parents: function (selector) { 1853 var self = this; 1854 var ctrl, parents = new Collection$2(); 1855 for (ctrl = self.parent(); ctrl; ctrl = ctrl.parent()) { 1856 parents.add(ctrl); 1857 } 1858 if (selector) { 1859 parents = parents.filter(selector); 1860 } 1861 return parents; 1862 }, 1863 parentsAndSelf: function (selector) { 1864 return new Collection$2(this).add(this.parents(selector)); 1865 }, 1866 next: function () { 1867 var parentControls = this.parent().items(); 1868 return parentControls[parentControls.indexOf(this) + 1]; 1869 }, 1870 prev: function () { 1871 var parentControls = this.parent().items(); 1872 return parentControls[parentControls.indexOf(this) - 1]; 1873 }, 1874 innerHtml: function (html) { 1875 this.$el.html(html); 1876 return this; 1877 }, 1878 getEl: function (suffix) { 1879 var id = suffix ? this._id + '-' + suffix : this._id; 1880 if (!this._elmCache[id]) { 1881 this._elmCache[id] = global$7('#' + id)[0]; 1882 } 1883 return this._elmCache[id]; 1884 }, 1885 show: function () { 1886 return this.visible(true); 1887 }, 1888 hide: function () { 1889 return this.visible(false); 1890 }, 1891 focus: function () { 1892 try { 1893 this.getEl().focus(); 1894 } catch (ex) { 1895 } 1896 return this; 1897 }, 1898 blur: function () { 1899 this.getEl().blur(); 1900 return this; 1901 }, 1902 aria: function (name, value) { 1903 var self = this, elm = self.getEl(self.ariaTarget); 1904 if (typeof value === 'undefined') { 1905 return self._aria[name]; 1906 } 1907 self._aria[name] = value; 1908 if (self.state.get('rendered')) { 1909 elm.setAttribute(name === 'role' ? name : 'aria-' + name, value); 1910 } 1911 return self; 1912 }, 1913 encode: function (text, translate) { 1914 if (translate !== false) { 1915 text = this.translate(text); 1916 } 1917 return (text || '').replace(/[&<>"]/g, function (match) { 1918 return '&#' + match.charCodeAt(0) + ';'; 1919 }); 1920 }, 1921 translate: function (text) { 1922 return Control.translate ? Control.translate(text) : text; 1923 }, 1924 before: function (items) { 1925 var self = this, parent = self.parent(); 1926 if (parent) { 1927 parent.insert(items, parent.items().indexOf(self), true); 1928 } 1929 return self; 1930 }, 1931 after: function (items) { 1932 var self = this, parent = self.parent(); 1933 if (parent) { 1934 parent.insert(items, parent.items().indexOf(self)); 1935 } 1936 return self; 1937 }, 1938 remove: function () { 1939 var self = this; 1940 var elm = self.getEl(); 1941 var parent = self.parent(); 1942 var newItems, i; 1943 if (self.items) { 1944 var controls = self.items().toArray(); 1945 i = controls.length; 1946 while (i--) { 1947 controls[i].remove(); 1948 } 1949 } 1950 if (parent && parent.items) { 1951 newItems = []; 1952 parent.items().each(function (item) { 1953 if (item !== self) { 1954 newItems.push(item); 1955 } 1956 }); 1957 parent.items().set(newItems); 1958 parent._lastRect = null; 1959 } 1960 if (self._eventsRoot && self._eventsRoot === self) { 1961 global$7(elm).off(); 1962 } 1963 var lookup = self.getRoot().controlIdLookup; 1964 if (lookup) { 1965 delete lookup[self._id]; 1966 } 1967 if (elm && elm.parentNode) { 1968 elm.parentNode.removeChild(elm); 1969 } 1970 self.state.set('rendered', false); 1971 self.state.destroy(); 1972 self.fire('remove'); 1973 return self; 1974 }, 1975 renderBefore: function (elm) { 1976 global$7(elm).before(this.renderHtml()); 1977 this.postRender(); 1978 return this; 1979 }, 1980 renderTo: function (elm) { 1981 global$7(elm || this.getContainerElm()).append(this.renderHtml()); 1982 this.postRender(); 1983 return this; 1984 }, 1985 preRender: function () { 1986 }, 1987 render: function () { 1988 }, 1989 renderHtml: function () { 1990 return '<div id="' + this._id + '" class="' + this.classes + '"></div>'; 1991 }, 1992 postRender: function () { 1993 var self = this; 1994 var settings = self.settings; 1995 var elm, box, parent, name, parentEventsRoot; 1996 self.$el = global$7(self.getEl()); 1997 self.state.set('rendered', true); 1998 for (name in settings) { 1999 if (name.indexOf('on') === 0) { 2000 self.on(name.substr(2), settings[name]); 2001 } 2002 } 2003 if (self._eventsRoot) { 2004 for (parent = self.parent(); !parentEventsRoot && parent; parent = parent.parent()) { 2005 parentEventsRoot = parent._eventsRoot; 2006 } 2007 if (parentEventsRoot) { 2008 for (name in parentEventsRoot._nativeEvents) { 2009 self._nativeEvents[name] = true; 2010 } 2011 } 2012 } 2013 bindPendingEvents(self); 2014 if (settings.style) { 2015 elm = self.getEl(); 2016 if (elm) { 2017 elm.setAttribute('style', settings.style); 2018 elm.style.cssText = settings.style; 2019 } 2020 } 2021 if (self.settings.border) { 2022 box = self.borderBox; 2023 self.$el.css({ 2024 'border-top-width': box.top, 2025 'border-right-width': box.right, 2026 'border-bottom-width': box.bottom, 2027 'border-left-width': box.left 2028 }); 2029 } 2030 var root = self.getRoot(); 2031 if (!root.controlIdLookup) { 2032 root.controlIdLookup = {}; 2033 } 2034 root.controlIdLookup[self._id] = self; 2035 for (var key in self._aria) { 2036 self.aria(key, self._aria[key]); 2037 } 2038 if (self.state.get('visible') === false) { 2039 self.getEl().style.display = 'none'; 2040 } 2041 self.bindStates(); 2042 self.state.on('change:visible', function (e) { 2043 var state = e.value; 2044 var parentCtrl; 2045 if (self.state.get('rendered')) { 2046 self.getEl().style.display = state === false ? 'none' : ''; 2047 self.getEl().getBoundingClientRect(); 2048 } 2049 parentCtrl = self.parent(); 2050 if (parentCtrl) { 2051 parentCtrl._lastRect = null; 2052 } 2053 self.fire(state ? 'show' : 'hide'); 2054 ReflowQueue.add(self); 2055 }); 2056 self.fire('postrender', {}, false); 2057 }, 2058 bindStates: function () { 2059 }, 2060 scrollIntoView: function (align) { 2061 function getOffset(elm, rootElm) { 2062 var x, y, parent = elm; 2063 x = y = 0; 2064 while (parent && parent !== rootElm && parent.nodeType) { 2065 x += parent.offsetLeft || 0; 2066 y += parent.offsetTop || 0; 2067 parent = parent.offsetParent; 2068 } 2069 return { 2070 x: x, 2071 y: y 2072 }; 2073 } 2074 var elm = this.getEl(), parentElm = elm.parentNode; 2075 var x, y, width, height, parentWidth, parentHeight; 2076 var pos = getOffset(elm, parentElm); 2077 x = pos.x; 2078 y = pos.y; 2079 width = elm.offsetWidth; 2080 height = elm.offsetHeight; 2081 parentWidth = parentElm.clientWidth; 2082 parentHeight = parentElm.clientHeight; 2083 if (align === 'end') { 2084 x -= parentWidth - width; 2085 y -= parentHeight - height; 2086 } else if (align === 'center') { 2087 x -= parentWidth / 2 - width / 2; 2088 y -= parentHeight / 2 - height / 2; 2089 } 2090 parentElm.scrollLeft = x; 2091 parentElm.scrollTop = y; 2092 return this; 2093 }, 2094 getRoot: function () { 2095 var ctrl = this, rootControl; 2096 var parents = []; 2097 while (ctrl) { 2098 if (ctrl.rootControl) { 2099 rootControl = ctrl.rootControl; 2100 break; 2101 } 2102 parents.push(ctrl); 2103 rootControl = ctrl; 2104 ctrl = ctrl.parent(); 2105 } 2106 if (!rootControl) { 2107 rootControl = this; 2108 } 2109 var i = parents.length; 2110 while (i--) { 2111 parents[i].rootControl = rootControl; 2112 } 2113 return rootControl; 2114 }, 2115 reflow: function () { 2116 ReflowQueue.remove(this); 2117 var parent = this.parent(); 2118 if (parent && parent._layout && !parent._layout.isNative()) { 2119 parent.reflow(); 2120 } 2121 return this; 2122 } 2123 }; 2124 global$4.each('text title visible disabled active value'.split(' '), function (name) { 2125 proto$1[name] = function (value) { 2126 if (arguments.length === 0) { 2127 return this.state.get(name); 2128 } 2129 if (typeof value !== 'undefined') { 2130 this.state.set(name, value); 2131 } 2132 return this; 2133 }; 2134 }); 2135 Control = global$8.extend(proto$1); 2136 function getEventDispatcher(obj) { 2137 if (!obj._eventDispatcher) { 2138 obj._eventDispatcher = new global$9({ 2139 scope: obj, 2140 toggleEvent: function (name, state) { 2141 if (state && global$9.isNative(name)) { 2142 if (!obj._nativeEvents) { 2143 obj._nativeEvents = {}; 2144 } 2145 obj._nativeEvents[name] = true; 2146 if (obj.state.get('rendered')) { 2147 bindPendingEvents(obj); 2148 } 2149 } 2150 } 2151 }); 2152 } 2153 return obj._eventDispatcher; 2154 } 2155 function bindPendingEvents(eventCtrl) { 2156 var i, l, parents, eventRootCtrl, nativeEvents, name; 2157 function delegate(e) { 2158 var control = eventCtrl.getParentCtrl(e.target); 2159 if (control) { 2160 control.fire(e.type, e); 2161 } 2162 } 2163 function mouseLeaveHandler() { 2164 var ctrl = eventRootCtrl._lastHoverCtrl; 2165 if (ctrl) { 2166 ctrl.fire('mouseleave', { target: ctrl.getEl() }); 2167 ctrl.parents().each(function (ctrl) { 2168 ctrl.fire('mouseleave', { target: ctrl.getEl() }); 2169 }); 2170 eventRootCtrl._lastHoverCtrl = null; 2171 } 2172 } 2173 function mouseEnterHandler(e) { 2174 var ctrl = eventCtrl.getParentCtrl(e.target), lastCtrl = eventRootCtrl._lastHoverCtrl, idx = 0, i, parents, lastParents; 2175 if (ctrl !== lastCtrl) { 2176 eventRootCtrl._lastHoverCtrl = ctrl; 2177 parents = ctrl.parents().toArray().reverse(); 2178 parents.push(ctrl); 2179 if (lastCtrl) { 2180 lastParents = lastCtrl.parents().toArray().reverse(); 2181 lastParents.push(lastCtrl); 2182 for (idx = 0; idx < lastParents.length; idx++) { 2183 if (parents[idx] !== lastParents[idx]) { 2184 break; 2185 } 2186 } 2187 for (i = lastParents.length - 1; i >= idx; i--) { 2188 lastCtrl = lastParents[i]; 2189 lastCtrl.fire('mouseleave', { target: lastCtrl.getEl() }); 2190 } 2191 } 2192 for (i = idx; i < parents.length; i++) { 2193 ctrl = parents[i]; 2194 ctrl.fire('mouseenter', { target: ctrl.getEl() }); 2195 } 2196 } 2197 } 2198 function fixWheelEvent(e) { 2199 e.preventDefault(); 2200 if (e.type === 'mousewheel') { 2201 e.deltaY = -1 / 40 * e.wheelDelta; 2202 if (e.wheelDeltaX) { 2203 e.deltaX = -1 / 40 * e.wheelDeltaX; 2204 } 2205 } else { 2206 e.deltaX = 0; 2207 e.deltaY = e.detail; 2208 } 2209 e = eventCtrl.fire('wheel', e); 2210 } 2211 nativeEvents = eventCtrl._nativeEvents; 2212 if (nativeEvents) { 2213 parents = eventCtrl.parents().toArray(); 2214 parents.unshift(eventCtrl); 2215 for (i = 0, l = parents.length; !eventRootCtrl && i < l; i++) { 2216 eventRootCtrl = parents[i]._eventsRoot; 2217 } 2218 if (!eventRootCtrl) { 2219 eventRootCtrl = parents[parents.length - 1] || eventCtrl; 2220 } 2221 eventCtrl._eventsRoot = eventRootCtrl; 2222 for (l = i, i = 0; i < l; i++) { 2223 parents[i]._eventsRoot = eventRootCtrl; 2224 } 2225 var eventRootDelegates = eventRootCtrl._delegates; 2226 if (!eventRootDelegates) { 2227 eventRootDelegates = eventRootCtrl._delegates = {}; 2228 } 2229 for (name in nativeEvents) { 2230 if (!nativeEvents) { 2231 return false; 2232 } 2233 if (name === 'wheel' && !hasWheelEventSupport) { 2234 if (hasMouseWheelEventSupport) { 2235 global$7(eventCtrl.getEl()).on('mousewheel', fixWheelEvent); 2236 } else { 2237 global$7(eventCtrl.getEl()).on('DOMMouseScroll', fixWheelEvent); 2238 } 2239 continue; 2240 } 2241 if (name === 'mouseenter' || name === 'mouseleave') { 2242 if (!eventRootCtrl._hasMouseEnter) { 2243 global$7(eventRootCtrl.getEl()).on('mouseleave', mouseLeaveHandler).on('mouseover', mouseEnterHandler); 2244 eventRootCtrl._hasMouseEnter = 1; 2245 } 2246 } else if (!eventRootDelegates[name]) { 2247 global$7(eventRootCtrl.getEl()).on(name, delegate); 2248 eventRootDelegates[name] = true; 2249 } 2250 nativeEvents[name] = false; 2251 } 2252 } 2253 } 2254 var Control$1 = Control; 2255 2256 var isStatic = function (elm) { 2257 return funcs.getRuntimeStyle(elm, 'position') === 'static'; 2258 }; 2259 var isFixed = function (ctrl) { 2260 return ctrl.state.get('fixed'); 2261 }; 2262 function calculateRelativePosition(ctrl, targetElm, rel) { 2263 var ctrlElm, pos, x, y, selfW, selfH, targetW, targetH, viewport, size; 2264 viewport = getWindowViewPort(); 2265 pos = funcs.getPos(targetElm, UiContainer.getUiContainer(ctrl)); 2266 x = pos.x; 2267 y = pos.y; 2268 if (isFixed(ctrl) && isStatic(domGlobals.document.body)) { 2269 x -= viewport.x; 2270 y -= viewport.y; 2271 } 2272 ctrlElm = ctrl.getEl(); 2273 size = funcs.getSize(ctrlElm); 2274 selfW = size.width; 2275 selfH = size.height; 2276 size = funcs.getSize(targetElm); 2277 targetW = size.width; 2278 targetH = size.height; 2279 rel = (rel || '').split(''); 2280 if (rel[0] === 'b') { 2281 y += targetH; 2282 } 2283 if (rel[1] === 'r') { 2284 x += targetW; 2285 } 2286 if (rel[0] === 'c') { 2287 y += Math.round(targetH / 2); 2288 } 2289 if (rel[1] === 'c') { 2290 x += Math.round(targetW / 2); 2291 } 2292 if (rel[3] === 'b') { 2293 y -= selfH; 2294 } 2295 if (rel[4] === 'r') { 2296 x -= selfW; 2297 } 2298 if (rel[3] === 'c') { 2299 y -= Math.round(selfH / 2); 2300 } 2301 if (rel[4] === 'c') { 2302 x -= Math.round(selfW / 2); 2303 } 2304 return { 2305 x: x, 2306 y: y, 2307 w: selfW, 2308 h: selfH 2309 }; 2310 } 2311 var getUiContainerViewPort = function (customUiContainer) { 2312 return { 2313 x: 0, 2314 y: 0, 2315 w: customUiContainer.scrollWidth - 1, 2316 h: customUiContainer.scrollHeight - 1 2317 }; 2318 }; 2319 var getWindowViewPort = function () { 2320 var win = domGlobals.window; 2321 var x = Math.max(win.pageXOffset, domGlobals.document.body.scrollLeft, domGlobals.document.documentElement.scrollLeft); 2322 var y = Math.max(win.pageYOffset, domGlobals.document.body.scrollTop, domGlobals.document.documentElement.scrollTop); 2323 var w = win.innerWidth || domGlobals.document.documentElement.clientWidth; 2324 var h = win.innerHeight || domGlobals.document.documentElement.clientHeight; 2325 return { 2326 x: x, 2327 y: y, 2328 w: w, 2329 h: h 2330 }; 2331 }; 2332 var getViewPortRect = function (ctrl) { 2333 var customUiContainer = UiContainer.getUiContainer(ctrl); 2334 return customUiContainer && !isFixed(ctrl) ? getUiContainerViewPort(customUiContainer) : getWindowViewPort(); 2335 }; 2336 var Movable = { 2337 testMoveRel: function (elm, rels) { 2338 var viewPortRect = getViewPortRect(this); 2339 for (var i = 0; i < rels.length; i++) { 2340 var pos = calculateRelativePosition(this, elm, rels[i]); 2341 if (isFixed(this)) { 2342 if (pos.x > 0 && pos.x + pos.w < viewPortRect.w && pos.y > 0 && pos.y + pos.h < viewPortRect.h) { 2343 return rels[i]; 2344 } 2345 } else { 2346 if (pos.x > viewPortRect.x && pos.x + pos.w < viewPortRect.w + viewPortRect.x && pos.y > viewPortRect.y && pos.y + pos.h < viewPortRect.h + viewPortRect.y) { 2347 return rels[i]; 2348 } 2349 } 2350 } 2351 return rels[0]; 2352 }, 2353 moveRel: function (elm, rel) { 2354 if (typeof rel !== 'string') { 2355 rel = this.testMoveRel(elm, rel); 2356 } 2357 var pos = calculateRelativePosition(this, elm, rel); 2358 return this.moveTo(pos.x, pos.y); 2359 }, 2360 moveBy: function (dx, dy) { 2361 var self = this, rect = self.layoutRect(); 2362 self.moveTo(rect.x + dx, rect.y + dy); 2363 return self; 2364 }, 2365 moveTo: function (x, y) { 2366 var self = this; 2367 function constrain(value, max, size) { 2368 if (value < 0) { 2369 return 0; 2370 } 2371 if (value + size > max) { 2372 value = max - size; 2373 return value < 0 ? 0 : value; 2374 } 2375 return value; 2376 } 2377 if (self.settings.constrainToViewport) { 2378 var viewPortRect = getViewPortRect(this); 2379 var layoutRect = self.layoutRect(); 2380 x = constrain(x, viewPortRect.w + viewPortRect.x, layoutRect.w); 2381 y = constrain(y, viewPortRect.h + viewPortRect.y, layoutRect.h); 2382 } 2383 var uiContainer = UiContainer.getUiContainer(self); 2384 if (uiContainer && isStatic(uiContainer) && !isFixed(self)) { 2385 x -= uiContainer.scrollLeft; 2386 y -= uiContainer.scrollTop; 2387 } 2388 if (uiContainer) { 2389 x += 1; 2390 y += 1; 2391 } 2392 if (self.state.get('rendered')) { 2393 self.layoutRect({ 2394 x: x, 2395 y: y 2396 }).repaint(); 2397 } else { 2398 self.settings.x = x; 2399 self.settings.y = y; 2400 } 2401 self.fire('move', { 2402 x: x, 2403 y: y 2404 }); 2405 return self; 2406 } 2407 }; 2408 2409 var Tooltip = Control$1.extend({ 2410 Mixins: [Movable], 2411 Defaults: { classes: 'widget tooltip tooltip-n' }, 2412 renderHtml: function () { 2413 var self = this, prefix = self.classPrefix; 2414 return '<div id="' + self._id + '" class="' + self.classes + '" role="presentation">' + '<div class="' + prefix + 'tooltip-arrow"></div>' + '<div class="' + prefix + 'tooltip-inner">' + self.encode(self.state.get('text')) + '</div>' + '</div>'; 2415 }, 2416 bindStates: function () { 2417 var self = this; 2418 self.state.on('change:text', function (e) { 2419 self.getEl().lastChild.innerHTML = self.encode(e.value); 2420 }); 2421 return self._super(); 2422 }, 2423 repaint: function () { 2424 var self = this; 2425 var style, rect; 2426 style = self.getEl().style; 2427 rect = self._layoutRect; 2428 style.left = rect.x + 'px'; 2429 style.top = rect.y + 'px'; 2430 style.zIndex = 65535 + 65535; 2431 } 2432 }); 2433 2434 var Widget = Control$1.extend({ 2435 init: function (settings) { 2436 var self = this; 2437 self._super(settings); 2438 settings = self.settings; 2439 self.canFocus = true; 2440 if (settings.tooltip && Widget.tooltips !== false) { 2441 self.on('mouseenter', function (e) { 2442 var tooltip = self.tooltip().moveTo(-65535); 2443 if (e.control === self) { 2444 var rel = tooltip.text(settings.tooltip).show().testMoveRel(self.getEl(), [ 2445 'bc-tc', 2446 'bc-tl', 2447 'bc-tr' 2448 ]); 2449 tooltip.classes.toggle('tooltip-n', rel === 'bc-tc'); 2450 tooltip.classes.toggle('tooltip-nw', rel === 'bc-tl'); 2451 tooltip.classes.toggle('tooltip-ne', rel === 'bc-tr'); 2452 tooltip.moveRel(self.getEl(), rel); 2453 } else { 2454 tooltip.hide(); 2455 } 2456 }); 2457 self.on('mouseleave mousedown click', function () { 2458 self.tooltip().remove(); 2459 self._tooltip = null; 2460 }); 2461 } 2462 self.aria('label', settings.ariaLabel || settings.tooltip); 2463 }, 2464 tooltip: function () { 2465 if (!this._tooltip) { 2466 this._tooltip = new Tooltip({ type: 'tooltip' }); 2467 UiContainer.inheritUiContainer(this, this._tooltip); 2468 this._tooltip.renderTo(); 2469 } 2470 return this._tooltip; 2471 }, 2472 postRender: function () { 2473 var self = this, settings = self.settings; 2474 self._super(); 2475 if (!self.parent() && (settings.width || settings.height)) { 2476 self.initLayoutRect(); 2477 self.repaint(); 2478 } 2479 if (settings.autofocus) { 2480 self.focus(); 2481 } 2482 }, 2483 bindStates: function () { 2484 var self = this; 2485 function disable(state) { 2486 self.aria('disabled', state); 2487 self.classes.toggle('disabled', state); 2488 } 2489 function active(state) { 2490 self.aria('pressed', state); 2491 self.classes.toggle('active', state); 2492 } 2493 self.state.on('change:disabled', function (e) { 2494 disable(e.value); 2495 }); 2496 self.state.on('change:active', function (e) { 2497 active(e.value); 2498 }); 2499 if (self.state.get('disabled')) { 2500 disable(true); 2501 } 2502 if (self.state.get('active')) { 2503 active(true); 2504 } 2505 return self._super(); 2506 }, 2507 remove: function () { 2508 this._super(); 2509 if (this._tooltip) { 2510 this._tooltip.remove(); 2511 this._tooltip = null; 2512 } 2513 } 2514 }); 2515 2516 var Progress = Widget.extend({ 2517 Defaults: { value: 0 }, 2518 init: function (settings) { 2519 var self = this; 2520 self._super(settings); 2521 self.classes.add('progress'); 2522 if (!self.settings.filter) { 2523 self.settings.filter = function (value) { 2524 return Math.round(value); 2525 }; 2526 } 2527 }, 2528 renderHtml: function () { 2529 var self = this, id = self._id, prefix = this.classPrefix; 2530 return '<div id="' + id + '" class="' + self.classes + '">' + '<div class="' + prefix + 'bar-container">' + '<div class="' + prefix + 'bar"></div>' + '</div>' + '<div class="' + prefix + 'text">0%</div>' + '</div>'; 2531 }, 2532 postRender: function () { 2533 var self = this; 2534 self._super(); 2535 self.value(self.settings.value); 2536 return self; 2537 }, 2538 bindStates: function () { 2539 var self = this; 2540 function setValue(value) { 2541 value = self.settings.filter(value); 2542 self.getEl().lastChild.innerHTML = value + '%'; 2543 self.getEl().firstChild.firstChild.style.width = value + '%'; 2544 } 2545 self.state.on('change:value', function (e) { 2546 setValue(e.value); 2547 }); 2548 setValue(self.state.get('value')); 2549 return self._super(); 2550 } 2551 }); 2552 2553 var updateLiveRegion = function (ctx, text) { 2554 ctx.getEl().lastChild.textContent = text + (ctx.progressBar ? ' ' + ctx.progressBar.value() + '%' : ''); 2555 }; 2556 var Notification = Control$1.extend({ 2557 Mixins: [Movable], 2558 Defaults: { classes: 'widget notification' }, 2559 init: function (settings) { 2560 var self = this; 2561 self._super(settings); 2562 self.maxWidth = settings.maxWidth; 2563 if (settings.text) { 2564 self.text(settings.text); 2565 } 2566 if (settings.icon) { 2567 self.icon = settings.icon; 2568 } 2569 if (settings.color) { 2570 self.color = settings.color; 2571 } 2572 if (settings.type) { 2573 self.classes.add('notification-' + settings.type); 2574 } 2575 if (settings.timeout && (settings.timeout < 0 || settings.timeout > 0) && !settings.closeButton) { 2576 self.closeButton = false; 2577 } else { 2578 self.classes.add('has-close'); 2579 self.closeButton = true; 2580 } 2581 if (settings.progressBar) { 2582 self.progressBar = new Progress(); 2583 } 2584 self.on('click', function (e) { 2585 if (e.target.className.indexOf(self.classPrefix + 'close') !== -1) { 2586 self.close(); 2587 } 2588 }); 2589 }, 2590 renderHtml: function () { 2591 var self = this; 2592 var prefix = self.classPrefix; 2593 var icon = '', closeButton = '', progressBar = '', notificationStyle = ''; 2594 if (self.icon) { 2595 icon = '<i class="' + prefix + 'ico' + ' ' + prefix + 'i-' + self.icon + '"></i>'; 2596 } 2597 notificationStyle = ' style="max-width: ' + self.maxWidth + 'px;' + (self.color ? 'background-color: ' + self.color + ';"' : '"'); 2598 if (self.closeButton) { 2599 closeButton = '<button type="button" class="' + prefix + 'close" aria-hidden="true">\xD7</button>'; 2600 } 2601 if (self.progressBar) { 2602 progressBar = self.progressBar.renderHtml(); 2603 } 2604 return '<div id="' + self._id + '" class="' + self.classes + '"' + notificationStyle + ' role="presentation">' + icon + '<div class="' + prefix + 'notification-inner">' + self.state.get('text') + '</div>' + progressBar + closeButton + '<div style="clip: rect(1px, 1px, 1px, 1px);height: 1px;overflow: hidden;position: absolute;width: 1px;"' + ' aria-live="assertive" aria-relevant="additions" aria-atomic="true"></div>' + '</div>'; 2605 }, 2606 postRender: function () { 2607 var self = this; 2608 global$3.setTimeout(function () { 2609 self.$el.addClass(self.classPrefix + 'in'); 2610 updateLiveRegion(self, self.state.get('text')); 2611 }, 100); 2612 return self._super(); 2613 }, 2614 bindStates: function () { 2615 var self = this; 2616 self.state.on('change:text', function (e) { 2617 self.getEl().firstChild.innerHTML = e.value; 2618 updateLiveRegion(self, e.value); 2619 }); 2620 if (self.progressBar) { 2621 self.progressBar.bindStates(); 2622 self.progressBar.state.on('change:value', function (e) { 2623 updateLiveRegion(self, self.state.get('text')); 2624 }); 2625 } 2626 return self._super(); 2627 }, 2628 close: function () { 2629 var self = this; 2630 if (!self.fire('close').isDefaultPrevented()) { 2631 self.remove(); 2632 } 2633 return self; 2634 }, 2635 repaint: function () { 2636 var self = this; 2637 var style, rect; 2638 style = self.getEl().style; 2639 rect = self._layoutRect; 2640 style.left = rect.x + 'px'; 2641 style.top = rect.y + 'px'; 2642 style.zIndex = 65535 - 1; 2643 } 2644 }); 2645 2646 function NotificationManagerImpl (editor) { 2647 var getEditorContainer = function (editor) { 2648 return editor.inline ? editor.getElement() : editor.getContentAreaContainer(); 2649 }; 2650 var getContainerWidth = function () { 2651 var container = getEditorContainer(editor); 2652 return funcs.getSize(container).width; 2653 }; 2654 var prePositionNotifications = function (notifications) { 2655 each(notifications, function (notification) { 2656 notification.moveTo(0, 0); 2657 }); 2658 }; 2659 var positionNotifications = function (notifications) { 2660 if (notifications.length > 0) { 2661 var firstItem = notifications.slice(0, 1)[0]; 2662 var container = getEditorContainer(editor); 2663 firstItem.moveRel(container, 'tc-tc'); 2664 each(notifications, function (notification, index) { 2665 if (index > 0) { 2666 notification.moveRel(notifications[index - 1].getEl(), 'bc-tc'); 2667 } 2668 }); 2669 } 2670 }; 2671 var reposition = function (notifications) { 2672 prePositionNotifications(notifications); 2673 positionNotifications(notifications); 2674 }; 2675 var open = function (args, closeCallback) { 2676 var extendedArgs = global$4.extend(args, { maxWidth: getContainerWidth() }); 2677 var notif = new Notification(extendedArgs); 2678 notif.args = extendedArgs; 2679 if (extendedArgs.timeout > 0) { 2680 notif.timer = setTimeout(function () { 2681 notif.close(); 2682 closeCallback(); 2683 }, extendedArgs.timeout); 2684 } 2685 notif.on('close', function () { 2686 closeCallback(); 2687 }); 2688 notif.renderTo(); 2689 return notif; 2690 }; 2691 var close = function (notification) { 2692 notification.close(); 2693 }; 2694 var getArgs = function (notification) { 2695 return notification.args; 2696 }; 2697 return { 2698 open: open, 2699 close: close, 2700 reposition: reposition, 2701 getArgs: getArgs 2702 }; 2703 } 2704 2705 function getDocumentSize(doc) { 2706 var documentElement, body, scrollWidth, clientWidth; 2707 var offsetWidth, scrollHeight, clientHeight, offsetHeight; 2708 var max = Math.max; 2709 documentElement = doc.documentElement; 2710 body = doc.body; 2711 scrollWidth = max(documentElement.scrollWidth, body.scrollWidth); 2712 clientWidth = max(documentElement.clientWidth, body.clientWidth); 2713 offsetWidth = max(documentElement.offsetWidth, body.offsetWidth); 2714 scrollHeight = max(documentElement.scrollHeight, body.scrollHeight); 2715 clientHeight = max(documentElement.clientHeight, body.clientHeight); 2716 offsetHeight = max(documentElement.offsetHeight, body.offsetHeight); 2717 return { 2718 width: scrollWidth < offsetWidth ? clientWidth : scrollWidth, 2719 height: scrollHeight < offsetHeight ? clientHeight : scrollHeight 2720 }; 2721 } 2722 function updateWithTouchData(e) { 2723 var keys, i; 2724 if (e.changedTouches) { 2725 keys = 'screenX screenY pageX pageY clientX clientY'.split(' '); 2726 for (i = 0; i < keys.length; i++) { 2727 e[keys[i]] = e.changedTouches[0][keys[i]]; 2728 } 2729 } 2730 } 2731 function DragHelper (id, settings) { 2732 var $eventOverlay; 2733 var doc = settings.document || domGlobals.document; 2734 var downButton; 2735 var start, stop, drag, startX, startY; 2736 settings = settings || {}; 2737 var handleElement = doc.getElementById(settings.handle || id); 2738 start = function (e) { 2739 var docSize = getDocumentSize(doc); 2740 var handleElm, cursor; 2741 updateWithTouchData(e); 2742 e.preventDefault(); 2743 downButton = e.button; 2744 handleElm = handleElement; 2745 startX = e.screenX; 2746 startY = e.screenY; 2747 if (domGlobals.window.getComputedStyle) { 2748 cursor = domGlobals.window.getComputedStyle(handleElm, null).getPropertyValue('cursor'); 2749 } else { 2750 cursor = handleElm.runtimeStyle.cursor; 2751 } 2752 $eventOverlay = global$7('<div></div>').css({ 2753 position: 'absolute', 2754 top: 0, 2755 left: 0, 2756 width: docSize.width, 2757 height: docSize.height, 2758 zIndex: 2147483647, 2759 opacity: 0.0001, 2760 cursor: cursor 2761 }).appendTo(doc.body); 2762 global$7(doc).on('mousemove touchmove', drag).on('mouseup touchend', stop); 2763 settings.start(e); 2764 }; 2765 drag = function (e) { 2766 updateWithTouchData(e); 2767 if (e.button !== downButton) { 2768 return stop(e); 2769 } 2770 e.deltaX = e.screenX - startX; 2771 e.deltaY = e.screenY - startY; 2772 e.preventDefault(); 2773 settings.drag(e); 2774 }; 2775 stop = function (e) { 2776 updateWithTouchData(e); 2777 global$7(doc).off('mousemove touchmove', drag).off('mouseup touchend', stop); 2778 $eventOverlay.remove(); 2779 if (settings.stop) { 2780 settings.stop(e); 2781 } 2782 }; 2783 this.destroy = function () { 2784 global$7(handleElement).off(); 2785 }; 2786 global$7(handleElement).on('mousedown touchstart', start); 2787 } 2788 2789 var global$b = tinymce.util.Tools.resolve('tinymce.ui.Factory'); 2790 2791 var hasTabstopData = function (elm) { 2792 return elm.getAttribute('data-mce-tabstop') ? true : false; 2793 }; 2794 function KeyboardNavigation (settings) { 2795 var root = settings.root; 2796 var focusedElement, focusedControl; 2797 function isElement(node) { 2798 return node && node.nodeType === 1; 2799 } 2800 try { 2801 focusedElement = domGlobals.document.activeElement; 2802 } catch (ex) { 2803 focusedElement = domGlobals.document.body; 2804 } 2805 focusedControl = root.getParentCtrl(focusedElement); 2806 function getRole(elm) { 2807 elm = elm || focusedElement; 2808 if (isElement(elm)) { 2809 return elm.getAttribute('role'); 2810 } 2811 return null; 2812 } 2813 function getParentRole(elm) { 2814 var role, parent = elm || focusedElement; 2815 while (parent = parent.parentNode) { 2816 if (role = getRole(parent)) { 2817 return role; 2818 } 2819 } 2820 } 2821 function getAriaProp(name) { 2822 var elm = focusedElement; 2823 if (isElement(elm)) { 2824 return elm.getAttribute('aria-' + name); 2825 } 2826 } 2827 function isTextInputElement(elm) { 2828 var tagName = elm.tagName.toUpperCase(); 2829 return tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT'; 2830 } 2831 function canFocus(elm) { 2832 if (isTextInputElement(elm) && !elm.hidden) { 2833 return true; 2834 } 2835 if (hasTabstopData(elm)) { 2836 return true; 2837 } 2838 if (/^(button|menuitem|checkbox|tab|menuitemcheckbox|option|gridcell|slider)$/.test(getRole(elm))) { 2839 return true; 2840 } 2841 return false; 2842 } 2843 function getFocusElements(elm) { 2844 var elements = []; 2845 function collect(elm) { 2846 if (elm.nodeType !== 1 || elm.style.display === 'none' || elm.disabled) { 2847 return; 2848 } 2849 if (canFocus(elm)) { 2850 elements.push(elm); 2851 } 2852 for (var i = 0; i < elm.childNodes.length; i++) { 2853 collect(elm.childNodes[i]); 2854 } 2855 } 2856 collect(elm || root.getEl()); 2857 return elements; 2858 } 2859 function getNavigationRoot(targetControl) { 2860 var navigationRoot, controls; 2861 targetControl = targetControl || focusedControl; 2862 controls = targetControl.parents().toArray(); 2863 controls.unshift(targetControl); 2864 for (var i = 0; i < controls.length; i++) { 2865 navigationRoot = controls[i]; 2866 if (navigationRoot.settings.ariaRoot) { 2867 break; 2868 } 2869 } 2870 return navigationRoot; 2871 } 2872 function focusFirst(targetControl) { 2873 var navigationRoot = getNavigationRoot(targetControl); 2874 var focusElements = getFocusElements(navigationRoot.getEl()); 2875 if (navigationRoot.settings.ariaRemember && 'lastAriaIndex' in navigationRoot) { 2876 moveFocusToIndex(navigationRoot.lastAriaIndex, focusElements); 2877 } else { 2878 moveFocusToIndex(0, focusElements); 2879 } 2880 } 2881 function moveFocusToIndex(idx, elements) { 2882 if (idx < 0) { 2883 idx = elements.length - 1; 2884 } else if (idx >= elements.length) { 2885 idx = 0; 2886 } 2887 if (elements[idx]) { 2888 elements[idx].focus(); 2889 } 2890 return idx; 2891 } 2892 function moveFocus(dir, elements) { 2893 var idx = -1; 2894 var navigationRoot = getNavigationRoot(); 2895 elements = elements || getFocusElements(navigationRoot.getEl()); 2896 for (var i = 0; i < elements.length; i++) { 2897 if (elements[i] === focusedElement) { 2898 idx = i; 2899 } 2900 } 2901 idx += dir; 2902 navigationRoot.lastAriaIndex = moveFocusToIndex(idx, elements); 2903 } 2904 function left() { 2905 var parentRole = getParentRole(); 2906 if (parentRole === 'tablist') { 2907 moveFocus(-1, getFocusElements(focusedElement.parentNode)); 2908 } else if (focusedControl.parent().submenu) { 2909 cancel(); 2910 } else { 2911 moveFocus(-1); 2912 } 2913 } 2914 function right() { 2915 var role = getRole(), parentRole = getParentRole(); 2916 if (parentRole === 'tablist') { 2917 moveFocus(1, getFocusElements(focusedElement.parentNode)); 2918 } else if (role === 'menuitem' && parentRole === 'menu' && getAriaProp('haspopup')) { 2919 enter(); 2920 } else { 2921 moveFocus(1); 2922 } 2923 } 2924 function up() { 2925 moveFocus(-1); 2926 } 2927 function down() { 2928 var role = getRole(), parentRole = getParentRole(); 2929 if (role === 'menuitem' && parentRole === 'menubar') { 2930 enter(); 2931 } else if (role === 'button' && getAriaProp('haspopup')) { 2932 enter({ key: 'down' }); 2933 } else { 2934 moveFocus(1); 2935 } 2936 } 2937 function tab(e) { 2938 var parentRole = getParentRole(); 2939 if (parentRole === 'tablist') { 2940 var elm = getFocusElements(focusedControl.getEl('body'))[0]; 2941 if (elm) { 2942 elm.focus(); 2943 } 2944 } else { 2945 moveFocus(e.shiftKey ? -1 : 1); 2946 } 2947 } 2948 function cancel() { 2949 focusedControl.fire('cancel'); 2950 } 2951 function enter(aria) { 2952 aria = aria || {}; 2953 focusedControl.fire('click', { 2954 target: focusedElement, 2955 aria: aria 2956 }); 2957 } 2958 root.on('keydown', function (e) { 2959 function handleNonTabOrEscEvent(e, handler) { 2960 if (isTextInputElement(focusedElement) || hasTabstopData(focusedElement)) { 2961 return; 2962 } 2963 if (getRole(focusedElement) === 'slider') { 2964 return; 2965 } 2966 if (handler(e) !== false) { 2967 e.preventDefault(); 2968 } 2969 } 2970 if (e.isDefaultPrevented()) { 2971 return; 2972 } 2973 switch (e.keyCode) { 2974 case 37: 2975 handleNonTabOrEscEvent(e, left); 2976 break; 2977 case 39: 2978 handleNonTabOrEscEvent(e, right); 2979 break; 2980 case 38: 2981 handleNonTabOrEscEvent(e, up); 2982 break; 2983 case 40: 2984 handleNonTabOrEscEvent(e, down); 2985 break; 2986 case 27: 2987 cancel(); 2988 break; 2989 case 14: 2990 case 13: 2991 case 32: 2992 handleNonTabOrEscEvent(e, enter); 2993 break; 2994 case 9: 2995 tab(e); 2996 e.preventDefault(); 2997 break; 2998 } 2999 }); 3000 root.on('focusin', function (e) { 3001 focusedElement = e.target; 3002 focusedControl = e.control; 3003 }); 3004 return { focusFirst: focusFirst }; 3005 } 3006 3007 var selectorCache = {}; 3008 var Container = Control$1.extend({ 3009 init: function (settings) { 3010 var self = this; 3011 self._super(settings); 3012 settings = self.settings; 3013 if (settings.fixed) { 3014 self.state.set('fixed', true); 3015 } 3016 self._items = new Collection$2(); 3017 if (self.isRtl()) { 3018 self.classes.add('rtl'); 3019 } 3020 self.bodyClasses = new ClassList(function () { 3021 if (self.state.get('rendered')) { 3022 self.getEl('body').className = this.toString(); 3023 } 3024 }); 3025 self.bodyClasses.prefix = self.classPrefix; 3026 self.classes.add('container'); 3027 self.bodyClasses.add('container-body'); 3028 if (settings.containerCls) { 3029 self.classes.add(settings.containerCls); 3030 } 3031 self._layout = global$b.create((settings.layout || '') + 'layout'); 3032 if (self.settings.items) { 3033 self.add(self.settings.items); 3034 } else { 3035 self.add(self.render()); 3036 } 3037 self._hasBody = true; 3038 }, 3039 items: function () { 3040 return this._items; 3041 }, 3042 find: function (selector) { 3043 selector = selectorCache[selector] = selectorCache[selector] || new Selector(selector); 3044 return selector.find(this); 3045 }, 3046 add: function (items) { 3047 var self = this; 3048 self.items().add(self.create(items)).parent(self); 3049 return self; 3050 }, 3051 focus: function (keyboard) { 3052 var self = this; 3053 var focusCtrl, keyboardNav, items; 3054 if (keyboard) { 3055 keyboardNav = self.keyboardNav || self.parents().eq(-1)[0].keyboardNav; 3056 if (keyboardNav) { 3057 keyboardNav.focusFirst(self); 3058 return; 3059 } 3060 } 3061 items = self.find('*'); 3062 if (self.statusbar) { 3063 items.add(self.statusbar.items()); 3064 } 3065 items.each(function (ctrl) { 3066 if (ctrl.settings.autofocus) { 3067 focusCtrl = null; 3068 return false; 3069 } 3070 if (ctrl.canFocus) { 3071 focusCtrl = focusCtrl || ctrl; 3072 } 3073 }); 3074 if (focusCtrl) { 3075 focusCtrl.focus(); 3076 } 3077 return self; 3078 }, 3079 replace: function (oldItem, newItem) { 3080 var ctrlElm; 3081 var items = this.items(); 3082 var i = items.length; 3083 while (i--) { 3084 if (items[i] === oldItem) { 3085 items[i] = newItem; 3086 break; 3087 } 3088 } 3089 if (i >= 0) { 3090 ctrlElm = newItem.getEl(); 3091 if (ctrlElm) { 3092 ctrlElm.parentNode.removeChild(ctrlElm); 3093 } 3094 ctrlElm = oldItem.getEl(); 3095 if (ctrlElm) { 3096 ctrlElm.parentNode.removeChild(ctrlElm); 3097 } 3098 } 3099 newItem.parent(this); 3100 }, 3101 create: function (items) { 3102 var self = this; 3103 var settings; 3104 var ctrlItems = []; 3105 if (!global$4.isArray(items)) { 3106 items = [items]; 3107 } 3108 global$4.each(items, function (item) { 3109 if (item) { 3110 if (!(item instanceof Control$1)) { 3111 if (typeof item === 'string') { 3112 item = { type: item }; 3113 } 3114 settings = global$4.extend({}, self.settings.defaults, item); 3115 item.type = settings.type = settings.type || item.type || self.settings.defaultType || (settings.defaults ? settings.defaults.type : null); 3116 item = global$b.create(settings); 3117 } 3118 ctrlItems.push(item); 3119 } 3120 }); 3121 return ctrlItems; 3122 }, 3123 renderNew: function () { 3124 var self = this; 3125 self.items().each(function (ctrl, index) { 3126 var containerElm; 3127 ctrl.parent(self); 3128 if (!ctrl.state.get('rendered')) { 3129 containerElm = self.getEl('body'); 3130 if (containerElm.hasChildNodes() && index <= containerElm.childNodes.length - 1) { 3131 global$7(containerElm.childNodes[index]).before(ctrl.renderHtml()); 3132 } else { 3133 global$7(containerElm).append(ctrl.renderHtml()); 3134 } 3135 ctrl.postRender(); 3136 ReflowQueue.add(ctrl); 3137 } 3138 }); 3139 self._layout.applyClasses(self.items().filter(':visible')); 3140 self._lastRect = null; 3141 return self; 3142 }, 3143 append: function (items) { 3144 return this.add(items).renderNew(); 3145 }, 3146 prepend: function (items) { 3147 var self = this; 3148 self.items().set(self.create(items).concat(self.items().toArray())); 3149 return self.renderNew(); 3150 }, 3151 insert: function (items, index, before) { 3152 var self = this; 3153 var curItems, beforeItems, afterItems; 3154 items = self.create(items); 3155 curItems = self.items(); 3156 if (!before && index < curItems.length - 1) { 3157 index += 1; 3158 } 3159 if (index >= 0 && index < curItems.length) { 3160 beforeItems = curItems.slice(0, index).toArray(); 3161 afterItems = curItems.slice(index).toArray(); 3162 curItems.set(beforeItems.concat(items, afterItems)); 3163 } 3164 return self.renderNew(); 3165 }, 3166 fromJSON: function (data) { 3167 var self = this; 3168 for (var name in data) { 3169 self.find('#' + name).value(data[name]); 3170 } 3171 return self; 3172 }, 3173 toJSON: function () { 3174 var self = this, data = {}; 3175 self.find('*').each(function (ctrl) { 3176 var name = ctrl.name(), value = ctrl.value(); 3177 if (name && typeof value !== 'undefined') { 3178 data[name] = value; 3179 } 3180 }); 3181 return data; 3182 }, 3183 renderHtml: function () { 3184 var self = this, layout = self._layout, role = this.settings.role; 3185 self.preRender(); 3186 layout.preRender(self); 3187 return '<div id="' + self._id + '" class="' + self.classes + '"' + (role ? ' role="' + this.settings.role + '"' : '') + '>' + '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + (self.settings.html || '') + layout.renderHtml(self) + '</div>' + '</div>'; 3188 }, 3189 postRender: function () { 3190 var self = this; 3191 var box; 3192 self.items().exec('postRender'); 3193 self._super(); 3194 self._layout.postRender(self); 3195 self.state.set('rendered', true); 3196 if (self.settings.style) { 3197 self.$el.css(self.settings.style); 3198 } 3199 if (self.settings.border) { 3200 box = self.borderBox; 3201 self.$el.css({ 3202 'border-top-width': box.top, 3203 'border-right-width': box.right, 3204 'border-bottom-width': box.bottom, 3205 'border-left-width': box.left 3206 }); 3207 } 3208 if (!self.parent()) { 3209 self.keyboardNav = KeyboardNavigation({ root: self }); 3210 } 3211 return self; 3212 }, 3213 initLayoutRect: function () { 3214 var self = this, layoutRect = self._super(); 3215 self._layout.recalc(self); 3216 return layoutRect; 3217 }, 3218 recalc: function () { 3219 var self = this; 3220 var rect = self._layoutRect; 3221 var lastRect = self._lastRect; 3222 if (!lastRect || lastRect.w !== rect.w || lastRect.h !== rect.h) { 3223 self._layout.recalc(self); 3224 rect = self.layoutRect(); 3225 self._lastRect = { 3226 x: rect.x, 3227 y: rect.y, 3228 w: rect.w, 3229 h: rect.h 3230 }; 3231 return true; 3232 } 3233 }, 3234 reflow: function () { 3235 var i; 3236 ReflowQueue.remove(this); 3237 if (this.visible()) { 3238 Control$1.repaintControls = []; 3239 Control$1.repaintControls.map = {}; 3240 this.recalc(); 3241 i = Control$1.repaintControls.length; 3242 while (i--) { 3243 Control$1.repaintControls[i].repaint(); 3244 } 3245 if (this.settings.layout !== 'flow' && this.settings.layout !== 'stack') { 3246 this.repaint(); 3247 } 3248 Control$1.repaintControls = []; 3249 } 3250 return this; 3251 } 3252 }); 3253 3254 var Scrollable = { 3255 init: function () { 3256 var self = this; 3257 self.on('repaint', self.renderScroll); 3258 }, 3259 renderScroll: function () { 3260 var self = this, margin = 2; 3261 function repaintScroll() { 3262 var hasScrollH, hasScrollV, bodyElm; 3263 function repaintAxis(axisName, posName, sizeName, contentSizeName, hasScroll, ax) { 3264 var containerElm, scrollBarElm, scrollThumbElm; 3265 var containerSize, scrollSize, ratio, rect; 3266 var posNameLower, sizeNameLower; 3267 scrollBarElm = self.getEl('scroll' + axisName); 3268 if (scrollBarElm) { 3269 posNameLower = posName.toLowerCase(); 3270 sizeNameLower = sizeName.toLowerCase(); 3271 global$7(self.getEl('absend')).css(posNameLower, self.layoutRect()[contentSizeName] - 1); 3272 if (!hasScroll) { 3273 global$7(scrollBarElm).css('display', 'none'); 3274 return; 3275 } 3276 global$7(scrollBarElm).css('display', 'block'); 3277 containerElm = self.getEl('body'); 3278 scrollThumbElm = self.getEl('scroll' + axisName + 't'); 3279 containerSize = containerElm['client' + sizeName] - margin * 2; 3280 containerSize -= hasScrollH && hasScrollV ? scrollBarElm['client' + ax] : 0; 3281 scrollSize = containerElm['scroll' + sizeName]; 3282 ratio = containerSize / scrollSize; 3283 rect = {}; 3284 rect[posNameLower] = containerElm['offset' + posName] + margin; 3285 rect[sizeNameLower] = containerSize; 3286 global$7(scrollBarElm).css(rect); 3287 rect = {}; 3288 rect[posNameLower] = containerElm['scroll' + posName] * ratio; 3289 rect[sizeNameLower] = containerSize * ratio; 3290 global$7(scrollThumbElm).css(rect); 3291 } 3292 } 3293 bodyElm = self.getEl('body'); 3294 hasScrollH = bodyElm.scrollWidth > bodyElm.clientWidth; 3295 hasScrollV = bodyElm.scrollHeight > bodyElm.clientHeight; 3296 repaintAxis('h', 'Left', 'Width', 'contentW', hasScrollH, 'Height'); 3297 repaintAxis('v', 'Top', 'Height', 'contentH', hasScrollV, 'Width'); 3298 } 3299 function addScroll() { 3300 function addScrollAxis(axisName, posName, sizeName, deltaPosName, ax) { 3301 var scrollStart; 3302 var axisId = self._id + '-scroll' + axisName, prefix = self.classPrefix; 3303 global$7(self.getEl()).append('<div id="' + axisId + '" class="' + prefix + 'scrollbar ' + prefix + 'scrollbar-' + axisName + '">' + '<div id="' + axisId + 't" class="' + prefix + 'scrollbar-thumb"></div>' + '</div>'); 3304 self.draghelper = new DragHelper(axisId + 't', { 3305 start: function () { 3306 scrollStart = self.getEl('body')['scroll' + posName]; 3307 global$7('#' + axisId).addClass(prefix + 'active'); 3308 }, 3309 drag: function (e) { 3310 var ratio, hasScrollH, hasScrollV, containerSize; 3311 var layoutRect = self.layoutRect(); 3312 hasScrollH = layoutRect.contentW > layoutRect.innerW; 3313 hasScrollV = layoutRect.contentH > layoutRect.innerH; 3314 containerSize = self.getEl('body')['client' + sizeName] - margin * 2; 3315 containerSize -= hasScrollH && hasScrollV ? self.getEl('scroll' + axisName)['client' + ax] : 0; 3316 ratio = containerSize / self.getEl('body')['scroll' + sizeName]; 3317 self.getEl('body')['scroll' + posName] = scrollStart + e['delta' + deltaPosName] / ratio; 3318 }, 3319 stop: function () { 3320 global$7('#' + axisId).removeClass(prefix + 'active'); 3321 } 3322 }); 3323 } 3324 self.classes.add('scroll'); 3325 addScrollAxis('v', 'Top', 'Height', 'Y', 'Width'); 3326 addScrollAxis('h', 'Left', 'Width', 'X', 'Height'); 3327 } 3328 if (self.settings.autoScroll) { 3329 if (!self._hasScroll) { 3330 self._hasScroll = true; 3331 addScroll(); 3332 self.on('wheel', function (e) { 3333 var bodyEl = self.getEl('body'); 3334 bodyEl.scrollLeft += (e.deltaX || 0) * 10; 3335 bodyEl.scrollTop += e.deltaY * 10; 3336 repaintScroll(); 3337 }); 3338 global$7(self.getEl('body')).on('scroll', repaintScroll); 3339 } 3340 repaintScroll(); 3341 } 3342 } 3343 }; 3344 3345 var Panel = Container.extend({ 3346 Defaults: { 3347 layout: 'fit', 3348 containerCls: 'panel' 3349 }, 3350 Mixins: [Scrollable], 3351 renderHtml: function () { 3352 var self = this; 3353 var layout = self._layout; 3354 var innerHtml = self.settings.html; 3355 self.preRender(); 3356 layout.preRender(self); 3357 if (typeof innerHtml === 'undefined') { 3358 innerHtml = '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + layout.renderHtml(self) + '</div>'; 3359 } else { 3360 if (typeof innerHtml === 'function') { 3361 innerHtml = innerHtml.call(self); 3362 } 3363 self._hasBody = false; 3364 } 3365 return '<div id="' + self._id + '" class="' + self.classes + '" hidefocus="1" tabindex="-1" role="group">' + (self._preBodyHtml || '') + innerHtml + '</div>'; 3366 } 3367 }); 3368 3369 var Resizable = { 3370 resizeToContent: function () { 3371 this._layoutRect.autoResize = true; 3372 this._lastRect = null; 3373 this.reflow(); 3374 }, 3375 resizeTo: function (w, h) { 3376 if (w <= 1 || h <= 1) { 3377 var rect = funcs.getWindowSize(); 3378 w = w <= 1 ? w * rect.w : w; 3379 h = h <= 1 ? h * rect.h : h; 3380 } 3381 this._layoutRect.autoResize = false; 3382 return this.layoutRect({ 3383 minW: w, 3384 minH: h, 3385 w: w, 3386 h: h 3387 }).reflow(); 3388 }, 3389 resizeBy: function (dw, dh) { 3390 var self = this, rect = self.layoutRect(); 3391 return self.resizeTo(rect.w + dw, rect.h + dh); 3392 } 3393 }; 3394 3395 var documentClickHandler, documentScrollHandler, windowResizeHandler; 3396 var visiblePanels = []; 3397 var zOrder = []; 3398 var hasModal; 3399 function isChildOf(ctrl, parent) { 3400 while (ctrl) { 3401 if (ctrl === parent) { 3402 return true; 3403 } 3404 ctrl = ctrl.parent(); 3405 } 3406 } 3407 function skipOrHidePanels(e) { 3408 var i = visiblePanels.length; 3409 while (i--) { 3410 var panel = visiblePanels[i], clickCtrl = panel.getParentCtrl(e.target); 3411 if (panel.settings.autohide) { 3412 if (clickCtrl) { 3413 if (isChildOf(clickCtrl, panel) || panel.parent() === clickCtrl) { 3414 continue; 3415 } 3416 } 3417 e = panel.fire('autohide', { target: e.target }); 3418 if (!e.isDefaultPrevented()) { 3419 panel.hide(); 3420 } 3421 } 3422 } 3423 } 3424 function bindDocumentClickHandler() { 3425 if (!documentClickHandler) { 3426 documentClickHandler = function (e) { 3427 if (e.button === 2) { 3428 return; 3429 } 3430 skipOrHidePanels(e); 3431 }; 3432 global$7(domGlobals.document).on('click touchstart', documentClickHandler); 3433 } 3434 } 3435 function bindDocumentScrollHandler() { 3436 if (!documentScrollHandler) { 3437 documentScrollHandler = function () { 3438 var i; 3439 i = visiblePanels.length; 3440 while (i--) { 3441 repositionPanel$1(visiblePanels[i]); 3442 } 3443 }; 3444 global$7(domGlobals.window).on('scroll', documentScrollHandler); 3445 } 3446 } 3447 function bindWindowResizeHandler() { 3448 if (!windowResizeHandler) { 3449 var docElm_1 = domGlobals.document.documentElement; 3450 var clientWidth_1 = docElm_1.clientWidth, clientHeight_1 = docElm_1.clientHeight; 3451 windowResizeHandler = function () { 3452 if (!domGlobals.document.all || clientWidth_1 !== docElm_1.clientWidth || clientHeight_1 !== docElm_1.clientHeight) { 3453 clientWidth_1 = docElm_1.clientWidth; 3454 clientHeight_1 = docElm_1.clientHeight; 3455 FloatPanel.hideAll(); 3456 } 3457 }; 3458 global$7(domGlobals.window).on('resize', windowResizeHandler); 3459 } 3460 } 3461 function repositionPanel$1(panel) { 3462 var scrollY = funcs.getViewPort().y; 3463 function toggleFixedChildPanels(fixed, deltaY) { 3464 var parent; 3465 for (var i = 0; i < visiblePanels.length; i++) { 3466 if (visiblePanels[i] !== panel) { 3467 parent = visiblePanels[i].parent(); 3468 while (parent && (parent = parent.parent())) { 3469 if (parent === panel) { 3470 visiblePanels[i].fixed(fixed).moveBy(0, deltaY).repaint(); 3471 } 3472 } 3473 } 3474 } 3475 } 3476 if (panel.settings.autofix) { 3477 if (!panel.state.get('fixed')) { 3478 panel._autoFixY = panel.layoutRect().y; 3479 if (panel._autoFixY < scrollY) { 3480 panel.fixed(true).layoutRect({ y: 0 }).repaint(); 3481 toggleFixedChildPanels(true, scrollY - panel._autoFixY); 3482 } 3483 } else { 3484 if (panel._autoFixY > scrollY) { 3485 panel.fixed(false).layoutRect({ y: panel._autoFixY }).repaint(); 3486 toggleFixedChildPanels(false, panel._autoFixY - scrollY); 3487 } 3488 } 3489 } 3490 } 3491 function addRemove(add, ctrl) { 3492 var i, zIndex = FloatPanel.zIndex || 65535, topModal; 3493 if (add) { 3494 zOrder.push(ctrl); 3495 } else { 3496 i = zOrder.length; 3497 while (i--) { 3498 if (zOrder[i] === ctrl) { 3499 zOrder.splice(i, 1); 3500 } 3501 } 3502 } 3503 if (zOrder.length) { 3504 for (i = 0; i < zOrder.length; i++) { 3505 if (zOrder[i].modal) { 3506 zIndex++; 3507 topModal = zOrder[i]; 3508 } 3509 zOrder[i].getEl().style.zIndex = zIndex; 3510 zOrder[i].zIndex = zIndex; 3511 zIndex++; 3512 } 3513 } 3514 var modalBlockEl = global$7('#' + ctrl.classPrefix + 'modal-block', ctrl.getContainerElm())[0]; 3515 if (topModal) { 3516 global$7(modalBlockEl).css('z-index', topModal.zIndex - 1); 3517 } else if (modalBlockEl) { 3518 modalBlockEl.parentNode.removeChild(modalBlockEl); 3519 hasModal = false; 3520 } 3521 FloatPanel.currentZIndex = zIndex; 3522 } 3523 var FloatPanel = Panel.extend({ 3524 Mixins: [ 3525 Movable, 3526 Resizable 3527 ], 3528 init: function (settings) { 3529 var self = this; 3530 self._super(settings); 3531 self._eventsRoot = self; 3532 self.classes.add('floatpanel'); 3533 if (settings.autohide) { 3534 bindDocumentClickHandler(); 3535 bindWindowResizeHandler(); 3536 visiblePanels.push(self); 3537 } 3538 if (settings.autofix) { 3539 bindDocumentScrollHandler(); 3540 self.on('move', function () { 3541 repositionPanel$1(this); 3542 }); 3543 } 3544 self.on('postrender show', function (e) { 3545 if (e.control === self) { 3546 var $modalBlockEl_1; 3547 var prefix_1 = self.classPrefix; 3548 if (self.modal && !hasModal) { 3549 $modalBlockEl_1 = global$7('#' + prefix_1 + 'modal-block', self.getContainerElm()); 3550 if (!$modalBlockEl_1[0]) { 3551 $modalBlockEl_1 = global$7('<div id="' + prefix_1 + 'modal-block" class="' + prefix_1 + 'reset ' + prefix_1 + 'fade"></div>').appendTo(self.getContainerElm()); 3552 } 3553 global$3.setTimeout(function () { 3554 $modalBlockEl_1.addClass(prefix_1 + 'in'); 3555 global$7(self.getEl()).addClass(prefix_1 + 'in'); 3556 }); 3557 hasModal = true; 3558 } 3559 addRemove(true, self); 3560 } 3561 }); 3562 self.on('show', function () { 3563 self.parents().each(function (ctrl) { 3564 if (ctrl.state.get('fixed')) { 3565 self.fixed(true); 3566 return false; 3567 } 3568 }); 3569 }); 3570 if (settings.popover) { 3571 self._preBodyHtml = '<div class="' + self.classPrefix + 'arrow"></div>'; 3572 self.classes.add('popover').add('bottom').add(self.isRtl() ? 'end' : 'start'); 3573 } 3574 self.aria('label', settings.ariaLabel); 3575 self.aria('labelledby', self._id); 3576 self.aria('describedby', self.describedBy || self._id + '-none'); 3577 }, 3578 fixed: function (state) { 3579 var self = this; 3580 if (self.state.get('fixed') !== state) { 3581 if (self.state.get('rendered')) { 3582 var viewport = funcs.getViewPort(); 3583 if (state) { 3584 self.layoutRect().y -= viewport.y; 3585 } else { 3586 self.layoutRect().y += viewport.y; 3587 } 3588 } 3589 self.classes.toggle('fixed', state); 3590 self.state.set('fixed', state); 3591 } 3592 return self; 3593 }, 3594 show: function () { 3595 var self = this; 3596 var i; 3597 var state = self._super(); 3598 i = visiblePanels.length; 3599 while (i--) { 3600 if (visiblePanels[i] === self) { 3601 break; 3602 } 3603 } 3604 if (i === -1) { 3605 visiblePanels.push(self); 3606 } 3607 return state; 3608 }, 3609 hide: function () { 3610 removeVisiblePanel(this); 3611 addRemove(false, this); 3612 return this._super(); 3613 }, 3614 hideAll: function () { 3615 FloatPanel.hideAll(); 3616 }, 3617 close: function () { 3618 var self = this; 3619 if (!self.fire('close').isDefaultPrevented()) { 3620 self.remove(); 3621 addRemove(false, self); 3622 } 3623 return self; 3624 }, 3625 remove: function () { 3626 removeVisiblePanel(this); 3627 this._super(); 3628 }, 3629 postRender: function () { 3630 var self = this; 3631 if (self.settings.bodyRole) { 3632 this.getEl('body').setAttribute('role', self.settings.bodyRole); 3633 } 3634 return self._super(); 3635 } 3636 }); 3637 FloatPanel.hideAll = function () { 3638 var i = visiblePanels.length; 3639 while (i--) { 3640 var panel = visiblePanels[i]; 3641 if (panel && panel.settings.autohide) { 3642 panel.hide(); 3643 visiblePanels.splice(i, 1); 3644 } 3645 } 3646 }; 3647 function removeVisiblePanel(panel) { 3648 var i; 3649 i = visiblePanels.length; 3650 while (i--) { 3651 if (visiblePanels[i] === panel) { 3652 visiblePanels.splice(i, 1); 3653 } 3654 } 3655 i = zOrder.length; 3656 while (i--) { 3657 if (zOrder[i] === panel) { 3658 zOrder.splice(i, 1); 3659 } 3660 } 3661 } 3662 3663 var windows = []; 3664 var oldMetaValue = ''; 3665 function toggleFullScreenState(state) { 3666 var noScaleMetaValue = 'width=device-width,initial-scale=1.0,user-scalable=0,minimum-scale=1.0,maximum-scale=1.0'; 3667 var viewport = global$7('meta[name=viewport]')[0], contentValue; 3668 if (global$1.overrideViewPort === false) { 3669 return; 3670 } 3671 if (!viewport) { 3672 viewport = domGlobals.document.createElement('meta'); 3673 viewport.setAttribute('name', 'viewport'); 3674 domGlobals.document.getElementsByTagName('head')[0].appendChild(viewport); 3675 } 3676 contentValue = viewport.getAttribute('content'); 3677 if (contentValue && typeof oldMetaValue !== 'undefined') { 3678 oldMetaValue = contentValue; 3679 } 3680 viewport.setAttribute('content', state ? noScaleMetaValue : oldMetaValue); 3681 } 3682 function toggleBodyFullScreenClasses(classPrefix, state) { 3683 if (checkFullscreenWindows() && state === false) { 3684 global$7([ 3685 domGlobals.document.documentElement, 3686 domGlobals.document.body 3687 ]).removeClass(classPrefix + 'fullscreen'); 3688 } 3689 } 3690 function checkFullscreenWindows() { 3691 for (var i = 0; i < windows.length; i++) { 3692 if (windows[i]._fullscreen) { 3693 return true; 3694 } 3695 } 3696 return false; 3697 } 3698 function handleWindowResize() { 3699 if (!global$1.desktop) { 3700 var lastSize_1 = { 3701 w: domGlobals.window.innerWidth, 3702 h: domGlobals.window.innerHeight 3703 }; 3704 global$3.setInterval(function () { 3705 var w = domGlobals.window.innerWidth, h = domGlobals.window.innerHeight; 3706 if (lastSize_1.w !== w || lastSize_1.h !== h) { 3707 lastSize_1 = { 3708 w: w, 3709 h: h 3710 }; 3711 global$7(domGlobals.window).trigger('resize'); 3712 } 3713 }, 100); 3714 } 3715 function reposition() { 3716 var i; 3717 var rect = funcs.getWindowSize(); 3718 var layoutRect; 3719 for (i = 0; i < windows.length; i++) { 3720 layoutRect = windows[i].layoutRect(); 3721 windows[i].moveTo(windows[i].settings.x || Math.max(0, rect.w / 2 - layoutRect.w / 2), windows[i].settings.y || Math.max(0, rect.h / 2 - layoutRect.h / 2)); 3722 } 3723 } 3724 global$7(domGlobals.window).on('resize', reposition); 3725 } 3726 var Window = FloatPanel.extend({ 3727 modal: true, 3728 Defaults: { 3729 border: 1, 3730 layout: 'flex', 3731 containerCls: 'panel', 3732 role: 'dialog', 3733 callbacks: { 3734 submit: function () { 3735 this.fire('submit', { data: this.toJSON() }); 3736 }, 3737 close: function () { 3738 this.close(); 3739 } 3740 } 3741 }, 3742 init: function (settings) { 3743 var self = this; 3744 self._super(settings); 3745 if (self.isRtl()) { 3746 self.classes.add('rtl'); 3747 } 3748 self.classes.add('window'); 3749 self.bodyClasses.add('window-body'); 3750 self.state.set('fixed', true); 3751 if (settings.buttons) { 3752 self.statusbar = new Panel({ 3753 layout: 'flex', 3754 border: '1 0 0 0', 3755 spacing: 3, 3756 padding: 10, 3757 align: 'center', 3758 pack: self.isRtl() ? 'start' : 'end', 3759 defaults: { type: 'button' }, 3760 items: settings.buttons 3761 }); 3762 self.statusbar.classes.add('foot'); 3763 self.statusbar.parent(self); 3764 } 3765 self.on('click', function (e) { 3766 var closeClass = self.classPrefix + 'close'; 3767 if (funcs.hasClass(e.target, closeClass) || funcs.hasClass(e.target.parentNode, closeClass)) { 3768 self.close(); 3769 } 3770 }); 3771 self.on('cancel', function () { 3772 self.close(); 3773 }); 3774 self.on('move', function (e) { 3775 if (e.control === self) { 3776 FloatPanel.hideAll(); 3777 } 3778 }); 3779 self.aria('describedby', self.describedBy || self._id + '-none'); 3780 self.aria('label', settings.title); 3781 self._fullscreen = false; 3782 }, 3783 recalc: function () { 3784 var self = this; 3785 var statusbar = self.statusbar; 3786 var layoutRect, width, x, needsRecalc; 3787 if (self._fullscreen) { 3788 self.layoutRect(funcs.getWindowSize()); 3789 self.layoutRect().contentH = self.layoutRect().innerH; 3790 } 3791 self._super(); 3792 layoutRect = self.layoutRect(); 3793 if (self.settings.title && !self._fullscreen) { 3794 width = layoutRect.headerW; 3795 if (width > layoutRect.w) { 3796 x = layoutRect.x - Math.max(0, width / 2); 3797 self.layoutRect({ 3798 w: width, 3799 x: x 3800 }); 3801 needsRecalc = true; 3802 } 3803 } 3804 if (statusbar) { 3805 statusbar.layoutRect({ w: self.layoutRect().innerW }).recalc(); 3806 width = statusbar.layoutRect().minW + layoutRect.deltaW; 3807 if (width > layoutRect.w) { 3808 x = layoutRect.x - Math.max(0, width - layoutRect.w); 3809 self.layoutRect({ 3810 w: width, 3811 x: x 3812 }); 3813 needsRecalc = true; 3814 } 3815 } 3816 if (needsRecalc) { 3817 self.recalc(); 3818 } 3819 }, 3820 initLayoutRect: function () { 3821 var self = this; 3822 var layoutRect = self._super(); 3823 var deltaH = 0, headEl; 3824 if (self.settings.title && !self._fullscreen) { 3825 headEl = self.getEl('head'); 3826 var size = funcs.getSize(headEl); 3827 layoutRect.headerW = size.width; 3828 layoutRect.headerH = size.height; 3829 deltaH += layoutRect.headerH; 3830 } 3831 if (self.statusbar) { 3832 deltaH += self.statusbar.layoutRect().h; 3833 } 3834 layoutRect.deltaH += deltaH; 3835 layoutRect.minH += deltaH; 3836 layoutRect.h += deltaH; 3837 var rect = funcs.getWindowSize(); 3838 layoutRect.x = self.settings.x || Math.max(0, rect.w / 2 - layoutRect.w / 2); 3839 layoutRect.y = self.settings.y || Math.max(0, rect.h / 2 - layoutRect.h / 2); 3840 return layoutRect; 3841 }, 3842 renderHtml: function () { 3843 var self = this, layout = self._layout, id = self._id, prefix = self.classPrefix; 3844 var settings = self.settings; 3845 var headerHtml = '', footerHtml = '', html = settings.html; 3846 self.preRender(); 3847 layout.preRender(self); 3848 if (settings.title) { 3849 headerHtml = '<div id="' + id + '-head" class="' + prefix + 'window-head">' + '<div id="' + id + '-title" class="' + prefix + 'title">' + self.encode(settings.title) + '</div>' + '<div id="' + id + '-dragh" class="' + prefix + 'dragh"></div>' + '<button type="button" class="' + prefix + 'close" aria-hidden="true">' + '<i class="mce-ico mce-i-remove"></i>' + '</button>' + '</div>'; 3850 } 3851 if (settings.url) { 3852 html = '<iframe src="' + settings.url + '" tabindex="-1"></iframe>'; 3853 } 3854 if (typeof html === 'undefined') { 3855 html = layout.renderHtml(self); 3856 } 3857 if (self.statusbar) { 3858 footerHtml = self.statusbar.renderHtml(); 3859 } 3860 return '<div id="' + id + '" class="' + self.classes + '" hidefocus="1">' + '<div class="' + self.classPrefix + 'reset" role="application">' + headerHtml + '<div id="' + id + '-body" class="' + self.bodyClasses + '">' + html + '</div>' + footerHtml + '</div>' + '</div>'; 3861 }, 3862 fullscreen: function (state) { 3863 var self = this; 3864 var documentElement = domGlobals.document.documentElement; 3865 var slowRendering; 3866 var prefix = self.classPrefix; 3867 var layoutRect; 3868 if (state !== self._fullscreen) { 3869 global$7(domGlobals.window).on('resize', function () { 3870 var time; 3871 if (self._fullscreen) { 3872 if (!slowRendering) { 3873 time = new Date().getTime(); 3874 var rect = funcs.getWindowSize(); 3875 self.moveTo(0, 0).resizeTo(rect.w, rect.h); 3876 if (new Date().getTime() - time > 50) { 3877 slowRendering = true; 3878 } 3879 } else { 3880 if (!self._timer) { 3881 self._timer = global$3.setTimeout(function () { 3882 var rect = funcs.getWindowSize(); 3883 self.moveTo(0, 0).resizeTo(rect.w, rect.h); 3884 self._timer = 0; 3885 }, 50); 3886 } 3887 } 3888 } 3889 }); 3890 layoutRect = self.layoutRect(); 3891 self._fullscreen = state; 3892 if (!state) { 3893 self.borderBox = BoxUtils.parseBox(self.settings.border); 3894 self.getEl('head').style.display = ''; 3895 layoutRect.deltaH += layoutRect.headerH; 3896 global$7([ 3897 documentElement, 3898 domGlobals.document.body 3899 ]).removeClass(prefix + 'fullscreen'); 3900 self.classes.remove('fullscreen'); 3901 self.moveTo(self._initial.x, self._initial.y).resizeTo(self._initial.w, self._initial.h); 3902 } else { 3903 self._initial = { 3904 x: layoutRect.x, 3905 y: layoutRect.y, 3906 w: layoutRect.w, 3907 h: layoutRect.h 3908 }; 3909 self.borderBox = BoxUtils.parseBox('0'); 3910 self.getEl('head').style.display = 'none'; 3911 layoutRect.deltaH -= layoutRect.headerH + 2; 3912 global$7([ 3913 documentElement, 3914 domGlobals.document.body 3915 ]).addClass(prefix + 'fullscreen'); 3916 self.classes.add('fullscreen'); 3917 var rect = funcs.getWindowSize(); 3918 self.moveTo(0, 0).resizeTo(rect.w, rect.h); 3919 } 3920 } 3921 return self.reflow(); 3922 }, 3923 postRender: function () { 3924 var self = this; 3925 var startPos; 3926 setTimeout(function () { 3927 self.classes.add('in'); 3928 self.fire('open'); 3929 }, 0); 3930 self._super(); 3931 if (self.statusbar) { 3932 self.statusbar.postRender(); 3933 } 3934 self.focus(); 3935 this.dragHelper = new DragHelper(self._id + '-dragh', { 3936 start: function () { 3937 startPos = { 3938 x: self.layoutRect().x, 3939 y: self.layoutRect().y 3940 }; 3941 }, 3942 drag: function (e) { 3943 self.moveTo(startPos.x + e.deltaX, startPos.y + e.deltaY); 3944 } 3945 }); 3946 self.on('submit', function (e) { 3947 if (!e.isDefaultPrevented()) { 3948 self.close(); 3949 } 3950 }); 3951 windows.push(self); 3952 toggleFullScreenState(true); 3953 }, 3954 submit: function () { 3955 return this.fire('submit', { data: this.toJSON() }); 3956 }, 3957 remove: function () { 3958 var self = this; 3959 var i; 3960 self.dragHelper.destroy(); 3961 self._super(); 3962 if (self.statusbar) { 3963 this.statusbar.remove(); 3964 } 3965 toggleBodyFullScreenClasses(self.classPrefix, false); 3966 i = windows.length; 3967 while (i--) { 3968 if (windows[i] === self) { 3969 windows.splice(i, 1); 3970 } 3971 } 3972 toggleFullScreenState(windows.length > 0); 3973 }, 3974 getContentWindow: function () { 3975 var ifr = this.getEl().getElementsByTagName('iframe')[0]; 3976 return ifr ? ifr.contentWindow : null; 3977 } 3978 }); 3979 handleWindowResize(); 3980 3981 var MessageBox = Window.extend({ 3982 init: function (settings) { 3983 settings = { 3984 border: 1, 3985 padding: 20, 3986 layout: 'flex', 3987 pack: 'center', 3988 align: 'center', 3989 containerCls: 'panel', 3990 autoScroll: true, 3991 buttons: { 3992 type: 'button', 3993 text: 'Ok', 3994 action: 'ok' 3995 }, 3996 items: { 3997 type: 'label', 3998 multiline: true, 3999 maxWidth: 500, 4000 maxHeight: 200 4001 } 4002 }; 4003 this._super(settings); 4004 }, 4005 Statics: { 4006 OK: 1, 4007 OK_CANCEL: 2, 4008 YES_NO: 3, 4009 YES_NO_CANCEL: 4, 4010 msgBox: function (settings) { 4011 var buttons; 4012 var callback = settings.callback || function () { 4013 }; 4014 function createButton(text, status, primary) { 4015 return { 4016 type: 'button', 4017 text: text, 4018 subtype: primary ? 'primary' : '', 4019 onClick: function (e) { 4020 e.control.parents()[1].close(); 4021 callback(status); 4022 } 4023 }; 4024 } 4025 switch (settings.buttons) { 4026 case MessageBox.OK_CANCEL: 4027 buttons = [ 4028 createButton('Ok', true, true), 4029 createButton('Cancel', false) 4030 ]; 4031 break; 4032 case MessageBox.YES_NO: 4033 case MessageBox.YES_NO_CANCEL: 4034 buttons = [ 4035 createButton('Yes', 1, true), 4036 createButton('No', 0) 4037 ]; 4038 if (settings.buttons === MessageBox.YES_NO_CANCEL) { 4039 buttons.push(createButton('Cancel', -1)); 4040 } 4041 break; 4042 default: 4043 buttons = [createButton('Ok', true, true)]; 4044 break; 4045 } 4046 return new Window({ 4047 padding: 20, 4048 x: settings.x, 4049 y: settings.y, 4050 minWidth: 300, 4051 minHeight: 100, 4052 layout: 'flex', 4053 pack: 'center', 4054 align: 'center', 4055 buttons: buttons, 4056 title: settings.title, 4057 role: 'alertdialog', 4058 items: { 4059 type: 'label', 4060 multiline: true, 4061 maxWidth: 500, 4062 maxHeight: 200, 4063 text: settings.text 4064 }, 4065 onPostRender: function () { 4066 this.aria('describedby', this.items()[0]._id); 4067 }, 4068 onClose: settings.onClose, 4069 onCancel: function () { 4070 callback(false); 4071 } 4072 }).renderTo(domGlobals.document.body).reflow(); 4073 }, 4074 alert: function (settings, callback) { 4075 if (typeof settings === 'string') { 4076 settings = { text: settings }; 4077 } 4078 settings.callback = callback; 4079 return MessageBox.msgBox(settings); 4080 }, 4081 confirm: function (settings, callback) { 4082 if (typeof settings === 'string') { 4083 settings = { text: settings }; 4084 } 4085 settings.callback = callback; 4086 settings.buttons = MessageBox.OK_CANCEL; 4087 return MessageBox.msgBox(settings); 4088 } 4089 } 4090 }); 4091 4092 function WindowManagerImpl (editor) { 4093 var open = function (args, params, closeCallback) { 4094 var win; 4095 args.title = args.title || ' '; 4096 args.url = args.url || args.file; 4097 if (args.url) { 4098 args.width = parseInt(args.width || 320, 10); 4099 args.height = parseInt(args.height || 240, 10); 4100 } 4101 if (args.body) { 4102 args.items = { 4103 defaults: args.defaults, 4104 type: args.bodyType || 'form', 4105 items: args.body, 4106 data: args.data, 4107 callbacks: args.commands 4108 }; 4109 } 4110 if (!args.url && !args.buttons) { 4111 args.buttons = [ 4112 { 4113 text: 'Ok', 4114 subtype: 'primary', 4115 onclick: function () { 4116 win.find('form')[0].submit(); 4117 } 4118 }, 4119 { 4120 text: 'Cancel', 4121 onclick: function () { 4122 win.close(); 4123 } 4124 } 4125 ]; 4126 } 4127 win = new Window(args); 4128 win.on('close', function () { 4129 closeCallback(win); 4130 }); 4131 if (args.data) { 4132 win.on('postRender', function () { 4133 this.find('*').each(function (ctrl) { 4134 var name = ctrl.name(); 4135 if (name in args.data) { 4136 ctrl.value(args.data[name]); 4137 } 4138 }); 4139 }); 4140 } 4141 win.features = args || {}; 4142 win.params = params || {}; 4143 win = win.renderTo(domGlobals.document.body).reflow(); 4144 return win; 4145 }; 4146 var alert = function (message, choiceCallback, closeCallback) { 4147 var win; 4148 win = MessageBox.alert(message, function () { 4149 choiceCallback(); 4150 }); 4151 win.on('close', function () { 4152 closeCallback(win); 4153 }); 4154 return win; 4155 }; 4156 var confirm = function (message, choiceCallback, closeCallback) { 4157 var win; 4158 win = MessageBox.confirm(message, function (state) { 4159 choiceCallback(state); 4160 }); 4161 win.on('close', function () { 4162 closeCallback(win); 4163 }); 4164 return win; 4165 }; 4166 var close = function (window) { 4167 window.close(); 4168 }; 4169 var getParams = function (window) { 4170 return window.params; 4171 }; 4172 var setParams = function (window, params) { 4173 window.params = params; 4174 }; 4175 return { 4176 open: open, 4177 alert: alert, 4178 confirm: confirm, 4179 close: close, 4180 getParams: getParams, 4181 setParams: setParams 4182 }; 4183 } 4184 4185 var get = function (editor, panel) { 4186 var renderUI = function () { 4187 return Render.renderUI(editor, panel); 4188 }; 4189 return { 4190 renderUI: renderUI, 4191 getNotificationManagerImpl: function () { 4192 return NotificationManagerImpl(editor); 4193 }, 4194 getWindowManagerImpl: function () { 4195 return WindowManagerImpl(); 4196 } 4197 }; 4198 }; 4199 var ThemeApi = { get: get }; 4200 4201 var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')(); 4202 4203 var path = function (parts, scope) { 4204 var o = scope !== undefined && scope !== null ? scope : Global; 4205 for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i) { 4206 o = o[parts[i]]; 4207 } 4208 return o; 4209 }; 4210 var resolve = function (p, scope) { 4211 var parts = p.split('.'); 4212 return path(parts, scope); 4213 }; 4214 4215 var unsafe = function (name, scope) { 4216 return resolve(name, scope); 4217 }; 4218 var getOrDie = function (name, scope) { 4219 var actual = unsafe(name, scope); 4220 if (actual === undefined || actual === null) { 4221 throw new Error(name + ' not available on this browser'); 4222 } 4223 return actual; 4224 }; 4225 var Global$1 = { getOrDie: getOrDie }; 4226 4227 function FileReader () { 4228 var f = Global$1.getOrDie('FileReader'); 4229 return new f(); 4230 } 4231 4232 var global$c = tinymce.util.Tools.resolve('tinymce.util.Promise'); 4233 4234 var blobToBase64 = function (blob) { 4235 return new global$c(function (resolve) { 4236 var reader = FileReader(); 4237 reader.onloadend = function () { 4238 resolve(reader.result.split(',')[1]); 4239 }; 4240 reader.readAsDataURL(blob); 4241 }); 4242 }; 4243 var Conversions = { blobToBase64: blobToBase64 }; 4244 4245 var pickFile = function () { 4246 return new global$c(function (resolve) { 4247 var fileInput; 4248 fileInput = domGlobals.document.createElement('input'); 4249 fileInput.type = 'file'; 4250 fileInput.style.position = 'fixed'; 4251 fileInput.style.left = 0; 4252 fileInput.style.top = 0; 4253 fileInput.style.opacity = 0.001; 4254 domGlobals.document.body.appendChild(fileInput); 4255 fileInput.onchange = function (e) { 4256 resolve(Array.prototype.slice.call(e.target.files)); 4257 }; 4258 fileInput.click(); 4259 fileInput.parentNode.removeChild(fileInput); 4260 }); 4261 }; 4262 var Picker = { pickFile: pickFile }; 4263 4264 var count$1 = 0; 4265 var seed = function () { 4266 var rnd = function () { 4267 return Math.round(Math.random() * 4294967295).toString(36); 4268 }; 4269 return 's' + Date.now().toString(36) + rnd() + rnd() + rnd(); 4270 }; 4271 var uuid = function (prefix) { 4272 return prefix + count$1++ + seed(); 4273 }; 4274 var Uuid = { uuid: uuid }; 4275 4276 var create$1 = function (dom, rng) { 4277 var bookmark = {}; 4278 function setupEndPoint(start) { 4279 var offsetNode, container, offset; 4280 container = rng[start ? 'startContainer' : 'endContainer']; 4281 offset = rng[start ? 'startOffset' : 'endOffset']; 4282 if (container.nodeType === 1) { 4283 offsetNode = dom.create('span', { 'data-mce-type': 'bookmark' }); 4284 if (container.hasChildNodes()) { 4285 offset = Math.min(offset, container.childNodes.length - 1); 4286 if (start) { 4287 container.insertBefore(offsetNode, container.childNodes[offset]); 4288 } else { 4289 dom.insertAfter(offsetNode, container.childNodes[offset]); 4290 } 4291 } else { 4292 container.appendChild(offsetNode); 4293 } 4294 container = offsetNode; 4295 offset = 0; 4296 } 4297 bookmark[start ? 'startContainer' : 'endContainer'] = container; 4298 bookmark[start ? 'startOffset' : 'endOffset'] = offset; 4299 } 4300 setupEndPoint(true); 4301 if (!rng.collapsed) { 4302 setupEndPoint(); 4303 } 4304 return bookmark; 4305 }; 4306 var resolve$1 = function (dom, bookmark) { 4307 function restoreEndPoint(start) { 4308 var container, offset, node; 4309 function nodeIndex(container) { 4310 var node = container.parentNode.firstChild, idx = 0; 4311 while (node) { 4312 if (node === container) { 4313 return idx; 4314 } 4315 if (node.nodeType !== 1 || node.getAttribute('data-mce-type') !== 'bookmark') { 4316 idx++; 4317 } 4318 node = node.nextSibling; 4319 } 4320 return -1; 4321 } 4322 container = node = bookmark[start ? 'startContainer' : 'endContainer']; 4323 offset = bookmark[start ? 'startOffset' : 'endOffset']; 4324 if (!container) { 4325 return; 4326 } 4327 if (container.nodeType === 1) { 4328 offset = nodeIndex(container); 4329 container = container.parentNode; 4330 dom.remove(node); 4331 } 4332 bookmark[start ? 'startContainer' : 'endContainer'] = container; 4333 bookmark[start ? 'startOffset' : 'endOffset'] = offset; 4334 } 4335 restoreEndPoint(true); 4336 restoreEndPoint(); 4337 var rng = dom.createRng(); 4338 rng.setStart(bookmark.startContainer, bookmark.startOffset); 4339 if (bookmark.endContainer) { 4340 rng.setEnd(bookmark.endContainer, bookmark.endOffset); 4341 } 4342 return rng; 4343 }; 4344 var Bookmark = { 4345 create: create$1, 4346 resolve: resolve$1 4347 }; 4348 4349 var global$d = tinymce.util.Tools.resolve('tinymce.dom.TreeWalker'); 4350 4351 var global$e = tinymce.util.Tools.resolve('tinymce.dom.RangeUtils'); 4352 4353 var getSelectedElements = function (rootElm, startNode, endNode) { 4354 var walker, node; 4355 var elms = []; 4356 walker = new global$d(startNode, rootElm); 4357 for (node = startNode; node; node = walker.next()) { 4358 if (node.nodeType === 1) { 4359 elms.push(node); 4360 } 4361 if (node === endNode) { 4362 break; 4363 } 4364 } 4365 return elms; 4366 }; 4367 var unwrapElements = function (editor, elms) { 4368 var bookmark, dom, selection; 4369 dom = editor.dom; 4370 selection = editor.selection; 4371 bookmark = Bookmark.create(dom, selection.getRng()); 4372 global$4.each(elms, function (elm) { 4373 editor.dom.remove(elm, true); 4374 }); 4375 selection.setRng(Bookmark.resolve(dom, bookmark)); 4376 }; 4377 var isLink = function (elm) { 4378 return elm.nodeName === 'A' && elm.hasAttribute('href'); 4379 }; 4380 var getParentAnchorOrSelf = function (dom, elm) { 4381 var anchorElm = dom.getParent(elm, isLink); 4382 return anchorElm ? anchorElm : elm; 4383 }; 4384 var getSelectedAnchors = function (editor) { 4385 var startElm, endElm, rootElm, anchorElms, selection, dom, rng; 4386 selection = editor.selection; 4387 dom = editor.dom; 4388 rng = selection.getRng(); 4389 startElm = getParentAnchorOrSelf(dom, global$e.getNode(rng.startContainer, rng.startOffset)); 4390 endElm = global$e.getNode(rng.endContainer, rng.endOffset); 4391 rootElm = editor.getBody(); 4392 anchorElms = global$4.grep(getSelectedElements(rootElm, startElm, endElm), isLink); 4393 return anchorElms; 4394 }; 4395 var unlinkSelection = function (editor) { 4396 unwrapElements(editor, getSelectedAnchors(editor)); 4397 }; 4398 var Unlink = { unlinkSelection: unlinkSelection }; 4399 4400 var createTableHtml = function (cols, rows) { 4401 var x, y, html; 4402 html = '<table data-mce-id="mce" style="width: 100%">'; 4403 html += '<tbody>'; 4404 for (y = 0; y < rows; y++) { 4405 html += '<tr>'; 4406 for (x = 0; x < cols; x++) { 4407 html += '<td><br></td>'; 4408 } 4409 html += '</tr>'; 4410 } 4411 html += '</tbody>'; 4412 html += '</table>'; 4413 return html; 4414 }; 4415 var getInsertedElement = function (editor) { 4416 var elms = editor.dom.select('*[data-mce-id]'); 4417 return elms[0]; 4418 }; 4419 var insertTableHtml = function (editor, cols, rows) { 4420 editor.undoManager.transact(function () { 4421 var tableElm, cellElm; 4422 editor.insertContent(createTableHtml(cols, rows)); 4423 tableElm = getInsertedElement(editor); 4424 tableElm.removeAttribute('data-mce-id'); 4425 cellElm = editor.dom.select('td,th', tableElm); 4426 editor.selection.setCursorLocation(cellElm[0], 0); 4427 }); 4428 }; 4429 var insertTable = function (editor, cols, rows) { 4430 editor.plugins.table ? editor.plugins.table.insertTable(cols, rows) : insertTableHtml(editor, cols, rows); 4431 }; 4432 var formatBlock = function (editor, formatName) { 4433 editor.execCommand('FormatBlock', false, formatName); 4434 }; 4435 var insertBlob = function (editor, base64, blob) { 4436 var blobCache, blobInfo; 4437 blobCache = editor.editorUpload.blobCache; 4438 blobInfo = blobCache.create(Uuid.uuid('mceu'), blob, base64); 4439 blobCache.add(blobInfo); 4440 editor.insertContent(editor.dom.createHTML('img', { src: blobInfo.blobUri() })); 4441 }; 4442 var collapseSelectionToEnd = function (editor) { 4443 editor.selection.collapse(false); 4444 }; 4445 var unlink = function (editor) { 4446 editor.focus(); 4447 Unlink.unlinkSelection(editor); 4448 collapseSelectionToEnd(editor); 4449 }; 4450 var changeHref = function (editor, elm, url) { 4451 editor.focus(); 4452 editor.dom.setAttrib(elm, 'href', url); 4453 collapseSelectionToEnd(editor); 4454 }; 4455 var insertLink = function (editor, url) { 4456 editor.execCommand('mceInsertLink', false, { href: url }); 4457 collapseSelectionToEnd(editor); 4458 }; 4459 var updateOrInsertLink = function (editor, url) { 4460 var elm = editor.dom.getParent(editor.selection.getStart(), 'a[href]'); 4461 elm ? changeHref(editor, elm, url) : insertLink(editor, url); 4462 }; 4463 var createLink = function (editor, url) { 4464 url.trim().length === 0 ? unlink(editor) : updateOrInsertLink(editor, url); 4465 }; 4466 var Actions = { 4467 insertTable: insertTable, 4468 formatBlock: formatBlock, 4469 insertBlob: insertBlob, 4470 createLink: createLink, 4471 unlink: unlink 4472 }; 4473 4474 var addHeaderButtons = function (editor) { 4475 var formatBlock = function (name) { 4476 return function () { 4477 Actions.formatBlock(editor, name); 4478 }; 4479 }; 4480 for (var i = 1; i < 6; i++) { 4481 var name = 'h' + i; 4482 editor.addButton(name, { 4483 text: name.toUpperCase(), 4484 tooltip: 'Heading ' + i, 4485 stateSelector: name, 4486 onclick: formatBlock(name), 4487 onPostRender: function () { 4488 var span = this.getEl().firstChild.firstChild; 4489 span.style.fontWeight = 'bold'; 4490 } 4491 }); 4492 } 4493 }; 4494 var addToEditor = function (editor, panel) { 4495 editor.addButton('quicklink', { 4496 icon: 'link', 4497 tooltip: 'Insert/Edit link', 4498 stateSelector: 'a[href]', 4499 onclick: function () { 4500 panel.showForm(editor, 'quicklink'); 4501 } 4502 }); 4503 editor.addButton('quickimage', { 4504 icon: 'image', 4505 tooltip: 'Insert image', 4506 onclick: function () { 4507 Picker.pickFile().then(function (files) { 4508 var blob = files[0]; 4509 Conversions.blobToBase64(blob).then(function (base64) { 4510 Actions.insertBlob(editor, base64, blob); 4511 }); 4512 }); 4513 } 4514 }); 4515 editor.addButton('quicktable', { 4516 icon: 'table', 4517 tooltip: 'Insert table', 4518 onclick: function () { 4519 panel.hide(); 4520 Actions.insertTable(editor, 2, 2); 4521 } 4522 }); 4523 addHeaderButtons(editor); 4524 }; 4525 var Buttons = { addToEditor: addToEditor }; 4526 4527 var getUiContainerDelta$1 = function () { 4528 var uiContainer = global$1.container; 4529 if (uiContainer && global$2.DOM.getStyle(uiContainer, 'position', true) !== 'static') { 4530 var containerPos = global$2.DOM.getPos(uiContainer); 4531 var dx = containerPos.x - uiContainer.scrollLeft; 4532 var dy = containerPos.y - uiContainer.scrollTop; 4533 return Option.some({ 4534 x: dx, 4535 y: dy 4536 }); 4537 } else { 4538 return Option.none(); 4539 } 4540 }; 4541 var UiContainer$1 = { getUiContainerDelta: getUiContainerDelta$1 }; 4542 4543 var isDomainLike = function (href) { 4544 return /^www\.|\.(com|org|edu|gov|uk|net|ca|de|jp|fr|au|us|ru|ch|it|nl|se|no|es|mil)$/i.test(href.trim()); 4545 }; 4546 var isAbsolute = function (href) { 4547 return /^https?:\/\//.test(href.trim()); 4548 }; 4549 var UrlType = { 4550 isDomainLike: isDomainLike, 4551 isAbsolute: isAbsolute 4552 }; 4553 4554 var focusFirstTextBox = function (form) { 4555 form.find('textbox').eq(0).each(function (ctrl) { 4556 ctrl.focus(); 4557 }); 4558 }; 4559 var createForm = function (name, spec) { 4560 var form = global$b.create(global$4.extend({ 4561 type: 'form', 4562 layout: 'flex', 4563 direction: 'row', 4564 padding: 5, 4565 name: name, 4566 spacing: 3 4567 }, spec)); 4568 form.on('show', function () { 4569 focusFirstTextBox(form); 4570 }); 4571 return form; 4572 }; 4573 var toggleVisibility = function (ctrl, state) { 4574 return state ? ctrl.show() : ctrl.hide(); 4575 }; 4576 var askAboutPrefix = function (editor, href) { 4577 return new global$c(function (resolve) { 4578 editor.windowManager.confirm('The URL you entered seems to be an external link. Do you want to add the required http:// prefix?', function (result) { 4579 var output = result === true ? 'http://' + href : href; 4580 resolve(output); 4581 }); 4582 }); 4583 }; 4584 var convertLinkToAbsolute = function (editor, href) { 4585 return !UrlType.isAbsolute(href) && UrlType.isDomainLike(href) ? askAboutPrefix(editor, href) : global$c.resolve(href); 4586 }; 4587 var createQuickLinkForm = function (editor, hide) { 4588 var attachState = {}; 4589 var unlink = function () { 4590 editor.focus(); 4591 Actions.unlink(editor); 4592 hide(); 4593 }; 4594 var onChangeHandler = function (e) { 4595 var meta = e.meta; 4596 if (meta && meta.attach) { 4597 attachState = { 4598 href: this.value(), 4599 attach: meta.attach 4600 }; 4601 } 4602 }; 4603 var onShowHandler = function (e) { 4604 if (e.control === this) { 4605 var elm = void 0, linkurl = ''; 4606 elm = editor.dom.getParent(editor.selection.getStart(), 'a[href]'); 4607 if (elm) { 4608 linkurl = editor.dom.getAttrib(elm, 'href'); 4609 } 4610 this.fromJSON({ linkurl: linkurl }); 4611 toggleVisibility(this.find('#unlink'), elm); 4612 this.find('#linkurl')[0].focus(); 4613 } 4614 }; 4615 return createForm('quicklink', { 4616 items: [ 4617 { 4618 type: 'button', 4619 name: 'unlink', 4620 icon: 'unlink', 4621 onclick: unlink, 4622 tooltip: 'Remove link' 4623 }, 4624 { 4625 type: 'filepicker', 4626 name: 'linkurl', 4627 placeholder: 'Paste or type a link', 4628 filetype: 'file', 4629 onchange: onChangeHandler 4630 }, 4631 { 4632 type: 'button', 4633 icon: 'checkmark', 4634 subtype: 'primary', 4635 tooltip: 'Ok', 4636 onclick: 'submit' 4637 } 4638 ], 4639 onshow: onShowHandler, 4640 onsubmit: function (e) { 4641 convertLinkToAbsolute(editor, e.data.linkurl).then(function (url) { 4642 editor.undoManager.transact(function () { 4643 if (url === attachState.href) { 4644 attachState.attach(); 4645 attachState = {}; 4646 } 4647 Actions.createLink(editor, url); 4648 }); 4649 hide(); 4650 }); 4651 } 4652 }); 4653 }; 4654 var Forms = { createQuickLinkForm: createQuickLinkForm }; 4655 4656 var getSelectorStateResult = function (itemName, item) { 4657 var result = function (selector, handler) { 4658 return { 4659 selector: selector, 4660 handler: handler 4661 }; 4662 }; 4663 var activeHandler = function (state) { 4664 item.active(state); 4665 }; 4666 var disabledHandler = function (state) { 4667 item.disabled(state); 4668 }; 4669 if (item.settings.stateSelector) { 4670 return result(item.settings.stateSelector, activeHandler); 4671 } 4672 if (item.settings.disabledStateSelector) { 4673 return result(item.settings.disabledStateSelector, disabledHandler); 4674 } 4675 return null; 4676 }; 4677 var bindSelectorChanged = function (editor, itemName, item) { 4678 return function () { 4679 var result = getSelectorStateResult(itemName, item); 4680 if (result !== null) { 4681 editor.selection.selectorChanged(result.selector, result.handler); 4682 } 4683 }; 4684 }; 4685 var itemsToArray$1 = function (items) { 4686 if (Type.isArray(items)) { 4687 return items; 4688 } else if (Type.isString(items)) { 4689 return items.split(/[ ,]/); 4690 } 4691 return []; 4692 }; 4693 var create$2 = function (editor, name, items) { 4694 var toolbarItems = []; 4695 var buttonGroup; 4696 if (!items) { 4697 return; 4698 } 4699 global$4.each(itemsToArray$1(items), function (item) { 4700 if (item === '|') { 4701 buttonGroup = null; 4702 } else { 4703 if (editor.buttons[item]) { 4704 if (!buttonGroup) { 4705 buttonGroup = { 4706 type: 'buttongroup', 4707 items: [] 4708 }; 4709 toolbarItems.push(buttonGroup); 4710 } 4711 var button = editor.buttons[item]; 4712 if (Type.isFunction(button)) { 4713 button = button(); 4714 } 4715 button.type = button.type || 'button'; 4716 button = global$b.create(button); 4717 button.on('postRender', bindSelectorChanged(editor, item, button)); 4718 buttonGroup.items.push(button); 4719 } 4720 } 4721 }); 4722 return global$b.create({ 4723 type: 'toolbar', 4724 layout: 'flow', 4725 name: name, 4726 items: toolbarItems 4727 }); 4728 }; 4729 var Toolbar = { create: create$2 }; 4730 4731 var create$3 = function () { 4732 var panel, currentRect; 4733 var createToolbars = function (editor, toolbars) { 4734 return global$4.map(toolbars, function (toolbar) { 4735 return Toolbar.create(editor, toolbar.id, toolbar.items); 4736 }); 4737 }; 4738 var hasToolbarItems = function (toolbar) { 4739 return toolbar.items().length > 0; 4740 }; 4741 var create = function (editor, toolbars) { 4742 var items = createToolbars(editor, toolbars).concat([ 4743 Toolbar.create(editor, 'text', Settings.getTextSelectionToolbarItems(editor)), 4744 Toolbar.create(editor, 'insert', Settings.getInsertToolbarItems(editor)), 4745 Forms.createQuickLinkForm(editor, hide) 4746 ]); 4747 return global$b.create({ 4748 type: 'floatpanel', 4749 role: 'dialog', 4750 classes: 'tinymce tinymce-inline arrow', 4751 ariaLabel: 'Inline toolbar', 4752 layout: 'flex', 4753 direction: 'column', 4754 align: 'stretch', 4755 autohide: false, 4756 autofix: true, 4757 fixed: true, 4758 border: 1, 4759 items: global$4.grep(items, hasToolbarItems), 4760 oncancel: function () { 4761 editor.focus(); 4762 } 4763 }); 4764 }; 4765 var showPanel = function (panel) { 4766 if (panel) { 4767 panel.show(); 4768 } 4769 }; 4770 var movePanelTo = function (panel, pos) { 4771 panel.moveTo(pos.x, pos.y); 4772 }; 4773 var togglePositionClass = function (panel, relPos) { 4774 relPos = relPos ? relPos.substr(0, 2) : ''; 4775 global$4.each({ 4776 t: 'down', 4777 b: 'up', 4778 c: 'center' 4779 }, function (cls, pos) { 4780 panel.classes.toggle('arrow-' + cls, pos === relPos.substr(0, 1)); 4781 }); 4782 if (relPos === 'cr') { 4783 panel.classes.toggle('arrow-left', true); 4784 panel.classes.toggle('arrow-right', false); 4785 } else if (relPos === 'cl') { 4786 panel.classes.toggle('arrow-left', false); 4787 panel.classes.toggle('arrow-right', true); 4788 } else { 4789 global$4.each({ 4790 l: 'left', 4791 r: 'right' 4792 }, function (cls, pos) { 4793 panel.classes.toggle('arrow-' + cls, pos === relPos.substr(1, 1)); 4794 }); 4795 } 4796 }; 4797 var showToolbar = function (panel, id) { 4798 var toolbars = panel.items().filter('#' + id); 4799 if (toolbars.length > 0) { 4800 toolbars[0].show(); 4801 panel.reflow(); 4802 return true; 4803 } 4804 return false; 4805 }; 4806 var repositionPanelAt = function (panel, id, editor, targetRect) { 4807 var contentAreaRect, panelRect, result, userConstainHandler; 4808 userConstainHandler = Settings.getPositionHandler(editor); 4809 contentAreaRect = Measure.getContentAreaRect(editor); 4810 panelRect = global$2.DOM.getRect(panel.getEl()); 4811 if (id === 'insert') { 4812 result = Layout.calcInsert(targetRect, contentAreaRect, panelRect); 4813 } else { 4814 result = Layout.calc(targetRect, contentAreaRect, panelRect); 4815 } 4816 if (result) { 4817 var delta = UiContainer$1.getUiContainerDelta().getOr({ 4818 x: 0, 4819 y: 0 4820 }); 4821 var transposedPanelRect = { 4822 x: result.rect.x - delta.x, 4823 y: result.rect.y - delta.y, 4824 w: result.rect.w, 4825 h: result.rect.h 4826 }; 4827 currentRect = targetRect; 4828 movePanelTo(panel, Layout.userConstrain(userConstainHandler, targetRect, contentAreaRect, transposedPanelRect)); 4829 togglePositionClass(panel, result.position); 4830 return true; 4831 } else { 4832 return false; 4833 } 4834 }; 4835 var showPanelAt = function (panel, id, editor, targetRect) { 4836 showPanel(panel); 4837 panel.items().hide(); 4838 if (!showToolbar(panel, id)) { 4839 hide(); 4840 return; 4841 } 4842 if (repositionPanelAt(panel, id, editor, targetRect) === false) { 4843 hide(); 4844 } 4845 }; 4846 var hasFormVisible = function () { 4847 return panel.items().filter('form:visible').length > 0; 4848 }; 4849 var showForm = function (editor, id) { 4850 if (panel) { 4851 panel.items().hide(); 4852 if (!showToolbar(panel, id)) { 4853 hide(); 4854 return; 4855 } 4856 var contentAreaRect = void 0, panelRect = void 0, result = void 0, userConstainHandler = void 0; 4857 showPanel(panel); 4858 panel.items().hide(); 4859 showToolbar(panel, id); 4860 userConstainHandler = Settings.getPositionHandler(editor); 4861 contentAreaRect = Measure.getContentAreaRect(editor); 4862 panelRect = global$2.DOM.getRect(panel.getEl()); 4863 result = Layout.calc(currentRect, contentAreaRect, panelRect); 4864 if (result) { 4865 panelRect = result.rect; 4866 movePanelTo(panel, Layout.userConstrain(userConstainHandler, currentRect, contentAreaRect, panelRect)); 4867 togglePositionClass(panel, result.position); 4868 } 4869 } 4870 }; 4871 var show = function (editor, id, targetRect, toolbars) { 4872 if (!panel) { 4873 Events.fireBeforeRenderUI(editor); 4874 panel = create(editor, toolbars); 4875 panel.renderTo().reflow().moveTo(targetRect.x, targetRect.y); 4876 editor.nodeChanged(); 4877 } 4878 showPanelAt(panel, id, editor, targetRect); 4879 }; 4880 var reposition = function (editor, id, targetRect) { 4881 if (panel) { 4882 repositionPanelAt(panel, id, editor, targetRect); 4883 } 4884 }; 4885 var hide = function () { 4886 if (panel) { 4887 panel.hide(); 4888 } 4889 }; 4890 var focus = function () { 4891 if (panel) { 4892 panel.find('toolbar:visible').eq(0).each(function (item) { 4893 item.focus(true); 4894 }); 4895 } 4896 }; 4897 var remove = function () { 4898 if (panel) { 4899 panel.remove(); 4900 panel = null; 4901 } 4902 }; 4903 var inForm = function () { 4904 return panel && panel.visible() && hasFormVisible(); 4905 }; 4906 return { 4907 show: show, 4908 showForm: showForm, 4909 reposition: reposition, 4910 inForm: inForm, 4911 hide: hide, 4912 focus: focus, 4913 remove: remove 4914 }; 4915 }; 4916 4917 var Layout$1 = global$8.extend({ 4918 Defaults: { 4919 firstControlClass: 'first', 4920 lastControlClass: 'last' 4921 }, 4922 init: function (settings) { 4923 this.settings = global$4.extend({}, this.Defaults, settings); 4924 }, 4925 preRender: function (container) { 4926 container.bodyClasses.add(this.settings.containerClass); 4927 }, 4928 applyClasses: function (items) { 4929 var self = this; 4930 var settings = self.settings; 4931 var firstClass, lastClass, firstItem, lastItem; 4932 firstClass = settings.firstControlClass; 4933 lastClass = settings.lastControlClass; 4934 items.each(function (item) { 4935 item.classes.remove(firstClass).remove(lastClass).add(settings.controlClass); 4936 if (item.visible()) { 4937 if (!firstItem) { 4938 firstItem = item; 4939 } 4940 lastItem = item; 4941 } 4942 }); 4943 if (firstItem) { 4944 firstItem.classes.add(firstClass); 4945 } 4946 if (lastItem) { 4947 lastItem.classes.add(lastClass); 4948 } 4949 }, 4950 renderHtml: function (container) { 4951 var self = this; 4952 var html = ''; 4953 self.applyClasses(container.items()); 4954 container.items().each(function (item) { 4955 html += item.renderHtml(); 4956 }); 4957 return html; 4958 }, 4959 recalc: function () { 4960 }, 4961 postRender: function () { 4962 }, 4963 isNative: function () { 4964 return false; 4965 } 4966 }); 4967 4968 var AbsoluteLayout = Layout$1.extend({ 4969 Defaults: { 4970 containerClass: 'abs-layout', 4971 controlClass: 'abs-layout-item' 4972 }, 4973 recalc: function (container) { 4974 container.items().filter(':visible').each(function (ctrl) { 4975 var settings = ctrl.settings; 4976 ctrl.layoutRect({ 4977 x: settings.x, 4978 y: settings.y, 4979 w: settings.w, 4980 h: settings.h 4981 }); 4982 if (ctrl.recalc) { 4983 ctrl.recalc(); 4984 } 4985 }); 4986 }, 4987 renderHtml: function (container) { 4988 return '<div id="' + container._id + '-absend" class="' + container.classPrefix + 'abs-end"></div>' + this._super(container); 4989 } 4990 }); 4991 4992 var Button = Widget.extend({ 4993 Defaults: { 4994 classes: 'widget btn', 4995 role: 'button' 4996 }, 4997 init: function (settings) { 4998 var self = this; 4999 var size; 5000 self._super(settings); 5001 settings = self.settings; 5002 size = self.settings.size; 5003 self.on('click mousedown', function (e) { 5004 e.preventDefault(); 5005 }); 5006 self.on('touchstart', function (e) { 5007 self.fire('click', e); 5008 e.preventDefault(); 5009 }); 5010 if (settings.subtype) { 5011 self.classes.add(settings.subtype); 5012 } 5013 if (size) { 5014 self.classes.add('btn-' + size); 5015 } 5016 if (settings.icon) { 5017 self.icon(settings.icon); 5018 } 5019 }, 5020 icon: function (icon) { 5021 if (!arguments.length) { 5022 return this.state.get('icon'); 5023 } 5024 this.state.set('icon', icon); 5025 return this; 5026 }, 5027 repaint: function () { 5028 var btnElm = this.getEl().firstChild; 5029 var btnStyle; 5030 if (btnElm) { 5031 btnStyle = btnElm.style; 5032 btnStyle.width = btnStyle.height = '100%'; 5033 } 5034 this._super(); 5035 }, 5036 renderHtml: function () { 5037 var self = this, id = self._id, prefix = self.classPrefix; 5038 var icon = self.state.get('icon'), image; 5039 var text = self.state.get('text'); 5040 var textHtml = ''; 5041 var ariaPressed; 5042 var settings = self.settings; 5043 image = settings.image; 5044 if (image) { 5045 icon = 'none'; 5046 if (typeof image !== 'string') { 5047 image = domGlobals.window.getSelection ? image[0] : image[1]; 5048 } 5049 image = ' style="background-image: url(\'' + image + '\')"'; 5050 } else { 5051 image = ''; 5052 } 5053 if (text) { 5054 self.classes.add('btn-has-text'); 5055 textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>'; 5056 } 5057 icon = icon ? prefix + 'ico ' + prefix + 'i-' + icon : ''; 5058 ariaPressed = typeof settings.active === 'boolean' ? ' aria-pressed="' + settings.active + '"' : ''; 5059 return '<div id="' + id + '" class="' + self.classes + '" tabindex="-1"' + ariaPressed + '>' + '<button id="' + id + '-button" role="presentation" type="button" tabindex="-1">' + (icon ? '<i class="' + icon + '"' + image + '></i>' : '') + textHtml + '</button>' + '</div>'; 5060 }, 5061 bindStates: function () { 5062 var self = this, $ = self.$, textCls = self.classPrefix + 'txt'; 5063 function setButtonText(text) { 5064 var $span = $('span.' + textCls, self.getEl()); 5065 if (text) { 5066 if (!$span[0]) { 5067 $('button:first', self.getEl()).append('<span class="' + textCls + '"></span>'); 5068 $span = $('span.' + textCls, self.getEl()); 5069 } 5070 $span.html(self.encode(text)); 5071 } else { 5072 $span.remove(); 5073 } 5074 self.classes.toggle('btn-has-text', !!text); 5075 } 5076 self.state.on('change:text', function (e) { 5077 setButtonText(e.value); 5078 }); 5079 self.state.on('change:icon', function (e) { 5080 var icon = e.value; 5081 var prefix = self.classPrefix; 5082 self.settings.icon = icon; 5083 icon = icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : ''; 5084 var btnElm = self.getEl().firstChild; 5085 var iconElm = btnElm.getElementsByTagName('i')[0]; 5086 if (icon) { 5087 if (!iconElm || iconElm !== btnElm.firstChild) { 5088 iconElm = domGlobals.document.createElement('i'); 5089 btnElm.insertBefore(iconElm, btnElm.firstChild); 5090 } 5091 iconElm.className = icon; 5092 } else if (iconElm) { 5093 btnElm.removeChild(iconElm); 5094 } 5095 setButtonText(self.state.get('text')); 5096 }); 5097 return self._super(); 5098 } 5099 }); 5100 5101 var BrowseButton = Button.extend({ 5102 init: function (settings) { 5103 var self = this; 5104 settings = global$4.extend({ 5105 text: 'Browse...', 5106 multiple: false, 5107 accept: null 5108 }, settings); 5109 self._super(settings); 5110 self.classes.add('browsebutton'); 5111 if (settings.multiple) { 5112 self.classes.add('multiple'); 5113 } 5114 }, 5115 postRender: function () { 5116 var self = this; 5117 var input = funcs.create('input', { 5118 type: 'file', 5119 id: self._id + '-browse', 5120 accept: self.settings.accept 5121 }); 5122 self._super(); 5123 global$7(input).on('change', function (e) { 5124 var files = e.target.files; 5125 self.value = function () { 5126 if (!files.length) { 5127 return null; 5128 } else if (self.settings.multiple) { 5129 return files; 5130 } else { 5131 return files[0]; 5132 } 5133 }; 5134 e.preventDefault(); 5135 if (files.length) { 5136 self.fire('change', e); 5137 } 5138 }); 5139 global$7(input).on('click', function (e) { 5140 e.stopPropagation(); 5141 }); 5142 global$7(self.getEl('button')).on('click touchstart', function (e) { 5143 e.stopPropagation(); 5144 input.click(); 5145 e.preventDefault(); 5146 }); 5147 self.getEl().appendChild(input); 5148 }, 5149 remove: function () { 5150 global$7(this.getEl('button')).off(); 5151 global$7(this.getEl('input')).off(); 5152 this._super(); 5153 } 5154 }); 5155 5156 var ButtonGroup = Container.extend({ 5157 Defaults: { 5158 defaultType: 'button', 5159 role: 'group' 5160 }, 5161 renderHtml: function () { 5162 var self = this, layout = self._layout; 5163 self.classes.add('btn-group'); 5164 self.preRender(); 5165 layout.preRender(self); 5166 return '<div id="' + self._id + '" class="' + self.classes + '">' + '<div id="' + self._id + '-body">' + (self.settings.html || '') + layout.renderHtml(self) + '</div>' + '</div>'; 5167 } 5168 }); 5169 5170 var Checkbox = Widget.extend({ 5171 Defaults: { 5172 classes: 'checkbox', 5173 role: 'checkbox', 5174 checked: false 5175 }, 5176 init: function (settings) { 5177 var self = this; 5178 self._super(settings); 5179 self.on('click mousedown', function (e) { 5180 e.preventDefault(); 5181 }); 5182 self.on('click', function (e) { 5183 e.preventDefault(); 5184 if (!self.disabled()) { 5185 self.checked(!self.checked()); 5186 } 5187 }); 5188 self.checked(self.settings.checked); 5189 }, 5190 checked: function (state) { 5191 if (!arguments.length) { 5192 return this.state.get('checked'); 5193 } 5194 this.state.set('checked', state); 5195 return this; 5196 }, 5197 value: function (state) { 5198 if (!arguments.length) { 5199 return this.checked(); 5200 } 5201 return this.checked(state); 5202 }, 5203 renderHtml: function () { 5204 var self = this, id = self._id, prefix = self.classPrefix; 5205 return '<div id="' + id + '" class="' + self.classes + '" unselectable="on" aria-labelledby="' + id + '-al" tabindex="-1">' + '<i class="' + prefix + 'ico ' + prefix + 'i-checkbox"></i>' + '<span id="' + id + '-al" class="' + prefix + 'label">' + self.encode(self.state.get('text')) + '</span>' + '</div>'; 5206 }, 5207 bindStates: function () { 5208 var self = this; 5209 function checked(state) { 5210 self.classes.toggle('checked', state); 5211 self.aria('checked', state); 5212 } 5213 self.state.on('change:text', function (e) { 5214 self.getEl('al').firstChild.data = self.translate(e.value); 5215 }); 5216 self.state.on('change:checked change:value', function (e) { 5217 self.fire('change'); 5218 checked(e.value); 5219 }); 5220 self.state.on('change:icon', function (e) { 5221 var icon = e.value; 5222 var prefix = self.classPrefix; 5223 if (typeof icon === 'undefined') { 5224 return self.settings.icon; 5225 } 5226 self.settings.icon = icon; 5227 icon = icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : ''; 5228 var btnElm = self.getEl().firstChild; 5229 var iconElm = btnElm.getElementsByTagName('i')[0]; 5230 if (icon) { 5231 if (!iconElm || iconElm !== btnElm.firstChild) { 5232 iconElm = domGlobals.document.createElement('i'); 5233 btnElm.insertBefore(iconElm, btnElm.firstChild); 5234 } 5235 iconElm.className = icon; 5236 } else if (iconElm) { 5237 btnElm.removeChild(iconElm); 5238 } 5239 }); 5240 if (self.state.get('checked')) { 5241 checked(true); 5242 } 5243 return self._super(); 5244 } 5245 }); 5246 5247 var global$f = tinymce.util.Tools.resolve('tinymce.util.VK'); 5248 5249 var ComboBox = Widget.extend({ 5250 init: function (settings) { 5251 var self = this; 5252 self._super(settings); 5253 settings = self.settings; 5254 self.classes.add('combobox'); 5255 self.subinput = true; 5256 self.ariaTarget = 'inp'; 5257 settings.menu = settings.menu || settings.values; 5258 if (settings.menu) { 5259 settings.icon = 'caret'; 5260 } 5261 self.on('click', function (e) { 5262 var elm = e.target; 5263 var root = self.getEl(); 5264 if (!global$7.contains(root, elm) && elm !== root) { 5265 return; 5266 } 5267 while (elm && elm !== root) { 5268 if (elm.id && elm.id.indexOf('-open') !== -1) { 5269 self.fire('action'); 5270 if (settings.menu) { 5271 self.showMenu(); 5272 if (e.aria) { 5273 self.menu.items()[0].focus(); 5274 } 5275 } 5276 } 5277 elm = elm.parentNode; 5278 } 5279 }); 5280 self.on('keydown', function (e) { 5281 var rootControl; 5282 if (e.keyCode === 13 && e.target.nodeName === 'INPUT') { 5283 e.preventDefault(); 5284 self.parents().reverse().each(function (ctrl) { 5285 if (ctrl.toJSON) { 5286 rootControl = ctrl; 5287 return false; 5288 } 5289 }); 5290 self.fire('submit', { data: rootControl.toJSON() }); 5291 } 5292 }); 5293 self.on('keyup', function (e) { 5294 if (e.target.nodeName === 'INPUT') { 5295 var oldValue = self.state.get('value'); 5296 var newValue = e.target.value; 5297 if (newValue !== oldValue) { 5298 self.state.set('value', newValue); 5299 self.fire('autocomplete', e); 5300 } 5301 } 5302 }); 5303 self.on('mouseover', function (e) { 5304 var tooltip = self.tooltip().moveTo(-65535); 5305 if (self.statusLevel() && e.target.className.indexOf(self.classPrefix + 'status') !== -1) { 5306 var statusMessage = self.statusMessage() || 'Ok'; 5307 var rel = tooltip.text(statusMessage).show().testMoveRel(e.target, [ 5308 'bc-tc', 5309 'bc-tl', 5310 'bc-tr' 5311 ]); 5312 tooltip.classes.toggle('tooltip-n', rel === 'bc-tc'); 5313 tooltip.classes.toggle('tooltip-nw', rel === 'bc-tl'); 5314 tooltip.classes.toggle('tooltip-ne', rel === 'bc-tr'); 5315 tooltip.moveRel(e.target, rel); 5316 } 5317 }); 5318 }, 5319 statusLevel: function (value) { 5320 if (arguments.length > 0) { 5321 this.state.set('statusLevel', value); 5322 } 5323 return this.state.get('statusLevel'); 5324 }, 5325 statusMessage: function (value) { 5326 if (arguments.length > 0) { 5327 this.state.set('statusMessage', value); 5328 } 5329 return this.state.get('statusMessage'); 5330 }, 5331 showMenu: function () { 5332 var self = this; 5333 var settings = self.settings; 5334 var menu; 5335 if (!self.menu) { 5336 menu = settings.menu || []; 5337 if (menu.length) { 5338 menu = { 5339 type: 'menu', 5340 items: menu 5341 }; 5342 } else { 5343 menu.type = menu.type || 'menu'; 5344 } 5345 self.menu = global$b.create(menu).parent(self).renderTo(self.getContainerElm()); 5346 self.fire('createmenu'); 5347 self.menu.reflow(); 5348 self.menu.on('cancel', function (e) { 5349 if (e.control === self.menu) { 5350 self.focus(); 5351 } 5352 }); 5353 self.menu.on('show hide', function (e) { 5354 e.control.items().each(function (ctrl) { 5355 ctrl.active(ctrl.value() === self.value()); 5356 }); 5357 }).fire('show'); 5358 self.menu.on('select', function (e) { 5359 self.value(e.control.value()); 5360 }); 5361 self.on('focusin', function (e) { 5362 if (e.target.tagName.toUpperCase() === 'INPUT') { 5363 self.menu.hide(); 5364 } 5365 }); 5366 self.aria('expanded', true); 5367 } 5368 self.menu.show(); 5369 self.menu.layoutRect({ w: self.layoutRect().w }); 5370 self.menu.moveRel(self.getEl(), self.isRtl() ? [ 5371 'br-tr', 5372 'tr-br' 5373 ] : [ 5374 'bl-tl', 5375 'tl-bl' 5376 ]); 5377 }, 5378 focus: function () { 5379 this.getEl('inp').focus(); 5380 }, 5381 repaint: function () { 5382 var self = this, elm = self.getEl(), openElm = self.getEl('open'), rect = self.layoutRect(); 5383 var width, lineHeight, innerPadding = 0; 5384 var inputElm = elm.firstChild; 5385 if (self.statusLevel() && self.statusLevel() !== 'none') { 5386 innerPadding = parseInt(funcs.getRuntimeStyle(inputElm, 'padding-right'), 10) - parseInt(funcs.getRuntimeStyle(inputElm, 'padding-left'), 10); 5387 } 5388 if (openElm) { 5389 width = rect.w - funcs.getSize(openElm).width - 10; 5390 } else { 5391 width = rect.w - 10; 5392 } 5393 var doc = domGlobals.document; 5394 if (doc.all && (!doc.documentMode || doc.documentMode <= 8)) { 5395 lineHeight = self.layoutRect().h - 2 + 'px'; 5396 } 5397 global$7(inputElm).css({ 5398 width: width - innerPadding, 5399 lineHeight: lineHeight 5400 }); 5401 self._super(); 5402 return self; 5403 }, 5404 postRender: function () { 5405 var self = this; 5406 global$7(this.getEl('inp')).on('change', function (e) { 5407 self.state.set('value', e.target.value); 5408 self.fire('change', e); 5409 }); 5410 return self._super(); 5411 }, 5412 renderHtml: function () { 5413 var self = this, id = self._id, settings = self.settings, prefix = self.classPrefix; 5414 var value = self.state.get('value') || ''; 5415 var icon, text, openBtnHtml = '', extraAttrs = '', statusHtml = ''; 5416 if ('spellcheck' in settings) { 5417 extraAttrs += ' spellcheck="' + settings.spellcheck + '"'; 5418 } 5419 if (settings.maxLength) { 5420 extraAttrs += ' maxlength="' + settings.maxLength + '"'; 5421 } 5422 if (settings.size) { 5423 extraAttrs += ' size="' + settings.size + '"'; 5424 } 5425 if (settings.subtype) { 5426 extraAttrs += ' type="' + settings.subtype + '"'; 5427 } 5428 statusHtml = '<i id="' + id + '-status" class="mce-status mce-ico" style="display: none"></i>'; 5429 if (self.disabled()) { 5430 extraAttrs += ' disabled="disabled"'; 5431 } 5432 icon = settings.icon; 5433 if (icon && icon !== 'caret') { 5434 icon = prefix + 'ico ' + prefix + 'i-' + settings.icon; 5435 } 5436 text = self.state.get('text'); 5437 if (icon || text) { 5438 openBtnHtml = '<div id="' + id + '-open" class="' + prefix + 'btn ' + prefix + 'open" tabIndex="-1" role="button">' + '<button id="' + id + '-action" type="button" hidefocus="1" tabindex="-1">' + (icon !== 'caret' ? '<i class="' + icon + '"></i>' : '<i class="' + prefix + 'caret"></i>') + (text ? (icon ? ' ' : '') + text : '') + '</button>' + '</div>'; 5439 self.classes.add('has-open'); 5440 } 5441 return '<div id="' + id + '" class="' + self.classes + '">' + '<input id="' + id + '-inp" class="' + prefix + 'textbox" value="' + self.encode(value, false) + '" hidefocus="1"' + extraAttrs + ' placeholder="' + self.encode(settings.placeholder) + '" />' + statusHtml + openBtnHtml + '</div>'; 5442 }, 5443 value: function (value) { 5444 if (arguments.length) { 5445 this.state.set('value', value); 5446 return this; 5447 } 5448 if (this.state.get('rendered')) { 5449 this.state.set('value', this.getEl('inp').value); 5450 } 5451 return this.state.get('value'); 5452 }, 5453 showAutoComplete: function (items, term) { 5454 var self = this; 5455 if (items.length === 0) { 5456 self.hideMenu(); 5457 return; 5458 } 5459 var insert = function (value, title) { 5460 return function () { 5461 self.fire('selectitem', { 5462 title: title, 5463 value: value 5464 }); 5465 }; 5466 }; 5467 if (self.menu) { 5468 self.menu.items().remove(); 5469 } else { 5470 self.menu = global$b.create({ 5471 type: 'menu', 5472 classes: 'combobox-menu', 5473 layout: 'flow' 5474 }).parent(self).renderTo(); 5475 } 5476 global$4.each(items, function (item) { 5477 self.menu.add({ 5478 text: item.title, 5479 url: item.previewUrl, 5480 match: term, 5481 classes: 'menu-item-ellipsis', 5482 onclick: insert(item.value, item.title) 5483 }); 5484 }); 5485 self.menu.renderNew(); 5486 self.hideMenu(); 5487 self.menu.on('cancel', function (e) { 5488 if (e.control.parent() === self.menu) { 5489 e.stopPropagation(); 5490 self.focus(); 5491 self.hideMenu(); 5492 } 5493 }); 5494 self.menu.on('select', function () { 5495 self.focus(); 5496 }); 5497 var maxW = self.layoutRect().w; 5498 self.menu.layoutRect({ 5499 w: maxW, 5500 minW: 0, 5501 maxW: maxW 5502 }); 5503 self.menu.repaint(); 5504 self.menu.reflow(); 5505 self.menu.show(); 5506 self.menu.moveRel(self.getEl(), self.isRtl() ? [ 5507 'br-tr', 5508 'tr-br' 5509 ] : [ 5510 'bl-tl', 5511 'tl-bl' 5512 ]); 5513 }, 5514 hideMenu: function () { 5515 if (this.menu) { 5516 this.menu.hide(); 5517 } 5518 }, 5519 bindStates: function () { 5520 var self = this; 5521 self.state.on('change:value', function (e) { 5522 if (self.getEl('inp').value !== e.value) { 5523 self.getEl('inp').value = e.value; 5524 } 5525 }); 5526 self.state.on('change:disabled', function (e) { 5527 self.getEl('inp').disabled = e.value; 5528 }); 5529 self.state.on('change:statusLevel', function (e) { 5530 var statusIconElm = self.getEl('status'); 5531 var prefix = self.classPrefix, value = e.value; 5532 funcs.css(statusIconElm, 'display', value === 'none' ? 'none' : ''); 5533 funcs.toggleClass(statusIconElm, prefix + 'i-checkmark', value === 'ok'); 5534 funcs.toggleClass(statusIconElm, prefix + 'i-warning', value === 'warn'); 5535 funcs.toggleClass(statusIconElm, prefix + 'i-error', value === 'error'); 5536 self.classes.toggle('has-status', value !== 'none'); 5537 self.repaint(); 5538 }); 5539 funcs.on(self.getEl('status'), 'mouseleave', function () { 5540 self.tooltip().hide(); 5541 }); 5542 self.on('cancel', function (e) { 5543 if (self.menu && self.menu.visible()) { 5544 e.stopPropagation(); 5545 self.hideMenu(); 5546 } 5547 }); 5548 var focusIdx = function (idx, menu) { 5549 if (menu && menu.items().length > 0) { 5550 menu.items().eq(idx)[0].focus(); 5551 } 5552 }; 5553 self.on('keydown', function (e) { 5554 var keyCode = e.keyCode; 5555 if (e.target.nodeName === 'INPUT') { 5556 if (keyCode === global$f.DOWN) { 5557 e.preventDefault(); 5558 self.fire('autocomplete'); 5559 focusIdx(0, self.menu); 5560 } else if (keyCode === global$f.UP) { 5561 e.preventDefault(); 5562 focusIdx(-1, self.menu); 5563 } 5564 } 5565 }); 5566 return self._super(); 5567 }, 5568 remove: function () { 5569 global$7(this.getEl('inp')).off(); 5570 if (this.menu) { 5571 this.menu.remove(); 5572 } 5573 this._super(); 5574 } 5575 }); 5576 5577 var ColorBox = ComboBox.extend({ 5578 init: function (settings) { 5579 var self = this; 5580 settings.spellcheck = false; 5581 if (settings.onaction) { 5582 settings.icon = 'none'; 5583 } 5584 self._super(settings); 5585 self.classes.add('colorbox'); 5586 self.on('change keyup postrender', function () { 5587 self.repaintColor(self.value()); 5588 }); 5589 }, 5590 repaintColor: function (value) { 5591 var openElm = this.getEl('open'); 5592 var elm = openElm ? openElm.getElementsByTagName('i')[0] : null; 5593 if (elm) { 5594 try { 5595 elm.style.background = value; 5596 } catch (ex) { 5597 } 5598 } 5599 }, 5600 bindStates: function () { 5601 var self = this; 5602 self.state.on('change:value', function (e) { 5603 if (self.state.get('rendered')) { 5604 self.repaintColor(e.value); 5605 } 5606 }); 5607 return self._super(); 5608 } 5609 }); 5610 5611 var PanelButton = Button.extend({ 5612 showPanel: function () { 5613 var self = this, settings = self.settings; 5614 self.classes.add('opened'); 5615 if (!self.panel) { 5616 var panelSettings = settings.panel; 5617 if (panelSettings.type) { 5618 panelSettings = { 5619 layout: 'grid', 5620 items: panelSettings 5621 }; 5622 } 5623 panelSettings.role = panelSettings.role || 'dialog'; 5624 panelSettings.popover = true; 5625 panelSettings.autohide = true; 5626 panelSettings.ariaRoot = true; 5627 self.panel = new FloatPanel(panelSettings).on('hide', function () { 5628 self.classes.remove('opened'); 5629 }).on('cancel', function (e) { 5630 e.stopPropagation(); 5631 self.focus(); 5632 self.hidePanel(); 5633 }).parent(self).renderTo(self.getContainerElm()); 5634 self.panel.fire('show'); 5635 self.panel.reflow(); 5636 } else { 5637 self.panel.show(); 5638 } 5639 var rtlRels = [ 5640 'bc-tc', 5641 'bc-tl', 5642 'bc-tr' 5643 ]; 5644 var ltrRels = [ 5645 'bc-tc', 5646 'bc-tr', 5647 'bc-tl', 5648 'tc-bc', 5649 'tc-br', 5650 'tc-bl' 5651 ]; 5652 var rel = self.panel.testMoveRel(self.getEl(), settings.popoverAlign || (self.isRtl() ? rtlRels : ltrRels)); 5653 self.panel.classes.toggle('start', rel.substr(-1) === 'l'); 5654 self.panel.classes.toggle('end', rel.substr(-1) === 'r'); 5655 var isTop = rel.substr(0, 1) === 't'; 5656 self.panel.classes.toggle('bottom', !isTop); 5657 self.panel.classes.toggle('top', isTop); 5658 self.panel.moveRel(self.getEl(), rel); 5659 }, 5660 hidePanel: function () { 5661 var self = this; 5662 if (self.panel) { 5663 self.panel.hide(); 5664 } 5665 }, 5666 postRender: function () { 5667 var self = this; 5668 self.aria('haspopup', true); 5669 self.on('click', function (e) { 5670 if (e.control === self) { 5671 if (self.panel && self.panel.visible()) { 5672 self.hidePanel(); 5673 } else { 5674 self.showPanel(); 5675 self.panel.focus(!!e.aria); 5676 } 5677 } 5678 }); 5679 return self._super(); 5680 }, 5681 remove: function () { 5682 if (this.panel) { 5683 this.panel.remove(); 5684 this.panel = null; 5685 } 5686 return this._super(); 5687 } 5688 }); 5689 5690 var DOM = global$2.DOM; 5691 var ColorButton = PanelButton.extend({ 5692 init: function (settings) { 5693 this._super(settings); 5694 this.classes.add('splitbtn'); 5695 this.classes.add('colorbutton'); 5696 }, 5697 color: function (color) { 5698 if (color) { 5699 this._color = color; 5700 this.getEl('preview').style.backgroundColor = color; 5701 return this; 5702 } 5703 return this._color; 5704 }, 5705 resetColor: function () { 5706 this._color = null; 5707 this.getEl('preview').style.backgroundColor = null; 5708 return this; 5709 }, 5710 renderHtml: function () { 5711 var self = this, id = self._id, prefix = self.classPrefix, text = self.state.get('text'); 5712 var icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : ''; 5713 var image = self.settings.image ? ' style="background-image: url(\'' + self.settings.image + '\')"' : ''; 5714 var textHtml = ''; 5715 if (text) { 5716 self.classes.add('btn-has-text'); 5717 textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>'; 5718 } 5719 return '<div id="' + id + '" class="' + self.classes + '" role="button" tabindex="-1" aria-haspopup="true">' + '<button role="presentation" hidefocus="1" type="button" tabindex="-1">' + (icon ? '<i class="' + icon + '"' + image + '></i>' : '') + '<span id="' + id + '-preview" class="' + prefix + 'preview"></span>' + textHtml + '</button>' + '<button type="button" class="' + prefix + 'open" hidefocus="1" tabindex="-1">' + ' <i class="' + prefix + 'caret"></i>' + '</button>' + '</div>'; 5720 }, 5721 postRender: function () { 5722 var self = this, onClickHandler = self.settings.onclick; 5723 self.on('click', function (e) { 5724 if (e.aria && e.aria.key === 'down') { 5725 return; 5726 } 5727 if (e.control === self && !DOM.getParent(e.target, '.' + self.classPrefix + 'open')) { 5728 e.stopImmediatePropagation(); 5729 onClickHandler.call(self, e); 5730 } 5731 }); 5732 delete self.settings.onclick; 5733 return self._super(); 5734 } 5735 }); 5736 5737 var global$g = tinymce.util.Tools.resolve('tinymce.util.Color'); 5738 5739 var ColorPicker = Widget.extend({ 5740 Defaults: { classes: 'widget colorpicker' }, 5741 init: function (settings) { 5742 this._super(settings); 5743 }, 5744 postRender: function () { 5745 var self = this; 5746 var color = self.color(); 5747 var hsv, hueRootElm, huePointElm, svRootElm, svPointElm; 5748 hueRootElm = self.getEl('h'); 5749 huePointElm = self.getEl('hp'); 5750 svRootElm = self.getEl('sv'); 5751 svPointElm = self.getEl('svp'); 5752 function getPos(elm, event) { 5753 var pos = funcs.getPos(elm); 5754 var x, y; 5755 x = event.pageX - pos.x; 5756 y = event.pageY - pos.y; 5757 x = Math.max(0, Math.min(x / elm.clientWidth, 1)); 5758 y = Math.max(0, Math.min(y / elm.clientHeight, 1)); 5759 return { 5760 x: x, 5761 y: y 5762 }; 5763 } 5764 function updateColor(hsv, hueUpdate) { 5765 var hue = (360 - hsv.h) / 360; 5766 funcs.css(huePointElm, { top: hue * 100 + '%' }); 5767 if (!hueUpdate) { 5768 funcs.css(svPointElm, { 5769 left: hsv.s + '%', 5770 top: 100 - hsv.v + '%' 5771 }); 5772 } 5773 svRootElm.style.background = global$g({ 5774 s: 100, 5775 v: 100, 5776 h: hsv.h 5777 }).toHex(); 5778 self.color().parse({ 5779 s: hsv.s, 5780 v: hsv.v, 5781 h: hsv.h 5782 }); 5783 } 5784 function updateSaturationAndValue(e) { 5785 var pos; 5786 pos = getPos(svRootElm, e); 5787 hsv.s = pos.x * 100; 5788 hsv.v = (1 - pos.y) * 100; 5789 updateColor(hsv); 5790 self.fire('change'); 5791 } 5792 function updateHue(e) { 5793 var pos; 5794 pos = getPos(hueRootElm, e); 5795 hsv = color.toHsv(); 5796 hsv.h = (1 - pos.y) * 360; 5797 updateColor(hsv, true); 5798 self.fire('change'); 5799 } 5800 self._repaint = function () { 5801 hsv = color.toHsv(); 5802 updateColor(hsv); 5803 }; 5804 self._super(); 5805 self._svdraghelper = new DragHelper(self._id + '-sv', { 5806 start: updateSaturationAndValue, 5807 drag: updateSaturationAndValue 5808 }); 5809 self._hdraghelper = new DragHelper(self._id + '-h', { 5810 start: updateHue, 5811 drag: updateHue 5812 }); 5813 self._repaint(); 5814 }, 5815 rgb: function () { 5816 return this.color().toRgb(); 5817 }, 5818 value: function (value) { 5819 var self = this; 5820 if (arguments.length) { 5821 self.color().parse(value); 5822 if (self._rendered) { 5823 self._repaint(); 5824 } 5825 } else { 5826 return self.color().toHex(); 5827 } 5828 }, 5829 color: function () { 5830 if (!this._color) { 5831 this._color = global$g(); 5832 } 5833 return this._color; 5834 }, 5835 renderHtml: function () { 5836 var self = this; 5837 var id = self._id; 5838 var prefix = self.classPrefix; 5839 var hueHtml; 5840 var stops = '#ff0000,#ff0080,#ff00ff,#8000ff,#0000ff,#0080ff,#00ffff,#00ff80,#00ff00,#80ff00,#ffff00,#ff8000,#ff0000'; 5841 function getOldIeFallbackHtml() { 5842 var i, l, html = '', gradientPrefix, stopsList; 5843 gradientPrefix = 'filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='; 5844 stopsList = stops.split(','); 5845 for (i = 0, l = stopsList.length - 1; i < l; i++) { 5846 html += '<div class="' + prefix + 'colorpicker-h-chunk" style="' + 'height:' + 100 / l + '%;' + gradientPrefix + stopsList[i] + ',endColorstr=' + stopsList[i + 1] + ');' + '-ms-' + gradientPrefix + stopsList[i] + ',endColorstr=' + stopsList[i + 1] + ')' + '"></div>'; 5847 } 5848 return html; 5849 } 5850 var gradientCssText = 'background: -ms-linear-gradient(top,' + stops + ');' + 'background: linear-gradient(to bottom,' + stops + ');'; 5851 hueHtml = '<div id="' + id + '-h" class="' + prefix + 'colorpicker-h" style="' + gradientCssText + '">' + getOldIeFallbackHtml() + '<div id="' + id + '-hp" class="' + prefix + 'colorpicker-h-marker"></div>' + '</div>'; 5852 return '<div id="' + id + '" class="' + self.classes + '">' + '<div id="' + id + '-sv" class="' + prefix + 'colorpicker-sv">' + '<div class="' + prefix + 'colorpicker-overlay1">' + '<div class="' + prefix + 'colorpicker-overlay2">' + '<div id="' + id + '-svp" class="' + prefix + 'colorpicker-selector1">' + '<div class="' + prefix + 'colorpicker-selector2"></div>' + '</div>' + '</div>' + '</div>' + '</div>' + hueHtml + '</div>'; 5853 } 5854 }); 5855 5856 var DropZone = Widget.extend({ 5857 init: function (settings) { 5858 var self = this; 5859 settings = global$4.extend({ 5860 height: 100, 5861 text: 'Drop an image here', 5862 multiple: false, 5863 accept: null 5864 }, settings); 5865 self._super(settings); 5866 self.classes.add('dropzone'); 5867 if (settings.multiple) { 5868 self.classes.add('multiple'); 5869 } 5870 }, 5871 renderHtml: function () { 5872 var self = this; 5873 var attrs, elm; 5874 var cfg = self.settings; 5875 attrs = { 5876 id: self._id, 5877 hidefocus: '1' 5878 }; 5879 elm = funcs.create('div', attrs, '<span>' + this.translate(cfg.text) + '</span>'); 5880 if (cfg.height) { 5881 funcs.css(elm, 'height', cfg.height + 'px'); 5882 } 5883 if (cfg.width) { 5884 funcs.css(elm, 'width', cfg.width + 'px'); 5885 } 5886 elm.className = self.classes; 5887 return elm.outerHTML; 5888 }, 5889 postRender: function () { 5890 var self = this; 5891 var toggleDragClass = function (e) { 5892 e.preventDefault(); 5893 self.classes.toggle('dragenter'); 5894 self.getEl().className = self.classes; 5895 }; 5896 var filter = function (files) { 5897 var accept = self.settings.accept; 5898 if (typeof accept !== 'string') { 5899 return files; 5900 } 5901 var re = new RegExp('(' + accept.split(/\s*,\s*/).join('|') + ')$', 'i'); 5902 return global$4.grep(files, function (file) { 5903 return re.test(file.name); 5904 }); 5905 }; 5906 self._super(); 5907 self.$el.on('dragover', function (e) { 5908 e.preventDefault(); 5909 }); 5910 self.$el.on('dragenter', toggleDragClass); 5911 self.$el.on('dragleave', toggleDragClass); 5912 self.$el.on('drop', function (e) { 5913 e.preventDefault(); 5914 if (self.state.get('disabled')) { 5915 return; 5916 } 5917 var files = filter(e.dataTransfer.files); 5918 self.value = function () { 5919 if (!files.length) { 5920 return null; 5921 } else if (self.settings.multiple) { 5922 return files; 5923 } else { 5924 return files[0]; 5925 } 5926 }; 5927 if (files.length) { 5928 self.fire('change', e); 5929 } 5930 }); 5931 }, 5932 remove: function () { 5933 this.$el.off(); 5934 this._super(); 5935 } 5936 }); 5937 5938 var Path = Widget.extend({ 5939 init: function (settings) { 5940 var self = this; 5941 if (!settings.delimiter) { 5942 settings.delimiter = '\xBB'; 5943 } 5944 self._super(settings); 5945 self.classes.add('path'); 5946 self.canFocus = true; 5947 self.on('click', function (e) { 5948 var index; 5949 var target = e.target; 5950 if (index = target.getAttribute('data-index')) { 5951 self.fire('select', { 5952 value: self.row()[index], 5953 index: index 5954 }); 5955 } 5956 }); 5957 self.row(self.settings.row); 5958 }, 5959 focus: function () { 5960 var self = this; 5961 self.getEl().firstChild.focus(); 5962 return self; 5963 }, 5964 row: function (row) { 5965 if (!arguments.length) { 5966 return this.state.get('row'); 5967 } 5968 this.state.set('row', row); 5969 return this; 5970 }, 5971 renderHtml: function () { 5972 var self = this; 5973 return '<div id="' + self._id + '" class="' + self.classes + '">' + self._getDataPathHtml(self.state.get('row')) + '</div>'; 5974 }, 5975 bindStates: function () { 5976 var self = this; 5977 self.state.on('change:row', function (e) { 5978 self.innerHtml(self._getDataPathHtml(e.value)); 5979 }); 5980 return self._super(); 5981 }, 5982 _getDataPathHtml: function (data) { 5983 var self = this; 5984 var parts = data || []; 5985 var i, l, html = ''; 5986 var prefix = self.classPrefix; 5987 for (i = 0, l = parts.length; i < l; i++) { 5988 html += (i > 0 ? '<div class="' + prefix + 'divider" aria-hidden="true"> ' + self.settings.delimiter + ' </div>' : '') + '<div role="button" class="' + prefix + 'path-item' + (i === l - 1 ? ' ' + prefix + 'last' : '') + '" data-index="' + i + '" tabindex="-1" id="' + self._id + '-' + i + '" aria-level="' + (i + 1) + '">' + parts[i].name + '</div>'; 5989 } 5990 if (!html) { 5991 html = '<div class="' + prefix + 'path-item">\xA0</div>'; 5992 } 5993 return html; 5994 } 5995 }); 5996 5997 var ElementPath = Path.extend({ 5998 postRender: function () { 5999 var self = this, editor = self.settings.editor; 6000 function isHidden(elm) { 6001 if (elm.nodeType === 1) { 6002 if (elm.nodeName === 'BR' || !!elm.getAttribute('data-mce-bogus')) { 6003 return true; 6004 } 6005 if (elm.getAttribute('data-mce-type') === 'bookmark') { 6006 return true; 6007 } 6008 } 6009 return false; 6010 } 6011 if (editor.settings.elementpath !== false) { 6012 self.on('select', function (e) { 6013 editor.focus(); 6014 editor.selection.select(this.row()[e.index].element); 6015 editor.nodeChanged(); 6016 }); 6017 editor.on('nodeChange', function (e) { 6018 var outParents = []; 6019 var parents = e.parents; 6020 var i = parents.length; 6021 while (i--) { 6022 if (parents[i].nodeType === 1 && !isHidden(parents[i])) { 6023 var args = editor.fire('ResolveName', { 6024 name: parents[i].nodeName.toLowerCase(), 6025 target: parents[i] 6026 }); 6027 if (!args.isDefaultPrevented()) { 6028 outParents.push({ 6029 name: args.name, 6030 element: parents[i] 6031 }); 6032 } 6033 if (args.isPropagationStopped()) { 6034 break; 6035 } 6036 } 6037 } 6038 self.row(outParents); 6039 }); 6040 } 6041 return self._super(); 6042 } 6043 }); 6044 6045 var FormItem = Container.extend({ 6046 Defaults: { 6047 layout: 'flex', 6048 align: 'center', 6049 defaults: { flex: 1 } 6050 }, 6051 renderHtml: function () { 6052 var self = this, layout = self._layout, prefix = self.classPrefix; 6053 self.classes.add('formitem'); 6054 layout.preRender(self); 6055 return '<div id="' + self._id + '" class="' + self.classes + '" hidefocus="1" tabindex="-1">' + (self.settings.title ? '<div id="' + self._id + '-title" class="' + prefix + 'title">' + self.settings.title + '</div>' : '') + '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + (self.settings.html || '') + layout.renderHtml(self) + '</div>' + '</div>'; 6056 } 6057 }); 6058 6059 var Form = Container.extend({ 6060 Defaults: { 6061 containerCls: 'form', 6062 layout: 'flex', 6063 direction: 'column', 6064 align: 'stretch', 6065 flex: 1, 6066 padding: 15, 6067 labelGap: 30, 6068 spacing: 10, 6069 callbacks: { 6070 submit: function () { 6071 this.submit(); 6072 } 6073 } 6074 }, 6075 preRender: function () { 6076 var self = this, items = self.items(); 6077 if (!self.settings.formItemDefaults) { 6078 self.settings.formItemDefaults = { 6079 layout: 'flex', 6080 autoResize: 'overflow', 6081 defaults: { flex: 1 } 6082 }; 6083 } 6084 items.each(function (ctrl) { 6085 var formItem; 6086 var label = ctrl.settings.label; 6087 if (label) { 6088 formItem = new FormItem(global$4.extend({ 6089 items: { 6090 type: 'label', 6091 id: ctrl._id + '-l', 6092 text: label, 6093 flex: 0, 6094 forId: ctrl._id, 6095 disabled: ctrl.disabled() 6096 } 6097 }, self.settings.formItemDefaults)); 6098 formItem.type = 'formitem'; 6099 ctrl.aria('labelledby', ctrl._id + '-l'); 6100 if (typeof ctrl.settings.flex === 'undefined') { 6101 ctrl.settings.flex = 1; 6102 } 6103 self.replace(ctrl, formItem); 6104 formItem.add(ctrl); 6105 } 6106 }); 6107 }, 6108 submit: function () { 6109 return this.fire('submit', { data: this.toJSON() }); 6110 }, 6111 postRender: function () { 6112 var self = this; 6113 self._super(); 6114 self.fromJSON(self.settings.data); 6115 }, 6116 bindStates: function () { 6117 var self = this; 6118 self._super(); 6119 function recalcLabels() { 6120 var maxLabelWidth = 0; 6121 var labels = []; 6122 var i, labelGap, items; 6123 if (self.settings.labelGapCalc === false) { 6124 return; 6125 } 6126 if (self.settings.labelGapCalc === 'children') { 6127 items = self.find('formitem'); 6128 } else { 6129 items = self.items(); 6130 } 6131 items.filter('formitem').each(function (item) { 6132 var labelCtrl = item.items()[0], labelWidth = labelCtrl.getEl().clientWidth; 6133 maxLabelWidth = labelWidth > maxLabelWidth ? labelWidth : maxLabelWidth; 6134 labels.push(labelCtrl); 6135 }); 6136 labelGap = self.settings.labelGap || 0; 6137 i = labels.length; 6138 while (i--) { 6139 labels[i].settings.minWidth = maxLabelWidth + labelGap; 6140 } 6141 } 6142 self.on('show', recalcLabels); 6143 recalcLabels(); 6144 } 6145 }); 6146 6147 var FieldSet = Form.extend({ 6148 Defaults: { 6149 containerCls: 'fieldset', 6150 layout: 'flex', 6151 direction: 'column', 6152 align: 'stretch', 6153 flex: 1, 6154 padding: '25 15 5 15', 6155 labelGap: 30, 6156 spacing: 10, 6157 border: 1 6158 }, 6159 renderHtml: function () { 6160 var self = this, layout = self._layout, prefix = self.classPrefix; 6161 self.preRender(); 6162 layout.preRender(self); 6163 return '<fieldset id="' + self._id + '" class="' + self.classes + '" hidefocus="1" tabindex="-1">' + (self.settings.title ? '<legend id="' + self._id + '-title" class="' + prefix + 'fieldset-title">' + self.settings.title + '</legend>' : '') + '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + (self.settings.html || '') + layout.renderHtml(self) + '</div>' + '</fieldset>'; 6164 } 6165 }); 6166 6167 var unique$1 = 0; 6168 var generate = function (prefix) { 6169 var date = new Date(); 6170 var time = date.getTime(); 6171 var random = Math.floor(Math.random() * 1000000000); 6172 unique$1++; 6173 return prefix + '_' + random + unique$1 + String(time); 6174 }; 6175 6176 var fromHtml = function (html, scope) { 6177 var doc = scope || domGlobals.document; 6178 var div = doc.createElement('div'); 6179 div.innerHTML = html; 6180 if (!div.hasChildNodes() || div.childNodes.length > 1) { 6181 domGlobals.console.error('HTML does not have a single root node', html); 6182 throw new Error('HTML must have a single root node'); 6183 } 6184 return fromDom(div.childNodes[0]); 6185 }; 6186 var fromTag = function (tag, scope) { 6187 var doc = scope || domGlobals.document; 6188 var node = doc.createElement(tag); 6189 return fromDom(node); 6190 }; 6191 var fromText = function (text, scope) { 6192 var doc = scope || domGlobals.document; 6193 var node = doc.createTextNode(text); 6194 return fromDom(node); 6195 }; 6196 var fromDom = function (node) { 6197 if (node === null || node === undefined) { 6198 throw new Error('Node cannot be null or undefined'); 6199 } 6200 return { dom: constant(node) }; 6201 }; 6202 var fromPoint = function (docElm, x, y) { 6203 var doc = docElm.dom(); 6204 return Option.from(doc.elementFromPoint(x, y)).map(fromDom); 6205 }; 6206 var Element = { 6207 fromHtml: fromHtml, 6208 fromTag: fromTag, 6209 fromText: fromText, 6210 fromDom: fromDom, 6211 fromPoint: fromPoint 6212 }; 6213 6214 var cached = function (f) { 6215 var called = false; 6216 var r; 6217 return function () { 6218 var args = []; 6219 for (var _i = 0; _i < arguments.length; _i++) { 6220 args[_i] = arguments[_i]; 6221 } 6222 if (!called) { 6223 called = true; 6224 r = f.apply(null, args); 6225 } 6226 return r; 6227 }; 6228 }; 6229 6230 var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE; 6231 var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE; 6232 var COMMENT = domGlobals.Node.COMMENT_NODE; 6233 var DOCUMENT = domGlobals.Node.DOCUMENT_NODE; 6234 var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE; 6235 var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE; 6236 var ELEMENT = domGlobals.Node.ELEMENT_NODE; 6237 var TEXT = domGlobals.Node.TEXT_NODE; 6238 var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE; 6239 var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE; 6240 var ENTITY = domGlobals.Node.ENTITY_NODE; 6241 var NOTATION = domGlobals.Node.NOTATION_NODE; 6242 6243 var Immutable = function () { 6244 var fields = []; 6245 for (var _i = 0; _i < arguments.length; _i++) { 6246 fields[_i] = arguments[_i]; 6247 } 6248 return function () { 6249 var values = []; 6250 for (var _i = 0; _i < arguments.length; _i++) { 6251 values[_i] = arguments[_i]; 6252 } 6253 if (fields.length !== values.length) { 6254 throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments'); 6255 } 6256 var struct = {}; 6257 each(fields, function (name, i) { 6258 struct[name] = constant(values[i]); 6259 }); 6260 return struct; 6261 }; 6262 }; 6263 6264 var node = function () { 6265 var f = Global$1.getOrDie('Node'); 6266 return f; 6267 }; 6268 var compareDocumentPosition = function (a, b, match) { 6269 return (a.compareDocumentPosition(b) & match) !== 0; 6270 }; 6271 var documentPositionPreceding = function (a, b) { 6272 return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_PRECEDING); 6273 }; 6274 var documentPositionContainedBy = function (a, b) { 6275 return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_CONTAINED_BY); 6276 }; 6277 var Node = { 6278 documentPositionPreceding: documentPositionPreceding, 6279 documentPositionContainedBy: documentPositionContainedBy 6280 }; 6281 6282 var firstMatch = function (regexes, s) { 6283 for (var i = 0; i < regexes.length; i++) { 6284 var x = regexes[i]; 6285 if (x.test(s)) { 6286 return x; 6287 } 6288 } 6289 return undefined; 6290 }; 6291 var find$1 = function (regexes, agent) { 6292 var r = firstMatch(regexes, agent); 6293 if (!r) { 6294 return { 6295 major: 0, 6296 minor: 0 6297 }; 6298 } 6299 var group = function (i) { 6300 return Number(agent.replace(r, '$' + i)); 6301 }; 6302 return nu(group(1), group(2)); 6303 }; 6304 var detect = function (versionRegexes, agent) { 6305 var cleanedAgent = String(agent).toLowerCase(); 6306 if (versionRegexes.length === 0) { 6307 return unknown(); 6308 } 6309 return find$1(versionRegexes, cleanedAgent); 6310 }; 6311 var unknown = function () { 6312 return nu(0, 0); 6313 }; 6314 var nu = function (major, minor) { 6315 return { 6316 major: major, 6317 minor: minor 6318 }; 6319 }; 6320 var Version = { 6321 nu: nu, 6322 detect: detect, 6323 unknown: unknown 6324 }; 6325 6326 var edge = 'Edge'; 6327 var chrome = 'Chrome'; 6328 var ie = 'IE'; 6329 var opera = 'Opera'; 6330 var firefox = 'Firefox'; 6331 var safari = 'Safari'; 6332 var isBrowser = function (name, current) { 6333 return function () { 6334 return current === name; 6335 }; 6336 }; 6337 var unknown$1 = function () { 6338 return nu$1({ 6339 current: undefined, 6340 version: Version.unknown() 6341 }); 6342 }; 6343 var nu$1 = function (info) { 6344 var current = info.current; 6345 var version = info.version; 6346 return { 6347 current: current, 6348 version: version, 6349 isEdge: isBrowser(edge, current), 6350 isChrome: isBrowser(chrome, current), 6351 isIE: isBrowser(ie, current), 6352 isOpera: isBrowser(opera, current), 6353 isFirefox: isBrowser(firefox, current), 6354 isSafari: isBrowser(safari, current) 6355 }; 6356 }; 6357 var Browser = { 6358 unknown: unknown$1, 6359 nu: nu$1, 6360 edge: constant(edge), 6361 chrome: constant(chrome), 6362 ie: constant(ie), 6363 opera: constant(opera), 6364 firefox: constant(firefox), 6365 safari: constant(safari) 6366 }; 6367 6368 var windows$1 = 'Windows'; 6369 var ios = 'iOS'; 6370 var android = 'Android'; 6371 var linux = 'Linux'; 6372 var osx = 'OSX'; 6373 var solaris = 'Solaris'; 6374 var freebsd = 'FreeBSD'; 6375 var isOS = function (name, current) { 6376 return function () { 6377 return current === name; 6378 }; 6379 }; 6380 var unknown$2 = function () { 6381 return nu$2({ 6382 current: undefined, 6383 version: Version.unknown() 6384 }); 6385 }; 6386 var nu$2 = function (info) { 6387 var current = info.current; 6388 var version = info.version; 6389 return { 6390 current: current, 6391 version: version, 6392 isWindows: isOS(windows$1, current), 6393 isiOS: isOS(ios, current), 6394 isAndroid: isOS(android, current), 6395 isOSX: isOS(osx, current), 6396 isLinux: isOS(linux, current), 6397 isSolaris: isOS(solaris, current), 6398 isFreeBSD: isOS(freebsd, current) 6399 }; 6400 }; 6401 var OperatingSystem = { 6402 unknown: unknown$2, 6403 nu: nu$2, 6404 windows: constant(windows$1), 6405 ios: constant(ios), 6406 android: constant(android), 6407 linux: constant(linux), 6408 osx: constant(osx), 6409 solaris: constant(solaris), 6410 freebsd: constant(freebsd) 6411 }; 6412 6413 var DeviceType = function (os, browser, userAgent) { 6414 var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true; 6415 var isiPhone = os.isiOS() && !isiPad; 6416 var isAndroid3 = os.isAndroid() && os.version.major === 3; 6417 var isAndroid4 = os.isAndroid() && os.version.major === 4; 6418 var isTablet = isiPad || isAndroid3 || isAndroid4 && /mobile/i.test(userAgent) === true; 6419 var isTouch = os.isiOS() || os.isAndroid(); 6420 var isPhone = isTouch && !isTablet; 6421 var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false; 6422 return { 6423 isiPad: constant(isiPad), 6424 isiPhone: constant(isiPhone), 6425 isTablet: constant(isTablet), 6426 isPhone: constant(isPhone), 6427 isTouch: constant(isTouch), 6428 isAndroid: os.isAndroid, 6429 isiOS: os.isiOS, 6430 isWebView: constant(iOSwebview) 6431 }; 6432 }; 6433 6434 var detect$1 = function (candidates, userAgent) { 6435 var agent = String(userAgent).toLowerCase(); 6436 return find(candidates, function (candidate) { 6437 return candidate.search(agent); 6438 }); 6439 }; 6440 var detectBrowser = function (browsers, userAgent) { 6441 return detect$1(browsers, userAgent).map(function (browser) { 6442 var version = Version.detect(browser.versionRegexes, userAgent); 6443 return { 6444 current: browser.name, 6445 version: version 6446 }; 6447 }); 6448 }; 6449 var detectOs = function (oses, userAgent) { 6450 return detect$1(oses, userAgent).map(function (os) { 6451 var version = Version.detect(os.versionRegexes, userAgent); 6452 return { 6453 current: os.name, 6454 version: version 6455 }; 6456 }); 6457 }; 6458 var UaString = { 6459 detectBrowser: detectBrowser, 6460 detectOs: detectOs 6461 }; 6462 6463 var contains = function (str, substr) { 6464 return str.indexOf(substr) !== -1; 6465 }; 6466 6467 var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/; 6468 var checkContains = function (target) { 6469 return function (uastring) { 6470 return contains(uastring, target); 6471 }; 6472 }; 6473 var browsers = [ 6474 { 6475 name: 'Edge', 6476 versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/], 6477 search: function (uastring) { 6478 return contains(uastring, 'edge/') && contains(uastring, 'chrome') && contains(uastring, 'safari') && contains(uastring, 'applewebkit'); 6479 } 6480 }, 6481 { 6482 name: 'Chrome', 6483 versionRegexes: [ 6484 /.*?chrome\/([0-9]+)\.([0-9]+).*/, 6485 normalVersionRegex 6486 ], 6487 search: function (uastring) { 6488 return contains(uastring, 'chrome') && !contains(uastring, 'chromeframe'); 6489 } 6490 }, 6491 { 6492 name: 'IE', 6493 versionRegexes: [ 6494 /.*?msie\ ?([0-9]+)\.([0-9]+).*/, 6495 /.*?rv:([0-9]+)\.([0-9]+).*/ 6496 ], 6497 search: function (uastring) { 6498 return contains(uastring, 'msie') || contains(uastring, 'trident'); 6499 } 6500 }, 6501 { 6502 name: 'Opera', 6503 versionRegexes: [ 6504 normalVersionRegex, 6505 /.*?opera\/([0-9]+)\.([0-9]+).*/ 6506 ], 6507 search: checkContains('opera') 6508 }, 6509 { 6510 name: 'Firefox', 6511 versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/], 6512 search: checkContains('firefox') 6513 }, 6514 { 6515 name: 'Safari', 6516 versionRegexes: [ 6517 normalVersionRegex, 6518 /.*?cpu os ([0-9]+)_([0-9]+).*/ 6519 ], 6520 search: function (uastring) { 6521 return (contains(uastring, 'safari') || contains(uastring, 'mobile/')) && contains(uastring, 'applewebkit'); 6522 } 6523 } 6524 ]; 6525 var oses = [ 6526 { 6527 name: 'Windows', 6528 search: checkContains('win'), 6529 versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/] 6530 }, 6531 { 6532 name: 'iOS', 6533 search: function (uastring) { 6534 return contains(uastring, 'iphone') || contains(uastring, 'ipad'); 6535 }, 6536 versionRegexes: [ 6537 /.*?version\/\ ?([0-9]+)\.([0-9]+).*/, 6538 /.*cpu os ([0-9]+)_([0-9]+).*/, 6539 /.*cpu iphone os ([0-9]+)_([0-9]+).*/ 6540 ] 6541 }, 6542 { 6543 name: 'Android', 6544 search: checkContains('android'), 6545 versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/] 6546 }, 6547 { 6548 name: 'OSX', 6549 search: checkContains('os x'), 6550 versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/] 6551 }, 6552 { 6553 name: 'Linux', 6554 search: checkContains('linux'), 6555 versionRegexes: [] 6556 }, 6557 { 6558 name: 'Solaris', 6559 search: checkContains('sunos'), 6560 versionRegexes: [] 6561 }, 6562 { 6563 name: 'FreeBSD', 6564 search: checkContains('freebsd'), 6565 versionRegexes: [] 6566 } 6567 ]; 6568 var PlatformInfo = { 6569 browsers: constant(browsers), 6570 oses: constant(oses) 6571 }; 6572 6573 var detect$2 = function (userAgent) { 6574 var browsers = PlatformInfo.browsers(); 6575 var oses = PlatformInfo.oses(); 6576 var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu); 6577 var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu); 6578 var deviceType = DeviceType(os, browser, userAgent); 6579 return { 6580 browser: browser, 6581 os: os, 6582 deviceType: deviceType 6583 }; 6584 }; 6585 var PlatformDetection = { detect: detect$2 }; 6586 6587 var detect$3 = cached(function () { 6588 var userAgent = domGlobals.navigator.userAgent; 6589 return PlatformDetection.detect(userAgent); 6590 }); 6591 var PlatformDetection$1 = { detect: detect$3 }; 6592 6593 var ELEMENT$1 = ELEMENT; 6594 var DOCUMENT$1 = DOCUMENT; 6595 var bypassSelector = function (dom) { 6596 return dom.nodeType !== ELEMENT$1 && dom.nodeType !== DOCUMENT$1 || dom.childElementCount === 0; 6597 }; 6598 var all = function (selector, scope) { 6599 var base = scope === undefined ? domGlobals.document : scope.dom(); 6600 return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), Element.fromDom); 6601 }; 6602 var one = function (selector, scope) { 6603 var base = scope === undefined ? domGlobals.document : scope.dom(); 6604 return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom); 6605 }; 6606 6607 var regularContains = function (e1, e2) { 6608 var d1 = e1.dom(); 6609 var d2 = e2.dom(); 6610 return d1 === d2 ? false : d1.contains(d2); 6611 }; 6612 var ieContains = function (e1, e2) { 6613 return Node.documentPositionContainedBy(e1.dom(), e2.dom()); 6614 }; 6615 var browser = PlatformDetection$1.detect().browser; 6616 var contains$1 = browser.isIE() ? ieContains : regularContains; 6617 6618 var spot = Immutable('element', 'offset'); 6619 6620 var descendants = function (scope, selector) { 6621 return all(selector, scope); 6622 }; 6623 6624 var trim = global$4.trim; 6625 var hasContentEditableState = function (value) { 6626 return function (node) { 6627 if (node && node.nodeType === 1) { 6628 if (node.contentEditable === value) { 6629 return true; 6630 } 6631 if (node.getAttribute('data-mce-contenteditable') === value) { 6632 return true; 6633 } 6634 } 6635 return false; 6636 }; 6637 }; 6638 var isContentEditableTrue = hasContentEditableState('true'); 6639 var isContentEditableFalse = hasContentEditableState('false'); 6640 var create$4 = function (type, title, url, level, attach) { 6641 return { 6642 type: type, 6643 title: title, 6644 url: url, 6645 level: level, 6646 attach: attach 6647 }; 6648 }; 6649 var isChildOfContentEditableTrue = function (node) { 6650 while (node = node.parentNode) { 6651 var value = node.contentEditable; 6652 if (value && value !== 'inherit') { 6653 return isContentEditableTrue(node); 6654 } 6655 } 6656 return false; 6657 }; 6658 var select = function (selector, root) { 6659 return map(descendants(Element.fromDom(root), selector), function (element) { 6660 return element.dom(); 6661 }); 6662 }; 6663 var getElementText = function (elm) { 6664 return elm.innerText || elm.textContent; 6665 }; 6666 var getOrGenerateId = function (elm) { 6667 return elm.id ? elm.id : generate('h'); 6668 }; 6669 var isAnchor = function (elm) { 6670 return elm && elm.nodeName === 'A' && (elm.id || elm.name); 6671 }; 6672 var isValidAnchor = function (elm) { 6673 return isAnchor(elm) && isEditable(elm); 6674 }; 6675 var isHeader = function (elm) { 6676 return elm && /^(H[1-6])$/.test(elm.nodeName); 6677 }; 6678 var isEditable = function (elm) { 6679 return isChildOfContentEditableTrue(elm) && !isContentEditableFalse(elm); 6680 }; 6681 var isValidHeader = function (elm) { 6682 return isHeader(elm) && isEditable(elm); 6683 }; 6684 var getLevel = function (elm) { 6685 return isHeader(elm) ? parseInt(elm.nodeName.substr(1), 10) : 0; 6686 }; 6687 var headerTarget = function (elm) { 6688 var headerId = getOrGenerateId(elm); 6689 var attach = function () { 6690 elm.id = headerId; 6691 }; 6692 return create$4('header', getElementText(elm), '#' + headerId, getLevel(elm), attach); 6693 }; 6694 var anchorTarget = function (elm) { 6695 var anchorId = elm.id || elm.name; 6696 var anchorText = getElementText(elm); 6697 return create$4('anchor', anchorText ? anchorText : '#' + anchorId, '#' + anchorId, 0, noop); 6698 }; 6699 var getHeaderTargets = function (elms) { 6700 return map(filter(elms, isValidHeader), headerTarget); 6701 }; 6702 var getAnchorTargets = function (elms) { 6703 return map(filter(elms, isValidAnchor), anchorTarget); 6704 }; 6705 var getTargetElements = function (elm) { 6706 var elms = select('h1,h2,h3,h4,h5,h6,a:not([href])', elm); 6707 return elms; 6708 }; 6709 var hasTitle = function (target) { 6710 return trim(target.title).length > 0; 6711 }; 6712 var find$2 = function (elm) { 6713 var elms = getTargetElements(elm); 6714 return filter(getHeaderTargets(elms).concat(getAnchorTargets(elms)), hasTitle); 6715 }; 6716 var LinkTargets = { find: find$2 }; 6717 6718 var getActiveEditor = function () { 6719 return window.tinymce ? window.tinymce.activeEditor : global$5.activeEditor; 6720 }; 6721 var history = {}; 6722 var HISTORY_LENGTH = 5; 6723 var clearHistory = function () { 6724 history = {}; 6725 }; 6726 var toMenuItem = function (target) { 6727 return { 6728 title: target.title, 6729 value: { 6730 title: { raw: target.title }, 6731 url: target.url, 6732 attach: target.attach 6733 } 6734 }; 6735 }; 6736 var toMenuItems = function (targets) { 6737 return global$4.map(targets, toMenuItem); 6738 }; 6739 var staticMenuItem = function (title, url) { 6740 return { 6741 title: title, 6742 value: { 6743 title: title, 6744 url: url, 6745 attach: noop 6746 } 6747 }; 6748 }; 6749 var isUniqueUrl = function (url, targets) { 6750 var foundTarget = exists(targets, function (target) { 6751 return target.url === url; 6752 }); 6753 return !foundTarget; 6754 }; 6755 var getSetting = function (editorSettings, name, defaultValue) { 6756 var value = name in editorSettings ? editorSettings[name] : defaultValue; 6757 return value === false ? null : value; 6758 }; 6759 var createMenuItems = function (term, targets, fileType, editorSettings) { 6760 var separator = { title: '-' }; 6761 var fromHistoryMenuItems = function (history) { 6762 var historyItems = history.hasOwnProperty(fileType) ? history[fileType] : []; 6763 var uniqueHistory = filter(historyItems, function (url) { 6764 return isUniqueUrl(url, targets); 6765 }); 6766 return global$4.map(uniqueHistory, function (url) { 6767 return { 6768 title: url, 6769 value: { 6770 title: url, 6771 url: url, 6772 attach: noop 6773 } 6774 }; 6775 }); 6776 }; 6777 var fromMenuItems = function (type) { 6778 var filteredTargets = filter(targets, function (target) { 6779 return target.type === type; 6780 }); 6781 return toMenuItems(filteredTargets); 6782 }; 6783 var anchorMenuItems = function () { 6784 var anchorMenuItems = fromMenuItems('anchor'); 6785 var topAnchor = getSetting(editorSettings, 'anchor_top', '#top'); 6786 var bottomAchor = getSetting(editorSettings, 'anchor_bottom', '#bottom'); 6787 if (topAnchor !== null) { 6788 anchorMenuItems.unshift(staticMenuItem('<top>', topAnchor)); 6789 } 6790 if (bottomAchor !== null) { 6791 anchorMenuItems.push(staticMenuItem('<bottom>', bottomAchor)); 6792 } 6793 return anchorMenuItems; 6794 }; 6795 var join = function (items) { 6796 return foldl(items, function (a, b) { 6797 var bothEmpty = a.length === 0 || b.length === 0; 6798 return bothEmpty ? a.concat(b) : a.concat(separator, b); 6799 }, []); 6800 }; 6801 if (editorSettings.typeahead_urls === false) { 6802 return []; 6803 } 6804 return fileType === 'file' ? join([ 6805 filterByQuery(term, fromHistoryMenuItems(history)), 6806 filterByQuery(term, fromMenuItems('header')), 6807 filterByQuery(term, anchorMenuItems()) 6808 ]) : filterByQuery(term, fromHistoryMenuItems(history)); 6809 }; 6810 var addToHistory = function (url, fileType) { 6811 var items = history[fileType]; 6812 if (!/^https?/.test(url)) { 6813 return; 6814 } 6815 if (items) { 6816 if (indexOf(items, url).isNone()) { 6817 history[fileType] = items.slice(0, HISTORY_LENGTH).concat(url); 6818 } 6819 } else { 6820 history[fileType] = [url]; 6821 } 6822 }; 6823 var filterByQuery = function (term, menuItems) { 6824 var lowerCaseTerm = term.toLowerCase(); 6825 var result = global$4.grep(menuItems, function (item) { 6826 return item.title.toLowerCase().indexOf(lowerCaseTerm) !== -1; 6827 }); 6828 return result.length === 1 && result[0].title === term ? [] : result; 6829 }; 6830 var getTitle = function (linkDetails) { 6831 var title = linkDetails.title; 6832 return title.raw ? title.raw : title; 6833 }; 6834 var setupAutoCompleteHandler = function (ctrl, editorSettings, bodyElm, fileType) { 6835 var autocomplete = function (term) { 6836 var linkTargets = LinkTargets.find(bodyElm); 6837 var menuItems = createMenuItems(term, linkTargets, fileType, editorSettings); 6838 ctrl.showAutoComplete(menuItems, term); 6839 }; 6840 ctrl.on('autocomplete', function () { 6841 autocomplete(ctrl.value()); 6842 }); 6843 ctrl.on('selectitem', function (e) { 6844 var linkDetails = e.value; 6845 ctrl.value(linkDetails.url); 6846 var title = getTitle(linkDetails); 6847 if (fileType === 'image') { 6848 ctrl.fire('change', { 6849 meta: { 6850 alt: title, 6851 attach: linkDetails.attach 6852 } 6853 }); 6854 } else { 6855 ctrl.fire('change', { 6856 meta: { 6857 text: title, 6858 attach: linkDetails.attach 6859 } 6860 }); 6861 } 6862 ctrl.focus(); 6863 }); 6864 ctrl.on('click', function (e) { 6865 if (ctrl.value().length === 0 && e.target.nodeName === 'INPUT') { 6866 autocomplete(''); 6867 } 6868 }); 6869 ctrl.on('PostRender', function () { 6870 ctrl.getRoot().on('submit', function (e) { 6871 if (!e.isDefaultPrevented()) { 6872 addToHistory(ctrl.value(), fileType); 6873 } 6874 }); 6875 }); 6876 }; 6877 var statusToUiState = function (result) { 6878 var status = result.status, message = result.message; 6879 if (status === 'valid') { 6880 return { 6881 status: 'ok', 6882 message: message 6883 }; 6884 } else if (status === 'unknown') { 6885 return { 6886 status: 'warn', 6887 message: message 6888 }; 6889 } else if (status === 'invalid') { 6890 return { 6891 status: 'warn', 6892 message: message 6893 }; 6894 } else { 6895 return { 6896 status: 'none', 6897 message: '' 6898 }; 6899 } 6900 }; 6901 var setupLinkValidatorHandler = function (ctrl, editorSettings, fileType) { 6902 var validatorHandler = editorSettings.filepicker_validator_handler; 6903 if (validatorHandler) { 6904 var validateUrl_1 = function (url) { 6905 if (url.length === 0) { 6906 ctrl.statusLevel('none'); 6907 return; 6908 } 6909 validatorHandler({ 6910 url: url, 6911 type: fileType 6912 }, function (result) { 6913 var uiState = statusToUiState(result); 6914 ctrl.statusMessage(uiState.message); 6915 ctrl.statusLevel(uiState.status); 6916 }); 6917 }; 6918 ctrl.state.on('change:value', function (e) { 6919 validateUrl_1(e.value); 6920 }); 6921 } 6922 }; 6923 var FilePicker = ComboBox.extend({ 6924 Statics: { clearHistory: clearHistory }, 6925 init: function (settings) { 6926 var self = this, editor = getActiveEditor(), editorSettings = editor.settings; 6927 var actionCallback, fileBrowserCallback, fileBrowserCallbackTypes; 6928 var fileType = settings.filetype; 6929 settings.spellcheck = false; 6930 fileBrowserCallbackTypes = editorSettings.file_picker_types || editorSettings.file_browser_callback_types; 6931 if (fileBrowserCallbackTypes) { 6932 fileBrowserCallbackTypes = global$4.makeMap(fileBrowserCallbackTypes, /[, ]/); 6933 } 6934 if (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[fileType]) { 6935 fileBrowserCallback = editorSettings.file_picker_callback; 6936 if (fileBrowserCallback && (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[fileType])) { 6937 actionCallback = function () { 6938 var meta = self.fire('beforecall').meta; 6939 meta = global$4.extend({ filetype: fileType }, meta); 6940 fileBrowserCallback.call(editor, function (value, meta) { 6941 self.value(value).fire('change', { meta: meta }); 6942 }, self.value(), meta); 6943 }; 6944 } else { 6945 fileBrowserCallback = editorSettings.file_browser_callback; 6946 if (fileBrowserCallback && (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[fileType])) { 6947 actionCallback = function () { 6948 fileBrowserCallback(self.getEl('inp').id, self.value(), fileType, window); 6949 }; 6950 } 6951 } 6952 } 6953 if (actionCallback) { 6954 settings.icon = 'browse'; 6955 settings.onaction = actionCallback; 6956 } 6957 self._super(settings); 6958 self.classes.add('filepicker'); 6959 setupAutoCompleteHandler(self, editorSettings, editor.getBody(), fileType); 6960 setupLinkValidatorHandler(self, editorSettings, fileType); 6961 } 6962 }); 6963 6964 var FitLayout = AbsoluteLayout.extend({ 6965 recalc: function (container) { 6966 var contLayoutRect = container.layoutRect(), paddingBox = container.paddingBox; 6967 container.items().filter(':visible').each(function (ctrl) { 6968 ctrl.layoutRect({ 6969 x: paddingBox.left, 6970 y: paddingBox.top, 6971 w: contLayoutRect.innerW - paddingBox.right - paddingBox.left, 6972 h: contLayoutRect.innerH - paddingBox.top - paddingBox.bottom 6973 }); 6974 if (ctrl.recalc) { 6975 ctrl.recalc(); 6976 } 6977 }); 6978 } 6979 }); 6980 6981 var FlexLayout = AbsoluteLayout.extend({ 6982 recalc: function (container) { 6983 var i, l, items, contLayoutRect, contPaddingBox, contSettings, align, pack, spacing, totalFlex, availableSpace, direction; 6984 var ctrl, ctrlLayoutRect, ctrlSettings, flex; 6985 var maxSizeItems = []; 6986 var size, maxSize, ratio, rect, pos, maxAlignEndPos; 6987 var sizeName, minSizeName, posName, maxSizeName, beforeName, innerSizeName, deltaSizeName, contentSizeName; 6988 var alignAxisName, alignInnerSizeName, alignSizeName, alignMinSizeName, alignBeforeName, alignAfterName; 6989 var alignDeltaSizeName, alignContentSizeName; 6990 var max = Math.max, min = Math.min; 6991 items = container.items().filter(':visible'); 6992 contLayoutRect = container.layoutRect(); 6993 contPaddingBox = container.paddingBox; 6994 contSettings = container.settings; 6995 direction = container.isRtl() ? contSettings.direction || 'row-reversed' : contSettings.direction; 6996 align = contSettings.align; 6997 pack = container.isRtl() ? contSettings.pack || 'end' : contSettings.pack; 6998 spacing = contSettings.spacing || 0; 6999 if (direction === 'row-reversed' || direction === 'column-reverse') { 7000 items = items.set(items.toArray().reverse()); 7001 direction = direction.split('-')[0]; 7002 } 7003 if (direction === 'column') { 7004 posName = 'y'; 7005 sizeName = 'h'; 7006 minSizeName = 'minH'; 7007 maxSizeName = 'maxH'; 7008 innerSizeName = 'innerH'; 7009 beforeName = 'top'; 7010 deltaSizeName = 'deltaH'; 7011 contentSizeName = 'contentH'; 7012 alignBeforeName = 'left'; 7013 alignSizeName = 'w'; 7014 alignAxisName = 'x'; 7015 alignInnerSizeName = 'innerW'; 7016 alignMinSizeName = 'minW'; 7017 alignAfterName = 'right'; 7018 alignDeltaSizeName = 'deltaW'; 7019 alignContentSizeName = 'contentW'; 7020 } else { 7021 posName = 'x'; 7022 sizeName = 'w'; 7023 minSizeName = 'minW'; 7024 maxSizeName = 'maxW'; 7025 innerSizeName = 'innerW'; 7026 beforeName = 'left'; 7027 deltaSizeName = 'deltaW'; 7028 contentSizeName = 'contentW'; 7029 alignBeforeName = 'top'; 7030 alignSizeName = 'h'; 7031 alignAxisName = 'y'; 7032 alignInnerSizeName = 'innerH'; 7033 alignMinSizeName = 'minH'; 7034 alignAfterName = 'bottom'; 7035 alignDeltaSizeName = 'deltaH'; 7036 alignContentSizeName = 'contentH'; 7037 } 7038 availableSpace = contLayoutRect[innerSizeName] - contPaddingBox[beforeName] - contPaddingBox[beforeName]; 7039 maxAlignEndPos = totalFlex = 0; 7040 for (i = 0, l = items.length; i < l; i++) { 7041 ctrl = items[i]; 7042 ctrlLayoutRect = ctrl.layoutRect(); 7043 ctrlSettings = ctrl.settings; 7044 flex = ctrlSettings.flex; 7045 availableSpace -= i < l - 1 ? spacing : 0; 7046 if (flex > 0) { 7047 totalFlex += flex; 7048 if (ctrlLayoutRect[maxSizeName]) { 7049 maxSizeItems.push(ctrl); 7050 } 7051 ctrlLayoutRect.flex = flex; 7052 } 7053 availableSpace -= ctrlLayoutRect[minSizeName]; 7054 size = contPaddingBox[alignBeforeName] + ctrlLayoutRect[alignMinSizeName] + contPaddingBox[alignAfterName]; 7055 if (size > maxAlignEndPos) { 7056 maxAlignEndPos = size; 7057 } 7058 } 7059 rect = {}; 7060 if (availableSpace < 0) { 7061 rect[minSizeName] = contLayoutRect[minSizeName] - availableSpace + contLayoutRect[deltaSizeName]; 7062 } else { 7063 rect[minSizeName] = contLayoutRect[innerSizeName] - availableSpace + contLayoutRect[deltaSizeName]; 7064 } 7065 rect[alignMinSizeName] = maxAlignEndPos + contLayoutRect[alignDeltaSizeName]; 7066 rect[contentSizeName] = contLayoutRect[innerSizeName] - availableSpace; 7067 rect[alignContentSizeName] = maxAlignEndPos; 7068 rect.minW = min(rect.minW, contLayoutRect.maxW); 7069 rect.minH = min(rect.minH, contLayoutRect.maxH); 7070 rect.minW = max(rect.minW, contLayoutRect.startMinWidth); 7071 rect.minH = max(rect.minH, contLayoutRect.startMinHeight); 7072 if (contLayoutRect.autoResize && (rect.minW !== contLayoutRect.minW || rect.minH !== contLayoutRect.minH)) { 7073 rect.w = rect.minW; 7074 rect.h = rect.minH; 7075 container.layoutRect(rect); 7076 this.recalc(container); 7077 if (container._lastRect === null) { 7078 var parentCtrl = container.parent(); 7079 if (parentCtrl) { 7080 parentCtrl._lastRect = null; 7081 parentCtrl.recalc(); 7082 } 7083 } 7084 return; 7085 } 7086 ratio = availableSpace / totalFlex; 7087 for (i = 0, l = maxSizeItems.length; i < l; i++) { 7088 ctrl = maxSizeItems[i]; 7089 ctrlLayoutRect = ctrl.layoutRect(); 7090 maxSize = ctrlLayoutRect[maxSizeName]; 7091 size = ctrlLayoutRect[minSizeName] + ctrlLayoutRect.flex * ratio; 7092 if (size > maxSize) { 7093 availableSpace -= ctrlLayoutRect[maxSizeName] - ctrlLayoutRect[minSizeName]; 7094 totalFlex -= ctrlLayoutRect.flex; 7095 ctrlLayoutRect.flex = 0; 7096 ctrlLayoutRect.maxFlexSize = maxSize; 7097 } else { 7098 ctrlLayoutRect.maxFlexSize = 0; 7099 } 7100 } 7101 ratio = availableSpace / totalFlex; 7102 pos = contPaddingBox[beforeName]; 7103 rect = {}; 7104 if (totalFlex === 0) { 7105 if (pack === 'end') { 7106 pos = availableSpace + contPaddingBox[beforeName]; 7107 } else if (pack === 'center') { 7108 pos = Math.round(contLayoutRect[innerSizeName] / 2 - (contLayoutRect[innerSizeName] - availableSpace) / 2) + contPaddingBox[beforeName]; 7109 if (pos < 0) { 7110 pos = contPaddingBox[beforeName]; 7111 } 7112 } else if (pack === 'justify') { 7113 pos = contPaddingBox[beforeName]; 7114 spacing = Math.floor(availableSpace / (items.length - 1)); 7115 } 7116 } 7117 rect[alignAxisName] = contPaddingBox[alignBeforeName]; 7118 for (i = 0, l = items.length; i < l; i++) { 7119 ctrl = items[i]; 7120 ctrlLayoutRect = ctrl.layoutRect(); 7121 size = ctrlLayoutRect.maxFlexSize || ctrlLayoutRect[minSizeName]; 7122 if (align === 'center') { 7123 rect[alignAxisName] = Math.round(contLayoutRect[alignInnerSizeName] / 2 - ctrlLayoutRect[alignSizeName] / 2); 7124 } else if (align === 'stretch') { 7125 rect[alignSizeName] = max(ctrlLayoutRect[alignMinSizeName] || 0, contLayoutRect[alignInnerSizeName] - contPaddingBox[alignBeforeName] - contPaddingBox[alignAfterName]); 7126 rect[alignAxisName] = contPaddingBox[alignBeforeName]; 7127 } else if (align === 'end') { 7128 rect[alignAxisName] = contLayoutRect[alignInnerSizeName] - ctrlLayoutRect[alignSizeName] - contPaddingBox.top; 7129 } 7130 if (ctrlLayoutRect.flex > 0) { 7131 size += ctrlLayoutRect.flex * ratio; 7132 } 7133 rect[sizeName] = size; 7134 rect[posName] = pos; 7135 ctrl.layoutRect(rect); 7136 if (ctrl.recalc) { 7137 ctrl.recalc(); 7138 } 7139 pos += size + spacing; 7140 } 7141 } 7142 }); 7143 7144 var FlowLayout = Layout$1.extend({ 7145 Defaults: { 7146 containerClass: 'flow-layout', 7147 controlClass: 'flow-layout-item', 7148 endClass: 'break' 7149 }, 7150 recalc: function (container) { 7151 container.items().filter(':visible').each(function (ctrl) { 7152 if (ctrl.recalc) { 7153 ctrl.recalc(); 7154 } 7155 }); 7156 }, 7157 isNative: function () { 7158 return true; 7159 } 7160 }); 7161 7162 var descendant = function (scope, selector) { 7163 return one(selector, scope); 7164 }; 7165 7166 var toggleFormat = function (editor, fmt) { 7167 return function () { 7168 editor.execCommand('mceToggleFormat', false, fmt); 7169 }; 7170 }; 7171 var addFormatChangedListener = function (editor, name, changed) { 7172 var handler = function (state) { 7173 changed(state, name); 7174 }; 7175 if (editor.formatter) { 7176 editor.formatter.formatChanged(name, handler); 7177 } else { 7178 editor.on('init', function () { 7179 editor.formatter.formatChanged(name, handler); 7180 }); 7181 } 7182 }; 7183 var postRenderFormatToggle = function (editor, name) { 7184 return function (e) { 7185 addFormatChangedListener(editor, name, function (state) { 7186 e.control.active(state); 7187 }); 7188 }; 7189 }; 7190 7191 var register = function (editor) { 7192 var alignFormats = [ 7193 'alignleft', 7194 'aligncenter', 7195 'alignright', 7196 'alignjustify' 7197 ]; 7198 var defaultAlign = 'alignleft'; 7199 var alignMenuItems = [ 7200 { 7201 text: 'Left', 7202 icon: 'alignleft', 7203 onclick: toggleFormat(editor, 'alignleft') 7204 }, 7205 { 7206 text: 'Center', 7207 icon: 'aligncenter', 7208 onclick: toggleFormat(editor, 'aligncenter') 7209 }, 7210 { 7211 text: 'Right', 7212 icon: 'alignright', 7213 onclick: toggleFormat(editor, 'alignright') 7214 }, 7215 { 7216 text: 'Justify', 7217 icon: 'alignjustify', 7218 onclick: toggleFormat(editor, 'alignjustify') 7219 } 7220 ]; 7221 editor.addMenuItem('align', { 7222 text: 'Align', 7223 menu: alignMenuItems 7224 }); 7225 editor.addButton('align', { 7226 type: 'menubutton', 7227 icon: defaultAlign, 7228 menu: alignMenuItems, 7229 onShowMenu: function (e) { 7230 var menu = e.control.menu; 7231 global$4.each(alignFormats, function (formatName, idx) { 7232 menu.items().eq(idx).each(function (item) { 7233 return item.active(editor.formatter.match(formatName)); 7234 }); 7235 }); 7236 }, 7237 onPostRender: function (e) { 7238 var ctrl = e.control; 7239 global$4.each(alignFormats, function (formatName, idx) { 7240 addFormatChangedListener(editor, formatName, function (state) { 7241 ctrl.icon(defaultAlign); 7242 if (state) { 7243 ctrl.icon(formatName); 7244 } 7245 }); 7246 }); 7247 } 7248 }); 7249 global$4.each({ 7250 alignleft: [ 7251 'Align left', 7252 'JustifyLeft' 7253 ], 7254 aligncenter: [ 7255 'Align center', 7256 'JustifyCenter' 7257 ], 7258 alignright: [ 7259 'Align right', 7260 'JustifyRight' 7261 ], 7262 alignjustify: [ 7263 'Justify', 7264 'JustifyFull' 7265 ], 7266 alignnone: [ 7267 'No alignment', 7268 'JustifyNone' 7269 ] 7270 }, function (item, name) { 7271 editor.addButton(name, { 7272 active: false, 7273 tooltip: item[0], 7274 cmd: item[1], 7275 onPostRender: postRenderFormatToggle(editor, name) 7276 }); 7277 }); 7278 }; 7279 var Align = { register: register }; 7280 7281 var getFirstFont = function (fontFamily) { 7282 return fontFamily ? fontFamily.split(',')[0] : ''; 7283 }; 7284 var findMatchingValue = function (items, fontFamily) { 7285 var font = fontFamily ? fontFamily.toLowerCase() : ''; 7286 var value; 7287 global$4.each(items, function (item) { 7288 if (item.value.toLowerCase() === font) { 7289 value = item.value; 7290 } 7291 }); 7292 global$4.each(items, function (item) { 7293 if (!value && getFirstFont(item.value).toLowerCase() === getFirstFont(font).toLowerCase()) { 7294 value = item.value; 7295 } 7296 }); 7297 return value; 7298 }; 7299 var createFontNameListBoxChangeHandler = function (editor, items) { 7300 return function () { 7301 var self = this; 7302 self.state.set('value', null); 7303 editor.on('init nodeChange', function (e) { 7304 var fontFamily = editor.queryCommandValue('FontName'); 7305 var match = findMatchingValue(items, fontFamily); 7306 self.value(match ? match : null); 7307 if (!match && fontFamily) { 7308 self.text(getFirstFont(fontFamily)); 7309 } 7310 }); 7311 }; 7312 }; 7313 var createFormats = function (formats) { 7314 formats = formats.replace(/;$/, '').split(';'); 7315 var i = formats.length; 7316 while (i--) { 7317 formats[i] = formats[i].split('='); 7318 } 7319 return formats; 7320 }; 7321 var getFontItems = function (editor) { 7322 var defaultFontsFormats = 'Andale Mono=andale mono,monospace;' + 'Arial=arial,helvetica,sans-serif;' + 'Arial Black=arial black,sans-serif;' + 'Book Antiqua=book antiqua,palatino,serif;' + 'Comic Sans MS=comic sans ms,sans-serif;' + 'Courier New=courier new,courier,monospace;' + 'Georgia=georgia,palatino,serif;' + 'Helvetica=helvetica,arial,sans-serif;' + 'Impact=impact,sans-serif;' + 'Symbol=symbol;' + 'Tahoma=tahoma,arial,helvetica,sans-serif;' + 'Terminal=terminal,monaco,monospace;' + 'Times New Roman=times new roman,times,serif;' + 'Trebuchet MS=trebuchet ms,geneva,sans-serif;' + 'Verdana=verdana,geneva,sans-serif;' + 'Webdings=webdings;' + 'Wingdings=wingdings,zapf dingbats'; 7323 var fonts = createFormats(editor.settings.font_formats || defaultFontsFormats); 7324 return global$4.map(fonts, function (font) { 7325 return { 7326 text: { raw: font[0] }, 7327 value: font[1], 7328 textStyle: font[1].indexOf('dings') === -1 ? 'font-family:' + font[1] : '' 7329 }; 7330 }); 7331 }; 7332 var registerButtons = function (editor) { 7333 editor.addButton('fontselect', function () { 7334 var items = getFontItems(editor); 7335 return { 7336 type: 'listbox', 7337 text: 'Font Family', 7338 tooltip: 'Font Family', 7339 values: items, 7340 fixedWidth: true, 7341 onPostRender: createFontNameListBoxChangeHandler(editor, items), 7342 onselect: function (e) { 7343 if (e.control.settings.value) { 7344 editor.execCommand('FontName', false, e.control.settings.value); 7345 } 7346 } 7347 }; 7348 }); 7349 }; 7350 var register$1 = function (editor) { 7351 registerButtons(editor); 7352 }; 7353 var FontSelect = { register: register$1 }; 7354 7355 var round = function (number, precision) { 7356 var factor = Math.pow(10, precision); 7357 return Math.round(number * factor) / factor; 7358 }; 7359 var toPt = function (fontSize, precision) { 7360 if (/[0-9.]+px$/.test(fontSize)) { 7361 return round(parseInt(fontSize, 10) * 72 / 96, precision || 0) + 'pt'; 7362 } 7363 return fontSize; 7364 }; 7365 var findMatchingValue$1 = function (items, pt, px) { 7366 var value; 7367 global$4.each(items, function (item) { 7368 if (item.value === px) { 7369 value = px; 7370 } else if (item.value === pt) { 7371 value = pt; 7372 } 7373 }); 7374 return value; 7375 }; 7376 var createFontSizeListBoxChangeHandler = function (editor, items) { 7377 return function () { 7378 var self = this; 7379 editor.on('init nodeChange', function (e) { 7380 var px, pt, precision, match; 7381 px = editor.queryCommandValue('FontSize'); 7382 if (px) { 7383 for (precision = 3; !match && precision >= 0; precision--) { 7384 pt = toPt(px, precision); 7385 match = findMatchingValue$1(items, pt, px); 7386 } 7387 } 7388 self.value(match ? match : null); 7389 if (!match) { 7390 self.text(pt); 7391 } 7392 }); 7393 }; 7394 }; 7395 var getFontSizeItems = function (editor) { 7396 var defaultFontsizeFormats = '8pt 10pt 12pt 14pt 18pt 24pt 36pt'; 7397 var fontsizeFormats = editor.settings.fontsize_formats || defaultFontsizeFormats; 7398 return global$4.map(fontsizeFormats.split(' '), function (item) { 7399 var text = item, value = item; 7400 var values = item.split('='); 7401 if (values.length > 1) { 7402 text = values[0]; 7403 value = values[1]; 7404 } 7405 return { 7406 text: text, 7407 value: value 7408 }; 7409 }); 7410 }; 7411 var registerButtons$1 = function (editor) { 7412 editor.addButton('fontsizeselect', function () { 7413 var items = getFontSizeItems(editor); 7414 return { 7415 type: 'listbox', 7416 text: 'Font Sizes', 7417 tooltip: 'Font Sizes', 7418 values: items, 7419 fixedWidth: true, 7420 onPostRender: createFontSizeListBoxChangeHandler(editor, items), 7421 onclick: function (e) { 7422 if (e.control.settings.value) { 7423 editor.execCommand('FontSize', false, e.control.settings.value); 7424 } 7425 } 7426 }; 7427 }); 7428 }; 7429 var register$2 = function (editor) { 7430 registerButtons$1(editor); 7431 }; 7432 var FontSizeSelect = { register: register$2 }; 7433 7434 var hideMenuObjects = function (editor, menu) { 7435 var count = menu.length; 7436 global$4.each(menu, function (item) { 7437 if (item.menu) { 7438 item.hidden = hideMenuObjects(editor, item.menu) === 0; 7439 } 7440 var formatName = item.format; 7441 if (formatName) { 7442 item.hidden = !editor.formatter.canApply(formatName); 7443 } 7444 if (item.hidden) { 7445 count--; 7446 } 7447 }); 7448 return count; 7449 }; 7450 var hideFormatMenuItems = function (editor, menu) { 7451 var count = menu.items().length; 7452 menu.items().each(function (item) { 7453 if (item.menu) { 7454 item.visible(hideFormatMenuItems(editor, item.menu) > 0); 7455 } 7456 if (!item.menu && item.settings.menu) { 7457 item.visible(hideMenuObjects(editor, item.settings.menu) > 0); 7458 } 7459 var formatName = item.settings.format; 7460 if (formatName) { 7461 item.visible(editor.formatter.canApply(formatName)); 7462 } 7463 if (!item.visible()) { 7464 count--; 7465 } 7466 }); 7467 return count; 7468 }; 7469 var createFormatMenu = function (editor) { 7470 var count = 0; 7471 var newFormats = []; 7472 var defaultStyleFormats = [ 7473 { 7474 title: 'Headings', 7475 items: [ 7476 { 7477 title: 'Heading 1', 7478 format: 'h1' 7479 }, 7480 { 7481 title: 'Heading 2', 7482 format: 'h2' 7483 }, 7484 { 7485 title: 'Heading 3', 7486 format: 'h3' 7487 }, 7488 { 7489 title: 'Heading 4', 7490 format: 'h4' 7491 }, 7492 { 7493 title: 'Heading 5', 7494 format: 'h5' 7495 }, 7496 { 7497 title: 'Heading 6', 7498 format: 'h6' 7499 } 7500 ] 7501 }, 7502 { 7503 title: 'Inline', 7504 items: [ 7505 { 7506 title: 'Bold', 7507 icon: 'bold', 7508 format: 'bold' 7509 }, 7510 { 7511 title: 'Italic', 7512 icon: 'italic', 7513 format: 'italic' 7514 }, 7515 { 7516 title: 'Underline', 7517 icon: 'underline', 7518 format: 'underline' 7519 }, 7520 { 7521 title: 'Strikethrough', 7522 icon: 'strikethrough', 7523 format: 'strikethrough' 7524 }, 7525 { 7526 title: 'Superscript', 7527 icon: 'superscript', 7528 format: 'superscript' 7529 }, 7530 { 7531 title: 'Subscript', 7532 icon: 'subscript', 7533 format: 'subscript' 7534 }, 7535 { 7536 title: 'Code', 7537 icon: 'code', 7538 format: 'code' 7539 } 7540 ] 7541 }, 7542 { 7543 title: 'Blocks', 7544 items: [ 7545 { 7546 title: 'Paragraph', 7547 format: 'p' 7548 }, 7549 { 7550 title: 'Blockquote', 7551 format: 'blockquote' 7552 }, 7553 { 7554 title: 'Div', 7555 format: 'div' 7556 }, 7557 { 7558 title: 'Pre', 7559 format: 'pre' 7560 } 7561 ] 7562 }, 7563 { 7564 title: 'Alignment', 7565 items: [ 7566 { 7567 title: 'Left', 7568 icon: 'alignleft', 7569 format: 'alignleft' 7570 }, 7571 { 7572 title: 'Center', 7573 icon: 'aligncenter', 7574 format: 'aligncenter' 7575 }, 7576 { 7577 title: 'Right', 7578 icon: 'alignright', 7579 format: 'alignright' 7580 }, 7581 { 7582 title: 'Justify', 7583 icon: 'alignjustify', 7584 format: 'alignjustify' 7585 } 7586 ] 7587 } 7588 ]; 7589 var createMenu = function (formats) { 7590 var menu = []; 7591 if (!formats) { 7592 return; 7593 } 7594 global$4.each(formats, function (format) { 7595 var menuItem = { 7596 text: format.title, 7597 icon: format.icon 7598 }; 7599 if (format.items) { 7600 menuItem.menu = createMenu(format.items); 7601 } else { 7602 var formatName = format.format || 'custom' + count++; 7603 if (!format.format) { 7604 format.name = formatName; 7605 newFormats.push(format); 7606 } 7607 menuItem.format = formatName; 7608 menuItem.cmd = format.cmd; 7609 } 7610 menu.push(menuItem); 7611 }); 7612 return menu; 7613 }; 7614 var createStylesMenu = function () { 7615 var menu; 7616 if (editor.settings.style_formats_merge) { 7617 if (editor.settings.style_formats) { 7618 menu = createMenu(defaultStyleFormats.concat(editor.settings.style_formats)); 7619 } else { 7620 menu = createMenu(defaultStyleFormats); 7621 } 7622 } else { 7623 menu = createMenu(editor.settings.style_formats || defaultStyleFormats); 7624 } 7625 return menu; 7626 }; 7627 editor.on('init', function () { 7628 global$4.each(newFormats, function (format) { 7629 editor.formatter.register(format.name, format); 7630 }); 7631 }); 7632 return { 7633 type: 'menu', 7634 items: createStylesMenu(), 7635 onPostRender: function (e) { 7636 editor.fire('renderFormatsMenu', { control: e.control }); 7637 }, 7638 itemDefaults: { 7639 preview: true, 7640 textStyle: function () { 7641 if (this.settings.format) { 7642 return editor.formatter.getCssText(this.settings.format); 7643 } 7644 }, 7645 onPostRender: function () { 7646 var self = this; 7647 self.parent().on('show', function () { 7648 var formatName, command; 7649 formatName = self.settings.format; 7650 if (formatName) { 7651 self.disabled(!editor.formatter.canApply(formatName)); 7652 self.active(editor.formatter.match(formatName)); 7653 } 7654 command = self.settings.cmd; 7655 if (command) { 7656 self.active(editor.queryCommandState(command)); 7657 } 7658 }); 7659 }, 7660 onclick: function () { 7661 if (this.settings.format) { 7662 toggleFormat(editor, this.settings.format)(); 7663 } 7664 if (this.settings.cmd) { 7665 editor.execCommand(this.settings.cmd); 7666 } 7667 } 7668 } 7669 }; 7670 }; 7671 var registerMenuItems = function (editor, formatMenu) { 7672 editor.addMenuItem('formats', { 7673 text: 'Formats', 7674 menu: formatMenu 7675 }); 7676 }; 7677 var registerButtons$2 = function (editor, formatMenu) { 7678 editor.addButton('styleselect', { 7679 type: 'menubutton', 7680 text: 'Formats', 7681 menu: formatMenu, 7682 onShowMenu: function () { 7683 if (editor.settings.style_formats_autohide) { 7684 hideFormatMenuItems(editor, this.menu); 7685 } 7686 } 7687 }); 7688 }; 7689 var register$3 = function (editor) { 7690 var formatMenu = createFormatMenu(editor); 7691 registerMenuItems(editor, formatMenu); 7692 registerButtons$2(editor, formatMenu); 7693 }; 7694 var Formats = { register: register$3 }; 7695 7696 var defaultBlocks = 'Paragraph=p;' + 'Heading 1=h1;' + 'Heading 2=h2;' + 'Heading 3=h3;' + 'Heading 4=h4;' + 'Heading 5=h5;' + 'Heading 6=h6;' + 'Preformatted=pre'; 7697 var createFormats$1 = function (formats) { 7698 formats = formats.replace(/;$/, '').split(';'); 7699 var i = formats.length; 7700 while (i--) { 7701 formats[i] = formats[i].split('='); 7702 } 7703 return formats; 7704 }; 7705 var createListBoxChangeHandler = function (editor, items, formatName) { 7706 return function () { 7707 var self = this; 7708 editor.on('nodeChange', function (e) { 7709 var formatter = editor.formatter; 7710 var value = null; 7711 global$4.each(e.parents, function (node) { 7712 global$4.each(items, function (item) { 7713 if (formatName) { 7714 if (formatter.matchNode(node, formatName, { value: item.value })) { 7715 value = item.value; 7716 } 7717 } else { 7718 if (formatter.matchNode(node, item.value)) { 7719 value = item.value; 7720 } 7721 } 7722 if (value) { 7723 return false; 7724 } 7725 }); 7726 if (value) { 7727 return false; 7728 } 7729 }); 7730 self.value(value); 7731 }); 7732 }; 7733 }; 7734 var lazyFormatSelectBoxItems = function (editor, blocks) { 7735 return function () { 7736 var items = []; 7737 global$4.each(blocks, function (block) { 7738 items.push({ 7739 text: block[0], 7740 value: block[1], 7741 textStyle: function () { 7742 return editor.formatter.getCssText(block[1]); 7743 } 7744 }); 7745 }); 7746 return { 7747 type: 'listbox', 7748 text: blocks[0][0], 7749 values: items, 7750 fixedWidth: true, 7751 onselect: function (e) { 7752 if (e.control) { 7753 var fmt = e.control.value(); 7754 toggleFormat(editor, fmt)(); 7755 } 7756 }, 7757 onPostRender: createListBoxChangeHandler(editor, items) 7758 }; 7759 }; 7760 }; 7761 var buildMenuItems = function (editor, blocks) { 7762 return global$4.map(blocks, function (block) { 7763 return { 7764 text: block[0], 7765 onclick: toggleFormat(editor, block[1]), 7766 textStyle: function () { 7767 return editor.formatter.getCssText(block[1]); 7768 } 7769 }; 7770 }); 7771 }; 7772 var register$4 = function (editor) { 7773 var blocks = createFormats$1(editor.settings.block_formats || defaultBlocks); 7774 editor.addMenuItem('blockformats', { 7775 text: 'Blocks', 7776 menu: buildMenuItems(editor, blocks) 7777 }); 7778 editor.addButton('formatselect', lazyFormatSelectBoxItems(editor, blocks)); 7779 }; 7780 var FormatSelect = { register: register$4 }; 7781 7782 var createCustomMenuItems = function (editor, names) { 7783 var items, nameList; 7784 if (typeof names === 'string') { 7785 nameList = names.split(' '); 7786 } else if (global$4.isArray(names)) { 7787 return flatten$1(global$4.map(names, function (names) { 7788 return createCustomMenuItems(editor, names); 7789 })); 7790 } 7791 items = global$4.grep(nameList, function (name) { 7792 return name === '|' || name in editor.menuItems; 7793 }); 7794 return global$4.map(items, function (name) { 7795 return name === '|' ? { text: '-' } : editor.menuItems[name]; 7796 }); 7797 }; 7798 var isSeparator = function (menuItem) { 7799 return menuItem && menuItem.text === '-'; 7800 }; 7801 var trimMenuItems = function (menuItems) { 7802 var menuItems2 = filter(menuItems, function (menuItem, i) { 7803 return !isSeparator(menuItem) || !isSeparator(menuItems[i - 1]); 7804 }); 7805 return filter(menuItems2, function (menuItem, i) { 7806 return !isSeparator(menuItem) || i > 0 && i < menuItems2.length - 1; 7807 }); 7808 }; 7809 var createContextMenuItems = function (editor, context) { 7810 var outputMenuItems = [{ text: '-' }]; 7811 var menuItems = global$4.grep(editor.menuItems, function (menuItem) { 7812 return menuItem.context === context; 7813 }); 7814 global$4.each(menuItems, function (menuItem) { 7815 if (menuItem.separator === 'before') { 7816 outputMenuItems.push({ text: '|' }); 7817 } 7818 if (menuItem.prependToContext) { 7819 outputMenuItems.unshift(menuItem); 7820 } else { 7821 outputMenuItems.push(menuItem); 7822 } 7823 if (menuItem.separator === 'after') { 7824 outputMenuItems.push({ text: '|' }); 7825 } 7826 }); 7827 return outputMenuItems; 7828 }; 7829 var createInsertMenu = function (editor) { 7830 var insertButtonItems = editor.settings.insert_button_items; 7831 if (insertButtonItems) { 7832 return trimMenuItems(createCustomMenuItems(editor, insertButtonItems)); 7833 } else { 7834 return trimMenuItems(createContextMenuItems(editor, 'insert')); 7835 } 7836 }; 7837 var registerButtons$3 = function (editor) { 7838 editor.addButton('insert', { 7839 type: 'menubutton', 7840 icon: 'insert', 7841 menu: [], 7842 oncreatemenu: function () { 7843 this.menu.add(createInsertMenu(editor)); 7844 this.menu.renderNew(); 7845 } 7846 }); 7847 }; 7848 var register$5 = function (editor) { 7849 registerButtons$3(editor); 7850 }; 7851 var InsertButton = { register: register$5 }; 7852 7853 var registerFormatButtons = function (editor) { 7854 global$4.each({ 7855 bold: 'Bold', 7856 italic: 'Italic', 7857 underline: 'Underline', 7858 strikethrough: 'Strikethrough', 7859 subscript: 'Subscript', 7860 superscript: 'Superscript' 7861 }, function (text, name) { 7862 editor.addButton(name, { 7863 active: false, 7864 tooltip: text, 7865 onPostRender: postRenderFormatToggle(editor, name), 7866 onclick: toggleFormat(editor, name) 7867 }); 7868 }); 7869 }; 7870 var registerCommandButtons = function (editor) { 7871 global$4.each({ 7872 outdent: [ 7873 'Decrease indent', 7874 'Outdent' 7875 ], 7876 indent: [ 7877 'Increase indent', 7878 'Indent' 7879 ], 7880 cut: [ 7881 'Cut', 7882 'Cut' 7883 ], 7884 copy: [ 7885 'Copy', 7886 'Copy' 7887 ], 7888 paste: [ 7889 'Paste', 7890 'Paste' 7891 ], 7892 help: [ 7893 'Help', 7894 'mceHelp' 7895 ], 7896 selectall: [ 7897 'Select all', 7898 'SelectAll' 7899 ], 7900 visualaid: [ 7901 'Visual aids', 7902 'mceToggleVisualAid' 7903 ], 7904 newdocument: [ 7905 'New document', 7906 'mceNewDocument' 7907 ], 7908 removeformat: [ 7909 'Clear formatting', 7910 'RemoveFormat' 7911 ], 7912 remove: [ 7913 'Remove', 7914 'Delete' 7915 ] 7916 }, function (item, name) { 7917 editor.addButton(name, { 7918 tooltip: item[0], 7919 cmd: item[1] 7920 }); 7921 }); 7922 }; 7923 var registerCommandToggleButtons = function (editor) { 7924 global$4.each({ 7925 blockquote: [ 7926 'Blockquote', 7927 'mceBlockQuote' 7928 ], 7929 subscript: [ 7930 'Subscript', 7931 'Subscript' 7932 ], 7933 superscript: [ 7934 'Superscript', 7935 'Superscript' 7936 ] 7937 }, function (item, name) { 7938 editor.addButton(name, { 7939 active: false, 7940 tooltip: item[0], 7941 cmd: item[1], 7942 onPostRender: postRenderFormatToggle(editor, name) 7943 }); 7944 }); 7945 }; 7946 var registerButtons$4 = function (editor) { 7947 registerFormatButtons(editor); 7948 registerCommandButtons(editor); 7949 registerCommandToggleButtons(editor); 7950 }; 7951 var registerMenuItems$1 = function (editor) { 7952 global$4.each({ 7953 bold: [ 7954 'Bold', 7955 'Bold', 7956 'Meta+B' 7957 ], 7958 italic: [ 7959 'Italic', 7960 'Italic', 7961 'Meta+I' 7962 ], 7963 underline: [ 7964 'Underline', 7965 'Underline', 7966 'Meta+U' 7967 ], 7968 strikethrough: [ 7969 'Strikethrough', 7970 'Strikethrough' 7971 ], 7972 subscript: [ 7973 'Subscript', 7974 'Subscript' 7975 ], 7976 superscript: [ 7977 'Superscript', 7978 'Superscript' 7979 ], 7980 removeformat: [ 7981 'Clear formatting', 7982 'RemoveFormat' 7983 ], 7984 newdocument: [ 7985 'New document', 7986 'mceNewDocument' 7987 ], 7988 cut: [ 7989 'Cut', 7990 'Cut', 7991 'Meta+X' 7992 ], 7993 copy: [ 7994 'Copy', 7995 'Copy', 7996 'Meta+C' 7997 ], 7998 paste: [ 7999 'Paste', 8000 'Paste', 8001 'Meta+V' 8002 ], 8003 selectall: [ 8004 'Select all', 8005 'SelectAll', 8006 'Meta+A' 8007 ] 8008 }, function (item, name) { 8009 editor.addMenuItem(name, { 8010 text: item[0], 8011 icon: name, 8012 shortcut: item[2], 8013 cmd: item[1] 8014 }); 8015 }); 8016 editor.addMenuItem('codeformat', { 8017 text: 'Code', 8018 icon: 'code', 8019 onclick: toggleFormat(editor, 'code') 8020 }); 8021 }; 8022 var register$6 = function (editor) { 8023 registerButtons$4(editor); 8024 registerMenuItems$1(editor); 8025 }; 8026 var SimpleControls = { register: register$6 }; 8027 8028 var toggleUndoRedoState = function (editor, type) { 8029 return function () { 8030 var self = this; 8031 var checkState = function () { 8032 var typeFn = type === 'redo' ? 'hasRedo' : 'hasUndo'; 8033 return editor.undoManager ? editor.undoManager[typeFn]() : false; 8034 }; 8035 self.disabled(!checkState()); 8036 editor.on('Undo Redo AddUndo TypingUndo ClearUndos SwitchMode', function () { 8037 self.disabled(editor.readonly || !checkState()); 8038 }); 8039 }; 8040 }; 8041 var registerMenuItems$2 = function (editor) { 8042 editor.addMenuItem('undo', { 8043 text: 'Undo', 8044 icon: 'undo', 8045 shortcut: 'Meta+Z', 8046 onPostRender: toggleUndoRedoState(editor, 'undo'), 8047 cmd: 'undo' 8048 }); 8049 editor.addMenuItem('redo', { 8050 text: 'Redo', 8051 icon: 'redo', 8052 shortcut: 'Meta+Y', 8053 onPostRender: toggleUndoRedoState(editor, 'redo'), 8054 cmd: 'redo' 8055 }); 8056 }; 8057 var registerButtons$5 = function (editor) { 8058 editor.addButton('undo', { 8059 tooltip: 'Undo', 8060 onPostRender: toggleUndoRedoState(editor, 'undo'), 8061 cmd: 'undo' 8062 }); 8063 editor.addButton('redo', { 8064 tooltip: 'Redo', 8065 onPostRender: toggleUndoRedoState(editor, 'redo'), 8066 cmd: 'redo' 8067 }); 8068 }; 8069 var register$7 = function (editor) { 8070 registerMenuItems$2(editor); 8071 registerButtons$5(editor); 8072 }; 8073 var UndoRedo = { register: register$7 }; 8074 8075 var toggleVisualAidState = function (editor) { 8076 return function () { 8077 var self = this; 8078 editor.on('VisualAid', function (e) { 8079 self.active(e.hasVisual); 8080 }); 8081 self.active(editor.hasVisual); 8082 }; 8083 }; 8084 var registerMenuItems$3 = function (editor) { 8085 editor.addMenuItem('visualaid', { 8086 text: 'Visual aids', 8087 selectable: true, 8088 onPostRender: toggleVisualAidState(editor), 8089 cmd: 'mceToggleVisualAid' 8090 }); 8091 }; 8092 var register$8 = function (editor) { 8093 registerMenuItems$3(editor); 8094 }; 8095 var VisualAid = { register: register$8 }; 8096 8097 var setupEnvironment = function () { 8098 Widget.tooltips = !global$1.iOS; 8099 Control$1.translate = function (text) { 8100 return global$5.translate(text); 8101 }; 8102 }; 8103 var setupUiContainer = function (editor) { 8104 if (editor.settings.ui_container) { 8105 global$1.container = descendant(Element.fromDom(domGlobals.document.body), editor.settings.ui_container).fold(constant(null), function (elm) { 8106 return elm.dom(); 8107 }); 8108 } 8109 }; 8110 var setupRtlMode = function (editor) { 8111 if (editor.rtl) { 8112 Control$1.rtl = true; 8113 } 8114 }; 8115 var setupHideFloatPanels = function (editor) { 8116 editor.on('mousedown progressstate', function () { 8117 FloatPanel.hideAll(); 8118 }); 8119 }; 8120 var setup = function (editor) { 8121 setupRtlMode(editor); 8122 setupHideFloatPanels(editor); 8123 setupUiContainer(editor); 8124 setupEnvironment(); 8125 FormatSelect.register(editor); 8126 Align.register(editor); 8127 SimpleControls.register(editor); 8128 UndoRedo.register(editor); 8129 FontSizeSelect.register(editor); 8130 FontSelect.register(editor); 8131 Formats.register(editor); 8132 VisualAid.register(editor); 8133 InsertButton.register(editor); 8134 }; 8135 var FormatControls = { setup: setup }; 8136 8137 var GridLayout = AbsoluteLayout.extend({ 8138 recalc: function (container) { 8139 var settings, rows, cols, items, contLayoutRect, width, height, rect, ctrlLayoutRect, ctrl, x, y, posX, posY, ctrlSettings, contPaddingBox, align, spacingH, spacingV, alignH, alignV, maxX, maxY; 8140 var colWidths = []; 8141 var rowHeights = []; 8142 var ctrlMinWidth, ctrlMinHeight, availableWidth, availableHeight, reverseRows, idx; 8143 settings = container.settings; 8144 items = container.items().filter(':visible'); 8145 contLayoutRect = container.layoutRect(); 8146 cols = settings.columns || Math.ceil(Math.sqrt(items.length)); 8147 rows = Math.ceil(items.length / cols); 8148 spacingH = settings.spacingH || settings.spacing || 0; 8149 spacingV = settings.spacingV || settings.spacing || 0; 8150 alignH = settings.alignH || settings.align; 8151 alignV = settings.alignV || settings.align; 8152 contPaddingBox = container.paddingBox; 8153 reverseRows = 'reverseRows' in settings ? settings.reverseRows : container.isRtl(); 8154 if (alignH && typeof alignH === 'string') { 8155 alignH = [alignH]; 8156 } 8157 if (alignV && typeof alignV === 'string') { 8158 alignV = [alignV]; 8159 } 8160 for (x = 0; x < cols; x++) { 8161 colWidths.push(0); 8162 } 8163 for (y = 0; y < rows; y++) { 8164 rowHeights.push(0); 8165 } 8166 for (y = 0; y < rows; y++) { 8167 for (x = 0; x < cols; x++) { 8168 ctrl = items[y * cols + x]; 8169 if (!ctrl) { 8170 break; 8171 } 8172 ctrlLayoutRect = ctrl.layoutRect(); 8173 ctrlMinWidth = ctrlLayoutRect.minW; 8174 ctrlMinHeight = ctrlLayoutRect.minH; 8175 colWidths[x] = ctrlMinWidth > colWidths[x] ? ctrlMinWidth : colWidths[x]; 8176 rowHeights[y] = ctrlMinHeight > rowHeights[y] ? ctrlMinHeight : rowHeights[y]; 8177 } 8178 } 8179 availableWidth = contLayoutRect.innerW - contPaddingBox.left - contPaddingBox.right; 8180 for (maxX = 0, x = 0; x < cols; x++) { 8181 maxX += colWidths[x] + (x > 0 ? spacingH : 0); 8182 availableWidth -= (x > 0 ? spacingH : 0) + colWidths[x]; 8183 } 8184 availableHeight = contLayoutRect.innerH - contPaddingBox.top - contPaddingBox.bottom; 8185 for (maxY = 0, y = 0; y < rows; y++) { 8186 maxY += rowHeights[y] + (y > 0 ? spacingV : 0); 8187 availableHeight -= (y > 0 ? spacingV : 0) + rowHeights[y]; 8188 } 8189 maxX += contPaddingBox.left + contPaddingBox.right; 8190 maxY += contPaddingBox.top + contPaddingBox.bottom; 8191 rect = {}; 8192 rect.minW = maxX + (contLayoutRect.w - contLayoutRect.innerW); 8193 rect.minH = maxY + (contLayoutRect.h - contLayoutRect.innerH); 8194 rect.contentW = rect.minW - contLayoutRect.deltaW; 8195 rect.contentH = rect.minH - contLayoutRect.deltaH; 8196 rect.minW = Math.min(rect.minW, contLayoutRect.maxW); 8197 rect.minH = Math.min(rect.minH, contLayoutRect.maxH); 8198 rect.minW = Math.max(rect.minW, contLayoutRect.startMinWidth); 8199 rect.minH = Math.max(rect.minH, contLayoutRect.startMinHeight); 8200 if (contLayoutRect.autoResize && (rect.minW !== contLayoutRect.minW || rect.minH !== contLayoutRect.minH)) { 8201 rect.w = rect.minW; 8202 rect.h = rect.minH; 8203 container.layoutRect(rect); 8204 this.recalc(container); 8205 if (container._lastRect === null) { 8206 var parentCtrl = container.parent(); 8207 if (parentCtrl) { 8208 parentCtrl._lastRect = null; 8209 parentCtrl.recalc(); 8210 } 8211 } 8212 return; 8213 } 8214 if (contLayoutRect.autoResize) { 8215 rect = container.layoutRect(rect); 8216 rect.contentW = rect.minW - contLayoutRect.deltaW; 8217 rect.contentH = rect.minH - contLayoutRect.deltaH; 8218 } 8219 var flexV; 8220 if (settings.packV === 'start') { 8221 flexV = 0; 8222 } else { 8223 flexV = availableHeight > 0 ? Math.floor(availableHeight / rows) : 0; 8224 } 8225 var totalFlex = 0; 8226 var flexWidths = settings.flexWidths; 8227 if (flexWidths) { 8228 for (x = 0; x < flexWidths.length; x++) { 8229 totalFlex += flexWidths[x]; 8230 } 8231 } else { 8232 totalFlex = cols; 8233 } 8234 var ratio = availableWidth / totalFlex; 8235 for (x = 0; x < cols; x++) { 8236 colWidths[x] += flexWidths ? flexWidths[x] * ratio : ratio; 8237 } 8238 posY = contPaddingBox.top; 8239 for (y = 0; y < rows; y++) { 8240 posX = contPaddingBox.left; 8241 height = rowHeights[y] + flexV; 8242 for (x = 0; x < cols; x++) { 8243 if (reverseRows) { 8244 idx = y * cols + cols - 1 - x; 8245 } else { 8246 idx = y * cols + x; 8247 } 8248 ctrl = items[idx]; 8249 if (!ctrl) { 8250 break; 8251 } 8252 ctrlSettings = ctrl.settings; 8253 ctrlLayoutRect = ctrl.layoutRect(); 8254 width = Math.max(colWidths[x], ctrlLayoutRect.startMinWidth); 8255 ctrlLayoutRect.x = posX; 8256 ctrlLayoutRect.y = posY; 8257 align = ctrlSettings.alignH || (alignH ? alignH[x] || alignH[0] : null); 8258 if (align === 'center') { 8259 ctrlLayoutRect.x = posX + width / 2 - ctrlLayoutRect.w / 2; 8260 } else if (align === 'right') { 8261 ctrlLayoutRect.x = posX + width - ctrlLayoutRect.w; 8262 } else if (align === 'stretch') { 8263 ctrlLayoutRect.w = width; 8264 } 8265 align = ctrlSettings.alignV || (alignV ? alignV[x] || alignV[0] : null); 8266 if (align === 'center') { 8267 ctrlLayoutRect.y = posY + height / 2 - ctrlLayoutRect.h / 2; 8268 } else if (align === 'bottom') { 8269 ctrlLayoutRect.y = posY + height - ctrlLayoutRect.h; 8270 } else if (align === 'stretch') { 8271 ctrlLayoutRect.h = height; 8272 } 8273 ctrl.layoutRect(ctrlLayoutRect); 8274 posX += width + spacingH; 8275 if (ctrl.recalc) { 8276 ctrl.recalc(); 8277 } 8278 } 8279 posY += height + spacingV; 8280 } 8281 } 8282 }); 8283 8284 var Iframe = Widget.extend({ 8285 renderHtml: function () { 8286 var self = this; 8287 self.classes.add('iframe'); 8288 self.canFocus = false; 8289 return '<iframe id="' + self._id + '" class="' + self.classes + '" tabindex="-1" src="' + (self.settings.url || 'javascript:\'\'') + '" frameborder="0"></iframe>'; 8290 }, 8291 src: function (src) { 8292 this.getEl().src = src; 8293 }, 8294 html: function (html, callback) { 8295 var self = this, body = this.getEl().contentWindow.document.body; 8296 if (!body) { 8297 global$3.setTimeout(function () { 8298 self.html(html); 8299 }); 8300 } else { 8301 body.innerHTML = html; 8302 if (callback) { 8303 callback(); 8304 } 8305 } 8306 return this; 8307 } 8308 }); 8309 8310 var InfoBox = Widget.extend({ 8311 init: function (settings) { 8312 var self = this; 8313 self._super(settings); 8314 self.classes.add('widget').add('infobox'); 8315 self.canFocus = false; 8316 }, 8317 severity: function (level) { 8318 this.classes.remove('error'); 8319 this.classes.remove('warning'); 8320 this.classes.remove('success'); 8321 this.classes.add(level); 8322 }, 8323 help: function (state) { 8324 this.state.set('help', state); 8325 }, 8326 renderHtml: function () { 8327 var self = this, prefix = self.classPrefix; 8328 return '<div id="' + self._id + '" class="' + self.classes + '">' + '<div id="' + self._id + '-body">' + self.encode(self.state.get('text')) + '<button role="button" tabindex="-1">' + '<i class="' + prefix + 'ico ' + prefix + 'i-help"></i>' + '</button>' + '</div>' + '</div>'; 8329 }, 8330 bindStates: function () { 8331 var self = this; 8332 self.state.on('change:text', function (e) { 8333 self.getEl('body').firstChild.data = self.encode(e.value); 8334 if (self.state.get('rendered')) { 8335 self.updateLayoutRect(); 8336 } 8337 }); 8338 self.state.on('change:help', function (e) { 8339 self.classes.toggle('has-help', e.value); 8340 if (self.state.get('rendered')) { 8341 self.updateLayoutRect(); 8342 } 8343 }); 8344 return self._super(); 8345 } 8346 }); 8347 8348 var Label = Widget.extend({ 8349 init: function (settings) { 8350 var self = this; 8351 self._super(settings); 8352 self.classes.add('widget').add('label'); 8353 self.canFocus = false; 8354 if (settings.multiline) { 8355 self.classes.add('autoscroll'); 8356 } 8357 if (settings.strong) { 8358 self.classes.add('strong'); 8359 } 8360 }, 8361 initLayoutRect: function () { 8362 var self = this, layoutRect = self._super(); 8363 if (self.settings.multiline) { 8364 var size = funcs.getSize(self.getEl()); 8365 if (size.width > layoutRect.maxW) { 8366 layoutRect.minW = layoutRect.maxW; 8367 self.classes.add('multiline'); 8368 } 8369 self.getEl().style.width = layoutRect.minW + 'px'; 8370 layoutRect.startMinH = layoutRect.h = layoutRect.minH = Math.min(layoutRect.maxH, funcs.getSize(self.getEl()).height); 8371 } 8372 return layoutRect; 8373 }, 8374 repaint: function () { 8375 var self = this; 8376 if (!self.settings.multiline) { 8377 self.getEl().style.lineHeight = self.layoutRect().h + 'px'; 8378 } 8379 return self._super(); 8380 }, 8381 severity: function (level) { 8382 this.classes.remove('error'); 8383 this.classes.remove('warning'); 8384 this.classes.remove('success'); 8385 this.classes.add(level); 8386 }, 8387 renderHtml: function () { 8388 var self = this; 8389 var targetCtrl, forName, forId = self.settings.forId; 8390 var text = self.settings.html ? self.settings.html : self.encode(self.state.get('text')); 8391 if (!forId && (forName = self.settings.forName)) { 8392 targetCtrl = self.getRoot().find('#' + forName)[0]; 8393 if (targetCtrl) { 8394 forId = targetCtrl._id; 8395 } 8396 } 8397 if (forId) { 8398 return '<label id="' + self._id + '" class="' + self.classes + '"' + (forId ? ' for="' + forId + '"' : '') + '>' + text + '</label>'; 8399 } 8400 return '<span id="' + self._id + '" class="' + self.classes + '">' + text + '</span>'; 8401 }, 8402 bindStates: function () { 8403 var self = this; 8404 self.state.on('change:text', function (e) { 8405 self.innerHtml(self.encode(e.value)); 8406 if (self.state.get('rendered')) { 8407 self.updateLayoutRect(); 8408 } 8409 }); 8410 return self._super(); 8411 } 8412 }); 8413 8414 var Toolbar$1 = Container.extend({ 8415 Defaults: { 8416 role: 'toolbar', 8417 layout: 'flow' 8418 }, 8419 init: function (settings) { 8420 var self = this; 8421 self._super(settings); 8422 self.classes.add('toolbar'); 8423 }, 8424 postRender: function () { 8425 var self = this; 8426 self.items().each(function (ctrl) { 8427 ctrl.classes.add('toolbar-item'); 8428 }); 8429 return self._super(); 8430 } 8431 }); 8432 8433 var MenuBar = Toolbar$1.extend({ 8434 Defaults: { 8435 role: 'menubar', 8436 containerCls: 'menubar', 8437 ariaRoot: true, 8438 defaults: { type: 'menubutton' } 8439 } 8440 }); 8441 8442 function isChildOf$1(node, parent) { 8443 while (node) { 8444 if (parent === node) { 8445 return true; 8446 } 8447 node = node.parentNode; 8448 } 8449 return false; 8450 } 8451 var MenuButton = Button.extend({ 8452 init: function (settings) { 8453 var self = this; 8454 self._renderOpen = true; 8455 self._super(settings); 8456 settings = self.settings; 8457 self.classes.add('menubtn'); 8458 if (settings.fixedWidth) { 8459 self.classes.add('fixed-width'); 8460 } 8461 self.aria('haspopup', true); 8462 self.state.set('menu', settings.menu || self.render()); 8463 }, 8464 showMenu: function (toggle) { 8465 var self = this; 8466 var menu; 8467 if (self.menu && self.menu.visible() && toggle !== false) { 8468 return self.hideMenu(); 8469 } 8470 if (!self.menu) { 8471 menu = self.state.get('menu') || []; 8472 self.classes.add('opened'); 8473 if (menu.length) { 8474 menu = { 8475 type: 'menu', 8476 animate: true, 8477 items: menu 8478 }; 8479 } else { 8480 menu.type = menu.type || 'menu'; 8481 menu.animate = true; 8482 } 8483 if (!menu.renderTo) { 8484 self.menu = global$b.create(menu).parent(self).renderTo(); 8485 } else { 8486 self.menu = menu.parent(self).show().renderTo(); 8487 } 8488 self.fire('createmenu'); 8489 self.menu.reflow(); 8490 self.menu.on('cancel', function (e) { 8491 if (e.control.parent() === self.menu) { 8492 e.stopPropagation(); 8493 self.focus(); 8494 self.hideMenu(); 8495 } 8496 }); 8497 self.menu.on('select', function () { 8498 self.focus(); 8499 }); 8500 self.menu.on('show hide', function (e) { 8501 if (e.type === 'hide' && e.control.parent() === self) { 8502 self.classes.remove('opened-under'); 8503 } 8504 if (e.control === self.menu) { 8505 self.activeMenu(e.type === 'show'); 8506 self.classes.toggle('opened', e.type === 'show'); 8507 } 8508 self.aria('expanded', e.type === 'show'); 8509 }).fire('show'); 8510 } 8511 self.menu.show(); 8512 self.menu.layoutRect({ w: self.layoutRect().w }); 8513 self.menu.repaint(); 8514 self.menu.moveRel(self.getEl(), self.isRtl() ? [ 8515 'br-tr', 8516 'tr-br' 8517 ] : [ 8518 'bl-tl', 8519 'tl-bl' 8520 ]); 8521 var menuLayoutRect = self.menu.layoutRect(); 8522 var selfBottom = self.$el.offset().top + self.layoutRect().h; 8523 if (selfBottom > menuLayoutRect.y && selfBottom < menuLayoutRect.y + menuLayoutRect.h) { 8524 self.classes.add('opened-under'); 8525 } 8526 self.fire('showmenu'); 8527 }, 8528 hideMenu: function () { 8529 var self = this; 8530 if (self.menu) { 8531 self.menu.items().each(function (item) { 8532 if (item.hideMenu) { 8533 item.hideMenu(); 8534 } 8535 }); 8536 self.menu.hide(); 8537 } 8538 }, 8539 activeMenu: function (state) { 8540 this.classes.toggle('active', state); 8541 }, 8542 renderHtml: function () { 8543 var self = this, id = self._id, prefix = self.classPrefix; 8544 var icon = self.settings.icon, image; 8545 var text = self.state.get('text'); 8546 var textHtml = ''; 8547 image = self.settings.image; 8548 if (image) { 8549 icon = 'none'; 8550 if (typeof image !== 'string') { 8551 image = domGlobals.window.getSelection ? image[0] : image[1]; 8552 } 8553 image = ' style="background-image: url(\'' + image + '\')"'; 8554 } else { 8555 image = ''; 8556 } 8557 if (text) { 8558 self.classes.add('btn-has-text'); 8559 textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>'; 8560 } 8561 icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + icon : ''; 8562 self.aria('role', self.parent() instanceof MenuBar ? 'menuitem' : 'button'); 8563 return '<div id="' + id + '" class="' + self.classes + '" tabindex="-1" aria-labelledby="' + id + '">' + '<button id="' + id + '-open" role="presentation" type="button" tabindex="-1">' + (icon ? '<i class="' + icon + '"' + image + '></i>' : '') + textHtml + ' <i class="' + prefix + 'caret"></i>' + '</button>' + '</div>'; 8564 }, 8565 postRender: function () { 8566 var self = this; 8567 self.on('click', function (e) { 8568 if (e.control === self && isChildOf$1(e.target, self.getEl())) { 8569 self.focus(); 8570 self.showMenu(!e.aria); 8571 if (e.aria) { 8572 self.menu.items().filter(':visible')[0].focus(); 8573 } 8574 } 8575 }); 8576 self.on('mouseenter', function (e) { 8577 var overCtrl = e.control; 8578 var parent = self.parent(); 8579 var hasVisibleSiblingMenu; 8580 if (overCtrl && parent && overCtrl instanceof MenuButton && overCtrl.parent() === parent) { 8581 parent.items().filter('MenuButton').each(function (ctrl) { 8582 if (ctrl.hideMenu && ctrl !== overCtrl) { 8583 if (ctrl.menu && ctrl.menu.visible()) { 8584 hasVisibleSiblingMenu = true; 8585 } 8586 ctrl.hideMenu(); 8587 } 8588 }); 8589 if (hasVisibleSiblingMenu) { 8590 overCtrl.focus(); 8591 overCtrl.showMenu(); 8592 } 8593 } 8594 }); 8595 return self._super(); 8596 }, 8597 bindStates: function () { 8598 var self = this; 8599 self.state.on('change:menu', function () { 8600 if (self.menu) { 8601 self.menu.remove(); 8602 } 8603 self.menu = null; 8604 }); 8605 return self._super(); 8606 }, 8607 remove: function () { 8608 this._super(); 8609 if (this.menu) { 8610 this.menu.remove(); 8611 } 8612 } 8613 }); 8614 8615 function Throbber (elm, inline) { 8616 var self = this; 8617 var state; 8618 var classPrefix = Control$1.classPrefix; 8619 var timer; 8620 self.show = function (time, callback) { 8621 function render() { 8622 if (state) { 8623 global$7(elm).append('<div class="' + classPrefix + 'throbber' + (inline ? ' ' + classPrefix + 'throbber-inline' : '') + '"></div>'); 8624 if (callback) { 8625 callback(); 8626 } 8627 } 8628 } 8629 self.hide(); 8630 state = true; 8631 if (time) { 8632 timer = global$3.setTimeout(render, time); 8633 } else { 8634 render(); 8635 } 8636 return self; 8637 }; 8638 self.hide = function () { 8639 var child = elm.lastChild; 8640 global$3.clearTimeout(timer); 8641 if (child && child.className.indexOf('throbber') !== -1) { 8642 child.parentNode.removeChild(child); 8643 } 8644 state = false; 8645 return self; 8646 }; 8647 } 8648 8649 var Menu = FloatPanel.extend({ 8650 Defaults: { 8651 defaultType: 'menuitem', 8652 border: 1, 8653 layout: 'stack', 8654 role: 'application', 8655 bodyRole: 'menu', 8656 ariaRoot: true 8657 }, 8658 init: function (settings) { 8659 var self = this; 8660 settings.autohide = true; 8661 settings.constrainToViewport = true; 8662 if (typeof settings.items === 'function') { 8663 settings.itemsFactory = settings.items; 8664 settings.items = []; 8665 } 8666 if (settings.itemDefaults) { 8667 var items = settings.items; 8668 var i = items.length; 8669 while (i--) { 8670 items[i] = global$4.extend({}, settings.itemDefaults, items[i]); 8671 } 8672 } 8673 self._super(settings); 8674 self.classes.add('menu'); 8675 if (settings.animate && global$1.ie !== 11) { 8676 self.classes.add('animate'); 8677 } 8678 }, 8679 repaint: function () { 8680 this.classes.toggle('menu-align', true); 8681 this._super(); 8682 this.getEl().style.height = ''; 8683 this.getEl('body').style.height = ''; 8684 return this; 8685 }, 8686 cancel: function () { 8687 var self = this; 8688 self.hideAll(); 8689 self.fire('select'); 8690 }, 8691 load: function () { 8692 var self = this; 8693 var time, factory; 8694 function hideThrobber() { 8695 if (self.throbber) { 8696 self.throbber.hide(); 8697 self.throbber = null; 8698 } 8699 } 8700 factory = self.settings.itemsFactory; 8701 if (!factory) { 8702 return; 8703 } 8704 if (!self.throbber) { 8705 self.throbber = new Throbber(self.getEl('body'), true); 8706 if (self.items().length === 0) { 8707 self.throbber.show(); 8708 self.fire('loading'); 8709 } else { 8710 self.throbber.show(100, function () { 8711 self.items().remove(); 8712 self.fire('loading'); 8713 }); 8714 } 8715 self.on('hide close', hideThrobber); 8716 } 8717 self.requestTime = time = new Date().getTime(); 8718 self.settings.itemsFactory(function (items) { 8719 if (items.length === 0) { 8720 self.hide(); 8721 return; 8722 } 8723 if (self.requestTime !== time) { 8724 return; 8725 } 8726 self.getEl().style.width = ''; 8727 self.getEl('body').style.width = ''; 8728 hideThrobber(); 8729 self.items().remove(); 8730 self.getEl('body').innerHTML = ''; 8731 self.add(items); 8732 self.renderNew(); 8733 self.fire('loaded'); 8734 }); 8735 }, 8736 hideAll: function () { 8737 var self = this; 8738 this.find('menuitem').exec('hideMenu'); 8739 return self._super(); 8740 }, 8741 preRender: function () { 8742 var self = this; 8743 self.items().each(function (ctrl) { 8744 var settings = ctrl.settings; 8745 if (settings.icon || settings.image || settings.selectable) { 8746 self._hasIcons = true; 8747 return false; 8748 } 8749 }); 8750 if (self.settings.itemsFactory) { 8751 self.on('postrender', function () { 8752 if (self.settings.itemsFactory) { 8753 self.load(); 8754 } 8755 }); 8756 } 8757 self.on('show hide', function (e) { 8758 if (e.control === self) { 8759 if (e.type === 'show') { 8760 global$3.setTimeout(function () { 8761 self.classes.add('in'); 8762 }, 0); 8763 } else { 8764 self.classes.remove('in'); 8765 } 8766 } 8767 }); 8768 return self._super(); 8769 } 8770 }); 8771 8772 var ListBox = MenuButton.extend({ 8773 init: function (settings) { 8774 var self = this; 8775 var values, selected, selectedText, lastItemCtrl; 8776 function setSelected(menuValues) { 8777 for (var i = 0; i < menuValues.length; i++) { 8778 selected = menuValues[i].selected || settings.value === menuValues[i].value; 8779 if (selected) { 8780 selectedText = selectedText || menuValues[i].text; 8781 self.state.set('value', menuValues[i].value); 8782 return true; 8783 } 8784 if (menuValues[i].menu) { 8785 if (setSelected(menuValues[i].menu)) { 8786 return true; 8787 } 8788 } 8789 } 8790 } 8791 self._super(settings); 8792 settings = self.settings; 8793 self._values = values = settings.values; 8794 if (values) { 8795 if (typeof settings.value !== 'undefined') { 8796 setSelected(values); 8797 } 8798 if (!selected && values.length > 0) { 8799 selectedText = values[0].text; 8800 self.state.set('value', values[0].value); 8801 } 8802 self.state.set('menu', values); 8803 } 8804 self.state.set('text', settings.text || selectedText); 8805 self.classes.add('listbox'); 8806 self.on('select', function (e) { 8807 var ctrl = e.control; 8808 if (lastItemCtrl) { 8809 e.lastControl = lastItemCtrl; 8810 } 8811 if (settings.multiple) { 8812 ctrl.active(!ctrl.active()); 8813 } else { 8814 self.value(e.control.value()); 8815 } 8816 lastItemCtrl = ctrl; 8817 }); 8818 }, 8819 value: function (value) { 8820 if (arguments.length === 0) { 8821 return this.state.get('value'); 8822 } 8823 if (typeof value === 'undefined') { 8824 return this; 8825 } 8826 function valueExists(values) { 8827 return exists(values, function (a) { 8828 return a.menu ? valueExists(a.menu) : a.value === value; 8829 }); 8830 } 8831 if (this.settings.values) { 8832 if (valueExists(this.settings.values)) { 8833 this.state.set('value', value); 8834 } else if (value === null) { 8835 this.state.set('value', null); 8836 } 8837 } else { 8838 this.state.set('value', value); 8839 } 8840 return this; 8841 }, 8842 bindStates: function () { 8843 var self = this; 8844 function activateMenuItemsByValue(menu, value) { 8845 if (menu instanceof Menu) { 8846 menu.items().each(function (ctrl) { 8847 if (!ctrl.hasMenus()) { 8848 ctrl.active(ctrl.value() === value); 8849 } 8850 }); 8851 } 8852 } 8853 function getSelectedItem(menuValues, value) { 8854 var selectedItem; 8855 if (!menuValues) { 8856 return; 8857 } 8858 for (var i = 0; i < menuValues.length; i++) { 8859 if (menuValues[i].value === value) { 8860 return menuValues[i]; 8861 } 8862 if (menuValues[i].menu) { 8863 selectedItem = getSelectedItem(menuValues[i].menu, value); 8864 if (selectedItem) { 8865 return selectedItem; 8866 } 8867 } 8868 } 8869 } 8870 self.on('show', function (e) { 8871 activateMenuItemsByValue(e.control, self.value()); 8872 }); 8873 self.state.on('change:value', function (e) { 8874 var selectedItem = getSelectedItem(self.state.get('menu'), e.value); 8875 if (selectedItem) { 8876 self.text(selectedItem.text); 8877 } else { 8878 self.text(self.settings.text); 8879 } 8880 }); 8881 return self._super(); 8882 } 8883 }); 8884 8885 var toggleTextStyle = function (ctrl, state) { 8886 var textStyle = ctrl._textStyle; 8887 if (textStyle) { 8888 var textElm = ctrl.getEl('text'); 8889 textElm.setAttribute('style', textStyle); 8890 if (state) { 8891 textElm.style.color = ''; 8892 textElm.style.backgroundColor = ''; 8893 } 8894 } 8895 }; 8896 var MenuItem = Widget.extend({ 8897 Defaults: { 8898 border: 0, 8899 role: 'menuitem' 8900 }, 8901 init: function (settings) { 8902 var self = this; 8903 var text; 8904 self._super(settings); 8905 settings = self.settings; 8906 self.classes.add('menu-item'); 8907 if (settings.menu) { 8908 self.classes.add('menu-item-expand'); 8909 } 8910 if (settings.preview) { 8911 self.classes.add('menu-item-preview'); 8912 } 8913 text = self.state.get('text'); 8914 if (text === '-' || text === '|') { 8915 self.classes.add('menu-item-sep'); 8916 self.aria('role', 'separator'); 8917 self.state.set('text', '-'); 8918 } 8919 if (settings.selectable) { 8920 self.aria('role', 'menuitemcheckbox'); 8921 self.classes.add('menu-item-checkbox'); 8922 settings.icon = 'selected'; 8923 } 8924 if (!settings.preview && !settings.selectable) { 8925 self.classes.add('menu-item-normal'); 8926 } 8927 self.on('mousedown', function (e) { 8928 e.preventDefault(); 8929 }); 8930 if (settings.menu && !settings.ariaHideMenu) { 8931 self.aria('haspopup', true); 8932 } 8933 }, 8934 hasMenus: function () { 8935 return !!this.settings.menu; 8936 }, 8937 showMenu: function () { 8938 var self = this; 8939 var settings = self.settings; 8940 var menu; 8941 var parent = self.parent(); 8942 parent.items().each(function (ctrl) { 8943 if (ctrl !== self) { 8944 ctrl.hideMenu(); 8945 } 8946 }); 8947 if (settings.menu) { 8948 menu = self.menu; 8949 if (!menu) { 8950 menu = settings.menu; 8951 if (menu.length) { 8952 menu = { 8953 type: 'menu', 8954 items: menu 8955 }; 8956 } else { 8957 menu.type = menu.type || 'menu'; 8958 } 8959 if (parent.settings.itemDefaults) { 8960 menu.itemDefaults = parent.settings.itemDefaults; 8961 } 8962 menu = self.menu = global$b.create(menu).parent(self).renderTo(); 8963 menu.reflow(); 8964 menu.on('cancel', function (e) { 8965 e.stopPropagation(); 8966 self.focus(); 8967 menu.hide(); 8968 }); 8969 menu.on('show hide', function (e) { 8970 if (e.control.items) { 8971 e.control.items().each(function (ctrl) { 8972 ctrl.active(ctrl.settings.selected); 8973 }); 8974 } 8975 }).fire('show'); 8976 menu.on('hide', function (e) { 8977 if (e.control === menu) { 8978 self.classes.remove('selected'); 8979 } 8980 }); 8981 menu.submenu = true; 8982 } else { 8983 menu.show(); 8984 } 8985 menu._parentMenu = parent; 8986 menu.classes.add('menu-sub'); 8987 var rel = menu.testMoveRel(self.getEl(), self.isRtl() ? [ 8988 'tl-tr', 8989 'bl-br', 8990 'tr-tl', 8991 'br-bl' 8992 ] : [ 8993 'tr-tl', 8994 'br-bl', 8995 'tl-tr', 8996 'bl-br' 8997 ]); 8998 menu.moveRel(self.getEl(), rel); 8999 menu.rel = rel; 9000 rel = 'menu-sub-' + rel; 9001 menu.classes.remove(menu._lastRel).add(rel); 9002 menu._lastRel = rel; 9003 self.classes.add('selected'); 9004 self.aria('expanded', true); 9005 } 9006 }, 9007 hideMenu: function () { 9008 var self = this; 9009 if (self.menu) { 9010 self.menu.items().each(function (item) { 9011 if (item.hideMenu) { 9012 item.hideMenu(); 9013 } 9014 }); 9015 self.menu.hide(); 9016 self.aria('expanded', false); 9017 } 9018 return self; 9019 }, 9020 renderHtml: function () { 9021 var self = this; 9022 var id = self._id; 9023 var settings = self.settings; 9024 var prefix = self.classPrefix; 9025 var text = self.state.get('text'); 9026 var icon = self.settings.icon, image = '', shortcut = settings.shortcut; 9027 var url = self.encode(settings.url), iconHtml = ''; 9028 function convertShortcut(shortcut) { 9029 var i, value, replace = {}; 9030 if (global$1.mac) { 9031 replace = { 9032 alt: '⌥', 9033 ctrl: '⌘', 9034 shift: '⇧', 9035 meta: '⌘' 9036 }; 9037 } else { 9038 replace = { meta: 'Ctrl' }; 9039 } 9040 shortcut = shortcut.split('+'); 9041 for (i = 0; i < shortcut.length; i++) { 9042 value = replace[shortcut[i].toLowerCase()]; 9043 if (value) { 9044 shortcut[i] = value; 9045 } 9046 } 9047 return shortcut.join('+'); 9048 } 9049 function escapeRegExp(str) { 9050 return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); 9051 } 9052 function markMatches(text) { 9053 var match = settings.match || ''; 9054 return match ? text.replace(new RegExp(escapeRegExp(match), 'gi'), function (match) { 9055 return '!mce~match[' + match + ']mce~match!'; 9056 }) : text; 9057 } 9058 function boldMatches(text) { 9059 return text.replace(new RegExp(escapeRegExp('!mce~match['), 'g'), '<b>').replace(new RegExp(escapeRegExp(']mce~match!'), 'g'), '</b>'); 9060 } 9061 if (icon) { 9062 self.parent().classes.add('menu-has-icons'); 9063 } 9064 if (settings.image) { 9065 image = ' style="background-image: url(\'' + settings.image + '\')"'; 9066 } 9067 if (shortcut) { 9068 shortcut = convertShortcut(shortcut); 9069 } 9070 icon = prefix + 'ico ' + prefix + 'i-' + (self.settings.icon || 'none'); 9071 iconHtml = text !== '-' ? '<i class="' + icon + '"' + image + '></i>\xA0' : ''; 9072 text = boldMatches(self.encode(markMatches(text))); 9073 url = boldMatches(self.encode(markMatches(url))); 9074 return '<div id="' + id + '" class="' + self.classes + '" tabindex="-1">' + iconHtml + (text !== '-' ? '<span id="' + id + '-text" class="' + prefix + 'text">' + text + '</span>' : '') + (shortcut ? '<div id="' + id + '-shortcut" class="' + prefix + 'menu-shortcut">' + shortcut + '</div>' : '') + (settings.menu ? '<div class="' + prefix + 'caret"></div>' : '') + (url ? '<div class="' + prefix + 'menu-item-link">' + url + '</div>' : '') + '</div>'; 9075 }, 9076 postRender: function () { 9077 var self = this, settings = self.settings; 9078 var textStyle = settings.textStyle; 9079 if (typeof textStyle === 'function') { 9080 textStyle = textStyle.call(this); 9081 } 9082 if (textStyle) { 9083 var textElm = self.getEl('text'); 9084 if (textElm) { 9085 textElm.setAttribute('style', textStyle); 9086 self._textStyle = textStyle; 9087 } 9088 } 9089 self.on('mouseenter click', function (e) { 9090 if (e.control === self) { 9091 if (!settings.menu && e.type === 'click') { 9092 self.fire('select'); 9093 global$3.requestAnimationFrame(function () { 9094 self.parent().hideAll(); 9095 }); 9096 } else { 9097 self.showMenu(); 9098 if (e.aria) { 9099 self.menu.focus(true); 9100 } 9101 } 9102 } 9103 }); 9104 self._super(); 9105 return self; 9106 }, 9107 hover: function () { 9108 var self = this; 9109 self.parent().items().each(function (ctrl) { 9110 ctrl.classes.remove('selected'); 9111 }); 9112 self.classes.toggle('selected', true); 9113 return self; 9114 }, 9115 active: function (state) { 9116 toggleTextStyle(this, state); 9117 if (typeof state !== 'undefined') { 9118 this.aria('checked', state); 9119 } 9120 return this._super(state); 9121 }, 9122 remove: function () { 9123 this._super(); 9124 if (this.menu) { 9125 this.menu.remove(); 9126 } 9127 } 9128 }); 9129 9130 var Radio = Checkbox.extend({ 9131 Defaults: { 9132 classes: 'radio', 9133 role: 'radio' 9134 } 9135 }); 9136 9137 var ResizeHandle = Widget.extend({ 9138 renderHtml: function () { 9139 var self = this, prefix = self.classPrefix; 9140 self.classes.add('resizehandle'); 9141 if (self.settings.direction === 'both') { 9142 self.classes.add('resizehandle-both'); 9143 } 9144 self.canFocus = false; 9145 return '<div id="' + self._id + '" class="' + self.classes + '">' + '<i class="' + prefix + 'ico ' + prefix + 'i-resize"></i>' + '</div>'; 9146 }, 9147 postRender: function () { 9148 var self = this; 9149 self._super(); 9150 self.resizeDragHelper = new DragHelper(this._id, { 9151 start: function () { 9152 self.fire('ResizeStart'); 9153 }, 9154 drag: function (e) { 9155 if (self.settings.direction !== 'both') { 9156 e.deltaX = 0; 9157 } 9158 self.fire('Resize', e); 9159 }, 9160 stop: function () { 9161 self.fire('ResizeEnd'); 9162 } 9163 }); 9164 }, 9165 remove: function () { 9166 if (this.resizeDragHelper) { 9167 this.resizeDragHelper.destroy(); 9168 } 9169 return this._super(); 9170 } 9171 }); 9172 9173 function createOptions(options) { 9174 var strOptions = ''; 9175 if (options) { 9176 for (var i = 0; i < options.length; i++) { 9177 strOptions += '<option value="' + options[i] + '">' + options[i] + '</option>'; 9178 } 9179 } 9180 return strOptions; 9181 } 9182 var SelectBox = Widget.extend({ 9183 Defaults: { 9184 classes: 'selectbox', 9185 role: 'selectbox', 9186 options: [] 9187 }, 9188 init: function (settings) { 9189 var self = this; 9190 self._super(settings); 9191 if (self.settings.size) { 9192 self.size = self.settings.size; 9193 } 9194 if (self.settings.options) { 9195 self._options = self.settings.options; 9196 } 9197 self.on('keydown', function (e) { 9198 var rootControl; 9199 if (e.keyCode === 13) { 9200 e.preventDefault(); 9201 self.parents().reverse().each(function (ctrl) { 9202 if (ctrl.toJSON) { 9203 rootControl = ctrl; 9204 return false; 9205 } 9206 }); 9207 self.fire('submit', { data: rootControl.toJSON() }); 9208 } 9209 }); 9210 }, 9211 options: function (state) { 9212 if (!arguments.length) { 9213 return this.state.get('options'); 9214 } 9215 this.state.set('options', state); 9216 return this; 9217 }, 9218 renderHtml: function () { 9219 var self = this; 9220 var options, size = ''; 9221 options = createOptions(self._options); 9222 if (self.size) { 9223 size = ' size = "' + self.size + '"'; 9224 } 9225 return '<select id="' + self._id + '" class="' + self.classes + '"' + size + '>' + options + '</select>'; 9226 }, 9227 bindStates: function () { 9228 var self = this; 9229 self.state.on('change:options', function (e) { 9230 self.getEl().innerHTML = createOptions(e.value); 9231 }); 9232 return self._super(); 9233 } 9234 }); 9235 9236 function constrain(value, minVal, maxVal) { 9237 if (value < minVal) { 9238 value = minVal; 9239 } 9240 if (value > maxVal) { 9241 value = maxVal; 9242 } 9243 return value; 9244 } 9245 function setAriaProp(el, name, value) { 9246 el.setAttribute('aria-' + name, value); 9247 } 9248 function updateSliderHandle(ctrl, value) { 9249 var maxHandlePos, shortSizeName, sizeName, stylePosName, styleValue, handleEl; 9250 if (ctrl.settings.orientation === 'v') { 9251 stylePosName = 'top'; 9252 sizeName = 'height'; 9253 shortSizeName = 'h'; 9254 } else { 9255 stylePosName = 'left'; 9256 sizeName = 'width'; 9257 shortSizeName = 'w'; 9258 } 9259 handleEl = ctrl.getEl('handle'); 9260 maxHandlePos = (ctrl.layoutRect()[shortSizeName] || 100) - funcs.getSize(handleEl)[sizeName]; 9261 styleValue = maxHandlePos * ((value - ctrl._minValue) / (ctrl._maxValue - ctrl._minValue)) + 'px'; 9262 handleEl.style[stylePosName] = styleValue; 9263 handleEl.style.height = ctrl.layoutRect().h + 'px'; 9264 setAriaProp(handleEl, 'valuenow', value); 9265 setAriaProp(handleEl, 'valuetext', '' + ctrl.settings.previewFilter(value)); 9266 setAriaProp(handleEl, 'valuemin', ctrl._minValue); 9267 setAriaProp(handleEl, 'valuemax', ctrl._maxValue); 9268 } 9269 var Slider = Widget.extend({ 9270 init: function (settings) { 9271 var self = this; 9272 if (!settings.previewFilter) { 9273 settings.previewFilter = function (value) { 9274 return Math.round(value * 100) / 100; 9275 }; 9276 } 9277 self._super(settings); 9278 self.classes.add('slider'); 9279 if (settings.orientation === 'v') { 9280 self.classes.add('vertical'); 9281 } 9282 self._minValue = isNumber$1(settings.minValue) ? settings.minValue : 0; 9283 self._maxValue = isNumber$1(settings.maxValue) ? settings.maxValue : 100; 9284 self._initValue = self.state.get('value'); 9285 }, 9286 renderHtml: function () { 9287 var self = this, id = self._id, prefix = self.classPrefix; 9288 return '<div id="' + id + '" class="' + self.classes + '">' + '<div id="' + id + '-handle" class="' + prefix + 'slider-handle" role="slider" tabindex="-1"></div>' + '</div>'; 9289 }, 9290 reset: function () { 9291 this.value(this._initValue).repaint(); 9292 }, 9293 postRender: function () { 9294 var self = this; 9295 var minValue, maxValue, screenCordName, stylePosName, sizeName, shortSizeName; 9296 function toFraction(min, max, val) { 9297 return (val + min) / (max - min); 9298 } 9299 function fromFraction(min, max, val) { 9300 return val * (max - min) - min; 9301 } 9302 function handleKeyboard(minValue, maxValue) { 9303 function alter(delta) { 9304 var value; 9305 value = self.value(); 9306 value = fromFraction(minValue, maxValue, toFraction(minValue, maxValue, value) + delta * 0.05); 9307 value = constrain(value, minValue, maxValue); 9308 self.value(value); 9309 self.fire('dragstart', { value: value }); 9310 self.fire('drag', { value: value }); 9311 self.fire('dragend', { value: value }); 9312 } 9313 self.on('keydown', function (e) { 9314 switch (e.keyCode) { 9315 case 37: 9316 case 38: 9317 alter(-1); 9318 break; 9319 case 39: 9320 case 40: 9321 alter(1); 9322 break; 9323 } 9324 }); 9325 } 9326 function handleDrag(minValue, maxValue, handleEl) { 9327 var startPos, startHandlePos, maxHandlePos, handlePos, value; 9328 self._dragHelper = new DragHelper(self._id, { 9329 handle: self._id + '-handle', 9330 start: function (e) { 9331 startPos = e[screenCordName]; 9332 startHandlePos = parseInt(self.getEl('handle').style[stylePosName], 10); 9333 maxHandlePos = (self.layoutRect()[shortSizeName] || 100) - funcs.getSize(handleEl)[sizeName]; 9334 self.fire('dragstart', { value: value }); 9335 }, 9336 drag: function (e) { 9337 var delta = e[screenCordName] - startPos; 9338 handlePos = constrain(startHandlePos + delta, 0, maxHandlePos); 9339 handleEl.style[stylePosName] = handlePos + 'px'; 9340 value = minValue + handlePos / maxHandlePos * (maxValue - minValue); 9341 self.value(value); 9342 self.tooltip().text('' + self.settings.previewFilter(value)).show().moveRel(handleEl, 'bc tc'); 9343 self.fire('drag', { value: value }); 9344 }, 9345 stop: function () { 9346 self.tooltip().hide(); 9347 self.fire('dragend', { value: value }); 9348 } 9349 }); 9350 } 9351 minValue = self._minValue; 9352 maxValue = self._maxValue; 9353 if (self.settings.orientation === 'v') { 9354 screenCordName = 'screenY'; 9355 stylePosName = 'top'; 9356 sizeName = 'height'; 9357 shortSizeName = 'h'; 9358 } else { 9359 screenCordName = 'screenX'; 9360 stylePosName = 'left'; 9361 sizeName = 'width'; 9362 shortSizeName = 'w'; 9363 } 9364 self._super(); 9365 handleKeyboard(minValue, maxValue); 9366 handleDrag(minValue, maxValue, self.getEl('handle')); 9367 }, 9368 repaint: function () { 9369 this._super(); 9370 updateSliderHandle(this, this.value()); 9371 }, 9372 bindStates: function () { 9373 var self = this; 9374 self.state.on('change:value', function (e) { 9375 updateSliderHandle(self, e.value); 9376 }); 9377 return self._super(); 9378 } 9379 }); 9380 9381 var Spacer = Widget.extend({ 9382 renderHtml: function () { 9383 var self = this; 9384 self.classes.add('spacer'); 9385 self.canFocus = false; 9386 return '<div id="' + self._id + '" class="' + self.classes + '"></div>'; 9387 } 9388 }); 9389 9390 var SplitButton = MenuButton.extend({ 9391 Defaults: { 9392 classes: 'widget btn splitbtn', 9393 role: 'button' 9394 }, 9395 repaint: function () { 9396 var self = this; 9397 var elm = self.getEl(); 9398 var rect = self.layoutRect(); 9399 var mainButtonElm, menuButtonElm; 9400 self._super(); 9401 mainButtonElm = elm.firstChild; 9402 menuButtonElm = elm.lastChild; 9403 global$7(mainButtonElm).css({ 9404 width: rect.w - funcs.getSize(menuButtonElm).width, 9405 height: rect.h - 2 9406 }); 9407 global$7(menuButtonElm).css({ height: rect.h - 2 }); 9408 return self; 9409 }, 9410 activeMenu: function (state) { 9411 var self = this; 9412 global$7(self.getEl().lastChild).toggleClass(self.classPrefix + 'active', state); 9413 }, 9414 renderHtml: function () { 9415 var self = this; 9416 var id = self._id; 9417 var prefix = self.classPrefix; 9418 var image; 9419 var icon = self.state.get('icon'); 9420 var text = self.state.get('text'); 9421 var settings = self.settings; 9422 var textHtml = '', ariaPressed; 9423 image = settings.image; 9424 if (image) { 9425 icon = 'none'; 9426 if (typeof image !== 'string') { 9427 image = domGlobals.window.getSelection ? image[0] : image[1]; 9428 } 9429 image = ' style="background-image: url(\'' + image + '\')"'; 9430 } else { 9431 image = ''; 9432 } 9433 icon = settings.icon ? prefix + 'ico ' + prefix + 'i-' + icon : ''; 9434 if (text) { 9435 self.classes.add('btn-has-text'); 9436 textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>'; 9437 } 9438 ariaPressed = typeof settings.active === 'boolean' ? ' aria-pressed="' + settings.active + '"' : ''; 9439 return '<div id="' + id + '" class="' + self.classes + '" role="button"' + ariaPressed + ' tabindex="-1">' + '<button type="button" hidefocus="1" tabindex="-1">' + (icon ? '<i class="' + icon + '"' + image + '></i>' : '') + textHtml + '</button>' + '<button type="button" class="' + prefix + 'open" hidefocus="1" tabindex="-1">' + (self._menuBtnText ? (icon ? '\xA0' : '') + self._menuBtnText : '') + ' <i class="' + prefix + 'caret"></i>' + '</button>' + '</div>'; 9440 }, 9441 postRender: function () { 9442 var self = this, onClickHandler = self.settings.onclick; 9443 self.on('click', function (e) { 9444 var node = e.target; 9445 if (e.control === this) { 9446 while (node) { 9447 if (e.aria && e.aria.key !== 'down' || node.nodeName === 'BUTTON' && node.className.indexOf('open') === -1) { 9448 e.stopImmediatePropagation(); 9449 if (onClickHandler) { 9450 onClickHandler.call(this, e); 9451 } 9452 return; 9453 } 9454 node = node.parentNode; 9455 } 9456 } 9457 }); 9458 delete self.settings.onclick; 9459 return self._super(); 9460 } 9461 }); 9462 9463 var StackLayout = FlowLayout.extend({ 9464 Defaults: { 9465 containerClass: 'stack-layout', 9466 controlClass: 'stack-layout-item', 9467 endClass: 'break' 9468 }, 9469 isNative: function () { 9470 return true; 9471 } 9472 }); 9473 9474 var TabPanel = Panel.extend({ 9475 Defaults: { 9476 layout: 'absolute', 9477 defaults: { type: 'panel' } 9478 }, 9479 activateTab: function (idx) { 9480 var activeTabElm; 9481 if (this.activeTabId) { 9482 activeTabElm = this.getEl(this.activeTabId); 9483 global$7(activeTabElm).removeClass(this.classPrefix + 'active'); 9484 activeTabElm.setAttribute('aria-selected', 'false'); 9485 } 9486 this.activeTabId = 't' + idx; 9487 activeTabElm = this.getEl('t' + idx); 9488 activeTabElm.setAttribute('aria-selected', 'true'); 9489 global$7(activeTabElm).addClass(this.classPrefix + 'active'); 9490 this.items()[idx].show().fire('showtab'); 9491 this.reflow(); 9492 this.items().each(function (item, i) { 9493 if (idx !== i) { 9494 item.hide(); 9495 } 9496 }); 9497 }, 9498 renderHtml: function () { 9499 var self = this; 9500 var layout = self._layout; 9501 var tabsHtml = ''; 9502 var prefix = self.classPrefix; 9503 self.preRender(); 9504 layout.preRender(self); 9505 self.items().each(function (ctrl, i) { 9506 var id = self._id + '-t' + i; 9507 ctrl.aria('role', 'tabpanel'); 9508 ctrl.aria('labelledby', id); 9509 tabsHtml += '<div id="' + id + '" class="' + prefix + 'tab" ' + 'unselectable="on" role="tab" aria-controls="' + ctrl._id + '" aria-selected="false" tabIndex="-1">' + self.encode(ctrl.settings.title) + '</div>'; 9510 }); 9511 return '<div id="' + self._id + '" class="' + self.classes + '" hidefocus="1" tabindex="-1">' + '<div id="' + self._id + '-head" class="' + prefix + 'tabs" role="tablist">' + tabsHtml + '</div>' + '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + layout.renderHtml(self) + '</div>' + '</div>'; 9512 }, 9513 postRender: function () { 9514 var self = this; 9515 self._super(); 9516 self.settings.activeTab = self.settings.activeTab || 0; 9517 self.activateTab(self.settings.activeTab); 9518 this.on('click', function (e) { 9519 var targetParent = e.target.parentNode; 9520 if (targetParent && targetParent.id === self._id + '-head') { 9521 var i = targetParent.childNodes.length; 9522 while (i--) { 9523 if (targetParent.childNodes[i] === e.target) { 9524 self.activateTab(i); 9525 } 9526 } 9527 } 9528 }); 9529 }, 9530 initLayoutRect: function () { 9531 var self = this; 9532 var rect, minW, minH; 9533 minW = funcs.getSize(self.getEl('head')).width; 9534 minW = minW < 0 ? 0 : minW; 9535 minH = 0; 9536 self.items().each(function (item) { 9537 minW = Math.max(minW, item.layoutRect().minW); 9538 minH = Math.max(minH, item.layoutRect().minH); 9539 }); 9540 self.items().each(function (ctrl) { 9541 ctrl.settings.x = 0; 9542 ctrl.settings.y = 0; 9543 ctrl.settings.w = minW; 9544 ctrl.settings.h = minH; 9545 ctrl.layoutRect({ 9546 x: 0, 9547 y: 0, 9548 w: minW, 9549 h: minH 9550 }); 9551 }); 9552 var headH = funcs.getSize(self.getEl('head')).height; 9553 self.settings.minWidth = minW; 9554 self.settings.minHeight = minH + headH; 9555 rect = self._super(); 9556 rect.deltaH += headH; 9557 rect.innerH = rect.h - rect.deltaH; 9558 return rect; 9559 } 9560 }); 9561 9562 var TextBox = Widget.extend({ 9563 init: function (settings) { 9564 var self = this; 9565 self._super(settings); 9566 self.classes.add('textbox'); 9567 if (settings.multiline) { 9568 self.classes.add('multiline'); 9569 } else { 9570 self.on('keydown', function (e) { 9571 var rootControl; 9572 if (e.keyCode === 13) { 9573 e.preventDefault(); 9574 self.parents().reverse().each(function (ctrl) { 9575 if (ctrl.toJSON) { 9576 rootControl = ctrl; 9577 return false; 9578 } 9579 }); 9580 self.fire('submit', { data: rootControl.toJSON() }); 9581 } 9582 }); 9583 self.on('keyup', function (e) { 9584 self.state.set('value', e.target.value); 9585 }); 9586 } 9587 }, 9588 repaint: function () { 9589 var self = this; 9590 var style, rect, borderBox, borderW, borderH = 0, lastRepaintRect; 9591 style = self.getEl().style; 9592 rect = self._layoutRect; 9593 lastRepaintRect = self._lastRepaintRect || {}; 9594 var doc = domGlobals.document; 9595 if (!self.settings.multiline && doc.all && (!doc.documentMode || doc.documentMode <= 8)) { 9596 style.lineHeight = rect.h - borderH + 'px'; 9597 } 9598 borderBox = self.borderBox; 9599 borderW = borderBox.left + borderBox.right + 8; 9600 borderH = borderBox.top + borderBox.bottom + (self.settings.multiline ? 8 : 0); 9601 if (rect.x !== lastRepaintRect.x) { 9602 style.left = rect.x + 'px'; 9603 lastRepaintRect.x = rect.x; 9604 } 9605 if (rect.y !== lastRepaintRect.y) { 9606 style.top = rect.y + 'px'; 9607 lastRepaintRect.y = rect.y; 9608 } 9609 if (rect.w !== lastRepaintRect.w) { 9610 style.width = rect.w - borderW + 'px'; 9611 lastRepaintRect.w = rect.w; 9612 } 9613 if (rect.h !== lastRepaintRect.h) { 9614 style.height = rect.h - borderH + 'px'; 9615 lastRepaintRect.h = rect.h; 9616 } 9617 self._lastRepaintRect = lastRepaintRect; 9618 self.fire('repaint', {}, false); 9619 return self; 9620 }, 9621 renderHtml: function () { 9622 var self = this; 9623 var settings = self.settings; 9624 var attrs, elm; 9625 attrs = { 9626 id: self._id, 9627 hidefocus: '1' 9628 }; 9629 global$4.each([ 9630 'rows', 9631 'spellcheck', 9632 'maxLength', 9633 'size', 9634 'readonly', 9635 'min', 9636 'max', 9637 'step', 9638 'list', 9639 'pattern', 9640 'placeholder', 9641 'required', 9642 'multiple' 9643 ], function (name) { 9644 attrs[name] = settings[name]; 9645 }); 9646 if (self.disabled()) { 9647 attrs.disabled = 'disabled'; 9648 } 9649 if (settings.subtype) { 9650 attrs.type = settings.subtype; 9651 } 9652 elm = funcs.create(settings.multiline ? 'textarea' : 'input', attrs); 9653 elm.value = self.state.get('value'); 9654 elm.className = self.classes.toString(); 9655 return elm.outerHTML; 9656 }, 9657 value: function (value) { 9658 if (arguments.length) { 9659 this.state.set('value', value); 9660 return this; 9661 } 9662 if (this.state.get('rendered')) { 9663 this.state.set('value', this.getEl().value); 9664 } 9665 return this.state.get('value'); 9666 }, 9667 postRender: function () { 9668 var self = this; 9669 self.getEl().value = self.state.get('value'); 9670 self._super(); 9671 self.$el.on('change', function (e) { 9672 self.state.set('value', e.target.value); 9673 self.fire('change', e); 9674 }); 9675 }, 9676 bindStates: function () { 9677 var self = this; 9678 self.state.on('change:value', function (e) { 9679 if (self.getEl().value !== e.value) { 9680 self.getEl().value = e.value; 9681 } 9682 }); 9683 self.state.on('change:disabled', function (e) { 9684 self.getEl().disabled = e.value; 9685 }); 9686 return self._super(); 9687 }, 9688 remove: function () { 9689 this.$el.off(); 9690 this._super(); 9691 } 9692 }); 9693 9694 var getApi = function () { 9695 return { 9696 Selector: Selector, 9697 Collection: Collection$2, 9698 ReflowQueue: ReflowQueue, 9699 Control: Control$1, 9700 Factory: global$b, 9701 KeyboardNavigation: KeyboardNavigation, 9702 Container: Container, 9703 DragHelper: DragHelper, 9704 Scrollable: Scrollable, 9705 Panel: Panel, 9706 Movable: Movable, 9707 Resizable: Resizable, 9708 FloatPanel: FloatPanel, 9709 Window: Window, 9710 MessageBox: MessageBox, 9711 Tooltip: Tooltip, 9712 Widget: Widget, 9713 Progress: Progress, 9714 Notification: Notification, 9715 Layout: Layout$1, 9716 AbsoluteLayout: AbsoluteLayout, 9717 Button: Button, 9718 ButtonGroup: ButtonGroup, 9719 Checkbox: Checkbox, 9720 ComboBox: ComboBox, 9721 ColorBox: ColorBox, 9722 PanelButton: PanelButton, 9723 ColorButton: ColorButton, 9724 ColorPicker: ColorPicker, 9725 Path: Path, 9726 ElementPath: ElementPath, 9727 FormItem: FormItem, 9728 Form: Form, 9729 FieldSet: FieldSet, 9730 FilePicker: FilePicker, 9731 FitLayout: FitLayout, 9732 FlexLayout: FlexLayout, 9733 FlowLayout: FlowLayout, 9734 FormatControls: FormatControls, 9735 GridLayout: GridLayout, 9736 Iframe: Iframe, 9737 InfoBox: InfoBox, 9738 Label: Label, 9739 Toolbar: Toolbar$1, 9740 MenuBar: MenuBar, 9741 MenuButton: MenuButton, 9742 MenuItem: MenuItem, 9743 Throbber: Throbber, 9744 Menu: Menu, 9745 ListBox: ListBox, 9746 Radio: Radio, 9747 ResizeHandle: ResizeHandle, 9748 SelectBox: SelectBox, 9749 Slider: Slider, 9750 Spacer: Spacer, 9751 SplitButton: SplitButton, 9752 StackLayout: StackLayout, 9753 TabPanel: TabPanel, 9754 TextBox: TextBox, 9755 DropZone: DropZone, 9756 BrowseButton: BrowseButton 9757 }; 9758 }; 9759 var appendTo = function (target) { 9760 if (target.ui) { 9761 global$4.each(getApi(), function (ref, key) { 9762 target.ui[key] = ref; 9763 }); 9764 } else { 9765 target.ui = getApi(); 9766 } 9767 }; 9768 var registerToFactory = function () { 9769 global$4.each(getApi(), function (ref, key) { 9770 global$b.add(key, ref); 9771 }); 9772 }; 9773 var Api = { 9774 appendTo: appendTo, 9775 registerToFactory: registerToFactory 9776 }; 9777 9778 Api.registerToFactory(); 9779 Api.appendTo(window.tinymce ? window.tinymce : {}); 9780 global.add('inlite', function (editor) { 9781 var panel = create$3(); 9782 FormatControls.setup(editor); 9783 Buttons.addToEditor(editor, panel); 9784 return ThemeApi.get(editor, panel); 9785 }); 9786 function Theme () { 9787 } 9788 9789 return Theme; 9790 9791 }(window)); 9792 })();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Nov 21 01:00:03 2024 | Cross-referenced by PHPXref 0.7.1 |