home *** CD-ROM | disk | FTP | other *** search
/ HTML Examples / WP.iso / wordpress2 / wp-includes / js / tinymce / themes / inlite / theme.js next >
Encoding:
JavaScript  |  2017-09-26  |  54.5 KB  |  2,169 lines

  1. (function () {
  2.  
  3. var defs = {}; // id -> {dependencies, definition, instance (possibly undefined)}
  4.  
  5. // Used when there is no 'main' module.
  6. // The name is probably (hopefully) unique so minification removes for releases.
  7. var register_3795 = function (id) {
  8.   var module = dem(id);
  9.   var fragments = id.split('.');
  10.   var target = Function('return this;')();
  11.   for (var i = 0; i < fragments.length - 1; ++i) {
  12.     if (target[fragments[i]] === undefined)
  13.       target[fragments[i]] = {};
  14.     target = target[fragments[i]];
  15.   }
  16.   target[fragments[fragments.length - 1]] = module;
  17. };
  18.  
  19. var instantiate = function (id) {
  20.   var actual = defs[id];
  21.   var dependencies = actual.deps;
  22.   var definition = actual.defn;
  23.   var len = dependencies.length;
  24.   var instances = new Array(len);
  25.   for (var i = 0; i < len; ++i)
  26.     instances[i] = dem(dependencies[i]);
  27.   var defResult = definition.apply(null, instances);
  28.   if (defResult === undefined)
  29.      throw 'module [' + id + '] returned undefined';
  30.   actual.instance = defResult;
  31. };
  32.  
  33. var def = function (id, dependencies, definition) {
  34.   if (typeof id !== 'string')
  35.     throw 'module id must be a string';
  36.   else if (dependencies === undefined)
  37.     throw 'no dependencies for ' + id;
  38.   else if (definition === undefined)
  39.     throw 'no definition function for ' + id;
  40.   defs[id] = {
  41.     deps: dependencies,
  42.     defn: definition,
  43.     instance: undefined
  44.   };
  45. };
  46.  
  47. var dem = function (id) {
  48.   var actual = defs[id];
  49.   if (actual === undefined)
  50.     throw 'module [' + id + '] was undefined';
  51.   else if (actual.instance === undefined)
  52.     instantiate(id);
  53.   return actual.instance;
  54. };
  55.  
  56. var req = function (ids, callback) {
  57.   var len = ids.length;
  58.   var instances = new Array(len);
  59.   for (var i = 0; i < len; ++i)
  60.     instances.push(dem(ids[i]));
  61.   callback.apply(null, callback);
  62. };
  63.  
  64. var ephox = {};
  65.  
  66. ephox.bolt = {
  67.   module: {
  68.     api: {
  69.       define: def,
  70.       require: req,
  71.       demand: dem
  72.     }
  73.   }
  74. };
  75.  
  76. var define = def;
  77. var require = req;
  78. var demand = dem;
  79. // this helps with minificiation when using a lot of global references
  80. var defineGlobal = function (id, ref) {
  81.   define(id, [], function () { return ref; });
  82. };
  83. /*jsc
  84. ["tinymce.themes.inlite.Theme","tinymce.core.ThemeManager","tinymce.core.ui.Api","tinymce.core.util.Delay","tinymce.themes.inlite.alien.Arr","tinymce.themes.inlite.alien.EditorSettings","tinymce.themes.inlite.core.ElementMatcher","tinymce.themes.inlite.core.Matcher","tinymce.themes.inlite.core.PredicateId","tinymce.themes.inlite.core.SelectionMatcher","tinymce.themes.inlite.core.SkinLoader","tinymce.themes.inlite.ui.Buttons","tinymce.themes.inlite.ui.Panel","global!tinymce.util.Tools.resolve","tinymce.themes.inlite.alien.Type","tinymce.themes.inlite.core.Measure","tinymce.core.util.Tools","tinymce.core.EditorManager","tinymce.core.dom.DOMUtils","tinymce.core.ui.Factory","tinymce.themes.inlite.ui.Toolbar","tinymce.themes.inlite.ui.Forms","tinymce.themes.inlite.core.Layout","tinymce.themes.inlite.file.Conversions","tinymce.themes.inlite.file.Picker","tinymce.themes.inlite.core.Actions","tinymce.themes.inlite.core.Convert","tinymce.core.util.Promise","tinymce.themes.inlite.alien.Uuid","tinymce.themes.inlite.alien.Unlink","tinymce.themes.inlite.core.UrlType","tinymce.core.geom.Rect","tinymce.themes.inlite.alien.Bookmark","tinymce.core.dom.TreeWalker","tinymce.core.dom.RangeUtils"]
  85. jsc*/
  86. defineGlobal("global!tinymce.util.Tools.resolve", tinymce.util.Tools.resolve);
  87. /**
  88.  * ResolveGlobal.js
  89.  *
  90.  * Released under LGPL License.
  91.  * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
  92.  *
  93.  * License: http://www.tinymce.com/license
  94.  * Contributing: http://www.tinymce.com/contributing
  95.  */
  96.  
  97. define(
  98.   'tinymce.core.ThemeManager',
  99.   [
  100.     'global!tinymce.util.Tools.resolve'
  101.   ],
  102.   function (resolve) {
  103.     return resolve('tinymce.ThemeManager');
  104.   }
  105. );
  106.  
  107. /**
  108.  * ResolveGlobal.js
  109.  *
  110.  * Released under LGPL License.
  111.  * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
  112.  *
  113.  * License: http://www.tinymce.com/license
  114.  * Contributing: http://www.tinymce.com/contributing
  115.  */
  116.  
  117. define(
  118.   'tinymce.core.ui.Api',
  119.   [
  120.     'global!tinymce.util.Tools.resolve'
  121.   ],
  122.   function (resolve) {
  123.     return resolve('tinymce.ui.Api');
  124.   }
  125. );
  126.  
  127. /**
  128.  * ResolveGlobal.js
  129.  *
  130.  * Released under LGPL License.
  131.  * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
  132.  *
  133.  * License: http://www.tinymce.com/license
  134.  * Contributing: http://www.tinymce.com/contributing
  135.  */
  136.  
  137. define(
  138.   'tinymce.core.util.Delay',
  139.   [
  140.     'global!tinymce.util.Tools.resolve'
  141.   ],
  142.   function (resolve) {
  143.     return resolve('tinymce.util.Delay');
  144.   }
  145. );
  146.  
  147. /**
  148.  * Arr.js
  149.  *
  150.  * Released under LGPL License.
  151.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  152.  *
  153.  * License: http://www.tinymce.com/license
  154.  * Contributing: http://www.tinymce.com/contributing
  155.  */
  156.  
  157. define(
  158.   'tinymce.themes.inlite.alien.Arr',
  159.   [
  160.   ],
  161.   function () {
  162.     var flatten = function (arr) {
  163.       return arr.reduce(function (results, item) {
  164.         return Array.isArray(item) ? results.concat(flatten(item)) : results.concat(item);
  165.       }, []);
  166.     };
  167.  
  168.     return {
  169.       flatten: flatten
  170.     };
  171.   }
  172. );
  173.  
  174. /**
  175.  * Type.js
  176.  *
  177.  * Released under LGPL License.
  178.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  179.  *
  180.  * License: http://www.tinymce.com/license
  181.  * Contributing: http://www.tinymce.com/contributing
  182.  */
  183.  
  184. define(
  185.   'tinymce.themes.inlite.alien.Type',
  186.   [
  187.   ],
  188.   function () {
  189.     var isType = function (type) {
  190.       return function (value) {
  191.         return typeof value === type;
  192.       };
  193.     };
  194.  
  195.     var isArray = function (value) {
  196.       return Array.isArray(value);
  197.     };
  198.  
  199.     var isNull = function (value) {
  200.       return value === null;
  201.     };
  202.  
  203.     var isObject = function (predicate) {
  204.       return function (value) {
  205.         return !isNull(value) && !isArray(value) && predicate(value);
  206.       };
  207.     };
  208.  
  209.     return {
  210.       isString: isType("string"),
  211.       isNumber: isType("number"),
  212.       isBoolean: isType("boolean"),
  213.       isFunction: isType("function"),
  214.       isObject: isObject(isType("object")),
  215.       isNull: isNull,
  216.       isArray: isArray
  217.     };
  218.   }
  219. );
  220.  
  221. /**
  222.  * EditorSettings.js
  223.  *
  224.  * Released under LGPL License.
  225.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  226.  *
  227.  * License: http://www.tinymce.com/license
  228.  * Contributing: http://www.tinymce.com/contributing
  229.  */
  230.  
  231. define(
  232.   'tinymce.themes.inlite.alien.EditorSettings',
  233.   [
  234.     'tinymce.themes.inlite.alien.Type'
  235.   ],
  236.   function (Type) {
  237.     var validDefaultOrDie = function (value, predicate) {
  238.       if (predicate(value)) {
  239.         return true;
  240.       }
  241.  
  242.       throw new Error('Default value doesn\'t match requested type.');
  243.     };
  244.  
  245.     var getByTypeOr = function (predicate) {
  246.       return function (editor, name, defaultValue) {
  247.         var settings = editor.settings;
  248.         validDefaultOrDie(defaultValue, predicate);
  249.         return name in settings && predicate(settings[name]) ? settings[name] : defaultValue;
  250.       };
  251.     };
  252.  
  253.     var splitNoEmpty = function (str, delim) {
  254.       return str.split(delim).filter(function (item) {
  255.         return item.length > 0;
  256.       });
  257.     };
  258.  
  259.     var itemsToArray = function (value, defaultValue) {
  260.       var stringToItemsArray = function (value) {
  261.         return typeof value === 'string' ? splitNoEmpty(value, /[ ,]/) : value;
  262.       };
  263.  
  264.       var boolToItemsArray = function (value, defaultValue) {
  265.         return value === false ? [] : defaultValue;
  266.       };
  267.  
  268.       if (Type.isArray(value)) {
  269.         return value;
  270.       } else if (Type.isString(value)) {
  271.         return stringToItemsArray(value);
  272.       } else if (Type.isBoolean(value)) {
  273.         return boolToItemsArray(value, defaultValue);
  274.       }
  275.  
  276.       return defaultValue;
  277.     };
  278.  
  279.     var getToolbarItemsOr = function (predicate) {
  280.       return function (editor, name, defaultValue) {
  281.         var value = name in editor.settings ? editor.settings[name] : defaultValue;
  282.         validDefaultOrDie(defaultValue, predicate);
  283.         return itemsToArray(value, defaultValue);
  284.       };
  285.     };
  286.  
  287.     return {
  288.       // TODO: Add Option based getString, getBool if merged with core
  289.       getStringOr: getByTypeOr(Type.isString),
  290.       getBoolOr: getByTypeOr(Type.isBoolean),
  291.       getNumberOr: getByTypeOr(Type.isNumber),
  292.       getHandlerOr: getByTypeOr(Type.isFunction),
  293.       getToolbarItemsOr: getToolbarItemsOr(Type.isArray)
  294.     };
  295.   }
  296. );
  297.  
  298. /**
  299.  * Matcher.js
  300.  *
  301.  * Released under LGPL License.
  302.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  303.  *
  304.  * License: http://www.tinymce.com/license
  305.  * Contributing: http://www.tinymce.com/contributing
  306.  */
  307.  
  308. define(
  309.   'tinymce.themes.inlite.core.Matcher',
  310.   [
  311.   ],
  312.   function () {
  313.     // result :: String, Rect -> Matcher.result
  314.     var result = function (id, rect) {
  315.       return {
  316.         id: id,
  317.         rect: rect
  318.       };
  319.     };
  320.  
  321.     // match :: Editor, [(Editor -> Matcher.result | Null)] -> Matcher.result | Null
  322.     var match = function (editor, matchers) {
  323.       for (var i = 0; i < matchers.length; i++) {
  324.         var f = matchers[i];
  325.         var result = f(editor);
  326.  
  327.         if (result) {
  328.           return result;
  329.         }
  330.       }
  331.  
  332.       return null;
  333.     };
  334.  
  335.     return {
  336.       match: match,
  337.       result: result
  338.     };
  339.   }
  340. );
  341.  
  342. /**
  343.  * ResolveGlobal.js
  344.  *
  345.  * Released under LGPL License.
  346.  * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
  347.  *
  348.  * License: http://www.tinymce.com/license
  349.  * Contributing: http://www.tinymce.com/contributing
  350.  */
  351.  
  352. define(
  353.   'tinymce.core.dom.DOMUtils',
  354.   [
  355.     'global!tinymce.util.Tools.resolve'
  356.   ],
  357.   function (resolve) {
  358.     return resolve('tinymce.dom.DOMUtils');
  359.   }
  360. );
  361.  
  362. /**
  363.  * Convert.js
  364.  *
  365.  * Released under LGPL License.
  366.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  367.  *
  368.  * License: http://www.tinymce.com/license
  369.  * Contributing: http://www.tinymce.com/contributing
  370.  */
  371.  
  372. define(
  373.   'tinymce.themes.inlite.core.Convert',
  374.   [
  375.   ],
  376.   function () {
  377.     var fromClientRect = function (clientRect) {
  378.       return {
  379.         x: clientRect.left,
  380.         y: clientRect.top,
  381.         w: clientRect.width,
  382.         h: clientRect.height
  383.       };
  384.     };
  385.  
  386.     var toClientRect = function (geomRect) {
  387.       return {
  388.         left: geomRect.x,
  389.         top: geomRect.y,
  390.         width: geomRect.w,
  391.         height: geomRect.h,
  392.         right: geomRect.x + geomRect.w,
  393.         bottom: geomRect.y + geomRect.h
  394.       };
  395.     };
  396.  
  397.     return {
  398.       fromClientRect: fromClientRect,
  399.       toClientRect: toClientRect
  400.     };
  401.   }
  402. );
  403.  
  404. /**
  405.  * Measure.js
  406.  *
  407.  * Released under LGPL License.
  408.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  409.  *
  410.  * License: http://www.tinymce.com/license
  411.  * Contributing: http://www.tinymce.com/contributing
  412.  */
  413.  
  414. define(
  415.   'tinymce.themes.inlite.core.Measure',
  416.   [
  417.     'tinymce.core.dom.DOMUtils',
  418.     'tinymce.themes.inlite.core.Convert'
  419.   ],
  420.   function (DOMUtils, Convert) {
  421.     var toAbsolute = function (rect) {
  422.       var vp = DOMUtils.DOM.getViewPort();
  423.  
  424.       return {
  425.         x: rect.x + vp.x,
  426.         y: rect.y + vp.y,
  427.         w: rect.w,
  428.         h: rect.h
  429.       };
  430.     };
  431.  
  432.     var measureElement = function (elm) {
  433.       var clientRect = elm.getBoundingClientRect();
  434.  
  435.       return toAbsolute({
  436.         x: clientRect.left,
  437.         y: clientRect.top,
  438.         w: Math.max(elm.clientWidth, elm.offsetWidth),
  439.         h: Math.max(elm.clientHeight, elm.offsetHeight)
  440.       });
  441.     };
  442.  
  443.     var getElementRect = function (editor, elm) {
  444.       return measureElement(elm);
  445.     };
  446.  
  447.     var getPageAreaRect = function (editor) {
  448.       return measureElement(editor.getElement().ownerDocument.body);
  449.     };
  450.  
  451.     var getContentAreaRect = function (editor) {
  452.       return measureElement(editor.getContentAreaContainer() || editor.getBody());
  453.     };
  454.  
  455.     var getSelectionRect = function (editor) {
  456.       var clientRect = editor.selection.getBoundingClientRect();
  457.       return clientRect ? toAbsolute(Convert.fromClientRect(clientRect)) : null;
  458.     };
  459.  
  460.     return {
  461.       getElementRect: getElementRect,
  462.       getPageAreaRect: getPageAreaRect,
  463.       getContentAreaRect: getContentAreaRect,
  464.       getSelectionRect: getSelectionRect
  465.     };
  466.   }
  467. );
  468.  
  469. /**
  470.  * ElementMatcher.js
  471.  *
  472.  * Released under LGPL License.
  473.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  474.  *
  475.  * License: http://www.tinymce.com/license
  476.  * Contributing: http://www.tinymce.com/contributing
  477.  */
  478.  
  479. define(
  480.   'tinymce.themes.inlite.core.ElementMatcher',
  481.   [
  482.     'tinymce.themes.inlite.core.Matcher',
  483.     'tinymce.themes.inlite.core.Measure'
  484.   ],
  485.   function (Matcher, Measure) {
  486.     // element :: Element, [PredicateId] -> (Editor -> Matcher.result | Null)
  487.     var element = function (element, predicateIds) {
  488.       return function (editor) {
  489.         for (var i = 0; i < predicateIds.length; i++) {
  490.           if (predicateIds[i].predicate(element)) {
  491.             return Matcher.result(predicateIds[i].id, Measure.getElementRect(editor, element));
  492.           }
  493.         }
  494.  
  495.         return null;
  496.       };
  497.     };
  498.  
  499.     // parent :: [Elements], [PredicateId] -> (Editor -> Matcher.result | Null)
  500.     var parent = function (elements, predicateIds) {
  501.       return function (editor) {
  502.         for (var i = 0; i < elements.length; i++) {
  503.           for (var x = 0; x < predicateIds.length; x++) {
  504.             if (predicateIds[x].predicate(elements[i])) {
  505.               return Matcher.result(predicateIds[x].id, Measure.getElementRect(editor, elements[i]));
  506.             }
  507.           }
  508.         }
  509.  
  510.         return null;
  511.       };
  512.     };
  513.  
  514.     return {
  515.       element: element,
  516.       parent: parent
  517.     };
  518.   }
  519. );
  520.  
  521. /**
  522.  * ResolveGlobal.js
  523.  *
  524.  * Released under LGPL License.
  525.  * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
  526.  *
  527.  * License: http://www.tinymce.com/license
  528.  * Contributing: http://www.tinymce.com/contributing
  529.  */
  530.  
  531. define(
  532.   'tinymce.core.util.Tools',
  533.   [
  534.     'global!tinymce.util.Tools.resolve'
  535.   ],
  536.   function (resolve) {
  537.     return resolve('tinymce.util.Tools');
  538.   }
  539. );
  540.  
  541. /**
  542.  * PredicateId.js
  543.  *
  544.  * Released under LGPL License.
  545.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  546.  *
  547.  * License: http://www.tinymce.com/license
  548.  * Contributing: http://www.tinymce.com/contributing
  549.  */
  550.  
  551. define(
  552.   'tinymce.themes.inlite.core.PredicateId',
  553.   [
  554.     'tinymce.core.util.Tools'
  555.   ],
  556.   function (Tools) {
  557.     var create = function (id, predicate) {
  558.       return {
  559.         id: id,
  560.         predicate: predicate
  561.       };
  562.     };
  563.  
  564.     // fromContextToolbars :: [ContextToolbar] -> [PredicateId]
  565.     var fromContextToolbars = function (toolbars) {
  566.       return Tools.map(toolbars, function (toolbar) {
  567.         return create(toolbar.id, toolbar.predicate);
  568.       });
  569.     };
  570.  
  571.     return {
  572.       create: create,
  573.       fromContextToolbars: fromContextToolbars
  574.     };
  575.   }
  576. );
  577.  
  578. /**
  579.  * SelectionMatcher.js
  580.  *
  581.  * Released under LGPL License.
  582.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  583.  *
  584.  * License: http://www.tinymce.com/license
  585.  * Contributing: http://www.tinymce.com/contributing
  586.  */
  587.  
  588. define(
  589.   'tinymce.themes.inlite.core.SelectionMatcher',
  590.   [
  591.     'tinymce.themes.inlite.core.Matcher',
  592.     'tinymce.themes.inlite.core.Measure'
  593.   ],
  594.   function (Matcher, Measure) {
  595.     // textSelection :: String -> (Editor -> Matcher.result | Null)
  596.     var textSelection = function (id) {
  597.       return function (editor) {
  598.         if (!editor.selection.isCollapsed()) {
  599.           return Matcher.result(id, Measure.getSelectionRect(editor));
  600.         }
  601.  
  602.         return null;
  603.       };
  604.     };
  605.  
  606.     // emptyTextBlock :: [Elements], String -> (Editor -> Matcher.result | Null)
  607.     var emptyTextBlock = function (elements, id) {
  608.       return function (editor) {
  609.         var i, textBlockElementsMap = editor.schema.getTextBlockElements();
  610.  
  611.         for (i = 0; i < elements.length; i++) {
  612.           if (elements[i].nodeName === 'TABLE') {
  613.             return null;
  614.           }
  615.         }
  616.  
  617.         for (i = 0; i < elements.length; i++) {
  618.           if (elements[i].nodeName in textBlockElementsMap) {
  619.             if (editor.dom.isEmpty(elements[i])) {
  620.               return Matcher.result(id, Measure.getSelectionRect(editor));
  621.             }
  622.  
  623.             return null;
  624.           }
  625.         }
  626.  
  627.         return null;
  628.       };
  629.     };
  630.  
  631.     return {
  632.       textSelection: textSelection,
  633.       emptyTextBlock: emptyTextBlock
  634.     };
  635.   }
  636. );
  637.  
  638. /**
  639.  * ResolveGlobal.js
  640.  *
  641.  * Released under LGPL License.
  642.  * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
  643.  *
  644.  * License: http://www.tinymce.com/license
  645.  * Contributing: http://www.tinymce.com/contributing
  646.  */
  647.  
  648. define(
  649.   'tinymce.core.EditorManager',
  650.   [
  651.     'global!tinymce.util.Tools.resolve'
  652.   ],
  653.   function (resolve) {
  654.     return resolve('tinymce.EditorManager');
  655.   }
  656. );
  657.  
  658. /**
  659.  * SkinLoader.js
  660.  *
  661.  * Released under LGPL License.
  662.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  663.  *
  664.  * License: http://www.tinymce.com/license
  665.  * Contributing: http://www.tinymce.com/contributing
  666.  */
  667.  
  668. define(
  669.   'tinymce.themes.inlite.core.SkinLoader',
  670.   [
  671.     'tinymce.core.EditorManager',
  672.     'tinymce.core.dom.DOMUtils'
  673.   ],
  674.   function (EditorManager, DOMUtils) {
  675.     var fireSkinLoaded = function (editor, callback) {
  676.       var done = function () {
  677.         editor._skinLoaded = true;
  678.         editor.fire('SkinLoaded');
  679.         callback();
  680.       };
  681.  
  682.       if (editor.initialized) {
  683.         done();
  684.       } else {
  685.         editor.on('init', done);
  686.       }
  687.     };
  688.  
  689.     var urlFromName = function (name) {
  690.       var prefix = EditorManager.baseURL + '/skins/';
  691.       return name ? prefix + name : prefix + 'lightgray';
  692.     };
  693.  
  694.     var toAbsoluteUrl = function (editor, url) {
  695.       return editor.documentBaseURI.toAbsolute(url);
  696.     };
  697.  
  698.     var load = function (editor, callback) {
  699.       var settings = editor.settings;
  700.       var skinUrl = settings.skin_url ? toAbsoluteUrl(editor, settings.skin_url) : urlFromName(settings.skin);
  701.  
  702.       var done = function () {
  703.         fireSkinLoaded(editor, callback);
  704.       };
  705.  
  706.       DOMUtils.DOM.styleSheetLoader.load(skinUrl + '/skin.min.css', done);
  707.       editor.contentCSS.push(skinUrl + '/content.inline.min.css');
  708.     };
  709.  
  710.     return {
  711.       load: load
  712.     };
  713.   }
  714. );
  715.  
  716.  
  717.  
  718. /**
  719.  * ResolveGlobal.js
  720.  *
  721.  * Released under LGPL License.
  722.  * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
  723.  *
  724.  * License: http://www.tinymce.com/license
  725.  * Contributing: http://www.tinymce.com/contributing
  726.  */
  727.  
  728. define(
  729.   'tinymce.core.ui.Factory',
  730.   [
  731.     'global!tinymce.util.Tools.resolve'
  732.   ],
  733.   function (resolve) {
  734.     return resolve('tinymce.ui.Factory');
  735.   }
  736. );
  737.  
  738. /**
  739.  * Toolbar.js
  740.  *
  741.  * Released under LGPL License.
  742.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  743.  *
  744.  * License: http://www.tinymce.com/license
  745.  * Contributing: http://www.tinymce.com/contributing
  746.  */
  747.  
  748. define(
  749.   'tinymce.themes.inlite.ui.Toolbar',
  750.   [
  751.     'tinymce.core.util.Tools',
  752.     'tinymce.core.ui.Factory',
  753.     'tinymce.themes.inlite.alien.Type'
  754.   ],
  755.   function (Tools, Factory, Type) {
  756.     var getSelectorStateResult = function (itemName, item) {
  757.       var result = function (selector, handler) {
  758.         return {
  759.           selector: selector,
  760.           handler: handler
  761.         };
  762.       };
  763.  
  764.       var activeHandler = function (state) {
  765.         item.active(state);
  766.       };
  767.  
  768.       var disabledHandler = function (state) {
  769.         item.disabled(state);
  770.       };
  771.  
  772.       if (item.settings.stateSelector) {
  773.         return result(item.settings.stateSelector, activeHandler);
  774.       }
  775.  
  776.       if (item.settings.disabledStateSelector) {
  777.         return result(item.settings.disabledStateSelector, disabledHandler);
  778.       }
  779.  
  780.       return null;
  781.     };
  782.  
  783.     var bindSelectorChanged = function (editor, itemName, item) {
  784.       return function () {
  785.         var result = getSelectorStateResult(itemName, item);
  786.         if (result !== null) {
  787.           editor.selection.selectorChanged(result.selector, result.handler);
  788.         }
  789.       };
  790.     };
  791.  
  792.     var itemsToArray = function (items) {
  793.       if (Type.isArray(items)) {
  794.         return items;
  795.       } else if (Type.isString(items)) {
  796.         return items.split(/[ ,]/);
  797.       }
  798.  
  799.       return [];
  800.     };
  801.  
  802.     var create = function (editor, name, items) {
  803.       var toolbarItems = [], buttonGroup;
  804.  
  805.       if (!items) {
  806.         return;
  807.       }
  808.  
  809.       Tools.each(itemsToArray(items), function (item) {
  810.         var itemName;
  811.  
  812.         if (item == '|') {
  813.           buttonGroup = null;
  814.         } else {
  815.           if (editor.buttons[item]) {
  816.             if (!buttonGroup) {
  817.               buttonGroup = { type: 'buttongroup', items: [] };
  818.               toolbarItems.push(buttonGroup);
  819.             }
  820.  
  821.             itemName = item;
  822.             item = editor.buttons[itemName];
  823.  
  824.             if (typeof item == 'function') {
  825.               item = item();
  826.             }
  827.  
  828.             item.type = item.type || 'button';
  829.  
  830.             item = Factory.create(item);
  831.             item.on('postRender', bindSelectorChanged(editor, itemName, item));
  832.             buttonGroup.items.push(item);
  833.           }
  834.         }
  835.       });
  836.  
  837.       return Factory.create({
  838.         type: 'toolbar',
  839.         layout: 'flow',
  840.         name: name,
  841.         items: toolbarItems
  842.       });
  843.     };
  844.  
  845.     return {
  846.       create: create
  847.     };
  848.   }
  849. );
  850.  
  851. /**
  852.  * ResolveGlobal.js
  853.  *
  854.  * Released under LGPL License.
  855.  * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
  856.  *
  857.  * License: http://www.tinymce.com/license
  858.  * Contributing: http://www.tinymce.com/contributing
  859.  */
  860.  
  861. define(
  862.   'tinymce.core.util.Promise',
  863.   [
  864.     'global!tinymce.util.Tools.resolve'
  865.   ],
  866.   function (resolve) {
  867.     return resolve('tinymce.util.Promise');
  868.   }
  869. );
  870.  
  871. /**
  872.  * Uuid.js
  873.  *
  874.  * Released under LGPL License.
  875.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  876.  *
  877.  * License: http://www.tinymce.com/license
  878.  * Contributing: http://www.tinymce.com/contributing
  879.  */
  880.  
  881. /**
  882.  * Generates unique ids this is the same as in core but since
  883.  * it's not exposed as a global we can't access it.
  884.  */
  885. define(
  886.   "tinymce.themes.inlite.alien.Uuid",
  887.   [
  888.   ],
  889.   function () {
  890.     var count = 0;
  891.  
  892.     var seed = function () {
  893.       var rnd = function () {
  894.         return Math.round(Math.random() * 0xFFFFFFFF).toString(36);
  895.       };
  896.  
  897.       return 's' + Date.now().toString(36) + rnd() + rnd() + rnd();
  898.     };
  899.  
  900.     var uuid = function (prefix) {
  901.       return prefix + (count++) + seed();
  902.     };
  903.  
  904.     return {
  905.       uuid: uuid
  906.     };
  907.   }
  908. );
  909.  
  910. /**
  911.  * Bookmark.js
  912.  *
  913.  * Released under LGPL License.
  914.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  915.  *
  916.  * License: http://www.tinymce.com/license
  917.  * Contributing: http://www.tinymce.com/contributing
  918.  */
  919.  
  920. define(
  921.   'tinymce.themes.inlite.alien.Bookmark',
  922.   [
  923.   ],
  924.   function () {
  925.     /**
  926.      * Returns a range bookmark. This will convert indexed bookmarks into temporary span elements with
  927.      * index 0 so that they can be restored properly after the DOM has been modified. Text bookmarks will not have spans
  928.      * added to them since they can be restored after a dom operation.
  929.      *
  930.      * So this: <p><b>|</b><b>|</b></p>
  931.      * becomes: <p><b><span data-mce-type="bookmark">|</span></b><b data-mce-type="bookmark">|</span></b></p>
  932.      *
  933.      * @param  {DOMRange} rng DOM Range to get bookmark on.
  934.      * @return {Object} Bookmark object.
  935.      */
  936.     var create = function (dom, rng) {
  937.       var bookmark = {};
  938.  
  939.       function setupEndPoint(start) {
  940.         var offsetNode, container, offset;
  941.  
  942.         container = rng[start ? 'startContainer' : 'endContainer'];
  943.         offset = rng[start ? 'startOffset' : 'endOffset'];
  944.  
  945.         if (container.nodeType == 1) {
  946.           offsetNode = dom.create('span', { 'data-mce-type': 'bookmark' });
  947.  
  948.           if (container.hasChildNodes()) {
  949.             offset = Math.min(offset, container.childNodes.length - 1);
  950.  
  951.             if (start) {
  952.               container.insertBefore(offsetNode, container.childNodes[offset]);
  953.             } else {
  954.               dom.insertAfter(offsetNode, container.childNodes[offset]);
  955.             }
  956.           } else {
  957.             container.appendChild(offsetNode);
  958.           }
  959.  
  960.           container = offsetNode;
  961.           offset = 0;
  962.         }
  963.  
  964.         bookmark[start ? 'startContainer' : 'endContainer'] = container;
  965.         bookmark[start ? 'startOffset' : 'endOffset'] = offset;
  966.       }
  967.  
  968.       setupEndPoint(true);
  969.  
  970.       if (!rng.collapsed) {
  971.         setupEndPoint();
  972.       }
  973.  
  974.       return bookmark;
  975.     };
  976.  
  977.     /**
  978.      * Moves the selection to the current bookmark and removes any selection container wrappers.
  979.      *
  980.      * @param {Object} bookmark Bookmark object to move selection to.
  981.      */
  982.     var resolve = function (dom, bookmark) {
  983.       function restoreEndPoint(start) {
  984.         var container, offset, node;
  985.  
  986.         function nodeIndex(container) {
  987.           var node = container.parentNode.firstChild, idx = 0;
  988.  
  989.           while (node) {
  990.             if (node == container) {
  991.               return idx;
  992.             }
  993.  
  994.             // Skip data-mce-type=bookmark nodes
  995.             if (node.nodeType != 1 || node.getAttribute('data-mce-type') != 'bookmark') {
  996.               idx++;
  997.             }
  998.  
  999.             node = node.nextSibling;
  1000.           }
  1001.  
  1002.           return -1;
  1003.         }
  1004.  
  1005.         container = node = bookmark[start ? 'startContainer' : 'endContainer'];
  1006.         offset = bookmark[start ? 'startOffset' : 'endOffset'];
  1007.  
  1008.         if (!container) {
  1009.           return;
  1010.         }
  1011.  
  1012.         if (container.nodeType == 1) {
  1013.           offset = nodeIndex(container);
  1014.           container = container.parentNode;
  1015.           dom.remove(node);
  1016.         }
  1017.  
  1018.         bookmark[start ? 'startContainer' : 'endContainer'] = container;
  1019.         bookmark[start ? 'startOffset' : 'endOffset'] = offset;
  1020.       }
  1021.  
  1022.       restoreEndPoint(true);
  1023.       restoreEndPoint();
  1024.  
  1025.       var rng = dom.createRng();
  1026.  
  1027.       rng.setStart(bookmark.startContainer, bookmark.startOffset);
  1028.  
  1029.       if (bookmark.endContainer) {
  1030.         rng.setEnd(bookmark.endContainer, bookmark.endOffset);
  1031.       }
  1032.  
  1033.       return rng;
  1034.     };
  1035.  
  1036.     return {
  1037.       create: create,
  1038.       resolve: resolve
  1039.     };
  1040.   }
  1041. );
  1042.  
  1043.  
  1044.  
  1045. /**
  1046.  * ResolveGlobal.js
  1047.  *
  1048.  * Released under LGPL License.
  1049.  * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
  1050.  *
  1051.  * License: http://www.tinymce.com/license
  1052.  * Contributing: http://www.tinymce.com/contributing
  1053.  */
  1054.  
  1055. define(
  1056.   'tinymce.core.dom.TreeWalker',
  1057.   [
  1058.     'global!tinymce.util.Tools.resolve'
  1059.   ],
  1060.   function (resolve) {
  1061.     return resolve('tinymce.dom.TreeWalker');
  1062.   }
  1063. );
  1064.  
  1065. /**
  1066.  * ResolveGlobal.js
  1067.  *
  1068.  * Released under LGPL License.
  1069.  * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
  1070.  *
  1071.  * License: http://www.tinymce.com/license
  1072.  * Contributing: http://www.tinymce.com/contributing
  1073.  */
  1074.  
  1075. define(
  1076.   'tinymce.core.dom.RangeUtils',
  1077.   [
  1078.     'global!tinymce.util.Tools.resolve'
  1079.   ],
  1080.   function (resolve) {
  1081.     return resolve('tinymce.dom.RangeUtils');
  1082.   }
  1083. );
  1084.  
  1085. /**
  1086.  * Unlink.js
  1087.  *
  1088.  * Released under LGPL License.
  1089.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  1090.  *
  1091.  * License: http://www.tinymce.com/license
  1092.  * Contributing: http://www.tinymce.com/contributing
  1093.  */
  1094.  
  1095. /**
  1096.  * Unlink implementation that doesn't leave partial links for example it would produce:
  1097.  *  a[b<a href="x">c]d</a>e -> a[bc]de
  1098.  * instead of:
  1099.  *  a[b<a href="x">c]d</a>e -> a[bc]<a href="x">d</a>e
  1100.  */
  1101. define(
  1102.   "tinymce.themes.inlite.alien.Unlink",
  1103.   [
  1104.     'tinymce.themes.inlite.alien.Bookmark',
  1105.     'tinymce.core.util.Tools',
  1106.     'tinymce.core.dom.TreeWalker',
  1107.     'tinymce.core.dom.RangeUtils'
  1108.   ],
  1109.   function (Bookmark, Tools, TreeWalker, RangeUtils) {
  1110.     var getSelectedElements = function (rootElm, startNode, endNode) {
  1111.       var walker, node, elms = [];
  1112.  
  1113.       walker = new TreeWalker(startNode, rootElm);
  1114.       for (node = startNode; node; node = walker.next()) {
  1115.         if (node.nodeType === 1) {
  1116.           elms.push(node);
  1117.         }
  1118.  
  1119.         if (node === endNode) {
  1120.           break;
  1121.         }
  1122.       }
  1123.  
  1124.       return elms;
  1125.     };
  1126.  
  1127.     var unwrapElements = function (editor, elms) {
  1128.       var bookmark, dom, selection;
  1129.  
  1130.       dom = editor.dom;
  1131.       selection = editor.selection;
  1132.       bookmark = Bookmark.create(dom, selection.getRng());
  1133.  
  1134.       Tools.each(elms, function (elm) {
  1135.         editor.dom.remove(elm, true);
  1136.       });
  1137.  
  1138.       selection.setRng(Bookmark.resolve(dom, bookmark));
  1139.     };
  1140.  
  1141.     var isLink = function (elm) {
  1142.       return elm.nodeName === 'A' && elm.hasAttribute('href');
  1143.     };
  1144.  
  1145.     var getParentAnchorOrSelf = function (dom, elm) {
  1146.       var anchorElm = dom.getParent(elm, isLink);
  1147.       return anchorElm ? anchorElm : elm;
  1148.     };
  1149.  
  1150.     var getSelectedAnchors = function (editor) {
  1151.       var startElm, endElm, rootElm, anchorElms, selection, dom, rng;
  1152.  
  1153.       selection = editor.selection;
  1154.       dom = editor.dom;
  1155.       rng = selection.getRng();
  1156.       startElm = getParentAnchorOrSelf(dom, RangeUtils.getNode(rng.startContainer, rng.startOffset));
  1157.       endElm = RangeUtils.getNode(rng.endContainer, rng.endOffset);
  1158.       rootElm = editor.getBody();
  1159.       anchorElms = Tools.grep(getSelectedElements(rootElm, startElm, endElm), isLink);
  1160.  
  1161.       return anchorElms;
  1162.     };
  1163.  
  1164.     var unlinkSelection = function (editor) {
  1165.       unwrapElements(editor, getSelectedAnchors(editor));
  1166.     };
  1167.  
  1168.     return {
  1169.       unlinkSelection: unlinkSelection
  1170.     };
  1171.   }
  1172. );
  1173.  
  1174. /**
  1175.  * Actions.js
  1176.  *
  1177.  * Released under LGPL License.
  1178.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  1179.  *
  1180.  * License: http://www.tinymce.com/license
  1181.  * Contributing: http://www.tinymce.com/contributing
  1182.  */
  1183.  
  1184. define(
  1185.   'tinymce.themes.inlite.core.Actions',
  1186.   [
  1187.     'tinymce.themes.inlite.alien.Uuid',
  1188.     'tinymce.themes.inlite.alien.Unlink'
  1189.   ],
  1190.   function (Uuid, Unlink) {
  1191.     var createTableHtml = function (cols, rows) {
  1192.       var x, y, html;
  1193.  
  1194.       html = '<table data-mce-id="mce" style="width: 100%">';
  1195.       html += '<tbody>';
  1196.  
  1197.       for (y = 0; y < rows; y++) {
  1198.         html += '<tr>';
  1199.  
  1200.         for (x = 0; x < cols; x++) {
  1201.           html += '<td><br></td>';
  1202.         }
  1203.  
  1204.         html += '</tr>';
  1205.       }
  1206.  
  1207.       html += '</tbody>';
  1208.       html += '</table>';
  1209.  
  1210.       return html;
  1211.     };
  1212.  
  1213.     var getInsertedElement = function (editor) {
  1214.       var elms = editor.dom.select('*[data-mce-id]');
  1215.       return elms[0];
  1216.     };
  1217.  
  1218.     var insertTable = function (editor, cols, rows) {
  1219.       editor.undoManager.transact(function () {
  1220.         var tableElm, cellElm;
  1221.  
  1222.         editor.insertContent(createTableHtml(cols, rows));
  1223.  
  1224.         tableElm = getInsertedElement(editor);
  1225.         tableElm.removeAttribute('data-mce-id');
  1226.         cellElm = editor.dom.select('td,th', tableElm);
  1227.         editor.selection.setCursorLocation(cellElm[0], 0);
  1228.       });
  1229.     };
  1230.  
  1231.     var formatBlock = function (editor, formatName) {
  1232.       editor.execCommand('FormatBlock', false, formatName);
  1233.     };
  1234.  
  1235.     var insertBlob = function (editor, base64, blob) {
  1236.       var blobCache, blobInfo;
  1237.  
  1238.       blobCache = editor.editorUpload.blobCache;
  1239.       blobInfo = blobCache.create(Uuid.uuid('mceu'), blob, base64);
  1240.       blobCache.add(blobInfo);
  1241.  
  1242.       editor.insertContent(editor.dom.createHTML('img', { src: blobInfo.blobUri() }));
  1243.     };
  1244.  
  1245.     var collapseSelectionToEnd = function (editor) {
  1246.       editor.selection.collapse(false);
  1247.     };
  1248.  
  1249.     var unlink = function (editor) {
  1250.       editor.focus();
  1251.       Unlink.unlinkSelection(editor);
  1252.       collapseSelectionToEnd(editor);
  1253.     };
  1254.  
  1255.     var changeHref = function (editor, elm, url) {
  1256.       editor.focus();
  1257.       editor.dom.setAttrib(elm, 'href', url);
  1258.       collapseSelectionToEnd(editor);
  1259.     };
  1260.  
  1261.     var insertLink = function (editor, url) {
  1262.       editor.execCommand('mceInsertLink', false, { href: url });
  1263.       collapseSelectionToEnd(editor);
  1264.     };
  1265.  
  1266.     var updateOrInsertLink = function (editor, url) {
  1267.       var elm = editor.dom.getParent(editor.selection.getStart(), 'a[href]');
  1268.       elm ? changeHref(editor, elm, url) : insertLink(editor, url);
  1269.     };
  1270.  
  1271.     var createLink = function (editor, url) {
  1272.       url.trim().length === 0 ? unlink(editor) : updateOrInsertLink(editor, url);
  1273.     };
  1274.  
  1275.     return {
  1276.       insertTable: insertTable,
  1277.       formatBlock: formatBlock,
  1278.       insertBlob: insertBlob,
  1279.       createLink: createLink,
  1280.       unlink: unlink
  1281.     };
  1282.   }
  1283. );
  1284.  
  1285. /**
  1286.  * UrlType.js
  1287.  *
  1288.  * Released under LGPL License.
  1289.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  1290.  *
  1291.  * License: http://www.tinymce.com/license
  1292.  * Contributing: http://www.tinymce.com/contributing
  1293.  */
  1294.  
  1295. define(
  1296.   'tinymce.themes.inlite.core.UrlType',
  1297.   [
  1298.   ],
  1299.   function () {
  1300.     var isDomainLike = function (href) {
  1301.       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());
  1302.     };
  1303.  
  1304.     var isAbsolute = function (href) {
  1305.       return /^https?:\/\//.test(href.trim());
  1306.     };
  1307.  
  1308.     return {
  1309.       isDomainLike: isDomainLike,
  1310.       isAbsolute: isAbsolute
  1311.     };
  1312.   }
  1313. );
  1314.  
  1315.  
  1316.  
  1317. /**
  1318.  * Forms.js
  1319.  *
  1320.  * Released under LGPL License.
  1321.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  1322.  *
  1323.  * License: http://www.tinymce.com/license
  1324.  * Contributing: http://www.tinymce.com/contributing
  1325.  */
  1326.  
  1327. define(
  1328.   'tinymce.themes.inlite.ui.Forms',
  1329.   [
  1330.     'tinymce.core.util.Tools',
  1331.     'tinymce.core.ui.Factory',
  1332.     'tinymce.core.util.Promise',
  1333.     'tinymce.themes.inlite.core.Actions',
  1334.     'tinymce.themes.inlite.core.UrlType'
  1335.   ],
  1336.   function (Tools, Factory, Promise, Actions, UrlType) {
  1337.     var focusFirstTextBox = function (form) {
  1338.       form.find('textbox').eq(0).each(function (ctrl) {
  1339.         ctrl.focus();
  1340.       });
  1341.     };
  1342.  
  1343.     var createForm = function (name, spec) {
  1344.       var form = Factory.create(
  1345.         Tools.extend({
  1346.           type: 'form',
  1347.           layout: 'flex',
  1348.           direction: 'row',
  1349.           padding: 5,
  1350.           name: name,
  1351.           spacing: 3
  1352.         }, spec)
  1353.       );
  1354.  
  1355.       form.on('show', function () {
  1356.         focusFirstTextBox(form);
  1357.       });
  1358.  
  1359.       return form;
  1360.     };
  1361.  
  1362.     var toggleVisibility = function (ctrl, state) {
  1363.       return state ? ctrl.show() : ctrl.hide();
  1364.     };
  1365.  
  1366.     var askAboutPrefix = function (editor, href) {
  1367.       return new Promise(function (resolve) {
  1368.         editor.windowManager.confirm(
  1369.           'The URL you entered seems to be an external link. Do you want to add the required http:// prefix?',
  1370.           function (result) {
  1371.             var output = result === true ? 'http://' + href : href;
  1372.             resolve(output);
  1373.           }
  1374.         );
  1375.       });
  1376.     };
  1377.  
  1378.     var convertLinkToAbsolute = function (editor, href) {
  1379.       return !UrlType.isAbsolute(href) && UrlType.isDomainLike(href) ? askAboutPrefix(editor, href) : Promise.resolve(href);
  1380.     };
  1381.  
  1382.     var createQuickLinkForm = function (editor, hide) {
  1383.       var attachState = {};
  1384.  
  1385.       var unlink = function () {
  1386.         editor.focus();
  1387.         Actions.unlink(editor);
  1388.         hide();
  1389.       };
  1390.  
  1391.       var onChangeHandler = function (e) {
  1392.         var meta = e.meta;
  1393.  
  1394.         if (meta && meta.attach) {
  1395.           attachState = {
  1396.             href: this.value(),
  1397.             attach: meta.attach
  1398.           };
  1399.         }
  1400.       };
  1401.  
  1402.       var onShowHandler = function (e) {
  1403.         if (e.control === this) {
  1404.           var elm, linkurl = '';
  1405.  
  1406.           elm = editor.dom.getParent(editor.selection.getStart(), 'a[href]');
  1407.           if (elm) {
  1408.             linkurl = editor.dom.getAttrib(elm, 'href');
  1409.           }
  1410.  
  1411.           this.fromJSON({
  1412.             linkurl: linkurl
  1413.           });
  1414.  
  1415.           toggleVisibility(this.find('#unlink'), elm);
  1416.           this.find('#linkurl')[0].focus();
  1417.         }
  1418.       };
  1419.  
  1420.       return createForm('quicklink', {
  1421.         items: [
  1422.           { type: 'button', name: 'unlink', icon: 'unlink', onclick: unlink, tooltip: 'Remove link' },
  1423.           { type: 'filepicker', name: 'linkurl', placeholder: 'Paste or type a link', filetype: 'file', onchange: onChangeHandler },
  1424.           { type: 'button', icon: 'checkmark', subtype: 'primary', tooltip: 'Ok', onclick: 'submit' }
  1425.         ],
  1426.         onshow: onShowHandler,
  1427.         onsubmit: function (e) {
  1428.           convertLinkToAbsolute(editor, e.data.linkurl).then(function (url) {
  1429.             editor.undoManager.transact(function () {
  1430.               if (url === attachState.href) {
  1431.                 attachState.attach();
  1432.                 attachState = {};
  1433.               }
  1434.  
  1435.               Actions.createLink(editor, url);
  1436.             });
  1437.  
  1438.             hide();
  1439.           });
  1440.         }
  1441.       });
  1442.     };
  1443.  
  1444.     return {
  1445.       createQuickLinkForm: createQuickLinkForm
  1446.     };
  1447.   }
  1448. );
  1449.  
  1450. /**
  1451.  * ResolveGlobal.js
  1452.  *
  1453.  * Released under LGPL License.
  1454.  * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
  1455.  *
  1456.  * License: http://www.tinymce.com/license
  1457.  * Contributing: http://www.tinymce.com/contributing
  1458.  */
  1459.  
  1460. define(
  1461.   'tinymce.core.geom.Rect',
  1462.   [
  1463.     'global!tinymce.util.Tools.resolve'
  1464.   ],
  1465.   function (resolve) {
  1466.     return resolve('tinymce.geom.Rect');
  1467.   }
  1468. );
  1469.  
  1470. /**
  1471.  * Layout.js
  1472.  *
  1473.  * Released under LGPL License.
  1474.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  1475.  *
  1476.  * License: http://www.tinymce.com/license
  1477.  * Contributing: http://www.tinymce.com/contributing
  1478.  */
  1479.  
  1480. define(
  1481.   'tinymce.themes.inlite.core.Layout',
  1482.   [
  1483.     'tinymce.core.geom.Rect',
  1484.     'tinymce.themes.inlite.core.Convert'
  1485.   ],
  1486.   function (Rect, Convert) {
  1487.     var result = function (rect, position) {
  1488.       return {
  1489.         rect: rect,
  1490.         position: position
  1491.       };
  1492.     };
  1493.  
  1494.     var moveTo = function (rect, toRect) {
  1495.       return { x: toRect.x, y: toRect.y, w: rect.w, h: rect.h };
  1496.     };
  1497.  
  1498.     var calcByPositions = function (testPositions1, testPositions2, targetRect, contentAreaRect, panelRect) {
  1499.       var relPos, relRect, outputPanelRect;
  1500.  
  1501.       var paddedContentRect = {
  1502.         x: contentAreaRect.x,
  1503.         y: contentAreaRect.y,
  1504.         w: contentAreaRect.w + (contentAreaRect.w < (panelRect.w + targetRect.w) ? panelRect.w : 0),
  1505.         h: contentAreaRect.h + (contentAreaRect.h < (panelRect.h + targetRect.h) ? panelRect.h : 0)
  1506.       };
  1507.  
  1508.       relPos = Rect.findBestRelativePosition(panelRect, targetRect, paddedContentRect, testPositions1);
  1509.       targetRect = Rect.clamp(targetRect, paddedContentRect);
  1510.  
  1511.       if (relPos) {
  1512.         relRect = Rect.relativePosition(panelRect, targetRect, relPos);
  1513.         outputPanelRect = moveTo(panelRect, relRect);
  1514.         return result(outputPanelRect, relPos);
  1515.       }
  1516.  
  1517.       targetRect = Rect.intersect(paddedContentRect, targetRect);
  1518.       if (targetRect) {
  1519.         relPos = Rect.findBestRelativePosition(panelRect, targetRect, paddedContentRect, testPositions2);
  1520.  
  1521.         if (relPos) {
  1522.           relRect = Rect.relativePosition(panelRect, targetRect, relPos);
  1523.           outputPanelRect = moveTo(panelRect, relRect);
  1524.           return result(outputPanelRect, relPos);
  1525.         }
  1526.  
  1527.         outputPanelRect = moveTo(panelRect, targetRect);
  1528.         return result(outputPanelRect, relPos);
  1529.       }
  1530.  
  1531.       return null;
  1532.     };
  1533.  
  1534.     var calcInsert = function (targetRect, contentAreaRect, panelRect) {
  1535.       return calcByPositions(
  1536.         ['cr-cl', 'cl-cr'],
  1537.         ['bc-tc', 'bl-tl', 'br-tr'],
  1538.         targetRect,
  1539.         contentAreaRect,
  1540.         panelRect
  1541.       );
  1542.     };
  1543.  
  1544.     var calc = function (targetRect, contentAreaRect, panelRect) {
  1545.       return calcByPositions(
  1546.         ['tc-bc', 'bc-tc', 'tl-bl', 'bl-tl', 'tr-br', 'br-tr', 'cr-cl', 'cl-cr'],
  1547.         ['bc-tc', 'bl-tl', 'br-tr', 'cr-cl'],
  1548.         targetRect,
  1549.         contentAreaRect,
  1550.         panelRect
  1551.       );
  1552.     };
  1553.  
  1554.     var userConstrain = function (handler, targetRect, contentAreaRect, panelRect) {
  1555.       var userConstrainedPanelRect;
  1556.  
  1557.       if (typeof handler === 'function') {
  1558.         userConstrainedPanelRect = handler({
  1559.           elementRect: Convert.toClientRect(targetRect),
  1560.           contentAreaRect: Convert.toClientRect(contentAreaRect),
  1561.           panelRect: Convert.toClientRect(panelRect)
  1562.         });
  1563.  
  1564.         return Convert.fromClientRect(userConstrainedPanelRect);
  1565.       }
  1566.  
  1567.       return panelRect;
  1568.     };
  1569.  
  1570.     var defaultHandler = function (rects) {
  1571.       return rects.panelRect;
  1572.     };
  1573.  
  1574.     return {
  1575.       calcInsert: calcInsert,
  1576.       calc: calc,
  1577.       userConstrain: userConstrain,
  1578.       defaultHandler: defaultHandler
  1579.     };
  1580.   }
  1581. );
  1582.  
  1583. /**
  1584.  * Panel.js
  1585.  *
  1586.  * Released under LGPL License.
  1587.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  1588.  *
  1589.  * License: http://www.tinymce.com/license
  1590.  * Contributing: http://www.tinymce.com/contributing
  1591.  */
  1592.  
  1593. define(
  1594.   'tinymce.themes.inlite.ui.Panel',
  1595.   [
  1596.     'tinymce.core.util.Tools',
  1597.     'tinymce.core.ui.Factory',
  1598.     'tinymce.core.dom.DOMUtils',
  1599.     'tinymce.themes.inlite.ui.Toolbar',
  1600.     'tinymce.themes.inlite.ui.Forms',
  1601.     'tinymce.themes.inlite.core.Measure',
  1602.     'tinymce.themes.inlite.core.Layout',
  1603.     'tinymce.themes.inlite.alien.EditorSettings'
  1604.   ],
  1605.   function (Tools, Factory, DOMUtils, Toolbar, Forms, Measure, Layout, EditorSettings) {
  1606.     return function () {
  1607.       var DEFAULT_TEXT_SELECTION_ITEMS = ['bold', 'italic', '|', 'quicklink', 'h2', 'h3', 'blockquote'];
  1608.       var DEFAULT_INSERT_TOOLBAR_ITEMS = ['quickimage', 'quicktable'];
  1609.       var panel, currentRect;
  1610.  
  1611.       var createToolbars = function (editor, toolbars) {
  1612.         return Tools.map(toolbars, function (toolbar) {
  1613.           return Toolbar.create(editor, toolbar.id, toolbar.items);
  1614.         });
  1615.       };
  1616.  
  1617.       var getTextSelectionToolbarItems = function (editor) {
  1618.         return EditorSettings.getToolbarItemsOr(editor, 'selection_toolbar', DEFAULT_TEXT_SELECTION_ITEMS);
  1619.       };
  1620.  
  1621.       var getInsertToolbarItems = function (editor) {
  1622.         return EditorSettings.getToolbarItemsOr(editor, 'insert_toolbar', DEFAULT_INSERT_TOOLBAR_ITEMS);
  1623.       };
  1624.  
  1625.       var hasToolbarItems = function (toolbar) {
  1626.         return toolbar.items().length > 0;
  1627.       };
  1628.  
  1629.       var create = function (editor, toolbars) {
  1630.         var items = createToolbars(editor, toolbars).concat([
  1631.           Toolbar.create(editor, 'text', getTextSelectionToolbarItems(editor)),
  1632.           Toolbar.create(editor, 'insert', getInsertToolbarItems(editor)),
  1633.           Forms.createQuickLinkForm(editor, hide)
  1634.         ]);
  1635.  
  1636.         return Factory.create({
  1637.           type: 'floatpanel',
  1638.           role: 'dialog',
  1639.           classes: 'tinymce tinymce-inline arrow',
  1640.           ariaLabel: 'Inline toolbar',
  1641.           layout: 'flex',
  1642.           direction: 'column',
  1643.           align: 'stretch',
  1644.           autohide: false,
  1645.           autofix: true,
  1646.           fixed: true,
  1647.           border: 1,
  1648.           items: Tools.grep(items, hasToolbarItems),
  1649.           oncancel: function () {
  1650.             editor.focus();
  1651.           }
  1652.         });
  1653.       };
  1654.  
  1655.       var showPanel = function (panel) {
  1656.         if (panel) {
  1657.           panel.show();
  1658.         }
  1659.       };
  1660.  
  1661.       var movePanelTo = function (panel, pos) {
  1662.         panel.moveTo(pos.x, pos.y);
  1663.       };
  1664.  
  1665.       var togglePositionClass = function (panel, relPos) {
  1666.         relPos = relPos ? relPos.substr(0, 2) : '';
  1667.  
  1668.         Tools.each({
  1669.           t: 'down',
  1670.           b: 'up',
  1671.           c: 'center'
  1672.         }, function (cls, pos) {
  1673.           panel.classes.toggle('arrow-' + cls, pos === relPos.substr(0, 1));
  1674.         });
  1675.  
  1676.         if (relPos === 'cr') {
  1677.           panel.classes.toggle('arrow-left', true);
  1678.           panel.classes.toggle('arrow-right', false);
  1679.         } else if (relPos === 'cl') {
  1680.           panel.classes.toggle('arrow-left', true);
  1681.           panel.classes.toggle('arrow-right', true);
  1682.         } else {
  1683.           Tools.each({
  1684.             l: 'left',
  1685.             r: 'right'
  1686.           }, function (cls, pos) {
  1687.             panel.classes.toggle('arrow-' + cls, pos === relPos.substr(1, 1));
  1688.           });
  1689.         }
  1690.       };
  1691.  
  1692.       var showToolbar = function (panel, id) {
  1693.         var toolbars = panel.items().filter('#' + id);
  1694.  
  1695.         if (toolbars.length > 0) {
  1696.           toolbars[0].show();
  1697.           panel.reflow();
  1698.           return true;
  1699.         }
  1700.  
  1701.         return false;
  1702.       };
  1703.  
  1704.       var repositionPanelAt = function (panel, id, editor, targetRect) {
  1705.         var contentAreaRect, panelRect, result, userConstainHandler;
  1706.  
  1707.         userConstainHandler = EditorSettings.getHandlerOr(editor, 'inline_toolbar_position_handler', Layout.defaultHandler);
  1708.         contentAreaRect = Measure.getContentAreaRect(editor);
  1709.         panelRect = DOMUtils.DOM.getRect(panel.getEl());
  1710.  
  1711.         if (id === 'insert') {
  1712.           result = Layout.calcInsert(targetRect, contentAreaRect, panelRect);
  1713.         } else {
  1714.           result = Layout.calc(targetRect, contentAreaRect, panelRect);
  1715.         }
  1716.  
  1717.         if (result) {
  1718.           panelRect = result.rect;
  1719.           currentRect = targetRect;
  1720.           movePanelTo(panel, Layout.userConstrain(userConstainHandler, targetRect, contentAreaRect, panelRect));
  1721.           togglePositionClass(panel, result.position);
  1722.           return true;
  1723.         } else {
  1724.           return false;
  1725.         }
  1726.       };
  1727.  
  1728.       var showPanelAt = function (panel, id, editor, targetRect) {
  1729.         showPanel(panel);
  1730.         panel.items().hide();
  1731.  
  1732.         if (!showToolbar(panel, id)) {
  1733.           hide(panel);
  1734.           return;
  1735.         }
  1736.  
  1737.         if (repositionPanelAt(panel, id, editor, targetRect) === false) {
  1738.           hide(panel);
  1739.         }
  1740.       };
  1741.  
  1742.       var hasFormVisible = function () {
  1743.         return panel.items().filter('form:visible').length > 0;
  1744.       };
  1745.  
  1746.       var showForm = function (editor, id) {
  1747.         if (panel) {
  1748.           panel.items().hide();
  1749.  
  1750.           if (!showToolbar(panel, id)) {
  1751.             hide(panel);
  1752.             return;
  1753.           }
  1754.  
  1755.           var contentAreaRect, panelRect, result, userConstainHandler;
  1756.  
  1757.           showPanel(panel);
  1758.           panel.items().hide();
  1759.           showToolbar(panel, id);
  1760.  
  1761.           userConstainHandler = EditorSettings.getHandlerOr(editor, 'inline_toolbar_position_handler', Layout.defaultHandler);
  1762.           contentAreaRect = Measure.getContentAreaRect(editor);
  1763.           panelRect = DOMUtils.DOM.getRect(panel.getEl());
  1764.  
  1765.           result = Layout.calc(currentRect, contentAreaRect, panelRect);
  1766.  
  1767.           if (result) {
  1768.             panelRect = result.rect;
  1769.             movePanelTo(panel, Layout.userConstrain(userConstainHandler, currentRect, contentAreaRect, panelRect));
  1770.             togglePositionClass(panel, result.position);
  1771.           }
  1772.         }
  1773.       };
  1774.  
  1775.       var show = function (editor, id, targetRect, toolbars) {
  1776.         if (!panel) {
  1777.           panel = create(editor, toolbars);
  1778.           panel.renderTo(document.body).reflow().moveTo(targetRect.x, targetRect.y);
  1779.           editor.nodeChanged();
  1780.         }
  1781.  
  1782.         showPanelAt(panel, id, editor, targetRect);
  1783.       };
  1784.  
  1785.       var reposition = function (editor, id, targetRect) {
  1786.         if (panel) {
  1787.           repositionPanelAt(panel, id, editor, targetRect);
  1788.         }
  1789.       };
  1790.  
  1791.       var hide = function () {
  1792.         if (panel) {
  1793.           panel.hide();
  1794.         }
  1795.       };
  1796.  
  1797.       var focus = function () {
  1798.         if (panel) {
  1799.           panel.find('toolbar:visible').eq(0).each(function (item) {
  1800.             item.focus(true);
  1801.           });
  1802.         }
  1803.       };
  1804.  
  1805.       var remove = function () {
  1806.         if (panel) {
  1807.           panel.remove();
  1808.           panel = null;
  1809.         }
  1810.       };
  1811.  
  1812.       var inForm = function () {
  1813.         return panel && panel.visible() && hasFormVisible();
  1814.       };
  1815.  
  1816.       return {
  1817.         show: show,
  1818.         showForm: showForm,
  1819.         reposition: reposition,
  1820.         inForm: inForm,
  1821.         hide: hide,
  1822.         focus: focus,
  1823.         remove: remove
  1824.       };
  1825.     };
  1826.   }
  1827. );
  1828.  
  1829. /**
  1830.  * Conversions.js
  1831.  *
  1832.  * Released under LGPL License.
  1833.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  1834.  *
  1835.  * License: http://www.tinymce.com/license
  1836.  * Contributing: http://www.tinymce.com/contributing
  1837.  */
  1838.  
  1839. define(
  1840.   'tinymce.themes.inlite.file.Conversions',
  1841.   [
  1842.     'tinymce.core.util.Promise'
  1843.   ],
  1844.   function (Promise) {
  1845.     var blobToBase64 = function (blob) {
  1846.       return new Promise(function (resolve) {
  1847.         var reader = new FileReader();
  1848.  
  1849.         reader.onloadend = function () {
  1850.           resolve(reader.result.split(',')[1]);
  1851.         };
  1852.  
  1853.         reader.readAsDataURL(blob);
  1854.       });
  1855.     };
  1856.  
  1857.     return {
  1858.       blobToBase64: blobToBase64
  1859.     };
  1860.   }
  1861. );
  1862.  
  1863.  
  1864.  
  1865. /**
  1866.  * Picker.js
  1867.  *
  1868.  * Released under LGPL License.
  1869.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  1870.  *
  1871.  * License: http://www.tinymce.com/license
  1872.  * Contributing: http://www.tinymce.com/contributing
  1873.  */
  1874.  
  1875. define(
  1876.   'tinymce.themes.inlite.file.Picker',
  1877.   [
  1878.     'tinymce.core.util.Promise'
  1879.   ],
  1880.   function (Promise) {
  1881.     var pickFile = function () {
  1882.       return new Promise(function (resolve) {
  1883.         var fileInput;
  1884.  
  1885.         fileInput = document.createElement("input");
  1886.         fileInput.type = "file";
  1887.         fileInput.style.position = 'fixed';
  1888.         fileInput.style.left = 0;
  1889.         fileInput.style.top = 0;
  1890.         fileInput.style.opacity = 0.001;
  1891.         document.body.appendChild(fileInput);
  1892.  
  1893.         fileInput.onchange = function (e) {
  1894.           resolve(Array.prototype.slice.call(e.target.files));
  1895.         };
  1896.  
  1897.         fileInput.click();
  1898.         fileInput.parentNode.removeChild(fileInput);
  1899.       });
  1900.     };
  1901.  
  1902.     return {
  1903.       pickFile: pickFile
  1904.     };
  1905.   }
  1906. );
  1907.  
  1908.  
  1909.  
  1910. /**
  1911.  * Buttons.js
  1912.  *
  1913.  * Released under LGPL License.
  1914.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  1915.  *
  1916.  * License: http://www.tinymce.com/license
  1917.  * Contributing: http://www.tinymce.com/contributing
  1918.  */
  1919.  
  1920. define(
  1921.   'tinymce.themes.inlite.ui.Buttons',
  1922.   [
  1923.     'tinymce.themes.inlite.ui.Panel',
  1924.     'tinymce.themes.inlite.file.Conversions',
  1925.     'tinymce.themes.inlite.file.Picker',
  1926.     'tinymce.themes.inlite.core.Actions'
  1927.   ],
  1928.   function (Panel, Conversions, Picker, Actions) {
  1929.     var addHeaderButtons = function (editor) {
  1930.       var formatBlock = function (name) {
  1931.         return function () {
  1932.           Actions.formatBlock(editor, name);
  1933.         };
  1934.       };
  1935.  
  1936.       for (var i = 1; i < 6; i++) {
  1937.         var name = 'h' + i;
  1938.  
  1939.         editor.addButton(name, {
  1940.           text: name.toUpperCase(),
  1941.           tooltip: 'Heading ' + i,
  1942.           stateSelector: name,
  1943.           onclick: formatBlock(name),
  1944.           onPostRender: function () {
  1945.             // TODO: Remove this hack that produces bold H1-H6 when we have proper icons
  1946.             var span = this.getEl().firstChild.firstChild;
  1947.             span.style.fontWeight = 'bold';
  1948.           }
  1949.         });
  1950.       }
  1951.     };
  1952.  
  1953.     var addToEditor = function (editor, panel) {
  1954.       editor.addButton('quicklink', {
  1955.         icon: 'link',
  1956.         tooltip: 'Insert/Edit link',
  1957.         stateSelector: 'a[href]',
  1958.         onclick: function () {
  1959.           panel.showForm(editor, 'quicklink');
  1960.         }
  1961.       });
  1962.  
  1963.       editor.addButton('quickimage', {
  1964.         icon: 'image',
  1965.         tooltip: 'Insert image',
  1966.         onclick: function () {
  1967.           Picker.pickFile().then(function (files) {
  1968.             var blob = files[0];
  1969.  
  1970.             Conversions.blobToBase64(blob).then(function (base64) {
  1971.               Actions.insertBlob(editor, base64, blob);
  1972.             });
  1973.           });
  1974.         }
  1975.       });
  1976.  
  1977.       editor.addButton('quicktable', {
  1978.         icon: 'table',
  1979.         tooltip: 'Insert table',
  1980.         onclick: function () {
  1981.           panel.hide();
  1982.           Actions.insertTable(editor, 2, 2);
  1983.         }
  1984.       });
  1985.  
  1986.       addHeaderButtons(editor);
  1987.     };
  1988.  
  1989.     return {
  1990.       addToEditor: addToEditor
  1991.     };
  1992.   }
  1993. );
  1994.  
  1995. /**
  1996.  * Theme.js
  1997.  *
  1998.  * Released under LGPL License.
  1999.  * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
  2000.  *
  2001.  * License: http://www.tinymce.com/license
  2002.  * Contributing: http://www.tinymce.com/contributing
  2003.  */
  2004.  
  2005. define(
  2006.   'tinymce.themes.inlite.Theme',
  2007.   [
  2008.     'tinymce.core.ThemeManager',
  2009.     'tinymce.core.ui.Api',
  2010.     'tinymce.core.util.Delay',
  2011.     'tinymce.themes.inlite.alien.Arr',
  2012.     'tinymce.themes.inlite.alien.EditorSettings',
  2013.     'tinymce.themes.inlite.core.ElementMatcher',
  2014.     'tinymce.themes.inlite.core.Matcher',
  2015.     'tinymce.themes.inlite.core.PredicateId',
  2016.     'tinymce.themes.inlite.core.SelectionMatcher',
  2017.     'tinymce.themes.inlite.core.SkinLoader',
  2018.     'tinymce.themes.inlite.ui.Buttons',
  2019.     'tinymce.themes.inlite.ui.Panel'
  2020.   ],
  2021.   function (
  2022.     ThemeManager, Api, Delay, Arr, EditorSettings, ElementMatcher, Matcher,
  2023.     PredicateId, SelectionMatcher, SkinLoader, Buttons, Panel
  2024.   ) {
  2025.     var getSelectionElements = function (editor) {
  2026.       var node = editor.selection.getNode();
  2027.       var elms = editor.dom.getParents(node);
  2028.       return elms;
  2029.     };
  2030.  
  2031.     var createToolbar = function (editor, selector, id, items) {
  2032.       var selectorPredicate = function (elm) {
  2033.         return editor.dom.is(elm, selector);
  2034.       };
  2035.  
  2036.       return {
  2037.         predicate: selectorPredicate,
  2038.         id: id,
  2039.         items: items
  2040.       };
  2041.     };
  2042.  
  2043.     var getToolbars = function (editor) {
  2044.       var contextToolbars = editor.contextToolbars;
  2045.  
  2046.       return Arr.flatten([
  2047.         contextToolbars ? contextToolbars : [],
  2048.         createToolbar(editor, 'img', 'image', 'alignleft aligncenter alignright')
  2049.       ]);
  2050.     };
  2051.  
  2052.     var findMatchResult = function (editor, toolbars) {
  2053.       var result, elements, contextToolbarsPredicateIds;
  2054.  
  2055.       elements = getSelectionElements(editor);
  2056.       contextToolbarsPredicateIds = PredicateId.fromContextToolbars(toolbars);
  2057.  
  2058.       result = Matcher.match(editor, [
  2059.         ElementMatcher.element(elements[0], contextToolbarsPredicateIds),
  2060.         SelectionMatcher.textSelection('text'),
  2061.         SelectionMatcher.emptyTextBlock(elements, 'insert'),
  2062.         ElementMatcher.parent(elements, contextToolbarsPredicateIds)
  2063.       ]);
  2064.  
  2065.       return result && result.rect ? result : null;
  2066.     };
  2067.  
  2068.     var togglePanel = function (editor, panel) {
  2069.       var toggle = function () {
  2070.         var toolbars = getToolbars(editor);
  2071.         var result = findMatchResult(editor, toolbars);
  2072.  
  2073.         if (result) {
  2074.           panel.show(editor, result.id, result.rect, toolbars);
  2075.         } else {
  2076.           panel.hide();
  2077.         }
  2078.       };
  2079.  
  2080.       return function () {
  2081.         if (!editor.removed) {
  2082.           toggle();
  2083.         }
  2084.       };
  2085.     };
  2086.  
  2087.     var repositionPanel = function (editor, panel) {
  2088.       return function () {
  2089.         var toolbars = getToolbars(editor);
  2090.         var result = findMatchResult(editor, toolbars);
  2091.  
  2092.         if (result) {
  2093.           panel.reposition(editor, result.id, result.rect);
  2094.         }
  2095.       };
  2096.     };
  2097.  
  2098.     var ignoreWhenFormIsVisible = function (editor, panel, f) {
  2099.       return function () {
  2100.         if (!editor.removed && !panel.inForm()) {
  2101.           f();
  2102.         }
  2103.       };
  2104.     };
  2105.  
  2106.     var bindContextualToolbarsEvents = function (editor, panel) {
  2107.       var throttledTogglePanel = Delay.throttle(togglePanel(editor, panel), 0);
  2108.       var throttledTogglePanelWhenNotInForm = Delay.throttle(ignoreWhenFormIsVisible(editor, panel, togglePanel(editor, panel)), 0);
  2109.  
  2110.       editor.on('blur hide ObjectResizeStart', panel.hide);
  2111.       editor.on('click', throttledTogglePanel);
  2112.       editor.on('nodeChange mouseup', throttledTogglePanelWhenNotInForm);
  2113.       editor.on('ResizeEditor keyup', throttledTogglePanel);
  2114.       editor.on('ResizeWindow', repositionPanel(editor, panel));
  2115.       editor.on('remove', panel.remove);
  2116.  
  2117.       editor.shortcuts.add('Alt+F10', '', panel.focus);
  2118.     };
  2119.  
  2120.     var overrideLinkShortcut = function (editor, panel) {
  2121.       editor.shortcuts.remove('meta+k');
  2122.       editor.shortcuts.add('meta+k', '', function () {
  2123.         var toolbars = getToolbars(editor);
  2124.         var result = result = Matcher.match(editor, [
  2125.           SelectionMatcher.textSelection('quicklink')
  2126.         ]);
  2127.  
  2128.         if (result) {
  2129.           panel.show(editor, result.id, result.rect, toolbars);
  2130.         }
  2131.       });
  2132.     };
  2133.  
  2134.     var renderInlineUI = function (editor, panel) {
  2135.       SkinLoader.load(editor, function () {
  2136.         bindContextualToolbarsEvents(editor, panel);
  2137.         overrideLinkShortcut(editor, panel);
  2138.       });
  2139.  
  2140.       return {};
  2141.     };
  2142.  
  2143.     var fail = function (message) {
  2144.       throw new Error(message);
  2145.     };
  2146.  
  2147.     ThemeManager.add('inlite', function (editor) {
  2148.       var panel = new Panel();
  2149.  
  2150.       Buttons.addToEditor(editor, panel);
  2151.  
  2152.       var renderUI = function () {
  2153.         return editor.inline ? renderInlineUI(editor, panel) : fail('inlite theme only supports inline mode.');
  2154.       };
  2155.  
  2156.       return {
  2157.         renderUI: renderUI
  2158.       };
  2159.     });
  2160.  
  2161.     Api.appendTo(window.tinymce ? window.tinymce : {});
  2162.  
  2163.     return function () { };
  2164.   }
  2165. );
  2166.  
  2167. dem('tinymce.themes.inlite.Theme')();
  2168. })();
  2169.