Edit file File name : require-built.js Content :/** vim: et:ts=4:sw=4:sts=4 * @license RequireJS 2.1.5 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. * Available via the MIT or new BSD license. * see: http://github.com/jrburke/requirejs for details */ //Not using strict: uneven strict support in browsers, #392, and causes //problems with requirejs.exec()/transpiler plugins that may not be strict. /*jslint regexp: true, nomen: true, sloppy: true */ /*global window, navigator, document, importScripts, setTimeout, opera */ var requirejs, require, define; (function (global) { var req, s, head, baseElement, dataMain, src, interactiveScript, currentlyAddingScript, mainScript, subPath, version = '2.1.5', commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, jsSuffixRegExp = /\.js$/, currDirRegExp = /^\.\//, op = Object.prototype, ostring = op.toString, hasOwn = op.hasOwnProperty, ap = Array.prototype, apsp = ap.splice, isBrowser = !!(typeof window !== 'undefined' && navigator && document), isWebWorker = !isBrowser && typeof importScripts !== 'undefined', //PS3 indicates loaded and complete, but need to wait for complete //specifically. Sequence is 'loading', 'loaded', execution, // then 'complete'. The UA check is unfortunate, but not sure how //to feature test w/o causing perf issues. readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ? /^complete$/ : /^(complete|loaded)$/, defContextName = '_', //Oh the tragedy, detecting opera. See the usage of isOpera for reason. isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]', contexts = {}, cfg = {}, globalDefQueue = [], useInteractive = false; function isFunction(it) { return ostring.call(it) === '[object Function]'; } function isArray(it) { return ostring.call(it) === '[object Array]'; } /** * Helper function for iterating over an array. If the func returns * a true value, it will break out of the loop. */ function each(ary, func) { if (ary) { var i; for (i = 0; i < ary.length; i += 1) { if (ary[i] && func(ary[i], i, ary)) { break; } } } } /** * Helper function for iterating over an array backwards. If the func * returns a true value, it will break out of the loop. */ function eachReverse(ary, func) { if (ary) { var i; for (i = ary.length - 1; i > -1; i -= 1) { if (ary[i] && func(ary[i], i, ary)) { break; } } } } function hasProp(obj, prop) { return hasOwn.call(obj, prop); } function getOwn(obj, prop) { return hasProp(obj, prop) && obj[prop]; } /** * Cycles over properties in an object and calls a function for each * property value. If the function returns a truthy value, then the * iteration is stopped. */ function eachProp(obj, func) { var prop; for (prop in obj) { if (hasProp(obj, prop)) { if (func(obj[prop], prop)) { break; } } } } /** * Simple function to mix in properties from source into target, * but only if target does not already have a property of the same name. */ function mixin(target, source, force, deepStringMixin) { if (source) { eachProp(source, function (value, prop) { if (force || !hasProp(target, prop)) { if (deepStringMixin && typeof value !== 'string') { if (!target[prop]) { target[prop] = {}; } mixin(target[prop], value, force, deepStringMixin); } else { target[prop] = value; } } }); } return target; } //Similar to Function.prototype.bind, but the 'this' object is specified //first, since it is easier to read/figure out what 'this' will be. function bind(obj, fn) { return function () { return fn.apply(obj, arguments); }; } function scripts() { return document.getElementsByTagName('script'); } //Allow getting a global that expressed in //dot notation, like 'a.b.c'. function getGlobal(value) { if (!value) { return value; } var g = global; each(value.split('.'), function (part) { g = g[part]; }); return g; } /** * Constructs an error with a pointer to an URL with more information. * @param {String} id the error ID that maps to an ID on a web page. * @param {String} message human readable error. * @param {Error} [err] the original error, if there is one. * * @returns {Error} */ function makeError(id, msg, err, requireModules) { var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id); e.requireType = id; e.requireModules = requireModules; if (err) { e.originalError = err; } return e; } if (typeof define !== 'undefined') { //If a define is already in play via another AMD loader, //do not overwrite. return; } if (typeof requirejs !== 'undefined') { if (isFunction(requirejs)) { //Do not overwrite and existing requirejs instance. return; } cfg = requirejs; requirejs = undefined; } //Allow for a require config object if (typeof require !== 'undefined' && !isFunction(require)) { //assume it is a config object. cfg = require; require = undefined; } function newContext(contextName) { var inCheckLoaded, Module, context, handlers, checkLoadedTimeoutId, config = { //Defaults. Do not set a default for map //config to speed up normalize(), which //will run faster if there is no default. waitSeconds: 7, baseUrl: './', paths: {}, pkgs: {}, shim: {}, config: {} }, registry = {}, //registry of just enabled modules, to speed //cycle breaking code when lots of modules //are registered, but not activated. enabledRegistry = {}, undefEvents = {}, defQueue = [], defined = {}, urlFetched = {}, requireCounter = 1, unnormalizedCounter = 1; /** * Trims the . and .. from an array of path segments. * It will keep a leading path segment if a .. will become * the first path segment, to help with module name lookups, * which act like paths, but can be remapped. But the end result, * all paths that use this function should look normalized. * NOTE: this method MODIFIES the input array. * @param {Array} ary the array of path segments. */ function trimDots(ary) { var i, part; for (i = 0; ary[i]; i += 1) { part = ary[i]; if (part === '.') { ary.splice(i, 1); i -= 1; } else if (part === '..') { if (i === 1 && (ary[2] === '..' || ary[0] === '..')) { //End of the line. Keep at least one non-dot //path segment at the front so it can be mapped //correctly to disk. Otherwise, there is likely //no path mapping for a path starting with '..'. //This can still fail, but catches the most reasonable //uses of .. break; } else if (i > 0) { ary.splice(i - 1, 2); i -= 2; } } } } /** * Given a relative module name, like ./something, normalize it to * a real name that can be mapped to a path. * @param {String} name the relative name * @param {String} baseName a real name that the name arg is relative * to. * @param {Boolean} applyMap apply the map config to the value. Should * only be done if this normalization is for a dependency ID. * @returns {String} normalized name */ function normalize(name, baseName, applyMap) { var pkgName, pkgConfig, mapValue, nameParts, i, j, nameSegment, foundMap, foundI, foundStarMap, starI, baseParts = baseName && baseName.split('/'), normalizedBaseParts = baseParts, map = config.map, starMap = map && map['*']; //Adjust any relative paths. if (name && name.charAt(0) === '.') { //If have a base name, try to normalize against it, //otherwise, assume it is a top-level require that will //be relative to baseUrl in the end. if (baseName) { if (getOwn(config.pkgs, baseName)) { //If the baseName is a package name, then just treat it as one //name to concat the name with. normalizedBaseParts = baseParts = [baseName]; } else { //Convert baseName to array, and lop off the last part, //so that . matches that 'directory' and not name of the baseName's //module. For instance, baseName of 'one/two/three', maps to //'one/two/three.js', but we want the directory, 'one/two' for //this normalization. normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); } name = normalizedBaseParts.concat(name.split('/')); trimDots(name); //Some use of packages may use a . path to reference the //'main' module name, so normalize for that. pkgConfig = getOwn(config.pkgs, (pkgName = name[0])); name = name.join('/'); if (pkgConfig && name === pkgName + '/' + pkgConfig.main) { name = pkgName; } } else if (name.indexOf('./') === 0) { // No baseName, so this is ID is resolved relative // to baseUrl, pull off the leading dot. name = name.substring(2); } } //Apply map config if available. if (applyMap && map && (baseParts || starMap)) { nameParts = name.split('/'); for (i = nameParts.length; i > 0; i -= 1) { nameSegment = nameParts.slice(0, i).join('/'); if (baseParts) { //Find the longest baseName segment match in the config. //So, do joins on the biggest to smallest lengths of baseParts. for (j = baseParts.length; j > 0; j -= 1) { mapValue = getOwn(map, baseParts.slice(0, j).join('/')); //baseName segment has config, find if it has one for //this name. if (mapValue) { mapValue = getOwn(mapValue, nameSegment); if (mapValue) { //Match, update name to the new value. foundMap = mapValue; foundI = i; break; } } } } if (foundMap) { break; } //Check for a star map match, but just hold on to it, //if there is a shorter segment match later in a matching //config, then favor over this star map. if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { foundStarMap = getOwn(starMap, nameSegment); starI = i; } } if (!foundMap && foundStarMap) { foundMap = foundStarMap; foundI = starI; } if (foundMap) { nameParts.splice(0, foundI, foundMap); name = nameParts.join('/'); } } return name; } function removeScript(name) { if (isBrowser) { each(scripts(), function (scriptNode) { if (scriptNode.getAttribute('data-requiremodule') === name && scriptNode.getAttribute('data-requirecontext') === context.contextName) { scriptNode.parentNode.removeChild(scriptNode); return true; } }); } } function hasPathFallback(id) { var pathConfig = getOwn(config.paths, id); if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { removeScript(id); //Pop off the first array value, since it failed, and //retry pathConfig.shift(); context.require.undef(id); context.require([id]); return true; } } //Turns a plugin!resource to [plugin, resource] //with the plugin being undefined if the name //did not have a plugin prefix. function splitPrefix(name) { var prefix, index = name ? name.indexOf('!') : -1; if (index > -1) { prefix = name.substring(0, index); name = name.substring(index + 1, name.length); } return [prefix, name]; } /** * Creates a module mapping that includes plugin prefix, module * name, and path. If parentModuleMap is provided it will * also normalize the name via require.normalize() * * @param {String} name the module name * @param {String} [parentModuleMap] parent module map * for the module name, used to resolve relative names. * @param {Boolean} isNormalized: is the ID already normalized. * This is true if this call is done for a define() module ID. * @param {Boolean} applyMap: apply the map config to the ID. * Should only be true if this map is for a dependency. * * @returns {Object} */ function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { var url, pluginModule, suffix, nameParts, prefix = null, parentName = parentModuleMap ? parentModuleMap.name : null, originalName = name, isDefine = true, normalizedName = ''; //If no name, then it means it is a require call, generate an //internal name. if (!name) { isDefine = false; name = '_@r' + (requireCounter += 1); } nameParts = splitPrefix(name); prefix = nameParts[0]; name = nameParts[1]; if (prefix) { prefix = normalize(prefix, parentName, applyMap); pluginModule = getOwn(defined, prefix); } //Account for relative paths if there is a base name. if (name) { if (prefix) { if (pluginModule && pluginModule.normalize) { //Plugin is loaded, use its normalize method. normalizedName = pluginModule.normalize(name, function (name) { return normalize(name, parentName, applyMap); }); } else { normalizedName = normalize(name, parentName, applyMap); } } else { //A regular module. normalizedName = normalize(name, parentName, applyMap); //Normalized name may be a plugin ID due to map config //application in normalize. The map config values must //already be normalized, so do not need to redo that part. nameParts = splitPrefix(normalizedName); prefix = nameParts[0]; normalizedName = nameParts[1]; isNormalized = true; url = context.nameToUrl(normalizedName); } } //If the id is a plugin id that cannot be determined if it needs //normalization, stamp it with a unique ID so two matching relative //ids that may conflict can be separate. suffix = prefix && !pluginModule && !isNormalized ? '_unnormalized' + (unnormalizedCounter += 1) : ''; return { prefix: prefix, name: normalizedName, parentMap: parentModuleMap, unnormalized: !!suffix, url: url, originalName: originalName, isDefine: isDefine, id: (prefix ? prefix + '!' + normalizedName : normalizedName) + suffix }; } function getModule(depMap) { var id = depMap.id, mod = getOwn(registry, id); if (!mod) { mod = registry[id] = new context.Module(depMap); } return mod; } function on(depMap, name, fn) { var id = depMap.id, mod = getOwn(registry, id); if (hasProp(defined, id) && (!mod || mod.defineEmitComplete)) { if (name === 'defined') { fn(defined[id]); } } else { getModule(depMap).on(name, fn); } } function onError(err, errback) { var ids = err.requireModules, notified = false; if (errback) { errback(err); } else { each(ids, function (id) { var mod = getOwn(registry, id); if (mod) { //Set error on module, so it skips timeout checks. mod.error = err; if (mod.events.error) { notified = true; mod.emit('error', err); } } }); if (!notified) { req.onError(err); } } } /** * Internal method to transfer globalQueue items to this context's * defQueue. */ function takeGlobalQueue() { //Push all the globalDefQueue items into the context's defQueue if (globalDefQueue.length) { //Array splice in the values since the context code has a //local var ref to defQueue, so cannot just reassign the one //on context. apsp.apply(defQueue, [defQueue.length - 1, 0].concat(globalDefQueue)); globalDefQueue = []; } } handlers = { 'require': function (mod) { if (mod.require) { return mod.require; } else { return (mod.require = context.makeRequire(mod.map)); } }, 'exports': function (mod) { mod.usingExports = true; if (mod.map.isDefine) { if (mod.exports) { return mod.exports; } else { return (mod.exports = defined[mod.map.id] = {}); } } }, 'module': function (mod) { if (mod.module) { return mod.module; } else { return (mod.module = { id: mod.map.id, uri: mod.map.url, config: function () { return (config.config && getOwn(config.config, mod.map.id)) || {}; }, exports: defined[mod.map.id] }); } } }; function cleanRegistry(id) { //Clean up machinery used for waiting modules. delete registry[id]; delete enabledRegistry[id]; } function breakCycle(mod, traced, processed) { var id = mod.map.id; if (mod.error) { mod.emit('error', mod.error); } else { traced[id] = true; each(mod.depMaps, function (depMap, i) { var depId = depMap.id, dep = getOwn(registry, depId); //Only force things that have not completed //being defined, so still in the registry, //and only if it has not been matched up //in the module already. if (dep && !mod.depMatched[i] && !processed[depId]) { if (getOwn(traced, depId)) { mod.defineDep(i, defined[depId]); mod.check(); //pass false? } else { breakCycle(dep, traced, processed); } } }); processed[id] = true; } } function checkLoaded() { var map, modId, err, usingPathFallback, waitInterval = config.waitSeconds * 1000, //It is possible to disable the wait interval by using waitSeconds of 0. expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), noLoads = [], reqCalls = [], stillLoading = false, needCycleCheck = true; //Do not bother if this call was a result of a cycle break. if (inCheckLoaded) { return; } inCheckLoaded = true; //Figure out the state of all the modules. eachProp(enabledRegistry, function (mod) { map = mod.map; modId = map.id; //Skip things that are not enabled or in error state. if (!mod.enabled) { return; } if (!map.isDefine) { reqCalls.push(mod); } if (!mod.error) { //If the module should be executed, and it has not //been inited and time is up, remember it. if (!mod.inited && expired) { if (hasPathFallback(modId)) { usingPathFallback = true; stillLoading = true; } else { noLoads.push(modId); removeScript(modId); } } else if (!mod.inited && mod.fetched && map.isDefine) { stillLoading = true; if (!map.prefix) { //No reason to keep looking for unfinished //loading. If the only stillLoading is a //plugin resource though, keep going, //because it may be that a plugin resource //is waiting on a non-plugin cycle. return (needCycleCheck = false); } } } }); if (expired && noLoads.length) { //If wait time expired, throw error of unloaded modules. err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads); err.contextName = context.contextName; return onError(err); } //Not expired, check for a cycle. if (needCycleCheck) { each(reqCalls, function (mod) { breakCycle(mod, {}, {}); }); } //If still waiting on loads, and the waiting load is something //other than a plugin resource, or there are still outstanding //scripts, then just try back later. if ((!expired || usingPathFallback) && stillLoading) { //Something is still waiting to load. Wait for it, but only //if a timeout is not already in effect. if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) { checkLoadedTimeoutId = setTimeout(function () { checkLoadedTimeoutId = 0; checkLoaded(); }, 50); } } inCheckLoaded = false; } Module = function (map) { this.events = getOwn(undefEvents, map.id) || {}; this.map = map; this.shim = getOwn(config.shim, map.id); this.depExports = []; this.depMaps = []; this.depMatched = []; this.pluginMaps = {}; this.depCount = 0; /* this.exports this.factory this.depMaps = [], this.enabled, this.fetched */ }; Module.prototype = { init: function (depMaps, factory, errback, options) { options = options || {}; //Do not do more inits if already done. Can happen if there //are multiple define calls for the same module. That is not //a normal, common case, but it is also not unexpected. if (this.inited) { return; } this.factory = factory; if (errback) { //Register for errors on this module. this.on('error', errback); } else if (this.events.error) { //If no errback already, but there are error listeners //on this module, set up an errback to pass to the deps. errback = bind(this, function (err) { this.emit('error', err); }); } //Do a copy of the dependency array, so that //source inputs are not modified. For example //"shim" deps are passed in here directly, and //doing a direct modification of the depMaps array //would affect that config. this.depMaps = depMaps && depMaps.slice(0); this.errback = errback; //Indicate this module has be initialized this.inited = true; this.ignore = options.ignore; //Could have option to init this module in enabled mode, //or could have been previously marked as enabled. However, //the dependencies are not known until init is called. So //if enabled previously, now trigger dependencies as enabled. if (options.enabled || this.enabled) { //Enable this module and dependencies. //Will call this.check() this.enable(); } else { this.check(); } }, defineDep: function (i, depExports) { //Because of cycles, defined callback for a given //export can be called more than once. if (!this.depMatched[i]) { this.depMatched[i] = true; this.depCount -= 1; this.depExports[i] = depExports; } }, fetch: function () { if (this.fetched) { return; } this.fetched = true; context.startTime = (new Date()).getTime(); var map = this.map; //If the manager is for a plugin managed resource, //ask the plugin to load it now. if (this.shim) { context.makeRequire(this.map, { enableBuildCallback: true })(this.shim.deps || [], bind(this, function () { return map.prefix ? this.callPlugin() : this.load(); })); } else { //Regular dependency. return map.prefix ? this.callPlugin() : this.load(); } }, load: function () { var url = this.map.url; //Regular dependency. if (!urlFetched[url]) { urlFetched[url] = true; context.load(this.map.id, url); } }, /** * Checks if the module is ready to define itself, and if so, * define it. */ check: function () { if (!this.enabled || this.enabling) { return; } var err, cjsModule, id = this.map.id, depExports = this.depExports, exports = this.exports, factory = this.factory; if (!this.inited) { this.fetch(); } else if (this.error) { this.emit('error', this.error); } else if (!this.defining) { //The factory could trigger another require call //that would result in checking this module to //define itself again. If already in the process //of doing that, skip this work. this.defining = true; if (this.depCount < 1 && !this.defined) { if (isFunction(factory)) { //If there is an error listener, favor passing //to that instead of throwing an error. if (this.events.error) { try { exports = context.execCb(id, factory, depExports, exports); } catch (e) { err = e; } } else { exports = context.execCb(id, factory, depExports, exports); } if (this.map.isDefine) { //If setting exports via 'module' is in play, //favor that over return value and exports. After that, //favor a non-undefined return value over exports use. cjsModule = this.module; if (cjsModule && cjsModule.exports !== undefined && //Make sure it is not already the exports value cjsModule.exports !== this.exports) { exports = cjsModule.exports; } else if (exports === undefined && this.usingExports) { //exports already set the defined value. exports = this.exports; } } if (err) { err.requireMap = this.map; err.requireModules = [this.map.id]; err.requireType = 'define'; return onError((this.error = err)); } } else { //Just a literal value exports = factory; } this.exports = exports; if (this.map.isDefine && !this.ignore) { defined[id] = exports; if (req.onResourceLoad) { req.onResourceLoad(context, this.map, this.depMaps); } } //Clean up cleanRegistry(id); this.defined = true; } //Finished the define stage. Allow calling check again //to allow define notifications below in the case of a //cycle. this.defining = false; if (this.defined && !this.defineEmitted) { this.defineEmitted = true; this.emit('defined', this.exports); this.defineEmitComplete = true; } } }, callPlugin: function () { var map = this.map, id = map.id, //Map already normalized the prefix. pluginMap = makeModuleMap(map.prefix); //Mark this as a dependency for this plugin, so it //can be traced for cycles. this.depMaps.push(pluginMap); on(pluginMap, 'defined', bind(this, function (plugin) { var load, normalizedMap, normalizedMod, name = this.map.name, parentName = this.map.parentMap ? this.map.parentMap.name : null, localRequire = context.makeRequire(map.parentMap, { enableBuildCallback: true }); //If current map is not normalized, wait for that //normalized name to load instead of continuing. if (this.map.unnormalized) { //Normalize the ID if the plugin allows it. if (plugin.normalize) { name = plugin.normalize(name, function (name) { return normalize(name, parentName, true); }) || ''; } //prefix and name should already be normalized, no need //for applying map config again either. normalizedMap = makeModuleMap(map.prefix + '!' + name, this.map.parentMap); on(normalizedMap, 'defined', bind(this, function (value) { this.init([], function () { return value; }, null, { enabled: true, ignore: true }); })); normalizedMod = getOwn(registry, normalizedMap.id); if (normalizedMod) { //Mark this as a dependency for this plugin, so it //can be traced for cycles. this.depMaps.push(normalizedMap); if (this.events.error) { normalizedMod.on('error', bind(this, function (err) { this.emit('error', err); })); } normalizedMod.enable(); } return; } load = bind(this, function (value) { this.init([], function () { return value; }, null, { enabled: true }); }); load.error = bind(this, function (err) { this.inited = true; this.error = err; err.requireModules = [id]; //Remove temp unnormalized modules for this module, //since they will never be resolved otherwise now. eachProp(registry, function (mod) { if (mod.map.id.indexOf(id + '_unnormalized') === 0) { cleanRegistry(mod.map.id); } }); onError(err); }); //Allow plugins to load other code without having to know the //context or how to 'complete' the load. load.fromText = bind(this, function (text, textAlt) { /*jslint evil: true */ var moduleName = map.name, moduleMap = makeModuleMap(moduleName), hasInteractive = useInteractive; //As of 2.1.0, support just passing the text, to reinforce //fromText only being called once per resource. Still //support old style of passing moduleName but discard //that moduleName in favor of the internal ref. if (textAlt) { text = textAlt; } //Turn off interactive script matching for IE for any define //calls in the text, then turn it back on at the end. if (hasInteractive) { useInteractive = false; } //Prime the system by creating a module instance for //it. getModule(moduleMap); //Transfer any config to this other module. if (hasProp(config.config, id)) { config.config[moduleName] = config.config[id]; } try { req.exec(text); } catch (e) { return onError(makeError('fromtexteval', 'fromText eval for ' + id + ' failed: ' + e, e, [id])); } if (hasInteractive) { useInteractive = true; } //Mark this as a dependency for the plugin //resource this.depMaps.push(moduleMap); //Support anonymous modules. context.completeLoad(moduleName); //Bind the value of that module to the value for this //resource ID. localRequire([moduleName], load); }); //Use parentName here since the plugin's name is not reliable, //could be some weird string with no path that actually wants to //reference the parentName's path. plugin.load(map.name, localRequire, load, config); })); context.enable(pluginMap, this); this.pluginMaps[pluginMap.id] = pluginMap; }, enable: function () { enabledRegistry[this.map.id] = this; this.enabled = true; //Set flag mentioning that the module is enabling, //so that immediate calls to the defined callbacks //for dependencies do not trigger inadvertent load //with the depCount still being zero. this.enabling = true; //Enable each dependency each(this.depMaps, bind(this, function (depMap, i) { var id, mod, handler; if (typeof depMap === 'string') { //Dependency needs to be converted to a depMap //and wired up to this module. depMap = makeModuleMap(depMap, (this.map.isDefine ? this.map : this.map.parentMap), false, !this.skipMap); this.depMaps[i] = depMap; handler = getOwn(handlers, depMap.id); if (handler) { this.depExports[i] = handler(this); return; } this.depCount += 1; on(depMap, 'defined', bind(this, function (depExports) { this.defineDep(i, depExports); this.check(); })); if (this.errback) { on(depMap, 'error', this.errback); } } id = depMap.id; mod = registry[id]; //Skip special modules like 'require', 'exports', 'module' //Also, don't call enable if it is already enabled, //important in circular dependency cases. if (!hasProp(handlers, id) && mod && !mod.enabled) { context.enable(depMap, this); } })); //Enable each plugin that is used in //a dependency eachProp(this.pluginMaps, bind(this, function (pluginMap) { var mod = getOwn(registry, pluginMap.id); if (mod && !mod.enabled) { context.enable(pluginMap, this); } })); this.enabling = false; this.check(); }, on: function (name, cb) { var cbs = this.events[name]; if (!cbs) { cbs = this.events[name] = []; } cbs.push(cb); }, emit: function (name, evt) { each(this.events[name], function (cb) { cb(evt); }); if (name === 'error') { //Now that the error handler was triggered, remove //the listeners, since this broken Module instance //can stay around for a while in the registry. delete this.events[name]; } } }; function callGetModule(args) { //Skip modules already defined. if (!hasProp(defined, args[0])) { getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]); } } function removeListener(node, func, name, ieName) { //Favor detachEvent because of IE9 //issue, see attachEvent/addEventListener comment elsewhere //in this file. if (node.detachEvent && !isOpera) { //Probably IE. If not it will throw an error, which will be //useful to know. if (ieName) { node.detachEvent(ieName, func); } } else { node.removeEventListener(name, func, false); } } /** * Given an event from a script node, get the requirejs info from it, * and then removes the event listeners on the node. * @param {Event} evt * @returns {Object} */ function getScriptData(evt) { //Using currentTarget instead of target for Firefox 2.0's sake. Not //all old browsers will be supported, but this one was easy enough //to support and still makes sense. var node = evt.currentTarget || evt.srcElement; //Remove the listeners once here. removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange'); removeListener(node, context.onScriptError, 'error'); return { node: node, id: node && node.getAttribute('data-requiremodule') }; } function intakeDefines() { var args; //Any defined modules in the global queue, intake them now. takeGlobalQueue(); //Make sure any remaining defQueue items get properly processed. while (defQueue.length) { args = defQueue.shift(); if (args[0] === null) { return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1])); } else { //args are id, deps, factory. Should be normalized by the //define() function. callGetModule(args); } } } context = { config: config, contextName: contextName, registry: registry, defined: defined, urlFetched: urlFetched, defQueue: defQueue, Module: Module, makeModuleMap: makeModuleMap, nextTick: req.nextTick, onError: onError, /** * Set a configuration for the context. * @param {Object} cfg config object to integrate. */ configure: function (cfg) { //Make sure the baseUrl ends in a slash. if (cfg.baseUrl) { if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') { cfg.baseUrl += '/'; } } //Save off the paths and packages since they require special processing, //they are additive. var pkgs = config.pkgs, shim = config.shim, objs = { paths: true, config: true, map: true }; eachProp(cfg, function (value, prop) { if (objs[prop]) { if (prop === 'map') { if (!config.map) { config.map = {}; } mixin(config[prop], value, true, true); } else { mixin(config[prop], value, true); } } else { config[prop] = value; } }); //Merge shim if (cfg.shim) { eachProp(cfg.shim, function (value, id) { //Normalize the structure if (isArray(value)) { value = { deps: value }; } if ((value.exports || value.init) && !value.exportsFn) { value.exportsFn = context.makeShimExports(value); } shim[id] = value; }); config.shim = shim; } //Adjust packages if necessary. if (cfg.packages) { each(cfg.packages, function (pkgObj) { var location; pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj; location = pkgObj.location; //Create a brand new object on pkgs, since currentPackages can //be passed in again, and config.pkgs is the internal transformed //state for all package configs. pkgs[pkgObj.name] = { name: pkgObj.name, location: location || pkgObj.name, //Remove leading dot in main, so main paths are normalized, //and remove any trailing .js, since different package //envs have different conventions: some use a module name, //some use a file name. main: (pkgObj.main || 'main') .replace(currDirRegExp, '') .replace(jsSuffixRegExp, '') }; }); //Done with modifications, assing packages back to context config config.pkgs = pkgs; } //If there are any "waiting to execute" modules in the registry, //update the maps for them, since their info, like URLs to load, //may have changed. eachProp(registry, function (mod, id) { //If module already has init called, since it is too //late to modify them, and ignore unnormalized ones //since they are transient. if (!mod.inited && !mod.map.unnormalized) { mod.map = makeModuleMap(id); } }); //If a deps array or a config callback is specified, then call //require with those args. This is useful when require is defined as a //config object before require.js is loaded. if (cfg.deps || cfg.callback) { context.require(cfg.deps || [], cfg.callback); } }, makeShimExports: function (value) { function fn() { var ret; if (value.init) { ret = value.init.apply(global, arguments); } return ret || (value.exports && getGlobal(value.exports)); } return fn; }, makeRequire: function (relMap, options) { options = options || {}; function localRequire(deps, callback, errback) { var id, map, requireMod; if (options.enableBuildCallback && callback && isFunction(callback)) { callback.__requireJsBuild = true; } if (typeof deps === 'string') { if (isFunction(callback)) { //Invalid call return onError(makeError('requireargs', 'Invalid require call'), errback); } //If require|exports|module are requested, get the //value for them from the special handlers. Caveat: //this only works while module is being defined. if (relMap && hasProp(handlers, deps)) { return handlers[deps](registry[relMap.id]); } //Synchronous access to one module. If require.get is //available (as in the Node adapter), prefer that. if (req.get) { return req.get(context, deps, relMap, localRequire); } //Normalize module name, if it contains . or .. map = makeModuleMap(deps, relMap, false, true); id = map.id; if (!hasProp(defined, id)) { return onError(makeError('notloaded', 'Module name "' + id + '" has not been loaded yet for context: ' + contextName + (relMap ? '' : '. Use require([])'))); } return defined[id]; } //Grab defines waiting in the global queue. intakeDefines(); //Mark all the dependencies as needing to be loaded. context.nextTick(function () { //Some defines could have been added since the //require call, collect them. intakeDefines(); requireMod = getModule(makeModuleMap(null, relMap)); //Store if map config should be applied to this require //call for dependencies. requireMod.skipMap = options.skipMap; requireMod.init(deps, callback, errback, { enabled: true }); checkLoaded(); }); return localRequire; } mixin(localRequire, { isBrowser: isBrowser, /** * Converts a module name + .extension into an URL path. * *Requires* the use of a module name. It does not support using * plain URLs like nameToUrl. */ toUrl: function (moduleNamePlusExt) { var ext, index = moduleNamePlusExt.lastIndexOf('.'), segment = moduleNamePlusExt.split('/')[0], isRelative = segment === '.' || segment === '..'; //Have a file extension alias, and it is not the //dots from a relative path. if (index !== -1 && (!isRelative || index > 1)) { ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); moduleNamePlusExt = moduleNamePlusExt.substring(0, index); } return context.nameToUrl(normalize(moduleNamePlusExt, relMap && relMap.id, true), ext, true); }, defined: function (id) { return hasProp(defined, makeModuleMap(id, relMap, false, true).id); }, specified: function (id) { id = makeModuleMap(id, relMap, false, true).id; return hasProp(defined, id) || hasProp(registry, id); } }); //Only allow undef on top level require calls if (!relMap) { localRequire.undef = function (id) { //Bind any waiting define() calls to this context, //fix for #408 takeGlobalQueue(); var map = makeModuleMap(id, relMap, true), mod = getOwn(registry, id); delete defined[id]; delete urlFetched[map.url]; delete undefEvents[id]; if (mod) { //Hold on to listeners in case the //module will be attempted to be reloaded //using a different config. if (mod.events.defined) { undefEvents[id] = mod.events; } cleanRegistry(id); } }; } return localRequire; }, /** * Called to enable a module if it is still in the registry * awaiting enablement. A second arg, parent, the parent module, * is passed in for context, when this method is overriden by * the optimizer. Not shown here to keep code compact. */ enable: function (depMap) { var mod = getOwn(registry, depMap.id); if (mod) { getModule(depMap).enable(); } }, /** * Internal method used by environment adapters to complete a load event. * A load event could be a script load or just a load pass from a synchronous * load call. * @param {String} moduleName the name of the module to potentially complete. */ completeLoad: function (moduleName) { var found, args, mod, shim = getOwn(config.shim, moduleName) || {}, shExports = shim.exports; takeGlobalQueue(); while (defQueue.length) { args = defQueue.shift(); if (args[0] === null) { args[0] = moduleName; //If already found an anonymous module and bound it //to this name, then this is some other anon module //waiting for its completeLoad to fire. if (found) { break; } found = true; } else if (args[0] === moduleName) { //Found matching define call for this script! found = true; } callGetModule(args); } //Do this after the cycle of callGetModule in case the result //of those calls/init calls changes the registry. mod = getOwn(registry, moduleName); if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { if (hasPathFallback(moduleName)) { return; } else { return onError(makeError('nodefine', 'No define call for ' + moduleName, null, [moduleName])); } } else { //A script that does not call define(), so just simulate //the call for it. callGetModule([moduleName, (shim.deps || []), shim.exportsFn]); } } checkLoaded(); }, /** * Converts a module name to a file path. Supports cases where * moduleName may actually be just an URL. * Note that it **does not** call normalize on the moduleName, * it is assumed to have already been normalized. This is an * internal API, not a public one. Use toUrl for the public API. */ nameToUrl: function (moduleName, ext, skipExt) { var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url, parentPath; //If a colon is in the URL, it indicates a protocol is used and it is just //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) //or ends with .js, then assume the user meant to use an url and not a module id. //The slash is important for protocol-less URLs as well as full paths. if (req.jsExtRegExp.test(moduleName)) { //Just a plain path, not module name lookup, so just return it. //Add extension if it is included. This is a bit wonky, only non-.js things pass //an extension, this method probably needs to be reworked. url = moduleName + (ext || ''); } else { //A module that needs to be converted to a path. paths = config.paths; pkgs = config.pkgs; syms = moduleName.split('/'); //For each module name segment, see if there is a path //registered for it. Start with most specific name //and work up from it. for (i = syms.length; i > 0; i -= 1) { parentModule = syms.slice(0, i).join('/'); pkg = getOwn(pkgs, parentModule); parentPath = getOwn(paths, parentModule); if (parentPath) { //If an array, it means there are a few choices, //Choose the one that is desired if (isArray(parentPath)) { parentPath = parentPath[0]; } syms.splice(0, i, parentPath); break; } else if (pkg) { //If module name is just the package name, then looking //for the main module. if (moduleName === pkg.name) { pkgPath = pkg.location + '/' + pkg.main; } else { pkgPath = pkg.location; } syms.splice(0, i, pkgPath); break; } } //Join the path parts together, then figure out if baseUrl is needed. url = syms.join('/'); url += (ext || (/\?/.test(url) || skipExt ? '' : '.js')); url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; } return config.urlArgs ? url + ((url.indexOf('?') === -1 ? '?' : '&') + config.urlArgs) : url; }, //Delegates to req.load. Broken out as a separate function to //allow overriding in the optimizer. load: function (id, url) { req.load(context, id, url); }, /** * Executes a module callack function. Broken out as a separate function * solely to allow the build system to sequence the files in the built * layer in the right sequence. * * @private */ execCb: function (name, callback, args, exports) { return callback.apply(exports, args); }, /** * callback for script loads, used to check status of loading. * * @param {Event} evt the event from the browser for the script * that was loaded. */ onScriptLoad: function (evt) { //Using currentTarget instead of target for Firefox 2.0's sake. Not //all old browsers will be supported, but this one was easy enough //to support and still makes sense. if (evt.type === 'load' || (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) { //Reset interactive script so a script node is not held onto for //to long. interactiveScript = null; //Pull out the name of the module and the context. var data = getScriptData(evt); context.completeLoad(data.id); } }, /** * Callback for script errors. */ onScriptError: function (evt) { var data = getScriptData(evt); if (!hasPathFallback(data.id)) { return onError(makeError('scripterror', 'Script error', evt, [data.id])); } } }; context.require = context.makeRequire(); return context; } /** * Main entry point. * * If the only argument to require is a string, then the module that * is represented by that string is fetched for the appropriate context. * * If the first argument is an array, then it will be treated as an array * of dependency string names to fetch. An optional function callback can * be specified to execute when all of those dependencies are available. * * Make a local req variable to help Caja compliance (it assumes things * on a require that are not standardized), and to give a short * name for minification/local scope use. */ req = requirejs = function (deps, callback, errback, optional) { //Find the right context, use default var context, config, contextName = defContextName; // Determine if have config object in the call. if (!isArray(deps) && typeof deps !== 'string') { // deps is a config object config = deps; if (isArray(callback)) { // Adjust args if there are dependencies deps = callback; callback = errback; errback = optional; } else { deps = []; } } if (config && config.context) { contextName = config.context; } context = getOwn(contexts, contextName); if (!context) { context = contexts[contextName] = req.s.newContext(contextName); } if (config) { context.configure(config); } return context.require(deps, callback, errback); }; /** * Support require.config() to make it easier to cooperate with other * AMD loaders on globally agreed names. */ req.config = function (config) { return req(config); }; /** * Execute something after the current tick * of the event loop. Override for other envs * that have a better solution than setTimeout. * @param {Function} fn function to execute later. */ req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) { setTimeout(fn, 4); } : function (fn) { fn(); }; /** * Export require as a global, but only if it does not already exist. */ if (!require) { require = req; } req.version = version; //Used to filter out dependencies that are already paths. req.jsExtRegExp = /^\/|:|\?|\.js$/; req.isBrowser = isBrowser; s = req.s = { contexts: contexts, newContext: newContext }; //Create default context. req({}); //Exports some context-sensitive methods on global require. each([ 'toUrl', 'undef', 'defined', 'specified' ], function (prop) { //Reference from contexts instead of early binding to default context, //so that during builds, the latest instance of the default context //with its config gets used. req[prop] = function () { var ctx = contexts[defContextName]; return ctx.require[prop].apply(ctx, arguments); }; }); if (isBrowser) { head = s.head = document.getElementsByTagName('head')[0]; //If BASE tag is in play, using appendChild is a problem for IE6. //When that browser dies, this can be removed. Details in this jQuery bug: //http://dev.jquery.com/ticket/2709 baseElement = document.getElementsByTagName('base')[0]; if (baseElement) { head = s.head = baseElement.parentNode; } } /** * Any errors that require explicitly generates will be passed to this * function. Intercept/override it if you want custom error handling. * @param {Error} err the error object. */ req.onError = function (err) { throw err; }; /** * Does the request to load a module for the browser case. * Make this a separate function to allow other environments * to override it. * * @param {Object} context the require context to find state. * @param {String} moduleName the name of the module. * @param {Object} url the URL to the module. */ req.load = function (context, moduleName, url) { var config = (context && context.config) || {}, node; if (isBrowser) { //In the browser so use a script tag node = config.xhtml ? document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') : document.createElement('script'); node.type = config.scriptType || 'text/javascript'; node.charset = 'utf-8'; node.async = true; node.setAttribute('data-requirecontext', context.contextName); node.setAttribute('data-requiremodule', moduleName); //Set up load listener. Test attachEvent first because IE9 has //a subtle issue in its addEventListener and script onload firings //that do not match the behavior of all other browsers with //addEventListener support, which fire the onload event for a //script right after the script execution. See: //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution //UNFORTUNATELY Opera implements attachEvent but does not follow the script //script execution mode. if (node.attachEvent && //Check if node.attachEvent is artificially added by custom script or //natively supported by browser //read https://github.com/jrburke/requirejs/issues/187 //if we can NOT find [native code] then it must NOT natively supported. //in IE8, node.attachEvent does not have toString() //Note the test for "[native code" with no closing brace, see: //https://github.com/jrburke/requirejs/issues/273 !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && !isOpera) { //Probably IE. IE (at least 6-8) do not fire //script onload right after executing the script, so //we cannot tie the anonymous define call to a name. //However, IE reports the script as being in 'interactive' //readyState at the time of the define call. useInteractive = true; node.attachEvent('onreadystatechange', context.onScriptLoad); //It would be great to add an error handler here to catch //404s in IE9+. However, onreadystatechange will fire before //the error handler, so that does not help. If addEventListener //is used, then IE will fire error before load, but we cannot //use that pathway given the connect.microsoft.com issue //mentioned above about not doing the 'script execute, //then fire the script load event listener before execute //next script' that other browsers do. //Best hope: IE10 fixes the issues, //and then destroys all installs of IE 6-9. //node.attachEvent('onerror', context.onScriptError); } else { node.addEventListener('load', context.onScriptLoad, false); node.addEventListener('error', context.onScriptError, false); } node.src = url; //For some cache cases in IE 6-8, the script executes before the end //of the appendChild execution, so to tie an anonymous define //call to the module name (which is stored on the node), hold on //to a reference to this node, but clear after the DOM insertion. currentlyAddingScript = node; if (baseElement) { head.insertBefore(node, baseElement); } else { head.appendChild(node); } currentlyAddingScript = null; return node; } else if (isWebWorker) { try { //In a web worker, use importScripts. This is not a very //efficient use of importScripts, importScripts will block until //its script is downloaded and evaluated. However, if web workers //are in play, the expectation that a build has been done so that //only one script needs to be loaded anyway. This may need to be //reevaluated if other use cases become common. importScripts(url); //Account for anonymous modules context.completeLoad(moduleName); } catch (e) { context.onError(makeError('importscripts', 'importScripts failed for ' + moduleName + ' at ' + url, e, [moduleName])); } } }; function getInteractiveScript() { if (interactiveScript && interactiveScript.readyState === 'interactive') { return interactiveScript; } eachReverse(scripts(), function (script) { if (script.readyState === 'interactive') { return (interactiveScript = script); } }); return interactiveScript; } //Look for a data-main script attribute, which could also adjust the baseUrl. if (isBrowser) { //Figure out baseUrl. Get it from the script tag with require.js in it. eachReverse(scripts(), function (script) { //Set the 'head' where we can append children by //using the script's parent. if (!head) { head = script.parentNode; } //Look for a data-main attribute to set main script for the page //to load. If it is there, the path to data main becomes the //baseUrl, if it is not already set. dataMain = script.getAttribute('data-main'); if (dataMain) { //Set final baseUrl if there is not already an explicit one. if (!cfg.baseUrl) { //Pull off the directory of data-main for use as the //baseUrl. src = dataMain.split('/'); mainScript = src.pop(); subPath = src.length ? src.join('/') + '/' : './'; cfg.baseUrl = subPath; dataMain = mainScript; } //Strip off any trailing .js since dataMain is now //like a module name. dataMain = dataMain.replace(jsSuffixRegExp, ''); //Put the data-main script in the files to load. cfg.deps = cfg.deps ? cfg.deps.concat(dataMain) : [dataMain]; return true; } }); } /** * The function that handles definitions of modules. Differs from * require() in that a string for the module should be the first argument, * and the function to execute after dependencies are loaded should * return a value to define the module corresponding to the first argument's * name. */ define = function (name, deps, callback) { var node, context; //Allow for anonymous modules if (typeof name !== 'string') { //Adjust args appropriately callback = deps; deps = name; name = null; } //This module may not have dependencies if (!isArray(deps)) { callback = deps; deps = []; } //If no name, and callback is a function, then figure out if it a //CommonJS thing with dependencies. if (!deps.length && isFunction(callback)) { //Remove comments from the callback string, //look for require calls, and pull them into the dependencies, //but only if there are function args. if (callback.length) { callback .toString() .replace(commentRegExp, '') .replace(cjsRequireRegExp, function (match, dep) { deps.push(dep); }); //May be a CommonJS thing even without require calls, but still //could use exports, and module. Avoid doing exports and module //work though if it just needs require. //REQUIRES the function to expect the CommonJS variables in the //order listed below. deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps); } } //If in IE 6-8 and hit an anonymous define() call, do the interactive //work. if (useInteractive) { node = currentlyAddingScript || getInteractiveScript(); if (node) { if (!name) { name = node.getAttribute('data-requiremodule'); } context = contexts[node.getAttribute('data-requirecontext')]; } } //Always save off evaluating the def call until the script onload handler. //This allows multiple modules to be in a file without prematurely //tracing dependencies, and allows for anonymous module support, //where the module name is not known until the script onload event //occurs. If no context, use the global queue, and get it processed //in the onscript load callback. (context ? context.defQueue : globalDefQueue).push([name, deps, callback]); }; define.amd = { jQuery: true }; /** * Executes the text. Normally just uses eval, but can be modified * to use a better, environment-specific call. Only used for transpiling * loader plugins, not for plain JS modules. * @param {String} text the text to execute/evaluate. */ req.exec = function (text) { /*jslint evil: true */ return eval(text); }; //Set up with config info. req(cfg); }(this)); var components = { "packages": [ { "name": "jquery", "main": "jquery-built.js" }, { "name": "fullcalendar", "main": "fullcalendar-built.js" }, { "name": "moment", "main": "moment-built.js" }, { "name": "tinymce", "main": "tinymce-built.js" } ], "baseUrl": "components" }; if (typeof require !== "undefined" && require.config) { require.config(components); } else { var require = components; } if (typeof exports !== "undefined" && typeof module !== "undefined") { module.exports = components; } define('jquery', function (require, exports, module) { /*! * jQuery JavaScript Library v3.3.1 * https://jquery.com/ * * Includes Sizzle.js * https://sizzlejs.com/ * * Copyright JS Foundation and other contributors * Released under the MIT license * https://jquery.org/license * * Date: 2018-01-20T17:24Z */ ( function( global, factory ) { "use strict"; if ( typeof module === "object" && typeof module.exports === "object" ) { // For CommonJS and CommonJS-like environments where a proper `window` // is present, execute the factory and get jQuery. // For environments that do not have a `window` with a `document` // (such as Node.js), expose a factory as module.exports. // This accentuates the need for the creation of a real `window`. // e.g. var jQuery = require("jquery")(window); // See ticket #14549 for more info. module.exports = global.document ? factory( global, true ) : function( w ) { if ( !w.document ) { throw new Error( "jQuery requires a window with a document" ); } return factory( w ); }; } else { factory( global ); } // Pass this if window is not defined yet } )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common // enough that all such attempts are guarded in a try block. "use strict"; var arr = []; var document = window.document; var getProto = Object.getPrototypeOf; var slice = arr.slice; var concat = arr.concat; var push = arr.push; var indexOf = arr.indexOf; var class2type = {}; var toString = class2type.toString; var hasOwn = class2type.hasOwnProperty; var fnToString = hasOwn.toString; var ObjectFunctionString = fnToString.call( Object ); var support = {}; var isFunction = function isFunction( obj ) { // Support: Chrome <=57, Firefox <=52 // In some browsers, typeof returns "function" for HTML <object> elements // (i.e., `typeof document.createElement( "object" ) === "function"`). // We don't want to classify *any* DOM node as a function. return typeof obj === "function" && typeof obj.nodeType !== "number"; }; var isWindow = function isWindow( obj ) { return obj != null && obj === obj.window; }; var preservedScriptAttributes = { type: true, src: true, noModule: true }; function DOMEval( code, doc, node ) { doc = doc || document; var i, script = doc.createElement( "script" ); script.text = code; if ( node ) { for ( i in preservedScriptAttributes ) { if ( node[ i ] ) { script[ i ] = node[ i ]; } } } doc.head.appendChild( script ).parentNode.removeChild( script ); } function toType( obj ) { if ( obj == null ) { return obj + ""; } // Support: Android <=2.3 only (functionish RegExp) return typeof obj === "object" || typeof obj === "function" ? class2type[ toString.call( obj ) ] || "object" : typeof obj; } /* global Symbol */ // Defining this global in .eslintrc.json would create a danger of using the global // unguarded in another place, it seems safer to define global only for this module var version = "3.3.1", // Define a local copy of jQuery jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery.fn.init( selector, context ); }, // Support: Android <=4.0 only // Make sure we trim BOM and NBSP rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; jQuery.fn = jQuery.prototype = { // The current version of jQuery being used jquery: version, constructor: jQuery, // The default length of a jQuery object is 0 length: 0, toArray: function() { return slice.call( this ); }, // Get the Nth element in the matched element set OR // Get the whole matched element set as a clean array get: function( num ) { // Return all the elements in a clean array if ( num == null ) { return slice.call( this ); } // Return just the one element from the set return num < 0 ? this[ num + this.length ] : this[ num ]; }, // Take an array of elements and push it onto the stack // (returning the new matched element set) pushStack: function( elems ) { // Build a new jQuery matched element set var ret = jQuery.merge( this.constructor(), elems ); // Add the old object onto the stack (as a reference) ret.prevObject = this; // Return the newly-formed element set return ret; }, // Execute a callback for every element in the matched set. each: function( callback ) { return jQuery.each( this, callback ); }, map: function( callback ) { return this.pushStack( jQuery.map( this, function( elem, i ) { return callback.call( elem, i, elem ); } ) ); }, slice: function() { return this.pushStack( slice.apply( this, arguments ) ); }, first: function() { return this.eq( 0 ); }, last: function() { return this.eq( -1 ); }, eq: function( i ) { var len = this.length, j = +i + ( i < 0 ? len : 0 ); return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); }, end: function() { return this.prevObject || this.constructor(); }, // For internal use only. // Behaves like an Array's method, not like a jQuery method. push: push, sort: arr.sort, splice: arr.splice }; jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone, target = arguments[ 0 ] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; // Skip the boolean and the target target = arguments[ i ] || {}; i++; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !isFunction( target ) ) { target = {}; } // Extend jQuery itself if only one argument is passed if ( i === length ) { target = this; i--; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( ( options = arguments[ i ] ) != null ) { // Extend the base object for ( name in options ) { src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject( copy ) || ( copyIsArray = Array.isArray( copy ) ) ) ) { if ( copyIsArray ) { copyIsArray = false; clone = src && Array.isArray( src ) ? src : []; } else { clone = src && jQuery.isPlainObject( src ) ? src : {}; } // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; }; jQuery.extend( { // Unique for each copy of jQuery on the page expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), // Assume jQuery is ready without the ready module isReady: true, error: function( msg ) { throw new Error( msg ); }, noop: function() {}, isPlainObject: function( obj ) { var proto, Ctor; // Detect obvious negatives // Use toString instead of jQuery.type to catch host objects if ( !obj || toString.call( obj ) !== "[object Object]" ) { return false; } proto = getProto( obj ); // Objects with no prototype (e.g., `Object.create( null )`) are plain if ( !proto ) { return true; } // Objects with prototype are plain iff they were constructed by a global Object function Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; }, isEmptyObject: function( obj ) { /* eslint-disable no-unused-vars */ // See https://github.com/eslint/eslint/issues/6125 var name; for ( name in obj ) { return false; } return true; }, // Evaluates a script in a global context globalEval: function( code ) { DOMEval( code ); }, each: function( obj, callback ) { var length, i = 0; if ( isArrayLike( obj ) ) { length = obj.length; for ( ; i < length; i++ ) { if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { break; } } } else { for ( i in obj ) { if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { break; } } } return obj; }, // Support: Android <=4.0 only trim: function( text ) { return text == null ? "" : ( text + "" ).replace( rtrim, "" ); }, // results is for internal usage only makeArray: function( arr, results ) { var ret = results || []; if ( arr != null ) { if ( isArrayLike( Object( arr ) ) ) { jQuery.merge( ret, typeof arr === "string" ? [ arr ] : arr ); } else { push.call( ret, arr ); } } return ret; }, inArray: function( elem, arr, i ) { return arr == null ? -1 : indexOf.call( arr, elem, i ); }, // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit merge: function( first, second ) { var len = +second.length, j = 0, i = first.length; for ( ; j < len; j++ ) { first[ i++ ] = second[ j ]; } first.length = i; return first; }, grep: function( elems, callback, invert ) { var callbackInverse, matches = [], i = 0, length = elems.length, callbackExpect = !invert; // Go through the array, only saving the items // that pass the validator function for ( ; i < length; i++ ) { callbackInverse = !callback( elems[ i ], i ); if ( callbackInverse !== callbackExpect ) { matches.push( elems[ i ] ); } } return matches; }, // arg is for internal usage only map: function( elems, callback, arg ) { var length, value, i = 0, ret = []; // Go through the array, translating each of the items to their new values if ( isArrayLike( elems ) ) { length = elems.length; for ( ; i < length; i++ ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret.push( value ); } } // Go through every key on the object, } else { for ( i in elems ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret.push( value ); } } } // Flatten any nested arrays return concat.apply( [], ret ); }, // A global GUID counter for objects guid: 1, // jQuery.support is not used in Core but other projects attach their // properties to it so it needs to exist. support: support } ); if ( typeof Symbol === "function" ) { jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; } // Populate the class2type map jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), function( i, name ) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); } ); function isArrayLike( obj ) { // Support: real iOS 8.2 only (not reproducible in simulator) // `in` check used to prevent JIT error (gh-2145) // hasOwn isn't used here due to false negatives // regarding Nodelist length in IE var length = !!obj && "length" in obj && obj.length, type = toType( obj ); if ( isFunction( obj ) || isWindow( obj ) ) { return false; } return type === "array" || length === 0 || typeof length === "number" && length > 0 && ( length - 1 ) in obj; } var Sizzle = /*! * Sizzle CSS Selector Engine v2.3.3 * https://sizzlejs.com/ * * Copyright jQuery Foundation and other contributors * Released under the MIT license * http://jquery.org/license * * Date: 2016-08-08 */ (function( window ) { var i, support, Expr, getText, isXML, tokenize, compile, select, outermostContext, sortInput, hasDuplicate, // Local document vars setDocument, document, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains, // Instance-specific data expando = "sizzle" + 1 * new Date(), preferredDoc = window.document, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), sortOrder = function( a, b ) { if ( a === b ) { hasDuplicate = true; } return 0; }, // Instance methods hasOwn = ({}).hasOwnProperty, arr = [], pop = arr.pop, push_native = arr.push, push = arr.push, slice = arr.slice, // Use a stripped-down indexOf as it's faster than native // https://jsperf.com/thor-indexof-vs-for/5 indexOf = function( list, elem ) { var i = 0, len = list.length; for ( ; i < len; i++ ) { if ( list[i] === elem ) { return i; } } return -1; }, booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", // Regular expressions // http://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2) "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]", pseudos = ":(" + identifier + ")(?:\\((" + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: // 1. quoted (capture 3; capture 4 or capture 5) "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + // 2. simple (capture 6) "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + // 3. anything else (capture 2) ".*" + ")\\)|)", // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter rwhitespace = new RegExp( whitespace + "+", "g" ), rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), rpseudo = new RegExp( pseudos ), ridentifier = new RegExp( "^" + identifier + "$" ), matchExpr = { "ID": new RegExp( "^#(" + identifier + ")" ), "CLASS": new RegExp( "^\\.(" + identifier + ")" ), "TAG": new RegExp( "^(" + identifier + "|[*])" ), "ATTR": new RegExp( "^" + attributes ), "PSEUDO": new RegExp( "^" + pseudos ), "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), // For use in libraries implementing .is() // We use this for POS matching in `select` "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) }, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, // Easily-parseable/retrievable ID or TAG or CLASS selectors rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, // CSS escapes // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), funescape = function( _, escaped, escapedWhitespace ) { var high = "0x" + escaped - 0x10000; // NaN means non-codepoint // Support: Firefox<24 // Workaround erroneous numeric interpretation of +"0x" return high !== high || escapedWhitespace ? escaped : high < 0 ? // BMP codepoint String.fromCharCode( high + 0x10000 ) : // Supplemental Plane codepoint (surrogate pair) String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); }, // CSS string/identifier serialization // https://drafts.csswg.org/cssom/#common-serializing-idioms rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, fcssescape = function( ch, asCodePoint ) { if ( asCodePoint ) { // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER if ( ch === "\0" ) { return "\uFFFD"; } // Control characters and (dependent upon position) numbers get escaped as code points return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; } // Other potentially-special ASCII characters get backslash-escaped return "\\" + ch; }, // Used for iframes // See setDocument() // Removing the function wrapper causes a "Permission Denied" // error in IE unloadHandler = function() { setDocument(); }, disabledAncestor = addCombinator( function( elem ) { return elem.disabled === true && ("form" in elem || "label" in elem); }, { dir: "parentNode", next: "legend" } ); // Optimize for push.apply( _, NodeList ) try { push.apply( (arr = slice.call( preferredDoc.childNodes )), preferredDoc.childNodes ); // Support: Android<4.0 // Detect silently failing push.apply arr[ preferredDoc.childNodes.length ].nodeType; } catch ( e ) { push = { apply: arr.length ? // Leverage slice if possible function( target, els ) { push_native.apply( target, slice.call(els) ); } : // Support: IE<9 // Otherwise append directly function( target, els ) { var j = target.length, i = 0; // Can't trust NodeList.length while ( (target[j++] = els[i++]) ) {} target.length = j - 1; } }; } function Sizzle( selector, context, results, seed ) { var m, i, elem, nid, match, groups, newSelector, newContext = context && context.ownerDocument, // nodeType defaults to 9, since context defaults to document nodeType = context ? context.nodeType : 9; results = results || []; // Return early from calls with invalid selector or context if ( typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { return results; } // Try to shortcut find operations (as opposed to filters) in HTML documents if ( !seed ) { if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { setDocument( context ); } context = context || document; if ( documentIsHTML ) { // If the selector is sufficiently simple, try using a "get*By*" DOM method // (excepting DocumentFragment context, where the methods don't exist) if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { // ID selector if ( (m = match[1]) ) { // Document context if ( nodeType === 9 ) { if ( (elem = context.getElementById( m )) ) { // Support: IE, Opera, Webkit // TODO: identify versions // getElementById can match elements by name instead of ID if ( elem.id === m ) { results.push( elem ); return results; } } else { return results; } // Element context } else { // Support: IE, Opera, Webkit // TODO: identify versions // getElementById can match elements by name instead of ID if ( newContext && (elem = newContext.getElementById( m )) && contains( context, elem ) && elem.id === m ) { results.push( elem ); return results; } } // Type selector } else if ( match[2] ) { push.apply( results, context.getElementsByTagName( selector ) ); return results; // Class selector } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { push.apply( results, context.getElementsByClassName( m ) ); return results; } } // Take advantage of querySelectorAll if ( support.qsa && !compilerCache[ selector + " " ] && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { if ( nodeType !== 1 ) { newContext = context; newSelector = selector; // qSA looks outside Element context, which is not what we want // Thanks to Andrew Dupont for this workaround technique // Support: IE <=8 // Exclude object elements } else if ( context.nodeName.toLowerCase() !== "object" ) { // Capture the context ID, setting it first if necessary if ( (nid = context.getAttribute( "id" )) ) { nid = nid.replace( rcssescape, fcssescape ); } else { context.setAttribute( "id", (nid = expando) ); } // Prefix every selector in the list groups = tokenize( selector ); i = groups.length; while ( i-- ) { groups[i] = "#" + nid + " " + toSelector( groups[i] ); } newSelector = groups.join( "," ); // Expand context for sibling selectors newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; } if ( newSelector ) { try { push.apply( results, newContext.querySelectorAll( newSelector ) ); return results; } catch ( qsaError ) { } finally { if ( nid === expando ) { context.removeAttribute( "id" ); } } } } } } // All others return select( selector.replace( rtrim, "$1" ), context, results, seed ); } /** * Create key-value caches of limited size * @returns {function(string, object)} Returns the Object data after storing it on itself with * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) * deleting the oldest entry */ function createCache() { var keys = []; function cache( key, value ) { // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) if ( keys.push( key + " " ) > Expr.cacheLength ) { // Only keep the most recent entries delete cache[ keys.shift() ]; } return (cache[ key + " " ] = value); } return cache; } /** * Mark a function for special use by Sizzle * @param {Function} fn The function to mark */ function markFunction( fn ) { fn[ expando ] = true; return fn; } /** * Support testing using an element * @param {Function} fn Passed the created element and returns a boolean result */ function assert( fn ) { var el = document.createElement("fieldset"); try { return !!fn( el ); } catch (e) { return false; } finally { // Remove from its parent by default if ( el.parentNode ) { el.parentNode.removeChild( el ); } // release memory in IE el = null; } } /** * Adds the same handler for all of the specified attrs * @param {String} attrs Pipe-separated list of attributes * @param {Function} handler The method that will be applied */ function addHandle( attrs, handler ) { var arr = attrs.split("|"), i = arr.length; while ( i-- ) { Expr.attrHandle[ arr[i] ] = handler; } } /** * Checks document order of two siblings * @param {Element} a * @param {Element} b * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b */ function siblingCheck( a, b ) { var cur = b && a, diff = cur && a.nodeType === 1 && b.nodeType === 1 && a.sourceIndex - b.sourceIndex; // Use IE sourceIndex if available on both nodes if ( diff ) { return diff; } // Check if b follows a if ( cur ) { while ( (cur = cur.nextSibling) ) { if ( cur === b ) { return -1; } } } return a ? 1 : -1; } /** * Returns a function to use in pseudos for input types * @param {String} type */ function createInputPseudo( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === type; }; } /** * Returns a function to use in pseudos for buttons * @param {String} type */ function createButtonPseudo( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); return (name === "input" || name === "button") && elem.type === type; }; } /** * Returns a function to use in pseudos for :enabled/:disabled * @param {Boolean} disabled true for :disabled; false for :enabled */ function createDisabledPseudo( disabled ) { // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable return function( elem ) { // Only certain elements can match :enabled or :disabled // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled if ( "form" in elem ) { // Check for inherited disabledness on relevant non-disabled elements: // * listed form-associated elements in a disabled fieldset // https://html.spec.whatwg.org/multipage/forms.html#category-listed // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled // * option elements in a disabled optgroup // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled // All such elements have a "form" property. if ( elem.parentNode && elem.disabled === false ) { // Option elements defer to a parent optgroup if present if ( "label" in elem ) { if ( "label" in elem.parentNode ) { return elem.parentNode.disabled === disabled; } else { return elem.disabled === disabled; } } // Support: IE 6 - 11 // Use the isDisabled shortcut property to check for disabled fieldset ancestors return elem.isDisabled === disabled || // Where there is no isDisabled, check manually /* jshint -W018 */ elem.isDisabled !== !disabled && disabledAncestor( elem ) === disabled; } return elem.disabled === disabled; // Try to winnow out elements that can't be disabled before trusting the disabled property. // Some victims get caught in our net (label, legend, menu, track), but it shouldn't // even exist on them, let alone have a boolean value. } else if ( "label" in elem ) { return elem.disabled === disabled; } // Remaining elements are neither :enabled nor :disabled return false; }; } /** * Returns a function to use in pseudos for positionals * @param {Function} fn */ function createPositionalPseudo( fn ) { return markFunction(function( argument ) { argument = +argument; return markFunction(function( seed, matches ) { var j, matchIndexes = fn( [], seed.length, argument ), i = matchIndexes.length; // Match elements found at the specified indexes while ( i-- ) { if ( seed[ (j = matchIndexes[i]) ] ) { seed[j] = !(matches[j] = seed[j]); } } }); }); } /** * Checks a node for validity as a Sizzle context * @param {Element|Object=} context * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value */ function testContext( context ) { return context && typeof context.getElementsByTagName !== "undefined" && context; } // Expose support vars for convenience support = Sizzle.support = {}; /** * Detects XML nodes * @param {Element|Object} elem An element or a document * @returns {Boolean} True iff elem is a non-HTML XML node */ isXML = Sizzle.isXML = function( elem ) { // documentElement is verified for cases where it doesn't yet exist // (such as loading iframes in IE - #4833) var documentElement = elem && (elem.ownerDocument || elem).documentElement; return documentElement ? documentElement.nodeName !== "HTML" : false; }; /** * Sets document-related variables once based on the current document * @param {Element|Object} [doc] An element or document object to use to set the document * @returns {Object} Returns the current document */ setDocument = Sizzle.setDocument = function( node ) { var hasCompare, subWindow, doc = node ? node.ownerDocument || node : preferredDoc; // Return early if doc is invalid or already selected if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { return document; } // Update global variables document = doc; docElem = document.documentElement; documentIsHTML = !isXML( document ); // Support: IE 9-11, Edge // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) if ( preferredDoc !== document && (subWindow = document.defaultView) && subWindow.top !== subWindow ) { // Support: IE 11, Edge if ( subWindow.addEventListener ) { subWindow.addEventListener( "unload", unloadHandler, false ); // Support: IE 9 - 10 only } else if ( subWindow.attachEvent ) { subWindow.attachEvent( "onunload", unloadHandler ); } } /* Attributes ---------------------------------------------------------------------- */ // Support: IE<8 // Verify that getAttribute really returns attributes and not properties // (excepting IE8 booleans) support.attributes = assert(function( el ) { el.className = "i"; return !el.getAttribute("className"); }); /* getElement(s)By* ---------------------------------------------------------------------- */ // Check if getElementsByTagName("*") returns only elements support.getElementsByTagName = assert(function( el ) { el.appendChild( document.createComment("") ); return !el.getElementsByTagName("*").length; }); // Support: IE<9 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); // Support: IE<10 // Check if getElementById returns elements by name // The broken getElementById methods don't pick up programmatically-set names, // so use a roundabout getElementsByName test support.getById = assert(function( el ) { docElem.appendChild( el ).id = expando; return !document.getElementsByName || !document.getElementsByName( expando ).length; }); // ID filter and find if ( support.getById ) { Expr.filter["ID"] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { return elem.getAttribute("id") === attrId; }; }; Expr.find["ID"] = function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var elem = context.getElementById( id ); return elem ? [ elem ] : []; } }; } else { Expr.filter["ID"] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); return node && node.value === attrId; }; }; // Support: IE 6 - 7 only // getElementById is not reliable as a find shortcut Expr.find["ID"] = function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var node, i, elems, elem = context.getElementById( id ); if ( elem ) { // Verify the id attribute node = elem.getAttributeNode("id"); if ( node && node.value === id ) { return [ elem ]; } // Fall back on getElementsByName elems = context.getElementsByName( id ); i = 0; while ( (elem = elems[i++]) ) { node = elem.getAttributeNode("id"); if ( node && node.value === id ) { return [ elem ]; } } } return []; } }; } // Tag Expr.find["TAG"] = support.getElementsByTagName ? function( tag, context ) { if ( typeof context.getElementsByTagName !== "undefined" ) { return context.getElementsByTagName( tag ); // DocumentFragment nodes don't have gEBTN } else if ( support.qsa ) { return context.querySelectorAll( tag ); } } : function( tag, context ) { var elem, tmp = [], i = 0, // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too results = context.getElementsByTagName( tag ); // Filter out possible comments if ( tag === "*" ) { while ( (elem = results[i++]) ) { if ( elem.nodeType === 1 ) { tmp.push( elem ); } } return tmp; } return results; }; // Class Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { return context.getElementsByClassName( className ); } }; /* QSA/matchesSelector ---------------------------------------------------------------------- */ // QSA and matchesSelector support // matchesSelector(:active) reports false when true (IE9/Opera 11.5) rbuggyMatches = []; // qSa(:focus) reports false when true (Chrome 21) // We allow this because of a bug in IE8/9 that throws an error // whenever `document.activeElement` is accessed on an iframe // So, we allow :focus to pass through QSA all the time to avoid the IE error // See https://bugs.jquery.com/ticket/13378 rbuggyQSA = []; if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { // Build QSA regex // Regex strategy adopted from Diego Perini assert(function( el ) { // Select is set to empty string on purpose // This is to test IE's treatment of not explicitly // setting a boolean content attribute, // since its presence should be enough // https://bugs.jquery.com/ticket/12359 docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" + "<select id='" + expando + "-\r\\' msallowcapture=''>" + "<option selected=''></option></select>"; // Support: IE8, Opera 11-12.16 // Nothing should be selected when empty strings follow ^= or $= or *= // The test attribute must be unknown in Opera but "safe" for WinRT // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section if ( el.querySelectorAll("[msallowcapture^='']").length ) { rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); } // Support: IE8 // Boolean attributes and "value" are not treated correctly if ( !el.querySelectorAll("[selected]").length ) { rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); } // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { rbuggyQSA.push("~="); } // Webkit/Opera - :checked should return selected option elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked // IE8 throws error here and will not see later tests if ( !el.querySelectorAll(":checked").length ) { rbuggyQSA.push(":checked"); } // Support: Safari 8+, iOS 8+ // https://bugs.webkit.org/show_bug.cgi?id=136851 // In-page `selector#id sibling-combinator selector` fails if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { rbuggyQSA.push(".#.+[+~]"); } }); assert(function( el ) { el.innerHTML = "<a href='' disabled='disabled'></a>" + "<select disabled='disabled'><option/></select>"; // Support: Windows 8 Native Apps // The type and name attributes are restricted during .innerHTML assignment var input = document.createElement("input"); input.setAttribute( "type", "hidden" ); el.appendChild( input ).setAttribute( "name", "D" ); // Support: IE8 // Enforce case-sensitivity of name attribute if ( el.querySelectorAll("[name=d]").length ) { rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) // IE8 throws error here and will not see later tests if ( el.querySelectorAll(":enabled").length !== 2 ) { rbuggyQSA.push( ":enabled", ":disabled" ); } // Support: IE9-11+ // IE's :disabled selector does not pick up the children of disabled fieldsets docElem.appendChild( el ).disabled = true; if ( el.querySelectorAll(":disabled").length !== 2 ) { rbuggyQSA.push( ":enabled", ":disabled" ); } // Opera 10-11 does not throw on post-comma invalid pseudos el.querySelectorAll("*,:x"); rbuggyQSA.push(",.*:"); }); } if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector) )) ) { assert(function( el ) { // Check to see if it's possible to do matchesSelector // on a disconnected node (IE 9) support.disconnectedMatch = matches.call( el, "*" ); // This should fail with an exception // Gecko does not error, returns false instead matches.call( el, "[s!='']:x" ); rbuggyMatches.push( "!=", pseudos ); }); } rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); /* Contains ---------------------------------------------------------------------- */ hasCompare = rnative.test( docElem.compareDocumentPosition ); // Element contains another // Purposefully self-exclusive // As in, an element does not contain itself contains = hasCompare || rnative.test( docElem.contains ) ? function( a, b ) { var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode; return a === bup || !!( bup && bup.nodeType === 1 && ( adown.contains ? adown.contains( bup ) : a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 )); } : function( a, b ) { if ( b ) { while ( (b = b.parentNode) ) { if ( b === a ) { return true; } } } return false; }; /* Sorting ---------------------------------------------------------------------- */ // Document order sorting sortOrder = hasCompare ? function( a, b ) { // Flag for duplicate removal if ( a === b ) { hasDuplicate = true; return 0; } // Sort on method existence if only one input has compareDocumentPosition var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; if ( compare ) { return compare; } // Calculate position if both inputs belong to the same document compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? a.compareDocumentPosition( b ) : // Otherwise we know they are disconnected 1; // Disconnected nodes if ( compare & 1 || (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { // Choose the first element that is related to our preferred document if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { return -1; } if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { return 1; } // Maintain original order return sortInput ? ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 0; } return compare & 4 ? -1 : 1; } : function( a, b ) { // Exit early if the nodes are identical if ( a === b ) { hasDuplicate = true; return 0; } var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [ a ], bp = [ b ]; // Parentless nodes are either documents or disconnected if ( !aup || !bup ) { return a === document ? -1 : b === document ? 1 : aup ? -1 : bup ? 1 : sortInput ? ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 0; // If the nodes are siblings, we can do a quick check } else if ( aup === bup ) { return siblingCheck( a, b ); } // Otherwise we need full lists of their ancestors for comparison cur = a; while ( (cur = cur.parentNode) ) { ap.unshift( cur ); } cur = b; while ( (cur = cur.parentNode) ) { bp.unshift( cur ); } // Walk down the tree looking for a discrepancy while ( ap[i] === bp[i] ) { i++; } return i ? // Do a sibling check if the nodes have a common ancestor siblingCheck( ap[i], bp[i] ) : // Otherwise nodes in our document sort first ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0; }; return document; }; Sizzle.matches = function( expr, elements ) { return Sizzle( expr, null, null, elements ); }; Sizzle.matchesSelector = function( elem, expr ) { // Set document vars if needed if ( ( elem.ownerDocument || elem ) !== document ) { setDocument( elem ); } // Make sure that attribute selectors are quoted expr = expr.replace( rattributeQuotes, "='$1']" ); if ( support.matchesSelector && documentIsHTML && !compilerCache[ expr + " " ] && ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { try { var ret = matches.call( elem, expr ); // IE 9's matchesSelector returns false on disconnected nodes if ( ret || support.disconnectedMatch || // As well, disconnected nodes are said to be in a document // fragment in IE 9 elem.document && elem.document.nodeType !== 11 ) { return ret; } } catch (e) {} } return Sizzle( expr, document, null, [ elem ] ).length > 0; }; Sizzle.contains = function( context, elem ) { // Set document vars if needed if ( ( context.ownerDocument || context ) !== document ) { setDocument( context ); } return contains( context, elem ); }; Sizzle.attr = function( elem, name ) { // Set document vars if needed if ( ( elem.ownerDocument || elem ) !== document ) { setDocument( elem ); } var fn = Expr.attrHandle[ name.toLowerCase() ], // Don't get fooled by Object.prototype properties (jQuery #13807) val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? fn( elem, name, !documentIsHTML ) : undefined; return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute( name ) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; }; Sizzle.escape = function( sel ) { return (sel + "").replace( rcssescape, fcssescape ); }; Sizzle.error = function( msg ) { throw new Error( "Syntax error, unrecognized expression: " + msg ); }; /** * Document sorting and removing duplicates * @param {ArrayLike} results */ Sizzle.uniqueSort = function( results ) { var elem, duplicates = [], j = 0, i = 0; // Unless we *know* we can detect duplicates, assume their presence hasDuplicate = !support.detectDuplicates; sortInput = !support.sortStable && results.slice( 0 ); results.sort( sortOrder ); if ( hasDuplicate ) { while ( (elem = results[i++]) ) { if ( elem === results[ i ] ) { j = duplicates.push( i ); } } while ( j-- ) { results.splice( duplicates[ j ], 1 ); } } // Clear input after sorting to release objects // See https://github.com/jquery/sizzle/pull/225 sortInput = null; return results; }; /** * Utility function for retrieving the text value of an array of DOM nodes * @param {Array|Element} elem */ getText = Sizzle.getText = function( elem ) { var node, ret = "", i = 0, nodeType = elem.nodeType; if ( !nodeType ) { // If no nodeType, this is expected to be an array while ( (node = elem[i++]) ) { // Do not traverse comment nodes ret += getText( node ); } } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { // Use textContent for elements // innerText usage removed for consistency of new lines (jQuery #11153) if ( typeof elem.textContent === "string" ) { return elem.textContent; } else { // Traverse its children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { ret += getText( elem ); } } } else if ( nodeType === 3 || nodeType === 4 ) { return elem.nodeValue; } // Do not include comment or processing instruction nodes return ret; }; Expr = Sizzle.selectors = { // Can be adjusted by the user cacheLength: 50, createPseudo: markFunction, match: matchExpr, attrHandle: {}, find: {}, relative: { ">": { dir: "parentNode", first: true }, " ": { dir: "parentNode" }, "+": { dir: "previousSibling", first: true }, "~": { dir: "previousSibling" } }, preFilter: { "ATTR": function( match ) { match[1] = match[1].replace( runescape, funescape ); // Move the given value to match[3] whether quoted or unquoted match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); if ( match[2] === "~=" ) { match[3] = " " + match[3] + " "; } return match.slice( 0, 4 ); }, "CHILD": function( match ) { /* matches from matchExpr["CHILD"] 1 type (only|nth|...) 2 what (child|of-type) 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 4 xn-component of xn+y argument ([+-]?\d*n|) 5 sign of xn-component 6 x of xn-component 7 sign of y-component 8 y of y-component */ match[1] = match[1].toLowerCase(); if ( match[1].slice( 0, 3 ) === "nth" ) { // nth-* requires argument if ( !match[3] ) { Sizzle.error( match[0] ); } // numeric x and y parameters for Expr.filter.CHILD // remember that false/true cast respectively to 0/1 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); // other types prohibit arguments } else if ( match[3] ) { Sizzle.error( match[0] ); } return match; }, "PSEUDO": function( match ) { var excess, unquoted = !match[6] && match[2]; if ( matchExpr["CHILD"].test( match[0] ) ) { return null; } // Accept quoted arguments as-is if ( match[3] ) { match[2] = match[4] || match[5] || ""; // Strip excess characters from unquoted arguments } else if ( unquoted && rpseudo.test( unquoted ) && // Get excess from tokenize (recursively) (excess = tokenize( unquoted, true )) && // advance to the next closing parenthesis (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { // excess is a negative index match[0] = match[0].slice( 0, excess ); match[2] = unquoted.slice( 0, excess ); } // Return only captures needed by the pseudo filter method (type and argument) return match.slice( 0, 3 ); } }, filter: { "TAG": function( nodeNameSelector ) { var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); return nodeNameSelector === "*" ? function() { return true; } : function( elem ) { return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; }; }, "CLASS": function( className ) { var pattern = classCache[ className + " " ]; return pattern || (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && classCache( className, function( elem ) { return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); }); }, "ATTR": function( name, operator, check ) { return function( elem ) { var result = Sizzle.attr( elem, name ); if ( result == null ) { return operator === "!="; } if ( !operator ) { return true; } result += ""; return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf( check ) === 0 : operator === "*=" ? check && result.indexOf( check ) > -1 : operator === "$=" ? check && result.slice( -check.length ) === check : operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : false; }; }, "CHILD": function( type, what, argument, first, last ) { var simple = type.slice( 0, 3 ) !== "nth", forward = type.slice( -4 ) !== "last", ofType = what === "of-type"; return first === 1 && last === 0 ? // Shortcut for :nth-*(n) function( elem ) { return !!elem.parentNode; } : function( elem, context, xml ) { var cache, uniqueCache, outerCache, node, nodeIndex, start, dir = simple !== forward ? "nextSibling" : "previousSibling", parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType, diff = false; if ( parent ) { // :(first|last|only)-(child|of-type) if ( simple ) { while ( dir ) { node = elem; while ( (node = node[ dir ]) ) { if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { return false; } } // Reverse direction for :only-* (if we haven't yet done so) start = dir = type === "only" && !start && "nextSibling"; } return true; } start = [ forward ? parent.firstChild : parent.lastChild ]; // non-xml :nth-child(...) stores cache data on `parent` if ( forward && useCache ) { // Seek `elem` from a previously-cached index // ...in a gzip-friendly way node = parent; outerCache = node[ expando ] || (node[ expando ] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || (outerCache[ node.uniqueID ] = {}); cache = uniqueCache[ type ] || []; nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; diff = nodeIndex && cache[ 2 ]; node = nodeIndex && parent.childNodes[ nodeIndex ]; while ( (node = ++nodeIndex && node && node[ dir ] || // Fallback to seeking `elem` from the start (diff = nodeIndex = 0) || start.pop()) ) { // When found, cache indexes on `parent` and break if ( node.nodeType === 1 && ++diff && node === elem ) { uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; break; } } } else { // Use previously-cached element index if available if ( useCache ) { // ...in a gzip-friendly way node = elem; outerCache = node[ expando ] || (node[ expando ] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || (outerCache[ node.uniqueID ] = {}); cache = uniqueCache[ type ] || []; nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; diff = nodeIndex; } // xml :nth-child(...) // or :nth-last-child(...) or :nth(-last)?-of-type(...) if ( diff === false ) { // Use the same loop as above to seek `elem` from the start while ( (node = ++nodeIndex && node && node[ dir ] || (diff = nodeIndex = 0) || start.pop()) ) { if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { // Cache the index of each encountered element if ( useCache ) { outerCache = node[ expando ] || (node[ expando ] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || (outerCache[ node.uniqueID ] = {}); uniqueCache[ type ] = [ dirruns, diff ]; } if ( node === elem ) { break; } } } } } // Incorporate the offset, then check against cycle size diff -= last; return diff === first || ( diff % first === 0 && diff / first >= 0 ); } }; }, "PSEUDO": function( pseudo, argument ) { // pseudo-class names are case-insensitive // http://www.w3.org/TR/selectors/#pseudo-classes // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters // Remember that setFilters inherits from pseudos var args, fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || Sizzle.error( "unsupported pseudo: " + pseudo ); // The user may use createPseudo to indicate that // arguments are needed to create the filter function // just as Sizzle does if ( fn[ expando ] ) { return fn( argument ); } // But maintain support for old signatures if ( fn.length > 1 ) { args = [ pseudo, pseudo, "", argument ]; return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? markFunction(function( seed, matches ) { var idx, matched = fn( seed, argument ), i = matched.length; while ( i-- ) { idx = indexOf( seed, matched[i] ); seed[ idx ] = !( matches[ idx ] = matched[i] ); } }) : function( elem ) { return fn( elem, 0, args ); }; } return fn; } }, pseudos: { // Potentially complex pseudos "not": markFunction(function( selector ) { // Trim the selector passed to compile // to avoid treating leading and trailing // spaces as combinators var input = [], results = [], matcher = compile( selector.replace( rtrim, "$1" ) ); return matcher[ expando ] ? markFunction(function( seed, matches, context, xml ) { var elem, unmatched = matcher( seed, null, xml, [] ), i = seed.length; // Match elements unmatched by `matcher` while ( i-- ) { if ( (elem = unmatched[i]) ) { seed[i] = !(matches[i] = elem); } } }) : function( elem, context, xml ) { input[0] = elem; matcher( input, null, xml, results ); // Don't keep the element (issue #299) input[0] = null; return !results.pop(); }; }), "has": markFunction(function( selector ) { return function( elem ) { return Sizzle( selector, elem ).length > 0; }; }), "contains": markFunction(function( text ) { text = text.replace( runescape, funescape ); return function( elem ) { return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; }; }), // "Whether an element is represented by a :lang() selector // is based solely on the element's language value // being equal to the identifier C, // or beginning with the identifier C immediately followed by "-". // The matching of C against the element's language value is performed case-insensitively. // The identifier C does not have to be a valid language name." // http://www.w3.org/TR/selectors/#lang-pseudo "lang": markFunction( function( lang ) { // lang value must be a valid identifier if ( !ridentifier.test(lang || "") ) { Sizzle.error( "unsupported lang: " + lang ); } lang = lang.replace( runescape, funescape ).toLowerCase(); return function( elem ) { var elemLang; do { if ( (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { elemLang = elemLang.toLowerCase(); return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; } } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); return false; }; }), // Miscellaneous "target": function( elem ) { var hash = window.location && window.location.hash; return hash && hash.slice( 1 ) === elem.id; }, "root": function( elem ) { return elem === docElem; }, "focus": function( elem ) { return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); }, // Boolean properties "enabled": createDisabledPseudo( false ), "disabled": createDisabledPseudo( true ), "checked": function( elem ) { // In CSS3, :checked should return both checked and selected elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked var nodeName = elem.nodeName.toLowerCase(); return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); }, "selected": function( elem ) { // Accessing this property makes selected-by-default // options in Safari work properly if ( elem.parentNode ) { elem.parentNode.selectedIndex; } return elem.selected === true; }, // Contents "empty": function( elem ) { // http://www.w3.org/TR/selectors/#empty-pseudo // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), // but not by others (comment: 8; processing instruction: 7; etc.) // nodeType < 6 works because attributes (2) do not appear as children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { if ( elem.nodeType < 6 ) { return false; } } return true; }, "parent": function( elem ) { return !Expr.pseudos["empty"]( elem ); }, // Element/input types "header": function( elem ) { return rheader.test( elem.nodeName ); }, "input": function( elem ) { return rinputs.test( elem.nodeName ); }, "button": function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === "button" || name === "button"; }, "text": function( elem ) { var attr; return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && // Support: IE<8 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); }, // Position-in-collection "first": createPositionalPseudo(function() { return [ 0 ]; }), "last": createPositionalPseudo(function( matchIndexes, length ) { return [ length - 1 ]; }), "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { return [ argument < 0 ? argument + length : argument ]; }), "even": createPositionalPseudo(function( matchIndexes, length ) { var i = 0; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; }), "odd": createPositionalPseudo(function( matchIndexes, length ) { var i = 1; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; }), "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument; for ( ; --i >= 0; ) { matchIndexes.push( i ); } return matchIndexes; }), "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument; for ( ; ++i < length; ) { matchIndexes.push( i ); } return matchIndexes; }) } }; Expr.pseudos["nth"] = Expr.pseudos["eq"]; // Add button/input type pseudos for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { Expr.pseudos[ i ] = createInputPseudo( i ); } for ( i in { submit: true, reset: true } ) { Expr.pseudos[ i ] = createButtonPseudo( i ); } // Easy API for creating new setFilters function setFilters() {} setFilters.prototype = Expr.filters = Expr.pseudos; Expr.setFilters = new setFilters(); tokenize = Sizzle.tokenize = function( selector, parseOnly ) { var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[ selector + " " ]; if ( cached ) { return parseOnly ? 0 : cached.slice( 0 ); } soFar = selector; groups = []; preFilters = Expr.preFilter; while ( soFar ) { // Comma and first run if ( !matched || (match = rcomma.exec( soFar )) ) { if ( match ) { // Don't consume trailing commas as valid soFar = soFar.slice( match[0].length ) || soFar; } groups.push( (tokens = []) ); } matched = false; // Combinators if ( (match = rcombinators.exec( soFar )) ) { matched = match.shift(); tokens.push({ value: matched, // Cast descendant combinators to space type: match[0].replace( rtrim, " " ) }); soFar = soFar.slice( matched.length ); } // Filters for ( type in Expr.filter ) { if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || (match = preFilters[ type ]( match ))) ) { matched = match.shift(); tokens.push({ value: matched, type: type, matches: match }); soFar = soFar.slice( matched.length ); } } if ( !matched ) { break; } } // Return the length of the invalid excess // if we're just parsing // Otherwise, throw an error or return tokens return parseOnly ? soFar.length : soFar ? Sizzle.error( selector ) : // Cache the tokens tokenCache( selector, groups ).slice( 0 ); }; function toSelector( tokens ) { var i = 0, len = tokens.length, selector = ""; for ( ; i < len; i++ ) { selector += tokens[i].value; } return selector; } function addCombinator( matcher, combinator, base ) { var dir = combinator.dir, skip = combinator.next, key = skip || dir, checkNonElements = base && key === "parentNode", doneName = done++; return combinator.first ? // Check against closest ancestor/preceding element function( elem, context, xml ) { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { return matcher( elem, context, xml ); } } return false; } : // Check against all ancestor/preceding elements function( elem, context, xml ) { var oldCache, uniqueCache, outerCache, newCache = [ dirruns, doneName ]; // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching if ( xml ) { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { if ( matcher( elem, context, xml ) ) { return true; } } } } else { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { outerCache = elem[ expando ] || (elem[ expando ] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); if ( skip && skip === elem.nodeName.toLowerCase() ) { elem = elem[ dir ] || elem; } else if ( (oldCache = uniqueCache[ key ]) && oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { // Assign to newCache so results back-propagate to previous elements return (newCache[ 2 ] = oldCache[ 2 ]); } else { // Reuse newcache so results back-propagate to previous elements uniqueCache[ key ] = newCache; // A match means we're done; a fail means we have to keep checking if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { return true; } } } } } return false; }; } function elementMatcher( matchers ) { return matchers.length > 1 ? function( elem, context, xml ) { var i = matchers.length; while ( i-- ) { if ( !matchers[i]( elem, context, xml ) ) { return false; } } return true; } : matchers[0]; } function multipleContexts( selector, contexts, results ) { var i = 0, len = contexts.length; for ( ; i < len; i++ ) { Sizzle( selector, contexts[i], results ); } return results; } function condense( unmatched, map, filter, context, xml ) { var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null; for ( ; i < len; i++ ) { if ( (elem = unmatched[i]) ) { if ( !filter || filter( elem, context, xml ) ) { newUnmatched.push( elem ); if ( mapped ) { map.push( i ); } } } } return newUnmatched; } function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { if ( postFilter && !postFilter[ expando ] ) { postFilter = setMatcher( postFilter ); } if ( postFinder && !postFinder[ expando ] ) { postFinder = setMatcher( postFinder, postSelector ); } return markFunction(function( seed, results, context, xml ) { var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, // Get initial elements from seed or context elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), // Prefilter to get matcher input, preserving a map for seed-results synchronization matcherIn = preFilter && ( seed || !selector ) ? condense( elems, preMap, preFilter, context, xml ) : elems, matcherOut = matcher ? // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, postFinder || ( seed ? preFilter : preexisting || postFilter ) ? // ...intermediate processing is necessary [] : // ...otherwise use results directly results : matcherIn; // Find primary matches if ( matcher ) { matcher( matcherIn, matcherOut, context, xml ); } // Apply postFilter if ( postFilter ) { temp = condense( matcherOut, postMap ); postFilter( temp, [], context, xml ); // Un-match failing elements by moving them back to matcherIn i = temp.length; while ( i-- ) { if ( (elem = temp[i]) ) { matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); } } } if ( seed ) { if ( postFinder || preFilter ) { if ( postFinder ) { // Get the final matcherOut by condensing this intermediate into postFinder contexts temp = []; i = matcherOut.length; while ( i-- ) { if ( (elem = matcherOut[i]) ) { // Restore matcherIn since elem is not yet a final match temp.push( (matcherIn[i] = elem) ); } } postFinder( null, (matcherOut = []), temp, xml ); } // Move matched elements from seed to results to keep them synchronized i = matcherOut.length; while ( i-- ) { if ( (elem = matcherOut[i]) && (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { seed[temp] = !(results[temp] = elem); } } } // Add elements to results, through postFinder if defined } else { matcherOut = condense( matcherOut === results ? matcherOut.splice( preexisting, matcherOut.length ) : matcherOut ); if ( postFinder ) { postFinder( null, results, matcherOut, xml ); } else { push.apply( results, matcherOut ); } } }); } function matcherFromTokens( tokens ) { var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[ tokens[0].type ], implicitRelative = leadingRelative || Expr.relative[" "], i = leadingRelative ? 1 : 0, // The foundational matcher ensures that elements are reachable from top-level context(s) matchContext = addCombinator( function( elem ) { return elem === checkContext; }, implicitRelative, true ), matchAnyContext = addCombinator( function( elem ) { return indexOf( checkContext, elem ) > -1; }, implicitRelative, true ), matchers = [ function( elem, context, xml ) { var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( (checkContext = context).nodeType ? matchContext( elem, context, xml ) : matchAnyContext( elem, context, xml ) ); // Avoid hanging onto element (issue #299) checkContext = null; return ret; } ]; for ( ; i < len; i++ ) { if ( (matcher = Expr.relative[ tokens[i].type ]) ) { matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; } else { matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); // Return special upon seeing a positional matcher if ( matcher[ expando ] ) { // Find the next relative operator (if any) for proper handling j = ++i; for ( ; j < len; j++ ) { if ( Expr.relative[ tokens[j].type ] ) { break; } } return setMatcher( i > 1 && elementMatcher( matchers ), i > 1 && toSelector( // If the preceding token was a descendant combinator, insert an implicit any-element `*` tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) ).replace( rtrim, "$1" ), matcher, i < j && matcherFromTokens( tokens.slice( i, j ) ), j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), j < len && toSelector( tokens ) ); } matchers.push( matcher ); } } return elementMatcher( matchers ); } function matcherFromGroupMatchers( elementMatchers, setMatchers ) { var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function( seed, context, xml, results, outermost ) { var elem, j, matcher, matchedCount = 0, i = "0", unmatched = seed && [], setMatched = [], contextBackup = outermostContext, // We must always have either seed elements or outermost context elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), // Use integer dirruns iff this is the outermost matcher dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), len = elems.length; if ( outermost ) { outermostContext = context === document || context || outermost; } // Add elements passing elementMatchers directly to results // Support: IE<9, Safari // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id for ( ; i !== len && (elem = elems[i]) != null; i++ ) { if ( byElement && elem ) { j = 0; if ( !context && elem.ownerDocument !== document ) { setDocument( elem ); xml = !documentIsHTML; } while ( (matcher = elementMatchers[j++]) ) { if ( matcher( elem, context || document, xml) ) { results.push( elem ); break; } } if ( outermost ) { dirruns = dirrunsUnique; } } // Track unmatched elements for set filters if ( bySet ) { // They will have gone through all possible matchers if ( (elem = !matcher && elem) ) { matchedCount--; } // Lengthen the array for every element, matched or not if ( seed ) { unmatched.push( elem ); } } } // `i` is now the count of elements visited above, and adding it to `matchedCount` // makes the latter nonnegative. matchedCount += i; // Apply set filters to unmatched elements // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` // equals `i`), unless we didn't visit _any_ elements in the above loop because we have // no element matchers and no seed. // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that // case, which will result in a "00" `matchedCount` that differs from `i` but is also // numerically zero. if ( bySet && i !== matchedCount ) { j = 0; while ( (matcher = setMatchers[j++]) ) { matcher( unmatched, setMatched, context, xml ); } if ( seed ) { // Reintegrate element matches to eliminate the need for sorting if ( matchedCount > 0 ) { while ( i-- ) { if ( !(unmatched[i] || setMatched[i]) ) { setMatched[i] = pop.call( results ); } } } // Discard index placeholder values to get only actual matches setMatched = condense( setMatched ); } // Add matches to results push.apply( results, setMatched ); // Seedless set matches succeeding multiple successful matchers stipulate sorting if ( outermost && !seed && setMatched.length > 0 && ( matchedCount + setMatchers.length ) > 1 ) { Sizzle.uniqueSort( results ); } } // Override manipulation of globals by nested matchers if ( outermost ) { dirruns = dirrunsUnique; outermostContext = contextBackup; } return unmatched; }; return bySet ? markFunction( superMatcher ) : superMatcher; } compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { var i, setMatchers = [], elementMatchers = [], cached = compilerCache[ selector + " " ]; if ( !cached ) { // Generate a function of recursive functions that can be used to check each element if ( !match ) { match = tokenize( selector ); } i = match.length; while ( i-- ) { cached = matcherFromTokens( match[i] ); if ( cached[ expando ] ) { setMatchers.push( cached ); } else { elementMatchers.push( cached ); } } // Cache the compiled function cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); // Save selector and tokenization cached.selector = selector; } return cached; }; /** * A low-level selection function that works with Sizzle's compiled * selector functions * @param {String|Function} selector A selector or a pre-compiled * selector function built with Sizzle.compile * @param {Element} context * @param {Array} [results] * @param {Array} [seed] A set of elements to match against */ select = Sizzle.select = function( selector, context, results, seed ) { var i, tokens, token, type, find, compiled = typeof selector === "function" && selector, match = !seed && tokenize( (selector = compiled.selector || selector) ); results = results || []; // Try to minimize operations if there is only one selector in the list and no seed // (the latter of which guarantees us context) if ( match.length === 1 ) { // Reduce context if the leading compound selector is an ID tokens = match[0] = match[0].slice( 0 ); if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; if ( !context ) { return results; // Precompiled matchers will still verify ancestry, so step up a level } else if ( compiled ) { context = context.parentNode; } selector = selector.slice( tokens.shift().value.length ); } // Fetch a seed set for right-to-left matching i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; while ( i-- ) { token = tokens[i]; // Abort if we hit a combinator if ( Expr.relative[ (type = token.type) ] ) { break; } if ( (find = Expr.find[ type ]) ) { // Search, expanding context for leading sibling combinators if ( (seed = find( token.matches[0].replace( runescape, funescape ), rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context )) ) { // If seed is empty or no tokens remain, we can return early tokens.splice( i, 1 ); selector = seed.length && toSelector( tokens ); if ( !selector ) { push.apply( results, seed ); return results; } break; } } } } // Compile and execute a filtering function if one is not provided // Provide `match` to avoid retokenization if we modified the selector above ( compiled || compile( selector, match ) )( seed, context, !documentIsHTML, results, !context || rsibling.test( selector ) && testContext( context.parentNode ) || context ); return results; }; // One-time assignments // Sort stability support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; // Support: Chrome 14-35+ // Always assume duplicates if they aren't passed to the comparison function support.detectDuplicates = !!hasDuplicate; // Initialize against the default document setDocument(); // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) // Detached nodes confoundingly follow *each other* support.sortDetached = assert(function( el ) { // Should return 1, but returns 4 (following) return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; }); // Support: IE<8 // Prevent attribute/property "interpolation" // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx if ( !assert(function( el ) { el.innerHTML = "<a href='#'></a>"; return el.firstChild.getAttribute("href") === "#" ; }) ) { addHandle( "type|href|height|width", function( elem, name, isXML ) { if ( !isXML ) { return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); } }); } // Support: IE<9 // Use defaultValue in place of getAttribute("value") if ( !support.attributes || !assert(function( el ) { el.innerHTML = "<input/>"; el.firstChild.setAttribute( "value", "" ); return el.firstChild.getAttribute( "value" ) === ""; }) ) { addHandle( "value", function( elem, name, isXML ) { if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { return elem.defaultValue; } }); } // Support: IE<9 // Use getAttributeNode to fetch booleans when getAttribute lies if ( !assert(function( el ) { return el.getAttribute("disabled") == null; }) ) { addHandle( booleans, function( elem, name, isXML ) { var val; if ( !isXML ) { return elem[ name ] === true ? name.toLowerCase() : (val = elem.getAttributeNode( name )) && val.specified ? val.value : null; } }); } return Sizzle; })( window ); jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; // Deprecated jQuery.expr[ ":" ] = jQuery.expr.pseudos; jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; jQuery.escapeSelector = Sizzle.escape; var dir = function( elem, dir, until ) { var matched = [], truncate = until !== undefined; while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { if ( elem.nodeType === 1 ) { if ( truncate && jQuery( elem ).is( until ) ) { break; } matched.push( elem ); } } return matched; }; var siblings = function( n, elem ) { var matched = []; for ( ; n; n = n.nextSibling ) { if ( n.nodeType === 1 && n !== elem ) { matched.push( n ); } } return matched; }; var rneedsContext = jQuery.expr.match.needsContext; function nodeName( elem, name ) { return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); }; var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); // Implement the identical functionality for filter and not function winnow( elements, qualifier, not ) { if ( isFunction( qualifier ) ) { return jQuery.grep( elements, function( elem, i ) { return !!qualifier.call( elem, i, elem ) !== not; } ); } // Single element if ( qualifier.nodeType ) { return jQuery.grep( elements, function( elem ) { return ( elem === qualifier ) !== not; } ); } // Arraylike of elements (jQuery, arguments, Array) if ( typeof qualifier !== "string" ) { return jQuery.grep( elements, function( elem ) { return ( indexOf.call( qualifier, elem ) > -1 ) !== not; } ); } // Filtered directly for both simple and complex selectors return jQuery.filter( qualifier, elements, not ); } jQuery.filter = function( expr, elems, not ) { var elem = elems[ 0 ]; if ( not ) { expr = ":not(" + expr + ")"; } if ( elems.length === 1 && elem.nodeType === 1 ) { return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; } return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { return elem.nodeType === 1; } ) ); }; jQuery.fn.extend( { find: function( selector ) { var i, ret, len = this.length, self = this; if ( typeof selector !== "string" ) { return this.pushStack( jQuery( selector ).filter( function() { for ( i = 0; i < len; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } } } ) ); } ret = this.pushStack( [] ); for ( i = 0; i < len; i++ ) { jQuery.find( selector, self[ i ], ret ); } return len > 1 ? jQuery.uniqueSort( ret ) : ret; }, filter: function( selector ) { return this.pushStack( winnow( this, selector || [], false ) ); }, not: function( selector ) { return this.pushStack( winnow( this, selector || [], true ) ); }, is: function( selector ) { return !!winnow( this, // If this is a positional/relative selector, check membership in the returned set // so $("p:first").is("p:last") won't return true for a doc with two "p". typeof selector === "string" && rneedsContext.test( selector ) ? jQuery( selector ) : selector || [], false ).length; } } ); // Initialize a jQuery object // A central reference to the root jQuery(document) var rootjQuery, // A simple way to check for HTML strings // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) // Strict HTML recognition (#11290: must start with <) // Shortcut simple #id case for speed rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, init = jQuery.fn.init = function( selector, context, root ) { var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { return this; } // Method init() accepts an alternate rootjQuery // so migrate can support jQuery.sub (gh-2101) root = root || rootjQuery; // Handle HTML strings if ( typeof selector === "string" ) { if ( selector[ 0 ] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ]; } else { match = rquickExpr.exec( selector ); } // Match html or make sure no context is specified for #id if ( match && ( match[ 1 ] || !context ) ) { // HANDLE: $(html) -> $(array) if ( match[ 1 ] ) { context = context instanceof jQuery ? context[ 0 ] : context; // Option to run scripts is true for back-compat // Intentionally let the error be thrown if parseHTML is not present jQuery.merge( this, jQuery.parseHTML( match[ 1 ], context && context.nodeType ? context.ownerDocument || context : document, true ) ); // HANDLE: $(html, props) if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { for ( match in context ) { // Properties of context are called as methods if possible if ( isFunction( this[ match ] ) ) { this[ match ]( context[ match ] ); // ...and otherwise set as attributes } else { this.attr( match, context[ match ] ); } } } return this; // HANDLE: $(#id) } else { elem = document.getElementById( match[ 2 ] ); if ( elem ) { // Inject the element directly into the jQuery object this[ 0 ] = elem; this.length = 1; } return this; } // HANDLE: $(expr, $(...)) } else if ( !context || context.jquery ) { return ( context || root ).find( selector ); // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { return this.constructor( context ).find( selector ); } // HANDLE: $(DOMElement) } else if ( selector.nodeType ) { this[ 0 ] = selector; this.length = 1; return this; // HANDLE: $(function) // Shortcut for document ready } else if ( isFunction( selector ) ) { return root.ready !== undefined ? root.ready( selector ) : // Execute immediately if ready is not present selector( jQuery ); } return jQuery.makeArray( selector, this ); }; // Give the init function the jQuery prototype for later instantiation init.prototype = jQuery.fn; // Initialize central reference rootjQuery = jQuery( document ); var rparentsprev = /^(?:parents|prev(?:Until|All))/, // Methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, contents: true, next: true, prev: true }; jQuery.fn.extend( { has: function( target ) { var targets = jQuery( target, this ), l = targets.length; return this.filter( function() { var i = 0; for ( ; i < l; i++ ) { if ( jQuery.contains( this, targets[ i ] ) ) { return true; } } } ); }, closest: function( selectors, context ) { var cur, i = 0, l = this.length, matched = [], targets = typeof selectors !== "string" && jQuery( selectors ); // Positional selectors never match, since there's no _selection_ context if ( !rneedsContext.test( selectors ) ) { for ( ; i < l; i++ ) { for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { // Always skip document fragments if ( cur.nodeType < 11 && ( targets ? targets.index( cur ) > -1 : // Don't pass non-elements to Sizzle cur.nodeType === 1 && jQuery.find.matchesSelector( cur, selectors ) ) ) { matched.push( cur ); break; } } } } return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); }, // Determine the position of an element within the set index: function( elem ) { // No argument, return index in parent if ( !elem ) { return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; } // Index in selector if ( typeof elem === "string" ) { return indexOf.call( jQuery( elem ), this[ 0 ] ); } // Locate the position of the desired element return indexOf.call( this, // If it receives a jQuery object, the first element is used elem.jquery ? elem[ 0 ] : elem ); }, add: function( selector, context ) { return this.pushStack( jQuery.uniqueSort( jQuery.merge( this.get(), jQuery( selector, context ) ) ) ); }, addBack: function( selector ) { return this.add( selector == null ? this.prevObject : this.prevObject.filter( selector ) ); } } ); function sibling( cur, dir ) { while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} return cur; } jQuery.each( { parent: function( elem ) { var parent = elem.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, parents: function( elem ) { return dir( elem, "parentNode" ); }, parentsUntil: function( elem, i, until ) { return dir( elem, "parentNode", until ); }, next: function( elem ) { return sibling( elem, "nextSibling" ); }, prev: function( elem ) { return sibling( elem, "previousSibling" ); }, nextAll: function( elem ) { return dir( elem, "nextSibling" ); }, prevAll: function( elem ) { return dir( elem, "previousSibling" ); }, nextUntil: function( elem, i, until ) { return dir( elem, "nextSibling", until ); }, prevUntil: function( elem, i, until ) { return dir( elem, "previousSibling", until ); }, siblings: function( elem ) { return siblings( ( elem.parentNode || {} ).firstChild, elem ); }, children: function( elem ) { return siblings( elem.firstChild ); }, contents: function( elem ) { if ( nodeName( elem, "iframe" ) ) { return elem.contentDocument; } // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only // Treat the template element as a regular one in browsers that // don't support it. if ( nodeName( elem, "template" ) ) { elem = elem.content || elem; } return jQuery.merge( [], elem.childNodes ); } }, function( name, fn ) { jQuery.fn[ name ] = function( until, selector ) { var matched = jQuery.map( this, fn, until ); if ( name.slice( -5 ) !== "Until" ) { selector = until; } if ( selector && typeof selector === "string" ) { matched = jQuery.filter( selector, matched ); } if ( this.length > 1 ) { // Remove duplicates if ( !guaranteedUnique[ name ] ) { jQuery.uniqueSort( matched ); } // Reverse order for parents* and prev-derivatives if ( rparentsprev.test( name ) ) { matched.reverse(); } } return this.pushStack( matched ); }; } ); var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); // Convert String-formatted options into Object-formatted ones function createOptions( options ) { var object = {}; jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { object[ flag ] = true; } ); return object; } /* * Create a callback list using the following parameters: * * options: an optional list of space-separated options that will change how * the callback list behaves or a more traditional option object * * By default a callback list will act like an event callback list and can be * "fired" multiple times. * * Possible options: * * once: will ensure the callback list can only be fired once (like a Deferred) * * memory: will keep track of previous values and will call any callback added * after the list has been fired right away with the latest "memorized" * values (like a Deferred) * * unique: will ensure a callback can only be added once (no duplicate in the list) * * stopOnFalse: interrupt callings when a callback returns false * */ jQuery.Callbacks = function( options ) { // Convert options from String-formatted to Object-formatted if needed // (we check in cache first) options = typeof options === "string" ? createOptions( options ) : jQuery.extend( {}, options ); var // Flag to know if list is currently firing firing, // Last fire value for non-forgettable lists memory, // Flag to know if list was already fired fired, // Flag to prevent firing locked, // Actual callback list list = [], // Queue of execution data for repeatable lists queue = [], // Index of currently firing callback (modified by add/remove as needed) firingIndex = -1, // Fire callbacks fire = function() { // Enforce single-firing locked = locked || options.once; // Execute callbacks for all pending executions, // respecting firingIndex overrides and runtime changes fired = firing = true; for ( ; queue.length; firingIndex = -1 ) { memory = queue.shift(); while ( ++firingIndex < list.length ) { // Run callback and check for early termination if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && options.stopOnFalse ) { // Jump to end and forget the data so .add doesn't re-fire firingIndex = list.length; memory = false; } } } // Forget the data if we're done with it if ( !options.memory ) { memory = false; } firing = false; // Clean up if we're done firing for good if ( locked ) { // Keep an empty list if we have data for future add calls if ( memory ) { list = []; // Otherwise, this object is spent } else { list = ""; } } }, // Actual Callbacks object self = { // Add a callback or a collection of callbacks to the list add: function() { if ( list ) { // If we have memory from a past run, we should fire after adding if ( memory && !firing ) { firingIndex = list.length - 1; queue.push( memory ); } ( function add( args ) { jQuery.each( args, function( _, arg ) { if ( isFunction( arg ) ) { if ( !options.unique || !self.has( arg ) ) { list.push( arg ); } } else if ( arg && arg.length && toType( arg ) !== "string" ) { // Inspect recursively add( arg ); } } ); } )( arguments ); if ( memory && !firing ) { fire(); } } return this; }, // Remove a callback from the list remove: function() { jQuery.each( arguments, function( _, arg ) { var index; while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { list.splice( index, 1 ); // Handle firing indexes if ( index <= firingIndex ) { firingIndex--; } } } ); return this; }, // Check if a given callback is in the list. // If no argument is given, return whether or not list has callbacks attached. has: function( fn ) { return fn ? jQuery.inArray( fn, list ) > -1 : list.length > 0; }, // Remove all callbacks from the list empty: function() { if ( list ) { list = []; } return this; }, // Disable .fire and .add // Abort any current/pending executions // Clear all callbacks and values disable: function() { locked = queue = []; list = memory = ""; return this; }, disabled: function() { return !list; }, // Disable .fire // Also disable .add unless we have memory (since it would have no effect) // Abort any pending executions lock: function() { locked = queue = []; if ( !memory && !firing ) { list = memory = ""; } return this; }, locked: function() { return !!locked; }, // Call all callbacks with the given context and arguments fireWith: function( context, args ) { if ( !locked ) { args = args || []; args = [ context, args.slice ? args.slice() : args ]; queue.push( args ); if ( !firing ) { fire(); } } return this; }, // Call all the callbacks with the given arguments fire: function() { self.fireWith( this, arguments ); return this; }, // To know if the callbacks have already been called at least once fired: function() { return !!fired; } }; return self; }; function Identity( v ) { return v; } function Thrower( ex ) { throw ex; } function adoptValue( value, resolve, reject, noValue ) { var method; try { // Check for promise aspect first to privilege synchronous behavior if ( value && isFunction( ( method = value.promise ) ) ) { method.call( value ).done( resolve ).fail( reject ); // Other thenables } else if ( value && isFunction( ( method = value.then ) ) ) { method.call( value, resolve, reject ); // Other non-thenables } else { // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: // * false: [ value ].slice( 0 ) => resolve( value ) // * true: [ value ].slice( 1 ) => resolve() resolve.apply( undefined, [ value ].slice( noValue ) ); } // For Promises/A+, convert exceptions into rejections // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in // Deferred#then to conditionally suppress rejection. } catch ( value ) { // Support: Android 4.0 only // Strict mode functions invoked without .call/.apply get global-object context reject.apply( undefined, [ value ] ); } } jQuery.extend( { Deferred: function( func ) { var tuples = [ // action, add listener, callbacks, // ... .then handlers, argument index, [final state] [ "notify", "progress", jQuery.Callbacks( "memory" ), jQuery.Callbacks( "memory" ), 2 ], [ "resolve", "done", jQuery.Callbacks( "once memory" ), jQuery.Callbacks( "once memory" ), 0, "resolved" ], [ "reject", "fail", jQuery.Callbacks( "once memory" ), jQuery.Callbacks( "once memory" ), 1, "rejected" ] ], state = "pending", promise = { state: function() { return state; }, always: function() { deferred.done( arguments ).fail( arguments ); return this; }, "catch": function( fn ) { return promise.then( null, fn ); }, // Keep pipe for back-compat pipe: function( /* fnDone, fnFail, fnProgress */ ) { var fns = arguments; return jQuery.Deferred( function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { // Map tuples (progress, done, fail) to arguments (done, fail, progress) var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; // deferred.progress(function() { bind to newDefer or newDefer.notify }) // deferred.done(function() { bind to newDefer or newDefer.resolve }) // deferred.fail(function() { bind to newDefer or newDefer.reject }) deferred[ tuple[ 1 ] ]( function() { var returned = fn && fn.apply( this, arguments ); if ( returned && isFunction( returned.promise ) ) { returned.promise() .progress( newDefer.notify ) .done( newDefer.resolve ) .fail( newDefer.reject ); } else { newDefer[ tuple[ 0 ] + "With" ]( this, fn ? [ returned ] : arguments ); } } ); } ); fns = null; } ).promise(); }, then: function( onFulfilled, onRejected, onProgress ) { var maxDepth = 0; function resolve( depth, deferred, handler, special ) { return function() { var that = this, args = arguments, mightThrow = function() { var returned, then; // Support: Promises/A+ section 2.3.3.3.3 // https://promisesaplus.com/#point-59 // Ignore double-resolution attempts if ( depth < maxDepth ) { return; } returned = handler.apply( that, args ); // Support: Promises/A+ section 2.3.1 // https://promisesaplus.com/#point-48 if ( returned === deferred.promise() ) { throw new TypeError( "Thenable self-resolution" ); } // Support: Promises/A+ sections 2.3.3.1, 3.5 // https://promisesaplus.com/#point-54 // https://promisesaplus.com/#point-75 // Retrieve `then` only once then = returned && // Support: Promises/A+ section 2.3.4 // https://promisesaplus.com/#point-64 // Only check objects and functions for thenability ( typeof returned === "object" || typeof returned === "function" ) && returned.then; // Handle a returned thenable if ( isFunction( then ) ) { // Special processors (notify) just wait for resolution if ( special ) { then.call( returned, resolve( maxDepth, deferred, Identity, special ), resolve( maxDepth, deferred, Thrower, special ) ); // Normal processors (resolve) also hook into progress } else { // ...and disregard older resolution values maxDepth++; then.call( returned, resolve( maxDepth, deferred, Identity, special ), resolve( maxDepth, deferred, Thrower, special ), resolve( maxDepth, deferred, Identity, deferred.notifyWith ) ); } // Handle all other returned values } else { // Only substitute handlers pass on context // and multiple values (non-spec behavior) if ( handler !== Identity ) { that = undefined; args = [ returned ]; } // Process the value(s) // Default process is resolve ( special || deferred.resolveWith )( that, args ); } }, // Only normal processors (resolve) catch and reject exceptions process = special ? mightThrow : function() { try { mightThrow(); } catch ( e ) { if ( jQuery.Deferred.exceptionHook ) { jQuery.Deferred.exceptionHook( e, process.stackTrace ); } // Support: Promises/A+ section 2.3.3.3.4.1 // https://promisesaplus.com/#point-61 // Ignore post-resolution exceptions if ( depth + 1 >= maxDepth ) { // Only substitute handlers pass on context // and multiple values (non-spec behavior) if ( handler !== Thrower ) { that = undefined; args = [ e ]; } deferred.rejectWith( that, args ); } } }; // Support: Promises/A+ section 2.3.3.3.1 // https://promisesaplus.com/#point-57 // Re-resolve promises immediately to dodge false rejection from // subsequent errors if ( depth ) { process(); } else { // Call an optional hook to record the stack, in case of exception // since it's otherwise lost when execution goes async if ( jQuery.Deferred.getStackHook ) { process.stackTrace = jQuery.Deferred.getStackHook(); } window.setTimeout( process ); } }; } return jQuery.Deferred( function( newDefer ) { // progress_handlers.add( ... ) tuples[ 0 ][ 3 ].add( resolve( 0, newDefer, isFunction( onProgress ) ? onProgress : Identity, newDefer.notifyWith ) ); // fulfilled_handlers.add( ... ) tuples[ 1 ][ 3 ].add( resolve( 0, newDefer, isFunction( onFulfilled ) ? onFulfilled : Identity ) ); // rejected_handlers.add( ... ) tuples[ 2 ][ 3 ].add( resolve( 0, newDefer, isFunction( onRejected ) ? onRejected : Thrower ) ); } ).promise(); }, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function( obj ) { return obj != null ? jQuery.extend( obj, promise ) : promise; } }, deferred = {}; // Add list-specific methods jQuery.each( tuples, function( i, tuple ) { var list = tuple[ 2 ], stateString = tuple[ 5 ]; // promise.progress = list.add // promise.done = list.add // promise.fail = list.add promise[ tuple[ 1 ] ] = list.add; // Handle state if ( stateString ) { list.add( function() { // state = "resolved" (i.e., fulfilled) // state = "rejected" state = stateString; }, // rejected_callbacks.disable // fulfilled_callbacks.disable tuples[ 3 - i ][ 2 ].disable, // rejected_handlers.disable // fulfilled_handlers.disable tuples[ 3 - i ][ 3 ].disable, // progress_callbacks.lock tuples[ 0 ][ 2 ].lock, // progress_handlers.lock tuples[ 0 ][ 3 ].lock ); } // progress_handlers.fire // fulfilled_handlers.fire // rejected_handlers.fire list.add( tuple[ 3 ].fire ); // deferred.notify = function() { deferred.notifyWith(...) } // deferred.resolve = function() { deferred.resolveWith(...) } // deferred.reject = function() { deferred.rejectWith(...) } deferred[ tuple[ 0 ] ] = function() { deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); return this; }; // deferred.notifyWith = list.fireWith // deferred.resolveWith = list.fireWith // deferred.rejectWith = list.fireWith deferred[ tuple[ 0 ] + "With" ] = list.fireWith; } ); // Make the deferred a promise promise.promise( deferred ); // Call given func if any if ( func ) { func.call( deferred, deferred ); } // All done! return deferred; }, // Deferred helper when: function( singleValue ) { var // count of uncompleted subordinates remaining = arguments.length, // count of unprocessed arguments i = remaining, // subordinate fulfillment data resolveContexts = Array( i ), resolveValues = slice.call( arguments ), // the master Deferred master = jQuery.Deferred(), // subordinate callback factory updateFunc = function( i ) { return function( value ) { resolveContexts[ i ] = this; resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; if ( !( --remaining ) ) { master.resolveWith( resolveContexts, resolveValues ); } }; }; // Single- and empty arguments are adopted like Promise.resolve if ( remaining <= 1 ) { adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, !remaining ); // Use .then() to unwrap secondary thenables (cf. gh-3000) if ( master.state() === "pending" || isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { return master.then(); } } // Multiple arguments are aggregated like Promise.all array elements while ( i-- ) { adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); } return master.promise(); } } ); // These usually indicate a programmer mistake during development, // warn about them ASAP rather than swallowing them by default. var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; jQuery.Deferred.exceptionHook = function( error, stack ) { // Support: IE 8 - 9 only // Console exists when dev tools are open, which can happen at any time if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); } }; jQuery.readyException = function( error ) { window.setTimeout( function() { throw error; } ); }; // The deferred used on DOM ready var readyList = jQuery.Deferred(); jQuery.fn.ready = function( fn ) { readyList .then( fn ) // Wrap jQuery.readyException in a function so that the lookup // happens at the time of error handling instead of callback // registration. .catch( function( error ) { jQuery.readyException( error ); } ); return this; }; jQuery.extend( { // Is the DOM ready to be used? Set to true once it occurs. isReady: false, // A counter to track how many items to wait for before // the ready event fires. See #6781 readyWait: 1, // Handle when the DOM is ready ready: function( wait ) { // Abort if there are pending holds or we're already ready if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return; } // Remember that the DOM is ready jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be if ( wait !== true && --jQuery.readyWait > 0 ) { return; } // If there are functions bound, to execute readyList.resolveWith( document, [ jQuery ] ); } } ); jQuery.ready.then = readyList.then; // The ready event handler and self cleanup method function completed() { document.removeEventListener( "DOMContentLoaded", completed ); window.removeEventListener( "load", completed ); jQuery.ready(); } // Catch cases where $(document).ready() is called // after the browser event has already occurred. // Support: IE <=9 - 10 only // Older IE sometimes signals "interactive" too soon if ( document.readyState === "complete" || ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { // Handle it asynchronously to allow scripts the opportunity to delay ready window.setTimeout( jQuery.ready ); } else { // Use the handy event callback document.addEventListener( "DOMContentLoaded", completed ); // A fallback to window.onload, that will always work window.addEventListener( "load", completed ); } // Multifunctional method to get and set values of a collection // The value/s can optionally be executed if it's a function var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { var i = 0, len = elems.length, bulk = key == null; // Sets many values if ( toType( key ) === "object" ) { chainable = true; for ( i in key ) { access( elems, fn, i, key[ i ], true, emptyGet, raw ); } // Sets one value } else if ( value !== undefined ) { chainable = true; if ( !isFunction( value ) ) { raw = true; } if ( bulk ) { // Bulk operations run against the entire set if ( raw ) { fn.call( elems, value ); fn = null; // ...except when executing function values } else { bulk = fn; fn = function( elem, key, value ) { return bulk.call( jQuery( elem ), value ); }; } } if ( fn ) { for ( ; i < len; i++ ) { fn( elems[ i ], key, raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) ) ); } } } if ( chainable ) { return elems; } // Gets if ( bulk ) { return fn.call( elems ); } return len ? fn( elems[ 0 ], key ) : emptyGet; }; // Matches dashed string for camelizing var rmsPrefix = /^-ms-/, rdashAlpha = /-([a-z])/g; // Used by camelCase as callback to replace() function fcamelCase( all, letter ) { return letter.toUpperCase(); } // Convert dashed to camelCase; used by the css and data modules // Support: IE <=9 - 11, Edge 12 - 15 // Microsoft forgot to hump their vendor prefix (#9572) function camelCase( string ) { return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); } var acceptData = function( owner ) { // Accepts only: // - Node // - Node.ELEMENT_NODE // - Node.DOCUMENT_NODE // - Object // - Any return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); }; function Data() { this.expando = jQuery.expando + Data.uid++; } Data.uid = 1; Data.prototype = { cache: function( owner ) { // Check if the owner object already has a cache var value = owner[ this.expando ]; // If not, create one if ( !value ) { value = {}; // We can accept data for non-element nodes in modern browsers, // but we should not, see #8335. // Always return an empty object. if ( acceptData( owner ) ) { // If it is a node unlikely to be stringify-ed or looped over // use plain assignment if ( owner.nodeType ) { owner[ this.expando ] = value; // Otherwise secure it in a non-enumerable property // configurable must be true to allow the property to be // deleted when data is removed } else { Object.defineProperty( owner, this.expando, { value: value, configurable: true } ); } } } return value; }, set: function( owner, data, value ) { var prop, cache = this.cache( owner ); // Handle: [ owner, key, value ] args // Always use camelCase key (gh-2257) if ( typeof data === "string" ) { cache[ camelCase( data ) ] = value; // Handle: [ owner, { properties } ] args } else { // Copy the properties one-by-one to the cache object for ( prop in data ) { cache[ camelCase( prop ) ] = data[ prop ]; } } return cache; }, get: function( owner, key ) { return key === undefined ? this.cache( owner ) : // Always use camelCase key (gh-2257) owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; }, access: function( owner, key, value ) { // In cases where either: // // 1. No key was specified // 2. A string key was specified, but no value provided // // Take the "read" path and allow the get method to determine // which value to return, respectively either: // // 1. The entire cache object // 2. The data stored at the key // if ( key === undefined || ( ( key && typeof key === "string" ) && value === undefined ) ) { return this.get( owner, key ); } // When the key is not a string, or both a key and value // are specified, set or extend (existing objects) with either: // // 1. An object of properties // 2. A key and value // this.set( owner, key, value ); // Since the "set" path can have two possible entry points // return the expected data based on which path was taken[*] return value !== undefined ? value : key; }, remove: function( owner, key ) { var i, cache = owner[ this.expando ]; if ( cache === undefined ) { return; } if ( key !== undefined ) { // Support array or space separated string of keys if ( Array.isArray( key ) ) { // If key is an array of keys... // We always set camelCase keys, so remove that. key = key.map( camelCase ); } else { key = camelCase( key ); // If a key with the spaces exists, use it. // Otherwise, create an array by matching non-whitespace key = key in cache ? [ key ] : ( key.match( rnothtmlwhite ) || [] ); } i = key.length; while ( i-- ) { delete cache[ key[ i ] ]; } } // Remove the expando if there's no more data if ( key === undefined || jQuery.isEmptyObject( cache ) ) { // Support: Chrome <=35 - 45 // Webkit & Blink performance suffers when deleting properties // from DOM nodes, so set to undefined instead // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) if ( owner.nodeType ) { owner[ this.expando ] = undefined; } else { delete owner[ this.expando ]; } } }, hasData: function( owner ) { var cache = owner[ this.expando ]; return cache !== undefined && !jQuery.isEmptyObject( cache ); } }; var dataPriv = new Data(); var dataUser = new Data(); // Implementation Summary // // 1. Enforce API surface and semantic compatibility with 1.9.x branch // 2. Improve the module's maintainability by reducing the storage // paths to a single mechanism. // 3. Use the same single mechanism to support "private" and "user" data. // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) // 5. Avoid exposing implementation details on user objects (eg. expando properties) // 6. Provide a clear path for implementation upgrade to WeakMap in 2014 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, rmultiDash = /[A-Z]/g; function getData( data ) { if ( data === "true" ) { return true; } if ( data === "false" ) { return false; } if ( data === "null" ) { return null; } // Only convert to a number if it doesn't change the string if ( data === +data + "" ) { return +data; } if ( rbrace.test( data ) ) { return JSON.parse( data ); } return data; } function dataAttr( elem, key, data ) { var name; // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); data = elem.getAttribute( name ); if ( typeof data === "string" ) { try { data = getData( data ); } catch ( e ) {} // Make sure we set the data so it isn't changed later dataUser.set( elem, key, data ); } else { data = undefined; } } return data; } jQuery.extend( { hasData: function( elem ) { return dataUser.hasData( elem ) || dataPriv.hasData( elem ); }, data: function( elem, name, data ) { return dataUser.access( elem, name, data ); }, removeData: function( elem, name ) { dataUser.remove( elem, name ); }, // TODO: Now that all calls to _data and _removeData have been replaced // with direct calls to dataPriv methods, these can be deprecated. _data: function( elem, name, data ) { return dataPriv.access( elem, name, data ); }, _removeData: function( elem, name ) { dataPriv.remove( elem, name ); } } ); jQuery.fn.extend( { data: function( key, value ) { var i, name, data, elem = this[ 0 ], attrs = elem && elem.attributes; // Gets all values if ( key === undefined ) { if ( this.length ) { data = dataUser.get( elem ); if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { i = attrs.length; while ( i-- ) { // Support: IE 11 only // The attrs elements can be null (#14894) if ( attrs[ i ] ) { name = attrs[ i ].name; if ( name.indexOf( "data-" ) === 0 ) { name = camelCase( name.slice( 5 ) ); dataAttr( elem, name, data[ name ] ); } } } dataPriv.set( elem, "hasDataAttrs", true ); } } return data; } // Sets multiple values if ( typeof key === "object" ) { return this.each( function() { dataUser.set( this, key ); } ); } return access( this, function( value ) { var data; // The calling jQuery object (element matches) is not empty // (and therefore has an element appears at this[ 0 ]) and the // `value` parameter was not undefined. An empty jQuery object // will result in `undefined` for elem = this[ 0 ] which will // throw an exception if an attempt to read a data cache is made. if ( elem && value === undefined ) { // Attempt to get data from the cache // The key will always be camelCased in Data data = dataUser.get( elem, key ); if ( data !== undefined ) { return data; } // Attempt to "discover" the data in // HTML5 custom data-* attrs data = dataAttr( elem, key ); if ( data !== undefined ) { return data; } // We tried really hard, but the data doesn't exist. return; } // Set the data... this.each( function() { // We always store the camelCased key dataUser.set( this, key, value ); } ); }, null, value, arguments.length > 1, null, true ); }, removeData: function( key ) { return this.each( function() { dataUser.remove( this, key ); } ); } } ); jQuery.extend( { queue: function( elem, type, data ) { var queue; if ( elem ) { type = ( type || "fx" ) + "queue"; queue = dataPriv.get( elem, type ); // Speed up dequeue by getting out quickly if this is just a lookup if ( data ) { if ( !queue || Array.isArray( data ) ) { queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); } else { queue.push( data ); } } return queue || []; } }, dequeue: function( elem, type ) { type = type || "fx"; var queue = jQuery.queue( elem, type ), startLength = queue.length, fn = queue.shift(), hooks = jQuery._queueHooks( elem, type ), next = function() { jQuery.dequeue( elem, type ); }; // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { fn = queue.shift(); startLength--; } if ( fn ) { // Add a progress sentinel to prevent the fx queue from being // automatically dequeued if ( type === "fx" ) { queue.unshift( "inprogress" ); } // Clear up the last queue stop function delete hooks.stop; fn.call( elem, next, hooks ); } if ( !startLength && hooks ) { hooks.empty.fire(); } }, // Not public - generate a queueHooks object, or return the current one _queueHooks: function( elem, type ) { var key = type + "queueHooks"; return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { empty: jQuery.Callbacks( "once memory" ).add( function() { dataPriv.remove( elem, [ type + "queue", key ] ); } ) } ); } } ); jQuery.fn.extend( { queue: function( type, data ) { var setter = 2; if ( typeof type !== "string" ) { data = type; type = "fx"; setter--; } if ( arguments.length < setter ) { return jQuery.queue( this[ 0 ], type ); } return data === undefined ? this : this.each( function() { var queue = jQuery.queue( this, type, data ); // Ensure a hooks for this queue jQuery._queueHooks( this, type ); if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { jQuery.dequeue( this, type ); } } ); }, dequeue: function( type ) { return this.each( function() { jQuery.dequeue( this, type ); } ); }, clearQueue: function( type ) { return this.queue( type || "fx", [] ); }, // Get a promise resolved when queues of a certain type // are emptied (fx is the type by default) promise: function( type, obj ) { var tmp, count = 1, defer = jQuery.Deferred(), elements = this, i = this.length, resolve = function() { if ( !( --count ) ) { defer.resolveWith( elements, [ elements ] ); } }; if ( typeof type !== "string" ) { obj = type; type = undefined; } type = type || "fx"; while ( i-- ) { tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); if ( tmp && tmp.empty ) { count++; tmp.empty.add( resolve ); } } resolve(); return defer.promise( obj ); } } ); var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; var isHiddenWithinTree = function( elem, el ) { // isHiddenWithinTree might be called from jQuery#filter function; // in that case, element will be second argument elem = el || elem; // Inline style trumps all return elem.style.display === "none" || elem.style.display === "" && // Otherwise, check computed style // Support: Firefox <=43 - 45 // Disconnected elements can have computed display: none, so first confirm that elem is // in the document. jQuery.contains( elem.ownerDocument, elem ) && jQuery.css( elem, "display" ) === "none"; }; var swap = function( elem, options, callback, args ) { var ret, name, old = {}; // Remember the old values, and insert the new ones for ( name in options ) { old[ name ] = elem.style[ name ]; elem.style[ name ] = options[ name ]; } ret = callback.apply( elem, args || [] ); // Revert the old values for ( name in options ) { elem.style[ name ] = old[ name ]; } return ret; }; function adjustCSS( elem, prop, valueParts, tween ) { var adjusted, scale, maxIterations = 20, currentValue = tween ? function() { return tween.cur(); } : function() { return jQuery.css( elem, prop, "" ); }, initial = currentValue(), unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), // Starting value computation is required for potential unit mismatches initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && rcssNum.exec( jQuery.css( elem, prop ) ); if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { // Support: Firefox <=54 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) initial = initial / 2; // Trust units reported by jQuery.css unit = unit || initialInUnit[ 3 ]; // Iteratively approximate from a nonzero starting point initialInUnit = +initial || 1; while ( maxIterations-- ) { // Evaluate and update our best guess (doubling guesses that zero out). // Finish if the scale equals or crosses 1 (making the old*new product non-positive). jQuery.style( elem, prop, initialInUnit + unit ); if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { maxIterations = 0; } initialInUnit = initialInUnit / scale; } initialInUnit = initialInUnit * 2; jQuery.style( elem, prop, initialInUnit + unit ); // Make sure we update the tween properties later on valueParts = valueParts || []; } if ( valueParts ) { initialInUnit = +initialInUnit || +initial || 0; // Apply relative offset (+=/-=) if specified adjusted = valueParts[ 1 ] ? initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : +valueParts[ 2 ]; if ( tween ) { tween.unit = unit; tween.start = initialInUnit; tween.end = adjusted; } } return adjusted; } var defaultDisplayMap = {}; function getDefaultDisplay( elem ) { var temp, doc = elem.ownerDocument, nodeName = elem.nodeName, display = defaultDisplayMap[ nodeName ]; if ( display ) { return display; } temp = doc.body.appendChild( doc.createElement( nodeName ) ); display = jQuery.css( temp, "display" ); temp.parentNode.removeChild( temp ); if ( display === "none" ) { display = "block"; } defaultDisplayMap[ nodeName ] = display; return display; } function showHide( elements, show ) { var display, elem, values = [], index = 0, length = elements.length; // Determine new display value for elements that need to change for ( ; index < length; index++ ) { elem = elements[ index ]; if ( !elem.style ) { continue; } display = elem.style.display; if ( show ) { // Since we force visibility upon cascade-hidden elements, an immediate (and slow) // check is required in this first loop unless we have a nonempty display value (either // inline or about-to-be-restored) if ( display === "none" ) { values[ index ] = dataPriv.get( elem, "display" ) || null; if ( !values[ index ] ) { elem.style.display = ""; } } if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { values[ index ] = getDefaultDisplay( elem ); } } else { if ( display !== "none" ) { values[ index ] = "none"; // Remember what we're overwriting dataPriv.set( elem, "display", display ); } } } // Set the display of the elements in a second loop to avoid constant reflow for ( index = 0; index < length; index++ ) { if ( values[ index ] != null ) { elements[ index ].style.display = values[ index ]; } } return elements; } jQuery.fn.extend( { show: function() { return showHide( this, true ); }, hide: function() { return showHide( this ); }, toggle: function( state ) { if ( typeof state === "boolean" ) { return state ? this.show() : this.hide(); } return this.each( function() { if ( isHiddenWithinTree( this ) ) { jQuery( this ).show(); } else { jQuery( this ).hide(); } } ); } } ); var rcheckableType = ( /^(?:checkbox|radio)$/i ); var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i ); var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); // We have to close these tags to support XHTML (#13200) var wrapMap = { // Support: IE <=9 only option: [ 1, "<select multiple='multiple'>", "</select>" ], // XHTML parsers do not magically insert elements in the // same way that tag soup parsers do. So we cannot shorten // this by omitting <tbody> or other required elements. thead: [ 1, "<table>", "</table>" ], col: [ 2, "<table><colgroup>", "</colgroup></table>" ], tr: [ 2, "<table><tbody>", "</tbody></table>" ], td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], _default: [ 0, "", "" ] }; // Support: IE <=9 only wrapMap.optgroup = wrapMap.option; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; function getAll( context, tag ) { // Support: IE <=9 - 11 only // Use typeof to avoid zero-argument method invocation on host objects (#15151) var ret; if ( typeof context.getElementsByTagName !== "undefined" ) { ret = context.getElementsByTagName( tag || "*" ); } else if ( typeof context.querySelectorAll !== "undefined" ) { ret = context.querySelectorAll( tag || "*" ); } else { ret = []; } if ( tag === undefined || tag && nodeName( context, tag ) ) { return jQuery.merge( [ context ], ret ); } return ret; } // Mark scripts as having already been evaluated function setGlobalEval( elems, refElements ) { var i = 0, l = elems.length; for ( ; i < l; i++ ) { dataPriv.set( elems[ i ], "globalEval", !refElements || dataPriv.get( refElements[ i ], "globalEval" ) ); } } var rhtml = /<|&#?\w+;/; function buildFragment( elems, context, scripts, selection, ignored ) { var elem, tmp, tag, wrap, contains, j, fragment = context.createDocumentFragment(), nodes = [], i = 0, l = elems.length; for ( ; i < l; i++ ) { elem = elems[ i ]; if ( elem || elem === 0 ) { // Add nodes directly if ( toType( elem ) === "object" ) { // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); // Convert non-html into a text node } else if ( !rhtml.test( elem ) ) { nodes.push( context.createTextNode( elem ) ); // Convert html into DOM nodes } else { tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); // Deserialize a standard representation tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); wrap = wrapMap[ tag ] || wrapMap._default; tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; // Descend through wrappers to the right content j = wrap[ 0 ]; while ( j-- ) { tmp = tmp.lastChild; } // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( nodes, tmp.childNodes ); // Remember the top-level container tmp = fragment.firstChild; // Ensure the created nodes are orphaned (#12392) tmp.textContent = ""; } } } // Remove wrapper from fragment fragment.textContent = ""; i = 0; while ( ( elem = nodes[ i++ ] ) ) { // Skip elements already in the context collection (trac-4087) if ( selection && jQuery.inArray( elem, selection ) > -1 ) { if ( ignored ) { ignored.push( elem ); } continue; } contains = jQuery.contains( elem.ownerDocument, elem ); // Append to fragment tmp = getAll( fragment.appendChild( elem ), "script" ); // Preserve script evaluation history if ( contains ) { setGlobalEval( tmp ); } // Capture executables if ( scripts ) { j = 0; while ( ( elem = tmp[ j++ ] ) ) { if ( rscriptType.test( elem.type || "" ) ) { scripts.push( elem ); } } } } return fragment; } ( function() { var fragment = document.createDocumentFragment(), div = fragment.appendChild( document.createElement( "div" ) ), input = document.createElement( "input" ); // Support: Android 4.0 - 4.3 only // Check state lost if the name is set (#11217) // Support: Windows Web Apps (WWA) // `name` and `type` must use .setAttribute for WWA (#14901) input.setAttribute( "type", "radio" ); input.setAttribute( "checked", "checked" ); input.setAttribute( "name", "t" ); div.appendChild( input ); // Support: Android <=4.1 only // Older WebKit doesn't clone checked state correctly in fragments support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; // Support: IE <=11 only // Make sure textarea (and checkbox) defaultValue is properly cloned div.innerHTML = "<textarea>x</textarea>"; support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; } )(); var documentElement = document.documentElement; var rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, rtypenamespace = /^([^.]*)(?:\.(.+)|)/; function returnTrue() { return true; } function returnFalse() { return false; } // Support: IE <=9 only // See #13393 for more info function safeActiveElement() { try { return document.activeElement; } catch ( err ) { } } function on( elem, types, selector, data, fn, one ) { var origFn, type; // Types can be a map of types/handlers if ( typeof types === "object" ) { // ( types-Object, selector, data ) if ( typeof selector !== "string" ) { // ( types-Object, data ) data = data || selector; selector = undefined; } for ( type in types ) { on( elem, type, selector, data, types[ type ], one ); } return elem; } if ( data == null && fn == null ) { // ( types, fn ) fn = selector; data = selector = undefined; } else if ( fn == null ) { if ( typeof selector === "string" ) { // ( types, selector, fn ) fn = data; data = undefined; } else { // ( types, data, fn ) fn = data; data = selector; selector = undefined; } } if ( fn === false ) { fn = returnFalse; } else if ( !fn ) { return elem; } if ( one === 1 ) { origFn = fn; fn = function( event ) { // Can use an empty set, since event contains the info jQuery().off( event ); return origFn.apply( this, arguments ); }; // Use same guid so caller can remove using origFn fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); } return elem.each( function() { jQuery.event.add( this, types, fn, data, selector ); } ); } /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. */ jQuery.event = { global: {}, add: function( elem, types, handler, data, selector ) { var handleObjIn, eventHandle, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.get( elem ); // Don't attach events to noData or text/comment nodes (but allow plain objects) if ( !elemData ) { return; } // Caller can pass in an object of custom data in lieu of the handler if ( handler.handler ) { handleObjIn = handler; handler = handleObjIn.handler; selector = handleObjIn.selector; } // Ensure that invalid selectors throw exceptions at attach time // Evaluate against documentElement in case elem is a non-element node (e.g., document) if ( selector ) { jQuery.find.matchesSelector( documentElement, selector ); } // Make sure that the handler has a unique ID, used to find/remove it later if ( !handler.guid ) { handler.guid = jQuery.guid++; } // Init the element's event structure and main handler, if this is the first if ( !( events = elemData.events ) ) { events = elemData.events = {}; } if ( !( eventHandle = elemData.handle ) ) { eventHandle = elemData.handle = function( e ) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply( elem, arguments ) : undefined; }; } // Handle multiple events separated by a space types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[ t ] ) || []; type = origType = tmp[ 1 ]; namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); // There *must* be a type, no attaching namespace-only handlers if ( !type ) { continue; } // If event changes its type, use the special event handlers for the changed type special = jQuery.event.special[ type ] || {}; // If selector defined, determine special event api type, otherwise given type type = ( selector ? special.delegateType : special.bindType ) || type; // Update special based on newly reset type special = jQuery.event.special[ type ] || {}; // handleObj is passed to all event handlers handleObj = jQuery.extend( { type: type, origType: origType, data: data, handler: handler, guid: handler.guid, selector: selector, needsContext: selector && jQuery.expr.match.needsContext.test( selector ), namespace: namespaces.join( "." ) }, handleObjIn ); // Init the event handler queue if we're the first if ( !( handlers = events[ type ] ) ) { handlers = events[ type ] = []; handlers.delegateCount = 0; // Only use addEventListener if the special events handler returns false if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { if ( elem.addEventListener ) { elem.addEventListener( type, eventHandle ); } } } if ( special.add ) { special.add.call( elem, handleObj ); if ( !handleObj.handler.guid ) { handleObj.handler.guid = handler.guid; } } // Add to the element's handler list, delegates in front if ( selector ) { handlers.splice( handlers.delegateCount++, 0, handleObj ); } else { handlers.push( handleObj ); } // Keep track of which events have ever been used, for event optimization jQuery.event.global[ type ] = true; } }, // Detach an event or set of events from an element remove: function( elem, types, handler, selector, mappedTypes ) { var j, origCount, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); if ( !elemData || !( events = elemData.events ) ) { return; } // Once for each type.namespace in types; type may be omitted types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[ t ] ) || []; type = origType = tmp[ 1 ]; namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); // Unbind all events (on this namespace, if provided) for the element if ( !type ) { for ( type in events ) { jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); } continue; } special = jQuery.event.special[ type ] || {}; type = ( selector ? special.delegateType : special.bindType ) || type; handlers = events[ type ] || []; tmp = tmp[ 2 ] && new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); // Remove matching events origCount = j = handlers.length; while ( j-- ) { handleObj = handlers[ j ]; if ( ( mappedTypes || origType === handleObj.origType ) && ( !handler || handler.guid === handleObj.guid ) && ( !tmp || tmp.test( handleObj.namespace ) ) && ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { handlers.splice( j, 1 ); if ( handleObj.selector ) { handlers.delegateCount--; } if ( special.remove ) { special.remove.call( elem, handleObj ); } } } // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) if ( origCount && !handlers.length ) { if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { jQuery.removeEvent( elem, type, elemData.handle ); } delete events[ type ]; } } // Remove data and the expando if it's no longer used if ( jQuery.isEmptyObject( events ) ) { dataPriv.remove( elem, "handle events" ); } }, dispatch: function( nativeEvent ) { // Make a writable jQuery.Event from the native event object var event = jQuery.event.fix( nativeEvent ); var i, j, ret, matched, handleObj, handlerQueue, args = new Array( arguments.length ), handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], special = jQuery.event.special[ event.type ] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event args[ 0 ] = event; for ( i = 1; i < arguments.length; i++ ) { args[ i ] = arguments[ i ]; } event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { return; } // Determine handlers handlerQueue = jQuery.event.handlers.call( this, event, handlers ); // Run delegates first; they may want to stop propagation beneath us i = 0; while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { event.currentTarget = matched.elem; j = 0; while ( ( handleObj = matched.handlers[ j++ ] ) && !event.isImmediatePropagationStopped() ) { // Triggered event must either 1) have no namespace, or 2) have namespace(s) // a subset or equal to those in the bound event (both can have no namespace). if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { event.handleObj = handleObj; event.data = handleObj.data; ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || handleObj.handler ).apply( matched.elem, args ); if ( ret !== undefined ) { if ( ( event.result = ret ) === false ) { event.preventDefault(); event.stopPropagation(); } } } } } // Call the postDispatch hook for the mapped type if ( special.postDispatch ) { special.postDispatch.call( this, event ); } return event.result; }, handlers: function( event, handlers ) { var i, handleObj, sel, matchedHandlers, matchedSelectors, handlerQueue = [], delegateCount = handlers.delegateCount, cur = event.target; // Find delegate handlers if ( delegateCount && // Support: IE <=9 // Black-hole SVG <use> instance trees (trac-13180) cur.nodeType && // Support: Firefox <=42 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click // Support: IE 11 only // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) !( event.type === "click" && event.button >= 1 ) ) { for ( ; cur !== this; cur = cur.parentNode || this ) { // Don't check non-elements (#13208) // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { matchedHandlers = []; matchedSelectors = {}; for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; // Don't conflict with Object.prototype properties (#13203) sel = handleObj.selector + " "; if ( matchedSelectors[ sel ] === undefined ) { matchedSelectors[ sel ] = handleObj.needsContext ? jQuery( sel, this ).index( cur ) > -1 : jQuery.find( sel, this, null, [ cur ] ).length; } if ( matchedSelectors[ sel ] ) { matchedHandlers.push( handleObj ); } } if ( matchedHandlers.length ) { handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); } } } } // Add the remaining (directly-bound) handlers cur = this; if ( delegateCount < handlers.length ) { handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); } return handlerQueue; }, addProp: function( name, hook ) { Object.defineProperty( jQuery.Event.prototype, name, { enumerable: true, configurable: true, get: isFunction( hook ) ? function() { if ( this.originalEvent ) { return hook( this.originalEvent ); } } : function() { if ( this.originalEvent ) { return this.originalEvent[ name ]; } }, set: function( value ) { Object.defineProperty( this, name, { enumerable: true, configurable: true, writable: true, value: value } ); } } ); }, fix: function( originalEvent ) { return originalEvent[ jQuery.expando ] ? originalEvent : new jQuery.Event( originalEvent ); }, special: { load: { // Prevent triggered image.load events from bubbling to window.load noBubble: true }, focus: { // Fire native event if possible so blur/focus sequence is correct trigger: function() { if ( this !== safeActiveElement() && this.focus ) { this.focus(); return false; } }, delegateType: "focusin" }, blur: { trigger: function() { if ( this === safeActiveElement() && this.blur ) { this.blur(); return false; } }, delegateType: "focusout" }, click: { // For checkbox, fire native event so checked state will be right trigger: function() { if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) { this.click(); return false; } }, // For cross-browser consistency, don't fire native .click() on links _default: function( event ) { return nodeName( event.target, "a" ); } }, beforeunload: { postDispatch: function( event ) { // Support: Firefox 20+ // Firefox doesn't alert if the returnValue field is not set. if ( event.result !== undefined && event.originalEvent ) { event.originalEvent.returnValue = event.result; } } } } }; jQuery.removeEvent = function( elem, type, handle ) { // This "if" is needed for plain objects if ( elem.removeEventListener ) { elem.removeEventListener( type, handle ); } }; jQuery.Event = function( src, props ) { // Allow instantiation without the 'new' keyword if ( !( this instanceof jQuery.Event ) ) { return new jQuery.Event( src, props ); } // Event object if ( src && src.type ) { this.originalEvent = src; this.type = src.type; // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && // Support: Android <=2.3 only src.returnValue === false ? returnTrue : returnFalse; // Create target properties // Support: Safari <=6 - 7 only // Target should not be a text node (#504, #13143) this.target = ( src.target && src.target.nodeType === 3 ) ? src.target.parentNode : src.target; this.currentTarget = src.currentTarget; this.relatedTarget = src.relatedTarget; // Event type } else { this.type = src; } // Put explicitly provided properties onto the event object if ( props ) { jQuery.extend( this, props ); } // Create a timestamp if incoming event doesn't have one this.timeStamp = src && src.timeStamp || Date.now(); // Mark it as fixed this[ jQuery.expando ] = true; }; // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { constructor: jQuery.Event, isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse, isSimulated: false, preventDefault: function() { var e = this.originalEvent; this.isDefaultPrevented = returnTrue; if ( e && !this.isSimulated ) { e.preventDefault(); } }, stopPropagation: function() { var e = this.originalEvent; this.isPropagationStopped = returnTrue; if ( e && !this.isSimulated ) { e.stopPropagation(); } }, stopImmediatePropagation: function() { var e = this.originalEvent; this.isImmediatePropagationStopped = returnTrue; if ( e && !this.isSimulated ) { e.stopImmediatePropagation(); } this.stopPropagation(); } }; // Includes all common event props including KeyEvent and MouseEvent specific props jQuery.each( { altKey: true, bubbles: true, cancelable: true, changedTouches: true, ctrlKey: true, detail: true, eventPhase: true, metaKey: true, pageX: true, pageY: true, shiftKey: true, view: true, "char": true, charCode: true, key: true, keyCode: true, button: true, buttons: true, clientX: true, clientY: true, offsetX: true, offsetY: true, pointerId: true, pointerType: true, screenX: true, screenY: true, targetTouches: true, toElement: true, touches: true, which: function( event ) { var button = event.button; // Add which for key events if ( event.which == null && rkeyEvent.test( event.type ) ) { return event.charCode != null ? event.charCode : event.keyCode; } // Add which for click: 1 === left; 2 === middle; 3 === right if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { if ( button & 1 ) { return 1; } if ( button & 2 ) { return 3; } if ( button & 4 ) { return 2; } return 0; } return event.which; } }, jQuery.event.addProp ); // Create mouseenter/leave events using mouseover/out and event-time checks // so that event delegation works in jQuery. // Do the same for pointerenter/pointerleave and pointerover/pointerout // // Support: Safari 7 only // Safari sends mouseenter too often; see: // https://bugs.chromium.org/p/chromium/issues/detail?id=470258 // for the description of the bug (it existed in older Chrome versions as well). jQuery.each( { mouseenter: "mouseover", mouseleave: "mouseout", pointerenter: "pointerover", pointerleave: "pointerout" }, function( orig, fix ) { jQuery.event.special[ orig ] = { delegateType: fix, bindType: fix, handle: function( event ) { var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj; // For mouseenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { event.type = handleObj.origType; ret = handleObj.handler.apply( this, arguments ); event.type = fix; } return ret; } }; } ); jQuery.fn.extend( { on: function( types, selector, data, fn ) { return on( this, types, selector, data, fn ); }, one: function( types, selector, data, fn ) { return on( this, types, selector, data, fn, 1 ); }, off: function( types, selector, fn ) { var handleObj, type; if ( types && types.preventDefault && types.handleObj ) { // ( event ) dispatched jQuery.Event handleObj = types.handleObj; jQuery( types.delegateTarget ).off( handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler ); return this; } if ( typeof types === "object" ) { // ( types-object [, selector] ) for ( type in types ) { this.off( type, selector, types[ type ] ); } return this; } if ( selector === false || typeof selector === "function" ) { // ( types [, fn] ) fn = selector; selector = undefined; } if ( fn === false ) { fn = returnFalse; } return this.each( function() { jQuery.event.remove( this, types, fn, selector ); } ); } } ); var /* eslint-disable max-len */ // See https://github.com/eslint/eslint/issues/3229 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, /* eslint-enable */ // Support: IE <=10 - 11, Edge 12 - 13 only // In IE/Edge using regex groups here causes severe slowdowns. // See https://connect.microsoft.com/IE/feedback/details/1736512/ rnoInnerhtml = /<script|<style|<link/i, // checked="checked" or checked rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; // Prefer a tbody over its parent table for containing new rows function manipulationTarget( elem, content ) { if ( nodeName( elem, "table" ) && nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { return jQuery( elem ).children( "tbody" )[ 0 ] || elem; } return elem; } // Replace/restore the type attribute of script elements for safe DOM manipulation function disableScript( elem ) { elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; return elem; } function restoreScript( elem ) { if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { elem.type = elem.type.slice( 5 ); } else { elem.removeAttribute( "type" ); } return elem; } function cloneCopyEvent( src, dest ) { var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; if ( dest.nodeType !== 1 ) { return; } // 1. Copy private data: events, handlers, etc. if ( dataPriv.hasData( src ) ) { pdataOld = dataPriv.access( src ); pdataCur = dataPriv.set( dest, pdataOld ); events = pdataOld.events; if ( events ) { delete pdataCur.handle; pdataCur.events = {}; for ( type in events ) { for ( i = 0, l = events[ type ].length; i < l; i++ ) { jQuery.event.add( dest, type, events[ type ][ i ] ); } } } } // 2. Copy user data if ( dataUser.hasData( src ) ) { udataOld = dataUser.access( src ); udataCur = jQuery.extend( {}, udataOld ); dataUser.set( dest, udataCur ); } } // Fix IE bugs, see support tests function fixInput( src, dest ) { var nodeName = dest.nodeName.toLowerCase(); // Fails to persist the checked state of a cloned checkbox or radio button. if ( nodeName === "input" && rcheckableType.test( src.type ) ) { dest.checked = src.checked; // Fails to return the selected option to the default selected state when cloning options } else if ( nodeName === "input" || nodeName === "textarea" ) { dest.defaultValue = src.defaultValue; } } function domManip( collection, args, callback, ignored ) { // Flatten any nested arrays args = concat.apply( [], args ); var fragment, first, scripts, hasScripts, node, doc, i = 0, l = collection.length, iNoClone = l - 1, value = args[ 0 ], valueIsFunction = isFunction( value ); // We can't cloneNode fragments that contain checked, in WebKit if ( valueIsFunction || ( l > 1 && typeof value === "string" && !support.checkClone && rchecked.test( value ) ) ) { return collection.each( function( index ) { var self = collection.eq( index ); if ( valueIsFunction ) { args[ 0 ] = value.call( this, index, self.html() ); } domManip( self, args, callback, ignored ); } ); } if ( l ) { fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); first = fragment.firstChild; if ( fragment.childNodes.length === 1 ) { fragment = first; } // Require either new content or an interest in ignored elements to invoke the callback if ( first || ignored ) { scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); hasScripts = scripts.length; // Use the original fragment for the last item // instead of the first because it can end up // being emptied incorrectly in certain situations (#8070). for ( ; i < l; i++ ) { node = fragment; if ( i !== iNoClone ) { node = jQuery.clone( node, true, true ); // Keep references to cloned scripts for later restoration if ( hasScripts ) { // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( scripts, getAll( node, "script" ) ); } } callback.call( collection[ i ], node, i ); } if ( hasScripts ) { doc = scripts[ scripts.length - 1 ].ownerDocument; // Reenable scripts jQuery.map( scripts, restoreScript ); // Evaluate executable scripts on first document insertion for ( i = 0; i < hasScripts; i++ ) { node = scripts[ i ]; if ( rscriptType.test( node.type || "" ) && !dataPriv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { // Optional AJAX dependency, but won't run scripts if not present if ( jQuery._evalUrl ) { jQuery._evalUrl( node.src ); } } else { DOMEval( node.textContent.replace( rcleanScript, "" ), doc, node ); } } } } } } return collection; } function remove( elem, selector, keepData ) { var node, nodes = selector ? jQuery.filter( selector, elem ) : elem, i = 0; for ( ; ( node = nodes[ i ] ) != null; i++ ) { if ( !keepData && node.nodeType === 1 ) { jQuery.cleanData( getAll( node ) ); } if ( node.parentNode ) { if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { setGlobalEval( getAll( node, "script" ) ); } node.parentNode.removeChild( node ); } } return elem; } jQuery.extend( { htmlPrefilter: function( html ) { return html.replace( rxhtmlTag, "<$1></$2>" ); }, clone: function( elem, dataAndEvents, deepDataAndEvents ) { var i, l, srcElements, destElements, clone = elem.cloneNode( true ), inPage = jQuery.contains( elem.ownerDocument, elem ); // Fix IE cloning issues if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) { // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 destElements = getAll( clone ); srcElements = getAll( elem ); for ( i = 0, l = srcElements.length; i < l; i++ ) { fixInput( srcElements[ i ], destElements[ i ] ); } } // Copy the events from the original to the clone if ( dataAndEvents ) { if ( deepDataAndEvents ) { srcElements = srcElements || getAll( elem ); destElements = destElements || getAll( clone ); for ( i = 0, l = srcElements.length; i < l; i++ ) { cloneCopyEvent( srcElements[ i ], destElements[ i ] ); } } else { cloneCopyEvent( elem, clone ); } } // Preserve script evaluation history destElements = getAll( clone, "script" ); if ( destElements.length > 0 ) { setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); } // Return the cloned set return clone; }, cleanData: function( elems ) { var data, elem, type, special = jQuery.event.special, i = 0; for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { if ( acceptData( elem ) ) { if ( ( data = elem[ dataPriv.expando ] ) ) { if ( data.events ) { for ( type in data.events ) { if ( special[ type ] ) { jQuery.event.remove( elem, type ); // This is a shortcut to avoid jQuery.event.remove's overhead } else { jQuery.removeEvent( elem, type, data.handle ); } } } // Support: Chrome <=35 - 45+ // Assign undefined instead of using delete, see Data#remove elem[ dataPriv.expando ] = undefined; } if ( elem[ dataUser.expando ] ) { // Support: Chrome <=35 - 45+ // Assign undefined instead of using delete, see Data#remove elem[ dataUser.expando ] = undefined; } } } } } ); jQuery.fn.extend( { detach: function( selector ) { return remove( this, selector, true ); }, remove: function( selector ) { return remove( this, selector ); }, text: function( value ) { return access( this, function( value ) { return value === undefined ? jQuery.text( this ) : this.empty().each( function() { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { this.textContent = value; } } ); }, null, value, arguments.length ); }, append: function() { return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.appendChild( elem ); } } ); }, prepend: function() { return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.insertBefore( elem, target.firstChild ); } } ); }, before: function() { return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this ); } } ); }, after: function() { return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this.nextSibling ); } } ); }, empty: function() { var elem, i = 0; for ( ; ( elem = this[ i ] ) != null; i++ ) { if ( elem.nodeType === 1 ) { // Prevent memory leaks jQuery.cleanData( getAll( elem, false ) ); // Remove any remaining nodes elem.textContent = ""; } } return this; }, clone: function( dataAndEvents, deepDataAndEvents ) { dataAndEvents = dataAndEvents == null ? false : dataAndEvents; deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; return this.map( function() { return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); } ); }, html: function( value ) { return access( this, function( value ) { var elem = this[ 0 ] || {}, i = 0, l = this.length; if ( value === undefined && elem.nodeType === 1 ) { return elem.innerHTML; } // See if we can take a shortcut and just use innerHTML if ( typeof value === "string" && !rnoInnerhtml.test( value ) && !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { value = jQuery.htmlPrefilter( value ); try { for ( ; i < l; i++ ) { elem = this[ i ] || {}; // Remove element nodes and prevent memory leaks if ( elem.nodeType === 1 ) { jQuery.cleanData( getAll( elem, false ) ); elem.innerHTML = value; } } elem = 0; // If using innerHTML throws an exception, use the fallback method } catch ( e ) {} } if ( elem ) { this.empty().append( value ); } }, null, value, arguments.length ); }, replaceWith: function() { var ignored = []; // Make the changes, replacing each non-ignored context element with the new content return domManip( this, arguments, function( elem ) { var parent = this.parentNode; if ( jQuery.inArray( this, ignored ) < 0 ) { jQuery.cleanData( getAll( this ) ); if ( parent ) { parent.replaceChild( elem, this ); } } // Force callback invocation }, ignored ); } } ); jQuery.each( { appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function( name, original ) { jQuery.fn[ name ] = function( selector ) { var elems, ret = [], insert = jQuery( selector ), last = insert.length - 1, i = 0; for ( ; i <= last; i++ ) { elems = i === last ? this : this.clone( true ); jQuery( insert[ i ] )[ original ]( elems ); // Support: Android <=4.0 only, PhantomJS 1 only // .get() because push.apply(_, arraylike) throws on ancient WebKit push.apply( ret, elems.get() ); } return this.pushStack( ret ); }; } ); var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); var getStyles = function( elem ) { // Support: IE <=11 only, Firefox <=30 (#15098, #14150) // IE throws on elements created in popups // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" var view = elem.ownerDocument.defaultView; if ( !view || !view.opener ) { view = window; } return view.getComputedStyle( elem ); }; var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); ( function() { // Executing both pixelPosition & boxSizingReliable tests require only one layout // so they're executed at the same time to save the second computation. function computeStyleTests() { // This is a singleton, we need to execute it only once if ( !div ) { return; } container.style.cssText = "position:absolute;left:-11111px;width:60px;" + "margin-top:1px;padding:0;border:0"; div.style.cssText = "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + "margin:auto;border:1px;padding:1px;" + "width:60%;top:1%"; documentElement.appendChild( container ).appendChild( div ); var divStyle = window.getComputedStyle( div ); pixelPositionVal = divStyle.top !== "1%"; // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 // Some styles come back with percentage values, even though they shouldn't div.style.right = "60%"; pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; // Support: IE 9 - 11 only // Detect misreporting of content dimensions for box-sizing:border-box elements boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; // Support: IE 9 only // Detect overflow:scroll screwiness (gh-3699) div.style.position = "absolute"; scrollboxSizeVal = div.offsetWidth === 36 || "absolute"; documentElement.removeChild( container ); // Nullify the div so it wouldn't be stored in the memory and // it will also be a sign that checks already performed div = null; } function roundPixelMeasures( measure ) { return Math.round( parseFloat( measure ) ); } var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, reliableMarginLeftVal, container = document.createElement( "div" ), div = document.createElement( "div" ); // Finish early in limited (non-browser) environments if ( !div.style ) { return; } // Support: IE <=9 - 11 only // Style of cloned element affects source element cloned (#8908) div.style.backgroundClip = "content-box"; div.cloneNode( true ).style.backgroundClip = ""; support.clearCloneStyle = div.style.backgroundClip === "content-box"; jQuery.extend( support, { boxSizingReliable: function() { computeStyleTests(); return boxSizingReliableVal; }, pixelBoxStyles: function() { computeStyleTests(); return pixelBoxStylesVal; }, pixelPosition: function() { computeStyleTests(); return pixelPositionVal; }, reliableMarginLeft: function() { computeStyleTests(); return reliableMarginLeftVal; }, scrollboxSize: function() { computeStyleTests(); return scrollboxSizeVal; } } ); } )(); function curCSS( elem, name, computed ) { var width, minWidth, maxWidth, ret, // Support: Firefox 51+ // Retrieving style before computed somehow // fixes an issue with getting wrong values // on detached elements style = elem.style; computed = computed || getStyles( elem ); // getPropertyValue is needed for: // .css('filter') (IE 9 only, #12537) // .css('--customProperty) (#3144) if ( computed ) { ret = computed.getPropertyValue( name ) || computed[ name ]; if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { ret = jQuery.style( elem, name ); } // A tribute to the "awesome hack by Dean Edwards" // Android Browser returns percentage for some values, // but width seems to be reliably pixels. // This is against the CSSOM draft spec: // https://drafts.csswg.org/cssom/#resolved-values if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { // Remember the original values width = style.width; minWidth = style.minWidth; maxWidth = style.maxWidth; // Put in the new values to get a computed value out style.minWidth = style.maxWidth = style.width = ret; ret = computed.width; // Revert the changed values style.width = width; style.minWidth = minWidth; style.maxWidth = maxWidth; } } return ret !== undefined ? // Support: IE <=9 - 11 only // IE returns zIndex value as an integer. ret + "" : ret; } function addGetHookIf( conditionFn, hookFn ) { // Define the hook, we'll check on the first run if it's really needed. return { get: function() { if ( conditionFn() ) { // Hook not needed (or it's not possible to use it due // to missing dependency), remove it. delete this.get; return; } // Hook needed; redefine it so that the support test is not executed again. return ( this.get = hookFn ).apply( this, arguments ); } }; } var // Swappable if display is none or starts with table // except "table", "table-cell", or "table-caption" // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display rdisplayswap = /^(none|table(?!-c[ea]).+)/, rcustomProp = /^--/, cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssNormalTransform = { letterSpacing: "0", fontWeight: "400" }, cssPrefixes = [ "Webkit", "Moz", "ms" ], emptyStyle = document.createElement( "div" ).style; // Return a css property mapped to a potentially vendor prefixed property function vendorPropName( name ) { // Shortcut for names that are not vendor prefixed if ( name in emptyStyle ) { return name; } // Check for vendor prefixed names var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), i = cssPrefixes.length; while ( i-- ) { name = cssPrefixes[ i ] + capName; if ( name in emptyStyle ) { return name; } } } // Return a property mapped along what jQuery.cssProps suggests or to // a vendor prefixed property. function finalPropName( name ) { var ret = jQuery.cssProps[ name ]; if ( !ret ) { ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name; } return ret; } function setPositiveNumber( elem, value, subtract ) { // Any relative (+/-) values have already been // normalized at this point var matches = rcssNum.exec( value ); return matches ? // Guard against undefined "subtract", e.g., when used as in cssHooks Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : value; } function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { var i = dimension === "width" ? 1 : 0, extra = 0, delta = 0; // Adjustment may not be necessary if ( box === ( isBorderBox ? "border" : "content" ) ) { return 0; } for ( ; i < 4; i += 2 ) { // Both box models exclude margin if ( box === "margin" ) { delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); } // If we get here with a content-box, we're seeking "padding" or "border" or "margin" if ( !isBorderBox ) { // Add padding delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); // For "border" or "margin", add border if ( box !== "padding" ) { delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); // But still keep track of it otherwise } else { extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } // If we get here with a border-box (content + padding + border), we're seeking "content" or // "padding" or "margin" } else { // For "content", subtract padding if ( box === "content" ) { delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); } // For "content" or "padding", subtract border if ( box !== "margin" ) { delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } } } // Account for positive content-box scroll gutter when requested by providing computedVal if ( !isBorderBox && computedVal >= 0 ) { // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border // Assuming integer scroll gutter, subtract the rest and round down delta += Math.max( 0, Math.ceil( elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - computedVal - delta - extra - 0.5 ) ); } return delta; } function getWidthOrHeight( elem, dimension, extra ) { // Start with computed style var styles = getStyles( elem ), val = curCSS( elem, dimension, styles ), isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box", valueIsBorderBox = isBorderBox; // Support: Firefox <=54 // Return a confounding non-pixel value or feign ignorance, as appropriate. if ( rnumnonpx.test( val ) ) { if ( !extra ) { return val; } val = "auto"; } // Check for style in case a browser which returns unreliable values // for getComputedStyle silently falls back to the reliable elem.style valueIsBorderBox = valueIsBorderBox && ( support.boxSizingReliable() || val === elem.style[ dimension ] ); // Fall back to offsetWidth/offsetHeight when value is "auto" // This happens for inline elements with no explicit setting (gh-3571) // Support: Android <=4.1 - 4.3 only // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) if ( val === "auto" || !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) { val = elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ]; // offsetWidth/offsetHeight provide border-box values valueIsBorderBox = true; } // Normalize "" and auto val = parseFloat( val ) || 0; // Adjust for the element's box model return ( val + boxModelAdjustment( elem, dimension, extra || ( isBorderBox ? "border" : "content" ), valueIsBorderBox, styles, // Provide the current computed size to request scroll gutter calculation (gh-3589) val ) ) + "px"; } jQuery.extend( { // Add in style property hooks for overriding the default // behavior of getting and setting a style property cssHooks: { opacity: { get: function( elem, computed ) { if ( computed ) { // We should always get a number back from opacity var ret = curCSS( elem, "opacity" ); return ret === "" ? "1" : ret; } } } }, // Don't automatically add "px" to these possibly-unitless properties cssNumber: { "animationIterationCount": true, "columnCount": true, "fillOpacity": true, "flexGrow": true, "flexShrink": true, "fontWeight": true, "lineHeight": true, "opacity": true, "order": true, "orphans": true, "widows": true, "zIndex": true, "zoom": true }, // Add in properties whose names you wish to fix before // setting or getting the value cssProps: {}, // Get and set the style property on a DOM Node style: function( elem, name, value, extra ) { // Don't set styles on text and comment nodes if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { return; } // Make sure that we're working with the right name var ret, type, hooks, origName = camelCase( name ), isCustomProp = rcustomProp.test( name ), style = elem.style; // Make sure that we're working with the right name. We don't // want to query the value if it is a CSS custom property // since they are user-defined. if ( !isCustomProp ) { name = finalPropName( origName ); } // Gets hook for the prefixed version, then unprefixed version hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // Check if we're setting a value if ( value !== undefined ) { type = typeof value; // Convert "+=" or "-=" to relative numbers (#7345) if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { value = adjustCSS( elem, name, ret ); // Fixes bug #9237 type = "number"; } // Make sure that null and NaN values aren't set (#7116) if ( value == null || value !== value ) { return; } // If a number was passed in, add the unit (except for certain CSS properties) if ( type === "number" ) { value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); } // background-* props affect original clone's values if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { style[ name ] = "inherit"; } // If a hook was provided, use that value, otherwise just set the specified value if ( !hooks || !( "set" in hooks ) || ( value = hooks.set( elem, value, extra ) ) !== undefined ) { if ( isCustomProp ) { style.setProperty( name, value ); } else { style[ name ] = value; } } } else { // If a hook was provided get the non-computed value from there if ( hooks && "get" in hooks && ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { return ret; } // Otherwise just get the value from the style object return style[ name ]; } }, css: function( elem, name, extra, styles ) { var val, num, hooks, origName = camelCase( name ), isCustomProp = rcustomProp.test( name ); // Make sure that we're working with the right name. We don't // want to modify the value if it is a CSS custom property // since they are user-defined. if ( !isCustomProp ) { name = finalPropName( origName ); } // Try prefixed name followed by the unprefixed name hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // If a hook was provided get the computed value from there if ( hooks && "get" in hooks ) { val = hooks.get( elem, true, extra ); } // Otherwise, if a way to get the computed value exists, use that if ( val === undefined ) { val = curCSS( elem, name, styles ); } // Convert "normal" to computed value if ( val === "normal" && name in cssNormalTransform ) { val = cssNormalTransform[ name ]; } // Make numeric if forced or a qualifier was provided and val looks numeric if ( extra === "" || extra ) { num = parseFloat( val ); return extra === true || isFinite( num ) ? num || 0 : val; } return val; } } ); jQuery.each( [ "height", "width" ], function( i, dimension ) { jQuery.cssHooks[ dimension ] = { get: function( elem, computed, extra ) { if ( computed ) { // Certain elements can have dimension info if we invisibly show them // but it must have a current display style that would benefit return rdisplayswap.test( jQuery.css( elem, "display" ) ) && // Support: Safari 8+ // Table columns in Safari have non-zero offsetWidth & zero // getBoundingClientRect().width unless display is changed. // Support: IE <=11 only // Running getBoundingClientRect on a disconnected node // in IE throws an error. ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? swap( elem, cssShow, function() { return getWidthOrHeight( elem, dimension, extra ); } ) : getWidthOrHeight( elem, dimension, extra ); } }, set: function( elem, value, extra ) { var matches, styles = getStyles( elem ), isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box", subtract = extra && boxModelAdjustment( elem, dimension, extra, isBorderBox, styles ); // Account for unreliable border-box dimensions by comparing offset* to computed and // faking a content-box to get border and padding (gh-3699) if ( isBorderBox && support.scrollboxSize() === styles.position ) { subtract -= Math.ceil( elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - parseFloat( styles[ dimension ] ) - boxModelAdjustment( elem, dimension, "border", false, styles ) - 0.5 ); } // Convert to pixels if value adjustment is needed if ( subtract && ( matches = rcssNum.exec( value ) ) && ( matches[ 3 ] || "px" ) !== "px" ) { elem.style[ dimension ] = value; value = jQuery.css( elem, dimension ); } return setPositiveNumber( elem, value, subtract ); } }; } ); jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, function( elem, computed ) { if ( computed ) { return ( parseFloat( curCSS( elem, "marginLeft" ) ) || elem.getBoundingClientRect().left - swap( elem, { marginLeft: 0 }, function() { return elem.getBoundingClientRect().left; } ) ) + "px"; } } ); // These hooks are used by animate to expand properties jQuery.each( { margin: "", padding: "", border: "Width" }, function( prefix, suffix ) { jQuery.cssHooks[ prefix + suffix ] = { expand: function( value ) { var i = 0, expanded = {}, // Assumes a single number if not a string parts = typeof value === "string" ? value.split( " " ) : [ value ]; for ( ; i < 4; i++ ) { expanded[ prefix + cssExpand[ i ] + suffix ] = parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; } return expanded; } }; if ( prefix !== "margin" ) { jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; } } ); jQuery.fn.extend( { css: function( name, value ) { return access( this, function( elem, name, value ) { var styles, len, map = {}, i = 0; if ( Array.isArray( name ) ) { styles = getStyles( elem ); len = name.length; for ( ; i < len; i++ ) { map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); } return map; } return value !== undefined ? jQuery.style( elem, name, value ) : jQuery.css( elem, name ); }, name, value, arguments.length > 1 ); } } ); function Tween( elem, options, prop, end, easing ) { return new Tween.prototype.init( elem, options, prop, end, easing ); } jQuery.Tween = Tween; Tween.prototype = { constructor: Tween, init: function( elem, options, prop, end, easing, unit ) { this.elem = elem; this.prop = prop; this.easing = easing || jQuery.easing._default; this.options = options; this.start = this.now = this.cur(); this.end = end; this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); }, cur: function() { var hooks = Tween.propHooks[ this.prop ]; return hooks && hooks.get ? hooks.get( this ) : Tween.propHooks._default.get( this ); }, run: function( percent ) { var eased, hooks = Tween.propHooks[ this.prop ]; if ( this.options.duration ) { this.pos = eased = jQuery.easing[ this.easing ]( percent, this.options.duration * percent, 0, 1, this.options.duration ); } else { this.pos = eased = percent; } this.now = ( this.end - this.start ) * eased + this.start; if ( this.options.step ) { this.options.step.call( this.elem, this.now, this ); } if ( hooks && hooks.set ) { hooks.set( this ); } else { Tween.propHooks._default.set( this ); } return this; } }; Tween.prototype.init.prototype = Tween.prototype; Tween.propHooks = { _default: { get: function( tween ) { var result; // Use a property on the element directly when it is not a DOM element, // or when there is no matching style property that exists. if ( tween.elem.nodeType !== 1 || tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { return tween.elem[ tween.prop ]; } // Passing an empty string as a 3rd parameter to .css will automatically // attempt a parseFloat and fallback to a string if the parse fails. // Simple values such as "10px" are parsed to Float; // complex values such as "rotate(1rad)" are returned as-is. result = jQuery.css( tween.elem, tween.prop, "" ); // Empty strings, null, undefined and "auto" are converted to 0. return !result || result === "auto" ? 0 : result; }, set: function( tween ) { // Use step hook for back compat. // Use cssHook if its there. // Use .style if available and use plain properties where available. if ( jQuery.fx.step[ tween.prop ] ) { jQuery.fx.step[ tween.prop ]( tween ); } else if ( tween.elem.nodeType === 1 && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); } else { tween.elem[ tween.prop ] = tween.now; } } } }; // Support: IE <=9 only // Panic based approach to setting things on disconnected nodes Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { set: function( tween ) { if ( tween.elem.nodeType && tween.elem.parentNode ) { tween.elem[ tween.prop ] = tween.now; } } }; jQuery.easing = { linear: function( p ) { return p; }, swing: function( p ) { return 0.5 - Math.cos( p * Math.PI ) / 2; }, _default: "swing" }; jQuery.fx = Tween.prototype.init; // Back compat <1.8 extension point jQuery.fx.step = {}; var fxNow, inProgress, rfxtypes = /^(?:toggle|show|hide)$/, rrun = /queueHooks$/; function schedule() { if ( inProgress ) { if ( document.hidden === false && window.requestAnimationFrame ) { window.requestAnimationFrame( schedule ); } else { window.setTimeout( schedule, jQuery.fx.interval ); } jQuery.fx.tick(); } } // Animations created synchronously will run synchronously function createFxNow() { window.setTimeout( function() { fxNow = undefined; } ); return ( fxNow = Date.now() ); } // Generate parameters to create a standard animation function genFx( type, includeWidth ) { var which, i = 0, attrs = { height: type }; // If we include width, step value is 1 to do all cssExpand values, // otherwise step value is 2 to skip over Left and Right includeWidth = includeWidth ? 1 : 0; for ( ; i < 4; i += 2 - includeWidth ) { which = cssExpand[ i ]; attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; } if ( includeWidth ) { attrs.opacity = attrs.width = type; } return attrs; } function createTween( value, prop, animation ) { var tween, collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), index = 0, length = collection.length; for ( ; index < length; index++ ) { if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { // We're done with this property return tween; } } } function defaultPrefilter( elem, props, opts ) { var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, isBox = "width" in props || "height" in props, anim = this, orig = {}, style = elem.style, hidden = elem.nodeType && isHiddenWithinTree( elem ), dataShow = dataPriv.get( elem, "fxshow" ); // Queue-skipping animations hijack the fx hooks if ( !opts.queue ) { hooks = jQuery._queueHooks( elem, "fx" ); if ( hooks.unqueued == null ) { hooks.unqueued = 0; oldfire = hooks.empty.fire; hooks.empty.fire = function() { if ( !hooks.unqueued ) { oldfire(); } }; } hooks.unqueued++; anim.always( function() { // Ensure the complete handler is called before this completes anim.always( function() { hooks.unqueued--; if ( !jQuery.queue( elem, "fx" ).length ) { hooks.empty.fire(); } } ); } ); } // Detect show/hide animations for ( prop in props ) { value = props[ prop ]; if ( rfxtypes.test( value ) ) { delete props[ prop ]; toggle = toggle || value === "toggle"; if ( value === ( hidden ? "hide" : "show" ) ) { // Pretend to be hidden if this is a "show" and // there is still data from a stopped show/hide if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { hidden = true; // Ignore all other no-op show/hide data } else { continue; } } orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); } } // Bail out if this is a no-op like .hide().hide() propTween = !jQuery.isEmptyObject( props ); if ( !propTween && jQuery.isEmptyObject( orig ) ) { return; } // Restrict "overflow" and "display" styles during box animations if ( isBox && elem.nodeType === 1 ) { // Support: IE <=9 - 11, Edge 12 - 15 // Record all 3 overflow attributes because IE does not infer the shorthand // from identically-valued overflowX and overflowY and Edge just mirrors // the overflowX value there. opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; // Identify a display type, preferring old show/hide data over the CSS cascade restoreDisplay = dataShow && dataShow.display; if ( restoreDisplay == null ) { restoreDisplay = dataPriv.get( elem, "display" ); } display = jQuery.css( elem, "display" ); if ( display === "none" ) { if ( restoreDisplay ) { display = restoreDisplay; } else { // Get nonempty value(s) by temporarily forcing visibility showHide( [ elem ], true ); restoreDisplay = elem.style.display || restoreDisplay; display = jQuery.css( elem, "display" ); showHide( [ elem ] ); } } // Animate inline elements as inline-block if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { if ( jQuery.css( elem, "float" ) === "none" ) { // Restore the original display value at the end of pure show/hide animations if ( !propTween ) { anim.done( function() { style.display = restoreDisplay; } ); if ( restoreDisplay == null ) { display = style.display; restoreDisplay = display === "none" ? "" : display; } } style.display = "inline-block"; } } } if ( opts.overflow ) { style.overflow = "hidden"; anim.always( function() { style.overflow = opts.overflow[ 0 ]; style.overflowX = opts.overflow[ 1 ]; style.overflowY = opts.overflow[ 2 ]; } ); } // Implement show/hide animations propTween = false; for ( prop in orig ) { // General show/hide setup for this element animation if ( !propTween ) { if ( dataShow ) { if ( "hidden" in dataShow ) { hidden = dataShow.hidden; } } else { dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); } // Store hidden/visible for toggle so `.stop().toggle()` "reverses" if ( toggle ) { dataShow.hidden = !hidden; } // Show elements before animating them if ( hidden ) { showHide( [ elem ], true ); } /* eslint-disable no-loop-func */ anim.done( function() { /* eslint-enable no-loop-func */ // The final step of a "hide" animation is actually hiding the element if ( !hidden ) { showHide( [ elem ] ); } dataPriv.remove( elem, "fxshow" ); for ( prop in orig ) { jQuery.style( elem, prop, orig[ prop ] ); } } ); } // Per-property setup propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); if ( !( prop in dataShow ) ) { dataShow[ prop ] = propTween.start; if ( hidden ) { propTween.end = propTween.start; propTween.start = 0; } } } } function propFilter( props, specialEasing ) { var index, name, easing, value, hooks; // camelCase, specialEasing and expand cssHook pass for ( index in props ) { name = camelCase( index ); easing = specialEasing[ name ]; value = props[ index ]; if ( Array.isArray( value ) ) { easing = value[ 1 ]; value = props[ index ] = value[ 0 ]; } if ( index !== name ) { props[ name ] = value; delete props[ index ]; } hooks = jQuery.cssHooks[ name ]; if ( hooks && "expand" in hooks ) { value = hooks.expand( value ); delete props[ name ]; // Not quite $.extend, this won't overwrite existing keys. // Reusing 'index' because we have the correct "name" for ( index in value ) { if ( !( index in props ) ) { props[ index ] = value[ index ]; specialEasing[ index ] = easing; } } } else { specialEasing[ name ] = easing; } } } function Animation( elem, properties, options ) { var result, stopped, index = 0, length = Animation.prefilters.length, deferred = jQuery.Deferred().always( function() { // Don't match elem in the :animated selector delete tick.elem; } ), tick = function() { if ( stopped ) { return false; } var currentTime = fxNow || createFxNow(), remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), // Support: Android 2.3 only // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) temp = remaining / animation.duration || 0, percent = 1 - temp, index = 0, length = animation.tweens.length; for ( ; index < length; index++ ) { animation.tweens[ index ].run( percent ); } deferred.notifyWith( elem, [ animation, percent, remaining ] ); // If there's more to do, yield if ( percent < 1 && length ) { return remaining; } // If this was an empty animation, synthesize a final progress notification if ( !length ) { deferred.notifyWith( elem, [ animation, 1, 0 ] ); } // Resolve the animation and report its conclusion deferred.resolveWith( elem, [ animation ] ); return false; }, animation = deferred.promise( { elem: elem, props: jQuery.extend( {}, properties ), opts: jQuery.extend( true, { specialEasing: {}, easing: jQuery.easing._default }, options ), originalProperties: properties, originalOptions: options, startTime: fxNow || createFxNow(), duration: options.duration, tweens: [], createTween: function( prop, end ) { var tween = jQuery.Tween( elem, animation.opts, prop, end, animation.opts.specialEasing[ prop ] || animation.opts.easing ); animation.tweens.push( tween ); return tween; }, stop: function( gotoEnd ) { var index = 0, // If we are going to the end, we want to run all the tweens // otherwise we skip this part length = gotoEnd ? animation.tweens.length : 0; if ( stopped ) { return this; } stopped = true; for ( ; index < length; index++ ) { animation.tweens[ index ].run( 1 ); } // Resolve when we played the last frame; otherwise, reject if ( gotoEnd ) { deferred.notifyWith( elem, [ animation, 1, 0 ] ); deferred.resolveWith( elem, [ animation, gotoEnd ] ); } else { deferred.rejectWith( elem, [ animation, gotoEnd ] ); } return this; } } ), props = animation.props; propFilter( props, animation.opts.specialEasing ); for ( ; index < length; index++ ) { result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); if ( result ) { if ( isFunction( result.stop ) ) { jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = result.stop.bind( result ); } return result; } } jQuery.map( props, createTween, animation ); if ( isFunction( animation.opts.start ) ) { animation.opts.start.call( elem, animation ); } // Attach callbacks from options animation .progress( animation.opts.progress ) .done( animation.opts.done, animation.opts.complete ) .fail( animation.opts.fail ) .always( animation.opts.always ); jQuery.fx.timer( jQuery.extend( tick, { elem: elem, anim: animation, queue: animation.opts.queue } ) ); return animation; } jQuery.Animation = jQuery.extend( Animation, { tweeners: { "*": [ function( prop, value ) { var tween = this.createTween( prop, value ); adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); return tween; } ] }, tweener: function( props, callback ) { if ( isFunction( props ) ) { callback = props; props = [ "*" ]; } else { props = props.match( rnothtmlwhite ); } var prop, index = 0, length = props.length; for ( ; index < length; index++ ) { prop = props[ index ]; Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; Animation.tweeners[ prop ].unshift( callback ); } }, prefilters: [ defaultPrefilter ], prefilter: function( callback, prepend ) { if ( prepend ) { Animation.prefilters.unshift( callback ); } else { Animation.prefilters.push( callback ); } } } ); jQuery.speed = function( speed, easing, fn ) { var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { complete: fn || !fn && easing || isFunction( speed ) && speed, duration: speed, easing: fn && easing || easing && !isFunction( easing ) && easing }; // Go to the end state if fx are off if ( jQuery.fx.off ) { opt.duration = 0; } else { if ( typeof opt.duration !== "number" ) { if ( opt.duration in jQuery.fx.speeds ) { opt.duration = jQuery.fx.speeds[ opt.duration ]; } else { opt.duration = jQuery.fx.speeds._default; } } } // Normalize opt.queue - true/undefined/null -> "fx" if ( opt.queue == null || opt.queue === true ) { opt.queue = "fx"; } // Queueing opt.old = opt.complete; opt.complete = function() { if ( isFunction( opt.old ) ) { opt.old.call( this ); } if ( opt.queue ) { jQuery.dequeue( this, opt.queue ); } }; return opt; }; jQuery.fn.extend( { fadeTo: function( speed, to, easing, callback ) { // Show any hidden elements after setting opacity to 0 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() // Animate to the value specified .end().animate( { opacity: to }, speed, easing, callback ); }, animate: function( prop, speed, easing, callback ) { var empty = jQuery.isEmptyObject( prop ), optall = jQuery.speed( speed, easing, callback ), doAnimation = function() { // Operate on a copy of prop so per-property easing won't be lost var anim = Animation( this, jQuery.extend( {}, prop ), optall ); // Empty animations, or finishing resolves immediately if ( empty || dataPriv.get( this, "finish" ) ) { anim.stop( true ); } }; doAnimation.finish = doAnimation; return empty || optall.queue === false ? this.each( doAnimation ) : this.queue( optall.queue, doAnimation ); }, stop: function( type, clearQueue, gotoEnd ) { var stopQueue = function( hooks ) { var stop = hooks.stop; delete hooks.stop; stop( gotoEnd ); }; if ( typeof type !== "string" ) { gotoEnd = clearQueue; clearQueue = type; type = undefined; } if ( clearQueue && type !== false ) { this.queue( type || "fx", [] ); } return this.each( function() { var dequeue = true, index = type != null && type + "queueHooks", timers = jQuery.timers, data = dataPriv.get( this ); if ( index ) { if ( data[ index ] && data[ index ].stop ) { stopQueue( data[ index ] ); } } else { for ( index in data ) { if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { stopQueue( data[ index ] ); } } } for ( index = timers.length; index--; ) { if ( timers[ index ].elem === this && ( type == null || timers[ index ].queue === type ) ) { timers[ index ].anim.stop( gotoEnd ); dequeue = false; timers.splice( index, 1 ); } } // Start the next in the queue if the last step wasn't forced. // Timers currently will call their complete callbacks, which // will dequeue but only if they were gotoEnd. if ( dequeue || !gotoEnd ) { jQuery.dequeue( this, type ); } } ); }, finish: function( type ) { if ( type !== false ) { type = type || "fx"; } return this.each( function() { var index, data = dataPriv.get( this ), queue = data[ type + "queue" ], hooks = data[ type + "queueHooks" ], timers = jQuery.timers, length = queue ? queue.length : 0; // Enable finishing flag on private data data.finish = true; // Empty the queue first jQuery.queue( this, type, [] ); if ( hooks && hooks.stop ) { hooks.stop.call( this, true ); } // Look for any active animations, and finish them for ( index = timers.length; index--; ) { if ( timers[ index ].elem === this && timers[ index ].queue === type ) { timers[ index ].anim.stop( true ); timers.splice( index, 1 ); } } // Look for any animations in the old queue and finish them for ( index = 0; index < length; index++ ) { if ( queue[ index ] && queue[ index ].finish ) { queue[ index ].finish.call( this ); } } // Turn off finishing flag delete data.finish; } ); } } ); jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { var cssFn = jQuery.fn[ name ]; jQuery.fn[ name ] = function( speed, easing, callback ) { return speed == null || typeof speed === "boolean" ? cssFn.apply( this, arguments ) : this.animate( genFx( name, true ), speed, easing, callback ); }; } ); // Generate shortcuts for custom animations jQuery.each( { slideDown: genFx( "show" ), slideUp: genFx( "hide" ), slideToggle: genFx( "toggle" ), fadeIn: { opacity: "show" }, fadeOut: { opacity: "hide" }, fadeToggle: { opacity: "toggle" } }, function( name, props ) { jQuery.fn[ name ] = function( speed, easing, callback ) { return this.animate( props, speed, easing, callback ); }; } ); jQuery.timers = []; jQuery.fx.tick = function() { var timer, i = 0, timers = jQuery.timers; fxNow = Date.now(); for ( ; i < timers.length; i++ ) { timer = timers[ i ]; // Run the timer and safely remove it when done (allowing for external removal) if ( !timer() && timers[ i ] === timer ) { timers.splice( i--, 1 ); } } if ( !timers.length ) { jQuery.fx.stop(); } fxNow = undefined; }; jQuery.fx.timer = function( timer ) { jQuery.timers.push( timer ); jQuery.fx.start(); }; jQuery.fx.interval = 13; jQuery.fx.start = function() { if ( inProgress ) { return; } inProgress = true; schedule(); }; jQuery.fx.stop = function() { inProgress = null; }; jQuery.fx.speeds = { slow: 600, fast: 200, // Default speed _default: 400 }; // Based off of the plugin by Clint Helfers, with permission. // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ jQuery.fn.delay = function( time, type ) { time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; type = type || "fx"; return this.queue( type, function( next, hooks ) { var timeout = window.setTimeout( next, time ); hooks.stop = function() { window.clearTimeout( timeout ); }; } ); }; ( function() { var input = document.createElement( "input" ), select = document.createElement( "select" ), opt = select.appendChild( document.createElement( "option" ) ); input.type = "checkbox"; // Support: Android <=4.3 only // Default value for a checkbox should be "on" support.checkOn = input.value !== ""; // Support: IE <=11 only // Must access selectedIndex to make default options select support.optSelected = opt.selected; // Support: IE <=11 only // An input loses its value after becoming a radio input = document.createElement( "input" ); input.value = "t"; input.type = "radio"; support.radioValue = input.value === "t"; } )(); var boolHook, attrHandle = jQuery.expr.attrHandle; jQuery.fn.extend( { attr: function( name, value ) { return access( this, jQuery.attr, name, value, arguments.length > 1 ); }, removeAttr: function( name ) { return this.each( function() { jQuery.removeAttr( this, name ); } ); } } ); jQuery.extend( { attr: function( elem, name, value ) { var ret, hooks, nType = elem.nodeType; // Don't get/set attributes on text, comment and attribute nodes if ( nType === 3 || nType === 8 || nType === 2 ) { return; } // Fallback to prop when attributes are not supported if ( typeof elem.getAttribute === "undefined" ) { return jQuery.prop( elem, name, value ); } // Attribute hooks are determined by the lowercase version // Grab necessary hook if one is defined if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { hooks = jQuery.attrHooks[ name.toLowerCase() ] || ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); } if ( value !== undefined ) { if ( value === null ) { jQuery.removeAttr( elem, name ); return; } if ( hooks && "set" in hooks && ( ret = hooks.set( elem, value, name ) ) !== undefined ) { return ret; } elem.setAttribute( name, value + "" ); return value; } if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { return ret; } ret = jQuery.find.attr( elem, name ); // Non-existent attributes return null, we normalize to undefined return ret == null ? undefined : ret; }, attrHooks: { type: { set: function( elem, value ) { if ( !support.radioValue && value === "radio" && nodeName( elem, "input" ) ) { var val = elem.value; elem.setAttribute( "type", value ); if ( val ) { elem.value = val; } return value; } } } }, removeAttr: function( elem, value ) { var name, i = 0, // Attribute names can contain non-HTML whitespace characters // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 attrNames = value && value.match( rnothtmlwhite ); if ( attrNames && elem.nodeType === 1 ) { while ( ( name = attrNames[ i++ ] ) ) { elem.removeAttribute( name ); } } } } ); // Hooks for boolean attributes boolHook = { set: function( elem, value, name ) { if ( value === false ) { // Remove boolean attributes when set to false jQuery.removeAttr( elem, name ); } else { elem.setAttribute( name, name ); } return name; } }; jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { var getter = attrHandle[ name ] || jQuery.find.attr; attrHandle[ name ] = function( elem, name, isXML ) { var ret, handle, lowercaseName = name.toLowerCase(); if ( !isXML ) { // Avoid an infinite loop by temporarily removing this function from the getter handle = attrHandle[ lowercaseName ]; attrHandle[ lowercaseName ] = ret; ret = getter( elem, name, isXML ) != null ? lowercaseName : null; attrHandle[ lowercaseName ] = handle; } return ret; }; } ); var rfocusable = /^(?:input|select|textarea|button)$/i, rclickable = /^(?:a|area)$/i; jQuery.fn.extend( { prop: function( name, value ) { return access( this, jQuery.prop, name, value, arguments.length > 1 ); }, removeProp: function( name ) { return this.each( function() { delete this[ jQuery.propFix[ name ] || name ]; } ); } } ); jQuery.extend( { prop: function( elem, name, value ) { var ret, hooks, nType = elem.nodeType; // Don't get/set properties on text, comment and attribute nodes if ( nType === 3 || nType === 8 || nType === 2 ) { return; } if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { // Fix name and attach hooks name = jQuery.propFix[ name ] || name; hooks = jQuery.propHooks[ name ]; } if ( value !== undefined ) { if ( hooks && "set" in hooks && ( ret = hooks.set( elem, value, name ) ) !== undefined ) { return ret; } return ( elem[ name ] = value ); } if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { return ret; } return elem[ name ]; }, propHooks: { tabIndex: { get: function( elem ) { // Support: IE <=9 - 11 only // elem.tabIndex doesn't always return the // correct value when it hasn't been explicitly set // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ // Use proper attribute retrieval(#12072) var tabindex = jQuery.find.attr( elem, "tabindex" ); if ( tabindex ) { return parseInt( tabindex, 10 ); } if ( rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ) { return 0; } return -1; } } }, propFix: { "for": "htmlFor", "class": "className" } } ); // Support: IE <=11 only // Accessing the selectedIndex property // forces the browser to respect setting selected // on the option // The getter ensures a default option is selected // when in an optgroup // eslint rule "no-unused-expressions" is disabled for this code // since it considers such accessions noop if ( !support.optSelected ) { jQuery.propHooks.selected = { get: function( elem ) { /* eslint no-unused-expressions: "off" */ var parent = elem.parentNode; if ( parent && parent.parentNode ) { parent.parentNode.selectedIndex; } return null; }, set: function( elem ) { /* eslint no-unused-expressions: "off" */ var parent = elem.parentNode; if ( parent ) { parent.selectedIndex; if ( parent.parentNode ) { parent.parentNode.selectedIndex; } } } }; } jQuery.each( [ "tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable" ], function() { jQuery.propFix[ this.toLowerCase() ] = this; } ); // Strip and collapse whitespace according to HTML spec // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace function stripAndCollapse( value ) { var tokens = value.match( rnothtmlwhite ) || []; return tokens.join( " " ); } function getClass( elem ) { return elem.getAttribute && elem.getAttribute( "class" ) || ""; } function classesToArray( value ) { if ( Array.isArray( value ) ) { return value; } if ( typeof value === "string" ) { return value.match( rnothtmlwhite ) || []; } return []; } jQuery.fn.extend( { addClass: function( value ) { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; if ( isFunction( value ) ) { return this.each( function( j ) { jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); } ); } classes = classesToArray( value ); if ( classes.length ) { while ( ( elem = this[ i++ ] ) ) { curValue = getClass( elem ); cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); if ( cur ) { j = 0; while ( ( clazz = classes[ j++ ] ) ) { if ( cur.indexOf( " " + clazz + " " ) < 0 ) { cur += clazz + " "; } } // Only assign if different to avoid unneeded rendering. finalValue = stripAndCollapse( cur ); if ( curValue !== finalValue ) { elem.setAttribute( "class", finalValue ); } } } } return this; }, removeClass: function( value ) { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; if ( isFunction( value ) ) { return this.each( function( j ) { jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); } ); } if ( !arguments.length ) { return this.attr( "class", "" ); } classes = classesToArray( value ); if ( classes.length ) { while ( ( elem = this[ i++ ] ) ) { curValue = getClass( elem ); // This expression is here for better compressibility (see addClass) cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); if ( cur ) { j = 0; while ( ( clazz = classes[ j++ ] ) ) { // Remove *all* instances while ( cur.indexOf( " " + clazz + " " ) > -1 ) { cur = cur.replace( " " + clazz + " ", " " ); } } // Only assign if different to avoid unneeded rendering. finalValue = stripAndCollapse( cur ); if ( curValue !== finalValue ) { elem.setAttribute( "class", finalValue ); } } } } return this; }, toggleClass: function( value, stateVal ) { var type = typeof value, isValidValue = type === "string" || Array.isArray( value ); if ( typeof stateVal === "boolean" && isValidValue ) { return stateVal ? this.addClass( value ) : this.removeClass( value ); } if ( isFunction( value ) ) { return this.each( function( i ) { jQuery( this ).toggleClass( value.call( this, i, getClass( this ), stateVal ), stateVal ); } ); } return this.each( function() { var className, i, self, classNames; if ( isValidValue ) { // Toggle individual class names i = 0; self = jQuery( this ); classNames = classesToArray( value ); while ( ( className = classNames[ i++ ] ) ) { // Check each className given, space separated list if ( self.hasClass( className ) ) { self.removeClass( className ); } else { self.addClass( className ); } } // Toggle whole class name } else if ( value === undefined || type === "boolean" ) { className = getClass( this ); if ( className ) { // Store className if set dataPriv.set( this, "__className__", className ); } // If the element has a class name or if we're passed `false`, // then remove the whole classname (if there was one, the above saved it). // Otherwise bring back whatever was previously saved (if anything), // falling back to the empty string if nothing was stored. if ( this.setAttribute ) { this.setAttribute( "class", className || value === false ? "" : dataPriv.get( this, "__className__" ) || "" ); } } } ); }, hasClass: function( selector ) { var className, elem, i = 0; className = " " + selector + " "; while ( ( elem = this[ i++ ] ) ) { if ( elem.nodeType === 1 && ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { return true; } } return false; } } ); var rreturn = /\r/g; jQuery.fn.extend( { val: function( value ) { var hooks, ret, valueIsFunction, elem = this[ 0 ]; if ( !arguments.length ) { if ( elem ) { hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; if ( hooks && "get" in hooks && ( ret = hooks.get( elem, "value" ) ) !== undefined ) { return ret; } ret = elem.value; // Handle most common string cases if ( typeof ret === "string" ) { return ret.replace( rreturn, "" ); } // Handle cases where value is null/undef or number return ret == null ? "" : ret; } return; } valueIsFunction = isFunction( value ); return this.each( function( i ) { var val; if ( this.nodeType !== 1 ) { return; } if ( valueIsFunction ) { val = value.call( this, i, jQuery( this ).val() ); } else { val = value; } // Treat null/undefined as ""; convert numbers to string if ( val == null ) { val = ""; } else if ( typeof val === "number" ) { val += ""; } else if ( Array.isArray( val ) ) { val = jQuery.map( val, function( value ) { return value == null ? "" : value + ""; } ); } hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; // If set returns undefined, fall back to normal setting if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { this.value = val; } } ); } } ); jQuery.extend( { valHooks: { option: { get: function( elem ) { var val = jQuery.find.attr( elem, "value" ); return val != null ? val : // Support: IE <=10 - 11 only // option.text throws exceptions (#14686, #14858) // Strip and collapse whitespace // https://html.spec.whatwg.org/#strip-and-collapse-whitespace stripAndCollapse( jQuery.text( elem ) ); } }, select: { get: function( elem ) { var value, option, i, options = elem.options, index = elem.selectedIndex, one = elem.type === "select-one", values = one ? null : [], max = one ? index + 1 : options.length; if ( index < 0 ) { i = max; } else { i = one ? index : 0; } // Loop through all the selected options for ( ; i < max; i++ ) { option = options[ i ]; // Support: IE <=9 only // IE8-9 doesn't update selected after form reset (#2551) if ( ( option.selected || i === index ) && // Don't return options that are disabled or in a disabled optgroup !option.disabled && ( !option.parentNode.disabled || !nodeName( option.parentNode, "optgroup" ) ) ) { // Get the specific value for the option value = jQuery( option ).val(); // We don't need an array for one selects if ( one ) { return value; } // Multi-Selects return an array values.push( value ); } } return values; }, set: function( elem, value ) { var optionSet, option, options = elem.options, values = jQuery.makeArray( value ), i = options.length; while ( i-- ) { option = options[ i ]; /* eslint-disable no-cond-assign */ if ( option.selected = jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 ) { optionSet = true; } /* eslint-enable no-cond-assign */ } // Force browsers to behave consistently when non-matching value is set if ( !optionSet ) { elem.selectedIndex = -1; } return values; } } } } ); // Radios and checkboxes getter/setter jQuery.each( [ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = { set: function( elem, value ) { if ( Array.isArray( value ) ) { return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); } } }; if ( !support.checkOn ) { jQuery.valHooks[ this ].get = function( elem ) { return elem.getAttribute( "value" ) === null ? "on" : elem.value; }; } } ); // Return jQuery for attributes-only inclusion support.focusin = "onfocusin" in window; var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, stopPropagationCallback = function( e ) { e.stopPropagation(); }; jQuery.extend( jQuery.event, { trigger: function( event, data, elem, onlyHandlers ) { var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, eventPath = [ elem || document ], type = hasOwn.call( event, "type" ) ? event.type : event, namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; cur = lastElement = tmp = elem = elem || document; // Don't do events on text and comment nodes if ( elem.nodeType === 3 || elem.nodeType === 8 ) { return; } // focus/blur morphs to focusin/out; ensure we're not firing them right now if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { return; } if ( type.indexOf( "." ) > -1 ) { // Namespaced trigger; create a regexp to match event type in handle() namespaces = type.split( "." ); type = namespaces.shift(); namespaces.sort(); } ontype = type.indexOf( ":" ) < 0 && "on" + type; // Caller can pass in a jQuery.Event object, Object, or just an event type string event = event[ jQuery.expando ] ? event : new jQuery.Event( type, typeof event === "object" && event ); // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) event.isTrigger = onlyHandlers ? 2 : 3; event.namespace = namespaces.join( "." ); event.rnamespace = event.namespace ? new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : null; // Clean up the event in case it is being reused event.result = undefined; if ( !event.target ) { event.target = elem; } // Clone any incoming data and prepend the event, creating the handler arg list data = data == null ? [ event ] : jQuery.makeArray( data, [ event ] ); // Allow special events to draw outside the lines special = jQuery.event.special[ type ] || {}; if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { return; } // Determine event propagation path in advance, per W3C events spec (#9951) // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { bubbleType = special.delegateType || type; if ( !rfocusMorph.test( bubbleType + type ) ) { cur = cur.parentNode; } for ( ; cur; cur = cur.parentNode ) { eventPath.push( cur ); tmp = cur; } // Only add window if we got to document (e.g., not plain obj or detached DOM) if ( tmp === ( elem.ownerDocument || document ) ) { eventPath.push( tmp.defaultView || tmp.parentWindow || window ); } } // Fire handlers on the event path i = 0; while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { lastElement = cur; event.type = i > 1 ? bubbleType : special.bindType || type; // jQuery handler handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && dataPriv.get( cur, "handle" ); if ( handle ) { handle.apply( cur, data ); } // Native handler handle = ontype && cur[ ontype ]; if ( handle && handle.apply && acceptData( cur ) ) { event.result = handle.apply( cur, data ); if ( event.result === false ) { event.preventDefault(); } } } event.type = type; // If nobody prevented the default action, do it now if ( !onlyHandlers && !event.isDefaultPrevented() ) { if ( ( !special._default || special._default.apply( eventPath.pop(), data ) === false ) && acceptData( elem ) ) { // Call a native DOM method on the target with the same name as the event. // Don't do default actions on window, that's where global variables be (#6170) if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { // Don't re-trigger an onFOO event when we call its FOO() method tmp = elem[ ontype ]; if ( tmp ) { elem[ ontype ] = null; } // Prevent re-triggering of the same event, since we already bubbled it above jQuery.event.triggered = type; if ( event.isPropagationStopped() ) { lastElement.addEventListener( type, stopPropagationCallback ); } elem[ type ](); if ( event.isPropagationStopped() ) { lastElement.removeEventListener( type, stopPropagationCallback ); } jQuery.event.triggered = undefined; if ( tmp ) { elem[ ontype ] = tmp; } } } } return event.result; }, // Piggyback on a donor event to simulate a different one // Used only for `focus(in | out)` events simulate: function( type, elem, event ) { var e = jQuery.extend( new jQuery.Event(), event, { type: type, isSimulated: true } ); jQuery.event.trigger( e, null, elem ); } } ); jQuery.fn.extend( { trigger: function( type, data ) { return this.each( function() { jQuery.event.trigger( type, data, this ); } ); }, triggerHandler: function( type, data ) { var elem = this[ 0 ]; if ( elem ) { return jQuery.event.trigger( type, data, elem, true ); } } } ); // Support: Firefox <=44 // Firefox doesn't have focus(in | out) events // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 // // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 // focus(in | out) events fire after focus & blur events, // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 if ( !support.focusin ) { jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { // Attach a single capturing handler on the document while someone wants focusin/focusout var handler = function( event ) { jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); }; jQuery.event.special[ fix ] = { setup: function() { var doc = this.ownerDocument || this, attaches = dataPriv.access( doc, fix ); if ( !attaches ) { doc.addEventListener( orig, handler, true ); } dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); }, teardown: function() { var doc = this.ownerDocument || this, attaches = dataPriv.access( doc, fix ) - 1; if ( !attaches ) { doc.removeEventListener( orig, handler, true ); dataPriv.remove( doc, fix ); } else { dataPriv.access( doc, fix, attaches ); } } }; } ); } var location = window.location; var nonce = Date.now(); var rquery = ( /\?/ ); // Cross-browser xml parsing jQuery.parseXML = function( data ) { var xml; if ( !data || typeof data !== "string" ) { return null; } // Support: IE 9 - 11 only // IE throws on parseFromString with invalid input. try { xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); } catch ( e ) { xml = undefined; } if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { jQuery.error( "Invalid XML: " + data ); } return xml; }; var rbracket = /\[\]$/, rCRLF = /\r?\n/g, rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, rsubmittable = /^(?:input|select|textarea|keygen)/i; function buildParams( prefix, obj, traditional, add ) { var name; if ( Array.isArray( obj ) ) { // Serialize array item. jQuery.each( obj, function( i, v ) { if ( traditional || rbracket.test( prefix ) ) { // Treat each array item as a scalar. add( prefix, v ); } else { // Item is non-scalar (array or object), encode its numeric index. buildParams( prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", v, traditional, add ); } } ); } else if ( !traditional && toType( obj ) === "object" ) { // Serialize object item. for ( name in obj ) { buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); } } else { // Serialize scalar item. add( prefix, obj ); } } // Serialize an array of form elements or a set of // key/values into a query string jQuery.param = function( a, traditional ) { var prefix, s = [], add = function( key, valueOrFunction ) { // If value is a function, invoke it and use its return value var value = isFunction( valueOrFunction ) ? valueOrFunction() : valueOrFunction; s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value == null ? "" : value ); }; // If an array was passed in, assume that it is an array of form elements. if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { // Serialize the form elements jQuery.each( a, function() { add( this.name, this.value ); } ); } else { // If traditional, encode the "old" way (the way 1.3.2 or older // did it), otherwise encode params recursively. for ( prefix in a ) { buildParams( prefix, a[ prefix ], traditional, add ); } } // Return the resulting serialization return s.join( "&" ); }; jQuery.fn.extend( { serialize: function() { return jQuery.param( this.serializeArray() ); }, serializeArray: function() { return this.map( function() { // Can add propHook for "elements" to filter or add form elements var elements = jQuery.prop( this, "elements" ); return elements ? jQuery.makeArray( elements ) : this; } ) .filter( function() { var type = this.type; // Use .is( ":disabled" ) so that fieldset[disabled] works return this.name && !jQuery( this ).is( ":disabled" ) && rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && ( this.checked || !rcheckableType.test( type ) ); } ) .map( function( i, elem ) { var val = jQuery( this ).val(); if ( val == null ) { return null; } if ( Array.isArray( val ) ) { return jQuery.map( val, function( val ) { return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; } ); } return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; } ).get(); } } ); var r20 = /%20/g, rhash = /#.*$/, rantiCache = /([?&])_=[^&]*/, rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, // #7653, #8125, #8152: local protocol detection rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, /* Prefilters * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) * 2) These are called: * - BEFORE asking for a transport * - AFTER param serialization (s.data is a string if s.processData is true) * 3) key is the dataType * 4) the catchall symbol "*" can be used * 5) execution will start with transport dataType and THEN continue down to "*" if needed */ prefilters = {}, /* Transports bindings * 1) key is the dataType * 2) the catchall symbol "*" can be used * 3) selection will start with transport dataType and THEN go to "*" if needed */ transports = {}, // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression allTypes = "*/".concat( "*" ), // Anchor tag for parsing the document origin originAnchor = document.createElement( "a" ); originAnchor.href = location.href; // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport function addToPrefiltersOrTransports( structure ) { // dataTypeExpression is optional and defaults to "*" return function( dataTypeExpression, func ) { if ( typeof dataTypeExpression !== "string" ) { func = dataTypeExpression; dataTypeExpression = "*"; } var dataType, i = 0, dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; if ( isFunction( func ) ) { // For each dataType in the dataTypeExpression while ( ( dataType = dataTypes[ i++ ] ) ) { // Prepend if requested if ( dataType[ 0 ] === "+" ) { dataType = dataType.slice( 1 ) || "*"; ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); // Otherwise append } else { ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); } } } }; } // Base inspection function for prefilters and transports function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { var inspected = {}, seekingTransport = ( structure === transports ); function inspect( dataType ) { var selected; inspected[ dataType ] = true; jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { options.dataTypes.unshift( dataTypeOrTransport ); inspect( dataTypeOrTransport ); return false; } else if ( seekingTransport ) { return !( selected = dataTypeOrTransport ); } } ); return selected; } return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); } // A special extend for ajax options // that takes "flat" options (not to be deep extended) // Fixes #9887 function ajaxExtend( target, src ) { var key, deep, flatOptions = jQuery.ajaxSettings.flatOptions || {}; for ( key in src ) { if ( src[ key ] !== undefined ) { ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; } } if ( deep ) { jQuery.extend( true, target, deep ); } return target; } /* Handles responses to an ajax request: * - finds the right dataType (mediates between content-type and expected dataType) * - returns the corresponding response */ function ajaxHandleResponses( s, jqXHR, responses ) { var ct, type, finalDataType, firstDataType, contents = s.contents, dataTypes = s.dataTypes; // Remove auto dataType and get content-type in the process while ( dataTypes[ 0 ] === "*" ) { dataTypes.shift(); if ( ct === undefined ) { ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); } } // Check if we're dealing with a known content-type if ( ct ) { for ( type in contents ) { if ( contents[ type ] && contents[ type ].test( ct ) ) { dataTypes.unshift( type ); break; } } } // Check to see if we have a response for the expected dataType if ( dataTypes[ 0 ] in responses ) { finalDataType = dataTypes[ 0 ]; } else { // Try convertible dataTypes for ( type in responses ) { if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { finalDataType = type; break; } if ( !firstDataType ) { firstDataType = type; } } // Or just use first one finalDataType = finalDataType || firstDataType; } // If we found a dataType // We add the dataType to the list if needed // and return the corresponding response if ( finalDataType ) { if ( finalDataType !== dataTypes[ 0 ] ) { dataTypes.unshift( finalDataType ); } return responses[ finalDataType ]; } } /* Chain conversions given the request and the original response * Also sets the responseXXX fields on the jqXHR instance */ function ajaxConvert( s, response, jqXHR, isSuccess ) { var conv2, current, conv, tmp, prev, converters = {}, // Work with a copy of dataTypes in case we need to modify it for conversion dataTypes = s.dataTypes.slice(); // Create converters map with lowercased keys if ( dataTypes[ 1 ] ) { for ( conv in s.converters ) { converters[ conv.toLowerCase() ] = s.converters[ conv ]; } } current = dataTypes.shift(); // Convert to each sequential dataType while ( current ) { if ( s.responseFields[ current ] ) { jqXHR[ s.responseFields[ current ] ] = response; } // Apply the dataFilter if provided if ( !prev && isSuccess && s.dataFilter ) { response = s.dataFilter( response, s.dataType ); } prev = current; current = dataTypes.shift(); if ( current ) { // There's only work to do if current dataType is non-auto if ( current === "*" ) { current = prev; // Convert response if prev dataType is non-auto and differs from current } else if ( prev !== "*" && prev !== current ) { // Seek a direct converter conv = converters[ prev + " " + current ] || converters[ "* " + current ]; // If none found, seek a pair if ( !conv ) { for ( conv2 in converters ) { // If conv2 outputs current tmp = conv2.split( " " ); if ( tmp[ 1 ] === current ) { // If prev can be converted to accepted input conv = converters[ prev + " " + tmp[ 0 ] ] || converters[ "* " + tmp[ 0 ] ]; if ( conv ) { // Condense equivalence converters if ( conv === true ) { conv = converters[ conv2 ]; // Otherwise, insert the intermediate dataType } else if ( converters[ conv2 ] !== true ) { current = tmp[ 0 ]; dataTypes.unshift( tmp[ 1 ] ); } break; } } } } // Apply converter (if not an equivalence) if ( conv !== true ) { // Unless errors are allowed to bubble, catch and return them if ( conv && s.throws ) { response = conv( response ); } else { try { response = conv( response ); } catch ( e ) { return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; } } } } } } return { state: "success", data: response }; } jQuery.extend( { // Counter for holding the number of active queries active: 0, // Last-Modified header cache for next request lastModified: {}, etag: {}, ajaxSettings: { url: location.href, type: "GET", isLocal: rlocalProtocol.test( location.protocol ), global: true, processData: true, async: true, contentType: "application/x-www-form-urlencoded; charset=UTF-8", /* timeout: 0, data: null, dataType: null, username: null, password: null, cache: null, throws: false, traditional: false, headers: {}, */ accepts: { "*": allTypes, text: "text/plain", html: "text/html", xml: "application/xml, text/xml", json: "application/json, text/javascript" }, contents: { xml: /\bxml\b/, html: /\bhtml/, json: /\bjson\b/ }, responseFields: { xml: "responseXML", text: "responseText", json: "responseJSON" }, // Data converters // Keys separate source (or catchall "*") and destination types with a single space converters: { // Convert anything to text "* text": String, // Text to html (true = no transformation) "text html": true, // Evaluate text as a json expression "text json": JSON.parse, // Parse text as xml "text xml": jQuery.parseXML }, // For options that shouldn't be deep extended: // you can add your own custom options here if // and when you create one that shouldn't be // deep extended (see ajaxExtend) flatOptions: { url: true, context: true } }, // Creates a full fledged settings object into target // with both ajaxSettings and settings fields. // If target is omitted, writes into ajaxSettings. ajaxSetup: function( target, settings ) { return settings ? // Building a settings object ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : // Extending ajaxSettings ajaxExtend( jQuery.ajaxSettings, target ); }, ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), ajaxTransport: addToPrefiltersOrTransports( transports ), // Main method ajax: function( url, options ) { // If url is an object, simulate pre-1.5 signature if ( typeof url === "object" ) { options = url; url = undefined; } // Force options to be an object options = options || {}; var transport, // URL without anti-cache param cacheURL, // Response headers responseHeadersString, responseHeaders, // timeout handle timeoutTimer, // Url cleanup var urlAnchor, // Request state (becomes false upon send and true upon completion) completed, // To know if global events are to be dispatched fireGlobals, // Loop variable i, // uncached part of the url uncached, // Create the final options object s = jQuery.ajaxSetup( {}, options ), // Callbacks context callbackContext = s.context || s, // Context for global events is callbackContext if it is a DOM node or jQuery collection globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? jQuery( callbackContext ) : jQuery.event, // Deferreds deferred = jQuery.Deferred(), completeDeferred = jQuery.Callbacks( "once memory" ), // Status-dependent callbacks statusCode = s.statusCode || {}, // Headers (they are sent all at once) requestHeaders = {}, requestHeadersNames = {}, // Default abort message strAbort = "canceled", // Fake xhr jqXHR = { readyState: 0, // Builds headers hashtable if needed getResponseHeader: function( key ) { var match; if ( completed ) { if ( !responseHeaders ) { responseHeaders = {}; while ( ( match = rheaders.exec( responseHeadersString ) ) ) { responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; } } match = responseHeaders[ key.toLowerCase() ]; } return match == null ? null : match; }, // Raw string getAllResponseHeaders: function() { return completed ? responseHeadersString : null; }, // Caches the header setRequestHeader: function( name, value ) { if ( completed == null ) { name = requestHeadersNames[ name.toLowerCase() ] = requestHeadersNames[ name.toLowerCase() ] || name; requestHeaders[ name ] = value; } return this; }, // Overrides response content-type header overrideMimeType: function( type ) { if ( completed == null ) { s.mimeType = type; } return this; }, // Status-dependent callbacks statusCode: function( map ) { var code; if ( map ) { if ( completed ) { // Execute the appropriate callbacks jqXHR.always( map[ jqXHR.status ] ); } else { // Lazy-add the new callbacks in a way that preserves old ones for ( code in map ) { statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; } } } return this; }, // Cancel the request abort: function( statusText ) { var finalText = statusText || strAbort; if ( transport ) { transport.abort( finalText ); } done( 0, finalText ); return this; } }; // Attach deferreds deferred.promise( jqXHR ); // Add protocol if not provided (prefilters might expect it) // Handle falsy url in the settings object (#10093: consistency with old signature) // We also use the url parameter if available s.url = ( ( url || s.url || location.href ) + "" ) .replace( rprotocol, location.protocol + "//" ); // Alias method option to type as per ticket #12004 s.type = options.method || options.type || s.method || s.type; // Extract dataTypes list s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; // A cross-domain request is in order when the origin doesn't match the current origin. if ( s.crossDomain == null ) { urlAnchor = document.createElement( "a" ); // Support: IE <=8 - 11, Edge 12 - 15 // IE throws exception on accessing the href property if url is malformed, // e.g. http://example.com:80x/ try { urlAnchor.href = s.url; // Support: IE <=8 - 11 only // Anchor's host property isn't correctly set when s.url is relative urlAnchor.href = urlAnchor.href; s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== urlAnchor.protocol + "//" + urlAnchor.host; } catch ( e ) { // If there is an error parsing the URL, assume it is crossDomain, // it can be rejected by the transport if it is invalid s.crossDomain = true; } } // Convert data if not already a string if ( s.data && s.processData && typeof s.data !== "string" ) { s.data = jQuery.param( s.data, s.traditional ); } // Apply prefilters inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); // If request was aborted inside a prefilter, stop there if ( completed ) { return jqXHR; } // We can fire global events as of now if asked to // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) fireGlobals = jQuery.event && s.global; // Watch for a new set of requests if ( fireGlobals && jQuery.active++ === 0 ) { jQuery.event.trigger( "ajaxStart" ); } // Uppercase the type s.type = s.type.toUpperCase(); // Determine if request has content s.hasContent = !rnoContent.test( s.type ); // Save the URL in case we're toying with the If-Modified-Since // and/or If-None-Match header later on // Remove hash to simplify url manipulation cacheURL = s.url.replace( rhash, "" ); // More options handling for requests with no content if ( !s.hasContent ) { // Remember the hash so we can put it back uncached = s.url.slice( cacheURL.length ); // If data is available and should be processed, append data to url if ( s.data && ( s.processData || typeof s.data === "string" ) ) { cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; // #9682: remove data so that it's not used in an eventual retry delete s.data; } // Add or update anti-cache param if needed if ( s.cache === false ) { cacheURL = cacheURL.replace( rantiCache, "$1" ); uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; } // Put hash and anti-cache on the URL that will be requested (gh-1732) s.url = cacheURL + uncached; // Change '%20' to '+' if this is encoded form body content (gh-2658) } else if ( s.data && s.processData && ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { s.data = s.data.replace( r20, "+" ); } // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { if ( jQuery.lastModified[ cacheURL ] ) { jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); } if ( jQuery.etag[ cacheURL ] ) { jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); } } // Set the correct header, if data is being sent if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { jqXHR.setRequestHeader( "Content-Type", s.contentType ); } // Set the Accepts header for the server, depending on the dataType jqXHR.setRequestHeader( "Accept", s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? s.accepts[ s.dataTypes[ 0 ] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : s.accepts[ "*" ] ); // Check for headers option for ( i in s.headers ) { jqXHR.setRequestHeader( i, s.headers[ i ] ); } // Allow custom headers/mimetypes and early abort if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { // Abort if not done already and return return jqXHR.abort(); } // Aborting is no longer a cancellation strAbort = "abort"; // Install callbacks on deferreds completeDeferred.add( s.complete ); jqXHR.done( s.success ); jqXHR.fail( s.error ); // Get transport transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); // If no transport, we auto-abort if ( !transport ) { done( -1, "No Transport" ); } else { jqXHR.readyState = 1; // Send global event if ( fireGlobals ) { globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); } // If request was aborted inside ajaxSend, stop there if ( completed ) { return jqXHR; } // Timeout if ( s.async && s.timeout > 0 ) { timeoutTimer = window.setTimeout( function() { jqXHR.abort( "timeout" ); }, s.timeout ); } try { completed = false; transport.send( requestHeaders, done ); } catch ( e ) { // Rethrow post-completion exceptions if ( completed ) { throw e; } // Propagate others as results done( -1, e ); } } // Callback for when everything is done function done( status, nativeStatusText, responses, headers ) { var isSuccess, success, error, response, modified, statusText = nativeStatusText; // Ignore repeat invocations if ( completed ) { return; } completed = true; // Clear timeout if it exists if ( timeoutTimer ) { window.clearTimeout( timeoutTimer ); } // Dereference transport for early garbage collection // (no matter how long the jqXHR object will be used) transport = undefined; // Cache response headers responseHeadersString = headers || ""; // Set readyState jqXHR.readyState = status > 0 ? 4 : 0; // Determine if successful isSuccess = status >= 200 && status < 300 || status === 304; // Get response data if ( responses ) { response = ajaxHandleResponses( s, jqXHR, responses ); } // Convert no matter what (that way responseXXX fields are always set) response = ajaxConvert( s, response, jqXHR, isSuccess ); // If successful, handle type chaining if ( isSuccess ) { // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { modified = jqXHR.getResponseHeader( "Last-Modified" ); if ( modified ) { jQuery.lastModified[ cacheURL ] = modified; } modified = jqXHR.getResponseHeader( "etag" ); if ( modified ) { jQuery.etag[ cacheURL ] = modified; } } // if no content if ( status === 204 || s.type === "HEAD" ) { statusText = "nocontent"; // if not modified } else if ( status === 304 ) { statusText = "notmodified"; // If we have data, let's convert it } else { statusText = response.state; success = response.data; error = response.error; isSuccess = !error; } } else { // Extract error from statusText and normalize for non-aborts error = statusText; if ( status || !statusText ) { statusText = "error"; if ( status < 0 ) { status = 0; } } } // Set data for the fake xhr object jqXHR.status = status; jqXHR.statusText = ( nativeStatusText || statusText ) + ""; // Success/Error if ( isSuccess ) { deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); } else { deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); } // Status-dependent callbacks jqXHR.statusCode( statusCode ); statusCode = undefined; if ( fireGlobals ) { globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", [ jqXHR, s, isSuccess ? success : error ] ); } // Complete completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); if ( fireGlobals ) { globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); // Handle the global AJAX counter if ( !( --jQuery.active ) ) { jQuery.event.trigger( "ajaxStop" ); } } } return jqXHR; }, getJSON: function( url, data, callback ) { return jQuery.get( url, data, callback, "json" ); }, getScript: function( url, callback ) { return jQuery.get( url, undefined, callback, "script" ); } } ); jQuery.each( [ "get", "post" ], function( i, method ) { jQuery[ method ] = function( url, data, callback, type ) { // Shift arguments if data argument was omitted if ( isFunction( data ) ) { type = type || callback; callback = data; data = undefined; } // The url can be an options object (which then must have .url) return jQuery.ajax( jQuery.extend( { url: url, type: method, dataType: type, data: data, success: callback }, jQuery.isPlainObject( url ) && url ) ); }; } ); jQuery._evalUrl = function( url ) { return jQuery.ajax( { url: url, // Make this explicit, since user can override this through ajaxSetup (#11264) type: "GET", dataType: "script", cache: true, async: false, global: false, "throws": true } ); }; jQuery.fn.extend( { wrapAll: function( html ) { var wrap; if ( this[ 0 ] ) { if ( isFunction( html ) ) { html = html.call( this[ 0 ] ); } // The elements to wrap the target around wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); if ( this[ 0 ].parentNode ) { wrap.insertBefore( this[ 0 ] ); } wrap.map( function() { var elem = this; while ( elem.firstElementChild ) { elem = elem.firstElementChild; } return elem; } ).append( this ); } return this; }, wrapInner: function( html ) { if ( isFunction( html ) ) { return this.each( function( i ) { jQuery( this ).wrapInner( html.call( this, i ) ); } ); } return this.each( function() { var self = jQuery( this ), contents = self.contents(); if ( contents.length ) { contents.wrapAll( html ); } else { self.append( html ); } } ); }, wrap: function( html ) { var htmlIsFunction = isFunction( html ); return this.each( function( i ) { jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); } ); }, unwrap: function( selector ) { this.parent( selector ).not( "body" ).each( function() { jQuery( this ).replaceWith( this.childNodes ); } ); return this; } } ); jQuery.expr.pseudos.hidden = function( elem ) { return !jQuery.expr.pseudos.visible( elem ); }; jQuery.expr.pseudos.visible = function( elem ) { return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); }; jQuery.ajaxSettings.xhr = function() { try { return new window.XMLHttpRequest(); } catch ( e ) {} }; var xhrSuccessStatus = { // File protocol always yields status code 0, assume 200 0: 200, // Support: IE <=9 only // #1450: sometimes IE returns 1223 when it should be 204 1223: 204 }, xhrSupported = jQuery.ajaxSettings.xhr(); support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); support.ajax = xhrSupported = !!xhrSupported; jQuery.ajaxTransport( function( options ) { var callback, errorCallback; // Cross domain only allowed if supported through XMLHttpRequest if ( support.cors || xhrSupported && !options.crossDomain ) { return { send: function( headers, complete ) { var i, xhr = options.xhr(); xhr.open( options.type, options.url, options.async, options.username, options.password ); // Apply custom fields if provided if ( options.xhrFields ) { for ( i in options.xhrFields ) { xhr[ i ] = options.xhrFields[ i ]; } } // Override mime type if needed if ( options.mimeType && xhr.overrideMimeType ) { xhr.overrideMimeType( options.mimeType ); } // X-Requested-With header // For cross-domain requests, seeing as conditions for a preflight are // akin to a jigsaw puzzle, we simply never set it to be sure. // (it can always be set on a per-request basis or even using ajaxSetup) // For same-domain requests, won't change header if already provided. if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { headers[ "X-Requested-With" ] = "XMLHttpRequest"; } // Set headers for ( i in headers ) { xhr.setRequestHeader( i, headers[ i ] ); } // Callback callback = function( type ) { return function() { if ( callback ) { callback = errorCallback = xhr.onload = xhr.onerror = xhr.onabort = xhr.ontimeout = xhr.onreadystatechange = null; if ( type === "abort" ) { xhr.abort(); } else if ( type === "error" ) { // Support: IE <=9 only // On a manual native abort, IE9 throws // errors on any property access that is not readyState if ( typeof xhr.status !== "number" ) { complete( 0, "error" ); } else { complete( // File: protocol always yields status 0; see #8605, #14207 xhr.status, xhr.statusText ); } } else { complete( xhrSuccessStatus[ xhr.status ] || xhr.status, xhr.statusText, // Support: IE <=9 only // IE9 has no XHR2 but throws on binary (trac-11426) // For XHR2 non-text, let the caller handle it (gh-2498) ( xhr.responseType || "text" ) !== "text" || typeof xhr.responseText !== "string" ? { binary: xhr.response } : { text: xhr.responseText }, xhr.getAllResponseHeaders() ); } } }; }; // Listen to events xhr.onload = callback(); errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); // Support: IE 9 only // Use onreadystatechange to replace onabort // to handle uncaught aborts if ( xhr.onabort !== undefined ) { xhr.onabort = errorCallback; } else { xhr.onreadystatechange = function() { // Check readyState before timeout as it changes if ( xhr.readyState === 4 ) { // Allow onerror to be called first, // but that will not handle a native abort // Also, save errorCallback to a variable // as xhr.onerror cannot be accessed window.setTimeout( function() { if ( callback ) { errorCallback(); } } ); } }; } // Create the abort callback callback = callback( "abort" ); try { // Do send the request (this may raise an exception) xhr.send( options.hasContent && options.data || null ); } catch ( e ) { // #14683: Only rethrow if this hasn't been notified as an error yet if ( callback ) { throw e; } } }, abort: function() { if ( callback ) { callback(); } } }; } } ); // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) jQuery.ajaxPrefilter( function( s ) { if ( s.crossDomain ) { s.contents.script = false; } } ); // Install script dataType jQuery.ajaxSetup( { accepts: { script: "text/javascript, application/javascript, " + "application/ecmascript, application/x-ecmascript" }, contents: { script: /\b(?:java|ecma)script\b/ }, converters: { "text script": function( text ) { jQuery.globalEval( text ); return text; } } } ); // Handle cache's special case and crossDomain jQuery.ajaxPrefilter( "script", function( s ) { if ( s.cache === undefined ) { s.cache = false; } if ( s.crossDomain ) { s.type = "GET"; } } ); // Bind script tag hack transport jQuery.ajaxTransport( "script", function( s ) { // This transport only deals with cross domain requests if ( s.crossDomain ) { var script, callback; return { send: function( _, complete ) { script = jQuery( "<script>" ).prop( { charset: s.scriptCharset, src: s.url } ).on( "load error", callback = function( evt ) { script.remove(); callback = null; if ( evt ) { complete( evt.type === "error" ? 404 : 200, evt.type ); } } ); // Use native DOM manipulation to avoid our domManip AJAX trickery document.head.appendChild( script[ 0 ] ); }, abort: function() { if ( callback ) { callback(); } } }; } } ); var oldCallbacks = [], rjsonp = /(=)\?(?=&|$)|\?\?/; // Default jsonp settings jQuery.ajaxSetup( { jsonp: "callback", jsonpCallback: function() { var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); this[ callback ] = true; return callback; } } ); // Detect, normalize options and install callbacks for jsonp requests jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { var callbackName, overwritten, responseContainer, jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? "url" : typeof s.data === "string" && ( s.contentType || "" ) .indexOf( "application/x-www-form-urlencoded" ) === 0 && rjsonp.test( s.data ) && "data" ); // Handle iff the expected data type is "jsonp" or we have a parameter to set if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { // Get callback name, remembering preexisting value associated with it callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback; // Insert callback into url or form data if ( jsonProp ) { s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); } else if ( s.jsonp !== false ) { s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; } // Use data converter to retrieve json after script execution s.converters[ "script json" ] = function() { if ( !responseContainer ) { jQuery.error( callbackName + " was not called" ); } return responseContainer[ 0 ]; }; // Force json dataType s.dataTypes[ 0 ] = "json"; // Install callback overwritten = window[ callbackName ]; window[ callbackName ] = function() { responseContainer = arguments; }; // Clean-up function (fires after converters) jqXHR.always( function() { // If previous value didn't exist - remove it if ( overwritten === undefined ) { jQuery( window ).removeProp( callbackName ); // Otherwise restore preexisting value } else { window[ callbackName ] = overwritten; } // Save back as free if ( s[ callbackName ] ) { // Make sure that re-using the options doesn't screw things around s.jsonpCallback = originalSettings.jsonpCallback; // Save the callback name for future use oldCallbacks.push( callbackName ); } // Call if it was a function and we have a response if ( responseContainer && isFunction( overwritten ) ) { overwritten( responseContainer[ 0 ] ); } responseContainer = overwritten = undefined; } ); // Delegate to script return "script"; } } ); // Support: Safari 8 only // In Safari 8 documents created via document.implementation.createHTMLDocument // collapse sibling forms: the second one becomes a child of the first one. // Because of that, this security measure has to be disabled in Safari 8. // https://bugs.webkit.org/show_bug.cgi?id=137337 support.createHTMLDocument = ( function() { var body = document.implementation.createHTMLDocument( "" ).body; body.innerHTML = "<form></form><form></form>"; return body.childNodes.length === 2; } )(); // Argument "data" should be string of html // context (optional): If specified, the fragment will be created in this context, // defaults to document // keepScripts (optional): If true, will include scripts passed in the html string jQuery.parseHTML = function( data, context, keepScripts ) { if ( typeof data !== "string" ) { return []; } if ( typeof context === "boolean" ) { keepScripts = context; context = false; } var base, parsed, scripts; if ( !context ) { // Stop scripts or inline event handlers from being executed immediately // by using document.implementation if ( support.createHTMLDocument ) { context = document.implementation.createHTMLDocument( "" ); // Set the base href for the created document // so any parsed elements with URLs // are based on the document's URL (gh-2965) base = context.createElement( "base" ); base.href = document.location.href; context.head.appendChild( base ); } else { context = document; } } parsed = rsingleTag.exec( data ); scripts = !keepScripts && []; // Single tag if ( parsed ) { return [ context.createElement( parsed[ 1 ] ) ]; } parsed = buildFragment( [ data ], context, scripts ); if ( scripts && scripts.length ) { jQuery( scripts ).remove(); } return jQuery.merge( [], parsed.childNodes ); }; /** * Load a url into a page */ jQuery.fn.load = function( url, params, callback ) { var selector, type, response, self = this, off = url.indexOf( " " ); if ( off > -1 ) { selector = stripAndCollapse( url.slice( off ) ); url = url.slice( 0, off ); } // If it's a function if ( isFunction( params ) ) { // We assume that it's the callback callback = params; params = undefined; // Otherwise, build a param string } else if ( params && typeof params === "object" ) { type = "POST"; } // If we have elements to modify, make the request if ( self.length > 0 ) { jQuery.ajax( { url: url, // If "type" variable is undefined, then "GET" method will be used. // Make value of this field explicit since // user can override it through ajaxSetup method type: type || "GET", dataType: "html", data: params } ).done( function( responseText ) { // Save response for use in complete callback response = arguments; self.html( selector ? // If a selector was specified, locate the right elements in a dummy div // Exclude scripts to avoid IE 'Permission Denied' errors jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : // Otherwise use the full result responseText ); // If the request succeeds, this function gets "data", "status", "jqXHR" // but they are ignored because response was set above. // If it fails, this function gets "jqXHR", "status", "error" } ).always( callback && function( jqXHR, status ) { self.each( function() { callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); } ); } ); } return this; }; // Attach a bunch of functions for handling common AJAX events jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) { jQuery.fn[ type ] = function( fn ) { return this.on( type, fn ); }; } ); jQuery.expr.pseudos.animated = function( elem ) { return jQuery.grep( jQuery.timers, function( fn ) { return elem === fn.elem; } ).length; }; jQuery.offset = { setOffset: function( elem, options, i ) { var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, position = jQuery.css( elem, "position" ), curElem = jQuery( elem ), props = {}; // Set position first, in-case top/left are set even on static elem if ( position === "static" ) { elem.style.position = "relative"; } curOffset = curElem.offset(); curCSSTop = jQuery.css( elem, "top" ); curCSSLeft = jQuery.css( elem, "left" ); calculatePosition = ( position === "absolute" || position === "fixed" ) && ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; // Need to be able to calculate position if either // top or left is auto and position is either absolute or fixed if ( calculatePosition ) { curPosition = curElem.position(); curTop = curPosition.top; curLeft = curPosition.left; } else { curTop = parseFloat( curCSSTop ) || 0; curLeft = parseFloat( curCSSLeft ) || 0; } if ( isFunction( options ) ) { // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); } if ( options.top != null ) { props.top = ( options.top - curOffset.top ) + curTop; } if ( options.left != null ) { props.left = ( options.left - curOffset.left ) + curLeft; } if ( "using" in options ) { options.using.call( elem, props ); } else { curElem.css( props ); } } }; jQuery.fn.extend( { // offset() relates an element's border box to the document origin offset: function( options ) { // Preserve chaining for setter if ( arguments.length ) { return options === undefined ? this : this.each( function( i ) { jQuery.offset.setOffset( this, options, i ); } ); } var rect, win, elem = this[ 0 ]; if ( !elem ) { return; } // Return zeros for disconnected and hidden (display: none) elements (gh-2310) // Support: IE <=11 only // Running getBoundingClientRect on a // disconnected node in IE throws an error if ( !elem.getClientRects().length ) { return { top: 0, left: 0 }; } // Get document-relative position by adding viewport scroll to viewport-relative gBCR rect = elem.getBoundingClientRect(); win = elem.ownerDocument.defaultView; return { top: rect.top + win.pageYOffset, left: rect.left + win.pageXOffset }; }, // position() relates an element's margin box to its offset parent's padding box // This corresponds to the behavior of CSS absolute positioning position: function() { if ( !this[ 0 ] ) { return; } var offsetParent, offset, doc, elem = this[ 0 ], parentOffset = { top: 0, left: 0 }; // position:fixed elements are offset from the viewport, which itself always has zero offset if ( jQuery.css( elem, "position" ) === "fixed" ) { // Assume position:fixed implies availability of getBoundingClientRect offset = elem.getBoundingClientRect(); } else { offset = this.offset(); // Account for the *real* offset parent, which can be the document or its root element // when a statically positioned element is identified doc = elem.ownerDocument; offsetParent = elem.offsetParent || doc.documentElement; while ( offsetParent && ( offsetParent === doc.body || offsetParent === doc.documentElement ) && jQuery.css( offsetParent, "position" ) === "static" ) { offsetParent = offsetParent.parentNode; } if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { // Incorporate borders into its offset, since they are outside its content origin parentOffset = jQuery( offsetParent ).offset(); parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true ); } } // Subtract parent offsets and element margins return { top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) }; }, // This method will return documentElement in the following cases: // 1) For the element inside the iframe without offsetParent, this method will return // documentElement of the parent window // 2) For the hidden or detached element // 3) For body or html element, i.e. in case of the html node - it will return itself // // but those exceptions were never presented as a real life use-cases // and might be considered as more preferable results. // // This logic, however, is not guaranteed and can change at any point in the future offsetParent: function() { return this.map( function() { var offsetParent = this.offsetParent; while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { offsetParent = offsetParent.offsetParent; } return offsetParent || documentElement; } ); } } ); // Create scrollLeft and scrollTop methods jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { var top = "pageYOffset" === prop; jQuery.fn[ method ] = function( val ) { return access( this, function( elem, method, val ) { // Coalesce documents and windows var win; if ( isWindow( elem ) ) { win = elem; } else if ( elem.nodeType === 9 ) { win = elem.defaultView; } if ( val === undefined ) { return win ? win[ prop ] : elem[ method ]; } if ( win ) { win.scrollTo( !top ? val : win.pageXOffset, top ? val : win.pageYOffset ); } else { elem[ method ] = val; } }, method, val, arguments.length ); }; } ); // Support: Safari <=7 - 9.1, Chrome <=37 - 49 // Add the top/left cssHooks using jQuery.fn.position // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 // getComputedStyle returns percent when specified for top/left/bottom/right; // rather than make the css module depend on the offset module, just check for it here jQuery.each( [ "top", "left" ], function( i, prop ) { jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, function( elem, computed ) { if ( computed ) { computed = curCSS( elem, prop ); // If curCSS returns percentage, fallback to offset return rnumnonpx.test( computed ) ? jQuery( elem ).position()[ prop ] + "px" : computed; } } ); } ); // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { // Margin is only for outerHeight, outerWidth jQuery.fn[ funcName ] = function( margin, value ) { var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); return access( this, function( elem, type, value ) { var doc; if ( isWindow( elem ) ) { // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) return funcName.indexOf( "outer" ) === 0 ? elem[ "inner" + name ] : elem.document.documentElement[ "client" + name ]; } // Get document width or height if ( elem.nodeType === 9 ) { doc = elem.documentElement; // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], // whichever is greatest return Math.max( elem.body[ "scroll" + name ], doc[ "scroll" + name ], elem.body[ "offset" + name ], doc[ "offset" + name ], doc[ "client" + name ] ); } return value === undefined ? // Get width or height on the element, requesting but not forcing parseFloat jQuery.css( elem, type, extra ) : // Set width or height on the element jQuery.style( elem, type, value, extra ); }, type, chainable ? margin : undefined, chainable ); }; } ); } ); jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "change select submit keydown keypress keyup contextmenu" ).split( " " ), function( i, name ) { // Handle event binding jQuery.fn[ name ] = function( data, fn ) { return arguments.length > 0 ? this.on( name, null, data, fn ) : this.trigger( name ); }; } ); jQuery.fn.extend( { hover: function( fnOver, fnOut ) { return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); } } ); jQuery.fn.extend( { bind: function( types, data, fn ) { return this.on( types, null, data, fn ); }, unbind: function( types, fn ) { return this.off( types, null, fn ); }, delegate: function( selector, types, data, fn ) { return this.on( types, selector, data, fn ); }, undelegate: function( selector, types, fn ) { // ( namespace ) or ( selector, types [, fn] ) return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); } } ); // Bind a function to a context, optionally partially applying any // arguments. // jQuery.proxy is deprecated to promote standards (specifically Function#bind) // However, it is not slated for removal any time soon jQuery.proxy = function( fn, context ) { var tmp, args, proxy; if ( typeof context === "string" ) { tmp = fn[ context ]; context = fn; fn = tmp; } // Quick check to determine if target is callable, in the spec // this throws a TypeError, but we will just return undefined. if ( !isFunction( fn ) ) { return undefined; } // Simulated bind args = slice.call( arguments, 2 ); proxy = function() { return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); }; // Set the guid of unique handler to the same of original handler, so it can be removed proxy.guid = fn.guid = fn.guid || jQuery.guid++; return proxy; }; jQuery.holdReady = function( hold ) { if ( hold ) { jQuery.readyWait++; } else { jQuery.ready( true ); } }; jQuery.isArray = Array.isArray; jQuery.parseJSON = JSON.parse; jQuery.nodeName = nodeName; jQuery.isFunction = isFunction; jQuery.isWindow = isWindow; jQuery.camelCase = camelCase; jQuery.type = toType; jQuery.now = Date.now; jQuery.isNumeric = function( obj ) { // As of jQuery 3.0, isNumeric is limited to // strings and numbers (primitives or objects) // that can be coerced to finite numbers (gh-2662) var type = jQuery.type( obj ); return ( type === "number" || type === "string" ) && // parseFloat NaNs numeric-cast false positives ("") // ...but misinterprets leading-number strings, particularly hex literals ("0x...") // subtraction forces infinities to NaN !isNaN( obj - parseFloat( obj ) ); }; // Register as a named AMD module, since jQuery can be concatenated with other // files that may use define, but not via a proper concatenation script that // understands anonymous AMD modules. A named AMD is safest and most robust // way to register. Lowercase jquery is used because AMD module names are // derived from file names, and jQuery is normally delivered in a lowercase // file name. Do this after creating the global so that if an AMD module wants // to call noConflict to hide this version of jQuery, it will work. // Note that for maximum portability, libraries that are not jQuery should // declare themselves as anonymous modules, and avoid setting a global if an // AMD loader is present. jQuery is a special case. For more information, see // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon if ( typeof define === "function" && define.amd ) { define( "jquery", [], function() { return jQuery; } ); } var // Map over jQuery in case of overwrite _jQuery = window.jQuery, // Map over the $ in case of overwrite _$ = window.$; jQuery.noConflict = function( deep ) { if ( window.$ === jQuery ) { window.$ = _$; } if ( deep && window.jQuery === jQuery ) { window.jQuery = _jQuery; } return jQuery; }; // Expose jQuery and $ identifiers, even in AMD // (#7102#comment:10, https://github.com/jquery/jquery/pull/557) // and CommonJS for browser emulators (#13566) if ( !noGlobal ) { window.jQuery = window.$ = jQuery; } return jQuery; } ); }); define('fullcalendar', function (require, exports, module) { /*! * FullCalendar v3.10.0 * Docs & License: https://fullcalendar.io/ * (c) 2018 Adam Shaw */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("moment"), require("jquery")); else if(typeof define === 'function' && define.amd) define(["moment", "jquery"], factory); else if(typeof exports === 'object') exports["FullCalendar"] = factory(require("moment"), require("jquery")); else root["FullCalendar"] = factory(root["moment"], root["jQuery"]); })(typeof self !== 'undefined' ? self : this, function(__WEBPACK_EXTERNAL_MODULE_0__, __WEBPACK_EXTERNAL_MODULE_3__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 256); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_0__; /***/ }), /* 1 */, /* 2 */ /***/ (function(module, exports) { /* derived from: https://github.com/Microsoft/tslib/blob/v1.6.0/tslib.js only include the helpers we need, to keep down filesize */ var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; exports.__extends = function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; /***/ }), /* 3 */ /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_3__; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var moment = __webpack_require__(0); var $ = __webpack_require__(3); /* FullCalendar-specific DOM Utilities ----------------------------------------------------------------------------------------------------------------------*/ // Given the scrollbar widths of some other container, create borders/margins on rowEls in order to match the left // and right space that was offset by the scrollbars. A 1-pixel border first, then margin beyond that. function compensateScroll(rowEls, scrollbarWidths) { if (scrollbarWidths.left) { rowEls.css({ 'border-left-width': 1, 'margin-left': scrollbarWidths.left - 1 }); } if (scrollbarWidths.right) { rowEls.css({ 'border-right-width': 1, 'margin-right': scrollbarWidths.right - 1 }); } } exports.compensateScroll = compensateScroll; // Undoes compensateScroll and restores all borders/margins function uncompensateScroll(rowEls) { rowEls.css({ 'margin-left': '', 'margin-right': '', 'border-left-width': '', 'border-right-width': '' }); } exports.uncompensateScroll = uncompensateScroll; // Make the mouse cursor express that an event is not allowed in the current area function disableCursor() { $('body').addClass('fc-not-allowed'); } exports.disableCursor = disableCursor; // Returns the mouse cursor to its original look function enableCursor() { $('body').removeClass('fc-not-allowed'); } exports.enableCursor = enableCursor; // Given a total available height to fill, have `els` (essentially child rows) expand to accomodate. // By default, all elements that are shorter than the recommended height are expanded uniformly, not considering // any other els that are already too tall. if `shouldRedistribute` is on, it considers these tall rows and // reduces the available height. function distributeHeight(els, availableHeight, shouldRedistribute) { // *FLOORING NOTE*: we floor in certain places because zoom can give inaccurate floating-point dimensions, // and it is better to be shorter than taller, to avoid creating unnecessary scrollbars. var minOffset1 = Math.floor(availableHeight / els.length); // for non-last element var minOffset2 = Math.floor(availableHeight - minOffset1 * (els.length - 1)); // for last element *FLOORING NOTE* var flexEls = []; // elements that are allowed to expand. array of DOM nodes var flexOffsets = []; // amount of vertical space it takes up var flexHeights = []; // actual css height var usedHeight = 0; undistributeHeight(els); // give all elements their natural height // find elements that are below the recommended height (expandable). // important to query for heights in a single first pass (to avoid reflow oscillation). els.each(function (i, el) { var minOffset = i === els.length - 1 ? minOffset2 : minOffset1; var naturalOffset = $(el).outerHeight(true); if (naturalOffset < minOffset) { flexEls.push(el); flexOffsets.push(naturalOffset); flexHeights.push($(el).height()); } else { // this element stretches past recommended height (non-expandable). mark the space as occupied. usedHeight += naturalOffset; } }); // readjust the recommended height to only consider the height available to non-maxed-out rows. if (shouldRedistribute) { availableHeight -= usedHeight; minOffset1 = Math.floor(availableHeight / flexEls.length); minOffset2 = Math.floor(availableHeight - minOffset1 * (flexEls.length - 1)); // *FLOORING NOTE* } // assign heights to all expandable elements $(flexEls).each(function (i, el) { var minOffset = i === flexEls.length - 1 ? minOffset2 : minOffset1; var naturalOffset = flexOffsets[i]; var naturalHeight = flexHeights[i]; var newHeight = minOffset - (naturalOffset - naturalHeight); // subtract the margin/padding if (naturalOffset < minOffset) { // we check this again because redistribution might have changed things $(el).height(newHeight); } }); } exports.distributeHeight = distributeHeight; // Undoes distrubuteHeight, restoring all els to their natural height function undistributeHeight(els) { els.height(''); } exports.undistributeHeight = undistributeHeight; // Given `els`, a jQuery set of <td> cells, find the cell with the largest natural width and set the widths of all the // cells to be that width. // PREREQUISITE: if you want a cell to take up width, it needs to have a single inner element w/ display:inline function matchCellWidths(els) { var maxInnerWidth = 0; els.find('> *').each(function (i, innerEl) { var innerWidth = $(innerEl).outerWidth(); if (innerWidth > maxInnerWidth) { maxInnerWidth = innerWidth; } }); maxInnerWidth++; // sometimes not accurate of width the text needs to stay on one line. insurance els.width(maxInnerWidth); return maxInnerWidth; } exports.matchCellWidths = matchCellWidths; // Given one element that resides inside another, // Subtracts the height of the inner element from the outer element. function subtractInnerElHeight(outerEl, innerEl) { var both = outerEl.add(innerEl); var diff; // effin' IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked both.css({ position: 'relative', left: -1 // ensure reflow in case the el was already relative. negative is less likely to cause new scroll }); diff = outerEl.outerHeight() - innerEl.outerHeight(); // grab the dimensions both.css({ position: '', left: '' }); // undo hack return diff; } exports.subtractInnerElHeight = subtractInnerElHeight; /* Element Geom Utilities ----------------------------------------------------------------------------------------------------------------------*/ // borrowed from https://github.com/jquery/jquery-ui/blob/1.11.0/ui/core.js#L51 function getScrollParent(el) { var position = el.css('position'); var scrollParent = el.parents().filter(function () { var parent = $(this); return (/(auto|scroll)/).test(parent.css('overflow') + parent.css('overflow-y') + parent.css('overflow-x')); }).eq(0); return position === 'fixed' || !scrollParent.length ? $(el[0].ownerDocument || document) : scrollParent; } exports.getScrollParent = getScrollParent; // Queries the outer bounding area of a jQuery element. // Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive). // Origin is optional. function getOuterRect(el, origin) { var offset = el.offset(); var left = offset.left - (origin ? origin.left : 0); var top = offset.top - (origin ? origin.top : 0); return { left: left, right: left + el.outerWidth(), top: top, bottom: top + el.outerHeight() }; } exports.getOuterRect = getOuterRect; // Queries the area within the margin/border/scrollbars of a jQuery element. Does not go within the padding. // Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive). // Origin is optional. // WARNING: given element can't have borders // NOTE: should use clientLeft/clientTop, but very unreliable cross-browser. function getClientRect(el, origin) { var offset = el.offset(); var scrollbarWidths = getScrollbarWidths(el); var left = offset.left + getCssFloat(el, 'border-left-width') + scrollbarWidths.left - (origin ? origin.left : 0); var top = offset.top + getCssFloat(el, 'border-top-width') + scrollbarWidths.top - (origin ? origin.top : 0); return { left: left, right: left + el[0].clientWidth, top: top, bottom: top + el[0].clientHeight // clientHeight includes padding but NOT scrollbars }; } exports.getClientRect = getClientRect; // Queries the area within the margin/border/padding of a jQuery element. Assumed not to have scrollbars. // Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive). // Origin is optional. function getContentRect(el, origin) { var offset = el.offset(); // just outside of border, margin not included var left = offset.left + getCssFloat(el, 'border-left-width') + getCssFloat(el, 'padding-left') - (origin ? origin.left : 0); var top = offset.top + getCssFloat(el, 'border-top-width') + getCssFloat(el, 'padding-top') - (origin ? origin.top : 0); return { left: left, right: left + el.width(), top: top, bottom: top + el.height() }; } exports.getContentRect = getContentRect; // Returns the computed left/right/top/bottom scrollbar widths for the given jQuery element. // WARNING: given element can't have borders (which will cause offsetWidth/offsetHeight to be larger). // NOTE: should use clientLeft/clientTop, but very unreliable cross-browser. function getScrollbarWidths(el) { var leftRightWidth = el[0].offsetWidth - el[0].clientWidth; var bottomWidth = el[0].offsetHeight - el[0].clientHeight; var widths; leftRightWidth = sanitizeScrollbarWidth(leftRightWidth); bottomWidth = sanitizeScrollbarWidth(bottomWidth); widths = { left: 0, right: 0, top: 0, bottom: bottomWidth }; if (getIsLeftRtlScrollbars() && el.css('direction') === 'rtl') { // is the scrollbar on the left side? widths.left = leftRightWidth; } else { widths.right = leftRightWidth; } return widths; } exports.getScrollbarWidths = getScrollbarWidths; // The scrollbar width computations in getScrollbarWidths are sometimes flawed when it comes to // retina displays, rounding, and IE11. Massage them into a usable value. function sanitizeScrollbarWidth(width) { width = Math.max(0, width); // no negatives width = Math.round(width); return width; } // Logic for determining if, when the element is right-to-left, the scrollbar appears on the left side var _isLeftRtlScrollbars = null; function getIsLeftRtlScrollbars() { if (_isLeftRtlScrollbars === null) { _isLeftRtlScrollbars = computeIsLeftRtlScrollbars(); } return _isLeftRtlScrollbars; } function computeIsLeftRtlScrollbars() { var el = $('<div><div/></div>') .css({ position: 'absolute', top: -1000, left: 0, border: 0, padding: 0, overflow: 'scroll', direction: 'rtl' }) .appendTo('body'); var innerEl = el.children(); var res = innerEl.offset().left > el.offset().left; // is the inner div shifted to accommodate a left scrollbar? el.remove(); return res; } // Retrieves a jQuery element's computed CSS value as a floating-point number. // If the queried value is non-numeric (ex: IE can return "medium" for border width), will just return zero. function getCssFloat(el, prop) { return parseFloat(el.css(prop)) || 0; } /* Mouse / Touch Utilities ----------------------------------------------------------------------------------------------------------------------*/ // Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac) function isPrimaryMouseButton(ev) { return ev.which === 1 && !ev.ctrlKey; } exports.isPrimaryMouseButton = isPrimaryMouseButton; function getEvX(ev) { var touches = ev.originalEvent.touches; // on mobile FF, pageX for touch events is present, but incorrect, // so, look at touch coordinates first. if (touches && touches.length) { return touches[0].pageX; } return ev.pageX; } exports.getEvX = getEvX; function getEvY(ev) { var touches = ev.originalEvent.touches; // on mobile FF, pageX for touch events is present, but incorrect, // so, look at touch coordinates first. if (touches && touches.length) { return touches[0].pageY; } return ev.pageY; } exports.getEvY = getEvY; function getEvIsTouch(ev) { return /^touch/.test(ev.type); } exports.getEvIsTouch = getEvIsTouch; function preventSelection(el) { el.addClass('fc-unselectable') .on('selectstart', preventDefault); } exports.preventSelection = preventSelection; function allowSelection(el) { el.removeClass('fc-unselectable') .off('selectstart', preventDefault); } exports.allowSelection = allowSelection; // Stops a mouse/touch event from doing it's native browser action function preventDefault(ev) { ev.preventDefault(); } exports.preventDefault = preventDefault; /* General Geometry Utils ----------------------------------------------------------------------------------------------------------------------*/ // Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false function intersectRects(rect1, rect2) { var res = { left: Math.max(rect1.left, rect2.left), right: Math.min(rect1.right, rect2.right), top: Math.max(rect1.top, rect2.top), bottom: Math.min(rect1.bottom, rect2.bottom) }; if (res.left < res.right && res.top < res.bottom) { return res; } return false; } exports.intersectRects = intersectRects; // Returns a new point that will have been moved to reside within the given rectangle function constrainPoint(point, rect) { return { left: Math.min(Math.max(point.left, rect.left), rect.right), top: Math.min(Math.max(point.top, rect.top), rect.bottom) }; } exports.constrainPoint = constrainPoint; // Returns a point that is the center of the given rectangle function getRectCenter(rect) { return { left: (rect.left + rect.right) / 2, top: (rect.top + rect.bottom) / 2 }; } exports.getRectCenter = getRectCenter; // Subtracts point2's coordinates from point1's coordinates, returning a delta function diffPoints(point1, point2) { return { left: point1.left - point2.left, top: point1.top - point2.top }; } exports.diffPoints = diffPoints; /* Object Ordering by Field ----------------------------------------------------------------------------------------------------------------------*/ function parseFieldSpecs(input) { var specs = []; var tokens = []; var i; var token; if (typeof input === 'string') { tokens = input.split(/\s*,\s*/); } else if (typeof input === 'function') { tokens = [input]; } else if ($.isArray(input)) { tokens = input; } for (i = 0; i < tokens.length; i++) { token = tokens[i]; if (typeof token === 'string') { specs.push(token.charAt(0) === '-' ? { field: token.substring(1), order: -1 } : { field: token, order: 1 }); } else if (typeof token === 'function') { specs.push({ func: token }); } } return specs; } exports.parseFieldSpecs = parseFieldSpecs; function compareByFieldSpecs(obj1, obj2, fieldSpecs, obj1fallback, obj2fallback) { var i; var cmp; for (i = 0; i < fieldSpecs.length; i++) { cmp = compareByFieldSpec(obj1, obj2, fieldSpecs[i], obj1fallback, obj2fallback); if (cmp) { return cmp; } } return 0; } exports.compareByFieldSpecs = compareByFieldSpecs; function compareByFieldSpec(obj1, obj2, fieldSpec, obj1fallback, obj2fallback) { if (fieldSpec.func) { return fieldSpec.func(obj1, obj2); } var val1 = obj1[fieldSpec.field]; var val2 = obj2[fieldSpec.field]; if (val1 == null && obj1fallback) { val1 = obj1fallback[fieldSpec.field]; } if (val2 == null && obj2fallback) { val2 = obj2fallback[fieldSpec.field]; } return flexibleCompare(val1, val2) * (fieldSpec.order || 1); } exports.compareByFieldSpec = compareByFieldSpec; function flexibleCompare(a, b) { if (!a && !b) { return 0; } if (b == null) { return -1; } if (a == null) { return 1; } if ($.type(a) === 'string' || $.type(b) === 'string') { return String(a).localeCompare(String(b)); } return a - b; } exports.flexibleCompare = flexibleCompare; /* Date Utilities ----------------------------------------------------------------------------------------------------------------------*/ exports.dayIDs = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']; exports.unitsDesc = ['year', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; // descending // Diffs the two moments into a Duration where full-days are recorded first, then the remaining time. // Moments will have their timezones normalized. function diffDayTime(a, b) { return moment.duration({ days: a.clone().stripTime().diff(b.clone().stripTime(), 'days'), ms: a.time() - b.time() // time-of-day from day start. disregards timezone }); } exports.diffDayTime = diffDayTime; // Diffs the two moments via their start-of-day (regardless of timezone). Produces whole-day durations. function diffDay(a, b) { return moment.duration({ days: a.clone().stripTime().diff(b.clone().stripTime(), 'days') }); } exports.diffDay = diffDay; // Diffs two moments, producing a duration, made of a whole-unit-increment of the given unit. Uses rounding. function diffByUnit(a, b, unit) { return moment.duration(Math.round(a.diff(b, unit, true)), // returnFloat=true unit); } exports.diffByUnit = diffByUnit; // Computes the unit name of the largest whole-unit period of time. // For example, 48 hours will be "days" whereas 49 hours will be "hours". // Accepts start/end, a range object, or an original duration object. function computeGreatestUnit(start, end) { var i; var unit; var val; for (i = 0; i < exports.unitsDesc.length; i++) { unit = exports.unitsDesc[i]; val = computeRangeAs(unit, start, end); if (val >= 1 && isInt(val)) { break; } } return unit; // will be "milliseconds" if nothing else matches } exports.computeGreatestUnit = computeGreatestUnit; // like computeGreatestUnit, but has special abilities to interpret the source input for clues function computeDurationGreatestUnit(duration, durationInput) { var unit = computeGreatestUnit(duration); // prevent days:7 from being interpreted as a week if (unit === 'week' && typeof durationInput === 'object' && durationInput.days) { unit = 'day'; } return unit; } exports.computeDurationGreatestUnit = computeDurationGreatestUnit; // Computes the number of units (like "hours") in the given range. // Range can be a {start,end} object, separate start/end args, or a Duration. // Results are based on Moment's .as() and .diff() methods, so results can depend on internal handling // of month-diffing logic (which tends to vary from version to version). function computeRangeAs(unit, start, end) { if (end != null) { // given start, end return end.diff(start, unit, true); } else if (moment.isDuration(start)) { // given duration return start.as(unit); } else { // given { start, end } range object return start.end.diff(start.start, unit, true); } } // Intelligently divides a range (specified by a start/end params) by a duration function divideRangeByDuration(start, end, dur) { var months; if (durationHasTime(dur)) { return (end - start) / dur; } months = dur.asMonths(); if (Math.abs(months) >= 1 && isInt(months)) { return end.diff(start, 'months', true) / months; } return end.diff(start, 'days', true) / dur.asDays(); } exports.divideRangeByDuration = divideRangeByDuration; // Intelligently divides one duration by another function divideDurationByDuration(dur1, dur2) { var months1; var months2; if (durationHasTime(dur1) || durationHasTime(dur2)) { return dur1 / dur2; } months1 = dur1.asMonths(); months2 = dur2.asMonths(); if (Math.abs(months1) >= 1 && isInt(months1) && Math.abs(months2) >= 1 && isInt(months2)) { return months1 / months2; } return dur1.asDays() / dur2.asDays(); } exports.divideDurationByDuration = divideDurationByDuration; // Intelligently multiplies a duration by a number function multiplyDuration(dur, n) { var months; if (durationHasTime(dur)) { return moment.duration(dur * n); } months = dur.asMonths(); if (Math.abs(months) >= 1 && isInt(months)) { return moment.duration({ months: months * n }); } return moment.duration({ days: dur.asDays() * n }); } exports.multiplyDuration = multiplyDuration; // Returns a boolean about whether the given duration has any time parts (hours/minutes/seconds/ms) function durationHasTime(dur) { return Boolean(dur.hours() || dur.minutes() || dur.seconds() || dur.milliseconds()); } exports.durationHasTime = durationHasTime; function isNativeDate(input) { return Object.prototype.toString.call(input) === '[object Date]' || input instanceof Date; } exports.isNativeDate = isNativeDate; // Returns a boolean about whether the given input is a time string, like "06:40:00" or "06:00" function isTimeString(str) { return typeof str === 'string' && /^\d+\:\d+(?:\:\d+\.?(?:\d{3})?)?$/.test(str); } exports.isTimeString = isTimeString; /* Logging and Debug ----------------------------------------------------------------------------------------------------------------------*/ function log() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var console = window.console; if (console && console.log) { return console.log.apply(console, args); } } exports.log = log; function warn() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var console = window.console; if (console && console.warn) { return console.warn.apply(console, args); } else { return log.apply(null, args); } } exports.warn = warn; /* General Utilities ----------------------------------------------------------------------------------------------------------------------*/ var hasOwnPropMethod = {}.hasOwnProperty; // Merges an array of objects into a single object. // The second argument allows for an array of property names who's object values will be merged together. function mergeProps(propObjs, complexProps) { var dest = {}; var i; var name; var complexObjs; var j; var val; var props; if (complexProps) { for (i = 0; i < complexProps.length; i++) { name = complexProps[i]; complexObjs = []; // collect the trailing object values, stopping when a non-object is discovered for (j = propObjs.length - 1; j >= 0; j--) { val = propObjs[j][name]; if (typeof val === 'object') { complexObjs.unshift(val); } else if (val !== undefined) { dest[name] = val; // if there were no objects, this value will be used break; } } // if the trailing values were objects, use the merged value if (complexObjs.length) { dest[name] = mergeProps(complexObjs); } } } // copy values into the destination, going from last to first for (i = propObjs.length - 1; i >= 0; i--) { props = propObjs[i]; for (name in props) { if (!(name in dest)) { // if already assigned by previous props or complex props, don't reassign dest[name] = props[name]; } } } return dest; } exports.mergeProps = mergeProps; function copyOwnProps(src, dest) { for (var name_1 in src) { if (hasOwnProp(src, name_1)) { dest[name_1] = src[name_1]; } } } exports.copyOwnProps = copyOwnProps; function hasOwnProp(obj, name) { return hasOwnPropMethod.call(obj, name); } exports.hasOwnProp = hasOwnProp; function applyAll(functions, thisObj, args) { if ($.isFunction(functions)) { functions = [functions]; } if (functions) { var i = void 0; var ret = void 0; for (i = 0; i < functions.length; i++) { ret = functions[i].apply(thisObj, args) || ret; } return ret; } } exports.applyAll = applyAll; function removeMatching(array, testFunc) { var removeCnt = 0; var i = 0; while (i < array.length) { if (testFunc(array[i])) { // truthy value means *remove* array.splice(i, 1); removeCnt++; } else { i++; } } return removeCnt; } exports.removeMatching = removeMatching; function removeExact(array, exactVal) { var removeCnt = 0; var i = 0; while (i < array.length) { if (array[i] === exactVal) { array.splice(i, 1); removeCnt++; } else { i++; } } return removeCnt; } exports.removeExact = removeExact; function isArraysEqual(a0, a1) { var len = a0.length; var i; if (len == null || len !== a1.length) { // not array? or not same length? return false; } for (i = 0; i < len; i++) { if (a0[i] !== a1[i]) { return false; } } return true; } exports.isArraysEqual = isArraysEqual; function firstDefined() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } for (var i = 0; i < args.length; i++) { if (args[i] !== undefined) { return args[i]; } } } exports.firstDefined = firstDefined; function htmlEscape(s) { return (s + '').replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/'/g, ''') .replace(/"/g, '"') .replace(/\n/g, '<br />'); } exports.htmlEscape = htmlEscape; function stripHtmlEntities(text) { return text.replace(/&.*?;/g, ''); } exports.stripHtmlEntities = stripHtmlEntities; // Given a hash of CSS properties, returns a string of CSS. // Uses property names as-is (no camel-case conversion). Will not make statements for null/undefined values. function cssToStr(cssProps) { var statements = []; $.each(cssProps, function (name, val) { if (val != null) { statements.push(name + ':' + val); } }); return statements.join(';'); } exports.cssToStr = cssToStr; // Given an object hash of HTML attribute names to values, // generates a string that can be injected between < > in HTML function attrsToStr(attrs) { var parts = []; $.each(attrs, function (name, val) { if (val != null) { parts.push(name + '="' + htmlEscape(val) + '"'); } }); return parts.join(' '); } exports.attrsToStr = attrsToStr; function capitaliseFirstLetter(str) { return str.charAt(0).toUpperCase() + str.slice(1); } exports.capitaliseFirstLetter = capitaliseFirstLetter; function compareNumbers(a, b) { return a - b; } exports.compareNumbers = compareNumbers; function isInt(n) { return n % 1 === 0; } exports.isInt = isInt; // Returns a method bound to the given object context. // Just like one of the jQuery.proxy signatures, but without the undesired behavior of treating the same method with // different contexts as identical when binding/unbinding events. function proxy(obj, methodName) { var method = obj[methodName]; return function () { return method.apply(obj, arguments); }; } exports.proxy = proxy; // Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for // N milliseconds. If `immediate` is passed, trigger the function on the // leading edge, instead of the trailing. // https://github.com/jashkenas/underscore/blob/1.6.0/underscore.js#L714 function debounce(func, wait, immediate) { if (immediate === void 0) { immediate = false; } var timeout; var args; var context; var timestamp; var result; var later = function () { var last = +new Date() - timestamp; if (last < wait) { timeout = setTimeout(later, wait - last); } else { timeout = null; if (!immediate) { result = func.apply(context, args); context = args = null; } } }; return function () { context = this; args = arguments; timestamp = +new Date(); var callNow = immediate && !timeout; if (!timeout) { timeout = setTimeout(later, wait); } if (callNow) { result = func.apply(context, args); context = args = null; } return result; }; } exports.debounce = debounce; /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var moment = __webpack_require__(0); var moment_ext_1 = __webpack_require__(11); var UnzonedRange = /** @class */ (function () { function UnzonedRange(startInput, endInput) { // TODO: move these into footprint. // Especially, doesn't make sense for null startMs/endMs. this.isStart = true; this.isEnd = true; if (moment.isMoment(startInput)) { startInput = startInput.clone().stripZone(); } if (moment.isMoment(endInput)) { endInput = endInput.clone().stripZone(); } if (startInput) { this.startMs = startInput.valueOf(); } if (endInput) { this.endMs = endInput.valueOf(); } } /* SIDEEFFECT: will mutate eventRanges. Will return a new array result. Only works for non-open-ended ranges. */ UnzonedRange.invertRanges = function (ranges, constraintRange) { var invertedRanges = []; var startMs = constraintRange.startMs; // the end of the previous range. the start of the new range var i; var dateRange; // ranges need to be in order. required for our date-walking algorithm ranges.sort(compareUnzonedRanges); for (i = 0; i < ranges.length; i++) { dateRange = ranges[i]; // add the span of time before the event (if there is any) if (dateRange.startMs > startMs) { // compare millisecond time (skip any ambig logic) invertedRanges.push(new UnzonedRange(startMs, dateRange.startMs)); } if (dateRange.endMs > startMs) { startMs = dateRange.endMs; } } // add the span of time after the last event (if there is any) if (startMs < constraintRange.endMs) { // compare millisecond time (skip any ambig logic) invertedRanges.push(new UnzonedRange(startMs, constraintRange.endMs)); } return invertedRanges; }; UnzonedRange.prototype.intersect = function (otherRange) { var startMs = this.startMs; var endMs = this.endMs; var newRange = null; if (otherRange.startMs != null) { if (startMs == null) { startMs = otherRange.startMs; } else { startMs = Math.max(startMs, otherRange.startMs); } } if (otherRange.endMs != null) { if (endMs == null) { endMs = otherRange.endMs; } else { endMs = Math.min(endMs, otherRange.endMs); } } if (startMs == null || endMs == null || startMs < endMs) { newRange = new UnzonedRange(startMs, endMs); newRange.isStart = this.isStart && startMs === this.startMs; newRange.isEnd = this.isEnd && endMs === this.endMs; } return newRange; }; UnzonedRange.prototype.intersectsWith = function (otherRange) { return (this.endMs == null || otherRange.startMs == null || this.endMs > otherRange.startMs) && (this.startMs == null || otherRange.endMs == null || this.startMs < otherRange.endMs); }; UnzonedRange.prototype.containsRange = function (innerRange) { return (this.startMs == null || (innerRange.startMs != null && innerRange.startMs >= this.startMs)) && (this.endMs == null || (innerRange.endMs != null && innerRange.endMs <= this.endMs)); }; // `date` can be a moment, a Date, or a millisecond time. UnzonedRange.prototype.containsDate = function (date) { var ms = date.valueOf(); return (this.startMs == null || ms >= this.startMs) && (this.endMs == null || ms < this.endMs); }; // If the given date is not within the given range, move it inside. // (If it's past the end, make it one millisecond before the end). // `date` can be a moment, a Date, or a millisecond time. // Returns a MS-time. UnzonedRange.prototype.constrainDate = function (date) { var ms = date.valueOf(); if (this.startMs != null && ms < this.startMs) { ms = this.startMs; } if (this.endMs != null && ms >= this.endMs) { ms = this.endMs - 1; } return ms; }; UnzonedRange.prototype.equals = function (otherRange) { return this.startMs === otherRange.startMs && this.endMs === otherRange.endMs; }; UnzonedRange.prototype.clone = function () { var range = new UnzonedRange(this.startMs, this.endMs); range.isStart = this.isStart; range.isEnd = this.isEnd; return range; }; // Returns an ambig-zoned moment from startMs. // BEWARE: returned moment is not localized. // Formatting and start-of-week will be default. UnzonedRange.prototype.getStart = function () { if (this.startMs != null) { return moment_ext_1.default.utc(this.startMs).stripZone(); } return null; }; // Returns an ambig-zoned moment from startMs. // BEWARE: returned moment is not localized. // Formatting and start-of-week will be default. UnzonedRange.prototype.getEnd = function () { if (this.endMs != null) { return moment_ext_1.default.utc(this.endMs).stripZone(); } return null; }; UnzonedRange.prototype.as = function (unit) { return moment.utc(this.endMs).diff(moment.utc(this.startMs), unit, true); }; return UnzonedRange; }()); exports.default = UnzonedRange; /* Only works for non-open-ended ranges. */ function compareUnzonedRanges(range1, range2) { return range1.startMs - range2.startMs; // earlier ranges go first } /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var ParsableModelMixin_1 = __webpack_require__(52); var Class_1 = __webpack_require__(35); var EventDefParser_1 = __webpack_require__(36); var EventSource = /** @class */ (function (_super) { tslib_1.__extends(EventSource, _super); // can we do away with calendar? at least for the abstract? // useful for buildEventDef function EventSource(calendar) { var _this = _super.call(this) || this; _this.calendar = calendar; _this.className = []; _this.uid = String(EventSource.uuid++); return _this; } /* rawInput can be any data type! */ EventSource.parse = function (rawInput, calendar) { var source = new this(calendar); if (typeof rawInput === 'object') { if (source.applyProps(rawInput)) { return source; } } return false; }; EventSource.normalizeId = function (id) { if (id) { return String(id); } return null; }; EventSource.prototype.fetch = function (start, end, timezone) { // subclasses must implement. must return a promise. }; EventSource.prototype.removeEventDefsById = function (eventDefId) { // optional for subclasses to implement }; EventSource.prototype.removeAllEventDefs = function () { // optional for subclasses to implement }; /* For compairing/matching */ EventSource.prototype.getPrimitive = function (otherSource) { // subclasses must implement }; EventSource.prototype.parseEventDefs = function (rawEventDefs) { var i; var eventDef; var eventDefs = []; for (i = 0; i < rawEventDefs.length; i++) { eventDef = this.parseEventDef(rawEventDefs[i]); if (eventDef) { eventDefs.push(eventDef); } } return eventDefs; }; EventSource.prototype.parseEventDef = function (rawInput) { var calendarTransform = this.calendar.opt('eventDataTransform'); var sourceTransform = this.eventDataTransform; if (calendarTransform) { rawInput = calendarTransform(rawInput, this.calendar); } if (sourceTransform) { rawInput = sourceTransform(rawInput, this.calendar); } return EventDefParser_1.default.parse(rawInput, this); }; EventSource.prototype.applyManualStandardProps = function (rawProps) { if (rawProps.id != null) { this.id = EventSource.normalizeId(rawProps.id); } // TODO: converge with EventDef if ($.isArray(rawProps.className)) { this.className = rawProps.className; } else if (typeof rawProps.className === 'string') { this.className = rawProps.className.split(/\s+/); } return true; }; EventSource.uuid = 0; EventSource.defineStandardProps = ParsableModelMixin_1.default.defineStandardProps; EventSource.copyVerbatimStandardProps = ParsableModelMixin_1.default.copyVerbatimStandardProps; return EventSource; }(Class_1.default)); exports.default = EventSource; ParsableModelMixin_1.default.mixInto(EventSource); // Parsing // --------------------------------------------------------------------------------------------------------------------- EventSource.defineStandardProps({ // manually process... id: false, className: false, // automatically transfer... color: true, backgroundColor: true, borderColor: true, textColor: true, editable: true, startEditable: true, durationEditable: true, rendering: true, overlap: true, constraint: true, allDayDefault: true, eventDataTransform: true }); /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { /* Utility methods for easily listening to events on another object, and more importantly, easily unlistening from them. USAGE: import { default as ListenerMixin, ListenerInterface } from './ListenerMixin' in class: listenTo: ListenerInterface['listenTo'] stopListeningTo: ListenerInterface['stopListeningTo'] after class: ListenerMixin.mixInto(TheClass) */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var Mixin_1 = __webpack_require__(15); var guid = 0; var ListenerMixin = /** @class */ (function (_super) { tslib_1.__extends(ListenerMixin, _super); function ListenerMixin() { return _super !== null && _super.apply(this, arguments) || this; } /* Given an `other` object that has on/off methods, bind the given `callback` to an event by the given name. The `callback` will be called with the `this` context of the object that .listenTo is being called on. Can be called: .listenTo(other, eventName, callback) OR .listenTo(other, { eventName1: callback1, eventName2: callback2 }) */ ListenerMixin.prototype.listenTo = function (other, arg, callback) { if (typeof arg === 'object') { // given dictionary of callbacks for (var eventName in arg) { if (arg.hasOwnProperty(eventName)) { this.listenTo(other, eventName, arg[eventName]); } } } else if (typeof arg === 'string') { other.on(arg + '.' + this.getListenerNamespace(), // use event namespacing to identify this object $.proxy(callback, this) // always use `this` context // the usually-undesired jQuery guid behavior doesn't matter, // because we always unbind via namespace ); } }; /* Causes the current object to stop listening to events on the `other` object. `eventName` is optional. If omitted, will stop listening to ALL events on `other`. */ ListenerMixin.prototype.stopListeningTo = function (other, eventName) { other.off((eventName || '') + '.' + this.getListenerNamespace()); }; /* Returns a string, unique to this object, to be used for event namespacing */ ListenerMixin.prototype.getListenerNamespace = function () { if (this.listenerId == null) { this.listenerId = guid++; } return '_listener' + this.listenerId; }; return ListenerMixin; }(Mixin_1.default)); exports.default = ListenerMixin; /***/ }), /* 8 */, /* 9 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var EventDef_1 = __webpack_require__(37); var EventInstance_1 = __webpack_require__(53); var EventDateProfile_1 = __webpack_require__(16); var SingleEventDef = /** @class */ (function (_super) { tslib_1.__extends(SingleEventDef, _super); function SingleEventDef() { return _super !== null && _super.apply(this, arguments) || this; } /* Will receive start/end params, but will be ignored. */ SingleEventDef.prototype.buildInstances = function () { return [this.buildInstance()]; }; SingleEventDef.prototype.buildInstance = function () { return new EventInstance_1.default(this, // definition this.dateProfile); }; SingleEventDef.prototype.isAllDay = function () { return this.dateProfile.isAllDay(); }; SingleEventDef.prototype.clone = function () { var def = _super.prototype.clone.call(this); def.dateProfile = this.dateProfile; return def; }; SingleEventDef.prototype.rezone = function () { var calendar = this.source.calendar; var dateProfile = this.dateProfile; this.dateProfile = new EventDateProfile_1.default(calendar.moment(dateProfile.start), dateProfile.end ? calendar.moment(dateProfile.end) : null, calendar); }; /* NOTE: if super-method fails, should still attempt to apply */ SingleEventDef.prototype.applyManualStandardProps = function (rawProps) { var superSuccess = _super.prototype.applyManualStandardProps.call(this, rawProps); var dateProfile = EventDateProfile_1.default.parse(rawProps, this.source); // returns null on failure if (dateProfile) { this.dateProfile = dateProfile; // make sure `date` shows up in the legacy event objects as-is if (rawProps.date != null) { this.miscProps.date = rawProps.date; } return superSuccess; } else { return false; } }; return SingleEventDef; }(EventDef_1.default)); exports.default = SingleEventDef; // Parsing // --------------------------------------------------------------------------------------------------------------------- SingleEventDef.defineStandardProps({ start: false, date: false, end: false, allDay: false }); /***/ }), /* 10 */, /* 11 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var moment = __webpack_require__(0); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var ambigDateOfMonthRegex = /^\s*\d{4}-\d\d$/; var ambigTimeOrZoneRegex = /^\s*\d{4}-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?)?$/; var newMomentProto = moment.fn; // where we will attach our new methods exports.newMomentProto = newMomentProto; var oldMomentProto = $.extend({}, newMomentProto); // copy of original moment methods exports.oldMomentProto = oldMomentProto; // tell momentjs to transfer these properties upon clone var momentProperties = moment.momentProperties; momentProperties.push('_fullCalendar'); momentProperties.push('_ambigTime'); momentProperties.push('_ambigZone'); /* Call this if you want Moment's original format method to be used */ function oldMomentFormat(mom, formatStr) { return oldMomentProto.format.call(mom, formatStr); // oldMomentProto defined in moment-ext.js } exports.oldMomentFormat = oldMomentFormat; // Creating // ------------------------------------------------------------------------------------------------- // Creates a new moment, similar to the vanilla moment(...) constructor, but with // extra features (ambiguous time, enhanced formatting). When given an existing moment, // it will function as a clone (and retain the zone of the moment). Anything else will // result in a moment in the local zone. var momentExt = function () { return makeMoment(arguments); }; exports.default = momentExt; // Sames as momentExt, but forces the resulting moment to be in the UTC timezone. momentExt.utc = function () { var mom = makeMoment(arguments, true); // Force it into UTC because makeMoment doesn't guarantee it // (if given a pre-existing moment for example) if (mom.hasTime()) { // don't give ambiguously-timed moments a UTC zone mom.utc(); } return mom; }; // Same as momentExt, but when given an ISO8601 string, the timezone offset is preserved. // ISO8601 strings with no timezone offset will become ambiguously zoned. momentExt.parseZone = function () { return makeMoment(arguments, true, true); }; // Builds an enhanced moment from args. When given an existing moment, it clones. When given a // native Date, or called with no arguments (the current time), the resulting moment will be local. // Anything else needs to be "parsed" (a string or an array), and will be affected by: // parseAsUTC - if there is no zone information, should we parse the input in UTC? // parseZone - if there is zone information, should we force the zone of the moment? function makeMoment(args, parseAsUTC, parseZone) { if (parseAsUTC === void 0) { parseAsUTC = false; } if (parseZone === void 0) { parseZone = false; } var input = args[0]; var isSingleString = args.length === 1 && typeof input === 'string'; var isAmbigTime; var isAmbigZone; var ambigMatch; var mom; if (moment.isMoment(input) || util_1.isNativeDate(input) || input === undefined) { mom = moment.apply(null, args); } else { // "parsing" is required isAmbigTime = false; isAmbigZone = false; if (isSingleString) { if (ambigDateOfMonthRegex.test(input)) { // accept strings like '2014-05', but convert to the first of the month input += '-01'; args = [input]; // for when we pass it on to moment's constructor isAmbigTime = true; isAmbigZone = true; } else if ((ambigMatch = ambigTimeOrZoneRegex.exec(input))) { isAmbigTime = !ambigMatch[5]; // no time part? isAmbigZone = true; } } else if ($.isArray(input)) { // arrays have no timezone information, so assume ambiguous zone isAmbigZone = true; } // otherwise, probably a string with a format if (parseAsUTC || isAmbigTime) { mom = moment.utc.apply(moment, args); } else { mom = moment.apply(null, args); } if (isAmbigTime) { mom._ambigTime = true; mom._ambigZone = true; // ambiguous time always means ambiguous zone } else if (parseZone) { // let's record the inputted zone somehow if (isAmbigZone) { mom._ambigZone = true; } else if (isSingleString) { mom.utcOffset(input); // if not a valid zone, will assign UTC } } } mom._fullCalendar = true; // flag for extended functionality return mom; } // Week Number // ------------------------------------------------------------------------------------------------- // Returns the week number, considering the locale's custom week number calcuation // `weeks` is an alias for `week` newMomentProto.week = newMomentProto.weeks = function (input) { var weekCalc = this._locale._fullCalendar_weekCalc; if (input == null && typeof weekCalc === 'function') { // custom function only works for getter return weekCalc(this); } else if (weekCalc === 'ISO') { return oldMomentProto.isoWeek.apply(this, arguments); // ISO getter/setter } return oldMomentProto.week.apply(this, arguments); // local getter/setter }; // Time-of-day // ------------------------------------------------------------------------------------------------- // GETTER // Returns a Duration with the hours/minutes/seconds/ms values of the moment. // If the moment has an ambiguous time, a duration of 00:00 will be returned. // // SETTER // You can supply a Duration, a Moment, or a Duration-like argument. // When setting the time, and the moment has an ambiguous time, it then becomes unambiguous. newMomentProto.time = function (time) { // Fallback to the original method (if there is one) if this moment wasn't created via FullCalendar. // `time` is a generic enough method name where this precaution is necessary to avoid collisions w/ other plugins. if (!this._fullCalendar) { return oldMomentProto.time.apply(this, arguments); } if (time == null) { // getter return moment.duration({ hours: this.hours(), minutes: this.minutes(), seconds: this.seconds(), milliseconds: this.milliseconds() }); } else { // setter this._ambigTime = false; // mark that the moment now has a time if (!moment.isDuration(time) && !moment.isMoment(time)) { time = moment.duration(time); } // The day value should cause overflow (so 24 hours becomes 00:00:00 of next day). // Only for Duration times, not Moment times. var dayHours = 0; if (moment.isDuration(time)) { dayHours = Math.floor(time.asDays()) * 24; } // We need to set the individual fields. // Can't use startOf('day') then add duration. In case of DST at start of day. return this.hours(dayHours + time.hours()) .minutes(time.minutes()) .seconds(time.seconds()) .milliseconds(time.milliseconds()); } }; // Converts the moment to UTC, stripping out its time-of-day and timezone offset, // but preserving its YMD. A moment with a stripped time will display no time // nor timezone offset when .format() is called. newMomentProto.stripTime = function () { if (!this._ambigTime) { this.utc(true); // keepLocalTime=true (for keeping *date* value) // set time to zero this.set({ hours: 0, minutes: 0, seconds: 0, ms: 0 }); // Mark the time as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(), // which clears all ambig flags. this._ambigTime = true; this._ambigZone = true; // if ambiguous time, also ambiguous timezone offset } return this; // for chaining }; // Returns if the moment has a non-ambiguous time (boolean) newMomentProto.hasTime = function () { return !this._ambigTime; }; // Timezone // ------------------------------------------------------------------------------------------------- // Converts the moment to UTC, stripping out its timezone offset, but preserving its // YMD and time-of-day. A moment with a stripped timezone offset will display no // timezone offset when .format() is called. newMomentProto.stripZone = function () { var wasAmbigTime; if (!this._ambigZone) { wasAmbigTime = this._ambigTime; this.utc(true); // keepLocalTime=true (for keeping date and time values) // the above call to .utc()/.utcOffset() unfortunately might clear the ambig flags, so restore this._ambigTime = wasAmbigTime || false; // Mark the zone as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(), // which clears the ambig flags. this._ambigZone = true; } return this; // for chaining }; // Returns of the moment has a non-ambiguous timezone offset (boolean) newMomentProto.hasZone = function () { return !this._ambigZone; }; // implicitly marks a zone newMomentProto.local = function (keepLocalTime) { // for when converting from ambiguously-zoned to local, // keep the time values when converting from UTC -> local oldMomentProto.local.call(this, this._ambigZone || keepLocalTime); // ensure non-ambiguous // this probably already happened via local() -> utcOffset(), but don't rely on Moment's internals this._ambigTime = false; this._ambigZone = false; return this; // for chaining }; // implicitly marks a zone newMomentProto.utc = function (keepLocalTime) { oldMomentProto.utc.call(this, keepLocalTime); // ensure non-ambiguous // this probably already happened via utc() -> utcOffset(), but don't rely on Moment's internals this._ambigTime = false; this._ambigZone = false; return this; }; // implicitly marks a zone (will probably get called upon .utc() and .local()) newMomentProto.utcOffset = function (tzo) { if (tzo != null) { // setter // these assignments needs to happen before the original zone method is called. // I forget why, something to do with a browser crash. this._ambigTime = false; this._ambigZone = false; } return oldMomentProto.utcOffset.apply(this, arguments); }; /***/ }), /* 12 */ /***/ (function(module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); /* Meant to be immutable */ var ComponentFootprint = /** @class */ (function () { function ComponentFootprint(unzonedRange, isAllDay) { this.isAllDay = false; // component can choose to ignore this this.unzonedRange = unzonedRange; this.isAllDay = isAllDay; } /* Only works for non-open-ended ranges. */ ComponentFootprint.prototype.toLegacy = function (calendar) { return { start: calendar.msToMoment(this.unzonedRange.startMs, this.isAllDay), end: calendar.msToMoment(this.unzonedRange.endMs, this.isAllDay) }; }; return ComponentFootprint; }()); exports.default = ComponentFootprint; /***/ }), /* 13 */ /***/ (function(module, exports, __webpack_require__) { /* USAGE: import { default as EmitterMixin, EmitterInterface } from './EmitterMixin' in class: on: EmitterInterface['on'] one: EmitterInterface['one'] off: EmitterInterface['off'] trigger: EmitterInterface['trigger'] triggerWith: EmitterInterface['triggerWith'] hasHandlers: EmitterInterface['hasHandlers'] after class: EmitterMixin.mixInto(TheClass) */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var Mixin_1 = __webpack_require__(15); var EmitterMixin = /** @class */ (function (_super) { tslib_1.__extends(EmitterMixin, _super); function EmitterMixin() { return _super !== null && _super.apply(this, arguments) || this; } // jQuery-ification via $(this) allows a non-DOM object to have // the same event handling capabilities (including namespaces). EmitterMixin.prototype.on = function (types, handler) { $(this).on(types, this._prepareIntercept(handler)); return this; // for chaining }; EmitterMixin.prototype.one = function (types, handler) { $(this).one(types, this._prepareIntercept(handler)); return this; // for chaining }; EmitterMixin.prototype._prepareIntercept = function (handler) { // handlers are always called with an "event" object as their first param. // sneak the `this` context and arguments into the extra parameter object // and forward them on to the original handler. var intercept = function (ev, extra) { return handler.apply(extra.context || this, extra.args || []); }; // mimick jQuery's internal "proxy" system (risky, I know) // causing all functions with the same .guid to appear to be the same. // https://github.com/jquery/jquery/blob/2.2.4/src/core.js#L448 // this is needed for calling .off with the original non-intercept handler. if (!handler.guid) { handler.guid = $.guid++; } intercept.guid = handler.guid; return intercept; }; EmitterMixin.prototype.off = function (types, handler) { $(this).off(types, handler); return this; // for chaining }; EmitterMixin.prototype.trigger = function (types) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } // pass in "extra" info to the intercept $(this).triggerHandler(types, { args: args }); return this; // for chaining }; EmitterMixin.prototype.triggerWith = function (types, context, args) { // `triggerHandler` is less reliant on the DOM compared to `trigger`. // pass in "extra" info to the intercept. $(this).triggerHandler(types, { context: context, args: args }); return this; // for chaining }; EmitterMixin.prototype.hasHandlers = function (type) { var hash = $._data(this, 'events'); // http://blog.jquery.com/2012/08/09/jquery-1-8-released/ return hash && hash[type] && hash[type].length > 0; }; return EmitterMixin; }(Mixin_1.default)); exports.default = EmitterMixin; /***/ }), /* 14 */ /***/ (function(module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); var Interaction = /** @class */ (function () { function Interaction(component) { this.view = component._getView(); this.component = component; } Interaction.prototype.opt = function (name) { return this.view.opt(name); }; Interaction.prototype.end = function () { // subclasses can implement }; return Interaction; }()); exports.default = Interaction; /***/ }), /* 15 */ /***/ (function(module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); var Mixin = /** @class */ (function () { function Mixin() { } Mixin.mixInto = function (destClass) { var _this = this; Object.getOwnPropertyNames(this.prototype).forEach(function (name) { if (!destClass.prototype[name]) { // if destination class doesn't already define it destClass.prototype[name] = _this.prototype[name]; } }); }; /* will override existing methods TODO: remove! not used anymore */ Mixin.mixOver = function (destClass) { var _this = this; Object.getOwnPropertyNames(this.prototype).forEach(function (name) { destClass.prototype[name] = _this.prototype[name]; }); }; return Mixin; }()); exports.default = Mixin; /***/ }), /* 16 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var UnzonedRange_1 = __webpack_require__(5); /* Meant to be immutable */ var EventDateProfile = /** @class */ (function () { function EventDateProfile(start, end, calendar) { this.start = start; this.end = end || null; this.unzonedRange = this.buildUnzonedRange(calendar); } /* Needs an EventSource object */ EventDateProfile.parse = function (rawProps, source) { var startInput = rawProps.start || rawProps.date; var endInput = rawProps.end; if (!startInput) { return false; } var calendar = source.calendar; var start = calendar.moment(startInput); var end = endInput ? calendar.moment(endInput) : null; var forcedAllDay = rawProps.allDay; var forceEventDuration = calendar.opt('forceEventDuration'); if (!start.isValid()) { return false; } if (forcedAllDay == null) { forcedAllDay = source.allDayDefault; if (forcedAllDay == null) { forcedAllDay = calendar.opt('allDayDefault'); } } if (forcedAllDay === true) { start.stripTime(); if (end) { end.stripTime(); } } else if (forcedAllDay === false) { if (!start.hasTime()) { start.time(0); } if (end && !end.hasTime()) { end.time(0); } } if (end && (!end.isValid() || !end.isAfter(start))) { end = null; } if (!end && forceEventDuration) { end = calendar.getDefaultEventEnd(!start.hasTime(), start); } return new EventDateProfile(start, end, calendar); }; EventDateProfile.isStandardProp = function (propName) { return propName === 'start' || propName === 'date' || propName === 'end' || propName === 'allDay'; }; EventDateProfile.prototype.isAllDay = function () { return !(this.start.hasTime() || (this.end && this.end.hasTime())); }; /* Needs a Calendar object */ EventDateProfile.prototype.buildUnzonedRange = function (calendar) { var startMs = this.start.clone().stripZone().valueOf(); var endMs = this.getEnd(calendar).stripZone().valueOf(); return new UnzonedRange_1.default(startMs, endMs); }; /* Needs a Calendar object */ EventDateProfile.prototype.getEnd = function (calendar) { return this.end ? this.end.clone() : // derive the end from the start and allDay. compute allDay if necessary calendar.getDefaultEventEnd(this.isAllDay(), this.start); }; return EventDateProfile; }()); exports.default = EventDateProfile; /***/ }), /* 17 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var util_1 = __webpack_require__(4); var DragListener_1 = __webpack_require__(59); /* Tracks mouse movements over a component and raises events about which hit the mouse is over. ------------------------------------------------------------------------------------------------------------------------ options: - subjectEl - subjectCenter */ var HitDragListener = /** @class */ (function (_super) { tslib_1.__extends(HitDragListener, _super); function HitDragListener(component, options) { var _this = _super.call(this, options) || this; _this.component = component; return _this; } // Called when drag listening starts (but a real drag has not necessarily began). // ev might be undefined if dragging was started manually. HitDragListener.prototype.handleInteractionStart = function (ev) { var subjectEl = this.subjectEl; var subjectRect; var origPoint; var point; this.component.hitsNeeded(); this.computeScrollBounds(); // for autoscroll if (ev) { origPoint = { left: util_1.getEvX(ev), top: util_1.getEvY(ev) }; point = origPoint; // constrain the point to bounds of the element being dragged if (subjectEl) { subjectRect = util_1.getOuterRect(subjectEl); // used for centering as well point = util_1.constrainPoint(point, subjectRect); } this.origHit = this.queryHit(point.left, point.top); // treat the center of the subject as the collision point? if (subjectEl && this.options.subjectCenter) { // only consider the area the subject overlaps the hit. best for large subjects. // TODO: skip this if hit didn't supply left/right/top/bottom if (this.origHit) { subjectRect = util_1.intersectRects(this.origHit, subjectRect) || subjectRect; // in case there is no intersection } point = util_1.getRectCenter(subjectRect); } this.coordAdjust = util_1.diffPoints(point, origPoint); // point - origPoint } else { this.origHit = null; this.coordAdjust = null; } // call the super-method. do it after origHit has been computed _super.prototype.handleInteractionStart.call(this, ev); }; // Called when the actual drag has started HitDragListener.prototype.handleDragStart = function (ev) { var hit; _super.prototype.handleDragStart.call(this, ev); // might be different from this.origHit if the min-distance is large hit = this.queryHit(util_1.getEvX(ev), util_1.getEvY(ev)); // report the initial hit the mouse is over // especially important if no min-distance and drag starts immediately if (hit) { this.handleHitOver(hit); } }; // Called when the drag moves HitDragListener.prototype.handleDrag = function (dx, dy, ev) { var hit; _super.prototype.handleDrag.call(this, dx, dy, ev); hit = this.queryHit(util_1.getEvX(ev), util_1.getEvY(ev)); if (!isHitsEqual(hit, this.hit)) { // a different hit than before? if (this.hit) { this.handleHitOut(); } if (hit) { this.handleHitOver(hit); } } }; // Called when dragging has been stopped HitDragListener.prototype.handleDragEnd = function (ev) { this.handleHitDone(); _super.prototype.handleDragEnd.call(this, ev); }; // Called when a the mouse has just moved over a new hit HitDragListener.prototype.handleHitOver = function (hit) { var isOrig = isHitsEqual(hit, this.origHit); this.hit = hit; this.trigger('hitOver', this.hit, isOrig, this.origHit); }; // Called when the mouse has just moved out of a hit HitDragListener.prototype.handleHitOut = function () { if (this.hit) { this.trigger('hitOut', this.hit); this.handleHitDone(); this.hit = null; } }; // Called after a hitOut. Also called before a dragStop HitDragListener.prototype.handleHitDone = function () { if (this.hit) { this.trigger('hitDone', this.hit); } }; // Called when the interaction ends, whether there was a real drag or not HitDragListener.prototype.handleInteractionEnd = function (ev, isCancelled) { _super.prototype.handleInteractionEnd.call(this, ev, isCancelled); this.origHit = null; this.hit = null; this.component.hitsNotNeeded(); }; // Called when scrolling has stopped, whether through auto scroll, or the user scrolling HitDragListener.prototype.handleScrollEnd = function () { _super.prototype.handleScrollEnd.call(this); // hits' absolute positions will be in new places after a user's scroll. // HACK for recomputing. if (this.isDragging) { this.component.releaseHits(); this.component.prepareHits(); } }; // Gets the hit underneath the coordinates for the given mouse event HitDragListener.prototype.queryHit = function (left, top) { if (this.coordAdjust) { left += this.coordAdjust.left; top += this.coordAdjust.top; } return this.component.queryHit(left, top); }; return HitDragListener; }(DragListener_1.default)); exports.default = HitDragListener; // Returns `true` if the hits are identically equal. `false` otherwise. Must be from the same component. // Two null values will be considered equal, as two "out of the component" states are the same. function isHitsEqual(hit0, hit1) { if (!hit0 && !hit1) { return true; } if (hit0 && hit1) { return hit0.component === hit1.component && isHitPropsWithin(hit0, hit1) && isHitPropsWithin(hit1, hit0); // ensures all props are identical } return false; } // Returns true if all of subHit's non-standard properties are within superHit function isHitPropsWithin(subHit, superHit) { for (var propName in subHit) { if (!/^(component|left|right|top|bottom)$/.test(propName)) { if (subHit[propName] !== superHit[propName]) { return false; } } } return true; } /***/ }), /* 18 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); exports.version = '3.10.0'; // When introducing internal API incompatibilities (where fullcalendar plugins would break), // the minor version of the calendar should be upped (ex: 2.7.2 -> 2.8.0) // and the below integer should be incremented. exports.internalApiVersion = 12; var util_1 = __webpack_require__(4); exports.applyAll = util_1.applyAll; exports.debounce = util_1.debounce; exports.isInt = util_1.isInt; exports.htmlEscape = util_1.htmlEscape; exports.cssToStr = util_1.cssToStr; exports.proxy = util_1.proxy; exports.capitaliseFirstLetter = util_1.capitaliseFirstLetter; exports.getOuterRect = util_1.getOuterRect; exports.getClientRect = util_1.getClientRect; exports.getContentRect = util_1.getContentRect; exports.getScrollbarWidths = util_1.getScrollbarWidths; exports.preventDefault = util_1.preventDefault; exports.parseFieldSpecs = util_1.parseFieldSpecs; exports.compareByFieldSpecs = util_1.compareByFieldSpecs; exports.compareByFieldSpec = util_1.compareByFieldSpec; exports.flexibleCompare = util_1.flexibleCompare; exports.computeGreatestUnit = util_1.computeGreatestUnit; exports.divideRangeByDuration = util_1.divideRangeByDuration; exports.divideDurationByDuration = util_1.divideDurationByDuration; exports.multiplyDuration = util_1.multiplyDuration; exports.durationHasTime = util_1.durationHasTime; exports.log = util_1.log; exports.warn = util_1.warn; exports.removeExact = util_1.removeExact; exports.intersectRects = util_1.intersectRects; exports.allowSelection = util_1.allowSelection; exports.attrsToStr = util_1.attrsToStr; exports.compareNumbers = util_1.compareNumbers; exports.compensateScroll = util_1.compensateScroll; exports.computeDurationGreatestUnit = util_1.computeDurationGreatestUnit; exports.constrainPoint = util_1.constrainPoint; exports.copyOwnProps = util_1.copyOwnProps; exports.diffByUnit = util_1.diffByUnit; exports.diffDay = util_1.diffDay; exports.diffDayTime = util_1.diffDayTime; exports.diffPoints = util_1.diffPoints; exports.disableCursor = util_1.disableCursor; exports.distributeHeight = util_1.distributeHeight; exports.enableCursor = util_1.enableCursor; exports.firstDefined = util_1.firstDefined; exports.getEvIsTouch = util_1.getEvIsTouch; exports.getEvX = util_1.getEvX; exports.getEvY = util_1.getEvY; exports.getRectCenter = util_1.getRectCenter; exports.getScrollParent = util_1.getScrollParent; exports.hasOwnProp = util_1.hasOwnProp; exports.isArraysEqual = util_1.isArraysEqual; exports.isNativeDate = util_1.isNativeDate; exports.isPrimaryMouseButton = util_1.isPrimaryMouseButton; exports.isTimeString = util_1.isTimeString; exports.matchCellWidths = util_1.matchCellWidths; exports.mergeProps = util_1.mergeProps; exports.preventSelection = util_1.preventSelection; exports.removeMatching = util_1.removeMatching; exports.stripHtmlEntities = util_1.stripHtmlEntities; exports.subtractInnerElHeight = util_1.subtractInnerElHeight; exports.uncompensateScroll = util_1.uncompensateScroll; exports.undistributeHeight = util_1.undistributeHeight; exports.dayIDs = util_1.dayIDs; exports.unitsDesc = util_1.unitsDesc; var date_formatting_1 = __webpack_require__(49); exports.formatDate = date_formatting_1.formatDate; exports.formatRange = date_formatting_1.formatRange; exports.queryMostGranularFormatUnit = date_formatting_1.queryMostGranularFormatUnit; var locale_1 = __webpack_require__(32); exports.datepickerLocale = locale_1.datepickerLocale; exports.locale = locale_1.locale; exports.getMomentLocaleData = locale_1.getMomentLocaleData; exports.populateInstanceComputableOptions = locale_1.populateInstanceComputableOptions; var util_2 = __webpack_require__(19); exports.eventDefsToEventInstances = util_2.eventDefsToEventInstances; exports.eventFootprintToComponentFootprint = util_2.eventFootprintToComponentFootprint; exports.eventInstanceToEventRange = util_2.eventInstanceToEventRange; exports.eventInstanceToUnzonedRange = util_2.eventInstanceToUnzonedRange; exports.eventRangeToEventFootprint = util_2.eventRangeToEventFootprint; var moment_ext_1 = __webpack_require__(11); exports.moment = moment_ext_1.default; var EmitterMixin_1 = __webpack_require__(13); exports.EmitterMixin = EmitterMixin_1.default; var ListenerMixin_1 = __webpack_require__(7); exports.ListenerMixin = ListenerMixin_1.default; var Model_1 = __webpack_require__(51); exports.Model = Model_1.default; var Constraints_1 = __webpack_require__(217); exports.Constraints = Constraints_1.default; var DateProfileGenerator_1 = __webpack_require__(55); exports.DateProfileGenerator = DateProfileGenerator_1.default; var UnzonedRange_1 = __webpack_require__(5); exports.UnzonedRange = UnzonedRange_1.default; var ComponentFootprint_1 = __webpack_require__(12); exports.ComponentFootprint = ComponentFootprint_1.default; var BusinessHourGenerator_1 = __webpack_require__(218); exports.BusinessHourGenerator = BusinessHourGenerator_1.default; var EventPeriod_1 = __webpack_require__(219); exports.EventPeriod = EventPeriod_1.default; var EventManager_1 = __webpack_require__(220); exports.EventManager = EventManager_1.default; var EventDef_1 = __webpack_require__(37); exports.EventDef = EventDef_1.default; var EventDefMutation_1 = __webpack_require__(39); exports.EventDefMutation = EventDefMutation_1.default; var EventDefParser_1 = __webpack_require__(36); exports.EventDefParser = EventDefParser_1.default; var EventInstance_1 = __webpack_require__(53); exports.EventInstance = EventInstance_1.default; var EventRange_1 = __webpack_require__(50); exports.EventRange = EventRange_1.default; var RecurringEventDef_1 = __webpack_require__(54); exports.RecurringEventDef = RecurringEventDef_1.default; var SingleEventDef_1 = __webpack_require__(9); exports.SingleEventDef = SingleEventDef_1.default; var EventDefDateMutation_1 = __webpack_require__(40); exports.EventDefDateMutation = EventDefDateMutation_1.default; var EventDateProfile_1 = __webpack_require__(16); exports.EventDateProfile = EventDateProfile_1.default; var EventSourceParser_1 = __webpack_require__(38); exports.EventSourceParser = EventSourceParser_1.default; var EventSource_1 = __webpack_require__(6); exports.EventSource = EventSource_1.default; var ThemeRegistry_1 = __webpack_require__(57); exports.defineThemeSystem = ThemeRegistry_1.defineThemeSystem; exports.getThemeSystemClass = ThemeRegistry_1.getThemeSystemClass; var EventInstanceGroup_1 = __webpack_require__(20); exports.EventInstanceGroup = EventInstanceGroup_1.default; var ArrayEventSource_1 = __webpack_require__(56); exports.ArrayEventSource = ArrayEventSource_1.default; var FuncEventSource_1 = __webpack_require__(223); exports.FuncEventSource = FuncEventSource_1.default; var JsonFeedEventSource_1 = __webpack_require__(224); exports.JsonFeedEventSource = JsonFeedEventSource_1.default; var EventFootprint_1 = __webpack_require__(34); exports.EventFootprint = EventFootprint_1.default; var Class_1 = __webpack_require__(35); exports.Class = Class_1.default; var Mixin_1 = __webpack_require__(15); exports.Mixin = Mixin_1.default; var CoordCache_1 = __webpack_require__(58); exports.CoordCache = CoordCache_1.default; var Iterator_1 = __webpack_require__(225); exports.Iterator = Iterator_1.default; var DragListener_1 = __webpack_require__(59); exports.DragListener = DragListener_1.default; var HitDragListener_1 = __webpack_require__(17); exports.HitDragListener = HitDragListener_1.default; var MouseFollower_1 = __webpack_require__(226); exports.MouseFollower = MouseFollower_1.default; var ParsableModelMixin_1 = __webpack_require__(52); exports.ParsableModelMixin = ParsableModelMixin_1.default; var Popover_1 = __webpack_require__(227); exports.Popover = Popover_1.default; var Promise_1 = __webpack_require__(21); exports.Promise = Promise_1.default; var TaskQueue_1 = __webpack_require__(228); exports.TaskQueue = TaskQueue_1.default; var RenderQueue_1 = __webpack_require__(229); exports.RenderQueue = RenderQueue_1.default; var Scroller_1 = __webpack_require__(41); exports.Scroller = Scroller_1.default; var Theme_1 = __webpack_require__(22); exports.Theme = Theme_1.default; var Component_1 = __webpack_require__(230); exports.Component = Component_1.default; var DateComponent_1 = __webpack_require__(231); exports.DateComponent = DateComponent_1.default; var InteractiveDateComponent_1 = __webpack_require__(42); exports.InteractiveDateComponent = InteractiveDateComponent_1.default; var Calendar_1 = __webpack_require__(232); exports.Calendar = Calendar_1.default; var View_1 = __webpack_require__(43); exports.View = View_1.default; var ViewRegistry_1 = __webpack_require__(24); exports.defineView = ViewRegistry_1.defineView; exports.getViewConfig = ViewRegistry_1.getViewConfig; var DayTableMixin_1 = __webpack_require__(60); exports.DayTableMixin = DayTableMixin_1.default; var BusinessHourRenderer_1 = __webpack_require__(61); exports.BusinessHourRenderer = BusinessHourRenderer_1.default; var EventRenderer_1 = __webpack_require__(44); exports.EventRenderer = EventRenderer_1.default; var FillRenderer_1 = __webpack_require__(62); exports.FillRenderer = FillRenderer_1.default; var HelperRenderer_1 = __webpack_require__(63); exports.HelperRenderer = HelperRenderer_1.default; var ExternalDropping_1 = __webpack_require__(233); exports.ExternalDropping = ExternalDropping_1.default; var EventResizing_1 = __webpack_require__(234); exports.EventResizing = EventResizing_1.default; var EventPointing_1 = __webpack_require__(64); exports.EventPointing = EventPointing_1.default; var EventDragging_1 = __webpack_require__(235); exports.EventDragging = EventDragging_1.default; var DateSelecting_1 = __webpack_require__(236); exports.DateSelecting = DateSelecting_1.default; var DateClicking_1 = __webpack_require__(237); exports.DateClicking = DateClicking_1.default; var Interaction_1 = __webpack_require__(14); exports.Interaction = Interaction_1.default; var StandardInteractionsMixin_1 = __webpack_require__(65); exports.StandardInteractionsMixin = StandardInteractionsMixin_1.default; var AgendaView_1 = __webpack_require__(238); exports.AgendaView = AgendaView_1.default; var TimeGrid_1 = __webpack_require__(239); exports.TimeGrid = TimeGrid_1.default; var TimeGridEventRenderer_1 = __webpack_require__(240); exports.TimeGridEventRenderer = TimeGridEventRenderer_1.default; var TimeGridFillRenderer_1 = __webpack_require__(242); exports.TimeGridFillRenderer = TimeGridFillRenderer_1.default; var TimeGridHelperRenderer_1 = __webpack_require__(241); exports.TimeGridHelperRenderer = TimeGridHelperRenderer_1.default; var DayGrid_1 = __webpack_require__(66); exports.DayGrid = DayGrid_1.default; var DayGridEventRenderer_1 = __webpack_require__(243); exports.DayGridEventRenderer = DayGridEventRenderer_1.default; var DayGridFillRenderer_1 = __webpack_require__(245); exports.DayGridFillRenderer = DayGridFillRenderer_1.default; var DayGridHelperRenderer_1 = __webpack_require__(244); exports.DayGridHelperRenderer = DayGridHelperRenderer_1.default; var BasicView_1 = __webpack_require__(67); exports.BasicView = BasicView_1.default; var BasicViewDateProfileGenerator_1 = __webpack_require__(68); exports.BasicViewDateProfileGenerator = BasicViewDateProfileGenerator_1.default; var MonthView_1 = __webpack_require__(246); exports.MonthView = MonthView_1.default; var MonthViewDateProfileGenerator_1 = __webpack_require__(247); exports.MonthViewDateProfileGenerator = MonthViewDateProfileGenerator_1.default; var ListView_1 = __webpack_require__(248); exports.ListView = ListView_1.default; var ListEventPointing_1 = __webpack_require__(250); exports.ListEventPointing = ListEventPointing_1.default; var ListEventRenderer_1 = __webpack_require__(249); exports.ListEventRenderer = ListEventRenderer_1.default; /***/ }), /* 19 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var EventRange_1 = __webpack_require__(50); var EventFootprint_1 = __webpack_require__(34); var ComponentFootprint_1 = __webpack_require__(12); function eventDefsToEventInstances(eventDefs, unzonedRange) { var eventInstances = []; var i; for (i = 0; i < eventDefs.length; i++) { eventInstances.push.apply(eventInstances, // append eventDefs[i].buildInstances(unzonedRange)); } return eventInstances; } exports.eventDefsToEventInstances = eventDefsToEventInstances; function eventInstanceToEventRange(eventInstance) { return new EventRange_1.default(eventInstance.dateProfile.unzonedRange, eventInstance.def, eventInstance); } exports.eventInstanceToEventRange = eventInstanceToEventRange; function eventRangeToEventFootprint(eventRange) { return new EventFootprint_1.default(new ComponentFootprint_1.default(eventRange.unzonedRange, eventRange.eventDef.isAllDay()), eventRange.eventDef, eventRange.eventInstance // might not exist ); } exports.eventRangeToEventFootprint = eventRangeToEventFootprint; function eventInstanceToUnzonedRange(eventInstance) { return eventInstance.dateProfile.unzonedRange; } exports.eventInstanceToUnzonedRange = eventInstanceToUnzonedRange; function eventFootprintToComponentFootprint(eventFootprint) { return eventFootprint.componentFootprint; } exports.eventFootprintToComponentFootprint = eventFootprintToComponentFootprint; /***/ }), /* 20 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var UnzonedRange_1 = __webpack_require__(5); var util_1 = __webpack_require__(19); var EventRange_1 = __webpack_require__(50); /* It's expected that there will be at least one EventInstance, OR that an explicitEventDef is assigned. */ var EventInstanceGroup = /** @class */ (function () { function EventInstanceGroup(eventInstances) { this.eventInstances = eventInstances || []; } EventInstanceGroup.prototype.getAllEventRanges = function (constraintRange) { if (constraintRange) { return this.sliceNormalRenderRanges(constraintRange); } else { return this.eventInstances.map(util_1.eventInstanceToEventRange); } }; EventInstanceGroup.prototype.sliceRenderRanges = function (constraintRange) { if (this.isInverse()) { return this.sliceInverseRenderRanges(constraintRange); } else { return this.sliceNormalRenderRanges(constraintRange); } }; EventInstanceGroup.prototype.sliceNormalRenderRanges = function (constraintRange) { var eventInstances = this.eventInstances; var i; var eventInstance; var slicedRange; var slicedEventRanges = []; for (i = 0; i < eventInstances.length; i++) { eventInstance = eventInstances[i]; slicedRange = eventInstance.dateProfile.unzonedRange.intersect(constraintRange); if (slicedRange) { slicedEventRanges.push(new EventRange_1.default(slicedRange, eventInstance.def, eventInstance)); } } return slicedEventRanges; }; EventInstanceGroup.prototype.sliceInverseRenderRanges = function (constraintRange) { var unzonedRanges = this.eventInstances.map(util_1.eventInstanceToUnzonedRange); var ownerDef = this.getEventDef(); unzonedRanges = UnzonedRange_1.default.invertRanges(unzonedRanges, constraintRange); return unzonedRanges.map(function (unzonedRange) { return new EventRange_1.default(unzonedRange, ownerDef); // don't give an EventInstance }); }; EventInstanceGroup.prototype.isInverse = function () { return this.getEventDef().hasInverseRendering(); }; EventInstanceGroup.prototype.getEventDef = function () { return this.explicitEventDef || this.eventInstances[0].def; }; return EventInstanceGroup; }()); exports.default = EventInstanceGroup; /***/ }), /* 21 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var $ = __webpack_require__(3); var PromiseStub = { construct: function (executor) { var deferred = $.Deferred(); var promise = deferred.promise(); if (typeof executor === 'function') { executor(function (val) { deferred.resolve(val); attachImmediatelyResolvingThen(promise, val); }, function () { deferred.reject(); attachImmediatelyRejectingThen(promise); }); } return promise; }, resolve: function (val) { var deferred = $.Deferred().resolve(val); var promise = deferred.promise(); attachImmediatelyResolvingThen(promise, val); return promise; }, reject: function () { var deferred = $.Deferred().reject(); var promise = deferred.promise(); attachImmediatelyRejectingThen(promise); return promise; } }; exports.default = PromiseStub; function attachImmediatelyResolvingThen(promise, val) { promise.then = function (onResolve) { if (typeof onResolve === 'function') { return PromiseStub.resolve(onResolve(val)); } return promise; }; } function attachImmediatelyRejectingThen(promise) { promise.then = function (onResolve, onReject) { if (typeof onReject === 'function') { onReject(); } return promise; }; } /***/ }), /* 22 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var $ = __webpack_require__(3); var Theme = /** @class */ (function () { function Theme(optionsManager) { this.optionsManager = optionsManager; this.processIconOverride(); } Theme.prototype.processIconOverride = function () { if (this.iconOverrideOption) { this.setIconOverride(this.optionsManager.get(this.iconOverrideOption)); } }; Theme.prototype.setIconOverride = function (iconOverrideHash) { var iconClassesCopy; var buttonName; if ($.isPlainObject(iconOverrideHash)) { iconClassesCopy = $.extend({}, this.iconClasses); for (buttonName in iconOverrideHash) { iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]); } this.iconClasses = iconClassesCopy; } else if (iconOverrideHash === false) { this.iconClasses = {}; } }; Theme.prototype.applyIconOverridePrefix = function (className) { var prefix = this.iconOverridePrefix; if (prefix && className.indexOf(prefix) !== 0) { // if not already present className = prefix + className; } return className; }; Theme.prototype.getClass = function (key) { return this.classes[key] || ''; }; Theme.prototype.getIconClass = function (buttonName) { var className = this.iconClasses[buttonName]; if (className) { return this.baseIconClass + ' ' + className; } return ''; }; Theme.prototype.getCustomButtonIconClass = function (customButtonProps) { var className; if (this.iconOverrideCustomButtonOption) { className = customButtonProps[this.iconOverrideCustomButtonOption]; if (className) { return this.baseIconClass + ' ' + this.applyIconOverridePrefix(className); } } return ''; }; return Theme; }()); exports.default = Theme; Theme.prototype.classes = {}; Theme.prototype.iconClasses = {}; Theme.prototype.baseIconClass = ''; Theme.prototype.iconOverridePrefix = ''; /***/ }), /* 23 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var $ = __webpack_require__(3); var exportHooks = __webpack_require__(18); var EmitterMixin_1 = __webpack_require__(13); var ListenerMixin_1 = __webpack_require__(7); exportHooks.touchMouseIgnoreWait = 500; var globalEmitter = null; var neededCount = 0; /* Listens to document and window-level user-interaction events, like touch events and mouse events, and fires these events as-is to whoever is observing a GlobalEmitter. Best when used as a singleton via GlobalEmitter.get() Normalizes mouse/touch events. For examples: - ignores the the simulated mouse events that happen after a quick tap: mousemove+mousedown+mouseup+click - compensates for various buggy scenarios where a touchend does not fire */ var GlobalEmitter = /** @class */ (function () { function GlobalEmitter() { this.isTouching = false; this.mouseIgnoreDepth = 0; } // gets the singleton GlobalEmitter.get = function () { if (!globalEmitter) { globalEmitter = new GlobalEmitter(); globalEmitter.bind(); } return globalEmitter; }; // called when an object knows it will need a GlobalEmitter in the near future. GlobalEmitter.needed = function () { GlobalEmitter.get(); // ensures globalEmitter neededCount++; }; // called when the object that originally called needed() doesn't need a GlobalEmitter anymore. GlobalEmitter.unneeded = function () { neededCount--; if (!neededCount) { // nobody else needs it globalEmitter.unbind(); globalEmitter = null; } }; GlobalEmitter.prototype.bind = function () { var _this = this; this.listenTo($(document), { touchstart: this.handleTouchStart, touchcancel: this.handleTouchCancel, touchend: this.handleTouchEnd, mousedown: this.handleMouseDown, mousemove: this.handleMouseMove, mouseup: this.handleMouseUp, click: this.handleClick, selectstart: this.handleSelectStart, contextmenu: this.handleContextMenu }); // because we need to call preventDefault // because https://www.chromestatus.com/features/5093566007214080 // TODO: investigate performance because this is a global handler window.addEventListener('touchmove', this.handleTouchMoveProxy = function (ev) { _this.handleTouchMove($.Event(ev)); }, { passive: false } // allows preventDefault() ); // attach a handler to get called when ANY scroll action happens on the page. // this was impossible to do with normal on/off because 'scroll' doesn't bubble. // http://stackoverflow.com/a/32954565/96342 window.addEventListener('scroll', this.handleScrollProxy = function (ev) { _this.handleScroll($.Event(ev)); }, true // useCapture ); }; GlobalEmitter.prototype.unbind = function () { this.stopListeningTo($(document)); window.removeEventListener('touchmove', this.handleTouchMoveProxy, { passive: false } // use same options as addEventListener ); window.removeEventListener('scroll', this.handleScrollProxy, true // useCapture ); }; // Touch Handlers // ----------------------------------------------------------------------------------------------------------------- GlobalEmitter.prototype.handleTouchStart = function (ev) { // if a previous touch interaction never ended with a touchend, then implicitly end it, // but since a new touch interaction is about to begin, don't start the mouse ignore period. this.stopTouch(ev, true); // skipMouseIgnore=true this.isTouching = true; this.trigger('touchstart', ev); }; GlobalEmitter.prototype.handleTouchMove = function (ev) { if (this.isTouching) { this.trigger('touchmove', ev); } }; GlobalEmitter.prototype.handleTouchCancel = function (ev) { if (this.isTouching) { this.trigger('touchcancel', ev); // Have touchcancel fire an artificial touchend. That way, handlers won't need to listen to both. // If touchend fires later, it won't have any effect b/c isTouching will be false. this.stopTouch(ev); } }; GlobalEmitter.prototype.handleTouchEnd = function (ev) { this.stopTouch(ev); }; // Mouse Handlers // ----------------------------------------------------------------------------------------------------------------- GlobalEmitter.prototype.handleMouseDown = function (ev) { if (!this.shouldIgnoreMouse()) { this.trigger('mousedown', ev); } }; GlobalEmitter.prototype.handleMouseMove = function (ev) { if (!this.shouldIgnoreMouse()) { this.trigger('mousemove', ev); } }; GlobalEmitter.prototype.handleMouseUp = function (ev) { if (!this.shouldIgnoreMouse()) { this.trigger('mouseup', ev); } }; GlobalEmitter.prototype.handleClick = function (ev) { if (!this.shouldIgnoreMouse()) { this.trigger('click', ev); } }; // Misc Handlers // ----------------------------------------------------------------------------------------------------------------- GlobalEmitter.prototype.handleSelectStart = function (ev) { this.trigger('selectstart', ev); }; GlobalEmitter.prototype.handleContextMenu = function (ev) { this.trigger('contextmenu', ev); }; GlobalEmitter.prototype.handleScroll = function (ev) { this.trigger('scroll', ev); }; // Utils // ----------------------------------------------------------------------------------------------------------------- GlobalEmitter.prototype.stopTouch = function (ev, skipMouseIgnore) { if (skipMouseIgnore === void 0) { skipMouseIgnore = false; } if (this.isTouching) { this.isTouching = false; this.trigger('touchend', ev); if (!skipMouseIgnore) { this.startTouchMouseIgnore(); } } }; GlobalEmitter.prototype.startTouchMouseIgnore = function () { var _this = this; var wait = exportHooks.touchMouseIgnoreWait; if (wait) { this.mouseIgnoreDepth++; setTimeout(function () { _this.mouseIgnoreDepth--; }, wait); } }; GlobalEmitter.prototype.shouldIgnoreMouse = function () { return this.isTouching || Boolean(this.mouseIgnoreDepth); }; return GlobalEmitter; }()); exports.default = GlobalEmitter; ListenerMixin_1.default.mixInto(GlobalEmitter); EmitterMixin_1.default.mixInto(GlobalEmitter); /***/ }), /* 24 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var exportHooks = __webpack_require__(18); exports.viewHash = {}; exportHooks.views = exports.viewHash; function defineView(viewName, viewConfig) { exports.viewHash[viewName] = viewConfig; } exports.defineView = defineView; function getViewConfig(viewName) { return exports.viewHash[viewName]; } exports.getViewConfig = getViewConfig; /***/ }), /* 25 */, /* 26 */, /* 27 */, /* 28 */, /* 29 */, /* 30 */, /* 31 */, /* 32 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var $ = __webpack_require__(3); var moment = __webpack_require__(0); var exportHooks = __webpack_require__(18); var options_1 = __webpack_require__(33); var util_1 = __webpack_require__(4); exports.localeOptionHash = {}; exportHooks.locales = exports.localeOptionHash; // NOTE: can't guarantee any of these computations will run because not every locale has datepicker // configs, so make sure there are English fallbacks for these in the defaults file. var dpComputableOptions = { buttonText: function (dpOptions) { return { // the translations sometimes wrongly contain HTML entities prev: util_1.stripHtmlEntities(dpOptions.prevText), next: util_1.stripHtmlEntities(dpOptions.nextText), today: util_1.stripHtmlEntities(dpOptions.currentText) }; }, // Produces format strings like "MMMM YYYY" -> "September 2014" monthYearFormat: function (dpOptions) { return dpOptions.showMonthAfterYear ? 'YYYY[' + dpOptions.yearSuffix + '] MMMM' : 'MMMM YYYY[' + dpOptions.yearSuffix + ']'; } }; var momComputableOptions = { // Produces format strings like "ddd M/D" -> "Fri 9/15" dayOfMonthFormat: function (momOptions, fcOptions) { var format = momOptions.longDateFormat('l'); // for the format like "M/D/YYYY" // strip the year off the edge, as well as other misc non-whitespace chars format = format.replace(/^Y+[^\w\s]*|[^\w\s]*Y+$/g, ''); if (fcOptions.isRTL) { format += ' ddd'; // for RTL, add day-of-week to end } else { format = 'ddd ' + format; // for LTR, add day-of-week to beginning } return format; }, // Produces format strings like "h:mma" -> "6:00pm" mediumTimeFormat: function (momOptions) { return momOptions.longDateFormat('LT') .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand }, // Produces format strings like "h(:mm)a" -> "6pm" / "6:30pm" smallTimeFormat: function (momOptions) { return momOptions.longDateFormat('LT') .replace(':mm', '(:mm)') .replace(/(\Wmm)$/, '($1)') // like above, but for foreign locales .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand }, // Produces format strings like "h(:mm)t" -> "6p" / "6:30p" extraSmallTimeFormat: function (momOptions) { return momOptions.longDateFormat('LT') .replace(':mm', '(:mm)') .replace(/(\Wmm)$/, '($1)') // like above, but for foreign locales .replace(/\s*a$/i, 't'); // convert to AM/PM/am/pm to lowercase one-letter. remove any spaces beforehand }, // Produces format strings like "ha" / "H" -> "6pm" / "18" hourFormat: function (momOptions) { return momOptions.longDateFormat('LT') .replace(':mm', '') .replace(/(\Wmm)$/, '') // like above, but for foreign locales .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand }, // Produces format strings like "h:mm" -> "6:30" (with no AM/PM) noMeridiemTimeFormat: function (momOptions) { return momOptions.longDateFormat('LT') .replace(/\s*a$/i, ''); // remove trailing AM/PM } }; // options that should be computed off live calendar options (considers override options) // TODO: best place for this? related to locale? // TODO: flipping text based on isRTL is a bad idea because the CSS `direction` might want to handle it var instanceComputableOptions = { // Produces format strings for results like "Mo 16" smallDayDateFormat: function (options) { return options.isRTL ? 'D dd' : 'dd D'; }, // Produces format strings for results like "Wk 5" weekFormat: function (options) { return options.isRTL ? 'w[ ' + options.weekNumberTitle + ']' : '[' + options.weekNumberTitle + ' ]w'; }, // Produces format strings for results like "Wk5" smallWeekFormat: function (options) { return options.isRTL ? 'w[' + options.weekNumberTitle + ']' : '[' + options.weekNumberTitle + ']w'; } }; // TODO: make these computable properties in optionsManager function populateInstanceComputableOptions(options) { $.each(instanceComputableOptions, function (name, func) { if (options[name] == null) { options[name] = func(options); } }); } exports.populateInstanceComputableOptions = populateInstanceComputableOptions; // Initialize jQuery UI datepicker translations while using some of the translations // Will set this as the default locales for datepicker. function datepickerLocale(localeCode, dpLocaleCode, dpOptions) { // get the FullCalendar internal option hash for this locale. create if necessary var fcOptions = exports.localeOptionHash[localeCode] || (exports.localeOptionHash[localeCode] = {}); // transfer some simple options from datepicker to fc fcOptions.isRTL = dpOptions.isRTL; fcOptions.weekNumberTitle = dpOptions.weekHeader; // compute some more complex options from datepicker $.each(dpComputableOptions, function (name, func) { fcOptions[name] = func(dpOptions); }); var jqDatePicker = $.datepicker; // is jQuery UI Datepicker is on the page? if (jqDatePicker) { // Register the locale data. // FullCalendar and MomentJS use locale codes like "pt-br" but Datepicker // does it like "pt-BR" or if it doesn't have the locale, maybe just "pt". // Make an alias so the locale can be referenced either way. jqDatePicker.regional[dpLocaleCode] = jqDatePicker.regional[localeCode] = // alias dpOptions; // Alias 'en' to the default locale data. Do this every time. jqDatePicker.regional.en = jqDatePicker.regional['']; // Set as Datepicker's global defaults. jqDatePicker.setDefaults(dpOptions); } } exports.datepickerLocale = datepickerLocale; // Sets FullCalendar-specific translations. Will set the locales as the global default. function locale(localeCode, newFcOptions) { var fcOptions; var momOptions; // get the FullCalendar internal option hash for this locale. create if necessary fcOptions = exports.localeOptionHash[localeCode] || (exports.localeOptionHash[localeCode] = {}); // provided new options for this locales? merge them in if (newFcOptions) { fcOptions = exports.localeOptionHash[localeCode] = options_1.mergeOptions([fcOptions, newFcOptions]); } // compute locale options that weren't defined. // always do this. newFcOptions can be undefined when initializing from i18n file, // so no way to tell if this is an initialization or a default-setting. momOptions = getMomentLocaleData(localeCode); // will fall back to en $.each(momComputableOptions, function (name, func) { if (fcOptions[name] == null) { fcOptions[name] = (func)(momOptions, fcOptions); } }); // set it as the default locale for FullCalendar options_1.globalDefaults.locale = localeCode; } exports.locale = locale; // Returns moment's internal locale data. If doesn't exist, returns English. function getMomentLocaleData(localeCode) { return moment.localeData(localeCode) || moment.localeData('en'); } exports.getMomentLocaleData = getMomentLocaleData; // Initialize English by forcing computation of moment-derived options. // Also, sets it as the default. locale('en', options_1.englishDefaults); /***/ }), /* 33 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = __webpack_require__(4); exports.globalDefaults = { titleRangeSeparator: ' \u2013 ', monthYearFormat: 'MMMM YYYY', defaultTimedEventDuration: '02:00:00', defaultAllDayEventDuration: { days: 1 }, forceEventDuration: false, nextDayThreshold: '09:00:00', // display columnHeader: true, defaultView: 'month', aspectRatio: 1.35, header: { left: 'title', center: '', right: 'today prev,next' }, weekends: true, weekNumbers: false, weekNumberTitle: 'W', weekNumberCalculation: 'local', // editable: false, // nowIndicator: false, scrollTime: '06:00:00', minTime: '00:00:00', maxTime: '24:00:00', showNonCurrentDates: true, // event ajax lazyFetching: true, startParam: 'start', endParam: 'end', timezoneParam: 'timezone', timezone: false, // allDayDefault: undefined, // locale locale: null, isRTL: false, buttonText: { prev: 'prev', next: 'next', prevYear: 'prev year', nextYear: 'next year', year: 'year', today: 'today', month: 'month', week: 'week', day: 'day' }, // buttonIcons: null, allDayText: 'all-day', // allows setting a min-height to the event segment to prevent short events overlapping each other agendaEventMinHeight: 0, // jquery-ui theming theme: false, // themeButtonIcons: null, // eventResizableFromStart: false, dragOpacity: .75, dragRevertDuration: 500, dragScroll: true, // selectable: false, unselectAuto: true, // selectMinDistance: 0, dropAccept: '*', eventOrder: 'title', // eventRenderWait: null, eventLimit: false, eventLimitText: 'more', eventLimitClick: 'popover', dayPopoverFormat: 'LL', handleWindowResize: true, windowResizeDelay: 100, longPressDelay: 1000 }; exports.englishDefaults = { dayPopoverFormat: 'dddd, MMMM D' }; exports.rtlDefaults = { header: { left: 'next,prev today', center: '', right: 'title' }, buttonIcons: { prev: 'right-single-arrow', next: 'left-single-arrow', prevYear: 'right-double-arrow', nextYear: 'left-double-arrow' }, themeButtonIcons: { prev: 'circle-triangle-e', next: 'circle-triangle-w', nextYear: 'seek-prev', prevYear: 'seek-next' } }; var complexOptions = [ 'header', 'footer', 'buttonText', 'buttonIcons', 'themeButtonIcons' ]; // Merges an array of option objects into a single object function mergeOptions(optionObjs) { return util_1.mergeProps(optionObjs, complexOptions); } exports.mergeOptions = mergeOptions; /***/ }), /* 34 */ /***/ (function(module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); var EventFootprint = /** @class */ (function () { function EventFootprint(componentFootprint, eventDef, eventInstance) { this.componentFootprint = componentFootprint; this.eventDef = eventDef; if (eventInstance) { this.eventInstance = eventInstance; } } EventFootprint.prototype.getEventLegacy = function () { return (this.eventInstance || this.eventDef).toLegacy(); }; return EventFootprint; }()); exports.default = EventFootprint; /***/ }), /* 35 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var util_1 = __webpack_require__(4); // Class that all other classes will inherit from var Class = /** @class */ (function () { function Class() { } // Called on a class to create a subclass. // LIMITATION: cannot provide a constructor! Class.extend = function (members) { var SubClass = /** @class */ (function (_super) { tslib_1.__extends(SubClass, _super); function SubClass() { return _super !== null && _super.apply(this, arguments) || this; } return SubClass; }(this)); util_1.copyOwnProps(members, SubClass.prototype); return SubClass; }; // Adds new member variables/methods to the class's prototype. // Can be called with another class, or a plain object hash containing new members. Class.mixin = function (members) { util_1.copyOwnProps(members, this.prototype); }; return Class; }()); exports.default = Class; /***/ }), /* 36 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var moment = __webpack_require__(0); var util_1 = __webpack_require__(4); var SingleEventDef_1 = __webpack_require__(9); var RecurringEventDef_1 = __webpack_require__(54); exports.default = { parse: function (eventInput, source) { if (util_1.isTimeString(eventInput.start) || moment.isDuration(eventInput.start) || util_1.isTimeString(eventInput.end) || moment.isDuration(eventInput.end)) { return RecurringEventDef_1.default.parse(eventInput, source); } else { return SingleEventDef_1.default.parse(eventInput, source); } } }; /***/ }), /* 37 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var $ = __webpack_require__(3); var ParsableModelMixin_1 = __webpack_require__(52); var EventDef = /** @class */ (function () { function EventDef(source) { this.source = source; this.className = []; this.miscProps = {}; } EventDef.parse = function (rawInput, source) { var def = new this(source); if (def.applyProps(rawInput)) { return def; } return false; }; EventDef.normalizeId = function (id) { return String(id); }; EventDef.generateId = function () { return '_fc' + (EventDef.uuid++); }; EventDef.prototype.clone = function () { var copy = new this.constructor(this.source); copy.id = this.id; copy.rawId = this.rawId; copy.uid = this.uid; // not really unique anymore :( EventDef.copyVerbatimStandardProps(this, copy); copy.className = this.className.slice(); // copy copy.miscProps = $.extend({}, this.miscProps); return copy; }; EventDef.prototype.hasInverseRendering = function () { return this.getRendering() === 'inverse-background'; }; EventDef.prototype.hasBgRendering = function () { var rendering = this.getRendering(); return rendering === 'inverse-background' || rendering === 'background'; }; EventDef.prototype.getRendering = function () { if (this.rendering != null) { return this.rendering; } return this.source.rendering; }; EventDef.prototype.getConstraint = function () { if (this.constraint != null) { return this.constraint; } if (this.source.constraint != null) { return this.source.constraint; } return this.source.calendar.opt('eventConstraint'); // what about View option? }; EventDef.prototype.getOverlap = function () { if (this.overlap != null) { return this.overlap; } if (this.source.overlap != null) { return this.source.overlap; } return this.source.calendar.opt('eventOverlap'); // what about View option? }; EventDef.prototype.isStartExplicitlyEditable = function () { if (this.startEditable != null) { return this.startEditable; } return this.source.startEditable; }; EventDef.prototype.isDurationExplicitlyEditable = function () { if (this.durationEditable != null) { return this.durationEditable; } return this.source.durationEditable; }; EventDef.prototype.isExplicitlyEditable = function () { if (this.editable != null) { return this.editable; } return this.source.editable; }; EventDef.prototype.toLegacy = function () { var obj = $.extend({}, this.miscProps); obj._id = this.uid; obj.source = this.source; obj.className = this.className.slice(); // copy obj.allDay = this.isAllDay(); if (this.rawId != null) { obj.id = this.rawId; } EventDef.copyVerbatimStandardProps(this, obj); return obj; }; EventDef.prototype.applyManualStandardProps = function (rawProps) { if (rawProps.id != null) { this.id = EventDef.normalizeId((this.rawId = rawProps.id)); } else { this.id = EventDef.generateId(); } if (rawProps._id != null) { // accept this prop, even tho somewhat internal this.uid = String(rawProps._id); } else { this.uid = EventDef.generateId(); } // TODO: converge with EventSource if ($.isArray(rawProps.className)) { this.className = rawProps.className; } if (typeof rawProps.className === 'string') { this.className = rawProps.className.split(/\s+/); } return true; }; EventDef.prototype.applyMiscProps = function (rawProps) { $.extend(this.miscProps, rawProps); }; EventDef.uuid = 0; EventDef.defineStandardProps = ParsableModelMixin_1.default.defineStandardProps; EventDef.copyVerbatimStandardProps = ParsableModelMixin_1.default.copyVerbatimStandardProps; return EventDef; }()); exports.default = EventDef; ParsableModelMixin_1.default.mixInto(EventDef); EventDef.defineStandardProps({ // not automatically assigned (`false`) _id: false, id: false, className: false, source: false, // automatically assigned (`true`) title: true, url: true, rendering: true, constraint: true, overlap: true, editable: true, startEditable: true, durationEditable: true, color: true, backgroundColor: true, borderColor: true, textColor: true }); /***/ }), /* 38 */ /***/ (function(module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.default = { sourceClasses: [], registerClass: function (EventSourceClass) { this.sourceClasses.unshift(EventSourceClass); // give highest priority }, parse: function (rawInput, calendar) { var sourceClasses = this.sourceClasses; var i; var eventSource; for (i = 0; i < sourceClasses.length; i++) { eventSource = sourceClasses[i].parse(rawInput, calendar); if (eventSource) { return eventSource; } } } }; /***/ }), /* 39 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = __webpack_require__(4); var EventDateProfile_1 = __webpack_require__(16); var EventDef_1 = __webpack_require__(37); var EventDefDateMutation_1 = __webpack_require__(40); var SingleEventDef_1 = __webpack_require__(9); var EventDefMutation = /** @class */ (function () { function EventDefMutation() { } EventDefMutation.createFromRawProps = function (eventInstance, rawProps, largeUnit) { var eventDef = eventInstance.def; var dateProps = {}; var standardProps = {}; var miscProps = {}; var verbatimStandardProps = {}; var eventDefId = null; var className = null; var propName; var dateProfile; var dateMutation; var defMutation; for (propName in rawProps) { if (EventDateProfile_1.default.isStandardProp(propName)) { dateProps[propName] = rawProps[propName]; } else if (eventDef.isStandardProp(propName)) { standardProps[propName] = rawProps[propName]; } else if (eventDef.miscProps[propName] !== rawProps[propName]) { // only if changed miscProps[propName] = rawProps[propName]; } } dateProfile = EventDateProfile_1.default.parse(dateProps, eventDef.source); if (dateProfile) { // no failure? dateMutation = EventDefDateMutation_1.default.createFromDiff(eventInstance.dateProfile, dateProfile, largeUnit); } if (standardProps.id !== eventDef.id) { eventDefId = standardProps.id; // only apply if there's a change } if (!util_1.isArraysEqual(standardProps.className, eventDef.className)) { className = standardProps.className; // only apply if there's a change } EventDef_1.default.copyVerbatimStandardProps(standardProps, // src verbatimStandardProps // dest ); defMutation = new EventDefMutation(); defMutation.eventDefId = eventDefId; defMutation.className = className; defMutation.verbatimStandardProps = verbatimStandardProps; defMutation.miscProps = miscProps; if (dateMutation) { defMutation.dateMutation = dateMutation; } return defMutation; }; /* eventDef assumed to be a SingleEventDef. returns an undo function. */ EventDefMutation.prototype.mutateSingle = function (eventDef) { var origDateProfile; if (this.dateMutation) { origDateProfile = eventDef.dateProfile; eventDef.dateProfile = this.dateMutation.buildNewDateProfile(origDateProfile, eventDef.source.calendar); } // can't undo // TODO: more DRY with EventDef::applyManualStandardProps if (this.eventDefId != null) { eventDef.id = EventDef_1.default.normalizeId((eventDef.rawId = this.eventDefId)); } // can't undo // TODO: more DRY with EventDef::applyManualStandardProps if (this.className) { eventDef.className = this.className; } // can't undo if (this.verbatimStandardProps) { SingleEventDef_1.default.copyVerbatimStandardProps(this.verbatimStandardProps, // src eventDef // dest ); } // can't undo if (this.miscProps) { eventDef.applyMiscProps(this.miscProps); } if (origDateProfile) { return function () { eventDef.dateProfile = origDateProfile; }; } else { return function () { }; } }; EventDefMutation.prototype.setDateMutation = function (dateMutation) { if (dateMutation && !dateMutation.isEmpty()) { this.dateMutation = dateMutation; } else { this.dateMutation = null; } }; EventDefMutation.prototype.isEmpty = function () { return !this.dateMutation; }; return EventDefMutation; }()); exports.default = EventDefMutation; /***/ }), /* 40 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var util_1 = __webpack_require__(4); var EventDateProfile_1 = __webpack_require__(16); var EventDefDateMutation = /** @class */ (function () { function EventDefDateMutation() { this.clearEnd = false; this.forceTimed = false; this.forceAllDay = false; } EventDefDateMutation.createFromDiff = function (dateProfile0, dateProfile1, largeUnit) { var clearEnd = dateProfile0.end && !dateProfile1.end; var forceTimed = dateProfile0.isAllDay() && !dateProfile1.isAllDay(); var forceAllDay = !dateProfile0.isAllDay() && dateProfile1.isAllDay(); var dateDelta; var endDiff; var endDelta; var mutation; // subtracts the dates in the appropriate way, returning a duration function subtractDates(date1, date0) { if (largeUnit) { return util_1.diffByUnit(date1, date0, largeUnit); // poorly named } else if (dateProfile1.isAllDay()) { return util_1.diffDay(date1, date0); // poorly named } else { return util_1.diffDayTime(date1, date0); // poorly named } } dateDelta = subtractDates(dateProfile1.start, dateProfile0.start); if (dateProfile1.end) { // use unzonedRanges because dateProfile0.end might be null endDiff = subtractDates(dateProfile1.unzonedRange.getEnd(), dateProfile0.unzonedRange.getEnd()); endDelta = endDiff.subtract(dateDelta); } mutation = new EventDefDateMutation(); mutation.clearEnd = clearEnd; mutation.forceTimed = forceTimed; mutation.forceAllDay = forceAllDay; mutation.setDateDelta(dateDelta); mutation.setEndDelta(endDelta); return mutation; }; /* returns an undo function. */ EventDefDateMutation.prototype.buildNewDateProfile = function (eventDateProfile, calendar) { var start = eventDateProfile.start.clone(); var end = null; var shouldRezone = false; if (eventDateProfile.end && !this.clearEnd) { end = eventDateProfile.end.clone(); } else if (this.endDelta && !end) { end = calendar.getDefaultEventEnd(eventDateProfile.isAllDay(), start); } if (this.forceTimed) { shouldRezone = true; if (!start.hasTime()) { start.time(0); } if (end && !end.hasTime()) { end.time(0); } } else if (this.forceAllDay) { if (start.hasTime()) { start.stripTime(); } if (end && end.hasTime()) { end.stripTime(); } } if (this.dateDelta) { shouldRezone = true; start.add(this.dateDelta); if (end) { end.add(this.dateDelta); } } // do this before adding startDelta to start, so we can work off of start if (this.endDelta) { shouldRezone = true; end.add(this.endDelta); } if (this.startDelta) { shouldRezone = true; start.add(this.startDelta); } if (shouldRezone) { start = calendar.applyTimezone(start); if (end) { end = calendar.applyTimezone(end); } } // TODO: okay to access calendar option? if (!end && calendar.opt('forceEventDuration')) { end = calendar.getDefaultEventEnd(eventDateProfile.isAllDay(), start); } return new EventDateProfile_1.default(start, end, calendar); }; EventDefDateMutation.prototype.setDateDelta = function (dateDelta) { if (dateDelta && dateDelta.valueOf()) { this.dateDelta = dateDelta; } else { this.dateDelta = null; } }; EventDefDateMutation.prototype.setStartDelta = function (startDelta) { if (startDelta && startDelta.valueOf()) { this.startDelta = startDelta; } else { this.startDelta = null; } }; EventDefDateMutation.prototype.setEndDelta = function (endDelta) { if (endDelta && endDelta.valueOf()) { this.endDelta = endDelta; } else { this.endDelta = null; } }; EventDefDateMutation.prototype.isEmpty = function () { return !this.clearEnd && !this.forceTimed && !this.forceAllDay && !this.dateDelta && !this.startDelta && !this.endDelta; }; return EventDefDateMutation; }()); exports.default = EventDefDateMutation; /***/ }), /* 41 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var Class_1 = __webpack_require__(35); /* Embodies a div that has potential scrollbars */ var Scroller = /** @class */ (function (_super) { tslib_1.__extends(Scroller, _super); function Scroller(options) { var _this = _super.call(this) || this; options = options || {}; _this.overflowX = options.overflowX || options.overflow || 'auto'; _this.overflowY = options.overflowY || options.overflow || 'auto'; return _this; } Scroller.prototype.render = function () { this.el = this.renderEl(); this.applyOverflow(); }; Scroller.prototype.renderEl = function () { return (this.scrollEl = $('<div class="fc-scroller"></div>')); }; // sets to natural height, unlocks overflow Scroller.prototype.clear = function () { this.setHeight('auto'); this.applyOverflow(); }; Scroller.prototype.destroy = function () { this.el.remove(); }; // Overflow // ----------------------------------------------------------------------------------------------------------------- Scroller.prototype.applyOverflow = function () { this.scrollEl.css({ 'overflow-x': this.overflowX, 'overflow-y': this.overflowY }); }; // Causes any 'auto' overflow values to resolves to 'scroll' or 'hidden'. // Useful for preserving scrollbar widths regardless of future resizes. // Can pass in scrollbarWidths for optimization. Scroller.prototype.lockOverflow = function (scrollbarWidths) { var overflowX = this.overflowX; var overflowY = this.overflowY; scrollbarWidths = scrollbarWidths || this.getScrollbarWidths(); if (overflowX === 'auto') { overflowX = (scrollbarWidths.top || scrollbarWidths.bottom || // horizontal scrollbars? // OR scrolling pane with massless scrollbars? this.scrollEl[0].scrollWidth - 1 > this.scrollEl[0].clientWidth // subtract 1 because of IE off-by-one issue ) ? 'scroll' : 'hidden'; } if (overflowY === 'auto') { overflowY = (scrollbarWidths.left || scrollbarWidths.right || // vertical scrollbars? // OR scrolling pane with massless scrollbars? this.scrollEl[0].scrollHeight - 1 > this.scrollEl[0].clientHeight // subtract 1 because of IE off-by-one issue ) ? 'scroll' : 'hidden'; } this.scrollEl.css({ 'overflow-x': overflowX, 'overflow-y': overflowY }); }; // Getters / Setters // ----------------------------------------------------------------------------------------------------------------- Scroller.prototype.setHeight = function (height) { this.scrollEl.height(height); }; Scroller.prototype.getScrollTop = function () { return this.scrollEl.scrollTop(); }; Scroller.prototype.setScrollTop = function (top) { this.scrollEl.scrollTop(top); }; Scroller.prototype.getClientWidth = function () { return this.scrollEl[0].clientWidth; }; Scroller.prototype.getClientHeight = function () { return this.scrollEl[0].clientHeight; }; Scroller.prototype.getScrollbarWidths = function () { return util_1.getScrollbarWidths(this.scrollEl); }; return Scroller; }(Class_1.default)); exports.default = Scroller; /***/ }), /* 42 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var DateComponent_1 = __webpack_require__(231); var GlobalEmitter_1 = __webpack_require__(23); var InteractiveDateComponent = /** @class */ (function (_super) { tslib_1.__extends(InteractiveDateComponent, _super); function InteractiveDateComponent(_view, _options) { var _this = _super.call(this, _view, _options) || this; // self-config, overridable by subclasses _this.segSelector = '.fc-event-container > *'; // what constitutes an event element? if (_this.dateSelectingClass) { _this.dateClicking = new _this.dateClickingClass(_this); } if (_this.dateSelectingClass) { _this.dateSelecting = new _this.dateSelectingClass(_this); } if (_this.eventPointingClass) { _this.eventPointing = new _this.eventPointingClass(_this); } if (_this.eventDraggingClass && _this.eventPointing) { _this.eventDragging = new _this.eventDraggingClass(_this, _this.eventPointing); } if (_this.eventResizingClass && _this.eventPointing) { _this.eventResizing = new _this.eventResizingClass(_this, _this.eventPointing); } if (_this.externalDroppingClass) { _this.externalDropping = new _this.externalDroppingClass(_this); } return _this; } // Sets the container element that the view should render inside of, does global DOM-related initializations, // and renders all the non-date-related content inside. InteractiveDateComponent.prototype.setElement = function (el) { _super.prototype.setElement.call(this, el); if (this.dateClicking) { this.dateClicking.bindToEl(el); } if (this.dateSelecting) { this.dateSelecting.bindToEl(el); } this.bindAllSegHandlersToEl(el); }; InteractiveDateComponent.prototype.removeElement = function () { this.endInteractions(); _super.prototype.removeElement.call(this); }; InteractiveDateComponent.prototype.executeEventUnrender = function () { this.endInteractions(); _super.prototype.executeEventUnrender.call(this); }; InteractiveDateComponent.prototype.bindGlobalHandlers = function () { _super.prototype.bindGlobalHandlers.call(this); if (this.externalDropping) { this.externalDropping.bindToDocument(); } }; InteractiveDateComponent.prototype.unbindGlobalHandlers = function () { _super.prototype.unbindGlobalHandlers.call(this); if (this.externalDropping) { this.externalDropping.unbindFromDocument(); } }; InteractiveDateComponent.prototype.bindDateHandlerToEl = function (el, name, handler) { var _this = this; // attach a handler to the grid's root element. // jQuery will take care of unregistering them when removeElement gets called. this.el.on(name, function (ev) { if (!$(ev.target).is(_this.segSelector + ':not(.fc-helper),' + // directly on an event element _this.segSelector + ':not(.fc-helper) *,' + // within an event element '.fc-more,' + // a "more.." link 'a[data-goto]' // a clickable nav link )) { return handler.call(_this, ev); } }); }; InteractiveDateComponent.prototype.bindAllSegHandlersToEl = function (el) { [ this.eventPointing, this.eventDragging, this.eventResizing ].forEach(function (eventInteraction) { if (eventInteraction) { eventInteraction.bindToEl(el); } }); }; InteractiveDateComponent.prototype.bindSegHandlerToEl = function (el, name, handler) { var _this = this; el.on(name, this.segSelector, function (ev) { var segEl = $(ev.currentTarget); if (!segEl.is('.fc-helper')) { var seg = segEl.data('fc-seg'); // grab segment data. put there by View::renderEventsPayload if (seg && !_this.shouldIgnoreEventPointing()) { return handler.call(_this, seg, ev); // context will be the Grid } } }); }; InteractiveDateComponent.prototype.shouldIgnoreMouse = function () { // HACK // This will still work even though bindDateHandlerToEl doesn't use GlobalEmitter. return GlobalEmitter_1.default.get().shouldIgnoreMouse(); }; InteractiveDateComponent.prototype.shouldIgnoreTouch = function () { var view = this._getView(); // On iOS (and Android?) when a new selection is initiated overtop another selection, // the touchend never fires because the elements gets removed mid-touch-interaction (my theory). // HACK: simply don't allow this to happen. // ALSO: prevent selection when an *event* is already raised. return view.isSelected || view.selectedEvent; }; InteractiveDateComponent.prototype.shouldIgnoreEventPointing = function () { // only call the handlers if there is not a drag/resize in progress return (this.eventDragging && this.eventDragging.isDragging) || (this.eventResizing && this.eventResizing.isResizing); }; InteractiveDateComponent.prototype.canStartSelection = function (seg, ev) { return util_1.getEvIsTouch(ev) && !this.canStartResize(seg, ev) && (this.isEventDefDraggable(seg.footprint.eventDef) || this.isEventDefResizable(seg.footprint.eventDef)); }; InteractiveDateComponent.prototype.canStartDrag = function (seg, ev) { return !this.canStartResize(seg, ev) && this.isEventDefDraggable(seg.footprint.eventDef); }; InteractiveDateComponent.prototype.canStartResize = function (seg, ev) { var view = this._getView(); var eventDef = seg.footprint.eventDef; return (!util_1.getEvIsTouch(ev) || view.isEventDefSelected(eventDef)) && this.isEventDefResizable(eventDef) && $(ev.target).is('.fc-resizer'); }; // Kills all in-progress dragging. // Useful for when public API methods that result in re-rendering are invoked during a drag. // Also useful for when touch devices misbehave and don't fire their touchend. InteractiveDateComponent.prototype.endInteractions = function () { [ this.dateClicking, this.dateSelecting, this.eventPointing, this.eventDragging, this.eventResizing ].forEach(function (interaction) { if (interaction) { interaction.end(); } }); }; // Event Drag-n-Drop // --------------------------------------------------------------------------------------------------------------- // Computes if the given event is allowed to be dragged by the user InteractiveDateComponent.prototype.isEventDefDraggable = function (eventDef) { return this.isEventDefStartEditable(eventDef); }; InteractiveDateComponent.prototype.isEventDefStartEditable = function (eventDef) { var isEditable = eventDef.isStartExplicitlyEditable(); if (isEditable == null) { isEditable = this.opt('eventStartEditable'); if (isEditable == null) { isEditable = this.isEventDefGenerallyEditable(eventDef); } } return isEditable; }; InteractiveDateComponent.prototype.isEventDefGenerallyEditable = function (eventDef) { var isEditable = eventDef.isExplicitlyEditable(); if (isEditable == null) { isEditable = this.opt('editable'); } return isEditable; }; // Event Resizing // --------------------------------------------------------------------------------------------------------------- // Computes if the given event is allowed to be resized from its starting edge InteractiveDateComponent.prototype.isEventDefResizableFromStart = function (eventDef) { return this.opt('eventResizableFromStart') && this.isEventDefResizable(eventDef); }; // Computes if the given event is allowed to be resized from its ending edge InteractiveDateComponent.prototype.isEventDefResizableFromEnd = function (eventDef) { return this.isEventDefResizable(eventDef); }; // Computes if the given event is allowed to be resized by the user at all InteractiveDateComponent.prototype.isEventDefResizable = function (eventDef) { var isResizable = eventDef.isDurationExplicitlyEditable(); if (isResizable == null) { isResizable = this.opt('eventDurationEditable'); if (isResizable == null) { isResizable = this.isEventDefGenerallyEditable(eventDef); } } return isResizable; }; // Event Mutation / Constraints // --------------------------------------------------------------------------------------------------------------- // Diffs the two dates, returning a duration, based on granularity of the grid // TODO: port isTimeScale into this system? InteractiveDateComponent.prototype.diffDates = function (a, b) { if (this.largeUnit) { return util_1.diffByUnit(a, b, this.largeUnit); } else { return util_1.diffDayTime(a, b); } }; // is it allowed, in relation to the view's validRange? // NOTE: very similar to isExternalInstanceGroupAllowed InteractiveDateComponent.prototype.isEventInstanceGroupAllowed = function (eventInstanceGroup) { var view = this._getView(); var dateProfile = this.dateProfile; var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges()); var i; for (i = 0; i < eventFootprints.length; i++) { // TODO: just use getAllEventRanges directly if (!dateProfile.validUnzonedRange.containsRange(eventFootprints[i].componentFootprint.unzonedRange)) { return false; } } return view.calendar.constraints.isEventInstanceGroupAllowed(eventInstanceGroup); }; // NOTE: very similar to isEventInstanceGroupAllowed // when it's a completely anonymous external drag, no event. InteractiveDateComponent.prototype.isExternalInstanceGroupAllowed = function (eventInstanceGroup) { var view = this._getView(); var dateProfile = this.dateProfile; var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges()); var i; for (i = 0; i < eventFootprints.length; i++) { if (!dateProfile.validUnzonedRange.containsRange(eventFootprints[i].componentFootprint.unzonedRange)) { return false; } } for (i = 0; i < eventFootprints.length; i++) { // treat it as a selection // TODO: pass in eventInstanceGroup instead // because we don't want calendar's constraint system to depend on a component's // determination of footprints. if (!view.calendar.constraints.isSelectionFootprintAllowed(eventFootprints[i].componentFootprint)) { return false; } } return true; }; return InteractiveDateComponent; }(DateComponent_1.default)); exports.default = InteractiveDateComponent; /***/ }), /* 43 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var moment = __webpack_require__(0); var util_1 = __webpack_require__(4); var RenderQueue_1 = __webpack_require__(229); var DateProfileGenerator_1 = __webpack_require__(55); var InteractiveDateComponent_1 = __webpack_require__(42); var GlobalEmitter_1 = __webpack_require__(23); var UnzonedRange_1 = __webpack_require__(5); /* An abstract class from which other views inherit from ----------------------------------------------------------------------------------------------------------------------*/ var View = /** @class */ (function (_super) { tslib_1.__extends(View, _super); function View(calendar, viewSpec) { var _this = _super.call(this, null, viewSpec.options) || this; _this.batchRenderDepth = 0; _this.isSelected = false; // boolean whether a range of time is user-selected or not _this.calendar = calendar; _this.viewSpec = viewSpec; // shortcuts _this.type = viewSpec.type; // .name is deprecated _this.name = _this.type; _this.initRenderQueue(); _this.initHiddenDays(); _this.dateProfileGenerator = new _this.dateProfileGeneratorClass(_this); _this.bindBaseRenderHandlers(); _this.eventOrderSpecs = util_1.parseFieldSpecs(_this.opt('eventOrder')); // legacy if (_this['initialize']) { _this['initialize'](); } return _this; } View.prototype._getView = function () { return this; }; // Retrieves an option with the given name View.prototype.opt = function (name) { return this.options[name]; }; /* Render Queue ------------------------------------------------------------------------------------------------------------------*/ View.prototype.initRenderQueue = function () { this.renderQueue = new RenderQueue_1.default({ event: this.opt('eventRenderWait') }); this.renderQueue.on('start', this.onRenderQueueStart.bind(this)); this.renderQueue.on('stop', this.onRenderQueueStop.bind(this)); this.on('before:change', this.startBatchRender); this.on('change', this.stopBatchRender); }; View.prototype.onRenderQueueStart = function () { this.calendar.freezeContentHeight(); this.addScroll(this.queryScroll()); }; View.prototype.onRenderQueueStop = function () { if (this.calendar.updateViewSize()) { // success? this.popScroll(); } this.calendar.thawContentHeight(); }; View.prototype.startBatchRender = function () { if (!(this.batchRenderDepth++)) { this.renderQueue.pause(); } }; View.prototype.stopBatchRender = function () { if (!(--this.batchRenderDepth)) { this.renderQueue.resume(); } }; View.prototype.requestRender = function (func, namespace, actionType) { this.renderQueue.queue(func, namespace, actionType); }; // given func will auto-bind to `this` View.prototype.whenSizeUpdated = function (func) { if (this.renderQueue.isRunning) { this.renderQueue.one('stop', func.bind(this)); } else { func.call(this); } }; /* Title and Date Formatting ------------------------------------------------------------------------------------------------------------------*/ // Computes what the title at the top of the calendar should be for this view View.prototype.computeTitle = function (dateProfile) { var unzonedRange; // for views that span a large unit of time, show the proper interval, ignoring stray days before and after if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) { unzonedRange = dateProfile.currentUnzonedRange; } else { // for day units or smaller, use the actual day range unzonedRange = dateProfile.activeUnzonedRange; } return this.formatRange({ start: this.calendar.msToMoment(unzonedRange.startMs, dateProfile.isRangeAllDay), end: this.calendar.msToMoment(unzonedRange.endMs, dateProfile.isRangeAllDay) }, dateProfile.isRangeAllDay, this.opt('titleFormat') || this.computeTitleFormat(dateProfile), this.opt('titleRangeSeparator')); }; // Generates the format string that should be used to generate the title for the current date range. // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`. View.prototype.computeTitleFormat = function (dateProfile) { var currentRangeUnit = dateProfile.currentRangeUnit; if (currentRangeUnit === 'year') { return 'YYYY'; } else if (currentRangeUnit === 'month') { return this.opt('monthYearFormat'); // like "September 2014" } else if (dateProfile.currentUnzonedRange.as('days') > 1) { return 'll'; // multi-day range. shorter, like "Sep 9 - 10 2014" } else { return 'LL'; // one day. longer, like "September 9 2014" } }; // Date Setting/Unsetting // ----------------------------------------------------------------------------------------------------------------- View.prototype.setDate = function (date) { var currentDateProfile = this.get('dateProfile'); var newDateProfile = this.dateProfileGenerator.build(date, undefined, true); // forceToValid=true if (!currentDateProfile || !currentDateProfile.activeUnzonedRange.equals(newDateProfile.activeUnzonedRange)) { this.set('dateProfile', newDateProfile); } }; View.prototype.unsetDate = function () { this.unset('dateProfile'); }; // Event Data // ----------------------------------------------------------------------------------------------------------------- View.prototype.fetchInitialEvents = function (dateProfile) { var calendar = this.calendar; var forceAllDay = dateProfile.isRangeAllDay && !this.usesMinMaxTime; return calendar.requestEvents(calendar.msToMoment(dateProfile.activeUnzonedRange.startMs, forceAllDay), calendar.msToMoment(dateProfile.activeUnzonedRange.endMs, forceAllDay)); }; View.prototype.bindEventChanges = function () { this.listenTo(this.calendar, 'eventsReset', this.resetEvents); // TODO: make this a real event }; View.prototype.unbindEventChanges = function () { this.stopListeningTo(this.calendar, 'eventsReset'); }; View.prototype.setEvents = function (eventsPayload) { this.set('currentEvents', eventsPayload); this.set('hasEvents', true); }; View.prototype.unsetEvents = function () { this.unset('currentEvents'); this.unset('hasEvents'); }; View.prototype.resetEvents = function (eventsPayload) { this.startBatchRender(); this.unsetEvents(); this.setEvents(eventsPayload); this.stopBatchRender(); }; // Date High-level Rendering // ----------------------------------------------------------------------------------------------------------------- View.prototype.requestDateRender = function (dateProfile) { var _this = this; this.requestRender(function () { _this.executeDateRender(dateProfile); }, 'date', 'init'); }; View.prototype.requestDateUnrender = function () { var _this = this; this.requestRender(function () { _this.executeDateUnrender(); }, 'date', 'destroy'); }; // if dateProfile not specified, uses current View.prototype.executeDateRender = function (dateProfile) { _super.prototype.executeDateRender.call(this, dateProfile); if (this['render']) { this['render'](); // TODO: deprecate } this.trigger('datesRendered'); this.addScroll({ isDateInit: true }); this.startNowIndicator(); // shouldn't render yet because updateSize will be called soon }; View.prototype.executeDateUnrender = function () { this.unselect(); this.stopNowIndicator(); this.trigger('before:datesUnrendered'); if (this['destroy']) { this['destroy'](); // TODO: deprecate } _super.prototype.executeDateUnrender.call(this); }; // "Base" rendering // ----------------------------------------------------------------------------------------------------------------- View.prototype.bindBaseRenderHandlers = function () { var _this = this; this.on('datesRendered', function () { _this.whenSizeUpdated(_this.triggerViewRender); }); this.on('before:datesUnrendered', function () { _this.triggerViewDestroy(); }); }; View.prototype.triggerViewRender = function () { this.publiclyTrigger('viewRender', { context: this, args: [this, this.el] }); }; View.prototype.triggerViewDestroy = function () { this.publiclyTrigger('viewDestroy', { context: this, args: [this, this.el] }); }; // Event High-level Rendering // ----------------------------------------------------------------------------------------------------------------- View.prototype.requestEventsRender = function (eventsPayload) { var _this = this; this.requestRender(function () { _this.executeEventRender(eventsPayload); _this.whenSizeUpdated(_this.triggerAfterEventsRendered); }, 'event', 'init'); }; View.prototype.requestEventsUnrender = function () { var _this = this; this.requestRender(function () { _this.triggerBeforeEventsDestroyed(); _this.executeEventUnrender(); }, 'event', 'destroy'); }; // Business Hour High-level Rendering // ----------------------------------------------------------------------------------------------------------------- View.prototype.requestBusinessHoursRender = function (businessHourGenerator) { var _this = this; this.requestRender(function () { _this.renderBusinessHours(businessHourGenerator); }, 'businessHours', 'init'); }; View.prototype.requestBusinessHoursUnrender = function () { var _this = this; this.requestRender(function () { _this.unrenderBusinessHours(); }, 'businessHours', 'destroy'); }; // Misc view rendering utils // ----------------------------------------------------------------------------------------------------------------- // Binds DOM handlers to elements that reside outside the view container, such as the document View.prototype.bindGlobalHandlers = function () { _super.prototype.bindGlobalHandlers.call(this); this.listenTo(GlobalEmitter_1.default.get(), { touchstart: this.processUnselect, mousedown: this.handleDocumentMousedown }); }; // Unbinds DOM handlers from elements that reside outside the view container View.prototype.unbindGlobalHandlers = function () { _super.prototype.unbindGlobalHandlers.call(this); this.stopListeningTo(GlobalEmitter_1.default.get()); }; /* Now Indicator ------------------------------------------------------------------------------------------------------------------*/ // Immediately render the current time indicator and begins re-rendering it at an interval, // which is defined by this.getNowIndicatorUnit(). // TODO: somehow do this for the current whole day's background too View.prototype.startNowIndicator = function () { var _this = this; var unit; var update; var delay; // ms wait value if (this.opt('nowIndicator')) { unit = this.getNowIndicatorUnit(); if (unit) { update = util_1.proxy(this, 'updateNowIndicator'); // bind to `this` this.initialNowDate = this.calendar.getNow(); this.initialNowQueriedMs = new Date().valueOf(); // wait until the beginning of the next interval delay = this.initialNowDate.clone().startOf(unit).add(1, unit).valueOf() - this.initialNowDate.valueOf(); this.nowIndicatorTimeoutID = setTimeout(function () { _this.nowIndicatorTimeoutID = null; update(); delay = +moment.duration(1, unit); delay = Math.max(100, delay); // prevent too frequent _this.nowIndicatorIntervalID = setInterval(update, delay); // update every interval }, delay); } // rendering will be initiated in updateSize } }; // rerenders the now indicator, computing the new current time from the amount of time that has passed // since the initial getNow call. View.prototype.updateNowIndicator = function () { if (this.isDatesRendered && this.initialNowDate // activated before? ) { this.unrenderNowIndicator(); // won't unrender if unnecessary this.renderNowIndicator(this.initialNowDate.clone().add(new Date().valueOf() - this.initialNowQueriedMs) // add ms ); this.isNowIndicatorRendered = true; } }; // Immediately unrenders the view's current time indicator and stops any re-rendering timers. // Won't cause side effects if indicator isn't rendered. View.prototype.stopNowIndicator = function () { if (this.isNowIndicatorRendered) { if (this.nowIndicatorTimeoutID) { clearTimeout(this.nowIndicatorTimeoutID); this.nowIndicatorTimeoutID = null; } if (this.nowIndicatorIntervalID) { clearInterval(this.nowIndicatorIntervalID); this.nowIndicatorIntervalID = null; } this.unrenderNowIndicator(); this.isNowIndicatorRendered = false; } }; /* Dimensions ------------------------------------------------------------------------------------------------------------------*/ View.prototype.updateSize = function (totalHeight, isAuto, isResize) { if (this['setHeight']) { // for legacy API this['setHeight'](totalHeight, isAuto); } else { _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize); } this.updateNowIndicator(); }; /* Scroller ------------------------------------------------------------------------------------------------------------------*/ View.prototype.addScroll = function (scroll) { var queuedScroll = this.queuedScroll || (this.queuedScroll = {}); $.extend(queuedScroll, scroll); }; View.prototype.popScroll = function () { this.applyQueuedScroll(); this.queuedScroll = null; }; View.prototype.applyQueuedScroll = function () { if (this.queuedScroll) { this.applyScroll(this.queuedScroll); } }; View.prototype.queryScroll = function () { var scroll = {}; if (this.isDatesRendered) { $.extend(scroll, this.queryDateScroll()); } return scroll; }; View.prototype.applyScroll = function (scroll) { if (scroll.isDateInit && this.isDatesRendered) { $.extend(scroll, this.computeInitialDateScroll()); } if (this.isDatesRendered) { this.applyDateScroll(scroll); } }; View.prototype.computeInitialDateScroll = function () { return {}; // subclasses must implement }; View.prototype.queryDateScroll = function () { return {}; // subclasses must implement }; View.prototype.applyDateScroll = function (scroll) { // subclasses must implement }; /* Event Drag-n-Drop ------------------------------------------------------------------------------------------------------------------*/ View.prototype.reportEventDrop = function (eventInstance, eventMutation, el, ev) { var eventManager = this.calendar.eventManager; var undoFunc = eventManager.mutateEventsWithId(eventInstance.def.id, eventMutation); var dateMutation = eventMutation.dateMutation; // update the EventInstance, for handlers if (dateMutation) { eventInstance.dateProfile = dateMutation.buildNewDateProfile(eventInstance.dateProfile, this.calendar); } this.triggerEventDrop(eventInstance, // a drop doesn't necessarily mean a date mutation (ex: resource change) (dateMutation && dateMutation.dateDelta) || moment.duration(), undoFunc, el, ev); }; // Triggers event-drop handlers that have subscribed via the API View.prototype.triggerEventDrop = function (eventInstance, dateDelta, undoFunc, el, ev) { this.publiclyTrigger('eventDrop', { context: el[0], args: [ eventInstance.toLegacy(), dateDelta, undoFunc, ev, {}, this ] }); }; /* External Element Drag-n-Drop ------------------------------------------------------------------------------------------------------------------*/ // Must be called when an external element, via jQuery UI, has been dropped onto the calendar. // `meta` is the parsed data that has been embedded into the dragging event. // `dropLocation` is an object that contains the new zoned start/end/allDay values for the event. View.prototype.reportExternalDrop = function (singleEventDef, isEvent, isSticky, el, ev, ui) { if (isEvent) { this.calendar.eventManager.addEventDef(singleEventDef, isSticky); } this.triggerExternalDrop(singleEventDef, isEvent, el, ev, ui); }; // Triggers external-drop handlers that have subscribed via the API View.prototype.triggerExternalDrop = function (singleEventDef, isEvent, el, ev, ui) { // trigger 'drop' regardless of whether element represents an event this.publiclyTrigger('drop', { context: el[0], args: [ singleEventDef.dateProfile.start.clone(), ev, ui, this ] }); if (isEvent) { // signal an external event landed this.publiclyTrigger('eventReceive', { context: this, args: [ singleEventDef.buildInstance().toLegacy(), this ] }); } }; /* Event Resizing ------------------------------------------------------------------------------------------------------------------*/ // Must be called when an event in the view has been resized to a new length View.prototype.reportEventResize = function (eventInstance, eventMutation, el, ev) { var eventManager = this.calendar.eventManager; var undoFunc = eventManager.mutateEventsWithId(eventInstance.def.id, eventMutation); // update the EventInstance, for handlers eventInstance.dateProfile = eventMutation.dateMutation.buildNewDateProfile(eventInstance.dateProfile, this.calendar); var resizeDelta = eventMutation.dateMutation.endDelta || eventMutation.dateMutation.startDelta; this.triggerEventResize(eventInstance, resizeDelta, undoFunc, el, ev); }; // Triggers event-resize handlers that have subscribed via the API View.prototype.triggerEventResize = function (eventInstance, resizeDelta, undoFunc, el, ev) { this.publiclyTrigger('eventResize', { context: el[0], args: [ eventInstance.toLegacy(), resizeDelta, undoFunc, ev, {}, this ] }); }; /* Selection (time range) ------------------------------------------------------------------------------------------------------------------*/ // Selects a date span on the view. `start` and `end` are both Moments. // `ev` is the native mouse event that begin the interaction. View.prototype.select = function (footprint, ev) { this.unselect(ev); this.renderSelectionFootprint(footprint); this.reportSelection(footprint, ev); }; View.prototype.renderSelectionFootprint = function (footprint) { if (this['renderSelection']) { // legacy method in custom view classes this['renderSelection'](footprint.toLegacy(this.calendar)); } else { _super.prototype.renderSelectionFootprint.call(this, footprint); } }; // Called when a new selection is made. Updates internal state and triggers handlers. View.prototype.reportSelection = function (footprint, ev) { this.isSelected = true; this.triggerSelect(footprint, ev); }; // Triggers handlers to 'select' View.prototype.triggerSelect = function (footprint, ev) { var dateProfile = this.calendar.footprintToDateProfile(footprint); // abuse of "Event"DateProfile? this.publiclyTrigger('select', { context: this, args: [ dateProfile.start, dateProfile.end, ev, this ] }); }; // Undoes a selection. updates in the internal state and triggers handlers. // `ev` is the native mouse event that began the interaction. View.prototype.unselect = function (ev) { if (this.isSelected) { this.isSelected = false; if (this['destroySelection']) { this['destroySelection'](); // TODO: deprecate } this.unrenderSelection(); this.publiclyTrigger('unselect', { context: this, args: [ev, this] }); } }; /* Event Selection ------------------------------------------------------------------------------------------------------------------*/ View.prototype.selectEventInstance = function (eventInstance) { if (!this.selectedEventInstance || this.selectedEventInstance !== eventInstance) { this.unselectEventInstance(); this.getEventSegs().forEach(function (seg) { if (seg.footprint.eventInstance === eventInstance && seg.el // necessary? ) { seg.el.addClass('fc-selected'); } }); this.selectedEventInstance = eventInstance; } }; View.prototype.unselectEventInstance = function () { if (this.selectedEventInstance) { this.getEventSegs().forEach(function (seg) { if (seg.el) { // necessary? seg.el.removeClass('fc-selected'); } }); this.selectedEventInstance = null; } }; View.prototype.isEventDefSelected = function (eventDef) { // event references might change on refetchEvents(), while selectedEventInstance doesn't, // so compare IDs return this.selectedEventInstance && this.selectedEventInstance.def.id === eventDef.id; }; /* Mouse / Touch Unselecting (time range & event unselection) ------------------------------------------------------------------------------------------------------------------*/ // TODO: move consistently to down/start or up/end? // TODO: don't kill previous selection if touch scrolling View.prototype.handleDocumentMousedown = function (ev) { if (util_1.isPrimaryMouseButton(ev)) { this.processUnselect(ev); } }; View.prototype.processUnselect = function (ev) { this.processRangeUnselect(ev); this.processEventUnselect(ev); }; View.prototype.processRangeUnselect = function (ev) { var ignore; // is there a time-range selection? if (this.isSelected && this.opt('unselectAuto')) { // only unselect if the clicked element is not identical to or inside of an 'unselectCancel' element ignore = this.opt('unselectCancel'); if (!ignore || !$(ev.target).closest(ignore).length) { this.unselect(ev); } } }; View.prototype.processEventUnselect = function (ev) { if (this.selectedEventInstance) { if (!$(ev.target).closest('.fc-selected').length) { this.unselectEventInstance(); } } }; /* Triggers ------------------------------------------------------------------------------------------------------------------*/ View.prototype.triggerBaseRendered = function () { this.publiclyTrigger('viewRender', { context: this, args: [this, this.el] }); }; View.prototype.triggerBaseUnrendered = function () { this.publiclyTrigger('viewDestroy', { context: this, args: [this, this.el] }); }; // Triggers handlers to 'dayClick' // Span has start/end of the clicked area. Only the start is useful. View.prototype.triggerDayClick = function (footprint, dayEl, ev) { var dateProfile = this.calendar.footprintToDateProfile(footprint); // abuse of "Event"DateProfile? this.publiclyTrigger('dayClick', { context: dayEl, args: [dateProfile.start, ev, this] }); }; /* Date Utils ------------------------------------------------------------------------------------------------------------------*/ // For DateComponent::getDayClasses View.prototype.isDateInOtherMonth = function (date, dateProfile) { return false; }; // Arguments after name will be forwarded to a hypothetical function value // WARNING: passed-in arguments will be given to generator functions as-is and can cause side-effects. // Always clone your objects if you fear mutation. View.prototype.getUnzonedRangeOption = function (name) { var val = this.opt(name); if (typeof val === 'function') { val = val.apply(null, Array.prototype.slice.call(arguments, 1)); } if (val) { return this.calendar.parseUnzonedRange(val); } }; /* Hidden Days ------------------------------------------------------------------------------------------------------------------*/ // Initializes internal variables related to calculating hidden days-of-week View.prototype.initHiddenDays = function () { var hiddenDays = this.opt('hiddenDays') || []; // array of day-of-week indices that are hidden var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool) var dayCnt = 0; var i; if (this.opt('weekends') === false) { hiddenDays.push(0, 6); // 0=sunday, 6=saturday } for (i = 0; i < 7; i++) { if (!(isHiddenDayHash[i] = $.inArray(i, hiddenDays) !== -1)) { dayCnt++; } } if (!dayCnt) { throw new Error('invalid hiddenDays'); // all days were hidden? bad. } this.isHiddenDayHash = isHiddenDayHash; }; // Remove days from the beginning and end of the range that are computed as hidden. // If the whole range is trimmed off, returns null View.prototype.trimHiddenDays = function (inputUnzonedRange) { var start = inputUnzonedRange.getStart(); var end = inputUnzonedRange.getEnd(); if (start) { start = this.skipHiddenDays(start); } if (end) { end = this.skipHiddenDays(end, -1, true); } if (start === null || end === null || start < end) { return new UnzonedRange_1.default(start, end); } return null; }; // Is the current day hidden? // `day` is a day-of-week index (0-6), or a Moment View.prototype.isHiddenDay = function (day) { if (moment.isMoment(day)) { day = day.day(); } return this.isHiddenDayHash[day]; }; // Incrementing the current day until it is no longer a hidden day, returning a copy. // DOES NOT CONSIDER validUnzonedRange! // If the initial value of `date` is not a hidden day, don't do anything. // Pass `isExclusive` as `true` if you are dealing with an end date. // `inc` defaults to `1` (increment one day forward each time) View.prototype.skipHiddenDays = function (date, inc, isExclusive) { if (inc === void 0) { inc = 1; } if (isExclusive === void 0) { isExclusive = false; } var out = date.clone(); while (this.isHiddenDayHash[(out.day() + (isExclusive ? inc : 0) + 7) % 7]) { out.add(inc, 'days'); } return out; }; return View; }(InteractiveDateComponent_1.default)); exports.default = View; View.prototype.usesMinMaxTime = false; View.prototype.dateProfileGeneratorClass = DateProfileGenerator_1.default; View.watch('displayingDates', ['isInDom', 'dateProfile'], function (deps) { this.requestDateRender(deps.dateProfile); }, function () { this.requestDateUnrender(); }); View.watch('displayingBusinessHours', ['displayingDates', 'businessHourGenerator'], function (deps) { this.requestBusinessHoursRender(deps.businessHourGenerator); }, function () { this.requestBusinessHoursUnrender(); }); View.watch('initialEvents', ['dateProfile'], function (deps) { return this.fetchInitialEvents(deps.dateProfile); }); View.watch('bindingEvents', ['initialEvents'], function (deps) { this.setEvents(deps.initialEvents); this.bindEventChanges(); }, function () { this.unbindEventChanges(); this.unsetEvents(); }); View.watch('displayingEvents', ['displayingDates', 'hasEvents'], function () { this.requestEventsRender(this.get('currentEvents')); }, function () { this.requestEventsUnrender(); }); View.watch('title', ['dateProfile'], function (deps) { return (this.title = this.computeTitle(deps.dateProfile)); // assign to View for legacy reasons }); View.watch('legacyDateProps', ['dateProfile'], function (deps) { var calendar = this.calendar; var dateProfile = deps.dateProfile; // DEPRECATED, but we need to keep it updated... this.start = calendar.msToMoment(dateProfile.activeUnzonedRange.startMs, dateProfile.isRangeAllDay); this.end = calendar.msToMoment(dateProfile.activeUnzonedRange.endMs, dateProfile.isRangeAllDay); this.intervalStart = calendar.msToMoment(dateProfile.currentUnzonedRange.startMs, dateProfile.isRangeAllDay); this.intervalEnd = calendar.msToMoment(dateProfile.currentUnzonedRange.endMs, dateProfile.isRangeAllDay); }); /***/ }), /* 44 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var EventRenderer = /** @class */ (function () { function EventRenderer(component, fillRenderer) { this.view = component._getView(); this.component = component; this.fillRenderer = fillRenderer; } EventRenderer.prototype.opt = function (name) { return this.view.opt(name); }; // Updates values that rely on options and also relate to range EventRenderer.prototype.rangeUpdated = function () { var displayEventTime; var displayEventEnd; this.eventTimeFormat = this.opt('eventTimeFormat') || this.opt('timeFormat') || // deprecated this.computeEventTimeFormat(); displayEventTime = this.opt('displayEventTime'); if (displayEventTime == null) { displayEventTime = this.computeDisplayEventTime(); // might be based off of range } displayEventEnd = this.opt('displayEventEnd'); if (displayEventEnd == null) { displayEventEnd = this.computeDisplayEventEnd(); // might be based off of range } this.displayEventTime = displayEventTime; this.displayEventEnd = displayEventEnd; }; EventRenderer.prototype.render = function (eventsPayload) { var dateProfile = this.component._getDateProfile(); var eventDefId; var instanceGroup; var eventRanges; var bgRanges = []; var fgRanges = []; for (eventDefId in eventsPayload) { instanceGroup = eventsPayload[eventDefId]; eventRanges = instanceGroup.sliceRenderRanges(dateProfile.activeUnzonedRange); if (instanceGroup.getEventDef().hasBgRendering()) { bgRanges.push.apply(bgRanges, eventRanges); } else { fgRanges.push.apply(fgRanges, eventRanges); } } this.renderBgRanges(bgRanges); this.renderFgRanges(fgRanges); }; EventRenderer.prototype.unrender = function () { this.unrenderBgRanges(); this.unrenderFgRanges(); }; EventRenderer.prototype.renderFgRanges = function (eventRanges) { var eventFootprints = this.component.eventRangesToEventFootprints(eventRanges); var segs = this.component.eventFootprintsToSegs(eventFootprints); // render an `.el` on each seg // returns a subset of the segs. segs that were actually rendered segs = this.renderFgSegEls(segs); if (this.renderFgSegs(segs) !== false) { // no failure? this.fgSegs = segs; } }; EventRenderer.prototype.unrenderFgRanges = function () { this.unrenderFgSegs(this.fgSegs || []); this.fgSegs = null; }; EventRenderer.prototype.renderBgRanges = function (eventRanges) { var eventFootprints = this.component.eventRangesToEventFootprints(eventRanges); var segs = this.component.eventFootprintsToSegs(eventFootprints); if (this.renderBgSegs(segs) !== false) { // no failure? this.bgSegs = segs; } }; EventRenderer.prototype.unrenderBgRanges = function () { this.unrenderBgSegs(); this.bgSegs = null; }; EventRenderer.prototype.getSegs = function () { return (this.bgSegs || []).concat(this.fgSegs || []); }; // Renders foreground event segments onto the grid EventRenderer.prototype.renderFgSegs = function (segs) { // subclasses must implement // segs already has rendered els, and has been filtered. return false; // signal failure if not implemented }; // Unrenders all currently rendered foreground segments EventRenderer.prototype.unrenderFgSegs = function (segs) { // subclasses must implement }; EventRenderer.prototype.renderBgSegs = function (segs) { var _this = this; if (this.fillRenderer) { this.fillRenderer.renderSegs('bgEvent', segs, { getClasses: function (seg) { return _this.getBgClasses(seg.footprint.eventDef); }, getCss: function (seg) { return { 'background-color': _this.getBgColor(seg.footprint.eventDef) }; }, filterEl: function (seg, el) { return _this.filterEventRenderEl(seg.footprint, el); } }); } else { return false; // signal failure if no fillRenderer } }; EventRenderer.prototype.unrenderBgSegs = function () { if (this.fillRenderer) { this.fillRenderer.unrender('bgEvent'); } }; // Renders and assigns an `el` property for each foreground event segment. // Only returns segments that successfully rendered. EventRenderer.prototype.renderFgSegEls = function (segs, disableResizing) { var _this = this; if (disableResizing === void 0) { disableResizing = false; } var hasEventRenderHandlers = this.view.hasPublicHandlers('eventRender'); var html = ''; var renderedSegs = []; var i; if (segs.length) { // don't build an empty html string // build a large concatenation of event segment HTML for (i = 0; i < segs.length; i++) { this.beforeFgSegHtml(segs[i]); html += this.fgSegHtml(segs[i], disableResizing); } // Grab individual elements from the combined HTML string. Use each as the default rendering. // Then, compute the 'el' for each segment. An el might be null if the eventRender callback returned false. $(html).each(function (i, node) { var seg = segs[i]; var el = $(node); if (hasEventRenderHandlers) { // optimization el = _this.filterEventRenderEl(seg.footprint, el); } if (el) { el.data('fc-seg', seg); // used by handlers seg.el = el; renderedSegs.push(seg); } }); } return renderedSegs; }; EventRenderer.prototype.beforeFgSegHtml = function (seg) { }; // Generates the HTML for the default rendering of a foreground event segment. Used by renderFgSegEls() EventRenderer.prototype.fgSegHtml = function (seg, disableResizing) { // subclasses should implement }; // Generic utility for generating the HTML classNames for an event segment's element EventRenderer.prototype.getSegClasses = function (seg, isDraggable, isResizable) { var classes = [ 'fc-event', seg.isStart ? 'fc-start' : 'fc-not-start', seg.isEnd ? 'fc-end' : 'fc-not-end' ].concat(this.getClasses(seg.footprint.eventDef)); if (isDraggable) { classes.push('fc-draggable'); } if (isResizable) { classes.push('fc-resizable'); } // event is currently selected? attach a className. if (this.view.isEventDefSelected(seg.footprint.eventDef)) { classes.push('fc-selected'); } return classes; }; // Given an event and the default element used for rendering, returns the element that should actually be used. // Basically runs events and elements through the eventRender hook. EventRenderer.prototype.filterEventRenderEl = function (eventFootprint, el) { var legacy = eventFootprint.getEventLegacy(); var custom = this.view.publiclyTrigger('eventRender', { context: legacy, args: [legacy, el, this.view] }); if (custom === false) { // means don't render at all el = null; } else if (custom && custom !== true) { el = $(custom); } return el; }; // Compute the text that should be displayed on an event's element. // `range` can be the Event object itself, or something range-like, with at least a `start`. // If event times are disabled, or the event has no time, will return a blank string. // If not specified, formatStr will default to the eventTimeFormat setting, // and displayEnd will default to the displayEventEnd setting. EventRenderer.prototype.getTimeText = function (eventFootprint, formatStr, displayEnd) { return this._getTimeText(eventFootprint.eventInstance.dateProfile.start, eventFootprint.eventInstance.dateProfile.end, eventFootprint.componentFootprint.isAllDay, formatStr, displayEnd); }; EventRenderer.prototype._getTimeText = function (start, end, isAllDay, formatStr, displayEnd) { if (formatStr == null) { formatStr = this.eventTimeFormat; } if (displayEnd == null) { displayEnd = this.displayEventEnd; } if (this.displayEventTime && !isAllDay) { if (displayEnd && end) { return this.view.formatRange({ start: start, end: end }, false, // allDay formatStr); } else { return start.format(formatStr); } } return ''; }; EventRenderer.prototype.computeEventTimeFormat = function () { return this.opt('smallTimeFormat'); }; EventRenderer.prototype.computeDisplayEventTime = function () { return true; }; EventRenderer.prototype.computeDisplayEventEnd = function () { return true; }; EventRenderer.prototype.getBgClasses = function (eventDef) { var classNames = this.getClasses(eventDef); classNames.push('fc-bgevent'); return classNames; }; EventRenderer.prototype.getClasses = function (eventDef) { var objs = this.getStylingObjs(eventDef); var i; var classNames = []; for (i = 0; i < objs.length; i++) { classNames.push.apply(// append classNames, objs[i].eventClassName || objs[i].className || []); } return classNames; }; // Utility for generating event skin-related CSS properties EventRenderer.prototype.getSkinCss = function (eventDef) { return { 'background-color': this.getBgColor(eventDef), 'border-color': this.getBorderColor(eventDef), color: this.getTextColor(eventDef) }; }; // Queries for caller-specified color, then falls back to default EventRenderer.prototype.getBgColor = function (eventDef) { var objs = this.getStylingObjs(eventDef); var i; var val; for (i = 0; i < objs.length && !val; i++) { val = objs[i].eventBackgroundColor || objs[i].eventColor || objs[i].backgroundColor || objs[i].color; } if (!val) { val = this.opt('eventBackgroundColor') || this.opt('eventColor'); } return val; }; // Queries for caller-specified color, then falls back to default EventRenderer.prototype.getBorderColor = function (eventDef) { var objs = this.getStylingObjs(eventDef); var i; var val; for (i = 0; i < objs.length && !val; i++) { val = objs[i].eventBorderColor || objs[i].eventColor || objs[i].borderColor || objs[i].color; } if (!val) { val = this.opt('eventBorderColor') || this.opt('eventColor'); } return val; }; // Queries for caller-specified color, then falls back to default EventRenderer.prototype.getTextColor = function (eventDef) { var objs = this.getStylingObjs(eventDef); var i; var val; for (i = 0; i < objs.length && !val; i++) { val = objs[i].eventTextColor || objs[i].textColor; } if (!val) { val = this.opt('eventTextColor'); } return val; }; EventRenderer.prototype.getStylingObjs = function (eventDef) { var objs = this.getFallbackStylingObjs(eventDef); objs.unshift(eventDef); return objs; }; EventRenderer.prototype.getFallbackStylingObjs = function (eventDef) { return [eventDef.source]; }; EventRenderer.prototype.sortEventSegs = function (segs) { segs.sort(util_1.proxy(this, 'compareEventSegs')); }; // A cmp function for determining which segments should take visual priority EventRenderer.prototype.compareEventSegs = function (seg1, seg2) { var f1 = seg1.footprint; var f2 = seg2.footprint; var cf1 = f1.componentFootprint; var cf2 = f2.componentFootprint; var r1 = cf1.unzonedRange; var r2 = cf2.unzonedRange; return r1.startMs - r2.startMs || // earlier events go first (r2.endMs - r2.startMs) - (r1.endMs - r1.startMs) || // tie? longer events go first cf2.isAllDay - cf1.isAllDay || // tie? put all-day events first (booleans cast to 0/1) util_1.compareByFieldSpecs(f1.eventDef, f2.eventDef, this.view.eventOrderSpecs, f1.eventDef.miscProps, f2.eventDef.miscProps); }; return EventRenderer; }()); exports.default = EventRenderer; /***/ }), /* 45 */, /* 46 */, /* 47 */, /* 48 */, /* 49 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var moment_ext_1 = __webpack_require__(11); // Plugin // ------------------------------------------------------------------------------------------------- moment_ext_1.newMomentProto.format = function () { if (this._fullCalendar && arguments[0]) { // an enhanced moment? and a format string provided? return formatDate(this, arguments[0]); // our extended formatting } if (this._ambigTime) { return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD'); } if (this._ambigZone) { return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss'); } if (this._fullCalendar) { // enhanced non-ambig moment? // moment.format() doesn't ensure english, but we want to. return moment_ext_1.oldMomentFormat(englishMoment(this)); } return moment_ext_1.oldMomentProto.format.apply(this, arguments); }; moment_ext_1.newMomentProto.toISOString = function () { if (this._ambigTime) { return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD'); } if (this._ambigZone) { return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss'); } if (this._fullCalendar) { // enhanced non-ambig moment? // depending on browser, moment might not output english. ensure english. // https://github.com/moment/moment/blob/2.18.1/src/lib/moment/format.js#L22 return moment_ext_1.oldMomentProto.toISOString.apply(englishMoment(this), arguments); } return moment_ext_1.oldMomentProto.toISOString.apply(this, arguments); }; function englishMoment(mom) { if (mom.locale() !== 'en') { return mom.clone().locale('en'); } return mom; } // Config // --------------------------------------------------------------------------------------------------------------------- /* Inserted between chunks in the fake ("intermediate") formatting string. Important that it passes as whitespace (\s) because moment often identifies non-standalone months via a regexp with an \s. */ var PART_SEPARATOR = '\u000b'; // vertical tab /* Inserted as the first character of a literal-text chunk to indicate that the literal text is not actually literal text, but rather, a "special" token that has custom rendering (see specialTokens map). */ var SPECIAL_TOKEN_MARKER = '\u001f'; // information separator 1 /* Inserted at the beginning and end of a span of text that must have non-zero numeric characters. Handling of these markers is done in a post-processing step at the very end of text rendering. */ var MAYBE_MARKER = '\u001e'; // information separator 2 var MAYBE_REGEXP = new RegExp(MAYBE_MARKER + '([^' + MAYBE_MARKER + ']*)' + MAYBE_MARKER, 'g'); // must be global /* Addition formatting tokens we want recognized */ var specialTokens = { t: function (date) { return moment_ext_1.oldMomentFormat(date, 'a').charAt(0); }, T: function (date) { return moment_ext_1.oldMomentFormat(date, 'A').charAt(0); } }; /* The first characters of formatting tokens for units that are 1 day or larger. `value` is for ranking relative size (lower means bigger). `unit` is a normalized unit, used for comparing moments. */ var largeTokenMap = { Y: { value: 1, unit: 'year' }, M: { value: 2, unit: 'month' }, W: { value: 3, unit: 'week' }, w: { value: 3, unit: 'week' }, D: { value: 4, unit: 'day' }, d: { value: 4, unit: 'day' } // day of week }; // Single Date Formatting // --------------------------------------------------------------------------------------------------------------------- /* Formats `date` with a Moment formatting string, but allow our non-zero areas and special token */ function formatDate(date, formatStr) { return renderFakeFormatString(getParsedFormatString(formatStr).fakeFormatString, date); } exports.formatDate = formatDate; // Date Range Formatting // ------------------------------------------------------------------------------------------------- // TODO: make it work with timezone offset /* Using a formatting string meant for a single date, generate a range string, like "Sep 2 - 9 2013", that intelligently inserts a separator where the dates differ. If the dates are the same as far as the format string is concerned, just return a single rendering of one date, without any separator. */ function formatRange(date1, date2, formatStr, separator, isRTL) { var localeData; date1 = moment_ext_1.default.parseZone(date1); date2 = moment_ext_1.default.parseZone(date2); localeData = date1.localeData(); // Expand localized format strings, like "LL" -> "MMMM D YYYY". // BTW, this is not important for `formatDate` because it is impossible to put custom tokens // or non-zero areas in Moment's localized format strings. formatStr = localeData.longDateFormat(formatStr) || formatStr; return renderParsedFormat(getParsedFormatString(formatStr), date1, date2, separator || ' - ', isRTL); } exports.formatRange = formatRange; /* Renders a range with an already-parsed format string. */ function renderParsedFormat(parsedFormat, date1, date2, separator, isRTL) { var sameUnits = parsedFormat.sameUnits; var unzonedDate1 = date1.clone().stripZone(); // for same-unit comparisons var unzonedDate2 = date2.clone().stripZone(); // " var renderedParts1 = renderFakeFormatStringParts(parsedFormat.fakeFormatString, date1); var renderedParts2 = renderFakeFormatStringParts(parsedFormat.fakeFormatString, date2); var leftI; var leftStr = ''; var rightI; var rightStr = ''; var middleI; var middleStr1 = ''; var middleStr2 = ''; var middleStr = ''; // Start at the leftmost side of the formatting string and continue until you hit a token // that is not the same between dates. for (leftI = 0; leftI < sameUnits.length && (!sameUnits[leftI] || unzonedDate1.isSame(unzonedDate2, sameUnits[leftI])); leftI++) { leftStr += renderedParts1[leftI]; } // Similarly, start at the rightmost side of the formatting string and move left for (rightI = sameUnits.length - 1; rightI > leftI && (!sameUnits[rightI] || unzonedDate1.isSame(unzonedDate2, sameUnits[rightI])); rightI--) { // If current chunk is on the boundary of unique date-content, and is a special-case // date-formatting postfix character, then don't consume it. Consider it unique date-content. // TODO: make configurable if (rightI - 1 === leftI && renderedParts1[rightI] === '.') { break; } rightStr = renderedParts1[rightI] + rightStr; } // The area in the middle is different for both of the dates. // Collect them distinctly so we can jam them together later. for (middleI = leftI; middleI <= rightI; middleI++) { middleStr1 += renderedParts1[middleI]; middleStr2 += renderedParts2[middleI]; } if (middleStr1 || middleStr2) { if (isRTL) { middleStr = middleStr2 + separator + middleStr1; } else { middleStr = middleStr1 + separator + middleStr2; } } return processMaybeMarkers(leftStr + middleStr + rightStr); } // Format String Parsing // --------------------------------------------------------------------------------------------------------------------- var parsedFormatStrCache = {}; /* Returns a parsed format string, leveraging a cache. */ function getParsedFormatString(formatStr) { return parsedFormatStrCache[formatStr] || (parsedFormatStrCache[formatStr] = parseFormatString(formatStr)); } /* Parses a format string into the following: - fakeFormatString: a momentJS formatting string, littered with special control characters that get post-processed. - sameUnits: for every part in fakeFormatString, if the part is a token, the value will be a unit string (like "day"), that indicates how similar a range's start & end must be in order to share the same formatted text. If not a token, then the value is null. Always a flat array (not nested liked "chunks"). */ function parseFormatString(formatStr) { var chunks = chunkFormatString(formatStr); return { fakeFormatString: buildFakeFormatString(chunks), sameUnits: buildSameUnits(chunks) }; } /* Break the formatting string into an array of chunks. A 'maybe' chunk will have nested chunks. */ function chunkFormatString(formatStr) { var chunks = []; var match; // TODO: more descrimination // \4 is a backreference to the first character of a multi-character set. var chunker = /\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g; while ((match = chunker.exec(formatStr))) { if (match[1]) { // a literal string inside [ ... ] chunks.push.apply(chunks, // append splitStringLiteral(match[1])); } else if (match[2]) { // non-zero formatting inside ( ... ) chunks.push({ maybe: chunkFormatString(match[2]) }); } else if (match[3]) { // a formatting token chunks.push({ token: match[3] }); } else if (match[5]) { // an unenclosed literal string chunks.push.apply(chunks, // append splitStringLiteral(match[5])); } } return chunks; } /* Potentially splits a literal-text string into multiple parts. For special cases. */ function splitStringLiteral(s) { if (s === '. ') { return ['.', ' ']; // for locales with periods bound to the end of each year/month/date } else { return [s]; } } /* Given chunks parsed from a real format string, generate a fake (aka "intermediate") format string with special control characters that will eventually be given to moment for formatting, and then post-processed. */ function buildFakeFormatString(chunks) { var parts = []; var i; var chunk; for (i = 0; i < chunks.length; i++) { chunk = chunks[i]; if (typeof chunk === 'string') { parts.push('[' + chunk + ']'); } else if (chunk.token) { if (chunk.token in specialTokens) { parts.push(SPECIAL_TOKEN_MARKER + // useful during post-processing '[' + chunk.token + ']' // preserve as literal text ); } else { parts.push(chunk.token); // unprotected text implies a format string } } else if (chunk.maybe) { parts.push(MAYBE_MARKER + // useful during post-processing buildFakeFormatString(chunk.maybe) + MAYBE_MARKER); } } return parts.join(PART_SEPARATOR); } /* Given parsed chunks from a real formatting string, generates an array of unit strings (like "day") that indicate in which regard two dates must be similar in order to share range formatting text. The `chunks` can be nested (because of "maybe" chunks), however, the returned array will be flat. */ function buildSameUnits(chunks) { var units = []; var i; var chunk; var tokenInfo; for (i = 0; i < chunks.length; i++) { chunk = chunks[i]; if (chunk.token) { tokenInfo = largeTokenMap[chunk.token.charAt(0)]; units.push(tokenInfo ? tokenInfo.unit : 'second'); // default to a very strict same-second } else if (chunk.maybe) { units.push.apply(units, // append buildSameUnits(chunk.maybe)); } else { units.push(null); } } return units; } // Rendering to text // --------------------------------------------------------------------------------------------------------------------- /* Formats a date with a fake format string, post-processes the control characters, then returns. */ function renderFakeFormatString(fakeFormatString, date) { return processMaybeMarkers(renderFakeFormatStringParts(fakeFormatString, date).join('')); } /* Formats a date into parts that will have been post-processed, EXCEPT for the "maybe" markers. */ function renderFakeFormatStringParts(fakeFormatString, date) { var parts = []; var fakeRender = moment_ext_1.oldMomentFormat(date, fakeFormatString); var fakeParts = fakeRender.split(PART_SEPARATOR); var i; var fakePart; for (i = 0; i < fakeParts.length; i++) { fakePart = fakeParts[i]; if (fakePart.charAt(0) === SPECIAL_TOKEN_MARKER) { parts.push( // the literal string IS the token's name. // call special token's registered function. specialTokens[fakePart.substring(1)](date)); } else { parts.push(fakePart); } } return parts; } /* Accepts an almost-finally-formatted string and processes the "maybe" control characters, returning a new string. */ function processMaybeMarkers(s) { return s.replace(MAYBE_REGEXP, function (m0, m1) { if (m1.match(/[1-9]/)) { // any non-zero numeric characters? return m1; } else { return ''; } }); } // Misc Utils // ------------------------------------------------------------------------------------------------- /* Returns a unit string, either 'year', 'month', 'day', or null for the most granular formatting token in the string. */ function queryMostGranularFormatUnit(formatStr) { var chunks = chunkFormatString(formatStr); var i; var chunk; var candidate; var best; for (i = 0; i < chunks.length; i++) { chunk = chunks[i]; if (chunk.token) { candidate = largeTokenMap[chunk.token.charAt(0)]; if (candidate) { if (!best || candidate.value > best.value) { best = candidate; } } } } if (best) { return best.unit; } return null; } exports.queryMostGranularFormatUnit = queryMostGranularFormatUnit; /***/ }), /* 50 */ /***/ (function(module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); var EventRange = /** @class */ (function () { function EventRange(unzonedRange, eventDef, eventInstance) { this.unzonedRange = unzonedRange; this.eventDef = eventDef; if (eventInstance) { this.eventInstance = eventInstance; } } return EventRange; }()); exports.default = EventRange; /***/ }), /* 51 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var Class_1 = __webpack_require__(35); var EmitterMixin_1 = __webpack_require__(13); var ListenerMixin_1 = __webpack_require__(7); var Model = /** @class */ (function (_super) { tslib_1.__extends(Model, _super); function Model() { var _this = _super.call(this) || this; _this._watchers = {}; _this._props = {}; _this.applyGlobalWatchers(); _this.constructed(); return _this; } Model.watch = function (name) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } // subclasses should make a masked-copy of the superclass's map // TODO: write test if (!this.prototype.hasOwnProperty('_globalWatchArgs')) { this.prototype._globalWatchArgs = Object.create(this.prototype._globalWatchArgs); } this.prototype._globalWatchArgs[name] = args; }; Model.prototype.constructed = function () { // useful for monkeypatching. TODO: BaseClass? }; Model.prototype.applyGlobalWatchers = function () { var map = this._globalWatchArgs; var name; for (name in map) { this.watch.apply(this, [name].concat(map[name])); } }; Model.prototype.has = function (name) { return name in this._props; }; Model.prototype.get = function (name) { if (name === undefined) { return this._props; } return this._props[name]; }; Model.prototype.set = function (name, val) { var newProps; if (typeof name === 'string') { newProps = {}; newProps[name] = val === undefined ? null : val; } else { newProps = name; } this.setProps(newProps); }; Model.prototype.reset = function (newProps) { var oldProps = this._props; var changeset = {}; // will have undefined's to signal unsets var name; for (name in oldProps) { changeset[name] = undefined; } for (name in newProps) { changeset[name] = newProps[name]; } this.setProps(changeset); }; Model.prototype.unset = function (name) { var newProps = {}; var names; var i; if (typeof name === 'string') { names = [name]; } else { names = name; } for (i = 0; i < names.length; i++) { newProps[names[i]] = undefined; } this.setProps(newProps); }; Model.prototype.setProps = function (newProps) { var changedProps = {}; var changedCnt = 0; var name; var val; for (name in newProps) { val = newProps[name]; // a change in value? // if an object, don't check equality, because might have been mutated internally. // TODO: eventually enforce immutability. if (typeof val === 'object' || val !== this._props[name]) { changedProps[name] = val; changedCnt++; } } if (changedCnt) { this.trigger('before:batchChange', changedProps); for (name in changedProps) { val = changedProps[name]; this.trigger('before:change', name, val); this.trigger('before:change:' + name, val); } for (name in changedProps) { val = changedProps[name]; if (val === undefined) { delete this._props[name]; } else { this._props[name] = val; } this.trigger('change:' + name, val); this.trigger('change', name, val); } this.trigger('batchChange', changedProps); } }; Model.prototype.watch = function (name, depList, startFunc, stopFunc) { var _this = this; this.unwatch(name); this._watchers[name] = this._watchDeps(depList, function (deps) { var res = startFunc.call(_this, deps); if (res && res.then) { _this.unset(name); // put in an unset state while resolving res.then(function (val) { _this.set(name, val); }); } else { _this.set(name, res); } }, function (deps) { _this.unset(name); if (stopFunc) { stopFunc.call(_this, deps); } }); }; Model.prototype.unwatch = function (name) { var watcher = this._watchers[name]; if (watcher) { delete this._watchers[name]; watcher.teardown(); } }; Model.prototype._watchDeps = function (depList, startFunc, stopFunc) { var _this = this; var queuedChangeCnt = 0; var depCnt = depList.length; var satisfyCnt = 0; var values = {}; // what's passed as the `deps` arguments var bindTuples = []; // array of [ eventName, handlerFunc ] arrays var isCallingStop = false; var onBeforeDepChange = function (depName, val, isOptional) { queuedChangeCnt++; if (queuedChangeCnt === 1) { // first change to cause a "stop" ? if (satisfyCnt === depCnt) { // all deps previously satisfied? isCallingStop = true; stopFunc(values); isCallingStop = false; } } }; var onDepChange = function (depName, val, isOptional) { if (val === undefined) { // unsetting a value? // required dependency that was previously set? if (!isOptional && values[depName] !== undefined) { satisfyCnt--; } delete values[depName]; } else { // setting a value? // required dependency that was previously unset? if (!isOptional && values[depName] === undefined) { satisfyCnt++; } values[depName] = val; } queuedChangeCnt--; if (!queuedChangeCnt) { // last change to cause a "start"? // now finally satisfied or satisfied all along? if (satisfyCnt === depCnt) { // if the stopFunc initiated another value change, ignore it. // it will be processed by another change event anyway. if (!isCallingStop) { startFunc(values); } } } }; // intercept for .on() that remembers handlers var bind = function (eventName, handler) { _this.on(eventName, handler); bindTuples.push([eventName, handler]); }; // listen to dependency changes depList.forEach(function (depName) { var isOptional = false; if (depName.charAt(0) === '?') { // TODO: more DRY depName = depName.substring(1); isOptional = true; } bind('before:change:' + depName, function (val) { onBeforeDepChange(depName, val, isOptional); }); bind('change:' + depName, function (val) { onDepChange(depName, val, isOptional); }); }); // process current dependency values depList.forEach(function (depName) { var isOptional = false; if (depName.charAt(0) === '?') { // TODO: more DRY depName = depName.substring(1); isOptional = true; } if (_this.has(depName)) { values[depName] = _this.get(depName); satisfyCnt++; } else if (isOptional) { satisfyCnt++; } }); // initially satisfied if (satisfyCnt === depCnt) { startFunc(values); } return { teardown: function () { // remove all handlers for (var i = 0; i < bindTuples.length; i++) { _this.off(bindTuples[i][0], bindTuples[i][1]); } bindTuples = null; // was satisfied, so call stopFunc if (satisfyCnt === depCnt) { stopFunc(); } }, flash: function () { if (satisfyCnt === depCnt) { stopFunc(); startFunc(values); } } }; }; Model.prototype.flash = function (name) { var watcher = this._watchers[name]; if (watcher) { watcher.flash(); } }; return Model; }(Class_1.default)); exports.default = Model; Model.prototype._globalWatchArgs = {}; // mutation protection in Model.watch EmitterMixin_1.default.mixInto(Model); ListenerMixin_1.default.mixInto(Model); /***/ }), /* 52 */ /***/ (function(module, exports, __webpack_require__) { /* USAGE: import { default as ParsableModelMixin, ParsableModelInterface } from './ParsableModelMixin' in class: applyProps: ParsableModelInterface['applyProps'] applyManualStandardProps: ParsableModelInterface['applyManualStandardProps'] applyMiscProps: ParsableModelInterface['applyMiscProps'] isStandardProp: ParsableModelInterface['isStandardProp'] static defineStandardProps = ParsableModelMixin.defineStandardProps static copyVerbatimStandardProps = ParsableModelMixin.copyVerbatimStandardProps after class: ParsableModelMixin.mixInto(TheClass) */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var util_1 = __webpack_require__(4); var Mixin_1 = __webpack_require__(15); var ParsableModelMixin = /** @class */ (function (_super) { tslib_1.__extends(ParsableModelMixin, _super); function ParsableModelMixin() { return _super !== null && _super.apply(this, arguments) || this; } ParsableModelMixin.defineStandardProps = function (propDefs) { var proto = this.prototype; if (!proto.hasOwnProperty('standardPropMap')) { proto.standardPropMap = Object.create(proto.standardPropMap); } util_1.copyOwnProps(propDefs, proto.standardPropMap); }; ParsableModelMixin.copyVerbatimStandardProps = function (src, dest) { var map = this.prototype.standardPropMap; var propName; for (propName in map) { if (src[propName] != null && // in the src object? map[propName] === true // false means "copy verbatim" ) { dest[propName] = src[propName]; } } }; /* Returns true/false for success. Meant to be only called ONCE, at object creation. */ ParsableModelMixin.prototype.applyProps = function (rawProps) { var standardPropMap = this.standardPropMap; var manualProps = {}; var miscProps = {}; var propName; for (propName in rawProps) { if (standardPropMap[propName] === true) { // copy verbatim this[propName] = rawProps[propName]; } else if (standardPropMap[propName] === false) { manualProps[propName] = rawProps[propName]; } else { miscProps[propName] = rawProps[propName]; } } this.applyMiscProps(miscProps); return this.applyManualStandardProps(manualProps); }; /* If subclasses override, they must call this supermethod and return the boolean response. Meant to be only called ONCE, at object creation. */ ParsableModelMixin.prototype.applyManualStandardProps = function (rawProps) { return true; }; /* Can be called even after initial object creation. */ ParsableModelMixin.prototype.applyMiscProps = function (rawProps) { // subclasses can implement }; /* TODO: why is this a method when defineStandardProps is static */ ParsableModelMixin.prototype.isStandardProp = function (propName) { return propName in this.standardPropMap; }; return ParsableModelMixin; }(Mixin_1.default)); exports.default = ParsableModelMixin; ParsableModelMixin.prototype.standardPropMap = {}; // will be cloned by defineStandardProps /***/ }), /* 53 */ /***/ (function(module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); var EventInstance = /** @class */ (function () { function EventInstance(def, dateProfile) { this.def = def; this.dateProfile = dateProfile; } EventInstance.prototype.toLegacy = function () { var dateProfile = this.dateProfile; var obj = this.def.toLegacy(); obj.start = dateProfile.start.clone(); obj.end = dateProfile.end ? dateProfile.end.clone() : null; return obj; }; return EventInstance; }()); exports.default = EventInstance; /***/ }), /* 54 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var moment = __webpack_require__(0); var EventDef_1 = __webpack_require__(37); var EventInstance_1 = __webpack_require__(53); var EventDateProfile_1 = __webpack_require__(16); var RecurringEventDef = /** @class */ (function (_super) { tslib_1.__extends(RecurringEventDef, _super); function RecurringEventDef() { return _super !== null && _super.apply(this, arguments) || this; } RecurringEventDef.prototype.isAllDay = function () { return !this.startTime && !this.endTime; }; RecurringEventDef.prototype.buildInstances = function (unzonedRange) { var calendar = this.source.calendar; var unzonedDate = unzonedRange.getStart(); var unzonedEnd = unzonedRange.getEnd(); var zonedDayStart; var instanceStart; var instanceEnd; var instances = []; while (unzonedDate.isBefore(unzonedEnd)) { // if everyday, or this particular day-of-week if (!this.dowHash || this.dowHash[unzonedDate.day()]) { zonedDayStart = calendar.applyTimezone(unzonedDate); instanceStart = zonedDayStart.clone(); instanceEnd = null; if (this.startTime) { instanceStart.time(this.startTime); } else { instanceStart.stripTime(); } if (this.endTime) { instanceEnd = zonedDayStart.clone().time(this.endTime); } instances.push(new EventInstance_1.default(this, // definition new EventDateProfile_1.default(instanceStart, instanceEnd, calendar))); } unzonedDate.add(1, 'days'); } return instances; }; RecurringEventDef.prototype.setDow = function (dowNumbers) { if (!this.dowHash) { this.dowHash = {}; } for (var i = 0; i < dowNumbers.length; i++) { this.dowHash[dowNumbers[i]] = true; } }; RecurringEventDef.prototype.clone = function () { var def = _super.prototype.clone.call(this); if (def.startTime) { def.startTime = moment.duration(this.startTime); } if (def.endTime) { def.endTime = moment.duration(this.endTime); } if (this.dowHash) { def.dowHash = $.extend({}, this.dowHash); } return def; }; return RecurringEventDef; }(EventDef_1.default)); exports.default = RecurringEventDef; /* HACK to work with TypeScript mixins NOTE: if super-method fails, should still attempt to apply */ RecurringEventDef.prototype.applyProps = function (rawProps) { var superSuccess = EventDef_1.default.prototype.applyProps.call(this, rawProps); if (rawProps.start) { this.startTime = moment.duration(rawProps.start); } if (rawProps.end) { this.endTime = moment.duration(rawProps.end); } if (rawProps.dow) { this.setDow(rawProps.dow); } return superSuccess; }; // Parsing // --------------------------------------------------------------------------------------------------------------------- RecurringEventDef.defineStandardProps({ start: false, end: false, dow: false }); /***/ }), /* 55 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var moment = __webpack_require__(0); var util_1 = __webpack_require__(4); var UnzonedRange_1 = __webpack_require__(5); var DateProfileGenerator = /** @class */ (function () { function DateProfileGenerator(_view) { this._view = _view; } DateProfileGenerator.prototype.opt = function (name) { return this._view.opt(name); }; DateProfileGenerator.prototype.trimHiddenDays = function (unzonedRange) { return this._view.trimHiddenDays(unzonedRange); }; DateProfileGenerator.prototype.msToUtcMoment = function (ms, forceAllDay) { return this._view.calendar.msToUtcMoment(ms, forceAllDay); }; /* Date Range Computation ------------------------------------------------------------------------------------------------------------------*/ // Builds a structure with info about what the dates/ranges will be for the "prev" view. DateProfileGenerator.prototype.buildPrev = function (currentDateProfile) { var prevDate = currentDateProfile.date.clone() .startOf(currentDateProfile.currentRangeUnit) .subtract(currentDateProfile.dateIncrement); return this.build(prevDate, -1); }; // Builds a structure with info about what the dates/ranges will be for the "next" view. DateProfileGenerator.prototype.buildNext = function (currentDateProfile) { var nextDate = currentDateProfile.date.clone() .startOf(currentDateProfile.currentRangeUnit) .add(currentDateProfile.dateIncrement); return this.build(nextDate, 1); }; // Builds a structure holding dates/ranges for rendering around the given date. // Optional direction param indicates whether the date is being incremented/decremented // from its previous value. decremented = -1, incremented = 1 (default). DateProfileGenerator.prototype.build = function (date, direction, forceToValid) { if (forceToValid === void 0) { forceToValid = false; } var isDateAllDay = !date.hasTime(); var validUnzonedRange; var minTime = null; var maxTime = null; var currentInfo; var isRangeAllDay; var renderUnzonedRange; var activeUnzonedRange; var isValid; validUnzonedRange = this.buildValidRange(); validUnzonedRange = this.trimHiddenDays(validUnzonedRange); if (forceToValid) { date = this.msToUtcMoment(validUnzonedRange.constrainDate(date), // returns MS isDateAllDay); } currentInfo = this.buildCurrentRangeInfo(date, direction); isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit); renderUnzonedRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.unzonedRange), currentInfo.unit, isRangeAllDay); renderUnzonedRange = this.trimHiddenDays(renderUnzonedRange); activeUnzonedRange = renderUnzonedRange.clone(); if (!this.opt('showNonCurrentDates')) { activeUnzonedRange = activeUnzonedRange.intersect(currentInfo.unzonedRange); } minTime = moment.duration(this.opt('minTime')); maxTime = moment.duration(this.opt('maxTime')); activeUnzonedRange = this.adjustActiveRange(activeUnzonedRange, minTime, maxTime); activeUnzonedRange = activeUnzonedRange.intersect(validUnzonedRange); // might return null if (activeUnzonedRange) { date = this.msToUtcMoment(activeUnzonedRange.constrainDate(date), // returns MS isDateAllDay); } // it's invalid if the originally requested date is not contained, // or if the range is completely outside of the valid range. isValid = currentInfo.unzonedRange.intersectsWith(validUnzonedRange); return { // constraint for where prev/next operations can go and where events can be dragged/resized to. // an object with optional start and end properties. validUnzonedRange: validUnzonedRange, // range the view is formally responsible for. // for example, a month view might have 1st-31st, excluding padded dates currentUnzonedRange: currentInfo.unzonedRange, // name of largest unit being displayed, like "month" or "week" currentRangeUnit: currentInfo.unit, isRangeAllDay: isRangeAllDay, // dates that display events and accept drag-n-drop // will be `null` if no dates accept events activeUnzonedRange: activeUnzonedRange, // date range with a rendered skeleton // includes not-active days that need some sort of DOM renderUnzonedRange: renderUnzonedRange, // Duration object that denotes the first visible time of any given day minTime: minTime, // Duration object that denotes the exclusive visible end time of any given day maxTime: maxTime, isValid: isValid, date: date, // how far the current date will move for a prev/next operation dateIncrement: this.buildDateIncrement(currentInfo.duration) // pass a fallback (might be null) ^ }; }; // Builds an object with optional start/end properties. // Indicates the minimum/maximum dates to display. // not responsible for trimming hidden days. DateProfileGenerator.prototype.buildValidRange = function () { return this._view.getUnzonedRangeOption('validRange', this._view.calendar.getNow()) || new UnzonedRange_1.default(); // completely open-ended }; // Builds a structure with info about the "current" range, the range that is // highlighted as being the current month for example. // See build() for a description of `direction`. // Guaranteed to have `range` and `unit` properties. `duration` is optional. // TODO: accept a MS-time instead of a moment `date`? DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) { var viewSpec = this._view.viewSpec; var duration = null; var unit = null; var unzonedRange = null; var dayCount; if (viewSpec.duration) { duration = viewSpec.duration; unit = viewSpec.durationUnit; unzonedRange = this.buildRangeFromDuration(date, direction, duration, unit); } else if ((dayCount = this.opt('dayCount'))) { unit = 'day'; unzonedRange = this.buildRangeFromDayCount(date, direction, dayCount); } else if ((unzonedRange = this.buildCustomVisibleRange(date))) { unit = util_1.computeGreatestUnit(unzonedRange.getStart(), unzonedRange.getEnd()); } else { duration = this.getFallbackDuration(); unit = util_1.computeGreatestUnit(duration); unzonedRange = this.buildRangeFromDuration(date, direction, duration, unit); } return { duration: duration, unit: unit, unzonedRange: unzonedRange }; }; DateProfileGenerator.prototype.getFallbackDuration = function () { return moment.duration({ days: 1 }); }; // Returns a new activeUnzonedRange to have time values (un-ambiguate) // minTime or maxTime causes the range to expand. DateProfileGenerator.prototype.adjustActiveRange = function (unzonedRange, minTime, maxTime) { var start = unzonedRange.getStart(); var end = unzonedRange.getEnd(); if (this._view.usesMinMaxTime) { if (minTime < 0) { start.time(0).add(minTime); } if (maxTime > 24 * 60 * 60 * 1000) { // beyond 24 hours? end.time(maxTime - (24 * 60 * 60 * 1000)); } } return new UnzonedRange_1.default(start, end); }; // Builds the "current" range when it is specified as an explicit duration. // `unit` is the already-computed computeGreatestUnit value of duration. // TODO: accept a MS-time instead of a moment `date`? DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) { var alignment = this.opt('dateAlignment'); var dateIncrementInput; var dateIncrementDuration; var start; var end; var res; // compute what the alignment should be if (!alignment) { dateIncrementInput = this.opt('dateIncrement'); if (dateIncrementInput) { dateIncrementDuration = moment.duration(dateIncrementInput); // use the smaller of the two units if (dateIncrementDuration < duration) { alignment = util_1.computeDurationGreatestUnit(dateIncrementDuration, dateIncrementInput); } else { alignment = unit; } } else { alignment = unit; } } // if the view displays a single day or smaller if (duration.as('days') <= 1) { if (this._view.isHiddenDay(start)) { start = this._view.skipHiddenDays(start, direction); start.startOf('day'); } } function computeRes() { start = date.clone().startOf(alignment); end = start.clone().add(duration); res = new UnzonedRange_1.default(start, end); } computeRes(); // if range is completely enveloped by hidden days, go past the hidden days if (!this.trimHiddenDays(res)) { date = this._view.skipHiddenDays(date, direction); computeRes(); } return res; }; // Builds the "current" range when a dayCount is specified. // TODO: accept a MS-time instead of a moment `date`? DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) { var customAlignment = this.opt('dateAlignment'); var runningCount = 0; var start; var end; if (customAlignment || direction !== -1) { start = date.clone(); if (customAlignment) { start.startOf(customAlignment); } start.startOf('day'); start = this._view.skipHiddenDays(start); end = start.clone(); do { end.add(1, 'day'); if (!this._view.isHiddenDay(end)) { runningCount++; } } while (runningCount < dayCount); } else { end = date.clone().startOf('day').add(1, 'day'); end = this._view.skipHiddenDays(end, -1, true); start = end.clone(); do { start.add(-1, 'day'); if (!this._view.isHiddenDay(start)) { runningCount++; } } while (runningCount < dayCount); } return new UnzonedRange_1.default(start, end); }; // Builds a normalized range object for the "visible" range, // which is a way to define the currentUnzonedRange and activeUnzonedRange at the same time. // TODO: accept a MS-time instead of a moment `date`? DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) { var visibleUnzonedRange = this._view.getUnzonedRangeOption('visibleRange', this._view.calendar.applyTimezone(date) // correct zone. also generates new obj that avoids mutations ); if (visibleUnzonedRange && (visibleUnzonedRange.startMs == null || visibleUnzonedRange.endMs == null)) { return null; } return visibleUnzonedRange; }; // Computes the range that will represent the element/cells for *rendering*, // but which may have voided days/times. // not responsible for trimming hidden days. DateProfileGenerator.prototype.buildRenderRange = function (currentUnzonedRange, currentRangeUnit, isRangeAllDay) { return currentUnzonedRange.clone(); }; // Compute the duration value that should be added/substracted to the current date // when a prev/next operation happens. DateProfileGenerator.prototype.buildDateIncrement = function (fallback) { var dateIncrementInput = this.opt('dateIncrement'); var customAlignment; if (dateIncrementInput) { return moment.duration(dateIncrementInput); } else if ((customAlignment = this.opt('dateAlignment'))) { return moment.duration(1, customAlignment); } else if (fallback) { return fallback; } else { return moment.duration({ days: 1 }); } }; return DateProfileGenerator; }()); exports.default = DateProfileGenerator; /***/ }), /* 56 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var Promise_1 = __webpack_require__(21); var EventSource_1 = __webpack_require__(6); var SingleEventDef_1 = __webpack_require__(9); var ArrayEventSource = /** @class */ (function (_super) { tslib_1.__extends(ArrayEventSource, _super); function ArrayEventSource(calendar) { var _this = _super.call(this, calendar) || this; _this.eventDefs = []; // for if setRawEventDefs is never called return _this; } ArrayEventSource.parse = function (rawInput, calendar) { var rawProps; // normalize raw input if ($.isArray(rawInput.events)) { // extended form rawProps = rawInput; } else if ($.isArray(rawInput)) { // short form rawProps = { events: rawInput }; } if (rawProps) { return EventSource_1.default.parse.call(this, rawProps, calendar); } return false; }; ArrayEventSource.prototype.setRawEventDefs = function (rawEventDefs) { this.rawEventDefs = rawEventDefs; this.eventDefs = this.parseEventDefs(rawEventDefs); }; ArrayEventSource.prototype.fetch = function (start, end, timezone) { var eventDefs = this.eventDefs; var i; if (this.currentTimezone != null && this.currentTimezone !== timezone) { for (i = 0; i < eventDefs.length; i++) { if (eventDefs[i] instanceof SingleEventDef_1.default) { eventDefs[i].rezone(); } } } this.currentTimezone = timezone; return Promise_1.default.resolve(eventDefs); }; ArrayEventSource.prototype.addEventDef = function (eventDef) { this.eventDefs.push(eventDef); }; /* eventDefId already normalized to a string */ ArrayEventSource.prototype.removeEventDefsById = function (eventDefId) { return util_1.removeMatching(this.eventDefs, function (eventDef) { return eventDef.id === eventDefId; }); }; ArrayEventSource.prototype.removeAllEventDefs = function () { this.eventDefs = []; }; ArrayEventSource.prototype.getPrimitive = function () { return this.rawEventDefs; }; ArrayEventSource.prototype.applyManualStandardProps = function (rawProps) { var superSuccess = _super.prototype.applyManualStandardProps.call(this, rawProps); this.setRawEventDefs(rawProps.events); return superSuccess; }; return ArrayEventSource; }(EventSource_1.default)); exports.default = ArrayEventSource; ArrayEventSource.defineStandardProps({ events: false // don't automatically transfer }); /***/ }), /* 57 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var StandardTheme_1 = __webpack_require__(221); var JqueryUiTheme_1 = __webpack_require__(222); var themeClassHash = {}; function defineThemeSystem(themeName, themeClass) { themeClassHash[themeName] = themeClass; } exports.defineThemeSystem = defineThemeSystem; function getThemeSystemClass(themeSetting) { if (!themeSetting) { return StandardTheme_1.default; } else if (themeSetting === true) { return JqueryUiTheme_1.default; } else { return themeClassHash[themeSetting]; } } exports.getThemeSystemClass = getThemeSystemClass; /***/ }), /* 58 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); /* A cache for the left/right/top/bottom/width/height values for one or more elements. Works with both offset (from topleft document) and position (from offsetParent). options: - els - isHorizontal - isVertical */ var CoordCache = /** @class */ (function () { function CoordCache(options) { this.isHorizontal = false; // whether to query for left/right/width this.isVertical = false; // whether to query for top/bottom/height this.els = $(options.els); this.isHorizontal = options.isHorizontal; this.isVertical = options.isVertical; this.forcedOffsetParentEl = options.offsetParent ? $(options.offsetParent) : null; } // Queries the els for coordinates and stores them. // Call this method before using and of the get* methods below. CoordCache.prototype.build = function () { var offsetParentEl = this.forcedOffsetParentEl; if (!offsetParentEl && this.els.length > 0) { offsetParentEl = this.els.eq(0).offsetParent(); } this.origin = offsetParentEl ? offsetParentEl.offset() : null; this.boundingRect = this.queryBoundingRect(); if (this.isHorizontal) { this.buildElHorizontals(); } if (this.isVertical) { this.buildElVerticals(); } }; // Destroys all internal data about coordinates, freeing memory CoordCache.prototype.clear = function () { this.origin = null; this.boundingRect = null; this.lefts = null; this.rights = null; this.tops = null; this.bottoms = null; }; // When called, if coord caches aren't built, builds them CoordCache.prototype.ensureBuilt = function () { if (!this.origin) { this.build(); } }; // Populates the left/right internal coordinate arrays CoordCache.prototype.buildElHorizontals = function () { var lefts = []; var rights = []; this.els.each(function (i, node) { var el = $(node); var left = el.offset().left; var width = el.outerWidth(); lefts.push(left); rights.push(left + width); }); this.lefts = lefts; this.rights = rights; }; // Populates the top/bottom internal coordinate arrays CoordCache.prototype.buildElVerticals = function () { var tops = []; var bottoms = []; this.els.each(function (i, node) { var el = $(node); var top = el.offset().top; var height = el.outerHeight(); tops.push(top); bottoms.push(top + height); }); this.tops = tops; this.bottoms = bottoms; }; // Given a left offset (from document left), returns the index of the el that it horizontally intersects. // If no intersection is made, returns undefined. CoordCache.prototype.getHorizontalIndex = function (leftOffset) { this.ensureBuilt(); var lefts = this.lefts; var rights = this.rights; var len = lefts.length; var i; for (i = 0; i < len; i++) { if (leftOffset >= lefts[i] && leftOffset < rights[i]) { return i; } } }; // Given a top offset (from document top), returns the index of the el that it vertically intersects. // If no intersection is made, returns undefined. CoordCache.prototype.getVerticalIndex = function (topOffset) { this.ensureBuilt(); var tops = this.tops; var bottoms = this.bottoms; var len = tops.length; var i; for (i = 0; i < len; i++) { if (topOffset >= tops[i] && topOffset < bottoms[i]) { return i; } } }; // Gets the left offset (from document left) of the element at the given index CoordCache.prototype.getLeftOffset = function (leftIndex) { this.ensureBuilt(); return this.lefts[leftIndex]; }; // Gets the left position (from offsetParent left) of the element at the given index CoordCache.prototype.getLeftPosition = function (leftIndex) { this.ensureBuilt(); return this.lefts[leftIndex] - this.origin.left; }; // Gets the right offset (from document left) of the element at the given index. // This value is NOT relative to the document's right edge, like the CSS concept of "right" would be. CoordCache.prototype.getRightOffset = function (leftIndex) { this.ensureBuilt(); return this.rights[leftIndex]; }; // Gets the right position (from offsetParent left) of the element at the given index. // This value is NOT relative to the offsetParent's right edge, like the CSS concept of "right" would be. CoordCache.prototype.getRightPosition = function (leftIndex) { this.ensureBuilt(); return this.rights[leftIndex] - this.origin.left; }; // Gets the width of the element at the given index CoordCache.prototype.getWidth = function (leftIndex) { this.ensureBuilt(); return this.rights[leftIndex] - this.lefts[leftIndex]; }; // Gets the top offset (from document top) of the element at the given index CoordCache.prototype.getTopOffset = function (topIndex) { this.ensureBuilt(); return this.tops[topIndex]; }; // Gets the top position (from offsetParent top) of the element at the given position CoordCache.prototype.getTopPosition = function (topIndex) { this.ensureBuilt(); return this.tops[topIndex] - this.origin.top; }; // Gets the bottom offset (from the document top) of the element at the given index. // This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of "bottom" would be. CoordCache.prototype.getBottomOffset = function (topIndex) { this.ensureBuilt(); return this.bottoms[topIndex]; }; // Gets the bottom position (from the offsetParent top) of the element at the given index. // This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of "bottom" would be. CoordCache.prototype.getBottomPosition = function (topIndex) { this.ensureBuilt(); return this.bottoms[topIndex] - this.origin.top; }; // Gets the height of the element at the given index CoordCache.prototype.getHeight = function (topIndex) { this.ensureBuilt(); return this.bottoms[topIndex] - this.tops[topIndex]; }; // Bounding Rect // TODO: decouple this from CoordCache // Compute and return what the elements' bounding rectangle is, from the user's perspective. // Right now, only returns a rectangle if constrained by an overflow:scroll element. // Returns null if there are no elements CoordCache.prototype.queryBoundingRect = function () { var scrollParentEl; if (this.els.length > 0) { scrollParentEl = util_1.getScrollParent(this.els.eq(0)); if (!scrollParentEl.is(document) && !scrollParentEl.is('html,body') // don't consider these bounding rects. solves issue 3615 ) { return util_1.getClientRect(scrollParentEl); } } return null; }; CoordCache.prototype.isPointInBounds = function (leftOffset, topOffset) { return this.isLeftInBounds(leftOffset) && this.isTopInBounds(topOffset); }; CoordCache.prototype.isLeftInBounds = function (leftOffset) { return !this.boundingRect || (leftOffset >= this.boundingRect.left && leftOffset < this.boundingRect.right); }; CoordCache.prototype.isTopInBounds = function (topOffset) { return !this.boundingRect || (topOffset >= this.boundingRect.top && topOffset < this.boundingRect.bottom); }; return CoordCache; }()); exports.default = CoordCache; /***/ }), /* 59 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var ListenerMixin_1 = __webpack_require__(7); var GlobalEmitter_1 = __webpack_require__(23); /* Tracks a drag's mouse movement, firing various handlers ----------------------------------------------------------------------------------------------------------------------*/ // TODO: use Emitter var DragListener = /** @class */ (function () { function DragListener(options) { this.isInteracting = false; this.isDistanceSurpassed = false; this.isDelayEnded = false; this.isDragging = false; this.isTouch = false; this.isGeneric = false; // initiated by 'dragstart' (jqui) this.shouldCancelTouchScroll = true; this.scrollAlwaysKills = false; this.isAutoScroll = false; // defaults this.scrollSensitivity = 30; // pixels from edge for scrolling to start this.scrollSpeed = 200; // pixels per second, at maximum speed this.scrollIntervalMs = 50; // millisecond wait between scroll increment this.options = options || {}; } // Interaction (high-level) // ----------------------------------------------------------------------------------------------------------------- DragListener.prototype.startInteraction = function (ev, extraOptions) { if (extraOptions === void 0) { extraOptions = {}; } if (ev.type === 'mousedown') { if (GlobalEmitter_1.default.get().shouldIgnoreMouse()) { return; } else if (!util_1.isPrimaryMouseButton(ev)) { return; } else { ev.preventDefault(); // prevents native selection in most browsers } } if (!this.isInteracting) { // process options this.delay = util_1.firstDefined(extraOptions.delay, this.options.delay, 0); this.minDistance = util_1.firstDefined(extraOptions.distance, this.options.distance, 0); this.subjectEl = this.options.subjectEl; util_1.preventSelection($('body')); this.isInteracting = true; this.isTouch = util_1.getEvIsTouch(ev); this.isGeneric = ev.type === 'dragstart'; this.isDelayEnded = false; this.isDistanceSurpassed = false; this.originX = util_1.getEvX(ev); this.originY = util_1.getEvY(ev); this.scrollEl = util_1.getScrollParent($(ev.target)); this.bindHandlers(); this.initAutoScroll(); this.handleInteractionStart(ev); this.startDelay(ev); if (!this.minDistance) { this.handleDistanceSurpassed(ev); } } }; DragListener.prototype.handleInteractionStart = function (ev) { this.trigger('interactionStart', ev); }; DragListener.prototype.endInteraction = function (ev, isCancelled) { if (this.isInteracting) { this.endDrag(ev); if (this.delayTimeoutId) { clearTimeout(this.delayTimeoutId); this.delayTimeoutId = null; } this.destroyAutoScroll(); this.unbindHandlers(); this.isInteracting = false; this.handleInteractionEnd(ev, isCancelled); util_1.allowSelection($('body')); } }; DragListener.prototype.handleInteractionEnd = function (ev, isCancelled) { this.trigger('interactionEnd', ev, isCancelled || false); }; // Binding To DOM // ----------------------------------------------------------------------------------------------------------------- DragListener.prototype.bindHandlers = function () { // some browsers (Safari in iOS 10) don't allow preventDefault on touch events that are bound after touchstart, // so listen to the GlobalEmitter singleton, which is always bound, instead of the document directly. var globalEmitter = GlobalEmitter_1.default.get(); if (this.isGeneric) { this.listenTo($(document), { drag: this.handleMove, dragstop: this.endInteraction }); } else if (this.isTouch) { this.listenTo(globalEmitter, { touchmove: this.handleTouchMove, touchend: this.endInteraction, scroll: this.handleTouchScroll }); } else { this.listenTo(globalEmitter, { mousemove: this.handleMouseMove, mouseup: this.endInteraction }); } this.listenTo(globalEmitter, { selectstart: util_1.preventDefault, contextmenu: util_1.preventDefault // long taps would open menu on Chrome dev tools }); }; DragListener.prototype.unbindHandlers = function () { this.stopListeningTo(GlobalEmitter_1.default.get()); this.stopListeningTo($(document)); // for isGeneric }; // Drag (high-level) // ----------------------------------------------------------------------------------------------------------------- // extraOptions ignored if drag already started DragListener.prototype.startDrag = function (ev, extraOptions) { this.startInteraction(ev, extraOptions); // ensure interaction began if (!this.isDragging) { this.isDragging = true; this.handleDragStart(ev); } }; DragListener.prototype.handleDragStart = function (ev) { this.trigger('dragStart', ev); }; DragListener.prototype.handleMove = function (ev) { var dx = util_1.getEvX(ev) - this.originX; var dy = util_1.getEvY(ev) - this.originY; var minDistance = this.minDistance; var distanceSq; // current distance from the origin, squared if (!this.isDistanceSurpassed) { distanceSq = dx * dx + dy * dy; if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem this.handleDistanceSurpassed(ev); } } if (this.isDragging) { this.handleDrag(dx, dy, ev); } }; // Called while the mouse is being moved and when we know a legitimate drag is taking place DragListener.prototype.handleDrag = function (dx, dy, ev) { this.trigger('drag', dx, dy, ev); this.updateAutoScroll(ev); // will possibly cause scrolling }; DragListener.prototype.endDrag = function (ev) { if (this.isDragging) { this.isDragging = false; this.handleDragEnd(ev); } }; DragListener.prototype.handleDragEnd = function (ev) { this.trigger('dragEnd', ev); }; // Delay // ----------------------------------------------------------------------------------------------------------------- DragListener.prototype.startDelay = function (initialEv) { var _this = this; if (this.delay) { this.delayTimeoutId = setTimeout(function () { _this.handleDelayEnd(initialEv); }, this.delay); } else { this.handleDelayEnd(initialEv); } }; DragListener.prototype.handleDelayEnd = function (initialEv) { this.isDelayEnded = true; if (this.isDistanceSurpassed) { this.startDrag(initialEv); } }; // Distance // ----------------------------------------------------------------------------------------------------------------- DragListener.prototype.handleDistanceSurpassed = function (ev) { this.isDistanceSurpassed = true; if (this.isDelayEnded) { this.startDrag(ev); } }; // Mouse / Touch // ----------------------------------------------------------------------------------------------------------------- DragListener.prototype.handleTouchMove = function (ev) { // prevent inertia and touchmove-scrolling while dragging if (this.isDragging && this.shouldCancelTouchScroll) { ev.preventDefault(); } this.handleMove(ev); }; DragListener.prototype.handleMouseMove = function (ev) { this.handleMove(ev); }; // Scrolling (unrelated to auto-scroll) // ----------------------------------------------------------------------------------------------------------------- DragListener.prototype.handleTouchScroll = function (ev) { // if the drag is being initiated by touch, but a scroll happens before // the drag-initiating delay is over, cancel the drag if (!this.isDragging || this.scrollAlwaysKills) { this.endInteraction(ev, true); // isCancelled=true } }; // Utils // ----------------------------------------------------------------------------------------------------------------- // Triggers a callback. Calls a function in the option hash of the same name. // Arguments beyond the first `name` are forwarded on. DragListener.prototype.trigger = function (name) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } if (this.options[name]) { this.options[name].apply(this, args); } // makes _methods callable by event name. TODO: kill this if (this['_' + name]) { this['_' + name].apply(this, args); } }; // Auto-scroll // ----------------------------------------------------------------------------------------------------------------- DragListener.prototype.initAutoScroll = function () { var scrollEl = this.scrollEl; this.isAutoScroll = this.options.scroll && scrollEl && !scrollEl.is(window) && !scrollEl.is(document); if (this.isAutoScroll) { // debounce makes sure rapid calls don't happen this.listenTo(scrollEl, 'scroll', util_1.debounce(this.handleDebouncedScroll, 100)); } }; DragListener.prototype.destroyAutoScroll = function () { this.endAutoScroll(); // kill any animation loop // remove the scroll handler if there is a scrollEl if (this.isAutoScroll) { this.stopListeningTo(this.scrollEl, 'scroll'); // will probably get removed by unbindHandlers too :( } }; // Computes and stores the bounding rectangle of scrollEl DragListener.prototype.computeScrollBounds = function () { if (this.isAutoScroll) { this.scrollBounds = util_1.getOuterRect(this.scrollEl); // TODO: use getClientRect in future. but prevents auto scrolling when on top of scrollbars } }; // Called when the dragging is in progress and scrolling should be updated DragListener.prototype.updateAutoScroll = function (ev) { var sensitivity = this.scrollSensitivity; var bounds = this.scrollBounds; var topCloseness; var bottomCloseness; var leftCloseness; var rightCloseness; var topVel = 0; var leftVel = 0; if (bounds) { // only scroll if scrollEl exists // compute closeness to edges. valid range is from 0.0 - 1.0 topCloseness = (sensitivity - (util_1.getEvY(ev) - bounds.top)) / sensitivity; bottomCloseness = (sensitivity - (bounds.bottom - util_1.getEvY(ev))) / sensitivity; leftCloseness = (sensitivity - (util_1.getEvX(ev) - bounds.left)) / sensitivity; rightCloseness = (sensitivity - (bounds.right - util_1.getEvX(ev))) / sensitivity; // translate vertical closeness into velocity. // mouse must be completely in bounds for velocity to happen. if (topCloseness >= 0 && topCloseness <= 1) { topVel = topCloseness * this.scrollSpeed * -1; // negative. for scrolling up } else if (bottomCloseness >= 0 && bottomCloseness <= 1) { topVel = bottomCloseness * this.scrollSpeed; } // translate horizontal closeness into velocity if (leftCloseness >= 0 && leftCloseness <= 1) { leftVel = leftCloseness * this.scrollSpeed * -1; // negative. for scrolling left } else if (rightCloseness >= 0 && rightCloseness <= 1) { leftVel = rightCloseness * this.scrollSpeed; } } this.setScrollVel(topVel, leftVel); }; // Sets the speed-of-scrolling for the scrollEl DragListener.prototype.setScrollVel = function (topVel, leftVel) { this.scrollTopVel = topVel; this.scrollLeftVel = leftVel; this.constrainScrollVel(); // massages into realistic values // if there is non-zero velocity, and an animation loop hasn't already started, then START if ((this.scrollTopVel || this.scrollLeftVel) && !this.scrollIntervalId) { this.scrollIntervalId = setInterval(util_1.proxy(this, 'scrollIntervalFunc'), // scope to `this` this.scrollIntervalMs); } }; // Forces scrollTopVel and scrollLeftVel to be zero if scrolling has already gone all the way DragListener.prototype.constrainScrollVel = function () { var el = this.scrollEl; if (this.scrollTopVel < 0) { // scrolling up? if (el.scrollTop() <= 0) { // already scrolled all the way up? this.scrollTopVel = 0; } } else if (this.scrollTopVel > 0) { // scrolling down? if (el.scrollTop() + el[0].clientHeight >= el[0].scrollHeight) { // already scrolled all the way down? this.scrollTopVel = 0; } } if (this.scrollLeftVel < 0) { // scrolling left? if (el.scrollLeft() <= 0) { // already scrolled all the left? this.scrollLeftVel = 0; } } else if (this.scrollLeftVel > 0) { // scrolling right? if (el.scrollLeft() + el[0].clientWidth >= el[0].scrollWidth) { // already scrolled all the way right? this.scrollLeftVel = 0; } } }; // This function gets called during every iteration of the scrolling animation loop DragListener.prototype.scrollIntervalFunc = function () { var el = this.scrollEl; var frac = this.scrollIntervalMs / 1000; // considering animation frequency, what the vel should be mult'd by // change the value of scrollEl's scroll if (this.scrollTopVel) { el.scrollTop(el.scrollTop() + this.scrollTopVel * frac); } if (this.scrollLeftVel) { el.scrollLeft(el.scrollLeft() + this.scrollLeftVel * frac); } this.constrainScrollVel(); // since the scroll values changed, recompute the velocities // if scrolled all the way, which causes the vels to be zero, stop the animation loop if (!this.scrollTopVel && !this.scrollLeftVel) { this.endAutoScroll(); } }; // Kills any existing scrolling animation loop DragListener.prototype.endAutoScroll = function () { if (this.scrollIntervalId) { clearInterval(this.scrollIntervalId); this.scrollIntervalId = null; this.handleScrollEnd(); } }; // Get called when the scrollEl is scrolled (NOTE: this is delayed via debounce) DragListener.prototype.handleDebouncedScroll = function () { // recompute all coordinates, but *only* if this is *not* part of our scrolling animation if (!this.scrollIntervalId) { this.handleScrollEnd(); } }; DragListener.prototype.handleScrollEnd = function () { // Called when scrolling has stopped, whether through auto scroll, or the user scrolling }; return DragListener; }()); exports.default = DragListener; ListenerMixin_1.default.mixInto(DragListener); /***/ }), /* 60 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var util_1 = __webpack_require__(4); var Mixin_1 = __webpack_require__(15); /* A set of rendering and date-related methods for a visual component comprised of one or more rows of day columns. Prerequisite: the object being mixed into needs to be a *Grid* */ var DayTableMixin = /** @class */ (function (_super) { tslib_1.__extends(DayTableMixin, _super); function DayTableMixin() { return _super !== null && _super.apply(this, arguments) || this; } // Populates internal variables used for date calculation and rendering DayTableMixin.prototype.updateDayTable = function () { var t = this; var view = t.view; var calendar = view.calendar; var date = calendar.msToUtcMoment(t.dateProfile.renderUnzonedRange.startMs, true); var end = calendar.msToUtcMoment(t.dateProfile.renderUnzonedRange.endMs, true); var dayIndex = -1; var dayIndices = []; var dayDates = []; var daysPerRow; var firstDay; var rowCnt; while (date.isBefore(end)) { // loop each day from start to end if (view.isHiddenDay(date)) { dayIndices.push(dayIndex + 0.5); // mark that it's between indices } else { dayIndex++; dayIndices.push(dayIndex); dayDates.push(date.clone()); } date.add(1, 'days'); } if (this.breakOnWeeks) { // count columns until the day-of-week repeats firstDay = dayDates[0].day(); for (daysPerRow = 1; daysPerRow < dayDates.length; daysPerRow++) { if (dayDates[daysPerRow].day() === firstDay) { break; } } rowCnt = Math.ceil(dayDates.length / daysPerRow); } else { rowCnt = 1; daysPerRow = dayDates.length; } this.dayDates = dayDates; this.dayIndices = dayIndices; this.daysPerRow = daysPerRow; this.rowCnt = rowCnt; this.updateDayTableCols(); }; // Computes and assigned the colCnt property and updates any options that may be computed from it DayTableMixin.prototype.updateDayTableCols = function () { this.colCnt = this.computeColCnt(); this.colHeadFormat = this.opt('columnHeaderFormat') || this.opt('columnFormat') || // deprecated this.computeColHeadFormat(); }; // Determines how many columns there should be in the table DayTableMixin.prototype.computeColCnt = function () { return this.daysPerRow; }; // Computes the ambiguously-timed moment for the given cell DayTableMixin.prototype.getCellDate = function (row, col) { return this.dayDates[this.getCellDayIndex(row, col)].clone(); }; // Computes the ambiguously-timed date range for the given cell DayTableMixin.prototype.getCellRange = function (row, col) { var start = this.getCellDate(row, col); var end = start.clone().add(1, 'days'); return { start: start, end: end }; }; // Returns the number of day cells, chronologically, from the first of the grid (0-based) DayTableMixin.prototype.getCellDayIndex = function (row, col) { return row * this.daysPerRow + this.getColDayIndex(col); }; // Returns the numner of day cells, chronologically, from the first cell in *any given row* DayTableMixin.prototype.getColDayIndex = function (col) { if (this.isRTL) { return this.colCnt - 1 - col; } else { return col; } }; // Given a date, returns its chronolocial cell-index from the first cell of the grid. // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets. // If before the first offset, returns a negative number. // If after the last offset, returns an offset past the last cell offset. // Only works for *start* dates of cells. Will not work for exclusive end dates for cells. DayTableMixin.prototype.getDateDayIndex = function (date) { var dayIndices = this.dayIndices; var dayOffset = date.diff(this.dayDates[0], 'days'); if (dayOffset < 0) { return dayIndices[0] - 1; } else if (dayOffset >= dayIndices.length) { return dayIndices[dayIndices.length - 1] + 1; } else { return dayIndices[dayOffset]; } }; /* Options ------------------------------------------------------------------------------------------------------------------*/ // Computes a default column header formatting string if `colFormat` is not explicitly defined DayTableMixin.prototype.computeColHeadFormat = function () { // if more than one week row, or if there are a lot of columns with not much space, // put just the day numbers will be in each cell if (this.rowCnt > 1 || this.colCnt > 10) { return 'ddd'; // "Sat" } else if (this.colCnt > 1) { return this.opt('dayOfMonthFormat'); // "Sat 12/10" } else { return 'dddd'; // "Saturday" } }; /* Slicing ------------------------------------------------------------------------------------------------------------------*/ // Slices up a date range into a segment for every week-row it intersects with DayTableMixin.prototype.sliceRangeByRow = function (unzonedRange) { var daysPerRow = this.daysPerRow; var normalRange = this.view.computeDayRange(unzonedRange); // make whole-day range, considering nextDayThreshold var rangeFirst = this.getDateDayIndex(normalRange.start); // inclusive first index var rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')); // inclusive last index var segs = []; var row; var rowFirst; var rowLast; // inclusive day-index range for current row var segFirst; var segLast; // inclusive day-index range for segment for (row = 0; row < this.rowCnt; row++) { rowFirst = row * daysPerRow; rowLast = rowFirst + daysPerRow - 1; // intersect segment's offset range with the row's segFirst = Math.max(rangeFirst, rowFirst); segLast = Math.min(rangeLast, rowLast); // deal with in-between indices segFirst = Math.ceil(segFirst); // in-between starts round to next cell segLast = Math.floor(segLast); // in-between ends round to prev cell if (segFirst <= segLast) { // was there any intersection with the current row? segs.push({ row: row, // normalize to start of row firstRowDayIndex: segFirst - rowFirst, lastRowDayIndex: segLast - rowFirst, // must be matching integers to be the segment's start/end isStart: segFirst === rangeFirst, isEnd: segLast === rangeLast }); } } return segs; }; // Slices up a date range into a segment for every day-cell it intersects with. // TODO: make more DRY with sliceRangeByRow somehow. DayTableMixin.prototype.sliceRangeByDay = function (unzonedRange) { var daysPerRow = this.daysPerRow; var normalRange = this.view.computeDayRange(unzonedRange); // make whole-day range, considering nextDayThreshold var rangeFirst = this.getDateDayIndex(normalRange.start); // inclusive first index var rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')); // inclusive last index var segs = []; var row; var rowFirst; var rowLast; // inclusive day-index range for current row var i; var segFirst; var segLast; // inclusive day-index range for segment for (row = 0; row < this.rowCnt; row++) { rowFirst = row * daysPerRow; rowLast = rowFirst + daysPerRow - 1; for (i = rowFirst; i <= rowLast; i++) { // intersect segment's offset range with the row's segFirst = Math.max(rangeFirst, i); segLast = Math.min(rangeLast, i); // deal with in-between indices segFirst = Math.ceil(segFirst); // in-between starts round to next cell segLast = Math.floor(segLast); // in-between ends round to prev cell if (segFirst <= segLast) { // was there any intersection with the current row? segs.push({ row: row, // normalize to start of row firstRowDayIndex: segFirst - rowFirst, lastRowDayIndex: segLast - rowFirst, // must be matching integers to be the segment's start/end isStart: segFirst === rangeFirst, isEnd: segLast === rangeLast }); } } } return segs; }; /* Header Rendering ------------------------------------------------------------------------------------------------------------------*/ DayTableMixin.prototype.renderHeadHtml = function () { var theme = this.view.calendar.theme; return '' + '<div class="fc-row ' + theme.getClass('headerRow') + '">' + '<table class="' + theme.getClass('tableGrid') + '">' + '<thead>' + this.renderHeadTrHtml() + '</thead>' + '</table>' + '</div>'; }; DayTableMixin.prototype.renderHeadIntroHtml = function () { return this.renderIntroHtml(); // fall back to generic }; DayTableMixin.prototype.renderHeadTrHtml = function () { return '' + '<tr>' + (this.isRTL ? '' : this.renderHeadIntroHtml()) + this.renderHeadDateCellsHtml() + (this.isRTL ? this.renderHeadIntroHtml() : '') + '</tr>'; }; DayTableMixin.prototype.renderHeadDateCellsHtml = function () { var htmls = []; var col; var date; for (col = 0; col < this.colCnt; col++) { date = this.getCellDate(0, col); htmls.push(this.renderHeadDateCellHtml(date)); } return htmls.join(''); }; // TODO: when internalApiVersion, accept an object for HTML attributes // (colspan should be no different) DayTableMixin.prototype.renderHeadDateCellHtml = function (date, colspan, otherAttrs) { var t = this; var view = t.view; var isDateValid = t.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow. var classNames = [ 'fc-day-header', view.calendar.theme.getClass('widgetHeader') ]; var innerHtml; if (typeof t.opt('columnHeaderHtml') === 'function') { innerHtml = t.opt('columnHeaderHtml')(date); } else if (typeof t.opt('columnHeaderText') === 'function') { innerHtml = util_1.htmlEscape(t.opt('columnHeaderText')(date)); } else { innerHtml = util_1.htmlEscape(date.format(t.colHeadFormat)); } // if only one row of days, the classNames on the header can represent the specific days beneath if (t.rowCnt === 1) { classNames = classNames.concat( // includes the day-of-week class // noThemeHighlight=true (don't highlight the header) t.getDayClasses(date, true)); } else { classNames.push('fc-' + util_1.dayIDs[date.day()]); // only add the day-of-week class } return '' + '<th class="' + classNames.join(' ') + '"' + ((isDateValid && t.rowCnt) === 1 ? ' data-date="' + date.format('YYYY-MM-DD') + '"' : '') + (colspan > 1 ? ' colspan="' + colspan + '"' : '') + (otherAttrs ? ' ' + otherAttrs : '') + '>' + (isDateValid ? // don't make a link if the heading could represent multiple days, or if there's only one day (forceOff) view.buildGotoAnchorHtml({ date: date, forceOff: t.rowCnt > 1 || t.colCnt === 1 }, innerHtml) : // if not valid, display text, but no link innerHtml) + '</th>'; }; /* Background Rendering ------------------------------------------------------------------------------------------------------------------*/ DayTableMixin.prototype.renderBgTrHtml = function (row) { return '' + '<tr>' + (this.isRTL ? '' : this.renderBgIntroHtml(row)) + this.renderBgCellsHtml(row) + (this.isRTL ? this.renderBgIntroHtml(row) : '') + '</tr>'; }; DayTableMixin.prototype.renderBgIntroHtml = function (row) { return this.renderIntroHtml(); // fall back to generic }; DayTableMixin.prototype.renderBgCellsHtml = function (row) { var htmls = []; var col; var date; for (col = 0; col < this.colCnt; col++) { date = this.getCellDate(row, col); htmls.push(this.renderBgCellHtml(date)); } return htmls.join(''); }; DayTableMixin.prototype.renderBgCellHtml = function (date, otherAttrs) { var t = this; var view = t.view; var isDateValid = t.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow. var classes = t.getDayClasses(date); classes.unshift('fc-day', view.calendar.theme.getClass('widgetContent')); return '<td class="' + classes.join(' ') + '"' + (isDateValid ? ' data-date="' + date.format('YYYY-MM-DD') + '"' : // if date has a time, won't format it '') + (otherAttrs ? ' ' + otherAttrs : '') + '></td>'; }; /* Generic ------------------------------------------------------------------------------------------------------------------*/ DayTableMixin.prototype.renderIntroHtml = function () { // Generates the default HTML intro for any row. User classes should override }; // TODO: a generic method for dealing with <tr>, RTL, intro // when increment internalApiVersion // wrapTr (scheduler) /* Utils ------------------------------------------------------------------------------------------------------------------*/ // Applies the generic "intro" and "outro" HTML to the given cells. // Intro means the leftmost cell when the calendar is LTR and the rightmost cell when RTL. Vice-versa for outro. DayTableMixin.prototype.bookendCells = function (trEl) { var introHtml = this.renderIntroHtml(); if (introHtml) { if (this.isRTL) { trEl.append(introHtml); } else { trEl.prepend(introHtml); } } }; return DayTableMixin; }(Mixin_1.default)); exports.default = DayTableMixin; /***/ }), /* 61 */ /***/ (function(module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); var BusinessHourRenderer = /** @class */ (function () { /* component implements: - eventRangesToEventFootprints - eventFootprintsToSegs */ function BusinessHourRenderer(component, fillRenderer) { this.component = component; this.fillRenderer = fillRenderer; } BusinessHourRenderer.prototype.render = function (businessHourGenerator) { var component = this.component; var unzonedRange = component._getDateProfile().activeUnzonedRange; var eventInstanceGroup = businessHourGenerator.buildEventInstanceGroup(component.hasAllDayBusinessHours, unzonedRange); var eventFootprints = eventInstanceGroup ? component.eventRangesToEventFootprints(eventInstanceGroup.sliceRenderRanges(unzonedRange)) : []; this.renderEventFootprints(eventFootprints); }; BusinessHourRenderer.prototype.renderEventFootprints = function (eventFootprints) { var segs = this.component.eventFootprintsToSegs(eventFootprints); this.renderSegs(segs); this.segs = segs; }; BusinessHourRenderer.prototype.renderSegs = function (segs) { if (this.fillRenderer) { this.fillRenderer.renderSegs('businessHours', segs, { getClasses: function (seg) { return ['fc-nonbusiness', 'fc-bgevent']; } }); } }; BusinessHourRenderer.prototype.unrender = function () { if (this.fillRenderer) { this.fillRenderer.unrender('businessHours'); } this.segs = null; }; BusinessHourRenderer.prototype.getSegs = function () { return this.segs || []; }; return BusinessHourRenderer; }()); exports.default = BusinessHourRenderer; /***/ }), /* 62 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var FillRenderer = /** @class */ (function () { function FillRenderer(component) { this.fillSegTag = 'div'; this.component = component; this.elsByFill = {}; } FillRenderer.prototype.renderFootprint = function (type, componentFootprint, props) { this.renderSegs(type, this.component.componentFootprintToSegs(componentFootprint), props); }; FillRenderer.prototype.renderSegs = function (type, segs, props) { var els; segs = this.buildSegEls(type, segs, props); // assignes `.el` to each seg. returns successfully rendered segs els = this.attachSegEls(type, segs); if (els) { this.reportEls(type, els); } return segs; }; // Unrenders a specific type of fill that is currently rendered on the grid FillRenderer.prototype.unrender = function (type) { var el = this.elsByFill[type]; if (el) { el.remove(); delete this.elsByFill[type]; } }; // Renders and assigns an `el` property for each fill segment. Generic enough to work with different types. // Only returns segments that successfully rendered. FillRenderer.prototype.buildSegEls = function (type, segs, props) { var _this = this; var html = ''; var renderedSegs = []; var i; if (segs.length) { // build a large concatenation of segment HTML for (i = 0; i < segs.length; i++) { html += this.buildSegHtml(type, segs[i], props); } // Grab individual elements from the combined HTML string. Use each as the default rendering. // Then, compute the 'el' for each segment. $(html).each(function (i, node) { var seg = segs[i]; var el = $(node); // allow custom filter methods per-type if (props.filterEl) { el = props.filterEl(seg, el); } if (el) { // custom filters did not cancel the render el = $(el); // allow custom filter to return raw DOM node // correct element type? (would be bad if a non-TD were inserted into a table for example) if (el.is(_this.fillSegTag)) { seg.el = el; renderedSegs.push(seg); } } }); } return renderedSegs; }; // Builds the HTML needed for one fill segment. Generic enough to work with different types. FillRenderer.prototype.buildSegHtml = function (type, seg, props) { // custom hooks per-type var classes = props.getClasses ? props.getClasses(seg) : []; var css = util_1.cssToStr(props.getCss ? props.getCss(seg) : {}); return '<' + this.fillSegTag + (classes.length ? ' class="' + classes.join(' ') + '"' : '') + (css ? ' style="' + css + '"' : '') + ' />'; }; // Should return wrapping DOM structure FillRenderer.prototype.attachSegEls = function (type, segs) { // subclasses must implement }; FillRenderer.prototype.reportEls = function (type, nodes) { if (this.elsByFill[type]) { this.elsByFill[type] = this.elsByFill[type].add(nodes); } else { this.elsByFill[type] = $(nodes); } }; return FillRenderer; }()); exports.default = FillRenderer; /***/ }), /* 63 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var SingleEventDef_1 = __webpack_require__(9); var EventFootprint_1 = __webpack_require__(34); var EventSource_1 = __webpack_require__(6); var HelperRenderer = /** @class */ (function () { function HelperRenderer(component, eventRenderer) { this.view = component._getView(); this.component = component; this.eventRenderer = eventRenderer; } HelperRenderer.prototype.renderComponentFootprint = function (componentFootprint) { this.renderEventFootprints([ this.fabricateEventFootprint(componentFootprint) ]); }; HelperRenderer.prototype.renderEventDraggingFootprints = function (eventFootprints, sourceSeg, isTouch) { this.renderEventFootprints(eventFootprints, sourceSeg, 'fc-dragging', isTouch ? null : this.view.opt('dragOpacity')); }; HelperRenderer.prototype.renderEventResizingFootprints = function (eventFootprints, sourceSeg, isTouch) { this.renderEventFootprints(eventFootprints, sourceSeg, 'fc-resizing'); }; HelperRenderer.prototype.renderEventFootprints = function (eventFootprints, sourceSeg, extraClassNames, opacity) { var segs = this.component.eventFootprintsToSegs(eventFootprints); var classNames = 'fc-helper ' + (extraClassNames || ''); var i; // assigns each seg's el and returns a subset of segs that were rendered segs = this.eventRenderer.renderFgSegEls(segs); for (i = 0; i < segs.length; i++) { segs[i].el.addClass(classNames); } if (opacity != null) { for (i = 0; i < segs.length; i++) { segs[i].el.css('opacity', opacity); } } this.helperEls = this.renderSegs(segs, sourceSeg); }; /* Must return all mock event elements */ HelperRenderer.prototype.renderSegs = function (segs, sourceSeg) { // Subclasses must implement }; HelperRenderer.prototype.unrender = function () { if (this.helperEls) { this.helperEls.remove(); this.helperEls = null; } }; HelperRenderer.prototype.fabricateEventFootprint = function (componentFootprint) { var calendar = this.view.calendar; var eventDateProfile = calendar.footprintToDateProfile(componentFootprint); var dummyEvent = new SingleEventDef_1.default(new EventSource_1.default(calendar)); var dummyInstance; dummyEvent.dateProfile = eventDateProfile; dummyInstance = dummyEvent.buildInstance(); return new EventFootprint_1.default(componentFootprint, dummyEvent, dummyInstance); }; return HelperRenderer; }()); exports.default = HelperRenderer; /***/ }), /* 64 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var GlobalEmitter_1 = __webpack_require__(23); var Interaction_1 = __webpack_require__(14); var EventPointing = /** @class */ (function (_super) { tslib_1.__extends(EventPointing, _super); function EventPointing() { return _super !== null && _super.apply(this, arguments) || this; } /* component must implement: - publiclyTrigger */ EventPointing.prototype.bindToEl = function (el) { var component = this.component; component.bindSegHandlerToEl(el, 'click', this.handleClick.bind(this)); component.bindSegHandlerToEl(el, 'mouseenter', this.handleMouseover.bind(this)); component.bindSegHandlerToEl(el, 'mouseleave', this.handleMouseout.bind(this)); }; EventPointing.prototype.handleClick = function (seg, ev) { var res = this.component.publiclyTrigger('eventClick', { context: seg.el[0], args: [seg.footprint.getEventLegacy(), ev, this.view] }); if (res === false) { ev.preventDefault(); } }; // Updates internal state and triggers handlers for when an event element is moused over EventPointing.prototype.handleMouseover = function (seg, ev) { if (!GlobalEmitter_1.default.get().shouldIgnoreMouse() && !this.mousedOverSeg) { this.mousedOverSeg = seg; // TODO: move to EventSelecting's responsibility if (this.view.isEventDefResizable(seg.footprint.eventDef)) { seg.el.addClass('fc-allow-mouse-resize'); } this.component.publiclyTrigger('eventMouseover', { context: seg.el[0], args: [seg.footprint.getEventLegacy(), ev, this.view] }); } }; // Updates internal state and triggers handlers for when an event element is moused out. // Can be given no arguments, in which case it will mouseout the segment that was previously moused over. EventPointing.prototype.handleMouseout = function (seg, ev) { if (this.mousedOverSeg) { this.mousedOverSeg = null; // TODO: move to EventSelecting's responsibility if (this.view.isEventDefResizable(seg.footprint.eventDef)) { seg.el.removeClass('fc-allow-mouse-resize'); } this.component.publiclyTrigger('eventMouseout', { context: seg.el[0], args: [ seg.footprint.getEventLegacy(), ev || {}, this.view ] }); } }; EventPointing.prototype.end = function () { if (this.mousedOverSeg) { this.handleMouseout(this.mousedOverSeg); } }; return EventPointing; }(Interaction_1.default)); exports.default = EventPointing; /***/ }), /* 65 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var Mixin_1 = __webpack_require__(15); var DateClicking_1 = __webpack_require__(237); var DateSelecting_1 = __webpack_require__(236); var EventPointing_1 = __webpack_require__(64); var EventDragging_1 = __webpack_require__(235); var EventResizing_1 = __webpack_require__(234); var ExternalDropping_1 = __webpack_require__(233); var StandardInteractionsMixin = /** @class */ (function (_super) { tslib_1.__extends(StandardInteractionsMixin, _super); function StandardInteractionsMixin() { return _super !== null && _super.apply(this, arguments) || this; } return StandardInteractionsMixin; }(Mixin_1.default)); exports.default = StandardInteractionsMixin; StandardInteractionsMixin.prototype.dateClickingClass = DateClicking_1.default; StandardInteractionsMixin.prototype.dateSelectingClass = DateSelecting_1.default; StandardInteractionsMixin.prototype.eventPointingClass = EventPointing_1.default; StandardInteractionsMixin.prototype.eventDraggingClass = EventDragging_1.default; StandardInteractionsMixin.prototype.eventResizingClass = EventResizing_1.default; StandardInteractionsMixin.prototype.externalDroppingClass = ExternalDropping_1.default; /***/ }), /* 66 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var CoordCache_1 = __webpack_require__(58); var Popover_1 = __webpack_require__(227); var UnzonedRange_1 = __webpack_require__(5); var ComponentFootprint_1 = __webpack_require__(12); var EventFootprint_1 = __webpack_require__(34); var BusinessHourRenderer_1 = __webpack_require__(61); var StandardInteractionsMixin_1 = __webpack_require__(65); var InteractiveDateComponent_1 = __webpack_require__(42); var DayTableMixin_1 = __webpack_require__(60); var DayGridEventRenderer_1 = __webpack_require__(243); var DayGridHelperRenderer_1 = __webpack_require__(244); var DayGridFillRenderer_1 = __webpack_require__(245); /* A component that renders a grid of whole-days that runs horizontally. There can be multiple rows, one per week. ----------------------------------------------------------------------------------------------------------------------*/ var DayGrid = /** @class */ (function (_super) { tslib_1.__extends(DayGrid, _super); function DayGrid(view) { var _this = _super.call(this, view) || this; _this.cellWeekNumbersVisible = false; // display week numbers in day cell? _this.bottomCoordPadding = 0; // hack for extending the hit area for the last row of the coordinate grid // isRigid determines whether the individual rows should ignore the contents and be a constant height. // Relies on the view's colCnt and rowCnt. In the future, this component should probably be self-sufficient. _this.isRigid = false; _this.hasAllDayBusinessHours = true; return _this; } // Slices up the given span (unzoned start/end with other misc data) into an array of segments DayGrid.prototype.componentFootprintToSegs = function (componentFootprint) { var segs = this.sliceRangeByRow(componentFootprint.unzonedRange); var i; var seg; for (i = 0; i < segs.length; i++) { seg = segs[i]; if (this.isRTL) { seg.leftCol = this.daysPerRow - 1 - seg.lastRowDayIndex; seg.rightCol = this.daysPerRow - 1 - seg.firstRowDayIndex; } else { seg.leftCol = seg.firstRowDayIndex; seg.rightCol = seg.lastRowDayIndex; } } return segs; }; /* Date Rendering ------------------------------------------------------------------------------------------------------------------*/ DayGrid.prototype.renderDates = function (dateProfile) { this.dateProfile = dateProfile; this.updateDayTable(); this.renderGrid(); }; DayGrid.prototype.unrenderDates = function () { this.removeSegPopover(); }; // Renders the rows and columns into the component's `this.el`, which should already be assigned. DayGrid.prototype.renderGrid = function () { var view = this.view; var rowCnt = this.rowCnt; var colCnt = this.colCnt; var html = ''; var row; var col; if (this.headContainerEl) { this.headContainerEl.html(this.renderHeadHtml()); } for (row = 0; row < rowCnt; row++) { html += this.renderDayRowHtml(row, this.isRigid); } this.el.html(html); this.rowEls = this.el.find('.fc-row'); this.cellEls = this.el.find('.fc-day, .fc-disabled-day'); this.rowCoordCache = new CoordCache_1.default({ els: this.rowEls, isVertical: true }); this.colCoordCache = new CoordCache_1.default({ els: this.cellEls.slice(0, this.colCnt), isHorizontal: true }); // trigger dayRender with each cell's element for (row = 0; row < rowCnt; row++) { for (col = 0; col < colCnt; col++) { this.publiclyTrigger('dayRender', { context: view, args: [ this.getCellDate(row, col), this.getCellEl(row, col), view ] }); } } }; // Generates the HTML for a single row, which is a div that wraps a table. // `row` is the row number. DayGrid.prototype.renderDayRowHtml = function (row, isRigid) { var theme = this.view.calendar.theme; var classes = ['fc-row', 'fc-week', theme.getClass('dayRow')]; if (isRigid) { classes.push('fc-rigid'); } return '' + '<div class="' + classes.join(' ') + '">' + '<div class="fc-bg">' + '<table class="' + theme.getClass('tableGrid') + '">' + this.renderBgTrHtml(row) + '</table>' + '</div>' + '<div class="fc-content-skeleton">' + '<table>' + (this.getIsNumbersVisible() ? '<thead>' + this.renderNumberTrHtml(row) + '</thead>' : '') + '</table>' + '</div>' + '</div>'; }; DayGrid.prototype.getIsNumbersVisible = function () { return this.getIsDayNumbersVisible() || this.cellWeekNumbersVisible; }; DayGrid.prototype.getIsDayNumbersVisible = function () { return this.rowCnt > 1; }; /* Grid Number Rendering ------------------------------------------------------------------------------------------------------------------*/ DayGrid.prototype.renderNumberTrHtml = function (row) { return '' + '<tr>' + (this.isRTL ? '' : this.renderNumberIntroHtml(row)) + this.renderNumberCellsHtml(row) + (this.isRTL ? this.renderNumberIntroHtml(row) : '') + '</tr>'; }; DayGrid.prototype.renderNumberIntroHtml = function (row) { return this.renderIntroHtml(); }; DayGrid.prototype.renderNumberCellsHtml = function (row) { var htmls = []; var col; var date; for (col = 0; col < this.colCnt; col++) { date = this.getCellDate(row, col); htmls.push(this.renderNumberCellHtml(date)); } return htmls.join(''); }; // Generates the HTML for the <td>s of the "number" row in the DayGrid's content skeleton. // The number row will only exist if either day numbers or week numbers are turned on. DayGrid.prototype.renderNumberCellHtml = function (date) { var view = this.view; var html = ''; var isDateValid = this.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow. var isDayNumberVisible = this.getIsDayNumbersVisible() && isDateValid; var classes; var weekCalcFirstDoW; if (!isDayNumberVisible && !this.cellWeekNumbersVisible) { // no numbers in day cell (week number must be along the side) return '<td/>'; // will create an empty space above events :( } classes = this.getDayClasses(date); classes.unshift('fc-day-top'); if (this.cellWeekNumbersVisible) { // To determine the day of week number change under ISO, we cannot // rely on moment.js methods such as firstDayOfWeek() or weekday(), // because they rely on the locale's dow (possibly overridden by // our firstDay option), which may not be Monday. We cannot change // dow, because that would affect the calendar start day as well. if (date._locale._fullCalendar_weekCalc === 'ISO') { weekCalcFirstDoW = 1; // Monday by ISO 8601 definition } else { weekCalcFirstDoW = date._locale.firstDayOfWeek(); } } html += '<td class="' + classes.join(' ') + '"' + (isDateValid ? ' data-date="' + date.format() + '"' : '') + '>'; if (this.cellWeekNumbersVisible && (date.day() === weekCalcFirstDoW)) { html += view.buildGotoAnchorHtml({ date: date, type: 'week' }, { 'class': 'fc-week-number' }, date.format('w') // inner HTML ); } if (isDayNumberVisible) { html += view.buildGotoAnchorHtml(date, { 'class': 'fc-day-number' }, date.format('D') // inner HTML ); } html += '</td>'; return html; }; /* Hit System ------------------------------------------------------------------------------------------------------------------*/ DayGrid.prototype.prepareHits = function () { this.colCoordCache.build(); this.rowCoordCache.build(); this.rowCoordCache.bottoms[this.rowCnt - 1] += this.bottomCoordPadding; // hack }; DayGrid.prototype.releaseHits = function () { this.colCoordCache.clear(); this.rowCoordCache.clear(); }; DayGrid.prototype.queryHit = function (leftOffset, topOffset) { if (this.colCoordCache.isLeftInBounds(leftOffset) && this.rowCoordCache.isTopInBounds(topOffset)) { var col = this.colCoordCache.getHorizontalIndex(leftOffset); var row = this.rowCoordCache.getVerticalIndex(topOffset); if (row != null && col != null) { return this.getCellHit(row, col); } } }; DayGrid.prototype.getHitFootprint = function (hit) { var range = this.getCellRange(hit.row, hit.col); return new ComponentFootprint_1.default(new UnzonedRange_1.default(range.start, range.end), true // all-day? ); }; DayGrid.prototype.getHitEl = function (hit) { return this.getCellEl(hit.row, hit.col); }; /* Cell System ------------------------------------------------------------------------------------------------------------------*/ // FYI: the first column is the leftmost column, regardless of date DayGrid.prototype.getCellHit = function (row, col) { return { row: row, col: col, component: this, left: this.colCoordCache.getLeftOffset(col), right: this.colCoordCache.getRightOffset(col), top: this.rowCoordCache.getTopOffset(row), bottom: this.rowCoordCache.getBottomOffset(row) }; }; DayGrid.prototype.getCellEl = function (row, col) { return this.cellEls.eq(row * this.colCnt + col); }; /* Event Rendering ------------------------------------------------------------------------------------------------------------------*/ // Unrenders all events currently rendered on the grid DayGrid.prototype.executeEventUnrender = function () { this.removeSegPopover(); // removes the "more.." events popover _super.prototype.executeEventUnrender.call(this); }; // Retrieves all rendered segment objects currently rendered on the grid DayGrid.prototype.getOwnEventSegs = function () { // append the segments from the "more..." popover return _super.prototype.getOwnEventSegs.call(this).concat(this.popoverSegs || []); }; /* Event Drag Visualization ------------------------------------------------------------------------------------------------------------------*/ // Renders a visual indication of an event or external element being dragged. // `eventLocation` has zoned start and end (optional) DayGrid.prototype.renderDrag = function (eventFootprints, seg, isTouch) { var i; for (i = 0; i < eventFootprints.length; i++) { this.renderHighlight(eventFootprints[i].componentFootprint); } // render drags from OTHER components as helpers if (eventFootprints.length && seg && seg.component !== this) { this.helperRenderer.renderEventDraggingFootprints(eventFootprints, seg, isTouch); return true; // signal helpers rendered } }; // Unrenders any visual indication of a hovering event DayGrid.prototype.unrenderDrag = function () { this.unrenderHighlight(); this.helperRenderer.unrender(); }; /* Event Resize Visualization ------------------------------------------------------------------------------------------------------------------*/ // Renders a visual indication of an event being resized DayGrid.prototype.renderEventResize = function (eventFootprints, seg, isTouch) { var i; for (i = 0; i < eventFootprints.length; i++) { this.renderHighlight(eventFootprints[i].componentFootprint); } this.helperRenderer.renderEventResizingFootprints(eventFootprints, seg, isTouch); }; // Unrenders a visual indication of an event being resized DayGrid.prototype.unrenderEventResize = function () { this.unrenderHighlight(); this.helperRenderer.unrender(); }; /* More+ Link Popover ------------------------------------------------------------------------------------------------------------------*/ DayGrid.prototype.removeSegPopover = function () { if (this.segPopover) { this.segPopover.hide(); // in handler, will call segPopover's removeElement } }; // Limits the number of "levels" (vertically stacking layers of events) for each row of the grid. // `levelLimit` can be false (don't limit), a number, or true (should be computed). DayGrid.prototype.limitRows = function (levelLimit) { var rowStructs = this.eventRenderer.rowStructs || []; var row; // row # var rowLevelLimit; for (row = 0; row < rowStructs.length; row++) { this.unlimitRow(row); if (!levelLimit) { rowLevelLimit = false; } else if (typeof levelLimit === 'number') { rowLevelLimit = levelLimit; } else { rowLevelLimit = this.computeRowLevelLimit(row); } if (rowLevelLimit !== false) { this.limitRow(row, rowLevelLimit); } } }; // Computes the number of levels a row will accomodate without going outside its bounds. // Assumes the row is "rigid" (maintains a constant height regardless of what is inside). // `row` is the row number. DayGrid.prototype.computeRowLevelLimit = function (row) { var rowEl = this.rowEls.eq(row); // the containing "fake" row div var rowHeight = rowEl.height(); // TODO: cache somehow? var trEls = this.eventRenderer.rowStructs[row].tbodyEl.children(); var i; var trEl; var trHeight; function iterInnerHeights(i, childNode) { trHeight = Math.max(trHeight, $(childNode).outerHeight()); } // Reveal one level <tr> at a time and stop when we find one out of bounds for (i = 0; i < trEls.length; i++) { trEl = trEls.eq(i).removeClass('fc-limited'); // reset to original state (reveal) // with rowspans>1 and IE8, trEl.outerHeight() would return the height of the largest cell, // so instead, find the tallest inner content element. trHeight = 0; trEl.find('> td > :first-child').each(iterInnerHeights); if (trEl.position().top + trHeight > rowHeight) { return i; } } return false; // should not limit at all }; // Limits the given grid row to the maximum number of levels and injects "more" links if necessary. // `row` is the row number. // `levelLimit` is a number for the maximum (inclusive) number of levels allowed. DayGrid.prototype.limitRow = function (row, levelLimit) { var _this = this; var rowStruct = this.eventRenderer.rowStructs[row]; var moreNodes = []; // array of "more" <a> links and <td> DOM nodes var col = 0; // col #, left-to-right (not chronologically) var levelSegs; // array of segment objects in the last allowable level, ordered left-to-right var cellMatrix; // a matrix (by level, then column) of all <td> jQuery elements in the row var limitedNodes; // array of temporarily hidden level <tr> and segment <td> DOM nodes var i; var seg; var segsBelow; // array of segment objects below `seg` in the current `col` var totalSegsBelow; // total number of segments below `seg` in any of the columns `seg` occupies var colSegsBelow; // array of segment arrays, below seg, one for each column (offset from segs's first column) var td; var rowspan; var segMoreNodes; // array of "more" <td> cells that will stand-in for the current seg's cell var j; var moreTd; var moreWrap; var moreLink; // Iterates through empty level cells and places "more" links inside if need be var emptyCellsUntil = function (endCol) { while (col < endCol) { segsBelow = _this.getCellSegs(row, col, levelLimit); if (segsBelow.length) { td = cellMatrix[levelLimit - 1][col]; moreLink = _this.renderMoreLink(row, col, segsBelow); moreWrap = $('<div/>').append(moreLink); td.append(moreWrap); moreNodes.push(moreWrap[0]); } col++; } }; if (levelLimit && levelLimit < rowStruct.segLevels.length) { // is it actually over the limit? levelSegs = rowStruct.segLevels[levelLimit - 1]; cellMatrix = rowStruct.cellMatrix; limitedNodes = rowStruct.tbodyEl.children().slice(levelLimit) // get level <tr> elements past the limit .addClass('fc-limited').get(); // hide elements and get a simple DOM-nodes array // iterate though segments in the last allowable level for (i = 0; i < levelSegs.length; i++) { seg = levelSegs[i]; emptyCellsUntil(seg.leftCol); // process empty cells before the segment // determine *all* segments below `seg` that occupy the same columns colSegsBelow = []; totalSegsBelow = 0; while (col <= seg.rightCol) { segsBelow = this.getCellSegs(row, col, levelLimit); colSegsBelow.push(segsBelow); totalSegsBelow += segsBelow.length; col++; } if (totalSegsBelow) { // do we need to replace this segment with one or many "more" links? td = cellMatrix[levelLimit - 1][seg.leftCol]; // the segment's parent cell rowspan = td.attr('rowspan') || 1; segMoreNodes = []; // make a replacement <td> for each column the segment occupies. will be one for each colspan for (j = 0; j < colSegsBelow.length; j++) { moreTd = $('<td class="fc-more-cell"/>').attr('rowspan', rowspan); segsBelow = colSegsBelow[j]; moreLink = this.renderMoreLink(row, seg.leftCol + j, [seg].concat(segsBelow) // count seg as hidden too ); moreWrap = $('<div/>').append(moreLink); moreTd.append(moreWrap); segMoreNodes.push(moreTd[0]); moreNodes.push(moreTd[0]); } td.addClass('fc-limited').after($(segMoreNodes)); // hide original <td> and inject replacements limitedNodes.push(td[0]); } } emptyCellsUntil(this.colCnt); // finish off the level rowStruct.moreEls = $(moreNodes); // for easy undoing later rowStruct.limitedEls = $(limitedNodes); // for easy undoing later } }; // Reveals all levels and removes all "more"-related elements for a grid's row. // `row` is a row number. DayGrid.prototype.unlimitRow = function (row) { var rowStruct = this.eventRenderer.rowStructs[row]; if (rowStruct.moreEls) { rowStruct.moreEls.remove(); rowStruct.moreEls = null; } if (rowStruct.limitedEls) { rowStruct.limitedEls.removeClass('fc-limited'); rowStruct.limitedEls = null; } }; // Renders an <a> element that represents hidden event element for a cell. // Responsible for attaching click handler as well. DayGrid.prototype.renderMoreLink = function (row, col, hiddenSegs) { var _this = this; var view = this.view; return $('<a class="fc-more"/>') .text(this.getMoreLinkText(hiddenSegs.length)) .on('click', function (ev) { var clickOption = _this.opt('eventLimitClick'); var date = _this.getCellDate(row, col); var moreEl = $(ev.currentTarget); var dayEl = _this.getCellEl(row, col); var allSegs = _this.getCellSegs(row, col); // rescope the segments to be within the cell's date var reslicedAllSegs = _this.resliceDaySegs(allSegs, date); var reslicedHiddenSegs = _this.resliceDaySegs(hiddenSegs, date); if (typeof clickOption === 'function') { // the returned value can be an atomic option clickOption = _this.publiclyTrigger('eventLimitClick', { context: view, args: [ { date: date.clone(), dayEl: dayEl, moreEl: moreEl, segs: reslicedAllSegs, hiddenSegs: reslicedHiddenSegs }, ev, view ] }); } if (clickOption === 'popover') { _this.showSegPopover(row, col, moreEl, reslicedAllSegs); } else if (typeof clickOption === 'string') { // a view name view.calendar.zoomTo(date, clickOption); } }); }; // Reveals the popover that displays all events within a cell DayGrid.prototype.showSegPopover = function (row, col, moreLink, segs) { var _this = this; var view = this.view; var moreWrap = moreLink.parent(); // the <div> wrapper around the <a> var topEl; // the element we want to match the top coordinate of var options; if (this.rowCnt === 1) { topEl = view.el; // will cause the popover to cover any sort of header } else { topEl = this.rowEls.eq(row); // will align with top of row } options = { className: 'fc-more-popover ' + view.calendar.theme.getClass('popover'), content: this.renderSegPopoverContent(row, col, segs), parentEl: view.el, top: topEl.offset().top, autoHide: true, viewportConstrain: this.opt('popoverViewportConstrain'), hide: function () { // kill everything when the popover is hidden // notify events to be removed if (_this.popoverSegs) { _this.triggerBeforeEventSegsDestroyed(_this.popoverSegs); } _this.segPopover.removeElement(); _this.segPopover = null; _this.popoverSegs = null; } }; // Determine horizontal coordinate. // We use the moreWrap instead of the <td> to avoid border confusion. if (this.isRTL) { options.right = moreWrap.offset().left + moreWrap.outerWidth() + 1; // +1 to be over cell border } else { options.left = moreWrap.offset().left - 1; // -1 to be over cell border } this.segPopover = new Popover_1.default(options); this.segPopover.show(); // the popover doesn't live within the grid's container element, and thus won't get the event // delegated-handlers for free. attach event-related handlers to the popover. this.bindAllSegHandlersToEl(this.segPopover.el); this.triggerAfterEventSegsRendered(segs); }; // Builds the inner DOM contents of the segment popover DayGrid.prototype.renderSegPopoverContent = function (row, col, segs) { var view = this.view; var theme = view.calendar.theme; var title = this.getCellDate(row, col).format(this.opt('dayPopoverFormat')); var content = $('<div class="fc-header ' + theme.getClass('popoverHeader') + '">' + '<span class="fc-close ' + theme.getIconClass('close') + '"></span>' + '<span class="fc-title">' + util_1.htmlEscape(title) + '</span>' + '<div class="fc-clear"/>' + '</div>' + '<div class="fc-body ' + theme.getClass('popoverContent') + '">' + '<div class="fc-event-container"></div>' + '</div>'); var segContainer = content.find('.fc-event-container'); var i; // render each seg's `el` and only return the visible segs segs = this.eventRenderer.renderFgSegEls(segs, true); // disableResizing=true this.popoverSegs = segs; for (i = 0; i < segs.length; i++) { // because segments in the popover are not part of a grid coordinate system, provide a hint to any // grids that want to do drag-n-drop about which cell it came from this.hitsNeeded(); segs[i].hit = this.getCellHit(row, col); this.hitsNotNeeded(); segContainer.append(segs[i].el); } return content; }; // Given the events within an array of segment objects, reslice them to be in a single day DayGrid.prototype.resliceDaySegs = function (segs, dayDate) { var dayStart = dayDate.clone(); var dayEnd = dayStart.clone().add(1, 'days'); var dayRange = new UnzonedRange_1.default(dayStart, dayEnd); var newSegs = []; var i; var seg; var slicedRange; for (i = 0; i < segs.length; i++) { seg = segs[i]; slicedRange = seg.footprint.componentFootprint.unzonedRange.intersect(dayRange); if (slicedRange) { newSegs.push($.extend({}, seg, { footprint: new EventFootprint_1.default(new ComponentFootprint_1.default(slicedRange, seg.footprint.componentFootprint.isAllDay), seg.footprint.eventDef, seg.footprint.eventInstance), isStart: seg.isStart && slicedRange.isStart, isEnd: seg.isEnd && slicedRange.isEnd })); } } // force an order because eventsToSegs doesn't guarantee one // TODO: research if still needed this.eventRenderer.sortEventSegs(newSegs); return newSegs; }; // Generates the text that should be inside a "more" link, given the number of events it represents DayGrid.prototype.getMoreLinkText = function (num) { var opt = this.opt('eventLimitText'); if (typeof opt === 'function') { return opt(num); } else { return '+' + num + ' ' + opt; } }; // Returns segments within a given cell. // If `startLevel` is specified, returns only events including and below that level. Otherwise returns all segs. DayGrid.prototype.getCellSegs = function (row, col, startLevel) { var segMatrix = this.eventRenderer.rowStructs[row].segMatrix; var level = startLevel || 0; var segs = []; var seg; while (level < segMatrix.length) { seg = segMatrix[level][col]; if (seg) { segs.push(seg); } level++; } return segs; }; return DayGrid; }(InteractiveDateComponent_1.default)); exports.default = DayGrid; DayGrid.prototype.eventRendererClass = DayGridEventRenderer_1.default; DayGrid.prototype.businessHourRendererClass = BusinessHourRenderer_1.default; DayGrid.prototype.helperRendererClass = DayGridHelperRenderer_1.default; DayGrid.prototype.fillRendererClass = DayGridFillRenderer_1.default; StandardInteractionsMixin_1.default.mixInto(DayGrid); DayTableMixin_1.default.mixInto(DayGrid); /***/ }), /* 67 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var Scroller_1 = __webpack_require__(41); var View_1 = __webpack_require__(43); var BasicViewDateProfileGenerator_1 = __webpack_require__(68); var DayGrid_1 = __webpack_require__(66); /* An abstract class for the "basic" views, as well as month view. Renders one or more rows of day cells. ----------------------------------------------------------------------------------------------------------------------*/ // It is a manager for a DayGrid subcomponent, which does most of the heavy lifting. // It is responsible for managing width/height. var BasicView = /** @class */ (function (_super) { tslib_1.__extends(BasicView, _super); function BasicView(calendar, viewSpec) { var _this = _super.call(this, calendar, viewSpec) || this; _this.dayGrid = _this.instantiateDayGrid(); _this.dayGrid.isRigid = _this.hasRigidRows(); if (_this.opt('weekNumbers')) { if (_this.opt('weekNumbersWithinDays')) { _this.dayGrid.cellWeekNumbersVisible = true; _this.dayGrid.colWeekNumbersVisible = false; } else { _this.dayGrid.cellWeekNumbersVisible = false; _this.dayGrid.colWeekNumbersVisible = true; } } _this.addChild(_this.dayGrid); _this.scroller = new Scroller_1.default({ overflowX: 'hidden', overflowY: 'auto' }); return _this; } // Generates the DayGrid object this view needs. Draws from this.dayGridClass BasicView.prototype.instantiateDayGrid = function () { // generate a subclass on the fly with BasicView-specific behavior // TODO: cache this subclass var subclass = makeDayGridSubclass(this.dayGridClass); return new subclass(this); }; BasicView.prototype.executeDateRender = function (dateProfile) { this.dayGrid.breakOnWeeks = /year|month|week/.test(dateProfile.currentRangeUnit); _super.prototype.executeDateRender.call(this, dateProfile); }; BasicView.prototype.renderSkeleton = function () { var dayGridContainerEl; var dayGridEl; this.el.addClass('fc-basic-view').html(this.renderSkeletonHtml()); this.scroller.render(); dayGridContainerEl = this.scroller.el.addClass('fc-day-grid-container'); dayGridEl = $('<div class="fc-day-grid" />').appendTo(dayGridContainerEl); this.el.find('.fc-body > tr > td').append(dayGridContainerEl); this.dayGrid.headContainerEl = this.el.find('.fc-head-container'); this.dayGrid.setElement(dayGridEl); }; BasicView.prototype.unrenderSkeleton = function () { this.dayGrid.removeElement(); this.scroller.destroy(); }; // Builds the HTML skeleton for the view. // The day-grid component will render inside of a container defined by this HTML. BasicView.prototype.renderSkeletonHtml = function () { var theme = this.calendar.theme; return '' + '<table class="' + theme.getClass('tableGrid') + '">' + (this.opt('columnHeader') ? '<thead class="fc-head">' + '<tr>' + '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '"> </td>' + '</tr>' + '</thead>' : '') + '<tbody class="fc-body">' + '<tr>' + '<td class="' + theme.getClass('widgetContent') + '"></td>' + '</tr>' + '</tbody>' + '</table>'; }; // Generates an HTML attribute string for setting the width of the week number column, if it is known BasicView.prototype.weekNumberStyleAttr = function () { if (this.weekNumberWidth != null) { return 'style="width:' + this.weekNumberWidth + 'px"'; } return ''; }; // Determines whether each row should have a constant height BasicView.prototype.hasRigidRows = function () { var eventLimit = this.opt('eventLimit'); return eventLimit && typeof eventLimit !== 'number'; }; /* Dimensions ------------------------------------------------------------------------------------------------------------------*/ // Refreshes the horizontal dimensions of the view BasicView.prototype.updateSize = function (totalHeight, isAuto, isResize) { var eventLimit = this.opt('eventLimit'); var headRowEl = this.dayGrid.headContainerEl.find('.fc-row'); var scrollerHeight; var scrollbarWidths; // hack to give the view some height prior to dayGrid's columns being rendered // TODO: separate setting height from scroller VS dayGrid. if (!this.dayGrid.rowEls) { if (!isAuto) { scrollerHeight = this.computeScrollerHeight(totalHeight); this.scroller.setHeight(scrollerHeight); } return; } _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize); if (this.dayGrid.colWeekNumbersVisible) { // Make sure all week number cells running down the side have the same width. // Record the width for cells created later. this.weekNumberWidth = util_1.matchCellWidths(this.el.find('.fc-week-number')); } // reset all heights to be natural this.scroller.clear(); util_1.uncompensateScroll(headRowEl); this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed // is the event limit a constant level number? if (eventLimit && typeof eventLimit === 'number') { this.dayGrid.limitRows(eventLimit); // limit the levels first so the height can redistribute after } // distribute the height to the rows // (totalHeight is a "recommended" value if isAuto) scrollerHeight = this.computeScrollerHeight(totalHeight); this.setGridHeight(scrollerHeight, isAuto); // is the event limit dynamically calculated? if (eventLimit && typeof eventLimit !== 'number') { this.dayGrid.limitRows(eventLimit); // limit the levels after the grid's row heights have been set } if (!isAuto) { // should we force dimensions of the scroll container? this.scroller.setHeight(scrollerHeight); scrollbarWidths = this.scroller.getScrollbarWidths(); if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars? util_1.compensateScroll(headRowEl, scrollbarWidths); // doing the scrollbar compensation might have created text overflow which created more height. redo scrollerHeight = this.computeScrollerHeight(totalHeight); this.scroller.setHeight(scrollerHeight); } // guarantees the same scrollbar widths this.scroller.lockOverflow(scrollbarWidths); } }; // given a desired total height of the view, returns what the height of the scroller should be BasicView.prototype.computeScrollerHeight = function (totalHeight) { return totalHeight - util_1.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller }; // Sets the height of just the DayGrid component in this view BasicView.prototype.setGridHeight = function (height, isAuto) { if (isAuto) { util_1.undistributeHeight(this.dayGrid.rowEls); // let the rows be their natural height with no expanding } else { util_1.distributeHeight(this.dayGrid.rowEls, height, true); // true = compensate for height-hogging rows } }; /* Scroll ------------------------------------------------------------------------------------------------------------------*/ BasicView.prototype.computeInitialDateScroll = function () { return { top: 0 }; }; BasicView.prototype.queryDateScroll = function () { return { top: this.scroller.getScrollTop() }; }; BasicView.prototype.applyDateScroll = function (scroll) { if (scroll.top !== undefined) { this.scroller.setScrollTop(scroll.top); } }; return BasicView; }(View_1.default)); exports.default = BasicView; BasicView.prototype.dateProfileGeneratorClass = BasicViewDateProfileGenerator_1.default; BasicView.prototype.dayGridClass = DayGrid_1.default; // customize the rendering behavior of BasicView's dayGrid function makeDayGridSubclass(SuperClass) { return /** @class */ (function (_super) { tslib_1.__extends(SubClass, _super); function SubClass() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.colWeekNumbersVisible = false; // display week numbers along the side? return _this; } // Generates the HTML that will go before the day-of week header cells SubClass.prototype.renderHeadIntroHtml = function () { var view = this.view; if (this.colWeekNumbersVisible) { return '' + '<th class="fc-week-number ' + view.calendar.theme.getClass('widgetHeader') + '" ' + view.weekNumberStyleAttr() + '>' + '<span>' + // needed for matchCellWidths util_1.htmlEscape(this.opt('weekNumberTitle')) + '</span>' + '</th>'; } return ''; }; // Generates the HTML that will go before content-skeleton cells that display the day/week numbers SubClass.prototype.renderNumberIntroHtml = function (row) { var view = this.view; var weekStart = this.getCellDate(row, 0); if (this.colWeekNumbersVisible) { return '' + '<td class="fc-week-number" ' + view.weekNumberStyleAttr() + '>' + view.buildGotoAnchorHtml(// aside from link, important for matchCellWidths { date: weekStart, type: 'week', forceOff: this.colCnt === 1 }, weekStart.format('w') // inner HTML ) + '</td>'; } return ''; }; // Generates the HTML that goes before the day bg cells for each day-row SubClass.prototype.renderBgIntroHtml = function () { var view = this.view; if (this.colWeekNumbersVisible) { return '<td class="fc-week-number ' + view.calendar.theme.getClass('widgetContent') + '" ' + view.weekNumberStyleAttr() + '></td>'; } return ''; }; // Generates the HTML that goes before every other type of row generated by DayGrid. // Affects helper-skeleton and highlight-skeleton rows. SubClass.prototype.renderIntroHtml = function () { var view = this.view; if (this.colWeekNumbersVisible) { return '<td class="fc-week-number" ' + view.weekNumberStyleAttr() + '></td>'; } return ''; }; SubClass.prototype.getIsNumbersVisible = function () { return DayGrid_1.default.prototype.getIsNumbersVisible.apply(this, arguments) || this.colWeekNumbersVisible; }; return SubClass; }(SuperClass)); } /***/ }), /* 68 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var UnzonedRange_1 = __webpack_require__(5); var DateProfileGenerator_1 = __webpack_require__(55); var BasicViewDateProfileGenerator = /** @class */ (function (_super) { tslib_1.__extends(BasicViewDateProfileGenerator, _super); function BasicViewDateProfileGenerator() { return _super !== null && _super.apply(this, arguments) || this; } // Computes the date range that will be rendered. BasicViewDateProfileGenerator.prototype.buildRenderRange = function (currentUnzonedRange, currentRangeUnit, isRangeAllDay) { var renderUnzonedRange = _super.prototype.buildRenderRange.call(this, currentUnzonedRange, currentRangeUnit, isRangeAllDay); // an UnzonedRange var start = this.msToUtcMoment(renderUnzonedRange.startMs, isRangeAllDay); var end = this.msToUtcMoment(renderUnzonedRange.endMs, isRangeAllDay); // year and month views should be aligned with weeks. this is already done for week if (/^(year|month)$/.test(currentRangeUnit)) { start.startOf('week'); // make end-of-week if not already if (end.weekday()) { end.add(1, 'week').startOf('week'); // exclusively move backwards } } return new UnzonedRange_1.default(start, end); }; return BasicViewDateProfileGenerator; }(DateProfileGenerator_1.default)); exports.default = BasicViewDateProfileGenerator; /***/ }), /* 69 */, /* 70 */, /* 71 */, /* 72 */, /* 73 */, /* 74 */, /* 75 */, /* 76 */, /* 77 */, /* 78 */, /* 79 */, /* 80 */, /* 81 */, /* 82 */, /* 83 */, /* 84 */, /* 85 */, /* 86 */, /* 87 */, /* 88 */, /* 89 */, /* 90 */, /* 91 */, /* 92 */, /* 93 */, /* 94 */, /* 95 */, /* 96 */, /* 97 */, /* 98 */, /* 99 */, /* 100 */, /* 101 */, /* 102 */, /* 103 */, /* 104 */, /* 105 */, /* 106 */, /* 107 */, /* 108 */, /* 109 */, /* 110 */, /* 111 */, /* 112 */, /* 113 */, /* 114 */, /* 115 */, /* 116 */, /* 117 */, /* 118 */, /* 119 */, /* 120 */, /* 121 */, /* 122 */, /* 123 */, /* 124 */, /* 125 */, /* 126 */, /* 127 */, /* 128 */, /* 129 */, /* 130 */, /* 131 */, /* 132 */, /* 133 */, /* 134 */, /* 135 */, /* 136 */, /* 137 */, /* 138 */, /* 139 */, /* 140 */, /* 141 */, /* 142 */, /* 143 */, /* 144 */, /* 145 */, /* 146 */, /* 147 */, /* 148 */, /* 149 */, /* 150 */, /* 151 */, /* 152 */, /* 153 */, /* 154 */, /* 155 */, /* 156 */, /* 157 */, /* 158 */, /* 159 */, /* 160 */, /* 161 */, /* 162 */, /* 163 */, /* 164 */, /* 165 */, /* 166 */, /* 167 */, /* 168 */, /* 169 */, /* 170 */, /* 171 */, /* 172 */, /* 173 */, /* 174 */, /* 175 */, /* 176 */, /* 177 */, /* 178 */, /* 179 */, /* 180 */, /* 181 */, /* 182 */, /* 183 */, /* 184 */, /* 185 */, /* 186 */, /* 187 */, /* 188 */, /* 189 */, /* 190 */, /* 191 */, /* 192 */, /* 193 */, /* 194 */, /* 195 */, /* 196 */, /* 197 */, /* 198 */, /* 199 */, /* 200 */, /* 201 */, /* 202 */, /* 203 */, /* 204 */, /* 205 */, /* 206 */, /* 207 */, /* 208 */, /* 209 */, /* 210 */, /* 211 */, /* 212 */, /* 213 */, /* 214 */, /* 215 */, /* 216 */, /* 217 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var UnzonedRange_1 = __webpack_require__(5); var ComponentFootprint_1 = __webpack_require__(12); var EventDefParser_1 = __webpack_require__(36); var EventSource_1 = __webpack_require__(6); var util_1 = __webpack_require__(19); var Constraints = /** @class */ (function () { function Constraints(eventManager, _calendar) { this.eventManager = eventManager; this._calendar = _calendar; } Constraints.prototype.opt = function (name) { return this._calendar.opt(name); }; /* determines if eventInstanceGroup is allowed, in relation to other EVENTS and business hours. */ Constraints.prototype.isEventInstanceGroupAllowed = function (eventInstanceGroup) { var eventDef = eventInstanceGroup.getEventDef(); var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges()); var i; var peerEventInstances = this.getPeerEventInstances(eventDef); var peerEventRanges = peerEventInstances.map(util_1.eventInstanceToEventRange); var peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges); var constraintVal = eventDef.getConstraint(); var overlapVal = eventDef.getOverlap(); var eventAllowFunc = this.opt('eventAllow'); for (i = 0; i < eventFootprints.length; i++) { if (!this.isFootprintAllowed(eventFootprints[i].componentFootprint, peerEventFootprints, constraintVal, overlapVal, eventFootprints[i].eventInstance)) { return false; } } if (eventAllowFunc) { for (i = 0; i < eventFootprints.length; i++) { if (eventAllowFunc(eventFootprints[i].componentFootprint.toLegacy(this._calendar), eventFootprints[i].getEventLegacy()) === false) { return false; } } } return true; }; Constraints.prototype.getPeerEventInstances = function (eventDef) { return this.eventManager.getEventInstancesWithoutId(eventDef.id); }; Constraints.prototype.isSelectionFootprintAllowed = function (componentFootprint) { var peerEventInstances = this.eventManager.getEventInstances(); var peerEventRanges = peerEventInstances.map(util_1.eventInstanceToEventRange); var peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges); var selectAllowFunc; if (this.isFootprintAllowed(componentFootprint, peerEventFootprints, this.opt('selectConstraint'), this.opt('selectOverlap'))) { selectAllowFunc = this.opt('selectAllow'); if (selectAllowFunc) { return selectAllowFunc(componentFootprint.toLegacy(this._calendar)) !== false; } else { return true; } } return false; }; Constraints.prototype.isFootprintAllowed = function (componentFootprint, peerEventFootprints, constraintVal, overlapVal, subjectEventInstance // optional ) { var constraintFootprints; // ComponentFootprint[] var overlapEventFootprints; // EventFootprint[] if (constraintVal != null) { constraintFootprints = this.constraintValToFootprints(constraintVal, componentFootprint.isAllDay); if (!this.isFootprintWithinConstraints(componentFootprint, constraintFootprints)) { return false; } } overlapEventFootprints = this.collectOverlapEventFootprints(peerEventFootprints, componentFootprint); if (overlapVal === false) { if (overlapEventFootprints.length) { return false; } } else if (typeof overlapVal === 'function') { if (!isOverlapsAllowedByFunc(overlapEventFootprints, overlapVal, subjectEventInstance)) { return false; } } if (subjectEventInstance) { if (!isOverlapEventInstancesAllowed(overlapEventFootprints, subjectEventInstance)) { return false; } } return true; }; // Constraint // ------------------------------------------------------------------------------------------------ Constraints.prototype.isFootprintWithinConstraints = function (componentFootprint, constraintFootprints) { var i; for (i = 0; i < constraintFootprints.length; i++) { if (this.footprintContainsFootprint(constraintFootprints[i], componentFootprint)) { return true; } } return false; }; Constraints.prototype.constraintValToFootprints = function (constraintVal, isAllDay) { var eventInstances; if (constraintVal === 'businessHours') { return this.buildCurrentBusinessFootprints(isAllDay); } else if (typeof constraintVal === 'object') { eventInstances = this.parseEventDefToInstances(constraintVal); // handles recurring events if (!eventInstances) { // invalid input. fallback to parsing footprint directly return this.parseFootprints(constraintVal); } else { return this.eventInstancesToFootprints(eventInstances); } } else if (constraintVal != null) { // an ID eventInstances = this.eventManager.getEventInstancesWithId(constraintVal); return this.eventInstancesToFootprints(eventInstances); } }; // returns ComponentFootprint[] // uses current view's range Constraints.prototype.buildCurrentBusinessFootprints = function (isAllDay) { var view = this._calendar.view; var businessHourGenerator = view.get('businessHourGenerator'); var unzonedRange = view.dateProfile.activeUnzonedRange; var eventInstanceGroup = businessHourGenerator.buildEventInstanceGroup(isAllDay, unzonedRange); if (eventInstanceGroup) { return this.eventInstancesToFootprints(eventInstanceGroup.eventInstances); } else { return []; } }; // conversion util Constraints.prototype.eventInstancesToFootprints = function (eventInstances) { var eventRanges = eventInstances.map(util_1.eventInstanceToEventRange); var eventFootprints = this.eventRangesToEventFootprints(eventRanges); return eventFootprints.map(util_1.eventFootprintToComponentFootprint); }; // Overlap // ------------------------------------------------------------------------------------------------ Constraints.prototype.collectOverlapEventFootprints = function (peerEventFootprints, targetFootprint) { var overlapEventFootprints = []; var i; for (i = 0; i < peerEventFootprints.length; i++) { if (this.footprintsIntersect(targetFootprint, peerEventFootprints[i].componentFootprint)) { overlapEventFootprints.push(peerEventFootprints[i]); } } return overlapEventFootprints; }; // Conversion: eventDefs -> eventInstances -> eventRanges -> eventFootprints -> componentFootprints // ------------------------------------------------------------------------------------------------ // NOTE: this might seem like repetitive code with the Grid class, however, this code is related to // constraints whereas the Grid code is related to rendering. Each approach might want to convert // eventRanges -> eventFootprints in a different way. Regardless, there are opportunities to make // this more DRY. /* Returns false on invalid input. */ Constraints.prototype.parseEventDefToInstances = function (eventInput) { var eventManager = this.eventManager; var eventDef = EventDefParser_1.default.parse(eventInput, new EventSource_1.default(this._calendar)); if (!eventDef) { // invalid return false; } return eventDef.buildInstances(eventManager.currentPeriod.unzonedRange); }; Constraints.prototype.eventRangesToEventFootprints = function (eventRanges) { var i; var eventFootprints = []; for (i = 0; i < eventRanges.length; i++) { eventFootprints.push.apply(// footprints eventFootprints, this.eventRangeToEventFootprints(eventRanges[i])); } return eventFootprints; }; Constraints.prototype.eventRangeToEventFootprints = function (eventRange) { return [util_1.eventRangeToEventFootprint(eventRange)]; }; /* Parses footprints directly. Very similar to EventDateProfile::parse :( */ Constraints.prototype.parseFootprints = function (rawInput) { var start; var end; if (rawInput.start) { start = this._calendar.moment(rawInput.start); if (!start.isValid()) { start = null; } } if (rawInput.end) { end = this._calendar.moment(rawInput.end); if (!end.isValid()) { end = null; } } return [ new ComponentFootprint_1.default(new UnzonedRange_1.default(start, end), (start && !start.hasTime()) || (end && !end.hasTime()) // isAllDay ) ]; }; // Footprint Utils // ---------------------------------------------------------------------------------------- Constraints.prototype.footprintContainsFootprint = function (outerFootprint, innerFootprint) { return outerFootprint.unzonedRange.containsRange(innerFootprint.unzonedRange); }; Constraints.prototype.footprintsIntersect = function (footprint0, footprint1) { return footprint0.unzonedRange.intersectsWith(footprint1.unzonedRange); }; return Constraints; }()); exports.default = Constraints; // optional subjectEventInstance function isOverlapsAllowedByFunc(overlapEventFootprints, overlapFunc, subjectEventInstance) { var i; for (i = 0; i < overlapEventFootprints.length; i++) { if (!overlapFunc(overlapEventFootprints[i].eventInstance.toLegacy(), subjectEventInstance ? subjectEventInstance.toLegacy() : null)) { return false; } } return true; } function isOverlapEventInstancesAllowed(overlapEventFootprints, subjectEventInstance) { var subjectLegacyInstance = subjectEventInstance.toLegacy(); var i; var overlapEventInstance; var overlapEventDef; var overlapVal; for (i = 0; i < overlapEventFootprints.length; i++) { overlapEventInstance = overlapEventFootprints[i].eventInstance; overlapEventDef = overlapEventInstance.def; // don't need to pass in calendar, because don't want to consider global eventOverlap property, // because we already considered that earlier in the process. overlapVal = overlapEventDef.getOverlap(); if (overlapVal === false) { return false; } else if (typeof overlapVal === 'function') { if (!overlapVal(overlapEventInstance.toLegacy(), subjectLegacyInstance)) { return false; } } } return true; } /***/ }), /* 218 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var $ = __webpack_require__(3); var util_1 = __webpack_require__(19); var EventInstanceGroup_1 = __webpack_require__(20); var RecurringEventDef_1 = __webpack_require__(54); var EventSource_1 = __webpack_require__(6); var BUSINESS_HOUR_EVENT_DEFAULTS = { start: '09:00', end: '17:00', dow: [1, 2, 3, 4, 5], rendering: 'inverse-background' // classNames are defined in businessHoursSegClasses }; var BusinessHourGenerator = /** @class */ (function () { function BusinessHourGenerator(rawComplexDef, calendar) { this.rawComplexDef = rawComplexDef; this.calendar = calendar; } BusinessHourGenerator.prototype.buildEventInstanceGroup = function (isAllDay, unzonedRange) { var eventDefs = this.buildEventDefs(isAllDay); var eventInstanceGroup; if (eventDefs.length) { eventInstanceGroup = new EventInstanceGroup_1.default(util_1.eventDefsToEventInstances(eventDefs, unzonedRange)); // so that inverse-background rendering can happen even when no eventRanges in view eventInstanceGroup.explicitEventDef = eventDefs[0]; return eventInstanceGroup; } }; BusinessHourGenerator.prototype.buildEventDefs = function (isAllDay) { var rawComplexDef = this.rawComplexDef; var rawDefs = []; var requireDow = false; var i; var defs = []; if (rawComplexDef === true) { rawDefs = [{}]; // will get BUSINESS_HOUR_EVENT_DEFAULTS verbatim } else if ($.isPlainObject(rawComplexDef)) { rawDefs = [rawComplexDef]; } else if ($.isArray(rawComplexDef)) { rawDefs = rawComplexDef; requireDow = true; // every sub-definition NEEDS a day-of-week } for (i = 0; i < rawDefs.length; i++) { if (!requireDow || rawDefs[i].dow) { defs.push(this.buildEventDef(isAllDay, rawDefs[i])); } } return defs; }; BusinessHourGenerator.prototype.buildEventDef = function (isAllDay, rawDef) { var fullRawDef = $.extend({}, BUSINESS_HOUR_EVENT_DEFAULTS, rawDef); if (isAllDay) { fullRawDef.start = null; fullRawDef.end = null; } return RecurringEventDef_1.default.parse(fullRawDef, new EventSource_1.default(this.calendar) // dummy source ); }; return BusinessHourGenerator; }()); exports.default = BusinessHourGenerator; /***/ }), /* 219 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var Promise_1 = __webpack_require__(21); var EmitterMixin_1 = __webpack_require__(13); var UnzonedRange_1 = __webpack_require__(5); var EventInstanceGroup_1 = __webpack_require__(20); var EventPeriod = /** @class */ (function () { function EventPeriod(start, end, timezone) { this.pendingCnt = 0; this.freezeDepth = 0; this.stuntedReleaseCnt = 0; this.releaseCnt = 0; this.start = start; this.end = end; this.timezone = timezone; this.unzonedRange = new UnzonedRange_1.default(start.clone().stripZone(), end.clone().stripZone()); this.requestsByUid = {}; this.eventDefsByUid = {}; this.eventDefsById = {}; this.eventInstanceGroupsById = {}; } EventPeriod.prototype.isWithinRange = function (start, end) { // TODO: use a range util function? return !start.isBefore(this.start) && !end.isAfter(this.end); }; // Requesting and Purging // ----------------------------------------------------------------------------------------------------------------- EventPeriod.prototype.requestSources = function (sources) { this.freeze(); for (var i = 0; i < sources.length; i++) { this.requestSource(sources[i]); } this.thaw(); }; EventPeriod.prototype.requestSource = function (source) { var _this = this; var request = { source: source, status: 'pending', eventDefs: null }; this.requestsByUid[source.uid] = request; this.pendingCnt += 1; source.fetch(this.start, this.end, this.timezone).then(function (eventDefs) { if (request.status !== 'cancelled') { request.status = 'completed'; request.eventDefs = eventDefs; _this.addEventDefs(eventDefs); _this.pendingCnt--; _this.tryRelease(); } }, function () { if (request.status !== 'cancelled') { request.status = 'failed'; _this.pendingCnt--; _this.tryRelease(); } }); }; EventPeriod.prototype.purgeSource = function (source) { var request = this.requestsByUid[source.uid]; if (request) { delete this.requestsByUid[source.uid]; if (request.status === 'pending') { request.status = 'cancelled'; this.pendingCnt--; this.tryRelease(); } else if (request.status === 'completed') { request.eventDefs.forEach(this.removeEventDef.bind(this)); } } }; EventPeriod.prototype.purgeAllSources = function () { var requestsByUid = this.requestsByUid; var uid; var request; var completedCnt = 0; for (uid in requestsByUid) { request = requestsByUid[uid]; if (request.status === 'pending') { request.status = 'cancelled'; } else if (request.status === 'completed') { completedCnt++; } } this.requestsByUid = {}; this.pendingCnt = 0; if (completedCnt) { this.removeAllEventDefs(); // might release } }; // Event Definitions // ----------------------------------------------------------------------------------------------------------------- EventPeriod.prototype.getEventDefByUid = function (eventDefUid) { return this.eventDefsByUid[eventDefUid]; }; EventPeriod.prototype.getEventDefsById = function (eventDefId) { var a = this.eventDefsById[eventDefId]; if (a) { return a.slice(); // clone } return []; }; EventPeriod.prototype.addEventDefs = function (eventDefs) { for (var i = 0; i < eventDefs.length; i++) { this.addEventDef(eventDefs[i]); } }; EventPeriod.prototype.addEventDef = function (eventDef) { var eventDefsById = this.eventDefsById; var eventDefId = eventDef.id; var eventDefs = eventDefsById[eventDefId] || (eventDefsById[eventDefId] = []); var eventInstances = eventDef.buildInstances(this.unzonedRange); var i; eventDefs.push(eventDef); this.eventDefsByUid[eventDef.uid] = eventDef; for (i = 0; i < eventInstances.length; i++) { this.addEventInstance(eventInstances[i], eventDefId); } }; EventPeriod.prototype.removeEventDefsById = function (eventDefId) { var _this = this; this.getEventDefsById(eventDefId).forEach(function (eventDef) { _this.removeEventDef(eventDef); }); }; EventPeriod.prototype.removeAllEventDefs = function () { var isEmpty = $.isEmptyObject(this.eventDefsByUid); this.eventDefsByUid = {}; this.eventDefsById = {}; this.eventInstanceGroupsById = {}; if (!isEmpty) { this.tryRelease(); } }; EventPeriod.prototype.removeEventDef = function (eventDef) { var eventDefsById = this.eventDefsById; var eventDefs = eventDefsById[eventDef.id]; delete this.eventDefsByUid[eventDef.uid]; if (eventDefs) { util_1.removeExact(eventDefs, eventDef); if (!eventDefs.length) { delete eventDefsById[eventDef.id]; } this.removeEventInstancesForDef(eventDef); } }; // Event Instances // ----------------------------------------------------------------------------------------------------------------- EventPeriod.prototype.getEventInstances = function () { var eventInstanceGroupsById = this.eventInstanceGroupsById; var eventInstances = []; var id; for (id in eventInstanceGroupsById) { eventInstances.push.apply(eventInstances, // append eventInstanceGroupsById[id].eventInstances); } return eventInstances; }; EventPeriod.prototype.getEventInstancesWithId = function (eventDefId) { var eventInstanceGroup = this.eventInstanceGroupsById[eventDefId]; if (eventInstanceGroup) { return eventInstanceGroup.eventInstances.slice(); // clone } return []; }; EventPeriod.prototype.getEventInstancesWithoutId = function (eventDefId) { var eventInstanceGroupsById = this.eventInstanceGroupsById; var matchingInstances = []; var id; for (id in eventInstanceGroupsById) { if (id !== eventDefId) { matchingInstances.push.apply(matchingInstances, // append eventInstanceGroupsById[id].eventInstances); } } return matchingInstances; }; EventPeriod.prototype.addEventInstance = function (eventInstance, eventDefId) { var eventInstanceGroupsById = this.eventInstanceGroupsById; var eventInstanceGroup = eventInstanceGroupsById[eventDefId] || (eventInstanceGroupsById[eventDefId] = new EventInstanceGroup_1.default()); eventInstanceGroup.eventInstances.push(eventInstance); this.tryRelease(); }; EventPeriod.prototype.removeEventInstancesForDef = function (eventDef) { var eventInstanceGroupsById = this.eventInstanceGroupsById; var eventInstanceGroup = eventInstanceGroupsById[eventDef.id]; var removeCnt; if (eventInstanceGroup) { removeCnt = util_1.removeMatching(eventInstanceGroup.eventInstances, function (currentEventInstance) { return currentEventInstance.def === eventDef; }); if (!eventInstanceGroup.eventInstances.length) { delete eventInstanceGroupsById[eventDef.id]; } if (removeCnt) { this.tryRelease(); } } }; // Releasing and Freezing // ----------------------------------------------------------------------------------------------------------------- EventPeriod.prototype.tryRelease = function () { if (!this.pendingCnt) { if (!this.freezeDepth) { this.release(); } else { this.stuntedReleaseCnt++; } } }; EventPeriod.prototype.release = function () { this.releaseCnt++; this.trigger('release', this.eventInstanceGroupsById); }; EventPeriod.prototype.whenReleased = function () { var _this = this; if (this.releaseCnt) { return Promise_1.default.resolve(this.eventInstanceGroupsById); } else { return Promise_1.default.construct(function (onResolve) { _this.one('release', onResolve); }); } }; EventPeriod.prototype.freeze = function () { if (!(this.freezeDepth++)) { this.stuntedReleaseCnt = 0; } }; EventPeriod.prototype.thaw = function () { if (!(--this.freezeDepth) && this.stuntedReleaseCnt && !this.pendingCnt) { this.release(); } }; return EventPeriod; }()); exports.default = EventPeriod; EmitterMixin_1.default.mixInto(EventPeriod); /***/ }), /* 220 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var EventPeriod_1 = __webpack_require__(219); var ArrayEventSource_1 = __webpack_require__(56); var EventSource_1 = __webpack_require__(6); var EventSourceParser_1 = __webpack_require__(38); var SingleEventDef_1 = __webpack_require__(9); var EventInstanceGroup_1 = __webpack_require__(20); var EmitterMixin_1 = __webpack_require__(13); var ListenerMixin_1 = __webpack_require__(7); var EventManager = /** @class */ (function () { function EventManager(calendar) { this.calendar = calendar; this.stickySource = new ArrayEventSource_1.default(calendar); this.otherSources = []; } EventManager.prototype.requestEvents = function (start, end, timezone, force) { if (force || !this.currentPeriod || !this.currentPeriod.isWithinRange(start, end) || timezone !== this.currentPeriod.timezone) { this.setPeriod(// will change this.currentPeriod new EventPeriod_1.default(start, end, timezone)); } return this.currentPeriod.whenReleased(); }; // Source Adding/Removing // ----------------------------------------------------------------------------------------------------------------- EventManager.prototype.addSource = function (eventSource) { this.otherSources.push(eventSource); if (this.currentPeriod) { this.currentPeriod.requestSource(eventSource); // might release } }; EventManager.prototype.removeSource = function (doomedSource) { util_1.removeExact(this.otherSources, doomedSource); if (this.currentPeriod) { this.currentPeriod.purgeSource(doomedSource); // might release } }; EventManager.prototype.removeAllSources = function () { this.otherSources = []; if (this.currentPeriod) { this.currentPeriod.purgeAllSources(); // might release } }; // Source Refetching // ----------------------------------------------------------------------------------------------------------------- EventManager.prototype.refetchSource = function (eventSource) { var currentPeriod = this.currentPeriod; if (currentPeriod) { currentPeriod.freeze(); currentPeriod.purgeSource(eventSource); currentPeriod.requestSource(eventSource); currentPeriod.thaw(); } }; EventManager.prototype.refetchAllSources = function () { var currentPeriod = this.currentPeriod; if (currentPeriod) { currentPeriod.freeze(); currentPeriod.purgeAllSources(); currentPeriod.requestSources(this.getSources()); currentPeriod.thaw(); } }; // Source Querying // ----------------------------------------------------------------------------------------------------------------- EventManager.prototype.getSources = function () { return [this.stickySource].concat(this.otherSources); }; // like querySources, but accepts multple match criteria (like multiple IDs) EventManager.prototype.multiQuerySources = function (matchInputs) { // coerce into an array if (!matchInputs) { matchInputs = []; } else if (!$.isArray(matchInputs)) { matchInputs = [matchInputs]; } var matchingSources = []; var i; // resolve raw inputs to real event source objects for (i = 0; i < matchInputs.length; i++) { matchingSources.push.apply(// append matchingSources, this.querySources(matchInputs[i])); } return matchingSources; }; // matchInput can either by a real event source object, an ID, or the function/URL for the source. // returns an array of matching source objects. EventManager.prototype.querySources = function (matchInput) { var sources = this.otherSources; var i; var source; // given a proper event source object for (i = 0; i < sources.length; i++) { source = sources[i]; if (source === matchInput) { return [source]; } } // an ID match source = this.getSourceById(EventSource_1.default.normalizeId(matchInput)); if (source) { return [source]; } // parse as an event source matchInput = EventSourceParser_1.default.parse(matchInput, this.calendar); if (matchInput) { return $.grep(sources, function (source) { return isSourcesEquivalent(matchInput, source); }); } }; /* ID assumed to already be normalized */ EventManager.prototype.getSourceById = function (id) { return $.grep(this.otherSources, function (source) { return source.id && source.id === id; })[0]; }; // Event-Period // ----------------------------------------------------------------------------------------------------------------- EventManager.prototype.setPeriod = function (eventPeriod) { if (this.currentPeriod) { this.unbindPeriod(this.currentPeriod); this.currentPeriod = null; } this.currentPeriod = eventPeriod; this.bindPeriod(eventPeriod); eventPeriod.requestSources(this.getSources()); }; EventManager.prototype.bindPeriod = function (eventPeriod) { this.listenTo(eventPeriod, 'release', function (eventsPayload) { this.trigger('release', eventsPayload); }); }; EventManager.prototype.unbindPeriod = function (eventPeriod) { this.stopListeningTo(eventPeriod); }; // Event Getting/Adding/Removing // ----------------------------------------------------------------------------------------------------------------- EventManager.prototype.getEventDefByUid = function (uid) { if (this.currentPeriod) { return this.currentPeriod.getEventDefByUid(uid); } }; EventManager.prototype.addEventDef = function (eventDef, isSticky) { if (isSticky) { this.stickySource.addEventDef(eventDef); } if (this.currentPeriod) { this.currentPeriod.addEventDef(eventDef); // might release } }; EventManager.prototype.removeEventDefsById = function (eventId) { this.getSources().forEach(function (eventSource) { eventSource.removeEventDefsById(eventId); }); if (this.currentPeriod) { this.currentPeriod.removeEventDefsById(eventId); // might release } }; EventManager.prototype.removeAllEventDefs = function () { this.getSources().forEach(function (eventSource) { eventSource.removeAllEventDefs(); }); if (this.currentPeriod) { this.currentPeriod.removeAllEventDefs(); } }; // Event Mutating // ----------------------------------------------------------------------------------------------------------------- /* Returns an undo function. */ EventManager.prototype.mutateEventsWithId = function (eventDefId, eventDefMutation) { var currentPeriod = this.currentPeriod; var eventDefs; var undoFuncs = []; if (currentPeriod) { currentPeriod.freeze(); eventDefs = currentPeriod.getEventDefsById(eventDefId); eventDefs.forEach(function (eventDef) { // add/remove esp because id might change currentPeriod.removeEventDef(eventDef); undoFuncs.push(eventDefMutation.mutateSingle(eventDef)); currentPeriod.addEventDef(eventDef); }); currentPeriod.thaw(); return function () { currentPeriod.freeze(); for (var i = 0; i < eventDefs.length; i++) { currentPeriod.removeEventDef(eventDefs[i]); undoFuncs[i](); currentPeriod.addEventDef(eventDefs[i]); } currentPeriod.thaw(); }; } return function () { }; }; /* copies and then mutates */ EventManager.prototype.buildMutatedEventInstanceGroup = function (eventDefId, eventDefMutation) { var eventDefs = this.getEventDefsById(eventDefId); var i; var defCopy; var allInstances = []; for (i = 0; i < eventDefs.length; i++) { defCopy = eventDefs[i].clone(); if (defCopy instanceof SingleEventDef_1.default) { eventDefMutation.mutateSingle(defCopy); allInstances.push.apply(allInstances, // append defCopy.buildInstances()); } } return new EventInstanceGroup_1.default(allInstances); }; // Freezing // ----------------------------------------------------------------------------------------------------------------- EventManager.prototype.freeze = function () { if (this.currentPeriod) { this.currentPeriod.freeze(); } }; EventManager.prototype.thaw = function () { if (this.currentPeriod) { this.currentPeriod.thaw(); } }; // methods that simply forward to EventPeriod EventManager.prototype.getEventDefsById = function (eventDefId) { return this.currentPeriod.getEventDefsById(eventDefId); }; EventManager.prototype.getEventInstances = function () { return this.currentPeriod.getEventInstances(); }; EventManager.prototype.getEventInstancesWithId = function (eventDefId) { return this.currentPeriod.getEventInstancesWithId(eventDefId); }; EventManager.prototype.getEventInstancesWithoutId = function (eventDefId) { return this.currentPeriod.getEventInstancesWithoutId(eventDefId); }; return EventManager; }()); exports.default = EventManager; EmitterMixin_1.default.mixInto(EventManager); ListenerMixin_1.default.mixInto(EventManager); function isSourcesEquivalent(source0, source1) { return source0.getPrimitive() === source1.getPrimitive(); } /***/ }), /* 221 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var Theme_1 = __webpack_require__(22); var StandardTheme = /** @class */ (function (_super) { tslib_1.__extends(StandardTheme, _super); function StandardTheme() { return _super !== null && _super.apply(this, arguments) || this; } return StandardTheme; }(Theme_1.default)); exports.default = StandardTheme; StandardTheme.prototype.classes = { widget: 'fc-unthemed', widgetHeader: 'fc-widget-header', widgetContent: 'fc-widget-content', buttonGroup: 'fc-button-group', button: 'fc-button', cornerLeft: 'fc-corner-left', cornerRight: 'fc-corner-right', stateDefault: 'fc-state-default', stateActive: 'fc-state-active', stateDisabled: 'fc-state-disabled', stateHover: 'fc-state-hover', stateDown: 'fc-state-down', popoverHeader: 'fc-widget-header', popoverContent: 'fc-widget-content', // day grid headerRow: 'fc-widget-header', dayRow: 'fc-widget-content', // list view listView: 'fc-widget-content' }; StandardTheme.prototype.baseIconClass = 'fc-icon'; StandardTheme.prototype.iconClasses = { close: 'fc-icon-x', prev: 'fc-icon-left-single-arrow', next: 'fc-icon-right-single-arrow', prevYear: 'fc-icon-left-double-arrow', nextYear: 'fc-icon-right-double-arrow' }; StandardTheme.prototype.iconOverrideOption = 'buttonIcons'; StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon'; StandardTheme.prototype.iconOverridePrefix = 'fc-icon-'; /***/ }), /* 222 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var Theme_1 = __webpack_require__(22); var JqueryUiTheme = /** @class */ (function (_super) { tslib_1.__extends(JqueryUiTheme, _super); function JqueryUiTheme() { return _super !== null && _super.apply(this, arguments) || this; } return JqueryUiTheme; }(Theme_1.default)); exports.default = JqueryUiTheme; JqueryUiTheme.prototype.classes = { widget: 'ui-widget', widgetHeader: 'ui-widget-header', widgetContent: 'ui-widget-content', buttonGroup: 'fc-button-group', button: 'ui-button', cornerLeft: 'ui-corner-left', cornerRight: 'ui-corner-right', stateDefault: 'ui-state-default', stateActive: 'ui-state-active', stateDisabled: 'ui-state-disabled', stateHover: 'ui-state-hover', stateDown: 'ui-state-down', today: 'ui-state-highlight', popoverHeader: 'ui-widget-header', popoverContent: 'ui-widget-content', // day grid headerRow: 'ui-widget-header', dayRow: 'ui-widget-content', // list view listView: 'ui-widget-content' }; JqueryUiTheme.prototype.baseIconClass = 'ui-icon'; JqueryUiTheme.prototype.iconClasses = { close: 'ui-icon-closethick', prev: 'ui-icon-circle-triangle-w', next: 'ui-icon-circle-triangle-e', prevYear: 'ui-icon-seek-prev', nextYear: 'ui-icon-seek-next' }; JqueryUiTheme.prototype.iconOverrideOption = 'themeButtonIcons'; JqueryUiTheme.prototype.iconOverrideCustomButtonOption = 'themeIcon'; JqueryUiTheme.prototype.iconOverridePrefix = 'ui-icon-'; /***/ }), /* 223 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var Promise_1 = __webpack_require__(21); var EventSource_1 = __webpack_require__(6); var FuncEventSource = /** @class */ (function (_super) { tslib_1.__extends(FuncEventSource, _super); function FuncEventSource() { return _super !== null && _super.apply(this, arguments) || this; } FuncEventSource.parse = function (rawInput, calendar) { var rawProps; // normalize raw input if ($.isFunction(rawInput.events)) { // extended form rawProps = rawInput; } else if ($.isFunction(rawInput)) { // short form rawProps = { events: rawInput }; } if (rawProps) { return EventSource_1.default.parse.call(this, rawProps, calendar); } return false; }; FuncEventSource.prototype.fetch = function (start, end, timezone) { var _this = this; this.calendar.pushLoading(); return Promise_1.default.construct(function (onResolve) { _this.func.call(_this.calendar, start.clone(), end.clone(), timezone, function (rawEventDefs) { _this.calendar.popLoading(); onResolve(_this.parseEventDefs(rawEventDefs)); }); }); }; FuncEventSource.prototype.getPrimitive = function () { return this.func; }; FuncEventSource.prototype.applyManualStandardProps = function (rawProps) { var superSuccess = _super.prototype.applyManualStandardProps.call(this, rawProps); this.func = rawProps.events; return superSuccess; }; return FuncEventSource; }(EventSource_1.default)); exports.default = FuncEventSource; FuncEventSource.defineStandardProps({ events: false // don't automatically transfer }); /***/ }), /* 224 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var Promise_1 = __webpack_require__(21); var EventSource_1 = __webpack_require__(6); var JsonFeedEventSource = /** @class */ (function (_super) { tslib_1.__extends(JsonFeedEventSource, _super); function JsonFeedEventSource() { return _super !== null && _super.apply(this, arguments) || this; } JsonFeedEventSource.parse = function (rawInput, calendar) { var rawProps; // normalize raw input if (typeof rawInput.url === 'string') { // extended form rawProps = rawInput; } else if (typeof rawInput === 'string') { // short form rawProps = { url: rawInput }; } if (rawProps) { return EventSource_1.default.parse.call(this, rawProps, calendar); } return false; }; JsonFeedEventSource.prototype.fetch = function (start, end, timezone) { var _this = this; var ajaxSettings = this.ajaxSettings; var onSuccess = ajaxSettings.success; var onError = ajaxSettings.error; var requestParams = this.buildRequestParams(start, end, timezone); // todo: eventually handle the promise's then, // don't intercept success/error // tho will be a breaking API change this.calendar.pushLoading(); return Promise_1.default.construct(function (onResolve, onReject) { $.ajax($.extend({}, // destination JsonFeedEventSource.AJAX_DEFAULTS, ajaxSettings, { url: _this.url, data: requestParams, success: function (rawEventDefs, status, xhr) { var callbackRes; _this.calendar.popLoading(); if (rawEventDefs) { callbackRes = util_1.applyAll(onSuccess, _this, [rawEventDefs, status, xhr]); // redirect `this` if ($.isArray(callbackRes)) { rawEventDefs = callbackRes; } onResolve(_this.parseEventDefs(rawEventDefs)); } else { onReject(); } }, error: function (xhr, statusText, errorThrown) { _this.calendar.popLoading(); util_1.applyAll(onError, _this, [xhr, statusText, errorThrown]); // redirect `this` onReject(); } })); }); }; JsonFeedEventSource.prototype.buildRequestParams = function (start, end, timezone) { var calendar = this.calendar; var ajaxSettings = this.ajaxSettings; var startParam; var endParam; var timezoneParam; var customRequestParams; var params = {}; startParam = this.startParam; if (startParam == null) { startParam = calendar.opt('startParam'); } endParam = this.endParam; if (endParam == null) { endParam = calendar.opt('endParam'); } timezoneParam = this.timezoneParam; if (timezoneParam == null) { timezoneParam = calendar.opt('timezoneParam'); } // retrieve any outbound GET/POST $.ajax data from the options if ($.isFunction(ajaxSettings.data)) { // supplied as a function that returns a key/value object customRequestParams = ajaxSettings.data(); } else { // probably supplied as a straight key/value object customRequestParams = ajaxSettings.data || {}; } $.extend(params, customRequestParams); params[startParam] = start.format(); params[endParam] = end.format(); if (timezone && timezone !== 'local') { params[timezoneParam] = timezone; } return params; }; JsonFeedEventSource.prototype.getPrimitive = function () { return this.url; }; JsonFeedEventSource.prototype.applyMiscProps = function (rawProps) { this.ajaxSettings = rawProps; }; JsonFeedEventSource.AJAX_DEFAULTS = { dataType: 'json', cache: false }; return JsonFeedEventSource; }(EventSource_1.default)); exports.default = JsonFeedEventSource; JsonFeedEventSource.defineStandardProps({ // automatically transfer (true)... url: true, startParam: true, endParam: true, timezoneParam: true }); /***/ }), /* 225 */ /***/ (function(module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); var Iterator = /** @class */ (function () { function Iterator(items) { this.items = items || []; } /* Calls a method on every item passing the arguments through */ Iterator.prototype.proxyCall = function (methodName) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } var results = []; this.items.forEach(function (item) { results.push(item[methodName].apply(item, args)); }); return results; }; return Iterator; }()); exports.default = Iterator; /***/ }), /* 226 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var ListenerMixin_1 = __webpack_require__(7); /* Creates a clone of an element and lets it track the mouse as it moves ----------------------------------------------------------------------------------------------------------------------*/ var MouseFollower = /** @class */ (function () { function MouseFollower(sourceEl, options) { this.isFollowing = false; this.isHidden = false; this.isAnimating = false; // doing the revert animation? this.options = options = options || {}; this.sourceEl = sourceEl; this.parentEl = options.parentEl ? $(options.parentEl) : sourceEl.parent(); // default to sourceEl's parent } // Causes the element to start following the mouse MouseFollower.prototype.start = function (ev) { if (!this.isFollowing) { this.isFollowing = true; this.y0 = util_1.getEvY(ev); this.x0 = util_1.getEvX(ev); this.topDelta = 0; this.leftDelta = 0; if (!this.isHidden) { this.updatePosition(); } if (util_1.getEvIsTouch(ev)) { this.listenTo($(document), 'touchmove', this.handleMove); } else { this.listenTo($(document), 'mousemove', this.handleMove); } } }; // Causes the element to stop following the mouse. If shouldRevert is true, will animate back to original position. // `callback` gets invoked when the animation is complete. If no animation, it is invoked immediately. MouseFollower.prototype.stop = function (shouldRevert, callback) { var _this = this; var revertDuration = this.options.revertDuration; var complete = function () { _this.isAnimating = false; _this.removeElement(); _this.top0 = _this.left0 = null; // reset state for future updatePosition calls if (callback) { callback(); } }; if (this.isFollowing && !this.isAnimating) { // disallow more than one stop animation at a time this.isFollowing = false; this.stopListeningTo($(document)); if (shouldRevert && revertDuration && !this.isHidden) { // do a revert animation? this.isAnimating = true; this.el.animate({ top: this.top0, left: this.left0 }, { duration: revertDuration, complete: complete }); } else { complete(); } } }; // Gets the tracking element. Create it if necessary MouseFollower.prototype.getEl = function () { var el = this.el; if (!el) { el = this.el = this.sourceEl.clone() .addClass(this.options.additionalClass || '') .css({ position: 'absolute', visibility: '', display: this.isHidden ? 'none' : '', margin: 0, right: 'auto', bottom: 'auto', width: this.sourceEl.width(), height: this.sourceEl.height(), opacity: this.options.opacity || '', zIndex: this.options.zIndex }); // we don't want long taps or any mouse interaction causing selection/menus. // would use preventSelection(), but that prevents selectstart, causing problems. el.addClass('fc-unselectable'); el.appendTo(this.parentEl); } return el; }; // Removes the tracking element if it has already been created MouseFollower.prototype.removeElement = function () { if (this.el) { this.el.remove(); this.el = null; } }; // Update the CSS position of the tracking element MouseFollower.prototype.updatePosition = function () { var sourceOffset; var origin; this.getEl(); // ensure this.el // make sure origin info was computed if (this.top0 == null) { sourceOffset = this.sourceEl.offset(); origin = this.el.offsetParent().offset(); this.top0 = sourceOffset.top - origin.top; this.left0 = sourceOffset.left - origin.left; } this.el.css({ top: this.top0 + this.topDelta, left: this.left0 + this.leftDelta }); }; // Gets called when the user moves the mouse MouseFollower.prototype.handleMove = function (ev) { this.topDelta = util_1.getEvY(ev) - this.y0; this.leftDelta = util_1.getEvX(ev) - this.x0; if (!this.isHidden) { this.updatePosition(); } }; // Temporarily makes the tracking element invisible. Can be called before following starts MouseFollower.prototype.hide = function () { if (!this.isHidden) { this.isHidden = true; if (this.el) { this.el.hide(); } } }; // Show the tracking element after it has been temporarily hidden MouseFollower.prototype.show = function () { if (this.isHidden) { this.isHidden = false; this.updatePosition(); this.getEl().show(); } }; return MouseFollower; }()); exports.default = MouseFollower; ListenerMixin_1.default.mixInto(MouseFollower); /***/ }), /* 227 */ /***/ (function(module, exports, __webpack_require__) { /* A rectangular panel that is absolutely positioned over other content ------------------------------------------------------------------------------------------------------------------------ Options: - className (string) - content (HTML string or jQuery element set) - parentEl - top - left - right (the x coord of where the right edge should be. not a "CSS" right) - autoHide (boolean) - show (callback) - hide (callback) */ Object.defineProperty(exports, "__esModule", { value: true }); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var ListenerMixin_1 = __webpack_require__(7); var Popover = /** @class */ (function () { function Popover(options) { this.isHidden = true; this.margin = 10; // the space required between the popover and the edges of the scroll container this.options = options || {}; } // Shows the popover on the specified position. Renders it if not already Popover.prototype.show = function () { if (this.isHidden) { if (!this.el) { this.render(); } this.el.show(); this.position(); this.isHidden = false; this.trigger('show'); } }; // Hides the popover, through CSS, but does not remove it from the DOM Popover.prototype.hide = function () { if (!this.isHidden) { this.el.hide(); this.isHidden = true; this.trigger('hide'); } }; // Creates `this.el` and renders content inside of it Popover.prototype.render = function () { var _this = this; var options = this.options; this.el = $('<div class="fc-popover"/>') .addClass(options.className || '') .css({ // position initially to the top left to avoid creating scrollbars top: 0, left: 0 }) .append(options.content) .appendTo(options.parentEl); // when a click happens on anything inside with a 'fc-close' className, hide the popover this.el.on('click', '.fc-close', function () { _this.hide(); }); if (options.autoHide) { this.listenTo($(document), 'mousedown', this.documentMousedown); } }; // Triggered when the user clicks *anywhere* in the document, for the autoHide feature Popover.prototype.documentMousedown = function (ev) { // only hide the popover if the click happened outside the popover if (this.el && !$(ev.target).closest(this.el).length) { this.hide(); } }; // Hides and unregisters any handlers Popover.prototype.removeElement = function () { this.hide(); if (this.el) { this.el.remove(); this.el = null; } this.stopListeningTo($(document), 'mousedown'); }; // Positions the popover optimally, using the top/left/right options Popover.prototype.position = function () { var options = this.options; var origin = this.el.offsetParent().offset(); var width = this.el.outerWidth(); var height = this.el.outerHeight(); var windowEl = $(window); var viewportEl = util_1.getScrollParent(this.el); var viewportTop; var viewportLeft; var viewportOffset; var top; // the "position" (not "offset") values for the popover var left; // // compute top and left top = options.top || 0; if (options.left !== undefined) { left = options.left; } else if (options.right !== undefined) { left = options.right - width; // derive the left value from the right value } else { left = 0; } if (viewportEl.is(window) || viewportEl.is(document)) { // normalize getScrollParent's result viewportEl = windowEl; viewportTop = 0; // the window is always at the top left viewportLeft = 0; // (and .offset() won't work if called here) } else { viewportOffset = viewportEl.offset(); viewportTop = viewportOffset.top; viewportLeft = viewportOffset.left; } // if the window is scrolled, it causes the visible area to be further down viewportTop += windowEl.scrollTop(); viewportLeft += windowEl.scrollLeft(); // constrain to the view port. if constrained by two edges, give precedence to top/left if (options.viewportConstrain !== false) { top = Math.min(top, viewportTop + viewportEl.outerHeight() - height - this.margin); top = Math.max(top, viewportTop + this.margin); left = Math.min(left, viewportLeft + viewportEl.outerWidth() - width - this.margin); left = Math.max(left, viewportLeft + this.margin); } this.el.css({ top: top - origin.top, left: left - origin.left }); }; // Triggers a callback. Calls a function in the option hash of the same name. // Arguments beyond the first `name` are forwarded on. // TODO: better code reuse for this. Repeat code Popover.prototype.trigger = function (name) { if (this.options[name]) { this.options[name].apply(this, Array.prototype.slice.call(arguments, 1)); } }; return Popover; }()); exports.default = Popover; ListenerMixin_1.default.mixInto(Popover); /***/ }), /* 228 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var EmitterMixin_1 = __webpack_require__(13); var TaskQueue = /** @class */ (function () { function TaskQueue() { this.q = []; this.isPaused = false; this.isRunning = false; } TaskQueue.prototype.queue = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } this.q.push.apply(this.q, args); // append this.tryStart(); }; TaskQueue.prototype.pause = function () { this.isPaused = true; }; TaskQueue.prototype.resume = function () { this.isPaused = false; this.tryStart(); }; TaskQueue.prototype.getIsIdle = function () { return !this.isRunning && !this.isPaused; }; TaskQueue.prototype.tryStart = function () { if (!this.isRunning && this.canRunNext()) { this.isRunning = true; this.trigger('start'); this.runRemaining(); } }; TaskQueue.prototype.canRunNext = function () { return !this.isPaused && this.q.length; }; TaskQueue.prototype.runRemaining = function () { var _this = this; var task; var res; do { task = this.q.shift(); // always freshly reference q. might have been reassigned. res = this.runTask(task); if (res && res.then) { res.then(function () { if (_this.canRunNext()) { _this.runRemaining(); } }); return; // prevent marking as stopped } } while (this.canRunNext()); this.trigger('stop'); // not really a 'stop' ... more of a 'drained' this.isRunning = false; // if 'stop' handler added more tasks.... TODO: write test for this this.tryStart(); }; TaskQueue.prototype.runTask = function (task) { return task(); // task *is* the function, but subclasses can change the format of a task }; return TaskQueue; }()); exports.default = TaskQueue; EmitterMixin_1.default.mixInto(TaskQueue); /***/ }), /* 229 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var TaskQueue_1 = __webpack_require__(228); var RenderQueue = /** @class */ (function (_super) { tslib_1.__extends(RenderQueue, _super); function RenderQueue(waitsByNamespace) { var _this = _super.call(this) || this; _this.waitsByNamespace = waitsByNamespace || {}; return _this; } RenderQueue.prototype.queue = function (taskFunc, namespace, type) { var task = { func: taskFunc, namespace: namespace, type: type }; var waitMs; if (namespace) { waitMs = this.waitsByNamespace[namespace]; } if (this.waitNamespace) { if (namespace === this.waitNamespace && waitMs != null) { this.delayWait(waitMs); } else { this.clearWait(); this.tryStart(); } } if (this.compoundTask(task)) { // appended to queue? if (!this.waitNamespace && waitMs != null) { this.startWait(namespace, waitMs); } else { this.tryStart(); } } }; RenderQueue.prototype.startWait = function (namespace, waitMs) { this.waitNamespace = namespace; this.spawnWait(waitMs); }; RenderQueue.prototype.delayWait = function (waitMs) { clearTimeout(this.waitId); this.spawnWait(waitMs); }; RenderQueue.prototype.spawnWait = function (waitMs) { var _this = this; this.waitId = setTimeout(function () { _this.waitNamespace = null; _this.tryStart(); }, waitMs); }; RenderQueue.prototype.clearWait = function () { if (this.waitNamespace) { clearTimeout(this.waitId); this.waitId = null; this.waitNamespace = null; } }; RenderQueue.prototype.canRunNext = function () { if (!_super.prototype.canRunNext.call(this)) { return false; } // waiting for a certain namespace to stop receiving tasks? if (this.waitNamespace) { var q = this.q; // if there was a different namespace task in the meantime, // that forces all previously-waiting tasks to suddenly execute. // TODO: find a way to do this in constant time. for (var i = 0; i < q.length; i++) { if (q[i].namespace !== this.waitNamespace) { return true; // allow execution } } return false; } return true; }; RenderQueue.prototype.runTask = function (task) { task.func(); }; RenderQueue.prototype.compoundTask = function (newTask) { var q = this.q; var shouldAppend = true; var i; var task; if (newTask.namespace && newTask.type === 'destroy') { // remove all init/add/remove ops with same namespace, regardless of order for (i = q.length - 1; i >= 0; i--) { task = q[i]; if (task.namespace === newTask.namespace) { switch (task.type) { case 'init': shouldAppend = false; // the latest destroy is cancelled out by not doing the init /* falls through */ case 'add': /* falls through */ case 'remove': q.splice(i, 1); // remove task } } } } if (shouldAppend) { q.push(newTask); } return shouldAppend; }; return RenderQueue; }(TaskQueue_1.default)); exports.default = RenderQueue; /***/ }), /* 230 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var Model_1 = __webpack_require__(51); var Component = /** @class */ (function (_super) { tslib_1.__extends(Component, _super); function Component() { return _super !== null && _super.apply(this, arguments) || this; } Component.prototype.setElement = function (el) { this.el = el; this.bindGlobalHandlers(); this.renderSkeleton(); this.set('isInDom', true); }; Component.prototype.removeElement = function () { this.unset('isInDom'); this.unrenderSkeleton(); this.unbindGlobalHandlers(); this.el.remove(); // NOTE: don't null-out this.el in case the View was destroyed within an API callback. // We don't null-out the View's other jQuery element references upon destroy, // so we shouldn't kill this.el either. }; Component.prototype.bindGlobalHandlers = function () { // subclasses can override }; Component.prototype.unbindGlobalHandlers = function () { // subclasses can override }; /* NOTE: Can't have a `render` method. Read the deprecation notice in View::executeDateRender */ // Renders the basic structure of the view before any content is rendered Component.prototype.renderSkeleton = function () { // subclasses should implement }; // Unrenders the basic structure of the view Component.prototype.unrenderSkeleton = function () { // subclasses should implement }; return Component; }(Model_1.default)); exports.default = Component; /***/ }), /* 231 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var moment = __webpack_require__(0); var util_1 = __webpack_require__(4); var moment_ext_1 = __webpack_require__(11); var date_formatting_1 = __webpack_require__(49); var Component_1 = __webpack_require__(230); var util_2 = __webpack_require__(19); var DateComponent = /** @class */ (function (_super) { tslib_1.__extends(DateComponent, _super); function DateComponent(_view, _options) { var _this = _super.call(this) || this; _this.isRTL = false; // frequently accessed options _this.hitsNeededDepth = 0; // necessary because multiple callers might need the same hits _this.hasAllDayBusinessHours = false; // TODO: unify with largeUnit and isTimeScale? _this.isDatesRendered = false; // hack to set options prior to the this.opt calls if (_view) { _this['view'] = _view; } if (_options) { _this['options'] = _options; } _this.uid = String(DateComponent.guid++); _this.childrenByUid = {}; _this.nextDayThreshold = moment.duration(_this.opt('nextDayThreshold')); _this.isRTL = _this.opt('isRTL'); if (_this.fillRendererClass) { _this.fillRenderer = new _this.fillRendererClass(_this); } if (_this.eventRendererClass) { // fillRenderer is optional -----v _this.eventRenderer = new _this.eventRendererClass(_this, _this.fillRenderer); } if (_this.helperRendererClass && _this.eventRenderer) { _this.helperRenderer = new _this.helperRendererClass(_this, _this.eventRenderer); } if (_this.businessHourRendererClass && _this.fillRenderer) { _this.businessHourRenderer = new _this.businessHourRendererClass(_this, _this.fillRenderer); } return _this; } DateComponent.prototype.addChild = function (child) { if (!this.childrenByUid[child.uid]) { this.childrenByUid[child.uid] = child; return true; } return false; }; DateComponent.prototype.removeChild = function (child) { if (this.childrenByUid[child.uid]) { delete this.childrenByUid[child.uid]; return true; } return false; }; // TODO: only do if isInDom? // TODO: make part of Component, along with children/batch-render system? DateComponent.prototype.updateSize = function (totalHeight, isAuto, isResize) { this.callChildren('updateSize', arguments); }; // Options // ----------------------------------------------------------------------------------------------------------------- DateComponent.prototype.opt = function (name) { return this._getView().opt(name); // default implementation }; DateComponent.prototype.publiclyTrigger = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var calendar = this._getCalendar(); return calendar.publiclyTrigger.apply(calendar, args); }; DateComponent.prototype.hasPublicHandlers = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var calendar = this._getCalendar(); return calendar.hasPublicHandlers.apply(calendar, args); }; // Date // ----------------------------------------------------------------------------------------------------------------- DateComponent.prototype.executeDateRender = function (dateProfile) { this.dateProfile = dateProfile; // for rendering this.renderDates(dateProfile); this.isDatesRendered = true; this.callChildren('executeDateRender', arguments); }; DateComponent.prototype.executeDateUnrender = function () { this.callChildren('executeDateUnrender', arguments); this.dateProfile = null; this.unrenderDates(); this.isDatesRendered = false; }; // date-cell content only DateComponent.prototype.renderDates = function (dateProfile) { // subclasses should implement }; // date-cell content only DateComponent.prototype.unrenderDates = function () { // subclasses should override }; // Now-Indicator // ----------------------------------------------------------------------------------------------------------------- // Returns a string unit, like 'second' or 'minute' that defined how often the current time indicator // should be refreshed. If something falsy is returned, no time indicator is rendered at all. DateComponent.prototype.getNowIndicatorUnit = function () { // subclasses should implement }; // Renders a current time indicator at the given datetime DateComponent.prototype.renderNowIndicator = function (date) { this.callChildren('renderNowIndicator', arguments); }; // Undoes the rendering actions from renderNowIndicator DateComponent.prototype.unrenderNowIndicator = function () { this.callChildren('unrenderNowIndicator', arguments); }; // Business Hours // --------------------------------------------------------------------------------------------------------------- DateComponent.prototype.renderBusinessHours = function (businessHourGenerator) { if (this.businessHourRenderer) { this.businessHourRenderer.render(businessHourGenerator); } this.callChildren('renderBusinessHours', arguments); }; // Unrenders previously-rendered business-hours DateComponent.prototype.unrenderBusinessHours = function () { this.callChildren('unrenderBusinessHours', arguments); if (this.businessHourRenderer) { this.businessHourRenderer.unrender(); } }; // Event Displaying // ----------------------------------------------------------------------------------------------------------------- DateComponent.prototype.executeEventRender = function (eventsPayload) { if (this.eventRenderer) { this.eventRenderer.rangeUpdated(); // poorly named now this.eventRenderer.render(eventsPayload); } else if (this['renderEvents']) { // legacy this['renderEvents'](convertEventsPayloadToLegacyArray(eventsPayload)); } this.callChildren('executeEventRender', arguments); }; DateComponent.prototype.executeEventUnrender = function () { this.callChildren('executeEventUnrender', arguments); if (this.eventRenderer) { this.eventRenderer.unrender(); } else if (this['destroyEvents']) { // legacy this['destroyEvents'](); } }; DateComponent.prototype.getBusinessHourSegs = function () { var segs = this.getOwnBusinessHourSegs(); this.iterChildren(function (child) { segs.push.apply(segs, child.getBusinessHourSegs()); }); return segs; }; DateComponent.prototype.getOwnBusinessHourSegs = function () { if (this.businessHourRenderer) { return this.businessHourRenderer.getSegs(); } return []; }; DateComponent.prototype.getEventSegs = function () { var segs = this.getOwnEventSegs(); this.iterChildren(function (child) { segs.push.apply(segs, child.getEventSegs()); }); return segs; }; DateComponent.prototype.getOwnEventSegs = function () { if (this.eventRenderer) { return this.eventRenderer.getSegs(); } return []; }; // Event Rendering Triggering // ----------------------------------------------------------------------------------------------------------------- DateComponent.prototype.triggerAfterEventsRendered = function () { this.triggerAfterEventSegsRendered(this.getEventSegs()); this.publiclyTrigger('eventAfterAllRender', { context: this, args: [this] }); }; DateComponent.prototype.triggerAfterEventSegsRendered = function (segs) { var _this = this; // an optimization, because getEventLegacy is expensive if (this.hasPublicHandlers('eventAfterRender')) { segs.forEach(function (seg) { var legacy; if (seg.el) { // necessary? legacy = seg.footprint.getEventLegacy(); _this.publiclyTrigger('eventAfterRender', { context: legacy, args: [legacy, seg.el, _this] }); } }); } }; DateComponent.prototype.triggerBeforeEventsDestroyed = function () { this.triggerBeforeEventSegsDestroyed(this.getEventSegs()); }; DateComponent.prototype.triggerBeforeEventSegsDestroyed = function (segs) { var _this = this; if (this.hasPublicHandlers('eventDestroy')) { segs.forEach(function (seg) { var legacy; if (seg.el) { // necessary? legacy = seg.footprint.getEventLegacy(); _this.publiclyTrigger('eventDestroy', { context: legacy, args: [legacy, seg.el, _this] }); } }); } }; // Event Rendering Utils // ----------------------------------------------------------------------------------------------------------------- // Hides all rendered event segments linked to the given event // RECURSIVE with subcomponents DateComponent.prototype.showEventsWithId = function (eventDefId) { this.getEventSegs().forEach(function (seg) { if (seg.footprint.eventDef.id === eventDefId && seg.el // necessary? ) { seg.el.css('visibility', ''); } }); this.callChildren('showEventsWithId', arguments); }; // Shows all rendered event segments linked to the given event // RECURSIVE with subcomponents DateComponent.prototype.hideEventsWithId = function (eventDefId) { this.getEventSegs().forEach(function (seg) { if (seg.footprint.eventDef.id === eventDefId && seg.el // necessary? ) { seg.el.css('visibility', 'hidden'); } }); this.callChildren('hideEventsWithId', arguments); }; // Drag-n-Drop Rendering (for both events and external elements) // --------------------------------------------------------------------------------------------------------------- // Renders a visual indication of a event or external-element drag over the given drop zone. // If an external-element, seg will be `null`. // Must return elements used for any mock events. DateComponent.prototype.renderDrag = function (eventFootprints, seg, isTouch) { var renderedHelper = false; this.iterChildren(function (child) { if (child.renderDrag(eventFootprints, seg, isTouch)) { renderedHelper = true; } }); return renderedHelper; }; // Unrenders a visual indication of an event or external-element being dragged. DateComponent.prototype.unrenderDrag = function () { this.callChildren('unrenderDrag', arguments); }; // Event Resizing // --------------------------------------------------------------------------------------------------------------- // Renders a visual indication of an event being resized. DateComponent.prototype.renderEventResize = function (eventFootprints, seg, isTouch) { this.callChildren('renderEventResize', arguments); }; // Unrenders a visual indication of an event being resized. DateComponent.prototype.unrenderEventResize = function () { this.callChildren('unrenderEventResize', arguments); }; // Selection // --------------------------------------------------------------------------------------------------------------- // Renders a visual indication of the selection // TODO: rename to `renderSelection` after legacy is gone DateComponent.prototype.renderSelectionFootprint = function (componentFootprint) { this.renderHighlight(componentFootprint); this.callChildren('renderSelectionFootprint', arguments); }; // Unrenders a visual indication of selection DateComponent.prototype.unrenderSelection = function () { this.unrenderHighlight(); this.callChildren('unrenderSelection', arguments); }; // Highlight // --------------------------------------------------------------------------------------------------------------- // Renders an emphasis on the given date range. Given a span (unzoned start/end and other misc data) DateComponent.prototype.renderHighlight = function (componentFootprint) { if (this.fillRenderer) { this.fillRenderer.renderFootprint('highlight', componentFootprint, { getClasses: function () { return ['fc-highlight']; } }); } this.callChildren('renderHighlight', arguments); }; // Unrenders the emphasis on a date range DateComponent.prototype.unrenderHighlight = function () { if (this.fillRenderer) { this.fillRenderer.unrender('highlight'); } this.callChildren('unrenderHighlight', arguments); }; // Hit Areas // --------------------------------------------------------------------------------------------------------------- // just because all DateComponents support this interface // doesn't mean they need to have their own internal coord system. they can defer to sub-components. DateComponent.prototype.hitsNeeded = function () { if (!(this.hitsNeededDepth++)) { this.prepareHits(); } this.callChildren('hitsNeeded', arguments); }; DateComponent.prototype.hitsNotNeeded = function () { if (this.hitsNeededDepth && !(--this.hitsNeededDepth)) { this.releaseHits(); } this.callChildren('hitsNotNeeded', arguments); }; DateComponent.prototype.prepareHits = function () { // subclasses can implement }; DateComponent.prototype.releaseHits = function () { // subclasses can implement }; // Given coordinates from the topleft of the document, return data about the date-related area underneath. // Can return an object with arbitrary properties (although top/right/left/bottom are encouraged). // Must have a `grid` property, a reference to this current grid. TODO: avoid this // The returned object will be processed by getHitFootprint and getHitEl. DateComponent.prototype.queryHit = function (leftOffset, topOffset) { var childrenByUid = this.childrenByUid; var uid; var hit; for (uid in childrenByUid) { hit = childrenByUid[uid].queryHit(leftOffset, topOffset); if (hit) { break; } } return hit; }; DateComponent.prototype.getSafeHitFootprint = function (hit) { var footprint = this.getHitFootprint(hit); if (!this.dateProfile.activeUnzonedRange.containsRange(footprint.unzonedRange)) { return null; } return footprint; }; DateComponent.prototype.getHitFootprint = function (hit) { // what about being abstract!? }; // Given position-level information about a date-related area within the grid, // should return a jQuery element that best represents it. passed to dayClick callback. DateComponent.prototype.getHitEl = function (hit) { // what about being abstract!? }; /* Converting eventRange -> eventFootprint ------------------------------------------------------------------------------------------------------------------*/ DateComponent.prototype.eventRangesToEventFootprints = function (eventRanges) { var eventFootprints = []; var i; for (i = 0; i < eventRanges.length; i++) { eventFootprints.push.apply(// append eventFootprints, this.eventRangeToEventFootprints(eventRanges[i])); } return eventFootprints; }; DateComponent.prototype.eventRangeToEventFootprints = function (eventRange) { return [util_2.eventRangeToEventFootprint(eventRange)]; }; /* Converting componentFootprint/eventFootprint -> segs ------------------------------------------------------------------------------------------------------------------*/ DateComponent.prototype.eventFootprintsToSegs = function (eventFootprints) { var segs = []; var i; for (i = 0; i < eventFootprints.length; i++) { segs.push.apply(segs, this.eventFootprintToSegs(eventFootprints[i])); } return segs; }; // Given an event's span (unzoned start/end and other misc data), and the event itself, // slices into segments and attaches event-derived properties to them. // eventSpan - { start, end, isStart, isEnd, otherthings... } DateComponent.prototype.eventFootprintToSegs = function (eventFootprint) { var unzonedRange = eventFootprint.componentFootprint.unzonedRange; var segs; var i; var seg; segs = this.componentFootprintToSegs(eventFootprint.componentFootprint); for (i = 0; i < segs.length; i++) { seg = segs[i]; if (!unzonedRange.isStart) { seg.isStart = false; } if (!unzonedRange.isEnd) { seg.isEnd = false; } seg.footprint = eventFootprint; // TODO: rename to seg.eventFootprint } return segs; }; DateComponent.prototype.componentFootprintToSegs = function (componentFootprint) { return []; }; // Utils // --------------------------------------------------------------------------------------------------------------- DateComponent.prototype.callChildren = function (methodName, args) { this.iterChildren(function (child) { child[methodName].apply(child, args); }); }; DateComponent.prototype.iterChildren = function (func) { var childrenByUid = this.childrenByUid; var uid; for (uid in childrenByUid) { func(childrenByUid[uid]); } }; DateComponent.prototype._getCalendar = function () { var t = this; return t.calendar || t.view.calendar; }; DateComponent.prototype._getView = function () { return this.view; }; DateComponent.prototype._getDateProfile = function () { return this._getView().get('dateProfile'); }; // Generates HTML for an anchor to another view into the calendar. // Will either generate an <a> tag or a non-clickable <span> tag, depending on enabled settings. // `gotoOptions` can either be a moment input, or an object with the form: // { date, type, forceOff } // `type` is a view-type like "day" or "week". default value is "day". // `attrs` and `innerHtml` are use to generate the rest of the HTML tag. DateComponent.prototype.buildGotoAnchorHtml = function (gotoOptions, attrs, innerHtml) { var date; var type; var forceOff; var finalOptions; if ($.isPlainObject(gotoOptions)) { date = gotoOptions.date; type = gotoOptions.type; forceOff = gotoOptions.forceOff; } else { date = gotoOptions; // a single moment input } date = moment_ext_1.default(date); // if a string, parse it finalOptions = { date: date.format('YYYY-MM-DD'), type: type || 'day' }; if (typeof attrs === 'string') { innerHtml = attrs; attrs = null; } attrs = attrs ? ' ' + util_1.attrsToStr(attrs) : ''; // will have a leading space innerHtml = innerHtml || ''; if (!forceOff && this.opt('navLinks')) { return '<a' + attrs + ' data-goto="' + util_1.htmlEscape(JSON.stringify(finalOptions)) + '">' + innerHtml + '</a>'; } else { return '<span' + attrs + '>' + innerHtml + '</span>'; } }; DateComponent.prototype.getAllDayHtml = function () { return this.opt('allDayHtml') || util_1.htmlEscape(this.opt('allDayText')); }; // Computes HTML classNames for a single-day element DateComponent.prototype.getDayClasses = function (date, noThemeHighlight) { var view = this._getView(); var classes = []; var today; if (!this.dateProfile.activeUnzonedRange.containsDate(date)) { classes.push('fc-disabled-day'); // TODO: jQuery UI theme? } else { classes.push('fc-' + util_1.dayIDs[date.day()]); if (view.isDateInOtherMonth(date, this.dateProfile)) { // TODO: use DateComponent subclass somehow classes.push('fc-other-month'); } today = view.calendar.getNow(); if (date.isSame(today, 'day')) { classes.push('fc-today'); if (noThemeHighlight !== true) { classes.push(view.calendar.theme.getClass('today')); } } else if (date < today) { classes.push('fc-past'); } else { classes.push('fc-future'); } } return classes; }; // Utility for formatting a range. Accepts a range object, formatting string, and optional separator. // Displays all-day ranges naturally, with an inclusive end. Takes the current isRTL into account. // The timezones of the dates within `range` will be respected. DateComponent.prototype.formatRange = function (range, isAllDay, formatStr, separator) { var end = range.end; if (isAllDay) { end = end.clone().subtract(1); // convert to inclusive. last ms of previous day } return date_formatting_1.formatRange(range.start, end, formatStr, separator, this.isRTL); }; // Compute the number of the give units in the "current" range. // Will return a floating-point number. Won't round. DateComponent.prototype.currentRangeAs = function (unit) { return this._getDateProfile().currentUnzonedRange.as(unit); }; // Returns the date range of the full days the given range visually appears to occupy. // Returns a plain object with start/end, NOT an UnzonedRange! DateComponent.prototype.computeDayRange = function (unzonedRange) { var calendar = this._getCalendar(); var startDay = calendar.msToUtcMoment(unzonedRange.startMs, true); // the beginning of the day the range starts var end = calendar.msToUtcMoment(unzonedRange.endMs); var endTimeMS = +end.time(); // # of milliseconds into `endDay` var endDay = end.clone().stripTime(); // the beginning of the day the range exclusively ends // If the end time is actually inclusively part of the next day and is equal to or // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`. // Otherwise, leaving it as inclusive will cause it to exclude `endDay`. if (endTimeMS && endTimeMS >= this.nextDayThreshold) { endDay.add(1, 'days'); } // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day. if (endDay <= startDay) { endDay = startDay.clone().add(1, 'days'); } return { start: startDay, end: endDay }; }; // Does the given range visually appear to occupy more than one day? DateComponent.prototype.isMultiDayRange = function (unzonedRange) { var dayRange = this.computeDayRange(unzonedRange); return dayRange.end.diff(dayRange.start, 'days') > 1; }; DateComponent.guid = 0; // TODO: better system for this? return DateComponent; }(Component_1.default)); exports.default = DateComponent; // legacy function convertEventsPayloadToLegacyArray(eventsPayload) { var eventDefId; var eventInstances; var legacyEvents = []; var i; for (eventDefId in eventsPayload) { eventInstances = eventsPayload[eventDefId].eventInstances; for (i = 0; i < eventInstances.length; i++) { legacyEvents.push(eventInstances[i].toLegacy()); } } return legacyEvents; } /***/ }), /* 232 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var $ = __webpack_require__(3); var moment = __webpack_require__(0); var util_1 = __webpack_require__(4); var options_1 = __webpack_require__(33); var Iterator_1 = __webpack_require__(225); var GlobalEmitter_1 = __webpack_require__(23); var EmitterMixin_1 = __webpack_require__(13); var ListenerMixin_1 = __webpack_require__(7); var Toolbar_1 = __webpack_require__(257); var OptionsManager_1 = __webpack_require__(258); var ViewSpecManager_1 = __webpack_require__(259); var Constraints_1 = __webpack_require__(217); var locale_1 = __webpack_require__(32); var moment_ext_1 = __webpack_require__(11); var UnzonedRange_1 = __webpack_require__(5); var ComponentFootprint_1 = __webpack_require__(12); var EventDateProfile_1 = __webpack_require__(16); var EventManager_1 = __webpack_require__(220); var BusinessHourGenerator_1 = __webpack_require__(218); var EventSourceParser_1 = __webpack_require__(38); var EventDefParser_1 = __webpack_require__(36); var SingleEventDef_1 = __webpack_require__(9); var EventDefMutation_1 = __webpack_require__(39); var EventSource_1 = __webpack_require__(6); var ThemeRegistry_1 = __webpack_require__(57); var Calendar = /** @class */ (function () { function Calendar(el, overrides) { this.loadingLevel = 0; // number of simultaneous loading tasks this.ignoreUpdateViewSize = 0; this.freezeContentHeightDepth = 0; // declare the current calendar instance relies on GlobalEmitter. needed for garbage collection. // unneeded() is called in destroy. GlobalEmitter_1.default.needed(); this.el = el; this.viewsByType = {}; this.optionsManager = new OptionsManager_1.default(this, overrides); this.viewSpecManager = new ViewSpecManager_1.default(this.optionsManager, this); this.initMomentInternals(); // needs to happen after options hash initialized this.initCurrentDate(); this.initEventManager(); this.constraints = new Constraints_1.default(this.eventManager, this); this.constructed(); } Calendar.prototype.constructed = function () { // useful for monkeypatching. used? }; Calendar.prototype.getView = function () { return this.view; }; Calendar.prototype.publiclyTrigger = function (name, triggerInfo) { var optHandler = this.opt(name); var context; var args; if ($.isPlainObject(triggerInfo)) { context = triggerInfo.context; args = triggerInfo.args; } else if ($.isArray(triggerInfo)) { args = triggerInfo; } if (context == null) { context = this.el[0]; // fallback context } if (!args) { args = []; } this.triggerWith(name, context, args); // Emitter's method if (optHandler) { return optHandler.apply(context, args); } }; Calendar.prototype.hasPublicHandlers = function (name) { return this.hasHandlers(name) || this.opt(name); // handler specified in options }; // Options Public API // ----------------------------------------------------------------------------------------------------------------- // public getter/setter Calendar.prototype.option = function (name, value) { var newOptionHash; if (typeof name === 'string') { if (value === undefined) { // getter return this.optionsManager.get(name); } else { // setter for individual option newOptionHash = {}; newOptionHash[name] = value; this.optionsManager.add(newOptionHash); } } else if (typeof name === 'object') { // compound setter with object input this.optionsManager.add(name); } }; // private getter Calendar.prototype.opt = function (name) { return this.optionsManager.get(name); }; // View // ----------------------------------------------------------------------------------------------------------------- // Given a view name for a custom view or a standard view, creates a ready-to-go View object Calendar.prototype.instantiateView = function (viewType) { var spec = this.viewSpecManager.getViewSpec(viewType); if (!spec) { throw new Error("View type \"" + viewType + "\" is not valid"); } return new spec['class'](this, spec); }; // Returns a boolean about whether the view is okay to instantiate at some point Calendar.prototype.isValidViewType = function (viewType) { return Boolean(this.viewSpecManager.getViewSpec(viewType)); }; Calendar.prototype.changeView = function (viewName, dateOrRange) { if (dateOrRange) { if (dateOrRange.start && dateOrRange.end) { // a range this.optionsManager.recordOverrides({ visibleRange: dateOrRange }); } else { // a date this.currentDate = this.moment(dateOrRange).stripZone(); // just like gotoDate } } this.renderView(viewName); }; // Forces navigation to a view for the given date. // `viewType` can be a specific view name or a generic one like "week" or "day". Calendar.prototype.zoomTo = function (newDate, viewType) { var spec; viewType = viewType || 'day'; // day is default zoom spec = this.viewSpecManager.getViewSpec(viewType) || this.viewSpecManager.getUnitViewSpec(viewType); this.currentDate = newDate.clone(); this.renderView(spec ? spec.type : null); }; // Current Date // ----------------------------------------------------------------------------------------------------------------- Calendar.prototype.initCurrentDate = function () { var defaultDateInput = this.opt('defaultDate'); // compute the initial ambig-timezone date if (defaultDateInput != null) { this.currentDate = this.moment(defaultDateInput).stripZone(); } else { this.currentDate = this.getNow(); // getNow already returns unzoned } }; Calendar.prototype.prev = function () { var view = this.view; var prevInfo = view.dateProfileGenerator.buildPrev(view.get('dateProfile')); if (prevInfo.isValid) { this.currentDate = prevInfo.date; this.renderView(); } }; Calendar.prototype.next = function () { var view = this.view; var nextInfo = view.dateProfileGenerator.buildNext(view.get('dateProfile')); if (nextInfo.isValid) { this.currentDate = nextInfo.date; this.renderView(); } }; Calendar.prototype.prevYear = function () { this.currentDate.add(-1, 'years'); this.renderView(); }; Calendar.prototype.nextYear = function () { this.currentDate.add(1, 'years'); this.renderView(); }; Calendar.prototype.today = function () { this.currentDate = this.getNow(); // should deny like prev/next? this.renderView(); }; Calendar.prototype.gotoDate = function (zonedDateInput) { this.currentDate = this.moment(zonedDateInput).stripZone(); this.renderView(); }; Calendar.prototype.incrementDate = function (delta) { this.currentDate.add(moment.duration(delta)); this.renderView(); }; // for external API Calendar.prototype.getDate = function () { return this.applyTimezone(this.currentDate); // infuse the calendar's timezone }; // Loading Triggering // ----------------------------------------------------------------------------------------------------------------- // Should be called when any type of async data fetching begins Calendar.prototype.pushLoading = function () { if (!(this.loadingLevel++)) { this.publiclyTrigger('loading', [true, this.view]); } }; // Should be called when any type of async data fetching completes Calendar.prototype.popLoading = function () { if (!(--this.loadingLevel)) { this.publiclyTrigger('loading', [false, this.view]); } }; // High-level Rendering // ----------------------------------------------------------------------------------- Calendar.prototype.render = function () { if (!this.contentEl) { this.initialRender(); } else if (this.elementVisible()) { // mainly for the public API this.calcSize(); this.updateViewSize(); } }; Calendar.prototype.initialRender = function () { var _this = this; var el = this.el; el.addClass('fc'); // event delegation for nav links el.on('click.fc', 'a[data-goto]', function (ev) { var anchorEl = $(ev.currentTarget); var gotoOptions = anchorEl.data('goto'); // will automatically parse JSON var date = _this.moment(gotoOptions.date); var viewType = gotoOptions.type; // property like "navLinkDayClick". might be a string or a function var customAction = _this.view.opt('navLink' + util_1.capitaliseFirstLetter(viewType) + 'Click'); if (typeof customAction === 'function') { customAction(date, ev); } else { if (typeof customAction === 'string') { viewType = customAction; } _this.zoomTo(date, viewType); } }); // called immediately, and upon option change this.optionsManager.watch('settingTheme', ['?theme', '?themeSystem'], function (opts) { var themeClass = ThemeRegistry_1.getThemeSystemClass(opts.themeSystem || opts.theme); var theme = new themeClass(_this.optionsManager); var widgetClass = theme.getClass('widget'); _this.theme = theme; if (widgetClass) { el.addClass(widgetClass); } }, function () { var widgetClass = _this.theme.getClass('widget'); _this.theme = null; if (widgetClass) { el.removeClass(widgetClass); } }); this.optionsManager.watch('settingBusinessHourGenerator', ['?businessHours'], function (deps) { _this.businessHourGenerator = new BusinessHourGenerator_1.default(deps.businessHours, _this); if (_this.view) { _this.view.set('businessHourGenerator', _this.businessHourGenerator); } }, function () { _this.businessHourGenerator = null; }); // called immediately, and upon option change. // HACK: locale often affects isRTL, so we explicitly listen to that too. this.optionsManager.watch('applyingDirClasses', ['?isRTL', '?locale'], function (opts) { el.toggleClass('fc-ltr', !opts.isRTL); el.toggleClass('fc-rtl', opts.isRTL); }); this.contentEl = $("<div class='fc-view-container'/>").prependTo(el); this.initToolbars(); this.renderHeader(); this.renderFooter(); this.renderView(this.opt('defaultView')); if (this.opt('handleWindowResize')) { $(window).resize(this.windowResizeProxy = util_1.debounce(// prevents rapid calls this.windowResize.bind(this), this.opt('windowResizeDelay'))); } }; Calendar.prototype.destroy = function () { if (this.view) { this.clearView(); } this.toolbarsManager.proxyCall('removeElement'); this.contentEl.remove(); this.el.removeClass('fc fc-ltr fc-rtl'); // removes theme-related root className this.optionsManager.unwatch('settingTheme'); this.optionsManager.unwatch('settingBusinessHourGenerator'); this.el.off('.fc'); // unbind nav link handlers if (this.windowResizeProxy) { $(window).unbind('resize', this.windowResizeProxy); this.windowResizeProxy = null; } GlobalEmitter_1.default.unneeded(); }; Calendar.prototype.elementVisible = function () { return this.el.is(':visible'); }; // Render Queue // ----------------------------------------------------------------------------------------------------------------- Calendar.prototype.bindViewHandlers = function (view) { var _this = this; view.watch('titleForCalendar', ['title'], function (deps) { if (view === _this.view) { // hack _this.setToolbarsTitle(deps.title); } }); view.watch('dateProfileForCalendar', ['dateProfile'], function (deps) { if (view === _this.view) { // hack _this.currentDate = deps.dateProfile.date; // might have been constrained by view dates _this.updateToolbarButtons(deps.dateProfile); } }); }; Calendar.prototype.unbindViewHandlers = function (view) { view.unwatch('titleForCalendar'); view.unwatch('dateProfileForCalendar'); }; // View Rendering // ----------------------------------------------------------------------------------- // Renders a view because of a date change, view-type change, or for the first time. // If not given a viewType, keep the current view but render different dates. // Accepts an optional scroll state to restore to. Calendar.prototype.renderView = function (viewType) { var oldView = this.view; var newView; this.freezeContentHeight(); if (oldView && viewType && oldView.type !== viewType) { this.clearView(); } // if viewType changed, or the view was never created, create a fresh view if (!this.view && viewType) { newView = this.view = this.viewsByType[viewType] || (this.viewsByType[viewType] = this.instantiateView(viewType)); this.bindViewHandlers(newView); newView.startBatchRender(); // so that setElement+setDate rendering are joined newView.setElement($("<div class='fc-view fc-" + viewType + "-view' />").appendTo(this.contentEl)); this.toolbarsManager.proxyCall('activateButton', viewType); } if (this.view) { // prevent unnecessary change firing if (this.view.get('businessHourGenerator') !== this.businessHourGenerator) { this.view.set('businessHourGenerator', this.businessHourGenerator); } this.view.setDate(this.currentDate); if (newView) { newView.stopBatchRender(); } } this.thawContentHeight(); }; // Unrenders the current view and reflects this change in the Header. // Unregsiters the `view`, but does not remove from viewByType hash. Calendar.prototype.clearView = function () { var currentView = this.view; this.toolbarsManager.proxyCall('deactivateButton', currentView.type); this.unbindViewHandlers(currentView); currentView.removeElement(); currentView.unsetDate(); // so bindViewHandlers doesn't fire with old values next time this.view = null; }; // Destroys the view, including the view object. Then, re-instantiates it and renders it. // Maintains the same scroll state. // TODO: maintain any other user-manipulated state. Calendar.prototype.reinitView = function () { var oldView = this.view; var scroll = oldView.queryScroll(); // wouldn't be so complicated if Calendar owned the scroll this.freezeContentHeight(); this.clearView(); this.calcSize(); this.renderView(oldView.type); // needs the type to freshly render this.view.applyScroll(scroll); this.thawContentHeight(); }; // Resizing // ----------------------------------------------------------------------------------- Calendar.prototype.getSuggestedViewHeight = function () { if (this.suggestedViewHeight == null) { this.calcSize(); } return this.suggestedViewHeight; }; Calendar.prototype.isHeightAuto = function () { return this.opt('contentHeight') === 'auto' || this.opt('height') === 'auto'; }; Calendar.prototype.updateViewSize = function (isResize) { if (isResize === void 0) { isResize = false; } var view = this.view; var scroll; if (!this.ignoreUpdateViewSize && view) { if (isResize) { this.calcSize(); scroll = view.queryScroll(); } this.ignoreUpdateViewSize++; view.updateSize(this.getSuggestedViewHeight(), this.isHeightAuto(), isResize); this.ignoreUpdateViewSize--; if (isResize) { view.applyScroll(scroll); } return true; // signal success } }; Calendar.prototype.calcSize = function () { if (this.elementVisible()) { this._calcSize(); } }; Calendar.prototype._calcSize = function () { var contentHeightInput = this.opt('contentHeight'); var heightInput = this.opt('height'); if (typeof contentHeightInput === 'number') { // exists and not 'auto' this.suggestedViewHeight = contentHeightInput; } else if (typeof contentHeightInput === 'function') { // exists and is a function this.suggestedViewHeight = contentHeightInput(); } else if (typeof heightInput === 'number') { // exists and not 'auto' this.suggestedViewHeight = heightInput - this.queryToolbarsHeight(); } else if (typeof heightInput === 'function') { // exists and is a function this.suggestedViewHeight = heightInput() - this.queryToolbarsHeight(); } else if (heightInput === 'parent') { // set to height of parent element this.suggestedViewHeight = this.el.parent().height() - this.queryToolbarsHeight(); } else { this.suggestedViewHeight = Math.round(this.contentEl.width() / Math.max(this.opt('aspectRatio'), .5)); } }; Calendar.prototype.windowResize = function (ev) { if ( // the purpose: so we don't process jqui "resize" events that have bubbled up // cast to any because .target, which is Element, can't be compared to window for some reason. ev.target === window && this.view && this.view.isDatesRendered) { if (this.updateViewSize(true)) { // isResize=true, returns true on success this.publiclyTrigger('windowResize', [this.view]); } } }; /* Height "Freezing" -----------------------------------------------------------------------------*/ Calendar.prototype.freezeContentHeight = function () { if (!(this.freezeContentHeightDepth++)) { this.forceFreezeContentHeight(); } }; Calendar.prototype.forceFreezeContentHeight = function () { this.contentEl.css({ width: '100%', height: this.contentEl.height(), overflow: 'hidden' }); }; Calendar.prototype.thawContentHeight = function () { this.freezeContentHeightDepth--; // always bring back to natural height this.contentEl.css({ width: '', height: '', overflow: '' }); // but if there are future thaws, re-freeze if (this.freezeContentHeightDepth) { this.forceFreezeContentHeight(); } }; // Toolbar // ----------------------------------------------------------------------------------------------------------------- Calendar.prototype.initToolbars = function () { this.header = new Toolbar_1.default(this, this.computeHeaderOptions()); this.footer = new Toolbar_1.default(this, this.computeFooterOptions()); this.toolbarsManager = new Iterator_1.default([this.header, this.footer]); }; Calendar.prototype.computeHeaderOptions = function () { return { extraClasses: 'fc-header-toolbar', layout: this.opt('header') }; }; Calendar.prototype.computeFooterOptions = function () { return { extraClasses: 'fc-footer-toolbar', layout: this.opt('footer') }; }; // can be called repeatedly and Header will rerender Calendar.prototype.renderHeader = function () { var header = this.header; header.setToolbarOptions(this.computeHeaderOptions()); header.render(); if (header.el) { this.el.prepend(header.el); } }; // can be called repeatedly and Footer will rerender Calendar.prototype.renderFooter = function () { var footer = this.footer; footer.setToolbarOptions(this.computeFooterOptions()); footer.render(); if (footer.el) { this.el.append(footer.el); } }; Calendar.prototype.setToolbarsTitle = function (title) { this.toolbarsManager.proxyCall('updateTitle', title); }; Calendar.prototype.updateToolbarButtons = function (dateProfile) { var now = this.getNow(); var view = this.view; var todayInfo = view.dateProfileGenerator.build(now); var prevInfo = view.dateProfileGenerator.buildPrev(view.get('dateProfile')); var nextInfo = view.dateProfileGenerator.buildNext(view.get('dateProfile')); this.toolbarsManager.proxyCall((todayInfo.isValid && !dateProfile.currentUnzonedRange.containsDate(now)) ? 'enableButton' : 'disableButton', 'today'); this.toolbarsManager.proxyCall(prevInfo.isValid ? 'enableButton' : 'disableButton', 'prev'); this.toolbarsManager.proxyCall(nextInfo.isValid ? 'enableButton' : 'disableButton', 'next'); }; Calendar.prototype.queryToolbarsHeight = function () { return this.toolbarsManager.items.reduce(function (accumulator, toolbar) { var toolbarHeight = toolbar.el ? toolbar.el.outerHeight(true) : 0; // includes margin return accumulator + toolbarHeight; }, 0); }; // Selection // ----------------------------------------------------------------------------------------------------------------- // this public method receives start/end dates in any format, with any timezone Calendar.prototype.select = function (zonedStartInput, zonedEndInput) { this.view.select(this.buildSelectFootprint.apply(this, arguments)); }; Calendar.prototype.unselect = function () { if (this.view) { this.view.unselect(); } }; // Given arguments to the select method in the API, returns a span (unzoned start/end and other info) Calendar.prototype.buildSelectFootprint = function (zonedStartInput, zonedEndInput) { var start = this.moment(zonedStartInput).stripZone(); var end; if (zonedEndInput) { end = this.moment(zonedEndInput).stripZone(); } else if (start.hasTime()) { end = start.clone().add(this.defaultTimedEventDuration); } else { end = start.clone().add(this.defaultAllDayEventDuration); } return new ComponentFootprint_1.default(new UnzonedRange_1.default(start, end), !start.hasTime()); }; // Date Utils // ----------------------------------------------------------------------------------------------------------------- Calendar.prototype.initMomentInternals = function () { var _this = this; this.defaultAllDayEventDuration = moment.duration(this.opt('defaultAllDayEventDuration')); this.defaultTimedEventDuration = moment.duration(this.opt('defaultTimedEventDuration')); // Called immediately, and when any of the options change. // Happens before any internal objects rebuild or rerender, because this is very core. this.optionsManager.watch('buildingMomentLocale', [ '?locale', '?monthNames', '?monthNamesShort', '?dayNames', '?dayNamesShort', '?firstDay', '?weekNumberCalculation' ], function (opts) { var weekNumberCalculation = opts.weekNumberCalculation; var firstDay = opts.firstDay; var _week; // normalize if (weekNumberCalculation === 'iso') { weekNumberCalculation = 'ISO'; // normalize } var localeData = Object.create(// make a cheap copy locale_1.getMomentLocaleData(opts.locale) // will fall back to en ); if (opts.monthNames) { localeData._months = opts.monthNames; } if (opts.monthNamesShort) { localeData._monthsShort = opts.monthNamesShort; } if (opts.dayNames) { localeData._weekdays = opts.dayNames; } if (opts.dayNamesShort) { localeData._weekdaysShort = opts.dayNamesShort; } if (firstDay == null && weekNumberCalculation === 'ISO') { firstDay = 1; } if (firstDay != null) { _week = Object.create(localeData._week); // _week: { dow: # } _week.dow = firstDay; localeData._week = _week; } if ( // whitelist certain kinds of input weekNumberCalculation === 'ISO' || weekNumberCalculation === 'local' || typeof weekNumberCalculation === 'function') { localeData._fullCalendar_weekCalc = weekNumberCalculation; // moment-ext will know what to do with it } _this.localeData = localeData; // If the internal current date object already exists, move to new locale. // We do NOT need to do this technique for event dates, because this happens when converting to "segments". if (_this.currentDate) { _this.localizeMoment(_this.currentDate); // sets to localeData } }); }; // Builds a moment using the settings of the current calendar: timezone and locale. // Accepts anything the vanilla moment() constructor accepts. Calendar.prototype.moment = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var mom; if (this.opt('timezone') === 'local') { mom = moment_ext_1.default.apply(null, args); // Force the moment to be local, because momentExt doesn't guarantee it. if (mom.hasTime()) { // don't give ambiguously-timed moments a local zone mom.local(); } } else if (this.opt('timezone') === 'UTC') { mom = moment_ext_1.default.utc.apply(null, args); // process as UTC } else { mom = moment_ext_1.default.parseZone.apply(null, args); // let the input decide the zone } this.localizeMoment(mom); // TODO return mom; }; Calendar.prototype.msToMoment = function (ms, forceAllDay) { var mom = moment_ext_1.default.utc(ms); // TODO: optimize by using Date.UTC if (forceAllDay) { mom.stripTime(); } else { mom = this.applyTimezone(mom); // may or may not apply locale } this.localizeMoment(mom); return mom; }; Calendar.prototype.msToUtcMoment = function (ms, forceAllDay) { var mom = moment_ext_1.default.utc(ms); // TODO: optimize by using Date.UTC if (forceAllDay) { mom.stripTime(); } this.localizeMoment(mom); return mom; }; // Updates the given moment's locale settings to the current calendar locale settings. Calendar.prototype.localizeMoment = function (mom) { mom._locale = this.localeData; }; // Returns a boolean about whether or not the calendar knows how to calculate // the timezone offset of arbitrary dates in the current timezone. Calendar.prototype.getIsAmbigTimezone = function () { return this.opt('timezone') !== 'local' && this.opt('timezone') !== 'UTC'; }; // Returns a copy of the given date in the current timezone. Has no effect on dates without times. Calendar.prototype.applyTimezone = function (date) { if (!date.hasTime()) { return date.clone(); } var zonedDate = this.moment(date.toArray()); var timeAdjust = date.time().asMilliseconds() - zonedDate.time().asMilliseconds(); var adjustedZonedDate; // Safari sometimes has problems with this coersion when near DST. Adjust if necessary. (bug #2396) if (timeAdjust) { // is the time result different than expected? adjustedZonedDate = zonedDate.clone().add(timeAdjust); // add milliseconds if (date.time().asMilliseconds() - adjustedZonedDate.time().asMilliseconds() === 0) { // does it match perfectly now? zonedDate = adjustedZonedDate; } } return zonedDate; }; /* Assumes the footprint is non-open-ended. */ Calendar.prototype.footprintToDateProfile = function (componentFootprint, ignoreEnd) { if (ignoreEnd === void 0) { ignoreEnd = false; } var start = moment_ext_1.default.utc(componentFootprint.unzonedRange.startMs); var end; if (!ignoreEnd) { end = moment_ext_1.default.utc(componentFootprint.unzonedRange.endMs); } if (componentFootprint.isAllDay) { start.stripTime(); if (end) { end.stripTime(); } } else { start = this.applyTimezone(start); if (end) { end = this.applyTimezone(end); } } this.localizeMoment(start); if (end) { this.localizeMoment(end); } return new EventDateProfile_1.default(start, end, this); }; // Returns a moment for the current date, as defined by the client's computer or from the `now` option. // Will return an moment with an ambiguous timezone. Calendar.prototype.getNow = function () { var now = this.opt('now'); if (typeof now === 'function') { now = now(); } return this.moment(now).stripZone(); }; // Produces a human-readable string for the given duration. // Side-effect: changes the locale of the given duration. Calendar.prototype.humanizeDuration = function (duration) { return duration.locale(this.opt('locale')).humanize(); }; // will return `null` if invalid range Calendar.prototype.parseUnzonedRange = function (rangeInput) { var start = null; var end = null; if (rangeInput.start) { start = this.moment(rangeInput.start).stripZone(); } if (rangeInput.end) { end = this.moment(rangeInput.end).stripZone(); } if (!start && !end) { return null; } if (start && end && end.isBefore(start)) { return null; } return new UnzonedRange_1.default(start, end); }; // Event-Date Utilities // ----------------------------------------------------------------------------------------------------------------- Calendar.prototype.initEventManager = function () { var _this = this; var eventManager = new EventManager_1.default(this); var rawSources = this.opt('eventSources') || []; var singleRawSource = this.opt('events'); this.eventManager = eventManager; if (singleRawSource) { rawSources.unshift(singleRawSource); } eventManager.on('release', function (eventsPayload) { _this.trigger('eventsReset', eventsPayload); }); eventManager.freeze(); rawSources.forEach(function (rawSource) { var source = EventSourceParser_1.default.parse(rawSource, _this); if (source) { eventManager.addSource(source); } }); eventManager.thaw(); }; Calendar.prototype.requestEvents = function (start, end) { return this.eventManager.requestEvents(start, end, this.opt('timezone'), !this.opt('lazyFetching')); }; // Get an event's normalized end date. If not present, calculate it from the defaults. Calendar.prototype.getEventEnd = function (event) { if (event.end) { return event.end.clone(); } else { return this.getDefaultEventEnd(event.allDay, event.start); } }; // Given an event's allDay status and start date, return what its fallback end date should be. // TODO: rename to computeDefaultEventEnd Calendar.prototype.getDefaultEventEnd = function (allDay, zonedStart) { var end = zonedStart.clone(); if (allDay) { end.stripTime().add(this.defaultAllDayEventDuration); } else { end.add(this.defaultTimedEventDuration); } if (this.getIsAmbigTimezone()) { end.stripZone(); // we don't know what the tzo should be } return end; }; // Public Events API // ----------------------------------------------------------------------------------------------------------------- Calendar.prototype.rerenderEvents = function () { this.view.flash('displayingEvents'); }; Calendar.prototype.refetchEvents = function () { this.eventManager.refetchAllSources(); }; Calendar.prototype.renderEvents = function (eventInputs, isSticky) { this.eventManager.freeze(); for (var i = 0; i < eventInputs.length; i++) { this.renderEvent(eventInputs[i], isSticky); } this.eventManager.thaw(); }; Calendar.prototype.renderEvent = function (eventInput, isSticky) { if (isSticky === void 0) { isSticky = false; } var eventManager = this.eventManager; var eventDef = EventDefParser_1.default.parse(eventInput, eventInput.source || eventManager.stickySource); if (eventDef) { eventManager.addEventDef(eventDef, isSticky); } }; // legacyQuery operates on legacy event instance objects Calendar.prototype.removeEvents = function (legacyQuery) { var eventManager = this.eventManager; var legacyInstances = []; var idMap = {}; var eventDef; var i; if (legacyQuery == null) { // shortcut for removing all eventManager.removeAllEventDefs(); // persist=true } else { eventManager.getEventInstances().forEach(function (eventInstance) { legacyInstances.push(eventInstance.toLegacy()); }); legacyInstances = filterLegacyEventInstances(legacyInstances, legacyQuery); // compute unique IDs for (i = 0; i < legacyInstances.length; i++) { eventDef = this.eventManager.getEventDefByUid(legacyInstances[i]._id); idMap[eventDef.id] = true; } eventManager.freeze(); for (i in idMap) { // reuse `i` as an "id" eventManager.removeEventDefsById(i); // persist=true } eventManager.thaw(); } }; // legacyQuery operates on legacy event instance objects Calendar.prototype.clientEvents = function (legacyQuery) { var legacyEventInstances = []; this.eventManager.getEventInstances().forEach(function (eventInstance) { legacyEventInstances.push(eventInstance.toLegacy()); }); return filterLegacyEventInstances(legacyEventInstances, legacyQuery); }; Calendar.prototype.updateEvents = function (eventPropsArray) { this.eventManager.freeze(); for (var i = 0; i < eventPropsArray.length; i++) { this.updateEvent(eventPropsArray[i]); } this.eventManager.thaw(); }; Calendar.prototype.updateEvent = function (eventProps) { var eventDef = this.eventManager.getEventDefByUid(eventProps._id); var eventInstance; var eventDefMutation; if (eventDef instanceof SingleEventDef_1.default) { eventInstance = eventDef.buildInstance(); eventDefMutation = EventDefMutation_1.default.createFromRawProps(eventInstance, eventProps, // raw props null // largeUnit -- who uses it? ); this.eventManager.mutateEventsWithId(eventDef.id, eventDefMutation); // will release } }; // Public Event Sources API // ------------------------------------------------------------------------------------ Calendar.prototype.getEventSources = function () { return this.eventManager.otherSources.slice(); // clone }; Calendar.prototype.getEventSourceById = function (id) { return this.eventManager.getSourceById(EventSource_1.default.normalizeId(id)); }; Calendar.prototype.addEventSource = function (sourceInput) { var source = EventSourceParser_1.default.parse(sourceInput, this); if (source) { this.eventManager.addSource(source); } }; Calendar.prototype.removeEventSources = function (sourceMultiQuery) { var eventManager = this.eventManager; var sources; var i; if (sourceMultiQuery == null) { this.eventManager.removeAllSources(); } else { sources = eventManager.multiQuerySources(sourceMultiQuery); eventManager.freeze(); for (i = 0; i < sources.length; i++) { eventManager.removeSource(sources[i]); } eventManager.thaw(); } }; Calendar.prototype.removeEventSource = function (sourceQuery) { var eventManager = this.eventManager; var sources = eventManager.querySources(sourceQuery); var i; eventManager.freeze(); for (i = 0; i < sources.length; i++) { eventManager.removeSource(sources[i]); } eventManager.thaw(); }; Calendar.prototype.refetchEventSources = function (sourceMultiQuery) { var eventManager = this.eventManager; var sources = eventManager.multiQuerySources(sourceMultiQuery); var i; eventManager.freeze(); for (i = 0; i < sources.length; i++) { eventManager.refetchSource(sources[i]); } eventManager.thaw(); }; // not for internal use. use options module directly instead. Calendar.defaults = options_1.globalDefaults; Calendar.englishDefaults = options_1.englishDefaults; Calendar.rtlDefaults = options_1.rtlDefaults; return Calendar; }()); exports.default = Calendar; EmitterMixin_1.default.mixInto(Calendar); ListenerMixin_1.default.mixInto(Calendar); function filterLegacyEventInstances(legacyEventInstances, legacyQuery) { if (legacyQuery == null) { return legacyEventInstances; } else if ($.isFunction(legacyQuery)) { return legacyEventInstances.filter(legacyQuery); } else { // an event ID legacyQuery += ''; // normalize to string return legacyEventInstances.filter(function (legacyEventInstance) { // soft comparison because id not be normalized to string // tslint:disable-next-line return legacyEventInstance.id == legacyQuery || legacyEventInstance._id === legacyQuery; // can specify internal id, but must exactly match }); } } /***/ }), /* 233 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var moment = __webpack_require__(0); var exportHooks = __webpack_require__(18); var util_1 = __webpack_require__(4); var moment_ext_1 = __webpack_require__(11); var ListenerMixin_1 = __webpack_require__(7); var HitDragListener_1 = __webpack_require__(17); var SingleEventDef_1 = __webpack_require__(9); var EventInstanceGroup_1 = __webpack_require__(20); var EventSource_1 = __webpack_require__(6); var Interaction_1 = __webpack_require__(14); var ExternalDropping = /** @class */ (function (_super) { tslib_1.__extends(ExternalDropping, _super); function ExternalDropping() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.isDragging = false; // jqui-dragging an external element? boolean return _this; } /* component impements: - eventRangesToEventFootprints - isEventInstanceGroupAllowed - isExternalInstanceGroupAllowed - renderDrag - unrenderDrag */ ExternalDropping.prototype.end = function () { if (this.dragListener) { this.dragListener.endInteraction(); } }; ExternalDropping.prototype.bindToDocument = function () { this.listenTo($(document), { dragstart: this.handleDragStart, sortstart: this.handleDragStart // jqui }); }; ExternalDropping.prototype.unbindFromDocument = function () { this.stopListeningTo($(document)); }; // Called when a jQuery UI drag is initiated anywhere in the DOM ExternalDropping.prototype.handleDragStart = function (ev, ui) { var el; var accept; if (this.opt('droppable')) { // only listen if this setting is on el = $((ui ? ui.item : null) || ev.target); // Test that the dragged element passes the dropAccept selector or filter function. // FYI, the default is "*" (matches all) accept = this.opt('dropAccept'); if ($.isFunction(accept) ? accept.call(el[0], el) : el.is(accept)) { if (!this.isDragging) { // prevent double-listening if fired twice this.listenToExternalDrag(el, ev, ui); } } } }; // Called when a jQuery UI drag starts and it needs to be monitored for dropping ExternalDropping.prototype.listenToExternalDrag = function (el, ev, ui) { var _this = this; var component = this.component; var view = this.view; var meta = getDraggedElMeta(el); // extra data about event drop, including possible event to create var singleEventDef; // a null value signals an unsuccessful drag // listener that tracks mouse movement over date-associated pixel regions var dragListener = this.dragListener = new HitDragListener_1.default(component, { interactionStart: function () { _this.isDragging = true; }, hitOver: function (hit) { var isAllowed = true; var hitFootprint = hit.component.getSafeHitFootprint(hit); // hit might not belong to this grid var mutatedEventInstanceGroup; if (hitFootprint) { singleEventDef = _this.computeExternalDrop(hitFootprint, meta); if (singleEventDef) { mutatedEventInstanceGroup = new EventInstanceGroup_1.default(singleEventDef.buildInstances()); isAllowed = meta.eventProps ? // isEvent? component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup) : component.isExternalInstanceGroupAllowed(mutatedEventInstanceGroup); } else { isAllowed = false; } } else { isAllowed = false; } if (!isAllowed) { singleEventDef = null; util_1.disableCursor(); } if (singleEventDef) { component.renderDrag(// called without a seg parameter component.eventRangesToEventFootprints(mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, view.calendar))); } }, hitOut: function () { singleEventDef = null; // signal unsuccessful }, hitDone: function () { util_1.enableCursor(); component.unrenderDrag(); }, interactionEnd: function (ev) { if (singleEventDef) { // element was dropped on a valid hit view.reportExternalDrop(singleEventDef, Boolean(meta.eventProps), // isEvent Boolean(meta.stick), // isSticky el, ev, ui); } _this.isDragging = false; _this.dragListener = null; } }); dragListener.startDrag(ev); // start listening immediately }; // Given a hit to be dropped upon, and misc data associated with the jqui drag (guaranteed to be a plain object), // returns the zoned start/end dates for the event that would result from the hypothetical drop. end might be null. // Returning a null value signals an invalid drop hit. // DOES NOT consider overlap/constraint. // Assumes both footprints are non-open-ended. ExternalDropping.prototype.computeExternalDrop = function (componentFootprint, meta) { var calendar = this.view.calendar; var start = moment_ext_1.default.utc(componentFootprint.unzonedRange.startMs).stripZone(); var end; var eventDef; if (componentFootprint.isAllDay) { // if dropped on an all-day span, and element's metadata specified a time, set it if (meta.startTime) { start.time(meta.startTime); } else { start.stripTime(); } } if (meta.duration) { end = start.clone().add(meta.duration); } start = calendar.applyTimezone(start); if (end) { end = calendar.applyTimezone(end); } eventDef = SingleEventDef_1.default.parse($.extend({}, meta.eventProps, { start: start, end: end }), new EventSource_1.default(calendar)); return eventDef; }; return ExternalDropping; }(Interaction_1.default)); exports.default = ExternalDropping; ListenerMixin_1.default.mixInto(ExternalDropping); /* External-Dragging-Element Data ----------------------------------------------------------------------------------------------------------------------*/ // Require all HTML5 data-* attributes used by FullCalendar to have this prefix. // A value of '' will query attributes like data-event. A value of 'fc' will query attributes like data-fc-event. exportHooks.dataAttrPrefix = ''; // Given a jQuery element that might represent a dragged FullCalendar event, returns an intermediate data structure // to be used for Event Object creation. // A defined `.eventProps`, even when empty, indicates that an event should be created. function getDraggedElMeta(el) { var prefix = exportHooks.dataAttrPrefix; var eventProps; // properties for creating the event, not related to date/time var startTime; // a Duration var duration; var stick; if (prefix) { prefix += '-'; } eventProps = el.data(prefix + 'event') || null; if (eventProps) { if (typeof eventProps === 'object') { eventProps = $.extend({}, eventProps); // make a copy } else { // something like 1 or true. still signal event creation eventProps = {}; } // pluck special-cased date/time properties startTime = eventProps.start; if (startTime == null) { startTime = eventProps.time; } // accept 'time' as well duration = eventProps.duration; stick = eventProps.stick; delete eventProps.start; delete eventProps.time; delete eventProps.duration; delete eventProps.stick; } // fallback to standalone attribute values for each of the date/time properties if (startTime == null) { startTime = el.data(prefix + 'start'); } if (startTime == null) { startTime = el.data(prefix + 'time'); } // accept 'time' as well if (duration == null) { duration = el.data(prefix + 'duration'); } if (stick == null) { stick = el.data(prefix + 'stick'); } // massage into correct data types startTime = startTime != null ? moment.duration(startTime) : null; duration = duration != null ? moment.duration(duration) : null; stick = Boolean(stick); return { eventProps: eventProps, startTime: startTime, duration: duration, stick: stick }; } /***/ }), /* 234 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var EventDefMutation_1 = __webpack_require__(39); var EventDefDateMutation_1 = __webpack_require__(40); var HitDragListener_1 = __webpack_require__(17); var Interaction_1 = __webpack_require__(14); var EventResizing = /** @class */ (function (_super) { tslib_1.__extends(EventResizing, _super); /* component impements: - bindSegHandlerToEl - publiclyTrigger - diffDates - eventRangesToEventFootprints - isEventInstanceGroupAllowed - getSafeHitFootprint */ function EventResizing(component, eventPointing) { var _this = _super.call(this, component) || this; _this.isResizing = false; _this.eventPointing = eventPointing; return _this; } EventResizing.prototype.end = function () { if (this.dragListener) { this.dragListener.endInteraction(); } }; EventResizing.prototype.bindToEl = function (el) { var component = this.component; component.bindSegHandlerToEl(el, 'mousedown', this.handleMouseDown.bind(this)); component.bindSegHandlerToEl(el, 'touchstart', this.handleTouchStart.bind(this)); }; EventResizing.prototype.handleMouseDown = function (seg, ev) { if (this.component.canStartResize(seg, ev)) { this.buildDragListener(seg, $(ev.target).is('.fc-start-resizer')) .startInteraction(ev, { distance: 5 }); } }; EventResizing.prototype.handleTouchStart = function (seg, ev) { if (this.component.canStartResize(seg, ev)) { this.buildDragListener(seg, $(ev.target).is('.fc-start-resizer')) .startInteraction(ev); } }; // Creates a listener that tracks the user as they resize an event segment. // Generic enough to work with any type of Grid. EventResizing.prototype.buildDragListener = function (seg, isStart) { var _this = this; var component = this.component; var view = this.view; var calendar = view.calendar; var eventManager = calendar.eventManager; var el = seg.el; var eventDef = seg.footprint.eventDef; var eventInstance = seg.footprint.eventInstance; var isDragging; var resizeMutation; // zoned event date properties. falsy if invalid resize // Tracks mouse movement over the *grid's* coordinate map var dragListener = this.dragListener = new HitDragListener_1.default(component, { scroll: this.opt('dragScroll'), subjectEl: el, interactionStart: function () { isDragging = false; }, dragStart: function (ev) { isDragging = true; // ensure a mouseout on the manipulated event has been reported _this.eventPointing.handleMouseout(seg, ev); _this.segResizeStart(seg, ev); }, hitOver: function (hit, isOrig, origHit) { var isAllowed = true; var origHitFootprint = component.getSafeHitFootprint(origHit); var hitFootprint = component.getSafeHitFootprint(hit); var mutatedEventInstanceGroup; if (origHitFootprint && hitFootprint) { resizeMutation = isStart ? _this.computeEventStartResizeMutation(origHitFootprint, hitFootprint, seg.footprint) : _this.computeEventEndResizeMutation(origHitFootprint, hitFootprint, seg.footprint); if (resizeMutation) { mutatedEventInstanceGroup = eventManager.buildMutatedEventInstanceGroup(eventDef.id, resizeMutation); isAllowed = component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup); } else { isAllowed = false; } } else { isAllowed = false; } if (!isAllowed) { resizeMutation = null; util_1.disableCursor(); } else if (resizeMutation.isEmpty()) { // no change. (FYI, event dates might have zones) resizeMutation = null; } if (resizeMutation) { view.hideEventsWithId(seg.footprint.eventDef.id); view.renderEventResize(component.eventRangesToEventFootprints(mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, calendar)), seg); } }, hitOut: function () { resizeMutation = null; }, hitDone: function () { view.unrenderEventResize(seg); view.showEventsWithId(seg.footprint.eventDef.id); util_1.enableCursor(); }, interactionEnd: function (ev) { if (isDragging) { _this.segResizeStop(seg, ev); } if (resizeMutation) { // valid date to resize to? // no need to re-show original, will rerender all anyways. esp important if eventRenderWait view.reportEventResize(eventInstance, resizeMutation, el, ev); } _this.dragListener = null; } }); return dragListener; }; // Called before event segment resizing starts EventResizing.prototype.segResizeStart = function (seg, ev) { this.isResizing = true; this.component.publiclyTrigger('eventResizeStart', { context: seg.el[0], args: [ seg.footprint.getEventLegacy(), ev, {}, this.view ] }); }; // Called after event segment resizing stops EventResizing.prototype.segResizeStop = function (seg, ev) { this.isResizing = false; this.component.publiclyTrigger('eventResizeStop', { context: seg.el[0], args: [ seg.footprint.getEventLegacy(), ev, {}, this.view ] }); }; // Returns new date-information for an event segment being resized from its start EventResizing.prototype.computeEventStartResizeMutation = function (startFootprint, endFootprint, origEventFootprint) { var origRange = origEventFootprint.componentFootprint.unzonedRange; var startDelta = this.component.diffDates(endFootprint.unzonedRange.getStart(), startFootprint.unzonedRange.getStart()); var dateMutation; var eventDefMutation; if (origRange.getStart().add(startDelta) < origRange.getEnd()) { dateMutation = new EventDefDateMutation_1.default(); dateMutation.setStartDelta(startDelta); eventDefMutation = new EventDefMutation_1.default(); eventDefMutation.setDateMutation(dateMutation); return eventDefMutation; } return false; }; // Returns new date-information for an event segment being resized from its end EventResizing.prototype.computeEventEndResizeMutation = function (startFootprint, endFootprint, origEventFootprint) { var origRange = origEventFootprint.componentFootprint.unzonedRange; var endDelta = this.component.diffDates(endFootprint.unzonedRange.getEnd(), startFootprint.unzonedRange.getEnd()); var dateMutation; var eventDefMutation; if (origRange.getEnd().add(endDelta) > origRange.getStart()) { dateMutation = new EventDefDateMutation_1.default(); dateMutation.setEndDelta(endDelta); eventDefMutation = new EventDefMutation_1.default(); eventDefMutation.setDateMutation(dateMutation); return eventDefMutation; } return false; }; return EventResizing; }(Interaction_1.default)); exports.default = EventResizing; /***/ }), /* 235 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var util_1 = __webpack_require__(4); var EventDefMutation_1 = __webpack_require__(39); var EventDefDateMutation_1 = __webpack_require__(40); var DragListener_1 = __webpack_require__(59); var HitDragListener_1 = __webpack_require__(17); var MouseFollower_1 = __webpack_require__(226); var Interaction_1 = __webpack_require__(14); var EventDragging = /** @class */ (function (_super) { tslib_1.__extends(EventDragging, _super); /* component implements: - bindSegHandlerToEl - publiclyTrigger - diffDates - eventRangesToEventFootprints - isEventInstanceGroupAllowed */ function EventDragging(component, eventPointing) { var _this = _super.call(this, component) || this; _this.isDragging = false; _this.eventPointing = eventPointing; return _this; } EventDragging.prototype.end = function () { if (this.dragListener) { this.dragListener.endInteraction(); } }; EventDragging.prototype.getSelectionDelay = function () { var delay = this.opt('eventLongPressDelay'); if (delay == null) { delay = this.opt('longPressDelay'); // fallback } return delay; }; EventDragging.prototype.bindToEl = function (el) { var component = this.component; component.bindSegHandlerToEl(el, 'mousedown', this.handleMousedown.bind(this)); component.bindSegHandlerToEl(el, 'touchstart', this.handleTouchStart.bind(this)); }; EventDragging.prototype.handleMousedown = function (seg, ev) { if (!this.component.shouldIgnoreMouse() && this.component.canStartDrag(seg, ev)) { this.buildDragListener(seg).startInteraction(ev, { distance: 5 }); } }; EventDragging.prototype.handleTouchStart = function (seg, ev) { var component = this.component; var settings = { delay: this.view.isEventDefSelected(seg.footprint.eventDef) ? // already selected? 0 : this.getSelectionDelay() }; if (component.canStartDrag(seg, ev)) { this.buildDragListener(seg).startInteraction(ev, settings); } else if (component.canStartSelection(seg, ev)) { this.buildSelectListener(seg).startInteraction(ev, settings); } }; // seg isn't draggable, but let's use a generic DragListener // simply for the delay, so it can be selected. // Has side effect of setting/unsetting `dragListener` EventDragging.prototype.buildSelectListener = function (seg) { var _this = this; var view = this.view; var eventDef = seg.footprint.eventDef; var eventInstance = seg.footprint.eventInstance; // null for inverse-background events if (this.dragListener) { return this.dragListener; } var dragListener = this.dragListener = new DragListener_1.default({ dragStart: function (ev) { if (dragListener.isTouch && !view.isEventDefSelected(eventDef) && eventInstance) { // if not previously selected, will fire after a delay. then, select the event view.selectEventInstance(eventInstance); } }, interactionEnd: function (ev) { _this.dragListener = null; } }); return dragListener; }; // Builds a listener that will track user-dragging on an event segment. // Generic enough to work with any type of Grid. // Has side effect of setting/unsetting `dragListener` EventDragging.prototype.buildDragListener = function (seg) { var _this = this; var component = this.component; var view = this.view; var calendar = view.calendar; var eventManager = calendar.eventManager; var el = seg.el; var eventDef = seg.footprint.eventDef; var eventInstance = seg.footprint.eventInstance; // null for inverse-background events var isDragging; var mouseFollower; // A clone of the original element that will move with the mouse var eventDefMutation; if (this.dragListener) { return this.dragListener; } // Tracks mouse movement over the *view's* coordinate map. Allows dragging and dropping between subcomponents // of the view. var dragListener = this.dragListener = new HitDragListener_1.default(view, { scroll: this.opt('dragScroll'), subjectEl: el, subjectCenter: true, interactionStart: function (ev) { seg.component = component; // for renderDrag isDragging = false; mouseFollower = new MouseFollower_1.default(seg.el, { additionalClass: 'fc-dragging', parentEl: view.el, opacity: dragListener.isTouch ? null : _this.opt('dragOpacity'), revertDuration: _this.opt('dragRevertDuration'), zIndex: 2 // one above the .fc-view }); mouseFollower.hide(); // don't show until we know this is a real drag mouseFollower.start(ev); }, dragStart: function (ev) { if (dragListener.isTouch && !view.isEventDefSelected(eventDef) && eventInstance) { // if not previously selected, will fire after a delay. then, select the event view.selectEventInstance(eventInstance); } isDragging = true; // ensure a mouseout on the manipulated event has been reported _this.eventPointing.handleMouseout(seg, ev); _this.segDragStart(seg, ev); view.hideEventsWithId(seg.footprint.eventDef.id); }, hitOver: function (hit, isOrig, origHit) { var isAllowed = true; var origFootprint; var footprint; var mutatedEventInstanceGroup; // starting hit could be forced (DayGrid.limit) if (seg.hit) { origHit = seg.hit; } // hit might not belong to this grid, so query origin grid origFootprint = origHit.component.getSafeHitFootprint(origHit); footprint = hit.component.getSafeHitFootprint(hit); if (origFootprint && footprint) { eventDefMutation = _this.computeEventDropMutation(origFootprint, footprint, eventDef); if (eventDefMutation) { mutatedEventInstanceGroup = eventManager.buildMutatedEventInstanceGroup(eventDef.id, eventDefMutation); isAllowed = component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup); } else { isAllowed = false; } } else { isAllowed = false; } if (!isAllowed) { eventDefMutation = null; util_1.disableCursor(); } // if a valid drop location, have the subclass render a visual indication if (eventDefMutation && view.renderDrag(// truthy if rendered something component.eventRangesToEventFootprints(mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, calendar)), seg, dragListener.isTouch)) { mouseFollower.hide(); // if the subclass is already using a mock event "helper", hide our own } else { mouseFollower.show(); // otherwise, have the helper follow the mouse (no snapping) } if (isOrig) { // needs to have moved hits to be a valid drop eventDefMutation = null; } }, hitOut: function () { view.unrenderDrag(seg); // unrender whatever was done in renderDrag mouseFollower.show(); // show in case we are moving out of all hits eventDefMutation = null; }, hitDone: function () { util_1.enableCursor(); }, interactionEnd: function (ev) { delete seg.component; // prevent side effects // do revert animation if hasn't changed. calls a callback when finished (whether animation or not) mouseFollower.stop(!eventDefMutation, function () { if (isDragging) { view.unrenderDrag(seg); _this.segDragStop(seg, ev); } view.showEventsWithId(seg.footprint.eventDef.id); if (eventDefMutation) { // no need to re-show original, will rerender all anyways. esp important if eventRenderWait view.reportEventDrop(eventInstance, eventDefMutation, el, ev); } }); _this.dragListener = null; } }); return dragListener; }; // Called before event segment dragging starts EventDragging.prototype.segDragStart = function (seg, ev) { this.isDragging = true; this.component.publiclyTrigger('eventDragStart', { context: seg.el[0], args: [ seg.footprint.getEventLegacy(), ev, {}, this.view ] }); }; // Called after event segment dragging stops EventDragging.prototype.segDragStop = function (seg, ev) { this.isDragging = false; this.component.publiclyTrigger('eventDragStop', { context: seg.el[0], args: [ seg.footprint.getEventLegacy(), ev, {}, this.view ] }); }; // DOES NOT consider overlap/constraint EventDragging.prototype.computeEventDropMutation = function (startFootprint, endFootprint, eventDef) { var eventDefMutation = new EventDefMutation_1.default(); eventDefMutation.setDateMutation(this.computeEventDateMutation(startFootprint, endFootprint)); return eventDefMutation; }; EventDragging.prototype.computeEventDateMutation = function (startFootprint, endFootprint) { var date0 = startFootprint.unzonedRange.getStart(); var date1 = endFootprint.unzonedRange.getStart(); var clearEnd = false; var forceTimed = false; var forceAllDay = false; var dateDelta; var dateMutation; if (startFootprint.isAllDay !== endFootprint.isAllDay) { clearEnd = true; if (endFootprint.isAllDay) { forceAllDay = true; date0.stripTime(); } else { forceTimed = true; } } dateDelta = this.component.diffDates(date1, date0); dateMutation = new EventDefDateMutation_1.default(); dateMutation.clearEnd = clearEnd; dateMutation.forceTimed = forceTimed; dateMutation.forceAllDay = forceAllDay; dateMutation.setDateDelta(dateDelta); return dateMutation; }; return EventDragging; }(Interaction_1.default)); exports.default = EventDragging; /***/ }), /* 236 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var util_1 = __webpack_require__(4); var HitDragListener_1 = __webpack_require__(17); var ComponentFootprint_1 = __webpack_require__(12); var UnzonedRange_1 = __webpack_require__(5); var Interaction_1 = __webpack_require__(14); var DateSelecting = /** @class */ (function (_super) { tslib_1.__extends(DateSelecting, _super); /* component must implement: - bindDateHandlerToEl - getSafeHitFootprint - renderHighlight - unrenderHighlight */ function DateSelecting(component) { var _this = _super.call(this, component) || this; _this.dragListener = _this.buildDragListener(); return _this; } DateSelecting.prototype.end = function () { this.dragListener.endInteraction(); }; DateSelecting.prototype.getDelay = function () { var delay = this.opt('selectLongPressDelay'); if (delay == null) { delay = this.opt('longPressDelay'); // fallback } return delay; }; DateSelecting.prototype.bindToEl = function (el) { var _this = this; var component = this.component; var dragListener = this.dragListener; component.bindDateHandlerToEl(el, 'mousedown', function (ev) { if (_this.opt('selectable') && !component.shouldIgnoreMouse()) { dragListener.startInteraction(ev, { distance: _this.opt('selectMinDistance') }); } }); component.bindDateHandlerToEl(el, 'touchstart', function (ev) { if (_this.opt('selectable') && !component.shouldIgnoreTouch()) { dragListener.startInteraction(ev, { delay: _this.getDelay() }); } }); util_1.preventSelection(el); }; // Creates a listener that tracks the user's drag across day elements, for day selecting. DateSelecting.prototype.buildDragListener = function () { var _this = this; var component = this.component; var selectionFootprint; // null if invalid selection var dragListener = new HitDragListener_1.default(component, { scroll: this.opt('dragScroll'), interactionStart: function () { selectionFootprint = null; }, dragStart: function (ev) { _this.view.unselect(ev); // since we could be rendering a new selection, we want to clear any old one }, hitOver: function (hit, isOrig, origHit) { var origHitFootprint; var hitFootprint; if (origHit) { // click needs to have started on a hit origHitFootprint = component.getSafeHitFootprint(origHit); hitFootprint = component.getSafeHitFootprint(hit); if (origHitFootprint && hitFootprint) { selectionFootprint = _this.computeSelection(origHitFootprint, hitFootprint); } else { selectionFootprint = null; } if (selectionFootprint) { component.renderSelectionFootprint(selectionFootprint); } else if (selectionFootprint === false) { util_1.disableCursor(); } } }, hitOut: function () { selectionFootprint = null; component.unrenderSelection(); }, hitDone: function () { util_1.enableCursor(); }, interactionEnd: function (ev, isCancelled) { if (!isCancelled && selectionFootprint) { // the selection will already have been rendered. just report it _this.view.reportSelection(selectionFootprint, ev); } } }); return dragListener; }; // Given the first and last date-spans of a selection, returns another date-span object. // Subclasses can override and provide additional data in the span object. Will be passed to renderSelectionFootprint(). // Will return false if the selection is invalid and this should be indicated to the user. // Will return null/undefined if a selection invalid but no error should be reported. DateSelecting.prototype.computeSelection = function (footprint0, footprint1) { var wholeFootprint = this.computeSelectionFootprint(footprint0, footprint1); if (wholeFootprint && !this.isSelectionFootprintAllowed(wholeFootprint)) { return false; } return wholeFootprint; }; // Given two spans, must return the combination of the two. // TODO: do this separation of concerns (combining VS validation) for event dnd/resize too. // Assumes both footprints are non-open-ended. DateSelecting.prototype.computeSelectionFootprint = function (footprint0, footprint1) { var ms = [ footprint0.unzonedRange.startMs, footprint0.unzonedRange.endMs, footprint1.unzonedRange.startMs, footprint1.unzonedRange.endMs ]; ms.sort(util_1.compareNumbers); return new ComponentFootprint_1.default(new UnzonedRange_1.default(ms[0], ms[3]), footprint0.isAllDay); }; DateSelecting.prototype.isSelectionFootprintAllowed = function (componentFootprint) { return this.component.dateProfile.validUnzonedRange.containsRange(componentFootprint.unzonedRange) && this.view.calendar.constraints.isSelectionFootprintAllowed(componentFootprint); }; return DateSelecting; }(Interaction_1.default)); exports.default = DateSelecting; /***/ }), /* 237 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var HitDragListener_1 = __webpack_require__(17); var Interaction_1 = __webpack_require__(14); var DateClicking = /** @class */ (function (_super) { tslib_1.__extends(DateClicking, _super); /* component must implement: - bindDateHandlerToEl - getSafeHitFootprint - getHitEl */ function DateClicking(component) { var _this = _super.call(this, component) || this; _this.dragListener = _this.buildDragListener(); return _this; } DateClicking.prototype.end = function () { this.dragListener.endInteraction(); }; DateClicking.prototype.bindToEl = function (el) { var component = this.component; var dragListener = this.dragListener; component.bindDateHandlerToEl(el, 'mousedown', function (ev) { if (!component.shouldIgnoreMouse()) { dragListener.startInteraction(ev); } }); component.bindDateHandlerToEl(el, 'touchstart', function (ev) { if (!component.shouldIgnoreTouch()) { dragListener.startInteraction(ev); } }); }; // Creates a listener that tracks the user's drag across day elements, for day clicking. DateClicking.prototype.buildDragListener = function () { var _this = this; var component = this.component; var dayClickHit; // null if invalid dayClick var dragListener = new HitDragListener_1.default(component, { scroll: this.opt('dragScroll'), interactionStart: function () { dayClickHit = dragListener.origHit; }, hitOver: function (hit, isOrig, origHit) { // if user dragged to another cell at any point, it can no longer be a dayClick if (!isOrig) { dayClickHit = null; } }, hitOut: function () { dayClickHit = null; }, interactionEnd: function (ev, isCancelled) { var componentFootprint; if (!isCancelled && dayClickHit) { componentFootprint = component.getSafeHitFootprint(dayClickHit); if (componentFootprint) { _this.view.triggerDayClick(componentFootprint, component.getHitEl(dayClickHit), ev); } } } }); // because dragListener won't be called with any time delay, "dragging" will begin immediately, // which will kill any touchmoving/scrolling. Prevent this. dragListener.shouldCancelTouchScroll = false; dragListener.scrollAlwaysKills = true; return dragListener; }; return DateClicking; }(Interaction_1.default)); exports.default = DateClicking; /***/ }), /* 238 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var moment = __webpack_require__(0); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var Scroller_1 = __webpack_require__(41); var View_1 = __webpack_require__(43); var TimeGrid_1 = __webpack_require__(239); var DayGrid_1 = __webpack_require__(66); var AGENDA_ALL_DAY_EVENT_LIMIT = 5; var agendaTimeGridMethods; var agendaDayGridMethods; /* An abstract class for all agenda-related views. Displays one more columns with time slots running vertically. ----------------------------------------------------------------------------------------------------------------------*/ // Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on). // Responsible for managing width/height. var AgendaView = /** @class */ (function (_super) { tslib_1.__extends(AgendaView, _super); function AgendaView(calendar, viewSpec) { var _this = _super.call(this, calendar, viewSpec) || this; _this.usesMinMaxTime = true; // indicates that minTime/maxTime affects rendering _this.timeGrid = _this.instantiateTimeGrid(); _this.addChild(_this.timeGrid); if (_this.opt('allDaySlot')) { // should we display the "all-day" area? _this.dayGrid = _this.instantiateDayGrid(); // the all-day subcomponent of this view _this.addChild(_this.dayGrid); } _this.scroller = new Scroller_1.default({ overflowX: 'hidden', overflowY: 'auto' }); return _this; } // Instantiates the TimeGrid object this view needs. Draws from this.timeGridClass AgendaView.prototype.instantiateTimeGrid = function () { var timeGrid = new this.timeGridClass(this); util_1.copyOwnProps(agendaTimeGridMethods, timeGrid); return timeGrid; }; // Instantiates the DayGrid object this view might need. Draws from this.dayGridClass AgendaView.prototype.instantiateDayGrid = function () { var dayGrid = new this.dayGridClass(this); util_1.copyOwnProps(agendaDayGridMethods, dayGrid); return dayGrid; }; /* Rendering ------------------------------------------------------------------------------------------------------------------*/ AgendaView.prototype.renderSkeleton = function () { var timeGridWrapEl; var timeGridEl; this.el.addClass('fc-agenda-view').html(this.renderSkeletonHtml()); this.scroller.render(); timeGridWrapEl = this.scroller.el.addClass('fc-time-grid-container'); timeGridEl = $('<div class="fc-time-grid" />').appendTo(timeGridWrapEl); this.el.find('.fc-body > tr > td').append(timeGridWrapEl); this.timeGrid.headContainerEl = this.el.find('.fc-head-container'); this.timeGrid.setElement(timeGridEl); if (this.dayGrid) { this.dayGrid.setElement(this.el.find('.fc-day-grid')); // have the day-grid extend it's coordinate area over the <hr> dividing the two grids this.dayGrid.bottomCoordPadding = this.dayGrid.el.next('hr').outerHeight(); } }; AgendaView.prototype.unrenderSkeleton = function () { this.timeGrid.removeElement(); if (this.dayGrid) { this.dayGrid.removeElement(); } this.scroller.destroy(); }; // Builds the HTML skeleton for the view. // The day-grid and time-grid components will render inside containers defined by this HTML. AgendaView.prototype.renderSkeletonHtml = function () { var theme = this.calendar.theme; return '' + '<table class="' + theme.getClass('tableGrid') + '">' + (this.opt('columnHeader') ? '<thead class="fc-head">' + '<tr>' + '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '"> </td>' + '</tr>' + '</thead>' : '') + '<tbody class="fc-body">' + '<tr>' + '<td class="' + theme.getClass('widgetContent') + '">' + (this.dayGrid ? '<div class="fc-day-grid"/>' + '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '"/>' : '') + '</td>' + '</tr>' + '</tbody>' + '</table>'; }; // Generates an HTML attribute string for setting the width of the axis, if it is known AgendaView.prototype.axisStyleAttr = function () { if (this.axisWidth != null) { return 'style="width:' + this.axisWidth + 'px"'; } return ''; }; /* Now Indicator ------------------------------------------------------------------------------------------------------------------*/ AgendaView.prototype.getNowIndicatorUnit = function () { return this.timeGrid.getNowIndicatorUnit(); }; /* Dimensions ------------------------------------------------------------------------------------------------------------------*/ // Adjusts the vertical dimensions of the view to the specified values AgendaView.prototype.updateSize = function (totalHeight, isAuto, isResize) { var eventLimit; var scrollerHeight; var scrollbarWidths; _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize); // make all axis cells line up, and record the width so newly created axis cells will have it this.axisWidth = util_1.matchCellWidths(this.el.find('.fc-axis')); // hack to give the view some height prior to timeGrid's columns being rendered // TODO: separate setting height from scroller VS timeGrid. if (!this.timeGrid.colEls) { if (!isAuto) { scrollerHeight = this.computeScrollerHeight(totalHeight); this.scroller.setHeight(scrollerHeight); } return; } // set of fake row elements that must compensate when scroller has scrollbars var noScrollRowEls = this.el.find('.fc-row:not(.fc-scroller *)'); // reset all dimensions back to the original state this.timeGrid.bottomRuleEl.hide(); // .show() will be called later if this <hr> is necessary this.scroller.clear(); // sets height to 'auto' and clears overflow util_1.uncompensateScroll(noScrollRowEls); // limit number of events in the all-day area if (this.dayGrid) { this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed eventLimit = this.opt('eventLimit'); if (eventLimit && typeof eventLimit !== 'number') { eventLimit = AGENDA_ALL_DAY_EVENT_LIMIT; // make sure "auto" goes to a real number } if (eventLimit) { this.dayGrid.limitRows(eventLimit); } } if (!isAuto) { // should we force dimensions of the scroll container? scrollerHeight = this.computeScrollerHeight(totalHeight); this.scroller.setHeight(scrollerHeight); scrollbarWidths = this.scroller.getScrollbarWidths(); if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars? // make the all-day and header rows lines up util_1.compensateScroll(noScrollRowEls, scrollbarWidths); // the scrollbar compensation might have changed text flow, which might affect height, so recalculate // and reapply the desired height to the scroller. scrollerHeight = this.computeScrollerHeight(totalHeight); this.scroller.setHeight(scrollerHeight); } // guarantees the same scrollbar widths this.scroller.lockOverflow(scrollbarWidths); // if there's any space below the slats, show the horizontal rule. // this won't cause any new overflow, because lockOverflow already called. if (this.timeGrid.getTotalSlatHeight() < scrollerHeight) { this.timeGrid.bottomRuleEl.show(); } } }; // given a desired total height of the view, returns what the height of the scroller should be AgendaView.prototype.computeScrollerHeight = function (totalHeight) { return totalHeight - util_1.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller }; /* Scroll ------------------------------------------------------------------------------------------------------------------*/ // Computes the initial pre-configured scroll state prior to allowing the user to change it AgendaView.prototype.computeInitialDateScroll = function () { var scrollTime = moment.duration(this.opt('scrollTime')); var top = this.timeGrid.computeTimeTop(scrollTime); // zoom can give weird floating-point values. rather scroll a little bit further top = Math.ceil(top); if (top) { top++; // to overcome top border that slots beyond the first have. looks better } return { top: top }; }; AgendaView.prototype.queryDateScroll = function () { return { top: this.scroller.getScrollTop() }; }; AgendaView.prototype.applyDateScroll = function (scroll) { if (scroll.top !== undefined) { this.scroller.setScrollTop(scroll.top); } }; /* Hit Areas ------------------------------------------------------------------------------------------------------------------*/ // forward all hit-related method calls to the grids (dayGrid might not be defined) AgendaView.prototype.getHitFootprint = function (hit) { // TODO: hit.component is set as a hack to identify where the hit came from return hit.component.getHitFootprint(hit); }; AgendaView.prototype.getHitEl = function (hit) { // TODO: hit.component is set as a hack to identify where the hit came from return hit.component.getHitEl(hit); }; /* Event Rendering ------------------------------------------------------------------------------------------------------------------*/ AgendaView.prototype.executeEventRender = function (eventsPayload) { var dayEventsPayload = {}; var timedEventsPayload = {}; var id; var eventInstanceGroup; // separate the events into all-day and timed for (id in eventsPayload) { eventInstanceGroup = eventsPayload[id]; if (eventInstanceGroup.getEventDef().isAllDay()) { dayEventsPayload[id] = eventInstanceGroup; } else { timedEventsPayload[id] = eventInstanceGroup; } } this.timeGrid.executeEventRender(timedEventsPayload); if (this.dayGrid) { this.dayGrid.executeEventRender(dayEventsPayload); } }; /* Dragging/Resizing Routing ------------------------------------------------------------------------------------------------------------------*/ // A returned value of `true` signals that a mock "helper" event has been rendered. AgendaView.prototype.renderDrag = function (eventFootprints, seg, isTouch) { var groups = groupEventFootprintsByAllDay(eventFootprints); var renderedHelper = false; renderedHelper = this.timeGrid.renderDrag(groups.timed, seg, isTouch); if (this.dayGrid) { renderedHelper = this.dayGrid.renderDrag(groups.allDay, seg, isTouch) || renderedHelper; } return renderedHelper; }; AgendaView.prototype.renderEventResize = function (eventFootprints, seg, isTouch) { var groups = groupEventFootprintsByAllDay(eventFootprints); this.timeGrid.renderEventResize(groups.timed, seg, isTouch); if (this.dayGrid) { this.dayGrid.renderEventResize(groups.allDay, seg, isTouch); } }; /* Selection ------------------------------------------------------------------------------------------------------------------*/ // Renders a visual indication of a selection AgendaView.prototype.renderSelectionFootprint = function (componentFootprint) { if (!componentFootprint.isAllDay) { this.timeGrid.renderSelectionFootprint(componentFootprint); } else if (this.dayGrid) { this.dayGrid.renderSelectionFootprint(componentFootprint); } }; return AgendaView; }(View_1.default)); exports.default = AgendaView; AgendaView.prototype.timeGridClass = TimeGrid_1.default; AgendaView.prototype.dayGridClass = DayGrid_1.default; // Will customize the rendering behavior of the AgendaView's timeGrid agendaTimeGridMethods = { // Generates the HTML that will go before the day-of week header cells renderHeadIntroHtml: function () { var view = this.view; var calendar = view.calendar; var weekStart = calendar.msToUtcMoment(this.dateProfile.renderUnzonedRange.startMs, true); var weekText; if (this.opt('weekNumbers')) { weekText = weekStart.format(this.opt('smallWeekFormat')); return '' + '<th class="fc-axis fc-week-number ' + calendar.theme.getClass('widgetHeader') + '" ' + view.axisStyleAttr() + '>' + view.buildGotoAnchorHtml(// aside from link, important for matchCellWidths { date: weekStart, type: 'week', forceOff: this.colCnt > 1 }, util_1.htmlEscape(weekText) // inner HTML ) + '</th>'; } else { return '<th class="fc-axis ' + calendar.theme.getClass('widgetHeader') + '" ' + view.axisStyleAttr() + '></th>'; } }, // Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column. renderBgIntroHtml: function () { var view = this.view; return '<td class="fc-axis ' + view.calendar.theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '></td>'; }, // Generates the HTML that goes before all other types of cells. // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid. renderIntroHtml: function () { var view = this.view; return '<td class="fc-axis" ' + view.axisStyleAttr() + '></td>'; } }; // Will customize the rendering behavior of the AgendaView's dayGrid agendaDayGridMethods = { // Generates the HTML that goes before the all-day cells renderBgIntroHtml: function () { var view = this.view; return '' + '<td class="fc-axis ' + view.calendar.theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '>' + '<span>' + // needed for matchCellWidths view.getAllDayHtml() + '</span>' + '</td>'; }, // Generates the HTML that goes before all other types of cells. // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid. renderIntroHtml: function () { var view = this.view; return '<td class="fc-axis" ' + view.axisStyleAttr() + '></td>'; } }; function groupEventFootprintsByAllDay(eventFootprints) { var allDay = []; var timed = []; var i; for (i = 0; i < eventFootprints.length; i++) { if (eventFootprints[i].componentFootprint.isAllDay) { allDay.push(eventFootprints[i]); } else { timed.push(eventFootprints[i]); } } return { allDay: allDay, timed: timed }; } /***/ }), /* 239 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var moment = __webpack_require__(0); var util_1 = __webpack_require__(4); var InteractiveDateComponent_1 = __webpack_require__(42); var BusinessHourRenderer_1 = __webpack_require__(61); var StandardInteractionsMixin_1 = __webpack_require__(65); var DayTableMixin_1 = __webpack_require__(60); var CoordCache_1 = __webpack_require__(58); var UnzonedRange_1 = __webpack_require__(5); var ComponentFootprint_1 = __webpack_require__(12); var TimeGridEventRenderer_1 = __webpack_require__(240); var TimeGridHelperRenderer_1 = __webpack_require__(241); var TimeGridFillRenderer_1 = __webpack_require__(242); /* A component that renders one or more columns of vertical time slots ----------------------------------------------------------------------------------------------------------------------*/ // We mixin DayTable, even though there is only a single row of days // potential nice values for the slot-duration and interval-duration // from largest to smallest var AGENDA_STOCK_SUB_DURATIONS = [ { hours: 1 }, { minutes: 30 }, { minutes: 15 }, { seconds: 30 }, { seconds: 15 } ]; var TimeGrid = /** @class */ (function (_super) { tslib_1.__extends(TimeGrid, _super); function TimeGrid(view) { var _this = _super.call(this, view) || this; _this.processOptions(); return _this; } // Slices up the given span (unzoned start/end with other misc data) into an array of segments TimeGrid.prototype.componentFootprintToSegs = function (componentFootprint) { var segs = this.sliceRangeByTimes(componentFootprint.unzonedRange); var i; for (i = 0; i < segs.length; i++) { if (this.isRTL) { segs[i].col = this.daysPerRow - 1 - segs[i].dayIndex; } else { segs[i].col = segs[i].dayIndex; } } return segs; }; /* Date Handling ------------------------------------------------------------------------------------------------------------------*/ TimeGrid.prototype.sliceRangeByTimes = function (unzonedRange) { var segs = []; var segRange; var dayIndex; for (dayIndex = 0; dayIndex < this.daysPerRow; dayIndex++) { segRange = unzonedRange.intersect(this.dayRanges[dayIndex]); if (segRange) { segs.push({ startMs: segRange.startMs, endMs: segRange.endMs, isStart: segRange.isStart, isEnd: segRange.isEnd, dayIndex: dayIndex }); } } return segs; }; /* Options ------------------------------------------------------------------------------------------------------------------*/ // Parses various options into properties of this object TimeGrid.prototype.processOptions = function () { var slotDuration = this.opt('slotDuration'); var snapDuration = this.opt('snapDuration'); var input; slotDuration = moment.duration(slotDuration); snapDuration = snapDuration ? moment.duration(snapDuration) : slotDuration; this.slotDuration = slotDuration; this.snapDuration = snapDuration; this.snapsPerSlot = slotDuration / snapDuration; // TODO: ensure an integer multiple? // might be an array value (for TimelineView). // if so, getting the most granular entry (the last one probably). input = this.opt('slotLabelFormat'); if ($.isArray(input)) { input = input[input.length - 1]; } this.labelFormat = input || this.opt('smallTimeFormat'); // the computed default input = this.opt('slotLabelInterval'); this.labelInterval = input ? moment.duration(input) : this.computeLabelInterval(slotDuration); }; // Computes an automatic value for slotLabelInterval TimeGrid.prototype.computeLabelInterval = function (slotDuration) { var i; var labelInterval; var slotsPerLabel; // find the smallest stock label interval that results in more than one slots-per-label for (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) { labelInterval = moment.duration(AGENDA_STOCK_SUB_DURATIONS[i]); slotsPerLabel = util_1.divideDurationByDuration(labelInterval, slotDuration); if (util_1.isInt(slotsPerLabel) && slotsPerLabel > 1) { return labelInterval; } } return moment.duration(slotDuration); // fall back. clone }; /* Date Rendering ------------------------------------------------------------------------------------------------------------------*/ TimeGrid.prototype.renderDates = function (dateProfile) { this.dateProfile = dateProfile; this.updateDayTable(); this.renderSlats(); this.renderColumns(); }; TimeGrid.prototype.unrenderDates = function () { // this.unrenderSlats(); // don't need this because repeated .html() calls clear this.unrenderColumns(); }; TimeGrid.prototype.renderSkeleton = function () { var theme = this.view.calendar.theme; this.el.html('<div class="fc-bg"></div>' + '<div class="fc-slats"></div>' + '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '" style="display:none" />'); this.bottomRuleEl = this.el.find('hr'); }; TimeGrid.prototype.renderSlats = function () { var theme = this.view.calendar.theme; this.slatContainerEl = this.el.find('> .fc-slats') .html(// avoids needing ::unrenderSlats() '<table class="' + theme.getClass('tableGrid') + '">' + this.renderSlatRowHtml() + '</table>'); this.slatEls = this.slatContainerEl.find('tr'); this.slatCoordCache = new CoordCache_1.default({ els: this.slatEls, isVertical: true }); }; // Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL. TimeGrid.prototype.renderSlatRowHtml = function () { var view = this.view; var calendar = view.calendar; var theme = calendar.theme; var isRTL = this.isRTL; var dateProfile = this.dateProfile; var html = ''; var slotTime = moment.duration(+dateProfile.minTime); // wish there was .clone() for durations var slotIterator = moment.duration(0); var slotDate; // will be on the view's first day, but we only care about its time var isLabeled; var axisHtml; // Calculate the time for each slot while (slotTime < dateProfile.maxTime) { slotDate = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.startMs).time(slotTime); isLabeled = util_1.isInt(util_1.divideDurationByDuration(slotIterator, this.labelInterval)); axisHtml = '<td class="fc-axis fc-time ' + theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '>' + (isLabeled ? '<span>' + // for matchCellWidths util_1.htmlEscape(slotDate.format(this.labelFormat)) + '</span>' : '') + '</td>'; html += '<tr data-time="' + slotDate.format('HH:mm:ss') + '"' + (isLabeled ? '' : ' class="fc-minor"') + '>' + (!isRTL ? axisHtml : '') + '<td class="' + theme.getClass('widgetContent') + '"/>' + (isRTL ? axisHtml : '') + '</tr>'; slotTime.add(this.slotDuration); slotIterator.add(this.slotDuration); } return html; }; TimeGrid.prototype.renderColumns = function () { var dateProfile = this.dateProfile; var theme = this.view.calendar.theme; this.dayRanges = this.dayDates.map(function (dayDate) { return new UnzonedRange_1.default(dayDate.clone().add(dateProfile.minTime), dayDate.clone().add(dateProfile.maxTime)); }); if (this.headContainerEl) { this.headContainerEl.html(this.renderHeadHtml()); } this.el.find('> .fc-bg').html('<table class="' + theme.getClass('tableGrid') + '">' + this.renderBgTrHtml(0) + // row=0 '</table>'); this.colEls = this.el.find('.fc-day, .fc-disabled-day'); this.colCoordCache = new CoordCache_1.default({ els: this.colEls, isHorizontal: true }); this.renderContentSkeleton(); }; TimeGrid.prototype.unrenderColumns = function () { this.unrenderContentSkeleton(); }; /* Content Skeleton ------------------------------------------------------------------------------------------------------------------*/ // Renders the DOM that the view's content will live in TimeGrid.prototype.renderContentSkeleton = function () { var cellHtml = ''; var i; var skeletonEl; for (i = 0; i < this.colCnt; i++) { cellHtml += '<td>' + '<div class="fc-content-col">' + '<div class="fc-event-container fc-helper-container"></div>' + '<div class="fc-event-container"></div>' + '<div class="fc-highlight-container"></div>' + '<div class="fc-bgevent-container"></div>' + '<div class="fc-business-container"></div>' + '</div>' + '</td>'; } skeletonEl = this.contentSkeletonEl = $('<div class="fc-content-skeleton">' + '<table>' + '<tr>' + cellHtml + '</tr>' + '</table>' + '</div>'); this.colContainerEls = skeletonEl.find('.fc-content-col'); this.helperContainerEls = skeletonEl.find('.fc-helper-container'); this.fgContainerEls = skeletonEl.find('.fc-event-container:not(.fc-helper-container)'); this.bgContainerEls = skeletonEl.find('.fc-bgevent-container'); this.highlightContainerEls = skeletonEl.find('.fc-highlight-container'); this.businessContainerEls = skeletonEl.find('.fc-business-container'); this.bookendCells(skeletonEl.find('tr')); // TODO: do this on string level this.el.append(skeletonEl); }; TimeGrid.prototype.unrenderContentSkeleton = function () { if (this.contentSkeletonEl) { // defensive :( this.contentSkeletonEl.remove(); this.contentSkeletonEl = null; this.colContainerEls = null; this.helperContainerEls = null; this.fgContainerEls = null; this.bgContainerEls = null; this.highlightContainerEls = null; this.businessContainerEls = null; } }; // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col TimeGrid.prototype.groupSegsByCol = function (segs) { var segsByCol = []; var i; for (i = 0; i < this.colCnt; i++) { segsByCol.push([]); } for (i = 0; i < segs.length; i++) { segsByCol[segs[i].col].push(segs[i]); } return segsByCol; }; // Given segments grouped by column, insert the segments' elements into a parallel array of container // elements, each living within a column. TimeGrid.prototype.attachSegsByCol = function (segsByCol, containerEls) { var col; var segs; var i; for (col = 0; col < this.colCnt; col++) { // iterate each column grouping segs = segsByCol[col]; for (i = 0; i < segs.length; i++) { containerEls.eq(col).append(segs[i].el); } } }; /* Now Indicator ------------------------------------------------------------------------------------------------------------------*/ TimeGrid.prototype.getNowIndicatorUnit = function () { return 'minute'; // will refresh on the minute }; TimeGrid.prototype.renderNowIndicator = function (date) { // HACK: if date columns not ready for some reason (scheduler) if (!this.colContainerEls) { return; } // seg system might be overkill, but it handles scenario where line needs to be rendered // more than once because of columns with the same date (resources columns for example) var segs = this.componentFootprintToSegs(new ComponentFootprint_1.default(new UnzonedRange_1.default(date, date.valueOf() + 1), // protect against null range false // all-day )); var top = this.computeDateTop(date, date); var nodes = []; var i; // render lines within the columns for (i = 0; i < segs.length; i++) { nodes.push($('<div class="fc-now-indicator fc-now-indicator-line"></div>') .css('top', top) .appendTo(this.colContainerEls.eq(segs[i].col))[0]); } // render an arrow over the axis if (segs.length > 0) { // is the current time in view? nodes.push($('<div class="fc-now-indicator fc-now-indicator-arrow"></div>') .css('top', top) .appendTo(this.el.find('.fc-content-skeleton'))[0]); } this.nowIndicatorEls = $(nodes); }; TimeGrid.prototype.unrenderNowIndicator = function () { if (this.nowIndicatorEls) { this.nowIndicatorEls.remove(); this.nowIndicatorEls = null; } }; /* Coordinates ------------------------------------------------------------------------------------------------------------------*/ TimeGrid.prototype.updateSize = function (totalHeight, isAuto, isResize) { _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize); this.slatCoordCache.build(); if (isResize) { this.updateSegVerticals([].concat(this.eventRenderer.getSegs(), this.businessSegs || [])); } }; TimeGrid.prototype.getTotalSlatHeight = function () { return this.slatContainerEl.outerHeight(); }; // Computes the top coordinate, relative to the bounds of the grid, of the given date. // `ms` can be a millisecond UTC time OR a UTC moment. // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight. TimeGrid.prototype.computeDateTop = function (ms, startOfDayDate) { return this.computeTimeTop(moment.duration(ms - startOfDayDate.clone().stripTime())); }; // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration). TimeGrid.prototype.computeTimeTop = function (time) { var len = this.slatEls.length; var dateProfile = this.dateProfile; var slatCoverage = (time - dateProfile.minTime) / this.slotDuration; // floating-point value of # of slots covered var slatIndex; var slatRemainder; // compute a floating-point number for how many slats should be progressed through. // from 0 to number of slats (inclusive) // constrained because minTime/maxTime might be customized. slatCoverage = Math.max(0, slatCoverage); slatCoverage = Math.min(len, slatCoverage); // an integer index of the furthest whole slat // from 0 to number slats (*exclusive*, so len-1) slatIndex = Math.floor(slatCoverage); slatIndex = Math.min(slatIndex, len - 1); // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition. // could be 1.0 if slatCoverage is covering *all* the slots slatRemainder = slatCoverage - slatIndex; return this.slatCoordCache.getTopPosition(slatIndex) + this.slatCoordCache.getHeight(slatIndex) * slatRemainder; }; // Refreshes the CSS top/bottom coordinates for each segment element. // Works when called after initial render, after a window resize/zoom for example. TimeGrid.prototype.updateSegVerticals = function (segs) { this.computeSegVerticals(segs); this.assignSegVerticals(segs); }; // For each segment in an array, computes and assigns its top and bottom properties TimeGrid.prototype.computeSegVerticals = function (segs) { var eventMinHeight = this.opt('agendaEventMinHeight'); var i; var seg; var dayDate; for (i = 0; i < segs.length; i++) { seg = segs[i]; dayDate = this.dayDates[seg.dayIndex]; seg.top = this.computeDateTop(seg.startMs, dayDate); seg.bottom = Math.max(seg.top + eventMinHeight, this.computeDateTop(seg.endMs, dayDate)); } }; // Given segments that already have their top/bottom properties computed, applies those values to // the segments' elements. TimeGrid.prototype.assignSegVerticals = function (segs) { var i; var seg; for (i = 0; i < segs.length; i++) { seg = segs[i]; seg.el.css(this.generateSegVerticalCss(seg)); } }; // Generates an object with CSS properties for the top/bottom coordinates of a segment element TimeGrid.prototype.generateSegVerticalCss = function (seg) { return { top: seg.top, bottom: -seg.bottom // flipped because needs to be space beyond bottom edge of event container }; }; /* Hit System ------------------------------------------------------------------------------------------------------------------*/ TimeGrid.prototype.prepareHits = function () { this.colCoordCache.build(); this.slatCoordCache.build(); }; TimeGrid.prototype.releaseHits = function () { this.colCoordCache.clear(); // NOTE: don't clear slatCoordCache because we rely on it for computeTimeTop }; TimeGrid.prototype.queryHit = function (leftOffset, topOffset) { var snapsPerSlot = this.snapsPerSlot; var colCoordCache = this.colCoordCache; var slatCoordCache = this.slatCoordCache; if (colCoordCache.isLeftInBounds(leftOffset) && slatCoordCache.isTopInBounds(topOffset)) { var colIndex = colCoordCache.getHorizontalIndex(leftOffset); var slatIndex = slatCoordCache.getVerticalIndex(topOffset); if (colIndex != null && slatIndex != null) { var slatTop = slatCoordCache.getTopOffset(slatIndex); var slatHeight = slatCoordCache.getHeight(slatIndex); var partial = (topOffset - slatTop) / slatHeight; // floating point number between 0 and 1 var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat var snapIndex = slatIndex * snapsPerSlot + localSnapIndex; var snapTop = slatTop + (localSnapIndex / snapsPerSlot) * slatHeight; var snapBottom = slatTop + ((localSnapIndex + 1) / snapsPerSlot) * slatHeight; return { col: colIndex, snap: snapIndex, component: this, left: colCoordCache.getLeftOffset(colIndex), right: colCoordCache.getRightOffset(colIndex), top: snapTop, bottom: snapBottom }; } } }; TimeGrid.prototype.getHitFootprint = function (hit) { var start = this.getCellDate(0, hit.col); // row=0 var time = this.computeSnapTime(hit.snap); // pass in the snap-index var end; start.time(time); end = start.clone().add(this.snapDuration); return new ComponentFootprint_1.default(new UnzonedRange_1.default(start, end), false // all-day? ); }; // Given a row number of the grid, representing a "snap", returns a time (Duration) from its start-of-day TimeGrid.prototype.computeSnapTime = function (snapIndex) { return moment.duration(this.dateProfile.minTime + this.snapDuration * snapIndex); }; TimeGrid.prototype.getHitEl = function (hit) { return this.colEls.eq(hit.col); }; /* Event Drag Visualization ------------------------------------------------------------------------------------------------------------------*/ // Renders a visual indication of an event being dragged over the specified date(s). // A returned value of `true` signals that a mock "helper" event has been rendered. TimeGrid.prototype.renderDrag = function (eventFootprints, seg, isTouch) { var i; if (seg) { // if there is event information for this drag, render a helper event if (eventFootprints.length) { this.helperRenderer.renderEventDraggingFootprints(eventFootprints, seg, isTouch); // signal that a helper has been rendered return true; } } else { // otherwise, just render a highlight for (i = 0; i < eventFootprints.length; i++) { this.renderHighlight(eventFootprints[i].componentFootprint); } } }; // Unrenders any visual indication of an event being dragged TimeGrid.prototype.unrenderDrag = function () { this.unrenderHighlight(); this.helperRenderer.unrender(); }; /* Event Resize Visualization ------------------------------------------------------------------------------------------------------------------*/ // Renders a visual indication of an event being resized TimeGrid.prototype.renderEventResize = function (eventFootprints, seg, isTouch) { this.helperRenderer.renderEventResizingFootprints(eventFootprints, seg, isTouch); }; // Unrenders any visual indication of an event being resized TimeGrid.prototype.unrenderEventResize = function () { this.helperRenderer.unrender(); }; /* Selection ------------------------------------------------------------------------------------------------------------------*/ // Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight. TimeGrid.prototype.renderSelectionFootprint = function (componentFootprint) { if (this.opt('selectHelper')) { // this setting signals that a mock helper event should be rendered this.helperRenderer.renderComponentFootprint(componentFootprint); } else { this.renderHighlight(componentFootprint); } }; // Unrenders any visual indication of a selection TimeGrid.prototype.unrenderSelection = function () { this.helperRenderer.unrender(); this.unrenderHighlight(); }; return TimeGrid; }(InteractiveDateComponent_1.default)); exports.default = TimeGrid; TimeGrid.prototype.eventRendererClass = TimeGridEventRenderer_1.default; TimeGrid.prototype.businessHourRendererClass = BusinessHourRenderer_1.default; TimeGrid.prototype.helperRendererClass = TimeGridHelperRenderer_1.default; TimeGrid.prototype.fillRendererClass = TimeGridFillRenderer_1.default; StandardInteractionsMixin_1.default.mixInto(TimeGrid); DayTableMixin_1.default.mixInto(TimeGrid); /***/ }), /* 240 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var util_1 = __webpack_require__(4); var EventRenderer_1 = __webpack_require__(44); /* Only handles foreground segs. Does not own rendering. Use for low-level util methods by TimeGrid. */ var TimeGridEventRenderer = /** @class */ (function (_super) { tslib_1.__extends(TimeGridEventRenderer, _super); function TimeGridEventRenderer(timeGrid, fillRenderer) { var _this = _super.call(this, timeGrid, fillRenderer) || this; _this.timeGrid = timeGrid; return _this; } TimeGridEventRenderer.prototype.renderFgSegs = function (segs) { this.renderFgSegsIntoContainers(segs, this.timeGrid.fgContainerEls); }; // Given an array of foreground segments, render a DOM element for each, computes position, // and attaches to the column inner-container elements. TimeGridEventRenderer.prototype.renderFgSegsIntoContainers = function (segs, containerEls) { var segsByCol; var col; segsByCol = this.timeGrid.groupSegsByCol(segs); for (col = 0; col < this.timeGrid.colCnt; col++) { this.updateFgSegCoords(segsByCol[col]); } this.timeGrid.attachSegsByCol(segsByCol, containerEls); }; TimeGridEventRenderer.prototype.unrenderFgSegs = function () { if (this.fgSegs) { // hack this.fgSegs.forEach(function (seg) { seg.el.remove(); }); } }; // Computes a default event time formatting string if `timeFormat` is not explicitly defined TimeGridEventRenderer.prototype.computeEventTimeFormat = function () { return this.opt('noMeridiemTimeFormat'); // like "6:30" (no AM/PM) }; // Computes a default `displayEventEnd` value if one is not expliclty defined TimeGridEventRenderer.prototype.computeDisplayEventEnd = function () { return true; }; // Renders the HTML for a single event segment's default rendering TimeGridEventRenderer.prototype.fgSegHtml = function (seg, disableResizing) { var view = this.view; var calendar = view.calendar; var componentFootprint = seg.footprint.componentFootprint; var isAllDay = componentFootprint.isAllDay; var eventDef = seg.footprint.eventDef; var isDraggable = view.isEventDefDraggable(eventDef); var isResizableFromStart = !disableResizing && seg.isStart && view.isEventDefResizableFromStart(eventDef); var isResizableFromEnd = !disableResizing && seg.isEnd && view.isEventDefResizableFromEnd(eventDef); var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd); var skinCss = util_1.cssToStr(this.getSkinCss(eventDef)); var timeText; var fullTimeText; // more verbose time text. for the print stylesheet var startTimeText; // just the start time text classes.unshift('fc-time-grid-event', 'fc-v-event'); // if the event appears to span more than one day... if (view.isMultiDayRange(componentFootprint.unzonedRange)) { // Don't display time text on segments that run entirely through a day. // That would appear as midnight-midnight and would look dumb. // Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am) if (seg.isStart || seg.isEnd) { var zonedStart = calendar.msToMoment(seg.startMs); var zonedEnd = calendar.msToMoment(seg.endMs); timeText = this._getTimeText(zonedStart, zonedEnd, isAllDay); fullTimeText = this._getTimeText(zonedStart, zonedEnd, isAllDay, 'LT'); startTimeText = this._getTimeText(zonedStart, zonedEnd, isAllDay, null, false); // displayEnd=false } } else { // Display the normal time text for the *event's* times timeText = this.getTimeText(seg.footprint); fullTimeText = this.getTimeText(seg.footprint, 'LT'); startTimeText = this.getTimeText(seg.footprint, null, false); // displayEnd=false } return '<a class="' + classes.join(' ') + '"' + (eventDef.url ? ' href="' + util_1.htmlEscape(eventDef.url) + '"' : '') + (skinCss ? ' style="' + skinCss + '"' : '') + '>' + '<div class="fc-content">' + (timeText ? '<div class="fc-time"' + ' data-start="' + util_1.htmlEscape(startTimeText) + '"' + ' data-full="' + util_1.htmlEscape(fullTimeText) + '"' + '>' + '<span>' + util_1.htmlEscape(timeText) + '</span>' + '</div>' : '') + (eventDef.title ? '<div class="fc-title">' + util_1.htmlEscape(eventDef.title) + '</div>' : '') + '</div>' + '<div class="fc-bg"/>' + /* TODO: write CSS for this (isResizableFromStart ? '<div class="fc-resizer fc-start-resizer" />' : '' ) + */ (isResizableFromEnd ? '<div class="fc-resizer fc-end-resizer" />' : '') + '</a>'; }; // Given segments that are assumed to all live in the *same column*, // compute their verical/horizontal coordinates and assign to their elements. TimeGridEventRenderer.prototype.updateFgSegCoords = function (segs) { this.timeGrid.computeSegVerticals(segs); // horizontals relies on this this.computeFgSegHorizontals(segs); // compute horizontal coordinates, z-index's, and reorder the array this.timeGrid.assignSegVerticals(segs); this.assignFgSegHorizontals(segs); }; // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each. // NOTE: Also reorders the given array by date! TimeGridEventRenderer.prototype.computeFgSegHorizontals = function (segs) { var levels; var level0; var i; this.sortEventSegs(segs); // order by certain criteria levels = buildSlotSegLevels(segs); computeForwardSlotSegs(levels); if ((level0 = levels[0])) { for (i = 0; i < level0.length; i++) { computeSlotSegPressures(level0[i]); } for (i = 0; i < level0.length; i++) { this.computeFgSegForwardBack(level0[i], 0, 0); } } }; // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left. // // The segment might be part of a "series", which means consecutive segments with the same pressure // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of // segments behind this one in the current series, and `seriesBackwardCoord` is the starting // coordinate of the first segment in the series. TimeGridEventRenderer.prototype.computeFgSegForwardBack = function (seg, seriesBackwardPressure, seriesBackwardCoord) { var forwardSegs = seg.forwardSegs; var i; if (seg.forwardCoord === undefined) { // not already computed if (!forwardSegs.length) { // if there are no forward segments, this segment should butt up against the edge seg.forwardCoord = 1; } else { // sort highest pressure first this.sortForwardSegs(forwardSegs); // this segment's forwardCoord will be calculated from the backwardCoord of the // highest-pressure forward segment. this.computeFgSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord); seg.forwardCoord = forwardSegs[0].backwardCoord; } // calculate the backwardCoord from the forwardCoord. consider the series seg.backwardCoord = seg.forwardCoord - (seg.forwardCoord - seriesBackwardCoord) / // available width for series (seriesBackwardPressure + 1); // # of segments in the series // use this segment's coordinates to computed the coordinates of the less-pressurized // forward segments for (i = 0; i < forwardSegs.length; i++) { this.computeFgSegForwardBack(forwardSegs[i], 0, seg.forwardCoord); } } }; TimeGridEventRenderer.prototype.sortForwardSegs = function (forwardSegs) { forwardSegs.sort(util_1.proxy(this, 'compareForwardSegs')); }; // A cmp function for determining which forward segment to rely on more when computing coordinates. TimeGridEventRenderer.prototype.compareForwardSegs = function (seg1, seg2) { // put higher-pressure first return seg2.forwardPressure - seg1.forwardPressure || // put segments that are closer to initial edge first (and favor ones with no coords yet) (seg1.backwardCoord || 0) - (seg2.backwardCoord || 0) || // do normal sorting... this.compareEventSegs(seg1, seg2); }; // Given foreground event segments that have already had their position coordinates computed, // assigns position-related CSS values to their elements. TimeGridEventRenderer.prototype.assignFgSegHorizontals = function (segs) { var i; var seg; for (i = 0; i < segs.length; i++) { seg = segs[i]; seg.el.css(this.generateFgSegHorizontalCss(seg)); // if the event is short that the title will be cut off, // attach a className that condenses the title into the time area. if (seg.footprint.eventDef.title && seg.bottom - seg.top < 30) { seg.el.addClass('fc-short'); // TODO: "condensed" is a better name } } }; // Generates an object with CSS properties/values that should be applied to an event segment element. // Contains important positioning-related properties that should be applied to any event element, customized or not. TimeGridEventRenderer.prototype.generateFgSegHorizontalCss = function (seg) { var shouldOverlap = this.opt('slotEventOverlap'); var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point var props = this.timeGrid.generateSegVerticalCss(seg); // get top/bottom first var isRTL = this.timeGrid.isRTL; var left; // amount of space from left edge, a fraction of the total width var right; // amount of space from right edge, a fraction of the total width if (shouldOverlap) { // double the width, but don't go beyond the maximum forward coordinate (1.0) forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2); } if (isRTL) { left = 1 - forwardCoord; right = backwardCoord; } else { left = backwardCoord; right = 1 - forwardCoord; } props.zIndex = seg.level + 1; // convert from 0-base to 1-based props.left = left * 100 + '%'; props.right = right * 100 + '%'; if (shouldOverlap && seg.forwardPressure) { // add padding to the edge so that forward stacked events don't cover the resizer's icon props[isRTL ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width } return props; }; return TimeGridEventRenderer; }(EventRenderer_1.default)); exports.default = TimeGridEventRenderer; // Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is // left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date. function buildSlotSegLevels(segs) { var levels = []; var i; var seg; var j; for (i = 0; i < segs.length; i++) { seg = segs[i]; // go through all the levels and stop on the first level where there are no collisions for (j = 0; j < levels.length; j++) { if (!computeSlotSegCollisions(seg, levels[j]).length) { break; } } seg.level = j; (levels[j] || (levels[j] = [])).push(seg); } return levels; } // For every segment, figure out the other segments that are in subsequent // levels that also occupy the same vertical space. Accumulate in seg.forwardSegs function computeForwardSlotSegs(levels) { var i; var level; var j; var seg; var k; for (i = 0; i < levels.length; i++) { level = levels[i]; for (j = 0; j < level.length; j++) { seg = level[j]; seg.forwardSegs = []; for (k = i + 1; k < levels.length; k++) { computeSlotSegCollisions(seg, levels[k], seg.forwardSegs); } } } } // Figure out which path forward (via seg.forwardSegs) results in the longest path until // the furthest edge is reached. The number of segments in this path will be seg.forwardPressure function computeSlotSegPressures(seg) { var forwardSegs = seg.forwardSegs; var forwardPressure = 0; var i; var forwardSeg; if (seg.forwardPressure === undefined) { // not already computed for (i = 0; i < forwardSegs.length; i++) { forwardSeg = forwardSegs[i]; // figure out the child's maximum forward path computeSlotSegPressures(forwardSeg); // either use the existing maximum, or use the child's forward pressure // plus one (for the forwardSeg itself) forwardPressure = Math.max(forwardPressure, 1 + forwardSeg.forwardPressure); } seg.forwardPressure = forwardPressure; } } // Find all the segments in `otherSegs` that vertically collide with `seg`. // Append into an optionally-supplied `results` array and return. function computeSlotSegCollisions(seg, otherSegs, results) { if (results === void 0) { results = []; } for (var i = 0; i < otherSegs.length; i++) { if (isSlotSegCollision(seg, otherSegs[i])) { results.push(otherSegs[i]); } } return results; } // Do these segments occupy the same vertical space? function isSlotSegCollision(seg1, seg2) { return seg1.bottom > seg2.top && seg1.top < seg2.bottom; } /***/ }), /* 241 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var HelperRenderer_1 = __webpack_require__(63); var TimeGridHelperRenderer = /** @class */ (function (_super) { tslib_1.__extends(TimeGridHelperRenderer, _super); function TimeGridHelperRenderer() { return _super !== null && _super.apply(this, arguments) || this; } TimeGridHelperRenderer.prototype.renderSegs = function (segs, sourceSeg) { var helperNodes = []; var i; var seg; var sourceEl; // TODO: not good to call eventRenderer this way this.eventRenderer.renderFgSegsIntoContainers(segs, this.component.helperContainerEls); // Try to make the segment that is in the same row as sourceSeg look the same for (i = 0; i < segs.length; i++) { seg = segs[i]; if (sourceSeg && sourceSeg.col === seg.col) { sourceEl = sourceSeg.el; seg.el.css({ left: sourceEl.css('left'), right: sourceEl.css('right'), 'margin-left': sourceEl.css('margin-left'), 'margin-right': sourceEl.css('margin-right') }); } helperNodes.push(seg.el[0]); } return $(helperNodes); // must return the elements rendered }; return TimeGridHelperRenderer; }(HelperRenderer_1.default)); exports.default = TimeGridHelperRenderer; /***/ }), /* 242 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var FillRenderer_1 = __webpack_require__(62); var TimeGridFillRenderer = /** @class */ (function (_super) { tslib_1.__extends(TimeGridFillRenderer, _super); function TimeGridFillRenderer() { return _super !== null && _super.apply(this, arguments) || this; } TimeGridFillRenderer.prototype.attachSegEls = function (type, segs) { var timeGrid = this.component; var containerEls; // TODO: more efficient lookup if (type === 'bgEvent') { containerEls = timeGrid.bgContainerEls; } else if (type === 'businessHours') { containerEls = timeGrid.businessContainerEls; } else if (type === 'highlight') { containerEls = timeGrid.highlightContainerEls; } timeGrid.updateSegVerticals(segs); timeGrid.attachSegsByCol(timeGrid.groupSegsByCol(segs), containerEls); return segs.map(function (seg) { return seg.el[0]; }); }; return TimeGridFillRenderer; }(FillRenderer_1.default)); exports.default = TimeGridFillRenderer; /***/ }), /* 243 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var EventRenderer_1 = __webpack_require__(44); /* Event-rendering methods for the DayGrid class ----------------------------------------------------------------------------------------------------------------------*/ var DayGridEventRenderer = /** @class */ (function (_super) { tslib_1.__extends(DayGridEventRenderer, _super); function DayGridEventRenderer(dayGrid, fillRenderer) { var _this = _super.call(this, dayGrid, fillRenderer) || this; _this.dayGrid = dayGrid; return _this; } DayGridEventRenderer.prototype.renderBgRanges = function (eventRanges) { // don't render timed background events eventRanges = $.grep(eventRanges, function (eventRange) { return eventRange.eventDef.isAllDay(); }); _super.prototype.renderBgRanges.call(this, eventRanges); }; // Renders the given foreground event segments onto the grid DayGridEventRenderer.prototype.renderFgSegs = function (segs) { var rowStructs = this.rowStructs = this.renderSegRows(segs); // append to each row's content skeleton this.dayGrid.rowEls.each(function (i, rowNode) { $(rowNode).find('.fc-content-skeleton > table').append(rowStructs[i].tbodyEl); }); }; // Unrenders all currently rendered foreground event segments DayGridEventRenderer.prototype.unrenderFgSegs = function () { var rowStructs = this.rowStructs || []; var rowStruct; while ((rowStruct = rowStructs.pop())) { rowStruct.tbodyEl.remove(); } this.rowStructs = null; }; // Uses the given events array to generate <tbody> elements that should be appended to each row's content skeleton. // Returns an array of rowStruct objects (see the bottom of `renderSegRow`). // PRECONDITION: each segment shoud already have a rendered and assigned `.el` DayGridEventRenderer.prototype.renderSegRows = function (segs) { var rowStructs = []; var segRows; var row; segRows = this.groupSegRows(segs); // group into nested arrays // iterate each row of segment groupings for (row = 0; row < segRows.length; row++) { rowStructs.push(this.renderSegRow(row, segRows[row])); } return rowStructs; }; // Given a row # and an array of segments all in the same row, render a <tbody> element, a skeleton that contains // the segments. Returns object with a bunch of internal data about how the render was calculated. // NOTE: modifies rowSegs DayGridEventRenderer.prototype.renderSegRow = function (row, rowSegs) { var colCnt = this.dayGrid.colCnt; var segLevels = this.buildSegLevels(rowSegs); // group into sub-arrays of levels var levelCnt = Math.max(1, segLevels.length); // ensure at least one level var tbody = $('<tbody/>'); var segMatrix = []; // lookup for which segments are rendered into which level+col cells var cellMatrix = []; // lookup for all <td> elements of the level+col matrix var loneCellMatrix = []; // lookup for <td> elements that only take up a single column var i; var levelSegs; var col; var tr; var j; var seg; var td; // populates empty cells from the current column (`col`) to `endCol` function emptyCellsUntil(endCol) { while (col < endCol) { // try to grab a cell from the level above and extend its rowspan. otherwise, create a fresh cell td = (loneCellMatrix[i - 1] || [])[col]; if (td) { td.attr('rowspan', parseInt(td.attr('rowspan') || 1, 10) + 1); } else { td = $('<td/>'); tr.append(td); } cellMatrix[i][col] = td; loneCellMatrix[i][col] = td; col++; } } for (i = 0; i < levelCnt; i++) { // iterate through all levels levelSegs = segLevels[i]; col = 0; tr = $('<tr/>'); segMatrix.push([]); cellMatrix.push([]); loneCellMatrix.push([]); // levelCnt might be 1 even though there are no actual levels. protect against this. // this single empty row is useful for styling. if (levelSegs) { for (j = 0; j < levelSegs.length; j++) { // iterate through segments in level seg = levelSegs[j]; emptyCellsUntil(seg.leftCol); // create a container that occupies or more columns. append the event element. td = $('<td class="fc-event-container"/>').append(seg.el); if (seg.leftCol !== seg.rightCol) { td.attr('colspan', seg.rightCol - seg.leftCol + 1); } else { // a single-column segment loneCellMatrix[i][col] = td; } while (col <= seg.rightCol) { cellMatrix[i][col] = td; segMatrix[i][col] = seg; col++; } tr.append(td); } } emptyCellsUntil(colCnt); // finish off the row this.dayGrid.bookendCells(tr); tbody.append(tr); } return { row: row, tbodyEl: tbody, cellMatrix: cellMatrix, segMatrix: segMatrix, segLevels: segLevels, segs: rowSegs }; }; // Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels. // NOTE: modifies segs DayGridEventRenderer.prototype.buildSegLevels = function (segs) { var levels = []; var i; var seg; var j; // Give preference to elements with certain criteria, so they have // a chance to be closer to the top. this.sortEventSegs(segs); for (i = 0; i < segs.length; i++) { seg = segs[i]; // loop through levels, starting with the topmost, until the segment doesn't collide with other segments for (j = 0; j < levels.length; j++) { if (!isDaySegCollision(seg, levels[j])) { break; } } // `j` now holds the desired subrow index seg.level = j; // create new level array if needed and append segment (levels[j] || (levels[j] = [])).push(seg); } // order segments left-to-right. very important if calendar is RTL for (j = 0; j < levels.length; j++) { levels[j].sort(compareDaySegCols); } return levels; }; // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row DayGridEventRenderer.prototype.groupSegRows = function (segs) { var segRows = []; var i; for (i = 0; i < this.dayGrid.rowCnt; i++) { segRows.push([]); } for (i = 0; i < segs.length; i++) { segRows[segs[i].row].push(segs[i]); } return segRows; }; // Computes a default event time formatting string if `timeFormat` is not explicitly defined DayGridEventRenderer.prototype.computeEventTimeFormat = function () { return this.opt('extraSmallTimeFormat'); // like "6p" or "6:30p" }; // Computes a default `displayEventEnd` value if one is not expliclty defined DayGridEventRenderer.prototype.computeDisplayEventEnd = function () { return this.dayGrid.colCnt === 1; // we'll likely have space if there's only one day }; // Builds the HTML to be used for the default element for an individual segment DayGridEventRenderer.prototype.fgSegHtml = function (seg, disableResizing) { var view = this.view; var eventDef = seg.footprint.eventDef; var isAllDay = seg.footprint.componentFootprint.isAllDay; var isDraggable = view.isEventDefDraggable(eventDef); var isResizableFromStart = !disableResizing && isAllDay && seg.isStart && view.isEventDefResizableFromStart(eventDef); var isResizableFromEnd = !disableResizing && isAllDay && seg.isEnd && view.isEventDefResizableFromEnd(eventDef); var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd); var skinCss = util_1.cssToStr(this.getSkinCss(eventDef)); var timeHtml = ''; var timeText; var titleHtml; classes.unshift('fc-day-grid-event', 'fc-h-event'); // Only display a timed events time if it is the starting segment if (seg.isStart) { timeText = this.getTimeText(seg.footprint); if (timeText) { timeHtml = '<span class="fc-time">' + util_1.htmlEscape(timeText) + '</span>'; } } titleHtml = '<span class="fc-title">' + (util_1.htmlEscape(eventDef.title || '') || ' ') + // we always want one line of height '</span>'; return '<a class="' + classes.join(' ') + '"' + (eventDef.url ? ' href="' + util_1.htmlEscape(eventDef.url) + '"' : '') + (skinCss ? ' style="' + skinCss + '"' : '') + '>' + '<div class="fc-content">' + (this.dayGrid.isRTL ? titleHtml + ' ' + timeHtml : // put a natural space in between timeHtml + ' ' + titleHtml // ) + '</div>' + (isResizableFromStart ? '<div class="fc-resizer fc-start-resizer" />' : '') + (isResizableFromEnd ? '<div class="fc-resizer fc-end-resizer" />' : '') + '</a>'; }; return DayGridEventRenderer; }(EventRenderer_1.default)); exports.default = DayGridEventRenderer; // Computes whether two segments' columns collide. They are assumed to be in the same row. function isDaySegCollision(seg, otherSegs) { var i; var otherSeg; for (i = 0; i < otherSegs.length; i++) { otherSeg = otherSegs[i]; if (otherSeg.leftCol <= seg.rightCol && otherSeg.rightCol >= seg.leftCol) { return true; } } return false; } // A cmp function for determining the leftmost event function compareDaySegCols(a, b) { return a.leftCol - b.leftCol; } /***/ }), /* 244 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var HelperRenderer_1 = __webpack_require__(63); var DayGridHelperRenderer = /** @class */ (function (_super) { tslib_1.__extends(DayGridHelperRenderer, _super); function DayGridHelperRenderer() { return _super !== null && _super.apply(this, arguments) || this; } // Renders a mock "helper" event. `sourceSeg` is the associated internal segment object. It can be null. DayGridHelperRenderer.prototype.renderSegs = function (segs, sourceSeg) { var helperNodes = []; var rowStructs; // TODO: not good to call eventRenderer this way rowStructs = this.eventRenderer.renderSegRows(segs); // inject each new event skeleton into each associated row this.component.rowEls.each(function (row, rowNode) { var rowEl = $(rowNode); // the .fc-row var skeletonEl = $('<div class="fc-helper-skeleton"><table/></div>'); // will be absolutely positioned var skeletonTopEl; var skeletonTop; // If there is an original segment, match the top position. Otherwise, put it at the row's top level if (sourceSeg && sourceSeg.row === row) { skeletonTop = sourceSeg.el.position().top; } else { skeletonTopEl = rowEl.find('.fc-content-skeleton tbody'); if (!skeletonTopEl.length) { // when no events skeletonTopEl = rowEl.find('.fc-content-skeleton table'); } skeletonTop = skeletonTopEl.position().top; } skeletonEl.css('top', skeletonTop) .find('table') .append(rowStructs[row].tbodyEl); rowEl.append(skeletonEl); helperNodes.push(skeletonEl[0]); }); return $(helperNodes); // must return the elements rendered }; return DayGridHelperRenderer; }(HelperRenderer_1.default)); exports.default = DayGridHelperRenderer; /***/ }), /* 245 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var FillRenderer_1 = __webpack_require__(62); var DayGridFillRenderer = /** @class */ (function (_super) { tslib_1.__extends(DayGridFillRenderer, _super); function DayGridFillRenderer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.fillSegTag = 'td'; // override the default tag name return _this; } DayGridFillRenderer.prototype.attachSegEls = function (type, segs) { var nodes = []; var i; var seg; var skeletonEl; for (i = 0; i < segs.length; i++) { seg = segs[i]; skeletonEl = this.renderFillRow(type, seg); this.component.rowEls.eq(seg.row).append(skeletonEl); nodes.push(skeletonEl[0]); } return nodes; }; // Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered. DayGridFillRenderer.prototype.renderFillRow = function (type, seg) { var colCnt = this.component.colCnt; var startCol = seg.leftCol; var endCol = seg.rightCol + 1; var className; var skeletonEl; var trEl; if (type === 'businessHours') { className = 'bgevent'; } else { className = type.toLowerCase(); } skeletonEl = $('<div class="fc-' + className + '-skeleton">' + '<table><tr/></table>' + '</div>'); trEl = skeletonEl.find('tr'); if (startCol > 0) { trEl.append( // will create (startCol + 1) td's new Array(startCol + 1).join('<td/>')); } trEl.append(seg.el.attr('colspan', endCol - startCol)); if (endCol < colCnt) { trEl.append( // will create (colCnt - endCol) td's new Array(colCnt - endCol + 1).join('<td/>')); } this.component.bookendCells(trEl); return skeletonEl; }; return DayGridFillRenderer; }(FillRenderer_1.default)); exports.default = DayGridFillRenderer; /***/ }), /* 246 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var moment = __webpack_require__(0); var util_1 = __webpack_require__(4); var BasicView_1 = __webpack_require__(67); var MonthViewDateProfileGenerator_1 = __webpack_require__(247); /* A month view with day cells running in rows (one-per-week) and columns ----------------------------------------------------------------------------------------------------------------------*/ var MonthView = /** @class */ (function (_super) { tslib_1.__extends(MonthView, _super); function MonthView() { return _super !== null && _super.apply(this, arguments) || this; } // Overrides the default BasicView behavior to have special multi-week auto-height logic MonthView.prototype.setGridHeight = function (height, isAuto) { // if auto, make the height of each row the height that it would be if there were 6 weeks if (isAuto) { height *= this.dayGrid.rowCnt / 6; } util_1.distributeHeight(this.dayGrid.rowEls, height, !isAuto); // if auto, don't compensate for height-hogging rows }; MonthView.prototype.isDateInOtherMonth = function (date, dateProfile) { return date.month() !== moment.utc(dateProfile.currentUnzonedRange.startMs).month(); // TODO: optimize }; return MonthView; }(BasicView_1.default)); exports.default = MonthView; MonthView.prototype.dateProfileGeneratorClass = MonthViewDateProfileGenerator_1.default; /***/ }), /* 247 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var BasicViewDateProfileGenerator_1 = __webpack_require__(68); var UnzonedRange_1 = __webpack_require__(5); var MonthViewDateProfileGenerator = /** @class */ (function (_super) { tslib_1.__extends(MonthViewDateProfileGenerator, _super); function MonthViewDateProfileGenerator() { return _super !== null && _super.apply(this, arguments) || this; } // Computes the date range that will be rendered. MonthViewDateProfileGenerator.prototype.buildRenderRange = function (currentUnzonedRange, currentRangeUnit, isRangeAllDay) { var renderUnzonedRange = _super.prototype.buildRenderRange.call(this, currentUnzonedRange, currentRangeUnit, isRangeAllDay); var start = this.msToUtcMoment(renderUnzonedRange.startMs, isRangeAllDay); var end = this.msToUtcMoment(renderUnzonedRange.endMs, isRangeAllDay); var rowCnt; // ensure 6 weeks if (this.opt('fixedWeekCount')) { rowCnt = Math.ceil(// could be partial weeks due to hiddenDays end.diff(start, 'weeks', true) // dontRound=true ); end.add(6 - rowCnt, 'weeks'); } return new UnzonedRange_1.default(start, end); }; return MonthViewDateProfileGenerator; }(BasicViewDateProfileGenerator_1.default)); exports.default = MonthViewDateProfileGenerator; /***/ }), /* 248 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var UnzonedRange_1 = __webpack_require__(5); var View_1 = __webpack_require__(43); var Scroller_1 = __webpack_require__(41); var ListEventRenderer_1 = __webpack_require__(249); var ListEventPointing_1 = __webpack_require__(250); /* Responsible for the scroller, and forwarding event-related actions into the "grid". */ var ListView = /** @class */ (function (_super) { tslib_1.__extends(ListView, _super); function ListView(calendar, viewSpec) { var _this = _super.call(this, calendar, viewSpec) || this; _this.segSelector = '.fc-list-item'; // which elements accept event actions _this.scroller = new Scroller_1.default({ overflowX: 'hidden', overflowY: 'auto' }); return _this; } ListView.prototype.renderSkeleton = function () { this.el.addClass('fc-list-view ' + this.calendar.theme.getClass('listView')); this.scroller.render(); this.scroller.el.appendTo(this.el); this.contentEl = this.scroller.scrollEl; // shortcut }; ListView.prototype.unrenderSkeleton = function () { this.scroller.destroy(); // will remove the Grid too }; ListView.prototype.updateSize = function (totalHeight, isAuto, isResize) { _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize); this.scroller.clear(); // sets height to 'auto' and clears overflow if (!isAuto) { this.scroller.setHeight(this.computeScrollerHeight(totalHeight)); } }; ListView.prototype.computeScrollerHeight = function (totalHeight) { return totalHeight - util_1.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller }; ListView.prototype.renderDates = function (dateProfile) { var calendar = this.calendar; var dayStart = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.startMs, true); var viewEnd = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.endMs, true); var dayDates = []; var dayRanges = []; while (dayStart < viewEnd) { dayDates.push(dayStart.clone()); dayRanges.push(new UnzonedRange_1.default(dayStart, dayStart.clone().add(1, 'day'))); dayStart.add(1, 'day'); } this.dayDates = dayDates; this.dayRanges = dayRanges; // all real rendering happens in EventRenderer }; // slices by day ListView.prototype.componentFootprintToSegs = function (footprint) { var dayRanges = this.dayRanges; var dayIndex; var segRange; var seg; var segs = []; for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex++) { segRange = footprint.unzonedRange.intersect(dayRanges[dayIndex]); if (segRange) { seg = { startMs: segRange.startMs, endMs: segRange.endMs, isStart: segRange.isStart, isEnd: segRange.isEnd, dayIndex: dayIndex }; segs.push(seg); // detect when footprint won't go fully into the next day, // and mutate the latest seg to the be the end. if (!seg.isEnd && !footprint.isAllDay && dayIndex + 1 < dayRanges.length && footprint.unzonedRange.endMs < dayRanges[dayIndex + 1].startMs + this.nextDayThreshold) { seg.endMs = footprint.unzonedRange.endMs; seg.isEnd = true; break; } } } return segs; }; ListView.prototype.renderEmptyMessage = function () { this.contentEl.html('<div class="fc-list-empty-wrap2">' + // TODO: try less wraps '<div class="fc-list-empty-wrap1">' + '<div class="fc-list-empty">' + util_1.htmlEscape(this.opt('noEventsMessage')) + '</div>' + '</div>' + '</div>'); }; // render the event segments in the view ListView.prototype.renderSegList = function (allSegs) { var segsByDay = this.groupSegsByDay(allSegs); // sparse array var dayIndex; var daySegs; var i; var tableEl = $('<table class="fc-list-table ' + this.calendar.theme.getClass('tableList') + '"><tbody/></table>'); var tbodyEl = tableEl.find('tbody'); for (dayIndex = 0; dayIndex < segsByDay.length; dayIndex++) { daySegs = segsByDay[dayIndex]; if (daySegs) { // sparse array, so might be undefined // append a day header tbodyEl.append(this.dayHeaderHtml(this.dayDates[dayIndex])); this.eventRenderer.sortEventSegs(daySegs); for (i = 0; i < daySegs.length; i++) { tbodyEl.append(daySegs[i].el); // append event row } } } this.contentEl.empty().append(tableEl); }; // Returns a sparse array of arrays, segs grouped by their dayIndex ListView.prototype.groupSegsByDay = function (segs) { var segsByDay = []; // sparse array var i; var seg; for (i = 0; i < segs.length; i++) { seg = segs[i]; (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = [])) .push(seg); } return segsByDay; }; // generates the HTML for the day headers that live amongst the event rows ListView.prototype.dayHeaderHtml = function (dayDate) { var mainFormat = this.opt('listDayFormat'); var altFormat = this.opt('listDayAltFormat'); return '<tr class="fc-list-heading" data-date="' + dayDate.format('YYYY-MM-DD') + '">' + '<td class="' + (this.calendar.theme.getClass('tableListHeading') || this.calendar.theme.getClass('widgetHeader')) + '" colspan="3">' + (mainFormat ? this.buildGotoAnchorHtml(dayDate, { 'class': 'fc-list-heading-main' }, util_1.htmlEscape(dayDate.format(mainFormat)) // inner HTML ) : '') + (altFormat ? this.buildGotoAnchorHtml(dayDate, { 'class': 'fc-list-heading-alt' }, util_1.htmlEscape(dayDate.format(altFormat)) // inner HTML ) : '') + '</td>' + '</tr>'; }; return ListView; }(View_1.default)); exports.default = ListView; ListView.prototype.eventRendererClass = ListEventRenderer_1.default; ListView.prototype.eventPointingClass = ListEventPointing_1.default; /***/ }), /* 249 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var util_1 = __webpack_require__(4); var EventRenderer_1 = __webpack_require__(44); var ListEventRenderer = /** @class */ (function (_super) { tslib_1.__extends(ListEventRenderer, _super); function ListEventRenderer() { return _super !== null && _super.apply(this, arguments) || this; } ListEventRenderer.prototype.renderFgSegs = function (segs) { if (!segs.length) { this.component.renderEmptyMessage(); } else { this.component.renderSegList(segs); } }; // generates the HTML for a single event row ListEventRenderer.prototype.fgSegHtml = function (seg) { var view = this.view; var calendar = view.calendar; var theme = calendar.theme; var eventFootprint = seg.footprint; var eventDef = eventFootprint.eventDef; var componentFootprint = eventFootprint.componentFootprint; var url = eventDef.url; var classes = ['fc-list-item'].concat(this.getClasses(eventDef)); var bgColor = this.getBgColor(eventDef); var timeHtml; if (componentFootprint.isAllDay) { timeHtml = view.getAllDayHtml(); } else if (view.isMultiDayRange(componentFootprint.unzonedRange)) { if (seg.isStart || seg.isEnd) { // outer segment that probably lasts part of the day timeHtml = util_1.htmlEscape(this._getTimeText(calendar.msToMoment(seg.startMs), calendar.msToMoment(seg.endMs), componentFootprint.isAllDay)); } else { // inner segment that lasts the whole day timeHtml = view.getAllDayHtml(); } } else { // Display the normal time text for the *event's* times timeHtml = util_1.htmlEscape(this.getTimeText(eventFootprint)); } if (url) { classes.push('fc-has-url'); } return '<tr class="' + classes.join(' ') + '">' + (this.displayEventTime ? '<td class="fc-list-item-time ' + theme.getClass('widgetContent') + '">' + (timeHtml || '') + '</td>' : '') + '<td class="fc-list-item-marker ' + theme.getClass('widgetContent') + '">' + '<span class="fc-event-dot"' + (bgColor ? ' style="background-color:' + bgColor + '"' : '') + '></span>' + '</td>' + '<td class="fc-list-item-title ' + theme.getClass('widgetContent') + '">' + '<a' + (url ? ' href="' + util_1.htmlEscape(url) + '"' : '') + '>' + util_1.htmlEscape(eventDef.title || '') + '</a>' + '</td>' + '</tr>'; }; // like "4:00am" ListEventRenderer.prototype.computeEventTimeFormat = function () { return this.opt('mediumTimeFormat'); }; return ListEventRenderer; }(EventRenderer_1.default)); exports.default = ListEventRenderer; /***/ }), /* 250 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var EventPointing_1 = __webpack_require__(64); var ListEventPointing = /** @class */ (function (_super) { tslib_1.__extends(ListEventPointing, _super); function ListEventPointing() { return _super !== null && _super.apply(this, arguments) || this; } // for events with a url, the whole <tr> should be clickable, // but it's impossible to wrap with an <a> tag. simulate this. ListEventPointing.prototype.handleClick = function (seg, ev) { var url; _super.prototype.handleClick.call(this, seg, ev); // might prevent the default action // not clicking on or within an <a> with an href if (!$(ev.target).closest('a[href]').length) { url = seg.footprint.eventDef.url; if (url && !ev.isDefaultPrevented()) { // jsEvent not cancelled in handler window.location.href = url; // simulate link click } } }; return ListEventPointing; }(EventPointing_1.default)); exports.default = ListEventPointing; /***/ }), /* 251 */, /* 252 */, /* 253 */, /* 254 */, /* 255 */, /* 256 */ /***/ (function(module, exports, __webpack_require__) { var $ = __webpack_require__(3); var exportHooks = __webpack_require__(18); var util_1 = __webpack_require__(4); var Calendar_1 = __webpack_require__(232); // for intentional side-effects __webpack_require__(11); __webpack_require__(49); __webpack_require__(260); __webpack_require__(261); __webpack_require__(264); __webpack_require__(265); __webpack_require__(266); __webpack_require__(267); $.fullCalendar = exportHooks; $.fn.fullCalendar = function (options) { var args = Array.prototype.slice.call(arguments, 1); // for a possible method call var res = this; // what this function will return (this jQuery object by default) this.each(function (i, _element) { var element = $(_element); var calendar = element.data('fullCalendar'); // get the existing calendar object (if any) var singleRes; // the returned value of this single method call // a method call if (typeof options === 'string') { if (options === 'getCalendar') { if (!i) { // first element only res = calendar; } } else if (options === 'destroy') { // don't warn if no calendar object if (calendar) { calendar.destroy(); element.removeData('fullCalendar'); } } else if (!calendar) { util_1.warn('Attempting to call a FullCalendar method on an element with no calendar.'); } else if ($.isFunction(calendar[options])) { singleRes = calendar[options].apply(calendar, args); if (!i) { res = singleRes; // record the first method call result } if (options === 'destroy') { // for the destroy method, must remove Calendar object data element.removeData('fullCalendar'); } } else { util_1.warn("'" + options + "' is an unknown FullCalendar method."); } } else if (!calendar) { // don't initialize twice calendar = new Calendar_1.default(element, options); element.data('fullCalendar', calendar); calendar.render(); } }); return res; }; module.exports = exportHooks; /***/ }), /* 257 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); /* Toolbar with buttons and title ----------------------------------------------------------------------------------------------------------------------*/ var Toolbar = /** @class */ (function () { function Toolbar(calendar, toolbarOptions) { this.el = null; // mirrors local `el` this.viewsWithButtons = []; this.calendar = calendar; this.toolbarOptions = toolbarOptions; } // method to update toolbar-specific options, not calendar-wide options Toolbar.prototype.setToolbarOptions = function (newToolbarOptions) { this.toolbarOptions = newToolbarOptions; }; // can be called repeatedly and will rerender Toolbar.prototype.render = function () { var sections = this.toolbarOptions.layout; var el = this.el; if (sections) { if (!el) { el = this.el = $("<div class='fc-toolbar " + this.toolbarOptions.extraClasses + "'/>"); } else { el.empty(); } el.append(this.renderSection('left')) .append(this.renderSection('right')) .append(this.renderSection('center')) .append('<div class="fc-clear"/>'); } else { this.removeElement(); } }; Toolbar.prototype.removeElement = function () { if (this.el) { this.el.remove(); this.el = null; } }; Toolbar.prototype.renderSection = function (position) { var _this = this; var calendar = this.calendar; var theme = calendar.theme; var optionsManager = calendar.optionsManager; var viewSpecManager = calendar.viewSpecManager; var sectionEl = $('<div class="fc-' + position + '"/>'); var buttonStr = this.toolbarOptions.layout[position]; var calendarCustomButtons = optionsManager.get('customButtons') || {}; var calendarButtonTextOverrides = optionsManager.overrides.buttonText || {}; var calendarButtonText = optionsManager.get('buttonText') || {}; if (buttonStr) { $.each(buttonStr.split(' '), function (i, buttonGroupStr) { var groupChildren = $(); var isOnlyButtons = true; var groupEl; $.each(buttonGroupStr.split(','), function (j, buttonName) { var customButtonProps; var viewSpec; var buttonClick; var buttonIcon; // only one of these will be set var buttonText; // " var buttonInnerHtml; var buttonClasses; var buttonEl; var buttonAriaAttr; if (buttonName === 'title') { groupChildren = groupChildren.add($('<h2> </h2>')); // we always want it to take up height isOnlyButtons = false; } else { if ((customButtonProps = calendarCustomButtons[buttonName])) { buttonClick = function (ev) { if (customButtonProps.click) { customButtonProps.click.call(buttonEl[0], ev); } }; (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) || (buttonIcon = theme.getIconClass(buttonName)) || (buttonText = customButtonProps.text); } else if ((viewSpec = viewSpecManager.getViewSpec(buttonName))) { _this.viewsWithButtons.push(buttonName); buttonClick = function () { calendar.changeView(buttonName); }; (buttonText = viewSpec.buttonTextOverride) || (buttonIcon = theme.getIconClass(buttonName)) || (buttonText = viewSpec.buttonTextDefault); } else if (calendar[buttonName]) { // a calendar method buttonClick = function () { calendar[buttonName](); }; (buttonText = calendarButtonTextOverrides[buttonName]) || (buttonIcon = theme.getIconClass(buttonName)) || (buttonText = calendarButtonText[buttonName]); // ^ everything else is considered default } if (buttonClick) { buttonClasses = [ 'fc-' + buttonName + '-button', theme.getClass('button'), theme.getClass('stateDefault') ]; if (buttonText) { buttonInnerHtml = util_1.htmlEscape(buttonText); buttonAriaAttr = ''; } else if (buttonIcon) { buttonInnerHtml = "<span class='" + buttonIcon + "'></span>"; buttonAriaAttr = ' aria-label="' + buttonName + '"'; } buttonEl = $(// type="button" so that it doesn't submit a form '<button type="button" class="' + buttonClasses.join(' ') + '"' + buttonAriaAttr + '>' + buttonInnerHtml + '</button>') .click(function (ev) { // don't process clicks for disabled buttons if (!buttonEl.hasClass(theme.getClass('stateDisabled'))) { buttonClick(ev); // after the click action, if the button becomes the "active" tab, or disabled, // it should never have a hover class, so remove it now. if (buttonEl.hasClass(theme.getClass('stateActive')) || buttonEl.hasClass(theme.getClass('stateDisabled'))) { buttonEl.removeClass(theme.getClass('stateHover')); } } }) .mousedown(function () { // the *down* effect (mouse pressed in). // only on buttons that are not the "active" tab, or disabled buttonEl .not('.' + theme.getClass('stateActive')) .not('.' + theme.getClass('stateDisabled')) .addClass(theme.getClass('stateDown')); }) .mouseup(function () { // undo the *down* effect buttonEl.removeClass(theme.getClass('stateDown')); }) .hover(function () { // the *hover* effect. // only on buttons that are not the "active" tab, or disabled buttonEl .not('.' + theme.getClass('stateActive')) .not('.' + theme.getClass('stateDisabled')) .addClass(theme.getClass('stateHover')); }, function () { // undo the *hover* effect buttonEl .removeClass(theme.getClass('stateHover')) .removeClass(theme.getClass('stateDown')); // if mouseleave happens before mouseup }); groupChildren = groupChildren.add(buttonEl); } } }); if (isOnlyButtons) { groupChildren .first().addClass(theme.getClass('cornerLeft')).end() .last().addClass(theme.getClass('cornerRight')).end(); } if (groupChildren.length > 1) { groupEl = $('<div/>'); if (isOnlyButtons) { groupEl.addClass(theme.getClass('buttonGroup')); } groupEl.append(groupChildren); sectionEl.append(groupEl); } else { sectionEl.append(groupChildren); // 1 or 0 children } }); } return sectionEl; }; Toolbar.prototype.updateTitle = function (text) { if (this.el) { this.el.find('h2').text(text); } }; Toolbar.prototype.activateButton = function (buttonName) { if (this.el) { this.el.find('.fc-' + buttonName + '-button') .addClass(this.calendar.theme.getClass('stateActive')); } }; Toolbar.prototype.deactivateButton = function (buttonName) { if (this.el) { this.el.find('.fc-' + buttonName + '-button') .removeClass(this.calendar.theme.getClass('stateActive')); } }; Toolbar.prototype.disableButton = function (buttonName) { if (this.el) { this.el.find('.fc-' + buttonName + '-button') .prop('disabled', true) .addClass(this.calendar.theme.getClass('stateDisabled')); } }; Toolbar.prototype.enableButton = function (buttonName) { if (this.el) { this.el.find('.fc-' + buttonName + '-button') .prop('disabled', false) .removeClass(this.calendar.theme.getClass('stateDisabled')); } }; Toolbar.prototype.getViewsWithButtons = function () { return this.viewsWithButtons; }; return Toolbar; }()); exports.default = Toolbar; /***/ }), /* 258 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var $ = __webpack_require__(3); var util_1 = __webpack_require__(4); var options_1 = __webpack_require__(33); var locale_1 = __webpack_require__(32); var Model_1 = __webpack_require__(51); var OptionsManager = /** @class */ (function (_super) { tslib_1.__extends(OptionsManager, _super); function OptionsManager(_calendar, overrides) { var _this = _super.call(this) || this; _this._calendar = _calendar; _this.overrides = $.extend({}, overrides); // make a copy _this.dynamicOverrides = {}; _this.compute(); return _this; } OptionsManager.prototype.add = function (newOptionHash) { var optionCnt = 0; var optionName; this.recordOverrides(newOptionHash); // will trigger this model's watchers for (optionName in newOptionHash) { optionCnt++; } // special-case handling of single option change. // if only one option change, `optionName` will be its name. if (optionCnt === 1) { if (optionName === 'height' || optionName === 'contentHeight' || optionName === 'aspectRatio') { this._calendar.updateViewSize(true); // isResize=true return; } else if (optionName === 'defaultDate') { return; // can't change date this way. use gotoDate instead } else if (optionName === 'businessHours') { return; // this model already reacts to this } else if (/^(event|select)(Overlap|Constraint|Allow)$/.test(optionName)) { return; // doesn't affect rendering. only interactions. } else if (optionName === 'timezone') { this._calendar.view.flash('initialEvents'); return; } } // catch-all. rerender the header and footer and rebuild/rerender the current view this._calendar.renderHeader(); this._calendar.renderFooter(); // even non-current views will be affected by this option change. do before rerender // TODO: detangle this._calendar.viewsByType = {}; this._calendar.reinitView(); }; // Computes the flattened options hash for the calendar and assigns to `this.options`. // Assumes this.overrides and this.dynamicOverrides have already been initialized. OptionsManager.prototype.compute = function () { var locale; var localeDefaults; var isRTL; var dirDefaults; var rawOptions; locale = util_1.firstDefined(// explicit locale option given? this.dynamicOverrides.locale, this.overrides.locale); localeDefaults = locale_1.localeOptionHash[locale]; if (!localeDefaults) { // explicit locale option not given or invalid? locale = options_1.globalDefaults.locale; localeDefaults = locale_1.localeOptionHash[locale] || {}; } isRTL = util_1.firstDefined(// based on options computed so far, is direction RTL? this.dynamicOverrides.isRTL, this.overrides.isRTL, localeDefaults.isRTL, options_1.globalDefaults.isRTL); dirDefaults = isRTL ? options_1.rtlDefaults : {}; this.dirDefaults = dirDefaults; this.localeDefaults = localeDefaults; rawOptions = options_1.mergeOptions([ options_1.globalDefaults, dirDefaults, localeDefaults, this.overrides, this.dynamicOverrides ]); locale_1.populateInstanceComputableOptions(rawOptions); // fill in gaps with computed options this.reset(rawOptions); }; // stores the new options internally, but does not rerender anything. OptionsManager.prototype.recordOverrides = function (newOptionHash) { var optionName; for (optionName in newOptionHash) { this.dynamicOverrides[optionName] = newOptionHash[optionName]; } this._calendar.viewSpecManager.clearCache(); // the dynamic override invalidates the options in this cache, so just clear it this.compute(); // this.options needs to be recomputed after the dynamic override }; return OptionsManager; }(Model_1.default)); exports.default = OptionsManager; /***/ }), /* 259 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var moment = __webpack_require__(0); var $ = __webpack_require__(3); var ViewRegistry_1 = __webpack_require__(24); var util_1 = __webpack_require__(4); var options_1 = __webpack_require__(33); var locale_1 = __webpack_require__(32); var ViewSpecManager = /** @class */ (function () { function ViewSpecManager(optionsManager, _calendar) { this.optionsManager = optionsManager; this._calendar = _calendar; this.clearCache(); } ViewSpecManager.prototype.clearCache = function () { this.viewSpecCache = {}; }; // Gets information about how to create a view. Will use a cache. ViewSpecManager.prototype.getViewSpec = function (viewType) { var cache = this.viewSpecCache; return cache[viewType] || (cache[viewType] = this.buildViewSpec(viewType)); }; // Given a duration singular unit, like "week" or "day", finds a matching view spec. // Preference is given to views that have corresponding buttons. ViewSpecManager.prototype.getUnitViewSpec = function (unit) { var viewTypes; var i; var spec; if ($.inArray(unit, util_1.unitsDesc) !== -1) { // put views that have buttons first. there will be duplicates, but oh well viewTypes = this._calendar.header.getViewsWithButtons(); // TODO: include footer as well? $.each(ViewRegistry_1.viewHash, function (viewType) { viewTypes.push(viewType); }); for (i = 0; i < viewTypes.length; i++) { spec = this.getViewSpec(viewTypes[i]); if (spec) { if (spec.singleUnit === unit) { return spec; } } } } }; // Builds an object with information on how to create a given view ViewSpecManager.prototype.buildViewSpec = function (requestedViewType) { var viewOverrides = this.optionsManager.overrides.views || {}; var specChain = []; // for the view. lowest to highest priority var defaultsChain = []; // for the view. lowest to highest priority var overridesChain = []; // for the view. lowest to highest priority var viewType = requestedViewType; var spec; // for the view var overrides; // for the view var durationInput; var duration; var unit; // iterate from the specific view definition to a more general one until we hit an actual View class while (viewType) { spec = ViewRegistry_1.viewHash[viewType]; overrides = viewOverrides[viewType]; viewType = null; // clear. might repopulate for another iteration if (typeof spec === 'function') { // TODO: deprecate spec = { 'class': spec }; } if (spec) { specChain.unshift(spec); defaultsChain.unshift(spec.defaults || {}); durationInput = durationInput || spec.duration; viewType = viewType || spec.type; } if (overrides) { overridesChain.unshift(overrides); // view-specific option hashes have options at zero-level durationInput = durationInput || overrides.duration; viewType = viewType || overrides.type; } } spec = util_1.mergeProps(specChain); spec.type = requestedViewType; if (!spec['class']) { return false; } // fall back to top-level `duration` option durationInput = durationInput || this.optionsManager.dynamicOverrides.duration || this.optionsManager.overrides.duration; if (durationInput) { duration = moment.duration(durationInput); if (duration.valueOf()) { // valid? unit = util_1.computeDurationGreatestUnit(duration, durationInput); spec.duration = duration; spec.durationUnit = unit; // view is a single-unit duration, like "week" or "day" // incorporate options for this. lowest priority if (duration.as(unit) === 1) { spec.singleUnit = unit; overridesChain.unshift(viewOverrides[unit] || {}); } } } spec.defaults = options_1.mergeOptions(defaultsChain); spec.overrides = options_1.mergeOptions(overridesChain); this.buildViewSpecOptions(spec); this.buildViewSpecButtonText(spec, requestedViewType); return spec; }; // Builds and assigns a view spec's options object from its already-assigned defaults and overrides ViewSpecManager.prototype.buildViewSpecOptions = function (spec) { var optionsManager = this.optionsManager; spec.options = options_1.mergeOptions([ options_1.globalDefaults, spec.defaults, optionsManager.dirDefaults, optionsManager.localeDefaults, optionsManager.overrides, spec.overrides, optionsManager.dynamicOverrides // dynamically set via setter. highest precedence ]); locale_1.populateInstanceComputableOptions(spec.options); }; // Computes and assigns a view spec's buttonText-related options ViewSpecManager.prototype.buildViewSpecButtonText = function (spec, requestedViewType) { var optionsManager = this.optionsManager; // given an options object with a possible `buttonText` hash, lookup the buttonText for the // requested view, falling back to a generic unit entry like "week" or "day" function queryButtonText(options) { var buttonText = options.buttonText || {}; return buttonText[requestedViewType] || // view can decide to look up a certain key (spec.buttonTextKey ? buttonText[spec.buttonTextKey] : null) || // a key like "month" (spec.singleUnit ? buttonText[spec.singleUnit] : null); } // highest to lowest priority spec.buttonTextOverride = queryButtonText(optionsManager.dynamicOverrides) || queryButtonText(optionsManager.overrides) || // constructor-specified buttonText lookup hash takes precedence spec.overrides.buttonText; // `buttonText` for view-specific options is a string // highest to lowest priority. mirrors buildViewSpecOptions spec.buttonTextDefault = queryButtonText(optionsManager.localeDefaults) || queryButtonText(optionsManager.dirDefaults) || spec.defaults.buttonText || // a single string. from ViewSubclass.defaults queryButtonText(options_1.globalDefaults) || (spec.duration ? this._calendar.humanizeDuration(spec.duration) : null) || // like "3 days" requestedViewType; // fall back to given view name }; return ViewSpecManager; }()); exports.default = ViewSpecManager; /***/ }), /* 260 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var EventSourceParser_1 = __webpack_require__(38); var ArrayEventSource_1 = __webpack_require__(56); var FuncEventSource_1 = __webpack_require__(223); var JsonFeedEventSource_1 = __webpack_require__(224); EventSourceParser_1.default.registerClass(ArrayEventSource_1.default); EventSourceParser_1.default.registerClass(FuncEventSource_1.default); EventSourceParser_1.default.registerClass(JsonFeedEventSource_1.default); /***/ }), /* 261 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var ThemeRegistry_1 = __webpack_require__(57); var StandardTheme_1 = __webpack_require__(221); var JqueryUiTheme_1 = __webpack_require__(222); var Bootstrap3Theme_1 = __webpack_require__(262); var Bootstrap4Theme_1 = __webpack_require__(263); ThemeRegistry_1.defineThemeSystem('standard', StandardTheme_1.default); ThemeRegistry_1.defineThemeSystem('jquery-ui', JqueryUiTheme_1.default); ThemeRegistry_1.defineThemeSystem('bootstrap3', Bootstrap3Theme_1.default); ThemeRegistry_1.defineThemeSystem('bootstrap4', Bootstrap4Theme_1.default); /***/ }), /* 262 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var Theme_1 = __webpack_require__(22); var Bootstrap3Theme = /** @class */ (function (_super) { tslib_1.__extends(Bootstrap3Theme, _super); function Bootstrap3Theme() { return _super !== null && _super.apply(this, arguments) || this; } return Bootstrap3Theme; }(Theme_1.default)); exports.default = Bootstrap3Theme; Bootstrap3Theme.prototype.classes = { widget: 'fc-bootstrap3', tableGrid: 'table-bordered', tableList: 'table', tableListHeading: 'active', buttonGroup: 'btn-group', button: 'btn btn-default', stateActive: 'active', stateDisabled: 'disabled', today: 'alert alert-info', popover: 'panel panel-default', popoverHeader: 'panel-heading', popoverContent: 'panel-body', // day grid // for left/right border color when border is inset from edges (all-day in agenda view) // avoid `panel` class b/c don't want margins/radius. only border color. headerRow: 'panel-default', dayRow: 'panel-default', // list view listView: 'panel panel-default' }; Bootstrap3Theme.prototype.baseIconClass = 'glyphicon'; Bootstrap3Theme.prototype.iconClasses = { close: 'glyphicon-remove', prev: 'glyphicon-chevron-left', next: 'glyphicon-chevron-right', prevYear: 'glyphicon-backward', nextYear: 'glyphicon-forward' }; Bootstrap3Theme.prototype.iconOverrideOption = 'bootstrapGlyphicons'; Bootstrap3Theme.prototype.iconOverrideCustomButtonOption = 'bootstrapGlyphicon'; Bootstrap3Theme.prototype.iconOverridePrefix = 'glyphicon-'; /***/ }), /* 263 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = __webpack_require__(2); var Theme_1 = __webpack_require__(22); var Bootstrap4Theme = /** @class */ (function (_super) { tslib_1.__extends(Bootstrap4Theme, _super); function Bootstrap4Theme() { return _super !== null && _super.apply(this, arguments) || this; } return Bootstrap4Theme; }(Theme_1.default)); exports.default = Bootstrap4Theme; Bootstrap4Theme.prototype.classes = { widget: 'fc-bootstrap4', tableGrid: 'table-bordered', tableList: 'table', tableListHeading: 'table-active', buttonGroup: 'btn-group', button: 'btn btn-primary', stateActive: 'active', stateDisabled: 'disabled', today: 'alert alert-info', popover: 'card card-primary', popoverHeader: 'card-header', popoverContent: 'card-body', // day grid // for left/right border color when border is inset from edges (all-day in agenda view) // avoid `table` class b/c don't want margins/padding/structure. only border color. headerRow: 'table-bordered', dayRow: 'table-bordered', // list view listView: 'card card-primary' }; Bootstrap4Theme.prototype.baseIconClass = 'fa'; Bootstrap4Theme.prototype.iconClasses = { close: 'fa-times', prev: 'fa-chevron-left', next: 'fa-chevron-right', prevYear: 'fa-angle-double-left', nextYear: 'fa-angle-double-right' }; Bootstrap4Theme.prototype.iconOverrideOption = 'bootstrapFontAwesome'; Bootstrap4Theme.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome'; Bootstrap4Theme.prototype.iconOverridePrefix = 'fa-'; /***/ }), /* 264 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var ViewRegistry_1 = __webpack_require__(24); var BasicView_1 = __webpack_require__(67); var MonthView_1 = __webpack_require__(246); ViewRegistry_1.defineView('basic', { 'class': BasicView_1.default }); ViewRegistry_1.defineView('basicDay', { type: 'basic', duration: { days: 1 } }); ViewRegistry_1.defineView('basicWeek', { type: 'basic', duration: { weeks: 1 } }); ViewRegistry_1.defineView('month', { 'class': MonthView_1.default, duration: { months: 1 }, defaults: { fixedWeekCount: true } }); /***/ }), /* 265 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var ViewRegistry_1 = __webpack_require__(24); var AgendaView_1 = __webpack_require__(238); ViewRegistry_1.defineView('agenda', { 'class': AgendaView_1.default, defaults: { allDaySlot: true, slotDuration: '00:30:00', slotEventOverlap: true // a bad name. confused with overlap/constraint system } }); ViewRegistry_1.defineView('agendaDay', { type: 'agenda', duration: { days: 1 } }); ViewRegistry_1.defineView('agendaWeek', { type: 'agenda', duration: { weeks: 1 } }); /***/ }), /* 266 */ /***/ (function(module, exports, __webpack_require__) { Object.defineProperty(exports, "__esModule", { value: true }); var ViewRegistry_1 = __webpack_require__(24); var ListView_1 = __webpack_require__(248); ViewRegistry_1.defineView('list', { 'class': ListView_1.default, buttonTextKey: 'list', defaults: { buttonText: 'list', listDayFormat: 'LL', noEventsMessage: 'No events to display' } }); ViewRegistry_1.defineView('listDay', { type: 'list', duration: { days: 1 }, defaults: { listDayFormat: 'dddd' // day-of-week is all we need. full date is probably in header } }); ViewRegistry_1.defineView('listWeek', { type: 'list', duration: { weeks: 1 }, defaults: { listDayFormat: 'dddd', listDayAltFormat: 'LL' } }); ViewRegistry_1.defineView('listMonth', { type: 'list', duration: { month: 1 }, defaults: { listDayAltFormat: 'dddd' // day-of-week is nice-to-have } }); ViewRegistry_1.defineView('listYear', { type: 'list', duration: { year: 1 }, defaults: { listDayAltFormat: 'dddd' // day-of-week is nice-to-have } }); /***/ }), /* 267 */ /***/ (function(module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); /***/ }) /******/ ]); }); }); define('moment', function (require, exports, module) { //! moment.js ;(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : global.moment = factory() }(this, (function () { 'use strict'; var hookCallback; function hooks () { return hookCallback.apply(null, arguments); } // This is done to register the method called with moment() // without creating circular dependencies. function setHookCallback (callback) { hookCallback = callback; } function isArray(input) { return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; } function isObject(input) { // IE8 will treat undefined and null as object if it wasn't for // input != null return input != null && Object.prototype.toString.call(input) === '[object Object]'; } function isObjectEmpty(obj) { if (Object.getOwnPropertyNames) { return (Object.getOwnPropertyNames(obj).length === 0); } else { var k; for (k in obj) { if (obj.hasOwnProperty(k)) { return false; } } return true; } } function isUndefined(input) { return input === void 0; } function isNumber(input) { return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; } function isDate(input) { return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; } function map(arr, fn) { var res = [], i; for (i = 0; i < arr.length; ++i) { res.push(fn(arr[i], i)); } return res; } function hasOwnProp(a, b) { return Object.prototype.hasOwnProperty.call(a, b); } function extend(a, b) { for (var i in b) { if (hasOwnProp(b, i)) { a[i] = b[i]; } } if (hasOwnProp(b, 'toString')) { a.toString = b.toString; } if (hasOwnProp(b, 'valueOf')) { a.valueOf = b.valueOf; } return a; } function createUTC (input, format, locale, strict) { return createLocalOrUTC(input, format, locale, strict, true).utc(); } function defaultParsingFlags() { // We need to deep clone this object. return { empty : false, unusedTokens : [], unusedInput : [], overflow : -2, charsLeftOver : 0, nullInput : false, invalidMonth : null, invalidFormat : false, userInvalidated : false, iso : false, parsedDateParts : [], meridiem : null, rfc2822 : false, weekdayMismatch : false }; } function getParsingFlags(m) { if (m._pf == null) { m._pf = defaultParsingFlags(); } return m._pf; } var some; if (Array.prototype.some) { some = Array.prototype.some; } else { some = function (fun) { var t = Object(this); var len = t.length >>> 0; for (var i = 0; i < len; i++) { if (i in t && fun.call(this, t[i], i, t)) { return true; } } return false; }; } function isValid(m) { if (m._isValid == null) { var flags = getParsingFlags(m); var parsedParts = some.call(flags.parsedDateParts, function (i) { return i != null; }); var isNowValid = !isNaN(m._d.getTime()) && flags.overflow < 0 && !flags.empty && !flags.invalidMonth && !flags.invalidWeekday && !flags.weekdayMismatch && !flags.nullInput && !flags.invalidFormat && !flags.userInvalidated && (!flags.meridiem || (flags.meridiem && parsedParts)); if (m._strict) { isNowValid = isNowValid && flags.charsLeftOver === 0 && flags.unusedTokens.length === 0 && flags.bigHour === undefined; } if (Object.isFrozen == null || !Object.isFrozen(m)) { m._isValid = isNowValid; } else { return isNowValid; } } return m._isValid; } function createInvalid (flags) { var m = createUTC(NaN); if (flags != null) { extend(getParsingFlags(m), flags); } else { getParsingFlags(m).userInvalidated = true; } return m; } // Plugins that add properties should also add the key here (null value), // so we can properly clone ourselves. var momentProperties = hooks.momentProperties = []; function copyConfig(to, from) { var i, prop, val; if (!isUndefined(from._isAMomentObject)) { to._isAMomentObject = from._isAMomentObject; } if (!isUndefined(from._i)) { to._i = from._i; } if (!isUndefined(from._f)) { to._f = from._f; } if (!isUndefined(from._l)) { to._l = from._l; } if (!isUndefined(from._strict)) { to._strict = from._strict; } if (!isUndefined(from._tzm)) { to._tzm = from._tzm; } if (!isUndefined(from._isUTC)) { to._isUTC = from._isUTC; } if (!isUndefined(from._offset)) { to._offset = from._offset; } if (!isUndefined(from._pf)) { to._pf = getParsingFlags(from); } if (!isUndefined(from._locale)) { to._locale = from._locale; } if (momentProperties.length > 0) { for (i = 0; i < momentProperties.length; i++) { prop = momentProperties[i]; val = from[prop]; if (!isUndefined(val)) { to[prop] = val; } } } return to; } var updateInProgress = false; // Moment prototype object function Moment(config) { copyConfig(this, config); this._d = new Date(config._d != null ? config._d.getTime() : NaN); if (!this.isValid()) { this._d = new Date(NaN); } // Prevent infinite loop in case updateOffset creates new moment // objects. if (updateInProgress === false) { updateInProgress = true; hooks.updateOffset(this); updateInProgress = false; } } function isMoment (obj) { return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); } function absFloor (number) { if (number < 0) { // -0 -> 0 return Math.ceil(number) || 0; } else { return Math.floor(number); } } function toInt(argumentForCoercion) { var coercedNumber = +argumentForCoercion, value = 0; if (coercedNumber !== 0 && isFinite(coercedNumber)) { value = absFloor(coercedNumber); } return value; } // compare two arrays, return the number of differences function compareArrays(array1, array2, dontConvert) { var len = Math.min(array1.length, array2.length), lengthDiff = Math.abs(array1.length - array2.length), diffs = 0, i; for (i = 0; i < len; i++) { if ((dontConvert && array1[i] !== array2[i]) || (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { diffs++; } } return diffs + lengthDiff; } function warn(msg) { if (hooks.suppressDeprecationWarnings === false && (typeof console !== 'undefined') && console.warn) { console.warn('Deprecation warning: ' + msg); } } function deprecate(msg, fn) { var firstTime = true; return extend(function () { if (hooks.deprecationHandler != null) { hooks.deprecationHandler(null, msg); } if (firstTime) { var args = []; var arg; for (var i = 0; i < arguments.length; i++) { arg = ''; if (typeof arguments[i] === 'object') { arg += '\n[' + i + '] '; for (var key in arguments[0]) { arg += key + ': ' + arguments[0][key] + ', '; } arg = arg.slice(0, -2); // Remove trailing comma and space } else { arg = arguments[i]; } args.push(arg); } warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack); firstTime = false; } return fn.apply(this, arguments); }, fn); } var deprecations = {}; function deprecateSimple(name, msg) { if (hooks.deprecationHandler != null) { hooks.deprecationHandler(name, msg); } if (!deprecations[name]) { warn(msg); deprecations[name] = true; } } hooks.suppressDeprecationWarnings = false; hooks.deprecationHandler = null; function isFunction(input) { return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; } function set (config) { var prop, i; for (i in config) { prop = config[i]; if (isFunction(prop)) { this[i] = prop; } else { this['_' + i] = prop; } } this._config = config; // Lenient ordinal parsing accepts just a number in addition to // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. // TODO: Remove "ordinalParse" fallback in next major release. this._dayOfMonthOrdinalParseLenient = new RegExp( (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + '|' + (/\d{1,2}/).source); } function mergeConfigs(parentConfig, childConfig) { var res = extend({}, parentConfig), prop; for (prop in childConfig) { if (hasOwnProp(childConfig, prop)) { if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { res[prop] = {}; extend(res[prop], parentConfig[prop]); extend(res[prop], childConfig[prop]); } else if (childConfig[prop] != null) { res[prop] = childConfig[prop]; } else { delete res[prop]; } } } for (prop in parentConfig) { if (hasOwnProp(parentConfig, prop) && !hasOwnProp(childConfig, prop) && isObject(parentConfig[prop])) { // make sure changes to properties don't modify parent config res[prop] = extend({}, res[prop]); } } return res; } function Locale(config) { if (config != null) { this.set(config); } } var keys; if (Object.keys) { keys = Object.keys; } else { keys = function (obj) { var i, res = []; for (i in obj) { if (hasOwnProp(obj, i)) { res.push(i); } } return res; }; } var defaultCalendar = { sameDay : '[Today at] LT', nextDay : '[Tomorrow at] LT', nextWeek : 'dddd [at] LT', lastDay : '[Yesterday at] LT', lastWeek : '[Last] dddd [at] LT', sameElse : 'L' }; function calendar (key, mom, now) { var output = this._calendar[key] || this._calendar['sameElse']; return isFunction(output) ? output.call(mom, now) : output; } var defaultLongDateFormat = { LTS : 'h:mm:ss A', LT : 'h:mm A', L : 'MM/DD/YYYY', LL : 'MMMM D, YYYY', LLL : 'MMMM D, YYYY h:mm A', LLLL : 'dddd, MMMM D, YYYY h:mm A' }; function longDateFormat (key) { var format = this._longDateFormat[key], formatUpper = this._longDateFormat[key.toUpperCase()]; if (format || !formatUpper) { return format; } this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { return val.slice(1); }); return this._longDateFormat[key]; } var defaultInvalidDate = 'Invalid date'; function invalidDate () { return this._invalidDate; } var defaultOrdinal = '%d'; var defaultDayOfMonthOrdinalParse = /\d{1,2}/; function ordinal (number) { return this._ordinal.replace('%d', number); } var defaultRelativeTime = { future : 'in %s', past : '%s ago', s : 'a few seconds', ss : '%d seconds', m : 'a minute', mm : '%d minutes', h : 'an hour', hh : '%d hours', d : 'a day', dd : '%d days', M : 'a month', MM : '%d months', y : 'a year', yy : '%d years' }; function relativeTime (number, withoutSuffix, string, isFuture) { var output = this._relativeTime[string]; return (isFunction(output)) ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number); } function pastFuture (diff, output) { var format = this._relativeTime[diff > 0 ? 'future' : 'past']; return isFunction(format) ? format(output) : format.replace(/%s/i, output); } var aliases = {}; function addUnitAlias (unit, shorthand) { var lowerCase = unit.toLowerCase(); aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; } function normalizeUnits(units) { return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; } function normalizeObjectUnits(inputObject) { var normalizedInput = {}, normalizedProp, prop; for (prop in inputObject) { if (hasOwnProp(inputObject, prop)) { normalizedProp = normalizeUnits(prop); if (normalizedProp) { normalizedInput[normalizedProp] = inputObject[prop]; } } } return normalizedInput; } var priorities = {}; function addUnitPriority(unit, priority) { priorities[unit] = priority; } function getPrioritizedUnits(unitsObj) { var units = []; for (var u in unitsObj) { units.push({unit: u, priority: priorities[u]}); } units.sort(function (a, b) { return a.priority - b.priority; }); return units; } function zeroFill(number, targetLength, forceSign) { var absNumber = '' + Math.abs(number), zerosToFill = targetLength - absNumber.length, sign = number >= 0; return (sign ? (forceSign ? '+' : '') : '-') + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; } var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; var formatFunctions = {}; var formatTokenFunctions = {}; // token: 'M' // padded: ['MM', 2] // ordinal: 'Mo' // callback: function () { this.month() + 1 } function addFormatToken (token, padded, ordinal, callback) { var func = callback; if (typeof callback === 'string') { func = function () { return this[callback](); }; } if (token) { formatTokenFunctions[token] = func; } if (padded) { formatTokenFunctions[padded[0]] = function () { return zeroFill(func.apply(this, arguments), padded[1], padded[2]); }; } if (ordinal) { formatTokenFunctions[ordinal] = function () { return this.localeData().ordinal(func.apply(this, arguments), token); }; } } function removeFormattingTokens(input) { if (input.match(/\[[\s\S]/)) { return input.replace(/^\[|\]$/g, ''); } return input.replace(/\\/g, ''); } function makeFormatFunction(format) { var array = format.match(formattingTokens), i, length; for (i = 0, length = array.length; i < length; i++) { if (formatTokenFunctions[array[i]]) { array[i] = formatTokenFunctions[array[i]]; } else { array[i] = removeFormattingTokens(array[i]); } } return function (mom) { var output = '', i; for (i = 0; i < length; i++) { output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; } return output; }; } // format date using native date object function formatMoment(m, format) { if (!m.isValid()) { return m.localeData().invalidDate(); } format = expandFormat(format, m.localeData()); formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); return formatFunctions[format](m); } function expandFormat(format, locale) { var i = 5; function replaceLongDateFormatTokens(input) { return locale.longDateFormat(input) || input; } localFormattingTokens.lastIndex = 0; while (i >= 0 && localFormattingTokens.test(format)) { format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); localFormattingTokens.lastIndex = 0; i -= 1; } return format; } var match1 = /\d/; // 0 - 9 var match2 = /\d\d/; // 00 - 99 var match3 = /\d{3}/; // 000 - 999 var match4 = /\d{4}/; // 0000 - 9999 var match6 = /[+-]?\d{6}/; // -999999 - 999999 var match1to2 = /\d\d?/; // 0 - 99 var match3to4 = /\d\d\d\d?/; // 999 - 9999 var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 var match1to3 = /\d{1,3}/; // 0 - 999 var match1to4 = /\d{1,4}/; // 0 - 9999 var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 var matchUnsigned = /\d+/; // 0 - inf var matchSigned = /[+-]?\d+/; // -inf - inf var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 // any word (or two) characters or numbers including two/three word month in arabic. // includes scottish gaelic two word and hyphenated months var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i; var regexes = {}; function addRegexToken (token, regex, strictRegex) { regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { return (isStrict && strictRegex) ? strictRegex : regex; }; } function getParseRegexForToken (token, config) { if (!hasOwnProp(regexes, token)) { return new RegExp(unescapeFormat(token)); } return regexes[token](config._strict, config._locale); } // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript function unescapeFormat(s) { return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { return p1 || p2 || p3 || p4; })); } function regexEscape(s) { return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); } var tokens = {}; function addParseToken (token, callback) { var i, func = callback; if (typeof token === 'string') { token = [token]; } if (isNumber(callback)) { func = function (input, array) { array[callback] = toInt(input); }; } for (i = 0; i < token.length; i++) { tokens[token[i]] = func; } } function addWeekParseToken (token, callback) { addParseToken(token, function (input, array, config, token) { config._w = config._w || {}; callback(input, config._w, config, token); }); } function addTimeToArrayFromToken(token, input, config) { if (input != null && hasOwnProp(tokens, token)) { tokens[token](input, config._a, config, token); } } var YEAR = 0; var MONTH = 1; var DATE = 2; var HOUR = 3; var MINUTE = 4; var SECOND = 5; var MILLISECOND = 6; var WEEK = 7; var WEEKDAY = 8; // FORMATTING addFormatToken('Y', 0, 0, function () { var y = this.year(); return y <= 9999 ? '' + y : '+' + y; }); addFormatToken(0, ['YY', 2], 0, function () { return this.year() % 100; }); addFormatToken(0, ['YYYY', 4], 0, 'year'); addFormatToken(0, ['YYYYY', 5], 0, 'year'); addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); // ALIASES addUnitAlias('year', 'y'); // PRIORITIES addUnitPriority('year', 1); // PARSING addRegexToken('Y', matchSigned); addRegexToken('YY', match1to2, match2); addRegexToken('YYYY', match1to4, match4); addRegexToken('YYYYY', match1to6, match6); addRegexToken('YYYYYY', match1to6, match6); addParseToken(['YYYYY', 'YYYYYY'], YEAR); addParseToken('YYYY', function (input, array) { array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); }); addParseToken('YY', function (input, array) { array[YEAR] = hooks.parseTwoDigitYear(input); }); addParseToken('Y', function (input, array) { array[YEAR] = parseInt(input, 10); }); // HELPERS function daysInYear(year) { return isLeapYear(year) ? 366 : 365; } function isLeapYear(year) { return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; } // HOOKS hooks.parseTwoDigitYear = function (input) { return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); }; // MOMENTS var getSetYear = makeGetSet('FullYear', true); function getIsLeapYear () { return isLeapYear(this.year()); } function makeGetSet (unit, keepTime) { return function (value) { if (value != null) { set$1(this, unit, value); hooks.updateOffset(this, keepTime); return this; } else { return get(this, unit); } }; } function get (mom, unit) { return mom.isValid() ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; } function set$1 (mom, unit, value) { if (mom.isValid() && !isNaN(value)) { if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); } else { mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); } } } // MOMENTS function stringGet (units) { units = normalizeUnits(units); if (isFunction(this[units])) { return this[units](); } return this; } function stringSet (units, value) { if (typeof units === 'object') { units = normalizeObjectUnits(units); var prioritized = getPrioritizedUnits(units); for (var i = 0; i < prioritized.length; i++) { this[prioritized[i].unit](units[prioritized[i].unit]); } } else { units = normalizeUnits(units); if (isFunction(this[units])) { return this[units](value); } } return this; } function mod(n, x) { return ((n % x) + x) % x; } var indexOf; if (Array.prototype.indexOf) { indexOf = Array.prototype.indexOf; } else { indexOf = function (o) { // I know var i; for (i = 0; i < this.length; ++i) { if (this[i] === o) { return i; } } return -1; }; } function daysInMonth(year, month) { if (isNaN(year) || isNaN(month)) { return NaN; } var modMonth = mod(month, 12); year += (month - modMonth) / 12; return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); } // FORMATTING addFormatToken('M', ['MM', 2], 'Mo', function () { return this.month() + 1; }); addFormatToken('MMM', 0, 0, function (format) { return this.localeData().monthsShort(this, format); }); addFormatToken('MMMM', 0, 0, function (format) { return this.localeData().months(this, format); }); // ALIASES addUnitAlias('month', 'M'); // PRIORITY addUnitPriority('month', 8); // PARSING addRegexToken('M', match1to2); addRegexToken('MM', match1to2, match2); addRegexToken('MMM', function (isStrict, locale) { return locale.monthsShortRegex(isStrict); }); addRegexToken('MMMM', function (isStrict, locale) { return locale.monthsRegex(isStrict); }); addParseToken(['M', 'MM'], function (input, array) { array[MONTH] = toInt(input) - 1; }); addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { var month = config._locale.monthsParse(input, token, config._strict); // if we didn't find a month name, mark the date as invalid. if (month != null) { array[MONTH] = month; } else { getParsingFlags(config).invalidMonth = input; } }); // LOCALES var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); function localeMonths (m, format) { if (!m) { return isArray(this._months) ? this._months : this._months['standalone']; } return isArray(this._months) ? this._months[m.month()] : this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; } var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); function localeMonthsShort (m, format) { if (!m) { return isArray(this._monthsShort) ? this._monthsShort : this._monthsShort['standalone']; } return isArray(this._monthsShort) ? this._monthsShort[m.month()] : this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; } function handleStrictParse(monthName, format, strict) { var i, ii, mom, llc = monthName.toLocaleLowerCase(); if (!this._monthsParse) { // this is not used this._monthsParse = []; this._longMonthsParse = []; this._shortMonthsParse = []; for (i = 0; i < 12; ++i) { mom = createUTC([2000, i]); this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); } } if (strict) { if (format === 'MMM') { ii = indexOf.call(this._shortMonthsParse, llc); return ii !== -1 ? ii : null; } else { ii = indexOf.call(this._longMonthsParse, llc); return ii !== -1 ? ii : null; } } else { if (format === 'MMM') { ii = indexOf.call(this._shortMonthsParse, llc); if (ii !== -1) { return ii; } ii = indexOf.call(this._longMonthsParse, llc); return ii !== -1 ? ii : null; } else { ii = indexOf.call(this._longMonthsParse, llc); if (ii !== -1) { return ii; } ii = indexOf.call(this._shortMonthsParse, llc); return ii !== -1 ? ii : null; } } } function localeMonthsParse (monthName, format, strict) { var i, mom, regex; if (this._monthsParseExact) { return handleStrictParse.call(this, monthName, format, strict); } if (!this._monthsParse) { this._monthsParse = []; this._longMonthsParse = []; this._shortMonthsParse = []; } // TODO: add sorting // Sorting makes sure if one month (or abbr) is a prefix of another // see sorting in computeMonthsParse for (i = 0; i < 12; i++) { // make the regex if we don't have it already mom = createUTC([2000, i]); if (strict && !this._longMonthsParse[i]) { this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); } if (!strict && !this._monthsParse[i]) { regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); } // test the regex if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { return i; } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { return i; } else if (!strict && this._monthsParse[i].test(monthName)) { return i; } } } // MOMENTS function setMonth (mom, value) { var dayOfMonth; if (!mom.isValid()) { // No op return mom; } if (typeof value === 'string') { if (/^\d+$/.test(value)) { value = toInt(value); } else { value = mom.localeData().monthsParse(value); // TODO: Another silent failure? if (!isNumber(value)) { return mom; } } } dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); return mom; } function getSetMonth (value) { if (value != null) { setMonth(this, value); hooks.updateOffset(this, true); return this; } else { return get(this, 'Month'); } } function getDaysInMonth () { return daysInMonth(this.year(), this.month()); } var defaultMonthsShortRegex = matchWord; function monthsShortRegex (isStrict) { if (this._monthsParseExact) { if (!hasOwnProp(this, '_monthsRegex')) { computeMonthsParse.call(this); } if (isStrict) { return this._monthsShortStrictRegex; } else { return this._monthsShortRegex; } } else { if (!hasOwnProp(this, '_monthsShortRegex')) { this._monthsShortRegex = defaultMonthsShortRegex; } return this._monthsShortStrictRegex && isStrict ? this._monthsShortStrictRegex : this._monthsShortRegex; } } var defaultMonthsRegex = matchWord; function monthsRegex (isStrict) { if (this._monthsParseExact) { if (!hasOwnProp(this, '_monthsRegex')) { computeMonthsParse.call(this); } if (isStrict) { return this._monthsStrictRegex; } else { return this._monthsRegex; } } else { if (!hasOwnProp(this, '_monthsRegex')) { this._monthsRegex = defaultMonthsRegex; } return this._monthsStrictRegex && isStrict ? this._monthsStrictRegex : this._monthsRegex; } } function computeMonthsParse () { function cmpLenRev(a, b) { return b.length - a.length; } var shortPieces = [], longPieces = [], mixedPieces = [], i, mom; for (i = 0; i < 12; i++) { // make the regex if we don't have it already mom = createUTC([2000, i]); shortPieces.push(this.monthsShort(mom, '')); longPieces.push(this.months(mom, '')); mixedPieces.push(this.months(mom, '')); mixedPieces.push(this.monthsShort(mom, '')); } // Sorting makes sure if one month (or abbr) is a prefix of another it // will match the longer piece. shortPieces.sort(cmpLenRev); longPieces.sort(cmpLenRev); mixedPieces.sort(cmpLenRev); for (i = 0; i < 12; i++) { shortPieces[i] = regexEscape(shortPieces[i]); longPieces[i] = regexEscape(longPieces[i]); } for (i = 0; i < 24; i++) { mixedPieces[i] = regexEscape(mixedPieces[i]); } this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); this._monthsShortRegex = this._monthsRegex; this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); } function createDate (y, m, d, h, M, s, ms) { // can't just apply() to create a date: // https://stackoverflow.com/q/181348 var date; // the date constructor remaps years 0-99 to 1900-1999 if (y < 100 && y >= 0) { // preserve leap years using a full 400 year cycle, then reset date = new Date(y + 400, m, d, h, M, s, ms); if (isFinite(date.getFullYear())) { date.setFullYear(y); } } else { date = new Date(y, m, d, h, M, s, ms); } return date; } function createUTCDate (y) { var date; // the Date.UTC function remaps years 0-99 to 1900-1999 if (y < 100 && y >= 0) { var args = Array.prototype.slice.call(arguments); // preserve leap years using a full 400 year cycle, then reset args[0] = y + 400; date = new Date(Date.UTC.apply(null, args)); if (isFinite(date.getUTCFullYear())) { date.setUTCFullYear(y); } } else { date = new Date(Date.UTC.apply(null, arguments)); } return date; } // start-of-first-week - start-of-year function firstWeekOffset(year, dow, doy) { var // first-week day -- which january is always in the first week (4 for iso, 1 for other) fwd = 7 + dow - doy, // first-week day local weekday -- which local weekday is fwd fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; return -fwdlw + fwd - 1; } // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday function dayOfYearFromWeeks(year, week, weekday, dow, doy) { var localWeekday = (7 + weekday - dow) % 7, weekOffset = firstWeekOffset(year, dow, doy), dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, resYear, resDayOfYear; if (dayOfYear <= 0) { resYear = year - 1; resDayOfYear = daysInYear(resYear) + dayOfYear; } else if (dayOfYear > daysInYear(year)) { resYear = year + 1; resDayOfYear = dayOfYear - daysInYear(year); } else { resYear = year; resDayOfYear = dayOfYear; } return { year: resYear, dayOfYear: resDayOfYear }; } function weekOfYear(mom, dow, doy) { var weekOffset = firstWeekOffset(mom.year(), dow, doy), week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, resWeek, resYear; if (week < 1) { resYear = mom.year() - 1; resWeek = week + weeksInYear(resYear, dow, doy); } else if (week > weeksInYear(mom.year(), dow, doy)) { resWeek = week - weeksInYear(mom.year(), dow, doy); resYear = mom.year() + 1; } else { resYear = mom.year(); resWeek = week; } return { week: resWeek, year: resYear }; } function weeksInYear(year, dow, doy) { var weekOffset = firstWeekOffset(year, dow, doy), weekOffsetNext = firstWeekOffset(year + 1, dow, doy); return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; } // FORMATTING addFormatToken('w', ['ww', 2], 'wo', 'week'); addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); // ALIASES addUnitAlias('week', 'w'); addUnitAlias('isoWeek', 'W'); // PRIORITIES addUnitPriority('week', 5); addUnitPriority('isoWeek', 5); // PARSING addRegexToken('w', match1to2); addRegexToken('ww', match1to2, match2); addRegexToken('W', match1to2); addRegexToken('WW', match1to2, match2); addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { week[token.substr(0, 1)] = toInt(input); }); // HELPERS // LOCALES function localeWeek (mom) { return weekOfYear(mom, this._week.dow, this._week.doy).week; } var defaultLocaleWeek = { dow : 0, // Sunday is the first day of the week. doy : 6 // The week that contains Jan 6th is the first week of the year. }; function localeFirstDayOfWeek () { return this._week.dow; } function localeFirstDayOfYear () { return this._week.doy; } // MOMENTS function getSetWeek (input) { var week = this.localeData().week(this); return input == null ? week : this.add((input - week) * 7, 'd'); } function getSetISOWeek (input) { var week = weekOfYear(this, 1, 4).week; return input == null ? week : this.add((input - week) * 7, 'd'); } // FORMATTING addFormatToken('d', 0, 'do', 'day'); addFormatToken('dd', 0, 0, function (format) { return this.localeData().weekdaysMin(this, format); }); addFormatToken('ddd', 0, 0, function (format) { return this.localeData().weekdaysShort(this, format); }); addFormatToken('dddd', 0, 0, function (format) { return this.localeData().weekdays(this, format); }); addFormatToken('e', 0, 0, 'weekday'); addFormatToken('E', 0, 0, 'isoWeekday'); // ALIASES addUnitAlias('day', 'd'); addUnitAlias('weekday', 'e'); addUnitAlias('isoWeekday', 'E'); // PRIORITY addUnitPriority('day', 11); addUnitPriority('weekday', 11); addUnitPriority('isoWeekday', 11); // PARSING addRegexToken('d', match1to2); addRegexToken('e', match1to2); addRegexToken('E', match1to2); addRegexToken('dd', function (isStrict, locale) { return locale.weekdaysMinRegex(isStrict); }); addRegexToken('ddd', function (isStrict, locale) { return locale.weekdaysShortRegex(isStrict); }); addRegexToken('dddd', function (isStrict, locale) { return locale.weekdaysRegex(isStrict); }); addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { var weekday = config._locale.weekdaysParse(input, token, config._strict); // if we didn't get a weekday name, mark the date as invalid if (weekday != null) { week.d = weekday; } else { getParsingFlags(config).invalidWeekday = input; } }); addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { week[token] = toInt(input); }); // HELPERS function parseWeekday(input, locale) { if (typeof input !== 'string') { return input; } if (!isNaN(input)) { return parseInt(input, 10); } input = locale.weekdaysParse(input); if (typeof input === 'number') { return input; } return null; } function parseIsoWeekday(input, locale) { if (typeof input === 'string') { return locale.weekdaysParse(input) % 7 || 7; } return isNaN(input) ? null : input; } // LOCALES function shiftWeekdays (ws, n) { return ws.slice(n, 7).concat(ws.slice(0, n)); } var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); function localeWeekdays (m, format) { var weekdays = isArray(this._weekdays) ? this._weekdays : this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone']; return (m === true) ? shiftWeekdays(weekdays, this._week.dow) : (m) ? weekdays[m.day()] : weekdays; } var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); function localeWeekdaysShort (m) { return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow) : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort; } var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); function localeWeekdaysMin (m) { return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow) : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin; } function handleStrictParse$1(weekdayName, format, strict) { var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); if (!this._weekdaysParse) { this._weekdaysParse = []; this._shortWeekdaysParse = []; this._minWeekdaysParse = []; for (i = 0; i < 7; ++i) { mom = createUTC([2000, 1]).day(i); this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); } } if (strict) { if (format === 'dddd') { ii = indexOf.call(this._weekdaysParse, llc); return ii !== -1 ? ii : null; } else if (format === 'ddd') { ii = indexOf.call(this._shortWeekdaysParse, llc); return ii !== -1 ? ii : null; } else { ii = indexOf.call(this._minWeekdaysParse, llc); return ii !== -1 ? ii : null; } } else { if (format === 'dddd') { ii = indexOf.call(this._weekdaysParse, llc); if (ii !== -1) { return ii; } ii = indexOf.call(this._shortWeekdaysParse, llc); if (ii !== -1) { return ii; } ii = indexOf.call(this._minWeekdaysParse, llc); return ii !== -1 ? ii : null; } else if (format === 'ddd') { ii = indexOf.call(this._shortWeekdaysParse, llc); if (ii !== -1) { return ii; } ii = indexOf.call(this._weekdaysParse, llc); if (ii !== -1) { return ii; } ii = indexOf.call(this._minWeekdaysParse, llc); return ii !== -1 ? ii : null; } else { ii = indexOf.call(this._minWeekdaysParse, llc); if (ii !== -1) { return ii; } ii = indexOf.call(this._weekdaysParse, llc); if (ii !== -1) { return ii; } ii = indexOf.call(this._shortWeekdaysParse, llc); return ii !== -1 ? ii : null; } } } function localeWeekdaysParse (weekdayName, format, strict) { var i, mom, regex; if (this._weekdaysParseExact) { return handleStrictParse$1.call(this, weekdayName, format, strict); } if (!this._weekdaysParse) { this._weekdaysParse = []; this._minWeekdaysParse = []; this._shortWeekdaysParse = []; this._fullWeekdaysParse = []; } for (i = 0; i < 7; i++) { // make the regex if we don't have it already mom = createUTC([2000, 1]).day(i); if (strict && !this._fullWeekdaysParse[i]) { this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i'); this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i'); this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i'); } if (!this._weekdaysParse[i]) { regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); } // test the regex if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { return i; } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { return i; } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { return i; } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { return i; } } } // MOMENTS function getSetDayOfWeek (input) { if (!this.isValid()) { return input != null ? this : NaN; } var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); if (input != null) { input = parseWeekday(input, this.localeData()); return this.add(input - day, 'd'); } else { return day; } } function getSetLocaleDayOfWeek (input) { if (!this.isValid()) { return input != null ? this : NaN; } var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; return input == null ? weekday : this.add(input - weekday, 'd'); } function getSetISODayOfWeek (input) { if (!this.isValid()) { return input != null ? this : NaN; } // behaves the same as moment#day except // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) // as a setter, sunday should belong to the previous week. if (input != null) { var weekday = parseIsoWeekday(input, this.localeData()); return this.day(this.day() % 7 ? weekday : weekday - 7); } else { return this.day() || 7; } } var defaultWeekdaysRegex = matchWord; function weekdaysRegex (isStrict) { if (this._weekdaysParseExact) { if (!hasOwnProp(this, '_weekdaysRegex')) { computeWeekdaysParse.call(this); } if (isStrict) { return this._weekdaysStrictRegex; } else { return this._weekdaysRegex; } } else { if (!hasOwnProp(this, '_weekdaysRegex')) { this._weekdaysRegex = defaultWeekdaysRegex; } return this._weekdaysStrictRegex && isStrict ? this._weekdaysStrictRegex : this._weekdaysRegex; } } var defaultWeekdaysShortRegex = matchWord; function weekdaysShortRegex (isStrict) { if (this._weekdaysParseExact) { if (!hasOwnProp(this, '_weekdaysRegex')) { computeWeekdaysParse.call(this); } if (isStrict) { return this._weekdaysShortStrictRegex; } else { return this._weekdaysShortRegex; } } else { if (!hasOwnProp(this, '_weekdaysShortRegex')) { this._weekdaysShortRegex = defaultWeekdaysShortRegex; } return this._weekdaysShortStrictRegex && isStrict ? this._weekdaysShortStrictRegex : this._weekdaysShortRegex; } } var defaultWeekdaysMinRegex = matchWord; function weekdaysMinRegex (isStrict) { if (this._weekdaysParseExact) { if (!hasOwnProp(this, '_weekdaysRegex')) { computeWeekdaysParse.call(this); } if (isStrict) { return this._weekdaysMinStrictRegex; } else { return this._weekdaysMinRegex; } } else { if (!hasOwnProp(this, '_weekdaysMinRegex')) { this._weekdaysMinRegex = defaultWeekdaysMinRegex; } return this._weekdaysMinStrictRegex && isStrict ? this._weekdaysMinStrictRegex : this._weekdaysMinRegex; } } function computeWeekdaysParse () { function cmpLenRev(a, b) { return b.length - a.length; } var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], i, mom, minp, shortp, longp; for (i = 0; i < 7; i++) { // make the regex if we don't have it already mom = createUTC([2000, 1]).day(i); minp = this.weekdaysMin(mom, ''); shortp = this.weekdaysShort(mom, ''); longp = this.weekdays(mom, ''); minPieces.push(minp); shortPieces.push(shortp); longPieces.push(longp); mixedPieces.push(minp); mixedPieces.push(shortp); mixedPieces.push(longp); } // Sorting makes sure if one weekday (or abbr) is a prefix of another it // will match the longer piece. minPieces.sort(cmpLenRev); shortPieces.sort(cmpLenRev); longPieces.sort(cmpLenRev); mixedPieces.sort(cmpLenRev); for (i = 0; i < 7; i++) { shortPieces[i] = regexEscape(shortPieces[i]); longPieces[i] = regexEscape(longPieces[i]); mixedPieces[i] = regexEscape(mixedPieces[i]); } this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); this._weekdaysShortRegex = this._weekdaysRegex; this._weekdaysMinRegex = this._weekdaysRegex; this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); } // FORMATTING function hFormat() { return this.hours() % 12 || 12; } function kFormat() { return this.hours() || 24; } addFormatToken('H', ['HH', 2], 0, 'hour'); addFormatToken('h', ['hh', 2], 0, hFormat); addFormatToken('k', ['kk', 2], 0, kFormat); addFormatToken('hmm', 0, 0, function () { return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); }); addFormatToken('hmmss', 0, 0, function () { return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2); }); addFormatToken('Hmm', 0, 0, function () { return '' + this.hours() + zeroFill(this.minutes(), 2); }); addFormatToken('Hmmss', 0, 0, function () { return '' + this.hours() + zeroFill(this.minutes(), 2) + zeroFill(this.seconds(), 2); }); function meridiem (token, lowercase) { addFormatToken(token, 0, 0, function () { return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); }); } meridiem('a', true); meridiem('A', false); // ALIASES addUnitAlias('hour', 'h'); // PRIORITY addUnitPriority('hour', 13); // PARSING function matchMeridiem (isStrict, locale) { return locale._meridiemParse; } addRegexToken('a', matchMeridiem); addRegexToken('A', matchMeridiem); addRegexToken('H', match1to2); addRegexToken('h', match1to2); addRegexToken('k', match1to2); addRegexToken('HH', match1to2, match2); addRegexToken('hh', match1to2, match2); addRegexToken('kk', match1to2, match2); addRegexToken('hmm', match3to4); addRegexToken('hmmss', match5to6); addRegexToken('Hmm', match3to4); addRegexToken('Hmmss', match5to6); addParseToken(['H', 'HH'], HOUR); addParseToken(['k', 'kk'], function (input, array, config) { var kInput = toInt(input); array[HOUR] = kInput === 24 ? 0 : kInput; }); addParseToken(['a', 'A'], function (input, array, config) { config._isPm = config._locale.isPM(input); config._meridiem = input; }); addParseToken(['h', 'hh'], function (input, array, config) { array[HOUR] = toInt(input); getParsingFlags(config).bigHour = true; }); addParseToken('hmm', function (input, array, config) { var pos = input.length - 2; array[HOUR] = toInt(input.substr(0, pos)); array[MINUTE] = toInt(input.substr(pos)); getParsingFlags(config).bigHour = true; }); addParseToken('hmmss', function (input, array, config) { var pos1 = input.length - 4; var pos2 = input.length - 2; array[HOUR] = toInt(input.substr(0, pos1)); array[MINUTE] = toInt(input.substr(pos1, 2)); array[SECOND] = toInt(input.substr(pos2)); getParsingFlags(config).bigHour = true; }); addParseToken('Hmm', function (input, array, config) { var pos = input.length - 2; array[HOUR] = toInt(input.substr(0, pos)); array[MINUTE] = toInt(input.substr(pos)); }); addParseToken('Hmmss', function (input, array, config) { var pos1 = input.length - 4; var pos2 = input.length - 2; array[HOUR] = toInt(input.substr(0, pos1)); array[MINUTE] = toInt(input.substr(pos1, 2)); array[SECOND] = toInt(input.substr(pos2)); }); // LOCALES function localeIsPM (input) { // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays // Using charAt should be more compatible. return ((input + '').toLowerCase().charAt(0) === 'p'); } var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; function localeMeridiem (hours, minutes, isLower) { if (hours > 11) { return isLower ? 'pm' : 'PM'; } else { return isLower ? 'am' : 'AM'; } } // MOMENTS // Setting the hour should keep the time, because the user explicitly // specified which hour they want. So trying to maintain the same hour (in // a new timezone) makes sense. Adding/subtracting hours does not follow // this rule. var getSetHour = makeGetSet('Hours', true); var baseConfig = { calendar: defaultCalendar, longDateFormat: defaultLongDateFormat, invalidDate: defaultInvalidDate, ordinal: defaultOrdinal, dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, relativeTime: defaultRelativeTime, months: defaultLocaleMonths, monthsShort: defaultLocaleMonthsShort, week: defaultLocaleWeek, weekdays: defaultLocaleWeekdays, weekdaysMin: defaultLocaleWeekdaysMin, weekdaysShort: defaultLocaleWeekdaysShort, meridiemParse: defaultLocaleMeridiemParse }; // internal storage for locale config files var locales = {}; var localeFamilies = {}; var globalLocale; function normalizeLocale(key) { return key ? key.toLowerCase().replace('_', '-') : key; } // pick the locale from the array // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root function chooseLocale(names) { var i = 0, j, next, locale, split; while (i < names.length) { split = normalizeLocale(names[i]).split('-'); j = split.length; next = normalizeLocale(names[i + 1]); next = next ? next.split('-') : null; while (j > 0) { locale = loadLocale(split.slice(0, j).join('-')); if (locale) { return locale; } if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { //the next array item is better than a shallower substring of this one break; } j--; } i++; } return globalLocale; } function loadLocale(name) { var oldLocale = null; // TODO: Find a better way to register and load all the locales in Node if (!locales[name] && (typeof module !== 'undefined') && module && module.exports) { try { oldLocale = globalLocale._abbr; var aliasedRequire = require; aliasedRequire('./locale/' + name); getSetGlobalLocale(oldLocale); } catch (e) {} } return locales[name]; } // This function will load locale and then set the global locale. If // no arguments are passed in, it will simply return the current global // locale key. function getSetGlobalLocale (key, values) { var data; if (key) { if (isUndefined(values)) { data = getLocale(key); } else { data = defineLocale(key, values); } if (data) { // moment.duration._locale = moment._locale = data; globalLocale = data; } else { if ((typeof console !== 'undefined') && console.warn) { //warn user if arguments are passed but the locale could not be set console.warn('Locale ' + key + ' not found. Did you forget to load it?'); } } } return globalLocale._abbr; } function defineLocale (name, config) { if (config !== null) { var locale, parentConfig = baseConfig; config.abbr = name; if (locales[name] != null) { deprecateSimple('defineLocaleOverride', 'use moment.updateLocale(localeName, config) to change ' + 'an existing locale. moment.defineLocale(localeName, ' + 'config) should only be used for creating a new locale ' + 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'); parentConfig = locales[name]._config; } else if (config.parentLocale != null) { if (locales[config.parentLocale] != null) { parentConfig = locales[config.parentLocale]._config; } else { locale = loadLocale(config.parentLocale); if (locale != null) { parentConfig = locale._config; } else { if (!localeFamilies[config.parentLocale]) { localeFamilies[config.parentLocale] = []; } localeFamilies[config.parentLocale].push({ name: name, config: config }); return null; } } } locales[name] = new Locale(mergeConfigs(parentConfig, config)); if (localeFamilies[name]) { localeFamilies[name].forEach(function (x) { defineLocale(x.name, x.config); }); } // backwards compat for now: also set the locale // make sure we set the locale AFTER all child locales have been // created, so we won't end up with the child locale set. getSetGlobalLocale(name); return locales[name]; } else { // useful for testing delete locales[name]; return null; } } function updateLocale(name, config) { if (config != null) { var locale, tmpLocale, parentConfig = baseConfig; // MERGE tmpLocale = loadLocale(name); if (tmpLocale != null) { parentConfig = tmpLocale._config; } config = mergeConfigs(parentConfig, config); locale = new Locale(config); locale.parentLocale = locales[name]; locales[name] = locale; // backwards compat for now: also set the locale getSetGlobalLocale(name); } else { // pass null for config to unupdate, useful for tests if (locales[name] != null) { if (locales[name].parentLocale != null) { locales[name] = locales[name].parentLocale; } else if (locales[name] != null) { delete locales[name]; } } } return locales[name]; } // returns locale data function getLocale (key) { var locale; if (key && key._locale && key._locale._abbr) { key = key._locale._abbr; } if (!key) { return globalLocale; } if (!isArray(key)) { //short-circuit everything else locale = loadLocale(key); if (locale) { return locale; } key = [key]; } return chooseLocale(key); } function listLocales() { return keys(locales); } function checkOverflow (m) { var overflow; var a = m._a; if (a && getParsingFlags(m).overflow === -2) { overflow = a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : -1; if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { overflow = DATE; } if (getParsingFlags(m)._overflowWeeks && overflow === -1) { overflow = WEEK; } if (getParsingFlags(m)._overflowWeekday && overflow === -1) { overflow = WEEKDAY; } getParsingFlags(m).overflow = overflow; } return m; } // Pick the first defined of two or three arguments. function defaults(a, b, c) { if (a != null) { return a; } if (b != null) { return b; } return c; } function currentDateArray(config) { // hooks is actually the exported moment object var nowValue = new Date(hooks.now()); if (config._useUTC) { return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; } return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; } // convert an array to a date. // the array should mirror the parameters below // note: all values past the year are optional and will default to the lowest possible value. // [year, month, day , hour, minute, second, millisecond] function configFromArray (config) { var i, date, input = [], currentDate, expectedWeekday, yearToUse; if (config._d) { return; } currentDate = currentDateArray(config); //compute day of the year from weeks and weekdays if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { dayOfYearFromWeekInfo(config); } //if the day of the year is set, figure out what it is if (config._dayOfYear != null) { yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { getParsingFlags(config)._overflowDayOfYear = true; } date = createUTCDate(yearToUse, 0, config._dayOfYear); config._a[MONTH] = date.getUTCMonth(); config._a[DATE] = date.getUTCDate(); } // Default to current date. // * if no year, month, day of month are given, default to today // * if day of month is given, default month and year // * if month is given, default only year // * if year is given, don't default anything for (i = 0; i < 3 && config._a[i] == null; ++i) { config._a[i] = input[i] = currentDate[i]; } // Zero out whatever was not defaulted, including time for (; i < 7; i++) { config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; } // Check for 24:00:00.000 if (config._a[HOUR] === 24 && config._a[MINUTE] === 0 && config._a[SECOND] === 0 && config._a[MILLISECOND] === 0) { config._nextDay = true; config._a[HOUR] = 0; } config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); // Apply timezone offset from input. The actual utcOffset can be changed // with parseZone. if (config._tzm != null) { config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); } if (config._nextDay) { config._a[HOUR] = 24; } // check for mismatching day of week if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) { getParsingFlags(config).weekdayMismatch = true; } } function dayOfYearFromWeekInfo(config) { var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; w = config._w; if (w.GG != null || w.W != null || w.E != null) { dow = 1; doy = 4; // TODO: We need to take the current isoWeekYear, but that depends on // how we interpret now (local, utc, fixed offset). So create // a now version of current config (take local/utc/offset flags, and // create now). weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); week = defaults(w.W, 1); weekday = defaults(w.E, 1); if (weekday < 1 || weekday > 7) { weekdayOverflow = true; } } else { dow = config._locale._week.dow; doy = config._locale._week.doy; var curWeek = weekOfYear(createLocal(), dow, doy); weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); // Default to current week. week = defaults(w.w, curWeek.week); if (w.d != null) { // weekday -- low day numbers are considered next week weekday = w.d; if (weekday < 0 || weekday > 6) { weekdayOverflow = true; } } else if (w.e != null) { // local weekday -- counting starts from beginning of week weekday = w.e + dow; if (w.e < 0 || w.e > 6) { weekdayOverflow = true; } } else { // default to beginning of week weekday = dow; } } if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { getParsingFlags(config)._overflowWeeks = true; } else if (weekdayOverflow != null) { getParsingFlags(config)._overflowWeekday = true; } else { temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); config._a[YEAR] = temp.year; config._dayOfYear = temp.dayOfYear; } } // iso 8601 regex // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; var isoDates = [ ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], ['GGGG-[W]WW', /\d{4}-W\d\d/, false], ['YYYY-DDD', /\d{4}-\d{3}/], ['YYYY-MM', /\d{4}-\d\d/, false], ['YYYYYYMMDD', /[+-]\d{10}/], ['YYYYMMDD', /\d{8}/], // YYYYMM is NOT allowed by the standard ['GGGG[W]WWE', /\d{4}W\d{3}/], ['GGGG[W]WW', /\d{4}W\d{2}/, false], ['YYYYDDD', /\d{7}/] ]; // iso time formats and regexes var isoTimes = [ ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], ['HH:mm:ss', /\d\d:\d\d:\d\d/], ['HH:mm', /\d\d:\d\d/], ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], ['HHmmss', /\d\d\d\d\d\d/], ['HHmm', /\d\d\d\d/], ['HH', /\d\d/] ]; var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; // date from iso format function configFromISO(config) { var i, l, string = config._i, match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), allowTime, dateFormat, timeFormat, tzFormat; if (match) { getParsingFlags(config).iso = true; for (i = 0, l = isoDates.length; i < l; i++) { if (isoDates[i][1].exec(match[1])) { dateFormat = isoDates[i][0]; allowTime = isoDates[i][2] !== false; break; } } if (dateFormat == null) { config._isValid = false; return; } if (match[3]) { for (i = 0, l = isoTimes.length; i < l; i++) { if (isoTimes[i][1].exec(match[3])) { // match[2] should be 'T' or space timeFormat = (match[2] || ' ') + isoTimes[i][0]; break; } } if (timeFormat == null) { config._isValid = false; return; } } if (!allowTime && timeFormat != null) { config._isValid = false; return; } if (match[4]) { if (tzRegex.exec(match[4])) { tzFormat = 'Z'; } else { config._isValid = false; return; } } config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); configFromStringAndFormat(config); } else { config._isValid = false; } } // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { var result = [ untruncateYear(yearStr), defaultLocaleMonthsShort.indexOf(monthStr), parseInt(dayStr, 10), parseInt(hourStr, 10), parseInt(minuteStr, 10) ]; if (secondStr) { result.push(parseInt(secondStr, 10)); } return result; } function untruncateYear(yearStr) { var year = parseInt(yearStr, 10); if (year <= 49) { return 2000 + year; } else if (year <= 999) { return 1900 + year; } return year; } function preprocessRFC2822(s) { // Remove comments and folding whitespace and replace multiple-spaces with a single space return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); } function checkWeekday(weekdayStr, parsedInput, config) { if (weekdayStr) { // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); if (weekdayProvided !== weekdayActual) { getParsingFlags(config).weekdayMismatch = true; config._isValid = false; return false; } } return true; } var obsOffsets = { UT: 0, GMT: 0, EDT: -4 * 60, EST: -5 * 60, CDT: -5 * 60, CST: -6 * 60, MDT: -6 * 60, MST: -7 * 60, PDT: -7 * 60, PST: -8 * 60 }; function calculateOffset(obsOffset, militaryOffset, numOffset) { if (obsOffset) { return obsOffsets[obsOffset]; } else if (militaryOffset) { // the only allowed military tz is Z return 0; } else { var hm = parseInt(numOffset, 10); var m = hm % 100, h = (hm - m) / 100; return h * 60 + m; } } // date and time from ref 2822 format function configFromRFC2822(config) { var match = rfc2822.exec(preprocessRFC2822(config._i)); if (match) { var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); if (!checkWeekday(match[1], parsedArray, config)) { return; } config._a = parsedArray; config._tzm = calculateOffset(match[8], match[9], match[10]); config._d = createUTCDate.apply(null, config._a); config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); getParsingFlags(config).rfc2822 = true; } else { config._isValid = false; } } // date from iso format or fallback function configFromString(config) { var matched = aspNetJsonRegex.exec(config._i); if (matched !== null) { config._d = new Date(+matched[1]); return; } configFromISO(config); if (config._isValid === false) { delete config._isValid; } else { return; } configFromRFC2822(config); if (config._isValid === false) { delete config._isValid; } else { return; } // Final attempt, use Input Fallback hooks.createFromInputFallback(config); } hooks.createFromInputFallback = deprecate( 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + 'discouraged and will be removed in an upcoming major release. Please refer to ' + 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', function (config) { config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); } ); // constant that refers to the ISO standard hooks.ISO_8601 = function () {}; // constant that refers to the RFC 2822 form hooks.RFC_2822 = function () {}; // date from string and format string function configFromStringAndFormat(config) { // TODO: Move this to another part of the creation flow to prevent circular deps if (config._f === hooks.ISO_8601) { configFromISO(config); return; } if (config._f === hooks.RFC_2822) { configFromRFC2822(config); return; } config._a = []; getParsingFlags(config).empty = true; // This array is used to make a Date, either with `new Date` or `Date.UTC` var string = '' + config._i, i, parsedInput, tokens, token, skipped, stringLength = string.length, totalParsedInputLength = 0; tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; for (i = 0; i < tokens.length; i++) { token = tokens[i]; parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; // console.log('token', token, 'parsedInput', parsedInput, // 'regex', getParseRegexForToken(token, config)); if (parsedInput) { skipped = string.substr(0, string.indexOf(parsedInput)); if (skipped.length > 0) { getParsingFlags(config).unusedInput.push(skipped); } string = string.slice(string.indexOf(parsedInput) + parsedInput.length); totalParsedInputLength += parsedInput.length; } // don't parse if it's not a known token if (formatTokenFunctions[token]) { if (parsedInput) { getParsingFlags(config).empty = false; } else { getParsingFlags(config).unusedTokens.push(token); } addTimeToArrayFromToken(token, parsedInput, config); } else if (config._strict && !parsedInput) { getParsingFlags(config).unusedTokens.push(token); } } // add remaining unparsed input length to the string getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; if (string.length > 0) { getParsingFlags(config).unusedInput.push(string); } // clear _12h flag if hour is <= 12 if (config._a[HOUR] <= 12 && getParsingFlags(config).bigHour === true && config._a[HOUR] > 0) { getParsingFlags(config).bigHour = undefined; } getParsingFlags(config).parsedDateParts = config._a.slice(0); getParsingFlags(config).meridiem = config._meridiem; // handle meridiem config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); configFromArray(config); checkOverflow(config); } function meridiemFixWrap (locale, hour, meridiem) { var isPm; if (meridiem == null) { // nothing to do return hour; } if (locale.meridiemHour != null) { return locale.meridiemHour(hour, meridiem); } else if (locale.isPM != null) { // Fallback isPm = locale.isPM(meridiem); if (isPm && hour < 12) { hour += 12; } if (!isPm && hour === 12) { hour = 0; } return hour; } else { // this is not supposed to happen return hour; } } // date from string and array of format strings function configFromStringAndArray(config) { var tempConfig, bestMoment, scoreToBeat, i, currentScore; if (config._f.length === 0) { getParsingFlags(config).invalidFormat = true; config._d = new Date(NaN); return; } for (i = 0; i < config._f.length; i++) { currentScore = 0; tempConfig = copyConfig({}, config); if (config._useUTC != null) { tempConfig._useUTC = config._useUTC; } tempConfig._f = config._f[i]; configFromStringAndFormat(tempConfig); if (!isValid(tempConfig)) { continue; } // if there is any input that was not parsed add a penalty for that format currentScore += getParsingFlags(tempConfig).charsLeftOver; //or tokens currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; getParsingFlags(tempConfig).score = currentScore; if (scoreToBeat == null || currentScore < scoreToBeat) { scoreToBeat = currentScore; bestMoment = tempConfig; } } extend(config, bestMoment || tempConfig); } function configFromObject(config) { if (config._d) { return; } var i = normalizeObjectUnits(config._i); config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { return obj && parseInt(obj, 10); }); configFromArray(config); } function createFromConfig (config) { var res = new Moment(checkOverflow(prepareConfig(config))); if (res._nextDay) { // Adding is smart enough around DST res.add(1, 'd'); res._nextDay = undefined; } return res; } function prepareConfig (config) { var input = config._i, format = config._f; config._locale = config._locale || getLocale(config._l); if (input === null || (format === undefined && input === '')) { return createInvalid({nullInput: true}); } if (typeof input === 'string') { config._i = input = config._locale.preparse(input); } if (isMoment(input)) { return new Moment(checkOverflow(input)); } else if (isDate(input)) { config._d = input; } else if (isArray(format)) { configFromStringAndArray(config); } else if (format) { configFromStringAndFormat(config); } else { configFromInput(config); } if (!isValid(config)) { config._d = null; } return config; } function configFromInput(config) { var input = config._i; if (isUndefined(input)) { config._d = new Date(hooks.now()); } else if (isDate(input)) { config._d = new Date(input.valueOf()); } else if (typeof input === 'string') { configFromString(config); } else if (isArray(input)) { config._a = map(input.slice(0), function (obj) { return parseInt(obj, 10); }); configFromArray(config); } else if (isObject(input)) { configFromObject(config); } else if (isNumber(input)) { // from milliseconds config._d = new Date(input); } else { hooks.createFromInputFallback(config); } } function createLocalOrUTC (input, format, locale, strict, isUTC) { var c = {}; if (locale === true || locale === false) { strict = locale; locale = undefined; } if ((isObject(input) && isObjectEmpty(input)) || (isArray(input) && input.length === 0)) { input = undefined; } // object construction must be done this way. // https://github.com/moment/moment/issues/1423 c._isAMomentObject = true; c._useUTC = c._isUTC = isUTC; c._l = locale; c._i = input; c._f = format; c._strict = strict; return createFromConfig(c); } function createLocal (input, format, locale, strict) { return createLocalOrUTC(input, format, locale, strict, false); } var prototypeMin = deprecate( 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', function () { var other = createLocal.apply(null, arguments); if (this.isValid() && other.isValid()) { return other < this ? this : other; } else { return createInvalid(); } } ); var prototypeMax = deprecate( 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', function () { var other = createLocal.apply(null, arguments); if (this.isValid() && other.isValid()) { return other > this ? this : other; } else { return createInvalid(); } } ); // Pick a moment m from moments so that m[fn](other) is true for all // other. This relies on the function fn to be transitive. // // moments should either be an array of moment objects or an array, whose // first element is an array of moment objects. function pickBy(fn, moments) { var res, i; if (moments.length === 1 && isArray(moments[0])) { moments = moments[0]; } if (!moments.length) { return createLocal(); } res = moments[0]; for (i = 1; i < moments.length; ++i) { if (!moments[i].isValid() || moments[i][fn](res)) { res = moments[i]; } } return res; } // TODO: Use [].sort instead? function min () { var args = [].slice.call(arguments, 0); return pickBy('isBefore', args); } function max () { var args = [].slice.call(arguments, 0); return pickBy('isAfter', args); } var now = function () { return Date.now ? Date.now() : +(new Date()); }; var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; function isDurationValid(m) { for (var key in m) { if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { return false; } } var unitHasDecimal = false; for (var i = 0; i < ordering.length; ++i) { if (m[ordering[i]]) { if (unitHasDecimal) { return false; // only allow non-integers for smallest unit } if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { unitHasDecimal = true; } } } return true; } function isValid$1() { return this._isValid; } function createInvalid$1() { return createDuration(NaN); } function Duration (duration) { var normalizedInput = normalizeObjectUnits(duration), years = normalizedInput.year || 0, quarters = normalizedInput.quarter || 0, months = normalizedInput.month || 0, weeks = normalizedInput.week || normalizedInput.isoWeek || 0, days = normalizedInput.day || 0, hours = normalizedInput.hour || 0, minutes = normalizedInput.minute || 0, seconds = normalizedInput.second || 0, milliseconds = normalizedInput.millisecond || 0; this._isValid = isDurationValid(normalizedInput); // representation for dateAddRemove this._milliseconds = +milliseconds + seconds * 1e3 + // 1000 minutes * 6e4 + // 1000 * 60 hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 // Because of dateAddRemove treats 24 hours as different from a // day when working around DST, we need to store them separately this._days = +days + weeks * 7; // It is impossible to translate months into days without knowing // which months you are are talking about, so we have to store // it separately. this._months = +months + quarters * 3 + years * 12; this._data = {}; this._locale = getLocale(); this._bubble(); } function isDuration (obj) { return obj instanceof Duration; } function absRound (number) { if (number < 0) { return Math.round(-1 * number) * -1; } else { return Math.round(number); } } // FORMATTING function offset (token, separator) { addFormatToken(token, 0, 0, function () { var offset = this.utcOffset(); var sign = '+'; if (offset < 0) { offset = -offset; sign = '-'; } return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); }); } offset('Z', ':'); offset('ZZ', ''); // PARSING addRegexToken('Z', matchShortOffset); addRegexToken('ZZ', matchShortOffset); addParseToken(['Z', 'ZZ'], function (input, array, config) { config._useUTC = true; config._tzm = offsetFromString(matchShortOffset, input); }); // HELPERS // timezone chunker // '+10:00' > ['10', '00'] // '-1530' > ['-15', '30'] var chunkOffset = /([\+\-]|\d\d)/gi; function offsetFromString(matcher, string) { var matches = (string || '').match(matcher); if (matches === null) { return null; } var chunk = matches[matches.length - 1] || []; var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; var minutes = +(parts[1] * 60) + toInt(parts[2]); return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes; } // Return a moment from input, that is local/utc/zone equivalent to model. function cloneWithOffset(input, model) { var res, diff; if (model._isUTC) { res = model.clone(); diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); // Use low-level api, because this fn is low-level api. res._d.setTime(res._d.valueOf() + diff); hooks.updateOffset(res, false); return res; } else { return createLocal(input).local(); } } function getDateOffset (m) { // On Firefox.24 Date#getTimezoneOffset returns a floating point. // https://github.com/moment/moment/pull/1871 return -Math.round(m._d.getTimezoneOffset() / 15) * 15; } // HOOKS // This function will be called whenever a moment is mutated. // It is intended to keep the offset in sync with the timezone. hooks.updateOffset = function () {}; // MOMENTS // keepLocalTime = true means only change the timezone, without // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset // +0200, so we adjust the time as needed, to be valid. // // Keeping the time actually adds/subtracts (one hour) // from the actual represented time. That is why we call updateOffset // a second time. In case it wants us to change the offset again // _changeInProgress == true case, then we have to adjust, because // there is no such time in the given timezone. function getSetOffset (input, keepLocalTime, keepMinutes) { var offset = this._offset || 0, localAdjust; if (!this.isValid()) { return input != null ? this : NaN; } if (input != null) { if (typeof input === 'string') { input = offsetFromString(matchShortOffset, input); if (input === null) { return this; } } else if (Math.abs(input) < 16 && !keepMinutes) { input = input * 60; } if (!this._isUTC && keepLocalTime) { localAdjust = getDateOffset(this); } this._offset = input; this._isUTC = true; if (localAdjust != null) { this.add(localAdjust, 'm'); } if (offset !== input) { if (!keepLocalTime || this._changeInProgress) { addSubtract(this, createDuration(input - offset, 'm'), 1, false); } else if (!this._changeInProgress) { this._changeInProgress = true; hooks.updateOffset(this, true); this._changeInProgress = null; } } return this; } else { return this._isUTC ? offset : getDateOffset(this); } } function getSetZone (input, keepLocalTime) { if (input != null) { if (typeof input !== 'string') { input = -input; } this.utcOffset(input, keepLocalTime); return this; } else { return -this.utcOffset(); } } function setOffsetToUTC (keepLocalTime) { return this.utcOffset(0, keepLocalTime); } function setOffsetToLocal (keepLocalTime) { if (this._isUTC) { this.utcOffset(0, keepLocalTime); this._isUTC = false; if (keepLocalTime) { this.subtract(getDateOffset(this), 'm'); } } return this; } function setOffsetToParsedOffset () { if (this._tzm != null) { this.utcOffset(this._tzm, false, true); } else if (typeof this._i === 'string') { var tZone = offsetFromString(matchOffset, this._i); if (tZone != null) { this.utcOffset(tZone); } else { this.utcOffset(0, true); } } return this; } function hasAlignedHourOffset (input) { if (!this.isValid()) { return false; } input = input ? createLocal(input).utcOffset() : 0; return (this.utcOffset() - input) % 60 === 0; } function isDaylightSavingTime () { return ( this.utcOffset() > this.clone().month(0).utcOffset() || this.utcOffset() > this.clone().month(5).utcOffset() ); } function isDaylightSavingTimeShifted () { if (!isUndefined(this._isDSTShifted)) { return this._isDSTShifted; } var c = {}; copyConfig(c, this); c = prepareConfig(c); if (c._a) { var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); this._isDSTShifted = this.isValid() && compareArrays(c._a, other.toArray()) > 0; } else { this._isDSTShifted = false; } return this._isDSTShifted; } function isLocal () { return this.isValid() ? !this._isUTC : false; } function isUtcOffset () { return this.isValid() ? this._isUTC : false; } function isUtc () { return this.isValid() ? this._isUTC && this._offset === 0 : false; } // ASP.NET json date format regex var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere // and further modified to allow for strings containing both week and day var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; function createDuration (input, key) { var duration = input, // matching against regexp is expensive, do it on demand match = null, sign, ret, diffRes; if (isDuration(input)) { duration = { ms : input._milliseconds, d : input._days, M : input._months }; } else if (isNumber(input)) { duration = {}; if (key) { duration[key] = input; } else { duration.milliseconds = input; } } else if (!!(match = aspNetRegex.exec(input))) { sign = (match[1] === '-') ? -1 : 1; duration = { y : 0, d : toInt(match[DATE]) * sign, h : toInt(match[HOUR]) * sign, m : toInt(match[MINUTE]) * sign, s : toInt(match[SECOND]) * sign, ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match }; } else if (!!(match = isoRegex.exec(input))) { sign = (match[1] === '-') ? -1 : 1; duration = { y : parseIso(match[2], sign), M : parseIso(match[3], sign), w : parseIso(match[4], sign), d : parseIso(match[5], sign), h : parseIso(match[6], sign), m : parseIso(match[7], sign), s : parseIso(match[8], sign) }; } else if (duration == null) {// checks for null or undefined duration = {}; } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); duration = {}; duration.ms = diffRes.milliseconds; duration.M = diffRes.months; } ret = new Duration(duration); if (isDuration(input) && hasOwnProp(input, '_locale')) { ret._locale = input._locale; } return ret; } createDuration.fn = Duration.prototype; createDuration.invalid = createInvalid$1; function parseIso (inp, sign) { // We'd normally use ~~inp for this, but unfortunately it also // converts floats to ints. // inp may be undefined, so careful calling replace on it. var res = inp && parseFloat(inp.replace(',', '.')); // apply sign while we're at it return (isNaN(res) ? 0 : res) * sign; } function positiveMomentsDifference(base, other) { var res = {}; res.months = other.month() - base.month() + (other.year() - base.year()) * 12; if (base.clone().add(res.months, 'M').isAfter(other)) { --res.months; } res.milliseconds = +other - +(base.clone().add(res.months, 'M')); return res; } function momentsDifference(base, other) { var res; if (!(base.isValid() && other.isValid())) { return {milliseconds: 0, months: 0}; } other = cloneWithOffset(other, base); if (base.isBefore(other)) { res = positiveMomentsDifference(base, other); } else { res = positiveMomentsDifference(other, base); res.milliseconds = -res.milliseconds; res.months = -res.months; } return res; } // TODO: remove 'name' arg after deprecation is removed function createAdder(direction, name) { return function (val, period) { var dur, tmp; //invert the arguments, but complain about it if (period !== null && !isNaN(+period)) { deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'); tmp = val; val = period; period = tmp; } val = typeof val === 'string' ? +val : val; dur = createDuration(val, period); addSubtract(this, dur, direction); return this; }; } function addSubtract (mom, duration, isAdding, updateOffset) { var milliseconds = duration._milliseconds, days = absRound(duration._days), months = absRound(duration._months); if (!mom.isValid()) { // No op return; } updateOffset = updateOffset == null ? true : updateOffset; if (months) { setMonth(mom, get(mom, 'Month') + months * isAdding); } if (days) { set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); } if (milliseconds) { mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); } if (updateOffset) { hooks.updateOffset(mom, days || months); } } var add = createAdder(1, 'add'); var subtract = createAdder(-1, 'subtract'); function getCalendarFormat(myMoment, now) { var diff = myMoment.diff(now, 'days', true); return diff < -6 ? 'sameElse' : diff < -1 ? 'lastWeek' : diff < 0 ? 'lastDay' : diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse'; } function calendar$1 (time, formats) { // We want to compare the start of today, vs this. // Getting start-of-today depends on whether we're local/utc/offset or not. var now = time || createLocal(), sod = cloneWithOffset(now, this).startOf('day'), format = hooks.calendarFormat(this, sod) || 'sameElse'; var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); return this.format(output || this.localeData().calendar(format, this, createLocal(now))); } function clone () { return new Moment(this); } function isAfter (input, units) { var localInput = isMoment(input) ? input : createLocal(input); if (!(this.isValid() && localInput.isValid())) { return false; } units = normalizeUnits(units) || 'millisecond'; if (units === 'millisecond') { return this.valueOf() > localInput.valueOf(); } else { return localInput.valueOf() < this.clone().startOf(units).valueOf(); } } function isBefore (input, units) { var localInput = isMoment(input) ? input : createLocal(input); if (!(this.isValid() && localInput.isValid())) { return false; } units = normalizeUnits(units) || 'millisecond'; if (units === 'millisecond') { return this.valueOf() < localInput.valueOf(); } else { return this.clone().endOf(units).valueOf() < localInput.valueOf(); } } function isBetween (from, to, units, inclusivity) { var localFrom = isMoment(from) ? from : createLocal(from), localTo = isMoment(to) ? to : createLocal(to); if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) { return false; } inclusivity = inclusivity || '()'; return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units)); } function isSame (input, units) { var localInput = isMoment(input) ? input : createLocal(input), inputMs; if (!(this.isValid() && localInput.isValid())) { return false; } units = normalizeUnits(units) || 'millisecond'; if (units === 'millisecond') { return this.valueOf() === localInput.valueOf(); } else { inputMs = localInput.valueOf(); return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); } } function isSameOrAfter (input, units) { return this.isSame(input, units) || this.isAfter(input, units); } function isSameOrBefore (input, units) { return this.isSame(input, units) || this.isBefore(input, units); } function diff (input, units, asFloat) { var that, zoneDelta, output; if (!this.isValid()) { return NaN; } that = cloneWithOffset(input, this); if (!that.isValid()) { return NaN; } zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; units = normalizeUnits(units); switch (units) { case 'year': output = monthDiff(this, that) / 12; break; case 'month': output = monthDiff(this, that); break; case 'quarter': output = monthDiff(this, that) / 3; break; case 'second': output = (this - that) / 1e3; break; // 1000 case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst default: output = this - that; } return asFloat ? output : absFloor(output); } function monthDiff (a, b) { // difference in months var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), // b is in (anchor - 1 month, anchor + 1 month) anchor = a.clone().add(wholeMonthDiff, 'months'), anchor2, adjust; if (b - anchor < 0) { anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); // linear across the month adjust = (b - anchor) / (anchor - anchor2); } else { anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); // linear across the month adjust = (b - anchor) / (anchor2 - anchor); } //check for negative zero, return zero if negative zero return -(wholeMonthDiff + adjust) || 0; } hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; function toString () { return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); } function toISOString(keepOffset) { if (!this.isValid()) { return null; } var utc = keepOffset !== true; var m = utc ? this.clone().utc() : this; if (m.year() < 0 || m.year() > 9999) { return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'); } if (isFunction(Date.prototype.toISOString)) { // native implementation is ~50x faster, use it when we can if (utc) { return this.toDate().toISOString(); } else { return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z')); } } return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'); } /** * Return a human readable representation of a moment that can * also be evaluated to get a new moment which is the same * * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects */ function inspect () { if (!this.isValid()) { return 'moment.invalid(/* ' + this._i + ' */)'; } var func = 'moment'; var zone = ''; if (!this.isLocal()) { func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; zone = 'Z'; } var prefix = '[' + func + '("]'; var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY'; var datetime = '-MM-DD[T]HH:mm:ss.SSS'; var suffix = zone + '[")]'; return this.format(prefix + year + datetime + suffix); } function format (inputString) { if (!inputString) { inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; } var output = formatMoment(this, inputString); return this.localeData().postformat(output); } function from (time, withoutSuffix) { if (this.isValid() && ((isMoment(time) && time.isValid()) || createLocal(time).isValid())) { return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); } else { return this.localeData().invalidDate(); } } function fromNow (withoutSuffix) { return this.from(createLocal(), withoutSuffix); } function to (time, withoutSuffix) { if (this.isValid() && ((isMoment(time) && time.isValid()) || createLocal(time).isValid())) { return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); } else { return this.localeData().invalidDate(); } } function toNow (withoutSuffix) { return this.to(createLocal(), withoutSuffix); } // If passed a locale key, it will set the locale for this // instance. Otherwise, it will return the locale configuration // variables for this instance. function locale (key) { var newLocaleData; if (key === undefined) { return this._locale._abbr; } else { newLocaleData = getLocale(key); if (newLocaleData != null) { this._locale = newLocaleData; } return this; } } var lang = deprecate( 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', function (key) { if (key === undefined) { return this.localeData(); } else { return this.locale(key); } } ); function localeData () { return this._locale; } var MS_PER_SECOND = 1000; var MS_PER_MINUTE = 60 * MS_PER_SECOND; var MS_PER_HOUR = 60 * MS_PER_MINUTE; var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; // actual modulo - handles negative numbers (for dates before 1970): function mod$1(dividend, divisor) { return (dividend % divisor + divisor) % divisor; } function localStartOfDate(y, m, d) { // the date constructor remaps years 0-99 to 1900-1999 if (y < 100 && y >= 0) { // preserve leap years using a full 400 year cycle, then reset return new Date(y + 400, m, d) - MS_PER_400_YEARS; } else { return new Date(y, m, d).valueOf(); } } function utcStartOfDate(y, m, d) { // Date.UTC remaps years 0-99 to 1900-1999 if (y < 100 && y >= 0) { // preserve leap years using a full 400 year cycle, then reset return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS; } else { return Date.UTC(y, m, d); } } function startOf (units) { var time; units = normalizeUnits(units); if (units === undefined || units === 'millisecond' || !this.isValid()) { return this; } var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; switch (units) { case 'year': time = startOfDate(this.year(), 0, 1); break; case 'quarter': time = startOfDate(this.year(), this.month() - this.month() % 3, 1); break; case 'month': time = startOfDate(this.year(), this.month(), 1); break; case 'week': time = startOfDate(this.year(), this.month(), this.date() - this.weekday()); break; case 'isoWeek': time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1)); break; case 'day': case 'date': time = startOfDate(this.year(), this.month(), this.date()); break; case 'hour': time = this._d.valueOf(); time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR); break; case 'minute': time = this._d.valueOf(); time -= mod$1(time, MS_PER_MINUTE); break; case 'second': time = this._d.valueOf(); time -= mod$1(time, MS_PER_SECOND); break; } this._d.setTime(time); hooks.updateOffset(this, true); return this; } function endOf (units) { var time; units = normalizeUnits(units); if (units === undefined || units === 'millisecond' || !this.isValid()) { return this; } var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; switch (units) { case 'year': time = startOfDate(this.year() + 1, 0, 1) - 1; break; case 'quarter': time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1; break; case 'month': time = startOfDate(this.year(), this.month() + 1, 1) - 1; break; case 'week': time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1; break; case 'isoWeek': time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1; break; case 'day': case 'date': time = startOfDate(this.year(), this.month(), this.date() + 1) - 1; break; case 'hour': time = this._d.valueOf(); time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1; break; case 'minute': time = this._d.valueOf(); time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1; break; case 'second': time = this._d.valueOf(); time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1; break; } this._d.setTime(time); hooks.updateOffset(this, true); return this; } function valueOf () { return this._d.valueOf() - ((this._offset || 0) * 60000); } function unix () { return Math.floor(this.valueOf() / 1000); } function toDate () { return new Date(this.valueOf()); } function toArray () { var m = this; return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; } function toObject () { var m = this; return { years: m.year(), months: m.month(), date: m.date(), hours: m.hours(), minutes: m.minutes(), seconds: m.seconds(), milliseconds: m.milliseconds() }; } function toJSON () { // new Date(NaN).toJSON() === null return this.isValid() ? this.toISOString() : null; } function isValid$2 () { return isValid(this); } function parsingFlags () { return extend({}, getParsingFlags(this)); } function invalidAt () { return getParsingFlags(this).overflow; } function creationData() { return { input: this._i, format: this._f, locale: this._locale, isUTC: this._isUTC, strict: this._strict }; } // FORMATTING addFormatToken(0, ['gg', 2], 0, function () { return this.weekYear() % 100; }); addFormatToken(0, ['GG', 2], 0, function () { return this.isoWeekYear() % 100; }); function addWeekYearFormatToken (token, getter) { addFormatToken(0, [token, token.length], 0, getter); } addWeekYearFormatToken('gggg', 'weekYear'); addWeekYearFormatToken('ggggg', 'weekYear'); addWeekYearFormatToken('GGGG', 'isoWeekYear'); addWeekYearFormatToken('GGGGG', 'isoWeekYear'); // ALIASES addUnitAlias('weekYear', 'gg'); addUnitAlias('isoWeekYear', 'GG'); // PRIORITY addUnitPriority('weekYear', 1); addUnitPriority('isoWeekYear', 1); // PARSING addRegexToken('G', matchSigned); addRegexToken('g', matchSigned); addRegexToken('GG', match1to2, match2); addRegexToken('gg', match1to2, match2); addRegexToken('GGGG', match1to4, match4); addRegexToken('gggg', match1to4, match4); addRegexToken('GGGGG', match1to6, match6); addRegexToken('ggggg', match1to6, match6); addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { week[token.substr(0, 2)] = toInt(input); }); addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { week[token] = hooks.parseTwoDigitYear(input); }); // MOMENTS function getSetWeekYear (input) { return getSetWeekYearHelper.call(this, input, this.week(), this.weekday(), this.localeData()._week.dow, this.localeData()._week.doy); } function getSetISOWeekYear (input) { return getSetWeekYearHelper.call(this, input, this.isoWeek(), this.isoWeekday(), 1, 4); } function getISOWeeksInYear () { return weeksInYear(this.year(), 1, 4); } function getWeeksInYear () { var weekInfo = this.localeData()._week; return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); } function getSetWeekYearHelper(input, week, weekday, dow, doy) { var weeksTarget; if (input == null) { return weekOfYear(this, dow, doy).year; } else { weeksTarget = weeksInYear(input, dow, doy); if (week > weeksTarget) { week = weeksTarget; } return setWeekAll.call(this, input, week, weekday, dow, doy); } } function setWeekAll(weekYear, week, weekday, dow, doy) { var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); this.year(date.getUTCFullYear()); this.month(date.getUTCMonth()); this.date(date.getUTCDate()); return this; } // FORMATTING addFormatToken('Q', 0, 'Qo', 'quarter'); // ALIASES addUnitAlias('quarter', 'Q'); // PRIORITY addUnitPriority('quarter', 7); // PARSING addRegexToken('Q', match1); addParseToken('Q', function (input, array) { array[MONTH] = (toInt(input) - 1) * 3; }); // MOMENTS function getSetQuarter (input) { return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); } // FORMATTING addFormatToken('D', ['DD', 2], 'Do', 'date'); // ALIASES addUnitAlias('date', 'D'); // PRIORITY addUnitPriority('date', 9); // PARSING addRegexToken('D', match1to2); addRegexToken('DD', match1to2, match2); addRegexToken('Do', function (isStrict, locale) { // TODO: Remove "ordinalParse" fallback in next major release. return isStrict ? (locale._dayOfMonthOrdinalParse || locale._ordinalParse) : locale._dayOfMonthOrdinalParseLenient; }); addParseToken(['D', 'DD'], DATE); addParseToken('Do', function (input, array) { array[DATE] = toInt(input.match(match1to2)[0]); }); // MOMENTS var getSetDayOfMonth = makeGetSet('Date', true); // FORMATTING addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); // ALIASES addUnitAlias('dayOfYear', 'DDD'); // PRIORITY addUnitPriority('dayOfYear', 4); // PARSING addRegexToken('DDD', match1to3); addRegexToken('DDDD', match3); addParseToken(['DDD', 'DDDD'], function (input, array, config) { config._dayOfYear = toInt(input); }); // HELPERS // MOMENTS function getSetDayOfYear (input) { var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); } // FORMATTING addFormatToken('m', ['mm', 2], 0, 'minute'); // ALIASES addUnitAlias('minute', 'm'); // PRIORITY addUnitPriority('minute', 14); // PARSING addRegexToken('m', match1to2); addRegexToken('mm', match1to2, match2); addParseToken(['m', 'mm'], MINUTE); // MOMENTS var getSetMinute = makeGetSet('Minutes', false); // FORMATTING addFormatToken('s', ['ss', 2], 0, 'second'); // ALIASES addUnitAlias('second', 's'); // PRIORITY addUnitPriority('second', 15); // PARSING addRegexToken('s', match1to2); addRegexToken('ss', match1to2, match2); addParseToken(['s', 'ss'], SECOND); // MOMENTS var getSetSecond = makeGetSet('Seconds', false); // FORMATTING addFormatToken('S', 0, 0, function () { return ~~(this.millisecond() / 100); }); addFormatToken(0, ['SS', 2], 0, function () { return ~~(this.millisecond() / 10); }); addFormatToken(0, ['SSS', 3], 0, 'millisecond'); addFormatToken(0, ['SSSS', 4], 0, function () { return this.millisecond() * 10; }); addFormatToken(0, ['SSSSS', 5], 0, function () { return this.millisecond() * 100; }); addFormatToken(0, ['SSSSSS', 6], 0, function () { return this.millisecond() * 1000; }); addFormatToken(0, ['SSSSSSS', 7], 0, function () { return this.millisecond() * 10000; }); addFormatToken(0, ['SSSSSSSS', 8], 0, function () { return this.millisecond() * 100000; }); addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { return this.millisecond() * 1000000; }); // ALIASES addUnitAlias('millisecond', 'ms'); // PRIORITY addUnitPriority('millisecond', 16); // PARSING addRegexToken('S', match1to3, match1); addRegexToken('SS', match1to3, match2); addRegexToken('SSS', match1to3, match3); var token; for (token = 'SSSS'; token.length <= 9; token += 'S') { addRegexToken(token, matchUnsigned); } function parseMs(input, array) { array[MILLISECOND] = toInt(('0.' + input) * 1000); } for (token = 'S'; token.length <= 9; token += 'S') { addParseToken(token, parseMs); } // MOMENTS var getSetMillisecond = makeGetSet('Milliseconds', false); // FORMATTING addFormatToken('z', 0, 0, 'zoneAbbr'); addFormatToken('zz', 0, 0, 'zoneName'); // MOMENTS function getZoneAbbr () { return this._isUTC ? 'UTC' : ''; } function getZoneName () { return this._isUTC ? 'Coordinated Universal Time' : ''; } var proto = Moment.prototype; proto.add = add; proto.calendar = calendar$1; proto.clone = clone; proto.diff = diff; proto.endOf = endOf; proto.format = format; proto.from = from; proto.fromNow = fromNow; proto.to = to; proto.toNow = toNow; proto.get = stringGet; proto.invalidAt = invalidAt; proto.isAfter = isAfter; proto.isBefore = isBefore; proto.isBetween = isBetween; proto.isSame = isSame; proto.isSameOrAfter = isSameOrAfter; proto.isSameOrBefore = isSameOrBefore; proto.isValid = isValid$2; proto.lang = lang; proto.locale = locale; proto.localeData = localeData; proto.max = prototypeMax; proto.min = prototypeMin; proto.parsingFlags = parsingFlags; proto.set = stringSet; proto.startOf = startOf; proto.subtract = subtract; proto.toArray = toArray; proto.toObject = toObject; proto.toDate = toDate; proto.toISOString = toISOString; proto.inspect = inspect; proto.toJSON = toJSON; proto.toString = toString; proto.unix = unix; proto.valueOf = valueOf; proto.creationData = creationData; proto.year = getSetYear; proto.isLeapYear = getIsLeapYear; proto.weekYear = getSetWeekYear; proto.isoWeekYear = getSetISOWeekYear; proto.quarter = proto.quarters = getSetQuarter; proto.month = getSetMonth; proto.daysInMonth = getDaysInMonth; proto.week = proto.weeks = getSetWeek; proto.isoWeek = proto.isoWeeks = getSetISOWeek; proto.weeksInYear = getWeeksInYear; proto.isoWeeksInYear = getISOWeeksInYear; proto.date = getSetDayOfMonth; proto.day = proto.days = getSetDayOfWeek; proto.weekday = getSetLocaleDayOfWeek; proto.isoWeekday = getSetISODayOfWeek; proto.dayOfYear = getSetDayOfYear; proto.hour = proto.hours = getSetHour; proto.minute = proto.minutes = getSetMinute; proto.second = proto.seconds = getSetSecond; proto.millisecond = proto.milliseconds = getSetMillisecond; proto.utcOffset = getSetOffset; proto.utc = setOffsetToUTC; proto.local = setOffsetToLocal; proto.parseZone = setOffsetToParsedOffset; proto.hasAlignedHourOffset = hasAlignedHourOffset; proto.isDST = isDaylightSavingTime; proto.isLocal = isLocal; proto.isUtcOffset = isUtcOffset; proto.isUtc = isUtc; proto.isUTC = isUtc; proto.zoneAbbr = getZoneAbbr; proto.zoneName = getZoneName; proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); function createUnix (input) { return createLocal(input * 1000); } function createInZone () { return createLocal.apply(null, arguments).parseZone(); } function preParsePostFormat (string) { return string; } var proto$1 = Locale.prototype; proto$1.calendar = calendar; proto$1.longDateFormat = longDateFormat; proto$1.invalidDate = invalidDate; proto$1.ordinal = ordinal; proto$1.preparse = preParsePostFormat; proto$1.postformat = preParsePostFormat; proto$1.relativeTime = relativeTime; proto$1.pastFuture = pastFuture; proto$1.set = set; proto$1.months = localeMonths; proto$1.monthsShort = localeMonthsShort; proto$1.monthsParse = localeMonthsParse; proto$1.monthsRegex = monthsRegex; proto$1.monthsShortRegex = monthsShortRegex; proto$1.week = localeWeek; proto$1.firstDayOfYear = localeFirstDayOfYear; proto$1.firstDayOfWeek = localeFirstDayOfWeek; proto$1.weekdays = localeWeekdays; proto$1.weekdaysMin = localeWeekdaysMin; proto$1.weekdaysShort = localeWeekdaysShort; proto$1.weekdaysParse = localeWeekdaysParse; proto$1.weekdaysRegex = weekdaysRegex; proto$1.weekdaysShortRegex = weekdaysShortRegex; proto$1.weekdaysMinRegex = weekdaysMinRegex; proto$1.isPM = localeIsPM; proto$1.meridiem = localeMeridiem; function get$1 (format, index, field, setter) { var locale = getLocale(); var utc = createUTC().set(setter, index); return locale[field](utc, format); } function listMonthsImpl (format, index, field) { if (isNumber(format)) { index = format; format = undefined; } format = format || ''; if (index != null) { return get$1(format, index, field, 'month'); } var i; var out = []; for (i = 0; i < 12; i++) { out[i] = get$1(format, i, field, 'month'); } return out; } // () // (5) // (fmt, 5) // (fmt) // (true) // (true, 5) // (true, fmt, 5) // (true, fmt) function listWeekdaysImpl (localeSorted, format, index, field) { if (typeof localeSorted === 'boolean') { if (isNumber(format)) { index = format; format = undefined; } format = format || ''; } else { format = localeSorted; index = format; localeSorted = false; if (isNumber(format)) { index = format; format = undefined; } format = format || ''; } var locale = getLocale(), shift = localeSorted ? locale._week.dow : 0; if (index != null) { return get$1(format, (index + shift) % 7, field, 'day'); } var i; var out = []; for (i = 0; i < 7; i++) { out[i] = get$1(format, (i + shift) % 7, field, 'day'); } return out; } function listMonths (format, index) { return listMonthsImpl(format, index, 'months'); } function listMonthsShort (format, index) { return listMonthsImpl(format, index, 'monthsShort'); } function listWeekdays (localeSorted, format, index) { return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); } function listWeekdaysShort (localeSorted, format, index) { return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); } function listWeekdaysMin (localeSorted, format, index) { return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); } getSetGlobalLocale('en', { dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, ordinal : function (number) { var b = number % 10, output = (toInt(number % 100 / 10) === 1) ? 'th' : (b === 1) ? 'st' : (b === 2) ? 'nd' : (b === 3) ? 'rd' : 'th'; return number + output; } }); // Side effect imports hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); var mathAbs = Math.abs; function abs () { var data = this._data; this._milliseconds = mathAbs(this._milliseconds); this._days = mathAbs(this._days); this._months = mathAbs(this._months); data.milliseconds = mathAbs(data.milliseconds); data.seconds = mathAbs(data.seconds); data.minutes = mathAbs(data.minutes); data.hours = mathAbs(data.hours); data.months = mathAbs(data.months); data.years = mathAbs(data.years); return this; } function addSubtract$1 (duration, input, value, direction) { var other = createDuration(input, value); duration._milliseconds += direction * other._milliseconds; duration._days += direction * other._days; duration._months += direction * other._months; return duration._bubble(); } // supports only 2.0-style add(1, 's') or add(duration) function add$1 (input, value) { return addSubtract$1(this, input, value, 1); } // supports only 2.0-style subtract(1, 's') or subtract(duration) function subtract$1 (input, value) { return addSubtract$1(this, input, value, -1); } function absCeil (number) { if (number < 0) { return Math.floor(number); } else { return Math.ceil(number); } } function bubble () { var milliseconds = this._milliseconds; var days = this._days; var months = this._months; var data = this._data; var seconds, minutes, hours, years, monthsFromDays; // if we have a mix of positive and negative values, bubble down first // check: https://github.com/moment/moment/issues/2166 if (!((milliseconds >= 0 && days >= 0 && months >= 0) || (milliseconds <= 0 && days <= 0 && months <= 0))) { milliseconds += absCeil(monthsToDays(months) + days) * 864e5; days = 0; months = 0; } // The following code bubbles up values, see the tests for // examples of what that means. data.milliseconds = milliseconds % 1000; seconds = absFloor(milliseconds / 1000); data.seconds = seconds % 60; minutes = absFloor(seconds / 60); data.minutes = minutes % 60; hours = absFloor(minutes / 60); data.hours = hours % 24; days += absFloor(hours / 24); // convert days to months monthsFromDays = absFloor(daysToMonths(days)); months += monthsFromDays; days -= absCeil(monthsToDays(monthsFromDays)); // 12 months -> 1 year years = absFloor(months / 12); months %= 12; data.days = days; data.months = months; data.years = years; return this; } function daysToMonths (days) { // 400 years have 146097 days (taking into account leap year rules) // 400 years have 12 months === 4800 return days * 4800 / 146097; } function monthsToDays (months) { // the reverse of daysToMonths return months * 146097 / 4800; } function as (units) { if (!this.isValid()) { return NaN; } var days; var months; var milliseconds = this._milliseconds; units = normalizeUnits(units); if (units === 'month' || units === 'quarter' || units === 'year') { days = this._days + milliseconds / 864e5; months = this._months + daysToMonths(days); switch (units) { case 'month': return months; case 'quarter': return months / 3; case 'year': return months / 12; } } else { // handle milliseconds separately because of floating point math errors (issue #1867) days = this._days + Math.round(monthsToDays(this._months)); switch (units) { case 'week' : return days / 7 + milliseconds / 6048e5; case 'day' : return days + milliseconds / 864e5; case 'hour' : return days * 24 + milliseconds / 36e5; case 'minute' : return days * 1440 + milliseconds / 6e4; case 'second' : return days * 86400 + milliseconds / 1000; // Math.floor prevents floating point math errors here case 'millisecond': return Math.floor(days * 864e5) + milliseconds; default: throw new Error('Unknown unit ' + units); } } } // TODO: Use this.as('ms')? function valueOf$1 () { if (!this.isValid()) { return NaN; } return ( this._milliseconds + this._days * 864e5 + (this._months % 12) * 2592e6 + toInt(this._months / 12) * 31536e6 ); } function makeAs (alias) { return function () { return this.as(alias); }; } var asMilliseconds = makeAs('ms'); var asSeconds = makeAs('s'); var asMinutes = makeAs('m'); var asHours = makeAs('h'); var asDays = makeAs('d'); var asWeeks = makeAs('w'); var asMonths = makeAs('M'); var asQuarters = makeAs('Q'); var asYears = makeAs('y'); function clone$1 () { return createDuration(this); } function get$2 (units) { units = normalizeUnits(units); return this.isValid() ? this[units + 's']() : NaN; } function makeGetter(name) { return function () { return this.isValid() ? this._data[name] : NaN; }; } var milliseconds = makeGetter('milliseconds'); var seconds = makeGetter('seconds'); var minutes = makeGetter('minutes'); var hours = makeGetter('hours'); var days = makeGetter('days'); var months = makeGetter('months'); var years = makeGetter('years'); function weeks () { return absFloor(this.days() / 7); } var round = Math.round; var thresholds = { ss: 44, // a few seconds to seconds s : 45, // seconds to minute m : 45, // minutes to hour h : 22, // hours to day d : 26, // days to month M : 11 // months to year }; // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); } function relativeTime$1 (posNegDuration, withoutSuffix, locale) { var duration = createDuration(posNegDuration).abs(); var seconds = round(duration.as('s')); var minutes = round(duration.as('m')); var hours = round(duration.as('h')); var days = round(duration.as('d')); var months = round(duration.as('M')); var years = round(duration.as('y')); var a = seconds <= thresholds.ss && ['s', seconds] || seconds < thresholds.s && ['ss', seconds] || minutes <= 1 && ['m'] || minutes < thresholds.m && ['mm', minutes] || hours <= 1 && ['h'] || hours < thresholds.h && ['hh', hours] || days <= 1 && ['d'] || days < thresholds.d && ['dd', days] || months <= 1 && ['M'] || months < thresholds.M && ['MM', months] || years <= 1 && ['y'] || ['yy', years]; a[2] = withoutSuffix; a[3] = +posNegDuration > 0; a[4] = locale; return substituteTimeAgo.apply(null, a); } // This function allows you to set the rounding function for relative time strings function getSetRelativeTimeRounding (roundingFunction) { if (roundingFunction === undefined) { return round; } if (typeof(roundingFunction) === 'function') { round = roundingFunction; return true; } return false; } // This function allows you to set a threshold for relative time strings function getSetRelativeTimeThreshold (threshold, limit) { if (thresholds[threshold] === undefined) { return false; } if (limit === undefined) { return thresholds[threshold]; } thresholds[threshold] = limit; if (threshold === 's') { thresholds.ss = limit - 1; } return true; } function humanize (withSuffix) { if (!this.isValid()) { return this.localeData().invalidDate(); } var locale = this.localeData(); var output = relativeTime$1(this, !withSuffix, locale); if (withSuffix) { output = locale.pastFuture(+this, output); } return locale.postformat(output); } var abs$1 = Math.abs; function sign(x) { return ((x > 0) - (x < 0)) || +x; } function toISOString$1() { // for ISO strings we do not use the normal bubbling rules: // * milliseconds bubble up until they become hours // * days do not bubble at all // * months bubble up until they become years // This is because there is no context-free conversion between hours and days // (think of clock changes) // and also not between days and months (28-31 days per month) if (!this.isValid()) { return this.localeData().invalidDate(); } var seconds = abs$1(this._milliseconds) / 1000; var days = abs$1(this._days); var months = abs$1(this._months); var minutes, hours, years; // 3600 seconds -> 60 minutes -> 1 hour minutes = absFloor(seconds / 60); hours = absFloor(minutes / 60); seconds %= 60; minutes %= 60; // 12 months -> 1 year years = absFloor(months / 12); months %= 12; // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js var Y = years; var M = months; var D = days; var h = hours; var m = minutes; var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; var total = this.asSeconds(); if (!total) { // this is the same as C#'s (Noda) and python (isodate)... // but not other JS (goog.date) return 'P0D'; } var totalSign = total < 0 ? '-' : ''; var ymSign = sign(this._months) !== sign(total) ? '-' : ''; var daysSign = sign(this._days) !== sign(total) ? '-' : ''; var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; return totalSign + 'P' + (Y ? ymSign + Y + 'Y' : '') + (M ? ymSign + M + 'M' : '') + (D ? daysSign + D + 'D' : '') + ((h || m || s) ? 'T' : '') + (h ? hmsSign + h + 'H' : '') + (m ? hmsSign + m + 'M' : '') + (s ? hmsSign + s + 'S' : ''); } var proto$2 = Duration.prototype; proto$2.isValid = isValid$1; proto$2.abs = abs; proto$2.add = add$1; proto$2.subtract = subtract$1; proto$2.as = as; proto$2.asMilliseconds = asMilliseconds; proto$2.asSeconds = asSeconds; proto$2.asMinutes = asMinutes; proto$2.asHours = asHours; proto$2.asDays = asDays; proto$2.asWeeks = asWeeks; proto$2.asMonths = asMonths; proto$2.asQuarters = asQuarters; proto$2.asYears = asYears; proto$2.valueOf = valueOf$1; proto$2._bubble = bubble; proto$2.clone = clone$1; proto$2.get = get$2; proto$2.milliseconds = milliseconds; proto$2.seconds = seconds; proto$2.minutes = minutes; proto$2.hours = hours; proto$2.days = days; proto$2.weeks = weeks; proto$2.months = months; proto$2.years = years; proto$2.humanize = humanize; proto$2.toISOString = toISOString$1; proto$2.toString = toISOString$1; proto$2.toJSON = toISOString$1; proto$2.locale = locale; proto$2.localeData = localeData; proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1); proto$2.lang = lang; // Side effect imports // FORMATTING addFormatToken('X', 0, 0, 'unix'); addFormatToken('x', 0, 0, 'valueOf'); // PARSING addRegexToken('x', matchSigned); addRegexToken('X', matchTimestamp); addParseToken('X', function (input, array, config) { config._d = new Date(parseFloat(input, 10) * 1000); }); addParseToken('x', function (input, array, config) { config._d = new Date(toInt(input)); }); // Side effect imports hooks.version = '2.24.0'; setHookCallback(createLocal); hooks.fn = proto; hooks.min = min; hooks.max = max; hooks.now = now; hooks.utc = createUTC; hooks.unix = createUnix; hooks.months = listMonths; hooks.isDate = isDate; hooks.locale = getSetGlobalLocale; hooks.invalid = createInvalid; hooks.duration = createDuration; hooks.isMoment = isMoment; hooks.weekdays = listWeekdays; hooks.parseZone = createInZone; hooks.localeData = getLocale; hooks.isDuration = isDuration; hooks.monthsShort = listMonthsShort; hooks.weekdaysMin = listWeekdaysMin; hooks.defineLocale = defineLocale; hooks.updateLocale = updateLocale; hooks.locales = listLocales; hooks.weekdaysShort = listWeekdaysShort; hooks.normalizeUnits = normalizeUnits; hooks.relativeTimeRounding = getSetRelativeTimeRounding; hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; hooks.calendarFormat = getCalendarFormat; hooks.prototype = proto; // currently HTML5 input type only supports 24-hour formats hooks.HTML5_FMT = { DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // <input type="datetime-local" /> DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // <input type="datetime-local" step="1" /> DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // <input type="datetime-local" step="0.001" /> DATE: 'YYYY-MM-DD', // <input type="date" /> TIME: 'HH:mm', // <input type="time" /> TIME_SECONDS: 'HH:mm:ss', // <input type="time" step="1" /> TIME_MS: 'HH:mm:ss.SSS', // <input type="time" step="0.001" /> WEEK: 'GGGG-[W]WW', // <input type="week" /> MONTH: 'YYYY-MM' // <input type="month" /> }; return hooks; }))); }); define('tinymce', function (require, exports, module) { // 4.9.4 (2019-03-20) (function () { (function (domGlobals) { 'use strict'; var noop = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } }; var compose = function (fa, fb) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return fa(fb.apply(null, args)); }; }; var constant = function (value) { return function () { return value; }; }; var identity = function (x) { return x; }; function curry(fn) { var initialArgs = []; for (var _i = 1; _i < arguments.length; _i++) { initialArgs[_i - 1] = arguments[_i]; } return function () { var restArgs = []; for (var _i = 0; _i < arguments.length; _i++) { restArgs[_i] = arguments[_i]; } var all = initialArgs.concat(restArgs); return fn.apply(null, all); }; } var not = function (f) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return !f.apply(null, args); }; }; var die = function (msg) { return function () { throw new Error(msg); }; }; var never = constant(false); var always = constant(true); var never$1 = never; var always$1 = always; var none = function () { return NONE; }; var NONE = function () { var eq = function (o) { return o.isNone(); }; var call = function (thunk) { return thunk(); }; var id = function (n) { return n; }; var noop = function () { }; var nul = function () { return null; }; var undef = function () { return undefined; }; var me = { fold: function (n, s) { return n(); }, is: never$1, isSome: never$1, isNone: always$1, getOr: id, getOrThunk: call, getOrDie: function (msg) { throw new Error(msg || 'error: getOrDie called on none.'); }, getOrNull: nul, getOrUndefined: undef, or: id, orThunk: call, map: none, ap: none, each: noop, bind: none, flatten: none, exists: never$1, forall: always$1, filter: none, equals: eq, equals_: eq, toArray: function () { return []; }, toString: constant('none()') }; if (Object.freeze) Object.freeze(me); return me; }(); var some = function (a) { var constant_a = function () { return a; }; var self = function () { return me; }; var map = function (f) { return some(f(a)); }; var bind = function (f) { return f(a); }; var me = { fold: function (n, s) { return s(a); }, is: function (v) { return a === v; }, isSome: always$1, isNone: never$1, getOr: constant_a, getOrThunk: constant_a, getOrDie: constant_a, getOrNull: constant_a, getOrUndefined: constant_a, or: self, orThunk: self, map: map, ap: function (optfab) { return optfab.fold(none, function (fab) { return some(fab(a)); }); }, each: function (f) { f(a); }, bind: bind, flatten: constant_a, exists: bind, forall: bind, filter: function (f) { return f(a) ? me : NONE; }, equals: function (o) { return o.is(a); }, equals_: function (o, elementEq) { return o.fold(never$1, function (b) { return elementEq(a, b); }); }, toArray: function () { return [a]; }, toString: function () { return 'some(' + a + ')'; } }; return me; }; var from = function (value) { return value === null || value === undefined ? NONE : some(value); }; var Option = { some: some, none: none, from: from }; var typeOf = function (x) { if (x === null) return 'null'; var t = typeof x; if (t === 'object' && Array.prototype.isPrototypeOf(x)) return 'array'; if (t === 'object' && String.prototype.isPrototypeOf(x)) return 'string'; return t; }; var isType = function (type) { return function (value) { return typeOf(value) === type; }; }; var isString = isType('string'); var isObject = isType('object'); var isArray = isType('array'); var isNull = isType('null'); var isBoolean = isType('boolean'); var isFunction = isType('function'); var isNumber = isType('number'); var rawIndexOf = function () { var pIndexOf = Array.prototype.indexOf; var fastIndex = function (xs, x) { return pIndexOf.call(xs, x); }; var slowIndex = function (xs, x) { return slowIndexOf(xs, x); }; return pIndexOf === undefined ? slowIndex : fastIndex; }(); var indexOf = function (xs, x) { var r = rawIndexOf(xs, x); return r === -1 ? Option.none() : Option.some(r); }; var contains = function (xs, x) { return rawIndexOf(xs, x) > -1; }; var exists = function (xs, pred) { return findIndex(xs, pred).isSome(); }; var map = function (xs, f) { var len = xs.length; var r = new Array(len); for (var i = 0; i < len; i++) { var x = xs[i]; r[i] = f(x, i, xs); } return r; }; var each = function (xs, f) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; f(x, i, xs); } }; var eachr = function (xs, f) { for (var i = xs.length - 1; i >= 0; i--) { var x = xs[i]; f(x, i, xs); } }; var partition = function (xs, pred) { var pass = []; var fail = []; for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; var arr = pred(x, i, xs) ? pass : fail; arr.push(x); } return { pass: pass, fail: fail }; }; var filter = function (xs, pred) { var r = []; for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { r.push(x); } } return r; }; var foldr = function (xs, f, acc) { eachr(xs, function (x) { acc = f(acc, x); }); return acc; }; var foldl = function (xs, f, acc) { each(xs, function (x) { acc = f(acc, x); }); return acc; }; var find = function (xs, pred) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { return Option.some(x); } } return Option.none(); }; var findIndex = function (xs, pred) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { return Option.some(i); } } return Option.none(); }; var slowIndexOf = function (xs, x) { for (var i = 0, len = xs.length; i < len; ++i) { if (xs[i] === x) { return i; } } return -1; }; var push = Array.prototype.push; var flatten = function (xs) { var r = []; for (var i = 0, len = xs.length; i < len; ++i) { if (!Array.prototype.isPrototypeOf(xs[i])) throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs); push.apply(r, xs[i]); } return r; }; var bind = function (xs, f) { var output = map(xs, f); return flatten(output); }; var forall = function (xs, pred) { for (var i = 0, len = xs.length; i < len; ++i) { var x = xs[i]; if (pred(x, i, xs) !== true) { return false; } } return true; }; var slice = Array.prototype.slice; var reverse = function (xs) { var r = slice.call(xs, 0); r.reverse(); return r; }; var difference = function (a1, a2) { return filter(a1, function (x) { return !contains(a2, x); }); }; var mapToObject = function (xs, f) { var r = {}; for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; r[String(x)] = f(x, i); } return r; }; var sort = function (xs, comparator) { var copy = slice.call(xs, 0); copy.sort(comparator); return copy; }; var head = function (xs) { return xs.length === 0 ? Option.none() : Option.some(xs[0]); }; var last = function (xs) { return xs.length === 0 ? Option.none() : Option.some(xs[xs.length - 1]); }; var from$1 = isFunction(Array.from) ? Array.from : function (x) { return slice.call(x); }; var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')(); var path = function (parts, scope) { var o = scope !== undefined && scope !== null ? scope : Global; for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i) o = o[parts[i]]; return o; }; var resolve = function (p, scope) { var parts = p.split('.'); return path(parts, scope); }; var unsafe = function (name, scope) { return resolve(name, scope); }; var getOrDie = function (name, scope) { var actual = unsafe(name, scope); if (actual === undefined || actual === null) throw name + ' not available on this browser'; return actual; }; var Global$1 = { getOrDie: getOrDie }; var url = function () { return Global$1.getOrDie('URL'); }; var createObjectURL = function (blob) { return url().createObjectURL(blob); }; var revokeObjectURL = function (u) { url().revokeObjectURL(u); }; var URL = { createObjectURL: createObjectURL, revokeObjectURL: revokeObjectURL }; var nav = domGlobals.navigator, userAgent = nav.userAgent; var opera, webkit, ie, ie11, ie12, gecko, mac, iDevice, android, fileApi, phone, tablet, windowsPhone; var matchMediaQuery = function (query) { return 'matchMedia' in domGlobals.window ? domGlobals.matchMedia(query).matches : false; }; opera = false; android = /Android/.test(userAgent); webkit = /WebKit/.test(userAgent); ie = !webkit && !opera && /MSIE/gi.test(userAgent) && /Explorer/gi.test(nav.appName); ie = ie && /MSIE (\w+)\./.exec(userAgent)[1]; ie11 = userAgent.indexOf('Trident/') !== -1 && (userAgent.indexOf('rv:') !== -1 || nav.appName.indexOf('Netscape') !== -1) ? 11 : false; ie12 = userAgent.indexOf('Edge/') !== -1 && !ie && !ie11 ? 12 : false; ie = ie || ie11 || ie12; gecko = !webkit && !ie11 && /Gecko/.test(userAgent); mac = userAgent.indexOf('Mac') !== -1; iDevice = /(iPad|iPhone)/.test(userAgent); fileApi = 'FormData' in domGlobals.window && 'FileReader' in domGlobals.window && 'URL' in domGlobals.window && !!URL.createObjectURL; phone = matchMediaQuery('only screen and (max-device-width: 480px)') && (android || iDevice); tablet = matchMediaQuery('only screen and (min-width: 800px)') && (android || iDevice); windowsPhone = userAgent.indexOf('Windows Phone') !== -1; if (ie12) { webkit = false; } var contentEditable = !iDevice || fileApi || parseInt(userAgent.match(/AppleWebKit\/(\d*)/)[1], 10) >= 534; var Env = { opera: opera, webkit: webkit, ie: ie, gecko: gecko, mac: mac, iOS: iDevice, android: android, contentEditable: contentEditable, transparentSrc: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7', caretAfter: ie !== 8, range: domGlobals.window.getSelection && 'Range' in domGlobals.window, documentMode: ie && !ie12 ? domGlobals.document.documentMode || 7 : 10, fileApi: fileApi, ceFalse: ie === false || ie > 8, cacheSuffix: null, container: null, overrideViewPort: null, experimentalShadowDom: false, canHaveCSP: ie === false || ie > 11, desktop: !phone && !tablet, windowsPhone: windowsPhone }; var promise = function () { function bind(fn, thisArg) { return function () { fn.apply(thisArg, arguments); }; } var isArray = Array.isArray || function (value) { return Object.prototype.toString.call(value) === '[object Array]'; }; var Promise = function (fn) { if (typeof this !== 'object') { throw new TypeError('Promises must be constructed via new'); } if (typeof fn !== 'function') { throw new TypeError('not a function'); } this._state = null; this._value = null; this._deferreds = []; doResolve(fn, bind(resolve, this), bind(reject, this)); }; var asap = Promise.immediateFn || typeof setImmediate === 'function' && setImmediate || function (fn) { setTimeout(fn, 1); }; function handle(deferred) { var me = this; if (this._state === null) { this._deferreds.push(deferred); return; } asap(function () { var cb = me._state ? deferred.onFulfilled : deferred.onRejected; if (cb === null) { (me._state ? deferred.resolve : deferred.reject)(me._value); return; } var ret; try { ret = cb(me._value); } catch (e) { deferred.reject(e); return; } deferred.resolve(ret); }); } function resolve(newValue) { try { if (newValue === this) { throw new TypeError('A promise cannot be resolved with itself.'); } if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { var then = newValue.then; if (typeof then === 'function') { doResolve(bind(then, newValue), bind(resolve, this), bind(reject, this)); return; } } this._state = true; this._value = newValue; finale.call(this); } catch (e) { reject.call(this, e); } } function reject(newValue) { this._state = false; this._value = newValue; finale.call(this); } function finale() { for (var i = 0, len = this._deferreds.length; i < len; i++) { handle.call(this, this._deferreds[i]); } this._deferreds = null; } function Handler(onFulfilled, onRejected, resolve, reject) { this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; this.onRejected = typeof onRejected === 'function' ? onRejected : null; this.resolve = resolve; this.reject = reject; } function doResolve(fn, onFulfilled, onRejected) { var done = false; try { fn(function (value) { if (done) { return; } done = true; onFulfilled(value); }, function (reason) { if (done) { return; } done = true; onRejected(reason); }); } catch (ex) { if (done) { return; } done = true; onRejected(ex); } } Promise.prototype.catch = function (onRejected) { return this.then(null, onRejected); }; Promise.prototype.then = function (onFulfilled, onRejected) { var me = this; return new Promise(function (resolve, reject) { handle.call(me, new Handler(onFulfilled, onRejected, resolve, reject)); }); }; Promise.all = function () { var args = Array.prototype.slice.call(arguments.length === 1 && isArray(arguments[0]) ? arguments[0] : arguments); return new Promise(function (resolve, reject) { if (args.length === 0) { return resolve([]); } var remaining = args.length; function res(i, val) { try { if (val && (typeof val === 'object' || typeof val === 'function')) { var then = val.then; if (typeof then === 'function') { then.call(val, function (val) { res(i, val); }, reject); return; } } args[i] = val; if (--remaining === 0) { resolve(args); } } catch (ex) { reject(ex); } } for (var i = 0; i < args.length; i++) { res(i, args[i]); } }); }; Promise.resolve = function (value) { if (value && typeof value === 'object' && value.constructor === Promise) { return value; } return new Promise(function (resolve) { resolve(value); }); }; Promise.reject = function (value) { return new Promise(function (resolve, reject) { reject(value); }); }; Promise.race = function (values) { return new Promise(function (resolve, reject) { for (var i = 0, len = values.length; i < len; i++) { values[i].then(resolve, reject); } }); }; return Promise; }; var promiseObj = window.Promise ? window.Promise : promise(); var requestAnimationFramePromise; var requestAnimationFrame = function (callback, element) { var i, requestAnimationFrameFunc = domGlobals.window.requestAnimationFrame; var vendors = [ 'ms', 'moz', 'webkit' ]; var featurefill = function (callback) { domGlobals.window.setTimeout(callback, 0); }; for (i = 0; i < vendors.length && !requestAnimationFrameFunc; i++) { requestAnimationFrameFunc = domGlobals.window[vendors[i] + 'RequestAnimationFrame']; } if (!requestAnimationFrameFunc) { requestAnimationFrameFunc = featurefill; } requestAnimationFrameFunc(callback, element); }; var wrappedSetTimeout = function (callback, time) { if (typeof time !== 'number') { time = 0; } return setTimeout(callback, time); }; var wrappedSetInterval = function (callback, time) { if (typeof time !== 'number') { time = 1; } return setInterval(callback, time); }; var wrappedClearTimeout = function (id) { return clearTimeout(id); }; var wrappedClearInterval = function (id) { return clearInterval(id); }; var debounce = function (callback, time) { var timer, func; func = function () { var args = arguments; clearTimeout(timer); timer = wrappedSetTimeout(function () { callback.apply(this, args); }, time); }; func.stop = function () { clearTimeout(timer); }; return func; }; var Delay = { requestAnimationFrame: function (callback, element) { if (requestAnimationFramePromise) { requestAnimationFramePromise.then(callback); return; } requestAnimationFramePromise = new promiseObj(function (resolve) { if (!element) { element = domGlobals.document.body; } requestAnimationFrame(resolve, element); }).then(callback); }, setTimeout: wrappedSetTimeout, setInterval: wrappedSetInterval, setEditorTimeout: function (editor, callback, time) { return wrappedSetTimeout(function () { if (!editor.removed) { callback(); } }, time); }, setEditorInterval: function (editor, callback, time) { var timer; timer = wrappedSetInterval(function () { if (!editor.removed) { callback(); } else { clearInterval(timer); } }, time); return timer; }, debounce: debounce, throttle: debounce, clearInterval: wrappedClearInterval, clearTimeout: wrappedClearTimeout }; var eventExpandoPrefix = 'mce-data-'; var mouseEventRe = /^(?:mouse|contextmenu)|click/; var deprecated = { keyLocation: 1, layerX: 1, layerY: 1, returnValue: 1, webkitMovementX: 1, webkitMovementY: 1, keyIdentifier: 1 }; var hasIsDefaultPrevented = function (event) { return event.isDefaultPrevented === returnTrue || event.isDefaultPrevented === returnFalse; }; var returnFalse = function () { return false; }; var returnTrue = function () { return true; }; var addEvent = function (target, name, callback, capture) { if (target.addEventListener) { target.addEventListener(name, callback, capture || false); } else if (target.attachEvent) { target.attachEvent('on' + name, callback); } }; var removeEvent = function (target, name, callback, capture) { if (target.removeEventListener) { target.removeEventListener(name, callback, capture || false); } else if (target.detachEvent) { target.detachEvent('on' + name, callback); } }; var getTargetFromShadowDom = function (event, defaultTarget) { if (event.composedPath) { var composedPath = event.composedPath(); if (composedPath && composedPath.length > 0) { return composedPath[0]; } } return defaultTarget; }; var fix = function (originalEvent, data) { var name; var event = data || {}; for (name in originalEvent) { if (!deprecated[name]) { event[name] = originalEvent[name]; } } if (!event.target) { event.target = event.srcElement || domGlobals.document; } if (Env.experimentalShadowDom) { event.target = getTargetFromShadowDom(originalEvent, event.target); } if (originalEvent && mouseEventRe.test(originalEvent.type) && originalEvent.pageX === undefined && originalEvent.clientX !== undefined) { var eventDoc = event.target.ownerDocument || domGlobals.document; var doc = eventDoc.documentElement; var body = eventDoc.body; event.pageX = originalEvent.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); event.pageY = originalEvent.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); } event.preventDefault = function () { event.isDefaultPrevented = returnTrue; if (originalEvent) { if (originalEvent.preventDefault) { originalEvent.preventDefault(); } else { originalEvent.returnValue = false; } } }; event.stopPropagation = function () { event.isPropagationStopped = returnTrue; if (originalEvent) { if (originalEvent.stopPropagation) { originalEvent.stopPropagation(); } else { originalEvent.cancelBubble = true; } } }; event.stopImmediatePropagation = function () { event.isImmediatePropagationStopped = returnTrue; event.stopPropagation(); }; if (hasIsDefaultPrevented(event) === false) { event.isDefaultPrevented = returnFalse; event.isPropagationStopped = returnFalse; event.isImmediatePropagationStopped = returnFalse; } if (typeof event.metaKey === 'undefined') { event.metaKey = false; } return event; }; var bindOnReady = function (win, callback, eventUtils) { var doc = win.document, event = { type: 'ready' }; if (eventUtils.domLoaded) { callback(event); return; } var isDocReady = function () { return doc.readyState === 'complete' || doc.readyState === 'interactive' && doc.body; }; var readyHandler = function () { if (!eventUtils.domLoaded) { eventUtils.domLoaded = true; callback(event); } }; var waitForDomLoaded = function () { if (isDocReady()) { removeEvent(doc, 'readystatechange', waitForDomLoaded); readyHandler(); } }; var tryScroll = function () { try { doc.documentElement.doScroll('left'); } catch (ex) { Delay.setTimeout(tryScroll); return; } readyHandler(); }; if (doc.addEventListener && !(Env.ie && Env.ie < 11)) { if (isDocReady()) { readyHandler(); } else { addEvent(win, 'DOMContentLoaded', readyHandler); } } else { addEvent(doc, 'readystatechange', waitForDomLoaded); if (doc.documentElement.doScroll && win.self === win.top) { tryScroll(); } } addEvent(win, 'load', readyHandler); }; var EventUtils = function () { var self = this; var events = {}, count, expando, hasFocusIn, hasMouseEnterLeave, mouseEnterLeave; expando = eventExpandoPrefix + (+new Date()).toString(32); hasMouseEnterLeave = 'onmouseenter' in domGlobals.document.documentElement; hasFocusIn = 'onfocusin' in domGlobals.document.documentElement; mouseEnterLeave = { mouseenter: 'mouseover', mouseleave: 'mouseout' }; count = 1; self.domLoaded = false; self.events = events; var executeHandlers = function (evt, id) { var callbackList, i, l, callback; var container = events[id]; callbackList = container && container[evt.type]; if (callbackList) { for (i = 0, l = callbackList.length; i < l; i++) { callback = callbackList[i]; if (callback && callback.func.call(callback.scope, evt) === false) { evt.preventDefault(); } if (evt.isImmediatePropagationStopped()) { return; } } } }; self.bind = function (target, names, callback, scope) { var id, callbackList, i, name, fakeName, nativeHandler, capture; var win = domGlobals.window; var defaultNativeHandler = function (evt) { executeHandlers(fix(evt || win.event), id); }; if (!target || target.nodeType === 3 || target.nodeType === 8) { return; } if (!target[expando]) { id = count++; target[expando] = id; events[id] = {}; } else { id = target[expando]; } scope = scope || target; names = names.split(' '); i = names.length; while (i--) { name = names[i]; nativeHandler = defaultNativeHandler; fakeName = capture = false; if (name === 'DOMContentLoaded') { name = 'ready'; } if (self.domLoaded && name === 'ready' && target.readyState === 'complete') { callback.call(scope, fix({ type: name })); continue; } if (!hasMouseEnterLeave) { fakeName = mouseEnterLeave[name]; if (fakeName) { nativeHandler = function (evt) { var current, related; current = evt.currentTarget; related = evt.relatedTarget; if (related && current.contains) { related = current.contains(related); } else { while (related && related !== current) { related = related.parentNode; } } if (!related) { evt = fix(evt || win.event); evt.type = evt.type === 'mouseout' ? 'mouseleave' : 'mouseenter'; evt.target = current; executeHandlers(evt, id); } }; } } if (!hasFocusIn && (name === 'focusin' || name === 'focusout')) { capture = true; fakeName = name === 'focusin' ? 'focus' : 'blur'; nativeHandler = function (evt) { evt = fix(evt || win.event); evt.type = evt.type === 'focus' ? 'focusin' : 'focusout'; executeHandlers(evt, id); }; } callbackList = events[id][name]; if (!callbackList) { events[id][name] = callbackList = [{ func: callback, scope: scope }]; callbackList.fakeName = fakeName; callbackList.capture = capture; callbackList.nativeHandler = nativeHandler; if (name === 'ready') { bindOnReady(target, nativeHandler, self); } else { addEvent(target, fakeName || name, nativeHandler, capture); } } else { if (name === 'ready' && self.domLoaded) { callback({ type: name }); } else { callbackList.push({ func: callback, scope: scope }); } } } target = callbackList = 0; return callback; }; self.unbind = function (target, names, callback) { var id, callbackList, i, ci, name, eventMap; if (!target || target.nodeType === 3 || target.nodeType === 8) { return self; } id = target[expando]; if (id) { eventMap = events[id]; if (names) { names = names.split(' '); i = names.length; while (i--) { name = names[i]; callbackList = eventMap[name]; if (callbackList) { if (callback) { ci = callbackList.length; while (ci--) { if (callbackList[ci].func === callback) { var nativeHandler = callbackList.nativeHandler; var fakeName = callbackList.fakeName, capture = callbackList.capture; callbackList = callbackList.slice(0, ci).concat(callbackList.slice(ci + 1)); callbackList.nativeHandler = nativeHandler; callbackList.fakeName = fakeName; callbackList.capture = capture; eventMap[name] = callbackList; } } } if (!callback || callbackList.length === 0) { delete eventMap[name]; removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture); } } } } else { for (name in eventMap) { callbackList = eventMap[name]; removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture); } eventMap = {}; } for (name in eventMap) { return self; } delete events[id]; try { delete target[expando]; } catch (ex) { target[expando] = null; } } return self; }; self.fire = function (target, name, args) { var id; if (!target || target.nodeType === 3 || target.nodeType === 8) { return self; } args = fix(null, args); args.type = name; args.target = target; do { id = target[expando]; if (id) { executeHandlers(args, id); } target = target.parentNode || target.ownerDocument || target.defaultView || target.parentWindow; } while (target && !args.isPropagationStopped()); return self; }; self.clean = function (target) { var i, children; var unbind = self.unbind; if (!target || target.nodeType === 3 || target.nodeType === 8) { return self; } if (target[expando]) { unbind(target); } if (!target.getElementsByTagName) { target = target.document; } if (target && target.getElementsByTagName) { unbind(target); children = target.getElementsByTagName('*'); i = children.length; while (i--) { target = children[i]; if (target[expando]) { unbind(target); } } } return self; }; self.destroy = function () { events = {}; }; self.cancel = function (e) { if (e) { e.preventDefault(); e.stopImmediatePropagation(); } return false; }; }; EventUtils.Event = new EventUtils(); EventUtils.Event.bind(domGlobals.window, 'ready', function () { }); var i, support, Expr, getText, isXML, tokenize, compile, select, outermostContext, sortInput, hasDuplicate, setDocument, document, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains$1, expando = 'sizzle' + -new Date(), preferredDoc = domGlobals.window.document, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), sortOrder = function (a, b) { if (a === b) { hasDuplicate = true; } return 0; }, strundefined = typeof undefined, MAX_NEGATIVE = 1 << 31, hasOwn = {}.hasOwnProperty, arr = [], pop = arr.pop, push_native = arr.push, push$1 = arr.push, slice$1 = arr.slice, indexOf$1 = arr.indexOf || function (elem) { var i = 0, len = this.length; for (; i < len; i++) { if (this[i] === elem) { return i; } } return -1; }, booleans = 'checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped', whitespace = '[\\x20\\t\\r\\n\\f]', identifier = '(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+', attributes = '\\[' + whitespace + '*(' + identifier + ')(?:' + whitespace + '*([*^$|!~]?=)' + whitespace + '*(?:\'((?:\\\\.|[^\\\\\'])*)\'|"((?:\\\\.|[^\\\\"])*)"|(' + identifier + '))|)' + whitespace + '*\\]', pseudos = ':(' + identifier + ')(?:\\((' + '(\'((?:\\\\.|[^\\\\\'])*)\'|"((?:\\\\.|[^\\\\"])*)")|' + '((?:\\\\.|[^\\\\()[\\]]|' + attributes + ')*)|' + '.*' + ')\\)|)', rtrim = new RegExp('^' + whitespace + '+|((?:^|[^\\\\])(?:\\\\.)*)' + whitespace + '+$', 'g'), rcomma = new RegExp('^' + whitespace + '*,' + whitespace + '*'), rcombinators = new RegExp('^' + whitespace + '*([>+~]|' + whitespace + ')' + whitespace + '*'), rattributeQuotes = new RegExp('=' + whitespace + '*([^\\]\'"]*?)' + whitespace + '*\\]', 'g'), rpseudo = new RegExp(pseudos), ridentifier = new RegExp('^' + identifier + '$'), matchExpr = { ID: new RegExp('^#(' + identifier + ')'), CLASS: new RegExp('^\\.(' + identifier + ')'), TAG: new RegExp('^(' + identifier + '|[*])'), ATTR: new RegExp('^' + attributes), PSEUDO: new RegExp('^' + pseudos), CHILD: new RegExp('^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(' + whitespace + '*(even|odd|(([+-]|)(\\d*)n|)' + whitespace + '*(?:([+-]|)' + whitespace + '*(\\d+)|))' + whitespace + '*\\)|)', 'i'), bool: new RegExp('^(?:' + booleans + ')$', 'i'), needsContext: new RegExp('^' + whitespace + '*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(' + whitespace + '*((?:-\\d)?\\d*)' + whitespace + '*\\)|)(?=[^-]|$)', 'i') }, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, rescape = /'|\\/g, runescape = new RegExp('\\\\([\\da-f]{1,6}' + whitespace + '?|(' + whitespace + ')|.)', 'ig'), funescape = function (_, escaped, escapedWhitespace) { var high = '0x' + escaped - 65536; return high !== high || escapedWhitespace ? escaped : high < 0 ? String.fromCharCode(high + 65536) : String.fromCharCode(high >> 10 | 55296, high & 1023 | 56320); }; try { push$1.apply(arr = slice$1.call(preferredDoc.childNodes), preferredDoc.childNodes); arr[preferredDoc.childNodes.length].nodeType; } catch (e) { push$1 = { apply: arr.length ? function (target, els) { push_native.apply(target, slice$1.call(els)); } : function (target, els) { var j = target.length, i = 0; while (target[j++] = els[i++]) { } target.length = j - 1; } }; } var Sizzle = function (selector, context, results, seed) { var match, elem, m, nodeType, i, groups, old, nid, newContext, newSelector; if ((context ? context.ownerDocument || context : preferredDoc) !== document) { setDocument(context); } context = context || document; results = results || []; if (!selector || typeof selector !== 'string') { return results; } if ((nodeType = context.nodeType) !== 1 && nodeType !== 9) { return []; } if (documentIsHTML && !seed) { if (match = rquickExpr.exec(selector)) { if (m = match[1]) { if (nodeType === 9) { elem = context.getElementById(m); if (elem && elem.parentNode) { if (elem.id === m) { results.push(elem); return results; } } else { return results; } } else { if (context.ownerDocument && (elem = context.ownerDocument.getElementById(m)) && contains$1(context, elem) && elem.id === m) { results.push(elem); return results; } } } else if (match[2]) { push$1.apply(results, context.getElementsByTagName(selector)); return results; } else if ((m = match[3]) && support.getElementsByClassName) { push$1.apply(results, context.getElementsByClassName(m)); return results; } } if (support.qsa && (!rbuggyQSA || !rbuggyQSA.test(selector))) { nid = old = expando; newContext = context; newSelector = nodeType === 9 && selector; if (nodeType === 1 && context.nodeName.toLowerCase() !== 'object') { groups = tokenize(selector); if (old = context.getAttribute('id')) { nid = old.replace(rescape, '\\$&'); } else { context.setAttribute('id', nid); } nid = '[id=\'' + nid + '\'] '; i = groups.length; while (i--) { groups[i] = nid + toSelector(groups[i]); } newContext = rsibling.test(selector) && testContext(context.parentNode) || context; newSelector = groups.join(','); } if (newSelector) { try { push$1.apply(results, newContext.querySelectorAll(newSelector)); return results; } catch (qsaError) { } finally { if (!old) { context.removeAttribute('id'); } } } } } return select(selector.replace(rtrim, '$1'), context, results, seed); }; function createCache() { var keys = []; function cache(key, value) { if (keys.push(key + ' ') > Expr.cacheLength) { delete cache[keys.shift()]; } return cache[key + ' '] = value; } return cache; } function markFunction(fn) { fn[expando] = true; return fn; } function siblingCheck(a, b) { var cur = b && a, diff = cur && a.nodeType === 1 && b.nodeType === 1 && (~b.sourceIndex || MAX_NEGATIVE) - (~a.sourceIndex || MAX_NEGATIVE); if (diff) { return diff; } if (cur) { while (cur = cur.nextSibling) { if (cur === b) { return -1; } } } return a ? 1 : -1; } function createInputPseudo(type) { return function (elem) { var name = elem.nodeName.toLowerCase(); return name === 'input' && elem.type === type; }; } function createButtonPseudo(type) { return function (elem) { var name = elem.nodeName.toLowerCase(); return (name === 'input' || name === 'button') && elem.type === type; }; } function createPositionalPseudo(fn) { return markFunction(function (argument) { argument = +argument; return markFunction(function (seed, matches) { var j, matchIndexes = fn([], seed.length, argument), i = matchIndexes.length; while (i--) { if (seed[j = matchIndexes[i]]) { seed[j] = !(matches[j] = seed[j]); } } }); }); } function testContext(context) { return context && typeof context.getElementsByTagName !== strundefined && context; } support = Sizzle.support = {}; isXML = Sizzle.isXML = function (elem) { var documentElement = elem && (elem.ownerDocument || elem).documentElement; return documentElement ? documentElement.nodeName !== 'HTML' : false; }; setDocument = Sizzle.setDocument = function (node) { var hasCompare, doc = node ? node.ownerDocument || node : preferredDoc, parent = doc.defaultView; function getTop(win) { try { return win.top; } catch (ex) { } return null; } if (doc === document || doc.nodeType !== 9 || !doc.documentElement) { return document; } document = doc; docElem = doc.documentElement; documentIsHTML = !isXML(doc); if (parent && parent !== getTop(parent)) { if (parent.addEventListener) { parent.addEventListener('unload', function () { setDocument(); }, false); } else if (parent.attachEvent) { parent.attachEvent('onunload', function () { setDocument(); }); } } support.attributes = true; support.getElementsByTagName = true; support.getElementsByClassName = rnative.test(doc.getElementsByClassName); support.getById = true; Expr.find.ID = function (id, context) { if (typeof context.getElementById !== strundefined && documentIsHTML) { var m = context.getElementById(id); return m && m.parentNode ? [m] : []; } }; Expr.filter.ID = function (id) { var attrId = id.replace(runescape, funescape); return function (elem) { return elem.getAttribute('id') === attrId; }; }; Expr.find.TAG = support.getElementsByTagName ? function (tag, context) { if (typeof context.getElementsByTagName !== strundefined) { return context.getElementsByTagName(tag); } } : function (tag, context) { var elem, tmp = [], i = 0, results = context.getElementsByTagName(tag); if (tag === '*') { while (elem = results[i++]) { if (elem.nodeType === 1) { tmp.push(elem); } } return tmp; } return results; }; Expr.find.CLASS = support.getElementsByClassName && function (className, context) { if (documentIsHTML) { return context.getElementsByClassName(className); } }; rbuggyMatches = []; rbuggyQSA = []; support.disconnectedMatch = true; rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join('|')); rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join('|')); hasCompare = rnative.test(docElem.compareDocumentPosition); contains$1 = hasCompare || rnative.test(docElem.contains) ? function (a, b) { var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode; return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16)); } : function (a, b) { if (b) { while (b = b.parentNode) { if (b === a) { return true; } } } return false; }; sortOrder = hasCompare ? function (a, b) { if (a === b) { hasDuplicate = true; return 0; } var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; if (compare) { return compare; } compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1; if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) { if (a === doc || a.ownerDocument === preferredDoc && contains$1(preferredDoc, a)) { return -1; } if (b === doc || b.ownerDocument === preferredDoc && contains$1(preferredDoc, b)) { return 1; } return sortInput ? indexOf$1.call(sortInput, a) - indexOf$1.call(sortInput, b) : 0; } return compare & 4 ? -1 : 1; } : function (a, b) { if (a === b) { hasDuplicate = true; return 0; } var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [a], bp = [b]; if (!aup || !bup) { return a === doc ? -1 : b === doc ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf$1.call(sortInput, a) - indexOf$1.call(sortInput, b) : 0; } else if (aup === bup) { return siblingCheck(a, b); } cur = a; while (cur = cur.parentNode) { ap.unshift(cur); } cur = b; while (cur = cur.parentNode) { bp.unshift(cur); } while (ap[i] === bp[i]) { i++; } return i ? siblingCheck(ap[i], bp[i]) : ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0; }; return doc; }; Sizzle.matches = function (expr, elements) { return Sizzle(expr, null, null, elements); }; Sizzle.matchesSelector = function (elem, expr) { if ((elem.ownerDocument || elem) !== document) { setDocument(elem); } expr = expr.replace(rattributeQuotes, '=\'$1\']'); if (support.matchesSelector && documentIsHTML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) { try { var ret = matches.call(elem, expr); if (ret || support.disconnectedMatch || elem.document && elem.document.nodeType !== 11) { return ret; } } catch (e) { } } return Sizzle(expr, document, null, [elem]).length > 0; }; Sizzle.contains = function (context, elem) { if ((context.ownerDocument || context) !== document) { setDocument(context); } return contains$1(context, elem); }; Sizzle.attr = function (elem, name) { if ((elem.ownerDocument || elem) !== document) { setDocument(elem); } var fn = Expr.attrHandle[name.toLowerCase()], val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined; return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; }; Sizzle.error = function (msg) { throw new Error('Syntax error, unrecognized expression: ' + msg); }; Sizzle.uniqueSort = function (results) { var elem, duplicates = [], j = 0, i = 0; hasDuplicate = !support.detectDuplicates; sortInput = !support.sortStable && results.slice(0); results.sort(sortOrder); if (hasDuplicate) { while (elem = results[i++]) { if (elem === results[i]) { j = duplicates.push(i); } } while (j--) { results.splice(duplicates[j], 1); } } sortInput = null; return results; }; getText = Sizzle.getText = function (elem) { var node, ret = '', i = 0, nodeType = elem.nodeType; if (!nodeType) { while (node = elem[i++]) { ret += getText(node); } } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) { if (typeof elem.textContent === 'string') { return elem.textContent; } else { for (elem = elem.firstChild; elem; elem = elem.nextSibling) { ret += getText(elem); } } } else if (nodeType === 3 || nodeType === 4) { return elem.nodeValue; } return ret; }; Expr = Sizzle.selectors = { cacheLength: 50, createPseudo: markFunction, match: matchExpr, attrHandle: {}, find: {}, relative: { '>': { dir: 'parentNode', first: true }, ' ': { dir: 'parentNode' }, '+': { dir: 'previousSibling', first: true }, '~': { dir: 'previousSibling' } }, preFilter: { ATTR: function (match) { match[1] = match[1].replace(runescape, funescape); match[3] = (match[3] || match[4] || match[5] || '').replace(runescape, funescape); if (match[2] === '~=') { match[3] = ' ' + match[3] + ' '; } return match.slice(0, 4); }, CHILD: function (match) { match[1] = match[1].toLowerCase(); if (match[1].slice(0, 3) === 'nth') { if (!match[3]) { Sizzle.error(match[0]); } match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === 'even' || match[3] === 'odd')); match[5] = +(match[7] + match[8] || match[3] === 'odd'); } else if (match[3]) { Sizzle.error(match[0]); } return match; }, PSEUDO: function (match) { var excess, unquoted = !match[6] && match[2]; if (matchExpr.CHILD.test(match[0])) { return null; } if (match[3]) { match[2] = match[4] || match[5] || ''; } else if (unquoted && rpseudo.test(unquoted) && (excess = tokenize(unquoted, true)) && (excess = unquoted.indexOf(')', unquoted.length - excess) - unquoted.length)) { match[0] = match[0].slice(0, excess); match[2] = unquoted.slice(0, excess); } return match.slice(0, 3); } }, filter: { TAG: function (nodeNameSelector) { var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase(); return nodeNameSelector === '*' ? function () { return true; } : function (elem) { return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; }; }, CLASS: function (className) { var pattern = classCache[className + ' ']; return pattern || (pattern = new RegExp('(^|' + whitespace + ')' + className + '(' + whitespace + '|$)')) && classCache(className, function (elem) { return pattern.test(typeof elem.className === 'string' && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute('class') || ''); }); }, ATTR: function (name, operator, check) { return function (elem) { var result = Sizzle.attr(elem, name); if (result == null) { return operator === '!='; } if (!operator) { return true; } result += ''; return operator === '=' ? result === check : operator === '!=' ? result !== check : operator === '^=' ? check && result.indexOf(check) === 0 : operator === '*=' ? check && result.indexOf(check) > -1 : operator === '$=' ? check && result.slice(-check.length) === check : operator === '~=' ? (' ' + result + ' ').indexOf(check) > -1 : operator === '|=' ? result === check || result.slice(0, check.length + 1) === check + '-' : false; }; }, CHILD: function (type, what, argument, first, last) { var simple = type.slice(0, 3) !== 'nth', forward = type.slice(-4) !== 'last', ofType = what === 'of-type'; return first === 1 && last === 0 ? function (elem) { return !!elem.parentNode; } : function (elem, context, xml) { var cache, outerCache, node, diff, nodeIndex, start, dir = simple !== forward ? 'nextSibling' : 'previousSibling', parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType; if (parent) { if (simple) { while (dir) { node = elem; while (node = node[dir]) { if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) { return false; } } start = dir = type === 'only' && !start && 'nextSibling'; } return true; } start = [forward ? parent.firstChild : parent.lastChild]; if (forward && useCache) { outerCache = parent[expando] || (parent[expando] = {}); cache = outerCache[type] || []; nodeIndex = cache[0] === dirruns && cache[1]; diff = cache[0] === dirruns && cache[2]; node = nodeIndex && parent.childNodes[nodeIndex]; while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) { if (node.nodeType === 1 && ++diff && node === elem) { outerCache[type] = [ dirruns, nodeIndex, diff ]; break; } } } else if (useCache && (cache = (elem[expando] || (elem[expando] = {}))[type]) && cache[0] === dirruns) { diff = cache[1]; } else { while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) { if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) { if (useCache) { (node[expando] || (node[expando] = {}))[type] = [ dirruns, diff ]; } if (node === elem) { break; } } } } diff -= last; return diff === first || diff % first === 0 && diff / first >= 0; } }; }, PSEUDO: function (pseudo, argument) { var args, fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error('unsupported pseudo: ' + pseudo); if (fn[expando]) { return fn(argument); } if (fn.length > 1) { args = [ pseudo, pseudo, '', argument ]; return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) { var idx, matched = fn(seed, argument), i = matched.length; while (i--) { idx = indexOf$1.call(seed, matched[i]); seed[idx] = !(matches[idx] = matched[i]); } }) : function (elem) { return fn(elem, 0, args); }; } return fn; } }, pseudos: { not: markFunction(function (selector) { var input = [], results = [], matcher = compile(selector.replace(rtrim, '$1')); return matcher[expando] ? markFunction(function (seed, matches, context, xml) { var elem, unmatched = matcher(seed, null, xml, []), i = seed.length; while (i--) { if (elem = unmatched[i]) { seed[i] = !(matches[i] = elem); } } }) : function (elem, context, xml) { input[0] = elem; matcher(input, null, xml, results); return !results.pop(); }; }), has: markFunction(function (selector) { return function (elem) { return Sizzle(selector, elem).length > 0; }; }), contains: markFunction(function (text) { text = text.replace(runescape, funescape); return function (elem) { return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1; }; }), lang: markFunction(function (lang) { if (!ridentifier.test(lang || '')) { Sizzle.error('unsupported lang: ' + lang); } lang = lang.replace(runescape, funescape).toLowerCase(); return function (elem) { var elemLang; do { if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute('xml:lang') || elem.getAttribute('lang')) { elemLang = elemLang.toLowerCase(); return elemLang === lang || elemLang.indexOf(lang + '-') === 0; } } while ((elem = elem.parentNode) && elem.nodeType === 1); return false; }; }), target: function (elem) { var hash = domGlobals.window.location && domGlobals.window.location.hash; return hash && hash.slice(1) === elem.id; }, root: function (elem) { return elem === docElem; }, focus: function (elem) { return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); }, enabled: function (elem) { return elem.disabled === false; }, disabled: function (elem) { return elem.disabled === true; }, checked: function (elem) { var nodeName = elem.nodeName.toLowerCase(); return nodeName === 'input' && !!elem.checked || nodeName === 'option' && !!elem.selected; }, selected: function (elem) { if (elem.parentNode) { elem.parentNode.selectedIndex; } return elem.selected === true; }, empty: function (elem) { for (elem = elem.firstChild; elem; elem = elem.nextSibling) { if (elem.nodeType < 6) { return false; } } return true; }, parent: function (elem) { return !Expr.pseudos.empty(elem); }, header: function (elem) { return rheader.test(elem.nodeName); }, input: function (elem) { return rinputs.test(elem.nodeName); }, button: function (elem) { var name = elem.nodeName.toLowerCase(); return name === 'input' && elem.type === 'button' || name === 'button'; }, text: function (elem) { var attr; return elem.nodeName.toLowerCase() === 'input' && elem.type === 'text' && ((attr = elem.getAttribute('type')) == null || attr.toLowerCase() === 'text'); }, first: createPositionalPseudo(function () { return [0]; }), last: createPositionalPseudo(function (matchIndexes, length) { return [length - 1]; }), eq: createPositionalPseudo(function (matchIndexes, length, argument) { return [argument < 0 ? argument + length : argument]; }), even: createPositionalPseudo(function (matchIndexes, length) { var i = 0; for (; i < length; i += 2) { matchIndexes.push(i); } return matchIndexes; }), odd: createPositionalPseudo(function (matchIndexes, length) { var i = 1; for (; i < length; i += 2) { matchIndexes.push(i); } return matchIndexes; }), lt: createPositionalPseudo(function (matchIndexes, length, argument) { var i = argument < 0 ? argument + length : argument; for (; --i >= 0;) { matchIndexes.push(i); } return matchIndexes; }), gt: createPositionalPseudo(function (matchIndexes, length, argument) { var i = argument < 0 ? argument + length : argument; for (; ++i < length;) { matchIndexes.push(i); } return matchIndexes; }) } }; Expr.pseudos.nth = Expr.pseudos.eq; for (i in { radio: true, checkbox: true, file: true, password: true, image: true }) { Expr.pseudos[i] = createInputPseudo(i); } for (i in { submit: true, reset: true }) { Expr.pseudos[i] = createButtonPseudo(i); } function setFilters() { } setFilters.prototype = Expr.filters = Expr.pseudos; Expr.setFilters = new setFilters(); tokenize = Sizzle.tokenize = function (selector, parseOnly) { var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[selector + ' ']; if (cached) { return parseOnly ? 0 : cached.slice(0); } soFar = selector; groups = []; preFilters = Expr.preFilter; while (soFar) { if (!matched || (match = rcomma.exec(soFar))) { if (match) { soFar = soFar.slice(match[0].length) || soFar; } groups.push(tokens = []); } matched = false; if (match = rcombinators.exec(soFar)) { matched = match.shift(); tokens.push({ value: matched, type: match[0].replace(rtrim, ' ') }); soFar = soFar.slice(matched.length); } for (type in Expr.filter) { if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) { matched = match.shift(); tokens.push({ value: matched, type: type, matches: match }); soFar = soFar.slice(matched.length); } } if (!matched) { break; } } return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) : tokenCache(selector, groups).slice(0); }; function toSelector(tokens) { var i = 0, len = tokens.length, selector = ''; for (; i < len; i++) { selector += tokens[i].value; } return selector; } function addCombinator(matcher, combinator, base) { var dir = combinator.dir, checkNonElements = base && dir === 'parentNode', doneName = done++; return combinator.first ? function (elem, context, xml) { while (elem = elem[dir]) { if (elem.nodeType === 1 || checkNonElements) { return matcher(elem, context, xml); } } } : function (elem, context, xml) { var oldCache, outerCache, newCache = [ dirruns, doneName ]; if (xml) { while (elem = elem[dir]) { if (elem.nodeType === 1 || checkNonElements) { if (matcher(elem, context, xml)) { return true; } } } } else { while (elem = elem[dir]) { if (elem.nodeType === 1 || checkNonElements) { outerCache = elem[expando] || (elem[expando] = {}); if ((oldCache = outerCache[dir]) && oldCache[0] === dirruns && oldCache[1] === doneName) { return newCache[2] = oldCache[2]; } else { outerCache[dir] = newCache; if (newCache[2] = matcher(elem, context, xml)) { return true; } } } } } }; } function elementMatcher(matchers) { return matchers.length > 1 ? function (elem, context, xml) { var i = matchers.length; while (i--) { if (!matchers[i](elem, context, xml)) { return false; } } return true; } : matchers[0]; } function multipleContexts(selector, contexts, results) { var i = 0, len = contexts.length; for (; i < len; i++) { Sizzle(selector, contexts[i], results); } return results; } function condense(unmatched, map, filter, context, xml) { var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null; for (; i < len; i++) { if (elem = unmatched[i]) { if (!filter || filter(elem, context, xml)) { newUnmatched.push(elem); if (mapped) { map.push(i); } } } } return newUnmatched; } function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) { if (postFilter && !postFilter[expando]) { postFilter = setMatcher(postFilter); } if (postFinder && !postFinder[expando]) { postFinder = setMatcher(postFinder, postSelector); } return markFunction(function (seed, results, context, xml) { var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, elems = seed || multipleContexts(selector || '*', context.nodeType ? [context] : context, []), matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems, matcherOut = matcher ? postFinder || (seed ? preFilter : preexisting || postFilter) ? [] : results : matcherIn; if (matcher) { matcher(matcherIn, matcherOut, context, xml); } if (postFilter) { temp = condense(matcherOut, postMap); postFilter(temp, [], context, xml); i = temp.length; while (i--) { if (elem = temp[i]) { matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem); } } } if (seed) { if (postFinder || preFilter) { if (postFinder) { temp = []; i = matcherOut.length; while (i--) { if (elem = matcherOut[i]) { temp.push(matcherIn[i] = elem); } } postFinder(null, matcherOut = [], temp, xml); } i = matcherOut.length; while (i--) { if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf$1.call(seed, elem) : preMap[i]) > -1) { seed[temp] = !(results[temp] = elem); } } } } else { matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut); if (postFinder) { postFinder(null, results, matcherOut, xml); } else { push$1.apply(results, matcherOut); } } }); } function matcherFromTokens(tokens) { var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[tokens[0].type], implicitRelative = leadingRelative || Expr.relative[' '], i = leadingRelative ? 1 : 0, matchContext = addCombinator(function (elem) { return elem === checkContext; }, implicitRelative, true), matchAnyContext = addCombinator(function (elem) { return indexOf$1.call(checkContext, elem) > -1; }, implicitRelative, true), matchers = [function (elem, context, xml) { return !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml)); }]; for (; i < len; i++) { if (matcher = Expr.relative[tokens[i].type]) { matchers = [addCombinator(elementMatcher(matchers), matcher)]; } else { matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches); if (matcher[expando]) { j = ++i; for (; j < len; j++) { if (Expr.relative[tokens[j].type]) { break; } } return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector(tokens.slice(0, i - 1).concat({ value: tokens[i - 2].type === ' ' ? '*' : '' })).replace(rtrim, '$1'), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens)); } matchers.push(matcher); } } return elementMatcher(matchers); } function matcherFromGroupMatchers(elementMatchers, setMatchers) { var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function (seed, context, xml, results, outermost) { var elem, j, matcher, matchedCount = 0, i = '0', unmatched = seed && [], setMatched = [], contextBackup = outermostContext, elems = seed || byElement && Expr.find.TAG('*', outermost), dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1, len = elems.length; if (outermost) { outermostContext = context !== document && context; } for (; i !== len && (elem = elems[i]) != null; i++) { if (byElement && elem) { j = 0; while (matcher = elementMatchers[j++]) { if (matcher(elem, context, xml)) { results.push(elem); break; } } if (outermost) { dirruns = dirrunsUnique; } } if (bySet) { if (elem = !matcher && elem) { matchedCount--; } if (seed) { unmatched.push(elem); } } } matchedCount += i; if (bySet && i !== matchedCount) { j = 0; while (matcher = setMatchers[j++]) { matcher(unmatched, setMatched, context, xml); } if (seed) { if (matchedCount > 0) { while (i--) { if (!(unmatched[i] || setMatched[i])) { setMatched[i] = pop.call(results); } } } setMatched = condense(setMatched); } push$1.apply(results, setMatched); if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) { Sizzle.uniqueSort(results); } } if (outermost) { dirruns = dirrunsUnique; outermostContext = contextBackup; } return unmatched; }; return bySet ? markFunction(superMatcher) : superMatcher; } compile = Sizzle.compile = function (selector, match) { var i, setMatchers = [], elementMatchers = [], cached = compilerCache[selector + ' ']; if (!cached) { if (!match) { match = tokenize(selector); } i = match.length; while (i--) { cached = matcherFromTokens(match[i]); if (cached[expando]) { setMatchers.push(cached); } else { elementMatchers.push(cached); } } cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers)); cached.selector = selector; } return cached; }; select = Sizzle.select = function (selector, context, results, seed) { var i, tokens, token, type, find, compiled = typeof selector === 'function' && selector, match = !seed && tokenize(selector = compiled.selector || selector); results = results || []; if (match.length === 1) { tokens = match[0] = match[0].slice(0); if (tokens.length > 2 && (token = tokens[0]).type === 'ID' && support.getById && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) { context = (Expr.find.ID(token.matches[0].replace(runescape, funescape), context) || [])[0]; if (!context) { return results; } else if (compiled) { context = context.parentNode; } selector = selector.slice(tokens.shift().value.length); } i = matchExpr.needsContext.test(selector) ? 0 : tokens.length; while (i--) { token = tokens[i]; if (Expr.relative[type = token.type]) { break; } if (find = Expr.find[type]) { if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testContext(context.parentNode) || context)) { tokens.splice(i, 1); selector = seed.length && toSelector(tokens); if (!selector) { push$1.apply(results, seed); return results; } break; } } } } (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, rsibling.test(selector) && testContext(context.parentNode) || context); return results; }; support.sortStable = expando.split('').sort(sortOrder).join('') === expando; support.detectDuplicates = !!hasDuplicate; setDocument(); support.sortDetached = true; var isArray$1 = Array.isArray; var toArray = function (obj) { var array = obj, i, l; if (!isArray$1(obj)) { array = []; for (i = 0, l = obj.length; i < l; i++) { array[i] = obj[i]; } } return array; }; var each$1 = function (o, cb, s) { var n, l; if (!o) { return 0; } s = s || o; if (o.length !== undefined) { for (n = 0, l = o.length; n < l; n++) { if (cb.call(s, o[n], n, o) === false) { return 0; } } } else { for (n in o) { if (o.hasOwnProperty(n)) { if (cb.call(s, o[n], n, o) === false) { return 0; } } } } return 1; }; var map$1 = function (array, callback) { var out = []; each$1(array, function (item, index) { out.push(callback(item, index, array)); }); return out; }; var filter$1 = function (a, f) { var o = []; each$1(a, function (v, index) { if (!f || f(v, index, a)) { o.push(v); } }); return o; }; var indexOf$2 = function (a, v) { var i, l; if (a) { for (i = 0, l = a.length; i < l; i++) { if (a[i] === v) { return i; } } } return -1; }; var reduce = function (collection, iteratee, accumulator, thisArg) { var i = 0; if (arguments.length < 3) { accumulator = collection[0]; } for (; i < collection.length; i++) { accumulator = iteratee.call(thisArg, accumulator, collection[i], i); } return accumulator; }; var findIndex$1 = function (array, predicate, thisArg) { var i, l; for (i = 0, l = array.length; i < l; i++) { if (predicate.call(thisArg, array[i], i, array)) { return i; } } return -1; }; var find$1 = function (array, predicate, thisArg) { var idx = findIndex$1(array, predicate, thisArg); if (idx !== -1) { return array[idx]; } return undefined; }; var last$1 = function (collection) { return collection[collection.length - 1]; }; var ArrUtils = { isArray: isArray$1, toArray: toArray, each: each$1, map: map$1, filter: filter$1, indexOf: indexOf$2, reduce: reduce, findIndex: findIndex$1, find: find$1, last: last$1 }; var whiteSpaceRegExp = /^\s*|\s*$/g; var trim = function (str) { return str === null || str === undefined ? '' : ('' + str).replace(whiteSpaceRegExp, ''); }; var is = function (obj, type) { if (!type) { return obj !== undefined; } if (type === 'array' && ArrUtils.isArray(obj)) { return true; } return typeof obj === type; }; var makeMap = function (items, delim, map) { var i; items = items || []; delim = delim || ','; if (typeof items === 'string') { items = items.split(delim); } map = map || {}; i = items.length; while (i--) { map[items[i]] = {}; } return map; }; var hasOwnProperty = function (obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }; var create = function (s, p, root) { var self = this; var sp, ns, cn, scn, c, de = 0; s = /^((static) )?([\w.]+)(:([\w.]+))?/.exec(s); cn = s[3].match(/(^|\.)(\w+)$/i)[2]; ns = self.createNS(s[3].replace(/\.\w+$/, ''), root); if (ns[cn]) { return; } if (s[2] === 'static') { ns[cn] = p; if (this.onCreate) { this.onCreate(s[2], s[3], ns[cn]); } return; } if (!p[cn]) { p[cn] = function () { }; de = 1; } ns[cn] = p[cn]; self.extend(ns[cn].prototype, p); if (s[5]) { sp = self.resolve(s[5]).prototype; scn = s[5].match(/\.(\w+)$/i)[1]; c = ns[cn]; if (de) { ns[cn] = function () { return sp[scn].apply(this, arguments); }; } else { ns[cn] = function () { this.parent = sp[scn]; return c.apply(this, arguments); }; } ns[cn].prototype[cn] = ns[cn]; self.each(sp, function (f, n) { ns[cn].prototype[n] = sp[n]; }); self.each(p, function (f, n) { if (sp[n]) { ns[cn].prototype[n] = function () { this.parent = sp[n]; return f.apply(this, arguments); }; } else { if (n !== cn) { ns[cn].prototype[n] = f; } } }); } self.each(p.static, function (f, n) { ns[cn][n] = f; }); }; var extend = function (obj, ext) { var x = []; for (var _i = 2; _i < arguments.length; _i++) { x[_i - 2] = arguments[_i]; } var i, l, name; var args = arguments; var value; for (i = 1, l = args.length; i < l; i++) { ext = args[i]; for (name in ext) { if (ext.hasOwnProperty(name)) { value = ext[name]; if (value !== undefined) { obj[name] = value; } } } } return obj; }; var walk = function (o, f, n, s) { s = s || this; if (o) { if (n) { o = o[n]; } ArrUtils.each(o, function (o, i) { if (f.call(s, o, i, n) === false) { return false; } walk(o, f, n, s); }); } }; var createNS = function (n, o) { var i, v; o = o || domGlobals.window; n = n.split('.'); for (i = 0; i < n.length; i++) { v = n[i]; if (!o[v]) { o[v] = {}; } o = o[v]; } return o; }; var resolve$1 = function (n, o) { var i, l; o = o || domGlobals.window; n = n.split('.'); for (i = 0, l = n.length; i < l; i++) { o = o[n[i]]; if (!o) { break; } } return o; }; var explode = function (s, d) { if (!s || is(s, 'array')) { return s; } return ArrUtils.map(s.split(d || ','), trim); }; var _addCacheSuffix = function (url) { var cacheSuffix = Env.cacheSuffix; if (cacheSuffix) { url += (url.indexOf('?') === -1 ? '?' : '&') + cacheSuffix; } return url; }; var Tools = { trim: trim, isArray: ArrUtils.isArray, is: is, toArray: ArrUtils.toArray, makeMap: makeMap, each: ArrUtils.each, map: ArrUtils.map, grep: ArrUtils.filter, inArray: ArrUtils.indexOf, hasOwn: hasOwnProperty, extend: extend, create: create, walk: walk, createNS: createNS, resolve: resolve$1, explode: explode, _addCacheSuffix: _addCacheSuffix }; var doc = domGlobals.document, push$2 = Array.prototype.push, slice$2 = Array.prototype.slice; var rquickExpr$1 = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/; var Event = EventUtils.Event; var skipUniques = Tools.makeMap('children,contents,next,prev'); var isDefined = function (obj) { return typeof obj !== 'undefined'; }; var isString$1 = function (obj) { return typeof obj === 'string'; }; var isWindow = function (obj) { return obj && obj === obj.window; }; var createFragment = function (html, fragDoc) { var frag, node, container; fragDoc = fragDoc || doc; container = fragDoc.createElement('div'); frag = fragDoc.createDocumentFragment(); container.innerHTML = html; while (node = container.firstChild) { frag.appendChild(node); } return frag; }; var domManipulate = function (targetNodes, sourceItem, callback, reverse) { var i; if (isString$1(sourceItem)) { sourceItem = createFragment(sourceItem, getElementDocument(targetNodes[0])); } else if (sourceItem.length && !sourceItem.nodeType) { sourceItem = DomQuery.makeArray(sourceItem); if (reverse) { for (i = sourceItem.length - 1; i >= 0; i--) { domManipulate(targetNodes, sourceItem[i], callback, reverse); } } else { for (i = 0; i < sourceItem.length; i++) { domManipulate(targetNodes, sourceItem[i], callback, reverse); } } return targetNodes; } if (sourceItem.nodeType) { i = targetNodes.length; while (i--) { callback.call(targetNodes[i], sourceItem); } } return targetNodes; }; var hasClass = function (node, className) { return node && className && (' ' + node.className + ' ').indexOf(' ' + className + ' ') !== -1; }; var wrap = function (elements, wrapper, all) { var lastParent, newWrapper; wrapper = DomQuery(wrapper)[0]; elements.each(function () { var self = this; if (!all || lastParent !== self.parentNode) { lastParent = self.parentNode; newWrapper = wrapper.cloneNode(false); self.parentNode.insertBefore(newWrapper, self); newWrapper.appendChild(self); } else { newWrapper.appendChild(self); } }); return elements; }; var numericCssMap = Tools.makeMap('fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom', ' '); var booleanMap = Tools.makeMap('checked compact declare defer disabled ismap multiple nohref noshade nowrap readonly selected', ' '); var propFix = { for: 'htmlFor', class: 'className', readonly: 'readOnly' }; var cssFix = { float: 'cssFloat' }; var attrHooks = {}, cssHooks = {}; var DomQuery = function (selector, context) { return new DomQuery.fn.init(selector, context); }; var inArray = function (item, array) { var i; if (array.indexOf) { return array.indexOf(item); } i = array.length; while (i--) { if (array[i] === item) { return i; } } return -1; }; var whiteSpaceRegExp$1 = /^\s*|\s*$/g; var trim$1 = function (str) { return str === null || str === undefined ? '' : ('' + str).replace(whiteSpaceRegExp$1, ''); }; var each$2 = function (obj, callback) { var length, key, i, value; if (obj) { length = obj.length; if (length === undefined) { for (key in obj) { if (obj.hasOwnProperty(key)) { value = obj[key]; if (callback.call(value, key, value) === false) { break; } } } } else { for (i = 0; i < length; i++) { value = obj[i]; if (callback.call(value, i, value) === false) { break; } } } } return obj; }; var grep = function (array, callback) { var out = []; each$2(array, function (i, item) { if (callback(item, i)) { out.push(item); } }); return out; }; var getElementDocument = function (element) { if (!element) { return doc; } if (element.nodeType === 9) { return element; } return element.ownerDocument; }; DomQuery.fn = DomQuery.prototype = { constructor: DomQuery, selector: '', context: null, length: 0, init: function (selector, context) { var self = this; var match, node; if (!selector) { return self; } if (selector.nodeType) { self.context = self[0] = selector; self.length = 1; return self; } if (context && context.nodeType) { self.context = context; } else { if (context) { return DomQuery(selector).attr(context); } self.context = context = domGlobals.document; } if (isString$1(selector)) { self.selector = selector; if (selector.charAt(0) === '<' && selector.charAt(selector.length - 1) === '>' && selector.length >= 3) { match = [ null, selector, null ]; } else { match = rquickExpr$1.exec(selector); } if (match) { if (match[1]) { node = createFragment(selector, getElementDocument(context)).firstChild; while (node) { push$2.call(self, node); node = node.nextSibling; } } else { node = getElementDocument(context).getElementById(match[2]); if (!node) { return self; } if (node.id !== match[2]) { return self.find(selector); } self.length = 1; self[0] = node; } } else { return DomQuery(context).find(selector); } } else { this.add(selector, false); } return self; }, toArray: function () { return Tools.toArray(this); }, add: function (items, sort) { var self = this; var nodes, i; if (isString$1(items)) { return self.add(DomQuery(items)); } if (sort !== false) { nodes = DomQuery.unique(self.toArray().concat(DomQuery.makeArray(items))); self.length = nodes.length; for (i = 0; i < nodes.length; i++) { self[i] = nodes[i]; } } else { push$2.apply(self, DomQuery.makeArray(items)); } return self; }, attr: function (name, value) { var self = this; var hook; if (typeof name === 'object') { each$2(name, function (name, value) { self.attr(name, value); }); } else if (isDefined(value)) { this.each(function () { var hook; if (this.nodeType === 1) { hook = attrHooks[name]; if (hook && hook.set) { hook.set(this, value); return; } if (value === null) { this.removeAttribute(name, 2); } else { this.setAttribute(name, value, 2); } } }); } else { if (self[0] && self[0].nodeType === 1) { hook = attrHooks[name]; if (hook && hook.get) { return hook.get(self[0], name); } if (booleanMap[name]) { return self.prop(name) ? name : undefined; } value = self[0].getAttribute(name, 2); if (value === null) { value = undefined; } } return value; } return self; }, removeAttr: function (name) { return this.attr(name, null); }, prop: function (name, value) { var self = this; name = propFix[name] || name; if (typeof name === 'object') { each$2(name, function (name, value) { self.prop(name, value); }); } else if (isDefined(value)) { this.each(function () { if (this.nodeType === 1) { this[name] = value; } }); } else { if (self[0] && self[0].nodeType && name in self[0]) { return self[0][name]; } return value; } return self; }, css: function (name, value) { var self = this; var elm, hook; var camel = function (name) { return name.replace(/-(\D)/g, function (a, b) { return b.toUpperCase(); }); }; var dashed = function (name) { return name.replace(/[A-Z]/g, function (a) { return '-' + a; }); }; if (typeof name === 'object') { each$2(name, function (name, value) { self.css(name, value); }); } else { if (isDefined(value)) { name = camel(name); if (typeof value === 'number' && !numericCssMap[name]) { value = value.toString() + 'px'; } self.each(function () { var style = this.style; hook = cssHooks[name]; if (hook && hook.set) { hook.set(this, value); return; } try { this.style[cssFix[name] || name] = value; } catch (ex) { } if (value === null || value === '') { if (style.removeProperty) { style.removeProperty(dashed(name)); } else { style.removeAttribute(name); } } }); } else { elm = self[0]; hook = cssHooks[name]; if (hook && hook.get) { return hook.get(elm); } if (elm.ownerDocument.defaultView) { try { return elm.ownerDocument.defaultView.getComputedStyle(elm, null).getPropertyValue(dashed(name)); } catch (ex) { return undefined; } } else if (elm.currentStyle) { return elm.currentStyle[camel(name)]; } else { return ''; } } } return self; }, remove: function () { var self = this; var node, i = this.length; while (i--) { node = self[i]; Event.clean(node); if (node.parentNode) { node.parentNode.removeChild(node); } } return this; }, empty: function () { var self = this; var node, i = this.length; while (i--) { node = self[i]; while (node.firstChild) { node.removeChild(node.firstChild); } } return this; }, html: function (value) { var self = this; var i; if (isDefined(value)) { i = self.length; try { while (i--) { self[i].innerHTML = value; } } catch (ex) { DomQuery(self[i]).empty().append(value); } return self; } return self[0] ? self[0].innerHTML : ''; }, text: function (value) { var self = this; var i; if (isDefined(value)) { i = self.length; while (i--) { if ('innerText' in self[i]) { self[i].innerText = value; } else { self[0].textContent = value; } } return self; } return self[0] ? self[0].innerText || self[0].textContent : ''; }, append: function () { return domManipulate(this, arguments, function (node) { if (this.nodeType === 1 || this.host && this.host.nodeType === 1) { this.appendChild(node); } }); }, prepend: function () { return domManipulate(this, arguments, function (node) { if (this.nodeType === 1 || this.host && this.host.nodeType === 1) { this.insertBefore(node, this.firstChild); } }, true); }, before: function () { var self = this; if (self[0] && self[0].parentNode) { return domManipulate(self, arguments, function (node) { this.parentNode.insertBefore(node, this); }); } return self; }, after: function () { var self = this; if (self[0] && self[0].parentNode) { return domManipulate(self, arguments, function (node) { this.parentNode.insertBefore(node, this.nextSibling); }, true); } return self; }, appendTo: function (val) { DomQuery(val).append(this); return this; }, prependTo: function (val) { DomQuery(val).prepend(this); return this; }, replaceWith: function (content) { return this.before(content).remove(); }, wrap: function (content) { return wrap(this, content); }, wrapAll: function (content) { return wrap(this, content, true); }, wrapInner: function (content) { this.each(function () { DomQuery(this).contents().wrapAll(content); }); return this; }, unwrap: function () { return this.parent().each(function () { DomQuery(this).replaceWith(this.childNodes); }); }, clone: function () { var result = []; this.each(function () { result.push(this.cloneNode(true)); }); return DomQuery(result); }, addClass: function (className) { return this.toggleClass(className, true); }, removeClass: function (className) { return this.toggleClass(className, false); }, toggleClass: function (className, state) { var self = this; if (typeof className !== 'string') { return self; } if (className.indexOf(' ') !== -1) { each$2(className.split(' '), function () { self.toggleClass(this, state); }); } else { self.each(function (index, node) { var existingClassName, classState; classState = hasClass(node, className); if (classState !== state) { existingClassName = node.className; if (classState) { node.className = trim$1((' ' + existingClassName + ' ').replace(' ' + className + ' ', ' ')); } else { node.className += existingClassName ? ' ' + className : className; } } }); } return self; }, hasClass: function (className) { return hasClass(this[0], className); }, each: function (callback) { return each$2(this, callback); }, on: function (name, callback) { return this.each(function () { Event.bind(this, name, callback); }); }, off: function (name, callback) { return this.each(function () { Event.unbind(this, name, callback); }); }, trigger: function (name) { return this.each(function () { if (typeof name === 'object') { Event.fire(this, name.type, name); } else { Event.fire(this, name); } }); }, show: function () { return this.css('display', ''); }, hide: function () { return this.css('display', 'none'); }, slice: function () { return new DomQuery(slice$2.apply(this, arguments)); }, eq: function (index) { return index === -1 ? this.slice(index) : this.slice(index, +index + 1); }, first: function () { return this.eq(0); }, last: function () { return this.eq(-1); }, find: function (selector) { var i, l; var ret = []; for (i = 0, l = this.length; i < l; i++) { DomQuery.find(selector, this[i], ret); } return DomQuery(ret); }, filter: function (selector) { if (typeof selector === 'function') { return DomQuery(grep(this.toArray(), function (item, i) { return selector(i, item); })); } return DomQuery(DomQuery.filter(selector, this.toArray())); }, closest: function (selector) { var result = []; if (selector instanceof DomQuery) { selector = selector[0]; } this.each(function (i, node) { while (node) { if (typeof selector === 'string' && DomQuery(node).is(selector)) { result.push(node); break; } else if (node === selector) { result.push(node); break; } node = node.parentNode; } }); return DomQuery(result); }, offset: function (offset) { var elm, doc, docElm; var x = 0, y = 0, pos; if (!offset) { elm = this[0]; if (elm) { doc = elm.ownerDocument; docElm = doc.documentElement; if (elm.getBoundingClientRect) { pos = elm.getBoundingClientRect(); x = pos.left + (docElm.scrollLeft || doc.body.scrollLeft) - docElm.clientLeft; y = pos.top + (docElm.scrollTop || doc.body.scrollTop) - docElm.clientTop; } } return { left: x, top: y }; } return this.css(offset); }, push: push$2, sort: [].sort, splice: [].splice }; Tools.extend(DomQuery, { extend: Tools.extend, makeArray: function (object) { if (isWindow(object) || object.nodeType) { return [object]; } return Tools.toArray(object); }, inArray: inArray, isArray: Tools.isArray, each: each$2, trim: trim$1, grep: grep, find: Sizzle, expr: Sizzle.selectors, unique: Sizzle.uniqueSort, text: Sizzle.getText, contains: Sizzle.contains, filter: function (expr, elems, not) { var i = elems.length; if (not) { expr = ':not(' + expr + ')'; } while (i--) { if (elems[i].nodeType !== 1) { elems.splice(i, 1); } } if (elems.length === 1) { elems = DomQuery.find.matchesSelector(elems[0], expr) ? [elems[0]] : []; } else { elems = DomQuery.find.matches(expr, elems); } return elems; } }); var dir = function (el, prop, until) { var matched = []; var cur = el[prop]; if (typeof until !== 'string' && until instanceof DomQuery) { until = until[0]; } while (cur && cur.nodeType !== 9) { if (until !== undefined) { if (cur === until) { break; } if (typeof until === 'string' && DomQuery(cur).is(until)) { break; } } if (cur.nodeType === 1) { matched.push(cur); } cur = cur[prop]; } return matched; }; var sibling = function (node, siblingName, nodeType, until) { var result = []; if (until instanceof DomQuery) { until = until[0]; } for (; node; node = node[siblingName]) { if (nodeType && node.nodeType !== nodeType) { continue; } if (until !== undefined) { if (node === until) { break; } if (typeof until === 'string' && DomQuery(node).is(until)) { break; } } result.push(node); } return result; }; var firstSibling = function (node, siblingName, nodeType) { for (node = node[siblingName]; node; node = node[siblingName]) { if (node.nodeType === nodeType) { return node; } } return null; }; each$2({ parent: function (node) { var parent = node.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, parents: function (node) { return dir(node, 'parentNode'); }, next: function (node) { return firstSibling(node, 'nextSibling', 1); }, prev: function (node) { return firstSibling(node, 'previousSibling', 1); }, children: function (node) { return sibling(node.firstChild, 'nextSibling', 1); }, contents: function (node) { return Tools.toArray((node.nodeName === 'iframe' ? node.contentDocument || node.contentWindow.document : node).childNodes); } }, function (name, fn) { DomQuery.fn[name] = function (selector) { var self = this; var result = []; self.each(function () { var nodes = fn.call(result, this, selector, result); if (nodes) { if (DomQuery.isArray(nodes)) { result.push.apply(result, nodes); } else { result.push(nodes); } } }); if (this.length > 1) { if (!skipUniques[name]) { result = DomQuery.unique(result); } if (name.indexOf('parents') === 0) { result = result.reverse(); } } result = DomQuery(result); if (selector) { return result.filter(selector); } return result; }; }); each$2({ parentsUntil: function (node, until) { return dir(node, 'parentNode', until); }, nextUntil: function (node, until) { return sibling(node, 'nextSibling', 1, until).slice(1); }, prevUntil: function (node, until) { return sibling(node, 'previousSibling', 1, until).slice(1); } }, function (name, fn) { DomQuery.fn[name] = function (selector, filter) { var self = this; var result = []; self.each(function () { var nodes = fn.call(result, this, selector, result); if (nodes) { if (DomQuery.isArray(nodes)) { result.push.apply(result, nodes); } else { result.push(nodes); } } }); if (this.length > 1) { result = DomQuery.unique(result); if (name.indexOf('parents') === 0 || name === 'prevUntil') { result = result.reverse(); } } result = DomQuery(result); if (filter) { return result.filter(filter); } return result; }; }); DomQuery.fn.is = function (selector) { return !!selector && this.filter(selector).length > 0; }; DomQuery.fn.init.prototype = DomQuery.fn; DomQuery.overrideDefaults = function (callback) { var defaults; var sub = function (selector, context) { defaults = defaults || callback(); if (arguments.length === 0) { selector = defaults.element; } if (!context) { context = defaults.context; } return new sub.fn.init(selector, context); }; DomQuery.extend(sub, this); return sub; }; var appendHooks = function (targetHooks, prop, hooks) { each$2(hooks, function (name, func) { targetHooks[name] = targetHooks[name] || {}; targetHooks[name][prop] = func; }); }; if (Env.ie && Env.ie < 8) { appendHooks(attrHooks, 'get', { maxlength: function (elm) { var value = elm.maxLength; if (value === 2147483647) { return undefined; } return value; }, size: function (elm) { var value = elm.size; if (value === 20) { return undefined; } return value; }, class: function (elm) { return elm.className; }, style: function (elm) { var value = elm.style.cssText; if (value.length === 0) { return undefined; } return value; } }); appendHooks(attrHooks, 'set', { class: function (elm, value) { elm.className = value; }, style: function (elm, value) { elm.style.cssText = value; } }); } if (Env.ie && Env.ie < 9) { cssFix.float = 'styleFloat'; appendHooks(cssHooks, 'set', { opacity: function (elm, value) { var style = elm.style; if (value === null || value === '') { style.removeAttribute('filter'); } else { style.zoom = 1; style.filter = 'alpha(opacity=' + value * 100 + ')'; } } }); } DomQuery.attrHooks = attrHooks; DomQuery.cssHooks = cssHooks; var cached = function (f) { var called = false; var r; return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (!called) { called = true; r = f.apply(null, args); } return r; }; }; var firstMatch = function (regexes, s) { for (var i = 0; i < regexes.length; i++) { var x = regexes[i]; if (x.test(s)) return x; } return undefined; }; var find$2 = function (regexes, agent) { var r = firstMatch(regexes, agent); if (!r) return { major: 0, minor: 0 }; var group = function (i) { return Number(agent.replace(r, '$' + i)); }; return nu(group(1), group(2)); }; var detect = function (versionRegexes, agent) { var cleanedAgent = String(agent).toLowerCase(); if (versionRegexes.length === 0) return unknown(); return find$2(versionRegexes, cleanedAgent); }; var unknown = function () { return nu(0, 0); }; var nu = function (major, minor) { return { major: major, minor: minor }; }; var Version = { nu: nu, detect: detect, unknown: unknown }; var edge = 'Edge'; var chrome = 'Chrome'; var ie$1 = 'IE'; var opera$1 = 'Opera'; var firefox = 'Firefox'; var safari = 'Safari'; var isBrowser = function (name, current) { return function () { return current === name; }; }; var unknown$1 = function () { return nu$1({ current: undefined, version: Version.unknown() }); }; var nu$1 = function (info) { var current = info.current; var version = info.version; return { current: current, version: version, isEdge: isBrowser(edge, current), isChrome: isBrowser(chrome, current), isIE: isBrowser(ie$1, current), isOpera: isBrowser(opera$1, current), isFirefox: isBrowser(firefox, current), isSafari: isBrowser(safari, current) }; }; var Browser = { unknown: unknown$1, nu: nu$1, edge: constant(edge), chrome: constant(chrome), ie: constant(ie$1), opera: constant(opera$1), firefox: constant(firefox), safari: constant(safari) }; var windows = 'Windows'; var ios = 'iOS'; var android$1 = 'Android'; var linux = 'Linux'; var osx = 'OSX'; var solaris = 'Solaris'; var freebsd = 'FreeBSD'; var isOS = function (name, current) { return function () { return current === name; }; }; var unknown$2 = function () { return nu$2({ current: undefined, version: Version.unknown() }); }; var nu$2 = function (info) { var current = info.current; var version = info.version; return { current: current, version: version, isWindows: isOS(windows, current), isiOS: isOS(ios, current), isAndroid: isOS(android$1, current), isOSX: isOS(osx, current), isLinux: isOS(linux, current), isSolaris: isOS(solaris, current), isFreeBSD: isOS(freebsd, current) }; }; var OperatingSystem = { unknown: unknown$2, nu: nu$2, windows: constant(windows), ios: constant(ios), android: constant(android$1), linux: constant(linux), osx: constant(osx), solaris: constant(solaris), freebsd: constant(freebsd) }; var DeviceType = function (os, browser, userAgent) { var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true; var isiPhone = os.isiOS() && !isiPad; var isAndroid3 = os.isAndroid() && os.version.major === 3; var isAndroid4 = os.isAndroid() && os.version.major === 4; var isTablet = isiPad || isAndroid3 || isAndroid4 && /mobile/i.test(userAgent) === true; var isTouch = os.isiOS() || os.isAndroid(); var isPhone = isTouch && !isTablet; var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false; return { isiPad: constant(isiPad), isiPhone: constant(isiPhone), isTablet: constant(isTablet), isPhone: constant(isPhone), isTouch: constant(isTouch), isAndroid: os.isAndroid, isiOS: os.isiOS, isWebView: constant(iOSwebview) }; }; var detect$1 = function (candidates, userAgent) { var agent = String(userAgent).toLowerCase(); return find(candidates, function (candidate) { return candidate.search(agent); }); }; var detectBrowser = function (browsers, userAgent) { return detect$1(browsers, userAgent).map(function (browser) { var version = Version.detect(browser.versionRegexes, userAgent); return { current: browser.name, version: version }; }); }; var detectOs = function (oses, userAgent) { return detect$1(oses, userAgent).map(function (os) { var version = Version.detect(os.versionRegexes, userAgent); return { current: os.name, version: version }; }); }; var UaString = { detectBrowser: detectBrowser, detectOs: detectOs }; var contains$2 = function (str, substr) { return str.indexOf(substr) !== -1; }; var trim$2 = function (str) { return str.replace(/^\s+|\s+$/g, ''); }; var lTrim = function (str) { return str.replace(/^\s+/g, ''); }; var rTrim = function (str) { return str.replace(/\s+$/g, ''); }; var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/; var checkContains = function (target) { return function (uastring) { return contains$2(uastring, target); }; }; var browsers = [ { name: 'Edge', versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/], search: function (uastring) { var monstrosity = contains$2(uastring, 'edge/') && contains$2(uastring, 'chrome') && contains$2(uastring, 'safari') && contains$2(uastring, 'applewebkit'); return monstrosity; } }, { name: 'Chrome', versionRegexes: [ /.*?chrome\/([0-9]+)\.([0-9]+).*/, normalVersionRegex ], search: function (uastring) { return contains$2(uastring, 'chrome') && !contains$2(uastring, 'chromeframe'); } }, { name: 'IE', versionRegexes: [ /.*?msie\ ?([0-9]+)\.([0-9]+).*/, /.*?rv:([0-9]+)\.([0-9]+).*/ ], search: function (uastring) { return contains$2(uastring, 'msie') || contains$2(uastring, 'trident'); } }, { name: 'Opera', versionRegexes: [ normalVersionRegex, /.*?opera\/([0-9]+)\.([0-9]+).*/ ], search: checkContains('opera') }, { name: 'Firefox', versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/], search: checkContains('firefox') }, { name: 'Safari', versionRegexes: [ normalVersionRegex, /.*?cpu os ([0-9]+)_([0-9]+).*/ ], search: function (uastring) { return (contains$2(uastring, 'safari') || contains$2(uastring, 'mobile/')) && contains$2(uastring, 'applewebkit'); } } ]; var oses = [ { name: 'Windows', search: checkContains('win'), versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/] }, { name: 'iOS', search: function (uastring) { return contains$2(uastring, 'iphone') || contains$2(uastring, 'ipad'); }, versionRegexes: [ /.*?version\/\ ?([0-9]+)\.([0-9]+).*/, /.*cpu os ([0-9]+)_([0-9]+).*/, /.*cpu iphone os ([0-9]+)_([0-9]+).*/ ] }, { name: 'Android', search: checkContains('android'), versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/] }, { name: 'OSX', search: checkContains('os x'), versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/] }, { name: 'Linux', search: checkContains('linux'), versionRegexes: [] }, { name: 'Solaris', search: checkContains('sunos'), versionRegexes: [] }, { name: 'FreeBSD', search: checkContains('freebsd'), versionRegexes: [] } ]; var PlatformInfo = { browsers: constant(browsers), oses: constant(oses) }; var detect$2 = function (userAgent) { var browsers = PlatformInfo.browsers(); var oses = PlatformInfo.oses(); var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu); var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu); var deviceType = DeviceType(os, browser, userAgent); return { browser: browser, os: os, deviceType: deviceType }; }; var PlatformDetection = { detect: detect$2 }; var detect$3 = cached(function () { var userAgent = domGlobals.navigator.userAgent; return PlatformDetection.detect(userAgent); }); var PlatformDetection$1 = { detect: detect$3 }; var fromHtml = function (html, scope) { var doc = scope || domGlobals.document; var div = doc.createElement('div'); div.innerHTML = html; if (!div.hasChildNodes() || div.childNodes.length > 1) { domGlobals.console.error('HTML does not have a single root node', html); throw new Error('HTML must have a single root node'); } return fromDom(div.childNodes[0]); }; var fromTag = function (tag, scope) { var doc = scope || domGlobals.document; var node = doc.createElement(tag); return fromDom(node); }; var fromText = function (text, scope) { var doc = scope || domGlobals.document; var node = doc.createTextNode(text); return fromDom(node); }; var fromDom = function (node) { if (node === null || node === undefined) { throw new Error('Node cannot be null or undefined'); } return { dom: constant(node) }; }; var fromPoint = function (docElm, x, y) { var doc = docElm.dom(); return Option.from(doc.elementFromPoint(x, y)).map(fromDom); }; var Element = { fromHtml: fromHtml, fromTag: fromTag, fromText: fromText, fromDom: fromDom, fromPoint: fromPoint }; var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE; var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE; var COMMENT = domGlobals.Node.COMMENT_NODE; var DOCUMENT = domGlobals.Node.DOCUMENT_NODE; var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE; var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE; var ELEMENT = domGlobals.Node.ELEMENT_NODE; var TEXT = domGlobals.Node.TEXT_NODE; var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE; var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE; var ENTITY = domGlobals.Node.ENTITY_NODE; var NOTATION = domGlobals.Node.NOTATION_NODE; var name = function (element) { var r = element.dom().nodeName; return r.toLowerCase(); }; var type = function (element) { return element.dom().nodeType; }; var isType$1 = function (t) { return function (element) { return type(element) === t; }; }; var isElement = isType$1(ELEMENT); var isText = isType$1(TEXT); var keys = Object.keys; var hasOwnProperty$1 = Object.hasOwnProperty; var each$3 = function (obj, f) { var props = keys(obj); for (var k = 0, len = props.length; k < len; k++) { var i = props[k]; var x = obj[i]; f(x, i, obj); } }; var map$2 = function (obj, f) { return tupleMap(obj, function (x, i, obj) { return { k: i, v: f(x, i, obj) }; }); }; var tupleMap = function (obj, f) { var r = {}; each$3(obj, function (x, i) { var tuple = f(x, i, obj); r[tuple.k] = tuple.v; }); return r; }; var bifilter = function (obj, pred) { var t = {}; var f = {}; each$3(obj, function (x, i) { var branch = pred(x, i) ? t : f; branch[i] = x; }); return { t: t, f: f }; }; var has = function (obj, key) { return hasOwnProperty$1.call(obj, key); }; var isSupported = function (dom) { return dom.style !== undefined; }; var inBody = function (element) { var dom = isText(element) ? element.dom().parentNode : element.dom(); return dom !== undefined && dom !== null && dom.ownerDocument.body.contains(dom); }; var rawSet = function (dom, key, value) { if (isString(value) || isBoolean(value) || isNumber(value)) { dom.setAttribute(key, value + ''); } else { domGlobals.console.error('Invalid call to Attr.set. Key ', key, ':: Value ', value, ':: Element ', dom); throw new Error('Attribute value was not simple'); } }; var set = function (element, key, value) { rawSet(element.dom(), key, value); }; var setAll = function (element, attrs) { var dom = element.dom(); each$3(attrs, function (v, k) { rawSet(dom, k, v); }); }; var get = function (element, key) { var v = element.dom().getAttribute(key); return v === null ? undefined : v; }; var has$1 = function (element, key) { var dom = element.dom(); return dom && dom.hasAttribute ? dom.hasAttribute(key) : false; }; var remove = function (element, key) { element.dom().removeAttribute(key); }; var internalSet = function (dom, property, value) { if (!isString(value)) { domGlobals.console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom); throw new Error('CSS value must be a string: ' + value); } if (isSupported(dom)) { dom.style.setProperty(property, value); } }; var setAll$1 = function (element, css) { var dom = element.dom(); each$3(css, function (v, k) { internalSet(dom, k, v); }); }; var get$1 = function (element, property) { var dom = element.dom(); var styles = domGlobals.window.getComputedStyle(dom); var r = styles.getPropertyValue(property); var v = r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r; return v === null ? undefined : v; }; var getUnsafeProperty = function (dom, property) { return isSupported(dom) ? dom.style.getPropertyValue(property) : ''; }; var getRaw = function (element, property) { var dom = element.dom(); var raw = getUnsafeProperty(dom, property); return Option.from(raw).filter(function (r) { return r.length > 0; }); }; var Immutable = function () { var fields = []; for (var _i = 0; _i < arguments.length; _i++) { fields[_i] = arguments[_i]; } return function () { var values = []; for (var _i = 0; _i < arguments.length; _i++) { values[_i] = arguments[_i]; } if (fields.length !== values.length) { throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments'); } var struct = {}; each(fields, function (name, i) { struct[name] = constant(values[i]); }); return struct; }; }; var toArray$1 = function (target, f) { var r = []; var recurse = function (e) { r.push(e); return f(e); }; var cur = f(target); do { cur = cur.bind(recurse); } while (cur.isSome()); return r; }; var Recurse = { toArray: toArray$1 }; var node = function () { var f = Global$1.getOrDie('Node'); return f; }; var compareDocumentPosition = function (a, b, match) { return (a.compareDocumentPosition(b) & match) !== 0; }; var documentPositionPreceding = function (a, b) { return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_PRECEDING); }; var documentPositionContainedBy = function (a, b) { return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_CONTAINED_BY); }; var Node = { documentPositionPreceding: documentPositionPreceding, documentPositionContainedBy: documentPositionContainedBy }; var ELEMENT$1 = ELEMENT; var DOCUMENT$1 = DOCUMENT; var is$1 = function (element, selector) { var elem = element.dom(); if (elem.nodeType !== ELEMENT$1) { return false; } else if (elem.matches !== undefined) { return elem.matches(selector); } else if (elem.msMatchesSelector !== undefined) { return elem.msMatchesSelector(selector); } else if (elem.webkitMatchesSelector !== undefined) { return elem.webkitMatchesSelector(selector); } else if (elem.mozMatchesSelector !== undefined) { return elem.mozMatchesSelector(selector); } else { throw new Error('Browser lacks native selectors'); } }; var bypassSelector = function (dom) { return dom.nodeType !== ELEMENT$1 && dom.nodeType !== DOCUMENT$1 || dom.childElementCount === 0; }; var all = function (selector, scope) { var base = scope === undefined ? domGlobals.document : scope.dom(); return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), Element.fromDom); }; var one = function (selector, scope) { var base = scope === undefined ? domGlobals.document : scope.dom(); return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom); }; var eq = function (e1, e2) { return e1.dom() === e2.dom(); }; var regularContains = function (e1, e2) { var d1 = e1.dom(); var d2 = e2.dom(); return d1 === d2 ? false : d1.contains(d2); }; var ieContains = function (e1, e2) { return Node.documentPositionContainedBy(e1.dom(), e2.dom()); }; var browser = PlatformDetection$1.detect().browser; var contains$3 = browser.isIE() ? ieContains : regularContains; var owner = function (element) { return Element.fromDom(element.dom().ownerDocument); }; var documentElement = function (element) { return Element.fromDom(element.dom().ownerDocument.documentElement); }; var defaultView = function (element) { var el = element.dom(); var defView = el.ownerDocument.defaultView; return Element.fromDom(defView); }; var parent = function (element) { var dom = element.dom(); return Option.from(dom.parentNode).map(Element.fromDom); }; var parents = function (element, isRoot) { var stop = isFunction(isRoot) ? isRoot : constant(false); var dom = element.dom(); var ret = []; while (dom.parentNode !== null && dom.parentNode !== undefined) { var rawParent = dom.parentNode; var p = Element.fromDom(rawParent); ret.push(p); if (stop(p) === true) { break; } else { dom = rawParent; } } return ret; }; var prevSibling = function (element) { var dom = element.dom(); return Option.from(dom.previousSibling).map(Element.fromDom); }; var nextSibling = function (element) { var dom = element.dom(); return Option.from(dom.nextSibling).map(Element.fromDom); }; var prevSiblings = function (element) { return reverse(Recurse.toArray(element, prevSibling)); }; var nextSiblings = function (element) { return Recurse.toArray(element, nextSibling); }; var children = function (element) { var dom = element.dom(); return map(dom.childNodes, Element.fromDom); }; var child = function (element, index) { var cs = element.dom().childNodes; return Option.from(cs[index]).map(Element.fromDom); }; var firstChild = function (element) { return child(element, 0); }; var lastChild = function (element) { return child(element, element.dom().childNodes.length - 1); }; var childNodesCount = function (element) { return element.dom().childNodes.length; }; var spot = Immutable('element', 'offset'); var browser$1 = PlatformDetection$1.detect().browser; var firstElement = function (nodes) { return find(nodes, isElement); }; var getTableCaptionDeltaY = function (elm) { if (browser$1.isFirefox() && name(elm) === 'table') { return firstElement(children(elm)).filter(function (elm) { return name(elm) === 'caption'; }).bind(function (caption) { return firstElement(nextSiblings(caption)).map(function (body) { var bodyTop = body.dom().offsetTop; var captionTop = caption.dom().offsetTop; var captionHeight = caption.dom().offsetHeight; return bodyTop <= captionTop ? -captionHeight : 0; }); }).getOr(0); } else { return 0; } }; var getPos = function (body, elm, rootElm) { var x = 0, y = 0, offsetParent; var doc = body.ownerDocument; var pos; rootElm = rootElm ? rootElm : body; if (elm) { if (rootElm === body && elm.getBoundingClientRect && get$1(Element.fromDom(body), 'position') === 'static') { pos = elm.getBoundingClientRect(); x = pos.left + (doc.documentElement.scrollLeft || body.scrollLeft) - doc.documentElement.clientLeft; y = pos.top + (doc.documentElement.scrollTop || body.scrollTop) - doc.documentElement.clientTop; return { x: x, y: y }; } offsetParent = elm; while (offsetParent && offsetParent !== rootElm && offsetParent.nodeType) { x += offsetParent.offsetLeft || 0; y += offsetParent.offsetTop || 0; offsetParent = offsetParent.offsetParent; } offsetParent = elm.parentNode; while (offsetParent && offsetParent !== rootElm && offsetParent.nodeType) { x -= offsetParent.scrollLeft || 0; y -= offsetParent.scrollTop || 0; offsetParent = offsetParent.parentNode; } y += getTableCaptionDeltaY(Element.fromDom(elm)); } return { x: x, y: y }; }; var Position = { getPos: getPos }; var nu$3 = function (baseFn) { var data = Option.none(); var callbacks = []; var map = function (f) { return nu$3(function (nCallback) { get(function (data) { nCallback(f(data)); }); }); }; var get = function (nCallback) { if (isReady()) call(nCallback); else callbacks.push(nCallback); }; var set = function (x) { data = Option.some(x); run(callbacks); callbacks = []; }; var isReady = function () { return data.isSome(); }; var run = function (cbs) { each(cbs, call); }; var call = function (cb) { data.each(function (x) { domGlobals.setTimeout(function () { cb(x); }, 0); }); }; baseFn(set); return { get: get, map: map, isReady: isReady }; }; var pure = function (a) { return nu$3(function (callback) { callback(a); }); }; var LazyValue = { nu: nu$3, pure: pure }; var bounce = function (f) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var me = this; domGlobals.setTimeout(function () { f.apply(me, args); }, 0); }; }; var nu$4 = function (baseFn) { var get = function (callback) { baseFn(bounce(callback)); }; var map = function (fab) { return nu$4(function (callback) { get(function (a) { var value = fab(a); callback(value); }); }); }; var bind = function (aFutureB) { return nu$4(function (callback) { get(function (a) { aFutureB(a).get(callback); }); }); }; var anonBind = function (futureB) { return nu$4(function (callback) { get(function (a) { futureB.get(callback); }); }); }; var toLazy = function () { return LazyValue.nu(get); }; var toCached = function () { var cache = null; return nu$4(function (callback) { if (cache === null) { cache = toLazy(); } cache.get(callback); }); }; return { map: map, bind: bind, anonBind: anonBind, toLazy: toLazy, toCached: toCached, get: get }; }; var pure$1 = function (a) { return nu$4(function (callback) { callback(a); }); }; var Future = { nu: nu$4, pure: pure$1 }; var par = function (asyncValues, nu) { return nu(function (callback) { var r = []; var count = 0; var cb = function (i) { return function (value) { r[i] = value; count++; if (count >= asyncValues.length) { callback(r); } }; }; if (asyncValues.length === 0) { callback([]); } else { each(asyncValues, function (asyncValue, i) { asyncValue.get(cb(i)); }); } }); }; var par$1 = function (futures) { return par(futures, Future.nu); }; var value = function (o) { var is = function (v) { return o === v; }; var or = function (opt) { return value(o); }; var orThunk = function (f) { return value(o); }; var map = function (f) { return value(f(o)); }; var mapError = function (f) { return value(o); }; var each = function (f) { f(o); }; var bind = function (f) { return f(o); }; var fold = function (_, onValue) { return onValue(o); }; var exists = function (f) { return f(o); }; var forall = function (f) { return f(o); }; var toOption = function () { return Option.some(o); }; return { is: is, isValue: always, isError: never, getOr: constant(o), getOrThunk: constant(o), getOrDie: constant(o), or: or, orThunk: orThunk, fold: fold, map: map, mapError: mapError, each: each, bind: bind, exists: exists, forall: forall, toOption: toOption }; }; var error = function (message) { var getOrThunk = function (f) { return f(); }; var getOrDie = function () { return die(String(message))(); }; var or = function (opt) { return opt; }; var orThunk = function (f) { return f(); }; var map = function (f) { return error(message); }; var mapError = function (f) { return error(f(message)); }; var bind = function (f) { return error(message); }; var fold = function (onError, _) { return onError(message); }; return { is: never, isValue: never, isError: always, getOr: identity, getOrThunk: getOrThunk, getOrDie: getOrDie, or: or, orThunk: orThunk, fold: fold, map: map, mapError: mapError, each: noop, bind: bind, exists: never, forall: always, toOption: Option.none }; }; var Result = { value: value, error: error }; function StyleSheetLoader(document, settings) { if (settings === void 0) { settings = {}; } var idCount = 0; var loadedStates = {}; var maxLoadTime; maxLoadTime = settings.maxLoadTime || 5000; var appendToHead = function (node) { document.getElementsByTagName('head')[0].appendChild(node); }; var load = function (url, loadedCallback, errorCallback) { var link, style, startTime, state; var passed = function () { var callbacks = state.passed; var i = callbacks.length; while (i--) { callbacks[i](); } state.status = 2; state.passed = []; state.failed = []; }; var failed = function () { var callbacks = state.failed; var i = callbacks.length; while (i--) { callbacks[i](); } state.status = 3; state.passed = []; state.failed = []; }; var isOldWebKit = function () { var webKitChunks = domGlobals.navigator.userAgent.match(/WebKit\/(\d*)/); return !!(webKitChunks && parseInt(webKitChunks[1], 10) < 536); }; var wait = function (testCallback, waitCallback) { if (!testCallback()) { if (new Date().getTime() - startTime < maxLoadTime) { Delay.setTimeout(waitCallback); } else { failed(); } } }; var waitForWebKitLinkLoaded = function () { wait(function () { var styleSheets = document.styleSheets; var styleSheet, i = styleSheets.length, owner; while (i--) { styleSheet = styleSheets[i]; owner = styleSheet.ownerNode ? styleSheet.ownerNode : styleSheet.owningElement; if (owner && owner.id === link.id) { passed(); return true; } } }, waitForWebKitLinkLoaded); }; var waitForGeckoLinkLoaded = function () { wait(function () { try { var cssRules = style.sheet.cssRules; passed(); return !!cssRules; } catch (ex) { } }, waitForGeckoLinkLoaded); }; url = Tools._addCacheSuffix(url); if (!loadedStates[url]) { state = { passed: [], failed: [] }; loadedStates[url] = state; } else { state = loadedStates[url]; } if (loadedCallback) { state.passed.push(loadedCallback); } if (errorCallback) { state.failed.push(errorCallback); } if (state.status === 1) { return; } if (state.status === 2) { passed(); return; } if (state.status === 3) { failed(); return; } state.status = 1; link = document.createElement('link'); link.rel = 'stylesheet'; link.type = 'text/css'; link.id = 'u' + idCount++; link.async = false; link.defer = false; startTime = new Date().getTime(); if (settings.contentCssCors) { link.crossOrigin = 'anonymous'; } if ('onload' in link && !isOldWebKit()) { link.onload = waitForWebKitLinkLoaded; link.onerror = failed; } else { if (domGlobals.navigator.userAgent.indexOf('Firefox') > 0) { style = document.createElement('style'); style.textContent = '@import "' + url + '"'; waitForGeckoLinkLoaded(); appendToHead(style); return; } waitForWebKitLinkLoaded(); } appendToHead(link); link.href = url; }; var loadF = function (url) { return Future.nu(function (resolve) { load(url, compose(resolve, constant(Result.value(url))), compose(resolve, constant(Result.error(url)))); }); }; var unbox = function (result) { return result.fold(identity, identity); }; var loadAll = function (urls, success, failure) { par$1(map(urls, loadF)).get(function (result) { var parts = partition(result, function (r) { return r.isValue(); }); if (parts.fail.length > 0) { failure(parts.fail.map(unbox)); } else { success(parts.pass.map(unbox)); } }); }; return { load: load, loadAll: loadAll }; } function TreeWalker (startNode, rootNode) { var node = startNode; var findSibling = function (node, startName, siblingName, shallow) { var sibling, parent; if (node) { if (!shallow && node[startName]) { return node[startName]; } if (node !== rootNode) { sibling = node[siblingName]; if (sibling) { return sibling; } for (parent = node.parentNode; parent && parent !== rootNode; parent = parent.parentNode) { sibling = parent[siblingName]; if (sibling) { return sibling; } } } } }; var findPreviousNode = function (node, startName, siblingName, shallow) { var sibling, parent, child; if (node) { sibling = node[siblingName]; if (rootNode && sibling === rootNode) { return; } if (sibling) { if (!shallow) { for (child = sibling[startName]; child; child = child[startName]) { if (!child[startName]) { return child; } } } return sibling; } parent = node.parentNode; if (parent && parent !== rootNode) { return parent; } } }; this.current = function () { return node; }; this.next = function (shallow) { node = findSibling(node, 'firstChild', 'nextSibling', shallow); return node; }; this.prev = function (shallow) { node = findSibling(node, 'lastChild', 'previousSibling', shallow); return node; }; this.prev2 = function (shallow) { node = findPreviousNode(node, 'lastChild', 'previousSibling', shallow); return node; }; } var blocks = [ 'article', 'aside', 'details', 'div', 'dt', 'figcaption', 'footer', 'form', 'fieldset', 'header', 'hgroup', 'html', 'main', 'nav', 'section', 'summary', 'body', 'p', 'dl', 'multicol', 'dd', 'figure', 'address', 'center', 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'listing', 'xmp', 'pre', 'plaintext', 'menu', 'dir', 'ul', 'ol', 'li', 'hr', 'table', 'tbody', 'thead', 'tfoot', 'th', 'tr', 'td', 'caption' ]; var voids = [ 'area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param', 'embed', 'source', 'wbr', 'track' ]; var tableCells = [ 'td', 'th' ]; var tableSections = [ 'thead', 'tbody', 'tfoot' ]; var textBlocks = [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'div', 'address', 'pre', 'form', 'blockquote', 'center', 'dir', 'fieldset', 'header', 'footer', 'article', 'section', 'hgroup', 'aside', 'nav', 'figure' ]; var headings = [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ]; var listItems = [ 'li', 'dd', 'dt' ]; var lists = [ 'ul', 'ol', 'dl' ]; var wsElements = [ 'pre', 'script', 'textarea', 'style' ]; var lazyLookup = function (items) { var lookup; return function (node) { lookup = lookup ? lookup : mapToObject(items, constant(true)); return lookup.hasOwnProperty(name(node)); }; }; var isHeading = lazyLookup(headings); var isBlock = lazyLookup(blocks); var isInline = function (node) { return isElement(node) && !isBlock(node); }; var isBr = function (node) { return isElement(node) && name(node) === 'br'; }; var isTextBlock = lazyLookup(textBlocks); var isList = lazyLookup(lists); var isListItem = lazyLookup(listItems); var isVoid = lazyLookup(voids); var isTableSection = lazyLookup(tableSections); var isTableCell = lazyLookup(tableCells); var isWsPreserveElement = lazyLookup(wsElements); var isNodeType = function (type) { return function (node) { return !!node && node.nodeType === type; }; }; var isElement$1 = isNodeType(1); var matchNodeNames = function (names) { var items = names.toLowerCase().split(' '); return function (node) { var i, name; if (node && node.nodeType) { name = node.nodeName.toLowerCase(); for (i = 0; i < items.length; i++) { if (name === items[i]) { return true; } } } return false; }; }; var matchStyleValues = function (name, values) { var items = values.toLowerCase().split(' '); return function (node) { var i, cssValue; if (isElement$1(node)) { for (i = 0; i < items.length; i++) { var computed = node.ownerDocument.defaultView.getComputedStyle(node, null); cssValue = computed ? computed.getPropertyValue(name) : null; if (cssValue === items[i]) { return true; } } } return false; }; }; var hasPropValue = function (propName, propValue) { return function (node) { return isElement$1(node) && node[propName] === propValue; }; }; var hasAttribute = function (attrName, attrValue) { return function (node) { return isElement$1(node) && node.hasAttribute(attrName); }; }; var hasAttributeValue = function (attrName, attrValue) { return function (node) { return isElement$1(node) && node.getAttribute(attrName) === attrValue; }; }; var isBogus = function (node) { return isElement$1(node) && node.hasAttribute('data-mce-bogus'); }; var isBogusAll = function (node) { return isElement$1(node) && node.getAttribute('data-mce-bogus') === 'all'; }; var isTable = function (node) { return isElement$1(node) && node.tagName === 'TABLE'; }; var hasContentEditableState = function (value) { return function (node) { if (isElement$1(node)) { if (node.contentEditable === value) { return true; } if (node.getAttribute('data-mce-contenteditable') === value) { return true; } } return false; }; }; var isText$1 = isNodeType(3); var isComment = isNodeType(8); var isDocument = isNodeType(9); var isDocumentFragment = isNodeType(11); var isBr$1 = matchNodeNames('br'); var isContentEditableTrue = hasContentEditableState('true'); var isContentEditableFalse = hasContentEditableState('false'); var NodeType = { isText: isText$1, isElement: isElement$1, isComment: isComment, isDocument: isDocument, isDocumentFragment: isDocumentFragment, isBr: isBr$1, isContentEditableTrue: isContentEditableTrue, isContentEditableFalse: isContentEditableFalse, matchNodeNames: matchNodeNames, hasPropValue: hasPropValue, hasAttribute: hasAttribute, hasAttributeValue: hasAttributeValue, matchStyleValues: matchStyleValues, isBogus: isBogus, isBogusAll: isBogusAll, isTable: isTable }; var surroundedBySpans = function (node) { var previousIsSpan = node.previousSibling && node.previousSibling.nodeName === 'SPAN'; var nextIsSpan = node.nextSibling && node.nextSibling.nodeName === 'SPAN'; return previousIsSpan && nextIsSpan; }; var isBookmarkNode = function (node) { return node && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark'; }; var trimNode = function (dom, node) { var i, children = node.childNodes; if (NodeType.isElement(node) && isBookmarkNode(node)) { return; } for (i = children.length - 1; i >= 0; i--) { trimNode(dom, children[i]); } if (NodeType.isDocument(node) === false) { if (NodeType.isText(node) && node.nodeValue.length > 0) { var trimmedLength = Tools.trim(node.nodeValue).length; if (dom.isBlock(node.parentNode) || trimmedLength > 0) { return; } if (trimmedLength === 0 && surroundedBySpans(node)) { return; } } else if (NodeType.isElement(node)) { children = node.childNodes; if (children.length === 1 && isBookmarkNode(children[0])) { node.parentNode.insertBefore(children[0], node); } if (children.length || isVoid(Element.fromDom(node))) { return; } } dom.remove(node); } return node; }; var TrimNode = { trimNode: trimNode }; var makeMap$1 = Tools.makeMap; var namedEntities, baseEntities, reverseEntities; var attrsCharsRegExp = /[&<>\"\u0060\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g; var textCharsRegExp = /[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g; var rawCharsRegExp = /[<>&\"\']/g; var entityRegExp = /&#([a-z0-9]+);?|&([a-z0-9]+);/gi; var asciiMap = { 128: '\u20AC', 130: '\u201A', 131: '\u0192', 132: '\u201E', 133: '\u2026', 134: '\u2020', 135: '\u2021', 136: '\u02c6', 137: '\u2030', 138: '\u0160', 139: '\u2039', 140: '\u0152', 142: '\u017d', 145: '\u2018', 146: '\u2019', 147: '\u201C', 148: '\u201D', 149: '\u2022', 150: '\u2013', 151: '\u2014', 152: '\u02DC', 153: '\u2122', 154: '\u0161', 155: '\u203A', 156: '\u0153', 158: '\u017e', 159: '\u0178' }; baseEntities = { '"': '"', '\'': ''', '<': '<', '>': '>', '&': '&', '`': '`' }; reverseEntities = { '<': '<', '>': '>', '&': '&', '"': '"', ''': '\'' }; var nativeDecode = function (text) { var elm; elm = Element.fromTag('div').dom(); elm.innerHTML = text; return elm.textContent || elm.innerText || text; }; var buildEntitiesLookup = function (items, radix) { var i, chr, entity; var lookup = {}; if (items) { items = items.split(','); radix = radix || 10; for (i = 0; i < items.length; i += 2) { chr = String.fromCharCode(parseInt(items[i], radix)); if (!baseEntities[chr]) { entity = '&' + items[i + 1] + ';'; lookup[chr] = entity; lookup[entity] = chr; } } return lookup; } }; namedEntities = buildEntitiesLookup('50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,' + '5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,' + '5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,' + '5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,' + '68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,' + '6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,' + '6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,' + '75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,' + '7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,' + '7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,' + 'sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,' + 'st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,' + 't9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,' + 'tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,' + 'u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,' + '81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,' + '8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,' + '8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,' + '8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,' + '8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,' + 'nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,' + 'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' + 'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' + '80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' + '811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro', 32); var encodeRaw = function (text, attr) { return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) { return baseEntities[chr] || chr; }); }; var encodeAllRaw = function (text) { return ('' + text).replace(rawCharsRegExp, function (chr) { return baseEntities[chr] || chr; }); }; var encodeNumeric = function (text, attr) { return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) { if (chr.length > 1) { return '&#' + ((chr.charCodeAt(0) - 55296) * 1024 + (chr.charCodeAt(1) - 56320) + 65536) + ';'; } return baseEntities[chr] || '&#' + chr.charCodeAt(0) + ';'; }); }; var encodeNamed = function (text, attr, entities) { entities = entities || namedEntities; return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) { return baseEntities[chr] || entities[chr] || chr; }); }; var getEncodeFunc = function (name, entities) { var entitiesMap = buildEntitiesLookup(entities) || namedEntities; var encodeNamedAndNumeric = function (text, attr) { return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) { if (baseEntities[chr] !== undefined) { return baseEntities[chr]; } if (entitiesMap[chr] !== undefined) { return entitiesMap[chr]; } if (chr.length > 1) { return '&#' + ((chr.charCodeAt(0) - 55296) * 1024 + (chr.charCodeAt(1) - 56320) + 65536) + ';'; } return '&#' + chr.charCodeAt(0) + ';'; }); }; var encodeCustomNamed = function (text, attr) { return encodeNamed(text, attr, entitiesMap); }; var nameMap = makeMap$1(name.replace(/\+/g, ',')); if (nameMap.named && nameMap.numeric) { return encodeNamedAndNumeric; } if (nameMap.named) { if (entities) { return encodeCustomNamed; } return encodeNamed; } if (nameMap.numeric) { return encodeNumeric; } return encodeRaw; }; var decode = function (text) { return text.replace(entityRegExp, function (all, numeric) { if (numeric) { if (numeric.charAt(0).toLowerCase() === 'x') { numeric = parseInt(numeric.substr(1), 16); } else { numeric = parseInt(numeric, 10); } if (numeric > 65535) { numeric -= 65536; return String.fromCharCode(55296 + (numeric >> 10), 56320 + (numeric & 1023)); } return asciiMap[numeric] || String.fromCharCode(numeric); } return reverseEntities[all] || namedEntities[all] || nativeDecode(all); }); }; var Entities = { encodeRaw: encodeRaw, encodeAllRaw: encodeAllRaw, encodeNumeric: encodeNumeric, encodeNamed: encodeNamed, getEncodeFunc: getEncodeFunc, decode: decode }; var mapCache = {}, dummyObj = {}; var makeMap$2 = Tools.makeMap, each$4 = Tools.each, extend$1 = Tools.extend, explode$1 = Tools.explode, inArray$1 = Tools.inArray; var split = function (items, delim) { items = Tools.trim(items); return items ? items.split(delim || ' ') : []; }; var compileSchema = function (type) { var schema = {}; var globalAttributes, blockContent; var phrasingContent, flowContent, html4BlockContent, html4PhrasingContent; var add = function (name, attributes, children) { var ni, attributesOrder, element; var arrayToMap = function (array, obj) { var map = {}; var i, l; for (i = 0, l = array.length; i < l; i++) { map[array[i]] = obj || {}; } return map; }; children = children || []; attributes = attributes || ''; if (typeof children === 'string') { children = split(children); } name = split(name); ni = name.length; while (ni--) { attributesOrder = split([ globalAttributes, attributes ].join(' ')); element = { attributes: arrayToMap(attributesOrder), attributesOrder: attributesOrder, children: arrayToMap(children, dummyObj) }; schema[name[ni]] = element; } }; var addAttrs = function (name, attributes) { var ni, schemaItem, i, l; name = split(name); ni = name.length; attributes = split(attributes); while (ni--) { schemaItem = schema[name[ni]]; for (i = 0, l = attributes.length; i < l; i++) { schemaItem.attributes[attributes[i]] = {}; schemaItem.attributesOrder.push(attributes[i]); } } }; if (mapCache[type]) { return mapCache[type]; } globalAttributes = 'id accesskey class dir lang style tabindex title role'; blockContent = 'address blockquote div dl fieldset form h1 h2 h3 h4 h5 h6 hr menu ol p pre table ul'; phrasingContent = 'a abbr b bdo br button cite code del dfn em embed i iframe img input ins kbd ' + 'label map noscript object q s samp script select small span strong sub sup ' + 'textarea u var #text #comment'; if (type !== 'html4') { globalAttributes += ' contenteditable contextmenu draggable dropzone ' + 'hidden spellcheck translate'; blockContent += ' article aside details dialog figure main header footer hgroup section nav'; phrasingContent += ' audio canvas command datalist mark meter output picture ' + 'progress time wbr video ruby bdi keygen'; } if (type !== 'html5-strict') { globalAttributes += ' xml:lang'; html4PhrasingContent = 'acronym applet basefont big font strike tt'; phrasingContent = [ phrasingContent, html4PhrasingContent ].join(' '); each$4(split(html4PhrasingContent), function (name) { add(name, '', phrasingContent); }); html4BlockContent = 'center dir isindex noframes'; blockContent = [ blockContent, html4BlockContent ].join(' '); flowContent = [ blockContent, phrasingContent ].join(' '); each$4(split(html4BlockContent), function (name) { add(name, '', flowContent); }); } flowContent = flowContent || [ blockContent, phrasingContent ].join(' '); add('html', 'manifest', 'head body'); add('head', '', 'base command link meta noscript script style title'); add('title hr noscript br'); add('base', 'href target'); add('link', 'href rel media hreflang type sizes hreflang'); add('meta', 'name http-equiv content charset'); add('style', 'media type scoped'); add('script', 'src async defer type charset'); add('body', 'onafterprint onbeforeprint onbeforeunload onblur onerror onfocus ' + 'onhashchange onload onmessage onoffline ononline onpagehide onpageshow ' + 'onpopstate onresize onscroll onstorage onunload', flowContent); add('address dt dd div caption', '', flowContent); add('h1 h2 h3 h4 h5 h6 pre p abbr code var samp kbd sub sup i b u bdo span legend em strong small s cite dfn', '', phrasingContent); add('blockquote', 'cite', flowContent); add('ol', 'reversed start type', 'li'); add('ul', '', 'li'); add('li', 'value', flowContent); add('dl', '', 'dt dd'); add('a', 'href target rel media hreflang type', phrasingContent); add('q', 'cite', phrasingContent); add('ins del', 'cite datetime', flowContent); add('img', 'src sizes srcset alt usemap ismap width height'); add('iframe', 'src name width height', flowContent); add('embed', 'src type width height'); add('object', 'data type typemustmatch name usemap form width height', [ flowContent, 'param' ].join(' ')); add('param', 'name value'); add('map', 'name', [ flowContent, 'area' ].join(' ')); add('area', 'alt coords shape href target rel media hreflang type'); add('table', 'border', 'caption colgroup thead tfoot tbody tr' + (type === 'html4' ? ' col' : '')); add('colgroup', 'span', 'col'); add('col', 'span'); add('tbody thead tfoot', '', 'tr'); add('tr', '', 'td th'); add('td', 'colspan rowspan headers', flowContent); add('th', 'colspan rowspan headers scope abbr', flowContent); add('form', 'accept-charset action autocomplete enctype method name novalidate target', flowContent); add('fieldset', 'disabled form name', [ flowContent, 'legend' ].join(' ')); add('label', 'form for', phrasingContent); add('input', 'accept alt autocomplete checked dirname disabled form formaction formenctype formmethod formnovalidate ' + 'formtarget height list max maxlength min multiple name pattern readonly required size src step type value width'); add('button', 'disabled form formaction formenctype formmethod formnovalidate formtarget name type value', type === 'html4' ? flowContent : phrasingContent); add('select', 'disabled form multiple name required size', 'option optgroup'); add('optgroup', 'disabled label', 'option'); add('option', 'disabled label selected value'); add('textarea', 'cols dirname disabled form maxlength name readonly required rows wrap'); add('menu', 'type label', [ flowContent, 'li' ].join(' ')); add('noscript', '', flowContent); if (type !== 'html4') { add('wbr'); add('ruby', '', [ phrasingContent, 'rt rp' ].join(' ')); add('figcaption', '', flowContent); add('mark rt rp summary bdi', '', phrasingContent); add('canvas', 'width height', flowContent); add('video', 'src crossorigin poster preload autoplay mediagroup loop ' + 'muted controls width height buffered', [ flowContent, 'track source' ].join(' ')); add('audio', 'src crossorigin preload autoplay mediagroup loop muted controls ' + 'buffered volume', [ flowContent, 'track source' ].join(' ')); add('picture', '', 'img source'); add('source', 'src srcset type media sizes'); add('track', 'kind src srclang label default'); add('datalist', '', [ phrasingContent, 'option' ].join(' ')); add('article section nav aside main header footer', '', flowContent); add('hgroup', '', 'h1 h2 h3 h4 h5 h6'); add('figure', '', [ flowContent, 'figcaption' ].join(' ')); add('time', 'datetime', phrasingContent); add('dialog', 'open', flowContent); add('command', 'type label icon disabled checked radiogroup command'); add('output', 'for form name', phrasingContent); add('progress', 'value max', phrasingContent); add('meter', 'value min max low high optimum', phrasingContent); add('details', 'open', [ flowContent, 'summary' ].join(' ')); add('keygen', 'autofocus challenge disabled form keytype name'); } if (type !== 'html5-strict') { addAttrs('script', 'language xml:space'); addAttrs('style', 'xml:space'); addAttrs('object', 'declare classid code codebase codetype archive standby align border hspace vspace'); addAttrs('embed', 'align name hspace vspace'); addAttrs('param', 'valuetype type'); addAttrs('a', 'charset name rev shape coords'); addAttrs('br', 'clear'); addAttrs('applet', 'codebase archive code object alt name width height align hspace vspace'); addAttrs('img', 'name longdesc align border hspace vspace'); addAttrs('iframe', 'longdesc frameborder marginwidth marginheight scrolling align'); addAttrs('font basefont', 'size color face'); addAttrs('input', 'usemap align'); addAttrs('select', 'onchange'); addAttrs('textarea'); addAttrs('h1 h2 h3 h4 h5 h6 div p legend caption', 'align'); addAttrs('ul', 'type compact'); addAttrs('li', 'type'); addAttrs('ol dl menu dir', 'compact'); addAttrs('pre', 'width xml:space'); addAttrs('hr', 'align noshade size width'); addAttrs('isindex', 'prompt'); addAttrs('table', 'summary width frame rules cellspacing cellpadding align bgcolor'); addAttrs('col', 'width align char charoff valign'); addAttrs('colgroup', 'width align char charoff valign'); addAttrs('thead', 'align char charoff valign'); addAttrs('tr', 'align char charoff valign bgcolor'); addAttrs('th', 'axis align char charoff valign nowrap bgcolor width height'); addAttrs('form', 'accept'); addAttrs('td', 'abbr axis scope align char charoff valign nowrap bgcolor width height'); addAttrs('tfoot', 'align char charoff valign'); addAttrs('tbody', 'align char charoff valign'); addAttrs('area', 'nohref'); addAttrs('body', 'background bgcolor text link vlink alink'); } if (type !== 'html4') { addAttrs('input button select textarea', 'autofocus'); addAttrs('input textarea', 'placeholder'); addAttrs('a', 'download'); addAttrs('link script img', 'crossorigin'); addAttrs('iframe', 'sandbox seamless allowfullscreen'); } each$4(split('a form meter progress dfn'), function (name) { if (schema[name]) { delete schema[name].children[name]; } }); delete schema.caption.children.table; delete schema.script; mapCache[type] = schema; return schema; }; var compileElementMap = function (value, mode) { var styles; if (value) { styles = {}; if (typeof value === 'string') { value = { '*': value }; } each$4(value, function (value, key) { styles[key] = styles[key.toUpperCase()] = mode === 'map' ? makeMap$2(value, /[, ]/) : explode$1(value, /[, ]/); }); } return styles; }; function Schema(settings) { var elements = {}; var children = {}; var patternElements = []; var validStyles; var invalidStyles; var schemaItems; var whiteSpaceElementsMap, selfClosingElementsMap, shortEndedElementsMap, boolAttrMap, validClasses; var blockElementsMap, nonEmptyElementsMap, moveCaretBeforeOnEnterElementsMap, textBlockElementsMap, textInlineElementsMap; var customElementsMap = {}, specialElements = {}; var createLookupTable = function (option, defaultValue, extendWith) { var value = settings[option]; if (!value) { value = mapCache[option]; if (!value) { value = makeMap$2(defaultValue, ' ', makeMap$2(defaultValue.toUpperCase(), ' ')); value = extend$1(value, extendWith); mapCache[option] = value; } } else { value = makeMap$2(value, /[, ]/, makeMap$2(value.toUpperCase(), /[, ]/)); } return value; }; settings = settings || {}; schemaItems = compileSchema(settings.schema); if (settings.verify_html === false) { settings.valid_elements = '*[*]'; } validStyles = compileElementMap(settings.valid_styles); invalidStyles = compileElementMap(settings.invalid_styles, 'map'); validClasses = compileElementMap(settings.valid_classes, 'map'); whiteSpaceElementsMap = createLookupTable('whitespace_elements', 'pre script noscript style textarea video audio iframe object code'); selfClosingElementsMap = createLookupTable('self_closing_elements', 'colgroup dd dt li option p td tfoot th thead tr'); shortEndedElementsMap = createLookupTable('short_ended_elements', 'area base basefont br col frame hr img input isindex link ' + 'meta param embed source wbr track'); boolAttrMap = createLookupTable('boolean_attributes', 'checked compact declare defer disabled ismap multiple nohref noresize ' + 'noshade nowrap readonly selected autoplay loop controls'); nonEmptyElementsMap = createLookupTable('non_empty_elements', 'td th iframe video audio object ' + 'script pre code', shortEndedElementsMap); moveCaretBeforeOnEnterElementsMap = createLookupTable('move_caret_before_on_enter_elements', 'table', nonEmptyElementsMap); textBlockElementsMap = createLookupTable('text_block_elements', 'h1 h2 h3 h4 h5 h6 p div address pre form ' + 'blockquote center dir fieldset header footer article section hgroup aside main nav figure'); blockElementsMap = createLookupTable('block_elements', 'hr table tbody thead tfoot ' + 'th tr td li ol ul caption dl dt dd noscript menu isindex option ' + 'datalist select optgroup figcaption details summary', textBlockElementsMap); textInlineElementsMap = createLookupTable('text_inline_elements', 'span strong b em i font strike u var cite ' + 'dfn code mark q sup sub samp'); each$4((settings.special || 'script noscript noframes noembed title style textarea xmp').split(' '), function (name) { specialElements[name] = new RegExp('</' + name + '[^>]*>', 'gi'); }); var patternToRegExp = function (str) { return new RegExp('^' + str.replace(/([?+*])/g, '.$1') + '$'); }; var addValidElements = function (validElements) { var ei, el, ai, al, matches, element, attr, attrData, elementName, attrName, attrType, attributes, attributesOrder, prefix, outputName, globalAttributes, globalAttributesOrder, key, value; var elementRuleRegExp = /^([#+\-])?([^\[!\/]+)(?:\/([^\[!]+))?(?:(!?)\[([^\]]+)\])?$/, attrRuleRegExp = /^([!\-])?(\w+[\\:]:\w+|[^=:<]+)?(?:([=:<])(.*))?$/, hasPatternsRegExp = /[*?+]/; if (validElements) { validElements = split(validElements, ','); if (elements['@']) { globalAttributes = elements['@'].attributes; globalAttributesOrder = elements['@'].attributesOrder; } for (ei = 0, el = validElements.length; ei < el; ei++) { matches = elementRuleRegExp.exec(validElements[ei]); if (matches) { prefix = matches[1]; elementName = matches[2]; outputName = matches[3]; attrData = matches[5]; attributes = {}; attributesOrder = []; element = { attributes: attributes, attributesOrder: attributesOrder }; if (prefix === '#') { element.paddEmpty = true; } if (prefix === '-') { element.removeEmpty = true; } if (matches[4] === '!') { element.removeEmptyAttrs = true; } if (globalAttributes) { for (key in globalAttributes) { attributes[key] = globalAttributes[key]; } attributesOrder.push.apply(attributesOrder, globalAttributesOrder); } if (attrData) { attrData = split(attrData, '|'); for (ai = 0, al = attrData.length; ai < al; ai++) { matches = attrRuleRegExp.exec(attrData[ai]); if (matches) { attr = {}; attrType = matches[1]; attrName = matches[2].replace(/[\\:]:/g, ':'); prefix = matches[3]; value = matches[4]; if (attrType === '!') { element.attributesRequired = element.attributesRequired || []; element.attributesRequired.push(attrName); attr.required = true; } if (attrType === '-') { delete attributes[attrName]; attributesOrder.splice(inArray$1(attributesOrder, attrName), 1); continue; } if (prefix) { if (prefix === '=') { element.attributesDefault = element.attributesDefault || []; element.attributesDefault.push({ name: attrName, value: value }); attr.defaultValue = value; } if (prefix === ':') { element.attributesForced = element.attributesForced || []; element.attributesForced.push({ name: attrName, value: value }); attr.forcedValue = value; } if (prefix === '<') { attr.validValues = makeMap$2(value, '?'); } } if (hasPatternsRegExp.test(attrName)) { element.attributePatterns = element.attributePatterns || []; attr.pattern = patternToRegExp(attrName); element.attributePatterns.push(attr); } else { if (!attributes[attrName]) { attributesOrder.push(attrName); } attributes[attrName] = attr; } } } } if (!globalAttributes && elementName === '@') { globalAttributes = attributes; globalAttributesOrder = attributesOrder; } if (outputName) { element.outputName = elementName; elements[outputName] = element; } if (hasPatternsRegExp.test(elementName)) { element.pattern = patternToRegExp(elementName); patternElements.push(element); } else { elements[elementName] = element; } } } } }; var setValidElements = function (validElements) { elements = {}; patternElements = []; addValidElements(validElements); each$4(schemaItems, function (element, name) { children[name] = element.children; }); }; var addCustomElements = function (customElements) { var customElementRegExp = /^(~)?(.+)$/; if (customElements) { mapCache.text_block_elements = mapCache.block_elements = null; each$4(split(customElements, ','), function (rule) { var matches = customElementRegExp.exec(rule), inline = matches[1] === '~', cloneName = inline ? 'span' : 'div', name = matches[2]; children[name] = children[cloneName]; customElementsMap[name] = cloneName; if (!inline) { blockElementsMap[name.toUpperCase()] = {}; blockElementsMap[name] = {}; } if (!elements[name]) { var customRule = elements[cloneName]; customRule = extend$1({}, customRule); delete customRule.removeEmptyAttrs; delete customRule.removeEmpty; elements[name] = customRule; } each$4(children, function (element, elmName) { if (element[cloneName]) { children[elmName] = element = extend$1({}, children[elmName]); element[name] = element[cloneName]; } }); }); } }; var addValidChildren = function (validChildren) { var childRuleRegExp = /^([+\-]?)(\w+)\[([^\]]+)\]$/; mapCache[settings.schema] = null; if (validChildren) { each$4(split(validChildren, ','), function (rule) { var matches = childRuleRegExp.exec(rule); var parent, prefix; if (matches) { prefix = matches[1]; if (prefix) { parent = children[matches[2]]; } else { parent = children[matches[2]] = { '#comment': {} }; } parent = children[matches[2]]; each$4(split(matches[3], '|'), function (child) { if (prefix === '-') { delete parent[child]; } else { parent[child] = {}; } }); } }); } }; var getElementRule = function (name) { var element = elements[name], i; if (element) { return element; } i = patternElements.length; while (i--) { element = patternElements[i]; if (element.pattern.test(name)) { return element; } } }; if (!settings.valid_elements) { each$4(schemaItems, function (element, name) { elements[name] = { attributes: element.attributes, attributesOrder: element.attributesOrder }; children[name] = element.children; }); if (settings.schema !== 'html5') { each$4(split('strong/b em/i'), function (item) { item = split(item, '/'); elements[item[1]].outputName = item[0]; }); } each$4(split('ol ul sub sup blockquote span font a table tbody tr strong em b i'), function (name) { if (elements[name]) { elements[name].removeEmpty = true; } }); each$4(split('p h1 h2 h3 h4 h5 h6 th td pre div address caption li'), function (name) { elements[name].paddEmpty = true; }); each$4(split('span'), function (name) { elements[name].removeEmptyAttrs = true; }); } else { setValidElements(settings.valid_elements); } addCustomElements(settings.custom_elements); addValidChildren(settings.valid_children); addValidElements(settings.extended_valid_elements); addValidChildren('+ol[ul|ol],+ul[ul|ol]'); each$4({ dd: 'dl', dt: 'dl', li: 'ul ol', td: 'tr', th: 'tr', tr: 'tbody thead tfoot', tbody: 'table', thead: 'table', tfoot: 'table', legend: 'fieldset', area: 'map', param: 'video audio object' }, function (parents, item) { if (elements[item]) { elements[item].parentsRequired = split(parents); } }); if (settings.invalid_elements) { each$4(explode$1(settings.invalid_elements), function (item) { if (elements[item]) { delete elements[item]; } }); } if (!getElementRule('span')) { addValidElements('span[!data-mce-type|*]'); } var getValidStyles = function () { return validStyles; }; var getInvalidStyles = function () { return invalidStyles; }; var getValidClasses = function () { return validClasses; }; var getBoolAttrs = function () { return boolAttrMap; }; var getBlockElements = function () { return blockElementsMap; }; var getTextBlockElements = function () { return textBlockElementsMap; }; var getTextInlineElements = function () { return textInlineElementsMap; }; var getShortEndedElements = function () { return shortEndedElementsMap; }; var getSelfClosingElements = function () { return selfClosingElementsMap; }; var getNonEmptyElements = function () { return nonEmptyElementsMap; }; var getMoveCaretBeforeOnEnterElements = function () { return moveCaretBeforeOnEnterElementsMap; }; var getWhiteSpaceElements = function () { return whiteSpaceElementsMap; }; var getSpecialElements = function () { return specialElements; }; var isValidChild = function (name, child) { var parent = children[name.toLowerCase()]; return !!(parent && parent[child.toLowerCase()]); }; var isValid = function (name, attr) { var attrPatterns, i; var rule = getElementRule(name); if (rule) { if (attr) { if (rule.attributes[attr]) { return true; } attrPatterns = rule.attributePatterns; if (attrPatterns) { i = attrPatterns.length; while (i--) { if (attrPatterns[i].pattern.test(name)) { return true; } } } } else { return true; } } return false; }; var getCustomElements = function () { return customElementsMap; }; return { children: children, elements: elements, getValidStyles: getValidStyles, getValidClasses: getValidClasses, getBlockElements: getBlockElements, getInvalidStyles: getInvalidStyles, getShortEndedElements: getShortEndedElements, getTextBlockElements: getTextBlockElements, getTextInlineElements: getTextInlineElements, getBoolAttrs: getBoolAttrs, getElementRule: getElementRule, getSelfClosingElements: getSelfClosingElements, getNonEmptyElements: getNonEmptyElements, getMoveCaretBeforeOnEnterElements: getMoveCaretBeforeOnEnterElements, getWhiteSpaceElements: getWhiteSpaceElements, getSpecialElements: getSpecialElements, isValidChild: isValidChild, isValid: isValid, getCustomElements: getCustomElements, addValidElements: addValidElements, setValidElements: setValidElements, addCustomElements: addCustomElements, addValidChildren: addValidChildren }; } var toHex = function (match, r, g, b) { var hex = function (val) { val = parseInt(val, 10).toString(16); return val.length > 1 ? val : '0' + val; }; return '#' + hex(r) + hex(g) + hex(b); }; function Styles(settings, schema) { var rgbRegExp = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi; var urlOrStrRegExp = /(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi; var styleRegExp = /\s*([^:]+):\s*([^;]+);?/g; var trimRightRegExp = /\s+$/; var i; var encodingLookup = {}; var encodingItems; var validStyles; var invalidStyles; var invisibleChar = '\uFEFF'; settings = settings || {}; if (schema) { validStyles = schema.getValidStyles(); invalidStyles = schema.getInvalidStyles(); } encodingItems = ('\\" \\\' \\; \\: ; : ' + invisibleChar).split(' '); for (i = 0; i < encodingItems.length; i++) { encodingLookup[encodingItems[i]] = invisibleChar + i; encodingLookup[invisibleChar + i] = encodingItems[i]; } return { toHex: function (color) { return color.replace(rgbRegExp, toHex); }, parse: function (css) { var styles = {}; var matches, name, value, isEncoded; var urlConverter = settings.url_converter; var urlConverterScope = settings.url_converter_scope || this; var compress = function (prefix, suffix, noJoin) { var top, right, bottom, left; top = styles[prefix + '-top' + suffix]; if (!top) { return; } right = styles[prefix + '-right' + suffix]; if (!right) { return; } bottom = styles[prefix + '-bottom' + suffix]; if (!bottom) { return; } left = styles[prefix + '-left' + suffix]; if (!left) { return; } var box = [ top, right, bottom, left ]; i = box.length - 1; while (i--) { if (box[i] !== box[i + 1]) { break; } } if (i > -1 && noJoin) { return; } styles[prefix + suffix] = i === -1 ? box[0] : box.join(' '); delete styles[prefix + '-top' + suffix]; delete styles[prefix + '-right' + suffix]; delete styles[prefix + '-bottom' + suffix]; delete styles[prefix + '-left' + suffix]; }; var canCompress = function (key) { var value = styles[key], i; if (!value) { return; } value = value.split(' '); i = value.length; while (i--) { if (value[i] !== value[0]) { return false; } } styles[key] = value[0]; return true; }; var compress2 = function (target, a, b, c) { if (!canCompress(a)) { return; } if (!canCompress(b)) { return; } if (!canCompress(c)) { return; } styles[target] = styles[a] + ' ' + styles[b] + ' ' + styles[c]; delete styles[a]; delete styles[b]; delete styles[c]; }; var encode = function (str) { isEncoded = true; return encodingLookup[str]; }; var decode = function (str, keepSlashes) { if (isEncoded) { str = str.replace(/\uFEFF[0-9]/g, function (str) { return encodingLookup[str]; }); } if (!keepSlashes) { str = str.replace(/\\([\'\";:])/g, '$1'); } return str; }; var decodeSingleHexSequence = function (escSeq) { return String.fromCharCode(parseInt(escSeq.slice(1), 16)); }; var decodeHexSequences = function (value) { return value.replace(/\\[0-9a-f]+/gi, decodeSingleHexSequence); }; var processUrl = function (match, url, url2, url3, str, str2) { str = str || str2; if (str) { str = decode(str); return '\'' + str.replace(/\'/g, '\\\'') + '\''; } url = decode(url || url2 || url3); if (!settings.allow_script_urls) { var scriptUrl = url.replace(/[\s\r\n]+/g, ''); if (/(java|vb)script:/i.test(scriptUrl)) { return ''; } if (!settings.allow_svg_data_urls && /^data:image\/svg/i.test(scriptUrl)) { return ''; } } if (urlConverter) { url = urlConverter.call(urlConverterScope, url, 'style'); } return 'url(\'' + url.replace(/\'/g, '\\\'') + '\')'; }; if (css) { css = css.replace(/[\u0000-\u001F]/g, ''); css = css.replace(/\\[\"\';:\uFEFF]/g, encode).replace(/\"[^\"]+\"|\'[^\']+\'/g, function (str) { return str.replace(/[;:]/g, encode); }); while (matches = styleRegExp.exec(css)) { styleRegExp.lastIndex = matches.index + matches[0].length; name = matches[1].replace(trimRightRegExp, '').toLowerCase(); value = matches[2].replace(trimRightRegExp, ''); if (name && value) { name = decodeHexSequences(name); value = decodeHexSequences(value); if (name.indexOf(invisibleChar) !== -1 || name.indexOf('"') !== -1) { continue; } if (!settings.allow_script_urls && (name === 'behavior' || /expression\s*\(|\/\*|\*\//.test(value))) { continue; } if (name === 'font-weight' && value === '700') { value = 'bold'; } else if (name === 'color' || name === 'background-color') { value = value.toLowerCase(); } value = value.replace(rgbRegExp, toHex); value = value.replace(urlOrStrRegExp, processUrl); styles[name] = isEncoded ? decode(value, true) : value; } } compress('border', '', true); compress('border', '-width'); compress('border', '-color'); compress('border', '-style'); compress('padding', ''); compress('margin', ''); compress2('border', 'border-width', 'border-style', 'border-color'); if (styles.border === 'medium none') { delete styles.border; } if (styles['border-image'] === 'none') { delete styles['border-image']; } } return styles; }, serialize: function (styles, elementName) { var css = '', name, value; var serializeStyles = function (name) { var styleList, i, l, value; styleList = validStyles[name]; if (styleList) { for (i = 0, l = styleList.length; i < l; i++) { name = styleList[i]; value = styles[name]; if (value) { css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';'; } } } }; var isValid = function (name, elementName) { var styleMap; styleMap = invalidStyles['*']; if (styleMap && styleMap[name]) { return false; } styleMap = invalidStyles[elementName]; if (styleMap && styleMap[name]) { return false; } return true; }; if (elementName && validStyles) { serializeStyles('*'); serializeStyles(elementName); } else { for (name in styles) { value = styles[name]; if (value && (!invalidStyles || isValid(name, elementName))) { css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';'; } } } return css; } }; } var each$5 = Tools.each; var grep$1 = Tools.grep; var isIE = Env.ie; var simpleSelectorRe = /^([a-z0-9],?)+$/i; var whiteSpaceRegExp$2 = /^[ \t\r\n]*$/; var setupAttrHooks = function (styles, settings, getContext) { var attrHooks = {}; var keepValues = settings.keep_values; var keepUrlHook = { set: function ($elm, value, name) { if (settings.url_converter) { value = settings.url_converter.call(settings.url_converter_scope || getContext(), value, name, $elm[0]); } $elm.attr('data-mce-' + name, value).attr(name, value); }, get: function ($elm, name) { return $elm.attr('data-mce-' + name) || $elm.attr(name); } }; attrHooks = { style: { set: function ($elm, value) { if (value !== null && typeof value === 'object') { $elm.css(value); return; } if (keepValues) { $elm.attr('data-mce-style', value); } $elm.attr('style', value); }, get: function ($elm) { var value = $elm.attr('data-mce-style') || $elm.attr('style'); value = styles.serialize(styles.parse(value), $elm[0].nodeName); return value; } } }; if (keepValues) { attrHooks.href = attrHooks.src = keepUrlHook; } return attrHooks; }; var updateInternalStyleAttr = function (styles, $elm) { var rawValue = $elm.attr('style'); var value = styles.serialize(styles.parse(rawValue), $elm[0].nodeName); if (!value) { value = null; } $elm.attr('data-mce-style', value); }; var findNodeIndex = function (node, normalized) { var idx = 0, lastNodeType, nodeType; if (node) { for (lastNodeType = node.nodeType, node = node.previousSibling; node; node = node.previousSibling) { nodeType = node.nodeType; if (normalized && nodeType === 3) { if (nodeType === lastNodeType || !node.nodeValue.length) { continue; } } idx++; lastNodeType = nodeType; } } return idx; }; function DOMUtils(doc, settings) { var _this = this; if (settings === void 0) { settings = {}; } var attrHooks; var addedStyles = {}; var win = domGlobals.window; var files = {}; var counter = 0; var stdMode = true; var boxModel = true; var styleSheetLoader = StyleSheetLoader(doc, { contentCssCors: settings.contentCssCors }); var boundEvents = []; var schema = settings.schema ? settings.schema : Schema({}); var styles = Styles({ url_converter: settings.url_converter, url_converter_scope: settings.url_converter_scope }, settings.schema); var events = settings.ownEvents ? new EventUtils(settings.proxy) : EventUtils.Event; var blockElementsMap = schema.getBlockElements(); var $ = DomQuery.overrideDefaults(function () { return { context: doc, element: self.getRoot() }; }); var isBlock = function (node) { if (typeof node === 'string') { return !!blockElementsMap[node]; } else if (node) { var type = node.nodeType; if (type) { return !!(type === 1 && blockElementsMap[node.nodeName]); } } return false; }; var get = function (elm) { if (elm && doc && typeof elm === 'string') { var node = doc.getElementById(elm); if (node && node.id !== elm) { return doc.getElementsByName(elm)[1]; } else { return node; } } return elm; }; var $$ = function (elm) { if (typeof elm === 'string') { elm = get(elm); } return $(elm); }; var getAttrib = function (elm, name, defaultVal) { var hook, value; var $elm = $$(elm); if ($elm.length) { hook = attrHooks[name]; if (hook && hook.get) { value = hook.get($elm, name); } else { value = $elm.attr(name); } } if (typeof value === 'undefined') { value = defaultVal || ''; } return value; }; var getAttribs = function (elm) { var node = get(elm); if (!node) { return []; } return node.attributes; }; var setAttrib = function (elm, name, value) { var originalValue, hook; if (value === '') { value = null; } var $elm = $$(elm); originalValue = $elm.attr(name); if (!$elm.length) { return; } hook = attrHooks[name]; if (hook && hook.set) { hook.set($elm, value, name); } else { $elm.attr(name, value); } if (originalValue !== value && settings.onSetAttrib) { settings.onSetAttrib({ attrElm: $elm, attrName: name, attrValue: value }); } }; var clone = function (node, deep) { if (!isIE || node.nodeType !== 1 || deep) { return node.cloneNode(deep); } if (!deep) { var clone_1 = doc.createElement(node.nodeName); each$5(getAttribs(node), function (attr) { setAttrib(clone_1, attr.nodeName, getAttrib(node, attr.nodeName)); }); return clone_1; } return null; }; var getRoot = function () { return settings.root_element || doc.body; }; var getViewPort = function (argWin) { var actWin = !argWin ? win : argWin; var doc = actWin.document; var rootElm = doc.documentElement; return { x: actWin.pageXOffset || rootElm.scrollLeft, y: actWin.pageYOffset || rootElm.scrollTop, w: actWin.innerWidth || rootElm.clientWidth, h: actWin.innerHeight || rootElm.clientHeight }; }; var getPos = function (elm, rootElm) { return Position.getPos(doc.body, get(elm), rootElm); }; var setStyle = function (elm, name, value) { var $elm = $$(elm).css(name, value); if (settings.update_styles) { updateInternalStyleAttr(styles, $elm); } }; var setStyles = function (elm, stylesArg) { var $elm = $$(elm).css(stylesArg); if (settings.update_styles) { updateInternalStyleAttr(styles, $elm); } }; var getStyle = function (elm, name, computed) { var $elm = $$(elm); if (computed) { return $elm.css(name); } name = name.replace(/-(\D)/g, function (a, b) { return b.toUpperCase(); }); if (name === 'float') { name = Env.ie && Env.ie < 12 ? 'styleFloat' : 'cssFloat'; } return $elm[0] && $elm[0].style ? $elm[0].style[name] : undefined; }; var getSize = function (elm) { var w, h; elm = get(elm); w = getStyle(elm, 'width'); h = getStyle(elm, 'height'); if (w.indexOf('px') === -1) { w = 0; } if (h.indexOf('px') === -1) { h = 0; } return { w: parseInt(w, 10) || elm.offsetWidth || elm.clientWidth, h: parseInt(h, 10) || elm.offsetHeight || elm.clientHeight }; }; var getRect = function (elm) { var pos, size; elm = get(elm); pos = getPos(elm); size = getSize(elm); return { x: pos.x, y: pos.y, w: size.w, h: size.h }; }; var is = function (elm, selector) { var i; if (!elm) { return false; } if (!Array.isArray(elm)) { if (selector === '*') { return elm.nodeType === 1; } if (simpleSelectorRe.test(selector)) { var selectors = selector.toLowerCase().split(/,/); var elmName = elm.nodeName.toLowerCase(); for (i = selectors.length - 1; i >= 0; i--) { if (selectors[i] === elmName) { return true; } } return false; } if (elm.nodeType && elm.nodeType !== 1) { return false; } } var elms = !Array.isArray(elm) ? [elm] : elm; return Sizzle(selector, elms[0].ownerDocument || elms[0], null, elms).length > 0; }; var getParents = function (elm, selector, root, collect) { var result = []; var selectorVal; var node = get(elm); collect = collect === undefined; root = root || (getRoot().nodeName !== 'BODY' ? getRoot().parentNode : null); if (Tools.is(selector, 'string')) { selectorVal = selector; if (selector === '*') { selector = function (node) { return node.nodeType === 1; }; } else { selector = function (node) { return is(node, selectorVal); }; } } while (node) { if (node === root || !node.nodeType || node.nodeType === 9) { break; } if (!selector || typeof selector === 'function' && selector(node)) { if (collect) { result.push(node); } else { return [node]; } } node = node.parentNode; } return collect ? result : null; }; var getParent = function (node, selector, root) { var parents = getParents(node, selector, root, false); return parents && parents.length > 0 ? parents[0] : null; }; var _findSib = function (node, selector, name) { var func = selector; if (node) { if (typeof selector === 'string') { func = function (node) { return is(node, selector); }; } for (node = node[name]; node; node = node[name]) { if (typeof func === 'function' && func(node)) { return node; } } } return null; }; var getNext = function (node, selector) { return _findSib(node, selector, 'nextSibling'); }; var getPrev = function (node, selector) { return _findSib(node, selector, 'previousSibling'); }; var select = function (selector, scope) { return Sizzle(selector, get(scope) || settings.root_element || doc, []); }; var run = function (elm, func, scope) { var result; var node = typeof elm === 'string' ? get(elm) : elm; if (!node) { return false; } if (Tools.isArray(node) && (node.length || node.length === 0)) { result = []; each$5(node, function (elm, i) { if (elm) { if (typeof elm === 'string') { elm = get(elm); } result.push(func.call(scope, elm, i)); } }); return result; } var context = scope ? scope : _this; return func.call(context, node); }; var setAttribs = function (elm, attrs) { $$(elm).each(function (i, node) { each$5(attrs, function (value, name) { setAttrib(node, name, value); }); }); }; var setHTML = function (elm, html) { var $elm = $$(elm); if (isIE) { $elm.each(function (i, target) { if (target.canHaveHTML === false) { return; } while (target.firstChild) { target.removeChild(target.firstChild); } try { target.innerHTML = '<br>' + html; target.removeChild(target.firstChild); } catch (ex) { DomQuery('<div></div>').html('<br>' + html).contents().slice(1).appendTo(target); } return html; }); } else { $elm.html(html); } }; var add = function (parentElm, name, attrs, html, create) { return run(parentElm, function (parentElm) { var newElm = typeof name === 'string' ? doc.createElement(name) : name; setAttribs(newElm, attrs); if (html) { if (typeof html !== 'string' && html.nodeType) { newElm.appendChild(html); } else if (typeof html === 'string') { setHTML(newElm, html); } } return !create ? parentElm.appendChild(newElm) : newElm; }); }; var create = function (name, attrs, html) { return add(doc.createElement(name), name, attrs, html, true); }; var decode = Entities.decode; var encode = Entities.encodeAllRaw; var createHTML = function (name, attrs, html) { var outHtml = '', key; outHtml += '<' + name; for (key in attrs) { if (attrs.hasOwnProperty(key) && attrs[key] !== null && typeof attrs[key] !== 'undefined') { outHtml += ' ' + key + '="' + encode(attrs[key]) + '"'; } } if (typeof html !== 'undefined') { return outHtml + '>' + html + '</' + name + '>'; } return outHtml + ' />'; }; var createFragment = function (html) { var node; var container = doc.createElement('div'); var frag = doc.createDocumentFragment(); if (html) { container.innerHTML = html; } while (node = container.firstChild) { frag.appendChild(node); } return frag; }; var remove = function (node, keepChildren) { var $node = $$(node); if (keepChildren) { $node.each(function () { var child; while (child = this.firstChild) { if (child.nodeType === 3 && child.data.length === 0) { this.removeChild(child); } else { this.parentNode.insertBefore(child, this); } } }).remove(); } else { $node.remove(); } return $node.length > 1 ? $node.toArray() : $node[0]; }; var removeAllAttribs = function (e) { return run(e, function (e) { var i; var attrs = e.attributes; for (i = attrs.length - 1; i >= 0; i--) { e.removeAttributeNode(attrs.item(i)); } }); }; var parseStyle = function (cssText) { return styles.parse(cssText); }; var serializeStyle = function (stylesArg, name) { return styles.serialize(stylesArg, name); }; var addStyle = function (cssText) { var head, styleElm; if (self !== DOMUtils.DOM && doc === domGlobals.document) { if (addedStyles[cssText]) { return; } addedStyles[cssText] = true; } styleElm = doc.getElementById('mceDefaultStyles'); if (!styleElm) { styleElm = doc.createElement('style'); styleElm.id = 'mceDefaultStyles'; styleElm.type = 'text/css'; head = doc.getElementsByTagName('head')[0]; if (head.firstChild) { head.insertBefore(styleElm, head.firstChild); } else { head.appendChild(styleElm); } } if (styleElm.styleSheet) { styleElm.styleSheet.cssText += cssText; } else { styleElm.appendChild(doc.createTextNode(cssText)); } }; var loadCSS = function (url) { var head; if (self !== DOMUtils.DOM && doc === domGlobals.document) { DOMUtils.DOM.loadCSS(url); return; } if (!url) { url = ''; } head = doc.getElementsByTagName('head')[0]; each$5(url.split(','), function (url) { var link; url = Tools._addCacheSuffix(url); if (files[url]) { return; } files[url] = true; link = create('link', { rel: 'stylesheet', href: url }); head.appendChild(link); }); }; var toggleClass = function (elm, cls, state) { $$(elm).toggleClass(cls, state).each(function () { if (this.className === '') { DomQuery(this).attr('class', null); } }); }; var addClass = function (elm, cls) { $$(elm).addClass(cls); }; var removeClass = function (elm, cls) { toggleClass(elm, cls, false); }; var hasClass = function (elm, cls) { return $$(elm).hasClass(cls); }; var show = function (elm) { $$(elm).show(); }; var hide = function (elm) { $$(elm).hide(); }; var isHidden = function (elm) { return $$(elm).css('display') === 'none'; }; var uniqueId = function (prefix) { return (!prefix ? 'mce_' : prefix) + counter++; }; var getOuterHTML = function (elm) { var node = typeof elm === 'string' ? get(elm) : elm; return NodeType.isElement(node) ? node.outerHTML : DomQuery('<div></div>').append(DomQuery(node).clone()).html(); }; var setOuterHTML = function (elm, html) { $$(elm).each(function () { try { if ('outerHTML' in this) { this.outerHTML = html; return; } } catch (ex) { } remove(DomQuery(this).html(html), true); }); }; var insertAfter = function (node, reference) { var referenceNode = get(reference); return run(node, function (node) { var parent, nextSibling; parent = referenceNode.parentNode; nextSibling = referenceNode.nextSibling; if (nextSibling) { parent.insertBefore(node, nextSibling); } else { parent.appendChild(node); } return node; }); }; var replace = function (newElm, oldElm, keepChildren) { return run(oldElm, function (oldElm) { if (Tools.is(oldElm, 'array')) { newElm = newElm.cloneNode(true); } if (keepChildren) { each$5(grep$1(oldElm.childNodes), function (node) { newElm.appendChild(node); }); } return oldElm.parentNode.replaceChild(newElm, oldElm); }); }; var rename = function (elm, name) { var newElm; if (elm.nodeName !== name.toUpperCase()) { newElm = create(name); each$5(getAttribs(elm), function (attrNode) { setAttrib(newElm, attrNode.nodeName, getAttrib(elm, attrNode.nodeName)); }); replace(newElm, elm, true); } return newElm || elm; }; var findCommonAncestor = function (a, b) { var ps = a, pe; while (ps) { pe = b; while (pe && ps !== pe) { pe = pe.parentNode; } if (ps === pe) { break; } ps = ps.parentNode; } if (!ps && a.ownerDocument) { return a.ownerDocument.documentElement; } return ps; }; var toHex = function (rgbVal) { return styles.toHex(Tools.trim(rgbVal)); }; var isEmpty = function (node, elements) { var i, attributes, type, whitespace, walker, name, brCount = 0; node = node.firstChild; if (node) { walker = new TreeWalker(node, node.parentNode); elements = elements || (schema ? schema.getNonEmptyElements() : null); whitespace = schema ? schema.getWhiteSpaceElements() : {}; do { type = node.nodeType; if (NodeType.isElement(node)) { var bogusVal = node.getAttribute('data-mce-bogus'); if (bogusVal) { node = walker.next(bogusVal === 'all'); continue; } name = node.nodeName.toLowerCase(); if (elements && elements[name]) { if (name === 'br') { brCount++; node = walker.next(); continue; } return false; } attributes = getAttribs(node); i = attributes.length; while (i--) { name = attributes[i].nodeName; if (name === 'name' || name === 'data-mce-bookmark') { return false; } } } if (type === 8) { return false; } if (type === 3 && !whiteSpaceRegExp$2.test(node.nodeValue)) { return false; } if (type === 3 && node.parentNode && whitespace[node.parentNode.nodeName] && whiteSpaceRegExp$2.test(node.nodeValue)) { return false; } node = walker.next(); } while (node); } return brCount <= 1; }; var createRng = function () { return doc.createRange(); }; var split = function (parentElm, splitElm, replacementElm) { var r = createRng(), bef, aft, pa; if (parentElm && splitElm) { r.setStart(parentElm.parentNode, findNodeIndex(parentElm)); r.setEnd(splitElm.parentNode, findNodeIndex(splitElm)); bef = r.extractContents(); r = createRng(); r.setStart(splitElm.parentNode, findNodeIndex(splitElm) + 1); r.setEnd(parentElm.parentNode, findNodeIndex(parentElm) + 1); aft = r.extractContents(); pa = parentElm.parentNode; pa.insertBefore(TrimNode.trimNode(self, bef), parentElm); if (replacementElm) { pa.insertBefore(replacementElm, parentElm); } else { pa.insertBefore(splitElm, parentElm); } pa.insertBefore(TrimNode.trimNode(self, aft), parentElm); remove(parentElm); return replacementElm || splitElm; } }; var bind = function (target, name, func, scope) { if (Tools.isArray(target)) { var i = target.length; while (i--) { target[i] = bind(target[i], name, func, scope); } return target; } if (settings.collect && (target === doc || target === win)) { boundEvents.push([ target, name, func, scope ]); } return events.bind(target, name, func, scope || self); }; var unbind = function (target, name, func) { var i; if (Tools.isArray(target)) { i = target.length; while (i--) { target[i] = unbind(target[i], name, func); } return target; } if (boundEvents && (target === doc || target === win)) { i = boundEvents.length; while (i--) { var item = boundEvents[i]; if (target === item[0] && (!name || name === item[1]) && (!func || func === item[2])) { events.unbind(item[0], item[1], item[2]); } } } return events.unbind(target, name, func); }; var fire = function (target, name, evt) { return events.fire(target, name, evt); }; var getContentEditable = function (node) { if (node && NodeType.isElement(node)) { var contentEditable = node.getAttribute('data-mce-contenteditable'); if (contentEditable && contentEditable !== 'inherit') { return contentEditable; } return node.contentEditable !== 'inherit' ? node.contentEditable : null; } else { return null; } }; var getContentEditableParent = function (node) { var root = getRoot(); var state = null; for (; node && node !== root; node = node.parentNode) { state = getContentEditable(node); if (state !== null) { break; } } return state; }; var destroy = function () { if (boundEvents) { var i = boundEvents.length; while (i--) { var item = boundEvents[i]; events.unbind(item[0], item[1], item[2]); } } if (Sizzle.setDocument) { Sizzle.setDocument(); } }; var isChildOf = function (node, parent) { while (node) { if (parent === node) { return true; } node = node.parentNode; } return false; }; var dumpRng = function (r) { return 'startContainer: ' + r.startContainer.nodeName + ', startOffset: ' + r.startOffset + ', endContainer: ' + r.endContainer.nodeName + ', endOffset: ' + r.endOffset; }; var self = { doc: doc, settings: settings, win: win, files: files, stdMode: stdMode, boxModel: boxModel, styleSheetLoader: styleSheetLoader, boundEvents: boundEvents, styles: styles, schema: schema, events: events, isBlock: isBlock, $: $, $$: $$, root: null, clone: clone, getRoot: getRoot, getViewPort: getViewPort, getRect: getRect, getSize: getSize, getParent: getParent, getParents: getParents, get: get, getNext: getNext, getPrev: getPrev, select: select, is: is, add: add, create: create, createHTML: createHTML, createFragment: createFragment, remove: remove, setStyle: setStyle, getStyle: getStyle, setStyles: setStyles, removeAllAttribs: removeAllAttribs, setAttrib: setAttrib, setAttribs: setAttribs, getAttrib: getAttrib, getPos: getPos, parseStyle: parseStyle, serializeStyle: serializeStyle, addStyle: addStyle, loadCSS: loadCSS, addClass: addClass, removeClass: removeClass, hasClass: hasClass, toggleClass: toggleClass, show: show, hide: hide, isHidden: isHidden, uniqueId: uniqueId, setHTML: setHTML, getOuterHTML: getOuterHTML, setOuterHTML: setOuterHTML, decode: decode, encode: encode, insertAfter: insertAfter, replace: replace, rename: rename, findCommonAncestor: findCommonAncestor, toHex: toHex, run: run, getAttribs: getAttribs, isEmpty: isEmpty, createRng: createRng, nodeIndex: findNodeIndex, split: split, bind: bind, unbind: unbind, fire: fire, getContentEditable: getContentEditable, getContentEditableParent: getContentEditableParent, destroy: destroy, isChildOf: isChildOf, dumpRng: dumpRng }; attrHooks = setupAttrHooks(styles, settings, function () { return self; }); return self; } (function (DOMUtils) { DOMUtils.DOM = DOMUtils(domGlobals.document); DOMUtils.nodeIndex = findNodeIndex; }(DOMUtils || (DOMUtils = {}))); var DOMUtils$1 = DOMUtils; var DOM = DOMUtils$1.DOM; var each$6 = Tools.each, grep$2 = Tools.grep; var isFunction$1 = function (f) { return typeof f === 'function'; }; var ScriptLoader = function () { var QUEUED = 0; var LOADING = 1; var LOADED = 2; var FAILED = 3; var states = {}; var queue = []; var scriptLoadedCallbacks = {}; var queueLoadedCallbacks = []; var loading = 0; var loadScript = function (url, success, failure) { var dom = DOM; var elm, id; var done = function () { dom.remove(id); if (elm) { elm.onreadystatechange = elm.onload = elm = null; } success(); }; var error = function () { if (isFunction$1(failure)) { failure(); } else { if (typeof console !== 'undefined' && console.log) { console.log('Failed to load script: ' + url); } } }; id = dom.uniqueId(); elm = domGlobals.document.createElement('script'); elm.id = id; elm.type = 'text/javascript'; elm.src = Tools._addCacheSuffix(url); elm.onload = done; elm.onerror = error; (domGlobals.document.getElementsByTagName('head')[0] || domGlobals.document.body).appendChild(elm); }; this.isDone = function (url) { return states[url] === LOADED; }; this.markDone = function (url) { states[url] = LOADED; }; this.add = this.load = function (url, success, scope, failure) { var state = states[url]; if (state === undefined) { queue.push(url); states[url] = QUEUED; } if (success) { if (!scriptLoadedCallbacks[url]) { scriptLoadedCallbacks[url] = []; } scriptLoadedCallbacks[url].push({ success: success, failure: failure, scope: scope || this }); } }; this.remove = function (url) { delete states[url]; delete scriptLoadedCallbacks[url]; }; this.loadQueue = function (success, scope, failure) { this.loadScripts(queue, success, scope, failure); }; this.loadScripts = function (scripts, success, scope, failure) { var loadScripts; var failures = []; var execCallbacks = function (name, url) { each$6(scriptLoadedCallbacks[url], function (callback) { if (isFunction$1(callback[name])) { callback[name].call(callback.scope); } }); scriptLoadedCallbacks[url] = undefined; }; queueLoadedCallbacks.push({ success: success, failure: failure, scope: scope || this }); loadScripts = function () { var loadingScripts = grep$2(scripts); scripts.length = 0; each$6(loadingScripts, function (url) { if (states[url] === LOADED) { execCallbacks('success', url); return; } if (states[url] === FAILED) { execCallbacks('failure', url); return; } if (states[url] !== LOADING) { states[url] = LOADING; loading++; loadScript(url, function () { states[url] = LOADED; loading--; execCallbacks('success', url); loadScripts(); }, function () { states[url] = FAILED; loading--; failures.push(url); execCallbacks('failure', url); loadScripts(); }); } }); if (!loading) { var notifyCallbacks = queueLoadedCallbacks.slice(0); queueLoadedCallbacks.length = 0; each$6(notifyCallbacks, function (callback) { if (failures.length === 0) { if (isFunction$1(callback.success)) { callback.success.call(callback.scope); } } else { if (isFunction$1(callback.failure)) { callback.failure.call(callback.scope, failures); } } }); } }; loadScripts(); }; }; ScriptLoader.ScriptLoader = new ScriptLoader(); var each$7 = Tools.each; function AddOnManager() { var _this = this; var items = []; var urls = {}; var lookup = {}; var _listeners = []; var get = function (name) { if (lookup[name]) { return lookup[name].instance; } return undefined; }; var dependencies = function (name) { var result; if (lookup[name]) { result = lookup[name].dependencies; } return result || []; }; var requireLangPack = function (name, languages) { var language = AddOnManager.language; if (language && AddOnManager.languageLoad !== false) { if (languages) { languages = ',' + languages + ','; if (languages.indexOf(',' + language.substr(0, 2) + ',') !== -1) { language = language.substr(0, 2); } else if (languages.indexOf(',' + language + ',') === -1) { return; } } ScriptLoader.ScriptLoader.add(urls[name] + '/langs/' + language + '.js'); } }; var add = function (id, addOn, dependencies) { items.push(addOn); lookup[id] = { instance: addOn, dependencies: dependencies }; var result = partition(_listeners, function (listener) { return listener.name === id; }); _listeners = result.fail; each$7(result.pass, function (listener) { listener.callback(); }); return addOn; }; var remove = function (name) { delete urls[name]; delete lookup[name]; }; var createUrl = function (baseUrl, dep) { if (typeof dep === 'object') { return dep; } return typeof baseUrl === 'string' ? { prefix: '', resource: dep, suffix: '' } : { prefix: baseUrl.prefix, resource: dep, suffix: baseUrl.suffix }; }; var addComponents = function (pluginName, scripts) { var pluginUrl = _this.urls[pluginName]; each$7(scripts, function (script) { ScriptLoader.ScriptLoader.add(pluginUrl + '/' + script); }); }; var loadDependencies = function (name, addOnUrl, success, scope) { var deps = dependencies(name); each$7(deps, function (dep) { var newUrl = createUrl(addOnUrl, dep); load(newUrl.resource, newUrl, undefined, undefined); }); if (success) { if (scope) { success.call(scope); } else { success.call(ScriptLoader); } } }; var load = function (name, addOnUrl, success, scope, failure) { if (urls[name]) { return; } var urlString = typeof addOnUrl === 'string' ? addOnUrl : addOnUrl.prefix + addOnUrl.resource + addOnUrl.suffix; if (urlString.indexOf('/') !== 0 && urlString.indexOf('://') === -1) { urlString = AddOnManager.baseURL + '/' + urlString; } urls[name] = urlString.substring(0, urlString.lastIndexOf('/')); if (lookup[name]) { loadDependencies(name, addOnUrl, success, scope); } else { ScriptLoader.ScriptLoader.add(urlString, function () { return loadDependencies(name, addOnUrl, success, scope); }, scope, failure); } }; var waitFor = function (name, callback) { if (lookup.hasOwnProperty(name)) { callback(); } else { _listeners.push({ name: name, callback: callback }); } }; return { items: items, urls: urls, lookup: lookup, _listeners: _listeners, get: get, dependencies: dependencies, requireLangPack: requireLangPack, add: add, remove: remove, createUrl: createUrl, addComponents: addComponents, load: load, waitFor: waitFor }; } (function (AddOnManager) { AddOnManager.PluginManager = AddOnManager(); AddOnManager.ThemeManager = AddOnManager(); }(AddOnManager || (AddOnManager = {}))); var before = function (marker, element) { var parent$1 = parent(marker); parent$1.each(function (v) { v.dom().insertBefore(element.dom(), marker.dom()); }); }; var after = function (marker, element) { var sibling = nextSibling(marker); sibling.fold(function () { var parent$1 = parent(marker); parent$1.each(function (v) { append(v, element); }); }, function (v) { before(v, element); }); }; var prepend = function (parent, element) { var firstChild$1 = firstChild(parent); firstChild$1.fold(function () { append(parent, element); }, function (v) { parent.dom().insertBefore(element.dom(), v.dom()); }); }; var append = function (parent, element) { parent.dom().appendChild(element.dom()); }; var wrap$1 = function (element, wrapper) { before(element, wrapper); append(wrapper, element); }; var before$1 = function (marker, elements) { each(elements, function (x) { before(marker, x); }); }; var append$1 = function (parent, elements) { each(elements, function (x) { append(parent, x); }); }; var empty = function (element) { element.dom().textContent = ''; each(children(element), function (rogue) { remove$1(rogue); }); }; var remove$1 = function (element) { var dom = element.dom(); if (dom.parentNode !== null) { dom.parentNode.removeChild(dom); } }; var unwrap = function (wrapper) { var children$1 = children(wrapper); if (children$1.length > 0) { before$1(wrapper, children$1); } remove$1(wrapper); }; var first = function (fn, rate) { var timer = null; var cancel = function () { if (timer !== null) { domGlobals.clearTimeout(timer); timer = null; } }; var throttle = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (timer === null) { timer = domGlobals.setTimeout(function () { fn.apply(null, args); timer = null; }, rate); } }; return { cancel: cancel, throttle: throttle }; }; var last$2 = function (fn, rate) { var timer = null; var cancel = function () { if (timer !== null) { domGlobals.clearTimeout(timer); timer = null; } }; var throttle = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (timer !== null) domGlobals.clearTimeout(timer); timer = domGlobals.setTimeout(function () { fn.apply(null, args); timer = null; }, rate); }; return { cancel: cancel, throttle: throttle }; }; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var read = function (element, attr) { var value = get(element, attr); return value === undefined || value === '' ? [] : value.split(' '); }; var add = function (element, attr, id) { var old = read(element, attr); var nu = old.concat([id]); set(element, attr, nu.join(' ')); return true; }; var remove$2 = function (element, attr, id) { var nu = filter(read(element, attr), function (v) { return v !== id; }); if (nu.length > 0) { set(element, attr, nu.join(' ')); } else { remove(element, attr); } return false; }; var supports = function (element) { return element.dom().classList !== undefined; }; var get$2 = function (element) { return read(element, 'class'); }; var add$1 = function (element, clazz) { return add(element, 'class', clazz); }; var remove$3 = function (element, clazz) { return remove$2(element, 'class', clazz); }; var add$2 = function (element, clazz) { if (supports(element)) { element.dom().classList.add(clazz); } else { add$1(element, clazz); } }; var cleanClass = function (element) { var classList = supports(element) ? element.dom().classList : get$2(element); if (classList.length === 0) { remove(element, 'class'); } }; var remove$4 = function (element, clazz) { if (supports(element)) { var classList = element.dom().classList; classList.remove(clazz); } else { remove$3(element, clazz); } cleanClass(element); }; var has$2 = function (element, clazz) { return supports(element) && element.dom().classList.contains(clazz); }; var descendants = function (scope, predicate) { var result = []; each(children(scope), function (x) { if (predicate(x)) { result = result.concat([x]); } result = result.concat(descendants(x, predicate)); }); return result; }; var descendants$1 = function (scope, selector) { return all(selector, scope); }; function ClosestOrAncestor (is, ancestor, scope, a, isRoot) { return is(scope, a) ? Option.some(scope) : isFunction(isRoot) && isRoot(scope) ? Option.none() : ancestor(scope, a, isRoot); } var ancestor = function (scope, predicate, isRoot) { var element = scope.dom(); var stop = isFunction(isRoot) ? isRoot : constant(false); while (element.parentNode) { element = element.parentNode; var el = Element.fromDom(element); if (predicate(el)) { return Option.some(el); } else if (stop(el)) { break; } } return Option.none(); }; var closest = function (scope, predicate, isRoot) { var is = function (s) { return predicate(s); }; return ClosestOrAncestor(is, ancestor, scope, predicate, isRoot); }; var ancestor$1 = function (scope, selector, isRoot) { return ancestor(scope, function (e) { return is$1(e, selector); }, isRoot); }; var descendant = function (scope, selector) { return one(selector, scope); }; var closest$1 = function (scope, selector, isRoot) { return ClosestOrAncestor(is$1, ancestor$1, scope, selector, isRoot); }; var annotation = constant('mce-annotation'); var dataAnnotation = constant('data-mce-annotation'); var dataAnnotationId = constant('data-mce-annotation-uid'); var identify = function (editor, annotationName) { var rng = editor.selection.getRng(); var start = Element.fromDom(rng.startContainer); var root = Element.fromDom(editor.getBody()); var selector = annotationName.fold(function () { return '.' + annotation(); }, function (an) { return '[' + dataAnnotation() + '="' + an + '"]'; }); var newStart = child(start, rng.startOffset).getOr(start); var closest = closest$1(newStart, selector, function (n) { return eq(n, root); }); var getAttr = function (c, property) { if (has$1(c, property)) { return Option.some(get(c, property)); } else { return Option.none(); } }; return closest.bind(function (c) { return getAttr(c, '' + dataAnnotationId()).bind(function (uid) { return getAttr(c, '' + dataAnnotation()).map(function (name) { var elements = findMarkers(editor, uid); return { uid: uid, name: name, elements: elements }; }); }); }); }; var isAnnotation = function (elem) { return isElement(elem) && has$2(elem, annotation()); }; var findMarkers = function (editor, uid) { var body = Element.fromDom(editor.getBody()); return descendants$1(body, '[' + dataAnnotationId() + '="' + uid + '"]'); }; var findAll = function (editor, name) { var body = Element.fromDom(editor.getBody()); var markers = descendants$1(body, '[' + dataAnnotation() + '="' + name + '"]'); var directory = {}; each(markers, function (m) { var uid = get(m, dataAnnotationId()); var nodesAlready = directory.hasOwnProperty(uid) ? directory[uid] : []; directory[uid] = nodesAlready.concat([m]); }); return directory; }; var setup = function (editor, registry) { var changeCallbacks = Cell({}); var initData = function () { return { listeners: [], previous: Cell(Option.none()) }; }; var withCallbacks = function (name, f) { updateCallbacks(name, function (data) { f(data); return data; }); }; var updateCallbacks = function (name, f) { var callbackMap = changeCallbacks.get(); var data = callbackMap.hasOwnProperty(name) ? callbackMap[name] : initData(); var outputData = f(data); callbackMap[name] = outputData; changeCallbacks.set(callbackMap); }; var fireCallbacks = function (name, uid, elements) { withCallbacks(name, function (data) { each(data.listeners, function (f) { return f(true, name, { uid: uid, nodes: map(elements, function (elem) { return elem.dom(); }) }); }); }); }; var fireNoAnnotation = function (name) { withCallbacks(name, function (data) { each(data.listeners, function (f) { return f(false, name); }); }); }; var onNodeChange = last$2(function () { var callbackMap = changeCallbacks.get(); var annotations = sort(keys(callbackMap)); each(annotations, function (name) { updateCallbacks(name, function (data) { var prev = data.previous.get(); identify(editor, Option.some(name)).fold(function () { if (prev.isSome()) { fireNoAnnotation(name); data.previous.set(Option.none()); } }, function (_a) { var uid = _a.uid, name = _a.name, elements = _a.elements; if (!prev.is(uid)) { fireCallbacks(name, uid, elements); data.previous.set(Option.some(uid)); } }); return { previous: data.previous, listeners: data.listeners }; }); }); }, 30); editor.on('remove', function () { onNodeChange.cancel(); }); editor.on('nodeChange', function () { onNodeChange.throttle(); }); var addListener = function (name, f) { updateCallbacks(name, function (data) { return { previous: data.previous, listeners: data.listeners.concat([f]) }; }); }; return { addListener: addListener }; }; var setup$1 = function (editor, registry) { var identifyParserNode = function (span) { var optAnnotation = Option.from(span.attributes.map[dataAnnotation()]); return optAnnotation.bind(registry.lookup); }; editor.on('init', function () { editor.serializer.addNodeFilter('span', function (spans) { each(spans, function (span) { identifyParserNode(span).each(function (settings) { if (settings.persistent === false) { span.unwrap(); } }); }); }); }); }; var create$1 = function () { var annotations = {}; var register = function (name, settings) { annotations[name] = { name: name, settings: settings }; }; var lookup = function (name) { return annotations.hasOwnProperty(name) ? Option.from(annotations[name]).map(function (a) { return a.settings; }) : Option.none(); }; return { register: register, lookup: lookup }; }; function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === 'function') for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) t[p[i]] = s[p[i]]; return t; } var unique = 0; var generate = function (prefix) { var date = new Date(); var time = date.getTime(); var random = Math.floor(Math.random() * 1000000000); unique++; return prefix + '_' + random + unique + String(time); }; var add$3 = function (element, classes) { each(classes, function (x) { add$2(element, x); }); }; var clone = function (original, isDeep) { return Element.fromDom(original.dom().cloneNode(isDeep)); }; var shallow = function (original) { return clone(original, false); }; var deep = function (original) { return clone(original, true); }; var fromHtml$1 = function (html, scope) { var doc = scope || domGlobals.document; var div = doc.createElement('div'); div.innerHTML = html; return children(Element.fromDom(div)); }; var get$3 = function (element) { return element.dom().innerHTML; }; var set$1 = function (element, content) { var owner$1 = owner(element); var docDom = owner$1.dom(); var fragment = Element.fromDom(docDom.createDocumentFragment()); var contentElements = fromHtml$1(content, docDom); append$1(fragment, contentElements); empty(element); append(element, fragment); }; var ZWSP = '\uFEFF'; var isZwsp = function (chr) { return chr === ZWSP; }; var trim$3 = function (text) { return text.replace(new RegExp(ZWSP, 'g'), ''); }; var Zwsp = { isZwsp: isZwsp, ZWSP: ZWSP, trim: trim$3 }; var isElement$2 = NodeType.isElement; var isText$2 = NodeType.isText; var isCaretContainerBlock = function (node) { if (isText$2(node)) { node = node.parentNode; } return isElement$2(node) && node.hasAttribute('data-mce-caret'); }; var isCaretContainerInline = function (node) { return isText$2(node) && Zwsp.isZwsp(node.data); }; var isCaretContainer = function (node) { return isCaretContainerBlock(node) || isCaretContainerInline(node); }; var hasContent = function (node) { return node.firstChild !== node.lastChild || !NodeType.isBr(node.firstChild); }; var insertInline = function (node, before) { var doc, sibling, textNode, parentNode; doc = node.ownerDocument; textNode = doc.createTextNode(Zwsp.ZWSP); parentNode = node.parentNode; if (!before) { sibling = node.nextSibling; if (isText$2(sibling)) { if (isCaretContainer(sibling)) { return sibling; } if (startsWithCaretContainer(sibling)) { sibling.splitText(1); return sibling; } } if (node.nextSibling) { parentNode.insertBefore(textNode, node.nextSibling); } else { parentNode.appendChild(textNode); } } else { sibling = node.previousSibling; if (isText$2(sibling)) { if (isCaretContainer(sibling)) { return sibling; } if (endsWithCaretContainer(sibling)) { return sibling.splitText(sibling.data.length - 1); } } parentNode.insertBefore(textNode, node); } return textNode; }; var isBeforeInline = function (pos) { var container = pos.container(); if (!pos || !NodeType.isText(container)) { return false; } return container.data.charAt(pos.offset()) === Zwsp.ZWSP || pos.isAtStart() && isCaretContainerInline(container.previousSibling); }; var isAfterInline = function (pos) { var container = pos.container(); if (!pos || !NodeType.isText(container)) { return false; } return container.data.charAt(pos.offset() - 1) === Zwsp.ZWSP || pos.isAtEnd() && isCaretContainerInline(container.nextSibling); }; var createBogusBr = function () { var br = domGlobals.document.createElement('br'); br.setAttribute('data-mce-bogus', '1'); return br; }; var insertBlock = function (blockName, node, before) { var doc, blockNode, parentNode; doc = node.ownerDocument; blockNode = doc.createElement(blockName); blockNode.setAttribute('data-mce-caret', before ? 'before' : 'after'); blockNode.setAttribute('data-mce-bogus', 'all'); blockNode.appendChild(createBogusBr()); parentNode = node.parentNode; if (!before) { if (node.nextSibling) { parentNode.insertBefore(blockNode, node.nextSibling); } else { parentNode.appendChild(blockNode); } } else { parentNode.insertBefore(blockNode, node); } return blockNode; }; var startsWithCaretContainer = function (node) { return isText$2(node) && node.data[0] === Zwsp.ZWSP; }; var endsWithCaretContainer = function (node) { return isText$2(node) && node.data[node.data.length - 1] === Zwsp.ZWSP; }; var trimBogusBr = function (elm) { var brs = elm.getElementsByTagName('br'); var lastBr = brs[brs.length - 1]; if (NodeType.isBogus(lastBr)) { lastBr.parentNode.removeChild(lastBr); } }; var showCaretContainerBlock = function (caretContainer) { if (caretContainer && caretContainer.hasAttribute('data-mce-caret')) { trimBogusBr(caretContainer); caretContainer.removeAttribute('data-mce-caret'); caretContainer.removeAttribute('data-mce-bogus'); caretContainer.removeAttribute('style'); caretContainer.removeAttribute('_moz_abspos'); return caretContainer; } return null; }; var isRangeInCaretContainerBlock = function (range) { return isCaretContainerBlock(range.startContainer); }; var isContentEditableTrue$1 = NodeType.isContentEditableTrue; var isContentEditableFalse$1 = NodeType.isContentEditableFalse; var isBr$2 = NodeType.isBr; var isText$3 = NodeType.isText; var isInvalidTextElement = NodeType.matchNodeNames('script style textarea'); var isAtomicInline = NodeType.matchNodeNames('img input textarea hr iframe video audio object'); var isTable$1 = NodeType.matchNodeNames('table'); var isCaretContainer$1 = isCaretContainer; var isCaretCandidate = function (node) { if (isCaretContainer$1(node)) { return false; } if (isText$3(node)) { if (isInvalidTextElement(node.parentNode)) { return false; } return true; } return isAtomicInline(node) || isBr$2(node) || isTable$1(node) || isNonUiContentEditableFalse(node); }; var isUnselectable = function (node) { return NodeType.isElement(node) && node.getAttribute('unselectable') === 'true'; }; var isNonUiContentEditableFalse = function (node) { return isUnselectable(node) === false && isContentEditableFalse$1(node); }; var isInEditable = function (node, root) { for (node = node.parentNode; node && node !== root; node = node.parentNode) { if (isNonUiContentEditableFalse(node)) { return false; } if (isContentEditableTrue$1(node)) { return true; } } return true; }; var isAtomicContentEditableFalse = function (node) { if (!isNonUiContentEditableFalse(node)) { return false; } return foldl(from$1(node.getElementsByTagName('*')), function (result, elm) { return result || isContentEditableTrue$1(elm); }, false) !== true; }; var isAtomic = function (node) { return isAtomicInline(node) || isAtomicContentEditableFalse(node); }; var isEditableCaretCandidate = function (node, root) { return isCaretCandidate(node) && isInEditable(node, root); }; var round = Math.round; var clone$1 = function (rect) { if (!rect) { return { left: 0, top: 0, bottom: 0, right: 0, width: 0, height: 0 }; } return { left: round(rect.left), top: round(rect.top), bottom: round(rect.bottom), right: round(rect.right), width: round(rect.width), height: round(rect.height) }; }; var collapse = function (rect, toStart) { rect = clone$1(rect); if (toStart) { rect.right = rect.left; } else { rect.left = rect.left + rect.width; rect.right = rect.left; } rect.width = 0; return rect; }; var isEqual = function (rect1, rect2) { return rect1.left === rect2.left && rect1.top === rect2.top && rect1.bottom === rect2.bottom && rect1.right === rect2.right; }; var isValidOverflow = function (overflowY, rect1, rect2) { return overflowY >= 0 && overflowY <= Math.min(rect1.height, rect2.height) / 2; }; var isAbove = function (rect1, rect2) { if (rect1.bottom - rect1.height / 2 < rect2.top) { return true; } if (rect1.top > rect2.bottom) { return false; } return isValidOverflow(rect2.top - rect1.bottom, rect1, rect2); }; var isBelow = function (rect1, rect2) { if (rect1.top > rect2.bottom) { return true; } if (rect1.bottom < rect2.top) { return false; } return isValidOverflow(rect2.bottom - rect1.top, rect1, rect2); }; var containsXY = function (rect, clientX, clientY) { return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom; }; var overflowX = function (outer, inner) { if (inner.left > outer.left && inner.right < outer.right) { return 0; } else { return inner.left < outer.left ? inner.left - outer.left : inner.right - outer.right; } }; var overflowY = function (outer, inner) { if (inner.top > outer.top && inner.bottom < outer.bottom) { return 0; } else { return inner.top < outer.top ? inner.top - outer.top : inner.bottom - outer.bottom; } }; var getOverflow = function (outer, inner) { return { x: overflowX(outer, inner), y: overflowY(outer, inner) }; }; var getSelectedNode = function (range) { var startContainer = range.startContainer, startOffset = range.startOffset; if (startContainer.hasChildNodes() && range.endOffset === startOffset + 1) { return startContainer.childNodes[startOffset]; } return null; }; var getNode = function (container, offset) { if (container.nodeType === 1 && container.hasChildNodes()) { if (offset >= container.childNodes.length) { offset = container.childNodes.length - 1; } container = container.childNodes[offset]; } return container; }; var extendingChars = new RegExp('[\u0300-\u036f\u0483-\u0487\u0488-\u0489\u0591-\u05bd\u05bf\u05c1-\u05c2\u05c4-\u05c5\u05c7\u0610-\u061a' + '\u064b-\u065f\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7-\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0' + '\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08E3-\u0902\u093a\u093c' + '\u0941-\u0948\u094d\u0951-\u0957\u0962-\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2-\u09e3' + '\u0a01-\u0a02\u0a3c\u0a41-\u0a42\u0a47-\u0a48\u0a4b-\u0a4d\u0a51\u0a70-\u0a71\u0a75\u0a81-\u0a82\u0abc' + '\u0ac1-\u0ac5\u0ac7-\u0ac8\u0acd\u0ae2-\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57' + '\u0b62-\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c00\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55-\u0c56' + '\u0c62-\u0c63\u0c81\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc-\u0ccd\u0cd5-\u0cd6\u0ce2-\u0ce3\u0d01\u0d3e\u0d41-\u0d44' + '\u0d4d\u0d57\u0d62-\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9' + '\u0ebb-\u0ebc\u0ec8-\u0ecd\u0f18-\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86-\u0f87\u0f8d-\u0f97' + '\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039-\u103a\u103d-\u103e\u1058-\u1059\u105e-\u1060\u1071-\u1074' + '\u1082\u1085-\u1086\u108d\u109d\u135d-\u135f\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17b4-\u17b5' + '\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927-\u1928\u1932\u1939-\u193b\u1a17-\u1a18' + '\u1a1b\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1ab0-\u1abd\u1ABE\u1b00-\u1b03\u1b34' + '\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80-\u1b81\u1ba2-\u1ba5\u1ba8-\u1ba9\u1bab-\u1bad\u1be6\u1be8-\u1be9' + '\u1bed\u1bef-\u1bf1\u1c2c-\u1c33\u1c36-\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1cf4\u1cf8-\u1cf9' + '\u1dc0-\u1df5\u1dfc-\u1dff\u200c-\u200d\u20d0-\u20dc\u20DD-\u20E0\u20e1\u20E2-\u20E4\u20e5-\u20f0\u2cef-\u2cf1' + '\u2d7f\u2de0-\u2dff\u302a-\u302d\u302e-\u302f\u3099-\u309a\ua66f\uA670-\uA672\ua674-\ua67d\uA69E-\ua69f\ua6f0-\ua6f1' + '\ua802\ua806\ua80b\ua825-\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc' + '\ua9e5\uaa29-\uaa2e\uaa31-\uaa32\uaa35-\uaa36\uaa43\uaa4c\uaa7c\uaab0\uaab2-\uaab4\uaab7-\uaab8\uaabe-\uaabf\uaac1' + '\uaaec-\uaaed\uaaf6\uabe5\uabe8\uabed\ufb1e\ufe00-\ufe0f\ufe20-\uFE2F\uff9e-\uff9f]'); var isExtendingChar = function (ch) { return typeof ch === 'string' && ch.charCodeAt(0) >= 768 && extendingChars.test(ch); }; var liftN = function (arr, f) { var r = []; for (var i = 0; i < arr.length; i++) { var x = arr[i]; if (x.isSome()) { r.push(x.getOrDie()); } else { return Option.none(); } } return Option.some(f.apply(null, r)); }; var slice$3 = [].slice; var or = function () { var x = []; for (var _i = 0; _i < arguments.length; _i++) { x[_i] = arguments[_i]; } var args = slice$3.call(arguments); return function (x) { for (var i = 0; i < args.length; i++) { if (args[i](x)) { return true; } } return false; }; }; var and = function () { var x = []; for (var _i = 0; _i < arguments.length; _i++) { x[_i] = arguments[_i]; } var args = slice$3.call(arguments); return function (x) { for (var i = 0; i < args.length; i++) { if (!args[i](x)) { return false; } } return true; }; }; var Predicate = { and: and, or: or }; var isElement$3 = NodeType.isElement; var isCaretCandidate$1 = isCaretCandidate; var isBlock$1 = NodeType.matchStyleValues('display', 'block table'); var isFloated = NodeType.matchStyleValues('float', 'left right'); var isValidElementCaretCandidate = Predicate.and(isElement$3, isCaretCandidate$1, not(isFloated)); var isNotPre = not(NodeType.matchStyleValues('white-space', 'pre pre-line pre-wrap')); var isText$4 = NodeType.isText; var isBr$3 = NodeType.isBr; var nodeIndex = DOMUtils$1.nodeIndex; var resolveIndex = getNode; var createRange = function (doc) { return 'createRange' in doc ? doc.createRange() : DOMUtils$1.DOM.createRng(); }; var isWhiteSpace = function (chr) { return chr && /[\r\n\t ]/.test(chr); }; var isRange = function (rng) { return !!rng.setStart && !!rng.setEnd; }; var isHiddenWhiteSpaceRange = function (range) { var container = range.startContainer; var offset = range.startOffset; var text; if (isWhiteSpace(range.toString()) && isNotPre(container.parentNode) && NodeType.isText(container)) { text = container.data; if (isWhiteSpace(text[offset - 1]) || isWhiteSpace(text[offset + 1])) { return true; } } return false; }; var getBrClientRect = function (brNode) { var doc = brNode.ownerDocument; var rng = createRange(doc); var nbsp = doc.createTextNode('\xA0'); var parentNode = brNode.parentNode; var clientRect; parentNode.insertBefore(nbsp, brNode); rng.setStart(nbsp, 0); rng.setEnd(nbsp, 1); clientRect = clone$1(rng.getBoundingClientRect()); parentNode.removeChild(nbsp); return clientRect; }; var getBoundingClientRectWebKitText = function (rng) { var sc = rng.startContainer; var ec = rng.endContainer; var so = rng.startOffset; var eo = rng.endOffset; if (sc === ec && NodeType.isText(ec) && so === 0 && eo === 1) { var newRng = rng.cloneRange(); newRng.setEndAfter(ec); return getBoundingClientRect(newRng); } else { return null; } }; var isZeroRect = function (r) { return r.left === 0 && r.right === 0 && r.top === 0 && r.bottom === 0; }; var getBoundingClientRect = function (item) { var clientRect, clientRects; clientRects = item.getClientRects(); if (clientRects.length > 0) { clientRect = clone$1(clientRects[0]); } else { clientRect = clone$1(item.getBoundingClientRect()); } if (!isRange(item) && isBr$3(item) && isZeroRect(clientRect)) { return getBrClientRect(item); } if (isZeroRect(clientRect) && isRange(item)) { return getBoundingClientRectWebKitText(item); } return clientRect; }; var collapseAndInflateWidth = function (clientRect, toStart) { var newClientRect = collapse(clientRect, toStart); newClientRect.width = 1; newClientRect.right = newClientRect.left + 1; return newClientRect; }; var getCaretPositionClientRects = function (caretPosition) { var clientRects = []; var beforeNode, node; var addUniqueAndValidRect = function (clientRect) { if (clientRect.height === 0) { return; } if (clientRects.length > 0) { if (isEqual(clientRect, clientRects[clientRects.length - 1])) { return; } } clientRects.push(clientRect); }; var addCharacterOffset = function (container, offset) { var range = createRange(container.ownerDocument); if (offset < container.data.length) { if (isExtendingChar(container.data[offset])) { return clientRects; } if (isExtendingChar(container.data[offset - 1])) { range.setStart(container, offset); range.setEnd(container, offset + 1); if (!isHiddenWhiteSpaceRange(range)) { addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), false)); return clientRects; } } } if (offset > 0) { range.setStart(container, offset - 1); range.setEnd(container, offset); if (!isHiddenWhiteSpaceRange(range)) { addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), false)); } } if (offset < container.data.length) { range.setStart(container, offset); range.setEnd(container, offset + 1); if (!isHiddenWhiteSpaceRange(range)) { addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), true)); } } }; if (isText$4(caretPosition.container())) { addCharacterOffset(caretPosition.container(), caretPosition.offset()); return clientRects; } if (isElement$3(caretPosition.container())) { if (caretPosition.isAtEnd()) { node = resolveIndex(caretPosition.container(), caretPosition.offset()); if (isText$4(node)) { addCharacterOffset(node, node.data.length); } if (isValidElementCaretCandidate(node) && !isBr$3(node)) { addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), false)); } } else { node = resolveIndex(caretPosition.container(), caretPosition.offset()); if (isText$4(node)) { addCharacterOffset(node, 0); } if (isValidElementCaretCandidate(node) && caretPosition.isAtEnd()) { addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), false)); return clientRects; } beforeNode = resolveIndex(caretPosition.container(), caretPosition.offset() - 1); if (isValidElementCaretCandidate(beforeNode) && !isBr$3(beforeNode)) { if (isBlock$1(beforeNode) || isBlock$1(node) || !isValidElementCaretCandidate(node)) { addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(beforeNode), false)); } } if (isValidElementCaretCandidate(node)) { addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), true)); } } } return clientRects; }; function CaretPosition(container, offset, clientRects) { var isAtStart = function () { if (isText$4(container)) { return offset === 0; } return offset === 0; }; var isAtEnd = function () { if (isText$4(container)) { return offset >= container.data.length; } return offset >= container.childNodes.length; }; var toRange = function () { var range; range = createRange(container.ownerDocument); range.setStart(container, offset); range.setEnd(container, offset); return range; }; var getClientRects = function () { if (!clientRects) { clientRects = getCaretPositionClientRects(CaretPosition(container, offset)); } return clientRects; }; var isVisible = function () { return getClientRects().length > 0; }; var isEqual = function (caretPosition) { return caretPosition && container === caretPosition.container() && offset === caretPosition.offset(); }; var getNode = function (before) { return resolveIndex(container, before ? offset - 1 : offset); }; return { container: constant(container), offset: constant(offset), toRange: toRange, getClientRects: getClientRects, isVisible: isVisible, isAtStart: isAtStart, isAtEnd: isAtEnd, isEqual: isEqual, getNode: getNode }; } (function (CaretPosition) { CaretPosition.fromRangeStart = function (range) { return CaretPosition(range.startContainer, range.startOffset); }; CaretPosition.fromRangeEnd = function (range) { return CaretPosition(range.endContainer, range.endOffset); }; CaretPosition.after = function (node) { return CaretPosition(node.parentNode, nodeIndex(node) + 1); }; CaretPosition.before = function (node) { return CaretPosition(node.parentNode, nodeIndex(node)); }; CaretPosition.isAbove = function (pos1, pos2) { return liftN([ head(pos2.getClientRects()), last(pos1.getClientRects()) ], isAbove).getOr(false); }; CaretPosition.isBelow = function (pos1, pos2) { return liftN([ last(pos2.getClientRects()), head(pos1.getClientRects()) ], isBelow).getOr(false); }; CaretPosition.isAtStart = function (pos) { return pos ? pos.isAtStart() : false; }; CaretPosition.isAtEnd = function (pos) { return pos ? pos.isAtEnd() : false; }; CaretPosition.isTextPosition = function (pos) { return pos ? NodeType.isText(pos.container()) : false; }; CaretPosition.isElementPosition = function (pos) { return CaretPosition.isTextPosition(pos) === false; }; }(CaretPosition || (CaretPosition = {}))); var CaretPosition$1 = CaretPosition; var isText$5 = NodeType.isText; var isBogus$1 = NodeType.isBogus; var nodeIndex$1 = DOMUtils$1.nodeIndex; var normalizedParent = function (node) { var parentNode = node.parentNode; if (isBogus$1(parentNode)) { return normalizedParent(parentNode); } return parentNode; }; var getChildNodes = function (node) { if (!node) { return []; } return ArrUtils.reduce(node.childNodes, function (result, node) { if (isBogus$1(node) && node.nodeName !== 'BR') { result = result.concat(getChildNodes(node)); } else { result.push(node); } return result; }, []); }; var normalizedTextOffset = function (node, offset) { while (node = node.previousSibling) { if (!isText$5(node)) { break; } offset += node.data.length; } return offset; }; var equal = function (a) { return function (b) { return a === b; }; }; var normalizedNodeIndex = function (node) { var nodes, index, numTextFragments; nodes = getChildNodes(normalizedParent(node)); index = ArrUtils.findIndex(nodes, equal(node), node); nodes = nodes.slice(0, index + 1); numTextFragments = ArrUtils.reduce(nodes, function (result, node, i) { if (isText$5(node) && isText$5(nodes[i - 1])) { result++; } return result; }, 0); nodes = ArrUtils.filter(nodes, NodeType.matchNodeNames(node.nodeName)); index = ArrUtils.findIndex(nodes, equal(node), node); return index - numTextFragments; }; var createPathItem = function (node) { var name; if (isText$5(node)) { name = 'text()'; } else { name = node.nodeName.toLowerCase(); } return name + '[' + normalizedNodeIndex(node) + ']'; }; var parentsUntil = function (root, node, predicate) { var parents = []; for (node = node.parentNode; node !== root; node = node.parentNode) { if (predicate && predicate(node)) { break; } parents.push(node); } return parents; }; var create$2 = function (root, caretPosition) { var container, offset, path = [], outputOffset, childNodes, parents; container = caretPosition.container(); offset = caretPosition.offset(); if (isText$5(container)) { outputOffset = normalizedTextOffset(container, offset); } else { childNodes = container.childNodes; if (offset >= childNodes.length) { outputOffset = 'after'; offset = childNodes.length - 1; } else { outputOffset = 'before'; } container = childNodes[offset]; } path.push(createPathItem(container)); parents = parentsUntil(root, container); parents = ArrUtils.filter(parents, not(NodeType.isBogus)); path = path.concat(ArrUtils.map(parents, function (node) { return createPathItem(node); })); return path.reverse().join('/') + ',' + outputOffset; }; var resolvePathItem = function (node, name, index) { var nodes = getChildNodes(node); nodes = ArrUtils.filter(nodes, function (node, index) { return !isText$5(node) || !isText$5(nodes[index - 1]); }); nodes = ArrUtils.filter(nodes, NodeType.matchNodeNames(name)); return nodes[index]; }; var findTextPosition = function (container, offset) { var node = container, targetOffset = 0, dataLen; while (isText$5(node)) { dataLen = node.data.length; if (offset >= targetOffset && offset <= targetOffset + dataLen) { container = node; offset = offset - targetOffset; break; } if (!isText$5(node.nextSibling)) { container = node; offset = dataLen; break; } targetOffset += dataLen; node = node.nextSibling; } if (isText$5(container) && offset > container.data.length) { offset = container.data.length; } return CaretPosition$1(container, offset); }; var resolve$2 = function (root, path) { var parts, container, offset; if (!path) { return null; } parts = path.split(','); path = parts[0].split('/'); offset = parts.length > 1 ? parts[1] : 'before'; container = ArrUtils.reduce(path, function (result, value) { value = /([\w\-\(\)]+)\[([0-9]+)\]/.exec(value); if (!value) { return null; } if (value[1] === 'text()') { value[1] = '#text'; } return resolvePathItem(result, value[1], parseInt(value[2], 10)); }, root); if (!container) { return null; } if (!isText$5(container)) { if (offset === 'after') { offset = nodeIndex$1(container) + 1; } else { offset = nodeIndex$1(container); } return CaretPosition$1(container.parentNode, offset); } return findTextPosition(container, parseInt(offset, 10)); }; var trimEmptyTextNode = function (dom, node) { if (NodeType.isText(node) && node.data.length === 0) { dom.remove(node); } }; var insertNode = function (dom, rng, node) { rng.insertNode(node); trimEmptyTextNode(dom, node.previousSibling); trimEmptyTextNode(dom, node.nextSibling); }; var insertFragment = function (dom, rng, frag) { var firstChild = Option.from(frag.firstChild); var lastChild = Option.from(frag.lastChild); rng.insertNode(frag); firstChild.each(function (child) { return trimEmptyTextNode(dom, child.previousSibling); }); lastChild.each(function (child) { return trimEmptyTextNode(dom, child.nextSibling); }); }; var rangeInsertNode = function (dom, rng, node) { if (NodeType.isDocumentFragment(node)) { insertFragment(dom, rng, node); } else { insertNode(dom, rng, node); } }; var isContentEditableFalse$2 = NodeType.isContentEditableFalse; var getNormalizedTextOffset = function (trim, container, offset) { var node, trimmedOffset; trimmedOffset = trim(container.data.slice(0, offset)).length; for (node = container.previousSibling; node && NodeType.isText(node); node = node.previousSibling) { trimmedOffset += trim(node.data).length; } return trimmedOffset; }; var getPoint = function (dom, trim, normalized, rng, start) { var container = rng[start ? 'startContainer' : 'endContainer']; var offset = rng[start ? 'startOffset' : 'endOffset']; var point = []; var childNodes, after = 0; var root = dom.getRoot(); if (NodeType.isText(container)) { point.push(normalized ? getNormalizedTextOffset(trim, container, offset) : offset); } else { childNodes = container.childNodes; if (offset >= childNodes.length && childNodes.length) { after = 1; offset = Math.max(0, childNodes.length - 1); } point.push(dom.nodeIndex(childNodes[offset], normalized) + after); } for (; container && container !== root; container = container.parentNode) { point.push(dom.nodeIndex(container, normalized)); } return point; }; var getLocation = function (trim, selection, normalized, rng) { var dom = selection.dom, bookmark = {}; bookmark.start = getPoint(dom, trim, normalized, rng, true); if (!selection.isCollapsed()) { bookmark.end = getPoint(dom, trim, normalized, rng, false); } return bookmark; }; var findIndex$2 = function (dom, name, element) { var count = 0; Tools.each(dom.select(name), function (node) { if (node.getAttribute('data-mce-bogus') === 'all') { return; } if (node === element) { return false; } count++; }); return count; }; var moveEndPoint = function (rng, start) { var container, offset, childNodes; var prefix = start ? 'start' : 'end'; container = rng[prefix + 'Container']; offset = rng[prefix + 'Offset']; if (NodeType.isElement(container) && container.nodeName === 'TR') { childNodes = container.childNodes; container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)]; if (container) { offset = start ? 0 : container.childNodes.length; rng['set' + (start ? 'Start' : 'End')](container, offset); } } }; var normalizeTableCellSelection = function (rng) { moveEndPoint(rng, true); moveEndPoint(rng, false); return rng; }; var findSibling = function (node, offset) { var sibling; if (NodeType.isElement(node)) { node = getNode(node, offset); if (isContentEditableFalse$2(node)) { return node; } } if (isCaretContainer(node)) { if (NodeType.isText(node) && isCaretContainerBlock(node)) { node = node.parentNode; } sibling = node.previousSibling; if (isContentEditableFalse$2(sibling)) { return sibling; } sibling = node.nextSibling; if (isContentEditableFalse$2(sibling)) { return sibling; } } }; var findAdjacentContentEditableFalseElm = function (rng) { return findSibling(rng.startContainer, rng.startOffset) || findSibling(rng.endContainer, rng.endOffset); }; var getOffsetBookmark = function (trim, normalized, selection) { var element = selection.getNode(); var name = element ? element.nodeName : null; var rng = selection.getRng(); if (isContentEditableFalse$2(element) || name === 'IMG') { return { name: name, index: findIndex$2(selection.dom, name, element) }; } var sibling = findAdjacentContentEditableFalseElm(rng); if (sibling) { name = sibling.tagName; return { name: name, index: findIndex$2(selection.dom, name, sibling) }; } return getLocation(trim, selection, normalized, rng); }; var getCaretBookmark = function (selection) { var rng = selection.getRng(); return { start: create$2(selection.dom.getRoot(), CaretPosition$1.fromRangeStart(rng)), end: create$2(selection.dom.getRoot(), CaretPosition$1.fromRangeEnd(rng)) }; }; var getRangeBookmark = function (selection) { return { rng: selection.getRng() }; }; var createBookmarkSpan = function (dom, id, filled) { var args = { 'data-mce-type': 'bookmark', 'id': id, 'style': 'overflow:hidden;line-height:0px' }; return filled ? dom.create('span', args, '') : dom.create('span', args); }; var getPersistentBookmark = function (selection, filled) { var dom = selection.dom; var rng = selection.getRng(); var id = dom.uniqueId(); var collapsed = selection.isCollapsed(); var element = selection.getNode(); var name = element.nodeName; if (name === 'IMG') { return { name: name, index: findIndex$2(dom, name, element) }; } var rng2 = normalizeTableCellSelection(rng.cloneRange()); if (!collapsed) { rng2.collapse(false); var endBookmarkNode = createBookmarkSpan(dom, id + '_end', filled); rangeInsertNode(dom, rng2, endBookmarkNode); } rng = normalizeTableCellSelection(rng); rng.collapse(true); var startBookmarkNode = createBookmarkSpan(dom, id + '_start', filled); rangeInsertNode(dom, rng, startBookmarkNode); selection.moveToBookmark({ id: id, keep: 1 }); return { id: id }; }; var getBookmark = function (selection, type, normalized) { if (type === 2) { return getOffsetBookmark(Zwsp.trim, normalized, selection); } else if (type === 3) { return getCaretBookmark(selection); } else if (type) { return getRangeBookmark(selection); } else { return getPersistentBookmark(selection, false); } }; var GetBookmark = { getBookmark: getBookmark, getUndoBookmark: curry(getOffsetBookmark, identity, true), getPersistentBookmark: getPersistentBookmark }; var CARET_ID = '_mce_caret'; var isCaretNode = function (node) { return NodeType.isElement(node) && node.id === CARET_ID; }; var getParentCaretContainer = function (body, node) { while (node && node !== body) { if (node.id === CARET_ID) { return node; } node = node.parentNode; } return null; }; var isElement$4 = NodeType.isElement; var isText$6 = NodeType.isText; var removeNode = function (node) { var parentNode = node.parentNode; if (parentNode) { parentNode.removeChild(node); } }; var getNodeValue = function (node) { try { return node.nodeValue; } catch (ex) { return ''; } }; var setNodeValue = function (node, text) { if (text.length === 0) { removeNode(node); } else { node.nodeValue = text; } }; var trimCount = function (text) { var trimmedText = Zwsp.trim(text); return { count: text.length - trimmedText.length, text: trimmedText }; }; var removeUnchanged = function (caretContainer, pos) { remove$5(caretContainer); return pos; }; var removeTextAndReposition = function (caretContainer, pos) { var before = trimCount(caretContainer.data.substr(0, pos.offset())); var after = trimCount(caretContainer.data.substr(pos.offset())); var text = before.text + after.text; if (text.length > 0) { setNodeValue(caretContainer, text); return CaretPosition$1(caretContainer, pos.offset() - before.count); } else { return pos; } }; var removeElementAndReposition = function (caretContainer, pos) { var parentNode = pos.container(); var newPosition = indexOf(from$1(parentNode.childNodes), caretContainer).map(function (index) { return index < pos.offset() ? CaretPosition$1(parentNode, pos.offset() - 1) : pos; }).getOr(pos); remove$5(caretContainer); return newPosition; }; var removeTextCaretContainer = function (caretContainer, pos) { return isText$6(caretContainer) && pos.container() === caretContainer ? removeTextAndReposition(caretContainer, pos) : removeUnchanged(caretContainer, pos); }; var removeElementCaretContainer = function (caretContainer, pos) { return pos.container() === caretContainer.parentNode ? removeElementAndReposition(caretContainer, pos) : removeUnchanged(caretContainer, pos); }; var removeAndReposition = function (container, pos) { return CaretPosition$1.isTextPosition(pos) ? removeTextCaretContainer(container, pos) : removeElementCaretContainer(container, pos); }; var remove$5 = function (caretContainerNode) { if (isElement$4(caretContainerNode) && isCaretContainer(caretContainerNode)) { if (hasContent(caretContainerNode)) { caretContainerNode.removeAttribute('data-mce-caret'); } else { removeNode(caretContainerNode); } } if (isText$6(caretContainerNode)) { var text = Zwsp.trim(getNodeValue(caretContainerNode)); setNodeValue(caretContainerNode, text); } }; var CaretContainerRemove = { removeAndReposition: removeAndReposition, remove: remove$5 }; var browser$2 = PlatformDetection$1.detect().browser; var isContentEditableFalse$3 = NodeType.isContentEditableFalse; var isTableCell$1 = function (node) { return NodeType.isElement(node) && /^(TD|TH)$/i.test(node.tagName); }; var getAbsoluteClientRect = function (root, element, before) { var clientRect = collapse(element.getBoundingClientRect(), before); var docElm, scrollX, scrollY, margin, rootRect; if (root.tagName === 'BODY') { docElm = root.ownerDocument.documentElement; scrollX = root.scrollLeft || docElm.scrollLeft; scrollY = root.scrollTop || docElm.scrollTop; } else { rootRect = root.getBoundingClientRect(); scrollX = root.scrollLeft - rootRect.left; scrollY = root.scrollTop - rootRect.top; } clientRect.left += scrollX; clientRect.right += scrollX; clientRect.top += scrollY; clientRect.bottom += scrollY; clientRect.width = 1; margin = element.offsetWidth - element.clientWidth; if (margin > 0) { if (before) { margin *= -1; } clientRect.left += margin; clientRect.right += margin; } return clientRect; }; var trimInlineCaretContainers = function (root) { var contentEditableFalseNodes, node, sibling, i, data; contentEditableFalseNodes = DomQuery('*[contentEditable=false]', root); for (i = 0; i < contentEditableFalseNodes.length; i++) { node = contentEditableFalseNodes[i]; sibling = node.previousSibling; if (endsWithCaretContainer(sibling)) { data = sibling.data; if (data.length === 1) { sibling.parentNode.removeChild(sibling); } else { sibling.deleteData(data.length - 1, 1); } } sibling = node.nextSibling; if (startsWithCaretContainer(sibling)) { data = sibling.data; if (data.length === 1) { sibling.parentNode.removeChild(sibling); } else { sibling.deleteData(0, 1); } } } }; var FakeCaret = function (root, isBlock, hasFocus) { var lastVisualCaret = Cell(Option.none()); var cursorInterval, caretContainerNode; var show = function (before, element) { var clientRect, rng; hide(); if (isTableCell$1(element)) { return null; } if (isBlock(element)) { caretContainerNode = insertBlock('p', element, before); clientRect = getAbsoluteClientRect(root, element, before); DomQuery(caretContainerNode).css('top', clientRect.top); var caret = DomQuery('<div class="mce-visual-caret" data-mce-bogus="all"></div>').css(clientRect).appendTo(root)[0]; lastVisualCaret.set(Option.some({ caret: caret, element: element, before: before })); lastVisualCaret.get().each(function (caretState) { if (before) { DomQuery(caretState.caret).addClass('mce-visual-caret-before'); } }); startBlink(); rng = element.ownerDocument.createRange(); rng.setStart(caretContainerNode, 0); rng.setEnd(caretContainerNode, 0); } else { caretContainerNode = insertInline(element, before); rng = element.ownerDocument.createRange(); if (isContentEditableFalse$3(caretContainerNode.nextSibling)) { rng.setStart(caretContainerNode, 0); rng.setEnd(caretContainerNode, 0); } else { rng.setStart(caretContainerNode, 1); rng.setEnd(caretContainerNode, 1); } return rng; } return rng; }; var hide = function () { trimInlineCaretContainers(root); if (caretContainerNode) { CaretContainerRemove.remove(caretContainerNode); caretContainerNode = null; } lastVisualCaret.get().each(function (caretState) { DomQuery(caretState.caret).remove(); lastVisualCaret.set(Option.none()); }); clearInterval(cursorInterval); }; var startBlink = function () { cursorInterval = Delay.setInterval(function () { if (hasFocus()) { DomQuery('div.mce-visual-caret', root).toggleClass('mce-visual-caret-hidden'); } else { DomQuery('div.mce-visual-caret', root).addClass('mce-visual-caret-hidden'); } }, 500); }; var reposition = function () { lastVisualCaret.get().each(function (caretState) { var clientRect = getAbsoluteClientRect(root, caretState.element, caretState.before); DomQuery(caretState.caret).css(clientRect); }); }; var destroy = function () { return Delay.clearInterval(cursorInterval); }; var getCss = function () { return '.mce-visual-caret {' + 'position: absolute;' + 'background-color: black;' + 'background-color: currentcolor;' + '}' + '.mce-visual-caret-hidden {' + 'display: none;' + '}' + '*[data-mce-caret] {' + 'position: absolute;' + 'left: -1000px;' + 'right: auto;' + 'top: 0;' + 'margin: 0;' + 'padding: 0;' + '}'; }; return { show: show, hide: hide, getCss: getCss, reposition: reposition, destroy: destroy }; }; var isFakeCaretTableBrowser = function () { return browser$2.isIE() || browser$2.isEdge() || browser$2.isFirefox(); }; var isFakeCaretTarget = function (node) { return isContentEditableFalse$3(node) || NodeType.isTable(node) && isFakeCaretTableBrowser(); }; var isContentEditableFalse$4 = NodeType.isContentEditableFalse; var isBlockLike = NodeType.matchStyleValues('display', 'block table table-cell table-caption list-item'); var isCaretContainer$2 = isCaretContainer; var isCaretContainerBlock$1 = isCaretContainerBlock; var isElement$5 = NodeType.isElement; var isCaretCandidate$2 = isCaretCandidate; var isForwards = function (direction) { return direction > 0; }; var isBackwards = function (direction) { return direction < 0; }; var skipCaretContainers = function (walk, shallow) { var node; while (node = walk(shallow)) { if (!isCaretContainerBlock$1(node)) { return node; } } return null; }; var findNode = function (node, direction, predicateFn, rootNode, shallow) { var walker = new TreeWalker(node, rootNode); if (isBackwards(direction)) { if (isContentEditableFalse$4(node) || isCaretContainerBlock$1(node)) { node = skipCaretContainers(walker.prev, true); if (predicateFn(node)) { return node; } } while (node = skipCaretContainers(walker.prev, shallow)) { if (predicateFn(node)) { return node; } } } if (isForwards(direction)) { if (isContentEditableFalse$4(node) || isCaretContainerBlock$1(node)) { node = skipCaretContainers(walker.next, true); if (predicateFn(node)) { return node; } } while (node = skipCaretContainers(walker.next, shallow)) { if (predicateFn(node)) { return node; } } } return null; }; var getParentBlock = function (node, rootNode) { while (node && node !== rootNode) { if (isBlockLike(node)) { return node; } node = node.parentNode; } return null; }; var isInSameBlock = function (caretPosition1, caretPosition2, rootNode) { return getParentBlock(caretPosition1.container(), rootNode) === getParentBlock(caretPosition2.container(), rootNode); }; var getChildNodeAtRelativeOffset = function (relativeOffset, caretPosition) { var container, offset; if (!caretPosition) { return null; } container = caretPosition.container(); offset = caretPosition.offset(); if (!isElement$5(container)) { return null; } return container.childNodes[offset + relativeOffset]; }; var beforeAfter = function (before, node) { var range = node.ownerDocument.createRange(); if (before) { range.setStartBefore(node); range.setEndBefore(node); } else { range.setStartAfter(node); range.setEndAfter(node); } return range; }; var isNodesInSameBlock = function (root, node1, node2) { return getParentBlock(node1, root) === getParentBlock(node2, root); }; var lean = function (left, root, node) { var sibling, siblingName; if (left) { siblingName = 'previousSibling'; } else { siblingName = 'nextSibling'; } while (node && node !== root) { sibling = node[siblingName]; if (isCaretContainer$2(sibling)) { sibling = sibling[siblingName]; } if (isContentEditableFalse$4(sibling)) { if (isNodesInSameBlock(root, sibling, node)) { return sibling; } break; } if (isCaretCandidate$2(sibling)) { break; } node = node.parentNode; } return null; }; var before$2 = curry(beforeAfter, true); var after$1 = curry(beforeAfter, false); var normalizeRange = function (direction, root, range) { var node, container, offset, location; var leanLeft = curry(lean, true, root); var leanRight = curry(lean, false, root); container = range.startContainer; offset = range.startOffset; if (isCaretContainerBlock(container)) { if (!isElement$5(container)) { container = container.parentNode; } location = container.getAttribute('data-mce-caret'); if (location === 'before') { node = container.nextSibling; if (isFakeCaretTarget(node)) { return before$2(node); } } if (location === 'after') { node = container.previousSibling; if (isFakeCaretTarget(node)) { return after$1(node); } } } if (!range.collapsed) { return range; } if (NodeType.isText(container)) { if (isCaretContainer$2(container)) { if (direction === 1) { node = leanRight(container); if (node) { return before$2(node); } node = leanLeft(container); if (node) { return after$1(node); } } if (direction === -1) { node = leanLeft(container); if (node) { return after$1(node); } node = leanRight(container); if (node) { return before$2(node); } } return range; } if (endsWithCaretContainer(container) && offset >= container.data.length - 1) { if (direction === 1) { node = leanRight(container); if (node) { return before$2(node); } } return range; } if (startsWithCaretContainer(container) && offset <= 1) { if (direction === -1) { node = leanLeft(container); if (node) { return after$1(node); } } return range; } if (offset === container.data.length) { node = leanRight(container); if (node) { return before$2(node); } return range; } if (offset === 0) { node = leanLeft(container); if (node) { return after$1(node); } return range; } } return range; }; var getRelativeCefElm = function (forward, caretPosition) { return Option.from(getChildNodeAtRelativeOffset(forward ? 0 : -1, caretPosition)).filter(isContentEditableFalse$4); }; var getNormalizedRangeEndPoint = function (direction, root, range) { var normalizedRange = normalizeRange(direction, root, range); if (direction === -1) { return CaretPosition.fromRangeStart(normalizedRange); } return CaretPosition.fromRangeEnd(normalizedRange); }; var getElementFromPosition = function (pos) { return Option.from(pos.getNode()).map(Element.fromDom); }; var getElementFromPrevPosition = function (pos) { return Option.from(pos.getNode(true)).map(Element.fromDom); }; var getVisualCaretPosition = function (walkFn, caretPosition) { while (caretPosition = walkFn(caretPosition)) { if (caretPosition.isVisible()) { return caretPosition; } } return caretPosition; }; var isMoveInsideSameBlock = function (from, to) { var inSameBlock = isInSameBlock(from, to); if (!inSameBlock && NodeType.isBr(from.getNode())) { return true; } return inSameBlock; }; var HDirection; (function (HDirection) { HDirection[HDirection['Backwards'] = -1] = 'Backwards'; HDirection[HDirection['Forwards'] = 1] = 'Forwards'; }(HDirection || (HDirection = {}))); var isContentEditableFalse$5 = NodeType.isContentEditableFalse; var isText$7 = NodeType.isText; var isElement$6 = NodeType.isElement; var isBr$4 = NodeType.isBr; var isCaretCandidate$3 = isCaretCandidate; var isAtomic$1 = isAtomic; var isEditableCaretCandidate$1 = isEditableCaretCandidate; var getParents = function (node, root) { var parents = []; while (node && node !== root) { parents.push(node); node = node.parentNode; } return parents; }; var nodeAtIndex = function (container, offset) { if (container.hasChildNodes() && offset < container.childNodes.length) { return container.childNodes[offset]; } return null; }; var getCaretCandidatePosition = function (direction, node) { if (isForwards(direction)) { if (isCaretCandidate$3(node.previousSibling) && !isText$7(node.previousSibling)) { return CaretPosition$1.before(node); } if (isText$7(node)) { return CaretPosition$1(node, 0); } } if (isBackwards(direction)) { if (isCaretCandidate$3(node.nextSibling) && !isText$7(node.nextSibling)) { return CaretPosition$1.after(node); } if (isText$7(node)) { return CaretPosition$1(node, node.data.length); } } if (isBackwards(direction)) { if (isBr$4(node)) { return CaretPosition$1.before(node); } return CaretPosition$1.after(node); } return CaretPosition$1.before(node); }; var moveForwardFromBr = function (root, nextNode) { var nextSibling = nextNode.nextSibling; if (nextSibling && isCaretCandidate$3(nextSibling)) { if (isText$7(nextSibling)) { return CaretPosition$1(nextSibling, 0); } else { return CaretPosition$1.before(nextSibling); } } else { return findCaretPosition(HDirection.Forwards, CaretPosition$1.after(nextNode), root); } }; var findCaretPosition = function (direction, startPos, root) { var node, nextNode, innerNode; var rootContentEditableFalseElm, caretPosition; if (!isElement$6(root) || !startPos) { return null; } if (startPos.isEqual(CaretPosition$1.after(root)) && root.lastChild) { caretPosition = CaretPosition$1.after(root.lastChild); if (isBackwards(direction) && isCaretCandidate$3(root.lastChild) && isElement$6(root.lastChild)) { return isBr$4(root.lastChild) ? CaretPosition$1.before(root.lastChild) : caretPosition; } } else { caretPosition = startPos; } var container = caretPosition.container(); var offset = caretPosition.offset(); if (isText$7(container)) { if (isBackwards(direction) && offset > 0) { return CaretPosition$1(container, --offset); } if (isForwards(direction) && offset < container.length) { return CaretPosition$1(container, ++offset); } node = container; } else { if (isBackwards(direction) && offset > 0) { nextNode = nodeAtIndex(container, offset - 1); if (isCaretCandidate$3(nextNode)) { if (!isAtomic$1(nextNode)) { innerNode = findNode(nextNode, direction, isEditableCaretCandidate$1, nextNode); if (innerNode) { if (isText$7(innerNode)) { return CaretPosition$1(innerNode, innerNode.data.length); } return CaretPosition$1.after(innerNode); } } if (isText$7(nextNode)) { return CaretPosition$1(nextNode, nextNode.data.length); } return CaretPosition$1.before(nextNode); } } if (isForwards(direction) && offset < container.childNodes.length) { nextNode = nodeAtIndex(container, offset); if (isCaretCandidate$3(nextNode)) { if (isBr$4(nextNode)) { return moveForwardFromBr(root, nextNode); } if (!isAtomic$1(nextNode)) { innerNode = findNode(nextNode, direction, isEditableCaretCandidate$1, nextNode); if (innerNode) { if (isText$7(innerNode)) { return CaretPosition$1(innerNode, 0); } return CaretPosition$1.before(innerNode); } } if (isText$7(nextNode)) { return CaretPosition$1(nextNode, 0); } return CaretPosition$1.after(nextNode); } } node = nextNode ? nextNode : caretPosition.getNode(); } if (isForwards(direction) && caretPosition.isAtEnd() || isBackwards(direction) && caretPosition.isAtStart()) { node = findNode(node, direction, constant(true), root, true); if (isEditableCaretCandidate$1(node, root)) { return getCaretCandidatePosition(direction, node); } } nextNode = findNode(node, direction, isEditableCaretCandidate$1, root); rootContentEditableFalseElm = ArrUtils.last(filter(getParents(container, root), isContentEditableFalse$5)); if (rootContentEditableFalseElm && (!nextNode || !rootContentEditableFalseElm.contains(nextNode))) { if (isForwards(direction)) { caretPosition = CaretPosition$1.after(rootContentEditableFalseElm); } else { caretPosition = CaretPosition$1.before(rootContentEditableFalseElm); } return caretPosition; } if (nextNode) { return getCaretCandidatePosition(direction, nextNode); } return null; }; var CaretWalker = function (root) { return { next: function (caretPosition) { return findCaretPosition(HDirection.Forwards, caretPosition, root); }, prev: function (caretPosition) { return findCaretPosition(HDirection.Backwards, caretPosition, root); } }; }; var walkToPositionIn = function (forward, root, start) { var position = forward ? CaretPosition$1.before(start) : CaretPosition$1.after(start); return fromPosition(forward, root, position); }; var afterElement = function (node) { return NodeType.isBr(node) ? CaretPosition$1.before(node) : CaretPosition$1.after(node); }; var isBeforeOrStart = function (position) { if (CaretPosition$1.isTextPosition(position)) { return position.offset() === 0; } else { return isCaretCandidate(position.getNode()); } }; var isAfterOrEnd = function (position) { if (CaretPosition$1.isTextPosition(position)) { var container = position.container(); return position.offset() === container.data.length; } else { return isCaretCandidate(position.getNode(true)); } }; var isBeforeAfterSameElement = function (from, to) { return !CaretPosition$1.isTextPosition(from) && !CaretPosition$1.isTextPosition(to) && from.getNode() === to.getNode(true); }; var isAtBr = function (position) { return !CaretPosition$1.isTextPosition(position) && NodeType.isBr(position.getNode()); }; var shouldSkipPosition = function (forward, from, to) { if (forward) { return !isBeforeAfterSameElement(from, to) && !isAtBr(from) && isAfterOrEnd(from) && isBeforeOrStart(to); } else { return !isBeforeAfterSameElement(to, from) && isBeforeOrStart(from) && isAfterOrEnd(to); } }; var fromPosition = function (forward, root, pos) { var walker = CaretWalker(root); return Option.from(forward ? walker.next(pos) : walker.prev(pos)); }; var navigate = function (forward, root, from) { return fromPosition(forward, root, from).bind(function (to) { if (isInSameBlock(from, to, root) && shouldSkipPosition(forward, from, to)) { return fromPosition(forward, root, to); } else { return Option.some(to); } }); }; var navigateIgnore = function (forward, root, from, ignoreFilter) { return navigate(forward, root, from).bind(function (pos) { return ignoreFilter(pos) ? navigateIgnore(forward, root, pos, ignoreFilter) : Option.some(pos); }); }; var positionIn = function (forward, element) { var startNode = forward ? element.firstChild : element.lastChild; if (NodeType.isText(startNode)) { return Option.some(CaretPosition$1(startNode, forward ? 0 : startNode.data.length)); } else if (startNode) { if (isCaretCandidate(startNode)) { return Option.some(forward ? CaretPosition$1.before(startNode) : afterElement(startNode)); } else { return walkToPositionIn(forward, element, startNode); } } else { return Option.none(); } }; var nextPosition = curry(fromPosition, true); var prevPosition = curry(fromPosition, false); var CaretFinder = { fromPosition: fromPosition, nextPosition: nextPosition, prevPosition: prevPosition, navigate: navigate, navigateIgnore: navigateIgnore, positionIn: positionIn, firstPositionIn: curry(positionIn, true), lastPositionIn: curry(positionIn, false) }; var isStringPathBookmark = function (bookmark) { return typeof bookmark.start === 'string'; }; var isRangeBookmark = function (bookmark) { return bookmark.hasOwnProperty('rng'); }; var isIdBookmark = function (bookmark) { return bookmark.hasOwnProperty('id'); }; var isIndexBookmark = function (bookmark) { return bookmark.hasOwnProperty('name'); }; var isPathBookmark = function (bookmark) { return Tools.isArray(bookmark.start); }; var addBogus = function (dom, node) { if (dom.isBlock(node) && !node.innerHTML && !Env.ie) { node.innerHTML = '<br data-mce-bogus="1" />'; } return node; }; var resolveCaretPositionBookmark = function (dom, bookmark) { var rng, pos; rng = dom.createRng(); pos = resolve$2(dom.getRoot(), bookmark.start); rng.setStart(pos.container(), pos.offset()); pos = resolve$2(dom.getRoot(), bookmark.end); rng.setEnd(pos.container(), pos.offset()); return rng; }; var insertZwsp = function (node, rng) { var textNode = node.ownerDocument.createTextNode(Zwsp.ZWSP); node.appendChild(textNode); rng.setStart(textNode, 0); rng.setEnd(textNode, 0); }; var isEmpty = function (node) { return node.hasChildNodes() === false; }; var tryFindRangePosition = function (node, rng) { return CaretFinder.lastPositionIn(node).fold(function () { return false; }, function (pos) { rng.setStart(pos.container(), pos.offset()); rng.setEnd(pos.container(), pos.offset()); return true; }); }; var padEmptyCaretContainer = function (root, node, rng) { if (isEmpty(node) && getParentCaretContainer(root, node)) { insertZwsp(node, rng); return true; } else { return false; } }; var setEndPoint = function (dom, start, bookmark, rng) { var point = bookmark[start ? 'start' : 'end']; var i, node, offset, children; var root = dom.getRoot(); if (point) { offset = point[0]; for (node = root, i = point.length - 1; i >= 1; i--) { children = node.childNodes; if (padEmptyCaretContainer(root, node, rng)) { return true; } if (point[i] > children.length - 1) { if (padEmptyCaretContainer(root, node, rng)) { return true; } return tryFindRangePosition(node, rng); } node = children[point[i]]; } if (node.nodeType === 3) { offset = Math.min(point[0], node.nodeValue.length); } if (node.nodeType === 1) { offset = Math.min(point[0], node.childNodes.length); } if (start) { rng.setStart(node, offset); } else { rng.setEnd(node, offset); } } return true; }; var isValidTextNode = function (node) { return NodeType.isText(node) && node.data.length > 0; }; var restoreEndPoint = function (dom, suffix, bookmark) { var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev; var keep = bookmark.keep; var container, offset; if (marker) { node = marker.parentNode; if (suffix === 'start') { if (!keep) { idx = dom.nodeIndex(marker); } else { if (marker.hasChildNodes()) { node = marker.firstChild; idx = 1; } else if (isValidTextNode(marker.nextSibling)) { node = marker.nextSibling; idx = 0; } else if (isValidTextNode(marker.previousSibling)) { node = marker.previousSibling; idx = marker.previousSibling.data.length; } else { node = marker.parentNode; idx = dom.nodeIndex(marker) + 1; } } container = node; offset = idx; } else { if (!keep) { idx = dom.nodeIndex(marker); } else { if (marker.hasChildNodes()) { node = marker.firstChild; idx = 1; } else if (isValidTextNode(marker.previousSibling)) { node = marker.previousSibling; idx = marker.previousSibling.data.length; } else { node = marker.parentNode; idx = dom.nodeIndex(marker); } } container = node; offset = idx; } if (!keep) { prev = marker.previousSibling; next = marker.nextSibling; Tools.each(Tools.grep(marker.childNodes), function (node) { if (NodeType.isText(node)) { node.nodeValue = node.nodeValue.replace(/\uFEFF/g, ''); } }); while (marker = dom.get(bookmark.id + '_' + suffix)) { dom.remove(marker, true); } if (prev && next && prev.nodeType === next.nodeType && NodeType.isText(prev) && !Env.opera) { idx = prev.nodeValue.length; prev.appendData(next.nodeValue); dom.remove(next); if (suffix === 'start') { container = prev; offset = idx; } else { container = prev; offset = idx; } } } return Option.some(CaretPosition$1(container, offset)); } else { return Option.none(); } }; var alt = function (o1, o2) { return o1.isSome() ? o1 : o2; }; var resolvePaths = function (dom, bookmark) { var rng = dom.createRng(); if (setEndPoint(dom, true, bookmark, rng) && setEndPoint(dom, false, bookmark, rng)) { return Option.some(rng); } else { return Option.none(); } }; var resolveId = function (dom, bookmark) { var startPos = restoreEndPoint(dom, 'start', bookmark); var endPos = restoreEndPoint(dom, 'end', bookmark); return liftN([ startPos, alt(endPos, startPos) ], function (spos, epos) { var rng = dom.createRng(); rng.setStart(addBogus(dom, spos.container()), spos.offset()); rng.setEnd(addBogus(dom, epos.container()), epos.offset()); return rng; }); }; var resolveIndex$1 = function (dom, bookmark) { return Option.from(dom.select(bookmark.name)[bookmark.index]).map(function (elm) { var rng = dom.createRng(); rng.selectNode(elm); return rng; }); }; var resolve$3 = function (selection, bookmark) { var dom = selection.dom; if (bookmark) { if (isPathBookmark(bookmark)) { return resolvePaths(dom, bookmark); } else if (isStringPathBookmark(bookmark)) { return Option.some(resolveCaretPositionBookmark(dom, bookmark)); } else if (isIdBookmark(bookmark)) { return resolveId(dom, bookmark); } else if (isIndexBookmark(bookmark)) { return resolveIndex$1(dom, bookmark); } else if (isRangeBookmark(bookmark)) { return Option.some(bookmark.rng); } } return Option.none(); }; var ResolveBookmark = { resolve: resolve$3 }; var getBookmark$1 = function (selection, type, normalized) { return GetBookmark.getBookmark(selection, type, normalized); }; var moveToBookmark = function (selection, bookmark) { ResolveBookmark.resolve(selection, bookmark).each(function (rng) { selection.setRng(rng); }); }; var isBookmarkNode$1 = function (node) { return NodeType.isElement(node) && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark'; }; var Bookmarks = { getBookmark: getBookmark$1, moveToBookmark: moveToBookmark, isBookmarkNode: isBookmarkNode$1 }; var isInlineBlock = function (node) { return node && /^(IMG)$/.test(node.nodeName); }; var moveStart = function (dom, selection, rng) { var offset = rng.startOffset; var container = rng.startContainer, walker, node, nodes; if (rng.startContainer === rng.endContainer) { if (isInlineBlock(rng.startContainer.childNodes[rng.startOffset])) { return; } } if (container.nodeType === 1) { nodes = container.childNodes; if (offset < nodes.length) { container = nodes[offset]; walker = new TreeWalker(container, dom.getParent(container, dom.isBlock)); } else { container = nodes[nodes.length - 1]; walker = new TreeWalker(container, dom.getParent(container, dom.isBlock)); walker.next(true); } for (node = walker.current(); node; node = walker.next()) { if (node.nodeType === 3 && !isWhiteSpaceNode(node)) { rng.setStart(node, 0); selection.setRng(rng); return; } } } }; var getNonWhiteSpaceSibling = function (node, next, inc) { if (node) { next = next ? 'nextSibling' : 'previousSibling'; for (node = inc ? node : node[next]; node; node = node[next]) { if (node.nodeType === 1 || !isWhiteSpaceNode(node)) { return node; } } } }; var isTextBlock$1 = function (editor, name) { if (name.nodeType) { name = name.nodeName; } return !!editor.schema.getTextBlockElements()[name.toLowerCase()]; }; var isValid = function (ed, parent, child) { return ed.schema.isValidChild(parent, child); }; var isWhiteSpaceNode = function (node) { return node && node.nodeType === 3 && /^([\t \r\n]+|)$/.test(node.nodeValue); }; var replaceVars = function (value, vars) { if (typeof value !== 'string') { value = value(vars); } else if (vars) { value = value.replace(/%(\w+)/g, function (str, name) { return vars[name] || str; }); } return value; }; var isEq = function (str1, str2) { str1 = str1 || ''; str2 = str2 || ''; str1 = '' + (str1.nodeName || str1); str2 = '' + (str2.nodeName || str2); return str1.toLowerCase() === str2.toLowerCase(); }; var normalizeStyleValue = function (dom, value, name) { if (name === 'color' || name === 'backgroundColor') { value = dom.toHex(value); } if (name === 'fontWeight' && value === 700) { value = 'bold'; } if (name === 'fontFamily') { value = value.replace(/[\'\"]/g, '').replace(/,\s+/g, ','); } return '' + value; }; var getStyle = function (dom, node, name) { return normalizeStyleValue(dom, dom.getStyle(node, name), name); }; var getTextDecoration = function (dom, node) { var decoration; dom.getParent(node, function (n) { decoration = dom.getStyle(n, 'text-decoration'); return decoration && decoration !== 'none'; }); return decoration; }; var getParents$1 = function (dom, node, selector) { return dom.getParents(node, selector, dom.getRoot()); }; var FormatUtils = { isInlineBlock: isInlineBlock, moveStart: moveStart, getNonWhiteSpaceSibling: getNonWhiteSpaceSibling, isTextBlock: isTextBlock$1, isValid: isValid, isWhiteSpaceNode: isWhiteSpaceNode, replaceVars: replaceVars, isEq: isEq, normalizeStyleValue: normalizeStyleValue, getStyle: getStyle, getTextDecoration: getTextDecoration, getParents: getParents$1 }; var isBookmarkNode$2 = Bookmarks.isBookmarkNode; var getParents$2 = FormatUtils.getParents, isWhiteSpaceNode$1 = FormatUtils.isWhiteSpaceNode, isTextBlock$2 = FormatUtils.isTextBlock; var findLeaf = function (node, offset) { if (typeof offset === 'undefined') { offset = node.nodeType === 3 ? node.length : node.childNodes.length; } while (node && node.hasChildNodes()) { node = node.childNodes[offset]; if (node) { offset = node.nodeType === 3 ? node.length : node.childNodes.length; } } return { node: node, offset: offset }; }; var excludeTrailingWhitespace = function (endContainer, endOffset) { var leaf = findLeaf(endContainer, endOffset); if (leaf.node) { while (leaf.node && leaf.offset === 0 && leaf.node.previousSibling) { leaf = findLeaf(leaf.node.previousSibling); } if (leaf.node && leaf.offset > 0 && leaf.node.nodeType === 3 && leaf.node.nodeValue.charAt(leaf.offset - 1) === ' ') { if (leaf.offset > 1) { endContainer = leaf.node; endContainer.splitText(leaf.offset - 1); } } } return endContainer; }; var isBogusBr = function (node) { return node.nodeName === 'BR' && node.getAttribute('data-mce-bogus') && !node.nextSibling; }; var findParentContentEditable = function (dom, node) { var parent = node; while (parent) { if (parent.nodeType === 1 && dom.getContentEditable(parent)) { return dom.getContentEditable(parent) === 'false' ? parent : node; } parent = parent.parentNode; } return node; }; var findSpace = function (start, remove, node, offset) { var pos, pos2; var str = node.nodeValue; if (typeof offset === 'undefined') { offset = start ? str.length : 0; } if (start) { pos = str.lastIndexOf(' ', offset); pos2 = str.lastIndexOf('\xA0', offset); pos = pos > pos2 ? pos : pos2; if (pos !== -1 && !remove && (pos < offset || !start) && pos <= str.length) { pos++; } } else { pos = str.indexOf(' ', offset); pos2 = str.indexOf('\xA0', offset); pos = pos !== -1 && (pos2 === -1 || pos < pos2) ? pos : pos2; } return pos; }; var findWordEndPoint = function (dom, body, container, offset, start, remove) { var walker, node, pos, lastTextNode; if (container.nodeType === 3) { pos = findSpace(start, remove, container, offset); if (pos !== -1) { return { container: container, offset: pos }; } lastTextNode = container; } walker = new TreeWalker(container, dom.getParent(container, dom.isBlock) || body); while (node = walker[start ? 'prev' : 'next']()) { if (node.nodeType === 3 && !isBookmarkNode$2(node.parentNode)) { lastTextNode = node; pos = findSpace(start, remove, node); if (pos !== -1) { return { container: node, offset: pos }; } } else if (dom.isBlock(node) || FormatUtils.isEq(node, 'BR')) { break; } } if (lastTextNode) { if (start) { offset = 0; } else { offset = lastTextNode.length; } return { container: lastTextNode, offset: offset }; } }; var findSelectorEndPoint = function (dom, format, rng, container, siblingName) { var parents, i, y, curFormat; if (container.nodeType === 3 && container.nodeValue.length === 0 && container[siblingName]) { container = container[siblingName]; } parents = getParents$2(dom, container); for (i = 0; i < parents.length; i++) { for (y = 0; y < format.length; y++) { curFormat = format[y]; if ('collapsed' in curFormat && curFormat.collapsed !== rng.collapsed) { continue; } if (dom.is(parents[i], curFormat.selector)) { return parents[i]; } } } return container; }; var findBlockEndPoint = function (editor, format, container, siblingName) { var node; var dom = editor.dom; var root = dom.getRoot(); if (!format[0].wrapper) { node = dom.getParent(container, format[0].block, root); } if (!node) { var scopeRoot = dom.getParent(container, 'LI,TD,TH'); node = dom.getParent(container.nodeType === 3 ? container.parentNode : container, function (node) { return node !== root && isTextBlock$2(editor, node); }, scopeRoot); } if (node && format[0].wrapper) { node = getParents$2(dom, node, 'ul,ol').reverse()[0] || node; } if (!node) { node = container; while (node[siblingName] && !dom.isBlock(node[siblingName])) { node = node[siblingName]; if (FormatUtils.isEq(node, 'br')) { break; } } } return node || container; }; var findParentContainer = function (dom, format, startContainer, startOffset, endContainer, endOffset, start) { var container, parent, sibling, siblingName, root; container = parent = start ? startContainer : endContainer; siblingName = start ? 'previousSibling' : 'nextSibling'; root = dom.getRoot(); if (container.nodeType === 3 && !isWhiteSpaceNode$1(container)) { if (start ? startOffset > 0 : endOffset < container.nodeValue.length) { return container; } } while (true) { if (!format[0].block_expand && dom.isBlock(parent)) { return parent; } for (sibling = parent[siblingName]; sibling; sibling = sibling[siblingName]) { if (!isBookmarkNode$2(sibling) && !isWhiteSpaceNode$1(sibling) && !isBogusBr(sibling)) { return parent; } } if (parent === root || parent.parentNode === root) { container = parent; break; } parent = parent.parentNode; } return container; }; var expandRng = function (editor, rng, format, remove) { var endPoint, startContainer = rng.startContainer, startOffset = rng.startOffset, endContainer = rng.endContainer, endOffset = rng.endOffset; var dom = editor.dom; if (startContainer.nodeType === 1 && startContainer.hasChildNodes()) { startContainer = getNode(startContainer, startOffset); if (startContainer.nodeType === 3) { startOffset = 0; } } if (endContainer.nodeType === 1 && endContainer.hasChildNodes()) { endContainer = getNode(endContainer, rng.collapsed ? endOffset : endOffset - 1); if (endContainer.nodeType === 3) { endOffset = endContainer.nodeValue.length; } } startContainer = findParentContentEditable(dom, startContainer); endContainer = findParentContentEditable(dom, endContainer); if (isBookmarkNode$2(startContainer.parentNode) || isBookmarkNode$2(startContainer)) { startContainer = isBookmarkNode$2(startContainer) ? startContainer : startContainer.parentNode; if (rng.collapsed) { startContainer = startContainer.previousSibling || startContainer; } else { startContainer = startContainer.nextSibling || startContainer; } if (startContainer.nodeType === 3) { startOffset = rng.collapsed ? startContainer.length : 0; } } if (isBookmarkNode$2(endContainer.parentNode) || isBookmarkNode$2(endContainer)) { endContainer = isBookmarkNode$2(endContainer) ? endContainer : endContainer.parentNode; if (rng.collapsed) { endContainer = endContainer.nextSibling || endContainer; } else { endContainer = endContainer.previousSibling || endContainer; } if (endContainer.nodeType === 3) { endOffset = rng.collapsed ? 0 : endContainer.length; } } if (rng.collapsed) { endPoint = findWordEndPoint(dom, editor.getBody(), startContainer, startOffset, true, remove); if (endPoint) { startContainer = endPoint.container; startOffset = endPoint.offset; } endPoint = findWordEndPoint(dom, editor.getBody(), endContainer, endOffset, false, remove); if (endPoint) { endContainer = endPoint.container; endOffset = endPoint.offset; } } if (format[0].inline) { endContainer = remove ? endContainer : excludeTrailingWhitespace(endContainer, endOffset); } if (format[0].inline || format[0].block_expand) { if (!format[0].inline || (startContainer.nodeType !== 3 || startOffset === 0)) { startContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, true); } if (!format[0].inline || (endContainer.nodeType !== 3 || endOffset === endContainer.nodeValue.length)) { endContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, false); } } if (format[0].selector && format[0].expand !== false && !format[0].inline) { startContainer = findSelectorEndPoint(dom, format, rng, startContainer, 'previousSibling'); endContainer = findSelectorEndPoint(dom, format, rng, endContainer, 'nextSibling'); } if (format[0].block || format[0].selector) { startContainer = findBlockEndPoint(editor, format, startContainer, 'previousSibling'); endContainer = findBlockEndPoint(editor, format, endContainer, 'nextSibling'); if (format[0].block) { if (!dom.isBlock(startContainer)) { startContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, true); } if (!dom.isBlock(endContainer)) { endContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, false); } } } if (startContainer.nodeType === 1) { startOffset = dom.nodeIndex(startContainer); startContainer = startContainer.parentNode; } if (endContainer.nodeType === 1) { endOffset = dom.nodeIndex(endContainer) + 1; endContainer = endContainer.parentNode; } return { startContainer: startContainer, startOffset: startOffset, endContainer: endContainer, endOffset: endOffset }; }; var ExpandRange = { expandRng: expandRng }; var each$8 = Tools.each; var getEndChild = function (container, index) { var childNodes = container.childNodes; index--; if (index > childNodes.length - 1) { index = childNodes.length - 1; } else if (index < 0) { index = 0; } return childNodes[index] || container; }; var walk$1 = function (dom, rng, callback) { var startContainer = rng.startContainer; var startOffset = rng.startOffset; var endContainer = rng.endContainer; var endOffset = rng.endOffset; var ancestor; var startPoint; var endPoint; var node; var parent; var siblings; var nodes; nodes = dom.select('td[data-mce-selected],th[data-mce-selected]'); if (nodes.length > 0) { each$8(nodes, function (node) { callback([node]); }); return; } var exclude = function (nodes) { var node; node = nodes[0]; if (node.nodeType === 3 && node === startContainer && startOffset >= node.nodeValue.length) { nodes.splice(0, 1); } node = nodes[nodes.length - 1]; if (endOffset === 0 && nodes.length > 0 && node === endContainer && node.nodeType === 3) { nodes.splice(nodes.length - 1, 1); } return nodes; }; var collectSiblings = function (node, name, endNode) { var siblings = []; for (; node && node !== endNode; node = node[name]) { siblings.push(node); } return siblings; }; var findEndPoint = function (node, root) { do { if (node.parentNode === root) { return node; } node = node.parentNode; } while (node); }; var walkBoundary = function (startNode, endNode, next) { var siblingName = next ? 'nextSibling' : 'previousSibling'; for (node = startNode, parent = node.parentNode; node && node !== endNode; node = parent) { parent = node.parentNode; siblings = collectSiblings(node === startNode ? node : node[siblingName], siblingName); if (siblings.length) { if (!next) { siblings.reverse(); } callback(exclude(siblings)); } } }; if (startContainer.nodeType === 1 && startContainer.hasChildNodes()) { startContainer = startContainer.childNodes[startOffset]; } if (endContainer.nodeType === 1 && endContainer.hasChildNodes()) { endContainer = getEndChild(endContainer, endOffset); } if (startContainer === endContainer) { return callback(exclude([startContainer])); } ancestor = dom.findCommonAncestor(startContainer, endContainer); for (node = startContainer; node; node = node.parentNode) { if (node === endContainer) { return walkBoundary(startContainer, ancestor, true); } if (node === ancestor) { break; } } for (node = endContainer; node; node = node.parentNode) { if (node === startContainer) { return walkBoundary(endContainer, ancestor); } if (node === ancestor) { break; } } startPoint = findEndPoint(startContainer, ancestor) || startContainer; endPoint = findEndPoint(endContainer, ancestor) || endContainer; walkBoundary(startContainer, startPoint, true); siblings = collectSiblings(startPoint === startContainer ? startPoint : startPoint.nextSibling, 'nextSibling', endPoint === endContainer ? endPoint.nextSibling : endPoint); if (siblings.length) { callback(exclude(siblings)); } walkBoundary(endContainer, endPoint); }; var RangeWalk = { walk: walk$1 }; var zeroWidth = function () { return '\uFEFF'; }; function NodeValue (is, name) { var get = function (element) { if (!is(element)) { throw new Error('Can only get ' + name + ' value of a ' + name + ' node'); } return getOption(element).getOr(''); }; var getOptionIE10 = function (element) { try { return getOptionSafe(element); } catch (e) { return Option.none(); } }; var getOptionSafe = function (element) { return is(element) ? Option.from(element.dom().nodeValue) : Option.none(); }; var browser = PlatformDetection$1.detect().browser; var getOption = browser.isIE() && browser.version.major === 10 ? getOptionIE10 : getOptionSafe; var set = function (element, value) { if (!is(element)) { throw new Error('Can only set raw ' + name + ' value of a ' + name + ' node'); } element.dom().nodeValue = value; }; return { get: get, getOption: getOption, set: set }; } var api = NodeValue(isText, 'text'); var get$4 = function (element) { return api.get(element); }; var isZeroWidth = function (elem) { return isText(elem) && get$4(elem) === zeroWidth(); }; var context = function (editor, elem, wrapName, nodeName) { return parent(elem).fold(function () { return 'skipping'; }, function (parent) { if (nodeName === 'br' || isZeroWidth(elem)) { return 'valid'; } else if (isAnnotation(elem)) { return 'existing'; } else if (isCaretNode(elem)) { return 'caret'; } else if (!FormatUtils.isValid(editor, wrapName, nodeName) || !FormatUtils.isValid(editor, name(parent), wrapName)) { return 'invalid-child'; } else { return 'valid'; } }); }; var shouldApplyToTrailingSpaces = function (rng) { return rng.startContainer.nodeType === 3 && rng.startContainer.nodeValue.length >= rng.startOffset && rng.startContainer.nodeValue[rng.startOffset] === '\xA0'; }; var applyWordGrab = function (editor, rng) { var r = ExpandRange.expandRng(editor, rng, [{ inline: true }], shouldApplyToTrailingSpaces(rng)); rng.setStart(r.startContainer, r.startOffset); rng.setEnd(r.endContainer, r.endOffset); editor.selection.setRng(rng); }; var makeAnnotation = function (eDoc, _a, annotationName, decorate) { var _b = _a.uid, uid = _b === void 0 ? generate('mce-annotation') : _b, data = __rest(_a, ['uid']); var master = Element.fromTag('span', eDoc); add$2(master, annotation()); set(master, '' + dataAnnotationId(), uid); set(master, '' + dataAnnotation(), annotationName); var _c = decorate(uid, data), _d = _c.attributes, attributes = _d === void 0 ? {} : _d, _e = _c.classes, classes = _e === void 0 ? [] : _e; setAll(master, attributes); add$3(master, classes); return master; }; var annotate = function (editor, rng, annotationName, decorate, data) { var newWrappers = []; var master = makeAnnotation(editor.getDoc(), data, annotationName, decorate); var wrapper = Cell(Option.none()); var finishWrapper = function () { wrapper.set(Option.none()); }; var getOrOpenWrapper = function () { return wrapper.get().getOrThunk(function () { var nu = shallow(master); newWrappers.push(nu); wrapper.set(Option.some(nu)); return nu; }); }; var processElements = function (elems) { each(elems, processElement); }; var processElement = function (elem) { var ctx = context(editor, elem, 'span', name(elem)); switch (ctx) { case 'invalid-child': { finishWrapper(); var children$1 = children(elem); processElements(children$1); finishWrapper(); break; } case 'valid': { var w = getOrOpenWrapper(); wrap$1(elem, w); break; } case 'skipping': case 'existing': case 'caret': } }; var processNodes = function (nodes) { var elems = map(nodes, Element.fromDom); processElements(elems); }; RangeWalk.walk(editor.dom, rng, function (nodes) { finishWrapper(); processNodes(nodes); }); return newWrappers; }; var annotateWithBookmark = function (editor, name, settings, data) { editor.undoManager.transact(function () { var initialRng = editor.selection.getRng(); if (initialRng.collapsed) { applyWordGrab(editor, initialRng); } if (editor.selection.getRng().collapsed) { var wrapper = makeAnnotation(editor.getDoc(), data, name, settings.decorate); set$1(wrapper, '\xA0'); editor.selection.getRng().insertNode(wrapper.dom()); editor.selection.select(wrapper.dom()); } else { var bookmark = GetBookmark.getPersistentBookmark(editor.selection, false); var rng = editor.selection.getRng(); annotate(editor, rng, name, settings.decorate, data); editor.selection.moveToBookmark(bookmark); } }); }; function Annotator (editor) { var registry = create$1(); setup$1(editor, registry); var changes = setup(editor, registry); return { register: function (name, settings) { registry.register(name, settings); }, annotate: function (name, data) { registry.lookup(name).each(function (settings) { annotateWithBookmark(editor, name, settings, data); }); }, annotationChanged: function (name, callback) { changes.addListener(name, callback); }, remove: function (name) { identify(editor, Option.some(name)).each(function (_a) { var elements = _a.elements; each(elements, unwrap); }); }, getAll: function (name) { var directory = findAll(editor, name); return map$2(directory, function (elems) { return map(elems, function (elem) { return elem.dom(); }); }); } }; } var hasOnlyOneChild = function (node) { return node.firstChild && node.firstChild === node.lastChild; }; var isPaddingNode = function (node) { return node.name === 'br' || node.value === '\xA0'; }; var isPaddedEmptyBlock = function (schema, node) { var blockElements = schema.getBlockElements(); return blockElements[node.name] && hasOnlyOneChild(node) && isPaddingNode(node.firstChild); }; var isEmptyFragmentElement = function (schema, node) { var nonEmptyElements = schema.getNonEmptyElements(); return node && (node.isEmpty(nonEmptyElements) || isPaddedEmptyBlock(schema, node)); }; var isListFragment = function (schema, fragment) { var firstChild = fragment.firstChild; var lastChild = fragment.lastChild; if (firstChild && firstChild.name === 'meta') { firstChild = firstChild.next; } if (lastChild && lastChild.attr('id') === 'mce_marker') { lastChild = lastChild.prev; } if (isEmptyFragmentElement(schema, lastChild)) { lastChild = lastChild.prev; } if (!firstChild || firstChild !== lastChild) { return false; } return firstChild.name === 'ul' || firstChild.name === 'ol'; }; var cleanupDomFragment = function (domFragment) { var firstChild = domFragment.firstChild; var lastChild = domFragment.lastChild; if (firstChild && firstChild.nodeName === 'META') { firstChild.parentNode.removeChild(firstChild); } if (lastChild && lastChild.id === 'mce_marker') { lastChild.parentNode.removeChild(lastChild); } return domFragment; }; var toDomFragment = function (dom, serializer, fragment) { var html = serializer.serialize(fragment); var domFragment = dom.createFragment(html); return cleanupDomFragment(domFragment); }; var listItems$1 = function (elm) { return Tools.grep(elm.childNodes, function (child) { return child.nodeName === 'LI'; }); }; var isPadding = function (node) { return node.data === '\xA0' || NodeType.isBr(node); }; var isListItemPadded = function (node) { return node && node.firstChild && node.firstChild === node.lastChild && isPadding(node.firstChild); }; var isEmptyOrPadded = function (elm) { return !elm.firstChild || isListItemPadded(elm); }; var trimListItems = function (elms) { return elms.length > 0 && isEmptyOrPadded(elms[elms.length - 1]) ? elms.slice(0, -1) : elms; }; var getParentLi = function (dom, node) { var parentBlock = dom.getParent(node, dom.isBlock); return parentBlock && parentBlock.nodeName === 'LI' ? parentBlock : null; }; var isParentBlockLi = function (dom, node) { return !!getParentLi(dom, node); }; var getSplit = function (parentNode, rng) { var beforeRng = rng.cloneRange(); var afterRng = rng.cloneRange(); beforeRng.setStartBefore(parentNode); afterRng.setEndAfter(parentNode); return [ beforeRng.cloneContents(), afterRng.cloneContents() ]; }; var findFirstIn = function (node, rootNode) { var caretPos = CaretPosition$1.before(node); var caretWalker = CaretWalker(rootNode); var newCaretPos = caretWalker.next(caretPos); return newCaretPos ? newCaretPos.toRange() : null; }; var findLastOf = function (node, rootNode) { var caretPos = CaretPosition$1.after(node); var caretWalker = CaretWalker(rootNode); var newCaretPos = caretWalker.prev(caretPos); return newCaretPos ? newCaretPos.toRange() : null; }; var insertMiddle = function (target, elms, rootNode, rng) { var parts = getSplit(target, rng); var parentElm = target.parentNode; parentElm.insertBefore(parts[0], target); Tools.each(elms, function (li) { parentElm.insertBefore(li, target); }); parentElm.insertBefore(parts[1], target); parentElm.removeChild(target); return findLastOf(elms[elms.length - 1], rootNode); }; var insertBefore = function (target, elms, rootNode) { var parentElm = target.parentNode; Tools.each(elms, function (elm) { parentElm.insertBefore(elm, target); }); return findFirstIn(target, rootNode); }; var insertAfter = function (target, elms, rootNode, dom) { dom.insertAfter(elms.reverse(), target); return findLastOf(elms[0], rootNode); }; var insertAtCaret = function (serializer, dom, rng, fragment) { var domFragment = toDomFragment(dom, serializer, fragment); var liTarget = getParentLi(dom, rng.startContainer); var liElms = trimListItems(listItems$1(domFragment.firstChild)); var BEGINNING = 1, END = 2; var rootNode = dom.getRoot(); var isAt = function (location) { var caretPos = CaretPosition$1.fromRangeStart(rng); var caretWalker = CaretWalker(dom.getRoot()); var newPos = location === BEGINNING ? caretWalker.prev(caretPos) : caretWalker.next(caretPos); return newPos ? getParentLi(dom, newPos.getNode()) !== liTarget : true; }; if (isAt(BEGINNING)) { return insertBefore(liTarget, liElms, rootNode); } else if (isAt(END)) { return insertAfter(liTarget, liElms, rootNode, dom); } return insertMiddle(liTarget, liElms, rootNode, rng); }; var InsertList = { isListFragment: isListFragment, insertAtCaret: insertAtCaret, isParentBlockLi: isParentBlockLi, trimListItems: trimListItems, listItems: listItems$1 }; var each$9 = Tools.each; var ElementUtils = function (dom) { this.compare = function (node1, node2) { if (node1.nodeName !== node2.nodeName) { return false; } var getAttribs = function (node) { var attribs = {}; each$9(dom.getAttribs(node), function (attr) { var name = attr.nodeName.toLowerCase(); if (name.indexOf('_') !== 0 && name !== 'style' && name.indexOf('data-') !== 0) { attribs[name] = dom.getAttrib(node, name); } }); return attribs; }; var compareObjects = function (obj1, obj2) { var value, name; for (name in obj1) { if (obj1.hasOwnProperty(name)) { value = obj2[name]; if (typeof value === 'undefined') { return false; } if (obj1[name] !== value) { return false; } delete obj2[name]; } } for (name in obj2) { if (obj2.hasOwnProperty(name)) { return false; } } return true; }; if (!compareObjects(getAttribs(node1), getAttribs(node2))) { return false; } if (!compareObjects(dom.parseStyle(dom.getAttrib(node1, 'style')), dom.parseStyle(dom.getAttrib(node2, 'style')))) { return false; } return !Bookmarks.isBookmarkNode(node1) && !Bookmarks.isBookmarkNode(node2); }; }; var getLastChildren = function (elm) { var children = []; var rawNode = elm.dom(); while (rawNode) { children.push(Element.fromDom(rawNode)); rawNode = rawNode.lastChild; } return children; }; var removeTrailingBr = function (elm) { var allBrs = descendants$1(elm, 'br'); var brs = filter(getLastChildren(elm).slice(-1), isBr); if (allBrs.length === brs.length) { each(brs, remove$1); } }; var fillWithPaddingBr = function (elm) { empty(elm); append(elm, Element.fromHtml('<br data-mce-bogus="1">')); }; var isPaddingContents = function (elm) { return isText(elm) ? get$4(elm) === '\xA0' : isBr(elm); }; var isPaddedElement = function (elm) { return filter(children(elm), isPaddingContents).length === 1; }; var trimBlockTrailingBr = function (elm) { lastChild(elm).each(function (lastChild) { prevSibling(lastChild).each(function (lastChildPrevSibling) { if (isBlock(elm) && isBr(lastChild) && isBlock(lastChildPrevSibling)) { remove$1(lastChild); } }); }); }; var PaddingBr = { removeTrailingBr: removeTrailingBr, fillWithPaddingBr: fillWithPaddingBr, isPaddedElement: isPaddedElement, trimBlockTrailingBr: trimBlockTrailingBr }; var makeMap$3 = Tools.makeMap; function Writer (settings) { var html = []; var indent, indentBefore, indentAfter, encode, htmlOutput; settings = settings || {}; indent = settings.indent; indentBefore = makeMap$3(settings.indent_before || ''); indentAfter = makeMap$3(settings.indent_after || ''); encode = Entities.getEncodeFunc(settings.entity_encoding || 'raw', settings.entities); htmlOutput = settings.element_format === 'html'; return { start: function (name, attrs, empty) { var i, l, attr, value; if (indent && indentBefore[name] && html.length > 0) { value = html[html.length - 1]; if (value.length > 0 && value !== '\n') { html.push('\n'); } } html.push('<', name); if (attrs) { for (i = 0, l = attrs.length; i < l; i++) { attr = attrs[i]; html.push(' ', attr.name, '="', encode(attr.value, true), '"'); } } if (!empty || htmlOutput) { html[html.length] = '>'; } else { html[html.length] = ' />'; } if (empty && indent && indentAfter[name] && html.length > 0) { value = html[html.length - 1]; if (value.length > 0 && value !== '\n') { html.push('\n'); } } }, end: function (name) { var value; html.push('</', name, '>'); if (indent && indentAfter[name] && html.length > 0) { value = html[html.length - 1]; if (value.length > 0 && value !== '\n') { html.push('\n'); } } }, text: function (text, raw) { if (text.length > 0) { html[html.length] = raw ? text : encode(text); } }, cdata: function (text) { html.push('<![CDATA[', text, ']]>'); }, comment: function (text) { html.push('<!--', text, '-->'); }, pi: function (name, text) { if (text) { html.push('<?', name, ' ', encode(text), '?>'); } else { html.push('<?', name, '?>'); } if (indent) { html.push('\n'); } }, doctype: function (text) { html.push('<!DOCTYPE', text, '>', indent ? '\n' : ''); }, reset: function () { html.length = 0; }, getContent: function () { return html.join('').replace(/\n$/, ''); } }; } function HtmlSerializer (settings, schema) { if (schema === void 0) { schema = Schema(); } var writer = Writer(settings); settings = settings || {}; settings.validate = 'validate' in settings ? settings.validate : true; var serialize = function (node) { var handlers, validate; validate = settings.validate; handlers = { 3: function (node) { writer.text(node.value, node.raw); }, 8: function (node) { writer.comment(node.value); }, 7: function (node) { writer.pi(node.name, node.value); }, 10: function (node) { writer.doctype(node.value); }, 4: function (node) { writer.cdata(node.value); }, 11: function (node) { if (node = node.firstChild) { do { walk(node); } while (node = node.next); } } }; writer.reset(); var walk = function (node) { var handler = handlers[node.type]; var name, isEmpty, attrs, attrName, attrValue, sortedAttrs, i, l, elementRule; if (!handler) { name = node.name; isEmpty = node.shortEnded; attrs = node.attributes; if (validate && attrs && attrs.length > 1) { sortedAttrs = []; sortedAttrs.map = {}; elementRule = schema.getElementRule(node.name); if (elementRule) { for (i = 0, l = elementRule.attributesOrder.length; i < l; i++) { attrName = elementRule.attributesOrder[i]; if (attrName in attrs.map) { attrValue = attrs.map[attrName]; sortedAttrs.map[attrName] = attrValue; sortedAttrs.push({ name: attrName, value: attrValue }); } } for (i = 0, l = attrs.length; i < l; i++) { attrName = attrs[i].name; if (!(attrName in sortedAttrs.map)) { attrValue = attrs.map[attrName]; sortedAttrs.map[attrName] = attrValue; sortedAttrs.push({ name: attrName, value: attrValue }); } } attrs = sortedAttrs; } } writer.start(node.name, attrs, isEmpty); if (!isEmpty) { if (node = node.firstChild) { do { walk(node); } while (node = node.next); } writer.end(name); } } else { handler(node); } }; if (node.type === 1 && !settings.inner) { walk(node); } else { handlers[11](node); } return writer.getContent(); }; return { serialize: serialize }; } var createRange$1 = function (sc, so, ec, eo) { var rng = domGlobals.document.createRange(); rng.setStart(sc, so); rng.setEnd(ec, eo); return rng; }; var normalizeBlockSelectionRange = function (rng) { var startPos = CaretPosition$1.fromRangeStart(rng); var endPos = CaretPosition$1.fromRangeEnd(rng); var rootNode = rng.commonAncestorContainer; return CaretFinder.fromPosition(false, rootNode, endPos).map(function (newEndPos) { if (!isInSameBlock(startPos, endPos, rootNode) && isInSameBlock(startPos, newEndPos, rootNode)) { return createRange$1(startPos.container(), startPos.offset(), newEndPos.container(), newEndPos.offset()); } else { return rng; } }).getOr(rng); }; var normalize = function (rng) { return rng.collapsed ? rng : normalizeBlockSelectionRange(rng); }; var RangeNormalizer = { normalize: normalize }; var isAfterNbsp = function (container, offset) { return NodeType.isText(container) && container.nodeValue[offset - 1] === '\xA0'; }; var trimOrPadLeftRight = function (rng, html) { var container, offset; container = rng.startContainer; offset = rng.startOffset; var hasSiblingText = function (siblingName) { return container[siblingName] && container[siblingName].nodeType === 3; }; if (container.nodeType === 3) { if (offset > 0) { html = html.replace(/^ /, ' '); } else if (!hasSiblingText('previousSibling')) { html = html.replace(/^ /, ' '); } if (offset < container.length) { html = html.replace(/ (<br>|)$/, ' '); } else if (!hasSiblingText('nextSibling')) { html = html.replace(/( | )(<br>|)$/, ' '); } } return html; }; var trimNbspAfterDeleteAndPadValue = function (rng, value) { var container, offset; container = rng.startContainer; offset = rng.startOffset; if (container.nodeType === 3 && rng.collapsed) { if (container.data[offset] === '\xA0') { container.deleteData(offset, 1); if (!/[\u00a0| ]$/.test(value)) { value += ' '; } } else if (container.data[offset - 1] === '\xA0') { container.deleteData(offset - 1, 1); if (!/[\u00a0| ]$/.test(value)) { value = ' ' + value; } } } return value; }; var isTableCell$2 = NodeType.matchNodeNames('td th'); var selectionSetContent = function (editor, content) { var rng = editor.selection.getRng(); var container = rng.startContainer; var offset = rng.startOffset; if (rng.collapsed && isAfterNbsp(container, offset) && NodeType.isText(container)) { container.insertData(offset - 1, ' '); container.deleteData(offset, 1); rng.setStart(container, offset); rng.setEnd(container, offset); editor.selection.setRng(rng); } editor.selection.setContent(content); }; var validInsertion = function (editor, value, parentNode) { if (parentNode.getAttribute('data-mce-bogus') === 'all') { parentNode.parentNode.insertBefore(editor.dom.createFragment(value), parentNode); } else { var node = parentNode.firstChild; var node2 = parentNode.lastChild; if (!node || node === node2 && node.nodeName === 'BR') { editor.dom.setHTML(parentNode, value); } else { selectionSetContent(editor, value); } } }; var trimBrsFromTableCell = function (dom, elm) { Option.from(dom.getParent(elm, 'td,th')).map(Element.fromDom).each(PaddingBr.trimBlockTrailingBr); }; var reduceInlineTextElements = function (editor, merge) { var textInlineElements = editor.schema.getTextInlineElements(); var dom = editor.dom; if (merge) { var root_1 = editor.getBody(), elementUtils_1 = new ElementUtils(dom); Tools.each(dom.select('*[data-mce-fragment]'), function (node) { for (var testNode = node.parentNode; testNode && testNode !== root_1; testNode = testNode.parentNode) { if (textInlineElements[node.nodeName.toLowerCase()] && elementUtils_1.compare(testNode, node)) { dom.remove(node, true); } } }); } }; var markFragmentElements = function (fragment) { var node = fragment; while (node = node.walk()) { if (node.type === 1) { node.attr('data-mce-fragment', '1'); } } }; var umarkFragmentElements = function (elm) { Tools.each(elm.getElementsByTagName('*'), function (elm) { elm.removeAttribute('data-mce-fragment'); }); }; var isPartOfFragment = function (node) { return !!node.getAttribute('data-mce-fragment'); }; var canHaveChildren = function (editor, node) { return node && !editor.schema.getShortEndedElements()[node.nodeName]; }; var moveSelectionToMarker = function (editor, marker) { var parentEditableFalseElm, parentBlock, nextRng; var dom = editor.dom, selection = editor.selection; var node, node2; var getContentEditableFalseParent = function (node) { var root = editor.getBody(); for (; node && node !== root; node = node.parentNode) { if (editor.dom.getContentEditable(node) === 'false') { return node; } } return null; }; if (!marker) { return; } editor.selection.scrollIntoView(marker); parentEditableFalseElm = getContentEditableFalseParent(marker); if (parentEditableFalseElm) { dom.remove(marker); selection.select(parentEditableFalseElm); return; } var rng = dom.createRng(); node = marker.previousSibling; if (node && node.nodeType === 3) { rng.setStart(node, node.nodeValue.length); if (!Env.ie) { node2 = marker.nextSibling; if (node2 && node2.nodeType === 3) { node.appendData(node2.data); node2.parentNode.removeChild(node2); } } } else { rng.setStartBefore(marker); rng.setEndBefore(marker); } var findNextCaretRng = function (rng) { var caretPos = CaretPosition$1.fromRangeStart(rng); var caretWalker = CaretWalker(editor.getBody()); caretPos = caretWalker.next(caretPos); if (caretPos) { return caretPos.toRange(); } }; parentBlock = dom.getParent(marker, dom.isBlock); dom.remove(marker); if (parentBlock && dom.isEmpty(parentBlock)) { editor.$(parentBlock).empty(); rng.setStart(parentBlock, 0); rng.setEnd(parentBlock, 0); if (!isTableCell$2(parentBlock) && !isPartOfFragment(parentBlock) && (nextRng = findNextCaretRng(rng))) { rng = nextRng; dom.remove(parentBlock); } else { dom.add(parentBlock, dom.create('br', { 'data-mce-bogus': '1' })); } } selection.setRng(rng); }; var insertHtmlAtCaret = function (editor, value, details) { var parser, serializer, parentNode, rootNode, fragment, args; var marker, rng, node, bookmarkHtml, merge; var selection = editor.selection, dom = editor.dom; if (/^ | $/.test(value)) { value = trimOrPadLeftRight(selection.getRng(), value); } parser = editor.parser; merge = details.merge; serializer = HtmlSerializer({ validate: editor.settings.validate }, editor.schema); bookmarkHtml = '<span id="mce_marker" data-mce-type="bookmark">​</span>'; args = { content: value, format: 'html', selection: true, paste: details.paste }; args = editor.fire('BeforeSetContent', args); if (args.isDefaultPrevented()) { editor.fire('SetContent', { content: args.content, format: 'html', selection: true, paste: details.paste }); return; } value = args.content; if (value.indexOf('{$caret}') === -1) { value += '{$caret}'; } value = value.replace(/\{\$caret\}/, bookmarkHtml); rng = selection.getRng(); var caretElement = rng.startContainer || (rng.parentElement ? rng.parentElement() : null); var body = editor.getBody(); if (caretElement === body && selection.isCollapsed()) { if (dom.isBlock(body.firstChild) && canHaveChildren(editor, body.firstChild) && dom.isEmpty(body.firstChild)) { rng = dom.createRng(); rng.setStart(body.firstChild, 0); rng.setEnd(body.firstChild, 0); selection.setRng(rng); } } if (!selection.isCollapsed()) { editor.selection.setRng(RangeNormalizer.normalize(editor.selection.getRng())); editor.getDoc().execCommand('Delete', false, null); value = trimNbspAfterDeleteAndPadValue(editor.selection.getRng(), value); } parentNode = selection.getNode(); var parserArgs = { context: parentNode.nodeName.toLowerCase(), data: details.data, insert: true }; fragment = parser.parse(value, parserArgs); if (details.paste === true && InsertList.isListFragment(editor.schema, fragment) && InsertList.isParentBlockLi(dom, parentNode)) { rng = InsertList.insertAtCaret(serializer, dom, editor.selection.getRng(), fragment); editor.selection.setRng(rng); editor.fire('SetContent', args); return; } markFragmentElements(fragment); node = fragment.lastChild; if (node.attr('id') === 'mce_marker') { marker = node; for (node = node.prev; node; node = node.walk(true)) { if (node.type === 3 || !dom.isBlock(node.name)) { if (editor.schema.isValidChild(node.parent.name, 'span')) { node.parent.insert(marker, node, node.name === 'br'); } break; } } } editor._selectionOverrides.showBlockCaretContainer(parentNode); if (!parserArgs.invalid) { value = serializer.serialize(fragment); validInsertion(editor, value, parentNode); } else { selectionSetContent(editor, bookmarkHtml); parentNode = selection.getNode(); rootNode = editor.getBody(); if (parentNode.nodeType === 9) { parentNode = node = rootNode; } else { node = parentNode; } while (node !== rootNode) { parentNode = node; node = node.parentNode; } value = parentNode === rootNode ? rootNode.innerHTML : dom.getOuterHTML(parentNode); value = serializer.serialize(parser.parse(value.replace(/<span (id="mce_marker"|id=mce_marker).+?<\/span>/i, function () { return serializer.serialize(fragment); }))); if (parentNode === rootNode) { dom.setHTML(rootNode, value); } else { dom.setOuterHTML(parentNode, value); } } reduceInlineTextElements(editor, merge); moveSelectionToMarker(editor, dom.get('mce_marker')); umarkFragmentElements(editor.getBody()); trimBrsFromTableCell(editor.dom, editor.selection.getStart()); editor.fire('SetContent', args); editor.addVisual(); }; var processValue = function (value) { var details; if (typeof value !== 'string') { details = Tools.extend({ paste: value.paste, data: { paste: value.paste } }, value); return { content: value.content, details: details }; } return { content: value, details: {} }; }; var insertAtCaret$1 = function (editor, value) { var result = processValue(value); insertHtmlAtCaret(editor, result.content, result.details); }; var InsertContent = { insertAtCaret: insertAtCaret$1 }; var sectionResult = Immutable('sections', 'settings'); var detection = PlatformDetection$1.detect(); var isTouch = detection.deviceType.isTouch(); var mobilePlugins = [ 'lists', 'autolink', 'autosave' ]; var defaultMobileSettings = { theme: 'mobile' }; var normalizePlugins = function (plugins) { var pluginNames = isArray(plugins) ? plugins.join(' ') : plugins; var trimmedPlugins = map(isString(pluginNames) ? pluginNames.split(' ') : [], trim$2); return filter(trimmedPlugins, function (item) { return item.length > 0; }); }; var filterMobilePlugins = function (plugins) { return filter(plugins, curry(contains, mobilePlugins)); }; var extractSections = function (keys, settings) { var result = bifilter(settings, function (value, key) { return contains(keys, key); }); return sectionResult(result.t, result.f); }; var getSection = function (sectionResult, name, defaults) { var sections = sectionResult.sections(); var sectionSettings = sections.hasOwnProperty(name) ? sections[name] : {}; return Tools.extend({}, defaults, sectionSettings); }; var hasSection = function (sectionResult, name) { return sectionResult.sections().hasOwnProperty(name); }; var getDefaultSettings = function (id, documentBaseUrl, editor) { return { id: id, theme: 'modern', delta_width: 0, delta_height: 0, popup_css: '', plugins: '', document_base_url: documentBaseUrl, add_form_submit_trigger: true, submit_patch: true, add_unload_trigger: true, convert_urls: true, relative_urls: true, remove_script_host: true, object_resizing: true, doctype: '<!DOCTYPE html>', visual: true, font_size_style_values: 'xx-small,x-small,small,medium,large,x-large,xx-large', font_size_legacy_values: 'xx-small,small,medium,large,x-large,xx-large,300%', forced_root_block: 'p', hidden_input: true, render_ui: true, indentation: '40px', inline_styles: true, convert_fonts_to_spans: true, indent: 'simple', indent_before: 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,' + 'tfoot,tbody,tr,section,summary,article,hgroup,aside,figure,figcaption,option,optgroup,datalist', indent_after: 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,' + 'tfoot,tbody,tr,section,summary,article,hgroup,aside,figure,figcaption,option,optgroup,datalist', entity_encoding: 'named', url_converter: editor.convertURL, url_converter_scope: editor, ie7_compat: true }; }; var getExternalPlugins = function (overrideSettings, settings) { var userDefinedExternalPlugins = settings.external_plugins ? settings.external_plugins : {}; if (overrideSettings && overrideSettings.external_plugins) { return Tools.extend({}, overrideSettings.external_plugins, userDefinedExternalPlugins); } else { return userDefinedExternalPlugins; } }; var combinePlugins = function (forcedPlugins, plugins) { return [].concat(normalizePlugins(forcedPlugins)).concat(normalizePlugins(plugins)); }; var processPlugins = function (isTouchDevice, sectionResult, defaultOverrideSettings, settings) { var forcedPlugins = normalizePlugins(defaultOverrideSettings.forced_plugins); var plugins = normalizePlugins(settings.plugins); var platformPlugins = isTouchDevice && hasSection(sectionResult, 'mobile') ? filterMobilePlugins(plugins) : plugins; var combinedPlugins = combinePlugins(forcedPlugins, platformPlugins); return Tools.extend(settings, { plugins: combinedPlugins.join(' ') }); }; var isOnMobile = function (isTouchDevice, sectionResult) { var isInline = sectionResult.settings().inline; return isTouchDevice && hasSection(sectionResult, 'mobile') && !isInline; }; var combineSettings = function (isTouchDevice, defaultSettings, defaultOverrideSettings, settings) { var sectionResult = extractSections(['mobile'], settings); var extendedSettings = Tools.extend(defaultSettings, defaultOverrideSettings, sectionResult.settings(), isOnMobile(isTouchDevice, sectionResult) ? getSection(sectionResult, 'mobile', defaultMobileSettings) : {}, { validate: true, content_editable: sectionResult.settings().inline, external_plugins: getExternalPlugins(defaultOverrideSettings, sectionResult.settings()) }); return processPlugins(isTouchDevice, sectionResult, defaultOverrideSettings, extendedSettings); }; var getEditorSettings = function (editor, id, documentBaseUrl, defaultOverrideSettings, settings) { var defaultSettings = getDefaultSettings(id, documentBaseUrl, editor); return combineSettings(isTouch, defaultSettings, defaultOverrideSettings, settings); }; var getFiltered = function (predicate, editor, name) { return Option.from(editor.settings[name]).filter(predicate); }; var getString = curry(getFiltered, isString); var getParamObject = function (value) { var output = {}; if (typeof value === 'string') { each(value.indexOf('=') > 0 ? value.split(/[;,](?![^=;,]*(?:[;,]|$))/) : value.split(','), function (val) { var arr = val.split('='); if (arr.length > 1) { output[Tools.trim(arr[0])] = Tools.trim(arr[1]); } else { output[Tools.trim(arr[0])] = Tools.trim(arr); } }); } else { output = value; } return output; }; var isArrayOf = function (p) { return function (a) { return isArray(a) && forall(a, p); }; }; var getParam = function (editor, name, defaultVal, type) { var value = name in editor.settings ? editor.settings[name] : defaultVal; if (type === 'hash') { return getParamObject(value); } else if (type === 'string') { return getFiltered(isString, editor, name).getOr(defaultVal); } else if (type === 'number') { return getFiltered(isNumber, editor, name).getOr(defaultVal); } else if (type === 'boolean') { return getFiltered(isBoolean, editor, name).getOr(defaultVal); } else if (type === 'object') { return getFiltered(isObject, editor, name).getOr(defaultVal); } else if (type === 'array') { return getFiltered(isArray, editor, name).getOr(defaultVal); } else if (type === 'string[]') { return getFiltered(isArrayOf(isString), editor, name).getOr(defaultVal); } else if (type === 'function') { return getFiltered(isFunction, editor, name).getOr(defaultVal); } else { return value; } }; var strongRtl = /[\u0591-\u07FF\uFB1D-\uFDFF\uFE70-\uFEFC]/; var hasStrongRtl = function (text) { return strongRtl.test(text); }; var isInlineTarget = function (editor, elm) { var selector = getString(editor, 'inline_boundaries_selector').getOr('a[href],code'); return is$1(Element.fromDom(elm), selector); }; var isRtl = function (element) { return DOMUtils$1.DOM.getStyle(element, 'direction', true) === 'rtl' || hasStrongRtl(element.textContent); }; var findInlineParents = function (isInlineTarget, rootNode, pos) { return filter(DOMUtils$1.DOM.getParents(pos.container(), '*', rootNode), isInlineTarget); }; var findRootInline = function (isInlineTarget, rootNode, pos) { var parents = findInlineParents(isInlineTarget, rootNode, pos); return Option.from(parents[parents.length - 1]); }; var hasSameParentBlock = function (rootNode, node1, node2) { var block1 = getParentBlock(node1, rootNode); var block2 = getParentBlock(node2, rootNode); return block1 && block1 === block2; }; var isAtZwsp = function (pos) { return isBeforeInline(pos) || isAfterInline(pos); }; var normalizePosition = function (forward, pos) { if (!pos) { return pos; } var container = pos.container(), offset = pos.offset(); if (forward) { if (isCaretContainerInline(container)) { if (NodeType.isText(container.nextSibling)) { return CaretPosition$1(container.nextSibling, 0); } else { return CaretPosition$1.after(container); } } else { return isBeforeInline(pos) ? CaretPosition$1(container, offset + 1) : pos; } } else { if (isCaretContainerInline(container)) { if (NodeType.isText(container.previousSibling)) { return CaretPosition$1(container.previousSibling, container.previousSibling.data.length); } else { return CaretPosition$1.before(container); } } else { return isAfterInline(pos) ? CaretPosition$1(container, offset - 1) : pos; } } }; var normalizeForwards = curry(normalizePosition, true); var normalizeBackwards = curry(normalizePosition, false); var InlineUtils = { isInlineTarget: isInlineTarget, findRootInline: findRootInline, isRtl: isRtl, isAtZwsp: isAtZwsp, normalizePosition: normalizePosition, normalizeForwards: normalizeForwards, normalizeBackwards: normalizeBackwards, hasSameParentBlock: hasSameParentBlock }; var isBeforeRoot = function (rootNode) { return function (elm) { return eq(rootNode, Element.fromDom(elm.dom().parentNode)); }; }; var getParentBlock$1 = function (rootNode, elm) { return contains$3(rootNode, elm) ? closest(elm, function (element) { return isTextBlock(element) || isListItem(element); }, isBeforeRoot(rootNode)) : Option.none(); }; var placeCaretInEmptyBody = function (editor) { var body = editor.getBody(); var node = body.firstChild && editor.dom.isBlock(body.firstChild) ? body.firstChild : body; editor.selection.setCursorLocation(node, 0); }; var paddEmptyBody = function (editor) { if (editor.dom.isEmpty(editor.getBody())) { editor.setContent(''); placeCaretInEmptyBody(editor); } }; var willDeleteLastPositionInElement = function (forward, fromPos, elm) { return liftN([ CaretFinder.firstPositionIn(elm), CaretFinder.lastPositionIn(elm) ], function (firstPos, lastPos) { var normalizedFirstPos = InlineUtils.normalizePosition(true, firstPos); var normalizedLastPos = InlineUtils.normalizePosition(false, lastPos); var normalizedFromPos = InlineUtils.normalizePosition(false, fromPos); if (forward) { return CaretFinder.nextPosition(elm, normalizedFromPos).map(function (nextPos) { return nextPos.isEqual(normalizedLastPos) && fromPos.isEqual(normalizedFirstPos); }).getOr(false); } else { return CaretFinder.prevPosition(elm, normalizedFromPos).map(function (prevPos) { return prevPos.isEqual(normalizedFirstPos) && fromPos.isEqual(normalizedLastPos); }).getOr(false); } }).getOr(true); }; var DeleteUtils = { getParentBlock: getParentBlock$1, paddEmptyBody: paddEmptyBody, willDeleteLastPositionInElement: willDeleteLastPositionInElement }; var ancestor$2 = function (scope, selector, isRoot) { return ancestor$1(scope, selector, isRoot).isSome(); }; var hasWhitespacePreserveParent = function (rootNode, node) { var rootElement = Element.fromDom(rootNode); var startNode = Element.fromDom(node); return ancestor$2(startNode, 'pre,code', curry(eq, rootElement)); }; var isWhitespace = function (rootNode, node) { return NodeType.isText(node) && /^[ \t\r\n]*$/.test(node.data) && hasWhitespacePreserveParent(rootNode, node) === false; }; var isNamedAnchor = function (node) { return NodeType.isElement(node) && node.nodeName === 'A' && node.hasAttribute('name'); }; var isContent = function (rootNode, node) { return isCaretCandidate(node) && isWhitespace(rootNode, node) === false || isNamedAnchor(node) || isBookmark(node); }; var isBookmark = NodeType.hasAttribute('data-mce-bookmark'); var isBogus$2 = NodeType.hasAttribute('data-mce-bogus'); var isBogusAll$1 = NodeType.hasAttributeValue('data-mce-bogus', 'all'); var isEmptyNode = function (targetNode) { var walker, node, brCount = 0; if (isContent(targetNode, targetNode)) { return false; } else { node = targetNode.firstChild; if (!node) { return true; } walker = new TreeWalker(node, targetNode); do { if (isBogusAll$1(node)) { node = walker.next(true); continue; } if (isBogus$2(node)) { node = walker.next(); continue; } if (NodeType.isBr(node)) { brCount++; node = walker.next(); continue; } if (isContent(targetNode, node)) { return false; } node = walker.next(); } while (node); return brCount <= 1; } }; var isEmpty$1 = function (elm) { return isEmptyNode(elm.dom()); }; var Empty = { isEmpty: isEmpty$1 }; var BlockPosition = Immutable('block', 'position'); var BlockBoundary = Immutable('from', 'to'); var getBlockPosition = function (rootNode, pos) { var rootElm = Element.fromDom(rootNode); var containerElm = Element.fromDom(pos.container()); return DeleteUtils.getParentBlock(rootElm, containerElm).map(function (block) { return BlockPosition(block, pos); }); }; var isDifferentBlocks = function (blockBoundary) { return eq(blockBoundary.from().block(), blockBoundary.to().block()) === false; }; var hasSameParent = function (blockBoundary) { return parent(blockBoundary.from().block()).bind(function (parent1) { return parent(blockBoundary.to().block()).filter(function (parent2) { return eq(parent1, parent2); }); }).isSome(); }; var isEditable = function (blockBoundary) { return NodeType.isContentEditableFalse(blockBoundary.from().block()) === false && NodeType.isContentEditableFalse(blockBoundary.to().block()) === false; }; var skipLastBr = function (rootNode, forward, blockPosition) { if (NodeType.isBr(blockPosition.position().getNode()) && Empty.isEmpty(blockPosition.block()) === false) { return CaretFinder.positionIn(false, blockPosition.block().dom()).bind(function (lastPositionInBlock) { if (lastPositionInBlock.isEqual(blockPosition.position())) { return CaretFinder.fromPosition(forward, rootNode, lastPositionInBlock).bind(function (to) { return getBlockPosition(rootNode, to); }); } else { return Option.some(blockPosition); } }).getOr(blockPosition); } else { return blockPosition; } }; var readFromRange = function (rootNode, forward, rng) { var fromBlockPos = getBlockPosition(rootNode, CaretPosition$1.fromRangeStart(rng)); var toBlockPos = fromBlockPos.bind(function (blockPos) { return CaretFinder.fromPosition(forward, rootNode, blockPos.position()).bind(function (to) { return getBlockPosition(rootNode, to).map(function (blockPos) { return skipLastBr(rootNode, forward, blockPos); }); }); }); return liftN([ fromBlockPos, toBlockPos ], BlockBoundary).filter(function (blockBoundary) { return isDifferentBlocks(blockBoundary) && hasSameParent(blockBoundary) && isEditable(blockBoundary); }); }; var read$1 = function (rootNode, forward, rng) { return rng.collapsed ? readFromRange(rootNode, forward, rng) : Option.none(); }; var BlockMergeBoundary = { read: read$1 }; var dropLast = function (xs) { return xs.slice(0, -1); }; var parentsUntil$1 = function (start, root, predicate) { if (contains$3(root, start)) { return dropLast(parents(start, function (elm) { return predicate(elm) || eq(elm, root); })); } else { return []; } }; var parents$1 = function (start, root) { return parentsUntil$1(start, root, constant(false)); }; var parentsAndSelf = function (start, root) { return [start].concat(parents$1(start, root)); }; var Parents = { parentsUntil: parentsUntil$1, parents: parents$1, parentsAndSelf: parentsAndSelf }; var getChildrenUntilBlockBoundary = function (block) { var children$1 = children(block); return findIndex(children$1, isBlock).fold(function () { return children$1; }, function (index) { return children$1.slice(0, index); }); }; var extractChildren = function (block) { var children = getChildrenUntilBlockBoundary(block); each(children, remove$1); return children; }; var removeEmptyRoot = function (rootNode, block) { var parents = Parents.parentsAndSelf(block, rootNode); return find(parents.reverse(), Empty.isEmpty).each(remove$1); }; var isEmptyBefore = function (el) { return filter(prevSiblings(el), function (el) { return !Empty.isEmpty(el); }).length === 0; }; var nestedBlockMerge = function (rootNode, fromBlock, toBlock, insertionPoint) { if (Empty.isEmpty(toBlock)) { PaddingBr.fillWithPaddingBr(toBlock); return CaretFinder.firstPositionIn(toBlock.dom()); } if (isEmptyBefore(insertionPoint) && Empty.isEmpty(fromBlock)) { before(insertionPoint, Element.fromTag('br')); } var position = CaretFinder.prevPosition(toBlock.dom(), CaretPosition$1.before(insertionPoint.dom())); each(extractChildren(fromBlock), function (child) { before(insertionPoint, child); }); removeEmptyRoot(rootNode, fromBlock); return position; }; var sidelongBlockMerge = function (rootNode, fromBlock, toBlock) { if (Empty.isEmpty(toBlock)) { remove$1(toBlock); if (Empty.isEmpty(fromBlock)) { PaddingBr.fillWithPaddingBr(fromBlock); } return CaretFinder.firstPositionIn(fromBlock.dom()); } var position = CaretFinder.lastPositionIn(toBlock.dom()); each(extractChildren(fromBlock), function (child) { append(toBlock, child); }); removeEmptyRoot(rootNode, fromBlock); return position; }; var findInsertionPoint = function (toBlock, block) { var parentsAndSelf = Parents.parentsAndSelf(block, toBlock); return Option.from(parentsAndSelf[parentsAndSelf.length - 1]); }; var getInsertionPoint = function (fromBlock, toBlock) { return contains$3(toBlock, fromBlock) ? findInsertionPoint(toBlock, fromBlock) : Option.none(); }; var trimBr = function (first, block) { CaretFinder.positionIn(first, block.dom()).map(function (position) { return position.getNode(); }).map(Element.fromDom).filter(isBr).each(remove$1); }; var mergeBlockInto = function (rootNode, fromBlock, toBlock) { trimBr(true, fromBlock); trimBr(false, toBlock); return getInsertionPoint(fromBlock, toBlock).fold(curry(sidelongBlockMerge, rootNode, fromBlock, toBlock), curry(nestedBlockMerge, rootNode, fromBlock, toBlock)); }; var mergeBlocks = function (rootNode, forward, block1, block2) { return forward ? mergeBlockInto(rootNode, block2, block1) : mergeBlockInto(rootNode, block1, block2); }; var MergeBlocks = { mergeBlocks: mergeBlocks }; var backspaceDelete = function (editor, forward) { var position; var rootNode = Element.fromDom(editor.getBody()); position = BlockMergeBoundary.read(rootNode.dom(), forward, editor.selection.getRng()).bind(function (blockBoundary) { return MergeBlocks.mergeBlocks(rootNode, forward, blockBoundary.from().block(), blockBoundary.to().block()); }); position.each(function (pos) { editor.selection.setRng(pos.toRange()); }); return position.isSome(); }; var BlockBoundaryDelete = { backspaceDelete: backspaceDelete }; var deleteRangeMergeBlocks = function (rootNode, selection) { var rng = selection.getRng(); return liftN([ DeleteUtils.getParentBlock(rootNode, Element.fromDom(rng.startContainer)), DeleteUtils.getParentBlock(rootNode, Element.fromDom(rng.endContainer)) ], function (block1, block2) { if (eq(block1, block2) === false) { rng.deleteContents(); MergeBlocks.mergeBlocks(rootNode, true, block1, block2).each(function (pos) { selection.setRng(pos.toRange()); }); return true; } else { return false; } }).getOr(false); }; var isRawNodeInTable = function (root, rawNode) { var node = Element.fromDom(rawNode); var isRoot = curry(eq, root); return ancestor(node, isTableCell, isRoot).isSome(); }; var isSelectionInTable = function (root, rng) { return isRawNodeInTable(root, rng.startContainer) || isRawNodeInTable(root, rng.endContainer); }; var isEverythingSelected = function (root, rng) { var noPrevious = CaretFinder.prevPosition(root.dom(), CaretPosition$1.fromRangeStart(rng)).isNone(); var noNext = CaretFinder.nextPosition(root.dom(), CaretPosition$1.fromRangeEnd(rng)).isNone(); return !isSelectionInTable(root, rng) && noPrevious && noNext; }; var emptyEditor = function (editor) { editor.setContent(''); editor.selection.setCursorLocation(); return true; }; var deleteRange = function (editor) { var rootNode = Element.fromDom(editor.getBody()); var rng = editor.selection.getRng(); return isEverythingSelected(rootNode, rng) ? emptyEditor(editor) : deleteRangeMergeBlocks(rootNode, editor.selection); }; var backspaceDelete$1 = function (editor, forward) { return editor.selection.isCollapsed() ? false : deleteRange(editor); }; var BlockRangeDelete = { backspaceDelete: backspaceDelete$1 }; var generate$1 = function (cases) { if (!isArray(cases)) { throw new Error('cases must be an array'); } if (cases.length === 0) { throw new Error('there must be at least one case'); } var constructors = []; var adt = {}; each(cases, function (acase, count) { var keys$1 = keys(acase); if (keys$1.length !== 1) { throw new Error('one and only one name per case'); } var key = keys$1[0]; var value = acase[key]; if (adt[key] !== undefined) { throw new Error('duplicate key detected:' + key); } else if (key === 'cata') { throw new Error('cannot have a case named cata (sorry)'); } else if (!isArray(value)) { throw new Error('case arguments must be an array'); } constructors.push(key); adt[key] = function () { var argLength = arguments.length; if (argLength !== value.length) { throw new Error('Wrong number of arguments to case ' + key + '. Expected ' + value.length + ' (' + value + '), got ' + argLength); } var args = new Array(argLength); for (var i = 0; i < args.length; i++) args[i] = arguments[i]; var match = function (branches) { var branchKeys = keys(branches); if (constructors.length !== branchKeys.length) { throw new Error('Wrong number of arguments to match. Expected: ' + constructors.join(',') + '\nActual: ' + branchKeys.join(',')); } var allReqd = forall(constructors, function (reqKey) { return contains(branchKeys, reqKey); }); if (!allReqd) throw new Error('Not all branches were specified when using match. Specified: ' + branchKeys.join(', ') + '\nRequired: ' + constructors.join(', ')); return branches[key].apply(null, args); }; return { fold: function () { if (arguments.length !== cases.length) { throw new Error('Wrong number of arguments to fold. Expected ' + cases.length + ', got ' + arguments.length); } var target = arguments[count]; return target.apply(null, args); }, match: match, log: function (label) { domGlobals.console.log(label, { constructors: constructors, constructor: key, params: args }); } }; }; }); return adt; }; var Adt = { generate: generate$1 }; var isBr$5 = function (pos) { return getElementFromPosition(pos).exists(isBr); }; var findBr = function (forward, root, pos) { var parentBlocks = filter(Parents.parentsAndSelf(Element.fromDom(pos.container()), root), isBlock); var scope = head(parentBlocks).getOr(root); return CaretFinder.fromPosition(forward, scope.dom(), pos).filter(isBr$5); }; var isBeforeBr = function (root, pos) { return getElementFromPosition(pos).exists(isBr) || findBr(true, root, pos).isSome(); }; var isAfterBr = function (root, pos) { return getElementFromPrevPosition(pos).exists(isBr) || findBr(false, root, pos).isSome(); }; var findPreviousBr = curry(findBr, false); var findNextBr = curry(findBr, true); var is$2 = function (expected) { return function (actual) { return expected === actual; }; }; var isNbsp = is$2('\xA0'); var isWhiteSpace$1 = function (chr) { return /^[\r\n\t ]$/.test(chr); }; var isContent$1 = function (chr) { return !isWhiteSpace$1(chr) && !isNbsp(chr); }; var isChar = function (forward, predicate, pos) { return Option.from(pos.container()).filter(NodeType.isText).exists(function (text) { var delta = forward ? 0 : -1; return predicate(text.data.charAt(pos.offset() + delta)); }); }; var isBeforeSpace = curry(isChar, true, isWhiteSpace$1); var isAfterSpace = curry(isChar, false, isWhiteSpace$1); var isEmptyText = function (pos) { var container = pos.container(); return NodeType.isText(container) && container.data.length === 0; }; var isNextToContentEditableFalse = function (relativeOffset, caretPosition) { var node = getChildNodeAtRelativeOffset(relativeOffset, caretPosition); return NodeType.isContentEditableFalse(node) && !NodeType.isBogusAll(node); }; var isBeforeContentEditableFalse = curry(isNextToContentEditableFalse, 0); var isAfterContentEditableFalse = curry(isNextToContentEditableFalse, -1); var isNextToTable = function (relativeOffset, caretPosition) { return NodeType.isTable(getChildNodeAtRelativeOffset(relativeOffset, caretPosition)); }; var isBeforeTable = curry(isNextToTable, 0); var isAfterTable = curry(isNextToTable, -1); var isCompoundElement = function (node) { return isTableCell(Element.fromDom(node)) || isListItem(Element.fromDom(node)); }; var DeleteAction = Adt.generate([ { remove: ['element'] }, { moveToElement: ['element'] }, { moveToPosition: ['position'] } ]); var isAtContentEditableBlockCaret = function (forward, from) { var elm = from.getNode(forward === false); var caretLocation = forward ? 'after' : 'before'; return NodeType.isElement(elm) && elm.getAttribute('data-mce-caret') === caretLocation; }; var isDeleteFromCefDifferentBlocks = function (root, forward, from, to) { var inSameBlock = function (elm) { return isInline(Element.fromDom(elm)) && !isInSameBlock(from, to, root); }; return getRelativeCefElm(!forward, from).fold(function () { return getRelativeCefElm(forward, to).fold(constant(false), inSameBlock); }, inSameBlock); }; var deleteEmptyBlockOrMoveToCef = function (root, forward, from, to) { var toCefElm = to.getNode(forward === false); return DeleteUtils.getParentBlock(Element.fromDom(root), Element.fromDom(from.getNode())).map(function (blockElm) { return Empty.isEmpty(blockElm) ? DeleteAction.remove(blockElm.dom()) : DeleteAction.moveToElement(toCefElm); }).orThunk(function () { return Option.some(DeleteAction.moveToElement(toCefElm)); }); }; var findCefPosition = function (root, forward, from) { return CaretFinder.fromPosition(forward, root, from).bind(function (to) { if (isCompoundElement(to.getNode())) { return Option.none(); } else if (isDeleteFromCefDifferentBlocks(root, forward, from, to)) { return Option.none(); } else if (forward && NodeType.isContentEditableFalse(to.getNode())) { return deleteEmptyBlockOrMoveToCef(root, forward, from, to); } else if (forward === false && NodeType.isContentEditableFalse(to.getNode(true))) { return deleteEmptyBlockOrMoveToCef(root, forward, from, to); } else if (forward && isAfterContentEditableFalse(from)) { return Option.some(DeleteAction.moveToPosition(to)); } else if (forward === false && isBeforeContentEditableFalse(from)) { return Option.some(DeleteAction.moveToPosition(to)); } else { return Option.none(); } }); }; var getContentEditableBlockAction = function (forward, elm) { if (forward && NodeType.isContentEditableFalse(elm.nextSibling)) { return Option.some(DeleteAction.moveToElement(elm.nextSibling)); } else if (forward === false && NodeType.isContentEditableFalse(elm.previousSibling)) { return Option.some(DeleteAction.moveToElement(elm.previousSibling)); } else { return Option.none(); } }; var skipMoveToActionFromInlineCefToContent = function (root, from, deleteAction) { return deleteAction.fold(function (elm) { return Option.some(DeleteAction.remove(elm)); }, function (elm) { return Option.some(DeleteAction.moveToElement(elm)); }, function (to) { if (isInSameBlock(from, to, root)) { return Option.none(); } else { return Option.some(DeleteAction.moveToPosition(to)); } }); }; var getContentEditableAction = function (root, forward, from) { if (isAtContentEditableBlockCaret(forward, from)) { return getContentEditableBlockAction(forward, from.getNode(forward === false)).fold(function () { return findCefPosition(root, forward, from); }, Option.some); } else { return findCefPosition(root, forward, from).bind(function (deleteAction) { return skipMoveToActionFromInlineCefToContent(root, from, deleteAction); }); } }; var read$2 = function (root, forward, rng) { var normalizedRange = normalizeRange(forward ? 1 : -1, root, rng); var from = CaretPosition$1.fromRangeStart(normalizedRange); var rootElement = Element.fromDom(root); if (forward === false && isAfterContentEditableFalse(from)) { return Option.some(DeleteAction.remove(from.getNode(true))); } else if (forward && isBeforeContentEditableFalse(from)) { return Option.some(DeleteAction.remove(from.getNode())); } else if (forward === false && isBeforeContentEditableFalse(from) && isAfterBr(rootElement, from)) { return findPreviousBr(rootElement, from).map(function (br) { return DeleteAction.remove(br.getNode()); }); } else if (forward && isAfterContentEditableFalse(from) && isBeforeBr(rootElement, from)) { return findNextBr(rootElement, from).map(function (br) { return DeleteAction.remove(br.getNode()); }); } else { return getContentEditableAction(root, forward, from); } }; var isCollapsibleWhitespace = function (c) { return ' \f\n\r\t\x0B'.indexOf(c) !== -1; }; var normalizeContent = function (content, isStartOfContent, isEndOfContent) { var result = foldl(content.split(''), function (acc, c) { if (isCollapsibleWhitespace(c) || c === '\xA0') { if (acc.previousCharIsSpace || acc.str === '' && isStartOfContent || acc.str.length === content.length - 1 && isEndOfContent) { return { previousCharIsSpace: false, str: acc.str + '\xA0' }; } else { return { previousCharIsSpace: true, str: acc.str + ' ' }; } } else { return { previousCharIsSpace: false, str: acc.str + c }; } }, { previousCharIsSpace: false, str: '' }); return result.str; }; var normalize$1 = function (node, offset, count) { if (count === 0) { return; } var whitespace = node.data.slice(offset, offset + count); var isEndOfContent = offset + count >= node.data.length; var isStartOfContent = offset === 0; node.replaceData(offset, count, normalizeContent(whitespace, isStartOfContent, isEndOfContent)); }; var normalizeWhitespaceAfter = function (node, offset) { var content = node.data.slice(offset); var whitespaceCount = content.length - lTrim(content).length; return normalize$1(node, offset, whitespaceCount); }; var normalizeWhitespaceBefore = function (node, offset) { var content = node.data.slice(0, offset); var whitespaceCount = content.length - rTrim(content).length; return normalize$1(node, offset - whitespaceCount, whitespaceCount); }; var mergeTextNodes = function (prevNode, nextNode, normalizeWhitespace) { var whitespaceOffset = rTrim(prevNode.data).length; prevNode.appendData(nextNode.data); remove$1(Element.fromDom(nextNode)); if (normalizeWhitespace) { normalizeWhitespaceAfter(prevNode, whitespaceOffset); } return prevNode; }; var needsReposition = function (pos, elm) { var container = pos.container(); var offset = pos.offset(); return CaretPosition$1.isTextPosition(pos) === false && container === elm.parentNode && offset > CaretPosition$1.before(elm).offset(); }; var reposition = function (elm, pos) { return needsReposition(pos, elm) ? CaretPosition$1(pos.container(), pos.offset() - 1) : pos; }; var beforeOrStartOf = function (node) { return NodeType.isText(node) ? CaretPosition$1(node, 0) : CaretPosition$1.before(node); }; var afterOrEndOf = function (node) { return NodeType.isText(node) ? CaretPosition$1(node, node.data.length) : CaretPosition$1.after(node); }; var getPreviousSiblingCaretPosition = function (elm) { if (isCaretCandidate(elm.previousSibling)) { return Option.some(afterOrEndOf(elm.previousSibling)); } else { return elm.previousSibling ? CaretFinder.lastPositionIn(elm.previousSibling) : Option.none(); } }; var getNextSiblingCaretPosition = function (elm) { if (isCaretCandidate(elm.nextSibling)) { return Option.some(beforeOrStartOf(elm.nextSibling)); } else { return elm.nextSibling ? CaretFinder.firstPositionIn(elm.nextSibling) : Option.none(); } }; var findCaretPositionBackwardsFromElm = function (rootElement, elm) { var startPosition = CaretPosition$1.before(elm.previousSibling ? elm.previousSibling : elm.parentNode); return CaretFinder.prevPosition(rootElement, startPosition).fold(function () { return CaretFinder.nextPosition(rootElement, CaretPosition$1.after(elm)); }, Option.some); }; var findCaretPositionForwardsFromElm = function (rootElement, elm) { return CaretFinder.nextPosition(rootElement, CaretPosition$1.after(elm)).fold(function () { return CaretFinder.prevPosition(rootElement, CaretPosition$1.before(elm)); }, Option.some); }; var findCaretPositionBackwards = function (rootElement, elm) { return getPreviousSiblingCaretPosition(elm).orThunk(function () { return getNextSiblingCaretPosition(elm); }).orThunk(function () { return findCaretPositionBackwardsFromElm(rootElement, elm); }); }; var findCaretPositionForward = function (rootElement, elm) { return getNextSiblingCaretPosition(elm).orThunk(function () { return getPreviousSiblingCaretPosition(elm); }).orThunk(function () { return findCaretPositionForwardsFromElm(rootElement, elm); }); }; var findCaretPosition$1 = function (forward, rootElement, elm) { return forward ? findCaretPositionForward(rootElement, elm) : findCaretPositionBackwards(rootElement, elm); }; var findCaretPosOutsideElmAfterDelete = function (forward, rootElement, elm) { return findCaretPosition$1(forward, rootElement, elm).map(curry(reposition, elm)); }; var setSelection = function (editor, forward, pos) { pos.fold(function () { editor.focus(); }, function (pos) { editor.selection.setRng(pos.toRange(), forward); }); }; var eqRawNode = function (rawNode) { return function (elm) { return elm.dom() === rawNode; }; }; var isBlock$2 = function (editor, elm) { return elm && editor.schema.getBlockElements().hasOwnProperty(name(elm)); }; var paddEmptyBlock = function (elm) { if (Empty.isEmpty(elm)) { var br = Element.fromHtml('<br data-mce-bogus="1">'); empty(elm); append(elm, br); return Option.some(CaretPosition$1.before(br.dom())); } else { return Option.none(); } }; var deleteNormalized = function (elm, afterDeletePosOpt, normalizeWhitespace) { var prevTextOpt = prevSibling(elm).filter(function (e) { return NodeType.isText(e.dom()); }); var nextTextOpt = nextSibling(elm).filter(function (e) { return NodeType.isText(e.dom()); }); remove$1(elm); return liftN([ prevTextOpt, nextTextOpt, afterDeletePosOpt ], function (prev, next, pos) { var prevNode = prev.dom(), nextNode = next.dom(); var offset = prevNode.data.length; mergeTextNodes(prevNode, nextNode, normalizeWhitespace); return pos.container() === nextNode ? CaretPosition$1(prevNode, offset) : pos; }).orThunk(function () { if (normalizeWhitespace) { prevTextOpt.each(function (elm) { return normalizeWhitespaceBefore(elm.dom(), elm.dom().length); }); nextTextOpt.each(function (elm) { return normalizeWhitespaceAfter(elm.dom(), 0); }); } return afterDeletePosOpt; }); }; var isInlineElement = function (editor, element) { return has(editor.schema.getTextInlineElements(), name(element)); }; var deleteElement = function (editor, forward, elm, moveCaret) { if (moveCaret === void 0) { moveCaret = true; } var afterDeletePos = findCaretPosOutsideElmAfterDelete(forward, editor.getBody(), elm.dom()); var parentBlock = ancestor(elm, curry(isBlock$2, editor), eqRawNode(editor.getBody())); var normalizedAfterDeletePos = deleteNormalized(elm, afterDeletePos, isInlineElement(editor, elm)); if (editor.dom.isEmpty(editor.getBody())) { editor.setContent(''); editor.selection.setCursorLocation(); } else { parentBlock.bind(paddEmptyBlock).fold(function () { if (moveCaret) { setSelection(editor, forward, normalizedAfterDeletePos); } }, function (paddPos) { if (moveCaret) { setSelection(editor, forward, Option.some(paddPos)); } }); } }; var DeleteElement = { deleteElement: deleteElement }; var deleteElement$1 = function (editor, forward) { return function (element) { editor._selectionOverrides.hideFakeCaret(); DeleteElement.deleteElement(editor, forward, Element.fromDom(element)); return true; }; }; var moveToElement = function (editor, forward) { return function (element) { var pos = forward ? CaretPosition$1.before(element) : CaretPosition$1.after(element); editor.selection.setRng(pos.toRange()); return true; }; }; var moveToPosition = function (editor) { return function (pos) { editor.selection.setRng(pos.toRange()); return true; }; }; var backspaceDeleteCaret = function (editor, forward) { var result = read$2(editor.getBody(), forward, editor.selection.getRng()).map(function (deleteAction) { return deleteAction.fold(deleteElement$1(editor, forward), moveToElement(editor, forward), moveToPosition(editor)); }); return result.getOr(false); }; var deleteOffscreenSelection = function (rootElement) { each(descendants$1(rootElement, '.mce-offscreen-selection'), remove$1); }; var backspaceDeleteRange = function (editor, forward) { var selectedElement = editor.selection.getNode(); if (NodeType.isContentEditableFalse(selectedElement)) { deleteOffscreenSelection(Element.fromDom(editor.getBody())); DeleteElement.deleteElement(editor, forward, Element.fromDom(editor.selection.getNode())); DeleteUtils.paddEmptyBody(editor); return true; } else { return false; } }; var getContentEditableRoot = function (root, node) { while (node && node !== root) { if (NodeType.isContentEditableTrue(node) || NodeType.isContentEditableFalse(node)) { return node; } node = node.parentNode; } return null; }; var paddEmptyElement = function (editor) { var br; var ceRoot = getContentEditableRoot(editor.getBody(), editor.selection.getNode()); if (NodeType.isContentEditableTrue(ceRoot) && editor.dom.isBlock(ceRoot) && editor.dom.isEmpty(ceRoot)) { br = editor.dom.create('br', { 'data-mce-bogus': '1' }); editor.dom.setHTML(ceRoot, ''); ceRoot.appendChild(br); editor.selection.setRng(CaretPosition$1.before(br).toRange()); } return true; }; var backspaceDelete$2 = function (editor, forward) { if (editor.selection.isCollapsed()) { return backspaceDeleteCaret(editor, forward); } else { return backspaceDeleteRange(editor, forward); } }; var CefDelete = { backspaceDelete: backspaceDelete$2, paddEmptyElement: paddEmptyElement }; var isText$8 = NodeType.isText; var startsWithCaretContainer$1 = function (node) { return isText$8(node) && node.data[0] === Zwsp.ZWSP; }; var endsWithCaretContainer$1 = function (node) { return isText$8(node) && node.data[node.data.length - 1] === Zwsp.ZWSP; }; var createZwsp = function (node) { return node.ownerDocument.createTextNode(Zwsp.ZWSP); }; var insertBefore$1 = function (node) { if (isText$8(node.previousSibling)) { if (endsWithCaretContainer$1(node.previousSibling)) { return node.previousSibling; } else { node.previousSibling.appendData(Zwsp.ZWSP); return node.previousSibling; } } else if (isText$8(node)) { if (startsWithCaretContainer$1(node)) { return node; } else { node.insertData(0, Zwsp.ZWSP); return node; } } else { var newNode = createZwsp(node); node.parentNode.insertBefore(newNode, node); return newNode; } }; var insertAfter$1 = function (node) { if (isText$8(node.nextSibling)) { if (startsWithCaretContainer$1(node.nextSibling)) { return node.nextSibling; } else { node.nextSibling.insertData(0, Zwsp.ZWSP); return node.nextSibling; } } else if (isText$8(node)) { if (endsWithCaretContainer$1(node)) { return node; } else { node.appendData(Zwsp.ZWSP); return node; } } else { var newNode = createZwsp(node); if (node.nextSibling) { node.parentNode.insertBefore(newNode, node.nextSibling); } else { node.parentNode.appendChild(newNode); } return newNode; } }; var insertInline$1 = function (before, node) { return before ? insertBefore$1(node) : insertAfter$1(node); }; var insertInlineBefore = curry(insertInline$1, true); var insertInlineAfter = curry(insertInline$1, false); var insertInlinePos = function (pos, before) { if (NodeType.isText(pos.container())) { return insertInline$1(before, pos.container()); } else { return insertInline$1(before, pos.getNode()); } }; var isPosCaretContainer = function (pos, caret) { var caretNode = caret.get(); return caretNode && pos.container() === caretNode && isCaretContainerInline(caretNode); }; var renderCaret = function (caret, location) { return location.fold(function (element) { CaretContainerRemove.remove(caret.get()); var text = insertInlineBefore(element); caret.set(text); return Option.some(CaretPosition$1(text, text.length - 1)); }, function (element) { return CaretFinder.firstPositionIn(element).map(function (pos) { if (!isPosCaretContainer(pos, caret)) { CaretContainerRemove.remove(caret.get()); var text = insertInlinePos(pos, true); caret.set(text); return CaretPosition$1(text, 1); } else { return CaretPosition$1(caret.get(), 1); } }); }, function (element) { return CaretFinder.lastPositionIn(element).map(function (pos) { if (!isPosCaretContainer(pos, caret)) { CaretContainerRemove.remove(caret.get()); var text = insertInlinePos(pos, false); caret.set(text); return CaretPosition$1(text, text.length - 1); } else { return CaretPosition$1(caret.get(), caret.get().length - 1); } }); }, function (element) { CaretContainerRemove.remove(caret.get()); var text = insertInlineAfter(element); caret.set(text); return Option.some(CaretPosition$1(text, 1)); }); }; var BoundaryCaret = { renderCaret: renderCaret }; var evaluateUntil = function (fns, args) { for (var i = 0; i < fns.length; i++) { var result = fns[i].apply(null, args); if (result.isSome()) { return result; } } return Option.none(); }; var LazyEvaluator = { evaluateUntil: evaluateUntil }; var Location = Adt.generate([ { before: ['element'] }, { start: ['element'] }, { end: ['element'] }, { after: ['element'] } ]); var rescope = function (rootNode, node) { var parentBlock = getParentBlock(node, rootNode); return parentBlock ? parentBlock : rootNode; }; var before$3 = function (isInlineTarget, rootNode, pos) { var nPos = InlineUtils.normalizeForwards(pos); var scope = rescope(rootNode, nPos.container()); return InlineUtils.findRootInline(isInlineTarget, scope, nPos).fold(function () { return CaretFinder.nextPosition(scope, nPos).bind(curry(InlineUtils.findRootInline, isInlineTarget, scope)).map(function (inline) { return Location.before(inline); }); }, Option.none); }; var isNotInsideFormatCaretContainer = function (rootNode, elm) { return getParentCaretContainer(rootNode, elm) === null; }; var findInsideRootInline = function (isInlineTarget, rootNode, pos) { return InlineUtils.findRootInline(isInlineTarget, rootNode, pos).filter(curry(isNotInsideFormatCaretContainer, rootNode)); }; var start = function (isInlineTarget, rootNode, pos) { var nPos = InlineUtils.normalizeBackwards(pos); return findInsideRootInline(isInlineTarget, rootNode, nPos).bind(function (inline) { var prevPos = CaretFinder.prevPosition(inline, nPos); return prevPos.isNone() ? Option.some(Location.start(inline)) : Option.none(); }); }; var end = function (isInlineTarget, rootNode, pos) { var nPos = InlineUtils.normalizeForwards(pos); return findInsideRootInline(isInlineTarget, rootNode, nPos).bind(function (inline) { var nextPos = CaretFinder.nextPosition(inline, nPos); return nextPos.isNone() ? Option.some(Location.end(inline)) : Option.none(); }); }; var after$2 = function (isInlineTarget, rootNode, pos) { var nPos = InlineUtils.normalizeBackwards(pos); var scope = rescope(rootNode, nPos.container()); return InlineUtils.findRootInline(isInlineTarget, scope, nPos).fold(function () { return CaretFinder.prevPosition(scope, nPos).bind(curry(InlineUtils.findRootInline, isInlineTarget, scope)).map(function (inline) { return Location.after(inline); }); }, Option.none); }; var isValidLocation = function (location) { return InlineUtils.isRtl(getElement(location)) === false; }; var readLocation = function (isInlineTarget, rootNode, pos) { var location = LazyEvaluator.evaluateUntil([ before$3, start, end, after$2 ], [ isInlineTarget, rootNode, pos ]); return location.filter(isValidLocation); }; var getElement = function (location) { return location.fold(identity, identity, identity, identity); }; var getName = function (location) { return location.fold(constant('before'), constant('start'), constant('end'), constant('after')); }; var outside = function (location) { return location.fold(Location.before, Location.before, Location.after, Location.after); }; var inside = function (location) { return location.fold(Location.start, Location.start, Location.end, Location.end); }; var isEq$1 = function (location1, location2) { return getName(location1) === getName(location2) && getElement(location1) === getElement(location2); }; var betweenInlines = function (forward, isInlineTarget, rootNode, from, to, location) { return liftN([ InlineUtils.findRootInline(isInlineTarget, rootNode, from), InlineUtils.findRootInline(isInlineTarget, rootNode, to) ], function (fromInline, toInline) { if (fromInline !== toInline && InlineUtils.hasSameParentBlock(rootNode, fromInline, toInline)) { return Location.after(forward ? fromInline : toInline); } else { return location; } }).getOr(location); }; var skipNoMovement = function (fromLocation, toLocation) { return fromLocation.fold(constant(true), function (fromLocation) { return !isEq$1(fromLocation, toLocation); }); }; var findLocationTraverse = function (forward, isInlineTarget, rootNode, fromLocation, pos) { var from = InlineUtils.normalizePosition(forward, pos); var to = CaretFinder.fromPosition(forward, rootNode, from).map(curry(InlineUtils.normalizePosition, forward)); var location = to.fold(function () { return fromLocation.map(outside); }, function (to) { return readLocation(isInlineTarget, rootNode, to).map(curry(betweenInlines, forward, isInlineTarget, rootNode, from, to)).filter(curry(skipNoMovement, fromLocation)); }); return location.filter(isValidLocation); }; var findLocationSimple = function (forward, location) { if (forward) { return location.fold(compose(Option.some, Location.start), Option.none, compose(Option.some, Location.after), Option.none); } else { return location.fold(Option.none, compose(Option.some, Location.before), Option.none, compose(Option.some, Location.end)); } }; var findLocation = function (forward, isInlineTarget, rootNode, pos) { var from = InlineUtils.normalizePosition(forward, pos); var fromLocation = readLocation(isInlineTarget, rootNode, from); return readLocation(isInlineTarget, rootNode, from).bind(curry(findLocationSimple, forward)).orThunk(function () { return findLocationTraverse(forward, isInlineTarget, rootNode, fromLocation, pos); }); }; var BoundaryLocation = { readLocation: readLocation, findLocation: findLocation, prevLocation: curry(findLocation, false), nextLocation: curry(findLocation, true), getElement: getElement, outside: outside, inside: inside }; var hasSelectionModifyApi = function (editor) { return isFunction(editor.selection.getSel().modify); }; var moveRel = function (forward, selection, pos) { var delta = forward ? 1 : -1; selection.setRng(CaretPosition$1(pos.container(), pos.offset() + delta).toRange()); selection.getSel().modify('move', forward ? 'forward' : 'backward', 'word'); return true; }; var moveByWord = function (forward, editor) { var rng = editor.selection.getRng(); var pos = forward ? CaretPosition$1.fromRangeEnd(rng) : CaretPosition$1.fromRangeStart(rng); if (!hasSelectionModifyApi(editor)) { return false; } else if (forward && isBeforeInline(pos)) { return moveRel(true, editor.selection, pos); } else if (!forward && isAfterInline(pos)) { return moveRel(false, editor.selection, pos); } else { return false; } }; var WordSelection = { hasSelectionModifyApi: hasSelectionModifyApi, moveByWord: moveByWord }; var setCaretPosition = function (editor, pos) { var rng = editor.dom.createRng(); rng.setStart(pos.container(), pos.offset()); rng.setEnd(pos.container(), pos.offset()); editor.selection.setRng(rng); }; var isFeatureEnabled = function (editor) { return editor.settings.inline_boundaries !== false; }; var setSelected = function (state, elm) { if (state) { elm.setAttribute('data-mce-selected', 'inline-boundary'); } else { elm.removeAttribute('data-mce-selected'); } }; var renderCaretLocation = function (editor, caret, location) { return BoundaryCaret.renderCaret(caret, location).map(function (pos) { setCaretPosition(editor, pos); return location; }); }; var findLocation$1 = function (editor, caret, forward) { var rootNode = editor.getBody(); var from = CaretPosition$1.fromRangeStart(editor.selection.getRng()); var isInlineTarget = curry(InlineUtils.isInlineTarget, editor); var location = BoundaryLocation.findLocation(forward, isInlineTarget, rootNode, from); return location.bind(function (location) { return renderCaretLocation(editor, caret, location); }); }; var toggleInlines = function (isInlineTarget, dom, elms) { var selectedInlines = filter(dom.select('*[data-mce-selected="inline-boundary"]'), isInlineTarget); var targetInlines = filter(elms, isInlineTarget); each(difference(selectedInlines, targetInlines), curry(setSelected, false)); each(difference(targetInlines, selectedInlines), curry(setSelected, true)); }; var safeRemoveCaretContainer = function (editor, caret) { if (editor.selection.isCollapsed() && editor.composing !== true && caret.get()) { var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng()); if (CaretPosition$1.isTextPosition(pos) && InlineUtils.isAtZwsp(pos) === false) { setCaretPosition(editor, CaretContainerRemove.removeAndReposition(caret.get(), pos)); caret.set(null); } } }; var renderInsideInlineCaret = function (isInlineTarget, editor, caret, elms) { if (editor.selection.isCollapsed()) { var inlines = filter(elms, isInlineTarget); each(inlines, function (inline) { var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng()); BoundaryLocation.readLocation(isInlineTarget, editor.getBody(), pos).bind(function (location) { return renderCaretLocation(editor, caret, location); }); }); } }; var move = function (editor, caret, forward) { return function () { return isFeatureEnabled(editor) ? findLocation$1(editor, caret, forward).isSome() : false; }; }; var moveWord = function (forward, editor, caret) { return function () { return isFeatureEnabled(editor) ? WordSelection.moveByWord(forward, editor) : false; }; }; var setupSelectedState = function (editor) { var caret = Cell(null); var isInlineTarget = curry(InlineUtils.isInlineTarget, editor); editor.on('NodeChange', function (e) { if (isFeatureEnabled(editor)) { toggleInlines(isInlineTarget, editor.dom, e.parents); safeRemoveCaretContainer(editor, caret); renderInsideInlineCaret(isInlineTarget, editor, caret, e.parents); } }); return caret; }; var moveNextWord = curry(moveWord, true); var movePrevWord = curry(moveWord, false); var BoundarySelection = { move: move, moveNextWord: moveNextWord, movePrevWord: movePrevWord, setupSelectedState: setupSelectedState, setCaretPosition: setCaretPosition }; var isFeatureEnabled$1 = function (editor) { return editor.settings.inline_boundaries !== false; }; var rangeFromPositions = function (from, to) { var range = domGlobals.document.createRange(); range.setStart(from.container(), from.offset()); range.setEnd(to.container(), to.offset()); return range; }; var hasOnlyTwoOrLessPositionsLeft = function (elm) { return liftN([ CaretFinder.firstPositionIn(elm), CaretFinder.lastPositionIn(elm) ], function (firstPos, lastPos) { var normalizedFirstPos = InlineUtils.normalizePosition(true, firstPos); var normalizedLastPos = InlineUtils.normalizePosition(false, lastPos); return CaretFinder.nextPosition(elm, normalizedFirstPos).map(function (pos) { return pos.isEqual(normalizedLastPos); }).getOr(true); }).getOr(true); }; var setCaretLocation = function (editor, caret) { return function (location) { return BoundaryCaret.renderCaret(caret, location).map(function (pos) { BoundarySelection.setCaretPosition(editor, pos); return true; }).getOr(false); }; }; var deleteFromTo = function (editor, caret, from, to) { var rootNode = editor.getBody(); var isInlineTarget = curry(InlineUtils.isInlineTarget, editor); editor.undoManager.ignore(function () { editor.selection.setRng(rangeFromPositions(from, to)); editor.execCommand('Delete'); BoundaryLocation.readLocation(isInlineTarget, rootNode, CaretPosition$1.fromRangeStart(editor.selection.getRng())).map(BoundaryLocation.inside).map(setCaretLocation(editor, caret)); }); editor.nodeChanged(); }; var rescope$1 = function (rootNode, node) { var parentBlock = getParentBlock(node, rootNode); return parentBlock ? parentBlock : rootNode; }; var backspaceDeleteCollapsed = function (editor, caret, forward, from) { var rootNode = rescope$1(editor.getBody(), from.container()); var isInlineTarget = curry(InlineUtils.isInlineTarget, editor); var fromLocation = BoundaryLocation.readLocation(isInlineTarget, rootNode, from); return fromLocation.bind(function (location) { if (forward) { return location.fold(constant(Option.some(BoundaryLocation.inside(location))), Option.none, constant(Option.some(BoundaryLocation.outside(location))), Option.none); } else { return location.fold(Option.none, constant(Option.some(BoundaryLocation.outside(location))), Option.none, constant(Option.some(BoundaryLocation.inside(location)))); } }).map(setCaretLocation(editor, caret)).getOrThunk(function () { var toPosition = CaretFinder.navigate(forward, rootNode, from); var toLocation = toPosition.bind(function (pos) { return BoundaryLocation.readLocation(isInlineTarget, rootNode, pos); }); if (fromLocation.isSome() && toLocation.isSome()) { return InlineUtils.findRootInline(isInlineTarget, rootNode, from).map(function (elm) { if (hasOnlyTwoOrLessPositionsLeft(elm)) { DeleteElement.deleteElement(editor, forward, Element.fromDom(elm)); return true; } else { return false; } }).getOr(false); } else { return toLocation.bind(function (_) { return toPosition.map(function (to) { if (forward) { deleteFromTo(editor, caret, from, to); } else { deleteFromTo(editor, caret, to, from); } return true; }); }).getOr(false); } }); }; var backspaceDelete$3 = function (editor, caret, forward) { if (editor.selection.isCollapsed() && isFeatureEnabled$1(editor)) { var from = CaretPosition$1.fromRangeStart(editor.selection.getRng()); return backspaceDeleteCollapsed(editor, caret, forward, from); } return false; }; var InlineBoundaryDelete = { backspaceDelete: backspaceDelete$3 }; var tableCellRng = Immutable('start', 'end'); var tableSelection = Immutable('rng', 'table', 'cells'); var deleteAction = Adt.generate([ { removeTable: ['element'] }, { emptyCells: ['cells'] } ]); var isRootFromElement = function (root) { return curry(eq, root); }; var getClosestCell = function (container, isRoot) { return closest$1(Element.fromDom(container), 'td,th', isRoot); }; var getClosestTable = function (cell, isRoot) { return ancestor$1(cell, 'table', isRoot); }; var isExpandedCellRng = function (cellRng) { return eq(cellRng.start(), cellRng.end()) === false; }; var getTableFromCellRng = function (cellRng, isRoot) { return getClosestTable(cellRng.start(), isRoot).bind(function (startParentTable) { return getClosestTable(cellRng.end(), isRoot).bind(function (endParentTable) { return eq(startParentTable, endParentTable) ? Option.some(startParentTable) : Option.none(); }); }); }; var getTableCells = function (table) { return descendants$1(table, 'td,th'); }; var getCellRangeFromStartTable = function (cellRng, isRoot) { return getClosestTable(cellRng.start(), isRoot).bind(function (table) { return last(getTableCells(table)).map(function (endCell) { return tableCellRng(cellRng.start(), endCell); }); }); }; var partialSelection = function (isRoot, rng) { var startCell = getClosestCell(rng.startContainer, isRoot); var endCell = getClosestCell(rng.endContainer, isRoot); return rng.collapsed ? Option.none() : liftN([ startCell, endCell ], tableCellRng).fold(function () { return startCell.fold(function () { return endCell.bind(function (endCell) { return getClosestTable(endCell, isRoot).bind(function (table) { return head(getTableCells(table)).map(function (startCell) { return tableCellRng(startCell, endCell); }); }); }); }, function (startCell) { return getClosestTable(startCell, isRoot).bind(function (table) { return last(getTableCells(table)).map(function (endCell) { return tableCellRng(startCell, endCell); }); }); }); }, function (cellRng) { return isWithinSameTable(isRoot, cellRng) ? Option.none() : getCellRangeFromStartTable(cellRng, isRoot); }); }; var isWithinSameTable = function (isRoot, cellRng) { return getTableFromCellRng(cellRng, isRoot).isSome(); }; var getCellRng = function (rng, isRoot) { var startCell = getClosestCell(rng.startContainer, isRoot); var endCell = getClosestCell(rng.endContainer, isRoot); return liftN([ startCell, endCell ], tableCellRng).filter(isExpandedCellRng).filter(function (cellRng) { return isWithinSameTable(isRoot, cellRng); }).orThunk(function () { return partialSelection(isRoot, rng); }); }; var getTableSelectionFromCellRng = function (cellRng, isRoot) { return getTableFromCellRng(cellRng, isRoot).map(function (table) { return tableSelection(cellRng, table, getTableCells(table)); }); }; var getTableSelectionFromRng = function (root, rng) { var isRoot = isRootFromElement(root); return getCellRng(rng, isRoot).bind(function (cellRng) { return getTableSelectionFromCellRng(cellRng, isRoot); }); }; var getCellIndex = function (cells, cell) { return findIndex(cells, function (x) { return eq(x, cell); }); }; var getSelectedCells = function (tableSelection) { return liftN([ getCellIndex(tableSelection.cells(), tableSelection.rng().start()), getCellIndex(tableSelection.cells(), tableSelection.rng().end()) ], function (startIndex, endIndex) { return tableSelection.cells().slice(startIndex, endIndex + 1); }); }; var getAction = function (tableSelection) { return getSelectedCells(tableSelection).map(function (selected) { var cells = tableSelection.cells(); return selected.length === cells.length ? deleteAction.removeTable(tableSelection.table()) : deleteAction.emptyCells(selected); }); }; var getActionFromCells = function (cells) { return deleteAction.emptyCells(cells); }; var getActionFromRange = function (root, rng) { return getTableSelectionFromRng(root, rng).bind(getAction); }; var TableDeleteAction = { getActionFromRange: getActionFromRange, getActionFromCells: getActionFromCells }; var getRanges = function (selection) { var ranges = []; if (selection) { for (var i = 0; i < selection.rangeCount; i++) { ranges.push(selection.getRangeAt(i)); } } return ranges; }; var getSelectedNodes = function (ranges) { return bind(ranges, function (range) { var node = getSelectedNode(range); return node ? [Element.fromDom(node)] : []; }); }; var hasMultipleRanges = function (selection) { return getRanges(selection).length > 1; }; var MultiRange = { getRanges: getRanges, getSelectedNodes: getSelectedNodes, hasMultipleRanges: hasMultipleRanges }; var getCellsFromRanges = function (ranges) { return filter(MultiRange.getSelectedNodes(ranges), isTableCell); }; var getCellsFromElement = function (elm) { var selectedCells = descendants$1(elm, 'td[data-mce-selected],th[data-mce-selected]'); return selectedCells; }; var getCellsFromElementOrRanges = function (ranges, element) { var selectedCells = getCellsFromElement(element); var rangeCells = getCellsFromRanges(ranges); return selectedCells.length > 0 ? selectedCells : rangeCells; }; var getCellsFromEditor = function (editor) { return getCellsFromElementOrRanges(MultiRange.getRanges(editor.selection.getSel()), Element.fromDom(editor.getBody())); }; var TableCellSelection = { getCellsFromRanges: getCellsFromRanges, getCellsFromElement: getCellsFromElement, getCellsFromElementOrRanges: getCellsFromElementOrRanges, getCellsFromEditor: getCellsFromEditor }; var emptyCells = function (editor, cells) { each(cells, PaddingBr.fillWithPaddingBr); editor.selection.setCursorLocation(cells[0].dom(), 0); return true; }; var deleteTableElement = function (editor, table) { DeleteElement.deleteElement(editor, false, table); return true; }; var deleteCellRange = function (editor, rootElm, rng) { return TableDeleteAction.getActionFromRange(rootElm, rng).map(function (action) { return action.fold(curry(deleteTableElement, editor), curry(emptyCells, editor)); }); }; var deleteCaptionRange = function (editor, caption) { return emptyElement(editor, caption); }; var deleteTableRange = function (editor, rootElm, rng, startElm) { return getParentCaption(rootElm, startElm).fold(function () { return deleteCellRange(editor, rootElm, rng); }, function (caption) { return deleteCaptionRange(editor, caption); }).getOr(false); }; var deleteRange$1 = function (editor, startElm) { var rootNode = Element.fromDom(editor.getBody()); var rng = editor.selection.getRng(); var selectedCells = TableCellSelection.getCellsFromEditor(editor); return selectedCells.length !== 0 ? emptyCells(editor, selectedCells) : deleteTableRange(editor, rootNode, rng, startElm); }; var getParentCell = function (rootElm, elm) { return find(Parents.parentsAndSelf(elm, rootElm), isTableCell); }; var getParentCaption = function (rootElm, elm) { return find(Parents.parentsAndSelf(elm, rootElm), function (elm) { return name(elm) === 'caption'; }); }; var deleteBetweenCells = function (editor, rootElm, forward, fromCell, from) { return CaretFinder.navigate(forward, editor.getBody(), from).bind(function (to) { return getParentCell(rootElm, Element.fromDom(to.getNode())).map(function (toCell) { return eq(toCell, fromCell) === false; }); }); }; var emptyElement = function (editor, elm) { PaddingBr.fillWithPaddingBr(elm); editor.selection.setCursorLocation(elm.dom(), 0); return Option.some(true); }; var isDeleteOfLastCharPos = function (fromCaption, forward, from, to) { return CaretFinder.firstPositionIn(fromCaption.dom()).bind(function (first) { return CaretFinder.lastPositionIn(fromCaption.dom()).map(function (last) { return forward ? from.isEqual(first) && to.isEqual(last) : from.isEqual(last) && to.isEqual(first); }); }).getOr(true); }; var emptyCaretCaption = function (editor, elm) { return emptyElement(editor, elm); }; var validateCaretCaption = function (rootElm, fromCaption, to) { return getParentCaption(rootElm, Element.fromDom(to.getNode())).map(function (toCaption) { return eq(toCaption, fromCaption) === false; }); }; var deleteCaretInsideCaption = function (editor, rootElm, forward, fromCaption, from) { return CaretFinder.navigate(forward, editor.getBody(), from).bind(function (to) { return isDeleteOfLastCharPos(fromCaption, forward, from, to) ? emptyCaretCaption(editor, fromCaption) : validateCaretCaption(rootElm, fromCaption, to); }).or(Option.some(true)); }; var deleteCaretCells = function (editor, forward, rootElm, startElm) { var from = CaretPosition$1.fromRangeStart(editor.selection.getRng()); return getParentCell(rootElm, startElm).bind(function (fromCell) { return Empty.isEmpty(fromCell) ? emptyElement(editor, fromCell) : deleteBetweenCells(editor, rootElm, forward, fromCell, from); }); }; var deleteCaretCaption = function (editor, forward, rootElm, fromCaption) { var from = CaretPosition$1.fromRangeStart(editor.selection.getRng()); return Empty.isEmpty(fromCaption) ? emptyElement(editor, fromCaption) : deleteCaretInsideCaption(editor, rootElm, forward, fromCaption, from); }; var deleteCaret = function (editor, forward, startElm) { var rootElm = Element.fromDom(editor.getBody()); return getParentCaption(rootElm, startElm).fold(function () { return deleteCaretCells(editor, forward, rootElm, startElm); }, function (fromCaption) { return deleteCaretCaption(editor, forward, rootElm, fromCaption); }).getOr(false); }; var backspaceDelete$4 = function (editor, forward) { var startElm = Element.fromDom(editor.selection.getStart(true)); var cells = TableCellSelection.getCellsFromEditor(editor); return editor.selection.isCollapsed() && cells.length === 0 ? deleteCaret(editor, forward, startElm) : deleteRange$1(editor, startElm); }; var TableDelete = { backspaceDelete: backspaceDelete$4 }; var isEq$2 = FormatUtils.isEq; var matchesUnInheritedFormatSelector = function (ed, node, name) { var formatList = ed.formatter.get(name); if (formatList) { for (var i = 0; i < formatList.length; i++) { if (formatList[i].inherit === false && ed.dom.is(node, formatList[i].selector)) { return true; } } } return false; }; var matchParents = function (editor, node, name, vars) { var root = editor.dom.getRoot(); if (node === root) { return false; } node = editor.dom.getParent(node, function (node) { if (matchesUnInheritedFormatSelector(editor, node, name)) { return true; } return node.parentNode === root || !!matchNode(editor, node, name, vars, true); }); return matchNode(editor, node, name, vars); }; var matchName = function (dom, node, format) { if (isEq$2(node, format.inline)) { return true; } if (isEq$2(node, format.block)) { return true; } if (format.selector) { return node.nodeType === 1 && dom.is(node, format.selector); } }; var matchItems = function (dom, node, format, itemName, similar, vars) { var key, value; var items = format[itemName]; var i; if (format.onmatch) { return format.onmatch(node, format, itemName); } if (items) { if (typeof items.length === 'undefined') { for (key in items) { if (items.hasOwnProperty(key)) { if (itemName === 'attributes') { value = dom.getAttrib(node, key); } else { value = FormatUtils.getStyle(dom, node, key); } if (similar && !value && !format.exact) { return; } if ((!similar || format.exact) && !isEq$2(value, FormatUtils.normalizeStyleValue(dom, FormatUtils.replaceVars(items[key], vars), key))) { return; } } } } else { for (i = 0; i < items.length; i++) { if (itemName === 'attributes' ? dom.getAttrib(node, items[i]) : FormatUtils.getStyle(dom, node, items[i])) { return format; } } } } return format; }; var matchNode = function (ed, node, name, vars, similar) { var formatList = ed.formatter.get(name); var format, i, x, classes; var dom = ed.dom; if (formatList && node) { for (i = 0; i < formatList.length; i++) { format = formatList[i]; if (matchName(ed.dom, node, format) && matchItems(dom, node, format, 'attributes', similar, vars) && matchItems(dom, node, format, 'styles', similar, vars)) { if (classes = format.classes) { for (x = 0; x < classes.length; x++) { if (!ed.dom.hasClass(node, classes[x])) { return; } } } return format; } } } }; var match = function (editor, name, vars, node) { var startNode; if (node) { return matchParents(editor, node, name, vars); } node = editor.selection.getNode(); if (matchParents(editor, node, name, vars)) { return true; } startNode = editor.selection.getStart(); if (startNode !== node) { if (matchParents(editor, startNode, name, vars)) { return true; } } return false; }; var matchAll = function (editor, names, vars) { var startElement; var matchedFormatNames = []; var checkedMap = {}; startElement = editor.selection.getStart(); editor.dom.getParent(startElement, function (node) { var i, name; for (i = 0; i < names.length; i++) { name = names[i]; if (!checkedMap[name] && matchNode(editor, node, name, vars)) { checkedMap[name] = true; matchedFormatNames.push(name); } } }, editor.dom.getRoot()); return matchedFormatNames; }; var canApply = function (editor, name) { var formatList = editor.formatter.get(name); var startNode, parents, i, x, selector; var dom = editor.dom; if (formatList) { startNode = editor.selection.getStart(); parents = FormatUtils.getParents(dom, startNode); for (x = formatList.length - 1; x >= 0; x--) { selector = formatList[x].selector; if (!selector || formatList[x].defaultBlock) { return true; } for (i = parents.length - 1; i >= 0; i--) { if (dom.is(parents[i], selector)) { return true; } } } } return false; }; var MatchFormat = { matchNode: matchNode, matchName: matchName, match: match, matchAll: matchAll, canApply: canApply, matchesUnInheritedFormatSelector: matchesUnInheritedFormatSelector }; var splitText = function (node, offset) { return node.splitText(offset); }; var split$1 = function (rng) { var startContainer = rng.startContainer, startOffset = rng.startOffset, endContainer = rng.endContainer, endOffset = rng.endOffset; if (startContainer === endContainer && NodeType.isText(startContainer)) { if (startOffset > 0 && startOffset < startContainer.nodeValue.length) { endContainer = splitText(startContainer, startOffset); startContainer = endContainer.previousSibling; if (endOffset > startOffset) { endOffset = endOffset - startOffset; startContainer = endContainer = splitText(endContainer, endOffset).previousSibling; endOffset = endContainer.nodeValue.length; startOffset = 0; } else { endOffset = 0; } } } else { if (NodeType.isText(startContainer) && startOffset > 0 && startOffset < startContainer.nodeValue.length) { startContainer = splitText(startContainer, startOffset); startOffset = 0; } if (NodeType.isText(endContainer) && endOffset > 0 && endOffset < endContainer.nodeValue.length) { endContainer = splitText(endContainer, endOffset).previousSibling; endOffset = endContainer.nodeValue.length; } } return { startContainer: startContainer, startOffset: startOffset, endContainer: endContainer, endOffset: endOffset }; }; var SplitRange = { split: split$1 }; var ZWSP$1 = Zwsp.ZWSP, CARET_ID$1 = '_mce_caret'; var importNode = function (ownerDocument, node) { return ownerDocument.importNode(node, true); }; var getEmptyCaretContainers = function (node) { var nodes = []; while (node) { if (node.nodeType === 3 && node.nodeValue !== ZWSP$1 || node.childNodes.length > 1) { return []; } if (node.nodeType === 1) { nodes.push(node); } node = node.firstChild; } return nodes; }; var isCaretContainerEmpty = function (node) { return getEmptyCaretContainers(node).length > 0; }; var findFirstTextNode = function (node) { var walker; if (node) { walker = new TreeWalker(node, node); for (node = walker.current(); node; node = walker.next()) { if (node.nodeType === 3) { return node; } } } return null; }; var createCaretContainer = function (fill) { var caretContainer = Element.fromTag('span'); setAll(caretContainer, { 'id': CARET_ID$1, 'data-mce-bogus': '1', 'data-mce-type': 'format-caret' }); if (fill) { append(caretContainer, Element.fromText(ZWSP$1)); } return caretContainer; }; var trimZwspFromCaretContainer = function (caretContainerNode) { var textNode = findFirstTextNode(caretContainerNode); if (textNode && textNode.nodeValue.charAt(0) === ZWSP$1) { textNode.deleteData(0, 1); } return textNode; }; var removeCaretContainerNode = function (editor, node, moveCaret) { if (moveCaret === void 0) { moveCaret = true; } var dom = editor.dom, selection = editor.selection; if (isCaretContainerEmpty(node)) { DeleteElement.deleteElement(editor, false, Element.fromDom(node), moveCaret); } else { var rng = selection.getRng(); var block = dom.getParent(node, dom.isBlock); var textNode = trimZwspFromCaretContainer(node); if (rng.startContainer === textNode && rng.startOffset > 0) { rng.setStart(textNode, rng.startOffset - 1); } if (rng.endContainer === textNode && rng.endOffset > 0) { rng.setEnd(textNode, rng.endOffset - 1); } dom.remove(node, true); if (block && dom.isEmpty(block)) { PaddingBr.fillWithPaddingBr(Element.fromDom(block)); } selection.setRng(rng); } }; var removeCaretContainer = function (editor, node, moveCaret) { if (moveCaret === void 0) { moveCaret = true; } var dom = editor.dom, selection = editor.selection; if (!node) { node = getParentCaretContainer(editor.getBody(), selection.getStart()); if (!node) { while (node = dom.get(CARET_ID$1)) { removeCaretContainerNode(editor, node, false); } } } else { removeCaretContainerNode(editor, node, moveCaret); } }; var insertCaretContainerNode = function (editor, caretContainer, formatNode) { var dom = editor.dom, block = dom.getParent(formatNode, curry(FormatUtils.isTextBlock, editor)); if (block && dom.isEmpty(block)) { formatNode.parentNode.replaceChild(caretContainer, formatNode); } else { PaddingBr.removeTrailingBr(Element.fromDom(formatNode)); if (dom.isEmpty(formatNode)) { formatNode.parentNode.replaceChild(caretContainer, formatNode); } else { dom.insertAfter(caretContainer, formatNode); } } }; var appendNode = function (parentNode, node) { parentNode.appendChild(node); return node; }; var insertFormatNodesIntoCaretContainer = function (formatNodes, caretContainer) { var innerMostFormatNode = foldr(formatNodes, function (parentNode, formatNode) { return appendNode(parentNode, formatNode.cloneNode(false)); }, caretContainer); return appendNode(innerMostFormatNode, innerMostFormatNode.ownerDocument.createTextNode(ZWSP$1)); }; var applyCaretFormat = function (editor, name, vars) { var rng, caretContainer, textNode, offset, bookmark, container, text; var selection = editor.selection; rng = selection.getRng(true); offset = rng.startOffset; container = rng.startContainer; text = container.nodeValue; caretContainer = getParentCaretContainer(editor.getBody(), selection.getStart()); if (caretContainer) { textNode = findFirstTextNode(caretContainer); } var wordcharRegex = /[^\s\u00a0\u00ad\u200b\ufeff]/; if (text && offset > 0 && offset < text.length && wordcharRegex.test(text.charAt(offset)) && wordcharRegex.test(text.charAt(offset - 1))) { bookmark = selection.getBookmark(); rng.collapse(true); rng = ExpandRange.expandRng(editor, rng, editor.formatter.get(name)); rng = SplitRange.split(rng); editor.formatter.apply(name, vars, rng); selection.moveToBookmark(bookmark); } else { if (!caretContainer || textNode.nodeValue !== ZWSP$1) { caretContainer = importNode(editor.getDoc(), createCaretContainer(true).dom()); textNode = caretContainer.firstChild; rng.insertNode(caretContainer); offset = 1; editor.formatter.apply(name, vars, caretContainer); } else { editor.formatter.apply(name, vars, caretContainer); } selection.setCursorLocation(textNode, offset); } }; var removeCaretFormat = function (editor, name, vars, similar) { var dom = editor.dom, selection = editor.selection; var container, offset, bookmark; var hasContentAfter, node, formatNode; var parents = [], rng = selection.getRng(); var caretContainer; container = rng.startContainer; offset = rng.startOffset; node = container; if (container.nodeType === 3) { if (offset !== container.nodeValue.length) { hasContentAfter = true; } node = node.parentNode; } while (node) { if (MatchFormat.matchNode(editor, node, name, vars, similar)) { formatNode = node; break; } if (node.nextSibling) { hasContentAfter = true; } parents.push(node); node = node.parentNode; } if (!formatNode) { return; } if (hasContentAfter) { bookmark = selection.getBookmark(); rng.collapse(true); var expandedRng = ExpandRange.expandRng(editor, rng, editor.formatter.get(name), true); expandedRng = SplitRange.split(expandedRng); editor.formatter.remove(name, vars, expandedRng); selection.moveToBookmark(bookmark); } else { caretContainer = getParentCaretContainer(editor.getBody(), formatNode); var newCaretContainer = createCaretContainer(false).dom(); var caretNode = insertFormatNodesIntoCaretContainer(parents, newCaretContainer); if (caretContainer) { insertCaretContainerNode(editor, newCaretContainer, caretContainer); } else { insertCaretContainerNode(editor, newCaretContainer, formatNode); } removeCaretContainerNode(editor, caretContainer, false); selection.setCursorLocation(caretNode, 1); if (dom.isEmpty(formatNode)) { dom.remove(formatNode); } } }; var disableCaretContainer = function (editor, keyCode) { var selection = editor.selection, body = editor.getBody(); removeCaretContainer(editor, null, false); if ((keyCode === 8 || keyCode === 46) && selection.isCollapsed() && selection.getStart().innerHTML === ZWSP$1) { removeCaretContainer(editor, getParentCaretContainer(body, selection.getStart())); } if (keyCode === 37 || keyCode === 39) { removeCaretContainer(editor, getParentCaretContainer(body, selection.getStart())); } }; var setup$2 = function (editor) { editor.on('mouseup keydown', function (e) { disableCaretContainer(editor, e.keyCode); }); }; var replaceWithCaretFormat = function (targetNode, formatNodes) { var caretContainer = createCaretContainer(false); var innerMost = insertFormatNodesIntoCaretContainer(formatNodes, caretContainer.dom()); before(Element.fromDom(targetNode), caretContainer); remove$1(Element.fromDom(targetNode)); return CaretPosition$1(innerMost, 0); }; var isFormatElement = function (editor, element) { var inlineElements = editor.schema.getTextInlineElements(); return inlineElements.hasOwnProperty(name(element)) && !isCaretNode(element.dom()) && !NodeType.isBogus(element.dom()); }; var isEmptyCaretFormatElement = function (element) { return isCaretNode(element.dom()) && isCaretContainerEmpty(element.dom()); }; var getParentInlines = function (rootElm, startElm) { var parents = Parents.parentsAndSelf(startElm, rootElm); return findIndex(parents, isBlock).fold(constant(parents), function (index) { return parents.slice(0, index); }); }; var hasOnlyOneChild$1 = function (elm) { return children(elm).length === 1; }; var deleteLastPosition = function (forward, editor, target, parentInlines) { var isFormatElement$1 = curry(isFormatElement, editor); var formatNodes = map(filter(parentInlines, isFormatElement$1), function (elm) { return elm.dom(); }); if (formatNodes.length === 0) { DeleteElement.deleteElement(editor, forward, target); } else { var pos = replaceWithCaretFormat(target.dom(), formatNodes); editor.selection.setRng(pos.toRange()); } }; var deleteCaret$1 = function (editor, forward) { var rootElm = Element.fromDom(editor.getBody()); var startElm = Element.fromDom(editor.selection.getStart()); var parentInlines = filter(getParentInlines(rootElm, startElm), hasOnlyOneChild$1); return last(parentInlines).map(function (target) { var fromPos = CaretPosition$1.fromRangeStart(editor.selection.getRng()); if (DeleteUtils.willDeleteLastPositionInElement(forward, fromPos, target.dom()) && !isEmptyCaretFormatElement(target)) { deleteLastPosition(forward, editor, target, parentInlines); return true; } else { return false; } }).getOr(false); }; var backspaceDelete$5 = function (editor, forward) { return editor.selection.isCollapsed() ? deleteCaret$1(editor, forward) : false; }; var InlineFormatDelete = { backspaceDelete: backspaceDelete$5 }; var isContentEditableTrue$2 = NodeType.isContentEditableTrue; var isContentEditableFalse$6 = NodeType.isContentEditableFalse; var showCaret = function (direction, editor, node, before, scrollIntoView) { return editor._selectionOverrides.showCaret(direction, node, before, scrollIntoView); }; var getNodeRange = function (node) { var rng = node.ownerDocument.createRange(); rng.selectNode(node); return rng; }; var selectNode = function (editor, node) { var e = editor.fire('BeforeObjectSelected', { target: node }); if (e.isDefaultPrevented()) { return null; } return getNodeRange(node); }; var renderCaretAtRange = function (editor, range, scrollIntoView) { var normalizedRange = normalizeRange(1, editor.getBody(), range); var caretPosition = CaretPosition$1.fromRangeStart(normalizedRange); var caretPositionNode = caretPosition.getNode(); if (isContentEditableFalse$6(caretPositionNode)) { return showCaret(1, editor, caretPositionNode, !caretPosition.isAtEnd(), false); } var caretPositionBeforeNode = caretPosition.getNode(true); if (isContentEditableFalse$6(caretPositionBeforeNode)) { return showCaret(1, editor, caretPositionBeforeNode, false, false); } var ceRoot = editor.dom.getParent(caretPosition.getNode(), function (node) { return isContentEditableFalse$6(node) || isContentEditableTrue$2(node); }); if (isContentEditableFalse$6(ceRoot)) { return showCaret(1, editor, ceRoot, false, scrollIntoView); } return null; }; var renderRangeCaret = function (editor, range, scrollIntoView) { if (!range || !range.collapsed) { return range; } var caretRange = renderCaretAtRange(editor, range, scrollIntoView); if (caretRange) { return caretRange; } return range; }; var trimEmptyTextNode$1 = function (dom, node) { if (NodeType.isText(node) && node.data.length === 0) { dom.remove(node); } }; var deleteContentAndShowCaret = function (editor, range, node, direction, forward, peekCaretPosition) { var caretRange = showCaret(direction, editor, peekCaretPosition.getNode(!forward), forward, true); if (range.collapsed) { var deleteRange = range.cloneRange(); if (forward) { deleteRange.setEnd(caretRange.startContainer, caretRange.startOffset); } else { deleteRange.setStart(caretRange.endContainer, caretRange.endOffset); } deleteRange.deleteContents(); } else { range.deleteContents(); } editor.selection.setRng(caretRange); trimEmptyTextNode$1(editor.dom, node); return true; }; var deleteCefBoundaryText = function (editor, forward) { var range = editor.selection.getRng(); if (!NodeType.isText(range.commonAncestorContainer)) { return false; } var direction = forward ? HDirection.Forwards : HDirection.Backwards; var caretWalker = CaretWalker(editor.getBody()); var getNextVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.next); var getPrevVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.prev); var getNextPosFn = forward ? getNextVisualCaretPosition : getPrevVisualCaretPosition; var isBeforeContentEditableFalseFn = forward ? isBeforeContentEditableFalse : isAfterContentEditableFalse; var caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range); var nextCaretPosition = InlineUtils.normalizePosition(forward, getNextPosFn(caretPosition)); if (!nextCaretPosition) { return false; } else if (isBeforeContentEditableFalseFn(nextCaretPosition)) { return deleteContentAndShowCaret(editor, range, caretPosition.getNode(), direction, forward, nextCaretPosition); } var peekCaretPosition = getNextPosFn(nextCaretPosition); if (peekCaretPosition && isBeforeContentEditableFalseFn(peekCaretPosition)) { if (isMoveInsideSameBlock(nextCaretPosition, peekCaretPosition)) { return deleteContentAndShowCaret(editor, range, caretPosition.getNode(), direction, forward, peekCaretPosition); } } return false; }; var backspaceDelete$6 = function (editor, forward) { return deleteCefBoundaryText(editor, forward); }; var CefBoundaryDelete = { backspaceDelete: backspaceDelete$6 }; var nativeCommand = function (editor, command) { editor.getDoc().execCommand(command, false, null); }; var deleteCommand = function (editor) { if (CefDelete.backspaceDelete(editor, false)) { return; } else if (CefBoundaryDelete.backspaceDelete(editor, false)) { return; } else if (InlineBoundaryDelete.backspaceDelete(editor, false)) { return; } else if (BlockBoundaryDelete.backspaceDelete(editor, false)) { return; } else if (TableDelete.backspaceDelete(editor)) { return; } else if (BlockRangeDelete.backspaceDelete(editor, false)) { return; } else if (InlineFormatDelete.backspaceDelete(editor, false)) { return; } else { nativeCommand(editor, 'Delete'); DeleteUtils.paddEmptyBody(editor); } }; var forwardDeleteCommand = function (editor) { if (CefDelete.backspaceDelete(editor, true)) { return; } else if (CefBoundaryDelete.backspaceDelete(editor, true)) { return; } else if (InlineBoundaryDelete.backspaceDelete(editor, true)) { return; } else if (BlockBoundaryDelete.backspaceDelete(editor, true)) { return; } else if (TableDelete.backspaceDelete(editor)) { return; } else if (BlockRangeDelete.backspaceDelete(editor, true)) { return; } else if (InlineFormatDelete.backspaceDelete(editor, true)) { return; } else { nativeCommand(editor, 'ForwardDelete'); } }; var DeleteCommands = { deleteCommand: deleteCommand, forwardDeleteCommand: forwardDeleteCommand }; var getBodySetting = function (editor, name, defaultValue) { var value = editor.getParam(name, defaultValue); if (value.indexOf('=') !== -1) { var bodyObj = editor.getParam(name, '', 'hash'); return bodyObj.hasOwnProperty(editor.id) ? bodyObj[editor.id] : defaultValue; } else { return value; } }; var getIframeAttrs = function (editor) { return editor.getParam('iframe_attrs', {}); }; var getDocType = function (editor) { return editor.getParam('doctype', '<!DOCTYPE html>'); }; var getDocumentBaseUrl = function (editor) { return editor.getParam('document_base_url', ''); }; var getBodyId = function (editor) { return getBodySetting(editor, 'body_id', 'tinymce'); }; var getBodyClass = function (editor) { return getBodySetting(editor, 'body_class', ''); }; var getContentSecurityPolicy = function (editor) { return editor.getParam('content_security_policy', ''); }; var shouldPutBrInPre = function (editor) { return editor.getParam('br_in_pre', true); }; var getForcedRootBlock = function (editor) { if (editor.getParam('force_p_newlines', false)) { return 'p'; } var block = editor.getParam('forced_root_block', 'p'); return block === false ? '' : block; }; var getForcedRootBlockAttrs = function (editor) { return editor.getParam('forced_root_block_attrs', {}); }; var getBrNewLineSelector = function (editor) { return editor.getParam('br_newline_selector', '.mce-toc h2,figcaption,caption'); }; var getNoNewLineSelector = function (editor) { return editor.getParam('no_newline_selector', ''); }; var shouldKeepStyles = function (editor) { return editor.getParam('keep_styles', true); }; var shouldEndContainerOnEmptyBlock = function (editor) { return editor.getParam('end_container_on_empty_block', false); }; var getFontStyleValues = function (editor) { return Tools.explode(editor.getParam('font_size_style_values', '')); }; var getFontSizeClasses = function (editor) { return Tools.explode(editor.getParam('font_size_classes', '')); }; var getImagesDataImgFilter = function (editor) { return editor.getParam('images_dataimg_filter', constant(true), 'function'); }; var isAutomaticUploadsEnabled = function (editor) { return editor.getParam('automatic_uploads', true, 'boolean'); }; var shouldReuseFileName = function (editor) { return editor.getParam('images_reuse_filename', false, 'boolean'); }; var shouldReplaceBlobUris = function (editor) { return editor.getParam('images_replace_blob_uris', true, 'boolean'); }; var getImageUploadUrl = function (editor) { return editor.getParam('images_upload_url', '', 'string'); }; var getImageUploadBasePath = function (editor) { return editor.getParam('images_upload_base_path', '', 'string'); }; var getImagesUploadCredentials = function (editor) { return editor.getParam('images_upload_credentials', false, 'boolean'); }; var getImagesUploadHandler = function (editor) { return editor.getParam('images_upload_handler', null, 'function'); }; var shouldUseContentCssCors = function (editor) { return editor.getParam('content_css_cors', false, 'boolean'); }; var Settings = { getIframeAttrs: getIframeAttrs, getDocType: getDocType, getDocumentBaseUrl: getDocumentBaseUrl, getBodyId: getBodyId, getBodyClass: getBodyClass, getContentSecurityPolicy: getContentSecurityPolicy, shouldPutBrInPre: shouldPutBrInPre, getForcedRootBlock: getForcedRootBlock, getForcedRootBlockAttrs: getForcedRootBlockAttrs, getBrNewLineSelector: getBrNewLineSelector, getNoNewLineSelector: getNoNewLineSelector, shouldKeepStyles: shouldKeepStyles, shouldEndContainerOnEmptyBlock: shouldEndContainerOnEmptyBlock, getFontStyleValues: getFontStyleValues, getFontSizeClasses: getFontSizeClasses, getImagesDataImgFilter: getImagesDataImgFilter, isAutomaticUploadsEnabled: isAutomaticUploadsEnabled, shouldReuseFileName: shouldReuseFileName, shouldReplaceBlobUris: shouldReplaceBlobUris, getImageUploadUrl: getImageUploadUrl, getImageUploadBasePath: getImageUploadBasePath, getImagesUploadCredentials: getImagesUploadCredentials, getImagesUploadHandler: getImagesUploadHandler, shouldUseContentCssCors: shouldUseContentCssCors }; var getSpecifiedFontProp = function (propName, rootElm, elm) { var getProperty = function (elm) { return getRaw(elm, propName); }; var isRoot = function (elm) { return eq(Element.fromDom(rootElm), elm); }; return closest(Element.fromDom(elm), function (elm) { return getProperty(elm).isSome(); }, isRoot).bind(getProperty); }; var round$1 = function (number, precision) { var factor = Math.pow(10, precision); return Math.round(number * factor) / factor; }; var toPt = function (fontSize, precision) { if (/[0-9.]+px$/.test(fontSize)) { return round$1(parseInt(fontSize, 10) * 72 / 96, precision || 0) + 'pt'; } return fontSize; }; var normalizeFontFamily = function (fontFamily) { return fontFamily.replace(/[\'\"\\]/g, '').replace(/,\s+/g, ','); }; var getComputedFontProp = function (propName, elm) { return Option.from(DOMUtils$1.DOM.getStyle(elm, propName, true)); }; var getFontProp = function (propName) { return function (rootElm, elm) { return Option.from(elm).map(Element.fromDom).filter(isElement).bind(function (element) { return getSpecifiedFontProp(propName, rootElm, element.dom()).or(getComputedFontProp(propName, element.dom())); }).getOr(''); }; }; var FontInfo = { getFontSize: getFontProp('font-size'), getFontFamily: compose(normalizeFontFamily, getFontProp('font-family')), toPt: toPt }; var findFirstCaretElement = function (editor) { return CaretFinder.firstPositionIn(editor.getBody()).map(function (caret) { var container = caret.container(); return NodeType.isText(container) ? container.parentNode : container; }); }; var isRangeAtStartOfNode = function (rng, root) { return rng.startContainer === root && rng.startOffset === 0; }; var getCaretElement = function (editor) { return Option.from(editor.selection.getRng()).bind(function (rng) { var root = editor.getBody(); return isRangeAtStartOfNode(rng, root) ? Option.none() : Option.from(editor.selection.getStart(true)); }); }; var fromFontSizeNumber = function (editor, value) { if (/^[0-9\.]+$/.test(value)) { var fontSizeNumber = parseInt(value, 10); if (fontSizeNumber >= 1 && fontSizeNumber <= 7) { var fontSizes = Settings.getFontStyleValues(editor); var fontClasses = Settings.getFontSizeClasses(editor); if (fontClasses) { return fontClasses[fontSizeNumber - 1] || value; } else { return fontSizes[fontSizeNumber - 1] || value; } } else { return value; } } else { return value; } }; var fontNameAction = function (editor, value) { editor.formatter.toggle('fontname', { value: fromFontSizeNumber(editor, value) }); editor.nodeChanged(); }; var fontNameQuery = function (editor) { return getCaretElement(editor).fold(function () { return findFirstCaretElement(editor).map(function (caretElement) { return FontInfo.getFontFamily(editor.getBody(), caretElement); }).getOr(''); }, function (caretElement) { return FontInfo.getFontFamily(editor.getBody(), caretElement); }); }; var fontSizeAction = function (editor, value) { editor.formatter.toggle('fontsize', { value: fromFontSizeNumber(editor, value) }); editor.nodeChanged(); }; var fontSizeQuery = function (editor) { return getCaretElement(editor).fold(function () { return findFirstCaretElement(editor).map(function (caretElement) { return FontInfo.getFontSize(editor.getBody(), caretElement); }).getOr(''); }, function (caretElement) { return FontInfo.getFontSize(editor.getBody(), caretElement); }); }; var isEq$3 = function (rng1, rng2) { return rng1 && rng2 && (rng1.startContainer === rng2.startContainer && rng1.startOffset === rng2.startOffset) && (rng1.endContainer === rng2.endContainer && rng1.endOffset === rng2.endOffset); }; var RangeCompare = { isEq: isEq$3 }; var findParent = function (node, rootNode, predicate) { while (node && node !== rootNode) { if (predicate(node)) { return node; } node = node.parentNode; } return null; }; var hasParent = function (node, rootNode, predicate) { return findParent(node, rootNode, predicate) !== null; }; var hasParentWithName = function (node, rootNode, name) { return hasParent(node, rootNode, function (node) { return node.nodeName === name; }); }; var isTable$2 = function (node) { return node && node.nodeName === 'TABLE'; }; var isTableCell$3 = function (node) { return node && /^(TD|TH|CAPTION)$/.test(node.nodeName); }; var isCeFalseCaretContainer = function (node, rootNode) { return isCaretContainer(node) && hasParent(node, rootNode, isCaretNode) === false; }; var hasBrBeforeAfter = function (dom, node, left) { var walker = new TreeWalker(node, dom.getParent(node.parentNode, dom.isBlock) || dom.getRoot()); while (node = walker[left ? 'prev' : 'next']()) { if (NodeType.isBr(node)) { return true; } } }; var isPrevNode = function (node, name) { return node.previousSibling && node.previousSibling.nodeName === name; }; var hasContentEditableFalseParent = function (body, node) { while (node && node !== body) { if (NodeType.isContentEditableFalse(node)) { return true; } node = node.parentNode; } return false; }; var findTextNodeRelative = function (dom, isAfterNode, collapsed, left, startNode) { var walker, lastInlineElement, parentBlockContainer; var body = dom.getRoot(); var node; var nonEmptyElementsMap = dom.schema.getNonEmptyElements(); parentBlockContainer = dom.getParent(startNode.parentNode, dom.isBlock) || body; if (left && NodeType.isBr(startNode) && isAfterNode && dom.isEmpty(parentBlockContainer)) { return Option.some(CaretPosition(startNode.parentNode, dom.nodeIndex(startNode))); } walker = new TreeWalker(startNode, parentBlockContainer); while (node = walker[left ? 'prev' : 'next']()) { if (dom.getContentEditableParent(node) === 'false' || isCeFalseCaretContainer(node, body)) { return Option.none(); } if (NodeType.isText(node) && node.nodeValue.length > 0) { if (hasParentWithName(node, body, 'A') === false) { return Option.some(CaretPosition(node, left ? node.nodeValue.length : 0)); } return Option.none(); } if (dom.isBlock(node) || nonEmptyElementsMap[node.nodeName.toLowerCase()]) { return Option.none(); } lastInlineElement = node; } if (collapsed && lastInlineElement) { return Option.some(CaretPosition(lastInlineElement, 0)); } return Option.none(); }; var normalizeEndPoint = function (dom, collapsed, start, rng) { var container, offset, walker; var body = dom.getRoot(); var node, nonEmptyElementsMap; var directionLeft, isAfterNode, normalized = false; container = rng[(start ? 'start' : 'end') + 'Container']; offset = rng[(start ? 'start' : 'end') + 'Offset']; isAfterNode = NodeType.isElement(container) && offset === container.childNodes.length; nonEmptyElementsMap = dom.schema.getNonEmptyElements(); directionLeft = start; if (isCaretContainer(container)) { return Option.none(); } if (NodeType.isElement(container) && offset > container.childNodes.length - 1) { directionLeft = false; } if (NodeType.isDocument(container)) { container = body; offset = 0; } if (container === body) { if (directionLeft) { node = container.childNodes[offset > 0 ? offset - 1 : 0]; if (node) { if (isCaretContainer(node)) { return Option.none(); } if (nonEmptyElementsMap[node.nodeName] || isTable$2(node)) { return Option.none(); } } } if (container.hasChildNodes()) { offset = Math.min(!directionLeft && offset > 0 ? offset - 1 : offset, container.childNodes.length - 1); container = container.childNodes[offset]; offset = NodeType.isText(container) && isAfterNode ? container.data.length : 0; if (!collapsed && container === body.lastChild && isTable$2(container)) { return Option.none(); } if (hasContentEditableFalseParent(body, container) || isCaretContainer(container)) { return Option.none(); } if (container.hasChildNodes() && isTable$2(container) === false) { node = container; walker = new TreeWalker(container, body); do { if (NodeType.isContentEditableFalse(node) || isCaretContainer(node)) { normalized = false; break; } if (NodeType.isText(node) && node.nodeValue.length > 0) { offset = directionLeft ? 0 : node.nodeValue.length; container = node; normalized = true; break; } if (nonEmptyElementsMap[node.nodeName.toLowerCase()] && !isTableCell$3(node)) { offset = dom.nodeIndex(node); container = node.parentNode; if (!directionLeft) { offset++; } normalized = true; break; } } while (node = directionLeft ? walker.next() : walker.prev()); } } } if (collapsed) { if (NodeType.isText(container) && offset === 0) { findTextNodeRelative(dom, isAfterNode, collapsed, true, container).each(function (pos) { container = pos.container(); offset = pos.offset(); normalized = true; }); } if (NodeType.isElement(container)) { node = container.childNodes[offset]; if (!node) { node = container.childNodes[offset - 1]; } if (node && NodeType.isBr(node) && !isPrevNode(node, 'A') && !hasBrBeforeAfter(dom, node, false) && !hasBrBeforeAfter(dom, node, true)) { findTextNodeRelative(dom, isAfterNode, collapsed, true, node).each(function (pos) { container = pos.container(); offset = pos.offset(); normalized = true; }); } } } if (directionLeft && !collapsed && NodeType.isText(container) && offset === container.nodeValue.length) { findTextNodeRelative(dom, isAfterNode, collapsed, false, container).each(function (pos) { container = pos.container(); offset = pos.offset(); normalized = true; }); } return normalized ? Option.some(CaretPosition(container, offset)) : Option.none(); }; var normalize$2 = function (dom, rng) { var collapsed = rng.collapsed, normRng = rng.cloneRange(); var startPos = CaretPosition.fromRangeStart(rng); normalizeEndPoint(dom, collapsed, true, normRng).each(function (pos) { if (!collapsed || !CaretPosition.isAbove(startPos, pos)) { normRng.setStart(pos.container(), pos.offset()); } }); if (!collapsed) { normalizeEndPoint(dom, collapsed, false, normRng).each(function (pos) { normRng.setEnd(pos.container(), pos.offset()); }); } if (collapsed) { normRng.collapse(true); } return RangeCompare.isEq(rng, normRng) ? Option.none() : Option.some(normRng); }; var NormalizeRange = { normalize: normalize$2 }; var hasRightSideContent = function (schema, container, parentBlock) { var walker = new TreeWalker(container, parentBlock); var node; var nonEmptyElementsMap = schema.getNonEmptyElements(); while (node = walker.next()) { if (nonEmptyElementsMap[node.nodeName.toLowerCase()] || node.length > 0) { return true; } } }; var scrollToBr = function (dom, selection, brElm) { var marker = dom.create('span', {}, ' '); brElm.parentNode.insertBefore(marker, brElm); selection.scrollIntoView(marker); dom.remove(marker); }; var moveSelectionToBr = function (dom, selection, brElm, extraBr) { var rng = dom.createRng(); if (!extraBr) { rng.setStartAfter(brElm); rng.setEndAfter(brElm); } else { rng.setStartBefore(brElm); rng.setEndBefore(brElm); } selection.setRng(rng); }; var insertBrAtCaret = function (editor, evt) { var selection = editor.selection; var dom = editor.dom; var rng = selection.getRng(); var brElm; var extraBr; NormalizeRange.normalize(dom, rng).each(function (normRng) { rng.setStart(normRng.startContainer, normRng.startOffset); rng.setEnd(normRng.endContainer, normRng.endOffset); }); var offset = rng.startOffset; var container = rng.startContainer; if (container.nodeType === 1 && container.hasChildNodes()) { var isAfterLastNodeInContainer = offset > container.childNodes.length - 1; container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container; if (isAfterLastNodeInContainer && container.nodeType === 3) { offset = container.nodeValue.length; } else { offset = 0; } } var parentBlock = dom.getParent(container, dom.isBlock); var containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null; var containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : ''; var isControlKey = evt && evt.ctrlKey; if (containerBlockName === 'LI' && !isControlKey) { parentBlock = containerBlock; } if (container && container.nodeType === 3 && offset >= container.nodeValue.length) { if (!hasRightSideContent(editor.schema, container, parentBlock)) { brElm = dom.create('br'); rng.insertNode(brElm); rng.setStartAfter(brElm); rng.setEndAfter(brElm); extraBr = true; } } brElm = dom.create('br'); rangeInsertNode(dom, rng, brElm); scrollToBr(dom, selection, brElm); moveSelectionToBr(dom, selection, brElm, extraBr); editor.undoManager.add(); }; var insertBrBefore = function (editor, inline) { var br = Element.fromTag('br'); before(Element.fromDom(inline), br); editor.undoManager.add(); }; var insertBrAfter = function (editor, inline) { if (!hasBrAfter(editor.getBody(), inline)) { after(Element.fromDom(inline), Element.fromTag('br')); } var br = Element.fromTag('br'); after(Element.fromDom(inline), br); scrollToBr(editor.dom, editor.selection, br.dom()); moveSelectionToBr(editor.dom, editor.selection, br.dom(), false); editor.undoManager.add(); }; var isBeforeBr$1 = function (pos) { return NodeType.isBr(pos.getNode()); }; var hasBrAfter = function (rootNode, startNode) { if (isBeforeBr$1(CaretPosition$1.after(startNode))) { return true; } else { return CaretFinder.nextPosition(rootNode, CaretPosition$1.after(startNode)).map(function (pos) { return NodeType.isBr(pos.getNode()); }).getOr(false); } }; var isAnchorLink = function (elm) { return elm && elm.nodeName === 'A' && 'href' in elm; }; var isInsideAnchor = function (location) { return location.fold(constant(false), isAnchorLink, isAnchorLink, constant(false)); }; var readInlineAnchorLocation = function (editor) { var isInlineTarget = curry(InlineUtils.isInlineTarget, editor); var position = CaretPosition$1.fromRangeStart(editor.selection.getRng()); return BoundaryLocation.readLocation(isInlineTarget, editor.getBody(), position).filter(isInsideAnchor); }; var insertBrOutsideAnchor = function (editor, location) { location.fold(noop, curry(insertBrBefore, editor), curry(insertBrAfter, editor), noop); }; var insert = function (editor, evt) { var anchorLocation = readInlineAnchorLocation(editor); if (anchorLocation.isSome()) { anchorLocation.each(curry(insertBrOutsideAnchor, editor)); } else { insertBrAtCaret(editor, evt); } }; var InsertBr = { insert: insert }; var adt = Adt.generate([ { before: ['element'] }, { on: [ 'element', 'offset' ] }, { after: ['element'] } ]); var type$1 = Adt.generate([ { domRange: ['rng'] }, { relative: [ 'startSitu', 'finishSitu' ] }, { exact: [ 'start', 'soffset', 'finish', 'foffset' ] } ]); var range = Immutable('start', 'soffset', 'finish', 'foffset'); var browser$3 = PlatformDetection$1.detect().browser; var clamp = function (offset, element) { var max = isText(element) ? get$4(element).length : children(element).length + 1; if (offset > max) { return max; } else if (offset < 0) { return 0; } return offset; }; var normalizeRng = function (rng) { return range(rng.start(), clamp(rng.soffset(), rng.start()), rng.finish(), clamp(rng.foffset(), rng.finish())); }; var isOrContains = function (root, elm) { return contains$3(root, elm) || eq(root, elm); }; var isRngInRoot = function (root) { return function (rng) { return isOrContains(root, rng.start()) && isOrContains(root, rng.finish()); }; }; var shouldStore = function (editor) { return editor.inline === true || browser$3.isIE(); }; var nativeRangeToSelectionRange = function (r) { return range(Element.fromDom(r.startContainer), r.startOffset, Element.fromDom(r.endContainer), r.endOffset); }; var readRange = function (win) { var selection = win.getSelection(); var rng = !selection || selection.rangeCount === 0 ? Option.none() : Option.from(selection.getRangeAt(0)); return rng.map(nativeRangeToSelectionRange); }; var getBookmark$2 = function (root) { var win = defaultView(root); return readRange(win.dom()).filter(isRngInRoot(root)); }; var validate = function (root, bookmark) { return Option.from(bookmark).filter(isRngInRoot(root)).map(normalizeRng); }; var bookmarkToNativeRng = function (bookmark) { var rng = domGlobals.document.createRange(); try { rng.setStart(bookmark.start().dom(), bookmark.soffset()); rng.setEnd(bookmark.finish().dom(), bookmark.foffset()); return Option.some(rng); } catch (_) { return Option.none(); } }; var store = function (editor) { var newBookmark = shouldStore(editor) ? getBookmark$2(Element.fromDom(editor.getBody())) : Option.none(); editor.bookmark = newBookmark.isSome() ? newBookmark : editor.bookmark; }; var storeNative = function (editor, rng) { var root = Element.fromDom(editor.getBody()); var range = shouldStore(editor) ? Option.from(rng) : Option.none(); var newBookmark = range.map(nativeRangeToSelectionRange).filter(isRngInRoot(root)); editor.bookmark = newBookmark.isSome() ? newBookmark : editor.bookmark; }; var getRng = function (editor) { var bookmark = editor.bookmark ? editor.bookmark : Option.none(); return bookmark.bind(curry(validate, Element.fromDom(editor.getBody()))).bind(bookmarkToNativeRng); }; var restore = function (editor) { getRng(editor).each(function (rng) { editor.selection.setRng(rng); }); }; var SelectionBookmark = { store: store, storeNative: storeNative, readRange: readRange, restore: restore, getRng: getRng, getBookmark: getBookmark$2, validate: validate }; var indentElement = function (dom, command, useMargin, value, unit, element) { if (dom.getContentEditable(element) === 'false') { return; } var indentStyleName = useMargin ? 'margin' : 'padding'; indentStyleName = element.nodeName === 'TABLE' ? 'margin' : indentStyleName; indentStyleName += dom.getStyle(element, 'direction', true) === 'rtl' ? 'Right' : 'Left'; if (command === 'outdent') { var styleValue = Math.max(0, parseInt(element.style[indentStyleName] || 0, 10) - value); dom.setStyle(element, indentStyleName, styleValue ? styleValue + unit : ''); } else { var styleValue = parseInt(element.style[indentStyleName] || 0, 10) + value + unit; dom.setStyle(element, indentStyleName, styleValue); } }; var isListComponent = function (el) { return isList(el) || isListItem(el); }; var parentIsListComponent = function (el) { return parent(el).map(isListComponent).getOr(false); }; var getBlocksToIndent = function (editor) { return filter(map(editor.selection.getSelectedBlocks(), Element.fromDom), function (el) { return !isListComponent(el) && !parentIsListComponent(el); }); }; var handle = function (editor, command) { var settings = editor.settings, dom = editor.dom, selection = editor.selection, formatter = editor.formatter; var indentUnit = /[a-z%]+$/i.exec(settings.indentation)[0]; var indentValue = parseInt(settings.indentation, 10); var useMargin = editor.getParam('indent_use_margin', false); if (!editor.queryCommandState('InsertUnorderedList') && !editor.queryCommandState('InsertOrderedList')) { if (!settings.forced_root_block && !dom.getParent(selection.getNode(), dom.isBlock)) { formatter.apply('div'); } } each(getBlocksToIndent(editor), function (block) { indentElement(dom, command, useMargin, indentValue, indentUnit, block.dom()); }); }; var each$a = Tools.each, extend$2 = Tools.extend; var map$3 = Tools.map, inArray$2 = Tools.inArray; function EditorCommands (editor) { var dom, selection, formatter; var commands = { state: {}, exec: {}, value: {} }; var settings = editor.settings, bookmark; editor.on('PreInit', function () { dom = editor.dom; selection = editor.selection; settings = editor.settings; formatter = editor.formatter; }); var execCommand = function (command, ui, value, args) { var func, customCommand, state = false; if (editor.removed) { return; } if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(command) && (!args || !args.skip_focus)) { editor.focus(); } else { SelectionBookmark.restore(editor); } args = editor.fire('BeforeExecCommand', { command: command, ui: ui, value: value }); if (args.isDefaultPrevented()) { return false; } customCommand = command.toLowerCase(); if (func = commands.exec[customCommand]) { func(customCommand, ui, value); editor.fire('ExecCommand', { command: command, ui: ui, value: value }); return true; } each$a(editor.plugins, function (p) { if (p.execCommand && p.execCommand(command, ui, value)) { editor.fire('ExecCommand', { command: command, ui: ui, value: value }); state = true; return false; } }); if (state) { return state; } if (editor.theme && editor.theme.execCommand && editor.theme.execCommand(command, ui, value)) { editor.fire('ExecCommand', { command: command, ui: ui, value: value }); return true; } try { state = editor.getDoc().execCommand(command, ui, value); } catch (ex) { } if (state) { editor.fire('ExecCommand', { command: command, ui: ui, value: value }); return true; } return false; }; var queryCommandState = function (command) { var func; if (editor.quirks.isHidden() || editor.removed) { return; } command = command.toLowerCase(); if (func = commands.state[command]) { return func(command); } try { return editor.getDoc().queryCommandState(command); } catch (ex) { } return false; }; var queryCommandValue = function (command) { var func; if (editor.quirks.isHidden() || editor.removed) { return; } command = command.toLowerCase(); if (func = commands.value[command]) { return func(command); } try { return editor.getDoc().queryCommandValue(command); } catch (ex) { } }; var addCommands = function (commandList, type) { type = type || 'exec'; each$a(commandList, function (callback, command) { each$a(command.toLowerCase().split(','), function (command) { commands[type][command] = callback; }); }); }; var addCommand = function (command, callback, scope) { command = command.toLowerCase(); commands.exec[command] = function (command, ui, value, args) { return callback.call(scope || editor, ui, value, args); }; }; var queryCommandSupported = function (command) { command = command.toLowerCase(); if (commands.exec[command]) { return true; } try { return editor.getDoc().queryCommandSupported(command); } catch (ex) { } return false; }; var addQueryStateHandler = function (command, callback, scope) { command = command.toLowerCase(); commands.state[command] = function () { return callback.call(scope || editor); }; }; var addQueryValueHandler = function (command, callback, scope) { command = command.toLowerCase(); commands.value[command] = function () { return callback.call(scope || editor); }; }; var hasCustomCommand = function (command) { command = command.toLowerCase(); return !!commands.exec[command]; }; extend$2(this, { execCommand: execCommand, queryCommandState: queryCommandState, queryCommandValue: queryCommandValue, queryCommandSupported: queryCommandSupported, addCommands: addCommands, addCommand: addCommand, addQueryStateHandler: addQueryStateHandler, addQueryValueHandler: addQueryValueHandler, hasCustomCommand: hasCustomCommand }); var execNativeCommand = function (command, ui, value) { if (ui === undefined) { ui = false; } if (value === undefined) { value = null; } return editor.getDoc().execCommand(command, ui, value); }; var isFormatMatch = function (name) { return formatter.match(name); }; var toggleFormat = function (name, value) { formatter.toggle(name, value ? { value: value } : undefined); editor.nodeChanged(); }; var storeSelection = function (type) { bookmark = selection.getBookmark(type); }; var restoreSelection = function () { selection.moveToBookmark(bookmark); }; addCommands({ 'mceResetDesignMode,mceBeginUndoLevel': function () { }, 'mceEndUndoLevel,mceAddUndoLevel': function () { editor.undoManager.add(); }, 'Cut,Copy,Paste': function (command) { var doc = editor.getDoc(); var failed; try { execNativeCommand(command); } catch (ex) { failed = true; } if (command === 'paste' && !doc.queryCommandEnabled(command)) { failed = true; } if (failed || !doc.queryCommandSupported(command)) { var msg = editor.translate('Your browser doesn\'t support direct access to the clipboard. ' + 'Please use the Ctrl+X/C/V keyboard shortcuts instead.'); if (Env.mac) { msg = msg.replace(/Ctrl\+/g, '\u2318+'); } editor.notificationManager.open({ text: msg, type: 'error' }); } }, 'unlink': function () { if (selection.isCollapsed()) { var elm = editor.dom.getParent(editor.selection.getStart(), 'a'); if (elm) { editor.dom.remove(elm, true); } return; } formatter.remove('link'); }, 'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull,JustifyNone': function (command) { var align = command.substring(7); if (align === 'full') { align = 'justify'; } each$a('left,center,right,justify'.split(','), function (name) { if (align !== name) { formatter.remove('align' + name); } }); if (align !== 'none') { toggleFormat('align' + align); } }, 'InsertUnorderedList,InsertOrderedList': function (command) { var listElm, listParent; execNativeCommand(command); listElm = dom.getParent(selection.getNode(), 'ol,ul'); if (listElm) { listParent = listElm.parentNode; if (/^(H[1-6]|P|ADDRESS|PRE)$/.test(listParent.nodeName)) { storeSelection(); dom.split(listParent, listElm); restoreSelection(); } } }, 'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function (command) { toggleFormat(command); }, 'ForeColor,HiliteColor': function (command, ui, value) { toggleFormat(command, value); }, 'FontName': function (command, ui, value) { fontNameAction(editor, value); }, 'FontSize': function (command, ui, value) { fontSizeAction(editor, value); }, 'RemoveFormat': function (command) { formatter.remove(command); }, 'mceBlockQuote': function () { toggleFormat('blockquote'); }, 'FormatBlock': function (command, ui, value) { return toggleFormat(value || 'p'); }, 'mceCleanup': function () { var bookmark = selection.getBookmark(); editor.setContent(editor.getContent()); selection.moveToBookmark(bookmark); }, 'mceRemoveNode': function (command, ui, value) { var node = value || selection.getNode(); if (node !== editor.getBody()) { storeSelection(); editor.dom.remove(node, true); restoreSelection(); } }, 'mceSelectNodeDepth': function (command, ui, value) { var counter = 0; dom.getParent(selection.getNode(), function (node) { if (node.nodeType === 1 && counter++ === value) { selection.select(node); return false; } }, editor.getBody()); }, 'mceSelectNode': function (command, ui, value) { selection.select(value); }, 'mceInsertContent': function (command, ui, value) { InsertContent.insertAtCaret(editor, value); }, 'mceInsertRawHTML': function (command, ui, value) { selection.setContent('tiny_mce_marker'); var content = editor.getContent(); editor.setContent(content.replace(/tiny_mce_marker/g, function () { return value; })); }, 'mceToggleFormat': function (command, ui, value) { toggleFormat(value); }, 'mceSetContent': function (command, ui, value) { editor.setContent(value); }, 'Indent,Outdent': function (command) { handle(editor, command); }, 'mceRepaint': function () { }, 'InsertHorizontalRule': function () { editor.execCommand('mceInsertContent', false, '<hr />'); }, 'mceToggleVisualAid': function () { editor.hasVisual = !editor.hasVisual; editor.addVisual(); }, 'mceReplaceContent': function (command, ui, value) { editor.execCommand('mceInsertContent', false, value.replace(/\{\$selection\}/g, selection.getContent({ format: 'text' }))); }, 'mceInsertLink': function (command, ui, value) { var anchor; if (typeof value === 'string') { value = { href: value }; } anchor = dom.getParent(selection.getNode(), 'a'); value.href = value.href.replace(' ', '%20'); if (!anchor || !value.href) { formatter.remove('link'); } if (value.href) { formatter.apply('link', value, anchor); } }, 'selectAll': function () { var editingHost = dom.getParent(selection.getStart(), NodeType.isContentEditableTrue); if (editingHost) { var rng = dom.createRng(); rng.selectNodeContents(editingHost); selection.setRng(rng); } }, 'delete': function () { DeleteCommands.deleteCommand(editor); }, 'forwardDelete': function () { DeleteCommands.forwardDeleteCommand(editor); }, 'mceNewDocument': function () { editor.setContent(''); }, 'InsertLineBreak': function (command, ui, value) { InsertBr.insert(editor, value); return true; } }); var alignStates = function (name) { return function () { var nodes = selection.isCollapsed() ? [dom.getParent(selection.getNode(), dom.isBlock)] : selection.getSelectedBlocks(); var matches = map$3(nodes, function (node) { return !!formatter.matchNode(node, name); }); return inArray$2(matches, true) !== -1; }; }; addCommands({ 'JustifyLeft': alignStates('alignleft'), 'JustifyCenter': alignStates('aligncenter'), 'JustifyRight': alignStates('alignright'), 'JustifyFull': alignStates('alignjustify'), 'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function (command) { return isFormatMatch(command); }, 'mceBlockQuote': function () { return isFormatMatch('blockquote'); }, 'Outdent': function () { var node; if (settings.inline_styles) { if ((node = dom.getParent(selection.getStart(), dom.isBlock)) && parseInt(node.style.paddingLeft, 10) > 0) { return true; } if ((node = dom.getParent(selection.getEnd(), dom.isBlock)) && parseInt(node.style.paddingLeft, 10) > 0) { return true; } } return queryCommandState('InsertUnorderedList') || queryCommandState('InsertOrderedList') || !settings.inline_styles && !!dom.getParent(selection.getNode(), 'BLOCKQUOTE'); }, 'InsertUnorderedList,InsertOrderedList': function (command) { var list = dom.getParent(selection.getNode(), 'ul,ol'); return list && (command === 'insertunorderedlist' && list.tagName === 'UL' || command === 'insertorderedlist' && list.tagName === 'OL'); } }, 'state'); addCommands({ Undo: function () { editor.undoManager.undo(); }, Redo: function () { editor.undoManager.redo(); } }); addQueryValueHandler('FontName', function () { return fontNameQuery(editor); }, this); addQueryValueHandler('FontSize', function () { return fontSizeQuery(editor); }, this); } var nativeEvents = Tools.makeMap('focus blur focusin focusout click dblclick mousedown mouseup mousemove mouseover beforepaste paste cut copy selectionchange ' + 'mouseout mouseenter mouseleave wheel keydown keypress keyup input contextmenu dragstart dragend dragover ' + 'draggesture dragdrop drop drag submit ' + 'compositionstart compositionend compositionupdate touchstart touchmove touchend', ' '); var Dispatcher = function (settings) { var self = this; var scope, bindings = {}, toggleEvent; var returnFalse = function () { return false; }; var returnTrue = function () { return true; }; settings = settings || {}; scope = settings.scope || self; toggleEvent = settings.toggleEvent || returnFalse; var fire = function (name, args) { var handlers, i, l, callback; name = name.toLowerCase(); args = args || {}; args.type = name; if (!args.target) { args.target = scope; } if (!args.preventDefault) { args.preventDefault = function () { args.isDefaultPrevented = returnTrue; }; args.stopPropagation = function () { args.isPropagationStopped = returnTrue; }; args.stopImmediatePropagation = function () { args.isImmediatePropagationStopped = returnTrue; }; args.isDefaultPrevented = returnFalse; args.isPropagationStopped = returnFalse; args.isImmediatePropagationStopped = returnFalse; } if (settings.beforeFire) { settings.beforeFire(args); } handlers = bindings[name]; if (handlers) { for (i = 0, l = handlers.length; i < l; i++) { callback = handlers[i]; if (callback.once) { off(name, callback.func); } if (args.isImmediatePropagationStopped()) { args.stopPropagation(); return args; } if (callback.func.call(scope, args) === false) { args.preventDefault(); return args; } } } return args; }; var on = function (name, callback, prepend, extra) { var handlers, names, i; if (callback === false) { callback = returnFalse; } if (callback) { callback = { func: callback }; if (extra) { Tools.extend(callback, extra); } names = name.toLowerCase().split(' '); i = names.length; while (i--) { name = names[i]; handlers = bindings[name]; if (!handlers) { handlers = bindings[name] = []; toggleEvent(name, true); } if (prepend) { handlers.unshift(callback); } else { handlers.push(callback); } } } return self; }; var off = function (name, callback) { var i, handlers, bindingName, names, hi; if (name) { names = name.toLowerCase().split(' '); i = names.length; while (i--) { name = names[i]; handlers = bindings[name]; if (!name) { for (bindingName in bindings) { toggleEvent(bindingName, false); delete bindings[bindingName]; } return self; } if (handlers) { if (!callback) { handlers.length = 0; } else { hi = handlers.length; while (hi--) { if (handlers[hi].func === callback) { handlers = handlers.slice(0, hi).concat(handlers.slice(hi + 1)); bindings[name] = handlers; } } } if (!handlers.length) { toggleEvent(name, false); delete bindings[name]; } } } } else { for (name in bindings) { toggleEvent(name, false); } bindings = {}; } return self; }; var once = function (name, callback, prepend) { return on(name, callback, prepend, { once: true }); }; var has = function (name) { name = name.toLowerCase(); return !(!bindings[name] || bindings[name].length === 0); }; self.fire = fire; self.on = on; self.off = off; self.once = once; self.has = has; }; Dispatcher.isNative = function (name) { return !!nativeEvents[name.toLowerCase()]; }; var getEventDispatcher = function (obj) { if (!obj._eventDispatcher) { obj._eventDispatcher = new Dispatcher({ scope: obj, toggleEvent: function (name, state) { if (Dispatcher.isNative(name) && obj.toggleNativeEvent) { obj.toggleNativeEvent(name, state); } } }); } return obj._eventDispatcher; }; var Observable = { fire: function (name, args, bubble) { var self = this; if (self.removed && name !== 'remove' && name !== 'detach') { return args; } args = getEventDispatcher(self).fire(name, args, bubble); if (bubble !== false && self.parent) { var parent = self.parent(); while (parent && !args.isPropagationStopped()) { parent.fire(name, args, false); parent = parent.parent(); } } return args; }, on: function (name, callback, prepend) { return getEventDispatcher(this).on(name, callback, prepend); }, off: function (name, callback) { return getEventDispatcher(this).off(name, callback); }, once: function (name, callback) { return getEventDispatcher(this).once(name, callback); }, hasEventListeners: function (name) { return getEventDispatcher(this).has(name); } }; var firePreProcess = function (editor, args) { return editor.fire('PreProcess', args); }; var firePostProcess = function (editor, args) { return editor.fire('PostProcess', args); }; var fireRemove = function (editor) { return editor.fire('remove'); }; var fireDetach = function (editor) { return editor.fire('detach'); }; var fireSwitchMode = function (editor, mode) { return editor.fire('SwitchMode', { mode: mode }); }; var fireObjectResizeStart = function (editor, target, width, height) { editor.fire('ObjectResizeStart', { target: target, width: width, height: height }); }; var fireObjectResized = function (editor, target, width, height) { editor.fire('ObjectResized', { target: target, width: width, height: height }); }; var Events = { firePreProcess: firePreProcess, firePostProcess: firePostProcess, fireRemove: fireRemove, fireDetach: fireDetach, fireSwitchMode: fireSwitchMode, fireObjectResizeStart: fireObjectResizeStart, fireObjectResized: fireObjectResized }; var setEditorCommandState = function (editor, cmd, state) { try { editor.getDoc().execCommand(cmd, false, state); } catch (ex) { } }; var toggleClass = function (elm, cls, state) { if (has$2(elm, cls) && state === false) { remove$4(elm, cls); } else if (state) { add$2(elm, cls); } }; var toggleReadOnly = function (editor, state) { toggleClass(Element.fromDom(editor.getBody()), 'mce-content-readonly', state); if (state) { editor.selection.controlSelection.hideResizeRect(); editor.readonly = true; editor.getBody().contentEditable = 'false'; } else { editor.readonly = false; editor.getBody().contentEditable = 'true'; setEditorCommandState(editor, 'StyleWithCSS', false); setEditorCommandState(editor, 'enableInlineTableEditing', false); setEditorCommandState(editor, 'enableObjectResizing', false); editor.focus(); editor.nodeChanged(); } }; var setMode = function (editor, mode) { if (mode === getMode(editor)) { return; } if (editor.initialized) { toggleReadOnly(editor, mode === 'readonly'); } else { editor.on('init', function () { toggleReadOnly(editor, mode === 'readonly'); }); } Events.fireSwitchMode(editor, mode); }; var getMode = function (editor) { return editor.readonly ? 'readonly' : 'design'; }; var isReadOnly = function (editor) { return editor.readonly === true; }; var DOM$1 = DOMUtils$1.DOM; var customEventRootDelegates; var getEventTarget = function (editor, eventName) { if (eventName === 'selectionchange') { return editor.getDoc(); } if (!editor.inline && /^mouse|touch|click|contextmenu|drop|dragover|dragend/.test(eventName)) { return editor.getDoc().documentElement; } if (editor.settings.event_root) { if (!editor.eventRoot) { editor.eventRoot = DOM$1.select(editor.settings.event_root)[0]; } return editor.eventRoot; } return editor.getBody(); }; var isListening = function (editor) { return !editor.hidden && !editor.readonly; }; var fireEvent = function (editor, eventName, e) { if (isListening(editor)) { editor.fire(eventName, e); } else if (isReadOnly(editor)) { e.preventDefault(); } }; var bindEventDelegate = function (editor, eventName) { var eventRootElm, delegate; if (!editor.delegates) { editor.delegates = {}; } if (editor.delegates[eventName] || editor.removed) { return; } eventRootElm = getEventTarget(editor, eventName); if (editor.settings.event_root) { if (!customEventRootDelegates) { customEventRootDelegates = {}; editor.editorManager.on('removeEditor', function () { var name; if (!editor.editorManager.activeEditor) { if (customEventRootDelegates) { for (name in customEventRootDelegates) { editor.dom.unbind(getEventTarget(editor, name)); } customEventRootDelegates = null; } } }); } if (customEventRootDelegates[eventName]) { return; } delegate = function (e) { var target = e.target; var editors = editor.editorManager.get(); var i = editors.length; while (i--) { var body = editors[i].getBody(); if (body === target || DOM$1.isChildOf(target, body)) { fireEvent(editors[i], eventName, e); } } }; customEventRootDelegates[eventName] = delegate; DOM$1.bind(eventRootElm, eventName, delegate); } else { delegate = function (e) { fireEvent(editor, eventName, e); }; DOM$1.bind(eventRootElm, eventName, delegate); editor.delegates[eventName] = delegate; } }; var EditorObservable = { bindPendingEventDelegates: function () { var self = this; Tools.each(self._pendingNativeEvents, function (name) { bindEventDelegate(self, name); }); }, toggleNativeEvent: function (name, state) { var self = this; if (name === 'focus' || name === 'blur') { return; } if (state) { if (self.initialized) { bindEventDelegate(self, name); } else { if (!self._pendingNativeEvents) { self._pendingNativeEvents = [name]; } else { self._pendingNativeEvents.push(name); } } } else if (self.initialized) { self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]); delete self.delegates[name]; } }, unbindAllNativeEvents: function () { var self = this; var body = self.getBody(); var dom = self.dom; var name; if (self.delegates) { for (name in self.delegates) { self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]); } delete self.delegates; } if (!self.inline && body && dom) { body.onload = null; dom.unbind(self.getWin()); dom.unbind(self.getDoc()); } if (dom) { dom.unbind(body); dom.unbind(self.getContainer()); } } }; EditorObservable = Tools.extend({}, Observable, EditorObservable); var EditorObservable$1 = EditorObservable; var each$b = Tools.each, explode$2 = Tools.explode; var keyCodeLookup = { f1: 112, f2: 113, f3: 114, f4: 115, f5: 116, f6: 117, f7: 118, f8: 119, f9: 120, f10: 121, f11: 122, f12: 123 }; var modifierNames = Tools.makeMap('alt,ctrl,shift,meta,access'); function Shortcuts (editor) { var self = this; var shortcuts = {}; var pendingPatterns = []; var parseShortcut = function (pattern) { var id, key; var shortcut = {}; each$b(explode$2(pattern, '+'), function (value) { if (value in modifierNames) { shortcut[value] = true; } else { if (/^[0-9]{2,}$/.test(value)) { shortcut.keyCode = parseInt(value, 10); } else { shortcut.charCode = value.charCodeAt(0); shortcut.keyCode = keyCodeLookup[value] || value.toUpperCase().charCodeAt(0); } } }); id = [shortcut.keyCode]; for (key in modifierNames) { if (shortcut[key]) { id.push(key); } else { shortcut[key] = false; } } shortcut.id = id.join(','); if (shortcut.access) { shortcut.alt = true; if (Env.mac) { shortcut.ctrl = true; } else { shortcut.shift = true; } } if (shortcut.meta) { if (Env.mac) { shortcut.meta = true; } else { shortcut.ctrl = true; shortcut.meta = false; } } return shortcut; }; var createShortcut = function (pattern, desc, cmdFunc, scope) { var shortcuts; shortcuts = Tools.map(explode$2(pattern, '>'), parseShortcut); shortcuts[shortcuts.length - 1] = Tools.extend(shortcuts[shortcuts.length - 1], { func: cmdFunc, scope: scope || editor }); return Tools.extend(shortcuts[0], { desc: editor.translate(desc), subpatterns: shortcuts.slice(1) }); }; var hasModifier = function (e) { return e.altKey || e.ctrlKey || e.metaKey; }; var isFunctionKey = function (e) { return e.type === 'keydown' && e.keyCode >= 112 && e.keyCode <= 123; }; var matchShortcut = function (e, shortcut) { if (!shortcut) { return false; } if (shortcut.ctrl !== e.ctrlKey || shortcut.meta !== e.metaKey) { return false; } if (shortcut.alt !== e.altKey || shortcut.shift !== e.shiftKey) { return false; } if (e.keyCode === shortcut.keyCode || e.charCode && e.charCode === shortcut.charCode) { e.preventDefault(); return true; } return false; }; var executeShortcutAction = function (shortcut) { return shortcut.func ? shortcut.func.call(shortcut.scope) : null; }; editor.on('keyup keypress keydown', function (e) { if ((hasModifier(e) || isFunctionKey(e)) && !e.isDefaultPrevented()) { each$b(shortcuts, function (shortcut) { if (matchShortcut(e, shortcut)) { pendingPatterns = shortcut.subpatterns.slice(0); if (e.type === 'keydown') { executeShortcutAction(shortcut); } return true; } }); if (matchShortcut(e, pendingPatterns[0])) { if (pendingPatterns.length === 1) { if (e.type === 'keydown') { executeShortcutAction(pendingPatterns[0]); } } pendingPatterns.shift(); } } }); self.add = function (pattern, desc, cmdFunc, scope) { var cmd; cmd = cmdFunc; if (typeof cmdFunc === 'string') { cmdFunc = function () { editor.execCommand(cmd, false, null); }; } else if (Tools.isArray(cmd)) { cmdFunc = function () { editor.execCommand(cmd[0], cmd[1], cmd[2]); }; } each$b(explode$2(Tools.trim(pattern.toLowerCase())), function (pattern) { var shortcut = createShortcut(pattern, desc, cmdFunc, scope); shortcuts[shortcut.id] = shortcut; }); return true; }; self.remove = function (pattern) { var shortcut = createShortcut(pattern); if (shortcuts[shortcut.id]) { delete shortcuts[shortcut.id]; return true; } return false; }; } var hasFocus = function (element) { var doc = owner(element).dom(); return element.dom() === doc.activeElement; }; var active = function (_DOC) { var doc = _DOC !== undefined ? _DOC.dom() : domGlobals.document; return Option.from(doc.activeElement).map(Element.fromDom); }; var search = function (element) { return active(owner(element)).filter(function (e) { return element.dom().contains(e.dom()); }); }; var getContentEditableHost = function (editor, node) { return editor.dom.getParent(node, function (node) { return editor.dom.getContentEditable(node) === 'true'; }); }; var getCollapsedNode = function (rng) { return rng.collapsed ? Option.from(getNode(rng.startContainer, rng.startOffset)).map(Element.fromDom) : Option.none(); }; var getFocusInElement = function (root, rng) { return getCollapsedNode(rng).bind(function (node) { if (isTableSection(node)) { return Option.some(node); } else if (contains$3(root, node) === false) { return Option.some(root); } else { return Option.none(); } }); }; var normalizeSelection = function (editor, rng) { getFocusInElement(Element.fromDom(editor.getBody()), rng).bind(function (elm) { return CaretFinder.firstPositionIn(elm.dom()); }).fold(function () { editor.selection.normalize(); return; }, function (caretPos) { return editor.selection.setRng(caretPos.toRange()); }); }; var focusBody = function (body) { if (body.setActive) { try { body.setActive(); } catch (ex) { body.focus(); } } else { body.focus(); } }; var hasElementFocus = function (elm) { return hasFocus(elm) || search(elm).isSome(); }; var hasIframeFocus = function (editor) { return editor.iframeElement && hasFocus(Element.fromDom(editor.iframeElement)); }; var hasInlineFocus = function (editor) { var rawBody = editor.getBody(); return rawBody && hasElementFocus(Element.fromDom(rawBody)); }; var hasFocus$1 = function (editor) { return editor.inline ? hasInlineFocus(editor) : hasIframeFocus(editor); }; var focusEditor = function (editor) { var selection = editor.selection, contentEditable = editor.settings.content_editable; var body = editor.getBody(); var rng = selection.getRng(); editor.quirks.refreshContentEditable(); var contentEditableHost = getContentEditableHost(editor, selection.getNode()); if (editor.$.contains(body, contentEditableHost)) { focusBody(contentEditableHost); normalizeSelection(editor, rng); activateEditor(editor); return; } if (editor.bookmark !== undefined && hasFocus$1(editor) === false) { SelectionBookmark.getRng(editor).each(function (bookmarkRng) { editor.selection.setRng(bookmarkRng); rng = bookmarkRng; }); } if (!contentEditable) { if (!Env.opera) { focusBody(body); } editor.getWin().focus(); } if (Env.gecko || contentEditable) { focusBody(body); normalizeSelection(editor, rng); } activateEditor(editor); }; var activateEditor = function (editor) { return editor.editorManager.setActive(editor); }; var focus = function (editor, skipFocus) { if (editor.removed) { return; } skipFocus ? activateEditor(editor) : focusEditor(editor); }; var EditorFocus = { focus: focus, hasFocus: hasFocus$1 }; var getProp = function (propName, elm) { var rawElm = elm.dom(); return rawElm[propName]; }; var getComputedSizeProp = function (propName, elm) { return parseInt(get$1(elm, propName), 10); }; var getClientWidth = curry(getProp, 'clientWidth'); var getClientHeight = curry(getProp, 'clientHeight'); var getMarginTop = curry(getComputedSizeProp, 'margin-top'); var getMarginLeft = curry(getComputedSizeProp, 'margin-left'); var getBoundingClientRect$1 = function (elm) { return elm.dom().getBoundingClientRect(); }; var isInsideElementContentArea = function (bodyElm, clientX, clientY) { var clientWidth = getClientWidth(bodyElm); var clientHeight = getClientHeight(bodyElm); return clientX >= 0 && clientY >= 0 && clientX <= clientWidth && clientY <= clientHeight; }; var transpose = function (inline, elm, clientX, clientY) { var clientRect = getBoundingClientRect$1(elm); var deltaX = inline ? clientRect.left + elm.dom().clientLeft + getMarginLeft(elm) : 0; var deltaY = inline ? clientRect.top + elm.dom().clientTop + getMarginTop(elm) : 0; var x = clientX - deltaX; var y = clientY - deltaY; return { x: x, y: y }; }; var isXYInContentArea = function (editor, clientX, clientY) { var bodyElm = Element.fromDom(editor.getBody()); var targetElm = editor.inline ? bodyElm : documentElement(bodyElm); var transposedPoint = transpose(editor.inline, targetElm, clientX, clientY); return isInsideElementContentArea(targetElm, transposedPoint.x, transposedPoint.y); }; var fromDomSafe = function (node) { return Option.from(node).map(Element.fromDom); }; var isEditorAttachedToDom = function (editor) { var rawContainer = editor.inline ? editor.getBody() : editor.getContentAreaContainer(); return fromDomSafe(rawContainer).map(function (container) { return contains$3(owner(container), container); }).getOr(false); }; var EditorView = { isXYInContentArea: isXYInContentArea, isEditorAttachedToDom: isEditorAttachedToDom }; function NotificationManagerImpl () { var unimplemented = function () { throw new Error('Theme did not provide a NotificationManager implementation.'); }; return { open: unimplemented, close: unimplemented, reposition: unimplemented, getArgs: unimplemented }; } function NotificationManager (editor) { var notifications = []; var getImplementation = function () { var theme = editor.theme; return theme && theme.getNotificationManagerImpl ? theme.getNotificationManagerImpl() : NotificationManagerImpl(); }; var getTopNotification = function () { return Option.from(notifications[0]); }; var isEqual = function (a, b) { return a.type === b.type && a.text === b.text && !a.progressBar && !a.timeout && !b.progressBar && !b.timeout; }; var reposition = function () { if (notifications.length > 0) { getImplementation().reposition(notifications); } }; var addNotification = function (notification) { notifications.push(notification); }; var closeNotification = function (notification) { findIndex(notifications, function (otherNotification) { return otherNotification === notification; }).each(function (index) { notifications.splice(index, 1); }); }; var open = function (args) { if (editor.removed || !EditorView.isEditorAttachedToDom(editor)) { return; } return find(notifications, function (notification) { return isEqual(getImplementation().getArgs(notification), args); }).getOrThunk(function () { editor.editorManager.setActive(editor); var notification = getImplementation().open(args, function () { closeNotification(notification); reposition(); }); addNotification(notification); reposition(); return notification; }); }; var close = function () { getTopNotification().each(function (notification) { getImplementation().close(notification); closeNotification(notification); reposition(); }); }; var getNotifications = function () { return notifications; }; var registerEvents = function (editor) { editor.on('SkinLoaded', function () { var serviceMessage = editor.settings.service_message; if (serviceMessage) { open({ text: serviceMessage, type: 'warning', timeout: 0, icon: '' }); } }); editor.on('ResizeEditor ResizeWindow', function () { Delay.requestAnimationFrame(reposition); }); editor.on('remove', function () { each(notifications.slice(), function (notification) { getImplementation().close(notification); }); }); }; registerEvents(editor); return { open: open, close: close, getNotifications: getNotifications }; } function WindowManagerImpl () { var unimplemented = function () { throw new Error('Theme did not provide a WindowManager implementation.'); }; return { open: unimplemented, alert: unimplemented, confirm: unimplemented, close: unimplemented, getParams: unimplemented, setParams: unimplemented }; } function WindowManager (editor) { var windows = []; var getImplementation = function () { var theme = editor.theme; return theme && theme.getWindowManagerImpl ? theme.getWindowManagerImpl() : WindowManagerImpl(); }; var funcBind = function (scope, f) { return function () { return f ? f.apply(scope, arguments) : undefined; }; }; var fireOpenEvent = function (win) { editor.fire('OpenWindow', { win: win }); }; var fireCloseEvent = function (win) { editor.fire('CloseWindow', { win: win }); }; var addWindow = function (win) { windows.push(win); fireOpenEvent(win); }; var closeWindow = function (win) { findIndex(windows, function (otherWindow) { return otherWindow === win; }).each(function (index) { windows.splice(index, 1); fireCloseEvent(win); if (windows.length === 0) { editor.focus(); } }); }; var getTopWindow = function () { return Option.from(windows[windows.length - 1]); }; var open = function (args, params) { editor.editorManager.setActive(editor); SelectionBookmark.store(editor); var win = getImplementation().open(args, params, closeWindow); addWindow(win); return win; }; var alert = function (message, callback, scope) { var win = getImplementation().alert(message, funcBind(scope ? scope : this, callback), closeWindow); addWindow(win); }; var confirm = function (message, callback, scope) { var win = getImplementation().confirm(message, funcBind(scope ? scope : this, callback), closeWindow); addWindow(win); }; var close = function () { getTopWindow().each(function (win) { getImplementation().close(win); closeWindow(win); }); }; var getParams = function () { return getTopWindow().map(getImplementation().getParams).getOr(null); }; var setParams = function (params) { getTopWindow().each(function (win) { getImplementation().setParams(win, params); }); }; var getWindows = function () { return windows; }; editor.on('remove', function () { each(windows.slice(0), function (win) { getImplementation().close(win); }); }); return { windows: windows, open: open, alert: alert, confirm: confirm, close: close, getParams: getParams, setParams: setParams, getWindows: getWindows }; } var data = {}; var code = 'en'; var I18n = { setCode: function (newCode) { if (newCode) { code = newCode; this.rtl = this.data[newCode] ? this.data[newCode]._dir === 'rtl' : false; } }, getCode: function () { return code; }, rtl: false, add: function (code, items) { var langData = data[code]; if (!langData) { data[code] = langData = {}; } for (var name in items) { langData[name] = items[name]; } this.setCode(code); }, translate: function (text) { var langData = data[code] || {}; var toString = function (obj) { if (Tools.is(obj, 'function')) { return Object.prototype.toString.call(obj); } return !isEmpty(obj) ? '' + obj : ''; }; var isEmpty = function (text) { return text === '' || text === null || Tools.is(text, 'undefined'); }; var getLangData = function (text) { text = toString(text); return Tools.hasOwn(langData, text) ? toString(langData[text]) : text; }; if (isEmpty(text)) { return ''; } if (Tools.is(text, 'object') && Tools.hasOwn(text, 'raw')) { return toString(text.raw); } if (Tools.is(text, 'array')) { var values_1 = text.slice(1); text = getLangData(text[0]).replace(/\{([0-9]+)\}/g, function ($1, $2) { return Tools.hasOwn(values_1, $2) ? toString(values_1[$2]) : $1; }); } return getLangData(text).replace(/{context:\w+}$/, ''); }, data: data }; var PluginManager = AddOnManager.PluginManager; var resolvePluginName = function (targetUrl, suffix) { for (var name in PluginManager.urls) { var matchUrl = PluginManager.urls[name] + '/plugin' + suffix + '.js'; if (matchUrl === targetUrl) { return name; } } return null; }; var pluginUrlToMessage = function (editor, url) { var plugin = resolvePluginName(url, editor.suffix); return plugin ? I18n.translate([ 'Failed to load plugin: {0} from url {1}', plugin, url ]) : I18n.translate([ 'Failed to load plugin url: {0}', url ]); }; var displayNotification = function (editor, message) { editor.notificationManager.open({ type: 'error', text: message }); }; var displayError = function (editor, message) { if (editor._skinLoaded) { displayNotification(editor, message); } else { editor.on('SkinLoaded', function () { displayNotification(editor, message); }); } }; var uploadError = function (editor, message) { displayError(editor, I18n.translate([ 'Failed to upload image: {0}', message ])); }; var pluginLoadError = function (editor, url) { displayError(editor, pluginUrlToMessage(editor, url)); }; var pluginInitError = function (editor, name, err) { var message = I18n.translate([ 'Failed to initialize plugin: {0}', name ]); initError(message, err); displayError(editor, message); }; var initError = function (message) { var x = []; for (var _i = 1; _i < arguments.length; _i++) { x[_i - 1] = arguments[_i]; } var console = domGlobals.window.console; if (console) { if (console.error) { console.error.apply(console, arguments); } else { console.log.apply(console, arguments); } } }; var ErrorReporter = { pluginLoadError: pluginLoadError, pluginInitError: pluginInitError, uploadError: uploadError, displayError: displayError, initError: initError }; var PluginManager$1 = AddOnManager.PluginManager; var ThemeManager = AddOnManager.ThemeManager; function XMLHttpRequest () { var f = Global$1.getOrDie('XMLHttpRequest'); return new f(); } function Uploader (uploadStatus, settings) { var pendingPromises = {}; var pathJoin = function (path1, path2) { if (path1) { return path1.replace(/\/$/, '') + '/' + path2.replace(/^\//, ''); } return path2; }; var defaultHandler = function (blobInfo, success, failure, progress) { var xhr, formData; xhr = XMLHttpRequest(); xhr.open('POST', settings.url); xhr.withCredentials = settings.credentials; xhr.upload.onprogress = function (e) { progress(e.loaded / e.total * 100); }; xhr.onerror = function () { failure('Image upload failed due to a XHR Transport error. Code: ' + xhr.status); }; xhr.onload = function () { var json; if (xhr.status < 200 || xhr.status >= 300) { failure('HTTP Error: ' + xhr.status); return; } json = JSON.parse(xhr.responseText); if (!json || typeof json.location !== 'string') { failure('Invalid JSON: ' + xhr.responseText); return; } success(pathJoin(settings.basePath, json.location)); }; formData = new domGlobals.FormData(); formData.append('file', blobInfo.blob(), blobInfo.filename()); xhr.send(formData); }; var noUpload = function () { return new promiseObj(function (resolve) { resolve([]); }); }; var handlerSuccess = function (blobInfo, url) { return { url: url, blobInfo: blobInfo, status: true }; }; var handlerFailure = function (blobInfo, error) { return { url: '', blobInfo: blobInfo, status: false, error: error }; }; var resolvePending = function (blobUri, result) { Tools.each(pendingPromises[blobUri], function (resolve) { resolve(result); }); delete pendingPromises[blobUri]; }; var uploadBlobInfo = function (blobInfo, handler, openNotification) { uploadStatus.markPending(blobInfo.blobUri()); return new promiseObj(function (resolve) { var notification, progress; var noop = function () { }; try { var closeNotification_1 = function () { if (notification) { notification.close(); progress = noop; } }; var success = function (url) { closeNotification_1(); uploadStatus.markUploaded(blobInfo.blobUri(), url); resolvePending(blobInfo.blobUri(), handlerSuccess(blobInfo, url)); resolve(handlerSuccess(blobInfo, url)); }; var failure = function (error) { closeNotification_1(); uploadStatus.removeFailed(blobInfo.blobUri()); resolvePending(blobInfo.blobUri(), handlerFailure(blobInfo, error)); resolve(handlerFailure(blobInfo, error)); }; progress = function (percent) { if (percent < 0 || percent > 100) { return; } if (!notification) { notification = openNotification(); } notification.progressBar.value(percent); }; handler(blobInfo, success, failure, progress); } catch (ex) { resolve(handlerFailure(blobInfo, ex.message)); } }); }; var isDefaultHandler = function (handler) { return handler === defaultHandler; }; var pendingUploadBlobInfo = function (blobInfo) { var blobUri = blobInfo.blobUri(); return new promiseObj(function (resolve) { pendingPromises[blobUri] = pendingPromises[blobUri] || []; pendingPromises[blobUri].push(resolve); }); }; var uploadBlobs = function (blobInfos, openNotification) { blobInfos = Tools.grep(blobInfos, function (blobInfo) { return !uploadStatus.isUploaded(blobInfo.blobUri()); }); return promiseObj.all(Tools.map(blobInfos, function (blobInfo) { return uploadStatus.isPending(blobInfo.blobUri()) ? pendingUploadBlobInfo(blobInfo) : uploadBlobInfo(blobInfo, settings.handler, openNotification); })); }; var upload = function (blobInfos, openNotification) { return !settings.url && isDefaultHandler(settings.handler) ? noUpload() : uploadBlobs(blobInfos, openNotification); }; if (isFunction(settings.handler) === false) { settings.handler = defaultHandler; } return { upload: upload }; } function FileReader () { var f = Global$1.getOrDie('FileReader'); return new f(); } function Uint8Array (arr) { var f = Global$1.getOrDie('Uint8Array'); return new f(arr); } var requestAnimationFrame$1 = function (callback) { var f = Global$1.getOrDie('requestAnimationFrame'); f(callback); }; var atob = function (base64) { var f = Global$1.getOrDie('atob'); return f(base64); }; var Window = { atob: atob, requestAnimationFrame: requestAnimationFrame$1 }; var blobUriToBlob = function (url) { return new promiseObj(function (resolve, reject) { var rejectWithError = function () { reject('Cannot convert ' + url + ' to Blob. Resource might not exist or is inaccessible.'); }; try { var xhr = XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'blob'; xhr.onload = function () { if (this.status === 200) { resolve(this.response); } else { rejectWithError(); } }; xhr.onerror = rejectWithError; xhr.send(); } catch (ex) { rejectWithError(); } }); }; var parseDataUri = function (uri) { var type, matches; var uriParts = decodeURIComponent(uri).split(','); matches = /data:([^;]+)/.exec(uriParts[0]); if (matches) { type = matches[1]; } return { type: type, data: uriParts[1] }; }; var dataUriToBlob = function (uri) { return new promiseObj(function (resolve) { var str, arr, i; var uriParts = parseDataUri(uri); try { str = Window.atob(uriParts.data); } catch (e) { resolve(new domGlobals.Blob([])); return; } arr = Uint8Array(str.length); for (i = 0; i < arr.length; i++) { arr[i] = str.charCodeAt(i); } resolve(new domGlobals.Blob([arr], { type: uriParts.type })); }); }; var uriToBlob = function (url) { if (url.indexOf('blob:') === 0) { return blobUriToBlob(url); } if (url.indexOf('data:') === 0) { return dataUriToBlob(url); } return null; }; var blobToDataUri = function (blob) { return new promiseObj(function (resolve) { var reader = FileReader(); reader.onloadend = function () { resolve(reader.result); }; reader.readAsDataURL(blob); }); }; var Conversions = { uriToBlob: uriToBlob, blobToDataUri: blobToDataUri, parseDataUri: parseDataUri }; var count = 0; var uniqueId = function (prefix) { return (prefix || 'blobid') + count++; }; var imageToBlobInfo = function (blobCache, img, resolve, reject) { var base64, blobInfo; if (img.src.indexOf('blob:') === 0) { blobInfo = blobCache.getByUri(img.src); if (blobInfo) { resolve({ image: img, blobInfo: blobInfo }); } else { Conversions.uriToBlob(img.src).then(function (blob) { Conversions.blobToDataUri(blob).then(function (dataUri) { base64 = Conversions.parseDataUri(dataUri).data; blobInfo = blobCache.create(uniqueId(), blob, base64); blobCache.add(blobInfo); resolve({ image: img, blobInfo: blobInfo }); }); }, function (err) { reject(err); }); } return; } base64 = Conversions.parseDataUri(img.src).data; blobInfo = blobCache.findFirst(function (cachedBlobInfo) { return cachedBlobInfo.base64() === base64; }); if (blobInfo) { resolve({ image: img, blobInfo: blobInfo }); } else { Conversions.uriToBlob(img.src).then(function (blob) { blobInfo = blobCache.create(uniqueId(), blob, base64); blobCache.add(blobInfo); resolve({ image: img, blobInfo: blobInfo }); }, function (err) { reject(err); }); } }; var getAllImages = function (elm) { return elm ? from$1(elm.getElementsByTagName('img')) : []; }; function ImageScanner (uploadStatus, blobCache) { var cachedPromises = {}; var findAll = function (elm, predicate) { var images; if (!predicate) { predicate = constant(true); } images = filter(getAllImages(elm), function (img) { var src = img.src; if (!Env.fileApi) { return false; } if (img.hasAttribute('data-mce-bogus')) { return false; } if (img.hasAttribute('data-mce-placeholder')) { return false; } if (!src || src === Env.transparentSrc) { return false; } if (src.indexOf('blob:') === 0) { return !uploadStatus.isUploaded(src) && predicate(img); } if (src.indexOf('data:') === 0) { return predicate(img); } return false; }); var promises = map(images, function (img) { if (cachedPromises[img.src]) { return new promiseObj(function (resolve) { cachedPromises[img.src].then(function (imageInfo) { if (typeof imageInfo === 'string') { return imageInfo; } resolve({ image: img, blobInfo: imageInfo.blobInfo }); }); }); } var newPromise = new promiseObj(function (resolve, reject) { imageToBlobInfo(blobCache, img, resolve, reject); }).then(function (result) { delete cachedPromises[result.image.src]; return result; }).catch(function (error) { delete cachedPromises[img.src]; return error; }); cachedPromises[img.src] = newPromise; return newPromise; }); return promiseObj.all(promises); }; return { findAll: findAll }; } var count$1 = 0; var seed = function () { var rnd = function () { return Math.round(Math.random() * 4294967295).toString(36); }; var now = new Date().getTime(); return 's' + now.toString(36) + rnd() + rnd() + rnd(); }; var uuid = function (prefix) { return prefix + count$1++ + seed(); }; var Uuid = { uuid: uuid }; function BlobCache () { var cache = []; var mimeToExt = function (mime) { var mimes = { 'image/jpeg': 'jpg', 'image/jpg': 'jpg', 'image/gif': 'gif', 'image/png': 'png' }; return mimes[mime.toLowerCase()] || 'dat'; }; var create = function (o, blob, base64, filename) { if (isString(o)) { var id = o; return toBlobInfo({ id: id, name: filename, blob: blob, base64: base64 }); } else if (isObject(o)) { return toBlobInfo(o); } else { throw new Error('Unknown input type'); } }; var toBlobInfo = function (o) { var id, name; if (!o.blob || !o.base64) { throw new Error('blob and base64 representations of the image are required for BlobInfo to be created'); } id = o.id || Uuid.uuid('blobid'); name = o.name || id; return { id: constant(id), name: constant(name), filename: constant(name + '.' + mimeToExt(o.blob.type)), blob: constant(o.blob), base64: constant(o.base64), blobUri: constant(o.blobUri || URL.createObjectURL(o.blob)), uri: constant(o.uri) }; }; var add = function (blobInfo) { if (!get(blobInfo.id())) { cache.push(blobInfo); } }; var get = function (id) { return findFirst(function (cachedBlobInfo) { return cachedBlobInfo.id() === id; }); }; var findFirst = function (predicate) { return filter(cache, predicate)[0]; }; var getByUri = function (blobUri) { return findFirst(function (blobInfo) { return blobInfo.blobUri() === blobUri; }); }; var removeByUri = function (blobUri) { cache = filter(cache, function (blobInfo) { if (blobInfo.blobUri() === blobUri) { URL.revokeObjectURL(blobInfo.blobUri()); return false; } return true; }); }; var destroy = function () { each(cache, function (cachedBlobInfo) { URL.revokeObjectURL(cachedBlobInfo.blobUri()); }); cache = []; }; return { create: create, add: add, get: get, getByUri: getByUri, findFirst: findFirst, removeByUri: removeByUri, destroy: destroy }; } function UploadStatus () { var PENDING = 1, UPLOADED = 2; var blobUriStatuses = {}; var createStatus = function (status, resultUri) { return { status: status, resultUri: resultUri }; }; var hasBlobUri = function (blobUri) { return blobUri in blobUriStatuses; }; var getResultUri = function (blobUri) { var result = blobUriStatuses[blobUri]; return result ? result.resultUri : null; }; var isPending = function (blobUri) { return hasBlobUri(blobUri) ? blobUriStatuses[blobUri].status === PENDING : false; }; var isUploaded = function (blobUri) { return hasBlobUri(blobUri) ? blobUriStatuses[blobUri].status === UPLOADED : false; }; var markPending = function (blobUri) { blobUriStatuses[blobUri] = createStatus(PENDING, null); }; var markUploaded = function (blobUri, resultUri) { blobUriStatuses[blobUri] = createStatus(UPLOADED, resultUri); }; var removeFailed = function (blobUri) { delete blobUriStatuses[blobUri]; }; var destroy = function () { blobUriStatuses = {}; }; return { hasBlobUri: hasBlobUri, getResultUri: getResultUri, isPending: isPending, isUploaded: isUploaded, markPending: markPending, markUploaded: markUploaded, removeFailed: removeFailed, destroy: destroy }; } function EditorUpload (editor) { var blobCache = BlobCache(); var uploader, imageScanner; var uploadStatus = UploadStatus(); var urlFilters = []; var aliveGuard = function (callback) { return function (result) { if (editor.selection) { return callback(result); } return []; }; }; var cacheInvalidator = function () { return '?' + new Date().getTime(); }; var replaceString = function (content, search, replace) { var index = 0; do { index = content.indexOf(search, index); if (index !== -1) { content = content.substring(0, index) + replace + content.substr(index + search.length); index += replace.length - search.length + 1; } } while (index !== -1); return content; }; var replaceImageUrl = function (content, targetUrl, replacementUrl) { content = replaceString(content, 'src="' + targetUrl + '"', 'src="' + replacementUrl + '"'); content = replaceString(content, 'data-mce-src="' + targetUrl + '"', 'data-mce-src="' + replacementUrl + '"'); return content; }; var replaceUrlInUndoStack = function (targetUrl, replacementUrl) { each(editor.undoManager.data, function (level) { if (level.type === 'fragmented') { level.fragments = map(level.fragments, function (fragment) { return replaceImageUrl(fragment, targetUrl, replacementUrl); }); } else { level.content = replaceImageUrl(level.content, targetUrl, replacementUrl); } }); }; var openNotification = function () { return editor.notificationManager.open({ text: editor.translate('Image uploading...'), type: 'info', timeout: -1, progressBar: true }); }; var replaceImageUri = function (image, resultUri) { blobCache.removeByUri(image.src); replaceUrlInUndoStack(image.src, resultUri); editor.$(image).attr({ 'src': Settings.shouldReuseFileName(editor) ? resultUri + cacheInvalidator() : resultUri, 'data-mce-src': editor.convertURL(resultUri, 'src') }); }; var uploadImages = function (callback) { if (!uploader) { uploader = Uploader(uploadStatus, { url: Settings.getImageUploadUrl(editor), basePath: Settings.getImageUploadBasePath(editor), credentials: Settings.getImagesUploadCredentials(editor), handler: Settings.getImagesUploadHandler(editor) }); } return scanForImages().then(aliveGuard(function (imageInfos) { var blobInfos; blobInfos = map(imageInfos, function (imageInfo) { return imageInfo.blobInfo; }); return uploader.upload(blobInfos, openNotification).then(aliveGuard(function (result) { var filteredResult = map(result, function (uploadInfo, index) { var image = imageInfos[index].image; if (uploadInfo.status && Settings.shouldReplaceBlobUris(editor)) { replaceImageUri(image, uploadInfo.url); } else if (uploadInfo.error) { ErrorReporter.uploadError(editor, uploadInfo.error); } return { element: image, status: uploadInfo.status }; }); if (callback) { callback(filteredResult); } return filteredResult; })); })); }; var uploadImagesAuto = function (callback) { if (Settings.isAutomaticUploadsEnabled(editor)) { return uploadImages(callback); } }; var isValidDataUriImage = function (imgElm) { if (forall(urlFilters, function (filter) { return filter(imgElm); }) === false) { return false; } if (imgElm.getAttribute('src').indexOf('data:') === 0) { var dataImgFilter = Settings.getImagesDataImgFilter(editor); return dataImgFilter(imgElm); } return true; }; var addFilter = function (filter) { urlFilters.push(filter); }; var scanForImages = function () { if (!imageScanner) { imageScanner = ImageScanner(uploadStatus, blobCache); } return imageScanner.findAll(editor.getBody(), isValidDataUriImage).then(aliveGuard(function (result) { result = filter(result, function (resultItem) { if (typeof resultItem === 'string') { ErrorReporter.displayError(editor, resultItem); return false; } return true; }); each(result, function (resultItem) { replaceUrlInUndoStack(resultItem.image.src, resultItem.blobInfo.blobUri()); resultItem.image.src = resultItem.blobInfo.blobUri(); resultItem.image.removeAttribute('data-mce-src'); }); return result; })); }; var destroy = function () { blobCache.destroy(); uploadStatus.destroy(); imageScanner = uploader = null; }; var replaceBlobUris = function (content) { return content.replace(/src="(blob:[^"]+)"/g, function (match, blobUri) { var resultUri = uploadStatus.getResultUri(blobUri); if (resultUri) { return 'src="' + resultUri + '"'; } var blobInfo = blobCache.getByUri(blobUri); if (!blobInfo) { blobInfo = foldl(editor.editorManager.get(), function (result, editor) { return result || editor.editorUpload && editor.editorUpload.blobCache.getByUri(blobUri); }, null); } if (blobInfo) { var blob = blobInfo.blob(); return 'src="data:' + blob.type + ';base64,' + blobInfo.base64() + '"'; } return match; }); }; editor.on('setContent', function () { if (Settings.isAutomaticUploadsEnabled(editor)) { uploadImagesAuto(); } else { scanForImages(); } }); editor.on('RawSaveContent', function (e) { e.content = replaceBlobUris(e.content); }); editor.on('getContent', function (e) { if (e.source_view || e.format === 'raw') { return; } e.content = replaceBlobUris(e.content); }); editor.on('PostRender', function () { editor.parser.addNodeFilter('img', function (images) { each(images, function (img) { var src = img.attr('src'); if (blobCache.getByUri(src)) { return; } var resultUri = uploadStatus.getResultUri(src); if (resultUri) { img.attr('src', resultUri); } }); }); }); return { blobCache: blobCache, addFilter: addFilter, uploadImages: uploadImages, uploadImagesAuto: uploadImagesAuto, scanForImages: scanForImages, destroy: destroy }; } var isBlockElement = function (blockElements, node) { return blockElements.hasOwnProperty(node.nodeName); }; var isValidTarget = function (blockElements, node) { if (NodeType.isText(node)) { return true; } else if (NodeType.isElement(node)) { return !isBlockElement(blockElements, node) && !Bookmarks.isBookmarkNode(node); } else { return false; } }; var hasBlockParent = function (blockElements, root, node) { return exists(Parents.parents(Element.fromDom(node), Element.fromDom(root)), function (elm) { return isBlockElement(blockElements, elm.dom()); }); }; var shouldRemoveTextNode = function (blockElements, node) { if (NodeType.isText(node)) { if (node.nodeValue.length === 0) { return true; } else if (/^\s+$/.test(node.nodeValue) && (!node.nextSibling || isBlockElement(blockElements, node.nextSibling))) { return true; } } return false; }; var addRootBlocks = function (editor) { var settings = editor.settings, dom = editor.dom, selection = editor.selection; var schema = editor.schema, blockElements = schema.getBlockElements(); var node = selection.getStart(); var rootNode = editor.getBody(); var rng; var startContainer, startOffset, endContainer, endOffset, rootBlockNode; var tempNode, wrapped, restoreSelection; var rootNodeName, forcedRootBlock; forcedRootBlock = settings.forced_root_block; if (!node || !NodeType.isElement(node) || !forcedRootBlock) { return; } rootNodeName = rootNode.nodeName.toLowerCase(); if (!schema.isValidChild(rootNodeName, forcedRootBlock.toLowerCase()) || hasBlockParent(blockElements, rootNode, node)) { return; } rng = selection.getRng(); startContainer = rng.startContainer; startOffset = rng.startOffset; endContainer = rng.endContainer; endOffset = rng.endOffset; restoreSelection = EditorFocus.hasFocus(editor); node = rootNode.firstChild; while (node) { if (isValidTarget(blockElements, node)) { if (shouldRemoveTextNode(blockElements, node)) { tempNode = node; node = node.nextSibling; dom.remove(tempNode); continue; } if (!rootBlockNode) { rootBlockNode = dom.create(forcedRootBlock, editor.settings.forced_root_block_attrs); node.parentNode.insertBefore(rootBlockNode, node); wrapped = true; } tempNode = node; node = node.nextSibling; rootBlockNode.appendChild(tempNode); } else { rootBlockNode = null; node = node.nextSibling; } } if (wrapped && restoreSelection) { rng.setStart(startContainer, startOffset); rng.setEnd(endContainer, endOffset); selection.setRng(rng); editor.nodeChanged(); } }; var setup$3 = function (editor) { if (editor.settings.forced_root_block) { editor.on('NodeChange', curry(addRootBlocks, editor)); } }; var ForceBlocks = { setup: setup$3 }; var getStartNode = function (rng) { var sc = rng.startContainer, so = rng.startOffset; if (NodeType.isText(sc)) { return so === 0 ? Option.some(Element.fromDom(sc)) : Option.none(); } else { return Option.from(sc.childNodes[so]).map(Element.fromDom); } }; var getEndNode = function (rng) { var ec = rng.endContainer, eo = rng.endOffset; if (NodeType.isText(ec)) { return eo === ec.data.length ? Option.some(Element.fromDom(ec)) : Option.none(); } else { return Option.from(ec.childNodes[eo - 1]).map(Element.fromDom); } }; var getFirstChildren = function (node) { return firstChild(node).fold(constant([node]), function (child) { return [node].concat(getFirstChildren(child)); }); }; var getLastChildren$1 = function (node) { return lastChild(node).fold(constant([node]), function (child) { if (name(child) === 'br') { return prevSibling(child).map(function (sibling) { return [node].concat(getLastChildren$1(sibling)); }).getOr([]); } else { return [node].concat(getLastChildren$1(child)); } }); }; var hasAllContentsSelected = function (elm, rng) { return liftN([ getStartNode(rng), getEndNode(rng) ], function (startNode, endNode) { var start = find(getFirstChildren(elm), curry(eq, startNode)); var end = find(getLastChildren$1(elm), curry(eq, endNode)); return start.isSome() && end.isSome(); }).getOr(false); }; var moveEndPoint$1 = function (dom, rng, node, start) { var root = node, walker = new TreeWalker(node, root); var nonEmptyElementsMap = dom.schema.getNonEmptyElements(); do { if (node.nodeType === 3 && Tools.trim(node.nodeValue).length !== 0) { if (start) { rng.setStart(node, 0); } else { rng.setEnd(node, node.nodeValue.length); } return; } if (nonEmptyElementsMap[node.nodeName] && !/^(TD|TH)$/.test(node.nodeName)) { if (start) { rng.setStartBefore(node); } else { if (node.nodeName === 'BR') { rng.setEndBefore(node); } else { rng.setEndAfter(node); } } return; } if (Env.ie && Env.ie < 11 && dom.isBlock(node) && dom.isEmpty(node)) { if (start) { rng.setStart(node, 0); } else { rng.setEnd(node, 0); } return; } } while (node = start ? walker.next() : walker.prev()); if (root.nodeName === 'BODY') { if (start) { rng.setStart(root, 0); } else { rng.setEnd(root, root.childNodes.length); } } }; var hasAnyRanges = function (editor) { var sel = editor.selection.getSel(); return sel && sel.rangeCount > 0; }; function NodeChange (editor) { var lastRng, lastPath = []; var isSameElementPath = function (startElm) { var i, currentPath; currentPath = editor.$(startElm).parentsUntil(editor.getBody()).add(startElm); if (currentPath.length === lastPath.length) { for (i = currentPath.length; i >= 0; i--) { if (currentPath[i] !== lastPath[i]) { break; } } if (i === -1) { lastPath = currentPath; return true; } } lastPath = currentPath; return false; }; if (!('onselectionchange' in editor.getDoc())) { editor.on('NodeChange Click MouseUp KeyUp Focus', function (e) { var nativeRng, fakeRng; nativeRng = editor.selection.getRng(); fakeRng = { startContainer: nativeRng.startContainer, startOffset: nativeRng.startOffset, endContainer: nativeRng.endContainer, endOffset: nativeRng.endOffset }; if (e.type === 'nodechange' || !RangeCompare.isEq(fakeRng, lastRng)) { editor.fire('SelectionChange'); } lastRng = fakeRng; }); } editor.on('contextmenu', function () { editor.fire('SelectionChange'); }); editor.on('SelectionChange', function () { var startElm = editor.selection.getStart(true); if (!startElm || !Env.range && editor.selection.isCollapsed()) { return; } if (hasAnyRanges(editor) && !isSameElementPath(startElm) && editor.dom.isChildOf(startElm, editor.getBody())) { editor.nodeChanged({ selectionChange: true }); } }); editor.on('MouseUp', function (e) { if (!e.isDefaultPrevented() && hasAnyRanges(editor)) { if (editor.selection.getNode().nodeName === 'IMG') { Delay.setEditorTimeout(editor, function () { editor.nodeChanged(); }); } else { editor.nodeChanged(); } } }); this.nodeChanged = function (args) { var selection = editor.selection; var node, parents, root; if (editor.initialized && selection && !editor.settings.disable_nodechange && !editor.readonly) { root = editor.getBody(); node = selection.getStart(true) || root; if (node.ownerDocument !== editor.getDoc() || !editor.dom.isChildOf(node, root)) { node = root; } parents = []; editor.dom.getParent(node, function (node) { if (node === root) { return true; } parents.push(node); }); args = args || {}; args.element = node; args.parents = parents; editor.fire('NodeChange', args); } }; } var getAbsolutePosition = function (elm) { var doc, docElem, win, clientRect; clientRect = elm.getBoundingClientRect(); doc = elm.ownerDocument; docElem = doc.documentElement; win = doc.defaultView; return { top: clientRect.top + win.pageYOffset - docElem.clientTop, left: clientRect.left + win.pageXOffset - docElem.clientLeft }; }; var getBodyPosition = function (editor) { return editor.inline ? getAbsolutePosition(editor.getBody()) : { left: 0, top: 0 }; }; var getScrollPosition = function (editor) { var body = editor.getBody(); return editor.inline ? { left: body.scrollLeft, top: body.scrollTop } : { left: 0, top: 0 }; }; var getBodyScroll = function (editor) { var body = editor.getBody(), docElm = editor.getDoc().documentElement; var inlineScroll = { left: body.scrollLeft, top: body.scrollTop }; var iframeScroll = { left: body.scrollLeft || docElm.scrollLeft, top: body.scrollTop || docElm.scrollTop }; return editor.inline ? inlineScroll : iframeScroll; }; var getMousePosition = function (editor, event) { if (event.target.ownerDocument !== editor.getDoc()) { var iframePosition = getAbsolutePosition(editor.getContentAreaContainer()); var scrollPosition = getBodyScroll(editor); return { left: event.pageX - iframePosition.left + scrollPosition.left, top: event.pageY - iframePosition.top + scrollPosition.top }; } return { left: event.pageX, top: event.pageY }; }; var calculatePosition = function (bodyPosition, scrollPosition, mousePosition) { return { pageX: mousePosition.left - bodyPosition.left + scrollPosition.left, pageY: mousePosition.top - bodyPosition.top + scrollPosition.top }; }; var calc = function (editor, event) { return calculatePosition(getBodyPosition(editor), getScrollPosition(editor), getMousePosition(editor, event)); }; var MousePosition = { calc: calc }; var isContentEditableFalse$7 = NodeType.isContentEditableFalse, isContentEditableTrue$3 = NodeType.isContentEditableTrue; var isDraggable = function (rootElm, elm) { return isContentEditableFalse$7(elm) && elm !== rootElm; }; var isValidDropTarget = function (editor, targetElement, dragElement) { if (targetElement === dragElement || editor.dom.isChildOf(targetElement, dragElement)) { return false; } if (isContentEditableFalse$7(targetElement)) { return false; } return true; }; var cloneElement = function (elm) { var cloneElm = elm.cloneNode(true); cloneElm.removeAttribute('data-mce-selected'); return cloneElm; }; var createGhost = function (editor, elm, width, height) { var clonedElm = elm.cloneNode(true); editor.dom.setStyles(clonedElm, { width: width, height: height }); editor.dom.setAttrib(clonedElm, 'data-mce-selected', null); var ghostElm = editor.dom.create('div', { 'class': 'mce-drag-container', 'data-mce-bogus': 'all', 'unselectable': 'on', 'contenteditable': 'false' }); editor.dom.setStyles(ghostElm, { position: 'absolute', opacity: 0.5, overflow: 'hidden', border: 0, padding: 0, margin: 0, width: width, height: height }); editor.dom.setStyles(clonedElm, { margin: 0, boxSizing: 'border-box' }); ghostElm.appendChild(clonedElm); return ghostElm; }; var appendGhostToBody = function (ghostElm, bodyElm) { if (ghostElm.parentNode !== bodyElm) { bodyElm.appendChild(ghostElm); } }; var moveGhost = function (ghostElm, position, width, height, maxX, maxY) { var overflowX = 0, overflowY = 0; ghostElm.style.left = position.pageX + 'px'; ghostElm.style.top = position.pageY + 'px'; if (position.pageX + width > maxX) { overflowX = position.pageX + width - maxX; } if (position.pageY + height > maxY) { overflowY = position.pageY + height - maxY; } ghostElm.style.width = width - overflowX + 'px'; ghostElm.style.height = height - overflowY + 'px'; }; var removeElement = function (elm) { if (elm && elm.parentNode) { elm.parentNode.removeChild(elm); } }; var isLeftMouseButtonPressed = function (e) { return e.button === 0; }; var hasDraggableElement = function (state) { return state.element; }; var applyRelPos = function (state, position) { return { pageX: position.pageX - state.relX, pageY: position.pageY + 5 }; }; var start$1 = function (state, editor) { return function (e) { if (isLeftMouseButtonPressed(e)) { var ceElm = find(editor.dom.getParents(e.target), Predicate.or(isContentEditableFalse$7, isContentEditableTrue$3)).getOr(null); if (isDraggable(editor.getBody(), ceElm)) { var elmPos = editor.dom.getPos(ceElm); var bodyElm = editor.getBody(); var docElm = editor.getDoc().documentElement; state.element = ceElm; state.screenX = e.screenX; state.screenY = e.screenY; state.maxX = (editor.inline ? bodyElm.scrollWidth : docElm.offsetWidth) - 2; state.maxY = (editor.inline ? bodyElm.scrollHeight : docElm.offsetHeight) - 2; state.relX = e.pageX - elmPos.x; state.relY = e.pageY - elmPos.y; state.width = ceElm.offsetWidth; state.height = ceElm.offsetHeight; state.ghost = createGhost(editor, ceElm, state.width, state.height); } } }; }; var move$1 = function (state, editor) { var throttledPlaceCaretAt = Delay.throttle(function (clientX, clientY) { editor._selectionOverrides.hideFakeCaret(); editor.selection.placeCaretAt(clientX, clientY); }, 0); return function (e) { var movement = Math.max(Math.abs(e.screenX - state.screenX), Math.abs(e.screenY - state.screenY)); if (hasDraggableElement(state) && !state.dragging && movement > 10) { var args = editor.fire('dragstart', { target: state.element }); if (args.isDefaultPrevented()) { return; } state.dragging = true; editor.focus(); } if (state.dragging) { var targetPos = applyRelPos(state, MousePosition.calc(editor, e)); appendGhostToBody(state.ghost, editor.getBody()); moveGhost(state.ghost, targetPos, state.width, state.height, state.maxX, state.maxY); throttledPlaceCaretAt(e.clientX, e.clientY); } }; }; var getRawTarget = function (selection) { var rng = selection.getSel().getRangeAt(0); var startContainer = rng.startContainer; return startContainer.nodeType === 3 ? startContainer.parentNode : startContainer; }; var drop = function (state, editor) { return function (e) { if (state.dragging) { if (isValidDropTarget(editor, getRawTarget(editor.selection), state.element)) { var targetClone_1 = cloneElement(state.element); var args = editor.fire('drop', { targetClone: targetClone_1, clientX: e.clientX, clientY: e.clientY }); if (!args.isDefaultPrevented()) { targetClone_1 = args.targetClone; editor.undoManager.transact(function () { removeElement(state.element); editor.insertContent(editor.dom.getOuterHTML(targetClone_1)); editor._selectionOverrides.hideFakeCaret(); }); } } } removeDragState(state); }; }; var stop = function (state, editor) { return function () { if (state.dragging) { editor.fire('dragend'); } removeDragState(state); }; }; var removeDragState = function (state) { state.dragging = false; state.element = null; removeElement(state.ghost); }; var bindFakeDragEvents = function (editor) { var state = {}; var pageDom, dragStartHandler, dragHandler, dropHandler, dragEndHandler, rootDocument; pageDom = DOMUtils$1.DOM; rootDocument = domGlobals.document; dragStartHandler = start$1(state, editor); dragHandler = move$1(state, editor); dropHandler = drop(state, editor); dragEndHandler = stop(state, editor); editor.on('mousedown', dragStartHandler); editor.on('mousemove', dragHandler); editor.on('mouseup', dropHandler); pageDom.bind(rootDocument, 'mousemove', dragHandler); pageDom.bind(rootDocument, 'mouseup', dragEndHandler); editor.on('remove', function () { pageDom.unbind(rootDocument, 'mousemove', dragHandler); pageDom.unbind(rootDocument, 'mouseup', dragEndHandler); }); }; var blockIeDrop = function (editor) { editor.on('drop', function (e) { var realTarget = typeof e.clientX !== 'undefined' ? editor.getDoc().elementFromPoint(e.clientX, e.clientY) : null; if (isContentEditableFalse$7(realTarget) || isContentEditableFalse$7(editor.dom.getContentEditableParent(realTarget))) { e.preventDefault(); } }); }; var init = function (editor) { bindFakeDragEvents(editor); blockIeDrop(editor); }; var DragDropOverrides = { init: init }; var getNodeClientRects = function (node) { var toArrayWithNode = function (clientRects) { return map(clientRects, function (clientRect) { clientRect = clone$1(clientRect); clientRect.node = node; return clientRect; }); }; if (NodeType.isElement(node)) { return toArrayWithNode(node.getClientRects()); } if (NodeType.isText(node)) { var rng = node.ownerDocument.createRange(); rng.setStart(node, 0); rng.setEnd(node, node.data.length); return toArrayWithNode(rng.getClientRects()); } }; var getClientRects = function (node) { return foldl(node, function (result, node) { return result.concat(getNodeClientRects(node)); }, []); }; var VDirection; (function (VDirection) { VDirection[VDirection['Up'] = -1] = 'Up'; VDirection[VDirection['Down'] = 1] = 'Down'; }(VDirection || (VDirection = {}))); var findUntil = function (direction, root, predicateFn, node) { while (node = findNode(node, direction, isEditableCaretCandidate, root)) { if (predicateFn(node)) { return; } } }; var walkUntil = function (direction, isAboveFn, isBeflowFn, root, predicateFn, caretPosition) { var line = 0, node; var result = []; var targetClientRect; var add = function (node) { var i, clientRect, clientRects; clientRects = getClientRects([node]); if (direction === -1) { clientRects = clientRects.reverse(); } for (i = 0; i < clientRects.length; i++) { clientRect = clientRects[i]; if (isBeflowFn(clientRect, targetClientRect)) { continue; } if (result.length > 0 && isAboveFn(clientRect, ArrUtils.last(result))) { line++; } clientRect.line = line; if (predicateFn(clientRect)) { return true; } result.push(clientRect); } }; targetClientRect = ArrUtils.last(caretPosition.getClientRects()); if (!targetClientRect) { return result; } node = caretPosition.getNode(); add(node); findUntil(direction, root, add, node); return result; }; var aboveLineNumber = function (lineNumber, clientRect) { return clientRect.line > lineNumber; }; var isLineNumber = function (lineNumber, clientRect) { return clientRect.line === lineNumber; }; var upUntil = curry(walkUntil, VDirection.Up, isAbove, isBelow); var downUntil = curry(walkUntil, VDirection.Down, isBelow, isAbove); var positionsUntil = function (direction, root, predicateFn, node) { var caretWalker = CaretWalker(root); var walkFn, isBelowFn, isAboveFn, caretPosition; var result = []; var line = 0, clientRect, targetClientRect; var getClientRect = function (caretPosition) { if (direction === 1) { return ArrUtils.last(caretPosition.getClientRects()); } return ArrUtils.last(caretPosition.getClientRects()); }; if (direction === 1) { walkFn = caretWalker.next; isBelowFn = isBelow; isAboveFn = isAbove; caretPosition = CaretPosition$1.after(node); } else { walkFn = caretWalker.prev; isBelowFn = isAbove; isAboveFn = isBelow; caretPosition = CaretPosition$1.before(node); } targetClientRect = getClientRect(caretPosition); do { if (!caretPosition.isVisible()) { continue; } clientRect = getClientRect(caretPosition); if (isAboveFn(clientRect, targetClientRect)) { continue; } if (result.length > 0 && isBelowFn(clientRect, ArrUtils.last(result))) { line++; } clientRect = clone$1(clientRect); clientRect.position = caretPosition; clientRect.line = line; if (predicateFn(clientRect)) { return result; } result.push(clientRect); } while (caretPosition = walkFn(caretPosition)); return result; }; var isAboveLine = function (lineNumber) { return function (clientRect) { return aboveLineNumber(lineNumber, clientRect); }; }; var isLine = function (lineNumber) { return function (clientRect) { return isLineNumber(lineNumber, clientRect); }; }; var isContentEditableFalse$8 = NodeType.isContentEditableFalse; var findNode$1 = findNode; var distanceToRectLeft = function (clientRect, clientX) { return Math.abs(clientRect.left - clientX); }; var distanceToRectRight = function (clientRect, clientX) { return Math.abs(clientRect.right - clientX); }; var isInside = function (clientX, clientRect) { return clientX >= clientRect.left && clientX <= clientRect.right; }; var findClosestClientRect = function (clientRects, clientX) { return ArrUtils.reduce(clientRects, function (oldClientRect, clientRect) { var oldDistance, newDistance; oldDistance = Math.min(distanceToRectLeft(oldClientRect, clientX), distanceToRectRight(oldClientRect, clientX)); newDistance = Math.min(distanceToRectLeft(clientRect, clientX), distanceToRectRight(clientRect, clientX)); if (isInside(clientX, clientRect)) { return clientRect; } if (isInside(clientX, oldClientRect)) { return oldClientRect; } if (newDistance === oldDistance && isContentEditableFalse$8(clientRect.node)) { return clientRect; } if (newDistance < oldDistance) { return clientRect; } return oldClientRect; }); }; var walkUntil$1 = function (direction, root, predicateFn, node) { while (node = findNode$1(node, direction, isEditableCaretCandidate, root)) { if (predicateFn(node)) { return; } } }; var findLineNodeRects = function (root, targetNodeRect) { var clientRects = []; var collect = function (checkPosFn, node) { var lineRects; lineRects = filter(getClientRects([node]), function (clientRect) { return !checkPosFn(clientRect, targetNodeRect); }); clientRects = clientRects.concat(lineRects); return lineRects.length === 0; }; clientRects.push(targetNodeRect); walkUntil$1(VDirection.Up, root, curry(collect, isAbove), targetNodeRect.node); walkUntil$1(VDirection.Down, root, curry(collect, isBelow), targetNodeRect.node); return clientRects; }; var getFakeCaretTargets = function (root) { return filter(from$1(root.getElementsByTagName('*')), isFakeCaretTarget); }; var caretInfo = function (clientRect, clientX) { return { node: clientRect.node, before: distanceToRectLeft(clientRect, clientX) < distanceToRectRight(clientRect, clientX) }; }; var closestCaret = function (root, clientX, clientY) { var closestNodeRect; var contentEditableFalseNodeRects = getClientRects(getFakeCaretTargets(root)); var targetNodeRects = filter(contentEditableFalseNodeRects, function (rect) { return clientY >= rect.top && clientY <= rect.bottom; }); closestNodeRect = findClosestClientRect(targetNodeRects, clientX); if (closestNodeRect) { closestNodeRect = findClosestClientRect(findLineNodeRects(root, closestNodeRect), clientX); if (closestNodeRect && isFakeCaretTarget(closestNodeRect.node)) { return caretInfo(closestNodeRect, clientX); } } return null; }; var isXYWithinRange = function (clientX, clientY, range) { if (range.collapsed) { return false; } return foldl(range.getClientRects(), function (state, rect) { return state || containsXY(rect, clientX, clientY); }, false); }; var RangePoint = { isXYWithinRange: isXYWithinRange }; var setup$4 = function (editor) { var renderFocusCaret = first(function () { if (!editor.removed) { var rng = editor.selection.getRng(); if (rng.collapsed) { var caretRange = renderRangeCaret(editor, editor.selection.getRng(), false); editor.selection.setRng(caretRange); } } }, 0); editor.on('focus', function () { renderFocusCaret.throttle(); }); editor.on('blur', function () { renderFocusCaret.cancel(); }); }; var CefFocus = { setup: setup$4 }; var VK = { BACKSPACE: 8, DELETE: 46, DOWN: 40, ENTER: 13, LEFT: 37, RIGHT: 39, SPACEBAR: 32, TAB: 9, UP: 38, END: 35, HOME: 36, modifierPressed: function (e) { return e.shiftKey || e.ctrlKey || e.altKey || this.metaKeyPressed(e); }, metaKeyPressed: function (e) { return Env.mac ? e.metaKey : e.ctrlKey && !e.altKey; } }; var isContentEditableTrue$4 = NodeType.isContentEditableTrue; var isContentEditableFalse$9 = NodeType.isContentEditableFalse; var getContentEditableRoot$1 = function (editor, node) { var root = editor.getBody(); while (node && node !== root) { if (isContentEditableTrue$4(node) || isContentEditableFalse$9(node)) { return node; } node = node.parentNode; } return null; }; var SelectionOverrides = function (editor) { var isBlock = function (node) { return editor.dom.isBlock(node); }; var rootNode = editor.getBody(); var fakeCaret = FakeCaret(editor.getBody(), isBlock, function () { return EditorFocus.hasFocus(editor); }); var realSelectionId = 'sel-' + editor.dom.uniqueId(); var selectedContentEditableNode; var isFakeSelectionElement = function (elm) { return editor.dom.hasClass(elm, 'mce-offscreen-selection'); }; var getRealSelectionElement = function () { var container = editor.dom.get(realSelectionId); return container ? container.getElementsByTagName('*')[0] : container; }; var setRange = function (range) { if (range) { editor.selection.setRng(range); } }; var getRange = function () { return editor.selection.getRng(); }; var showCaret = function (direction, node, before, scrollIntoView) { if (scrollIntoView === void 0) { scrollIntoView = true; } var e; e = editor.fire('ShowCaret', { target: node, direction: direction, before: before }); if (e.isDefaultPrevented()) { return null; } if (scrollIntoView) { editor.selection.scrollIntoView(node, direction === -1); } return fakeCaret.show(before, node); }; var getNormalizedRangeEndPoint = function (direction, range) { range = normalizeRange(direction, rootNode, range); if (direction === -1) { return CaretPosition$1.fromRangeStart(range); } return CaretPosition$1.fromRangeEnd(range); }; var showBlockCaretContainer = function (blockCaretContainer) { if (blockCaretContainer.hasAttribute('data-mce-caret')) { showCaretContainerBlock(blockCaretContainer); setRange(getRange()); editor.selection.scrollIntoView(blockCaretContainer[0]); } }; var registerEvents = function () { editor.on('mouseup', function (e) { var range = getRange(); if (range.collapsed && EditorView.isXYInContentArea(editor, e.clientX, e.clientY)) { setRange(renderCaretAtRange(editor, range, false)); } }); editor.on('click', function (e) { var contentEditableRoot; contentEditableRoot = getContentEditableRoot$1(editor, e.target); if (contentEditableRoot) { if (isContentEditableFalse$9(contentEditableRoot)) { e.preventDefault(); editor.focus(); } if (isContentEditableTrue$4(contentEditableRoot)) { if (editor.dom.isChildOf(contentEditableRoot, editor.selection.getNode())) { removeContentEditableSelection(); } } } }); editor.on('blur NewBlock', function () { removeContentEditableSelection(); }); editor.on('ResizeWindow FullscreenStateChanged', function () { return fakeCaret.reposition(); }); var handleTouchSelect = function (editor) { var moved = false; editor.on('touchstart', function () { moved = false; }); editor.on('touchmove', function () { moved = true; }); editor.on('touchend', function (e) { var contentEditableRoot = getContentEditableRoot$1(editor, e.target); if (isContentEditableFalse$9(contentEditableRoot)) { if (!moved) { e.preventDefault(); setContentEditableSelection(selectNode(editor, contentEditableRoot)); } } }); }; var hasNormalCaretPosition = function (elm) { var caretWalker = CaretWalker(elm); if (!elm.firstChild) { return false; } var startPos = CaretPosition$1.before(elm.firstChild); var newPos = caretWalker.next(startPos); return newPos && !isBeforeContentEditableFalse(newPos) && !isAfterContentEditableFalse(newPos); }; var isInSameBlock = function (node1, node2) { var block1 = editor.dom.getParent(node1, editor.dom.isBlock); var block2 = editor.dom.getParent(node2, editor.dom.isBlock); return block1 === block2; }; var hasBetterMouseTarget = function (targetNode, caretNode) { var targetBlock = editor.dom.getParent(targetNode, editor.dom.isBlock); var caretBlock = editor.dom.getParent(caretNode, editor.dom.isBlock); if (targetBlock && editor.dom.isChildOf(targetBlock, caretBlock) && isContentEditableFalse$9(getContentEditableRoot$1(editor, targetBlock)) === false) { return true; } return targetBlock && !isInSameBlock(targetBlock, caretBlock) && hasNormalCaretPosition(targetBlock); }; handleTouchSelect(editor); editor.on('mousedown', function (e) { var contentEditableRoot; var targetElm = e.target; if (targetElm !== rootNode && targetElm.nodeName !== 'HTML' && !editor.dom.isChildOf(targetElm, rootNode)) { return; } if (EditorView.isXYInContentArea(editor, e.clientX, e.clientY) === false) { return; } contentEditableRoot = getContentEditableRoot$1(editor, targetElm); if (contentEditableRoot) { if (isContentEditableFalse$9(contentEditableRoot)) { e.preventDefault(); setContentEditableSelection(selectNode(editor, contentEditableRoot)); } else { removeContentEditableSelection(); if (!(isContentEditableTrue$4(contentEditableRoot) && e.shiftKey) && !RangePoint.isXYWithinRange(e.clientX, e.clientY, editor.selection.getRng())) { hideFakeCaret(); editor.selection.placeCaretAt(e.clientX, e.clientY); } } } else if (isFakeCaretTarget(targetElm) === false) { removeContentEditableSelection(); hideFakeCaret(); var caretInfo = closestCaret(rootNode, e.clientX, e.clientY); if (caretInfo) { if (!hasBetterMouseTarget(e.target, caretInfo.node)) { e.preventDefault(); var range = showCaret(1, caretInfo.node, caretInfo.before, false); editor.getBody().focus(); setRange(range); } } } }); editor.on('keypress', function (e) { if (VK.modifierPressed(e)) { return; } switch (e.keyCode) { default: if (isContentEditableFalse$9(editor.selection.getNode())) { e.preventDefault(); } break; } }); editor.on('getSelectionRange', function (e) { var rng = e.range; if (selectedContentEditableNode) { if (!selectedContentEditableNode.parentNode) { selectedContentEditableNode = null; return; } rng = rng.cloneRange(); rng.selectNode(selectedContentEditableNode); e.range = rng; } }); editor.on('setSelectionRange', function (e) { var rng; rng = setContentEditableSelection(e.range, e.forward); if (rng) { e.range = rng; } }); var isPasteBin = function (node) { return node.id === 'mcepastebin'; }; editor.on('AfterSetSelectionRange', function (e) { var rng = e.range; if (!isRangeInCaretContainer(rng) && !isPasteBin(rng.startContainer.parentNode)) { hideFakeCaret(); } if (!isFakeSelectionElement(rng.startContainer.parentNode)) { removeContentEditableSelection(); } }); editor.on('copy', function (e) { var clipboardData = e.clipboardData; if (!e.isDefaultPrevented() && e.clipboardData && !Env.ie) { var realSelectionElement = getRealSelectionElement(); if (realSelectionElement) { e.preventDefault(); clipboardData.clearData(); clipboardData.setData('text/html', realSelectionElement.outerHTML); clipboardData.setData('text/plain', realSelectionElement.outerText); } } }); DragDropOverrides.init(editor); CefFocus.setup(editor); }; var addCss = function () { var styles = editor.contentStyles, rootClass = '.mce-content-body'; styles.push(fakeCaret.getCss()); styles.push(rootClass + ' .mce-offscreen-selection {' + 'position: absolute;' + 'left: -9999999999px;' + 'max-width: 1000000px;' + '}' + rootClass + ' *[contentEditable=false] {' + 'cursor: default;' + '}' + rootClass + ' *[contentEditable=true] {' + 'cursor: text;' + '}'); }; var isWithinCaretContainer = function (node) { return isCaretContainer(node) || startsWithCaretContainer(node) || endsWithCaretContainer(node); }; var isRangeInCaretContainer = function (rng) { return isWithinCaretContainer(rng.startContainer) || isWithinCaretContainer(rng.endContainer); }; var setContentEditableSelection = function (range, forward) { var node; var $ = editor.$; var dom = editor.dom; var $realSelectionContainer, sel, startContainer, startOffset, endOffset, e, caretPosition, targetClone, origTargetClone; if (!range) { return null; } if (range.collapsed) { if (!isRangeInCaretContainer(range)) { if (forward === false) { caretPosition = getNormalizedRangeEndPoint(-1, range); if (isFakeCaretTarget(caretPosition.getNode(true))) { return showCaret(-1, caretPosition.getNode(true), false, false); } if (isFakeCaretTarget(caretPosition.getNode())) { return showCaret(-1, caretPosition.getNode(), !caretPosition.isAtEnd(), false); } } else { caretPosition = getNormalizedRangeEndPoint(1, range); if (isFakeCaretTarget(caretPosition.getNode())) { return showCaret(1, caretPosition.getNode(), !caretPosition.isAtEnd(), false); } if (isFakeCaretTarget(caretPosition.getNode(true))) { return showCaret(1, caretPosition.getNode(true), false, false); } } } return null; } startContainer = range.startContainer; startOffset = range.startOffset; endOffset = range.endOffset; if (startContainer.nodeType === 3 && startOffset === 0 && isContentEditableFalse$9(startContainer.parentNode)) { startContainer = startContainer.parentNode; startOffset = dom.nodeIndex(startContainer); startContainer = startContainer.parentNode; } if (startContainer.nodeType !== 1) { return null; } if (endOffset === startOffset + 1) { node = startContainer.childNodes[startOffset]; } if (!isContentEditableFalse$9(node)) { return null; } targetClone = origTargetClone = node.cloneNode(true); e = editor.fire('ObjectSelected', { target: node, targetClone: targetClone }); if (e.isDefaultPrevented()) { return null; } $realSelectionContainer = descendant(Element.fromDom(editor.getBody()), '#' + realSelectionId).fold(function () { return $([]); }, function (elm) { return $([elm.dom()]); }); targetClone = e.targetClone; if ($realSelectionContainer.length === 0) { $realSelectionContainer = $('<div data-mce-bogus="all" class="mce-offscreen-selection"></div>').attr('id', realSelectionId); $realSelectionContainer.appendTo(editor.getBody()); } range = editor.dom.createRng(); if (targetClone === origTargetClone && Env.ie) { $realSelectionContainer.empty().append('<p style="font-size: 0" data-mce-bogus="all">\xA0</p>').append(targetClone); range.setStartAfter($realSelectionContainer[0].firstChild.firstChild); range.setEndAfter(targetClone); } else { $realSelectionContainer.empty().append('\xA0').append(targetClone).append('\xA0'); range.setStart($realSelectionContainer[0].firstChild, 1); range.setEnd($realSelectionContainer[0].lastChild, 0); } $realSelectionContainer.css({ top: dom.getPos(node, editor.getBody()).y }); $realSelectionContainer[0].focus(); sel = editor.selection.getSel(); sel.removeAllRanges(); sel.addRange(range); each(descendants$1(Element.fromDom(editor.getBody()), '*[data-mce-selected]'), function (elm) { remove(elm, 'data-mce-selected'); }); node.setAttribute('data-mce-selected', '1'); selectedContentEditableNode = node; hideFakeCaret(); return range; }; var removeContentEditableSelection = function () { if (selectedContentEditableNode) { selectedContentEditableNode.removeAttribute('data-mce-selected'); descendant(Element.fromDom(editor.getBody()), '#' + realSelectionId).each(remove$1); selectedContentEditableNode = null; } descendant(Element.fromDom(editor.getBody()), '#' + realSelectionId).each(remove$1); selectedContentEditableNode = null; }; var destroy = function () { fakeCaret.destroy(); selectedContentEditableNode = null; }; var hideFakeCaret = function () { fakeCaret.hide(); }; if (Env.ceFalse) { registerEvents(); addCss(); } return { showCaret: showCaret, showBlockCaretContainer: showBlockCaretContainer, hideFakeCaret: hideFakeCaret, destroy: destroy }; }; var isValidPrefixAttrName = function (name) { return name.indexOf('data-') === 0 || name.indexOf('aria-') === 0; }; var trimComments = function (text) { return text.replace(/<!--|-->/g, ''); }; var isInvalidUri = function (settings, uri) { if (settings.allow_html_data_urls) { return false; } else if (/^data:image\//i.test(uri)) { return settings.allow_svg_data_urls === false && /^data:image\/svg\+xml/i.test(uri); } else { return /^data:/i.test(uri); } }; var findEndTagIndex = function (schema, html, startIndex) { var count = 1, index, matches, tokenRegExp, shortEndedElements; shortEndedElements = schema.getShortEndedElements(); tokenRegExp = /<([!?\/])?([A-Za-z0-9\-_\:\.]+)((?:\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\/|\s+)>/g; tokenRegExp.lastIndex = index = startIndex; while (matches = tokenRegExp.exec(html)) { index = tokenRegExp.lastIndex; if (matches[1] === '/') { count--; } else if (!matches[1]) { if (matches[2] in shortEndedElements) { continue; } count++; } if (count === 0) { break; } } return index; }; var checkBogusAttribute = function (regExp, attrString) { var matches = regExp.exec(attrString); if (matches) { var name = matches[1]; var value = matches[2]; return typeof name === 'string' && name.toLowerCase() === 'data-mce-bogus' ? value : null; } else { return null; } }; function SaxParser(settings, schema) { if (schema === void 0) { schema = Schema(); } var noop = function () { }; settings = settings || {}; if (settings.fix_self_closing !== false) { settings.fix_self_closing = true; } var comment = settings.comment ? settings.comment : noop; var cdata = settings.cdata ? settings.cdata : noop; var text = settings.text ? settings.text : noop; var start = settings.start ? settings.start : noop; var end = settings.end ? settings.end : noop; var pi = settings.pi ? settings.pi : noop; var doctype = settings.doctype ? settings.doctype : noop; var parse = function (html) { var matches, index = 0, value, endRegExp; var stack = []; var attrList, i, textData, name; var isInternalElement, removeInternalElements, shortEndedElements, fillAttrsMap, isShortEnded; var validate, elementRule, isValidElement, attr, attribsValue, validAttributesMap, validAttributePatterns; var attributesRequired, attributesDefault, attributesForced, processHtml; var anyAttributesRequired, selfClosing, tokenRegExp, attrRegExp, specialElements, attrValue, idCount = 0; var decode = Entities.decode; var fixSelfClosing; var filteredUrlAttrs = Tools.makeMap('src,href,data,background,formaction,poster,xlink:href'); var scriptUriRegExp = /((java|vb)script|mhtml):/i; var processEndTag = function (name) { var pos, i; pos = stack.length; while (pos--) { if (stack[pos].name === name) { break; } } if (pos >= 0) { for (i = stack.length - 1; i >= pos; i--) { name = stack[i]; if (name.valid) { end(name.name); } } stack.length = pos; } }; var parseAttribute = function (match, name, value, val2, val3) { var attrRule, i; var trimRegExp = /[\s\u0000-\u001F]+/g; name = name.toLowerCase(); value = name in fillAttrsMap ? name : decode(value || val2 || val3 || ''); if (validate && !isInternalElement && isValidPrefixAttrName(name) === false) { attrRule = validAttributesMap[name]; if (!attrRule && validAttributePatterns) { i = validAttributePatterns.length; while (i--) { attrRule = validAttributePatterns[i]; if (attrRule.pattern.test(name)) { break; } } if (i === -1) { attrRule = null; } } if (!attrRule) { return; } if (attrRule.validValues && !(value in attrRule.validValues)) { return; } } if (filteredUrlAttrs[name] && !settings.allow_script_urls) { var uri = value.replace(trimRegExp, ''); try { uri = decodeURIComponent(uri); } catch (ex) { uri = unescape(uri); } if (scriptUriRegExp.test(uri)) { return; } if (isInvalidUri(settings, uri)) { return; } } if (isInternalElement && (name in filteredUrlAttrs || name.indexOf('on') === 0)) { return; } attrList.map[name] = value; attrList.push({ name: name, value: value }); }; tokenRegExp = new RegExp('<(?:' + '(?:!--([\\w\\W]*?)-->)|' + '(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|' + '(?:!DOCTYPE([\\w\\W]*?)>)|' + '(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|' + '(?:\\/([A-Za-z][A-Za-z0-9\\-_\\:\\.]*)>)|' + '(?:([A-Za-z][A-Za-z0-9\\-_\\:\\.]*)((?:\\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\\/|\\s+)>)' + ')', 'g'); attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:[^\"])*)\")|(?:\'((?:[^\'])*)\')|([^>\s]+)))?/g; shortEndedElements = schema.getShortEndedElements(); selfClosing = settings.self_closing_elements || schema.getSelfClosingElements(); fillAttrsMap = schema.getBoolAttrs(); validate = settings.validate; removeInternalElements = settings.remove_internals; fixSelfClosing = settings.fix_self_closing; specialElements = schema.getSpecialElements(); processHtml = html + '>'; while (matches = tokenRegExp.exec(processHtml)) { if (index < matches.index) { text(decode(html.substr(index, matches.index - index))); } if (value = matches[6]) { value = value.toLowerCase(); if (value.charAt(0) === ':') { value = value.substr(1); } processEndTag(value); } else if (value = matches[7]) { if (matches.index + matches[0].length > html.length) { text(decode(html.substr(matches.index))); index = matches.index + matches[0].length; continue; } value = value.toLowerCase(); if (value.charAt(0) === ':') { value = value.substr(1); } isShortEnded = value in shortEndedElements; if (fixSelfClosing && selfClosing[value] && stack.length > 0 && stack[stack.length - 1].name === value) { processEndTag(value); } var bogusValue = checkBogusAttribute(attrRegExp, matches[8]); if (bogusValue !== null) { if (bogusValue === 'all') { index = findEndTagIndex(schema, html, tokenRegExp.lastIndex); tokenRegExp.lastIndex = index; continue; } isValidElement = false; } if (!validate || (elementRule = schema.getElementRule(value))) { isValidElement = true; if (validate) { validAttributesMap = elementRule.attributes; validAttributePatterns = elementRule.attributePatterns; } if (attribsValue = matches[8]) { isInternalElement = attribsValue.indexOf('data-mce-type') !== -1; if (isInternalElement && removeInternalElements) { isValidElement = false; } attrList = []; attrList.map = {}; attribsValue.replace(attrRegExp, parseAttribute); } else { attrList = []; attrList.map = {}; } if (validate && !isInternalElement) { attributesRequired = elementRule.attributesRequired; attributesDefault = elementRule.attributesDefault; attributesForced = elementRule.attributesForced; anyAttributesRequired = elementRule.removeEmptyAttrs; if (anyAttributesRequired && !attrList.length) { isValidElement = false; } if (attributesForced) { i = attributesForced.length; while (i--) { attr = attributesForced[i]; name = attr.name; attrValue = attr.value; if (attrValue === '{$uid}') { attrValue = 'mce_' + idCount++; } attrList.map[name] = attrValue; attrList.push({ name: name, value: attrValue }); } } if (attributesDefault) { i = attributesDefault.length; while (i--) { attr = attributesDefault[i]; name = attr.name; if (!(name in attrList.map)) { attrValue = attr.value; if (attrValue === '{$uid}') { attrValue = 'mce_' + idCount++; } attrList.map[name] = attrValue; attrList.push({ name: name, value: attrValue }); } } } if (attributesRequired) { i = attributesRequired.length; while (i--) { if (attributesRequired[i] in attrList.map) { break; } } if (i === -1) { isValidElement = false; } } if (attr = attrList.map['data-mce-bogus']) { if (attr === 'all') { index = findEndTagIndex(schema, html, tokenRegExp.lastIndex); tokenRegExp.lastIndex = index; continue; } isValidElement = false; } } if (isValidElement) { start(value, attrList, isShortEnded); } } else { isValidElement = false; } if (endRegExp = specialElements[value]) { endRegExp.lastIndex = index = matches.index + matches[0].length; if (matches = endRegExp.exec(html)) { if (isValidElement) { textData = html.substr(index, matches.index - index); } index = matches.index + matches[0].length; } else { textData = html.substr(index); index = html.length; } if (isValidElement) { if (textData.length > 0) { text(textData, true); } end(value); } tokenRegExp.lastIndex = index; continue; } if (!isShortEnded) { if (!attribsValue || attribsValue.indexOf('/') !== attribsValue.length - 1) { stack.push({ name: value, valid: isValidElement }); } else if (isValidElement) { end(value); } } } else if (value = matches[1]) { if (value.charAt(0) === '>') { value = ' ' + value; } if (!settings.allow_conditional_comments && value.substr(0, 3).toLowerCase() === '[if') { value = ' ' + value; } comment(value); } else if (value = matches[2]) { cdata(trimComments(value)); } else if (value = matches[3]) { doctype(value); } else if (value = matches[4]) { pi(value, matches[5]); } index = matches.index + matches[0].length; } if (index < html.length) { text(decode(html.substr(index))); } for (i = stack.length - 1; i >= 0; i--) { value = stack[i]; if (value.valid) { end(value.name); } } }; return { parse: parse }; } (function (SaxParser) { SaxParser.findEndTag = findEndTagIndex; }(SaxParser || (SaxParser = {}))); var SaxParser$1 = SaxParser; var trimHtml = function (tempAttrs, html) { var trimContentRegExp = new RegExp(['\\s?(' + tempAttrs.join('|') + ')="[^"]+"'].join('|'), 'gi'); return html.replace(trimContentRegExp, ''); }; var trimInternal = function (serializer, html) { var content = html; var bogusAllRegExp = /<(\w+) [^>]*data-mce-bogus="all"[^>]*>/g; var endTagIndex, index, matchLength, matches, shortEndedElements; var schema = serializer.schema; content = trimHtml(serializer.getTempAttrs(), content); shortEndedElements = schema.getShortEndedElements(); while (matches = bogusAllRegExp.exec(content)) { index = bogusAllRegExp.lastIndex; matchLength = matches[0].length; if (shortEndedElements[matches[1]]) { endTagIndex = index; } else { endTagIndex = SaxParser$1.findEndTag(schema, content, index); } content = content.substring(0, index - matchLength) + content.substring(endTagIndex); bogusAllRegExp.lastIndex = index - matchLength; } return Zwsp.trim(content); }; var trimExternal = trimInternal; var TrimHtml = { trimExternal: trimExternal, trimInternal: trimInternal }; var KEEP = 0, INSERT = 1, DELETE = 2; var diff = function (left, right) { var size = left.length + right.length + 2; var vDown = new Array(size); var vUp = new Array(size); var snake = function (start, end, diag) { return { start: start, end: end, diag: diag }; }; var buildScript = function (start1, end1, start2, end2, script) { var middle = getMiddleSnake(start1, end1, start2, end2); if (middle === null || middle.start === end1 && middle.diag === end1 - end2 || middle.end === start1 && middle.diag === start1 - start2) { var i = start1; var j = start2; while (i < end1 || j < end2) { if (i < end1 && j < end2 && left[i] === right[j]) { script.push([ KEEP, left[i] ]); ++i; ++j; } else { if (end1 - start1 > end2 - start2) { script.push([ DELETE, left[i] ]); ++i; } else { script.push([ INSERT, right[j] ]); ++j; } } } } else { buildScript(start1, middle.start, start2, middle.start - middle.diag, script); for (var i2 = middle.start; i2 < middle.end; ++i2) { script.push([ KEEP, left[i2] ]); } buildScript(middle.end, end1, middle.end - middle.diag, end2, script); } }; var buildSnake = function (start, diag, end1, end2) { var end = start; while (end - diag < end2 && end < end1 && left[end] === right[end - diag]) { ++end; } return snake(start, end, diag); }; var getMiddleSnake = function (start1, end1, start2, end2) { var m = end1 - start1; var n = end2 - start2; if (m === 0 || n === 0) { return null; } var delta = m - n; var sum = n + m; var offset = (sum % 2 === 0 ? sum : sum + 1) / 2; vDown[1 + offset] = start1; vUp[1 + offset] = end1 + 1; var d, k, i, x, y; for (d = 0; d <= offset; ++d) { for (k = -d; k <= d; k += 2) { i = k + offset; if (k === -d || k !== d && vDown[i - 1] < vDown[i + 1]) { vDown[i] = vDown[i + 1]; } else { vDown[i] = vDown[i - 1] + 1; } x = vDown[i]; y = x - start1 + start2 - k; while (x < end1 && y < end2 && left[x] === right[y]) { vDown[i] = ++x; ++y; } if (delta % 2 !== 0 && delta - d <= k && k <= delta + d) { if (vUp[i - delta] <= vDown[i]) { return buildSnake(vUp[i - delta], k + start1 - start2, end1, end2); } } } for (k = delta - d; k <= delta + d; k += 2) { i = k + offset - delta; if (k === delta - d || k !== delta + d && vUp[i + 1] <= vUp[i - 1]) { vUp[i] = vUp[i + 1] - 1; } else { vUp[i] = vUp[i - 1]; } x = vUp[i] - 1; y = x - start1 + start2 - k; while (x >= start1 && y >= start2 && left[x] === right[y]) { vUp[i] = x--; y--; } if (delta % 2 === 0 && -d <= k && k <= d) { if (vUp[i] <= vDown[i + delta]) { return buildSnake(vUp[i], k + start1 - start2, end1, end2); } } } } }; var script = []; buildScript(0, left.length, 0, right.length, script); return script; }; var Diff = { KEEP: KEEP, DELETE: DELETE, INSERT: INSERT, diff: diff }; var getOuterHtml = function (elm) { if (NodeType.isElement(elm)) { return elm.outerHTML; } else if (NodeType.isText(elm)) { return Entities.encodeRaw(elm.data, false); } else if (NodeType.isComment(elm)) { return '<!--' + elm.data + '-->'; } return ''; }; var createFragment$1 = function (html) { var frag, node, container; container = domGlobals.document.createElement('div'); frag = domGlobals.document.createDocumentFragment(); if (html) { container.innerHTML = html; } while (node = container.firstChild) { frag.appendChild(node); } return frag; }; var insertAt = function (elm, html, index) { var fragment = createFragment$1(html); if (elm.hasChildNodes() && index < elm.childNodes.length) { var target = elm.childNodes[index]; target.parentNode.insertBefore(fragment, target); } else { elm.appendChild(fragment); } }; var removeAt = function (elm, index) { if (elm.hasChildNodes() && index < elm.childNodes.length) { var target = elm.childNodes[index]; target.parentNode.removeChild(target); } }; var applyDiff = function (diff, elm) { var index = 0; each(diff, function (action) { if (action[0] === Diff.KEEP) { index++; } else if (action[0] === Diff.INSERT) { insertAt(elm, action[1], index); index++; } else if (action[0] === Diff.DELETE) { removeAt(elm, index); } }); }; var read$3 = function (elm) { return filter(map(from$1(elm.childNodes), getOuterHtml), function (item) { return item.length > 0; }); }; var write = function (fragments, elm) { var currentFragments = map(from$1(elm.childNodes), getOuterHtml); applyDiff(Diff.diff(currentFragments, fragments), elm); return elm; }; var Fragments = { read: read$3, write: write }; var undoLevelDocument = Cell(Option.none()); var lazyTempDocument = function () { return undoLevelDocument.get().getOrThunk(function () { var doc = domGlobals.document.implementation.createHTMLDocument('undo'); undoLevelDocument.set(Option.some(doc)); return doc; }); }; var hasIframes = function (html) { return html.indexOf('</iframe>') !== -1; }; var createFragmentedLevel = function (fragments) { return { type: 'fragmented', fragments: fragments, content: '', bookmark: null, beforeBookmark: null }; }; var createCompleteLevel = function (content) { return { type: 'complete', fragments: null, content: content, bookmark: null, beforeBookmark: null }; }; var createFromEditor = function (editor) { var fragments, content, trimmedFragments; fragments = Fragments.read(editor.getBody()); trimmedFragments = bind(fragments, function (html) { var trimmed = TrimHtml.trimInternal(editor.serializer, html); return trimmed.length > 0 ? [trimmed] : []; }); content = trimmedFragments.join(''); return hasIframes(content) ? createFragmentedLevel(trimmedFragments) : createCompleteLevel(content); }; var applyToEditor = function (editor, level, before) { if (level.type === 'fragmented') { Fragments.write(level.fragments, editor.getBody()); } else { editor.setContent(level.content, { format: 'raw' }); } editor.selection.moveToBookmark(before ? level.beforeBookmark : level.bookmark); }; var getLevelContent = function (level) { return level.type === 'fragmented' ? level.fragments.join('') : level.content; }; var getCleanLevelContent = function (level) { var elm = Element.fromTag('body', lazyTempDocument()); set$1(elm, getLevelContent(level)); each(descendants$1(elm, '*[data-mce-bogus]'), unwrap); return get$3(elm); }; var hasEqualContent = function (level1, level2) { return getLevelContent(level1) === getLevelContent(level2); }; var hasEqualCleanedContent = function (level1, level2) { return getCleanLevelContent(level1) === getCleanLevelContent(level2); }; var isEq$4 = function (level1, level2) { if (!level1 || !level2) { return false; } else if (hasEqualContent(level1, level2)) { return true; } else { return hasEqualCleanedContent(level1, level2); } }; var Levels = { createFragmentedLevel: createFragmentedLevel, createCompleteLevel: createCompleteLevel, createFromEditor: createFromEditor, applyToEditor: applyToEditor, isEq: isEq$4 }; function UndoManager (editor) { var self = this, index = 0, data = [], beforeBookmark, isFirstTypedCharacter, locks = 0; var isUnlocked = function () { return locks === 0; }; var setTyping = function (typing) { if (isUnlocked()) { self.typing = typing; } }; var setDirty = function (state) { editor.setDirty(state); }; var addNonTypingUndoLevel = function (e) { setTyping(false); self.add({}, e); }; var endTyping = function () { if (self.typing) { setTyping(false); self.add(); } }; editor.on('init', function () { self.add(); }); editor.on('BeforeExecCommand', function (e) { var cmd = e.command; if (cmd !== 'Undo' && cmd !== 'Redo' && cmd !== 'mceRepaint') { endTyping(); self.beforeChange(); } }); editor.on('ExecCommand', function (e) { var cmd = e.command; if (cmd !== 'Undo' && cmd !== 'Redo' && cmd !== 'mceRepaint') { addNonTypingUndoLevel(e); } }); editor.on('ObjectResizeStart Cut', function () { self.beforeChange(); }); editor.on('SaveContent ObjectResized blur', addNonTypingUndoLevel); editor.on('DragEnd', addNonTypingUndoLevel); editor.on('KeyUp', function (e) { var keyCode = e.keyCode; if (e.isDefaultPrevented()) { return; } if (keyCode >= 33 && keyCode <= 36 || keyCode >= 37 && keyCode <= 40 || keyCode === 45 || e.ctrlKey) { addNonTypingUndoLevel(); editor.nodeChanged(); } if (keyCode === 46 || keyCode === 8) { editor.nodeChanged(); } if (isFirstTypedCharacter && self.typing && Levels.isEq(Levels.createFromEditor(editor), data[0]) === false) { if (editor.isDirty() === false) { setDirty(true); editor.fire('change', { level: data[0], lastLevel: null }); } editor.fire('TypingUndo'); isFirstTypedCharacter = false; editor.nodeChanged(); } }); editor.on('KeyDown', function (e) { var keyCode = e.keyCode; if (e.isDefaultPrevented()) { return; } if (keyCode >= 33 && keyCode <= 36 || keyCode >= 37 && keyCode <= 40 || keyCode === 45) { if (self.typing) { addNonTypingUndoLevel(e); } return; } var modKey = e.ctrlKey && !e.altKey || e.metaKey; if ((keyCode < 16 || keyCode > 20) && keyCode !== 224 && keyCode !== 91 && !self.typing && !modKey) { self.beforeChange(); setTyping(true); self.add({}, e); isFirstTypedCharacter = true; } }); editor.on('MouseDown', function (e) { if (self.typing) { addNonTypingUndoLevel(e); } }); var isInsertReplacementText = function (event) { return event.inputType === 'insertReplacementText'; }; var isInsertTextDataNull = function (event) { return event.inputType === 'insertText' && event.data === null; }; editor.on('input', function (e) { if (e.inputType && (isInsertReplacementText(e) || isInsertTextDataNull(e))) { addNonTypingUndoLevel(e); } }); editor.addShortcut('meta+z', '', 'Undo'); editor.addShortcut('meta+y,meta+shift+z', '', 'Redo'); editor.on('AddUndo Undo Redo ClearUndos', function (e) { if (!e.isDefaultPrevented()) { editor.nodeChanged(); } }); self = { data: data, typing: false, beforeChange: function () { if (isUnlocked()) { beforeBookmark = GetBookmark.getUndoBookmark(editor.selection); } }, add: function (level, event) { var i; var settings = editor.settings; var lastLevel, currentLevel; currentLevel = Levels.createFromEditor(editor); level = level || {}; level = Tools.extend(level, currentLevel); if (isUnlocked() === false || editor.removed) { return null; } lastLevel = data[index]; if (editor.fire('BeforeAddUndo', { level: level, lastLevel: lastLevel, originalEvent: event }).isDefaultPrevented()) { return null; } if (lastLevel && Levels.isEq(lastLevel, level)) { return null; } if (data[index]) { data[index].beforeBookmark = beforeBookmark; } if (settings.custom_undo_redo_levels) { if (data.length > settings.custom_undo_redo_levels) { for (i = 0; i < data.length - 1; i++) { data[i] = data[i + 1]; } data.length--; index = data.length; } } level.bookmark = GetBookmark.getUndoBookmark(editor.selection); if (index < data.length - 1) { data.length = index + 1; } data.push(level); index = data.length - 1; var args = { level: level, lastLevel: lastLevel, originalEvent: event }; editor.fire('AddUndo', args); if (index > 0) { setDirty(true); editor.fire('change', args); } return level; }, undo: function () { var level; if (self.typing) { self.add(); self.typing = false; setTyping(false); } if (index > 0) { level = data[--index]; Levels.applyToEditor(editor, level, true); setDirty(true); editor.fire('undo', { level: level }); } return level; }, redo: function () { var level; if (index < data.length - 1) { level = data[++index]; Levels.applyToEditor(editor, level, false); setDirty(true); editor.fire('redo', { level: level }); } return level; }, clear: function () { data = []; index = 0; self.typing = false; self.data = data; editor.fire('ClearUndos'); }, hasUndo: function () { return index > 0 || self.typing && data[0] && !Levels.isEq(Levels.createFromEditor(editor), data[0]); }, hasRedo: function () { return index < data.length - 1 && !self.typing; }, transact: function (callback) { endTyping(); self.beforeChange(); self.ignore(callback); return self.add(); }, ignore: function (callback) { try { locks++; callback(); } finally { locks--; } }, extra: function (callback1, callback2) { var lastLevel, bookmark; if (self.transact(callback1)) { bookmark = data[index].bookmark; lastLevel = data[index - 1]; Levels.applyToEditor(editor, lastLevel, true); if (self.transact(callback2)) { data[index - 1].beforeBookmark = bookmark; } } } }; return self; } var postProcessHooks = {}, filter$2 = ArrUtils.filter, each$c = ArrUtils.each; var addPostProcessHook = function (name, hook) { var hooks = postProcessHooks[name]; if (!hooks) { postProcessHooks[name] = hooks = []; } postProcessHooks[name].push(hook); }; var postProcess = function (name, editor) { each$c(postProcessHooks[name], function (hook) { hook(editor); }); }; addPostProcessHook('pre', function (editor) { var rng = editor.selection.getRng(); var isPre, blocks; var hasPreSibling = function (pre) { return isPre(pre.previousSibling) && ArrUtils.indexOf(blocks, pre.previousSibling) !== -1; }; var joinPre = function (pre1, pre2) { DomQuery(pre2).remove(); DomQuery(pre1).append('<br><br>').append(pre2.childNodes); }; isPre = NodeType.matchNodeNames('pre'); if (!rng.collapsed) { blocks = editor.selection.getSelectedBlocks(); each$c(filter$2(filter$2(blocks, isPre), hasPreSibling), function (pre) { joinPre(pre.previousSibling, pre); }); } }); var Hooks = { postProcess: postProcess }; var MCE_ATTR_RE = /^(src|href|style)$/; var each$d = Tools.each; var isEq$5 = FormatUtils.isEq; var isTableCell$4 = function (node) { return /^(TH|TD)$/.test(node.nodeName); }; var isChildOfInlineParent = function (dom, node, parent) { return dom.isChildOf(node, parent) && node !== parent && !dom.isBlock(parent); }; var getContainer = function (ed, rng, start) { var container, offset, lastIdx; container = rng[start ? 'startContainer' : 'endContainer']; offset = rng[start ? 'startOffset' : 'endOffset']; if (NodeType.isElement(container)) { lastIdx = container.childNodes.length - 1; if (!start && offset) { offset--; } container = container.childNodes[offset > lastIdx ? lastIdx : offset]; } if (NodeType.isText(container) && start && offset >= container.nodeValue.length) { container = new TreeWalker(container, ed.getBody()).next() || container; } if (NodeType.isText(container) && !start && offset === 0) { container = new TreeWalker(container, ed.getBody()).prev() || container; } return container; }; var wrap$2 = function (dom, node, name, attrs) { var wrapper = dom.create(name, attrs); node.parentNode.insertBefore(wrapper, node); wrapper.appendChild(node); return wrapper; }; var wrapWithSiblings = function (dom, node, next, name, attrs) { var start = Element.fromDom(node); var wrapper = Element.fromDom(dom.create(name, attrs)); var siblings = next ? nextSiblings(start) : prevSiblings(start); append$1(wrapper, siblings); if (next) { before(start, wrapper); prepend(wrapper, start); } else { after(start, wrapper); append(wrapper, start); } return wrapper.dom(); }; var matchName$1 = function (dom, node, format) { if (isEq$5(node, format.inline)) { return true; } if (isEq$5(node, format.block)) { return true; } if (format.selector) { return NodeType.isElement(node) && dom.is(node, format.selector); } }; var isColorFormatAndAnchor = function (node, format) { return format.links && node.tagName === 'A'; }; var find$3 = function (dom, node, next, inc) { node = FormatUtils.getNonWhiteSpaceSibling(node, next, inc); return !node || (node.nodeName === 'BR' || dom.isBlock(node)); }; var removeNode$1 = function (ed, node, format) { var parentNode = node.parentNode; var rootBlockElm; var dom = ed.dom, forcedRootBlock = ed.settings.forced_root_block; if (format.block) { if (!forcedRootBlock) { if (dom.isBlock(node) && !dom.isBlock(parentNode)) { if (!find$3(dom, node, false) && !find$3(dom, node.firstChild, true, 1)) { node.insertBefore(dom.create('br'), node.firstChild); } if (!find$3(dom, node, true) && !find$3(dom, node.lastChild, false, 1)) { node.appendChild(dom.create('br')); } } } else { if (parentNode === dom.getRoot()) { if (!format.list_block || !isEq$5(node, format.list_block)) { each$d(Tools.grep(node.childNodes), function (node) { if (FormatUtils.isValid(ed, forcedRootBlock, node.nodeName.toLowerCase())) { if (!rootBlockElm) { rootBlockElm = wrap$2(dom, node, forcedRootBlock); dom.setAttribs(rootBlockElm, ed.settings.forced_root_block_attrs); } else { rootBlockElm.appendChild(node); } } else { rootBlockElm = 0; } }); } } } } if (format.selector && format.inline && !isEq$5(format.inline, node)) { return; } dom.remove(node, 1); }; var removeFormat = function (ed, format, vars, node, compareNode) { var i, attrs, stylesModified; var dom = ed.dom; if (!matchName$1(dom, node, format) && !isColorFormatAndAnchor(node, format)) { return false; } if (format.remove !== 'all') { each$d(format.styles, function (value, name) { value = FormatUtils.normalizeStyleValue(dom, FormatUtils.replaceVars(value, vars), name); if (typeof name === 'number') { name = value; compareNode = 0; } if (format.remove_similar || (!compareNode || isEq$5(FormatUtils.getStyle(dom, compareNode, name), value))) { dom.setStyle(node, name, ''); } stylesModified = 1; }); if (stylesModified && dom.getAttrib(node, 'style') === '') { node.removeAttribute('style'); node.removeAttribute('data-mce-style'); } each$d(format.attributes, function (value, name) { var valueOut; value = FormatUtils.replaceVars(value, vars); if (typeof name === 'number') { name = value; compareNode = 0; } if (!compareNode || isEq$5(dom.getAttrib(compareNode, name), value)) { if (name === 'class') { value = dom.getAttrib(node, name); if (value) { valueOut = ''; each$d(value.split(/\s+/), function (cls) { if (/mce\-\w+/.test(cls)) { valueOut += (valueOut ? ' ' : '') + cls; } }); if (valueOut) { dom.setAttrib(node, name, valueOut); return; } } } if (name === 'class') { node.removeAttribute('className'); } if (MCE_ATTR_RE.test(name)) { node.removeAttribute('data-mce-' + name); } node.removeAttribute(name); } }); each$d(format.classes, function (value) { value = FormatUtils.replaceVars(value, vars); if (!compareNode || dom.hasClass(compareNode, value)) { dom.removeClass(node, value); } }); attrs = dom.getAttribs(node); for (i = 0; i < attrs.length; i++) { var attrName = attrs[i].nodeName; if (attrName.indexOf('_') !== 0 && attrName.indexOf('data-') !== 0) { return false; } } } if (format.remove !== 'none') { removeNode$1(ed, node, format); return true; } }; var findFormatRoot = function (editor, container, name, vars, similar) { var formatRoot; each$d(FormatUtils.getParents(editor.dom, container.parentNode).reverse(), function (parent) { var format; if (!formatRoot && parent.id !== '_start' && parent.id !== '_end') { format = MatchFormat.matchNode(editor, parent, name, vars, similar); if (format && format.split !== false) { formatRoot = parent; } } }); return formatRoot; }; var wrapAndSplit = function (editor, formatList, formatRoot, container, target, split, format, vars) { var parent, clone, lastClone, firstClone, i, formatRootParent; var dom = editor.dom; if (formatRoot) { formatRootParent = formatRoot.parentNode; for (parent = container.parentNode; parent && parent !== formatRootParent; parent = parent.parentNode) { clone = dom.clone(parent, false); for (i = 0; i < formatList.length; i++) { if (removeFormat(editor, formatList[i], vars, clone, clone)) { clone = 0; break; } } if (clone) { if (lastClone) { clone.appendChild(lastClone); } if (!firstClone) { firstClone = clone; } lastClone = clone; } } if (split && (!format.mixed || !dom.isBlock(formatRoot))) { container = dom.split(formatRoot, container); } if (lastClone) { target.parentNode.insertBefore(lastClone, target); firstClone.appendChild(target); } } return container; }; var remove$6 = function (ed, name, vars, node, similar) { var formatList = ed.formatter.get(name), format = formatList[0]; var bookmark, rng, contentEditable = true; var dom = ed.dom; var selection = ed.selection; var splitToFormatRoot = function (container) { var formatRoot = findFormatRoot(ed, container, name, vars, similar); return wrapAndSplit(ed, formatList, formatRoot, container, container, true, format, vars); }; var isRemoveBookmarkNode = function (node) { return Bookmarks.isBookmarkNode(node) && NodeType.isElement(node) && (node.id === '_start' || node.id === '_end'); }; var process = function (node) { var children, i, l, lastContentEditable, hasContentEditableState; if (NodeType.isElement(node) && dom.getContentEditable(node)) { lastContentEditable = contentEditable; contentEditable = dom.getContentEditable(node) === 'true'; hasContentEditableState = true; } children = Tools.grep(node.childNodes); if (contentEditable && !hasContentEditableState) { for (i = 0, l = formatList.length; i < l; i++) { if (removeFormat(ed, formatList[i], vars, node, node)) { break; } } } if (format.deep) { if (children.length) { for (i = 0, l = children.length; i < l; i++) { process(children[i]); } if (hasContentEditableState) { contentEditable = lastContentEditable; } } } }; var unwrap = function (start) { var node = dom.get(start ? '_start' : '_end'); var out = node[start ? 'firstChild' : 'lastChild']; if (isRemoveBookmarkNode(out)) { out = out[start ? 'firstChild' : 'lastChild']; } if (NodeType.isText(out) && out.data.length === 0) { out = start ? node.previousSibling || node.nextSibling : node.nextSibling || node.previousSibling; } dom.remove(node, true); return out; }; var removeRngStyle = function (rng) { var startContainer, endContainer; var commonAncestorContainer = rng.commonAncestorContainer; rng = ExpandRange.expandRng(ed, rng, formatList, true); if (format.split) { rng = SplitRange.split(rng); startContainer = getContainer(ed, rng, true); endContainer = getContainer(ed, rng); if (startContainer !== endContainer) { if (/^(TR|TH|TD)$/.test(startContainer.nodeName) && startContainer.firstChild) { if (startContainer.nodeName === 'TR') { startContainer = startContainer.firstChild.firstChild || startContainer; } else { startContainer = startContainer.firstChild || startContainer; } } if (commonAncestorContainer && /^T(HEAD|BODY|FOOT|R)$/.test(commonAncestorContainer.nodeName) && isTableCell$4(endContainer) && endContainer.firstChild) { endContainer = endContainer.firstChild || endContainer; } if (isChildOfInlineParent(dom, startContainer, endContainer)) { var marker = Option.from(startContainer.firstChild).getOr(startContainer); splitToFormatRoot(wrapWithSiblings(dom, marker, true, 'span', { 'id': '_start', 'data-mce-type': 'bookmark' })); unwrap(true); return; } if (isChildOfInlineParent(dom, endContainer, startContainer)) { var marker = Option.from(endContainer.lastChild).getOr(endContainer); splitToFormatRoot(wrapWithSiblings(dom, marker, false, 'span', { 'id': '_end', 'data-mce-type': 'bookmark' })); unwrap(false); return; } startContainer = wrap$2(dom, startContainer, 'span', { 'id': '_start', 'data-mce-type': 'bookmark' }); endContainer = wrap$2(dom, endContainer, 'span', { 'id': '_end', 'data-mce-type': 'bookmark' }); splitToFormatRoot(startContainer); splitToFormatRoot(endContainer); startContainer = unwrap(true); endContainer = unwrap(); } else { startContainer = endContainer = splitToFormatRoot(startContainer); } rng.startContainer = startContainer.parentNode ? startContainer.parentNode : startContainer; rng.startOffset = dom.nodeIndex(startContainer); rng.endContainer = endContainer.parentNode ? endContainer.parentNode : endContainer; rng.endOffset = dom.nodeIndex(endContainer) + 1; } RangeWalk.walk(dom, rng, function (nodes) { each$d(nodes, function (node) { process(node); if (NodeType.isElement(node) && ed.dom.getStyle(node, 'text-decoration') === 'underline' && node.parentNode && FormatUtils.getTextDecoration(dom, node.parentNode) === 'underline') { removeFormat(ed, { deep: false, exact: true, inline: 'span', styles: { textDecoration: 'underline' } }, null, node); } }); }); }; if (node) { if (node.nodeType) { rng = dom.createRng(); rng.setStartBefore(node); rng.setEndAfter(node); removeRngStyle(rng); } else { removeRngStyle(node); } return; } if (dom.getContentEditable(selection.getNode()) === 'false') { node = selection.getNode(); for (var i = 0, l = formatList.length; i < l; i++) { if (formatList[i].ceFalseOverride) { if (removeFormat(ed, formatList[i], vars, node, node)) { break; } } } return; } if (!selection.isCollapsed() || !format.inline || dom.select('td[data-mce-selected],th[data-mce-selected]').length) { bookmark = GetBookmark.getPersistentBookmark(ed.selection, true); removeRngStyle(selection.getRng()); selection.moveToBookmark(bookmark); if (format.inline && MatchFormat.match(ed, name, vars, selection.getStart())) { FormatUtils.moveStart(dom, selection, selection.getRng()); } ed.nodeChanged(); } else { removeCaretFormat(ed, name, vars, similar); } }; var RemoveFormat = { removeFormat: removeFormat, remove: remove$6 }; var each$e = Tools.each; var isElementNode = function (node) { return node && node.nodeType === 1 && !Bookmarks.isBookmarkNode(node) && !isCaretNode(node) && !NodeType.isBogus(node); }; var findElementSibling = function (node, siblingName) { var sibling; for (sibling = node; sibling; sibling = sibling[siblingName]) { if (sibling.nodeType === 3 && sibling.nodeValue.length !== 0) { return node; } if (sibling.nodeType === 1 && !Bookmarks.isBookmarkNode(sibling)) { return sibling; } } return node; }; var mergeSiblingsNodes = function (dom, prev, next) { var sibling, tmpSibling; var elementUtils = new ElementUtils(dom); if (prev && next) { prev = findElementSibling(prev, 'previousSibling'); next = findElementSibling(next, 'nextSibling'); if (elementUtils.compare(prev, next)) { for (sibling = prev.nextSibling; sibling && sibling !== next;) { tmpSibling = sibling; sibling = sibling.nextSibling; prev.appendChild(tmpSibling); } dom.remove(next); Tools.each(Tools.grep(next.childNodes), function (node) { prev.appendChild(node); }); return prev; } } return next; }; var processChildElements = function (node, filter, process) { each$e(node.childNodes, function (node) { if (isElementNode(node)) { if (filter(node)) { process(node); } if (node.hasChildNodes()) { processChildElements(node, filter, process); } } }); }; var hasStyle = function (dom, name) { return curry(function (name, node) { return !!(node && FormatUtils.getStyle(dom, node, name)); }, name); }; var applyStyle = function (dom, name, value) { return curry(function (name, value, node) { dom.setStyle(node, name, value); if (node.getAttribute('style') === '') { node.removeAttribute('style'); } unwrapEmptySpan(dom, node); }, name, value); }; var unwrapEmptySpan = function (dom, node) { if (node.nodeName === 'SPAN' && dom.getAttribs(node).length === 0) { dom.remove(node, true); } }; var processUnderlineAndColor = function (dom, node) { var textDecoration; if (node.nodeType === 1 && node.parentNode && node.parentNode.nodeType === 1) { textDecoration = FormatUtils.getTextDecoration(dom, node.parentNode); if (dom.getStyle(node, 'color') && textDecoration) { dom.setStyle(node, 'text-decoration', textDecoration); } else if (dom.getStyle(node, 'text-decoration') === textDecoration) { dom.setStyle(node, 'text-decoration', null); } } }; var mergeUnderlineAndColor = function (dom, format, vars, node) { if (format.styles.color || format.styles.textDecoration) { Tools.walk(node, curry(processUnderlineAndColor, dom), 'childNodes'); processUnderlineAndColor(dom, node); } }; var mergeBackgroundColorAndFontSize = function (dom, format, vars, node) { if (format.styles && format.styles.backgroundColor) { processChildElements(node, hasStyle(dom, 'fontSize'), applyStyle(dom, 'backgroundColor', FormatUtils.replaceVars(format.styles.backgroundColor, vars))); } }; var mergeSubSup = function (dom, format, vars, node) { if (format.inline === 'sub' || format.inline === 'sup') { processChildElements(node, hasStyle(dom, 'fontSize'), applyStyle(dom, 'fontSize', '')); dom.remove(dom.select(format.inline === 'sup' ? 'sub' : 'sup', node), true); } }; var mergeSiblings = function (dom, format, vars, node) { if (node && format.merge_siblings !== false) { node = mergeSiblingsNodes(dom, FormatUtils.getNonWhiteSpaceSibling(node), node); node = mergeSiblingsNodes(dom, node, FormatUtils.getNonWhiteSpaceSibling(node, true)); } }; var clearChildStyles = function (dom, format, node) { if (format.clear_child_styles) { var selector = format.links ? '*:not(a)' : '*'; each$e(dom.select(selector, node), function (node) { if (isElementNode(node)) { each$e(format.styles, function (value, name) { dom.setStyle(node, name, ''); }); } }); } }; var mergeWithChildren = function (editor, formatList, vars, node) { each$e(formatList, function (format) { each$e(editor.dom.select(format.inline, node), function (child) { if (!isElementNode(child)) { return; } RemoveFormat.removeFormat(editor, format, vars, child, format.exact ? child : null); }); clearChildStyles(editor.dom, format, node); }); }; var mergeWithParents = function (editor, format, name, vars, node) { if (MatchFormat.matchNode(editor, node.parentNode, name, vars)) { if (RemoveFormat.removeFormat(editor, format, vars, node)) { return; } } if (format.merge_with_parents) { editor.dom.getParent(node.parentNode, function (parent) { if (MatchFormat.matchNode(editor, parent, name, vars)) { RemoveFormat.removeFormat(editor, format, vars, node); return true; } }); } }; var MergeFormats = { mergeWithChildren: mergeWithChildren, mergeUnderlineAndColor: mergeUnderlineAndColor, mergeBackgroundColorAndFontSize: mergeBackgroundColorAndFontSize, mergeSubSup: mergeSubSup, mergeSiblings: mergeSiblings, mergeWithParents: mergeWithParents }; var each$f = Tools.each; var isElementNode$1 = function (node) { return node && node.nodeType === 1 && !Bookmarks.isBookmarkNode(node) && !isCaretNode(node) && !NodeType.isBogus(node); }; var applyFormat = function (ed, name, vars, node) { var formatList = ed.formatter.get(name); var format = formatList[0]; var bookmark, rng; var isCollapsed = !node && ed.selection.isCollapsed(); var dom = ed.dom, selection = ed.selection; var setElementFormat = function (elm, fmt) { fmt = fmt || format; if (elm) { if (fmt.onformat) { fmt.onformat(elm, fmt, vars, node); } each$f(fmt.styles, function (value, name) { dom.setStyle(elm, name, FormatUtils.replaceVars(value, vars)); }); if (fmt.styles) { var styleVal = dom.getAttrib(elm, 'style'); if (styleVal) { elm.setAttribute('data-mce-style', styleVal); } } each$f(fmt.attributes, function (value, name) { dom.setAttrib(elm, name, FormatUtils.replaceVars(value, vars)); }); each$f(fmt.classes, function (value) { value = FormatUtils.replaceVars(value, vars); if (!dom.hasClass(elm, value)) { dom.addClass(elm, value); } }); } }; var applyNodeStyle = function (formatList, node) { var found = false; if (!format.selector) { return false; } each$f(formatList, function (format) { if ('collapsed' in format && format.collapsed !== isCollapsed) { return; } if (dom.is(node, format.selector) && !isCaretNode(node)) { setElementFormat(node, format); found = true; return false; } }); return found; }; var applyRngStyle = function (dom, rng, bookmark, nodeSpecific) { var newWrappers = []; var wrapName, wrapElm, contentEditable = true; wrapName = format.inline || format.block; wrapElm = dom.create(wrapName); setElementFormat(wrapElm); RangeWalk.walk(dom, rng, function (nodes) { var currentWrapElm; var process = function (node) { var nodeName, parentName, hasContentEditableState, lastContentEditable; lastContentEditable = contentEditable; nodeName = node.nodeName.toLowerCase(); parentName = node.parentNode.nodeName.toLowerCase(); if (node.nodeType === 1 && dom.getContentEditable(node)) { lastContentEditable = contentEditable; contentEditable = dom.getContentEditable(node) === 'true'; hasContentEditableState = true; } if (FormatUtils.isEq(nodeName, 'br')) { currentWrapElm = 0; if (format.block) { dom.remove(node); } return; } if (format.wrapper && MatchFormat.matchNode(ed, node, name, vars)) { currentWrapElm = 0; return; } if (contentEditable && !hasContentEditableState && format.block && !format.wrapper && FormatUtils.isTextBlock(ed, nodeName) && FormatUtils.isValid(ed, parentName, wrapName)) { node = dom.rename(node, wrapName); setElementFormat(node); newWrappers.push(node); currentWrapElm = 0; return; } if (format.selector) { var found = applyNodeStyle(formatList, node); if (!format.inline || found) { currentWrapElm = 0; return; } } if (contentEditable && !hasContentEditableState && FormatUtils.isValid(ed, wrapName, nodeName) && FormatUtils.isValid(ed, parentName, wrapName) && !(!nodeSpecific && node.nodeType === 3 && node.nodeValue.length === 1 && node.nodeValue.charCodeAt(0) === 65279) && !isCaretNode(node) && (!format.inline || !dom.isBlock(node))) { if (!currentWrapElm) { currentWrapElm = dom.clone(wrapElm, false); node.parentNode.insertBefore(currentWrapElm, node); newWrappers.push(currentWrapElm); } currentWrapElm.appendChild(node); } else { currentWrapElm = 0; each$f(Tools.grep(node.childNodes), process); if (hasContentEditableState) { contentEditable = lastContentEditable; } currentWrapElm = 0; } }; each$f(nodes, process); }); if (format.links === true) { each$f(newWrappers, function (node) { var process = function (node) { if (node.nodeName === 'A') { setElementFormat(node, format); } each$f(Tools.grep(node.childNodes), process); }; process(node); }); } each$f(newWrappers, function (node) { var childCount; var getChildCount = function (node) { var count = 0; each$f(node.childNodes, function (node) { if (!FormatUtils.isWhiteSpaceNode(node) && !Bookmarks.isBookmarkNode(node)) { count++; } }); return count; }; var getChildElementNode = function (root) { var child = false; each$f(root.childNodes, function (node) { if (isElementNode$1(node)) { child = node; return false; } }); return child; }; var mergeStyles = function (node) { var child, clone; child = getChildElementNode(node); if (child && !Bookmarks.isBookmarkNode(child) && MatchFormat.matchName(dom, child, format)) { clone = dom.clone(child, false); setElementFormat(clone); dom.replace(clone, node, true); dom.remove(child, 1); } return clone || node; }; childCount = getChildCount(node); if ((newWrappers.length > 1 || !dom.isBlock(node)) && childCount === 0) { dom.remove(node, 1); return; } if (format.inline || format.wrapper) { if (!format.exact && childCount === 1) { node = mergeStyles(node); } MergeFormats.mergeWithChildren(ed, formatList, vars, node); MergeFormats.mergeWithParents(ed, format, name, vars, node); MergeFormats.mergeBackgroundColorAndFontSize(dom, format, vars, node); MergeFormats.mergeSubSup(dom, format, vars, node); MergeFormats.mergeSiblings(dom, format, vars, node); } }); }; if (dom.getContentEditable(selection.getNode()) === 'false') { node = selection.getNode(); for (var i = 0, l = formatList.length; i < l; i++) { if (formatList[i].ceFalseOverride && dom.is(node, formatList[i].selector)) { setElementFormat(node, formatList[i]); return; } } return; } if (format) { if (node) { if (node.nodeType) { if (!applyNodeStyle(formatList, node)) { rng = dom.createRng(); rng.setStartBefore(node); rng.setEndAfter(node); applyRngStyle(dom, ExpandRange.expandRng(ed, rng, formatList), null, true); } } else { applyRngStyle(dom, node, null, true); } } else { if (!isCollapsed || !format.inline || dom.select('td[data-mce-selected],th[data-mce-selected]').length) { var curSelNode = ed.selection.getNode(); if (!ed.settings.forced_root_block && formatList[0].defaultBlock && !dom.getParent(curSelNode, dom.isBlock)) { applyFormat(ed, formatList[0].defaultBlock); } ed.selection.setRng(RangeNormalizer.normalize(ed.selection.getRng())); bookmark = GetBookmark.getPersistentBookmark(ed.selection, true); applyRngStyle(dom, ExpandRange.expandRng(ed, selection.getRng(), formatList), bookmark); if (format.styles) { MergeFormats.mergeUnderlineAndColor(dom, format, vars, curSelNode); } selection.moveToBookmark(bookmark); FormatUtils.moveStart(dom, selection, selection.getRng()); ed.nodeChanged(); } else { applyCaretFormat(ed, name, vars); } } Hooks.postProcess(name, ed); } }; var ApplyFormat = { applyFormat: applyFormat }; var each$g = Tools.each; var setup$5 = function (formatChangeData, editor) { var currentFormats = {}; formatChangeData.set({}); editor.on('NodeChange', function (e) { var parents = FormatUtils.getParents(editor.dom, e.element); var matchedFormats = {}; parents = Tools.grep(parents, function (node) { return node.nodeType === 1 && !node.getAttribute('data-mce-bogus'); }); each$g(formatChangeData.get(), function (callbacks, format) { each$g(parents, function (node) { if (editor.formatter.matchNode(node, format, {}, callbacks.similar)) { if (!currentFormats[format]) { each$g(callbacks, function (callback) { callback(true, { node: node, format: format, parents: parents }); }); currentFormats[format] = callbacks; } matchedFormats[format] = callbacks; return false; } if (MatchFormat.matchesUnInheritedFormatSelector(editor, node, format)) { return false; } }); }); each$g(currentFormats, function (callbacks, format) { if (!matchedFormats[format]) { delete currentFormats[format]; each$g(callbacks, function (callback) { callback(false, { node: e.element, format: format, parents: parents }); }); } }); }); }; var addListeners = function (formatChangeData, formats, callback, similar) { var formatChangeItems = formatChangeData.get(); each$g(formats.split(','), function (format) { if (!formatChangeItems[format]) { formatChangeItems[format] = []; formatChangeItems[format].similar = similar; } formatChangeItems[format].push(callback); }); formatChangeData.set(formatChangeItems); }; var formatChanged = function (editor, formatChangeState, formats, callback, similar) { if (formatChangeState.get() === null) { setup$5(formatChangeState, editor); } addListeners(formatChangeState, formats, callback, similar); }; var FormatChanged = { formatChanged: formatChanged }; var get$5 = function (dom) { var formats = { valigntop: [{ selector: 'td,th', styles: { verticalAlign: 'top' } }], valignmiddle: [{ selector: 'td,th', styles: { verticalAlign: 'middle' } }], valignbottom: [{ selector: 'td,th', styles: { verticalAlign: 'bottom' } }], alignleft: [ { selector: 'figure.image', collapsed: false, classes: 'align-left', ceFalseOverride: true, preview: 'font-family font-size' }, { selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li', styles: { textAlign: 'left' }, inherit: false, preview: false, defaultBlock: 'div' }, { selector: 'img,table', collapsed: false, styles: { float: 'left' }, preview: 'font-family font-size' } ], aligncenter: [ { selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li', styles: { textAlign: 'center' }, inherit: false, preview: 'font-family font-size', defaultBlock: 'div' }, { selector: 'figure.image', collapsed: false, classes: 'align-center', ceFalseOverride: true, preview: 'font-family font-size' }, { selector: 'img', collapsed: false, styles: { display: 'block', marginLeft: 'auto', marginRight: 'auto' }, preview: false }, { selector: 'table', collapsed: false, styles: { marginLeft: 'auto', marginRight: 'auto' }, preview: 'font-family font-size' } ], alignright: [ { selector: 'figure.image', collapsed: false, classes: 'align-right', ceFalseOverride: true, preview: 'font-family font-size' }, { selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li', styles: { textAlign: 'right' }, inherit: false, preview: 'font-family font-size', defaultBlock: 'div' }, { selector: 'img,table', collapsed: false, styles: { float: 'right' }, preview: 'font-family font-size' } ], alignjustify: [{ selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li', styles: { textAlign: 'justify' }, inherit: false, defaultBlock: 'div', preview: 'font-family font-size' }], bold: [ { inline: 'strong', remove: 'all' }, { inline: 'span', styles: { fontWeight: 'bold' } }, { inline: 'b', remove: 'all' } ], italic: [ { inline: 'em', remove: 'all' }, { inline: 'span', styles: { fontStyle: 'italic' } }, { inline: 'i', remove: 'all' } ], underline: [ { inline: 'span', styles: { textDecoration: 'underline' }, exact: true }, { inline: 'u', remove: 'all' } ], strikethrough: [ { inline: 'span', styles: { textDecoration: 'line-through' }, exact: true }, { inline: 'strike', remove: 'all' } ], forecolor: { inline: 'span', styles: { color: '%value' }, links: true, remove_similar: true, clear_child_styles: true }, hilitecolor: { inline: 'span', styles: { backgroundColor: '%value' }, links: true, remove_similar: true, clear_child_styles: true }, fontname: { inline: 'span', toggle: false, styles: { fontFamily: '%value' }, clear_child_styles: true }, fontsize: { inline: 'span', toggle: false, styles: { fontSize: '%value' }, clear_child_styles: true }, fontsize_class: { inline: 'span', attributes: { class: '%value' } }, blockquote: { block: 'blockquote', wrapper: 1, remove: 'all' }, subscript: { inline: 'sub' }, superscript: { inline: 'sup' }, code: { inline: 'code' }, link: { inline: 'a', selector: 'a', remove: 'all', split: true, deep: true, onmatch: function () { return true; }, onformat: function (elm, fmt, vars) { Tools.each(vars, function (value, key) { dom.setAttrib(elm, key, value); }); } }, removeformat: [ { selector: 'b,strong,em,i,font,u,strike,sub,sup,dfn,code,samp,kbd,var,cite,mark,q,del,ins', remove: 'all', split: true, expand: false, block_expand: true, deep: true }, { selector: 'span', attributes: [ 'style', 'class' ], remove: 'empty', split: true, expand: false, deep: true }, { selector: '*', attributes: [ 'style', 'class' ], split: false, expand: false, deep: true } ] }; Tools.each('p h1 h2 h3 h4 h5 h6 div address pre div dt dd samp'.split(/\s/), function (name) { formats[name] = { block: name, remove: 'all' }; }); return formats; }; var DefaultFormats = { get: get$5 }; function FormatRegistry (editor) { var formats = {}; var get = function (name) { return name ? formats[name] : formats; }; var register = function (name, format) { if (name) { if (typeof name !== 'string') { Tools.each(name, function (format, name) { register(name, format); }); } else { format = format.length ? format : [format]; Tools.each(format, function (format) { if (typeof format.deep === 'undefined') { format.deep = !format.selector; } if (typeof format.split === 'undefined') { format.split = !format.selector || format.inline; } if (typeof format.remove === 'undefined' && format.selector && !format.inline) { format.remove = 'none'; } if (format.selector && format.inline) { format.mixed = true; format.block_expand = true; } if (typeof format.classes === 'string') { format.classes = format.classes.split(/\s+/); } }); formats[name] = format; } } }; var unregister = function (name) { if (name && formats[name]) { delete formats[name]; } return formats; }; register(DefaultFormats.get(editor.dom)); register(editor.settings.formats); return { get: get, register: register, unregister: unregister }; } var each$h = Tools.each; var dom = DOMUtils$1.DOM; var parsedSelectorToHtml = function (ancestry, editor) { var elm, item, fragment; var schema = editor && editor.schema || Schema({}); var decorate = function (elm, item) { if (item.classes.length) { dom.addClass(elm, item.classes.join(' ')); } dom.setAttribs(elm, item.attrs); }; var createElement = function (sItem) { var elm; item = typeof sItem === 'string' ? { name: sItem, classes: [], attrs: {} } : sItem; elm = dom.create(item.name); decorate(elm, item); return elm; }; var getRequiredParent = function (elm, candidate) { var name = typeof elm !== 'string' ? elm.nodeName.toLowerCase() : elm; var elmRule = schema.getElementRule(name); var parentsRequired = elmRule && elmRule.parentsRequired; if (parentsRequired && parentsRequired.length) { return candidate && Tools.inArray(parentsRequired, candidate) !== -1 ? candidate : parentsRequired[0]; } else { return false; } }; var wrapInHtml = function (elm, ancestry, siblings) { var parent, parentCandidate, parentRequired; var ancestor = ancestry.length > 0 && ancestry[0]; var ancestorName = ancestor && ancestor.name; parentRequired = getRequiredParent(elm, ancestorName); if (parentRequired) { if (ancestorName === parentRequired) { parentCandidate = ancestry[0]; ancestry = ancestry.slice(1); } else { parentCandidate = parentRequired; } } else if (ancestor) { parentCandidate = ancestry[0]; ancestry = ancestry.slice(1); } else if (!siblings) { return elm; } if (parentCandidate) { parent = createElement(parentCandidate); parent.appendChild(elm); } if (siblings) { if (!parent) { parent = dom.create('div'); parent.appendChild(elm); } Tools.each(siblings, function (sibling) { var siblingElm = createElement(sibling); parent.insertBefore(siblingElm, elm); }); } return wrapInHtml(parent, ancestry, parentCandidate && parentCandidate.siblings); }; if (ancestry && ancestry.length) { item = ancestry[0]; elm = createElement(item); fragment = dom.create('div'); fragment.appendChild(wrapInHtml(elm, ancestry.slice(1), item.siblings)); return fragment; } else { return ''; } }; var selectorToHtml = function (selector, editor) { return parsedSelectorToHtml(parseSelector(selector), editor); }; var parseSelectorItem = function (item) { var tagName; var obj = { classes: [], attrs: {} }; item = obj.selector = Tools.trim(item); if (item !== '*') { tagName = item.replace(/(?:([#\.]|::?)([\w\-]+)|(\[)([^\]]+)\]?)/g, function ($0, $1, $2, $3, $4) { switch ($1) { case '#': obj.attrs.id = $2; break; case '.': obj.classes.push($2); break; case ':': if (Tools.inArray('checked disabled enabled read-only required'.split(' '), $2) !== -1) { obj.attrs[$2] = $2; } break; } if ($3 === '[') { var m = $4.match(/([\w\-]+)(?:\=\"([^\"]+))?/); if (m) { obj.attrs[m[1]] = m[2]; } } return ''; }); } obj.name = tagName || 'div'; return obj; }; var parseSelector = function (selector) { if (!selector || typeof selector !== 'string') { return []; } selector = selector.split(/\s*,\s*/)[0]; selector = selector.replace(/\s*(~\+|~|\+|>)\s*/g, '$1'); return Tools.map(selector.split(/(?:>|\s+(?![^\[\]]+\]))/), function (item) { var siblings = Tools.map(item.split(/(?:~\+|~|\+)/), parseSelectorItem); var obj = siblings.pop(); if (siblings.length) { obj.siblings = siblings; } return obj; }).reverse(); }; var getCssText = function (editor, format) { var name, previewFrag, previewElm, items; var previewCss = '', parentFontSize, previewStyles; previewStyles = editor.settings.preview_styles; if (previewStyles === false) { return ''; } if (typeof previewStyles !== 'string') { previewStyles = 'font-family font-size font-weight font-style text-decoration ' + 'text-transform color background-color border border-radius outline text-shadow'; } var removeVars = function (val) { return val.replace(/%(\w+)/g, ''); }; if (typeof format === 'string') { format = editor.formatter.get(format); if (!format) { return; } format = format[0]; } if ('preview' in format) { previewStyles = format.preview; if (previewStyles === false) { return ''; } } name = format.block || format.inline || 'span'; items = parseSelector(format.selector); if (items.length) { if (!items[0].name) { items[0].name = name; } name = format.selector; previewFrag = parsedSelectorToHtml(items, editor); } else { previewFrag = parsedSelectorToHtml([name], editor); } previewElm = dom.select(name, previewFrag)[0] || previewFrag.firstChild; each$h(format.styles, function (value, name) { value = removeVars(value); if (value) { dom.setStyle(previewElm, name, value); } }); each$h(format.attributes, function (value, name) { value = removeVars(value); if (value) { dom.setAttrib(previewElm, name, value); } }); each$h(format.classes, function (value) { value = removeVars(value); if (!dom.hasClass(previewElm, value)) { dom.addClass(previewElm, value); } }); editor.fire('PreviewFormats'); dom.setStyles(previewFrag, { position: 'absolute', left: -65535 }); editor.getBody().appendChild(previewFrag); parentFontSize = dom.getStyle(editor.getBody(), 'fontSize', true); parentFontSize = /px$/.test(parentFontSize) ? parseInt(parentFontSize, 10) : 0; each$h(previewStyles.split(' '), function (name) { var value = dom.getStyle(previewElm, name, true); if (name === 'background-color' && /transparent|rgba\s*\([^)]+,\s*0\)/.test(value)) { value = dom.getStyle(editor.getBody(), name, true); if (dom.toHex(value).toLowerCase() === '#ffffff') { return; } } if (name === 'color') { if (dom.toHex(value).toLowerCase() === '#000000') { return; } } if (name === 'font-size') { if (/em|%$/.test(value)) { if (parentFontSize === 0) { return; } var numValue = parseFloat(value) / (/%$/.test(value) ? 100 : 1); value = numValue * parentFontSize + 'px'; } } if (name === 'border' && value) { previewCss += 'padding:0 2px;'; } previewCss += name + ':' + value + ';'; }); editor.fire('AfterPreviewFormats'); dom.remove(previewFrag); return previewCss; }; var Preview = { getCssText: getCssText, parseSelector: parseSelector, selectorToHtml: selectorToHtml }; var toggle = function (editor, formats, name, vars, node) { var fmt = formats.get(name); if (MatchFormat.match(editor, name, vars, node) && (!('toggle' in fmt[0]) || fmt[0].toggle)) { RemoveFormat.remove(editor, name, vars, node); } else { ApplyFormat.applyFormat(editor, name, vars, node); } }; var ToggleFormat = { toggle: toggle }; var setup$6 = function (editor) { editor.addShortcut('meta+b', '', 'Bold'); editor.addShortcut('meta+i', '', 'Italic'); editor.addShortcut('meta+u', '', 'Underline'); for (var i = 1; i <= 6; i++) { editor.addShortcut('access+' + i, '', [ 'FormatBlock', false, 'h' + i ]); } editor.addShortcut('access+7', '', [ 'FormatBlock', false, 'p' ]); editor.addShortcut('access+8', '', [ 'FormatBlock', false, 'div' ]); editor.addShortcut('access+9', '', [ 'FormatBlock', false, 'address' ]); }; var FormatShortcuts = { setup: setup$6 }; function Formatter (editor) { var formats = FormatRegistry(editor); var formatChangeState = Cell(null); FormatShortcuts.setup(editor); setup$2(editor); return { get: formats.get, register: formats.register, unregister: formats.unregister, apply: curry(ApplyFormat.applyFormat, editor), remove: curry(RemoveFormat.remove, editor), toggle: curry(ToggleFormat.toggle, editor, formats), match: curry(MatchFormat.match, editor), matchAll: curry(MatchFormat.matchAll, editor), matchNode: curry(MatchFormat.matchNode, editor), canApply: curry(MatchFormat.canApply, editor), formatChanged: curry(FormatChanged.formatChanged, editor, formatChangeState), getCssText: curry(Preview.getCssText, editor) }; } var hasOwnProperty$2 = Object.prototype.hasOwnProperty; var shallow$1 = function (old, nu) { return nu; }; var baseMerge = function (merger) { return function () { var objects = new Array(arguments.length); for (var i = 0; i < objects.length; i++) objects[i] = arguments[i]; if (objects.length === 0) throw new Error('Can\'t merge zero objects'); var ret = {}; for (var j = 0; j < objects.length; j++) { var curObject = objects[j]; for (var key in curObject) if (hasOwnProperty$2.call(curObject, key)) { ret[key] = merger(ret[key], curObject[key]); } } return ret; }; }; var merge = baseMerge(shallow$1); var register = function (htmlParser, settings, dom) { htmlParser.addAttributeFilter('data-mce-tabindex', function (nodes, name) { var i = nodes.length, node; while (i--) { node = nodes[i]; node.attr('tabindex', node.attributes.map['data-mce-tabindex']); node.attr(name, null); } }); htmlParser.addAttributeFilter('src,href,style', function (nodes, name) { var i = nodes.length, node, value; var internalName = 'data-mce-' + name; var urlConverter = settings.url_converter; var urlConverterScope = settings.url_converter_scope; while (i--) { node = nodes[i]; value = node.attributes.map[internalName]; if (value !== undefined) { node.attr(name, value.length > 0 ? value : null); node.attr(internalName, null); } else { value = node.attributes.map[name]; if (name === 'style') { value = dom.serializeStyle(dom.parseStyle(value), node.name); } else if (urlConverter) { value = urlConverter.call(urlConverterScope, value, name, node.name); } node.attr(name, value.length > 0 ? value : null); } } }); htmlParser.addAttributeFilter('class', function (nodes) { var i = nodes.length, node, value; while (i--) { node = nodes[i]; value = node.attr('class'); if (value) { value = node.attr('class').replace(/(?:^|\s)mce-item-\w+(?!\S)/g, ''); node.attr('class', value.length > 0 ? value : null); } } }); htmlParser.addAttributeFilter('data-mce-type', function (nodes, name, args) { var i = nodes.length, node; while (i--) { node = nodes[i]; if (node.attributes.map['data-mce-type'] === 'bookmark' && !args.cleanup) { var hasChildren = Option.from(node.firstChild).exists(function (firstChild) { return !Zwsp.isZwsp(firstChild.value); }); if (hasChildren) { node.unwrap(); } else { node.remove(); } } } }); htmlParser.addNodeFilter('noscript', function (nodes) { var i = nodes.length, node; while (i--) { node = nodes[i].firstChild; if (node) { node.value = Entities.decode(node.value); } } }); htmlParser.addNodeFilter('script,style', function (nodes, name) { var i = nodes.length, node, value, type; var trim = function (value) { return value.replace(/(<!--\[CDATA\[|\]\]-->)/g, '\n').replace(/^[\r\n]*|[\r\n]*$/g, '').replace(/^\s*((<!--)?(\s*\/\/)?\s*<!\[CDATA\[|(<!--\s*)?\/\*\s*<!\[CDATA\[\s*\*\/|(\/\/)?\s*<!--|\/\*\s*<!--\s*\*\/)\s*[\r\n]*/gi, '').replace(/\s*(\/\*\s*\]\]>\s*\*\/(-->)?|\s*\/\/\s*\]\]>(-->)?|\/\/\s*(-->)?|\]\]>|\/\*\s*-->\s*\*\/|\s*-->\s*)\s*$/g, ''); }; while (i--) { node = nodes[i]; value = node.firstChild ? node.firstChild.value : ''; if (name === 'script') { type = node.attr('type'); if (type) { node.attr('type', type === 'mce-no/type' ? null : type.replace(/^mce\-/, '')); } if (settings.element_format === 'xhtml' && value.length > 0) { node.firstChild.value = '// <![CDATA[\n' + trim(value) + '\n// ]]>'; } } else { if (settings.element_format === 'xhtml' && value.length > 0) { node.firstChild.value = '<!--\n' + trim(value) + '\n-->'; } } } }); htmlParser.addNodeFilter('#comment', function (nodes) { var i = nodes.length, node; while (i--) { node = nodes[i]; if (node.value.indexOf('[CDATA[') === 0) { node.name = '#cdata'; node.type = 4; node.value = node.value.replace(/^\[CDATA\[|\]\]$/g, ''); } else if (node.value.indexOf('mce:protected ') === 0) { node.name = '#text'; node.type = 3; node.raw = true; node.value = unescape(node.value).substr(14); } } }); htmlParser.addNodeFilter('xml:namespace,input', function (nodes, name) { var i = nodes.length, node; while (i--) { node = nodes[i]; if (node.type === 7) { node.remove(); } else if (node.type === 1) { if (name === 'input' && !('type' in node.attributes.map)) { node.attr('type', 'text'); } } } }); htmlParser.addAttributeFilter('data-mce-type', function (nodes) { each(nodes, function (node) { if (node.attr('data-mce-type') === 'format-caret') { if (node.isEmpty(htmlParser.schema.getNonEmptyElements())) { node.remove(); } else { node.unwrap(); } } }); }); htmlParser.addAttributeFilter('data-mce-src,data-mce-href,data-mce-style,' + 'data-mce-selected,data-mce-expando,' + 'data-mce-type,data-mce-resize', function (nodes, name) { var i = nodes.length; while (i--) { nodes[i].attr(name, null); } }); }; var trimTrailingBr = function (rootNode) { var brNode1, brNode2; var isBr = function (node) { return node && node.name === 'br'; }; brNode1 = rootNode.lastChild; if (isBr(brNode1)) { brNode2 = brNode1.prev; if (isBr(brNode2)) { brNode1.remove(); brNode2.remove(); } } }; var DomSerializerFilters = { register: register, trimTrailingBr: trimTrailingBr }; var preProcess = function (editor, node, args) { var impl, doc, oldDoc; var dom = editor.dom; node = node.cloneNode(true); impl = domGlobals.document.implementation; if (impl.createHTMLDocument) { doc = impl.createHTMLDocument(''); Tools.each(node.nodeName === 'BODY' ? node.childNodes : [node], function (node) { doc.body.appendChild(doc.importNode(node, true)); }); if (node.nodeName !== 'BODY') { node = doc.body.firstChild; } else { node = doc.body; } oldDoc = dom.doc; dom.doc = doc; } Events.firePreProcess(editor, merge(args, { node: node })); if (oldDoc) { dom.doc = oldDoc; } return node; }; var shouldFireEvent = function (editor, args) { return editor && editor.hasEventListeners('PreProcess') && !args.no_events; }; var process = function (editor, node, args) { return shouldFireEvent(editor, args) ? preProcess(editor, node, args) : node; }; var DomSerializerPreProcess = { process: process }; var removeAttrs = function (node, names) { each(names, function (name) { node.attr(name, null); }); }; var addFontToSpansFilter = function (domParser, styles, fontSizes) { domParser.addNodeFilter('font', function (nodes) { each(nodes, function (node) { var props = styles.parse(node.attr('style')); var color = node.attr('color'); var face = node.attr('face'); var size = node.attr('size'); if (color) { props.color = color; } if (face) { props['font-family'] = face; } if (size) { props['font-size'] = fontSizes[parseInt(node.attr('size'), 10) - 1]; } node.name = 'span'; node.attr('style', styles.serialize(props)); removeAttrs(node, [ 'color', 'face', 'size' ]); }); }); }; var addStrikeToSpanFilter = function (domParser, styles) { domParser.addNodeFilter('strike', function (nodes) { each(nodes, function (node) { var props = styles.parse(node.attr('style')); props['text-decoration'] = 'line-through'; node.name = 'span'; node.attr('style', styles.serialize(props)); }); }); }; var addFilters = function (domParser, settings) { var styles = Styles(); if (settings.convert_fonts_to_spans) { addFontToSpansFilter(domParser, styles, Tools.explode(settings.font_size_legacy_values)); } addStrikeToSpanFilter(domParser, styles); }; var register$1 = function (domParser, settings) { if (settings.inline_styles) { addFilters(domParser, settings); } }; var LegacyFilter = { register: register$1 }; var whiteSpaceRegExp$3 = /^[ \t\r\n]*$/; var typeLookup = { '#text': 3, '#comment': 8, '#cdata': 4, '#pi': 7, '#doctype': 10, '#document-fragment': 11 }; var walk$2 = function (node, root, prev) { var sibling; var parent; var startName = prev ? 'lastChild' : 'firstChild'; var siblingName = prev ? 'prev' : 'next'; if (node[startName]) { return node[startName]; } if (node !== root) { sibling = node[siblingName]; if (sibling) { return sibling; } for (parent = node.parent; parent && parent !== root; parent = parent.parent) { sibling = parent[siblingName]; if (sibling) { return sibling; } } } }; var Node$1 = function () { function Node(name, type) { this.name = name; this.type = type; if (type === 1) { this.attributes = []; this.attributes.map = {}; } } Node.create = function (name, attrs) { var node, attrName; node = new Node(name, typeLookup[name] || 1); if (attrs) { for (attrName in attrs) { node.attr(attrName, attrs[attrName]); } } return node; }; Node.prototype.replace = function (node) { var self = this; if (node.parent) { node.remove(); } self.insert(node, self); self.remove(); return self; }; Node.prototype.attr = function (name, value) { var self = this; var attrs, i; if (typeof name !== 'string') { for (i in name) { self.attr(i, name[i]); } return self; } if (attrs = self.attributes) { if (value !== undefined) { if (value === null) { if (name in attrs.map) { delete attrs.map[name]; i = attrs.length; while (i--) { if (attrs[i].name === name) { attrs = attrs.splice(i, 1); return self; } } } return self; } if (name in attrs.map) { i = attrs.length; while (i--) { if (attrs[i].name === name) { attrs[i].value = value; break; } } } else { attrs.push({ name: name, value: value }); } attrs.map[name] = value; return self; } return attrs.map[name]; } }; Node.prototype.clone = function () { var self = this; var clone = new Node(self.name, self.type); var i, l, selfAttrs, selfAttr, cloneAttrs; if (selfAttrs = self.attributes) { cloneAttrs = []; cloneAttrs.map = {}; for (i = 0, l = selfAttrs.length; i < l; i++) { selfAttr = selfAttrs[i]; if (selfAttr.name !== 'id') { cloneAttrs[cloneAttrs.length] = { name: selfAttr.name, value: selfAttr.value }; cloneAttrs.map[selfAttr.name] = selfAttr.value; } } clone.attributes = cloneAttrs; } clone.value = self.value; clone.shortEnded = self.shortEnded; return clone; }; Node.prototype.wrap = function (wrapper) { var self = this; self.parent.insert(wrapper, self); wrapper.append(self); return self; }; Node.prototype.unwrap = function () { var self = this; var node, next; for (node = self.firstChild; node;) { next = node.next; self.insert(node, self, true); node = next; } self.remove(); }; Node.prototype.remove = function () { var self = this, parent = self.parent, next = self.next, prev = self.prev; if (parent) { if (parent.firstChild === self) { parent.firstChild = next; if (next) { next.prev = null; } } else { prev.next = next; } if (parent.lastChild === self) { parent.lastChild = prev; if (prev) { prev.next = null; } } else { next.prev = prev; } self.parent = self.next = self.prev = null; } return self; }; Node.prototype.append = function (node) { var self = this; var last; if (node.parent) { node.remove(); } last = self.lastChild; if (last) { last.next = node; node.prev = last; self.lastChild = node; } else { self.lastChild = self.firstChild = node; } node.parent = self; return node; }; Node.prototype.insert = function (node, refNode, before) { var parent; if (node.parent) { node.remove(); } parent = refNode.parent || this; if (before) { if (refNode === parent.firstChild) { parent.firstChild = node; } else { refNode.prev.next = node; } node.prev = refNode.prev; node.next = refNode; refNode.prev = node; } else { if (refNode === parent.lastChild) { parent.lastChild = node; } else { refNode.next.prev = node; } node.next = refNode.next; node.prev = refNode; refNode.next = node; } node.parent = parent; return node; }; Node.prototype.getAll = function (name) { var self = this; var node; var collection = []; for (node = self.firstChild; node; node = walk$2(node, self)) { if (node.name === name) { collection.push(node); } } return collection; }; Node.prototype.empty = function () { var self = this; var nodes, i, node; if (self.firstChild) { nodes = []; for (node = self.firstChild; node; node = walk$2(node, self)) { nodes.push(node); } i = nodes.length; while (i--) { node = nodes[i]; node.parent = node.firstChild = node.lastChild = node.next = node.prev = null; } } self.firstChild = self.lastChild = null; return self; }; Node.prototype.isEmpty = function (elements, whitespace, predicate) { var self = this; var node = self.firstChild, i, name; whitespace = whitespace || {}; if (node) { do { if (node.type === 1) { if (node.attributes.map['data-mce-bogus']) { continue; } if (elements[node.name]) { return false; } i = node.attributes.length; while (i--) { name = node.attributes[i].name; if (name === 'name' || name.indexOf('data-mce-bookmark') === 0) { return false; } } } if (node.type === 8) { return false; } if (node.type === 3 && !whiteSpaceRegExp$3.test(node.value)) { return false; } if (node.type === 3 && node.parent && whitespace[node.parent.name] && whiteSpaceRegExp$3.test(node.value)) { return false; } if (predicate && predicate(node)) { return false; } } while (node = walk$2(node, self)); } return true; }; Node.prototype.walk = function (prev) { return walk$2(this, null, prev); }; return Node; }(); var paddEmptyNode = function (settings, args, blockElements, node) { var brPreferred = settings.padd_empty_with_br || args.insert; if (brPreferred && blockElements[node.name]) { node.empty().append(new Node$1('br', 1)).shortEnded = true; } else { node.empty().append(new Node$1('#text', 3)).value = '\xA0'; } }; var isPaddedWithNbsp = function (node) { return hasOnlyChild(node, '#text') && node.firstChild.value === '\xA0'; }; var hasOnlyChild = function (node, name) { return node && node.firstChild && node.firstChild === node.lastChild && node.firstChild.name === name; }; var isPadded = function (schema, node) { var rule = schema.getElementRule(node.name); return rule && rule.paddEmpty; }; var isEmpty$2 = function (schema, nonEmptyElements, whitespaceElements, node) { return node.isEmpty(nonEmptyElements, whitespaceElements, function (node) { return isPadded(schema, node); }); }; var isLineBreakNode = function (node, blockElements) { return node && (blockElements[node.name] || node.name === 'br'); }; var register$2 = function (parser, settings) { var schema = parser.schema; if (settings.remove_trailing_brs) { parser.addNodeFilter('br', function (nodes, _, args) { var i; var l = nodes.length; var node; var blockElements = Tools.extend({}, schema.getBlockElements()); var nonEmptyElements = schema.getNonEmptyElements(); var parent, lastParent, prev, prevName; var whiteSpaceElements = schema.getNonEmptyElements(); var elementRule, textNode; blockElements.body = 1; for (i = 0; i < l; i++) { node = nodes[i]; parent = node.parent; if (blockElements[node.parent.name] && node === parent.lastChild) { prev = node.prev; while (prev) { prevName = prev.name; if (prevName !== 'span' || prev.attr('data-mce-type') !== 'bookmark') { if (prevName !== 'br') { break; } if (prevName === 'br') { node = null; break; } } prev = prev.prev; } if (node) { node.remove(); if (isEmpty$2(schema, nonEmptyElements, whiteSpaceElements, parent)) { elementRule = schema.getElementRule(parent.name); if (elementRule) { if (elementRule.removeEmpty) { parent.remove(); } else if (elementRule.paddEmpty) { paddEmptyNode(settings, args, blockElements, parent); } } } } } else { lastParent = node; while (parent && parent.firstChild === lastParent && parent.lastChild === lastParent) { lastParent = parent; if (blockElements[parent.name]) { break; } parent = parent.parent; } if (lastParent === parent && settings.padd_empty_with_br !== true) { textNode = new Node$1('#text', 3); textNode.value = '\xA0'; node.replace(textNode); } } } }); } parser.addAttributeFilter('href', function (nodes) { var i = nodes.length, node; var appendRel = function (rel) { var parts = rel.split(' ').filter(function (p) { return p.length > 0; }); return parts.concat(['noopener']).sort().join(' '); }; var addNoOpener = function (rel) { var newRel = rel ? Tools.trim(rel) : ''; if (!/\b(noopener)\b/g.test(newRel)) { return appendRel(newRel); } else { return newRel; } }; if (!settings.allow_unsafe_link_target) { while (i--) { node = nodes[i]; if (node.name === 'a' && node.attr('target') === '_blank') { node.attr('rel', addNoOpener(node.attr('rel'))); } } } }); if (!settings.allow_html_in_named_anchor) { parser.addAttributeFilter('id,name', function (nodes) { var i = nodes.length, sibling, prevSibling, parent, node; while (i--) { node = nodes[i]; if (node.name === 'a' && node.firstChild && !node.attr('href')) { parent = node.parent; sibling = node.lastChild; do { prevSibling = sibling.prev; parent.insert(sibling, node); sibling = prevSibling; } while (sibling); } } }); } if (settings.fix_list_elements) { parser.addNodeFilter('ul,ol', function (nodes) { var i = nodes.length, node, parentNode; while (i--) { node = nodes[i]; parentNode = node.parent; if (parentNode.name === 'ul' || parentNode.name === 'ol') { if (node.prev && node.prev.name === 'li') { node.prev.append(node); } else { var li = new Node$1('li', 1); li.attr('style', 'list-style-type: none'); node.wrap(li); } } } }); } if (settings.validate && schema.getValidClasses()) { parser.addAttributeFilter('class', function (nodes) { var i = nodes.length, node, classList, ci, className, classValue; var validClasses = schema.getValidClasses(); var validClassesMap, valid; while (i--) { node = nodes[i]; classList = node.attr('class').split(' '); classValue = ''; for (ci = 0; ci < classList.length; ci++) { className = classList[ci]; valid = false; validClassesMap = validClasses['*']; if (validClassesMap && validClassesMap[className]) { valid = true; } validClassesMap = validClasses[node.name]; if (!valid && validClassesMap && validClassesMap[className]) { valid = true; } if (valid) { if (classValue) { classValue += ' '; } classValue += className; } } if (!classValue.length) { classValue = null; } node.attr('class', classValue); } }); } }; var makeMap$4 = Tools.makeMap, each$i = Tools.each, explode$3 = Tools.explode, extend$3 = Tools.extend; function DomParser (settings, schema) { if (schema === void 0) { schema = Schema(); } var nodeFilters = {}; var attributeFilters = []; var matchedNodes = {}; var matchedAttributes = {}; settings = settings || {}; settings.validate = 'validate' in settings ? settings.validate : true; settings.root_name = settings.root_name || 'body'; var fixInvalidChildren = function (nodes) { var ni, node, parent, parents, newParent, currentNode, tempNode, childNode, i; var nonEmptyElements, whitespaceElements, nonSplitableElements, textBlockElements, specialElements, sibling, nextNode; nonSplitableElements = makeMap$4('tr,td,th,tbody,thead,tfoot,table'); nonEmptyElements = schema.getNonEmptyElements(); whitespaceElements = schema.getWhiteSpaceElements(); textBlockElements = schema.getTextBlockElements(); specialElements = schema.getSpecialElements(); for (ni = 0; ni < nodes.length; ni++) { node = nodes[ni]; if (!node.parent || node.fixed) { continue; } if (textBlockElements[node.name] && node.parent.name === 'li') { sibling = node.next; while (sibling) { if (textBlockElements[sibling.name]) { sibling.name = 'li'; sibling.fixed = true; node.parent.insert(sibling, node.parent); } else { break; } sibling = sibling.next; } node.unwrap(node); continue; } parents = [node]; for (parent = node.parent; parent && !schema.isValidChild(parent.name, node.name) && !nonSplitableElements[parent.name]; parent = parent.parent) { parents.push(parent); } if (parent && parents.length > 1) { parents.reverse(); newParent = currentNode = filterNode(parents[0].clone()); for (i = 0; i < parents.length - 1; i++) { if (schema.isValidChild(currentNode.name, parents[i].name)) { tempNode = filterNode(parents[i].clone()); currentNode.append(tempNode); } else { tempNode = currentNode; } for (childNode = parents[i].firstChild; childNode && childNode !== parents[i + 1];) { nextNode = childNode.next; tempNode.append(childNode); childNode = nextNode; } currentNode = tempNode; } if (!isEmpty$2(schema, nonEmptyElements, whitespaceElements, newParent)) { parent.insert(newParent, parents[0], true); parent.insert(node, newParent); } else { parent.insert(node, parents[0], true); } parent = parents[0]; if (isEmpty$2(schema, nonEmptyElements, whitespaceElements, parent) || hasOnlyChild(parent, 'br')) { parent.empty().remove(); } } else if (node.parent) { if (node.name === 'li') { sibling = node.prev; if (sibling && (sibling.name === 'ul' || sibling.name === 'ul')) { sibling.append(node); continue; } sibling = node.next; if (sibling && (sibling.name === 'ul' || sibling.name === 'ul')) { sibling.insert(node, sibling.firstChild, true); continue; } node.wrap(filterNode(new Node$1('ul', 1))); continue; } if (schema.isValidChild(node.parent.name, 'div') && schema.isValidChild('div', node.name)) { node.wrap(filterNode(new Node$1('div', 1))); } else { if (specialElements[node.name]) { node.empty().remove(); } else { node.unwrap(); } } } } }; var filterNode = function (node) { var i, name, list; name = node.name; if (name in nodeFilters) { list = matchedNodes[name]; if (list) { list.push(node); } else { matchedNodes[name] = [node]; } } i = attributeFilters.length; while (i--) { name = attributeFilters[i].name; if (name in node.attributes.map) { list = matchedAttributes[name]; if (list) { list.push(node); } else { matchedAttributes[name] = [node]; } } } return node; }; var addNodeFilter = function (name, callback) { each$i(explode$3(name), function (name) { var list = nodeFilters[name]; if (!list) { nodeFilters[name] = list = []; } list.push(callback); }); }; var getNodeFilters = function () { var out = []; for (var name in nodeFilters) { if (nodeFilters.hasOwnProperty(name)) { out.push({ name: name, callbacks: nodeFilters[name] }); } } return out; }; var addAttributeFilter = function (name, callback) { each$i(explode$3(name), function (name) { var i; for (i = 0; i < attributeFilters.length; i++) { if (attributeFilters[i].name === name) { attributeFilters[i].callbacks.push(callback); return; } } attributeFilters.push({ name: name, callbacks: [callback] }); }); }; var getAttributeFilters = function () { return [].concat(attributeFilters); }; var parse = function (html, args) { var parser, nodes, i, l, fi, fl, list, name; var blockElements; var invalidChildren = []; var isInWhiteSpacePreservedElement; var node; args = args || {}; matchedNodes = {}; matchedAttributes = {}; blockElements = extend$3(makeMap$4('script,style,head,html,body,title,meta,param'), schema.getBlockElements()); var nonEmptyElements = schema.getNonEmptyElements(); var children = schema.children; var validate = settings.validate; var rootBlockName = 'forced_root_block' in args ? args.forced_root_block : settings.forced_root_block; var whiteSpaceElements = schema.getWhiteSpaceElements(); var startWhiteSpaceRegExp = /^[ \t\r\n]+/; var endWhiteSpaceRegExp = /[ \t\r\n]+$/; var allWhiteSpaceRegExp = /[ \t\r\n]+/g; var isAllWhiteSpaceRegExp = /^[ \t\r\n]+$/; isInWhiteSpacePreservedElement = whiteSpaceElements.hasOwnProperty(args.context) || whiteSpaceElements.hasOwnProperty(settings.root_name); var addRootBlocks = function () { var node = rootNode.firstChild, next, rootBlockNode; var trim = function (rootBlockNode) { if (rootBlockNode) { node = rootBlockNode.firstChild; if (node && node.type === 3) { node.value = node.value.replace(startWhiteSpaceRegExp, ''); } node = rootBlockNode.lastChild; if (node && node.type === 3) { node.value = node.value.replace(endWhiteSpaceRegExp, ''); } } }; if (!schema.isValidChild(rootNode.name, rootBlockName.toLowerCase())) { return; } while (node) { next = node.next; if (node.type === 3 || node.type === 1 && node.name !== 'p' && !blockElements[node.name] && !node.attr('data-mce-type')) { if (!rootBlockNode) { rootBlockNode = createNode(rootBlockName, 1); rootBlockNode.attr(settings.forced_root_block_attrs); rootNode.insert(rootBlockNode, node); rootBlockNode.append(node); } else { rootBlockNode.append(node); } } else { trim(rootBlockNode); rootBlockNode = null; } node = next; } trim(rootBlockNode); }; var createNode = function (name, type) { var node = new Node$1(name, type); var list; if (name in nodeFilters) { list = matchedNodes[name]; if (list) { list.push(node); } else { matchedNodes[name] = [node]; } } return node; }; var removeWhitespaceBefore = function (node) { var textNode, textNodeNext, textVal, sibling; var blockElements = schema.getBlockElements(); for (textNode = node.prev; textNode && textNode.type === 3;) { textVal = textNode.value.replace(endWhiteSpaceRegExp, ''); if (textVal.length > 0) { textNode.value = textVal; return; } textNodeNext = textNode.next; if (textNodeNext) { if (textNodeNext.type === 3 && textNodeNext.value.length) { textNode = textNode.prev; continue; } if (!blockElements[textNodeNext.name] && textNodeNext.name !== 'script' && textNodeNext.name !== 'style') { textNode = textNode.prev; continue; } } sibling = textNode.prev; textNode.remove(); textNode = sibling; } }; var cloneAndExcludeBlocks = function (input) { var name; var output = {}; for (name in input) { if (name !== 'li' && name !== 'p') { output[name] = input[name]; } } return output; }; parser = SaxParser$1({ validate: validate, allow_script_urls: settings.allow_script_urls, allow_conditional_comments: settings.allow_conditional_comments, self_closing_elements: cloneAndExcludeBlocks(schema.getSelfClosingElements()), cdata: function (text) { node.append(createNode('#cdata', 4)).value = text; }, text: function (text, raw) { var textNode; if (!isInWhiteSpacePreservedElement) { text = text.replace(allWhiteSpaceRegExp, ' '); if (isLineBreakNode(node.lastChild, blockElements)) { text = text.replace(startWhiteSpaceRegExp, ''); } } if (text.length !== 0) { textNode = createNode('#text', 3); textNode.raw = !!raw; node.append(textNode).value = text; } }, comment: function (text) { node.append(createNode('#comment', 8)).value = text; }, pi: function (name, text) { node.append(createNode(name, 7)).value = text; removeWhitespaceBefore(node); }, doctype: function (text) { var newNode; newNode = node.append(createNode('#doctype', 10)); newNode.value = text; removeWhitespaceBefore(node); }, start: function (name, attrs, empty) { var newNode, attrFiltersLen, elementRule, attrName, parent; elementRule = validate ? schema.getElementRule(name) : {}; if (elementRule) { newNode = createNode(elementRule.outputName || name, 1); newNode.attributes = attrs; newNode.shortEnded = empty; node.append(newNode); parent = children[node.name]; if (parent && children[newNode.name] && !parent[newNode.name]) { invalidChildren.push(newNode); } attrFiltersLen = attributeFilters.length; while (attrFiltersLen--) { attrName = attributeFilters[attrFiltersLen].name; if (attrName in attrs.map) { list = matchedAttributes[attrName]; if (list) { list.push(newNode); } else { matchedAttributes[attrName] = [newNode]; } } } if (blockElements[name]) { removeWhitespaceBefore(newNode); } if (!empty) { node = newNode; } if (!isInWhiteSpacePreservedElement && whiteSpaceElements[name]) { isInWhiteSpacePreservedElement = true; } } }, end: function (name) { var textNode, elementRule, text, sibling, tempNode; elementRule = validate ? schema.getElementRule(name) : {}; if (elementRule) { if (blockElements[name]) { if (!isInWhiteSpacePreservedElement) { textNode = node.firstChild; if (textNode && textNode.type === 3) { text = textNode.value.replace(startWhiteSpaceRegExp, ''); if (text.length > 0) { textNode.value = text; textNode = textNode.next; } else { sibling = textNode.next; textNode.remove(); textNode = sibling; while (textNode && textNode.type === 3) { text = textNode.value; sibling = textNode.next; if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) { textNode.remove(); textNode = sibling; } textNode = sibling; } } } textNode = node.lastChild; if (textNode && textNode.type === 3) { text = textNode.value.replace(endWhiteSpaceRegExp, ''); if (text.length > 0) { textNode.value = text; textNode = textNode.prev; } else { sibling = textNode.prev; textNode.remove(); textNode = sibling; while (textNode && textNode.type === 3) { text = textNode.value; sibling = textNode.prev; if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) { textNode.remove(); textNode = sibling; } textNode = sibling; } } } } } if (isInWhiteSpacePreservedElement && whiteSpaceElements[name]) { isInWhiteSpacePreservedElement = false; } if (elementRule.removeEmpty && isEmpty$2(schema, nonEmptyElements, whiteSpaceElements, node)) { if (!node.attributes.map.name && !node.attr('id')) { tempNode = node.parent; if (blockElements[node.name]) { node.empty().remove(); } else { node.unwrap(); } node = tempNode; return; } } if (elementRule.paddEmpty && (isPaddedWithNbsp(node) || isEmpty$2(schema, nonEmptyElements, whiteSpaceElements, node))) { paddEmptyNode(settings, args, blockElements, node); } node = node.parent; } } }, schema); var rootNode = node = new Node$1(args.context || settings.root_name, 11); parser.parse(html); if (validate && invalidChildren.length) { if (!args.context) { fixInvalidChildren(invalidChildren); } else { args.invalid = true; } } if (rootBlockName && (rootNode.name === 'body' || args.isRootContent)) { addRootBlocks(); } if (!args.invalid) { for (name in matchedNodes) { list = nodeFilters[name]; nodes = matchedNodes[name]; fi = nodes.length; while (fi--) { if (!nodes[fi].parent) { nodes.splice(fi, 1); } } for (i = 0, l = list.length; i < l; i++) { list[i](nodes, name, args); } } for (i = 0, l = attributeFilters.length; i < l; i++) { list = attributeFilters[i]; if (list.name in matchedAttributes) { nodes = matchedAttributes[list.name]; fi = nodes.length; while (fi--) { if (!nodes[fi].parent) { nodes.splice(fi, 1); } } for (fi = 0, fl = list.callbacks.length; fi < fl; fi++) { list.callbacks[fi](nodes, list.name, args); } } } } return rootNode; }; var exports = { schema: schema, addAttributeFilter: addAttributeFilter, getAttributeFilters: getAttributeFilters, addNodeFilter: addNodeFilter, getNodeFilters: getNodeFilters, filterNode: filterNode, parse: parse }; register$2(exports, settings); LegacyFilter.register(exports, settings); return exports; } var addTempAttr = function (htmlParser, tempAttrs, name) { if (Tools.inArray(tempAttrs, name) === -1) { htmlParser.addAttributeFilter(name, function (nodes, name) { var i = nodes.length; while (i--) { nodes[i].attr(name, null); } }); tempAttrs.push(name); } }; var postProcess$1 = function (editor, args, content) { if (!args.no_events && editor) { var outArgs = Events.firePostProcess(editor, merge(args, { content: content })); return outArgs.content; } else { return content; } }; var getHtmlFromNode = function (dom, node, args) { var html = Zwsp.trim(args.getInner ? node.innerHTML : dom.getOuterHTML(node)); return args.selection || isWsPreserveElement(Element.fromDom(node)) ? html : Tools.trim(html); }; var parseHtml = function (htmlParser, html, args) { var parserArgs = args.selection ? merge({ forced_root_block: false }, args) : args; var rootNode = htmlParser.parse(html, parserArgs); DomSerializerFilters.trimTrailingBr(rootNode); return rootNode; }; var serializeNode = function (settings, schema, node) { var htmlSerializer = HtmlSerializer(settings, schema); return htmlSerializer.serialize(node); }; var toHtml = function (editor, settings, schema, rootNode, args) { var content = serializeNode(settings, schema, rootNode); return postProcess$1(editor, args, content); }; function DomSerializer (settings, editor) { var dom, schema, htmlParser; var tempAttrs = ['data-mce-selected']; dom = editor && editor.dom ? editor.dom : DOMUtils$1.DOM; schema = editor && editor.schema ? editor.schema : Schema(settings); settings.entity_encoding = settings.entity_encoding || 'named'; settings.remove_trailing_brs = 'remove_trailing_brs' in settings ? settings.remove_trailing_brs : true; htmlParser = DomParser(settings, schema); DomSerializerFilters.register(htmlParser, settings, dom); var serialize = function (node, parserArgs) { var args = merge({ format: 'html' }, parserArgs ? parserArgs : {}); var targetNode = DomSerializerPreProcess.process(editor, node, args); var html = getHtmlFromNode(dom, targetNode, args); var rootNode = parseHtml(htmlParser, html, args); return args.format === 'tree' ? rootNode : toHtml(editor, settings, schema, rootNode, args); }; return { schema: schema, addNodeFilter: htmlParser.addNodeFilter, addAttributeFilter: htmlParser.addAttributeFilter, serialize: serialize, addRules: function (rules) { schema.addValidElements(rules); }, setRules: function (rules) { schema.setValidElements(rules); }, addTempAttr: curry(addTempAttr, htmlParser, tempAttrs), getTempAttrs: function () { return tempAttrs; } }; } function DomSerializer$1 (settings, editor) { var domSerializer = DomSerializer(settings, editor); return { schema: domSerializer.schema, addNodeFilter: domSerializer.addNodeFilter, addAttributeFilter: domSerializer.addAttributeFilter, serialize: domSerializer.serialize, addRules: domSerializer.addRules, setRules: domSerializer.setRules, addTempAttr: domSerializer.addTempAttr, getTempAttrs: domSerializer.getTempAttrs }; } function BookmarkManager(selection) { return { getBookmark: curry(Bookmarks.getBookmark, selection), moveToBookmark: curry(Bookmarks.moveToBookmark, selection) }; } (function (BookmarkManager) { BookmarkManager.isBookmarkNode = Bookmarks.isBookmarkNode; }(BookmarkManager || (BookmarkManager = {}))); var BookmarkManager$1 = BookmarkManager; var isContentEditableFalse$a = NodeType.isContentEditableFalse; var isContentEditableTrue$5 = NodeType.isContentEditableTrue; var getContentEditableRoot$2 = function (root, node) { while (node && node !== root) { if (isContentEditableTrue$5(node) || isContentEditableFalse$a(node)) { return node; } node = node.parentNode; } return null; }; var ControlSelection = function (selection, editor) { var dom = editor.dom, each = Tools.each; var selectedElm, selectedElmGhost, resizeHelper, resizeHandles, selectedHandle; var startX, startY, selectedElmX, selectedElmY, startW, startH, ratio, resizeStarted; var width, height; var editableDoc = editor.getDoc(), rootDocument = domGlobals.document; var abs = Math.abs, round = Math.round, rootElement = editor.getBody(); var startScrollWidth, startScrollHeight; resizeHandles = { nw: [ 0, 0, -1, -1 ], ne: [ 1, 0, 1, -1 ], se: [ 1, 1, 1, 1 ], sw: [ 0, 1, -1, 1 ] }; var rootClass = '.mce-content-body'; editor.contentStyles.push(rootClass + ' div.mce-resizehandle {' + 'position: absolute;' + 'border: 1px solid black;' + 'box-sizing: content-box;' + 'background: #FFF;' + 'width: 7px;' + 'height: 7px;' + 'z-index: 10000' + '}' + rootClass + ' .mce-resizehandle:hover {' + 'background: #000' + '}' + rootClass + ' img[data-mce-selected],' + rootClass + ' hr[data-mce-selected] {' + 'outline: 1px solid black;' + 'resize: none' + '}' + rootClass + ' .mce-clonedresizable {' + 'position: absolute;' + (Env.gecko ? '' : 'outline: 1px dashed black;') + 'opacity: .5;' + 'filter: alpha(opacity=50);' + 'z-index: 10000' + '}' + rootClass + ' .mce-resize-helper {' + 'background: #555;' + 'background: rgba(0,0,0,0.75);' + 'border-radius: 3px;' + 'border: 1px;' + 'color: white;' + 'display: none;' + 'font-family: sans-serif;' + 'font-size: 12px;' + 'white-space: nowrap;' + 'line-height: 14px;' + 'margin: 5px 10px;' + 'padding: 5px;' + 'position: absolute;' + 'z-index: 10001' + '}'); var isImage = function (elm) { return elm && (elm.nodeName === 'IMG' || editor.dom.is(elm, 'figure.image')); }; var isEventOnImageOutsideRange = function (evt, range) { return isImage(evt.target) && !RangePoint.isXYWithinRange(evt.clientX, evt.clientY, range); }; var contextMenuSelectImage = function (evt) { var target = evt.target; if (isEventOnImageOutsideRange(evt, editor.selection.getRng()) && !evt.isDefaultPrevented()) { evt.preventDefault(); editor.selection.select(target); } }; var getResizeTarget = function (elm) { return editor.dom.is(elm, 'figure.image') ? elm.querySelector('img') : elm; }; var isResizable = function (elm) { var selector = editor.settings.object_resizing; if (selector === false || Env.iOS) { return false; } if (typeof selector !== 'string') { selector = 'table,img,figure.image,div'; } if (elm.getAttribute('data-mce-resize') === 'false') { return false; } if (elm === editor.getBody()) { return false; } return is$1(Element.fromDom(elm), selector); }; var resizeGhostElement = function (e) { var deltaX, deltaY, proportional; var resizeHelperX, resizeHelperY; deltaX = e.screenX - startX; deltaY = e.screenY - startY; width = deltaX * selectedHandle[2] + startW; height = deltaY * selectedHandle[3] + startH; width = width < 5 ? 5 : width; height = height < 5 ? 5 : height; if (isImage(selectedElm) && editor.settings.resize_img_proportional !== false) { proportional = !VK.modifierPressed(e); } else { proportional = VK.modifierPressed(e) || isImage(selectedElm) && selectedHandle[2] * selectedHandle[3] !== 0; } if (proportional) { if (abs(deltaX) > abs(deltaY)) { height = round(width * ratio); width = round(height / ratio); } else { width = round(height / ratio); height = round(width * ratio); } } dom.setStyles(getResizeTarget(selectedElmGhost), { width: width, height: height }); resizeHelperX = selectedHandle.startPos.x + deltaX; resizeHelperY = selectedHandle.startPos.y + deltaY; resizeHelperX = resizeHelperX > 0 ? resizeHelperX : 0; resizeHelperY = resizeHelperY > 0 ? resizeHelperY : 0; dom.setStyles(resizeHelper, { left: resizeHelperX, top: resizeHelperY, display: 'block' }); resizeHelper.innerHTML = width + ' × ' + height; if (selectedHandle[2] < 0 && selectedElmGhost.clientWidth <= width) { dom.setStyle(selectedElmGhost, 'left', selectedElmX + (startW - width)); } if (selectedHandle[3] < 0 && selectedElmGhost.clientHeight <= height) { dom.setStyle(selectedElmGhost, 'top', selectedElmY + (startH - height)); } deltaX = rootElement.scrollWidth - startScrollWidth; deltaY = rootElement.scrollHeight - startScrollHeight; if (deltaX + deltaY !== 0) { dom.setStyles(resizeHelper, { left: resizeHelperX - deltaX, top: resizeHelperY - deltaY }); } if (!resizeStarted) { Events.fireObjectResizeStart(editor, selectedElm, startW, startH); resizeStarted = true; } }; var endGhostResize = function () { resizeStarted = false; var setSizeProp = function (name, value) { if (value) { if (selectedElm.style[name] || !editor.schema.isValid(selectedElm.nodeName.toLowerCase(), name)) { dom.setStyle(getResizeTarget(selectedElm), name, value); } else { dom.setAttrib(getResizeTarget(selectedElm), name, value); } } }; setSizeProp('width', width); setSizeProp('height', height); dom.unbind(editableDoc, 'mousemove', resizeGhostElement); dom.unbind(editableDoc, 'mouseup', endGhostResize); if (rootDocument !== editableDoc) { dom.unbind(rootDocument, 'mousemove', resizeGhostElement); dom.unbind(rootDocument, 'mouseup', endGhostResize); } dom.remove(selectedElmGhost); dom.remove(resizeHelper); showResizeRect(selectedElm); Events.fireObjectResized(editor, selectedElm, width, height); dom.setAttrib(selectedElm, 'style', dom.getAttrib(selectedElm, 'style')); editor.nodeChanged(); }; var showResizeRect = function (targetElm) { var position, targetWidth, targetHeight, e, rect; hideResizeRect(); unbindResizeHandleEvents(); position = dom.getPos(targetElm, rootElement); selectedElmX = position.x; selectedElmY = position.y; rect = targetElm.getBoundingClientRect(); targetWidth = rect.width || rect.right - rect.left; targetHeight = rect.height || rect.bottom - rect.top; if (selectedElm !== targetElm) { selectedElm = targetElm; width = height = 0; } e = editor.fire('ObjectSelected', { target: targetElm }); if (isResizable(targetElm) && !e.isDefaultPrevented()) { each(resizeHandles, function (handle, name) { var handleElm; var startDrag = function (e) { startX = e.screenX; startY = e.screenY; startW = getResizeTarget(selectedElm).clientWidth; startH = getResizeTarget(selectedElm).clientHeight; ratio = startH / startW; selectedHandle = handle; handle.startPos = { x: targetWidth * handle[0] + selectedElmX, y: targetHeight * handle[1] + selectedElmY }; startScrollWidth = rootElement.scrollWidth; startScrollHeight = rootElement.scrollHeight; selectedElmGhost = selectedElm.cloneNode(true); dom.addClass(selectedElmGhost, 'mce-clonedresizable'); dom.setAttrib(selectedElmGhost, 'data-mce-bogus', 'all'); selectedElmGhost.contentEditable = false; selectedElmGhost.unSelectabe = true; dom.setStyles(selectedElmGhost, { left: selectedElmX, top: selectedElmY, margin: 0 }); selectedElmGhost.removeAttribute('data-mce-selected'); rootElement.appendChild(selectedElmGhost); dom.bind(editableDoc, 'mousemove', resizeGhostElement); dom.bind(editableDoc, 'mouseup', endGhostResize); if (rootDocument !== editableDoc) { dom.bind(rootDocument, 'mousemove', resizeGhostElement); dom.bind(rootDocument, 'mouseup', endGhostResize); } resizeHelper = dom.add(rootElement, 'div', { 'class': 'mce-resize-helper', 'data-mce-bogus': 'all' }, startW + ' × ' + startH); }; handleElm = dom.get('mceResizeHandle' + name); if (handleElm) { dom.remove(handleElm); } handleElm = dom.add(rootElement, 'div', { 'id': 'mceResizeHandle' + name, 'data-mce-bogus': 'all', 'class': 'mce-resizehandle', 'unselectable': true, 'style': 'cursor:' + name + '-resize; margin:0; padding:0' }); if (Env.ie === 11) { handleElm.contentEditable = false; } dom.bind(handleElm, 'mousedown', function (e) { e.stopImmediatePropagation(); e.preventDefault(); startDrag(e); }); handle.elm = handleElm; dom.setStyles(handleElm, { left: targetWidth * handle[0] + selectedElmX - handleElm.offsetWidth / 2, top: targetHeight * handle[1] + selectedElmY - handleElm.offsetHeight / 2 }); }); } else { hideResizeRect(); } selectedElm.setAttribute('data-mce-selected', '1'); }; var hideResizeRect = function () { var name, handleElm; unbindResizeHandleEvents(); if (selectedElm) { selectedElm.removeAttribute('data-mce-selected'); } for (name in resizeHandles) { handleElm = dom.get('mceResizeHandle' + name); if (handleElm) { dom.unbind(handleElm); dom.remove(handleElm); } } }; var updateResizeRect = function (e) { var startElm, controlElm; var isChildOrEqual = function (node, parent) { if (node) { do { if (node === parent) { return true; } } while (node = node.parentNode); } }; if (resizeStarted || editor.removed) { return; } each(dom.select('img[data-mce-selected],hr[data-mce-selected]'), function (img) { img.removeAttribute('data-mce-selected'); }); controlElm = e.type === 'mousedown' ? e.target : selection.getNode(); controlElm = dom.$(controlElm).closest('table,img,figure.image,hr')[0]; if (isChildOrEqual(controlElm, rootElement)) { disableGeckoResize(); startElm = selection.getStart(true); if (isChildOrEqual(startElm, controlElm) && isChildOrEqual(selection.getEnd(true), controlElm)) { showResizeRect(controlElm); return; } } hideResizeRect(); }; var isWithinContentEditableFalse = function (elm) { return isContentEditableFalse$a(getContentEditableRoot$2(editor.getBody(), elm)); }; var unbindResizeHandleEvents = function () { for (var name in resizeHandles) { var handle = resizeHandles[name]; if (handle.elm) { dom.unbind(handle.elm); delete handle.elm; } } }; var disableGeckoResize = function () { try { editor.getDoc().execCommand('enableObjectResizing', false, false); } catch (ex) { } }; editor.on('init', function () { disableGeckoResize(); if (Env.ie && Env.ie >= 11) { editor.on('mousedown click', function (e) { var target = e.target, nodeName = target.nodeName; if (!resizeStarted && /^(TABLE|IMG|HR)$/.test(nodeName) && !isWithinContentEditableFalse(target)) { if (e.button !== 2) { editor.selection.select(target, nodeName === 'TABLE'); } if (e.type === 'mousedown') { editor.nodeChanged(); } } }); editor.dom.bind(rootElement, 'mscontrolselect', function (e) { var delayedSelect = function (node) { Delay.setEditorTimeout(editor, function () { editor.selection.select(node); }); }; if (isWithinContentEditableFalse(e.target)) { e.preventDefault(); delayedSelect(e.target); return; } if (/^(TABLE|IMG|HR)$/.test(e.target.nodeName)) { e.preventDefault(); if (e.target.tagName === 'IMG') { delayedSelect(e.target); } } }); } var throttledUpdateResizeRect = Delay.throttle(function (e) { if (!editor.composing) { updateResizeRect(e); } }); editor.on('nodechange ResizeEditor ResizeWindow drop FullscreenStateChanged', throttledUpdateResizeRect); editor.on('keyup compositionend', function (e) { if (selectedElm && selectedElm.nodeName === 'TABLE') { throttledUpdateResizeRect(e); } }); editor.on('hide blur', hideResizeRect); editor.on('contextmenu', contextMenuSelectImage); }); editor.on('remove', unbindResizeHandleEvents); var destroy = function () { selectedElm = selectedElmGhost = null; }; return { isResizable: isResizable, showResizeRect: showResizeRect, hideResizeRect: hideResizeRect, updateResizeRect: updateResizeRect, destroy: destroy }; }; var getPos$1 = function (elm) { var x = 0, y = 0; var offsetParent = elm; while (offsetParent && offsetParent.nodeType) { x += offsetParent.offsetLeft || 0; y += offsetParent.offsetTop || 0; offsetParent = offsetParent.offsetParent; } return { x: x, y: y }; }; var fireScrollIntoViewEvent = function (editor, elm, alignToTop) { var scrollEvent = { elm: elm, alignToTop: alignToTop }; editor.fire('scrollIntoView', scrollEvent); return scrollEvent.isDefaultPrevented(); }; var scrollElementIntoView = function (editor, elm, alignToTop) { var y, viewPort; var dom = editor.dom; var root = dom.getRoot(); var viewPortY, viewPortH, offsetY = 0; if (fireScrollIntoViewEvent(editor, elm, alignToTop)) { return; } if (!NodeType.isElement(elm)) { return; } if (alignToTop === false) { offsetY = elm.offsetHeight; } if (root.nodeName !== 'BODY') { var scrollContainer = editor.selection.getScrollContainer(); if (scrollContainer) { y = getPos$1(elm).y - getPos$1(scrollContainer).y + offsetY; viewPortH = scrollContainer.clientHeight; viewPortY = scrollContainer.scrollTop; if (y < viewPortY || y + 25 > viewPortY + viewPortH) { scrollContainer.scrollTop = y < viewPortY ? y : y - viewPortH + 25; } return; } } viewPort = dom.getViewPort(editor.getWin()); y = dom.getPos(elm).y + offsetY; viewPortY = viewPort.y; viewPortH = viewPort.h; if (y < viewPort.y || y + 25 > viewPortY + viewPortH) { editor.getWin().scrollTo(0, y < viewPortY ? y : y - viewPortH + 25); } }; var getViewPortRect = function (editor) { if (editor.inline) { return editor.getBody().getBoundingClientRect(); } else { var win = editor.getWin(); return { left: 0, right: win.innerWidth, top: 0, bottom: win.innerHeight, width: win.innerWidth, height: win.innerHeight }; } }; var scrollBy = function (editor, dx, dy) { if (editor.inline) { editor.getBody().scrollLeft += dx; editor.getBody().scrollTop += dy; } else { editor.getWin().scrollBy(dx, dy); } }; var scrollRangeIntoView = function (editor, rng) { head(CaretPosition.fromRangeStart(rng).getClientRects()).each(function (rngRect) { var bodyRect = getViewPortRect(editor); var overflow = getOverflow(bodyRect, rngRect); var margin = 4; var dx = overflow.x > 0 ? overflow.x + margin : overflow.x - margin; var dy = overflow.y > 0 ? overflow.y + margin : overflow.y - margin; scrollBy(editor, overflow.x !== 0 ? dx : 0, overflow.y !== 0 ? dy : 0); }); }; var ScrollIntoView = { scrollElementIntoView: scrollElementIntoView, scrollRangeIntoView: scrollRangeIntoView }; var hasCeProperty = function (node) { return NodeType.isContentEditableTrue(node) || NodeType.isContentEditableFalse(node); }; var findParent$1 = function (node, rootNode, predicate) { while (node && node !== rootNode) { if (predicate(node)) { return node; } node = node.parentNode; } return null; }; var findClosestIeRange = function (clientX, clientY, doc) { var element, rng, rects; element = doc.elementFromPoint(clientX, clientY); rng = doc.body.createTextRange(); if (!element || element.tagName === 'HTML') { element = doc.body; } rng.moveToElementText(element); rects = Tools.toArray(rng.getClientRects()); rects = rects.sort(function (a, b) { a = Math.abs(Math.max(a.top - clientY, a.bottom - clientY)); b = Math.abs(Math.max(b.top - clientY, b.bottom - clientY)); return a - b; }); if (rects.length > 0) { clientY = (rects[0].bottom + rects[0].top) / 2; try { rng.moveToPoint(clientX, clientY); rng.collapse(true); return rng; } catch (ex) { } } return null; }; var moveOutOfContentEditableFalse = function (rng, rootNode) { var parentElement = rng && rng.parentElement ? rng.parentElement() : null; return NodeType.isContentEditableFalse(findParent$1(parentElement, rootNode, hasCeProperty)) ? null : rng; }; var fromPoint$1 = function (clientX, clientY, doc) { var rng, point; var pointDoc = doc; if (pointDoc.caretPositionFromPoint) { point = pointDoc.caretPositionFromPoint(clientX, clientY); if (point) { rng = doc.createRange(); rng.setStart(point.offsetNode, point.offset); rng.collapse(true); } } else if (doc.caretRangeFromPoint) { rng = doc.caretRangeFromPoint(clientX, clientY); } else if (pointDoc.body.createTextRange) { rng = pointDoc.body.createTextRange(); try { rng.moveToPoint(clientX, clientY); rng.collapse(true); } catch (ex) { rng = findClosestIeRange(clientX, clientY, doc); } return moveOutOfContentEditableFalse(rng, doc.body); } return rng; }; var CaretRangeFromPoint = { fromPoint: fromPoint$1 }; var processRanges = function (editor, ranges) { return map(ranges, function (range) { var evt = editor.fire('GetSelectionRange', { range: range }); return evt.range !== range ? evt.range : range; }); }; var EventProcessRanges = { processRanges: processRanges }; var fromElements = function (elements, scope) { var doc = scope || domGlobals.document; var fragment = doc.createDocumentFragment(); each(elements, function (element) { fragment.appendChild(element.dom()); }); return Element.fromDom(fragment); }; var tableModel = Immutable('element', 'width', 'rows'); var tableRow = Immutable('element', 'cells'); var cellPosition = Immutable('x', 'y'); var getSpan = function (td, key) { var value = parseInt(get(td, key), 10); return isNaN(value) ? 1 : value; }; var fillout = function (table, x, y, tr, td) { var rowspan = getSpan(td, 'rowspan'); var colspan = getSpan(td, 'colspan'); var rows = table.rows(); for (var y2 = y; y2 < y + rowspan; y2++) { if (!rows[y2]) { rows[y2] = tableRow(deep(tr), []); } for (var x2 = x; x2 < x + colspan; x2++) { var cells = rows[y2].cells(); cells[x2] = y2 === y && x2 === x ? td : shallow(td); } } }; var cellExists = function (table, x, y) { var rows = table.rows(); var cells = rows[y] ? rows[y].cells() : []; return !!cells[x]; }; var skipCellsX = function (table, x, y) { while (cellExists(table, x, y)) { x++; } return x; }; var getWidth = function (rows) { return foldl(rows, function (acc, row) { return row.cells().length > acc ? row.cells().length : acc; }, 0); }; var findElementPos = function (table, element) { var rows = table.rows(); for (var y = 0; y < rows.length; y++) { var cells = rows[y].cells(); for (var x = 0; x < cells.length; x++) { if (eq(cells[x], element)) { return Option.some(cellPosition(x, y)); } } } return Option.none(); }; var extractRows = function (table, sx, sy, ex, ey) { var newRows = []; var rows = table.rows(); for (var y = sy; y <= ey; y++) { var cells = rows[y].cells(); var slice = sx < ex ? cells.slice(sx, ex + 1) : cells.slice(ex, sx + 1); newRows.push(tableRow(rows[y].element(), slice)); } return newRows; }; var subTable = function (table, startPos, endPos) { var sx = startPos.x(), sy = startPos.y(); var ex = endPos.x(), ey = endPos.y(); var newRows = sy < ey ? extractRows(table, sx, sy, ex, ey) : extractRows(table, sx, ey, ex, sy); return tableModel(table.element(), getWidth(newRows), newRows); }; var createDomTable = function (table, rows) { var tableElement = shallow(table.element()); var tableBody = Element.fromTag('tbody'); append$1(tableBody, rows); append(tableElement, tableBody); return tableElement; }; var modelRowsToDomRows = function (table) { return map(table.rows(), function (row) { var cells = map(row.cells(), function (cell) { var td = deep(cell); remove(td, 'colspan'); remove(td, 'rowspan'); return td; }); var tr = shallow(row.element()); append$1(tr, cells); return tr; }); }; var fromDom$1 = function (tableElm) { var table = tableModel(shallow(tableElm), 0, []); each(descendants$1(tableElm, 'tr'), function (tr, y) { each(descendants$1(tr, 'td,th'), function (td, x) { fillout(table, skipCellsX(table, x, y), y, tr, td); }); }); return tableModel(table.element(), getWidth(table.rows()), table.rows()); }; var toDom = function (table) { return createDomTable(table, modelRowsToDomRows(table)); }; var subsection = function (table, startElement, endElement) { return findElementPos(table, startElement).bind(function (startPos) { return findElementPos(table, endElement).map(function (endPos) { return subTable(table, startPos, endPos); }); }); }; var SimpleTableModel = { fromDom: fromDom$1, toDom: toDom, subsection: subsection }; var findParentListContainer = function (parents) { return find(parents, function (elm) { return name(elm) === 'ul' || name(elm) === 'ol'; }); }; var getFullySelectedListWrappers = function (parents, rng) { return find(parents, function (elm) { return name(elm) === 'li' && hasAllContentsSelected(elm, rng); }).fold(constant([]), function (li) { return findParentListContainer(parents).map(function (listCont) { return [ Element.fromTag('li'), Element.fromTag(name(listCont)) ]; }).getOr([]); }); }; var wrap$3 = function (innerElm, elms) { var wrapped = foldl(elms, function (acc, elm) { append(elm, acc); return elm; }, innerElm); return elms.length > 0 ? fromElements([wrapped]) : wrapped; }; var directListWrappers = function (commonAnchorContainer) { if (isListItem(commonAnchorContainer)) { return parent(commonAnchorContainer).filter(isList).fold(constant([]), function (listElm) { return [ commonAnchorContainer, listElm ]; }); } else { return isList(commonAnchorContainer) ? [commonAnchorContainer] : []; } }; var getWrapElements = function (rootNode, rng) { var commonAnchorContainer = Element.fromDom(rng.commonAncestorContainer); var parents = Parents.parentsAndSelf(commonAnchorContainer, rootNode); var wrapElements = filter(parents, function (elm) { return isInline(elm) || isHeading(elm); }); var listWrappers = getFullySelectedListWrappers(parents, rng); var allWrappers = wrapElements.concat(listWrappers.length ? listWrappers : directListWrappers(commonAnchorContainer)); return map(allWrappers, shallow); }; var emptyFragment = function () { return fromElements([]); }; var getFragmentFromRange = function (rootNode, rng) { return wrap$3(Element.fromDom(rng.cloneContents()), getWrapElements(rootNode, rng)); }; var getParentTable = function (rootElm, cell) { return ancestor$1(cell, 'table', curry(eq, rootElm)); }; var getTableFragment = function (rootNode, selectedTableCells) { return getParentTable(rootNode, selectedTableCells[0]).bind(function (tableElm) { var firstCell = selectedTableCells[0]; var lastCell = selectedTableCells[selectedTableCells.length - 1]; var fullTableModel = SimpleTableModel.fromDom(tableElm); return SimpleTableModel.subsection(fullTableModel, firstCell, lastCell).map(function (sectionedTableModel) { return fromElements([SimpleTableModel.toDom(sectionedTableModel)]); }); }).getOrThunk(emptyFragment); }; var getSelectionFragment = function (rootNode, ranges) { return ranges.length > 0 && ranges[0].collapsed ? emptyFragment() : getFragmentFromRange(rootNode, ranges[0]); }; var read$4 = function (rootNode, ranges) { var selectedCells = TableCellSelection.getCellsFromElementOrRanges(ranges, rootNode); return selectedCells.length > 0 ? getTableFragment(rootNode, selectedCells) : getSelectionFragment(rootNode, ranges); }; var FragmentReader = { read: read$4 }; var getTextContent = function (editor) { return Option.from(editor.selection.getRng()).map(function (rng) { var bin = editor.dom.add(editor.getBody(), 'div', { 'data-mce-bogus': 'all', 'style': 'overflow: hidden; opacity: 0;' }, rng.cloneContents()); var text = Zwsp.trim(bin.innerText); editor.dom.remove(bin); return text; }).getOr(''); }; var getHtmlContent = function (editor, args) { var rng = editor.selection.getRng(), tmpElm = editor.dom.create('body'); var sel = editor.selection.getSel(); var fragment; var ranges = EventProcessRanges.processRanges(editor, MultiRange.getRanges(sel)); fragment = args.contextual ? FragmentReader.read(Element.fromDom(editor.getBody()), ranges).dom() : rng.cloneContents(); if (fragment) { tmpElm.appendChild(fragment); } return editor.selection.serializer.serialize(tmpElm, args); }; var getContent = function (editor, args) { if (args === void 0) { args = {}; } args.get = true; args.format = args.format || 'html'; args.selection = true; args = editor.fire('BeforeGetContent', args); if (args.isDefaultPrevented()) { editor.fire('GetContent', args); return args.content; } if (args.format === 'text') { return getTextContent(editor); } else { args.getInner = true; var content = getHtmlContent(editor, args); if (args.format === 'tree') { return content; } else { args.content = editor.selection.isCollapsed() ? '' : content; editor.fire('GetContent', args); return args.content; } } }; var GetSelectionContent = { getContent: getContent }; var setContent = function (editor, content, args) { var rng = editor.selection.getRng(), caretNode; var doc = editor.getDoc(); var frag, temp; args = args || { format: 'html' }; args.set = true; args.selection = true; args.content = content; if (!args.no_events) { args = editor.fire('BeforeSetContent', args); if (args.isDefaultPrevented()) { editor.fire('SetContent', args); return; } } content = args.content; if (rng.insertNode) { content += '<span id="__caret">_</span>'; if (rng.startContainer === doc && rng.endContainer === doc) { doc.body.innerHTML = content; } else { rng.deleteContents(); if (doc.body.childNodes.length === 0) { doc.body.innerHTML = content; } else { if (rng.createContextualFragment) { rng.insertNode(rng.createContextualFragment(content)); } else { frag = doc.createDocumentFragment(); temp = doc.createElement('div'); frag.appendChild(temp); temp.outerHTML = content; rng.insertNode(frag); } } } caretNode = editor.dom.get('__caret'); rng = doc.createRange(); rng.setStartBefore(caretNode); rng.setEndBefore(caretNode); editor.selection.setRng(rng); editor.dom.remove('__caret'); try { editor.selection.setRng(rng); } catch (ex) { } } else { if (rng.item) { doc.execCommand('Delete', false, null); rng = editor.getRng(); } if (/^\s+/.test(content)) { rng.pasteHTML('<span id="__mce_tmp">_</span>' + content); editor.dom.remove('__mce_tmp'); } else { rng.pasteHTML(content); } } if (!args.no_events) { editor.fire('SetContent', args); } }; var SetSelectionContent = { setContent: setContent }; var getEndpointElement = function (root, rng, start, real, resolve) { var container = start ? rng.startContainer : rng.endContainer; var offset = start ? rng.startOffset : rng.endOffset; return Option.from(container).map(Element.fromDom).map(function (elm) { return !real || !rng.collapsed ? child(elm, resolve(elm, offset)).getOr(elm) : elm; }).bind(function (elm) { return isElement(elm) ? Option.some(elm) : parent(elm); }).map(function (elm) { return elm.dom(); }).getOr(root); }; var getStart = function (root, rng, real) { return getEndpointElement(root, rng, true, real, function (elm, offset) { return Math.min(childNodesCount(elm), offset); }); }; var getEnd = function (root, rng, real) { return getEndpointElement(root, rng, false, real, function (elm, offset) { return offset > 0 ? offset - 1 : offset; }); }; var skipEmptyTextNodes = function (node, forwards) { var orig = node; while (node && NodeType.isText(node) && node.length === 0) { node = forwards ? node.nextSibling : node.previousSibling; } return node || orig; }; var getNode$1 = function (root, rng) { var elm, startContainer, endContainer, startOffset, endOffset; if (!rng) { return root; } startContainer = rng.startContainer; endContainer = rng.endContainer; startOffset = rng.startOffset; endOffset = rng.endOffset; elm = rng.commonAncestorContainer; if (!rng.collapsed) { if (startContainer === endContainer) { if (endOffset - startOffset < 2) { if (startContainer.hasChildNodes()) { elm = startContainer.childNodes[startOffset]; } } } if (startContainer.nodeType === 3 && endContainer.nodeType === 3) { if (startContainer.length === startOffset) { startContainer = skipEmptyTextNodes(startContainer.nextSibling, true); } else { startContainer = startContainer.parentNode; } if (endOffset === 0) { endContainer = skipEmptyTextNodes(endContainer.previousSibling, false); } else { endContainer = endContainer.parentNode; } if (startContainer && startContainer === endContainer) { return startContainer; } } } if (elm && elm.nodeType === 3) { return elm.parentNode; } return elm; }; var getSelectedBlocks = function (dom, rng, startElm, endElm) { var node, root; var selectedBlocks = []; root = dom.getRoot(); startElm = dom.getParent(startElm || getStart(root, rng, rng.collapsed), dom.isBlock); endElm = dom.getParent(endElm || getEnd(root, rng, rng.collapsed), dom.isBlock); if (startElm && startElm !== root) { selectedBlocks.push(startElm); } if (startElm && endElm && startElm !== endElm) { node = startElm; var walker = new TreeWalker(startElm, root); while ((node = walker.next()) && node !== endElm) { if (dom.isBlock(node)) { selectedBlocks.push(node); } } } if (endElm && startElm !== endElm && endElm !== root) { selectedBlocks.push(endElm); } return selectedBlocks; }; var select$1 = function (dom, node, content) { return Option.from(node).map(function (node) { var idx = dom.nodeIndex(node); var rng = dom.createRng(); rng.setStart(node.parentNode, idx); rng.setEnd(node.parentNode, idx + 1); if (content) { moveEndPoint$1(dom, rng, node, true); moveEndPoint$1(dom, rng, node, false); } return rng; }); }; var each$j = Tools.each; var isNativeIeSelection = function (rng) { return !!rng.select; }; var isAttachedToDom = function (node) { return !!(node && node.ownerDocument) && contains$3(Element.fromDom(node.ownerDocument), Element.fromDom(node)); }; var isValidRange = function (rng) { if (!rng) { return false; } else if (isNativeIeSelection(rng)) { return true; } else { return isAttachedToDom(rng.startContainer) && isAttachedToDom(rng.endContainer); } }; var Selection = function (dom, win, serializer, editor) { var bookmarkManager, controlSelection; var selectedRange, explicitRange, selectorChangedData; var setCursorLocation = function (node, offset) { var rng = dom.createRng(); if (!node) { moveEndPoint$1(dom, rng, editor.getBody(), true); setRng(rng); } else { rng.setStart(node, offset); rng.setEnd(node, offset); setRng(rng); collapse(false); } }; var getContent = function (args) { return GetSelectionContent.getContent(editor, args); }; var setContent = function (content, args) { return SetSelectionContent.setContent(editor, content, args); }; var getStart$1 = function (real) { return getStart(editor.getBody(), getRng(), real); }; var getEnd$1 = function (real) { return getEnd(editor.getBody(), getRng(), real); }; var getBookmark = function (type, normalized) { return bookmarkManager.getBookmark(type, normalized); }; var moveToBookmark = function (bookmark) { return bookmarkManager.moveToBookmark(bookmark); }; var select = function (node, content) { select$1(dom, node, content).each(setRng); return node; }; var isCollapsed = function () { var rng = getRng(), sel = getSel(); if (!rng || rng.item) { return false; } if (rng.compareEndPoints) { return rng.compareEndPoints('StartToEnd', rng) === 0; } return !sel || rng.collapsed; }; var collapse = function (toStart) { var rng = getRng(); rng.collapse(!!toStart); setRng(rng); }; var getSel = function () { return win.getSelection ? win.getSelection() : win.document.selection; }; var getRng = function () { var selection, rng, elm, doc; var tryCompareBoundaryPoints = function (how, sourceRange, destinationRange) { try { return sourceRange.compareBoundaryPoints(how, destinationRange); } catch (ex) { return -1; } }; if (!win) { return null; } doc = win.document; if (typeof doc === 'undefined' || doc === null) { return null; } if (editor.bookmark !== undefined && EditorFocus.hasFocus(editor) === false) { var bookmark = SelectionBookmark.getRng(editor); if (bookmark.isSome()) { return bookmark.map(function (r) { return EventProcessRanges.processRanges(editor, [r])[0]; }).getOr(doc.createRange()); } } try { if (selection = getSel()) { if (selection.rangeCount > 0) { rng = selection.getRangeAt(0); } else { rng = selection.createRange ? selection.createRange() : doc.createRange(); } } } catch (ex) { } rng = EventProcessRanges.processRanges(editor, [rng])[0]; if (!rng) { rng = doc.createRange ? doc.createRange() : doc.body.createTextRange(); } if (rng.setStart && rng.startContainer.nodeType === 9 && rng.collapsed) { elm = dom.getRoot(); rng.setStart(elm, 0); rng.setEnd(elm, 0); } if (selectedRange && explicitRange) { if (tryCompareBoundaryPoints(rng.START_TO_START, rng, selectedRange) === 0 && tryCompareBoundaryPoints(rng.END_TO_END, rng, selectedRange) === 0) { rng = explicitRange; } else { selectedRange = null; explicitRange = null; } } return rng; }; var setRng = function (rng, forward) { var sel, node, evt; if (!isValidRange(rng)) { return; } var ieRange = isNativeIeSelection(rng) ? rng : null; if (ieRange) { explicitRange = null; try { ieRange.select(); } catch (ex) { } return; } sel = getSel(); evt = editor.fire('SetSelectionRange', { range: rng, forward: forward }); rng = evt.range; if (sel) { explicitRange = rng; try { sel.removeAllRanges(); sel.addRange(rng); } catch (ex) { } if (forward === false && sel.extend) { sel.collapse(rng.endContainer, rng.endOffset); sel.extend(rng.startContainer, rng.startOffset); } selectedRange = sel.rangeCount > 0 ? sel.getRangeAt(0) : null; } if (!rng.collapsed && rng.startContainer === rng.endContainer && sel.setBaseAndExtent && !Env.ie) { if (rng.endOffset - rng.startOffset < 2) { if (rng.startContainer.hasChildNodes()) { node = rng.startContainer.childNodes[rng.startOffset]; if (node && node.tagName === 'IMG') { sel.setBaseAndExtent(rng.startContainer, rng.startOffset, rng.endContainer, rng.endOffset); if (sel.anchorNode !== rng.startContainer || sel.focusNode !== rng.endContainer) { sel.setBaseAndExtent(node, 0, node, 1); } } } } } editor.fire('AfterSetSelectionRange', { range: rng, forward: forward }); }; var setNode = function (elm) { setContent(dom.getOuterHTML(elm)); return elm; }; var getNode = function () { return getNode$1(editor.getBody(), getRng()); }; var getSelectedBlocks$1 = function (startElm, endElm) { return getSelectedBlocks(dom, getRng(), startElm, endElm); }; var isForward = function () { var sel = getSel(); var anchorRange, focusRange; if (!sel || !sel.anchorNode || !sel.focusNode) { return true; } anchorRange = dom.createRng(); anchorRange.setStart(sel.anchorNode, sel.anchorOffset); anchorRange.collapse(true); focusRange = dom.createRng(); focusRange.setStart(sel.focusNode, sel.focusOffset); focusRange.collapse(true); return anchorRange.compareBoundaryPoints(anchorRange.START_TO_START, focusRange) <= 0; }; var normalize = function () { var rng = getRng(); var sel = getSel(); if (!MultiRange.hasMultipleRanges(sel) && hasAnyRanges(editor)) { var normRng = NormalizeRange.normalize(dom, rng); normRng.each(function (normRng) { setRng(normRng, isForward()); }); return normRng.getOr(rng); } return rng; }; var selectorChanged = function (selector, callback) { var currentSelectors; if (!selectorChangedData) { selectorChangedData = {}; currentSelectors = {}; editor.on('NodeChange', function (e) { var node = e.element, parents = dom.getParents(node, null, dom.getRoot()), matchedSelectors = {}; each$j(selectorChangedData, function (callbacks, selector) { each$j(parents, function (node) { if (dom.is(node, selector)) { if (!currentSelectors[selector]) { each$j(callbacks, function (callback) { callback(true, { node: node, selector: selector, parents: parents }); }); currentSelectors[selector] = callbacks; } matchedSelectors[selector] = callbacks; return false; } }); }); each$j(currentSelectors, function (callbacks, selector) { if (!matchedSelectors[selector]) { delete currentSelectors[selector]; each$j(callbacks, function (callback) { callback(false, { node: node, selector: selector, parents: parents }); }); } }); }); } if (!selectorChangedData[selector]) { selectorChangedData[selector] = []; } selectorChangedData[selector].push(callback); return exports; }; var getScrollContainer = function () { var scrollContainer; var node = dom.getRoot(); while (node && node.nodeName !== 'BODY') { if (node.scrollHeight > node.clientHeight) { scrollContainer = node; break; } node = node.parentNode; } return scrollContainer; }; var scrollIntoView = function (elm, alignToTop) { return ScrollIntoView.scrollElementIntoView(editor, elm, alignToTop); }; var placeCaretAt = function (clientX, clientY) { return setRng(CaretRangeFromPoint.fromPoint(clientX, clientY, editor.getDoc())); }; var getBoundingClientRect = function () { var rng = getRng(); return rng.collapsed ? CaretPosition$1.fromRangeStart(rng).getClientRects()[0] : rng.getBoundingClientRect(); }; var destroy = function () { win = selectedRange = explicitRange = null; controlSelection.destroy(); }; var exports = { bookmarkManager: null, controlSelection: null, dom: dom, win: win, serializer: serializer, editor: editor, collapse: collapse, setCursorLocation: setCursorLocation, getContent: getContent, setContent: setContent, getBookmark: getBookmark, moveToBookmark: moveToBookmark, select: select, isCollapsed: isCollapsed, isForward: isForward, setNode: setNode, getNode: getNode, getSel: getSel, setRng: setRng, getRng: getRng, getStart: getStart$1, getEnd: getEnd$1, getSelectedBlocks: getSelectedBlocks$1, normalize: normalize, selectorChanged: selectorChanged, getScrollContainer: getScrollContainer, scrollIntoView: scrollIntoView, placeCaretAt: placeCaretAt, getBoundingClientRect: getBoundingClientRect, destroy: destroy }; bookmarkManager = BookmarkManager$1(exports); controlSelection = ControlSelection(exports, editor); exports.bookmarkManager = bookmarkManager; exports.controlSelection = controlSelection; return exports; }; var BreakType; (function (BreakType) { BreakType[BreakType['Br'] = 0] = 'Br'; BreakType[BreakType['Block'] = 1] = 'Block'; BreakType[BreakType['Wrap'] = 2] = 'Wrap'; BreakType[BreakType['Eol'] = 3] = 'Eol'; }(BreakType || (BreakType = {}))); var flip = function (direction, positions) { return direction === HDirection.Backwards ? positions.reverse() : positions; }; var walk$3 = function (direction, caretWalker, pos) { return direction === HDirection.Forwards ? caretWalker.next(pos) : caretWalker.prev(pos); }; var getBreakType = function (scope, direction, currentPos, nextPos) { if (NodeType.isBr(nextPos.getNode(direction === HDirection.Forwards))) { return BreakType.Br; } else if (isInSameBlock(currentPos, nextPos) === false) { return BreakType.Block; } else { return BreakType.Wrap; } }; var getPositionsUntil = function (predicate, direction, scope, start) { var caretWalker = CaretWalker(scope); var currentPos = start, nextPos; var positions = []; while (currentPos) { nextPos = walk$3(direction, caretWalker, currentPos); if (!nextPos) { break; } if (NodeType.isBr(nextPos.getNode(false))) { if (direction === HDirection.Forwards) { return { positions: flip(direction, positions).concat([nextPos]), breakType: BreakType.Br, breakAt: Option.some(nextPos) }; } else { return { positions: flip(direction, positions), breakType: BreakType.Br, breakAt: Option.some(nextPos) }; } } if (!nextPos.isVisible()) { currentPos = nextPos; continue; } if (predicate(currentPos, nextPos)) { var breakType = getBreakType(scope, direction, currentPos, nextPos); return { positions: flip(direction, positions), breakType: breakType, breakAt: Option.some(nextPos) }; } positions.push(nextPos); currentPos = nextPos; } return { positions: flip(direction, positions), breakType: BreakType.Eol, breakAt: Option.none() }; }; var getAdjacentLinePositions = function (direction, getPositionsUntilBreak, scope, start) { return getPositionsUntilBreak(scope, start).breakAt.map(function (pos) { var positions = getPositionsUntilBreak(scope, pos).positions; return direction === HDirection.Backwards ? positions.concat(pos) : [pos].concat(positions); }).getOr([]); }; var findClosestHorizontalPositionFromPoint = function (positions, x) { return foldl(positions, function (acc, newPos) { return acc.fold(function () { return Option.some(newPos); }, function (lastPos) { return liftN([ head(lastPos.getClientRects()), head(newPos.getClientRects()) ], function (lastRect, newRect) { var lastDist = Math.abs(x - lastRect.left); var newDist = Math.abs(x - newRect.left); return newDist <= lastDist ? newPos : lastPos; }).or(acc); }); }, Option.none()); }; var findClosestHorizontalPosition = function (positions, pos) { return head(pos.getClientRects()).bind(function (targetRect) { return findClosestHorizontalPositionFromPoint(positions, targetRect.left); }); }; var getPositionsUntilPreviousLine = curry(getPositionsUntil, CaretPosition.isAbove, -1); var getPositionsUntilNextLine = curry(getPositionsUntil, CaretPosition.isBelow, 1); var isAtFirstLine = function (scope, pos) { return getPositionsUntilPreviousLine(scope, pos).breakAt.isNone(); }; var isAtLastLine = function (scope, pos) { return getPositionsUntilNextLine(scope, pos).breakAt.isNone(); }; var getPositionsAbove = curry(getAdjacentLinePositions, -1, getPositionsUntilPreviousLine); var getPositionsBelow = curry(getAdjacentLinePositions, 1, getPositionsUntilNextLine); var getFirstLinePositions = function (scope) { return CaretFinder.firstPositionIn(scope).map(function (pos) { return [pos].concat(getPositionsUntilNextLine(scope, pos).positions); }).getOr([]); }; var getLastLinePositions = function (scope) { return CaretFinder.lastPositionIn(scope).map(function (pos) { return getPositionsUntilPreviousLine(scope, pos).positions.concat(pos); }).getOr([]); }; var isContentEditableFalse$b = NodeType.isContentEditableFalse; var getSelectedNode$1 = getSelectedNode; var moveToCeFalseHorizontally = function (direction, editor, getNextPosFn, range) { var forwards = direction === HDirection.Forwards; var isBeforeContentEditableFalseFn = forwards ? isBeforeContentEditableFalse : isAfterContentEditableFalse; if (!range.collapsed) { var node = getSelectedNode$1(range); if (isContentEditableFalse$b(node)) { return showCaret(direction, editor, node, direction === HDirection.Backwards, true); } } var rangeIsInContainerBlock = isRangeInCaretContainerBlock(range); var caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range); if (isBeforeContentEditableFalseFn(caretPosition)) { return selectNode(editor, caretPosition.getNode(!forwards)); } var nextCaretPosition = InlineUtils.normalizePosition(forwards, getNextPosFn(caretPosition)); if (!nextCaretPosition) { if (rangeIsInContainerBlock) { return range; } return null; } if (isBeforeContentEditableFalseFn(nextCaretPosition)) { return showCaret(direction, editor, nextCaretPosition.getNode(!forwards), forwards, true); } var peekCaretPosition = getNextPosFn(nextCaretPosition); if (peekCaretPosition && isBeforeContentEditableFalseFn(peekCaretPosition)) { if (isMoveInsideSameBlock(nextCaretPosition, peekCaretPosition)) { return showCaret(direction, editor, peekCaretPosition.getNode(!forwards), forwards, true); } } if (rangeIsInContainerBlock) { return renderRangeCaret(editor, nextCaretPosition.toRange(), true); } return null; }; var moveToCeFalseVertically = function (direction, editor, walkerFn, range) { var caretPosition, linePositions, nextLinePositions; var closestNextLineRect, caretClientRect, clientX; var dist1, dist2, contentEditableFalseNode; contentEditableFalseNode = getSelectedNode$1(range); caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range); linePositions = walkerFn(editor.getBody(), isAboveLine(1), caretPosition); nextLinePositions = filter(linePositions, isLine(1)); caretClientRect = ArrUtils.last(caretPosition.getClientRects()); if (isBeforeContentEditableFalse(caretPosition) || isBeforeTable(caretPosition)) { contentEditableFalseNode = caretPosition.getNode(); } if (isAfterContentEditableFalse(caretPosition) || isAfterTable(caretPosition)) { contentEditableFalseNode = caretPosition.getNode(true); } if (!caretClientRect) { return null; } clientX = caretClientRect.left; closestNextLineRect = findClosestClientRect(nextLinePositions, clientX); if (closestNextLineRect) { if (isContentEditableFalse$b(closestNextLineRect.node)) { dist1 = Math.abs(clientX - closestNextLineRect.left); dist2 = Math.abs(clientX - closestNextLineRect.right); return showCaret(direction, editor, closestNextLineRect.node, dist1 < dist2, true); } } if (contentEditableFalseNode) { var caretPositions = positionsUntil(direction, editor.getBody(), isAboveLine(1), contentEditableFalseNode); closestNextLineRect = findClosestClientRect(filter(caretPositions, isLine(1)), clientX); if (closestNextLineRect) { return renderRangeCaret(editor, closestNextLineRect.position.toRange(), true); } closestNextLineRect = ArrUtils.last(filter(caretPositions, isLine(0))); if (closestNextLineRect) { return renderRangeCaret(editor, closestNextLineRect.position.toRange(), true); } } }; var createTextBlock = function (editor) { var textBlock = editor.dom.create(Settings.getForcedRootBlock(editor)); if (!Env.ie || Env.ie >= 11) { textBlock.innerHTML = '<br data-mce-bogus="1">'; } return textBlock; }; var exitPreBlock = function (editor, direction, range) { var pre, caretPos, newBlock; var caretWalker = CaretWalker(editor.getBody()); var getNextVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.next); var getPrevVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.prev); if (range.collapsed && editor.settings.forced_root_block) { pre = editor.dom.getParent(range.startContainer, 'PRE'); if (!pre) { return; } if (direction === 1) { caretPos = getNextVisualCaretPosition(CaretPosition$1.fromRangeStart(range)); } else { caretPos = getPrevVisualCaretPosition(CaretPosition$1.fromRangeStart(range)); } if (!caretPos) { newBlock = createTextBlock(editor); if (direction === 1) { editor.$(pre).after(newBlock); } else { editor.$(pre).before(newBlock); } editor.selection.select(newBlock, true); editor.selection.collapse(); } } }; var getHorizontalRange = function (editor, forward) { var caretWalker = CaretWalker(editor.getBody()); var getNextVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.next); var getPrevVisualCaretPosition = curry(getVisualCaretPosition, caretWalker.prev); var newRange; var direction = forward ? HDirection.Forwards : HDirection.Backwards; var getNextPosFn = forward ? getNextVisualCaretPosition : getPrevVisualCaretPosition; var range = editor.selection.getRng(); newRange = moveToCeFalseHorizontally(direction, editor, getNextPosFn, range); if (newRange) { return newRange; } newRange = exitPreBlock(editor, direction, range); if (newRange) { return newRange; } return null; }; var getVerticalRange = function (editor, down) { var newRange; var direction = down ? 1 : -1; var walkerFn = down ? downUntil : upUntil; var range = editor.selection.getRng(); newRange = moveToCeFalseVertically(direction, editor, walkerFn, range); if (newRange) { return newRange; } newRange = exitPreBlock(editor, direction, range); if (newRange) { return newRange; } return null; }; var moveH = function (editor, forward) { return function () { var newRng = getHorizontalRange(editor, forward); if (newRng) { editor.selection.setRng(newRng); return true; } else { return false; } }; }; var moveV = function (editor, down) { return function () { var newRng = getVerticalRange(editor, down); if (newRng) { editor.selection.setRng(newRng); return true; } else { return false; } }; }; var isCefPosition = function (forward) { return function (pos) { return forward ? isAfterContentEditableFalse(pos) : isBeforeContentEditableFalse(pos); }; }; var moveToLineEndPoint = function (editor, forward) { return function () { var from = forward ? CaretPosition$1.fromRangeEnd(editor.selection.getRng()) : CaretPosition$1.fromRangeStart(editor.selection.getRng()); var result = forward ? getPositionsUntilNextLine(editor.getBody(), from) : getPositionsUntilPreviousLine(editor.getBody(), from); var to = forward ? last(result.positions) : head(result.positions); return to.filter(isCefPosition(forward)).fold(constant(false), function (pos) { editor.selection.setRng(pos.toRange()); return true; }); }; }; var deflate = function (rect, delta) { return { left: rect.left - delta, top: rect.top - delta, right: rect.right + delta * 2, bottom: rect.bottom + delta * 2, width: rect.width + delta, height: rect.height + delta }; }; var getCorners = function (getYAxisValue, tds) { return bind(tds, function (td) { var rect = deflate(clone$1(td.getBoundingClientRect()), -1); return [ { x: rect.left, y: getYAxisValue(rect), cell: td }, { x: rect.right, y: getYAxisValue(rect), cell: td } ]; }); }; var findClosestCorner = function (corners, x, y) { return foldl(corners, function (acc, newCorner) { return acc.fold(function () { return Option.some(newCorner); }, function (oldCorner) { var oldDist = Math.sqrt(Math.abs(oldCorner.x - x) + Math.abs(oldCorner.y - y)); var newDist = Math.sqrt(Math.abs(newCorner.x - x) + Math.abs(newCorner.y - y)); return Option.some(newDist < oldDist ? newCorner : oldCorner); }); }, Option.none()); }; var getClosestCell$1 = function (getYAxisValue, isTargetCorner, table, x, y) { var cells = descendants$1(Element.fromDom(table), 'td,th,caption').map(function (e) { return e.dom(); }); var corners = filter(getCorners(getYAxisValue, cells), function (corner) { return isTargetCorner(corner, y); }); return findClosestCorner(corners, x, y).map(function (corner) { return corner.cell; }); }; var getBottomValue = function (rect) { return rect.bottom; }; var getTopValue = function (rect) { return rect.top; }; var isAbove$1 = function (corner, y) { return corner.y < y; }; var isBelow$1 = function (corner, y) { return corner.y > y; }; var getClosestCellAbove = curry(getClosestCell$1, getBottomValue, isAbove$1); var getClosestCellBelow = curry(getClosestCell$1, getTopValue, isBelow$1); var findClosestPositionInAboveCell = function (table, pos) { return head(pos.getClientRects()).bind(function (rect) { return getClosestCellAbove(table, rect.left, rect.top); }).bind(function (cell) { return findClosestHorizontalPosition(getLastLinePositions(cell), pos); }); }; var findClosestPositionInBelowCell = function (table, pos) { return last(pos.getClientRects()).bind(function (rect) { return getClosestCellBelow(table, rect.left, rect.top); }).bind(function (cell) { return findClosestHorizontalPosition(getFirstLinePositions(cell), pos); }); }; var moveToRange = function (editor, rng) { editor.selection.setRng(rng); ScrollIntoView.scrollRangeIntoView(editor, rng); }; var hasNextBreak = function (getPositionsUntil, scope, lineInfo) { return lineInfo.breakAt.map(function (breakPos) { return getPositionsUntil(scope, breakPos).breakAt.isSome(); }).getOr(false); }; var startsWithWrapBreak = function (lineInfo) { return lineInfo.breakType === BreakType.Wrap && lineInfo.positions.length === 0; }; var startsWithBrBreak = function (lineInfo) { return lineInfo.breakType === BreakType.Br && lineInfo.positions.length === 1; }; var isAtTableCellLine = function (getPositionsUntil, scope, pos) { var lineInfo = getPositionsUntil(scope, pos); if (startsWithWrapBreak(lineInfo) || !NodeType.isBr(pos.getNode()) && startsWithBrBreak(lineInfo)) { return !hasNextBreak(getPositionsUntil, scope, lineInfo); } else { return lineInfo.breakAt.isNone(); } }; var isAtFirstTableCellLine = curry(isAtTableCellLine, getPositionsUntilPreviousLine); var isAtLastTableCellLine = curry(isAtTableCellLine, getPositionsUntilNextLine); var isCaretAtStartOrEndOfTable = function (forward, rng, table) { var caretPos = CaretPosition$1.fromRangeStart(rng); return CaretFinder.positionIn(!forward, table).map(function (pos) { return pos.isEqual(caretPos); }).getOr(false); }; var navigateHorizontally = function (editor, forward, table, td) { var rng = editor.selection.getRng(); var direction = forward ? 1 : -1; if (isFakeCaretTableBrowser() && isCaretAtStartOrEndOfTable(forward, rng, table)) { var newRng = showCaret(direction, editor, table, !forward, true); moveToRange(editor, newRng); return true; } return false; }; var getClosestAbovePosition = function (root, table, start) { return findClosestPositionInAboveCell(table, start).orThunk(function () { return head(start.getClientRects()).bind(function (rect) { return findClosestHorizontalPositionFromPoint(getPositionsAbove(root, CaretPosition$1.before(table)), rect.left); }); }).getOr(CaretPosition$1.before(table)); }; var getClosestBelowPosition = function (root, table, start) { return findClosestPositionInBelowCell(table, start).orThunk(function () { return head(start.getClientRects()).bind(function (rect) { return findClosestHorizontalPositionFromPoint(getPositionsBelow(root, CaretPosition$1.after(table)), rect.left); }); }).getOr(CaretPosition$1.after(table)); }; var getTable = function (previous, pos) { var node = pos.getNode(previous); return NodeType.isElement(node) && node.nodeName === 'TABLE' ? Option.some(node) : Option.none(); }; var renderBlock = function (down, editor, table, pos) { var forcedRootBlock = Settings.getForcedRootBlock(editor); if (forcedRootBlock) { editor.undoManager.transact(function () { var element = Element.fromTag(forcedRootBlock); setAll(element, Settings.getForcedRootBlockAttrs(editor)); append(element, Element.fromTag('br')); if (down) { after(Element.fromDom(table), element); } else { before(Element.fromDom(table), element); } var rng = editor.dom.createRng(); rng.setStart(element.dom(), 0); rng.setEnd(element.dom(), 0); moveToRange(editor, rng); }); } else { moveToRange(editor, pos.toRange()); } }; var moveCaret = function (editor, down, pos) { var table = down ? getTable(true, pos) : getTable(false, pos); var last = down === false; table.fold(function () { return moveToRange(editor, pos.toRange()); }, function (table) { return CaretFinder.positionIn(last, editor.getBody()).filter(function (lastPos) { return lastPos.isEqual(pos); }).fold(function () { return moveToRange(editor, pos.toRange()); }, function (_) { return renderBlock(down, editor, table, pos); }); }); }; var navigateVertically = function (editor, down, table, td) { var rng = editor.selection.getRng(); var pos = CaretPosition$1.fromRangeStart(rng); var root = editor.getBody(); if (!down && isAtFirstTableCellLine(td, pos)) { var newPos = getClosestAbovePosition(root, table, pos); moveCaret(editor, down, newPos); return true; } else if (down && isAtLastTableCellLine(td, pos)) { var newPos = getClosestBelowPosition(root, table, pos); moveCaret(editor, down, newPos); return true; } else { return false; } }; var moveH$1 = function (editor, forward) { return function () { return Option.from(editor.dom.getParent(editor.selection.getNode(), 'td,th')).bind(function (td) { return Option.from(editor.dom.getParent(td, 'table')).map(function (table) { return navigateHorizontally(editor, forward, table, td); }); }).getOr(false); }; }; var moveV$1 = function (editor, forward) { return function () { return Option.from(editor.dom.getParent(editor.selection.getNode(), 'td,th')).bind(function (td) { return Option.from(editor.dom.getParent(td, 'table')).map(function (table) { return navigateVertically(editor, forward, table, td); }); }).getOr(false); }; }; var isTarget = function (node) { return contains(['figcaption'], name(node)); }; var rangeBefore = function (target) { var rng = domGlobals.document.createRange(); rng.setStartBefore(target.dom()); rng.setEndBefore(target.dom()); return rng; }; var insertElement = function (root, elm, forward) { if (forward) { append(root, elm); } else { prepend(root, elm); } }; var insertBr = function (root, forward) { var br = Element.fromTag('br'); insertElement(root, br, forward); return rangeBefore(br); }; var insertBlock$1 = function (root, forward, blockName, attrs) { var block = Element.fromTag(blockName); var br = Element.fromTag('br'); setAll(block, attrs); append(block, br); insertElement(root, block, forward); return rangeBefore(br); }; var insertEmptyLine = function (root, rootBlockName, attrs, forward) { if (rootBlockName === '') { return insertBr(root, forward); } else { return insertBlock$1(root, forward, rootBlockName, attrs); } }; var getClosestTargetBlock = function (pos, root) { var isRoot = curry(eq, root); return closest(Element.fromDom(pos.container()), isBlock, isRoot).filter(isTarget); }; var isAtFirstOrLastLine = function (root, forward, pos) { return forward ? isAtLastLine(root.dom(), pos) : isAtFirstLine(root.dom(), pos); }; var moveCaretToNewEmptyLine = function (editor, forward) { var root = Element.fromDom(editor.getBody()); var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng()); var rootBlock = Settings.getForcedRootBlock(editor); var rootBlockAttrs = Settings.getForcedRootBlockAttrs(editor); return getClosestTargetBlock(pos, root).exists(function () { if (isAtFirstOrLastLine(root, forward, pos)) { var rng = insertEmptyLine(root, rootBlock, rootBlockAttrs, forward); editor.selection.setRng(rng); return true; } else { return false; } }); }; var moveV$2 = function (editor, forward) { return function () { if (editor.selection.isCollapsed()) { return moveCaretToNewEmptyLine(editor, forward); } else { return false; } }; }; var defaultPatterns = function (patterns) { return map(patterns, function (pattern) { return merge({ shiftKey: false, altKey: false, ctrlKey: false, metaKey: false, keyCode: 0, action: noop }, pattern); }); }; var matchesEvent = function (pattern, evt) { return evt.keyCode === pattern.keyCode && evt.shiftKey === pattern.shiftKey && evt.altKey === pattern.altKey && evt.ctrlKey === pattern.ctrlKey && evt.metaKey === pattern.metaKey; }; var match$1 = function (patterns, evt) { return bind(defaultPatterns(patterns), function (pattern) { return matchesEvent(pattern, evt) ? [pattern] : []; }); }; var action = function (f) { var x = []; for (var _i = 1; _i < arguments.length; _i++) { x[_i - 1] = arguments[_i]; } var args = Array.prototype.slice.call(arguments, 1); return function () { return f.apply(null, args); }; }; var execute = function (patterns, evt) { return find(match$1(patterns, evt), function (pattern) { return pattern.action(); }); }; var MatchKeys = { match: match$1, action: action, execute: execute }; var executeKeydownOverride = function (editor, caret, evt) { var os = PlatformDetection$1.detect().os; MatchKeys.execute([ { keyCode: VK.RIGHT, action: moveH(editor, true) }, { keyCode: VK.LEFT, action: moveH(editor, false) }, { keyCode: VK.UP, action: moveV(editor, false) }, { keyCode: VK.DOWN, action: moveV(editor, true) }, { keyCode: VK.RIGHT, action: moveH$1(editor, true) }, { keyCode: VK.LEFT, action: moveH$1(editor, false) }, { keyCode: VK.UP, action: moveV$1(editor, false) }, { keyCode: VK.DOWN, action: moveV$1(editor, true) }, { keyCode: VK.RIGHT, action: BoundarySelection.move(editor, caret, true) }, { keyCode: VK.LEFT, action: BoundarySelection.move(editor, caret, false) }, { keyCode: VK.RIGHT, ctrlKey: !os.isOSX(), altKey: os.isOSX(), action: BoundarySelection.moveNextWord(editor, caret) }, { keyCode: VK.LEFT, ctrlKey: !os.isOSX(), altKey: os.isOSX(), action: BoundarySelection.movePrevWord(editor, caret) }, { keyCode: VK.UP, action: moveV$2(editor, false) }, { keyCode: VK.DOWN, action: moveV$2(editor, true) } ], evt).each(function (_) { evt.preventDefault(); }); }; var setup$7 = function (editor, caret) { editor.on('keydown', function (evt) { if (evt.isDefaultPrevented() === false) { executeKeydownOverride(editor, caret, evt); } }); }; var ArrowKeys = { setup: setup$7 }; var executeKeydownOverride$1 = function (editor, caret, evt) { MatchKeys.execute([ { keyCode: VK.BACKSPACE, action: MatchKeys.action(CefDelete.backspaceDelete, editor, false) }, { keyCode: VK.DELETE, action: MatchKeys.action(CefDelete.backspaceDelete, editor, true) }, { keyCode: VK.BACKSPACE, action: MatchKeys.action(CefBoundaryDelete.backspaceDelete, editor, false) }, { keyCode: VK.DELETE, action: MatchKeys.action(CefBoundaryDelete.backspaceDelete, editor, true) }, { keyCode: VK.BACKSPACE, action: MatchKeys.action(InlineBoundaryDelete.backspaceDelete, editor, caret, false) }, { keyCode: VK.DELETE, action: MatchKeys.action(InlineBoundaryDelete.backspaceDelete, editor, caret, true) }, { keyCode: VK.BACKSPACE, action: MatchKeys.action(TableDelete.backspaceDelete, editor, false) }, { keyCode: VK.DELETE, action: MatchKeys.action(TableDelete.backspaceDelete, editor, true) }, { keyCode: VK.BACKSPACE, action: MatchKeys.action(BlockRangeDelete.backspaceDelete, editor, false) }, { keyCode: VK.DELETE, action: MatchKeys.action(BlockRangeDelete.backspaceDelete, editor, true) }, { keyCode: VK.BACKSPACE, action: MatchKeys.action(BlockBoundaryDelete.backspaceDelete, editor, false) }, { keyCode: VK.DELETE, action: MatchKeys.action(BlockBoundaryDelete.backspaceDelete, editor, true) }, { keyCode: VK.BACKSPACE, action: MatchKeys.action(InlineFormatDelete.backspaceDelete, editor, false) }, { keyCode: VK.DELETE, action: MatchKeys.action(InlineFormatDelete.backspaceDelete, editor, true) } ], evt).each(function (_) { evt.preventDefault(); }); }; var executeKeyupOverride = function (editor, evt) { MatchKeys.execute([ { keyCode: VK.BACKSPACE, action: MatchKeys.action(CefDelete.paddEmptyElement, editor) }, { keyCode: VK.DELETE, action: MatchKeys.action(CefDelete.paddEmptyElement, editor) } ], evt); }; var setup$8 = function (editor, caret) { editor.on('keydown', function (evt) { if (evt.isDefaultPrevented() === false) { executeKeydownOverride$1(editor, caret, evt); } }); editor.on('keyup', function (evt) { if (evt.isDefaultPrevented() === false) { executeKeyupOverride(editor, evt); } }); }; var DeleteBackspaceKeys = { setup: setup$8 }; var firstNonWhiteSpaceNodeSibling = function (node) { while (node) { if (node.nodeType === 1 || node.nodeType === 3 && node.data && /[\r\n\s]/.test(node.data)) { return node; } node = node.nextSibling; } }; var moveToCaretPosition = function (editor, root) { var walker, node, rng, lastNode = root, tempElm; var dom = editor.dom; var moveCaretBeforeOnEnterElementsMap = editor.schema.getMoveCaretBeforeOnEnterElements(); if (!root) { return; } if (/^(LI|DT|DD)$/.test(root.nodeName)) { var firstChild = firstNonWhiteSpaceNodeSibling(root.firstChild); if (firstChild && /^(UL|OL|DL)$/.test(firstChild.nodeName)) { root.insertBefore(dom.doc.createTextNode('\xA0'), root.firstChild); } } rng = dom.createRng(); root.normalize(); if (root.hasChildNodes()) { walker = new TreeWalker(root, root); while (node = walker.current()) { if (NodeType.isText(node)) { rng.setStart(node, 0); rng.setEnd(node, 0); break; } if (moveCaretBeforeOnEnterElementsMap[node.nodeName.toLowerCase()]) { rng.setStartBefore(node); rng.setEndBefore(node); break; } lastNode = node; node = walker.next(); } if (!node) { rng.setStart(lastNode, 0); rng.setEnd(lastNode, 0); } } else { if (NodeType.isBr(root)) { if (root.nextSibling && dom.isBlock(root.nextSibling)) { rng.setStartBefore(root); rng.setEndBefore(root); } else { rng.setStartAfter(root); rng.setEndAfter(root); } } else { rng.setStart(root, 0); rng.setEnd(root, 0); } } editor.selection.setRng(rng); dom.remove(tempElm); editor.selection.scrollIntoView(root); }; var getEditableRoot = function (dom, node) { var root = dom.getRoot(); var parent, editableRoot; parent = node; while (parent !== root && dom.getContentEditable(parent) !== 'false') { if (dom.getContentEditable(parent) === 'true') { editableRoot = parent; } parent = parent.parentNode; } return parent !== root ? editableRoot : root; }; var getParentBlock$2 = function (editor) { return Option.from(editor.dom.getParent(editor.selection.getStart(true), editor.dom.isBlock)); }; var getParentBlockName = function (editor) { return getParentBlock$2(editor).fold(constant(''), function (parentBlock) { return parentBlock.nodeName.toUpperCase(); }); }; var isListItemParentBlock = function (editor) { return getParentBlock$2(editor).filter(function (elm) { return isListItem(Element.fromDom(elm)); }).isSome(); }; var NewLineUtils = { moveToCaretPosition: moveToCaretPosition, getEditableRoot: getEditableRoot, getParentBlock: getParentBlock$2, getParentBlockName: getParentBlockName, isListItemParentBlock: isListItemParentBlock }; var hasFirstChild = function (elm, name) { return elm.firstChild && elm.firstChild.nodeName === name; }; var hasParent$1 = function (elm, parentName) { return elm && elm.parentNode && elm.parentNode.nodeName === parentName; }; var isListBlock = function (elm) { return elm && /^(OL|UL|LI)$/.test(elm.nodeName); }; var isNestedList = function (elm) { return isListBlock(elm) && isListBlock(elm.parentNode); }; var getContainerBlock = function (containerBlock) { var containerBlockParent = containerBlock.parentNode; if (/^(LI|DT|DD)$/.test(containerBlockParent.nodeName)) { return containerBlockParent; } return containerBlock; }; var isFirstOrLastLi = function (containerBlock, parentBlock, first) { var node = containerBlock[first ? 'firstChild' : 'lastChild']; while (node) { if (NodeType.isElement(node)) { break; } node = node[first ? 'nextSibling' : 'previousSibling']; } return node === parentBlock; }; var insert$1 = function (editor, createNewBlock, containerBlock, parentBlock, newBlockName) { var dom = editor.dom; var rng = editor.selection.getRng(); if (containerBlock === editor.getBody()) { return; } if (isNestedList(containerBlock)) { newBlockName = 'LI'; } var newBlock = newBlockName ? createNewBlock(newBlockName) : dom.create('BR'); if (isFirstOrLastLi(containerBlock, parentBlock, true) && isFirstOrLastLi(containerBlock, parentBlock, false)) { if (hasParent$1(containerBlock, 'LI')) { dom.insertAfter(newBlock, getContainerBlock(containerBlock)); } else { dom.replace(newBlock, containerBlock); } } else if (isFirstOrLastLi(containerBlock, parentBlock, true)) { if (hasParent$1(containerBlock, 'LI')) { dom.insertAfter(newBlock, getContainerBlock(containerBlock)); newBlock.appendChild(dom.doc.createTextNode(' ')); newBlock.appendChild(containerBlock); } else { containerBlock.parentNode.insertBefore(newBlock, containerBlock); } } else if (isFirstOrLastLi(containerBlock, parentBlock, false)) { dom.insertAfter(newBlock, getContainerBlock(containerBlock)); } else { containerBlock = getContainerBlock(containerBlock); var tmpRng = rng.cloneRange(); tmpRng.setStartAfter(parentBlock); tmpRng.setEndAfter(containerBlock); var fragment = tmpRng.extractContents(); if (newBlockName === 'LI' && hasFirstChild(fragment, 'LI')) { newBlock = fragment.firstChild; dom.insertAfter(fragment, containerBlock); } else { dom.insertAfter(fragment, containerBlock); dom.insertAfter(newBlock, containerBlock); } } dom.remove(parentBlock); NewLineUtils.moveToCaretPosition(editor, newBlock); }; var InsertLi = { insert: insert$1 }; var trimZwsp = function (fragment) { each(descendants(Element.fromDom(fragment), isText), function (text) { var rawNode = text.dom(); rawNode.nodeValue = Zwsp.trim(rawNode.nodeValue); }); }; var isEmptyAnchor = function (dom, elm) { return elm && elm.nodeName === 'A' && dom.isEmpty(elm); }; var isTableCell$5 = function (node) { return node && /^(TD|TH|CAPTION)$/.test(node.nodeName); }; var emptyBlock = function (elm) { elm.innerHTML = '<br data-mce-bogus="1">'; }; var containerAndSiblingName = function (container, nodeName) { return container.nodeName === nodeName || container.previousSibling && container.previousSibling.nodeName === nodeName; }; var canSplitBlock = function (dom, node) { return node && dom.isBlock(node) && !/^(TD|TH|CAPTION|FORM)$/.test(node.nodeName) && !/^(fixed|absolute)/i.test(node.style.position) && dom.getContentEditable(node) !== 'true'; }; var trimInlineElementsOnLeftSideOfBlock = function (dom, nonEmptyElementsMap, block) { var node = block; var firstChilds = []; var i; if (!node) { return; } while (node = node.firstChild) { if (dom.isBlock(node)) { return; } if (NodeType.isElement(node) && !nonEmptyElementsMap[node.nodeName.toLowerCase()]) { firstChilds.push(node); } } i = firstChilds.length; while (i--) { node = firstChilds[i]; if (!node.hasChildNodes() || node.firstChild === node.lastChild && node.firstChild.nodeValue === '') { dom.remove(node); } else { if (isEmptyAnchor(dom, node)) { dom.remove(node); } } } }; var normalizeZwspOffset = function (start, container, offset) { if (NodeType.isText(container) === false) { return offset; } else if (start) { return offset === 1 && container.data.charAt(offset - 1) === Zwsp.ZWSP ? 0 : offset; } else { return offset === container.data.length - 1 && container.data.charAt(offset) === Zwsp.ZWSP ? container.data.length : offset; } }; var includeZwspInRange = function (rng) { var newRng = rng.cloneRange(); newRng.setStart(rng.startContainer, normalizeZwspOffset(true, rng.startContainer, rng.startOffset)); newRng.setEnd(rng.endContainer, normalizeZwspOffset(false, rng.endContainer, rng.endOffset)); return newRng; }; var trimLeadingLineBreaks = function (node) { do { if (NodeType.isText(node)) { node.nodeValue = node.nodeValue.replace(/^[\r\n]+/, ''); } node = node.firstChild; } while (node); }; var getEditableRoot$1 = function (dom, node) { var root = dom.getRoot(); var parent, editableRoot; parent = node; while (parent !== root && dom.getContentEditable(parent) !== 'false') { if (dom.getContentEditable(parent) === 'true') { editableRoot = parent; } parent = parent.parentNode; } return parent !== root ? editableRoot : root; }; var setForcedBlockAttrs = function (editor, node) { var forcedRootBlockName = Settings.getForcedRootBlock(editor); if (forcedRootBlockName && forcedRootBlockName.toLowerCase() === node.tagName.toLowerCase()) { editor.dom.setAttribs(node, Settings.getForcedRootBlockAttrs(editor)); } }; var wrapSelfAndSiblingsInDefaultBlock = function (editor, newBlockName, rng, container, offset) { var newBlock, parentBlock, startNode, node, next, rootBlockName; var blockName = newBlockName || 'P'; var dom = editor.dom, editableRoot = getEditableRoot$1(dom, container); parentBlock = dom.getParent(container, dom.isBlock); if (!parentBlock || !canSplitBlock(dom, parentBlock)) { parentBlock = parentBlock || editableRoot; if (parentBlock === editor.getBody() || isTableCell$5(parentBlock)) { rootBlockName = parentBlock.nodeName.toLowerCase(); } else { rootBlockName = parentBlock.parentNode.nodeName.toLowerCase(); } if (!parentBlock.hasChildNodes()) { newBlock = dom.create(blockName); setForcedBlockAttrs(editor, newBlock); parentBlock.appendChild(newBlock); rng.setStart(newBlock, 0); rng.setEnd(newBlock, 0); return newBlock; } node = container; while (node.parentNode !== parentBlock) { node = node.parentNode; } while (node && !dom.isBlock(node)) { startNode = node; node = node.previousSibling; } if (startNode && editor.schema.isValidChild(rootBlockName, blockName.toLowerCase())) { newBlock = dom.create(blockName); setForcedBlockAttrs(editor, newBlock); startNode.parentNode.insertBefore(newBlock, startNode); node = startNode; while (node && !dom.isBlock(node)) { next = node.nextSibling; newBlock.appendChild(node); node = next; } rng.setStart(container, offset); rng.setEnd(container, offset); } } return container; }; var addBrToBlockIfNeeded = function (dom, block) { var lastChild; block.normalize(); lastChild = block.lastChild; if (!lastChild || /^(left|right)$/gi.test(dom.getStyle(lastChild, 'float', true))) { dom.add(block, 'br'); } }; var insert$2 = function (editor, evt) { var tmpRng, editableRoot, container, offset, parentBlock, shiftKey; var newBlock, fragment, containerBlock, parentBlockName, containerBlockName, newBlockName, isAfterLastNodeInContainer; var dom = editor.dom; var schema = editor.schema, nonEmptyElementsMap = schema.getNonEmptyElements(); var rng = editor.selection.getRng(); var createNewBlock = function (name) { var node = container, block, clonedNode, caretNode; var textInlineElements = schema.getTextInlineElements(); if (name || parentBlockName === 'TABLE' || parentBlockName === 'HR') { block = dom.create(name || newBlockName); setForcedBlockAttrs(editor, block); } else { block = parentBlock.cloneNode(false); } caretNode = block; if (Settings.shouldKeepStyles(editor) === false) { dom.setAttrib(block, 'style', null); dom.setAttrib(block, 'class', null); } else { do { if (textInlineElements[node.nodeName]) { if (isCaretNode(node) || Bookmarks.isBookmarkNode(node)) { continue; } clonedNode = node.cloneNode(false); dom.setAttrib(clonedNode, 'id', ''); if (block.hasChildNodes()) { clonedNode.appendChild(block.firstChild); block.appendChild(clonedNode); } else { caretNode = clonedNode; block.appendChild(clonedNode); } } } while ((node = node.parentNode) && node !== editableRoot); } emptyBlock(caretNode); return block; }; var isCaretAtStartOrEndOfBlock = function (start) { var walker, node, name, normalizedOffset; normalizedOffset = normalizeZwspOffset(start, container, offset); if (NodeType.isText(container) && (start ? normalizedOffset > 0 : normalizedOffset < container.nodeValue.length)) { return false; } if (container.parentNode === parentBlock && isAfterLastNodeInContainer && !start) { return true; } if (start && NodeType.isElement(container) && container === parentBlock.firstChild) { return true; } if (containerAndSiblingName(container, 'TABLE') || containerAndSiblingName(container, 'HR')) { return isAfterLastNodeInContainer && !start || !isAfterLastNodeInContainer && start; } walker = new TreeWalker(container, parentBlock); if (NodeType.isText(container)) { if (start && normalizedOffset === 0) { walker.prev(); } else if (!start && normalizedOffset === container.nodeValue.length) { walker.next(); } } while (node = walker.current()) { if (NodeType.isElement(node)) { if (!node.getAttribute('data-mce-bogus')) { name = node.nodeName.toLowerCase(); if (nonEmptyElementsMap[name] && name !== 'br') { return false; } } } else if (NodeType.isText(node) && !/^[ \t\r\n]*$/.test(node.nodeValue)) { return false; } if (start) { walker.prev(); } else { walker.next(); } } return true; }; var insertNewBlockAfter = function () { if (/^(H[1-6]|PRE|FIGURE)$/.test(parentBlockName) && containerBlockName !== 'HGROUP') { newBlock = createNewBlock(newBlockName); } else { newBlock = createNewBlock(); } if (Settings.shouldEndContainerOnEmptyBlock(editor) && canSplitBlock(dom, containerBlock) && dom.isEmpty(parentBlock)) { newBlock = dom.split(containerBlock, parentBlock); } else { dom.insertAfter(newBlock, parentBlock); } NewLineUtils.moveToCaretPosition(editor, newBlock); }; NormalizeRange.normalize(dom, rng).each(function (normRng) { rng.setStart(normRng.startContainer, normRng.startOffset); rng.setEnd(normRng.endContainer, normRng.endOffset); }); container = rng.startContainer; offset = rng.startOffset; newBlockName = Settings.getForcedRootBlock(editor); shiftKey = evt.shiftKey; if (NodeType.isElement(container) && container.hasChildNodes()) { isAfterLastNodeInContainer = offset > container.childNodes.length - 1; container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container; if (isAfterLastNodeInContainer && NodeType.isText(container)) { offset = container.nodeValue.length; } else { offset = 0; } } editableRoot = getEditableRoot$1(dom, container); if (!editableRoot) { return; } if (newBlockName && !shiftKey || !newBlockName && shiftKey) { container = wrapSelfAndSiblingsInDefaultBlock(editor, newBlockName, rng, container, offset); } parentBlock = dom.getParent(container, dom.isBlock); containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null; parentBlockName = parentBlock ? parentBlock.nodeName.toUpperCase() : ''; containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : ''; if (containerBlockName === 'LI' && !evt.ctrlKey) { parentBlock = containerBlock; containerBlock = containerBlock.parentNode; parentBlockName = containerBlockName; } if (/^(LI|DT|DD)$/.test(parentBlockName)) { if (dom.isEmpty(parentBlock)) { InsertLi.insert(editor, createNewBlock, containerBlock, parentBlock, newBlockName); return; } } if (newBlockName && parentBlock === editor.getBody()) { return; } newBlockName = newBlockName || 'P'; if (isCaretContainerBlock(parentBlock)) { newBlock = showCaretContainerBlock(parentBlock); if (dom.isEmpty(parentBlock)) { emptyBlock(parentBlock); } NewLineUtils.moveToCaretPosition(editor, newBlock); } else if (isCaretAtStartOrEndOfBlock()) { insertNewBlockAfter(); } else if (isCaretAtStartOrEndOfBlock(true)) { newBlock = parentBlock.parentNode.insertBefore(createNewBlock(), parentBlock); NewLineUtils.moveToCaretPosition(editor, containerAndSiblingName(parentBlock, 'HR') ? newBlock : parentBlock); } else { tmpRng = includeZwspInRange(rng).cloneRange(); tmpRng.setEndAfter(parentBlock); fragment = tmpRng.extractContents(); trimZwsp(fragment); trimLeadingLineBreaks(fragment); newBlock = fragment.firstChild; dom.insertAfter(fragment, parentBlock); trimInlineElementsOnLeftSideOfBlock(dom, nonEmptyElementsMap, newBlock); addBrToBlockIfNeeded(dom, parentBlock); if (dom.isEmpty(parentBlock)) { emptyBlock(parentBlock); } newBlock.normalize(); if (dom.isEmpty(newBlock)) { dom.remove(newBlock); insertNewBlockAfter(); } else { NewLineUtils.moveToCaretPosition(editor, newBlock); } } dom.setAttrib(newBlock, 'id', ''); editor.fire('NewBlock', { newBlock: newBlock }); }; var InsertBlock = { insert: insert$2 }; var matchesSelector = function (editor, selector) { return NewLineUtils.getParentBlock(editor).filter(function (parentBlock) { return selector.length > 0 && is$1(Element.fromDom(parentBlock), selector); }).isSome(); }; var shouldInsertBr = function (editor) { return matchesSelector(editor, Settings.getBrNewLineSelector(editor)); }; var shouldBlockNewLine = function (editor) { return matchesSelector(editor, Settings.getNoNewLineSelector(editor)); }; var ContextSelectors = { shouldInsertBr: shouldInsertBr, shouldBlockNewLine: shouldBlockNewLine }; var newLineAction = Adt.generate([ { br: [] }, { block: [] }, { none: [] } ]); var shouldBlockNewLine$1 = function (editor, shiftKey) { return ContextSelectors.shouldBlockNewLine(editor); }; var isBrMode = function (requiredState) { return function (editor, shiftKey) { var brMode = Settings.getForcedRootBlock(editor) === ''; return brMode === requiredState; }; }; var inListBlock = function (requiredState) { return function (editor, shiftKey) { return NewLineUtils.isListItemParentBlock(editor) === requiredState; }; }; var inBlock = function (blockName, requiredState) { return function (editor, shiftKey) { var state = NewLineUtils.getParentBlockName(editor) === blockName.toUpperCase(); return state === requiredState; }; }; var inPreBlock = function (requiredState) { return inBlock('pre', requiredState); }; var inSummaryBlock = function () { return inBlock('summary', true); }; var shouldPutBrInPre$1 = function (requiredState) { return function (editor, shiftKey) { return Settings.shouldPutBrInPre(editor) === requiredState; }; }; var inBrContext = function (editor, shiftKey) { return ContextSelectors.shouldInsertBr(editor); }; var hasShiftKey = function (editor, shiftKey) { return shiftKey; }; var canInsertIntoEditableRoot = function (editor) { var forcedRootBlock = Settings.getForcedRootBlock(editor); var rootEditable = NewLineUtils.getEditableRoot(editor.dom, editor.selection.getStart()); return rootEditable && editor.schema.isValidChild(rootEditable.nodeName, forcedRootBlock ? forcedRootBlock : 'P'); }; var match$2 = function (predicates, action) { return function (editor, shiftKey) { var isMatch = foldl(predicates, function (res, p) { return res && p(editor, shiftKey); }, true); return isMatch ? Option.some(action) : Option.none(); }; }; var getAction$1 = function (editor, evt) { return LazyEvaluator.evaluateUntil([ match$2([shouldBlockNewLine$1], newLineAction.none()), match$2([inSummaryBlock()], newLineAction.br()), match$2([ inPreBlock(true), shouldPutBrInPre$1(false), hasShiftKey ], newLineAction.br()), match$2([ inPreBlock(true), shouldPutBrInPre$1(false) ], newLineAction.block()), match$2([ inPreBlock(true), shouldPutBrInPre$1(true), hasShiftKey ], newLineAction.block()), match$2([ inPreBlock(true), shouldPutBrInPre$1(true) ], newLineAction.br()), match$2([ inListBlock(true), hasShiftKey ], newLineAction.br()), match$2([inListBlock(true)], newLineAction.block()), match$2([ isBrMode(true), hasShiftKey, canInsertIntoEditableRoot ], newLineAction.block()), match$2([isBrMode(true)], newLineAction.br()), match$2([inBrContext], newLineAction.br()), match$2([ isBrMode(false), hasShiftKey ], newLineAction.br()), match$2([canInsertIntoEditableRoot], newLineAction.block()) ], [ editor, evt.shiftKey ]).getOr(newLineAction.none()); }; var NewLineAction = { getAction: getAction$1 }; var insert$3 = function (editor, evt) { NewLineAction.getAction(editor, evt).fold(function () { InsertBr.insert(editor, evt); }, function () { InsertBlock.insert(editor, evt); }, noop); }; var InsertNewLine = { insert: insert$3 }; var endTypingLevel = function (undoManager) { if (undoManager.typing) { undoManager.typing = false; undoManager.add(); } }; var handleEnterKeyEvent = function (editor, event) { if (event.isDefaultPrevented()) { return; } event.preventDefault(); endTypingLevel(editor.undoManager); editor.undoManager.transact(function () { if (editor.selection.isCollapsed() === false) { editor.execCommand('Delete'); } InsertNewLine.insert(editor, event); }); }; var setup$9 = function (editor) { editor.on('keydown', function (event) { if (event.keyCode === VK.ENTER) { handleEnterKeyEvent(editor, event); } }); }; var EnterKey = { setup: setup$9 }; var insertTextAtPosition = function (text, pos) { var container = pos.container(); var offset = pos.offset(); if (NodeType.isText(container)) { container.insertData(offset, text); return Option.some(CaretPosition(container, offset + text.length)); } else { return getElementFromPosition(pos).map(function (elm) { var textNode = Element.fromText(text); if (pos.isAtEnd()) { after(elm, textNode); } else { before(elm, textNode); } return CaretPosition(textNode.dom(), text.length); }); } }; var insertNbspAtPosition = curry(insertTextAtPosition, '\xA0'); var insertSpaceAtPosition = curry(insertTextAtPosition, ' '); var navigateIgnoreEmptyTextNodes = function (forward, root, from) { return CaretFinder.navigateIgnore(forward, root, from, isEmptyText); }; var isAtBlockBoundary = function (forward, root, pos) { var parentBlocks = filter(Parents.parentsAndSelf(Element.fromDom(pos.container()), root), isBlock); return head(parentBlocks).fold(function () { return navigateIgnoreEmptyTextNodes(forward, root.dom(), pos).forall(function (newPos) { return isInSameBlock(newPos, pos, root.dom()) === false; }); }, function (parent) { return navigateIgnoreEmptyTextNodes(forward, parent.dom(), pos).isNone(); }); }; var isAtStartOfBlock = curry(isAtBlockBoundary, false); var isAtEndOfBlock = curry(isAtBlockBoundary, true); var nbsp = '\xA0'; var isInMiddleOfText = function (pos) { return CaretPosition.isTextPosition(pos) && !pos.isAtStart() && !pos.isAtEnd(); }; var getClosestBlock = function (root, pos) { var parentBlocks = filter(Parents.parentsAndSelf(Element.fromDom(pos.container()), root), isBlock); return head(parentBlocks).getOr(root); }; var hasSpaceBefore = function (root, pos) { if (isInMiddleOfText(pos)) { return isAfterSpace(pos); } else { return isAfterSpace(pos) || CaretFinder.prevPosition(getClosestBlock(root, pos).dom(), pos).exists(isAfterSpace); } }; var hasSpaceAfter = function (root, pos) { if (isInMiddleOfText(pos)) { return isBeforeSpace(pos); } else { return isBeforeSpace(pos) || CaretFinder.nextPosition(getClosestBlock(root, pos).dom(), pos).exists(isBeforeSpace); } }; var isPreValue = function (value) { return contains([ 'pre', 'pre-line', 'pre-wrap' ], value); }; var isInPre = function (pos) { return getElementFromPosition(pos).bind(function (elm) { return closest(elm, isElement); }).exists(function (elm) { return isPreValue(get$1(elm, 'white-space')); }); }; var isAtBeginningOfBody = function (root, pos) { return CaretFinder.prevPosition(root.dom(), pos).isNone(); }; var isAtEndOfBody = function (root, pos) { return CaretFinder.nextPosition(root.dom(), pos).isNone(); }; var isAtLineBoundary = function (root, pos) { return isAtBeginningOfBody(root, pos) || isAtEndOfBody(root, pos) || isAtStartOfBlock(root, pos) || isAtEndOfBlock(root, pos) || isAfterBr(root, pos) || isBeforeBr(root, pos); }; var needsToHaveNbsp = function (root, pos) { if (isInPre(pos)) { return false; } else { return isAtLineBoundary(root, pos) || hasSpaceBefore(root, pos) || hasSpaceAfter(root, pos); } }; var needsToBeNbspLeft = function (root, pos) { if (isInPre(pos)) { return false; } else { return isAtStartOfBlock(root, pos) || isAfterBr(root, pos) || hasSpaceBefore(root, pos); } }; var leanRight = function (pos) { var container = pos.container(); var offset = pos.offset(); if (NodeType.isText(container) && offset < container.data.length) { return CaretPosition(container, offset + 1); } else { return pos; } }; var needsToBeNbspRight = function (root, pos) { var afterPos = leanRight(pos); if (isInPre(afterPos)) { return false; } else { return isAtEndOfBlock(root, afterPos) || isBeforeBr(root, afterPos) || hasSpaceAfter(root, afterPos); } }; var needsToBeNbsp = function (root, pos) { return needsToBeNbspLeft(root, pos) || needsToBeNbspRight(root, pos); }; var isNbspAt = function (text, offset) { return isNbsp(text.charAt(offset)); }; var hasNbsp = function (pos) { var container = pos.container(); return NodeType.isText(container) && contains$2(container.data, nbsp); }; var normalizeNbspMiddle = function (text) { return map(text.split(''), function (chr, i, chars) { if (isNbsp(chr) && i > 0 && i < chars.length - 1 && isContent$1(chars[i - 1]) && isContent$1(chars[i + 1])) { return ' '; } else { return chr; } }).join(''); }; var normalizeNbspAtStart = function (root, node) { var text = node.data; var firstPos = CaretPosition(node, 0); if (isNbspAt(text, 0) && !needsToBeNbsp(root, firstPos)) { node.data = ' ' + text.slice(1); return true; } else { return false; } }; var normalizeNbspInMiddleOfTextNode = function (node) { var text = node.data; var newText = normalizeNbspMiddle(text); if (newText !== text) { node.data = newText; return true; } else { return false; } }; var normalizeNbspAtEnd = function (root, node) { var text = node.data; var lastPos = CaretPosition(node, text.length - 1); if (isNbspAt(text, text.length - 1) && !needsToBeNbsp(root, lastPos)) { node.data = text.slice(0, -1) + ' '; return true; } else { return false; } }; var normalizeNbsps = function (root, pos) { return Option.some(pos).filter(hasNbsp).bind(function (pos) { var container = pos.container(); var normalized = normalizeNbspAtStart(root, container) || normalizeNbspInMiddleOfTextNode(container) || normalizeNbspAtEnd(root, container); return normalized ? Option.some(pos) : Option.none(); }); }; var normalizeNbspsInEditor = function (editor) { var root = Element.fromDom(editor.getBody()); if (editor.selection.isCollapsed()) { normalizeNbsps(root, CaretPosition.fromRangeStart(editor.selection.getRng())).each(function (pos) { editor.selection.setRng(pos.toRange()); }); } }; var locationToCaretPosition = function (root) { return function (location) { return location.fold(function (element) { return CaretFinder.prevPosition(root.dom(), CaretPosition$1.before(element)); }, function (element) { return CaretFinder.firstPositionIn(element); }, function (element) { return CaretFinder.lastPositionIn(element); }, function (element) { return CaretFinder.nextPosition(root.dom(), CaretPosition$1.after(element)); }); }; }; var insertInlineBoundarySpaceOrNbsp = function (root, pos) { return function (checkPos) { return needsToHaveNbsp(root, checkPos) ? insertNbspAtPosition(pos) : insertSpaceAtPosition(pos); }; }; var setSelection$1 = function (editor) { return function (pos) { editor.selection.setRng(pos.toRange()); editor.nodeChanged(); return true; }; }; var insertSpaceOrNbspAtSelection = function (editor) { var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng()); var root = Element.fromDom(editor.getBody()); if (editor.selection.isCollapsed()) { var isInlineTarget = curry(InlineUtils.isInlineTarget, editor); var caretPosition = CaretPosition$1.fromRangeStart(editor.selection.getRng()); return BoundaryLocation.readLocation(isInlineTarget, editor.getBody(), caretPosition).bind(locationToCaretPosition(root)).bind(insertInlineBoundarySpaceOrNbsp(root, pos)).exists(setSelection$1(editor)); } else { return false; } }; var executeKeydownOverride$2 = function (editor, evt) { MatchKeys.execute([{ keyCode: VK.SPACEBAR, action: MatchKeys.action(insertSpaceOrNbspAtSelection, editor) }], evt).each(function (_) { evt.preventDefault(); }); }; var setup$a = function (editor) { editor.on('keydown', function (evt) { if (evt.isDefaultPrevented() === false) { executeKeydownOverride$2(editor, evt); } }); }; var SpaceKey = { setup: setup$a }; var findBlockCaretContainer = function (editor) { return descendant(Element.fromDom(editor.getBody()), '*[data-mce-caret]').fold(constant(null), function (elm) { return elm.dom(); }); }; var removeIeControlRect = function (editor) { editor.selection.setRng(editor.selection.getRng()); }; var showBlockCaretContainer = function (editor, blockCaretContainer) { if (blockCaretContainer.hasAttribute('data-mce-caret')) { showCaretContainerBlock(blockCaretContainer); removeIeControlRect(editor); editor.selection.scrollIntoView(blockCaretContainer); } }; var handleBlockContainer = function (editor, e) { var blockCaretContainer = findBlockCaretContainer(editor); if (!blockCaretContainer) { return; } if (e.type === 'compositionstart') { e.preventDefault(); e.stopPropagation(); showBlockCaretContainer(editor, blockCaretContainer); return; } if (hasContent(blockCaretContainer)) { showBlockCaretContainer(editor, blockCaretContainer); editor.undoManager.add(); } }; var setup$b = function (editor) { editor.on('keyup compositionstart', curry(handleBlockContainer, editor)); }; var CaretContainerInput = { setup: setup$b }; var browser$4 = PlatformDetection$1.detect().browser; var setupIeInput = function (editor) { var keypressThrotter = first(function () { if (!editor.composing) { normalizeNbspsInEditor(editor); } }, 0); if (browser$4.isIE()) { editor.on('keypress', function (e) { keypressThrotter.throttle(); }); editor.on('remove', function (e) { keypressThrotter.cancel(); }); } }; var setup$c = function (editor) { setupIeInput(editor); editor.on('input', function (e) { if (e.isComposing === false) { normalizeNbspsInEditor(editor); } }); }; var executeKeydownOverride$3 = function (editor, evt) { MatchKeys.execute([ { keyCode: VK.END, action: moveToLineEndPoint(editor, true) }, { keyCode: VK.HOME, action: moveToLineEndPoint(editor, false) } ], evt).each(function (_) { evt.preventDefault(); }); }; var setup$d = function (editor) { editor.on('keydown', function (evt) { if (evt.isDefaultPrevented() === false) { executeKeydownOverride$3(editor, evt); } }); }; var HomeEndKeys = { setup: setup$d }; var setup$e = function (editor) { var caret = BoundarySelection.setupSelectedState(editor); CaretContainerInput.setup(editor); ArrowKeys.setup(editor, caret); DeleteBackspaceKeys.setup(editor, caret); EnterKey.setup(editor); SpaceKey.setup(editor); setup$c(editor); HomeEndKeys.setup(editor); }; var KeyboardOverrides = { setup: setup$e }; function Quirks (editor) { var each = Tools.each; var BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE, dom = editor.dom, selection = editor.selection, settings = editor.settings, parser = editor.parser; var isGecko = Env.gecko, isIE = Env.ie, isWebKit = Env.webkit; var mceInternalUrlPrefix = 'data:text/mce-internal,'; var mceInternalDataType = isIE ? 'Text' : 'URL'; var setEditorCommandState = function (cmd, state) { try { editor.getDoc().execCommand(cmd, false, state); } catch (ex) { } }; var isDefaultPrevented = function (e) { return e.isDefaultPrevented(); }; var setMceInternalContent = function (e) { var selectionHtml, internalContent; if (e.dataTransfer) { if (editor.selection.isCollapsed() && e.target.tagName === 'IMG') { selection.select(e.target); } selectionHtml = editor.selection.getContent(); if (selectionHtml.length > 0) { internalContent = mceInternalUrlPrefix + escape(editor.id) + ',' + escape(selectionHtml); e.dataTransfer.setData(mceInternalDataType, internalContent); } } }; var getMceInternalContent = function (e) { var internalContent; if (e.dataTransfer) { internalContent = e.dataTransfer.getData(mceInternalDataType); if (internalContent && internalContent.indexOf(mceInternalUrlPrefix) >= 0) { internalContent = internalContent.substr(mceInternalUrlPrefix.length).split(','); return { id: unescape(internalContent[0]), html: unescape(internalContent[1]) }; } } return null; }; var insertClipboardContents = function (content, internal) { if (editor.queryCommandSupported('mceInsertClipboardContent')) { editor.execCommand('mceInsertClipboardContent', false, { content: content, internal: internal }); } else { editor.execCommand('mceInsertContent', false, content); } }; var emptyEditorWhenDeleting = function () { var serializeRng = function (rng) { var body = dom.create('body'); var contents = rng.cloneContents(); body.appendChild(contents); return selection.serializer.serialize(body, { format: 'html' }); }; var allContentsSelected = function (rng) { var selection = serializeRng(rng); var allRng = dom.createRng(); allRng.selectNode(editor.getBody()); var allSelection = serializeRng(allRng); return selection === allSelection; }; editor.on('keydown', function (e) { var keyCode = e.keyCode; var isCollapsed, body; if (!isDefaultPrevented(e) && (keyCode === DELETE || keyCode === BACKSPACE)) { isCollapsed = editor.selection.isCollapsed(); body = editor.getBody(); if (isCollapsed && !dom.isEmpty(body)) { return; } if (!isCollapsed && !allContentsSelected(editor.selection.getRng())) { return; } e.preventDefault(); editor.setContent(''); if (body.firstChild && dom.isBlock(body.firstChild)) { editor.selection.setCursorLocation(body.firstChild, 0); } else { editor.selection.setCursorLocation(body, 0); } editor.nodeChanged(); } }); }; var selectAll = function () { editor.shortcuts.add('meta+a', null, 'SelectAll'); }; var inputMethodFocus = function () { if (!editor.settings.content_editable) { dom.bind(editor.getDoc(), 'mousedown mouseup', function (e) { var rng; if (e.target === editor.getDoc().documentElement) { rng = selection.getRng(); editor.getBody().focus(); if (e.type === 'mousedown') { if (isCaretContainer(rng.startContainer)) { return; } selection.placeCaretAt(e.clientX, e.clientY); } else { selection.setRng(rng); } } }); } }; var removeHrOnBackspace = function () { editor.on('keydown', function (e) { if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) { if (!editor.getBody().getElementsByTagName('hr').length) { return; } if (selection.isCollapsed() && selection.getRng().startOffset === 0) { var node = selection.getNode(); var previousSibling = node.previousSibling; if (node.nodeName === 'HR') { dom.remove(node); e.preventDefault(); return; } if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === 'hr') { dom.remove(previousSibling); e.preventDefault(); } } } }); }; var focusBody = function () { if (!domGlobals.Range.prototype.getClientRects) { editor.on('mousedown', function (e) { if (!isDefaultPrevented(e) && e.target.nodeName === 'HTML') { var body_1 = editor.getBody(); body_1.blur(); Delay.setEditorTimeout(editor, function () { body_1.focus(); }); } }); } }; var selectControlElements = function () { editor.on('click', function (e) { var target = e.target; if (/^(IMG|HR)$/.test(target.nodeName) && dom.getContentEditableParent(target) !== 'false') { e.preventDefault(); editor.selection.select(target); editor.nodeChanged(); } if (target.nodeName === 'A' && dom.hasClass(target, 'mce-item-anchor')) { e.preventDefault(); selection.select(target); } }); }; var removeStylesWhenDeletingAcrossBlockElements = function () { var getAttributeApplyFunction = function () { var template = dom.getAttribs(selection.getStart().cloneNode(false)); return function () { var target = selection.getStart(); if (target !== editor.getBody()) { dom.setAttrib(target, 'style', null); each(template, function (attr) { target.setAttributeNode(attr.cloneNode(true)); }); } }; }; var isSelectionAcrossElements = function () { return !selection.isCollapsed() && dom.getParent(selection.getStart(), dom.isBlock) !== dom.getParent(selection.getEnd(), dom.isBlock); }; editor.on('keypress', function (e) { var applyAttributes; if (!isDefaultPrevented(e) && (e.keyCode === 8 || e.keyCode === 46) && isSelectionAcrossElements()) { applyAttributes = getAttributeApplyFunction(); editor.getDoc().execCommand('delete', false, null); applyAttributes(); e.preventDefault(); return false; } }); dom.bind(editor.getDoc(), 'cut', function (e) { var applyAttributes; if (!isDefaultPrevented(e) && isSelectionAcrossElements()) { applyAttributes = getAttributeApplyFunction(); Delay.setEditorTimeout(editor, function () { applyAttributes(); }); } }); }; var disableBackspaceIntoATable = function () { editor.on('keydown', function (e) { if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) { if (selection.isCollapsed() && selection.getRng().startOffset === 0) { var previousSibling = selection.getNode().previousSibling; if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === 'table') { e.preventDefault(); return false; } } } }); }; var removeBlockQuoteOnBackSpace = function () { editor.on('keydown', function (e) { var rng, container, offset, root, parent; if (isDefaultPrevented(e) || e.keyCode !== VK.BACKSPACE) { return; } rng = selection.getRng(); container = rng.startContainer; offset = rng.startOffset; root = dom.getRoot(); parent = container; if (!rng.collapsed || offset !== 0) { return; } while (parent && parent.parentNode && parent.parentNode.firstChild === parent && parent.parentNode !== root) { parent = parent.parentNode; } if (parent.tagName === 'BLOCKQUOTE') { editor.formatter.toggle('blockquote', null, parent); rng = dom.createRng(); rng.setStart(container, 0); rng.setEnd(container, 0); selection.setRng(rng); } }); }; var setGeckoEditingOptions = function () { var setOpts = function () { setEditorCommandState('StyleWithCSS', false); setEditorCommandState('enableInlineTableEditing', false); if (!settings.object_resizing) { setEditorCommandState('enableObjectResizing', false); } }; if (!settings.readonly) { editor.on('BeforeExecCommand MouseDown', setOpts); } }; var addBrAfterLastLinks = function () { var fixLinks = function () { each(dom.select('a'), function (node) { var parentNode = node.parentNode; var root = dom.getRoot(); if (parentNode.lastChild === node) { while (parentNode && !dom.isBlock(parentNode)) { if (parentNode.parentNode.lastChild !== parentNode || parentNode === root) { return; } parentNode = parentNode.parentNode; } dom.add(parentNode, 'br', { 'data-mce-bogus': 1 }); } }); }; editor.on('SetContent ExecCommand', function (e) { if (e.type === 'setcontent' || e.command === 'mceInsertLink') { fixLinks(); } }); }; var setDefaultBlockType = function () { if (settings.forced_root_block) { editor.on('init', function () { setEditorCommandState('DefaultParagraphSeparator', settings.forced_root_block); }); } }; var normalizeSelection = function () { editor.on('keyup focusin mouseup', function (e) { if (!VK.modifierPressed(e)) { selection.normalize(); } }, true); }; var showBrokenImageIcon = function () { editor.contentStyles.push('img:-moz-broken {' + '-moz-force-broken-image-icon:1;' + 'min-width:24px;' + 'min-height:24px' + '}'); }; var restoreFocusOnKeyDown = function () { if (!editor.inline) { editor.on('keydown', function () { if (domGlobals.document.activeElement === domGlobals.document.body) { editor.getWin().focus(); } }); } }; var bodyHeight = function () { if (!editor.inline) { editor.contentStyles.push('body {min-height: 150px}'); editor.on('click', function (e) { var rng; if (e.target.nodeName === 'HTML') { if (Env.ie > 11) { editor.getBody().focus(); return; } rng = editor.selection.getRng(); editor.getBody().focus(); editor.selection.setRng(rng); editor.selection.normalize(); editor.nodeChanged(); } }); } }; var blockCmdArrowNavigation = function () { if (Env.mac) { editor.on('keydown', function (e) { if (VK.metaKeyPressed(e) && !e.shiftKey && (e.keyCode === 37 || e.keyCode === 39)) { e.preventDefault(); editor.selection.getSel().modify('move', e.keyCode === 37 ? 'backward' : 'forward', 'lineboundary'); } }); } }; var disableAutoUrlDetect = function () { setEditorCommandState('AutoUrlDetect', false); }; var tapLinksAndImages = function () { editor.on('click', function (e) { var elm = e.target; do { if (elm.tagName === 'A') { e.preventDefault(); return; } } while (elm = elm.parentNode); }); editor.contentStyles.push('.mce-content-body {-webkit-touch-callout: none}'); }; var blockFormSubmitInsideEditor = function () { editor.on('init', function () { editor.dom.bind(editor.getBody(), 'submit', function (e) { e.preventDefault(); }); }); }; var removeAppleInterchangeBrs = function () { parser.addNodeFilter('br', function (nodes) { var i = nodes.length; while (i--) { if (nodes[i].attr('class') === 'Apple-interchange-newline') { nodes[i].remove(); } } }); }; var ieInternalDragAndDrop = function () { editor.on('dragstart', function (e) { setMceInternalContent(e); }); editor.on('drop', function (e) { if (!isDefaultPrevented(e)) { var internalContent = getMceInternalContent(e); if (internalContent && internalContent.id !== editor.id) { e.preventDefault(); var rng = CaretRangeFromPoint.fromPoint(e.x, e.y, editor.getDoc()); selection.setRng(rng); insertClipboardContents(internalContent.html, true); } } }); }; var refreshContentEditable = function () { }; var isHidden = function () { var sel; if (!isGecko || editor.removed) { return 0; } sel = editor.selection.getSel(); return !sel || !sel.rangeCount || sel.rangeCount === 0; }; removeBlockQuoteOnBackSpace(); emptyEditorWhenDeleting(); if (!Env.windowsPhone) { normalizeSelection(); } if (isWebKit) { inputMethodFocus(); selectControlElements(); setDefaultBlockType(); blockFormSubmitInsideEditor(); disableBackspaceIntoATable(); removeAppleInterchangeBrs(); if (Env.iOS) { restoreFocusOnKeyDown(); bodyHeight(); tapLinksAndImages(); } else { selectAll(); } } if (Env.ie >= 11) { bodyHeight(); disableBackspaceIntoATable(); } if (Env.ie) { selectAll(); disableAutoUrlDetect(); ieInternalDragAndDrop(); } if (isGecko) { removeHrOnBackspace(); focusBody(); removeStylesWhenDeletingAcrossBlockElements(); setGeckoEditingOptions(); addBrAfterLastLinks(); showBrokenImageIcon(); blockCmdArrowNavigation(); disableBackspaceIntoATable(); } return { refreshContentEditable: refreshContentEditable, isHidden: isHidden }; } var isTextBlockNode = function (node) { return NodeType.isElement(node) && isTextBlock(Element.fromDom(node)); }; var normalizeSelection$1 = function (editor) { var rng = editor.selection.getRng(); var startPos = CaretPosition.fromRangeStart(rng); var endPos = CaretPosition.fromRangeEnd(rng); if (CaretPosition.isElementPosition(startPos)) { var container = startPos.container(); if (isTextBlockNode(container)) { CaretFinder.firstPositionIn(container).each(function (pos) { return rng.setStart(pos.container(), pos.offset()); }); } } if (CaretPosition.isElementPosition(endPos)) { var container = startPos.container(); if (isTextBlockNode(container)) { CaretFinder.lastPositionIn(container).each(function (pos) { return rng.setEnd(pos.container(), pos.offset()); }); } } editor.selection.setRng(RangeNormalizer.normalize(rng)); }; var setup$f = function (editor) { editor.on('click', function (e) { if (e.detail >= 3) { normalizeSelection$1(editor); } }); }; var preventSummaryToggle = function (editor) { editor.on('click', function (e) { if (editor.dom.getParent(e.target, 'details')) { e.preventDefault(); } }); }; var filterDetails = function (editor) { editor.parser.addNodeFilter('details', function (elms) { each(elms, function (details) { details.attr('data-mce-open', details.attr('open')); details.attr('open', 'open'); }); }); editor.serializer.addNodeFilter('details', function (elms) { each(elms, function (details) { var open = details.attr('data-mce-open'); details.attr('open', isString(open) ? open : null); details.attr('data-mce-open', null); }); }); }; var setup$g = function (editor) { preventSummaryToggle(editor); filterDetails(editor); }; var DOM$2 = DOMUtils$1.DOM; var appendStyle = function (editor, text) { var head = Element.fromDom(editor.getDoc().head); var tag = Element.fromTag('style'); set(tag, 'type', 'text/css'); append(tag, Element.fromText(text)); append(head, tag); }; var createParser = function (editor) { var parser = DomParser(editor.settings, editor.schema); parser.addAttributeFilter('src,href,style,tabindex', function (nodes, name) { var i = nodes.length, node; var dom = editor.dom; var value, internalName; while (i--) { node = nodes[i]; value = node.attr(name); internalName = 'data-mce-' + name; if (!node.attributes.map[internalName]) { if (value.indexOf('data:') === 0 || value.indexOf('blob:') === 0) { continue; } if (name === 'style') { value = dom.serializeStyle(dom.parseStyle(value), node.name); if (!value.length) { value = null; } node.attr(internalName, value); node.attr(name, value); } else if (name === 'tabindex') { node.attr(internalName, value); node.attr(name, null); } else { node.attr(internalName, editor.convertURL(value, name, node.name)); } } } }); parser.addNodeFilter('script', function (nodes) { var i = nodes.length, node, type; while (i--) { node = nodes[i]; type = node.attr('type') || 'no/type'; if (type.indexOf('mce-') !== 0) { node.attr('type', 'mce-' + type); } } }); parser.addNodeFilter('#cdata', function (nodes) { var i = nodes.length, node; while (i--) { node = nodes[i]; node.type = 8; node.name = '#comment'; node.value = '[CDATA[' + node.value + ']]'; } }); parser.addNodeFilter('p,h1,h2,h3,h4,h5,h6,div', function (nodes) { var i = nodes.length, node; var nonEmptyElements = editor.schema.getNonEmptyElements(); while (i--) { node = nodes[i]; if (node.isEmpty(nonEmptyElements) && node.getAll('br').length === 0) { node.append(new Node$1('br', 1)).shortEnded = true; } } }); return parser; }; var autoFocus = function (editor) { if (editor.settings.auto_focus) { Delay.setEditorTimeout(editor, function () { var focusEditor; if (editor.settings.auto_focus === true) { focusEditor = editor; } else { focusEditor = editor.editorManager.get(editor.settings.auto_focus); } if (!focusEditor.destroyed) { focusEditor.focus(); } }, 100); } }; var initEditor = function (editor) { editor.bindPendingEventDelegates(); editor.initialized = true; editor.fire('init'); editor.focus(true); editor.nodeChanged({ initial: true }); editor.execCallback('init_instance_callback', editor); autoFocus(editor); }; var getStyleSheetLoader = function (editor) { return editor.inline ? DOM$2.styleSheetLoader : editor.dom.styleSheetLoader; }; var initContentBody = function (editor, skipWrite) { var settings = editor.settings; var targetElm = editor.getElement(); var doc = editor.getDoc(), body, contentCssText; if (!settings.inline) { editor.getElement().style.visibility = editor.orgVisibility; } if (!skipWrite && !settings.content_editable) { doc.open(); doc.write(editor.iframeHTML); doc.close(); } if (settings.content_editable) { editor.on('remove', function () { var bodyEl = this.getBody(); DOM$2.removeClass(bodyEl, 'mce-content-body'); DOM$2.removeClass(bodyEl, 'mce-edit-focus'); DOM$2.setAttrib(bodyEl, 'contentEditable', null); }); DOM$2.addClass(targetElm, 'mce-content-body'); editor.contentDocument = doc = settings.content_document || domGlobals.document; editor.contentWindow = settings.content_window || domGlobals.window; editor.bodyElement = targetElm; settings.content_document = settings.content_window = null; settings.root_name = targetElm.nodeName.toLowerCase(); } body = editor.getBody(); body.disabled = true; editor.readonly = settings.readonly; if (!editor.readonly) { if (editor.inline && DOM$2.getStyle(body, 'position', true) === 'static') { body.style.position = 'relative'; } body.contentEditable = editor.getParam('content_editable_state', true); } body.disabled = false; editor.editorUpload = EditorUpload(editor); editor.schema = Schema(settings); editor.dom = DOMUtils$1(doc, { keep_values: true, url_converter: editor.convertURL, url_converter_scope: editor, hex_colors: settings.force_hex_style_colors, class_filter: settings.class_filter, update_styles: true, root_element: editor.inline ? editor.getBody() : null, collect: settings.content_editable, schema: editor.schema, contentCssCors: Settings.shouldUseContentCssCors(editor), onSetAttrib: function (e) { editor.fire('SetAttrib', e); } }); editor.parser = createParser(editor); editor.serializer = DomSerializer$1(settings, editor); editor.selection = Selection(editor.dom, editor.getWin(), editor.serializer, editor); editor.annotator = Annotator(editor); editor.formatter = Formatter(editor); editor.undoManager = UndoManager(editor); editor._nodeChangeDispatcher = new NodeChange(editor); editor._selectionOverrides = SelectionOverrides(editor); setup$g(editor); setup$f(editor); KeyboardOverrides.setup(editor); ForceBlocks.setup(editor); editor.fire('PreInit'); if (!settings.browser_spellcheck && !settings.gecko_spellcheck) { doc.body.spellcheck = false; DOM$2.setAttrib(body, 'spellcheck', 'false'); } editor.quirks = Quirks(editor); editor.fire('PostRender'); if (settings.directionality) { body.dir = settings.directionality; } if (settings.nowrap) { body.style.whiteSpace = 'nowrap'; } if (settings.protect) { editor.on('BeforeSetContent', function (e) { Tools.each(settings.protect, function (pattern) { e.content = e.content.replace(pattern, function (str) { return '<!--mce:protected ' + escape(str) + '-->'; }); }); }); } editor.on('SetContent', function () { editor.addVisual(editor.getBody()); }); editor.load({ initial: true, format: 'html' }); editor.startContent = editor.getContent({ format: 'raw' }); editor.on('compositionstart compositionend', function (e) { editor.composing = e.type === 'compositionstart'; }); if (editor.contentStyles.length > 0) { contentCssText = ''; Tools.each(editor.contentStyles, function (style) { contentCssText += style + '\r\n'; }); editor.dom.addStyle(contentCssText); } getStyleSheetLoader(editor).loadAll(editor.contentCSS, function (_) { initEditor(editor); }, function (urls) { initEditor(editor); }); if (settings.content_style) { appendStyle(editor, settings.content_style); } }; var InitContentBody = { initContentBody: initContentBody }; var DOM$3 = DOMUtils$1.DOM; var relaxDomain = function (editor, ifr) { if (domGlobals.document.domain !== domGlobals.window.location.hostname && Env.ie && Env.ie < 12) { var bodyUuid = Uuid.uuid('mce'); editor[bodyUuid] = function () { InitContentBody.initContentBody(editor); }; var domainRelaxUrl = 'javascript:(function(){' + 'document.open();document.domain="' + domGlobals.document.domain + '";' + 'var ed = window.parent.tinymce.get("' + editor.id + '");document.write(ed.iframeHTML);' + 'document.close();ed.' + bodyUuid + '(true);})()'; DOM$3.setAttrib(ifr, 'src', domainRelaxUrl); return true; } return false; }; var normalizeHeight = function (height) { var normalizedHeight = typeof height === 'number' ? height + 'px' : height; return normalizedHeight ? normalizedHeight : ''; }; var createIframeElement = function (id, title, height, customAttrs) { var iframe = Element.fromTag('iframe'); setAll(iframe, customAttrs); setAll(iframe, { id: id + '_ifr', frameBorder: '0', allowTransparency: 'true', title: title }); setAll$1(iframe, { width: '100%', height: normalizeHeight(height), display: 'block' }); return iframe; }; var getIframeHtml = function (editor) { var bodyId, bodyClass, iframeHTML; iframeHTML = Settings.getDocType(editor) + '<html><head>'; if (Settings.getDocumentBaseUrl(editor) !== editor.documentBaseUrl) { iframeHTML += '<base href="' + editor.documentBaseURI.getURI() + '" />'; } iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />'; bodyId = Settings.getBodyId(editor); bodyClass = Settings.getBodyClass(editor); if (Settings.getContentSecurityPolicy(editor)) { iframeHTML += '<meta http-equiv="Content-Security-Policy" content="' + Settings.getContentSecurityPolicy(editor) + '" />'; } iframeHTML += '</head><body id="' + bodyId + '" class="mce-content-body ' + bodyClass + '" data-id="' + editor.id + '"><br></body></html>'; return iframeHTML; }; var createIframe = function (editor, o) { var title = editor.editorManager.translate('Rich Text Area. Press ALT-F9 for menu. ' + 'Press ALT-F10 for toolbar. Press ALT-0 for help'); var ifr = createIframeElement(editor.id, title, o.height, Settings.getIframeAttrs(editor)).dom(); ifr.onload = function () { ifr.onload = null; editor.fire('load'); }; var isDomainRelaxed = relaxDomain(editor, ifr); editor.contentAreaContainer = o.iframeContainer; editor.iframeElement = ifr; editor.iframeHTML = getIframeHtml(editor); DOM$3.add(o.iframeContainer, ifr); return isDomainRelaxed; }; var init$1 = function (editor, boxInfo) { var isDomainRelaxed = createIframe(editor, boxInfo); if (boxInfo.editorContainer) { DOM$3.get(boxInfo.editorContainer).style.display = editor.orgDisplay; editor.hidden = DOM$3.isHidden(boxInfo.editorContainer); } editor.getElement().style.display = 'none'; DOM$3.setAttrib(editor.id, 'aria-hidden', 'true'); if (!isDomainRelaxed) { InitContentBody.initContentBody(editor); } }; var InitIframe = { init: init$1 }; var DOM$4 = DOMUtils$1.DOM; var initPlugin = function (editor, initializedPlugins, plugin) { var Plugin = PluginManager$1.get(plugin); var pluginUrl = PluginManager$1.urls[plugin] || editor.documentBaseUrl.replace(/\/$/, ''); plugin = Tools.trim(plugin); if (Plugin && Tools.inArray(initializedPlugins, plugin) === -1) { Tools.each(PluginManager$1.dependencies(plugin), function (dep) { initPlugin(editor, initializedPlugins, dep); }); if (editor.plugins[plugin]) { return; } try { var pluginInstance = new Plugin(editor, pluginUrl, editor.$); editor.plugins[plugin] = pluginInstance; if (pluginInstance.init) { pluginInstance.init(editor, pluginUrl); initializedPlugins.push(plugin); } } catch (e) { ErrorReporter.pluginInitError(editor, plugin, e); } } }; var trimLegacyPrefix = function (name) { return name.replace(/^\-/, ''); }; var initPlugins = function (editor) { var initializedPlugins = []; Tools.each(editor.settings.plugins.split(/[ ,]/), function (name) { initPlugin(editor, initializedPlugins, trimLegacyPrefix(name)); }); }; var initTheme = function (editor) { var Theme; var theme = editor.settings.theme; if (isString(theme)) { editor.settings.theme = trimLegacyPrefix(theme); Theme = ThemeManager.get(theme); editor.theme = new Theme(editor, ThemeManager.urls[theme]); if (editor.theme.init) { editor.theme.init(editor, ThemeManager.urls[theme] || editor.documentBaseUrl.replace(/\/$/, ''), editor.$); } } else { editor.theme = {}; } }; var renderFromLoadedTheme = function (editor) { var w, h, minHeight, re, info; var settings = editor.settings; var elm = editor.getElement(); w = settings.width || DOM$4.getStyle(elm, 'width') || '100%'; h = settings.height || DOM$4.getStyle(elm, 'height') || elm.offsetHeight; minHeight = settings.min_height || 100; re = /^[0-9\.]+(|px)$/i; if (re.test('' + w)) { w = Math.max(parseInt(w, 10), 100); } if (re.test('' + h)) { h = Math.max(parseInt(h, 10), minHeight); } info = editor.theme.renderUI({ targetNode: elm, width: w, height: h, deltaWidth: settings.delta_width, deltaHeight: settings.delta_height }); if (!settings.content_editable) { h = (info.iframeHeight || h) + (typeof h === 'number' ? info.deltaHeight || 0 : ''); if (h < minHeight) { h = minHeight; } } info.height = h; return info; }; var renderFromThemeFunc = function (editor) { var info; var elm = editor.getElement(); info = editor.settings.theme(editor, elm); if (info.editorContainer.nodeType) { info.editorContainer.id = info.editorContainer.id || editor.id + '_parent'; } if (info.iframeContainer && info.iframeContainer.nodeType) { info.iframeContainer.id = info.iframeContainer.id || editor.id + '_iframecontainer'; } info.height = info.iframeHeight ? info.iframeHeight : elm.offsetHeight; return info; }; var createThemeFalseResult = function (element) { return { editorContainer: element, iframeContainer: element }; }; var renderThemeFalseIframe = function (targetElement) { var iframeContainer = DOM$4.create('div'); DOM$4.insertAfter(iframeContainer, targetElement); return createThemeFalseResult(iframeContainer); }; var renderThemeFalse = function (editor) { var targetElement = editor.getElement(); return editor.inline ? createThemeFalseResult(null) : renderThemeFalseIframe(targetElement); }; var renderThemeUi = function (editor) { var settings = editor.settings, elm = editor.getElement(); editor.orgDisplay = elm.style.display; if (isString(settings.theme)) { return renderFromLoadedTheme(editor); } else if (isFunction(settings.theme)) { return renderFromThemeFunc(editor); } else { return renderThemeFalse(editor); } }; var init$2 = function (editor) { var settings = editor.settings; var elm = editor.getElement(); var boxInfo; editor.rtl = settings.rtl_ui || editor.editorManager.i18n.rtl; editor.editorManager.i18n.setCode(settings.language); settings.aria_label = settings.aria_label || DOM$4.getAttrib(elm, 'aria-label', editor.getLang('aria.rich_text_area')); editor.fire('ScriptsLoaded'); initTheme(editor); initPlugins(editor); boxInfo = renderThemeUi(editor); editor.editorContainer = boxInfo.editorContainer ? boxInfo.editorContainer : null; if (settings.content_css) { Tools.each(Tools.explode(settings.content_css), function (u) { editor.contentCSS.push(editor.documentBaseURI.toAbsolute(u)); }); } if (settings.content_editable) { return InitContentBody.initContentBody(editor); } else { return InitIframe.init(editor, boxInfo); } }; var Init = { init: init$2 }; var DOM$5 = DOMUtils$1.DOM; var hasSkipLoadPrefix = function (name) { return name.charAt(0) === '-'; }; var loadLanguage = function (scriptLoader, editor) { var settings = editor.settings; if (settings.language && settings.language !== 'en' && !settings.language_url) { settings.language_url = editor.editorManager.baseURL + '/langs/' + settings.language + '.js'; } if (settings.language_url && !editor.editorManager.i18n.data[settings.language]) { scriptLoader.add(settings.language_url); } }; var loadTheme = function (scriptLoader, editor, suffix, callback) { var settings = editor.settings, theme = settings.theme; if (isString(theme)) { if (!hasSkipLoadPrefix(theme) && !ThemeManager.urls.hasOwnProperty(theme)) { var themeUrl = settings.theme_url; if (themeUrl) { ThemeManager.load(theme, editor.documentBaseURI.toAbsolute(themeUrl)); } else { ThemeManager.load(theme, 'themes/' + theme + '/theme' + suffix + '.js'); } } scriptLoader.loadQueue(function () { ThemeManager.waitFor(theme, callback); }); } else { callback(); } }; var loadPlugins = function (settings, suffix) { if (Tools.isArray(settings.plugins)) { settings.plugins = settings.plugins.join(' '); } Tools.each(settings.external_plugins, function (url, name) { PluginManager$1.load(name, url); settings.plugins += ' ' + name; }); Tools.each(settings.plugins.split(/[ ,]/), function (plugin) { plugin = Tools.trim(plugin); if (plugin && !PluginManager$1.urls[plugin]) { if (hasSkipLoadPrefix(plugin)) { plugin = plugin.substr(1, plugin.length); var dependencies = PluginManager$1.dependencies(plugin); Tools.each(dependencies, function (dep) { var defaultSettings = { prefix: 'plugins/', resource: dep, suffix: '/plugin' + suffix + '.js' }; dep = PluginManager$1.createUrl(defaultSettings, dep); PluginManager$1.load(dep.resource, dep); }); } else { PluginManager$1.load(plugin, { prefix: 'plugins/', resource: plugin, suffix: '/plugin' + suffix + '.js' }); } } }); }; var loadScripts = function (editor, suffix) { var scriptLoader = ScriptLoader.ScriptLoader; loadTheme(scriptLoader, editor, suffix, function () { loadLanguage(scriptLoader, editor); loadPlugins(editor.settings, suffix); scriptLoader.loadQueue(function () { if (!editor.removed) { Init.init(editor); } }, editor, function (urls) { ErrorReporter.pluginLoadError(editor, urls[0]); if (!editor.removed) { Init.init(editor); } }); }); }; var render = function (editor) { var settings = editor.settings, id = editor.id; var readyHandler = function () { DOM$5.unbind(domGlobals.window, 'ready', readyHandler); editor.render(); }; if (!EventUtils.Event.domLoaded) { DOM$5.bind(domGlobals.window, 'ready', readyHandler); return; } if (!editor.getElement()) { return; } if (!Env.contentEditable) { return; } if (!settings.inline) { editor.orgVisibility = editor.getElement().style.visibility; editor.getElement().style.visibility = 'hidden'; } else { editor.inline = true; } var form = editor.getElement().form || DOM$5.getParent(id, 'form'); if (form) { editor.formElement = form; if (settings.hidden_input && !/TEXTAREA|INPUT/i.test(editor.getElement().nodeName)) { DOM$5.insertAfter(DOM$5.create('input', { type: 'hidden', name: id }), id); editor.hasHiddenInput = true; } editor.formEventDelegate = function (e) { editor.fire(e.type, e); }; DOM$5.bind(form, 'submit reset', editor.formEventDelegate); editor.on('reset', function () { editor.setContent(editor.startContent, { format: 'raw' }); }); if (settings.submit_patch && !form.submit.nodeType && !form.submit.length && !form._mceOldSubmit) { form._mceOldSubmit = form.submit; form.submit = function () { editor.editorManager.triggerSave(); editor.setDirty(false); return form._mceOldSubmit(form); }; } } editor.windowManager = WindowManager(editor); editor.notificationManager = NotificationManager(editor); if (settings.encoding === 'xml') { editor.on('GetContent', function (e) { if (e.save) { e.content = DOM$5.encode(e.content); } }); } if (settings.add_form_submit_trigger) { editor.on('submit', function () { if (editor.initialized) { editor.save(); } }); } if (settings.add_unload_trigger) { editor._beforeUnload = function () { if (editor.initialized && !editor.destroyed && !editor.isHidden()) { editor.save({ format: 'raw', no_events: true, set_dirty: false }); } }; editor.editorManager.on('BeforeUnload', editor._beforeUnload); } editor.editorManager.add(editor); loadScripts(editor, editor.suffix); }; var Render = { render: render }; var add$4 = function (editor, name, settings) { var sidebars = editor.sidebars ? editor.sidebars : []; sidebars.push({ name: name, settings: settings }); editor.sidebars = sidebars; }; var Sidebar = { add: add$4 }; var each$k = Tools.each, trim$4 = Tools.trim; var queryParts = 'source protocol authority userInfo user password host port relative path directory file query anchor'.split(' '); var DEFAULT_PORTS = { ftp: 21, http: 80, https: 443, mailto: 25 }; var URI = function (url, settings) { var self = this; var baseUri, baseUrl; url = trim$4(url); settings = self.settings = settings || {}; baseUri = settings.base_uri; if (/^([\w\-]+):([^\/]{2})/i.test(url) || /^\s*#/.test(url)) { self.source = url; return; } var isProtocolRelative = url.indexOf('//') === 0; if (url.indexOf('/') === 0 && !isProtocolRelative) { url = (baseUri ? baseUri.protocol || 'http' : 'http') + '://mce_host' + url; } if (!/^[\w\-]*:?\/\//.test(url)) { baseUrl = settings.base_uri ? settings.base_uri.path : new URI(domGlobals.document.location.href).directory; if (settings.base_uri.protocol == '') { url = '//mce_host' + self.toAbsPath(baseUrl, url); } else { url = /([^#?]*)([#?]?.*)/.exec(url); url = (baseUri && baseUri.protocol || 'http') + '://mce_host' + self.toAbsPath(baseUrl, url[1]) + url[2]; } } url = url.replace(/@@/g, '(mce_at)'); url = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(url); each$k(queryParts, function (v, i) { var part = url[i]; if (part) { part = part.replace(/\(mce_at\)/g, '@@'); } self[v] = part; }); if (baseUri) { if (!self.protocol) { self.protocol = baseUri.protocol; } if (!self.userInfo) { self.userInfo = baseUri.userInfo; } if (!self.port && self.host === 'mce_host') { self.port = baseUri.port; } if (!self.host || self.host === 'mce_host') { self.host = baseUri.host; } self.source = ''; } if (isProtocolRelative) { self.protocol = ''; } }; URI.prototype = { setPath: function (path) { var self = this; path = /^(.*?)\/?(\w+)?$/.exec(path); self.path = path[0]; self.directory = path[1]; self.file = path[2]; self.source = ''; self.getURI(); }, toRelative: function (uri) { var self = this; var output; if (uri === './') { return uri; } uri = new URI(uri, { base_uri: self }); if (uri.host !== 'mce_host' && self.host !== uri.host && uri.host || self.port !== uri.port || self.protocol !== uri.protocol && uri.protocol !== '') { return uri.getURI(); } var tu = self.getURI(), uu = uri.getURI(); if (tu === uu || tu.charAt(tu.length - 1) === '/' && tu.substr(0, tu.length - 1) === uu) { return tu; } output = self.toRelPath(self.path, uri.path); if (uri.query) { output += '?' + uri.query; } if (uri.anchor) { output += '#' + uri.anchor; } return output; }, toAbsolute: function (uri, noHost) { uri = new URI(uri, { base_uri: this }); return uri.getURI(noHost && this.isSameOrigin(uri)); }, isSameOrigin: function (uri) { if (this.host == uri.host && this.protocol == uri.protocol) { if (this.port == uri.port) { return true; } var defaultPort = DEFAULT_PORTS[this.protocol]; if (defaultPort && (this.port || defaultPort) == (uri.port || defaultPort)) { return true; } } return false; }, toRelPath: function (base, path) { var items, breakPoint = 0, out = '', i, l; base = base.substring(0, base.lastIndexOf('/')); base = base.split('/'); items = path.split('/'); if (base.length >= items.length) { for (i = 0, l = base.length; i < l; i++) { if (i >= items.length || base[i] !== items[i]) { breakPoint = i + 1; break; } } } if (base.length < items.length) { for (i = 0, l = items.length; i < l; i++) { if (i >= base.length || base[i] !== items[i]) { breakPoint = i + 1; break; } } } if (breakPoint === 1) { return path; } for (i = 0, l = base.length - (breakPoint - 1); i < l; i++) { out += '../'; } for (i = breakPoint - 1, l = items.length; i < l; i++) { if (i !== breakPoint - 1) { out += '/' + items[i]; } else { out += items[i]; } } return out; }, toAbsPath: function (base, path) { var i, nb = 0, o = [], tr, outPath; tr = /\/$/.test(path) ? '/' : ''; base = base.split('/'); path = path.split('/'); each$k(base, function (k) { if (k) { o.push(k); } }); base = o; for (i = path.length - 1, o = []; i >= 0; i--) { if (path[i].length === 0 || path[i] === '.') { continue; } if (path[i] === '..') { nb++; continue; } if (nb > 0) { nb--; continue; } o.push(path[i]); } i = base.length - nb; if (i <= 0) { outPath = o.reverse().join('/'); } else { outPath = base.slice(0, i).join('/') + '/' + o.reverse().join('/'); } if (outPath.indexOf('/') !== 0) { outPath = '/' + outPath; } if (tr && outPath.lastIndexOf('/') !== outPath.length - 1) { outPath += tr; } return outPath; }, getURI: function (noProtoHost) { var s; var self = this; if (!self.source || noProtoHost) { s = ''; if (!noProtoHost) { if (self.protocol) { s += self.protocol + '://'; } else { s += '//'; } if (self.userInfo) { s += self.userInfo + '@'; } if (self.host) { s += self.host; } if (self.port) { s += ':' + self.port; } } if (self.path) { s += self.path; } if (self.query) { s += '?' + self.query; } if (self.anchor) { s += '#' + self.anchor; } self.source = s; } return self.source; } }; URI.parseDataUri = function (uri) { var type, matches; uri = decodeURIComponent(uri).split(','); matches = /data:([^;]+)/.exec(uri[0]); if (matches) { type = matches[1]; } return { type: type, data: uri[1] }; }; URI.getDocumentBaseUrl = function (loc) { var baseUrl; if (loc.protocol.indexOf('http') !== 0 && loc.protocol !== 'file:') { baseUrl = loc.href; } else { baseUrl = loc.protocol + '//' + loc.host + loc.pathname; } if (/^[^:]+:\/\/\/?[^\/]+\//.test(baseUrl)) { baseUrl = baseUrl.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, ''); if (!/[\/\\]$/.test(baseUrl)) { baseUrl += '/'; } } return baseUrl; }; var defaultFormat = 'html'; var trimEmptyContents = function (editor, html) { var blockName = Settings.getForcedRootBlock(editor); var emptyRegExp = new RegExp('^(<' + blockName + '[^>]*>( | |\\s|\xA0|<br \\/>|)<\\/' + blockName + '>[\r\n]*|<br \\/>[\r\n]*)$'); return html.replace(emptyRegExp, ''); }; var getContentFromBody = function (editor, args, body) { var content; args.format = args.format ? args.format : defaultFormat; args.get = true; args.getInner = true; if (!args.no_events) { editor.fire('BeforeGetContent', args); } if (args.format === 'raw') { content = Tools.trim(TrimHtml.trimExternal(editor.serializer, body.innerHTML)); } else if (args.format === 'text') { content = Zwsp.trim(body.innerText || body.textContent); } else if (args.format === 'tree') { return editor.serializer.serialize(body, args); } else { content = trimEmptyContents(editor, editor.serializer.serialize(body, args)); } if (args.format !== 'text' && !isWsPreserveElement(Element.fromDom(body))) { args.content = Tools.trim(content); } else { args.content = content; } if (!args.no_events) { editor.fire('GetContent', args); } return args.content; }; var getContent$1 = function (editor, args) { if (args === void 0) { args = {}; } return Option.from(editor.getBody()).fold(constant(args.format === 'tree' ? new Node$1('body', 11) : ''), function (body) { return getContentFromBody(editor, args, body); }); }; var traverse = function (node, fn) { fn(node); if (node.firstChild) { traverse(node.firstChild, fn); } if (node.next) { traverse(node.next, fn); } }; var findMatchingNodes = function (nodeFilters, attributeFilters, node) { var nodeMatches = {}; var attrMatches = {}; var matches = []; if (node.firstChild) { traverse(node.firstChild, function (node) { each(nodeFilters, function (filter) { if (filter.name === node.name) { if (nodeMatches[filter.name]) { nodeMatches[filter.name].nodes.push(node); } else { nodeMatches[filter.name] = { filter: filter, nodes: [node] }; } } }); each(attributeFilters, function (filter) { if (typeof node.attr(filter.name) === 'string') { if (attrMatches[filter.name]) { attrMatches[filter.name].nodes.push(node); } else { attrMatches[filter.name] = { filter: filter, nodes: [node] }; } } }); }); } for (var name in nodeMatches) { if (nodeMatches.hasOwnProperty(name)) { matches.push(nodeMatches[name]); } } for (var name in attrMatches) { if (attrMatches.hasOwnProperty(name)) { matches.push(attrMatches[name]); } } return matches; }; var filter$3 = function (nodeFilters, attributeFilters, node) { var matches = findMatchingNodes(nodeFilters, attributeFilters, node); each(matches, function (match) { each(match.filter.callbacks, function (callback) { callback(match.nodes, match.filter.name, {}); }); }); }; var defaultFormat$1 = 'html'; var isTreeNode = function (content) { return content instanceof Node$1; }; var moveSelection = function (editor) { if (EditorFocus.hasFocus(editor)) { CaretFinder.firstPositionIn(editor.getBody()).each(function (pos) { var node = pos.getNode(); var caretPos = NodeType.isTable(node) ? CaretFinder.firstPositionIn(node).getOr(pos) : pos; editor.selection.setRng(caretPos.toRange()); }); } }; var setEditorHtml = function (editor, html) { editor.dom.setHTML(editor.getBody(), html); moveSelection(editor); }; var setContentString = function (editor, body, content, args) { var forcedRootBlockName, padd; if (content.length === 0 || /^\s+$/.test(content)) { padd = '<br data-mce-bogus="1">'; if (body.nodeName === 'TABLE') { content = '<tr><td>' + padd + '</td></tr>'; } else if (/^(UL|OL)$/.test(body.nodeName)) { content = '<li>' + padd + '</li>'; } forcedRootBlockName = Settings.getForcedRootBlock(editor); if (forcedRootBlockName && editor.schema.isValidChild(body.nodeName.toLowerCase(), forcedRootBlockName.toLowerCase())) { content = padd; content = editor.dom.createHTML(forcedRootBlockName, editor.settings.forced_root_block_attrs, content); } else if (!content) { content = '<br data-mce-bogus="1">'; } setEditorHtml(editor, content); editor.fire('SetContent', args); } else { if (args.format !== 'raw') { content = HtmlSerializer({ validate: editor.validate }, editor.schema).serialize(editor.parser.parse(content, { isRootContent: true, insert: true })); } args.content = isWsPreserveElement(Element.fromDom(body)) ? content : Tools.trim(content); setEditorHtml(editor, args.content); if (!args.no_events) { editor.fire('SetContent', args); } } return args.content; }; var setContentTree = function (editor, body, content, args) { filter$3(editor.parser.getNodeFilters(), editor.parser.getAttributeFilters(), content); var html = HtmlSerializer({ validate: editor.validate }, editor.schema).serialize(content); args.content = isWsPreserveElement(Element.fromDom(body)) ? html : Tools.trim(html); setEditorHtml(editor, args.content); if (!args.no_events) { editor.fire('SetContent', args); } return content; }; var setContent$1 = function (editor, content, args) { if (args === void 0) { args = {}; } args.format = args.format ? args.format : defaultFormat$1; args.set = true; args.content = isTreeNode(content) ? '' : content; if (!isTreeNode(content) && !args.no_events) { editor.fire('BeforeSetContent', args); content = args.content; } return Option.from(editor.getBody()).fold(constant(content), function (body) { return isTreeNode(content) ? setContentTree(editor, body, content, args) : setContentString(editor, body, content, args); }); }; var DOM$6 = DOMUtils$1.DOM; var restoreOriginalStyles = function (editor) { DOM$6.setStyle(editor.id, 'display', editor.orgDisplay); }; var safeDestroy = function (x) { return Option.from(x).each(function (x) { return x.destroy(); }); }; var clearDomReferences = function (editor) { editor.contentAreaContainer = editor.formElement = editor.container = editor.editorContainer = null; editor.bodyElement = editor.contentDocument = editor.contentWindow = null; editor.iframeElement = editor.targetElm = null; if (editor.selection) { editor.selection = editor.selection.win = editor.selection.dom = editor.selection.dom.doc = null; } }; var restoreForm = function (editor) { var form = editor.formElement; if (form) { if (form._mceOldSubmit) { form.submit = form._mceOldSubmit; form._mceOldSubmit = null; } DOM$6.unbind(form, 'submit reset', editor.formEventDelegate); } }; var remove$7 = function (editor) { if (!editor.removed) { var _selectionOverrides = editor._selectionOverrides, editorUpload = editor.editorUpload; var body = editor.getBody(); var element = editor.getElement(); if (body) { editor.save({ is_removing: true }); } editor.removed = true; editor.unbindAllNativeEvents(); if (editor.hasHiddenInput && element) { DOM$6.remove(element.nextSibling); } Events.fireRemove(editor); editor.editorManager.remove(editor); if (!editor.inline && body) { restoreOriginalStyles(editor); } Events.fireDetach(editor); DOM$6.remove(editor.getContainer()); safeDestroy(_selectionOverrides); safeDestroy(editorUpload); editor.destroy(); } }; var destroy = function (editor, automatic) { var selection = editor.selection, dom = editor.dom; if (editor.destroyed) { return; } if (!automatic && !editor.removed) { editor.remove(); return; } if (!automatic) { editor.editorManager.off('beforeunload', editor._beforeUnload); if (editor.theme && editor.theme.destroy) { editor.theme.destroy(); } safeDestroy(selection); safeDestroy(dom); } restoreForm(editor); clearDomReferences(editor); editor.destroyed = true; }; var DOM$7 = DOMUtils$1.DOM; var extend$4 = Tools.extend, each$l = Tools.each; var resolve$4 = Tools.resolve; var ie$2 = Env.ie; var Editor = function (id, settings, editorManager) { var self = this; var documentBaseUrl = self.documentBaseUrl = editorManager.documentBaseURL; var baseUri = editorManager.baseURI; settings = getEditorSettings(self, id, documentBaseUrl, editorManager.defaultSettings, settings); self.settings = settings; AddOnManager.language = settings.language || 'en'; AddOnManager.languageLoad = settings.language_load; AddOnManager.baseURL = editorManager.baseURL; self.id = id; self.setDirty(false); self.plugins = {}; self.documentBaseURI = new URI(settings.document_base_url, { base_uri: baseUri }); self.baseURI = baseUri; self.contentCSS = []; self.contentStyles = []; self.shortcuts = new Shortcuts(self); self.loadedCSS = {}; self.editorCommands = new EditorCommands(self); self.suffix = editorManager.suffix; self.editorManager = editorManager; self.inline = settings.inline; self.buttons = {}; self.menuItems = {}; if (settings.cache_suffix) { Env.cacheSuffix = settings.cache_suffix.replace(/^[\?\&]+/, ''); } if (settings.override_viewport === false) { Env.overrideViewPort = false; } editorManager.fire('SetupEditor', { editor: self }); self.execCallback('setup', self); self.$ = DomQuery.overrideDefaults(function () { return { context: self.inline ? self.getBody() : self.getDoc(), element: self.getBody() }; }); }; Editor.prototype = { render: function () { Render.render(this); }, focus: function (skipFocus) { EditorFocus.focus(this, skipFocus); }, hasFocus: function () { return EditorFocus.hasFocus(this); }, execCallback: function (name) { var x = []; for (var _i = 1; _i < arguments.length; _i++) { x[_i - 1] = arguments[_i]; } var self = this; var callback = self.settings[name], scope; if (!callback) { return; } if (self.callbackLookup && (scope = self.callbackLookup[name])) { callback = scope.func; scope = scope.scope; } if (typeof callback === 'string') { scope = callback.replace(/\.\w+$/, ''); scope = scope ? resolve$4(scope) : 0; callback = resolve$4(callback); self.callbackLookup = self.callbackLookup || {}; self.callbackLookup[name] = { func: callback, scope: scope }; } return callback.apply(scope || self, Array.prototype.slice.call(arguments, 1)); }, translate: function (text) { if (text && Tools.is(text, 'string')) { var lang_1 = this.settings.language || 'en', i18n_1 = this.editorManager.i18n; text = i18n_1.data[lang_1 + '.' + text] || text.replace(/\{\#([^\}]+)\}/g, function (a, b) { return i18n_1.data[lang_1 + '.' + b] || '{#' + b + '}'; }); } return this.editorManager.translate(text); }, getLang: function (name, defaultVal) { return this.editorManager.i18n.data[(this.settings.language || 'en') + '.' + name] || (defaultVal !== undefined ? defaultVal : '{#' + name + '}'); }, getParam: function (name, defaultVal, type) { return getParam(this, name, defaultVal, type); }, nodeChanged: function (args) { this._nodeChangeDispatcher.nodeChanged(args); }, addButton: function (name, settings) { var self = this; if (settings.cmd) { settings.onclick = function () { self.execCommand(settings.cmd); }; } if (settings.stateSelector && typeof settings.active === 'undefined') { settings.active = false; } if (!settings.text && !settings.icon) { settings.icon = name; } settings.tooltip = settings.tooltip || settings.title; self.buttons[name] = settings; }, addSidebar: function (name, settings) { return Sidebar.add(this, name, settings); }, addMenuItem: function (name, settings) { var self = this; if (settings.cmd) { settings.onclick = function () { self.execCommand(settings.cmd); }; } self.menuItems[name] = settings; }, addContextToolbar: function (predicate, items) { var self = this; var selector; self.contextToolbars = self.contextToolbars || []; if (typeof predicate === 'string') { selector = predicate; predicate = function (elm) { return self.dom.is(elm, selector); }; } self.contextToolbars.push({ id: Uuid.uuid('mcet'), predicate: predicate, items: items }); }, addCommand: function (name, callback, scope) { this.editorCommands.addCommand(name, callback, scope); }, addQueryStateHandler: function (name, callback, scope) { this.editorCommands.addQueryStateHandler(name, callback, scope); }, addQueryValueHandler: function (name, callback, scope) { this.editorCommands.addQueryValueHandler(name, callback, scope); }, addShortcut: function (pattern, desc, cmdFunc, scope) { this.shortcuts.add(pattern, desc, cmdFunc, scope); }, execCommand: function (cmd, ui, value, args) { return this.editorCommands.execCommand(cmd, ui, value, args); }, queryCommandState: function (cmd) { return this.editorCommands.queryCommandState(cmd); }, queryCommandValue: function (cmd) { return this.editorCommands.queryCommandValue(cmd); }, queryCommandSupported: function (cmd) { return this.editorCommands.queryCommandSupported(cmd); }, show: function () { var self = this; if (self.hidden) { self.hidden = false; if (self.inline) { self.getBody().contentEditable = true; } else { DOM$7.show(self.getContainer()); DOM$7.hide(self.id); } self.load(); self.fire('show'); } }, hide: function () { var self = this, doc = self.getDoc(); if (!self.hidden) { if (ie$2 && doc && !self.inline) { doc.execCommand('SelectAll'); } self.save(); if (self.inline) { self.getBody().contentEditable = false; if (self === self.editorManager.focusedEditor) { self.editorManager.focusedEditor = null; } } else { DOM$7.hide(self.getContainer()); DOM$7.setStyle(self.id, 'display', self.orgDisplay); } self.hidden = true; self.fire('hide'); } }, isHidden: function () { return !!this.hidden; }, setProgressState: function (state, time) { this.fire('ProgressState', { state: state, time: time }); }, load: function (args) { var self = this; var elm = self.getElement(), html; if (self.removed) { return ''; } if (elm) { args = args || {}; args.load = true; html = self.setContent(elm.value !== undefined ? elm.value : elm.innerHTML, args); args.element = elm; if (!args.no_events) { self.fire('LoadContent', args); } args.element = elm = null; return html; } }, save: function (args) { var self = this; var elm = self.getElement(), html, form; if (!elm || !self.initialized || self.removed) { return; } args = args || {}; args.save = true; args.element = elm; html = args.content = self.getContent(args); if (!args.no_events) { self.fire('SaveContent', args); } if (args.format === 'raw') { self.fire('RawSaveContent', args); } html = args.content; if (!/TEXTAREA|INPUT/i.test(elm.nodeName)) { if (args.is_removing || !self.inline) { elm.innerHTML = html; } if (form = DOM$7.getParent(self.id, 'form')) { each$l(form.elements, function (elm) { if (elm.name === self.id) { elm.value = html; return false; } }); } } else { elm.value = html; } args.element = elm = null; if (args.set_dirty !== false) { self.setDirty(false); } return html; }, setContent: function (content, args) { return setContent$1(this, content, args); }, getContent: function (args) { return getContent$1(this, args); }, insertContent: function (content, args) { if (args) { content = extend$4({ content: content }, args); } this.execCommand('mceInsertContent', false, content); }, isDirty: function () { return !this.isNotDirty; }, setDirty: function (state) { var oldState = !this.isNotDirty; this.isNotDirty = !state; if (state && state !== oldState) { this.fire('dirty'); } }, setMode: function (mode) { setMode(this, mode); }, getContainer: function () { var self = this; if (!self.container) { self.container = DOM$7.get(self.editorContainer || self.id + '_parent'); } return self.container; }, getContentAreaContainer: function () { return this.contentAreaContainer; }, getElement: function () { if (!this.targetElm) { this.targetElm = DOM$7.get(this.id); } return this.targetElm; }, getWin: function () { var self = this; var elm; if (!self.contentWindow) { elm = self.iframeElement; if (elm) { self.contentWindow = elm.contentWindow; } } return self.contentWindow; }, getDoc: function () { var self = this; var win; if (!self.contentDocument) { win = self.getWin(); if (win) { self.contentDocument = win.document; } } return self.contentDocument; }, getBody: function () { var doc = this.getDoc(); return this.bodyElement || (doc ? doc.body : null); }, convertURL: function (url, name, elm) { var self = this, settings = self.settings; if (settings.urlconverter_callback) { return self.execCallback('urlconverter_callback', url, elm, true, name); } if (!settings.convert_urls || elm && elm.nodeName === 'LINK' || url.indexOf('file:') === 0 || url.length === 0) { return url; } if (settings.relative_urls) { return self.documentBaseURI.toRelative(url); } url = self.documentBaseURI.toAbsolute(url, settings.remove_script_host); return url; }, addVisual: function (elm) { var self = this; var settings = self.settings; var dom = self.dom; var cls; elm = elm || self.getBody(); if (self.hasVisual === undefined) { self.hasVisual = settings.visual; } each$l(dom.select('table,a', elm), function (elm) { var value; switch (elm.nodeName) { case 'TABLE': cls = settings.visual_table_class || 'mce-item-table'; value = dom.getAttrib(elm, 'border'); if ((!value || value === '0') && self.hasVisual) { dom.addClass(elm, cls); } else { dom.removeClass(elm, cls); } return; case 'A': if (!dom.getAttrib(elm, 'href')) { value = dom.getAttrib(elm, 'name') || elm.id; cls = settings.visual_anchor_class || 'mce-item-anchor'; if (value && self.hasVisual) { dom.addClass(elm, cls); } else { dom.removeClass(elm, cls); } } return; } }); self.fire('VisualAid', { element: elm, hasVisual: self.hasVisual }); }, remove: function () { remove$7(this); }, destroy: function (automatic) { destroy(this, automatic); }, uploadImages: function (callback) { return this.editorUpload.uploadImages(callback); }, _scanForImages: function () { return this.editorUpload.scanForImages(); } }; extend$4(Editor.prototype, EditorObservable$1); var isEditorUIElement = function (elm) { return elm.className.toString().indexOf('mce-') !== -1; }; var FocusManager = { isEditorUIElement: isEditorUIElement }; var isManualNodeChange = function (e) { return e.type === 'nodechange' && e.selectionChange; }; var registerPageMouseUp = function (editor, throttledStore) { var mouseUpPage = function () { throttledStore.throttle(); }; DOMUtils$1.DOM.bind(domGlobals.document, 'mouseup', mouseUpPage); editor.on('remove', function () { DOMUtils$1.DOM.unbind(domGlobals.document, 'mouseup', mouseUpPage); }); }; var registerFocusOut = function (editor) { editor.on('focusout', function () { SelectionBookmark.store(editor); }); }; var registerMouseUp = function (editor, throttledStore) { editor.on('mouseup touchend', function (e) { throttledStore.throttle(); }); }; var registerEditorEvents = function (editor, throttledStore) { var browser = PlatformDetection$1.detect().browser; if (browser.isIE()) { registerFocusOut(editor); } else { registerMouseUp(editor, throttledStore); } editor.on('keyup nodechange', function (e) { if (!isManualNodeChange(e)) { SelectionBookmark.store(editor); } }); }; var register$3 = function (editor) { var throttledStore = first(function () { SelectionBookmark.store(editor); }, 0); if (editor.inline) { registerPageMouseUp(editor, throttledStore); } editor.on('init', function () { registerEditorEvents(editor, throttledStore); }); editor.on('remove', function () { throttledStore.cancel(); }); }; var SelectionRestore = { register: register$3 }; var documentFocusInHandler; var DOM$8 = DOMUtils$1.DOM; var isEditorUIElement$1 = function (elm) { return FocusManager.isEditorUIElement(elm); }; var isUIElement = function (editor, elm) { var customSelector = editor ? editor.settings.custom_ui_selector : ''; var parent = DOM$8.getParent(elm, function (elm) { return isEditorUIElement$1(elm) || (customSelector ? editor.dom.is(elm, customSelector) : false); }); return parent !== null; }; var getActiveElement = function () { try { return domGlobals.document.activeElement; } catch (ex) { return domGlobals.document.body; } }; var registerEvents = function (editorManager, e) { var editor = e.editor; SelectionRestore.register(editor); editor.on('focusin', function () { var self = this; var focusedEditor = editorManager.focusedEditor; if (focusedEditor !== self) { if (focusedEditor) { focusedEditor.fire('blur', { focusedEditor: self }); } editorManager.setActive(self); editorManager.focusedEditor = self; self.fire('focus', { blurredEditor: focusedEditor }); self.focus(true); } }); editor.on('focusout', function () { var self = this; Delay.setEditorTimeout(self, function () { var focusedEditor = editorManager.focusedEditor; if (!isUIElement(self, getActiveElement()) && focusedEditor === self) { self.fire('blur', { focusedEditor: null }); editorManager.focusedEditor = null; } }); }); if (!documentFocusInHandler) { documentFocusInHandler = function (e) { var activeEditor = editorManager.activeEditor; var target; target = e.target; if (activeEditor && target.ownerDocument === domGlobals.document) { if (target !== domGlobals.document.body && !isUIElement(activeEditor, target) && editorManager.focusedEditor === activeEditor) { activeEditor.fire('blur', { focusedEditor: null }); editorManager.focusedEditor = null; } } }; DOM$8.bind(domGlobals.document, 'focusin', documentFocusInHandler); } }; var unregisterDocumentEvents = function (editorManager, e) { if (editorManager.focusedEditor === e.editor) { editorManager.focusedEditor = null; } if (!editorManager.activeEditor) { DOM$8.unbind(domGlobals.document, 'focusin', documentFocusInHandler); documentFocusInHandler = null; } }; var setup$h = function (editorManager) { editorManager.on('AddEditor', curry(registerEvents, editorManager)); editorManager.on('RemoveEditor', curry(unregisterDocumentEvents, editorManager)); }; var FocusController = { setup: setup$h, isEditorUIElement: isEditorUIElement$1, isUIElement: isUIElement }; var DOM$9 = DOMUtils$1.DOM; var explode$4 = Tools.explode, each$m = Tools.each, extend$5 = Tools.extend; var instanceCounter = 0, beforeUnloadDelegate, EditorManager, boundGlobalEvents = false; var legacyEditors = []; var editors = []; var isValidLegacyKey = function (id) { return id !== 'length'; }; var globalEventDelegate = function (e) { var type = e.type; each$m(EditorManager.get(), function (editor) { switch (type) { case 'scroll': editor.fire('ScrollWindow', e); break; case 'resize': editor.fire('ResizeWindow', e); break; } }); }; var toggleGlobalEvents = function (state) { if (state !== boundGlobalEvents) { if (state) { DomQuery(window).on('resize scroll', globalEventDelegate); } else { DomQuery(window).off('resize scroll', globalEventDelegate); } boundGlobalEvents = state; } }; var removeEditorFromList = function (targetEditor) { var oldEditors = editors; delete legacyEditors[targetEditor.id]; for (var i = 0; i < legacyEditors.length; i++) { if (legacyEditors[i] === targetEditor) { legacyEditors.splice(i, 1); break; } } editors = filter(editors, function (editor) { return targetEditor !== editor; }); if (EditorManager.activeEditor === targetEditor) { EditorManager.activeEditor = editors.length > 0 ? editors[0] : null; } if (EditorManager.focusedEditor === targetEditor) { EditorManager.focusedEditor = null; } return oldEditors.length !== editors.length; }; var purgeDestroyedEditor = function (editor) { if (editor && editor.initialized && !(editor.getContainer() || editor.getBody()).parentNode) { removeEditorFromList(editor); editor.unbindAllNativeEvents(); editor.destroy(true); editor.removed = true; editor = null; } return editor; }; EditorManager = { defaultSettings: {}, $: DomQuery, majorVersion: '4', minorVersion: '9.4', releaseDate: '2019-03-20', editors: legacyEditors, i18n: I18n, activeEditor: null, settings: {}, setup: function () { var self = this; var baseURL, documentBaseURL, suffix = '', preInit, src; documentBaseURL = URI.getDocumentBaseUrl(domGlobals.document.location); if (/^[^:]+:\/\/\/?[^\/]+\//.test(documentBaseURL)) { documentBaseURL = documentBaseURL.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, ''); if (!/[\/\\]$/.test(documentBaseURL)) { documentBaseURL += '/'; } } preInit = window.tinymce || window.tinyMCEPreInit; if (preInit) { baseURL = preInit.base || preInit.baseURL; suffix = preInit.suffix; } else { var scripts = domGlobals.document.getElementsByTagName('script'); for (var i = 0; i < scripts.length; i++) { src = scripts[i].src; var srcScript = src.substring(src.lastIndexOf('/')); if (/tinymce(\.full|\.jquery|)(\.min|\.dev|)\.js/.test(src)) { if (srcScript.indexOf('.min') !== -1) { suffix = '.min'; } baseURL = src.substring(0, src.lastIndexOf('/')); break; } } if (!baseURL && domGlobals.document.currentScript) { src = domGlobals.document.currentScript.src; if (src.indexOf('.min') !== -1) { suffix = '.min'; } baseURL = src.substring(0, src.lastIndexOf('/')); } } self.baseURL = new URI(documentBaseURL).toAbsolute(baseURL); self.documentBaseURL = documentBaseURL; self.baseURI = new URI(self.baseURL); self.suffix = suffix; FocusController.setup(self); }, overrideDefaults: function (defaultSettings) { var baseUrl, suffix; baseUrl = defaultSettings.base_url; if (baseUrl) { this.baseURL = new URI(this.documentBaseURL).toAbsolute(baseUrl.replace(/\/+$/, '')); this.baseURI = new URI(this.baseURL); } suffix = defaultSettings.suffix; if (defaultSettings.suffix) { this.suffix = suffix; } this.defaultSettings = defaultSettings; var pluginBaseUrls = defaultSettings.plugin_base_urls; for (var name in pluginBaseUrls) { AddOnManager.PluginManager.urls[name] = pluginBaseUrls[name]; } }, init: function (settings) { var self = this; var result, invalidInlineTargets; invalidInlineTargets = Tools.makeMap('area base basefont br col frame hr img input isindex link meta param embed source wbr track ' + 'colgroup option tbody tfoot thead tr script noscript style textarea video audio iframe object menu', ' '); var isInvalidInlineTarget = function (settings, elm) { return settings.inline && elm.tagName.toLowerCase() in invalidInlineTargets; }; var createId = function (elm) { var id = elm.id; if (!id) { id = elm.name; if (id && !DOM$9.get(id)) { id = elm.name; } else { id = DOM$9.uniqueId(); } elm.setAttribute('id', id); } return id; }; var execCallback = function (name) { var callback = settings[name]; if (!callback) { return; } return callback.apply(self, Array.prototype.slice.call(arguments, 2)); }; var hasClass = function (elm, className) { return className.constructor === RegExp ? className.test(elm.className) : DOM$9.hasClass(elm, className); }; var findTargets = function (settings) { var l, targets = []; if (Env.ie && Env.ie < 11) { ErrorReporter.initError('TinyMCE does not support the browser you are using. For a list of supported' + ' browsers please see: https://www.tinymce.com/docs/get-started/system-requirements/'); return []; } if (settings.types) { each$m(settings.types, function (type) { targets = targets.concat(DOM$9.select(type.selector)); }); return targets; } else if (settings.selector) { return DOM$9.select(settings.selector); } else if (settings.target) { return [settings.target]; } switch (settings.mode) { case 'exact': l = settings.elements || ''; if (l.length > 0) { each$m(explode$4(l), function (id) { var elm; if (elm = DOM$9.get(id)) { targets.push(elm); } else { each$m(domGlobals.document.forms, function (f) { each$m(f.elements, function (e) { if (e.name === id) { id = 'mce_editor_' + instanceCounter++; DOM$9.setAttrib(e, 'id', id); targets.push(e); } }); }); } }); } break; case 'textareas': case 'specific_textareas': each$m(DOM$9.select('textarea'), function (elm) { if (settings.editor_deselector && hasClass(elm, settings.editor_deselector)) { return; } if (!settings.editor_selector || hasClass(elm, settings.editor_selector)) { targets.push(elm); } }); break; } return targets; }; var provideResults = function (editors) { result = editors; }; var initEditors = function () { var initCount = 0; var editors = []; var targets; var createEditor = function (id, settings, targetElm) { var editor = new Editor(id, settings, self); editors.push(editor); editor.on('init', function () { if (++initCount === targets.length) { provideResults(editors); } }); editor.targetElm = editor.targetElm || targetElm; editor.render(); }; DOM$9.unbind(window, 'ready', initEditors); execCallback('onpageload'); targets = DomQuery.unique(findTargets(settings)); if (settings.types) { each$m(settings.types, function (type) { Tools.each(targets, function (elm) { if (DOM$9.is(elm, type.selector)) { createEditor(createId(elm), extend$5({}, settings, type), elm); return false; } return true; }); }); return; } Tools.each(targets, function (elm) { purgeDestroyedEditor(self.get(elm.id)); }); targets = Tools.grep(targets, function (elm) { return !self.get(elm.id); }); if (targets.length === 0) { provideResults([]); } else { each$m(targets, function (elm) { if (isInvalidInlineTarget(settings, elm)) { ErrorReporter.initError('Could not initialize inline editor on invalid inline target element', elm); } else { createEditor(createId(elm), settings, elm); } }); } }; self.settings = settings; DOM$9.bind(window, 'ready', initEditors); return new promiseObj(function (resolve) { if (result) { resolve(result); } else { provideResults = function (editors) { resolve(editors); }; } }); }, get: function (id) { if (arguments.length === 0) { return editors.slice(0); } else if (isString(id)) { return find(editors, function (editor) { return editor.id === id; }).getOr(null); } else if (isNumber(id)) { return editors[id] ? editors[id] : null; } else { return null; } }, add: function (editor) { var self = this; var existingEditor; existingEditor = legacyEditors[editor.id]; if (existingEditor === editor) { return editor; } if (self.get(editor.id) === null) { if (isValidLegacyKey(editor.id)) { legacyEditors[editor.id] = editor; } legacyEditors.push(editor); editors.push(editor); } toggleGlobalEvents(true); self.activeEditor = editor; self.fire('AddEditor', { editor: editor }); if (!beforeUnloadDelegate) { beforeUnloadDelegate = function () { self.fire('BeforeUnload'); }; DOM$9.bind(window, 'beforeunload', beforeUnloadDelegate); } return editor; }, createEditor: function (id, settings) { return this.add(new Editor(id, settings, this)); }, remove: function (selector) { var self = this; var i, editor; if (!selector) { for (i = editors.length - 1; i >= 0; i--) { self.remove(editors[i]); } return; } if (isString(selector)) { each$m(DOM$9.select(selector), function (elm) { editor = self.get(elm.id); if (editor) { self.remove(editor); } }); return; } editor = selector; if (isNull(self.get(editor.id))) { return null; } if (removeEditorFromList(editor)) { self.fire('RemoveEditor', { editor: editor }); } if (editors.length === 0) { DOM$9.unbind(window, 'beforeunload', beforeUnloadDelegate); } editor.remove(); toggleGlobalEvents(editors.length > 0); return editor; }, execCommand: function (cmd, ui, value) { var self = this, editor = self.get(value); switch (cmd) { case 'mceAddEditor': if (!self.get(value)) { new Editor(value, self.settings, self).render(); } return true; case 'mceRemoveEditor': if (editor) { editor.remove(); } return true; case 'mceToggleEditor': if (!editor) { self.execCommand('mceAddEditor', 0, value); return true; } if (editor.isHidden()) { editor.show(); } else { editor.hide(); } return true; } if (self.activeEditor) { return self.activeEditor.execCommand(cmd, ui, value); } return false; }, triggerSave: function () { each$m(editors, function (editor) { editor.save(); }); }, addI18n: function (code, items) { I18n.add(code, items); }, translate: function (text) { return I18n.translate(text); }, setActive: function (editor) { var activeEditor = this.activeEditor; if (this.activeEditor !== editor) { if (activeEditor) { activeEditor.fire('deactivate', { relatedTarget: editor }); } editor.fire('activate', { relatedTarget: activeEditor }); } this.activeEditor = editor; } }; extend$5(EditorManager, Observable); EditorManager.setup(); var EditorManager$1 = EditorManager; function RangeUtils(dom) { var walk = function (rng, callback) { return RangeWalk.walk(dom, rng, callback); }; var split = SplitRange.split; var normalize = function (rng) { return NormalizeRange.normalize(dom, rng).fold(constant(false), function (normalizedRng) { rng.setStart(normalizedRng.startContainer, normalizedRng.startOffset); rng.setEnd(normalizedRng.endContainer, normalizedRng.endOffset); return true; }); }; return { walk: walk, split: split, normalize: normalize }; } (function (RangeUtils) { RangeUtils.compareRanges = RangeCompare.isEq; RangeUtils.getCaretRangeFromPoint = CaretRangeFromPoint.fromPoint; RangeUtils.getSelectedNode = getSelectedNode; RangeUtils.getNode = getNode; }(RangeUtils || (RangeUtils = {}))); var RangeUtils$1 = RangeUtils; var min = Math.min, max = Math.max, round$2 = Math.round; var relativePosition = function (rect, targetRect, rel) { var x, y, w, h, targetW, targetH; x = targetRect.x; y = targetRect.y; w = rect.w; h = rect.h; targetW = targetRect.w; targetH = targetRect.h; rel = (rel || '').split(''); if (rel[0] === 'b') { y += targetH; } if (rel[1] === 'r') { x += targetW; } if (rel[0] === 'c') { y += round$2(targetH / 2); } if (rel[1] === 'c') { x += round$2(targetW / 2); } if (rel[3] === 'b') { y -= h; } if (rel[4] === 'r') { x -= w; } if (rel[3] === 'c') { y -= round$2(h / 2); } if (rel[4] === 'c') { x -= round$2(w / 2); } return create$3(x, y, w, h); }; var findBestRelativePosition = function (rect, targetRect, constrainRect, rels) { var pos, i; for (i = 0; i < rels.length; i++) { pos = relativePosition(rect, targetRect, rels[i]); if (pos.x >= constrainRect.x && pos.x + pos.w <= constrainRect.w + constrainRect.x && pos.y >= constrainRect.y && pos.y + pos.h <= constrainRect.h + constrainRect.y) { return rels[i]; } } return null; }; var inflate = function (rect, w, h) { return create$3(rect.x - w, rect.y - h, rect.w + w * 2, rect.h + h * 2); }; var intersect = function (rect, cropRect) { var x1, y1, x2, y2; x1 = max(rect.x, cropRect.x); y1 = max(rect.y, cropRect.y); x2 = min(rect.x + rect.w, cropRect.x + cropRect.w); y2 = min(rect.y + rect.h, cropRect.y + cropRect.h); if (x2 - x1 < 0 || y2 - y1 < 0) { return null; } return create$3(x1, y1, x2 - x1, y2 - y1); }; var clamp$1 = function (rect, clampRect, fixedSize) { var underflowX1, underflowY1, overflowX2, overflowY2, x1, y1, x2, y2, cx2, cy2; x1 = rect.x; y1 = rect.y; x2 = rect.x + rect.w; y2 = rect.y + rect.h; cx2 = clampRect.x + clampRect.w; cy2 = clampRect.y + clampRect.h; underflowX1 = max(0, clampRect.x - x1); underflowY1 = max(0, clampRect.y - y1); overflowX2 = max(0, x2 - cx2); overflowY2 = max(0, y2 - cy2); x1 += underflowX1; y1 += underflowY1; if (fixedSize) { x2 += underflowX1; y2 += underflowY1; x1 -= overflowX2; y1 -= overflowY2; } x2 -= overflowX2; y2 -= overflowY2; return create$3(x1, y1, x2 - x1, y2 - y1); }; var create$3 = function (x, y, w, h) { return { x: x, y: y, w: w, h: h }; }; var fromClientRect = function (clientRect) { return create$3(clientRect.left, clientRect.top, clientRect.width, clientRect.height); }; var Rect = { inflate: inflate, relativePosition: relativePosition, findBestRelativePosition: findBestRelativePosition, intersect: intersect, clamp: clamp$1, create: create$3, fromClientRect: fromClientRect }; var types = {}; var Factory = { add: function (type, typeClass) { types[type.toLowerCase()] = typeClass; }, has: function (type) { return !!types[type.toLowerCase()]; }, get: function (type) { var lctype = type.toLowerCase(); var controlType = types.hasOwnProperty(lctype) ? types[lctype] : null; if (controlType === null) { throw new Error('Could not find module for type: ' + type); } return controlType; }, create: function (type, settings) { var ControlType; if (typeof type === 'string') { settings = settings || {}; settings.type = type; } else { settings = type; type = settings.type; } type = type.toLowerCase(); ControlType = types[type]; if (!ControlType) { throw new Error('Could not find control by type: ' + type); } ControlType = new ControlType(settings); ControlType.type = type; return ControlType; } }; var each$n = Tools.each, extend$6 = Tools.extend; var extendClass, initializing; var Class = function () { }; Class.extend = extendClass = function (prop) { var self = this; var _super = self.prototype; var prototype, name, member; var Class = function () { var i, mixins, mixin; var self = this; if (!initializing) { if (self.init) { self.init.apply(self, arguments); } mixins = self.Mixins; if (mixins) { i = mixins.length; while (i--) { mixin = mixins[i]; if (mixin.init) { mixin.init.apply(self, arguments); } } } } }; var dummy = function () { return this; }; var createMethod = function (name, fn) { return function () { var self = this; var tmp = self._super; var ret; self._super = _super[name]; ret = fn.apply(self, arguments); self._super = tmp; return ret; }; }; initializing = true; prototype = new self(); initializing = false; if (prop.Mixins) { each$n(prop.Mixins, function (mixin) { for (var name_1 in mixin) { if (name_1 !== 'init') { prop[name_1] = mixin[name_1]; } } }); if (_super.Mixins) { prop.Mixins = _super.Mixins.concat(prop.Mixins); } } if (prop.Methods) { each$n(prop.Methods.split(','), function (name) { prop[name] = dummy; }); } if (prop.Properties) { each$n(prop.Properties.split(','), function (name) { var fieldName = '_' + name; prop[name] = function (value) { var self = this; if (value !== undefined) { self[fieldName] = value; return self; } return self[fieldName]; }; }); } if (prop.Statics) { each$n(prop.Statics, function (func, name) { Class[name] = func; }); } if (prop.Defaults && _super.Defaults) { prop.Defaults = extend$6({}, _super.Defaults, prop.Defaults); } for (name in prop) { member = prop[name]; if (typeof member === 'function' && _super[name]) { prototype[name] = createMethod(name, member); } else { prototype[name] = member; } } Class.prototype = prototype; Class.constructor = Class; Class.extend = extendClass; return Class; }; var min$1 = Math.min, max$1 = Math.max, round$3 = Math.round; var Color = function (value) { var self = {}; var r = 0, g = 0, b = 0; var rgb2hsv = function (r, g, b) { var h, s, v, d, minRGB, maxRGB; h = 0; s = 0; v = 0; r = r / 255; g = g / 255; b = b / 255; minRGB = min$1(r, min$1(g, b)); maxRGB = max$1(r, max$1(g, b)); if (minRGB === maxRGB) { v = minRGB; return { h: 0, s: 0, v: v * 100 }; } d = r === minRGB ? g - b : b === minRGB ? r - g : b - r; h = r === minRGB ? 3 : b === minRGB ? 1 : 5; h = 60 * (h - d / (maxRGB - minRGB)); s = (maxRGB - minRGB) / maxRGB; v = maxRGB; return { h: round$3(h), s: round$3(s * 100), v: round$3(v * 100) }; }; var hsvToRgb = function (hue, saturation, brightness) { var side, chroma, x, match; hue = (parseInt(hue, 10) || 0) % 360; saturation = parseInt(saturation, 10) / 100; brightness = parseInt(brightness, 10) / 100; saturation = max$1(0, min$1(saturation, 1)); brightness = max$1(0, min$1(brightness, 1)); if (saturation === 0) { r = g = b = round$3(255 * brightness); return; } side = hue / 60; chroma = brightness * saturation; x = chroma * (1 - Math.abs(side % 2 - 1)); match = brightness - chroma; switch (Math.floor(side)) { case 0: r = chroma; g = x; b = 0; break; case 1: r = x; g = chroma; b = 0; break; case 2: r = 0; g = chroma; b = x; break; case 3: r = 0; g = x; b = chroma; break; case 4: r = x; g = 0; b = chroma; break; case 5: r = chroma; g = 0; b = x; break; default: r = g = b = 0; } r = round$3(255 * (r + match)); g = round$3(255 * (g + match)); b = round$3(255 * (b + match)); }; var toHex = function () { var hex = function (val) { val = parseInt(val, 10).toString(16); return val.length > 1 ? val : '0' + val; }; return '#' + hex(r) + hex(g) + hex(b); }; var toRgb = function () { return { r: r, g: g, b: b }; }; var toHsv = function () { return rgb2hsv(r, g, b); }; var parse = function (value) { var matches; if (typeof value === 'object') { if ('r' in value) { r = value.r; g = value.g; b = value.b; } else if ('v' in value) { hsvToRgb(value.h, value.s, value.v); } } else { if (matches = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)[^\)]*\)/gi.exec(value)) { r = parseInt(matches[1], 10); g = parseInt(matches[2], 10); b = parseInt(matches[3], 10); } else if (matches = /#([0-F]{2})([0-F]{2})([0-F]{2})/gi.exec(value)) { r = parseInt(matches[1], 16); g = parseInt(matches[2], 16); b = parseInt(matches[3], 16); } else if (matches = /#([0-F])([0-F])([0-F])/gi.exec(value)) { r = parseInt(matches[1] + matches[1], 16); g = parseInt(matches[2] + matches[2], 16); b = parseInt(matches[3] + matches[3], 16); } } r = r < 0 ? 0 : r > 255 ? 255 : r; g = g < 0 ? 0 : g > 255 ? 255 : g; b = b < 0 ? 0 : b > 255 ? 255 : b; return self; }; if (value) { parse(value); } self.toRgb = toRgb; self.toHsv = toHsv; self.toHex = toHex; self.parse = parse; return self; }; var serialize = function (o, quote) { var i, v, t, name; quote = quote || '"'; if (o === null) { return 'null'; } t = typeof o; if (t === 'string') { v = '\bb\tt\nn\ff\rr""\'\'\\\\'; return quote + o.replace(/([\u0080-\uFFFF\x00-\x1f\"\'\\])/g, function (a, b) { if (quote === '"' && a === '\'') { return a; } i = v.indexOf(b); if (i + 1) { return '\\' + v.charAt(i + 1); } a = b.charCodeAt().toString(16); return '\\u' + '0000'.substring(a.length) + a; }) + quote; } if (t === 'object') { if (o.hasOwnProperty && Object.prototype.toString.call(o) === '[object Array]') { for (i = 0, v = '['; i < o.length; i++) { v += (i > 0 ? ',' : '') + serialize(o[i], quote); } return v + ']'; } v = '{'; for (name in o) { if (o.hasOwnProperty(name)) { v += typeof o[name] !== 'function' ? (v.length > 1 ? ',' + quote : quote) + name + quote + ':' + serialize(o[name], quote) : ''; } } return v + '}'; } return '' + o; }; var JSON$1 = { serialize: serialize, parse: function (text) { try { return JSON.parse(text); } catch (ex) { } } }; var JSONP = { callbacks: {}, count: 0, send: function (settings) { var self = this, dom = DOMUtils$1.DOM, count = settings.count !== undefined ? settings.count : self.count; var id = 'tinymce_jsonp_' + count; self.callbacks[count] = function (json) { dom.remove(id); delete self.callbacks[count]; settings.callback(json); }; dom.add(dom.doc.body, 'script', { id: id, src: settings.url, type: 'text/javascript' }); self.count++; } }; var XHR = { send: function (settings) { var xhr, count = 0; var ready = function () { if (!settings.async || xhr.readyState === 4 || count++ > 10000) { if (settings.success && count < 10000 && xhr.status === 200) { settings.success.call(settings.success_scope, '' + xhr.responseText, xhr, settings); } else if (settings.error) { settings.error.call(settings.error_scope, count > 10000 ? 'TIMED_OUT' : 'GENERAL', xhr, settings); } xhr = null; } else { setTimeout(ready, 10); } }; settings.scope = settings.scope || this; settings.success_scope = settings.success_scope || settings.scope; settings.error_scope = settings.error_scope || settings.scope; settings.async = settings.async === false ? false : true; settings.data = settings.data || ''; XHR.fire('beforeInitialize', { settings: settings }); xhr = XMLHttpRequest(); if (xhr) { if (xhr.overrideMimeType) { xhr.overrideMimeType(settings.content_type); } xhr.open(settings.type || (settings.data ? 'POST' : 'GET'), settings.url, settings.async); if (settings.crossDomain) { xhr.withCredentials = true; } if (settings.content_type) { xhr.setRequestHeader('Content-Type', settings.content_type); } if (settings.requestheaders) { Tools.each(settings.requestheaders, function (header) { xhr.setRequestHeader(header.key, header.value); }); } xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); xhr = XHR.fire('beforeSend', { xhr: xhr, settings: settings }).xhr; xhr.send(settings.data); if (!settings.async) { return ready(); } setTimeout(ready, 10); } } }; Tools.extend(XHR, Observable); var extend$7 = Tools.extend; var JSONRequest = function (settings) { this.settings = extend$7({}, settings); this.count = 0; }; JSONRequest.sendRPC = function (o) { return new JSONRequest().send(o); }; JSONRequest.prototype = { send: function (args) { var ecb = args.error, scb = args.success; args = extend$7(this.settings, args); args.success = function (c, x) { c = JSON$1.parse(c); if (typeof c === 'undefined') { c = { error: 'JSON Parse error.' }; } if (c.error) { ecb.call(args.error_scope || args.scope, c.error, x); } else { scb.call(args.success_scope || args.scope, c.result); } }; args.error = function (ty, x) { if (ecb) { ecb.call(args.error_scope || args.scope, ty, x); } }; args.data = JSON$1.serialize({ id: args.id || 'c' + this.count++, method: args.method, params: args.params }); args.content_type = 'application/json'; XHR.send(args); } }; var create$4 = function () { return function () { var data = {}; var keys = []; var storage = { getItem: function (key) { var item = data[key]; return item ? item : null; }, setItem: function (key, value) { keys.push(key); data[key] = String(value); }, key: function (index) { return keys[index]; }, removeItem: function (key) { keys = keys.filter(function (k) { return k === key; }); delete data[key]; }, clear: function () { keys = []; data = {}; }, length: 0 }; Object.defineProperty(storage, 'length', { get: function () { return keys.length; }, configurable: false, enumerable: false }); return storage; }(); }; var localStorage; try { localStorage = domGlobals.window.localStorage; } catch (e) { localStorage = create$4(); } var LocalStorage = localStorage; var tinymce = EditorManager$1; var publicApi = { geom: { Rect: Rect }, util: { Promise: promiseObj, Delay: Delay, Tools: Tools, VK: VK, URI: URI, Class: Class, EventDispatcher: Dispatcher, Observable: Observable, I18n: I18n, XHR: XHR, JSON: JSON$1, JSONRequest: JSONRequest, JSONP: JSONP, LocalStorage: LocalStorage, Color: Color }, dom: { EventUtils: EventUtils, Sizzle: Sizzle, DomQuery: DomQuery, TreeWalker: TreeWalker, DOMUtils: DOMUtils$1, ScriptLoader: ScriptLoader, RangeUtils: RangeUtils$1, Serializer: DomSerializer$1, ControlSelection: ControlSelection, BookmarkManager: BookmarkManager$1, Selection: Selection, Event: EventUtils.Event }, html: { Styles: Styles, Entities: Entities, Node: Node$1, Schema: Schema, SaxParser: SaxParser$1, DomParser: DomParser, Writer: Writer, Serializer: HtmlSerializer }, ui: { Factory: Factory }, Env: Env, AddOnManager: AddOnManager, Annotator: Annotator, Formatter: Formatter, UndoManager: UndoManager, EditorCommands: EditorCommands, WindowManager: WindowManager, NotificationManager: NotificationManager, EditorObservable: EditorObservable$1, Shortcuts: Shortcuts, Editor: Editor, FocusManager: FocusManager, EditorManager: EditorManager$1, DOM: DOMUtils$1.DOM, ScriptLoader: ScriptLoader.ScriptLoader, PluginManager: AddOnManager.PluginManager, ThemeManager: AddOnManager.ThemeManager, trim: Tools.trim, isArray: Tools.isArray, is: Tools.is, toArray: Tools.toArray, makeMap: Tools.makeMap, each: Tools.each, map: Tools.map, grep: Tools.grep, inArray: Tools.inArray, extend: Tools.extend, create: Tools.create, walk: Tools.walk, createNS: Tools.createNS, resolve: Tools.resolve, explode: Tools.explode, _addCacheSuffix: Tools._addCacheSuffix, isOpera: Env.opera, isWebKit: Env.webkit, isIE: Env.ie, isGecko: Env.gecko, isMac: Env.mac }; tinymce = Tools.extend(tinymce, publicApi); var Tinymce = tinymce; var exportToModuleLoaders = function (tinymce) { if (typeof module === 'object') { try { module.exports = tinymce; } catch (_) { } } }; var exportToWindowGlobal = function (tinymce) { window.tinymce = tinymce; window.tinyMCE = tinymce; }; exportToWindowGlobal(Tinymce); exportToModuleLoaders(Tinymce); }(window)); })(); (function () { var advlist = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var applyListFormat = function (editor, listName, styleValue) { var cmd = listName === 'UL' ? 'InsertUnorderedList' : 'InsertOrderedList'; editor.execCommand(cmd, false, styleValue === false ? null : { 'list-style-type': styleValue }); }; var Actions = { applyListFormat: applyListFormat }; var register = function (editor) { editor.addCommand('ApplyUnorderedListStyle', function (ui, value) { Actions.applyListFormat(editor, 'UL', value['list-style-type']); }); editor.addCommand('ApplyOrderedListStyle', function (ui, value) { Actions.applyListFormat(editor, 'OL', value['list-style-type']); }); }; var Commands = { register: register }; var getNumberStyles = function (editor) { var styles = editor.getParam('advlist_number_styles', 'default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman'); return styles ? styles.split(/[ ,]/) : []; }; var getBulletStyles = function (editor) { var styles = editor.getParam('advlist_bullet_styles', 'default,circle,disc,square'); return styles ? styles.split(/[ ,]/) : []; }; var Settings = { getNumberStyles: getNumberStyles, getBulletStyles: getBulletStyles }; var isChildOfBody = function (editor, elm) { return editor.$.contains(editor.getBody(), elm); }; var isTableCellNode = function (node) { return node && /^(TH|TD)$/.test(node.nodeName); }; var isListNode = function (editor) { return function (node) { return node && /^(OL|UL|DL)$/.test(node.nodeName) && isChildOfBody(editor, node); }; }; var getSelectedStyleType = function (editor) { var listElm = editor.dom.getParent(editor.selection.getNode(), 'ol,ul'); return editor.dom.getStyle(listElm, 'listStyleType') || ''; }; var ListUtils = { isTableCellNode: isTableCellNode, isListNode: isListNode, getSelectedStyleType: getSelectedStyleType }; var styleValueToText = function (styleValue) { return styleValue.replace(/\-/g, ' ').replace(/\b\w/g, function (chr) { return chr.toUpperCase(); }); }; var toMenuItems = function (styles) { return global$1.map(styles, function (styleValue) { var text = styleValueToText(styleValue); var data = styleValue === 'default' ? '' : styleValue; return { text: text, data: data }; }); }; var ListStyles = { toMenuItems: toMenuItems }; var findIndex = function (list, predicate) { for (var index = 0; index < list.length; index++) { var element = list[index]; if (predicate(element)) { return index; } } return -1; }; var listState = function (editor, listName) { return function (e) { var ctrl = e.control; editor.on('NodeChange', function (e) { var tableCellIndex = findIndex(e.parents, ListUtils.isTableCellNode); var parents = tableCellIndex !== -1 ? e.parents.slice(0, tableCellIndex) : e.parents; var lists = global$1.grep(parents, ListUtils.isListNode(editor)); ctrl.active(lists.length > 0 && lists[0].nodeName === listName); }); }; }; var updateSelection = function (editor) { return function (e) { var listStyleType = ListUtils.getSelectedStyleType(editor); e.control.items().each(function (ctrl) { ctrl.active(ctrl.settings.data === listStyleType); }); }; }; var addSplitButton = function (editor, id, tooltip, cmd, nodeName, styles) { editor.addButton(id, { active: false, type: 'splitbutton', tooltip: tooltip, menu: ListStyles.toMenuItems(styles), onPostRender: listState(editor, nodeName), onshow: updateSelection(editor), onselect: function (e) { Actions.applyListFormat(editor, nodeName, e.control.settings.data); }, onclick: function () { editor.execCommand(cmd); } }); }; var addButton = function (editor, id, tooltip, cmd, nodeName, styles) { editor.addButton(id, { active: false, type: 'button', tooltip: tooltip, onPostRender: listState(editor, nodeName), onclick: function () { editor.execCommand(cmd); } }); }; var addControl = function (editor, id, tooltip, cmd, nodeName, styles) { if (styles.length > 0) { addSplitButton(editor, id, tooltip, cmd, nodeName, styles); } else { addButton(editor, id, tooltip, cmd, nodeName, styles); } }; var register$1 = function (editor) { addControl(editor, 'numlist', 'Numbered list', 'InsertOrderedList', 'OL', Settings.getNumberStyles(editor)); addControl(editor, 'bullist', 'Bullet list', 'InsertUnorderedList', 'UL', Settings.getBulletStyles(editor)); }; var Buttons = { register: register$1 }; global.add('advlist', function (editor) { var hasPlugin = function (editor, plugin) { var plugins = editor.settings.plugins ? editor.settings.plugins : ''; return global$1.inArray(plugins.split(/[ ,]/), plugin) !== -1; }; if (hasPlugin(editor, 'lists')) { Buttons.register(editor); Commands.register(editor); } }); function Plugin () { } return Plugin; }()); })(); (function () { var anchor = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var isValidId = function (id) { return /^[A-Za-z][A-Za-z0-9\-:._]*$/.test(id); }; var getId = function (editor) { var selectedNode = editor.selection.getNode(); var isAnchor = selectedNode.tagName === 'A' && editor.dom.getAttrib(selectedNode, 'href') === ''; return isAnchor ? selectedNode.id || selectedNode.name : ''; }; var insert = function (editor, id) { var selectedNode = editor.selection.getNode(); var isAnchor = selectedNode.tagName === 'A' && editor.dom.getAttrib(selectedNode, 'href') === ''; if (isAnchor) { selectedNode.removeAttribute('name'); selectedNode.id = id; editor.undoManager.add(); } else { editor.focus(); editor.selection.collapse(true); editor.execCommand('mceInsertContent', false, editor.dom.createHTML('a', { id: id })); } }; var Anchor = { isValidId: isValidId, getId: getId, insert: insert }; var insertAnchor = function (editor, newId) { if (!Anchor.isValidId(newId)) { editor.windowManager.alert('Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.'); return true; } else { Anchor.insert(editor, newId); return false; } }; var open = function (editor) { var currentId = Anchor.getId(editor); editor.windowManager.open({ title: 'Anchor', body: { type: 'textbox', name: 'id', size: 40, label: 'Id', value: currentId }, onsubmit: function (e) { var newId = e.data.id; if (insertAnchor(editor, newId)) { e.preventDefault(); } } }); }; var Dialog = { open: open }; var register = function (editor) { editor.addCommand('mceAnchor', function () { Dialog.open(editor); }); }; var Commands = { register: register }; var isAnchorNode = function (node) { return !node.attr('href') && (node.attr('id') || node.attr('name')) && !node.firstChild; }; var setContentEditable = function (state) { return function (nodes) { for (var i = 0; i < nodes.length; i++) { if (isAnchorNode(nodes[i])) { nodes[i].attr('contenteditable', state); } } }; }; var setup = function (editor) { editor.on('PreInit', function () { editor.parser.addNodeFilter('a', setContentEditable('false')); editor.serializer.addNodeFilter('a', setContentEditable(null)); }); }; var FilterContent = { setup: setup }; var register$1 = function (editor) { editor.addButton('anchor', { icon: 'anchor', tooltip: 'Anchor', cmd: 'mceAnchor', stateSelector: 'a:not([href])' }); editor.addMenuItem('anchor', { icon: 'anchor', text: 'Anchor', context: 'insert', cmd: 'mceAnchor' }); }; var Buttons = { register: register$1 }; global.add('anchor', function (editor) { FilterContent.setup(editor); Commands.register(editor); Buttons.register(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var autolink = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.Env'); var getAutoLinkPattern = function (editor) { return editor.getParam('autolink_pattern', /^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i); }; var getDefaultLinkTarget = function (editor) { return editor.getParam('default_link_target', ''); }; var Settings = { getAutoLinkPattern: getAutoLinkPattern, getDefaultLinkTarget: getDefaultLinkTarget }; var rangeEqualsDelimiterOrSpace = function (rangeString, delimiter) { return rangeString === delimiter || rangeString === ' ' || rangeString.charCodeAt(0) === 160; }; var handleEclipse = function (editor) { parseCurrentLine(editor, -1, '('); }; var handleSpacebar = function (editor) { parseCurrentLine(editor, 0, ''); }; var handleEnter = function (editor) { parseCurrentLine(editor, -1, ''); }; var scopeIndex = function (container, index) { if (index < 0) { index = 0; } if (container.nodeType === 3) { var len = container.data.length; if (index > len) { index = len; } } return index; }; var setStart = function (rng, container, offset) { if (container.nodeType !== 1 || container.hasChildNodes()) { rng.setStart(container, scopeIndex(container, offset)); } else { rng.setStartBefore(container); } }; var setEnd = function (rng, container, offset) { if (container.nodeType !== 1 || container.hasChildNodes()) { rng.setEnd(container, scopeIndex(container, offset)); } else { rng.setEndAfter(container); } }; var parseCurrentLine = function (editor, endOffset, delimiter) { var rng, end, start, endContainer, bookmark, text, matches, prev, len, rngText; var autoLinkPattern = Settings.getAutoLinkPattern(editor); var defaultLinkTarget = Settings.getDefaultLinkTarget(editor); if (editor.selection.getNode().tagName === 'A') { return; } rng = editor.selection.getRng(true).cloneRange(); if (rng.startOffset < 5) { prev = rng.endContainer.previousSibling; if (!prev) { if (!rng.endContainer.firstChild || !rng.endContainer.firstChild.nextSibling) { return; } prev = rng.endContainer.firstChild.nextSibling; } len = prev.length; setStart(rng, prev, len); setEnd(rng, prev, len); if (rng.endOffset < 5) { return; } end = rng.endOffset; endContainer = prev; } else { endContainer = rng.endContainer; if (endContainer.nodeType !== 3 && endContainer.firstChild) { while (endContainer.nodeType !== 3 && endContainer.firstChild) { endContainer = endContainer.firstChild; } if (endContainer.nodeType === 3) { setStart(rng, endContainer, 0); setEnd(rng, endContainer, endContainer.nodeValue.length); } } if (rng.endOffset === 1) { end = 2; } else { end = rng.endOffset - 1 - endOffset; } } start = end; do { setStart(rng, endContainer, end >= 2 ? end - 2 : 0); setEnd(rng, endContainer, end >= 1 ? end - 1 : 0); end -= 1; rngText = rng.toString(); } while (rngText !== ' ' && rngText !== '' && rngText.charCodeAt(0) !== 160 && end - 2 >= 0 && rngText !== delimiter); if (rangeEqualsDelimiterOrSpace(rng.toString(), delimiter)) { setStart(rng, endContainer, end); setEnd(rng, endContainer, start); end += 1; } else if (rng.startOffset === 0) { setStart(rng, endContainer, 0); setEnd(rng, endContainer, start); } else { setStart(rng, endContainer, end); setEnd(rng, endContainer, start); } text = rng.toString(); if (text.charAt(text.length - 1) === '.') { setEnd(rng, endContainer, start - 1); } text = rng.toString().trim(); matches = text.match(autoLinkPattern); if (matches) { if (matches[1] === 'www.') { matches[1] = 'http://www.'; } else if (/@$/.test(matches[1]) && !/^mailto:/.test(matches[1])) { matches[1] = 'mailto:' + matches[1]; } bookmark = editor.selection.getBookmark(); editor.selection.setRng(rng); editor.execCommand('createlink', false, matches[1] + matches[2]); if (defaultLinkTarget) { editor.dom.setAttrib(editor.selection.getNode(), 'target', defaultLinkTarget); } editor.selection.moveToBookmark(bookmark); editor.nodeChanged(); } }; var setup = function (editor) { var autoUrlDetectState; editor.on('keydown', function (e) { if (e.keyCode === 13) { return handleEnter(editor); } }); if (global$1.ie) { editor.on('focus', function () { if (!autoUrlDetectState) { autoUrlDetectState = true; try { editor.execCommand('AutoUrlDetect', false, true); } catch (ex) { } } }); return; } editor.on('keypress', function (e) { if (e.keyCode === 41) { return handleEclipse(editor); } }); editor.on('keyup', function (e) { if (e.keyCode === 32) { return handleSpacebar(editor); } }); }; var Keys = { setup: setup }; global.add('autolink', function (editor) { Keys.setup(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var autoresize = (function () { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.Env'); var global$2 = tinymce.util.Tools.resolve('tinymce.util.Delay'); var getAutoResizeMinHeight = function (editor) { return parseInt(editor.getParam('autoresize_min_height', editor.getElement().offsetHeight), 10); }; var getAutoResizeMaxHeight = function (editor) { return parseInt(editor.getParam('autoresize_max_height', 0), 10); }; var getAutoResizeOverflowPadding = function (editor) { return editor.getParam('autoresize_overflow_padding', 1); }; var getAutoResizeBottomMargin = function (editor) { return editor.getParam('autoresize_bottom_margin', 50); }; var shouldAutoResizeOnInit = function (editor) { return editor.getParam('autoresize_on_init', true); }; var Settings = { getAutoResizeMinHeight: getAutoResizeMinHeight, getAutoResizeMaxHeight: getAutoResizeMaxHeight, getAutoResizeOverflowPadding: getAutoResizeOverflowPadding, getAutoResizeBottomMargin: getAutoResizeBottomMargin, shouldAutoResizeOnInit: shouldAutoResizeOnInit }; var isFullscreen = function (editor) { return editor.plugins.fullscreen && editor.plugins.fullscreen.isFullscreen(); }; var wait = function (editor, oldSize, times, interval, callback) { global$2.setEditorTimeout(editor, function () { resize(editor, oldSize); if (times--) { wait(editor, oldSize, times, interval, callback); } else if (callback) { callback(); } }, interval); }; var toggleScrolling = function (editor, state) { var body = editor.getBody(); if (body) { body.style.overflowY = state ? '' : 'hidden'; if (!state) { body.scrollTop = 0; } } }; var resize = function (editor, oldSize) { var deltaSize, doc, body, resizeHeight, myHeight; var marginTop, marginBottom, paddingTop, paddingBottom, borderTop, borderBottom; var dom = editor.dom; doc = editor.getDoc(); if (!doc) { return; } if (isFullscreen(editor)) { toggleScrolling(editor, true); return; } body = doc.body; resizeHeight = Settings.getAutoResizeMinHeight(editor); marginTop = dom.getStyle(body, 'margin-top', true); marginBottom = dom.getStyle(body, 'margin-bottom', true); paddingTop = dom.getStyle(body, 'padding-top', true); paddingBottom = dom.getStyle(body, 'padding-bottom', true); borderTop = dom.getStyle(body, 'border-top-width', true); borderBottom = dom.getStyle(body, 'border-bottom-width', true); myHeight = body.offsetHeight + parseInt(marginTop, 10) + parseInt(marginBottom, 10) + parseInt(paddingTop, 10) + parseInt(paddingBottom, 10) + parseInt(borderTop, 10) + parseInt(borderBottom, 10); if (isNaN(myHeight) || myHeight <= 0) { myHeight = global$1.ie ? body.scrollHeight : global$1.webkit && body.clientHeight === 0 ? 0 : body.offsetHeight; } if (myHeight > Settings.getAutoResizeMinHeight(editor)) { resizeHeight = myHeight; } var maxHeight = Settings.getAutoResizeMaxHeight(editor); if (maxHeight && myHeight > maxHeight) { resizeHeight = maxHeight; toggleScrolling(editor, true); } else { toggleScrolling(editor, false); } if (resizeHeight !== oldSize.get()) { deltaSize = resizeHeight - oldSize.get(); dom.setStyle(editor.iframeElement, 'height', resizeHeight + 'px'); oldSize.set(resizeHeight); if (global$1.webkit && deltaSize < 0) { resize(editor, oldSize); } } }; var setup = function (editor, oldSize) { editor.on('init', function () { var overflowPadding, bottomMargin; var dom = editor.dom; overflowPadding = Settings.getAutoResizeOverflowPadding(editor); bottomMargin = Settings.getAutoResizeBottomMargin(editor); if (overflowPadding !== false) { dom.setStyles(editor.getBody(), { paddingLeft: overflowPadding, paddingRight: overflowPadding }); } if (bottomMargin !== false) { dom.setStyles(editor.getBody(), { paddingBottom: bottomMargin }); } }); editor.on('nodechange setcontent keyup FullscreenStateChanged', function (e) { resize(editor, oldSize); }); if (Settings.shouldAutoResizeOnInit(editor)) { editor.on('init', function () { wait(editor, oldSize, 20, 100, function () { wait(editor, oldSize, 5, 1000); }); }); } }; var Resize = { setup: setup, resize: resize }; var register = function (editor, oldSize) { editor.addCommand('mceAutoResize', function () { Resize.resize(editor, oldSize); }); }; var Commands = { register: register }; global.add('autoresize', function (editor) { if (!editor.inline) { var oldSize = Cell(0); Commands.register(editor, oldSize); Resize.setup(editor, oldSize); } }); function Plugin () { } return Plugin; }()); })(); (function () { var autosave = (function (domGlobals) { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.util.LocalStorage'); var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var fireRestoreDraft = function (editor) { return editor.fire('RestoreDraft'); }; var fireStoreDraft = function (editor) { return editor.fire('StoreDraft'); }; var fireRemoveDraft = function (editor) { return editor.fire('RemoveDraft'); }; var parse = function (timeString, defaultTime) { var multiples = { s: 1000, m: 60000 }; var toParse = timeString || defaultTime; var parsedTime = /^(\d+)([ms]?)$/.exec('' + toParse); return (parsedTime[2] ? multiples[parsedTime[2]] : 1) * parseInt(toParse, 10); }; var shouldAskBeforeUnload = function (editor) { return editor.getParam('autosave_ask_before_unload', true); }; var getAutoSavePrefix = function (editor) { var prefix = editor.getParam('autosave_prefix', 'tinymce-autosave-{path}{query}{hash}-{id}-'); prefix = prefix.replace(/\{path\}/g, domGlobals.document.location.pathname); prefix = prefix.replace(/\{query\}/g, domGlobals.document.location.search); prefix = prefix.replace(/\{hash\}/g, domGlobals.document.location.hash); prefix = prefix.replace(/\{id\}/g, editor.id); return prefix; }; var shouldRestoreWhenEmpty = function (editor) { return editor.getParam('autosave_restore_when_empty', false); }; var getAutoSaveInterval = function (editor) { return parse(editor.settings.autosave_interval, '30s'); }; var getAutoSaveRetention = function (editor) { return parse(editor.settings.autosave_retention, '20m'); }; var isEmpty = function (editor, html) { var forcedRootBlockName = editor.settings.forced_root_block; html = global$2.trim(typeof html === 'undefined' ? editor.getBody().innerHTML : html); return html === '' || new RegExp('^<' + forcedRootBlockName + '[^>]*>((\xA0| |[ \t]|<br[^>]*>)+?|)</' + forcedRootBlockName + '>|<br>$', 'i').test(html); }; var hasDraft = function (editor) { var time = parseInt(global$1.getItem(getAutoSavePrefix(editor) + 'time'), 10) || 0; if (new Date().getTime() - time > getAutoSaveRetention(editor)) { removeDraft(editor, false); return false; } return true; }; var removeDraft = function (editor, fire) { var prefix = getAutoSavePrefix(editor); global$1.removeItem(prefix + 'draft'); global$1.removeItem(prefix + 'time'); if (fire !== false) { fireRemoveDraft(editor); } }; var storeDraft = function (editor) { var prefix = getAutoSavePrefix(editor); if (!isEmpty(editor) && editor.isDirty()) { global$1.setItem(prefix + 'draft', editor.getContent({ format: 'raw', no_events: true })); global$1.setItem(prefix + 'time', new Date().getTime().toString()); fireStoreDraft(editor); } }; var restoreDraft = function (editor) { var prefix = getAutoSavePrefix(editor); if (hasDraft(editor)) { editor.setContent(global$1.getItem(prefix + 'draft'), { format: 'raw' }); fireRestoreDraft(editor); } }; var startStoreDraft = function (editor, started) { var interval = getAutoSaveInterval(editor); if (!started.get()) { setInterval(function () { if (!editor.removed) { storeDraft(editor); } }, interval); started.set(true); } }; var restoreLastDraft = function (editor) { editor.undoManager.transact(function () { restoreDraft(editor); removeDraft(editor); }); editor.focus(); }; function curry(fn) { var initialArgs = []; for (var _i = 1; _i < arguments.length; _i++) { initialArgs[_i - 1] = arguments[_i]; } return function () { var restArgs = []; for (var _i = 0; _i < arguments.length; _i++) { restArgs[_i] = arguments[_i]; } var all = initialArgs.concat(restArgs); return fn.apply(null, all); }; } var get = function (editor) { return { hasDraft: curry(hasDraft, editor), storeDraft: curry(storeDraft, editor), restoreDraft: curry(restoreDraft, editor), removeDraft: curry(removeDraft, editor), isEmpty: curry(isEmpty, editor) }; }; var global$3 = tinymce.util.Tools.resolve('tinymce.EditorManager'); global$3._beforeUnloadHandler = function () { var msg; global$2.each(global$3.get(), function (editor) { if (editor.plugins.autosave) { editor.plugins.autosave.storeDraft(); } if (!msg && editor.isDirty() && shouldAskBeforeUnload(editor)) { msg = editor.translate('You have unsaved changes are you sure you want to navigate away?'); } }); return msg; }; var setup = function (editor) { domGlobals.window.onbeforeunload = global$3._beforeUnloadHandler; }; var postRender = function (editor, started) { return function (e) { var ctrl = e.control; ctrl.disabled(!hasDraft(editor)); editor.on('StoreDraft RestoreDraft RemoveDraft', function () { ctrl.disabled(!hasDraft(editor)); }); startStoreDraft(editor, started); }; }; var register = function (editor, started) { editor.addButton('restoredraft', { title: 'Restore last draft', onclick: function () { restoreLastDraft(editor); }, onPostRender: postRender(editor, started) }); editor.addMenuItem('restoredraft', { text: 'Restore last draft', onclick: function () { restoreLastDraft(editor); }, onPostRender: postRender(editor, started), context: 'file' }); }; global.add('autosave', function (editor) { var started = Cell(false); setup(editor); register(editor, started); editor.on('init', function () { if (shouldRestoreWhenEmpty(editor) && editor.dom.isEmpty(editor.getBody())) { restoreDraft(editor); } }); return get(editor); }); function Plugin () { } return Plugin; }(window)); })(); (function () { var bbcode = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var html2bbcode = function (s) { s = global$1.trim(s); var rep = function (re, str) { s = s.replace(re, str); }; rep(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi, '[url=$1]$2[/url]'); rep(/<font.*?color=\"(.*?)\".*?class=\"codeStyle\".*?>(.*?)<\/font>/gi, '[code][color=$1]$2[/color][/code]'); rep(/<font.*?color=\"(.*?)\".*?class=\"quoteStyle\".*?>(.*?)<\/font>/gi, '[quote][color=$1]$2[/color][/quote]'); rep(/<font.*?class=\"codeStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi, '[code][color=$1]$2[/color][/code]'); rep(/<font.*?class=\"quoteStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi, '[quote][color=$1]$2[/color][/quote]'); rep(/<span style=\"color: ?(.*?);\">(.*?)<\/span>/gi, '[color=$1]$2[/color]'); rep(/<font.*?color=\"(.*?)\".*?>(.*?)<\/font>/gi, '[color=$1]$2[/color]'); rep(/<span style=\"font-size:(.*?);\">(.*?)<\/span>/gi, '[size=$1]$2[/size]'); rep(/<font>(.*?)<\/font>/gi, '$1'); rep(/<img.*?src=\"(.*?)\".*?\/>/gi, '[img]$1[/img]'); rep(/<span class=\"codeStyle\">(.*?)<\/span>/gi, '[code]$1[/code]'); rep(/<span class=\"quoteStyle\">(.*?)<\/span>/gi, '[quote]$1[/quote]'); rep(/<strong class=\"codeStyle\">(.*?)<\/strong>/gi, '[code][b]$1[/b][/code]'); rep(/<strong class=\"quoteStyle\">(.*?)<\/strong>/gi, '[quote][b]$1[/b][/quote]'); rep(/<em class=\"codeStyle\">(.*?)<\/em>/gi, '[code][i]$1[/i][/code]'); rep(/<em class=\"quoteStyle\">(.*?)<\/em>/gi, '[quote][i]$1[/i][/quote]'); rep(/<u class=\"codeStyle\">(.*?)<\/u>/gi, '[code][u]$1[/u][/code]'); rep(/<u class=\"quoteStyle\">(.*?)<\/u>/gi, '[quote][u]$1[/u][/quote]'); rep(/<\/(strong|b)>/gi, '[/b]'); rep(/<(strong|b)>/gi, '[b]'); rep(/<\/(em|i)>/gi, '[/i]'); rep(/<(em|i)>/gi, '[i]'); rep(/<\/u>/gi, '[/u]'); rep(/<span style=\"text-decoration: ?underline;\">(.*?)<\/span>/gi, '[u]$1[/u]'); rep(/<u>/gi, '[u]'); rep(/<blockquote[^>]*>/gi, '[quote]'); rep(/<\/blockquote>/gi, '[/quote]'); rep(/<br \/>/gi, '\n'); rep(/<br\/>/gi, '\n'); rep(/<br>/gi, '\n'); rep(/<p>/gi, ''); rep(/<\/p>/gi, '\n'); rep(/ |\u00a0/gi, ' '); rep(/"/gi, '"'); rep(/</gi, '<'); rep(/>/gi, '>'); rep(/&/gi, '&'); return s; }; var bbcode2html = function (s) { s = global$1.trim(s); var rep = function (re, str) { s = s.replace(re, str); }; rep(/\n/gi, '<br />'); rep(/\[b\]/gi, '<strong>'); rep(/\[\/b\]/gi, '</strong>'); rep(/\[i\]/gi, '<em>'); rep(/\[\/i\]/gi, '</em>'); rep(/\[u\]/gi, '<u>'); rep(/\[\/u\]/gi, '</u>'); rep(/\[url=([^\]]+)\](.*?)\[\/url\]/gi, '<a href="$1">$2</a>'); rep(/\[url\](.*?)\[\/url\]/gi, '<a href="$1">$1</a>'); rep(/\[img\](.*?)\[\/img\]/gi, '<img src="$1" />'); rep(/\[color=(.*?)\](.*?)\[\/color\]/gi, '<font color="$1">$2</font>'); rep(/\[code\](.*?)\[\/code\]/gi, '<span class="codeStyle">$1</span> '); rep(/\[quote.*?\](.*?)\[\/quote\]/gi, '<span class="quoteStyle">$1</span> '); return s; }; var Convert = { html2bbcode: html2bbcode, bbcode2html: bbcode2html }; global.add('bbcode', function () { return { init: function (editor) { editor.on('beforeSetContent', function (e) { e.content = Convert.bbcode2html(e.content); }); editor.on('postProcess', function (e) { if (e.set) { e.content = Convert.bbcode2html(e.content); } if (e.get) { e.content = Convert.html2bbcode(e.content); } }); } }; }); function Plugin () { } return Plugin; }()); })(); (function () { var charmap = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var fireInsertCustomChar = function (editor, chr) { return editor.fire('insertCustomChar', { chr: chr }); }; var Events = { fireInsertCustomChar: fireInsertCustomChar }; var insertChar = function (editor, chr) { var evtChr = Events.fireInsertCustomChar(editor, chr).chr; editor.execCommand('mceInsertContent', false, evtChr); }; var Actions = { insertChar: insertChar }; var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var getCharMap = function (editor) { return editor.settings.charmap; }; var getCharMapAppend = function (editor) { return editor.settings.charmap_append; }; var Settings = { getCharMap: getCharMap, getCharMapAppend: getCharMapAppend }; var isArray = global$1.isArray; var getDefaultCharMap = function () { return [ [ '160', 'no-break space' ], [ '173', 'soft hyphen' ], [ '34', 'quotation mark' ], [ '162', 'cent sign' ], [ '8364', 'euro sign' ], [ '163', 'pound sign' ], [ '165', 'yen sign' ], [ '169', 'copyright sign' ], [ '174', 'registered sign' ], [ '8482', 'trade mark sign' ], [ '8240', 'per mille sign' ], [ '181', 'micro sign' ], [ '183', 'middle dot' ], [ '8226', 'bullet' ], [ '8230', 'three dot leader' ], [ '8242', 'minutes / feet' ], [ '8243', 'seconds / inches' ], [ '167', 'section sign' ], [ '182', 'paragraph sign' ], [ '223', 'sharp s / ess-zed' ], [ '8249', 'single left-pointing angle quotation mark' ], [ '8250', 'single right-pointing angle quotation mark' ], [ '171', 'left pointing guillemet' ], [ '187', 'right pointing guillemet' ], [ '8216', 'left single quotation mark' ], [ '8217', 'right single quotation mark' ], [ '8220', 'left double quotation mark' ], [ '8221', 'right double quotation mark' ], [ '8218', 'single low-9 quotation mark' ], [ '8222', 'double low-9 quotation mark' ], [ '60', 'less-than sign' ], [ '62', 'greater-than sign' ], [ '8804', 'less-than or equal to' ], [ '8805', 'greater-than or equal to' ], [ '8211', 'en dash' ], [ '8212', 'em dash' ], [ '175', 'macron' ], [ '8254', 'overline' ], [ '164', 'currency sign' ], [ '166', 'broken bar' ], [ '168', 'diaeresis' ], [ '161', 'inverted exclamation mark' ], [ '191', 'turned question mark' ], [ '710', 'circumflex accent' ], [ '732', 'small tilde' ], [ '176', 'degree sign' ], [ '8722', 'minus sign' ], [ '177', 'plus-minus sign' ], [ '247', 'division sign' ], [ '8260', 'fraction slash' ], [ '215', 'multiplication sign' ], [ '185', 'superscript one' ], [ '178', 'superscript two' ], [ '179', 'superscript three' ], [ '188', 'fraction one quarter' ], [ '189', 'fraction one half' ], [ '190', 'fraction three quarters' ], [ '402', 'function / florin' ], [ '8747', 'integral' ], [ '8721', 'n-ary sumation' ], [ '8734', 'infinity' ], [ '8730', 'square root' ], [ '8764', 'similar to' ], [ '8773', 'approximately equal to' ], [ '8776', 'almost equal to' ], [ '8800', 'not equal to' ], [ '8801', 'identical to' ], [ '8712', 'element of' ], [ '8713', 'not an element of' ], [ '8715', 'contains as member' ], [ '8719', 'n-ary product' ], [ '8743', 'logical and' ], [ '8744', 'logical or' ], [ '172', 'not sign' ], [ '8745', 'intersection' ], [ '8746', 'union' ], [ '8706', 'partial differential' ], [ '8704', 'for all' ], [ '8707', 'there exists' ], [ '8709', 'diameter' ], [ '8711', 'backward difference' ], [ '8727', 'asterisk operator' ], [ '8733', 'proportional to' ], [ '8736', 'angle' ], [ '180', 'acute accent' ], [ '184', 'cedilla' ], [ '170', 'feminine ordinal indicator' ], [ '186', 'masculine ordinal indicator' ], [ '8224', 'dagger' ], [ '8225', 'double dagger' ], [ '192', 'A - grave' ], [ '193', 'A - acute' ], [ '194', 'A - circumflex' ], [ '195', 'A - tilde' ], [ '196', 'A - diaeresis' ], [ '197', 'A - ring above' ], [ '256', 'A - macron' ], [ '198', 'ligature AE' ], [ '199', 'C - cedilla' ], [ '200', 'E - grave' ], [ '201', 'E - acute' ], [ '202', 'E - circumflex' ], [ '203', 'E - diaeresis' ], [ '274', 'E - macron' ], [ '204', 'I - grave' ], [ '205', 'I - acute' ], [ '206', 'I - circumflex' ], [ '207', 'I - diaeresis' ], [ '298', 'I - macron' ], [ '208', 'ETH' ], [ '209', 'N - tilde' ], [ '210', 'O - grave' ], [ '211', 'O - acute' ], [ '212', 'O - circumflex' ], [ '213', 'O - tilde' ], [ '214', 'O - diaeresis' ], [ '216', 'O - slash' ], [ '332', 'O - macron' ], [ '338', 'ligature OE' ], [ '352', 'S - caron' ], [ '217', 'U - grave' ], [ '218', 'U - acute' ], [ '219', 'U - circumflex' ], [ '220', 'U - diaeresis' ], [ '362', 'U - macron' ], [ '221', 'Y - acute' ], [ '376', 'Y - diaeresis' ], [ '562', 'Y - macron' ], [ '222', 'THORN' ], [ '224', 'a - grave' ], [ '225', 'a - acute' ], [ '226', 'a - circumflex' ], [ '227', 'a - tilde' ], [ '228', 'a - diaeresis' ], [ '229', 'a - ring above' ], [ '257', 'a - macron' ], [ '230', 'ligature ae' ], [ '231', 'c - cedilla' ], [ '232', 'e - grave' ], [ '233', 'e - acute' ], [ '234', 'e - circumflex' ], [ '235', 'e - diaeresis' ], [ '275', 'e - macron' ], [ '236', 'i - grave' ], [ '237', 'i - acute' ], [ '238', 'i - circumflex' ], [ '239', 'i - diaeresis' ], [ '299', 'i - macron' ], [ '240', 'eth' ], [ '241', 'n - tilde' ], [ '242', 'o - grave' ], [ '243', 'o - acute' ], [ '244', 'o - circumflex' ], [ '245', 'o - tilde' ], [ '246', 'o - diaeresis' ], [ '248', 'o slash' ], [ '333', 'o macron' ], [ '339', 'ligature oe' ], [ '353', 's - caron' ], [ '249', 'u - grave' ], [ '250', 'u - acute' ], [ '251', 'u - circumflex' ], [ '252', 'u - diaeresis' ], [ '363', 'u - macron' ], [ '253', 'y - acute' ], [ '254', 'thorn' ], [ '255', 'y - diaeresis' ], [ '563', 'y - macron' ], [ '913', 'Alpha' ], [ '914', 'Beta' ], [ '915', 'Gamma' ], [ '916', 'Delta' ], [ '917', 'Epsilon' ], [ '918', 'Zeta' ], [ '919', 'Eta' ], [ '920', 'Theta' ], [ '921', 'Iota' ], [ '922', 'Kappa' ], [ '923', 'Lambda' ], [ '924', 'Mu' ], [ '925', 'Nu' ], [ '926', 'Xi' ], [ '927', 'Omicron' ], [ '928', 'Pi' ], [ '929', 'Rho' ], [ '931', 'Sigma' ], [ '932', 'Tau' ], [ '933', 'Upsilon' ], [ '934', 'Phi' ], [ '935', 'Chi' ], [ '936', 'Psi' ], [ '937', 'Omega' ], [ '945', 'alpha' ], [ '946', 'beta' ], [ '947', 'gamma' ], [ '948', 'delta' ], [ '949', 'epsilon' ], [ '950', 'zeta' ], [ '951', 'eta' ], [ '952', 'theta' ], [ '953', 'iota' ], [ '954', 'kappa' ], [ '955', 'lambda' ], [ '956', 'mu' ], [ '957', 'nu' ], [ '958', 'xi' ], [ '959', 'omicron' ], [ '960', 'pi' ], [ '961', 'rho' ], [ '962', 'final sigma' ], [ '963', 'sigma' ], [ '964', 'tau' ], [ '965', 'upsilon' ], [ '966', 'phi' ], [ '967', 'chi' ], [ '968', 'psi' ], [ '969', 'omega' ], [ '8501', 'alef symbol' ], [ '982', 'pi symbol' ], [ '8476', 'real part symbol' ], [ '978', 'upsilon - hook symbol' ], [ '8472', 'Weierstrass p' ], [ '8465', 'imaginary part' ], [ '8592', 'leftwards arrow' ], [ '8593', 'upwards arrow' ], [ '8594', 'rightwards arrow' ], [ '8595', 'downwards arrow' ], [ '8596', 'left right arrow' ], [ '8629', 'carriage return' ], [ '8656', 'leftwards double arrow' ], [ '8657', 'upwards double arrow' ], [ '8658', 'rightwards double arrow' ], [ '8659', 'downwards double arrow' ], [ '8660', 'left right double arrow' ], [ '8756', 'therefore' ], [ '8834', 'subset of' ], [ '8835', 'superset of' ], [ '8836', 'not a subset of' ], [ '8838', 'subset of or equal to' ], [ '8839', 'superset of or equal to' ], [ '8853', 'circled plus' ], [ '8855', 'circled times' ], [ '8869', 'perpendicular' ], [ '8901', 'dot operator' ], [ '8968', 'left ceiling' ], [ '8969', 'right ceiling' ], [ '8970', 'left floor' ], [ '8971', 'right floor' ], [ '9001', 'left-pointing angle bracket' ], [ '9002', 'right-pointing angle bracket' ], [ '9674', 'lozenge' ], [ '9824', 'black spade suit' ], [ '9827', 'black club suit' ], [ '9829', 'black heart suit' ], [ '9830', 'black diamond suit' ], [ '8194', 'en space' ], [ '8195', 'em space' ], [ '8201', 'thin space' ], [ '8204', 'zero width non-joiner' ], [ '8205', 'zero width joiner' ], [ '8206', 'left-to-right mark' ], [ '8207', 'right-to-left mark' ] ]; }; var charmapFilter = function (charmap) { return global$1.grep(charmap, function (item) { return isArray(item) && item.length === 2; }); }; var getCharsFromSetting = function (settingValue) { if (isArray(settingValue)) { return [].concat(charmapFilter(settingValue)); } if (typeof settingValue === 'function') { return settingValue(); } return []; }; var extendCharMap = function (editor, charmap) { var userCharMap = Settings.getCharMap(editor); if (userCharMap) { charmap = getCharsFromSetting(userCharMap); } var userCharMapAppend = Settings.getCharMapAppend(editor); if (userCharMapAppend) { return [].concat(charmap).concat(getCharsFromSetting(userCharMapAppend)); } return charmap; }; var getCharMap$1 = function (editor) { return extendCharMap(editor, getDefaultCharMap()); }; var CharMap = { getCharMap: getCharMap$1 }; var get = function (editor) { var getCharMap = function () { return CharMap.getCharMap(editor); }; var insertChar = function (chr) { Actions.insertChar(editor, chr); }; return { getCharMap: getCharMap, insertChar: insertChar }; }; var Api = { get: get }; var getHtml = function (charmap) { var gridHtml, x, y; var width = Math.min(charmap.length, 25); var height = Math.ceil(charmap.length / width); gridHtml = '<table role="presentation" cellspacing="0" class="mce-charmap"><tbody>'; for (y = 0; y < height; y++) { gridHtml += '<tr>'; for (x = 0; x < width; x++) { var index = y * width + x; if (index < charmap.length) { var chr = charmap[index]; var charCode = parseInt(chr[0], 10); var chrText = chr ? String.fromCharCode(charCode) : ' '; gridHtml += '<td title="' + chr[1] + '">' + '<div tabindex="-1" title="' + chr[1] + '" role="button" data-chr="' + charCode + '">' + chrText + '</div>' + '</td>'; } else { gridHtml += '<td />'; } } gridHtml += '</tr>'; } gridHtml += '</tbody></table>'; return gridHtml; }; var GridHtml = { getHtml: getHtml }; var getParentTd = function (elm) { while (elm) { if (elm.nodeName === 'TD') { return elm; } elm = elm.parentNode; } }; var open = function (editor) { var win; var charMapPanel = { type: 'container', html: GridHtml.getHtml(CharMap.getCharMap(editor)), onclick: function (e) { var target = e.target; if (/^(TD|DIV)$/.test(target.nodeName)) { var charDiv = getParentTd(target).firstChild; if (charDiv && charDiv.hasAttribute('data-chr')) { var charCodeString = charDiv.getAttribute('data-chr'); var charCode = parseInt(charCodeString, 10); if (!isNaN(charCode)) { Actions.insertChar(editor, String.fromCharCode(charCode)); } if (!e.ctrlKey) { win.close(); } } } }, onmouseover: function (e) { var td = getParentTd(e.target); if (td && td.firstChild) { win.find('#preview').text(td.firstChild.firstChild.data); win.find('#previewTitle').text(td.title); } else { win.find('#preview').text(' '); win.find('#previewTitle').text(' '); } } }; win = editor.windowManager.open({ title: 'Special character', spacing: 10, padding: 10, items: [ charMapPanel, { type: 'container', layout: 'flex', direction: 'column', align: 'center', spacing: 5, minWidth: 160, minHeight: 160, items: [ { type: 'label', name: 'preview', text: ' ', style: 'font-size: 40px; text-align: center', border: 1, minWidth: 140, minHeight: 80 }, { type: 'spacer', minHeight: 20 }, { type: 'label', name: 'previewTitle', text: ' ', style: 'white-space: pre-wrap;', border: 1, minWidth: 140 } ] } ], buttons: [{ text: 'Close', onclick: function () { win.close(); } }] }); }; var Dialog = { open: open }; var register = function (editor) { editor.addCommand('mceShowCharmap', function () { Dialog.open(editor); }); }; var Commands = { register: register }; var register$1 = function (editor) { editor.addButton('charmap', { icon: 'charmap', tooltip: 'Special character', cmd: 'mceShowCharmap' }); editor.addMenuItem('charmap', { icon: 'charmap', text: 'Special character', cmd: 'mceShowCharmap', context: 'insert' }); }; var Buttons = { register: register$1 }; global.add('charmap', function (editor) { Commands.register(editor); Buttons.register(editor); return Api.get(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var code = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var getMinWidth = function (editor) { return editor.getParam('code_dialog_width', 600); }; var getMinHeight = function (editor) { return editor.getParam('code_dialog_height', Math.min(global$1.DOM.getViewPort().h - 200, 500)); }; var Settings = { getMinWidth: getMinWidth, getMinHeight: getMinHeight }; var setContent = function (editor, html) { editor.focus(); editor.undoManager.transact(function () { editor.setContent(html); }); editor.selection.setCursorLocation(); editor.nodeChanged(); }; var getContent = function (editor) { return editor.getContent({ source_view: true }); }; var Content = { setContent: setContent, getContent: getContent }; var open = function (editor) { var minWidth = Settings.getMinWidth(editor); var minHeight = Settings.getMinHeight(editor); var win = editor.windowManager.open({ title: 'Source code', body: { type: 'textbox', name: 'code', multiline: true, minWidth: minWidth, minHeight: minHeight, spellcheck: false, style: 'direction: ltr; text-align: left' }, onSubmit: function (e) { Content.setContent(editor, e.data.code); } }); win.find('#code').value(Content.getContent(editor)); }; var Dialog = { open: open }; var register = function (editor) { editor.addCommand('mceCodeEditor', function () { Dialog.open(editor); }); }; var Commands = { register: register }; var register$1 = function (editor) { editor.addButton('code', { icon: 'code', tooltip: 'Source code', onclick: function () { Dialog.open(editor); } }); editor.addMenuItem('code', { icon: 'code', text: 'Source code', onclick: function () { Dialog.open(editor); } }); }; var Buttons = { register: register$1 }; global.add('code', function (editor) { Commands.register(editor); Buttons.register(editor); return {}; }); function Plugin () { } return Plugin; }()); })(); (function () { var codesample = (function (domGlobals) { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var getContentCss = function (editor) { return editor.settings.codesample_content_css; }; var getLanguages = function (editor) { return editor.settings.codesample_languages; }; var getDialogMinWidth = function (editor) { return Math.min(global$1.DOM.getViewPort().w, editor.getParam('codesample_dialog_width', 800)); }; var getDialogMinHeight = function (editor) { return Math.min(global$1.DOM.getViewPort().w, editor.getParam('codesample_dialog_height', 650)); }; var Settings = { getContentCss: getContentCss, getLanguages: getLanguages, getDialogMinWidth: getDialogMinWidth, getDialogMinHeight: getDialogMinHeight }; var window = {}; var global$2 = window; var _self = typeof window !== 'undefined' ? window : typeof WorkerGlobalScope !== 'undefined' && domGlobals.self instanceof WorkerGlobalScope ? domGlobals.self : {}; var Prism = function () { var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i; var _ = _self.Prism = { util: { encode: function (tokens) { if (tokens instanceof Token) { return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias); } else if (_.util.type(tokens) === 'Array') { return tokens.map(_.util.encode); } else { return tokens.replace(/&/g, '&').replace(/</g, '<').replace(/\u00a0/g, ' '); } }, type: function (o) { return Object.prototype.toString.call(o).match(/\[object (\w+)\]/)[1]; }, clone: function (o) { var type = _.util.type(o); switch (type) { case 'Object': var clone = {}; for (var key in o) { if (o.hasOwnProperty(key)) { clone[key] = _.util.clone(o[key]); } } return clone; case 'Array': return o.map && o.map(function (v) { return _.util.clone(v); }); } return o; } }, languages: { extend: function (id, redef) { var lang = _.util.clone(_.languages[id]); for (var key in redef) { lang[key] = redef[key]; } return lang; }, insertBefore: function (inside, before, insert, root) { root = root || _.languages; var grammar = root[inside]; if (arguments.length === 2) { insert = arguments[1]; for (var newToken in insert) { if (insert.hasOwnProperty(newToken)) { grammar[newToken] = insert[newToken]; } } return grammar; } var ret = {}; for (var token in grammar) { if (grammar.hasOwnProperty(token)) { if (token === before) { for (var newToken in insert) { if (insert.hasOwnProperty(newToken)) { ret[newToken] = insert[newToken]; } } } ret[token] = grammar[token]; } } _.languages.DFS(_.languages, function (key, value) { if (value === root[inside] && key !== inside) { this[key] = ret; } }); return root[inside] = ret; }, DFS: function (o, callback, type) { for (var i in o) { if (o.hasOwnProperty(i)) { callback.call(o, i, o[i], type || i); if (_.util.type(o[i]) === 'Object') { _.languages.DFS(o[i], callback); } else if (_.util.type(o[i]) === 'Array') { _.languages.DFS(o[i], callback, i); } } } } }, plugins: {}, highlightAll: function (async, callback) { var elements = domGlobals.document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'); for (var i = 0, element = void 0; element = elements[i++];) { _.highlightElement(element, async === true, callback); } }, highlightElement: function (element, async, callback) { var language, grammar, parent = element; while (parent && !lang.test(parent.className)) { parent = parent.parentNode; } if (parent) { language = (parent.className.match(lang) || [ , '' ])[1]; grammar = _.languages[language]; } element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; parent = element.parentNode; if (/pre/i.test(parent.nodeName)) { parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; } var code = element.textContent; var env = { element: element, language: language, grammar: grammar, code: code }; if (!code || !grammar) { _.hooks.run('complete', env); return; } _.hooks.run('before-highlight', env); if (async && _self.Worker) { var worker = new domGlobals.Worker(_.filename); worker.onmessage = function (evt) { env.highlightedCode = evt.data; _.hooks.run('before-insert', env); env.element.innerHTML = env.highlightedCode; if (callback) { callback.call(env.element); } _.hooks.run('after-highlight', env); _.hooks.run('complete', env); }; worker.postMessage(JSON.stringify({ language: env.language, code: env.code, immediateClose: true })); } else { env.highlightedCode = _.highlight(env.code, env.grammar, env.language); _.hooks.run('before-insert', env); env.element.innerHTML = env.highlightedCode; if (callback) { callback.call(element); } _.hooks.run('after-highlight', env); _.hooks.run('complete', env); } }, highlight: function (text, grammar, language) { var tokens = _.tokenize(text, grammar); return Token.stringify(_.util.encode(tokens), language); }, tokenize: function (text, grammar, language) { var Token = _.Token; var strarr = [text]; var rest = grammar.rest; if (rest) { for (var token in rest) { grammar[token] = rest[token]; } delete grammar.rest; } tokenloop: for (var token in grammar) { if (!grammar.hasOwnProperty(token) || !grammar[token]) { continue; } var patterns = grammar[token]; patterns = _.util.type(patterns) === 'Array' ? patterns : [patterns]; for (var j = 0; j < patterns.length; ++j) { var pattern = patterns[j]; var inside = pattern.inside; var lookbehind = !!pattern.lookbehind; var lookbehindLength = 0; var alias = pattern.alias; pattern = pattern.pattern || pattern; for (var i = 0; i < strarr.length; i++) { var str = strarr[i]; if (strarr.length > text.length) { break tokenloop; } if (str instanceof Token) { continue; } pattern.lastIndex = 0; var match = pattern.exec(str); if (match) { if (lookbehind) { lookbehindLength = match[1].length; } var from = match.index - 1 + lookbehindLength; match = match[0].slice(lookbehindLength); var len = match.length, to = from + len, before = str.slice(0, from + 1), after = str.slice(to + 1); var args = [ i, 1 ]; if (before) { args.push(before); } var wrapped = new Token(token, inside ? _.tokenize(match, inside) : match, alias); args.push(wrapped); if (after) { args.push(after); } Array.prototype.splice.apply(strarr, args); } } } } return strarr; }, hooks: { all: {}, add: function (name, callback) { var hooks = _.hooks.all; hooks[name] = hooks[name] || []; hooks[name].push(callback); }, run: function (name, env) { var callbacks = _.hooks.all[name]; if (!callbacks || !callbacks.length) { return; } for (var i = 0, callback = void 0; callback = callbacks[i++];) { callback(env); } } } }; var Token = _.Token = function (type, content, alias) { this.type = type; this.content = content; this.alias = alias; }; Token.stringify = function (o, language, parent) { if (typeof o === 'string') { return o; } if (_.util.type(o) === 'Array') { return o.map(function (element) { return Token.stringify(element, language, o); }).join(''); } var env = { type: o.type, content: Token.stringify(o.content, language, parent), tag: 'span', classes: [ 'token', o.type ], attributes: {}, language: language, parent: parent }; if (env.type === 'comment') { env.attributes.spellcheck = 'true'; } if (o.alias) { var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias]; Array.prototype.push.apply(env.classes, aliases); } _.hooks.run('wrap', env); var attributes = ''; for (var name in env.attributes) { attributes += (attributes ? ' ' : '') + name + '="' + (env.attributes[name] || '') + '"'; } return '<' + env.tag + ' class="' + env.classes.join(' ') + '" ' + attributes + '>' + env.content + '</' + env.tag + '>'; }; if (!_self.document) { if (!_self.addEventListener) { return _self.Prism; } _self.addEventListener('message', function (evt) { var message = JSON.parse(evt.data), lang = message.language, code = message.code, immediateClose = message.immediateClose; _self.postMessage(_.highlight(code, _.languages[lang], lang)); if (immediateClose) { _self.close(); } }, false); return _self.Prism; } }(); if (typeof global$2 !== 'undefined') { global$2.Prism = Prism; } Prism.languages.markup = { comment: /<!--[\w\W]*?-->/, prolog: /<\?[\w\W]+?\?>/, doctype: /<!DOCTYPE[\w\W]+?>/, cdata: /<!\[CDATA\[[\w\W]*?]]>/i, tag: { pattern: /<\/?[^\s>\/=.]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i, inside: { 'tag': { pattern: /^<\/?[^\s>\/]+/i, inside: { punctuation: /^<\/?/, namespace: /^[^\s>\/:]+:/ } }, 'attr-value': { pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i, inside: { punctuation: /[=>"']/ } }, 'punctuation': /\/?>/, 'attr-name': { pattern: /[^\s>\/]+/, inside: { namespace: /^[^\s>\/:]+:/ } } } }, entity: /&#?[\da-z]{1,8};/i }; Prism.hooks.add('wrap', function (env) { if (env.type === 'entity') { env.attributes.title = env.content.replace(/&/, '&'); } }); Prism.languages.xml = Prism.languages.markup; Prism.languages.html = Prism.languages.markup; Prism.languages.mathml = Prism.languages.markup; Prism.languages.svg = Prism.languages.markup; Prism.languages.css = { comment: /\/\*[\w\W]*?\*\//, atrule: { pattern: /@[\w-]+?.*?(;|(?=\s*\{))/i, inside: { rule: /@[\w-]+/ } }, url: /url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i, selector: /[^\{\}\s][^\{\};]*?(?=\s*\{)/, string: /("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/, property: /(\b|\B)[\w-]+(?=\s*:)/i, important: /\B!important\b/i, function: /[-a-z0-9]+(?=\()/i, punctuation: /[(){};:]/ }; Prism.languages.css.atrule.inside.rest = Prism.util.clone(Prism.languages.css); if (Prism.languages.markup) { Prism.languages.insertBefore('markup', 'tag', { style: { pattern: /<style[\w\W]*?>[\w\W]*?<\/style>/i, inside: { tag: { pattern: /<style[\w\W]*?>|<\/style>/i, inside: Prism.languages.markup.tag.inside }, rest: Prism.languages.css }, alias: 'language-css' } }); Prism.languages.insertBefore('inside', 'attr-value', { 'style-attr': { pattern: /\s*style=("|').*?\1/i, inside: { 'attr-name': { pattern: /^\s*style/i, inside: Prism.languages.markup.tag.inside }, 'punctuation': /^\s*=\s*['"]|['"]\s*$/, 'attr-value': { pattern: /.+/i, inside: Prism.languages.css } }, alias: 'language-css' } }, Prism.languages.markup.tag); } Prism.languages.clike = { 'comment': [ { pattern: /(^|[^\\])\/\*[\w\W]*?\*\//, lookbehind: true }, { pattern: /(^|[^\\:])\/\/.*/, lookbehind: true } ], 'string': /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, 'class-name': { pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i, lookbehind: true, inside: { punctuation: /(\.|\\)/ } }, 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, 'boolean': /\b(true|false)\b/, 'function': /[a-z0-9_]+(?=\()/i, 'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i, 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/, 'punctuation': /[{}[\];(),.:]/ }; Prism.languages.javascript = Prism.languages.extend('clike', { keyword: /\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/, number: /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/, function: /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i }); Prism.languages.insertBefore('javascript', 'keyword', { regex: { pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/, lookbehind: true } }); Prism.languages.insertBefore('javascript', 'class-name', { 'template-string': { pattern: /`(?:\\`|\\?[^`])*`/, inside: { interpolation: { pattern: /\$\{[^}]+\}/, inside: { 'interpolation-punctuation': { pattern: /^\$\{|\}$/, alias: 'punctuation' }, 'rest': Prism.languages.javascript } }, string: /[\s\S]+/ } } }); if (Prism.languages.markup) { Prism.languages.insertBefore('markup', 'tag', { script: { pattern: /<script[\w\W]*?>[\w\W]*?<\/script>/i, inside: { tag: { pattern: /<script[\w\W]*?>|<\/script>/i, inside: Prism.languages.markup.tag.inside }, rest: Prism.languages.javascript }, alias: 'language-javascript' } }); } Prism.languages.js = Prism.languages.javascript; Prism.languages.c = Prism.languages.extend('clike', { keyword: /\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/, operator: /\-[>-]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|?\||[~^%?*\/]/, number: /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)[ful]*\b/i }); Prism.languages.insertBefore('c', 'string', { macro: { pattern: /(^\s*)#\s*[a-z]+([^\r\n\\]|\\.|\\(?:\r\n?|\n))*/im, lookbehind: true, alias: 'property', inside: { string: { pattern: /(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/, lookbehind: true } } } }); delete Prism.languages.c['class-name']; delete Prism.languages.c.boolean; Prism.languages.csharp = Prism.languages.extend('clike', { keyword: /\b(abstract|as|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while|add|alias|ascending|async|await|descending|dynamic|from|get|global|group|into|join|let|orderby|partial|remove|select|set|value|var|where|yield)\b/, string: [ /@("|')(\1\1|\\\1|\\?(?!\1)[\s\S])*\1/, /("|')(\\?.)*?\1/ ], number: /\b-?(0x[\da-f]+|\d*\.?\d+)\b/i }); Prism.languages.insertBefore('csharp', 'keyword', { preprocessor: { pattern: /(^\s*)#.*/m, lookbehind: true } }); Prism.languages.cpp = Prism.languages.extend('c', { keyword: /\b(alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/, boolean: /\b(true|false)\b/, operator: /[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|:{1,2}|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\/|\b(and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/ }); Prism.languages.insertBefore('cpp', 'keyword', { 'class-name': { pattern: /(class\s+)[a-z0-9_]+/i, lookbehind: true } }); Prism.languages.java = Prism.languages.extend('clike', { keyword: /\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/, number: /\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+(?:e[+-]?\d+)?[df]?\b/i, operator: { pattern: /(^|[^.])(?:\+[+=]?|-[-=]?|!=?|<<?=?|>>?>?=?|==?|&[&=]?|\|[|=]?|\*=?|\/=?|%=?|\^=?|[?:~])/m, lookbehind: true } }); Prism.languages.php = Prism.languages.extend('clike', { keyword: /\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i, constant: /\b[A-Z0-9_]{2,}\b/, comment: { pattern: /(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/, lookbehind: true } }); Prism.languages.insertBefore('php', 'class-name', { 'shell-comment': { pattern: /(^|[^\\])#.*/, lookbehind: true, alias: 'comment' } }); Prism.languages.insertBefore('php', 'keyword', { delimiter: /\?>|<\?(?:php)?/i, variable: /\$\w+\b/i, package: { pattern: /(\\|namespace\s+|use\s+)[\w\\]+/, lookbehind: true, inside: { punctuation: /\\/ } } }); Prism.languages.insertBefore('php', 'operator', { property: { pattern: /(->)[\w]+/, lookbehind: true } }); if (Prism.languages.markup) { Prism.hooks.add('before-highlight', function (env) { if (env.language !== 'php') { return; } env.tokenStack = []; env.backupCode = env.code; env.code = env.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/ig, function (match) { env.tokenStack.push(match); return '{{{PHP' + env.tokenStack.length + '}}}'; }); }); Prism.hooks.add('before-insert', function (env) { if (env.language === 'php') { env.code = env.backupCode; delete env.backupCode; } }); Prism.hooks.add('after-highlight', function (env) { if (env.language !== 'php') { return; } for (var i = 0, t = void 0; t = env.tokenStack[i]; i++) { env.highlightedCode = env.highlightedCode.replace('{{{PHP' + (i + 1) + '}}}', Prism.highlight(t, env.grammar, 'php').replace(/\$/g, '$$$$')); } env.element.innerHTML = env.highlightedCode; }); Prism.hooks.add('wrap', function (env) { if (env.language === 'php' && env.type === 'markup') { env.content = env.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g, '<span class="token php">$1</span>'); } }); Prism.languages.insertBefore('php', 'comment', { markup: { pattern: /<[^?]\/?(.*?)>/, inside: Prism.languages.markup }, php: /\{\{\{PHP[0-9]+\}\}\}/ }); } Prism.languages.python = { 'comment': { pattern: /(^|[^\\])#.*/, lookbehind: true }, 'string': /"""[\s\S]+?"""|'''[\s\S]+?'''|("|')(?:\\?.)*?\1/, 'function': { pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_][a-zA-Z0-9_]*(?=\()/g, lookbehind: true }, 'class-name': { pattern: /(\bclass\s+)[a-z0-9_]+/i, lookbehind: true }, 'keyword': /\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/, 'boolean': /\b(?:True|False)\b/, 'number': /\b-?(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i, 'operator': /[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/, 'punctuation': /[{}[\];(),.:]/ }; (function (Prism) { Prism.languages.ruby = Prism.languages.extend('clike', { comment: /#(?!\{[^\r\n]*?\}).*/, keyword: /\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/ }); var interpolation = { pattern: /#\{[^}]+\}/, inside: { delimiter: { pattern: /^#\{|\}$/, alias: 'tag' }, rest: Prism.util.clone(Prism.languages.ruby) } }; Prism.languages.insertBefore('ruby', 'keyword', { regex: [ { pattern: /%r([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1[gim]{0,3}/, inside: { interpolation: interpolation } }, { pattern: /%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/, inside: { interpolation: interpolation } }, { pattern: /%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/, inside: { interpolation: interpolation } }, { pattern: /%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/, inside: { interpolation: interpolation } }, { pattern: /%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/, inside: { interpolation: interpolation } }, { pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/, lookbehind: true } ], variable: /[@$]+[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/, symbol: /:[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/ }); Prism.languages.insertBefore('ruby', 'number', { builtin: /\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/, constant: /\b[A-Z][a-zA-Z_0-9]*(?:[?!]|\b)/ }); Prism.languages.ruby.string = [ { pattern: /%[qQiIwWxs]?([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1/, inside: { interpolation: interpolation } }, { pattern: /%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/, inside: { interpolation: interpolation } }, { pattern: /%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/, inside: { interpolation: interpolation } }, { pattern: /%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/, inside: { interpolation: interpolation } }, { pattern: /%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/, inside: { interpolation: interpolation } }, { pattern: /("|')(#\{[^}]+\}|\\(?:\r?\n|\r)|\\?.)*?\1/, inside: { interpolation: interpolation } } ]; }(Prism)); function isCodeSample(elm) { return elm && elm.nodeName === 'PRE' && elm.className.indexOf('language-') !== -1; } function trimArg(predicateFn) { return function (arg1, arg2) { return predicateFn(arg2); }; } var Utils = { isCodeSample: isCodeSample, trimArg: trimArg }; var getSelectedCodeSample = function (editor) { var node = editor.selection.getNode(); if (Utils.isCodeSample(node)) { return node; } return null; }; var insertCodeSample = function (editor, language, code) { editor.undoManager.transact(function () { var node = getSelectedCodeSample(editor); code = global$1.DOM.encode(code); if (node) { editor.dom.setAttrib(node, 'class', 'language-' + language); node.innerHTML = code; Prism.highlightElement(node); editor.selection.select(node); } else { editor.insertContent('<pre id="__new" class="language-' + language + '">' + code + '</pre>'); editor.selection.select(editor.$('#__new').removeAttr('id')[0]); } }); }; var getCurrentCode = function (editor) { var node = getSelectedCodeSample(editor); if (node) { return node.textContent; } return ''; }; var CodeSample = { getSelectedCodeSample: getSelectedCodeSample, insertCodeSample: insertCodeSample, getCurrentCode: getCurrentCode }; var getLanguages$1 = function (editor) { var defaultLanguages = [ { text: 'HTML/XML', value: 'markup' }, { text: 'JavaScript', value: 'javascript' }, { text: 'CSS', value: 'css' }, { text: 'PHP', value: 'php' }, { text: 'Ruby', value: 'ruby' }, { text: 'Python', value: 'python' }, { text: 'Java', value: 'java' }, { text: 'C', value: 'c' }, { text: 'C#', value: 'csharp' }, { text: 'C++', value: 'cpp' } ]; var customLanguages = Settings.getLanguages(editor); return customLanguages ? customLanguages : defaultLanguages; }; var getCurrentLanguage = function (editor) { var matches; var node = CodeSample.getSelectedCodeSample(editor); if (node) { matches = node.className.match(/language-(\w+)/); return matches ? matches[1] : ''; } return ''; }; var Languages = { getLanguages: getLanguages$1, getCurrentLanguage: getCurrentLanguage }; var Dialog = { open: function (editor) { var minWidth = Settings.getDialogMinWidth(editor); var minHeight = Settings.getDialogMinHeight(editor); var currentLanguage = Languages.getCurrentLanguage(editor); var currentLanguages = Languages.getLanguages(editor); var currentCode = CodeSample.getCurrentCode(editor); editor.windowManager.open({ title: 'Insert/Edit code sample', minWidth: minWidth, minHeight: minHeight, layout: 'flex', direction: 'column', align: 'stretch', body: [ { type: 'listbox', name: 'language', label: 'Language', maxWidth: 200, value: currentLanguage, values: currentLanguages }, { type: 'textbox', name: 'code', multiline: true, spellcheck: false, ariaLabel: 'Code view', flex: 1, style: 'direction: ltr; text-align: left', classes: 'monospace', value: currentCode, autofocus: true } ], onSubmit: function (e) { CodeSample.insertCodeSample(editor, e.data.language, e.data.code); } }); } }; var register = function (editor) { editor.addCommand('codesample', function () { var node = editor.selection.getNode(); if (editor.selection.isCollapsed() || Utils.isCodeSample(node)) { Dialog.open(editor); } else { editor.formatter.toggle('code'); } }); }; var Commands = { register: register }; var setup = function (editor) { var $ = editor.$; editor.on('PreProcess', function (e) { $('pre[contenteditable=false]', e.node).filter(Utils.trimArg(Utils.isCodeSample)).each(function (idx, elm) { var $elm = $(elm), code = elm.textContent; $elm.attr('class', $.trim($elm.attr('class'))); $elm.removeAttr('contentEditable'); $elm.empty().append($('<code></code>').each(function () { this.textContent = code; })); }); }); editor.on('SetContent', function () { var unprocessedCodeSamples = $('pre').filter(Utils.trimArg(Utils.isCodeSample)).filter(function (idx, elm) { return elm.contentEditable !== 'false'; }); if (unprocessedCodeSamples.length) { editor.undoManager.transact(function () { unprocessedCodeSamples.each(function (idx, elm) { $(elm).find('br').each(function (idx, elm) { elm.parentNode.replaceChild(editor.getDoc().createTextNode('\n'), elm); }); elm.contentEditable = false; elm.innerHTML = editor.dom.encode(elm.textContent); Prism.highlightElement(elm); elm.className = $.trim(elm.className); }); }); } }); }; var FilterContent = { setup: setup }; var loadCss = function (editor, pluginUrl, addedInlineCss, addedCss) { var linkElm; var contentCss = Settings.getContentCss(editor); if (editor.inline && addedInlineCss.get()) { return; } if (!editor.inline && addedCss.get()) { return; } if (editor.inline) { addedInlineCss.set(true); } else { addedCss.set(true); } if (contentCss !== false) { linkElm = editor.dom.create('link', { rel: 'stylesheet', href: contentCss ? contentCss : pluginUrl + '/css/prism.css' }); editor.getDoc().getElementsByTagName('head')[0].appendChild(linkElm); } }; var LoadCss = { loadCss: loadCss }; var register$1 = function (editor) { editor.addButton('codesample', { cmd: 'codesample', title: 'Insert/Edit code sample' }); editor.addMenuItem('codesample', { cmd: 'codesample', text: 'Code sample', icon: 'codesample' }); }; var Buttons = { register: register$1 }; var addedInlineCss = Cell(false); global.add('codesample', function (editor, pluginUrl) { var addedCss = Cell(false); FilterContent.setup(editor); Buttons.register(editor); Commands.register(editor); editor.on('init', function () { LoadCss.loadCss(editor, pluginUrl, addedInlineCss, addedCss); }); editor.on('dblclick', function (ev) { if (Utils.isCodeSample(ev.target)) { Dialog.open(editor); } }); }); function Plugin () { } return Plugin; }(window)); })(); (function () { var colorpicker = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.util.Color'); var showPreview = function (win, hexColor) { win.find('#preview')[0].getEl().style.background = hexColor; }; var setColor = function (win, value) { var color = global$1(value), rgb = color.toRgb(); win.fromJSON({ r: rgb.r, g: rgb.g, b: rgb.b, hex: color.toHex().substr(1) }); showPreview(win, color.toHex()); }; var open = function (editor, callback, value) { var win = editor.windowManager.open({ title: 'Color', items: { type: 'container', layout: 'flex', direction: 'row', align: 'stretch', padding: 5, spacing: 10, items: [ { type: 'colorpicker', value: value, onchange: function () { var rgb = this.rgb(); if (win) { win.find('#r').value(rgb.r); win.find('#g').value(rgb.g); win.find('#b').value(rgb.b); win.find('#hex').value(this.value().substr(1)); showPreview(win, this.value()); } } }, { type: 'form', padding: 0, labelGap: 5, defaults: { type: 'textbox', size: 7, value: '0', flex: 1, spellcheck: false, onchange: function () { var colorPickerCtrl = win.find('colorpicker')[0]; var name, value; name = this.name(); value = this.value(); if (name === 'hex') { value = '#' + value; setColor(win, value); colorPickerCtrl.value(value); return; } value = { r: win.find('#r').value(), g: win.find('#g').value(), b: win.find('#b').value() }; colorPickerCtrl.value(value); setColor(win, value); } }, items: [ { name: 'r', label: 'R', autofocus: 1 }, { name: 'g', label: 'G' }, { name: 'b', label: 'B' }, { name: 'hex', label: '#', value: '000000' }, { name: 'preview', type: 'container', border: 1 } ] } ] }, onSubmit: function () { callback('#' + win.toJSON().hex); } }); setColor(win, value); }; var Dialog = { open: open }; global.add('colorpicker', function (editor) { if (!editor.settings.color_picker_callback) { editor.settings.color_picker_callback = function (callback, value) { Dialog.open(editor, callback, value); }; } }); function Plugin () { } return Plugin; }()); })(); (function () { var contextmenu = (function () { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var get = function (visibleState) { var isContextMenuVisible = function () { return visibleState.get(); }; return { isContextMenuVisible: isContextMenuVisible }; }; var Api = { get: get }; var shouldNeverUseNative = function (editor) { return editor.settings.contextmenu_never_use_native; }; var getContextMenu = function (editor) { return editor.getParam('contextmenu', 'link openlink image inserttable | cell row column deletetable'); }; var Settings = { shouldNeverUseNative: shouldNeverUseNative, getContextMenu: getContextMenu }; var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var getUiContainer = function (editor) { return global$1.DOM.select(editor.settings.ui_container)[0]; }; var nu = function (x, y) { return { x: x, y: y }; }; var transpose = function (pos, dx, dy) { return nu(pos.x + dx, pos.y + dy); }; var fromPageXY = function (e) { return nu(e.pageX, e.pageY); }; var fromClientXY = function (e) { return nu(e.clientX, e.clientY); }; var transposeUiContainer = function (element, pos) { if (element && global$1.DOM.getStyle(element, 'position', true) !== 'static') { var containerPos = global$1.DOM.getPos(element); var dx = containerPos.x - element.scrollLeft; var dy = containerPos.y - element.scrollTop; return transpose(pos, -dx, -dy); } else { return transpose(pos, 0, 0); } }; var transposeContentAreaContainer = function (element, pos) { var containerPos = global$1.DOM.getPos(element); return transpose(pos, containerPos.x, containerPos.y); }; var getPos = function (editor, e) { if (editor.inline) { return transposeUiContainer(getUiContainer(editor), fromPageXY(e)); } else { var iframePos = transposeContentAreaContainer(editor.getContentAreaContainer(), fromClientXY(e)); return transposeUiContainer(getUiContainer(editor), iframePos); } }; var Coords = { getPos: getPos }; var global$2 = tinymce.util.Tools.resolve('tinymce.ui.Factory'); var global$3 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var renderMenu = function (editor, visibleState) { var menu, contextmenu; var items = []; contextmenu = Settings.getContextMenu(editor); global$3.each(contextmenu.split(/[ ,]/), function (name) { var item = editor.menuItems[name]; if (name === '|') { item = { text: name }; } if (item) { item.shortcut = ''; items.push(item); } }); for (var i = 0; i < items.length; i++) { if (items[i].text === '|') { if (i === 0 || i === items.length - 1) { items.splice(i, 1); } } } menu = global$2.create('menu', { items: items, context: 'contextmenu', classes: 'contextmenu' }); menu.uiContainer = getUiContainer(editor); menu.renderTo(getUiContainer(editor)); menu.on('hide', function (e) { if (e.control === this) { visibleState.set(false); } }); editor.on('remove', function () { menu.remove(); menu = null; }); return menu; }; var show = function (editor, pos, visibleState, menu) { if (menu.get() === null) { menu.set(renderMenu(editor, visibleState)); } else { menu.get().show(); } menu.get().moveTo(pos.x, pos.y); visibleState.set(true); }; var ContextMenu = { show: show }; var isNativeOverrideKeyEvent = function (editor, e) { return e.ctrlKey && !Settings.shouldNeverUseNative(editor); }; var setup = function (editor, visibleState, menu) { editor.on('contextmenu', function (e) { if (isNativeOverrideKeyEvent(editor, e)) { return; } e.preventDefault(); ContextMenu.show(editor, Coords.getPos(editor, e), visibleState, menu); }); }; var Bind = { setup: setup }; global.add('contextmenu', function (editor) { var menu = Cell(null), visibleState = Cell(false); Bind.setup(editor, visibleState, menu); return Api.get(visibleState); }); function Plugin () { } return Plugin; }()); })(); (function () { var directionality = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var setDir = function (editor, dir) { var dom = editor.dom; var curDir; var blocks = editor.selection.getSelectedBlocks(); if (blocks.length) { curDir = dom.getAttrib(blocks[0], 'dir'); global$1.each(blocks, function (block) { if (!dom.getParent(block.parentNode, '*[dir="' + dir + '"]', dom.getRoot())) { dom.setAttrib(block, 'dir', curDir !== dir ? dir : null); } }); editor.nodeChanged(); } }; var Direction = { setDir: setDir }; var register = function (editor) { editor.addCommand('mceDirectionLTR', function () { Direction.setDir(editor, 'ltr'); }); editor.addCommand('mceDirectionRTL', function () { Direction.setDir(editor, 'rtl'); }); }; var Commands = { register: register }; var generateSelector = function (dir) { var selector = []; global$1.each('h1 h2 h3 h4 h5 h6 div p'.split(' '), function (name) { selector.push(name + '[dir=' + dir + ']'); }); return selector.join(','); }; var register$1 = function (editor) { editor.addButton('ltr', { title: 'Left to right', cmd: 'mceDirectionLTR', stateSelector: generateSelector('ltr') }); editor.addButton('rtl', { title: 'Right to left', cmd: 'mceDirectionRTL', stateSelector: generateSelector('rtl') }); }; var Buttons = { register: register$1 }; global.add('directionality', function (editor) { Commands.register(editor); Buttons.register(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var emoticons = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var emoticons = [ [ 'cool', 'cry', 'embarassed', 'foot-in-mouth' ], [ 'frown', 'innocent', 'kiss', 'laughing' ], [ 'money-mouth', 'sealed', 'smile', 'surprised' ], [ 'tongue-out', 'undecided', 'wink', 'yell' ] ]; var getHtml = function (pluginUrl) { var emoticonsHtml; emoticonsHtml = '<table role="list" class="mce-grid">'; global$1.each(emoticons, function (row) { emoticonsHtml += '<tr>'; global$1.each(row, function (icon) { var emoticonUrl = pluginUrl + '/img/smiley-' + icon + '.gif'; emoticonsHtml += '<td><a href="#" data-mce-url="' + emoticonUrl + '" data-mce-alt="' + icon + '" tabindex="-1" ' + 'role="option" aria-label="' + icon + '"><img src="' + emoticonUrl + '" style="width: 18px; height: 18px" role="presentation" /></a></td>'; }); emoticonsHtml += '</tr>'; }); emoticonsHtml += '</table>'; return emoticonsHtml; }; var PanelHtml = { getHtml: getHtml }; var insertEmoticon = function (editor, src, alt) { editor.insertContent(editor.dom.createHTML('img', { src: src, alt: alt })); }; var register = function (editor, pluginUrl) { var panelHtml = PanelHtml.getHtml(pluginUrl); editor.addButton('emoticons', { type: 'panelbutton', panel: { role: 'application', autohide: true, html: panelHtml, onclick: function (e) { var linkElm = editor.dom.getParent(e.target, 'a'); if (linkElm) { insertEmoticon(editor, linkElm.getAttribute('data-mce-url'), linkElm.getAttribute('data-mce-alt')); this.hide(); } } }, tooltip: 'Emoticons' }); }; var Buttons = { register: register }; global.add('emoticons', function (editor, pluginUrl) { Buttons.register(editor, pluginUrl); }); function Plugin () { } return Plugin; }()); })(); (function () { var fullpage = (function () { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var global$2 = tinymce.util.Tools.resolve('tinymce.html.DomParser'); var global$3 = tinymce.util.Tools.resolve('tinymce.html.Node'); var global$4 = tinymce.util.Tools.resolve('tinymce.html.Serializer'); var shouldHideInSourceView = function (editor) { return editor.getParam('fullpage_hide_in_source_view'); }; var getDefaultXmlPi = function (editor) { return editor.getParam('fullpage_default_xml_pi'); }; var getDefaultEncoding = function (editor) { return editor.getParam('fullpage_default_encoding'); }; var getDefaultFontFamily = function (editor) { return editor.getParam('fullpage_default_font_family'); }; var getDefaultFontSize = function (editor) { return editor.getParam('fullpage_default_font_size'); }; var getDefaultTextColor = function (editor) { return editor.getParam('fullpage_default_text_color'); }; var getDefaultTitle = function (editor) { return editor.getParam('fullpage_default_title'); }; var getDefaultDocType = function (editor) { return editor.getParam('fullpage_default_doctype', '<!DOCTYPE html>'); }; var Settings = { shouldHideInSourceView: shouldHideInSourceView, getDefaultXmlPi: getDefaultXmlPi, getDefaultEncoding: getDefaultEncoding, getDefaultFontFamily: getDefaultFontFamily, getDefaultFontSize: getDefaultFontSize, getDefaultTextColor: getDefaultTextColor, getDefaultTitle: getDefaultTitle, getDefaultDocType: getDefaultDocType }; var parseHeader = function (head) { return global$2({ validate: false, root_name: '#document' }).parse(head); }; var htmlToData = function (editor, head) { var headerFragment = parseHeader(head); var data = {}; var elm, matches; function getAttr(elm, name) { var value = elm.attr(name); return value || ''; } data.fontface = Settings.getDefaultFontFamily(editor); data.fontsize = Settings.getDefaultFontSize(editor); elm = headerFragment.firstChild; if (elm.type === 7) { data.xml_pi = true; matches = /encoding="([^"]+)"/.exec(elm.value); if (matches) { data.docencoding = matches[1]; } } elm = headerFragment.getAll('#doctype')[0]; if (elm) { data.doctype = '<!DOCTYPE' + elm.value + '>'; } elm = headerFragment.getAll('title')[0]; if (elm && elm.firstChild) { data.title = elm.firstChild.value; } global$1.each(headerFragment.getAll('meta'), function (meta) { var name = meta.attr('name'); var httpEquiv = meta.attr('http-equiv'); var matches; if (name) { data[name.toLowerCase()] = meta.attr('content'); } else if (httpEquiv === 'Content-Type') { matches = /charset\s*=\s*(.*)\s*/gi.exec(meta.attr('content')); if (matches) { data.docencoding = matches[1]; } } }); elm = headerFragment.getAll('html')[0]; if (elm) { data.langcode = getAttr(elm, 'lang') || getAttr(elm, 'xml:lang'); } data.stylesheets = []; global$1.each(headerFragment.getAll('link'), function (link) { if (link.attr('rel') === 'stylesheet') { data.stylesheets.push(link.attr('href')); } }); elm = headerFragment.getAll('body')[0]; if (elm) { data.langdir = getAttr(elm, 'dir'); data.style = getAttr(elm, 'style'); data.visited_color = getAttr(elm, 'vlink'); data.link_color = getAttr(elm, 'link'); data.active_color = getAttr(elm, 'alink'); } return data; }; var dataToHtml = function (editor, data, head) { var headerFragment, headElement, html, elm, value; var dom = editor.dom; function setAttr(elm, name, value) { elm.attr(name, value ? value : undefined); } function addHeadNode(node) { if (headElement.firstChild) { headElement.insert(node, headElement.firstChild); } else { headElement.append(node); } } headerFragment = parseHeader(head); headElement = headerFragment.getAll('head')[0]; if (!headElement) { elm = headerFragment.getAll('html')[0]; headElement = new global$3('head', 1); if (elm.firstChild) { elm.insert(headElement, elm.firstChild, true); } else { elm.append(headElement); } } elm = headerFragment.firstChild; if (data.xml_pi) { value = 'version="1.0"'; if (data.docencoding) { value += ' encoding="' + data.docencoding + '"'; } if (elm.type !== 7) { elm = new global$3('xml', 7); headerFragment.insert(elm, headerFragment.firstChild, true); } elm.value = value; } else if (elm && elm.type === 7) { elm.remove(); } elm = headerFragment.getAll('#doctype')[0]; if (data.doctype) { if (!elm) { elm = new global$3('#doctype', 10); if (data.xml_pi) { headerFragment.insert(elm, headerFragment.firstChild); } else { addHeadNode(elm); } } elm.value = data.doctype.substring(9, data.doctype.length - 1); } else if (elm) { elm.remove(); } elm = null; global$1.each(headerFragment.getAll('meta'), function (meta) { if (meta.attr('http-equiv') === 'Content-Type') { elm = meta; } }); if (data.docencoding) { if (!elm) { elm = new global$3('meta', 1); elm.attr('http-equiv', 'Content-Type'); elm.shortEnded = true; addHeadNode(elm); } elm.attr('content', 'text/html; charset=' + data.docencoding); } else if (elm) { elm.remove(); } elm = headerFragment.getAll('title')[0]; if (data.title) { if (!elm) { elm = new global$3('title', 1); addHeadNode(elm); } else { elm.empty(); } elm.append(new global$3('#text', 3)).value = data.title; } else if (elm) { elm.remove(); } global$1.each('keywords,description,author,copyright,robots'.split(','), function (name) { var nodes = headerFragment.getAll('meta'); var i, meta; var value = data[name]; for (i = 0; i < nodes.length; i++) { meta = nodes[i]; if (meta.attr('name') === name) { if (value) { meta.attr('content', value); } else { meta.remove(); } return; } } if (value) { elm = new global$3('meta', 1); elm.attr('name', name); elm.attr('content', value); elm.shortEnded = true; addHeadNode(elm); } }); var currentStyleSheetsMap = {}; global$1.each(headerFragment.getAll('link'), function (stylesheet) { if (stylesheet.attr('rel') === 'stylesheet') { currentStyleSheetsMap[stylesheet.attr('href')] = stylesheet; } }); global$1.each(data.stylesheets, function (stylesheet) { if (!currentStyleSheetsMap[stylesheet]) { elm = new global$3('link', 1); elm.attr({ rel: 'stylesheet', text: 'text/css', href: stylesheet }); elm.shortEnded = true; addHeadNode(elm); } delete currentStyleSheetsMap[stylesheet]; }); global$1.each(currentStyleSheetsMap, function (stylesheet) { stylesheet.remove(); }); elm = headerFragment.getAll('body')[0]; if (elm) { setAttr(elm, 'dir', data.langdir); setAttr(elm, 'style', data.style); setAttr(elm, 'vlink', data.visited_color); setAttr(elm, 'link', data.link_color); setAttr(elm, 'alink', data.active_color); dom.setAttribs(editor.getBody(), { style: data.style, dir: data.dir, vLink: data.visited_color, link: data.link_color, aLink: data.active_color }); } elm = headerFragment.getAll('html')[0]; if (elm) { setAttr(elm, 'lang', data.langcode); setAttr(elm, 'xml:lang', data.langcode); } if (!headElement.firstChild) { headElement.remove(); } html = global$4({ validate: false, indent: true, apply_source_formatting: true, indent_before: 'head,html,body,meta,title,script,link,style', indent_after: 'head,html,body,meta,title,script,link,style' }).serialize(headerFragment); return html.substring(0, html.indexOf('</body>')); }; var Parser = { parseHeader: parseHeader, htmlToData: htmlToData, dataToHtml: dataToHtml }; var open = function (editor, headState) { var data = Parser.htmlToData(editor, headState.get()); editor.windowManager.open({ title: 'Document properties', data: data, defaults: { type: 'textbox', size: 40 }, body: [ { name: 'title', label: 'Title' }, { name: 'keywords', label: 'Keywords' }, { name: 'description', label: 'Description' }, { name: 'robots', label: 'Robots' }, { name: 'author', label: 'Author' }, { name: 'docencoding', label: 'Encoding' } ], onSubmit: function (e) { var headHtml = Parser.dataToHtml(editor, global$1.extend(data, e.data), headState.get()); headState.set(headHtml); } }); }; var Dialog = { open: open }; var register = function (editor, headState) { editor.addCommand('mceFullPageProperties', function () { Dialog.open(editor, headState); }); }; var Commands = { register: register }; var protectHtml = function (protect, html) { global$1.each(protect, function (pattern) { html = html.replace(pattern, function (str) { return '<!--mce:protected ' + escape(str) + '-->'; }); }); return html; }; var unprotectHtml = function (html) { return html.replace(/<!--mce:protected ([\s\S]*?)-->/g, function (a, m) { return unescape(m); }); }; var Protect = { protectHtml: protectHtml, unprotectHtml: unprotectHtml }; var each = global$1.each; var low = function (s) { return s.replace(/<\/?[A-Z]+/g, function (a) { return a.toLowerCase(); }); }; var handleSetContent = function (editor, headState, footState, evt) { var startPos, endPos, content, headerFragment, styles = ''; var dom = editor.dom; var elm; if (evt.selection) { return; } content = Protect.protectHtml(editor.settings.protect, evt.content); if (evt.format === 'raw' && headState.get()) { return; } if (evt.source_view && Settings.shouldHideInSourceView(editor)) { return; } if (content.length === 0 && !evt.source_view) { content = global$1.trim(headState.get()) + '\n' + global$1.trim(content) + '\n' + global$1.trim(footState.get()); } content = content.replace(/<(\/?)BODY/gi, '<$1body'); startPos = content.indexOf('<body'); if (startPos !== -1) { startPos = content.indexOf('>', startPos); headState.set(low(content.substring(0, startPos + 1))); endPos = content.indexOf('</body', startPos); if (endPos === -1) { endPos = content.length; } evt.content = global$1.trim(content.substring(startPos + 1, endPos)); footState.set(low(content.substring(endPos))); } else { headState.set(getDefaultHeader(editor)); footState.set('\n</body>\n</html>'); } headerFragment = Parser.parseHeader(headState.get()); each(headerFragment.getAll('style'), function (node) { if (node.firstChild) { styles += node.firstChild.value; } }); elm = headerFragment.getAll('body')[0]; if (elm) { dom.setAttribs(editor.getBody(), { style: elm.attr('style') || '', dir: elm.attr('dir') || '', vLink: elm.attr('vlink') || '', link: elm.attr('link') || '', aLink: elm.attr('alink') || '' }); } dom.remove('fullpage_styles'); var headElm = editor.getDoc().getElementsByTagName('head')[0]; if (styles) { dom.add(headElm, 'style', { id: 'fullpage_styles' }, styles); elm = dom.get('fullpage_styles'); if (elm.styleSheet) { elm.styleSheet.cssText = styles; } } var currentStyleSheetsMap = {}; global$1.each(headElm.getElementsByTagName('link'), function (stylesheet) { if (stylesheet.rel === 'stylesheet' && stylesheet.getAttribute('data-mce-fullpage')) { currentStyleSheetsMap[stylesheet.href] = stylesheet; } }); global$1.each(headerFragment.getAll('link'), function (stylesheet) { var href = stylesheet.attr('href'); if (!href) { return true; } if (!currentStyleSheetsMap[href] && stylesheet.attr('rel') === 'stylesheet') { dom.add(headElm, 'link', { 'rel': 'stylesheet', 'text': 'text/css', 'href': href, 'data-mce-fullpage': '1' }); } delete currentStyleSheetsMap[href]; }); global$1.each(currentStyleSheetsMap, function (stylesheet) { stylesheet.parentNode.removeChild(stylesheet); }); }; var getDefaultHeader = function (editor) { var header = '', value, styles = ''; if (Settings.getDefaultXmlPi(editor)) { var piEncoding = Settings.getDefaultEncoding(editor); header += '<?xml version="1.0" encoding="' + (piEncoding ? piEncoding : 'ISO-8859-1') + '" ?>\n'; } header += Settings.getDefaultDocType(editor); header += '\n<html>\n<head>\n'; if (value = Settings.getDefaultTitle(editor)) { header += '<title>' + value + '</title>\n'; } if (value = Settings.getDefaultEncoding(editor)) { header += '<meta http-equiv="Content-Type" content="text/html; charset=' + value + '" />\n'; } if (value = Settings.getDefaultFontFamily(editor)) { styles += 'font-family: ' + value + ';'; } if (value = Settings.getDefaultFontSize(editor)) { styles += 'font-size: ' + value + ';'; } if (value = Settings.getDefaultTextColor(editor)) { styles += 'color: ' + value + ';'; } header += '</head>\n<body' + (styles ? ' style="' + styles + '"' : '') + '>\n'; return header; }; var handleGetContent = function (editor, head, foot, evt) { if (!evt.selection && (!evt.source_view || !Settings.shouldHideInSourceView(editor))) { evt.content = Protect.unprotectHtml(global$1.trim(head) + '\n' + global$1.trim(evt.content) + '\n' + global$1.trim(foot)); } }; var setup = function (editor, headState, footState) { editor.on('BeforeSetContent', function (evt) { handleSetContent(editor, headState, footState, evt); }); editor.on('GetContent', function (evt) { handleGetContent(editor, headState.get(), footState.get(), evt); }); }; var FilterContent = { setup: setup }; var register$1 = function (editor) { editor.addButton('fullpage', { title: 'Document properties', cmd: 'mceFullPageProperties' }); editor.addMenuItem('fullpage', { text: 'Document properties', cmd: 'mceFullPageProperties', context: 'file' }); }; var Buttons = { register: register$1 }; global.add('fullpage', function (editor) { var headState = Cell(''), footState = Cell(''); Commands.register(editor, headState); Buttons.register(editor); FilterContent.setup(editor, headState, footState); }); function Plugin () { } return Plugin; }()); })(); (function () { var fullscreen = (function (domGlobals) { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var get = function (fullscreenState) { return { isFullscreen: function () { return fullscreenState.get() !== null; } }; }; var Api = { get: get }; var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var fireFullscreenStateChanged = function (editor, state) { editor.fire('FullscreenStateChanged', { state: state }); }; var Events = { fireFullscreenStateChanged: fireFullscreenStateChanged }; var DOM = global$1.DOM; var getWindowSize = function () { var w; var h; var win = domGlobals.window; var doc = domGlobals.document; var body = doc.body; if (body.offsetWidth) { w = body.offsetWidth; h = body.offsetHeight; } if (win.innerWidth && win.innerHeight) { w = win.innerWidth; h = win.innerHeight; } return { w: w, h: h }; }; var getScrollPos = function () { var vp = DOM.getViewPort(); return { x: vp.x, y: vp.y }; }; var setScrollPos = function (pos) { domGlobals.window.scrollTo(pos.x, pos.y); }; var toggleFullscreen = function (editor, fullscreenState) { var body = domGlobals.document.body; var documentElement = domGlobals.document.documentElement; var editorContainerStyle; var editorContainer, iframe, iframeStyle; var fullscreenInfo = fullscreenState.get(); var resize = function () { DOM.setStyle(iframe, 'height', getWindowSize().h - (editorContainer.clientHeight - iframe.clientHeight)); }; var removeResize = function () { DOM.unbind(domGlobals.window, 'resize', resize); }; editorContainer = editor.getContainer(); editorContainerStyle = editorContainer.style; iframe = editor.getContentAreaContainer().firstChild; iframeStyle = iframe.style; if (!fullscreenInfo) { var newFullScreenInfo = { scrollPos: getScrollPos(), containerWidth: editorContainerStyle.width, containerHeight: editorContainerStyle.height, iframeWidth: iframeStyle.width, iframeHeight: iframeStyle.height, resizeHandler: resize, removeHandler: removeResize }; iframeStyle.width = iframeStyle.height = '100%'; editorContainerStyle.width = editorContainerStyle.height = ''; DOM.addClass(body, 'mce-fullscreen'); DOM.addClass(documentElement, 'mce-fullscreen'); DOM.addClass(editorContainer, 'mce-fullscreen'); DOM.bind(domGlobals.window, 'resize', resize); editor.on('remove', removeResize); resize(); fullscreenState.set(newFullScreenInfo); Events.fireFullscreenStateChanged(editor, true); } else { iframeStyle.width = fullscreenInfo.iframeWidth; iframeStyle.height = fullscreenInfo.iframeHeight; if (fullscreenInfo.containerWidth) { editorContainerStyle.width = fullscreenInfo.containerWidth; } if (fullscreenInfo.containerHeight) { editorContainerStyle.height = fullscreenInfo.containerHeight; } DOM.removeClass(body, 'mce-fullscreen'); DOM.removeClass(documentElement, 'mce-fullscreen'); DOM.removeClass(editorContainer, 'mce-fullscreen'); setScrollPos(fullscreenInfo.scrollPos); DOM.unbind(domGlobals.window, 'resize', fullscreenInfo.resizeHandler); editor.off('remove', fullscreenInfo.removeHandler); fullscreenState.set(null); Events.fireFullscreenStateChanged(editor, false); } }; var Actions = { toggleFullscreen: toggleFullscreen }; var register = function (editor, fullscreenState) { editor.addCommand('mceFullScreen', function () { Actions.toggleFullscreen(editor, fullscreenState); }); }; var Commands = { register: register }; var postRender = function (editor) { return function (e) { var ctrl = e.control; editor.on('FullscreenStateChanged', function (e) { ctrl.active(e.state); }); }; }; var register$1 = function (editor) { editor.addMenuItem('fullscreen', { text: 'Fullscreen', shortcut: 'Ctrl+Shift+F', selectable: true, cmd: 'mceFullScreen', onPostRender: postRender(editor), context: 'view' }); editor.addButton('fullscreen', { active: false, tooltip: 'Fullscreen', cmd: 'mceFullScreen', onPostRender: postRender(editor) }); }; var Buttons = { register: register$1 }; global.add('fullscreen', function (editor) { var fullscreenState = Cell(null); if (editor.settings.inline) { return Api.get(fullscreenState); } Commands.register(editor, fullscreenState); Buttons.register(editor); editor.addShortcut('Ctrl+Shift+F', '', 'mceFullScreen'); return Api.get(fullscreenState); }); function Plugin () { } return Plugin; }(window)); })(); (function () { var help = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var constant = function (value) { return function () { return value; }; }; function curry(fn) { var initialArgs = []; for (var _i = 1; _i < arguments.length; _i++) { initialArgs[_i - 1] = arguments[_i]; } return function () { var restArgs = []; for (var _i = 0; _i < arguments.length; _i++) { restArgs[_i] = arguments[_i]; } var all = initialArgs.concat(restArgs); return fn.apply(null, all); }; } var not = function (f) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return !f.apply(null, args); }; }; var never = constant(false); var always = constant(true); var never$1 = never; var always$1 = always; var none = function () { return NONE; }; var NONE = function () { var eq = function (o) { return o.isNone(); }; var call = function (thunk) { return thunk(); }; var id = function (n) { return n; }; var noop = function () { }; var nul = function () { return null; }; var undef = function () { return undefined; }; var me = { fold: function (n, s) { return n(); }, is: never$1, isSome: never$1, isNone: always$1, getOr: id, getOrThunk: call, getOrDie: function (msg) { throw new Error(msg || 'error: getOrDie called on none.'); }, getOrNull: nul, getOrUndefined: undef, or: id, orThunk: call, map: none, ap: none, each: noop, bind: none, flatten: none, exists: never$1, forall: always$1, filter: none, equals: eq, equals_: eq, toArray: function () { return []; }, toString: constant('none()') }; if (Object.freeze) Object.freeze(me); return me; }(); var some = function (a) { var constant_a = function () { return a; }; var self = function () { return me; }; var map = function (f) { return some(f(a)); }; var bind = function (f) { return f(a); }; var me = { fold: function (n, s) { return s(a); }, is: function (v) { return a === v; }, isSome: always$1, isNone: never$1, getOr: constant_a, getOrThunk: constant_a, getOrDie: constant_a, getOrNull: constant_a, getOrUndefined: constant_a, or: self, orThunk: self, map: map, ap: function (optfab) { return optfab.fold(none, function (fab) { return some(fab(a)); }); }, each: function (f) { f(a); }, bind: bind, flatten: constant_a, exists: bind, forall: bind, filter: function (f) { return f(a) ? me : NONE; }, equals: function (o) { return o.is(a); }, equals_: function (o, elementEq) { return o.fold(never$1, function (b) { return elementEq(a, b); }); }, toArray: function () { return [a]; }, toString: function () { return 'some(' + a + ')'; } }; return me; }; var from = function (value) { return value === null || value === undefined ? NONE : some(value); }; var Option = { some: some, none: none, from: from }; var typeOf = function (x) { if (x === null) return 'null'; var t = typeof x; if (t === 'object' && Array.prototype.isPrototypeOf(x)) return 'array'; if (t === 'object' && String.prototype.isPrototypeOf(x)) return 'string'; return t; }; var isType = function (type) { return function (value) { return typeOf(value) === type; }; }; var isFunction = isType('function'); var rawIndexOf = function () { var pIndexOf = Array.prototype.indexOf; var fastIndex = function (xs, x) { return pIndexOf.call(xs, x); }; var slowIndex = function (xs, x) { return slowIndexOf(xs, x); }; return pIndexOf === undefined ? slowIndex : fastIndex; }(); var contains = function (xs, x) { return rawIndexOf(xs, x) > -1; }; var map = function (xs, f) { var len = xs.length; var r = new Array(len); for (var i = 0; i < len; i++) { var x = xs[i]; r[i] = f(x, i, xs); } return r; }; var filter = function (xs, pred) { var r = []; for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { r.push(x); } } return r; }; var find = function (xs, pred) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { return Option.some(x); } } return Option.none(); }; var slowIndexOf = function (xs, x) { for (var i = 0, len = xs.length; i < len; ++i) { if (xs[i] === x) { return i; } } return -1; }; var slice = Array.prototype.slice; var from$1 = isFunction(Array.from) ? Array.from : function (x) { return slice.call(x); }; var global$1 = tinymce.util.Tools.resolve('tinymce.util.I18n'); var global$2 = tinymce.util.Tools.resolve('tinymce.Env'); var meta = global$2.mac ? '\u2318' : 'Ctrl'; var access = global$2.mac ? 'Ctrl + Alt' : 'Shift + Alt'; var shortcuts = [ { shortcut: meta + ' + B', action: 'Bold' }, { shortcut: meta + ' + I', action: 'Italic' }, { shortcut: meta + ' + U', action: 'Underline' }, { shortcut: meta + ' + A', action: 'Select all' }, { shortcut: meta + ' + Y or ' + meta + ' + Shift + Z', action: 'Redo' }, { shortcut: meta + ' + Z', action: 'Undo' }, { shortcut: access + ' + 1', action: 'Header 1' }, { shortcut: access + ' + 2', action: 'Header 2' }, { shortcut: access + ' + 3', action: 'Header 3' }, { shortcut: access + ' + 4', action: 'Header 4' }, { shortcut: access + ' + 5', action: 'Header 5' }, { shortcut: access + ' + 6', action: 'Header 6' }, { shortcut: access + ' + 7', action: 'Paragraph' }, { shortcut: access + ' + 8', action: 'Div' }, { shortcut: access + ' + 9', action: 'Address' }, { shortcut: 'Alt + F9', action: 'Focus to menubar' }, { shortcut: 'Alt + F10', action: 'Focus to toolbar' }, { shortcut: 'Alt + F11', action: 'Focus to element path' }, { shortcut: 'Ctrl + F9', action: 'Focus to contextual toolbar' }, { shortcut: meta + ' + K', action: 'Insert link (if link plugin activated)' }, { shortcut: meta + ' + S', action: 'Save (if save plugin activated)' }, { shortcut: meta + ' + F', action: 'Find (if searchreplace plugin activated)' } ]; var KeyboardShortcuts = { shortcuts: shortcuts }; var makeTab = function () { var makeAriaLabel = function (shortcut) { return 'aria-label="Action: ' + shortcut.action + ', Shortcut: ' + shortcut.shortcut.replace(/Ctrl/g, 'Control') + '"'; }; var shortcutLisString = map(KeyboardShortcuts.shortcuts, function (shortcut) { return '<tr data-mce-tabstop="1" tabindex="-1" ' + makeAriaLabel(shortcut) + '>' + '<td>' + global$1.translate(shortcut.action) + '</td>' + '<td>' + shortcut.shortcut + '</td>' + '</tr>'; }).join(''); return { title: 'Handy Shortcuts', type: 'container', style: 'overflow-y: auto; overflow-x: hidden; max-height: 250px', items: [{ type: 'container', html: '<div>' + '<table class="mce-table-striped">' + '<thead>' + '<th>' + global$1.translate('Action') + '</th>' + '<th>' + global$1.translate('Shortcut') + '</th>' + '</thead>' + shortcutLisString + '</table>' + '</div>' }] }; }; var KeyboardShortcutsTab = { makeTab: makeTab }; var keys = Object.keys; var supplant = function (str, obj) { var isStringOrNumber = function (a) { var t = typeof a; return t === 'string' || t === 'number'; }; return str.replace(/\$\{([^{}]*)\}/g, function (fullMatch, key) { var value = obj[key]; return isStringOrNumber(value) ? value.toString() : fullMatch; }); }; var urls = [ { key: 'advlist', name: 'Advanced List' }, { key: 'anchor', name: 'Anchor' }, { key: 'autolink', name: 'Autolink' }, { key: 'autoresize', name: 'Autoresize' }, { key: 'autosave', name: 'Autosave' }, { key: 'bbcode', name: 'BBCode' }, { key: 'charmap', name: 'Character Map' }, { key: 'code', name: 'Code' }, { key: 'codesample', name: 'Code Sample' }, { key: 'colorpicker', name: 'Color Picker' }, { key: 'compat3x', name: '3.x Compatibility' }, { key: 'contextmenu', name: 'Context Menu' }, { key: 'directionality', name: 'Directionality' }, { key: 'emoticons', name: 'Emoticons' }, { key: 'fullpage', name: 'Full Page' }, { key: 'fullscreen', name: 'Full Screen' }, { key: 'help', name: 'Help' }, { key: 'hr', name: 'Horizontal Rule' }, { key: 'image', name: 'Image' }, { key: 'imagetools', name: 'Image Tools' }, { key: 'importcss', name: 'Import CSS' }, { key: 'insertdatetime', name: 'Insert Date/Time' }, { key: 'legacyoutput', name: 'Legacy Output' }, { key: 'link', name: 'Link' }, { key: 'lists', name: 'Lists' }, { key: 'media', name: 'Media' }, { key: 'nonbreaking', name: 'Nonbreaking' }, { key: 'noneditable', name: 'Noneditable' }, { key: 'pagebreak', name: 'Page Break' }, { key: 'paste', name: 'Paste' }, { key: 'preview', name: 'Preview' }, { key: 'print', name: 'Print' }, { key: 'save', name: 'Save' }, { key: 'searchreplace', name: 'Search and Replace' }, { key: 'spellchecker', name: 'Spell Checker' }, { key: 'tabfocus', name: 'Tab Focus' }, { key: 'table', name: 'Table' }, { key: 'template', name: 'Template' }, { key: 'textcolor', name: 'Text Color' }, { key: 'textpattern', name: 'Text Pattern' }, { key: 'toc', name: 'Table of Contents' }, { key: 'visualblocks', name: 'Visual Blocks' }, { key: 'visualchars', name: 'Visual Characters' }, { key: 'wordcount', name: 'Word Count' } ]; var PluginUrls = { urls: urls }; var makeLink = curry(supplant, '<a href="${url}" target="_blank" rel="noopener">${name}</a>'); var maybeUrlize = function (editor, key) { return find(PluginUrls.urls, function (x) { return x.key === key; }).fold(function () { var getMetadata = editor.plugins[key].getMetadata; return typeof getMetadata === 'function' ? makeLink(getMetadata()) : key; }, function (x) { return makeLink({ name: x.name, url: 'https://www.tinymce.com/docs/plugins/' + x.key }); }); }; var getPluginKeys = function (editor) { var keys$1 = keys(editor.plugins); return editor.settings.forced_plugins === undefined ? keys$1 : filter(keys$1, not(curry(contains, editor.settings.forced_plugins))); }; var pluginLister = function (editor) { var pluginKeys = getPluginKeys(editor); var pluginLis = map(pluginKeys, function (key) { return '<li>' + maybeUrlize(editor, key) + '</li>'; }); var count = pluginLis.length; var pluginsString = pluginLis.join(''); return '<p><b>' + global$1.translate([ 'Plugins installed ({0}):', count ]) + '</b></p>' + '<ul>' + pluginsString + '</ul>'; }; var installedPlugins = function (editor) { return { type: 'container', html: '<div style="overflow-y: auto; overflow-x: hidden; max-height: 230px; height: 230px;" data-mce-tabstop="1" tabindex="-1">' + pluginLister(editor) + '</div>', flex: 1 }; }; var availablePlugins = function () { return { type: 'container', html: '<div style="padding: 10px; background: #e3e7f4; height: 100%;" data-mce-tabstop="1" tabindex="-1">' + '<p><b>' + global$1.translate('Premium plugins:') + '</b></p>' + '<ul>' + '<li>PowerPaste</li>' + '<li>Spell Checker Pro</li>' + '<li>Accessibility Checker</li>' + '<li>Advanced Code Editor</li>' + '<li>Enhanced Media Embed</li>' + '<li>Link Checker</li>' + '</ul><br />' + '<p style="float: right;"><a href="https://www.tinymce.com/pricing/?utm_campaign=editor_referral&utm_medium=help_dialog&utm_source=tinymce" target="_blank">' + global$1.translate('Learn more...') + '</a></p>' + '</div>', flex: 1 }; }; var makeTab$1 = function (editor) { return { title: 'Plugins', type: 'container', style: 'overflow-y: auto; overflow-x: hidden;', layout: 'flex', padding: 10, spacing: 10, items: [ installedPlugins(editor), availablePlugins() ] }; }; var PluginsTab = { makeTab: makeTab$1 }; var global$3 = tinymce.util.Tools.resolve('tinymce.EditorManager'); var getVersion = function (major, minor) { return major.indexOf('@') === 0 ? 'X.X.X' : major + '.' + minor; }; var makeRow = function () { var version = getVersion(global$3.majorVersion, global$3.minorVersion); var changeLogLink = '<a href="https://www.tinymce.com/docs/changelog/?utm_campaign=editor_referral&utm_medium=help_dialog&utm_source=tinymce" target="_blank">TinyMCE ' + version + '</a>'; return [ { type: 'label', html: global$1.translate([ 'You are using {0}', changeLogLink ]) }, { type: 'spacer', flex: 1 }, { text: 'Close', onclick: function () { this.parent().parent().close(); } } ]; }; var ButtonsRow = { makeRow: makeRow }; var open = function (editor, pluginUrl) { return function () { editor.windowManager.open({ title: 'Help', bodyType: 'tabpanel', layout: 'flex', body: [ KeyboardShortcutsTab.makeTab(), PluginsTab.makeTab(editor) ], buttons: ButtonsRow.makeRow(), onPostRender: function () { var title = this.getEl('title'); title.innerHTML = '<img src="' + pluginUrl + '/img/logo.png" alt="TinyMCE Logo" style="display: inline-block; width: 200px; height: 50px">'; } }); }; }; var Dialog = { open: open }; var register = function (editor, pluginUrl) { editor.addCommand('mceHelp', Dialog.open(editor, pluginUrl)); }; var Commands = { register: register }; var register$1 = function (editor, pluginUrl) { editor.addButton('help', { icon: 'help', onclick: Dialog.open(editor, pluginUrl) }); editor.addMenuItem('help', { text: 'Help', icon: 'help', context: 'help', onclick: Dialog.open(editor, pluginUrl) }); }; var Buttons = { register: register$1 }; global.add('help', function (editor, pluginUrl) { Buttons.register(editor, pluginUrl); Commands.register(editor, pluginUrl); editor.shortcuts.add('Alt+0', 'Open help dialog', 'mceHelp'); }); function Plugin () { } return Plugin; }()); })(); (function () { var hr = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var register = function (editor) { editor.addCommand('InsertHorizontalRule', function () { editor.execCommand('mceInsertContent', false, '<hr />'); }); }; var Commands = { register: register }; var register$1 = function (editor) { editor.addButton('hr', { icon: 'hr', tooltip: 'Horizontal line', cmd: 'InsertHorizontalRule' }); editor.addMenuItem('hr', { icon: 'hr', text: 'Horizontal line', cmd: 'InsertHorizontalRule', context: 'insert' }); }; var Buttons = { register: register$1 }; global.add('hr', function (editor) { Commands.register(editor); Buttons.register(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var image = (function (domGlobals) { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var hasDimensions = function (editor) { return editor.settings.image_dimensions === false ? false : true; }; var hasAdvTab = function (editor) { return editor.settings.image_advtab === true ? true : false; }; var getPrependUrl = function (editor) { return editor.getParam('image_prepend_url', ''); }; var getClassList = function (editor) { return editor.getParam('image_class_list'); }; var hasDescription = function (editor) { return editor.settings.image_description === false ? false : true; }; var hasImageTitle = function (editor) { return editor.settings.image_title === true ? true : false; }; var hasImageCaption = function (editor) { return editor.settings.image_caption === true ? true : false; }; var getImageList = function (editor) { return editor.getParam('image_list', false); }; var hasUploadUrl = function (editor) { return editor.getParam('images_upload_url', false); }; var hasUploadHandler = function (editor) { return editor.getParam('images_upload_handler', false); }; var getUploadUrl = function (editor) { return editor.getParam('images_upload_url'); }; var getUploadHandler = function (editor) { return editor.getParam('images_upload_handler'); }; var getUploadBasePath = function (editor) { return editor.getParam('images_upload_base_path'); }; var getUploadCredentials = function (editor) { return editor.getParam('images_upload_credentials'); }; var Settings = { hasDimensions: hasDimensions, hasAdvTab: hasAdvTab, getPrependUrl: getPrependUrl, getClassList: getClassList, hasDescription: hasDescription, hasImageTitle: hasImageTitle, hasImageCaption: hasImageCaption, getImageList: getImageList, hasUploadUrl: hasUploadUrl, hasUploadHandler: hasUploadHandler, getUploadUrl: getUploadUrl, getUploadHandler: getUploadHandler, getUploadBasePath: getUploadBasePath, getUploadCredentials: getUploadCredentials }; var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')(); var path = function (parts, scope) { var o = scope !== undefined && scope !== null ? scope : Global; for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i) o = o[parts[i]]; return o; }; var resolve = function (p, scope) { var parts = p.split('.'); return path(parts, scope); }; var unsafe = function (name, scope) { return resolve(name, scope); }; var getOrDie = function (name, scope) { var actual = unsafe(name, scope); if (actual === undefined || actual === null) throw name + ' not available on this browser'; return actual; }; var Global$1 = { getOrDie: getOrDie }; function FileReader () { var f = Global$1.getOrDie('FileReader'); return new f(); } var global$1 = tinymce.util.Tools.resolve('tinymce.util.Promise'); var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var global$3 = tinymce.util.Tools.resolve('tinymce.util.XHR'); var parseIntAndGetMax = function (val1, val2) { return Math.max(parseInt(val1, 10), parseInt(val2, 10)); }; var getImageSize = function (url, callback) { var img = domGlobals.document.createElement('img'); function done(width, height) { if (img.parentNode) { img.parentNode.removeChild(img); } callback({ width: width, height: height }); } img.onload = function () { var width = parseIntAndGetMax(img.width, img.clientWidth); var height = parseIntAndGetMax(img.height, img.clientHeight); done(width, height); }; img.onerror = function () { done(0, 0); }; var style = img.style; style.visibility = 'hidden'; style.position = 'fixed'; style.bottom = style.left = '0px'; style.width = style.height = 'auto'; domGlobals.document.body.appendChild(img); img.src = url; }; var buildListItems = function (inputList, itemCallback, startItems) { function appendItems(values, output) { output = output || []; global$2.each(values, function (item) { var menuItem = { text: item.text || item.title }; if (item.menu) { menuItem.menu = appendItems(item.menu); } else { menuItem.value = item.value; itemCallback(menuItem); } output.push(menuItem); }); return output; } return appendItems(inputList, startItems || []); }; var removePixelSuffix = function (value) { if (value) { value = value.replace(/px$/, ''); } return value; }; var addPixelSuffix = function (value) { if (value.length > 0 && /^[0-9]+$/.test(value)) { value += 'px'; } return value; }; var mergeMargins = function (css) { if (css.margin) { var splitMargin = css.margin.split(' '); switch (splitMargin.length) { case 1: css['margin-top'] = css['margin-top'] || splitMargin[0]; css['margin-right'] = css['margin-right'] || splitMargin[0]; css['margin-bottom'] = css['margin-bottom'] || splitMargin[0]; css['margin-left'] = css['margin-left'] || splitMargin[0]; break; case 2: css['margin-top'] = css['margin-top'] || splitMargin[0]; css['margin-right'] = css['margin-right'] || splitMargin[1]; css['margin-bottom'] = css['margin-bottom'] || splitMargin[0]; css['margin-left'] = css['margin-left'] || splitMargin[1]; break; case 3: css['margin-top'] = css['margin-top'] || splitMargin[0]; css['margin-right'] = css['margin-right'] || splitMargin[1]; css['margin-bottom'] = css['margin-bottom'] || splitMargin[2]; css['margin-left'] = css['margin-left'] || splitMargin[1]; break; case 4: css['margin-top'] = css['margin-top'] || splitMargin[0]; css['margin-right'] = css['margin-right'] || splitMargin[1]; css['margin-bottom'] = css['margin-bottom'] || splitMargin[2]; css['margin-left'] = css['margin-left'] || splitMargin[3]; } delete css.margin; } return css; }; var createImageList = function (editor, callback) { var imageList = Settings.getImageList(editor); if (typeof imageList === 'string') { global$3.send({ url: imageList, success: function (text) { callback(JSON.parse(text)); } }); } else if (typeof imageList === 'function') { imageList(callback); } else { callback(imageList); } }; var waitLoadImage = function (editor, data, imgElm) { function selectImage() { imgElm.onload = imgElm.onerror = null; if (editor.selection) { editor.selection.select(imgElm); editor.nodeChanged(); } } imgElm.onload = function () { if (!data.width && !data.height && Settings.hasDimensions(editor)) { editor.dom.setAttribs(imgElm, { width: imgElm.clientWidth, height: imgElm.clientHeight }); } selectImage(); }; imgElm.onerror = selectImage; }; var blobToDataUri = function (blob) { return new global$1(function (resolve, reject) { var reader = FileReader(); reader.onload = function () { resolve(reader.result); }; reader.onerror = function () { reject(reader.error.message); }; reader.readAsDataURL(blob); }); }; var Utils = { getImageSize: getImageSize, buildListItems: buildListItems, removePixelSuffix: removePixelSuffix, addPixelSuffix: addPixelSuffix, mergeMargins: mergeMargins, createImageList: createImageList, waitLoadImage: waitLoadImage, blobToDataUri: blobToDataUri }; var global$4 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var hasOwnProperty = Object.prototype.hasOwnProperty; var shallow = function (old, nu) { return nu; }; var baseMerge = function (merger) { return function () { var objects = new Array(arguments.length); for (var i = 0; i < objects.length; i++) objects[i] = arguments[i]; if (objects.length === 0) throw new Error('Can\'t merge zero objects'); var ret = {}; for (var j = 0; j < objects.length; j++) { var curObject = objects[j]; for (var key in curObject) if (hasOwnProperty.call(curObject, key)) { ret[key] = merger(ret[key], curObject[key]); } } return ret; }; }; var merge = baseMerge(shallow); var DOM = global$4.DOM; var getHspace = function (image) { if (image.style.marginLeft && image.style.marginRight && image.style.marginLeft === image.style.marginRight) { return Utils.removePixelSuffix(image.style.marginLeft); } else { return ''; } }; var getVspace = function (image) { if (image.style.marginTop && image.style.marginBottom && image.style.marginTop === image.style.marginBottom) { return Utils.removePixelSuffix(image.style.marginTop); } else { return ''; } }; var getBorder = function (image) { if (image.style.borderWidth) { return Utils.removePixelSuffix(image.style.borderWidth); } else { return ''; } }; var getAttrib = function (image, name) { if (image.hasAttribute(name)) { return image.getAttribute(name); } else { return ''; } }; var getStyle = function (image, name) { return image.style[name] ? image.style[name] : ''; }; var hasCaption = function (image) { return image.parentNode !== null && image.parentNode.nodeName === 'FIGURE'; }; var setAttrib = function (image, name, value) { image.setAttribute(name, value); }; var wrapInFigure = function (image) { var figureElm = DOM.create('figure', { class: 'image' }); DOM.insertAfter(figureElm, image); figureElm.appendChild(image); figureElm.appendChild(DOM.create('figcaption', { contentEditable: true }, 'Caption')); figureElm.contentEditable = 'false'; }; var removeFigure = function (image) { var figureElm = image.parentNode; DOM.insertAfter(image, figureElm); DOM.remove(figureElm); }; var toggleCaption = function (image) { if (hasCaption(image)) { removeFigure(image); } else { wrapInFigure(image); } }; var normalizeStyle = function (image, normalizeCss) { var attrValue = image.getAttribute('style'); var value = normalizeCss(attrValue !== null ? attrValue : ''); if (value.length > 0) { image.setAttribute('style', value); image.setAttribute('data-mce-style', value); } else { image.removeAttribute('style'); } }; var setSize = function (name, normalizeCss) { return function (image, name, value) { if (image.style[name]) { image.style[name] = Utils.addPixelSuffix(value); normalizeStyle(image, normalizeCss); } else { setAttrib(image, name, value); } }; }; var getSize = function (image, name) { if (image.style[name]) { return Utils.removePixelSuffix(image.style[name]); } else { return getAttrib(image, name); } }; var setHspace = function (image, value) { var pxValue = Utils.addPixelSuffix(value); image.style.marginLeft = pxValue; image.style.marginRight = pxValue; }; var setVspace = function (image, value) { var pxValue = Utils.addPixelSuffix(value); image.style.marginTop = pxValue; image.style.marginBottom = pxValue; }; var setBorder = function (image, value) { var pxValue = Utils.addPixelSuffix(value); image.style.borderWidth = pxValue; }; var setBorderStyle = function (image, value) { image.style.borderStyle = value; }; var getBorderStyle = function (image) { return getStyle(image, 'borderStyle'); }; var isFigure = function (elm) { return elm.nodeName === 'FIGURE'; }; var defaultData = function () { return { src: '', alt: '', title: '', width: '', height: '', class: '', style: '', caption: false, hspace: '', vspace: '', border: '', borderStyle: '' }; }; var getStyleValue = function (normalizeCss, data) { var image = domGlobals.document.createElement('img'); setAttrib(image, 'style', data.style); if (getHspace(image) || data.hspace !== '') { setHspace(image, data.hspace); } if (getVspace(image) || data.vspace !== '') { setVspace(image, data.vspace); } if (getBorder(image) || data.border !== '') { setBorder(image, data.border); } if (getBorderStyle(image) || data.borderStyle !== '') { setBorderStyle(image, data.borderStyle); } return normalizeCss(image.getAttribute('style')); }; var create = function (normalizeCss, data) { var image = domGlobals.document.createElement('img'); write(normalizeCss, merge(data, { caption: false }), image); setAttrib(image, 'alt', data.alt); if (data.caption) { var figure = DOM.create('figure', { class: 'image' }); figure.appendChild(image); figure.appendChild(DOM.create('figcaption', { contentEditable: true }, 'Caption')); figure.contentEditable = 'false'; return figure; } else { return image; } }; var read = function (normalizeCss, image) { return { src: getAttrib(image, 'src'), alt: getAttrib(image, 'alt'), title: getAttrib(image, 'title'), width: getSize(image, 'width'), height: getSize(image, 'height'), class: getAttrib(image, 'class'), style: normalizeCss(getAttrib(image, 'style')), caption: hasCaption(image), hspace: getHspace(image), vspace: getVspace(image), border: getBorder(image), borderStyle: getStyle(image, 'borderStyle') }; }; var updateProp = function (image, oldData, newData, name, set) { if (newData[name] !== oldData[name]) { set(image, name, newData[name]); } }; var normalized = function (set, normalizeCss) { return function (image, name, value) { set(image, value); normalizeStyle(image, normalizeCss); }; }; var write = function (normalizeCss, newData, image) { var oldData = read(normalizeCss, image); updateProp(image, oldData, newData, 'caption', function (image, _name, _value) { return toggleCaption(image); }); updateProp(image, oldData, newData, 'src', setAttrib); updateProp(image, oldData, newData, 'alt', setAttrib); updateProp(image, oldData, newData, 'title', setAttrib); updateProp(image, oldData, newData, 'width', setSize('width', normalizeCss)); updateProp(image, oldData, newData, 'height', setSize('height', normalizeCss)); updateProp(image, oldData, newData, 'class', setAttrib); updateProp(image, oldData, newData, 'style', normalized(function (image, value) { return setAttrib(image, 'style', value); }, normalizeCss)); updateProp(image, oldData, newData, 'hspace', normalized(setHspace, normalizeCss)); updateProp(image, oldData, newData, 'vspace', normalized(setVspace, normalizeCss)); updateProp(image, oldData, newData, 'border', normalized(setBorder, normalizeCss)); updateProp(image, oldData, newData, 'borderStyle', normalized(setBorderStyle, normalizeCss)); }; var normalizeCss = function (editor, cssText) { var css = editor.dom.styles.parse(cssText); var mergedCss = Utils.mergeMargins(css); var compressed = editor.dom.styles.parse(editor.dom.styles.serialize(mergedCss)); return editor.dom.styles.serialize(compressed); }; var getSelectedImage = function (editor) { var imgElm = editor.selection.getNode(); var figureElm = editor.dom.getParent(imgElm, 'figure.image'); if (figureElm) { return editor.dom.select('img', figureElm)[0]; } if (imgElm && (imgElm.nodeName !== 'IMG' || imgElm.getAttribute('data-mce-object') || imgElm.getAttribute('data-mce-placeholder'))) { return null; } return imgElm; }; var splitTextBlock = function (editor, figure) { var dom = editor.dom; var textBlock = dom.getParent(figure.parentNode, function (node) { return editor.schema.getTextBlockElements()[node.nodeName]; }, editor.getBody()); if (textBlock) { return dom.split(textBlock, figure); } else { return figure; } }; var readImageDataFromSelection = function (editor) { var image = getSelectedImage(editor); return image ? read(function (css) { return normalizeCss(editor, css); }, image) : defaultData(); }; var insertImageAtCaret = function (editor, data) { var elm = create(function (css) { return normalizeCss(editor, css); }, data); editor.dom.setAttrib(elm, 'data-mce-id', '__mcenew'); editor.focus(); editor.selection.setContent(elm.outerHTML); var insertedElm = editor.dom.select('*[data-mce-id="__mcenew"]')[0]; editor.dom.setAttrib(insertedElm, 'data-mce-id', null); if (isFigure(insertedElm)) { var figure = splitTextBlock(editor, insertedElm); editor.selection.select(figure); } else { editor.selection.select(insertedElm); } }; var syncSrcAttr = function (editor, image) { editor.dom.setAttrib(image, 'src', image.getAttribute('src')); }; var deleteImage = function (editor, image) { if (image) { var elm = editor.dom.is(image.parentNode, 'figure.image') ? image.parentNode : image; editor.dom.remove(elm); editor.focus(); editor.nodeChanged(); if (editor.dom.isEmpty(editor.getBody())) { editor.setContent(''); editor.selection.setCursorLocation(); } } }; var writeImageDataToSelection = function (editor, data) { var image = getSelectedImage(editor); write(function (css) { return normalizeCss(editor, css); }, data, image); syncSrcAttr(editor, image); if (isFigure(image.parentNode)) { var figure = image.parentNode; splitTextBlock(editor, figure); editor.selection.select(image.parentNode); } else { editor.selection.select(image); Utils.waitLoadImage(editor, data, image); } }; var insertOrUpdateImage = function (editor, data) { var image = getSelectedImage(editor); if (image) { if (data.src) { writeImageDataToSelection(editor, data); } else { deleteImage(editor, image); } } else if (data.src) { insertImageAtCaret(editor, data); } }; var updateVSpaceHSpaceBorder = function (editor) { return function (evt) { var dom = editor.dom; var rootControl = evt.control.rootControl; if (!Settings.hasAdvTab(editor)) { return; } var data = rootControl.toJSON(); var css = dom.parseStyle(data.style); rootControl.find('#vspace').value(''); rootControl.find('#hspace').value(''); css = Utils.mergeMargins(css); if (css['margin-top'] && css['margin-bottom'] || css['margin-right'] && css['margin-left']) { if (css['margin-top'] === css['margin-bottom']) { rootControl.find('#vspace').value(Utils.removePixelSuffix(css['margin-top'])); } else { rootControl.find('#vspace').value(''); } if (css['margin-right'] === css['margin-left']) { rootControl.find('#hspace').value(Utils.removePixelSuffix(css['margin-right'])); } else { rootControl.find('#hspace').value(''); } } if (css['border-width']) { rootControl.find('#border').value(Utils.removePixelSuffix(css['border-width'])); } else { rootControl.find('#border').value(''); } if (css['border-style']) { rootControl.find('#borderStyle').value(css['border-style']); } else { rootControl.find('#borderStyle').value(''); } rootControl.find('#style').value(dom.serializeStyle(dom.parseStyle(dom.serializeStyle(css)))); }; }; var updateStyle = function (editor, win) { win.find('#style').each(function (ctrl) { var value = getStyleValue(function (css) { return normalizeCss(editor, css); }, merge(defaultData(), win.toJSON())); ctrl.value(value); }); }; var makeTab = function (editor) { return { title: 'Advanced', type: 'form', pack: 'start', items: [ { label: 'Style', name: 'style', type: 'textbox', onchange: updateVSpaceHSpaceBorder(editor) }, { type: 'form', layout: 'grid', packV: 'start', columns: 2, padding: 0, defaults: { type: 'textbox', maxWidth: 50, onchange: function (evt) { updateStyle(editor, evt.control.rootControl); } }, items: [ { label: 'Vertical space', name: 'vspace' }, { label: 'Border width', name: 'border' }, { label: 'Horizontal space', name: 'hspace' }, { label: 'Border style', type: 'listbox', name: 'borderStyle', width: 90, maxWidth: 90, onselect: function (evt) { updateStyle(editor, evt.control.rootControl); }, values: [ { text: 'Select...', value: '' }, { text: 'Solid', value: 'solid' }, { text: 'Dotted', value: 'dotted' }, { text: 'Dashed', value: 'dashed' }, { text: 'Double', value: 'double' }, { text: 'Groove', value: 'groove' }, { text: 'Ridge', value: 'ridge' }, { text: 'Inset', value: 'inset' }, { text: 'Outset', value: 'outset' }, { text: 'None', value: 'none' }, { text: 'Hidden', value: 'hidden' } ] } ] } ] }; }; var AdvTab = { makeTab: makeTab }; var doSyncSize = function (widthCtrl, heightCtrl) { widthCtrl.state.set('oldVal', widthCtrl.value()); heightCtrl.state.set('oldVal', heightCtrl.value()); }; var doSizeControls = function (win, f) { var widthCtrl = win.find('#width')[0]; var heightCtrl = win.find('#height')[0]; var constrained = win.find('#constrain')[0]; if (widthCtrl && heightCtrl && constrained) { f(widthCtrl, heightCtrl, constrained.checked()); } }; var doUpdateSize = function (widthCtrl, heightCtrl, isContrained) { var oldWidth = widthCtrl.state.get('oldVal'); var oldHeight = heightCtrl.state.get('oldVal'); var newWidth = widthCtrl.value(); var newHeight = heightCtrl.value(); if (isContrained && oldWidth && oldHeight && newWidth && newHeight) { if (newWidth !== oldWidth) { newHeight = Math.round(newWidth / oldWidth * newHeight); if (!isNaN(newHeight)) { heightCtrl.value(newHeight); } } else { newWidth = Math.round(newHeight / oldHeight * newWidth); if (!isNaN(newWidth)) { widthCtrl.value(newWidth); } } } doSyncSize(widthCtrl, heightCtrl); }; var syncSize = function (win) { doSizeControls(win, doSyncSize); }; var updateSize = function (win) { doSizeControls(win, doUpdateSize); }; var createUi = function () { var recalcSize = function (evt) { updateSize(evt.control.rootControl); }; return { type: 'container', label: 'Dimensions', layout: 'flex', align: 'center', spacing: 5, items: [ { name: 'width', type: 'textbox', maxLength: 5, size: 5, onchange: recalcSize, ariaLabel: 'Width' }, { type: 'label', text: 'x' }, { name: 'height', type: 'textbox', maxLength: 5, size: 5, onchange: recalcSize, ariaLabel: 'Height' }, { name: 'constrain', type: 'checkbox', checked: true, text: 'Constrain proportions' } ] }; }; var SizeManager = { createUi: createUi, syncSize: syncSize, updateSize: updateSize }; var onSrcChange = function (evt, editor) { var srcURL, prependURL, absoluteURLPattern; var meta = evt.meta || {}; var control = evt.control; var rootControl = control.rootControl; var imageListCtrl = rootControl.find('#image-list')[0]; if (imageListCtrl) { imageListCtrl.value(editor.convertURL(control.value(), 'src')); } global$2.each(meta, function (value, key) { rootControl.find('#' + key).value(value); }); if (!meta.width && !meta.height) { srcURL = editor.convertURL(control.value(), 'src'); prependURL = Settings.getPrependUrl(editor); absoluteURLPattern = new RegExp('^(?:[a-z]+:)?//', 'i'); if (prependURL && !absoluteURLPattern.test(srcURL) && srcURL.substring(0, prependURL.length) !== prependURL) { srcURL = prependURL + srcURL; } control.value(srcURL); Utils.getImageSize(editor.documentBaseURI.toAbsolute(control.value()), function (data) { if (data.width && data.height && Settings.hasDimensions(editor)) { rootControl.find('#width').value(data.width); rootControl.find('#height').value(data.height); SizeManager.syncSize(rootControl); } }); } }; var onBeforeCall = function (evt) { evt.meta = evt.control.rootControl.toJSON(); }; var getGeneralItems = function (editor, imageListCtrl) { var generalFormItems = [ { name: 'src', type: 'filepicker', filetype: 'image', label: 'Source', autofocus: true, onchange: function (evt) { onSrcChange(evt, editor); }, onbeforecall: onBeforeCall }, imageListCtrl ]; if (Settings.hasDescription(editor)) { generalFormItems.push({ name: 'alt', type: 'textbox', label: 'Image description' }); } if (Settings.hasImageTitle(editor)) { generalFormItems.push({ name: 'title', type: 'textbox', label: 'Image Title' }); } if (Settings.hasDimensions(editor)) { generalFormItems.push(SizeManager.createUi()); } if (Settings.getClassList(editor)) { generalFormItems.push({ name: 'class', type: 'listbox', label: 'Class', values: Utils.buildListItems(Settings.getClassList(editor), function (item) { if (item.value) { item.textStyle = function () { return editor.formatter.getCssText({ inline: 'img', classes: [item.value] }); }; } }) }); } if (Settings.hasImageCaption(editor)) { generalFormItems.push({ name: 'caption', type: 'checkbox', label: 'Caption' }); } return generalFormItems; }; var makeTab$1 = function (editor, imageListCtrl) { return { title: 'General', type: 'form', items: getGeneralItems(editor, imageListCtrl) }; }; var MainTab = { makeTab: makeTab$1, getGeneralItems: getGeneralItems }; var url = function () { return Global$1.getOrDie('URL'); }; var createObjectURL = function (blob) { return url().createObjectURL(blob); }; var revokeObjectURL = function (u) { url().revokeObjectURL(u); }; var URL = { createObjectURL: createObjectURL, revokeObjectURL: revokeObjectURL }; var global$5 = tinymce.util.Tools.resolve('tinymce.ui.Factory'); function XMLHttpRequest () { var f = Global$1.getOrDie('XMLHttpRequest'); return new f(); } var noop = function () { }; var pathJoin = function (path1, path2) { if (path1) { return path1.replace(/\/$/, '') + '/' + path2.replace(/^\//, ''); } return path2; }; function Uploader (settings) { var defaultHandler = function (blobInfo, success, failure, progress) { var xhr, formData; xhr = XMLHttpRequest(); xhr.open('POST', settings.url); xhr.withCredentials = settings.credentials; xhr.upload.onprogress = function (e) { progress(e.loaded / e.total * 100); }; xhr.onerror = function () { failure('Image upload failed due to a XHR Transport error. Code: ' + xhr.status); }; xhr.onload = function () { var json; if (xhr.status < 200 || xhr.status >= 300) { failure('HTTP Error: ' + xhr.status); return; } json = JSON.parse(xhr.responseText); if (!json || typeof json.location !== 'string') { failure('Invalid JSON: ' + xhr.responseText); return; } success(pathJoin(settings.basePath, json.location)); }; formData = new domGlobals.FormData(); formData.append('file', blobInfo.blob(), blobInfo.filename()); xhr.send(formData); }; var uploadBlob = function (blobInfo, handler) { return new global$1(function (resolve, reject) { try { handler(blobInfo, resolve, reject, noop); } catch (ex) { reject(ex.message); } }); }; var isDefaultHandler = function (handler) { return handler === defaultHandler; }; var upload = function (blobInfo) { return !settings.url && isDefaultHandler(settings.handler) ? global$1.reject('Upload url missing from the settings.') : uploadBlob(blobInfo, settings.handler); }; settings = global$2.extend({ credentials: false, handler: defaultHandler }, settings); return { upload: upload }; } var onFileInput = function (editor) { return function (evt) { var Throbber = global$5.get('Throbber'); var rootControl = evt.control.rootControl; var throbber = new Throbber(rootControl.getEl()); var file = evt.control.value(); var blobUri = URL.createObjectURL(file); var uploader = Uploader({ url: Settings.getUploadUrl(editor), basePath: Settings.getUploadBasePath(editor), credentials: Settings.getUploadCredentials(editor), handler: Settings.getUploadHandler(editor) }); var finalize = function () { throbber.hide(); URL.revokeObjectURL(blobUri); }; throbber.show(); return Utils.blobToDataUri(file).then(function (dataUrl) { var blobInfo = editor.editorUpload.blobCache.create({ blob: file, blobUri: blobUri, name: file.name ? file.name.replace(/\.[^\.]+$/, '') : null, base64: dataUrl.split(',')[1] }); return uploader.upload(blobInfo).then(function (url) { var src = rootControl.find('#src'); src.value(url); rootControl.find('tabpanel')[0].activateTab(0); src.fire('change'); finalize(); return url; }); }).catch(function (err) { editor.windowManager.alert(err); finalize(); }); }; }; var acceptExts = '.jpg,.jpeg,.png,.gif'; var makeTab$2 = function (editor) { return { title: 'Upload', type: 'form', layout: 'flex', direction: 'column', align: 'stretch', padding: '20 20 20 20', items: [ { type: 'container', layout: 'flex', direction: 'column', align: 'center', spacing: 10, items: [ { text: 'Browse for an image', type: 'browsebutton', accept: acceptExts, onchange: onFileInput(editor) }, { text: 'OR', type: 'label' } ] }, { text: 'Drop an image here', type: 'dropzone', accept: acceptExts, height: 100, onchange: onFileInput(editor) } ] }; }; var UploadTab = { makeTab: makeTab$2 }; function curry(fn) { var initialArgs = []; for (var _i = 1; _i < arguments.length; _i++) { initialArgs[_i - 1] = arguments[_i]; } return function () { var restArgs = []; for (var _i = 0; _i < arguments.length; _i++) { restArgs[_i] = arguments[_i]; } var all = initialArgs.concat(restArgs); return fn.apply(null, all); }; } var submitForm = function (editor, evt) { var win = evt.control.getRoot(); SizeManager.updateSize(win); editor.undoManager.transact(function () { var data = merge(readImageDataFromSelection(editor), win.toJSON()); insertOrUpdateImage(editor, data); }); editor.editorUpload.uploadImagesAuto(); }; function Dialog (editor) { function showDialog(imageList) { var data = readImageDataFromSelection(editor); var win, imageListCtrl; if (imageList) { imageListCtrl = { type: 'listbox', label: 'Image list', name: 'image-list', values: Utils.buildListItems(imageList, function (item) { item.value = editor.convertURL(item.value || item.url, 'src'); }, [{ text: 'None', value: '' }]), value: data.src && editor.convertURL(data.src, 'src'), onselect: function (e) { var altCtrl = win.find('#alt'); if (!altCtrl.value() || e.lastControl && altCtrl.value() === e.lastControl.text()) { altCtrl.value(e.control.text()); } win.find('#src').value(e.control.value()).fire('change'); }, onPostRender: function () { imageListCtrl = this; } }; } if (Settings.hasAdvTab(editor) || Settings.hasUploadUrl(editor) || Settings.hasUploadHandler(editor)) { var body = [MainTab.makeTab(editor, imageListCtrl)]; if (Settings.hasAdvTab(editor)) { body.push(AdvTab.makeTab(editor)); } if (Settings.hasUploadUrl(editor) || Settings.hasUploadHandler(editor)) { body.push(UploadTab.makeTab(editor)); } win = editor.windowManager.open({ title: 'Insert/edit image', data: data, bodyType: 'tabpanel', body: body, onSubmit: curry(submitForm, editor) }); } else { win = editor.windowManager.open({ title: 'Insert/edit image', data: data, body: MainTab.getGeneralItems(editor, imageListCtrl), onSubmit: curry(submitForm, editor) }); } SizeManager.syncSize(win); } function open() { Utils.createImageList(editor, showDialog); } return { open: open }; } var register = function (editor) { editor.addCommand('mceImage', Dialog(editor).open); }; var Commands = { register: register }; var hasImageClass = function (node) { var className = node.attr('class'); return className && /\bimage\b/.test(className); }; var toggleContentEditableState = function (state) { return function (nodes) { var i = nodes.length, node; var toggleContentEditable = function (node) { node.attr('contenteditable', state ? 'true' : null); }; while (i--) { node = nodes[i]; if (hasImageClass(node)) { node.attr('contenteditable', state ? 'false' : null); global$2.each(node.getAll('figcaption'), toggleContentEditable); } } }; }; var setup = function (editor) { editor.on('preInit', function () { editor.parser.addNodeFilter('figure', toggleContentEditableState(true)); editor.serializer.addNodeFilter('figure', toggleContentEditableState(false)); }); }; var FilterContent = { setup: setup }; var register$1 = function (editor) { editor.addButton('image', { icon: 'image', tooltip: 'Insert/edit image', onclick: Dialog(editor).open, stateSelector: 'img:not([data-mce-object],[data-mce-placeholder]),figure.image' }); editor.addMenuItem('image', { icon: 'image', text: 'Image', onclick: Dialog(editor).open, context: 'insert', prependToContext: true }); }; var Buttons = { register: register$1 }; global.add('image', function (editor) { FilterContent.setup(editor); Buttons.register(editor); Commands.register(editor); }); function Plugin () { } return Plugin; }(window)); })(); (function () { var imagetools = (function (domGlobals) { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); function create(width, height) { return resize(domGlobals.document.createElement('canvas'), width, height); } function clone(canvas) { var tCanvas, ctx; tCanvas = create(canvas.width, canvas.height); ctx = get2dContext(tCanvas); ctx.drawImage(canvas, 0, 0); return tCanvas; } function get2dContext(canvas) { return canvas.getContext('2d'); } function get3dContext(canvas) { var gl = null; try { gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); } catch (e) { } if (!gl) { gl = null; } return gl; } function resize(canvas, width, height) { canvas.width = width; canvas.height = height; return canvas; } var Canvas = { create: create, clone: clone, resize: resize, get2dContext: get2dContext, get3dContext: get3dContext }; function getWidth(image) { return image.naturalWidth || image.width; } function getHeight(image) { return image.naturalHeight || image.height; } var ImageSize = { getWidth: getWidth, getHeight: getHeight }; var promise = function () { var Promise = function (fn) { if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new'); if (typeof fn !== 'function') throw new TypeError('not a function'); this._state = null; this._value = null; this._deferreds = []; doResolve(fn, bind(resolve, this), bind(reject, this)); }; var asap = Promise.immediateFn || typeof window.setImmediate === 'function' && window.setImmediate || function (fn) { domGlobals.setTimeout(fn, 1); }; function bind(fn, thisArg) { return function () { fn.apply(thisArg, arguments); }; } var isArray = Array.isArray || function (value) { return Object.prototype.toString.call(value) === '[object Array]'; }; function handle(deferred) { var me = this; if (this._state === null) { this._deferreds.push(deferred); return; } asap(function () { var cb = me._state ? deferred.onFulfilled : deferred.onRejected; if (cb === null) { (me._state ? deferred.resolve : deferred.reject)(me._value); return; } var ret; try { ret = cb(me._value); } catch (e) { deferred.reject(e); return; } deferred.resolve(ret); }); } function resolve(newValue) { try { if (newValue === this) throw new TypeError('A promise cannot be resolved with itself.'); if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { var then = newValue.then; if (typeof then === 'function') { doResolve(bind(then, newValue), bind(resolve, this), bind(reject, this)); return; } } this._state = true; this._value = newValue; finale.call(this); } catch (e) { reject.call(this, e); } } function reject(newValue) { this._state = false; this._value = newValue; finale.call(this); } function finale() { for (var i = 0, len = this._deferreds.length; i < len; i++) { handle.call(this, this._deferreds[i]); } this._deferreds = null; } function Handler(onFulfilled, onRejected, resolve, reject) { this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; this.onRejected = typeof onRejected === 'function' ? onRejected : null; this.resolve = resolve; this.reject = reject; } function doResolve(fn, onFulfilled, onRejected) { var done = false; try { fn(function (value) { if (done) return; done = true; onFulfilled(value); }, function (reason) { if (done) return; done = true; onRejected(reason); }); } catch (ex) { if (done) return; done = true; onRejected(ex); } } Promise.prototype['catch'] = function (onRejected) { return this.then(null, onRejected); }; Promise.prototype.then = function (onFulfilled, onRejected) { var me = this; return new Promise(function (resolve, reject) { handle.call(me, new Handler(onFulfilled, onRejected, resolve, reject)); }); }; Promise.all = function () { var args = Array.prototype.slice.call(arguments.length === 1 && isArray(arguments[0]) ? arguments[0] : arguments); return new Promise(function (resolve, reject) { if (args.length === 0) return resolve([]); var remaining = args.length; function res(i, val) { try { if (val && (typeof val === 'object' || typeof val === 'function')) { var then = val.then; if (typeof then === 'function') { then.call(val, function (val) { res(i, val); }, reject); return; } } args[i] = val; if (--remaining === 0) { resolve(args); } } catch (ex) { reject(ex); } } for (var i = 0; i < args.length; i++) { res(i, args[i]); } }); }; Promise.resolve = function (value) { if (value && typeof value === 'object' && value.constructor === Promise) { return value; } return new Promise(function (resolve) { resolve(value); }); }; Promise.reject = function (value) { return new Promise(function (resolve, reject) { reject(value); }); }; Promise.race = function (values) { return new Promise(function (resolve, reject) { for (var i = 0, len = values.length; i < len; i++) { values[i].then(resolve, reject); } }); }; return Promise; }; var Promise = window.Promise ? window.Promise : promise(); var constant = function (value) { return function () { return value; }; }; function curry(fn) { var initialArgs = []; for (var _i = 1; _i < arguments.length; _i++) { initialArgs[_i - 1] = arguments[_i]; } return function () { var restArgs = []; for (var _i = 0; _i < arguments.length; _i++) { restArgs[_i] = arguments[_i]; } var all = initialArgs.concat(restArgs); return fn.apply(null, all); }; } var never = constant(false); var always = constant(true); var never$1 = never; var always$1 = always; var none = function () { return NONE; }; var NONE = function () { var eq = function (o) { return o.isNone(); }; var call = function (thunk) { return thunk(); }; var id = function (n) { return n; }; var noop = function () { }; var nul = function () { return null; }; var undef = function () { return undefined; }; var me = { fold: function (n, s) { return n(); }, is: never$1, isSome: never$1, isNone: always$1, getOr: id, getOrThunk: call, getOrDie: function (msg) { throw new Error(msg || 'error: getOrDie called on none.'); }, getOrNull: nul, getOrUndefined: undef, or: id, orThunk: call, map: none, ap: none, each: noop, bind: none, flatten: none, exists: never$1, forall: always$1, filter: none, equals: eq, equals_: eq, toArray: function () { return []; }, toString: constant('none()') }; if (Object.freeze) Object.freeze(me); return me; }(); var some = function (a) { var constant_a = function () { return a; }; var self = function () { return me; }; var map = function (f) { return some(f(a)); }; var bind = function (f) { return f(a); }; var me = { fold: function (n, s) { return s(a); }, is: function (v) { return a === v; }, isSome: always$1, isNone: never$1, getOr: constant_a, getOrThunk: constant_a, getOrDie: constant_a, getOrNull: constant_a, getOrUndefined: constant_a, or: self, orThunk: self, map: map, ap: function (optfab) { return optfab.fold(none, function (fab) { return some(fab(a)); }); }, each: function (f) { f(a); }, bind: bind, flatten: constant_a, exists: bind, forall: bind, filter: function (f) { return f(a) ? me : NONE; }, equals: function (o) { return o.is(a); }, equals_: function (o, elementEq) { return o.fold(never$1, function (b) { return elementEq(a, b); }); }, toArray: function () { return [a]; }, toString: function () { return 'some(' + a + ')'; } }; return me; }; var from = function (value) { return value === null || value === undefined ? NONE : some(value); }; var Option = { some: some, none: none, from: from }; var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')(); var path = function (parts, scope) { var o = scope !== undefined && scope !== null ? scope : Global; for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i) o = o[parts[i]]; return o; }; var resolve = function (p, scope) { var parts = p.split('.'); return path(parts, scope); }; var unsafe = function (name, scope) { return resolve(name, scope); }; var getOrDie = function (name, scope) { var actual = unsafe(name, scope); if (actual === undefined || actual === null) throw name + ' not available on this browser'; return actual; }; var Global$1 = { getOrDie: getOrDie }; function Blob (parts, properties) { var f = Global$1.getOrDie('Blob'); return new f(parts, properties); } function FileReader () { var f = Global$1.getOrDie('FileReader'); return new f(); } function Uint8Array (arr) { var f = Global$1.getOrDie('Uint8Array'); return new f(arr); } var requestAnimationFrame = function (callback) { var f = Global$1.getOrDie('requestAnimationFrame'); f(callback); }; var atob = function (base64) { var f = Global$1.getOrDie('atob'); return f(base64); }; var Window = { atob: atob, requestAnimationFrame: requestAnimationFrame }; function imageToBlob(image) { var src = image.src; if (src.indexOf('data:') === 0) { return dataUriToBlob(src); } return anyUriToBlob(src); } function blobToImage(blob) { return new Promise(function (resolve, reject) { var blobUrl = domGlobals.URL.createObjectURL(blob); var image = new domGlobals.Image(); var removeListeners = function () { image.removeEventListener('load', loaded); image.removeEventListener('error', error); }; function loaded() { removeListeners(); resolve(image); } function error() { removeListeners(); reject('Unable to load data of type ' + blob.type + ': ' + blobUrl); } image.addEventListener('load', loaded); image.addEventListener('error', error); image.src = blobUrl; if (image.complete) { loaded(); } }); } function anyUriToBlob(url) { return new Promise(function (resolve, reject) { var xhr = new domGlobals.XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'blob'; xhr.onload = function () { if (this.status == 200) { resolve(this.response); } }; xhr.onerror = function () { var _this = this; var corsError = function () { var obj = new Error('No access to download image'); obj.code = 18; obj.name = 'SecurityError'; return obj; }; var genericError = function () { return new Error('Error ' + _this.status + ' downloading image'); }; reject(this.status === 0 ? corsError() : genericError()); }; xhr.send(); }); } function dataUriToBlobSync(uri) { var data = uri.split(','); var matches = /data:([^;]+)/.exec(data[0]); if (!matches) return Option.none(); var mimetype = matches[1]; var base64 = data[1]; var sliceSize = 1024; var byteCharacters = Window.atob(base64); var bytesLength = byteCharacters.length; var slicesCount = Math.ceil(bytesLength / sliceSize); var byteArrays = new Array(slicesCount); for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) { var begin = sliceIndex * sliceSize; var end = Math.min(begin + sliceSize, bytesLength); var bytes = new Array(end - begin); for (var offset = begin, i = 0; offset < end; ++i, ++offset) { bytes[i] = byteCharacters[offset].charCodeAt(0); } byteArrays[sliceIndex] = Uint8Array(bytes); } return Option.some(Blob(byteArrays, { type: mimetype })); } function dataUriToBlob(uri) { return new Promise(function (resolve, reject) { dataUriToBlobSync(uri).fold(function () { reject('uri is not base64: ' + uri); }, resolve); }); } function uriToBlob(url) { if (url.indexOf('blob:') === 0) { return anyUriToBlob(url); } if (url.indexOf('data:') === 0) { return dataUriToBlob(url); } return null; } function canvasToBlob(canvas, type, quality) { type = type || 'image/png'; if (domGlobals.HTMLCanvasElement.prototype.toBlob) { return new Promise(function (resolve) { canvas.toBlob(function (blob) { resolve(blob); }, type, quality); }); } else { return dataUriToBlob(canvas.toDataURL(type, quality)); } } function canvasToDataURL(getCanvas, type, quality) { type = type || 'image/png'; return getCanvas.then(function (canvas) { return canvas.toDataURL(type, quality); }); } function blobToCanvas(blob) { return blobToImage(blob).then(function (image) { revokeImageUrl(image); var context, canvas; canvas = Canvas.create(ImageSize.getWidth(image), ImageSize.getHeight(image)); context = Canvas.get2dContext(canvas); context.drawImage(image, 0, 0); return canvas; }); } function blobToDataUri(blob) { return new Promise(function (resolve) { var reader = FileReader(); reader.onloadend = function () { resolve(reader.result); }; reader.readAsDataURL(blob); }); } function blobToArrayBuffer(blob) { return new Promise(function (resolve) { var reader = FileReader(); reader.onloadend = function () { resolve(reader.result); }; reader.readAsArrayBuffer(blob); }); } function blobToBase64(blob) { return blobToDataUri(blob).then(function (dataUri) { return dataUri.split(',')[1]; }); } function revokeImageUrl(image) { domGlobals.URL.revokeObjectURL(image.src); } var Conversions = { blobToImage: blobToImage, imageToBlob: imageToBlob, blobToArrayBuffer: blobToArrayBuffer, blobToDataUri: blobToDataUri, blobToBase64: blobToBase64, dataUriToBlobSync: dataUriToBlobSync, canvasToBlob: canvasToBlob, canvasToDataURL: canvasToDataURL, blobToCanvas: blobToCanvas, uriToBlob: uriToBlob }; var blobToImage$1 = function (image) { return Conversions.blobToImage(image); }; var imageToBlob$1 = function (blob) { return Conversions.imageToBlob(blob); }; var blobToDataUri$1 = function (blob) { return Conversions.blobToDataUri(blob); }; var blobToBase64$1 = function (blob) { return Conversions.blobToBase64(blob); }; var dataUriToBlobSync$1 = function (uri) { return Conversions.dataUriToBlobSync(uri); }; var uriToBlob$1 = function (uri) { return Option.from(Conversions.uriToBlob(uri)); }; var BlobConversions = { blobToImage: blobToImage$1, imageToBlob: imageToBlob$1, blobToDataUri: blobToDataUri$1, blobToBase64: blobToBase64$1, dataUriToBlobSync: dataUriToBlobSync$1, uriToBlob: uriToBlob$1 }; function create$1(getCanvas, blob, uri) { var initialType = blob.type; var getType = constant(initialType); function toBlob() { return Promise.resolve(blob); } function toDataURL() { return uri; } function toBase64() { return uri.split(',')[1]; } function toAdjustedBlob(type, quality) { return getCanvas.then(function (canvas) { return Conversions.canvasToBlob(canvas, type, quality); }); } function toAdjustedDataURL(type, quality) { return getCanvas.then(function (canvas) { return Conversions.canvasToDataURL(canvas, type, quality); }); } function toAdjustedBase64(type, quality) { return toAdjustedDataURL(type, quality).then(function (dataurl) { return dataurl.split(',')[1]; }); } function toCanvas() { return getCanvas.then(Canvas.clone); } return { getType: getType, toBlob: toBlob, toDataURL: toDataURL, toBase64: toBase64, toAdjustedBlob: toAdjustedBlob, toAdjustedDataURL: toAdjustedDataURL, toAdjustedBase64: toAdjustedBase64, toCanvas: toCanvas }; } function fromBlob(blob) { return Conversions.blobToDataUri(blob).then(function (uri) { return create$1(Conversions.blobToCanvas(blob), blob, uri); }); } function fromCanvas(canvas, type) { return Conversions.canvasToBlob(canvas, type).then(function (blob) { return create$1(Promise.resolve(canvas), blob, canvas.toDataURL()); }); } function fromImage(image) { return Conversions.imageToBlob(image).then(function (blob) { return fromBlob(blob); }); } var fromBlobAndUrlSync = function (blob, url) { return create$1(Conversions.blobToCanvas(blob), blob, url); }; var ImageResult = { fromBlob: fromBlob, fromCanvas: fromCanvas, fromImage: fromImage, fromBlobAndUrlSync: fromBlobAndUrlSync }; function clamp(value, min, max) { value = parseFloat(value); if (value > max) { value = max; } else if (value < min) { value = min; } return value; } function identity() { return [ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 ]; } var DELTA_INDEX = [ 0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.11, 0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.2, 0.21, 0.22, 0.24, 0.25, 0.27, 0.28, 0.3, 0.32, 0.34, 0.36, 0.38, 0.4, 0.42, 0.44, 0.46, 0.48, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, 0.71, 0.74, 0.77, 0.8, 0.83, 0.86, 0.89, 0.92, 0.95, 0.98, 1, 1.06, 1.12, 1.18, 1.24, 1.3, 1.36, 1.42, 1.48, 1.54, 1.6, 1.66, 1.72, 1.78, 1.84, 1.9, 1.96, 2, 2.12, 2.25, 2.37, 2.5, 2.62, 2.75, 2.87, 3, 3.2, 3.4, 3.6, 3.8, 4, 4.3, 4.7, 4.9, 5, 5.5, 6, 6.5, 6.8, 7, 7.3, 7.5, 7.8, 8, 8.4, 8.7, 9, 9.4, 9.6, 9.8, 10 ]; function multiply(matrix1, matrix2) { var i, j, k, val, col = [], out = new Array(10); for (i = 0; i < 5; i++) { for (j = 0; j < 5; j++) { col[j] = matrix2[j + i * 5]; } for (j = 0; j < 5; j++) { val = 0; for (k = 0; k < 5; k++) { val += matrix1[j + k * 5] * col[k]; } out[j + i * 5] = val; } } return out; } function adjust(matrix, adjustValue) { adjustValue = clamp(adjustValue, 0, 1); return matrix.map(function (value, index) { if (index % 6 === 0) { value = 1 - (1 - value) * adjustValue; } else { value *= adjustValue; } return clamp(value, 0, 1); }); } function adjustContrast(matrix, value) { var x; value = clamp(value, -1, 1); value *= 100; if (value < 0) { x = 127 + value / 100 * 127; } else { x = value % 1; if (x === 0) { x = DELTA_INDEX[value]; } else { x = DELTA_INDEX[Math.floor(value)] * (1 - x) + DELTA_INDEX[Math.floor(value) + 1] * x; } x = x * 127 + 127; } return multiply(matrix, [ x / 127, 0, 0, 0, 0.5 * (127 - x), 0, x / 127, 0, 0, 0.5 * (127 - x), 0, 0, x / 127, 0, 0.5 * (127 - x), 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 ]); } function adjustSaturation(matrix, value) { var x, lumR, lumG, lumB; value = clamp(value, -1, 1); x = 1 + (value > 0 ? 3 * value : value); lumR = 0.3086; lumG = 0.6094; lumB = 0.082; return multiply(matrix, [ lumR * (1 - x) + x, lumG * (1 - x), lumB * (1 - x), 0, 0, lumR * (1 - x), lumG * (1 - x) + x, lumB * (1 - x), 0, 0, lumR * (1 - x), lumG * (1 - x), lumB * (1 - x) + x, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 ]); } function adjustHue(matrix, angle) { var cosVal, sinVal, lumR, lumG, lumB; angle = clamp(angle, -180, 180) / 180 * Math.PI; cosVal = Math.cos(angle); sinVal = Math.sin(angle); lumR = 0.213; lumG = 0.715; lumB = 0.072; return multiply(matrix, [ lumR + cosVal * (1 - lumR) + sinVal * -lumR, lumG + cosVal * -lumG + sinVal * -lumG, lumB + cosVal * -lumB + sinVal * (1 - lumB), 0, 0, lumR + cosVal * -lumR + sinVal * 0.143, lumG + cosVal * (1 - lumG) + sinVal * 0.14, lumB + cosVal * -lumB + sinVal * -0.283, 0, 0, lumR + cosVal * -lumR + sinVal * -(1 - lumR), lumG + cosVal * -lumG + sinVal * lumG, lumB + cosVal * (1 - lumB) + sinVal * lumB, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 ]); } function adjustBrightness(matrix, value) { value = clamp(255 * value, -255, 255); return multiply(matrix, [ 1, 0, 0, 0, value, 0, 1, 0, 0, value, 0, 0, 1, 0, value, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 ]); } function adjustColors(matrix, adjustR, adjustG, adjustB) { adjustR = clamp(adjustR, 0, 2); adjustG = clamp(adjustG, 0, 2); adjustB = clamp(adjustB, 0, 2); return multiply(matrix, [ adjustR, 0, 0, 0, 0, 0, adjustG, 0, 0, 0, 0, 0, adjustB, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 ]); } function adjustSepia(matrix, value) { value = clamp(value, 0, 1); return multiply(matrix, adjust([ 0.393, 0.769, 0.189, 0, 0, 0.349, 0.686, 0.168, 0, 0, 0.272, 0.534, 0.131, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 ], value)); } function adjustGrayscale(matrix, value) { value = clamp(value, 0, 1); return multiply(matrix, adjust([ 0.33, 0.34, 0.33, 0, 0, 0.33, 0.34, 0.33, 0, 0, 0.33, 0.34, 0.33, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 ], value)); } var ColorMatrix = { identity: identity, adjust: adjust, multiply: multiply, adjustContrast: adjustContrast, adjustBrightness: adjustBrightness, adjustSaturation: adjustSaturation, adjustHue: adjustHue, adjustColors: adjustColors, adjustSepia: adjustSepia, adjustGrayscale: adjustGrayscale }; function colorFilter(ir, matrix) { return ir.toCanvas().then(function (canvas) { return applyColorFilter(canvas, ir.getType(), matrix); }); } function applyColorFilter(canvas, type, matrix) { var context = Canvas.get2dContext(canvas); var pixels; function applyMatrix(pixels, m) { var d = pixels.data, r, g, b, a, i, m0 = m[0], m1 = m[1], m2 = m[2], m3 = m[3], m4 = m[4], m5 = m[5], m6 = m[6], m7 = m[7], m8 = m[8], m9 = m[9], m10 = m[10], m11 = m[11], m12 = m[12], m13 = m[13], m14 = m[14], m15 = m[15], m16 = m[16], m17 = m[17], m18 = m[18], m19 = m[19]; for (i = 0; i < d.length; i += 4) { r = d[i]; g = d[i + 1]; b = d[i + 2]; a = d[i + 3]; d[i] = r * m0 + g * m1 + b * m2 + a * m3 + m4; d[i + 1] = r * m5 + g * m6 + b * m7 + a * m8 + m9; d[i + 2] = r * m10 + g * m11 + b * m12 + a * m13 + m14; d[i + 3] = r * m15 + g * m16 + b * m17 + a * m18 + m19; } return pixels; } pixels = applyMatrix(context.getImageData(0, 0, canvas.width, canvas.height), matrix); context.putImageData(pixels, 0, 0); return ImageResult.fromCanvas(canvas, type); } function convoluteFilter(ir, matrix) { return ir.toCanvas().then(function (canvas) { return applyConvoluteFilter(canvas, ir.getType(), matrix); }); } function applyConvoluteFilter(canvas, type, matrix) { var context = Canvas.get2dContext(canvas); var pixelsIn, pixelsOut; function applyMatrix(pixelsIn, pixelsOut, matrix) { var rgba, drgba, side, halfSide, x, y, r, g, b, cx, cy, scx, scy, offset, wt, w, h; function clamp(value, min, max) { if (value > max) { value = max; } else if (value < min) { value = min; } return value; } side = Math.round(Math.sqrt(matrix.length)); halfSide = Math.floor(side / 2); rgba = pixelsIn.data; drgba = pixelsOut.data; w = pixelsIn.width; h = pixelsIn.height; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { r = g = b = 0; for (cy = 0; cy < side; cy++) { for (cx = 0; cx < side; cx++) { scx = clamp(x + cx - halfSide, 0, w - 1); scy = clamp(y + cy - halfSide, 0, h - 1); offset = (scy * w + scx) * 4; wt = matrix[cy * side + cx]; r += rgba[offset] * wt; g += rgba[offset + 1] * wt; b += rgba[offset + 2] * wt; } } offset = (y * w + x) * 4; drgba[offset] = clamp(r, 0, 255); drgba[offset + 1] = clamp(g, 0, 255); drgba[offset + 2] = clamp(b, 0, 255); } } return pixelsOut; } pixelsIn = context.getImageData(0, 0, canvas.width, canvas.height); pixelsOut = context.getImageData(0, 0, canvas.width, canvas.height); pixelsOut = applyMatrix(pixelsIn, pixelsOut, matrix); context.putImageData(pixelsOut, 0, 0); return ImageResult.fromCanvas(canvas, type); } function functionColorFilter(colorFn) { var filterImpl = function (canvas, type, value) { var context = Canvas.get2dContext(canvas); var pixels, i, lookup = new Array(256); function applyLookup(pixels, lookup) { var d = pixels.data, i; for (i = 0; i < d.length; i += 4) { d[i] = lookup[d[i]]; d[i + 1] = lookup[d[i + 1]]; d[i + 2] = lookup[d[i + 2]]; } return pixels; } for (i = 0; i < lookup.length; i++) { lookup[i] = colorFn(i, value); } pixels = applyLookup(context.getImageData(0, 0, canvas.width, canvas.height), lookup); context.putImageData(pixels, 0, 0); return ImageResult.fromCanvas(canvas, type); }; return function (ir, value) { return ir.toCanvas().then(function (canvas) { return filterImpl(canvas, ir.getType(), value); }); }; } function complexAdjustableColorFilter(matrixAdjustFn) { return function (ir, adjust) { return colorFilter(ir, matrixAdjustFn(ColorMatrix.identity(), adjust)); }; } function basicColorFilter(matrix) { return function (ir) { return colorFilter(ir, matrix); }; } function basicConvolutionFilter(kernel) { return function (ir) { return convoluteFilter(ir, kernel); }; } var Filters = { invert: basicColorFilter([ -1, 0, 0, 0, 255, 0, -1, 0, 0, 255, 0, 0, -1, 0, 255, 0, 0, 0, 1, 0 ]), brightness: complexAdjustableColorFilter(ColorMatrix.adjustBrightness), hue: complexAdjustableColorFilter(ColorMatrix.adjustHue), saturate: complexAdjustableColorFilter(ColorMatrix.adjustSaturation), contrast: complexAdjustableColorFilter(ColorMatrix.adjustContrast), grayscale: complexAdjustableColorFilter(ColorMatrix.adjustGrayscale), sepia: complexAdjustableColorFilter(ColorMatrix.adjustSepia), colorize: function (ir, adjustR, adjustG, adjustB) { return colorFilter(ir, ColorMatrix.adjustColors(ColorMatrix.identity(), adjustR, adjustG, adjustB)); }, sharpen: basicConvolutionFilter([ 0, -1, 0, -1, 5, -1, 0, -1, 0 ]), emboss: basicConvolutionFilter([ -2, -1, 0, -1, 1, 1, 0, 1, 2 ]), gamma: functionColorFilter(function (color, value) { return Math.pow(color / 255, 1 - value) * 255; }), exposure: functionColorFilter(function (color, value) { return 255 * (1 - Math.exp(-(color / 255) * value)); }), colorFilter: colorFilter, convoluteFilter: convoluteFilter }; function scale(image, dW, dH) { var sW = ImageSize.getWidth(image); var sH = ImageSize.getHeight(image); var wRatio = dW / sW; var hRatio = dH / sH; var scaleCapped = false; if (wRatio < 0.5 || wRatio > 2) { wRatio = wRatio < 0.5 ? 0.5 : 2; scaleCapped = true; } if (hRatio < 0.5 || hRatio > 2) { hRatio = hRatio < 0.5 ? 0.5 : 2; scaleCapped = true; } var scaled = _scale(image, wRatio, hRatio); return !scaleCapped ? scaled : scaled.then(function (tCanvas) { return scale(tCanvas, dW, dH); }); } function _scale(image, wRatio, hRatio) { return new Promise(function (resolve) { var sW = ImageSize.getWidth(image); var sH = ImageSize.getHeight(image); var dW = Math.floor(sW * wRatio); var dH = Math.floor(sH * hRatio); var canvas = Canvas.create(dW, dH); var context = Canvas.get2dContext(canvas); context.drawImage(image, 0, 0, sW, sH, 0, 0, dW, dH); resolve(canvas); }); } var ImageResizerCanvas = { scale: scale }; function rotate(ir, angle) { return ir.toCanvas().then(function (canvas) { return applyRotate(canvas, ir.getType(), angle); }); } function applyRotate(image, type, angle) { var canvas = Canvas.create(image.width, image.height); var context = Canvas.get2dContext(canvas); var translateX = 0, translateY = 0; angle = angle < 0 ? 360 + angle : angle; if (angle == 90 || angle == 270) { Canvas.resize(canvas, canvas.height, canvas.width); } if (angle == 90 || angle == 180) { translateX = canvas.width; } if (angle == 270 || angle == 180) { translateY = canvas.height; } context.translate(translateX, translateY); context.rotate(angle * Math.PI / 180); context.drawImage(image, 0, 0); return ImageResult.fromCanvas(canvas, type); } function flip(ir, axis) { return ir.toCanvas().then(function (canvas) { return applyFlip(canvas, ir.getType(), axis); }); } function applyFlip(image, type, axis) { var canvas = Canvas.create(image.width, image.height); var context = Canvas.get2dContext(canvas); if (axis == 'v') { context.scale(1, -1); context.drawImage(image, 0, -canvas.height); } else { context.scale(-1, 1); context.drawImage(image, -canvas.width, 0); } return ImageResult.fromCanvas(canvas, type); } function crop(ir, x, y, w, h) { return ir.toCanvas().then(function (canvas) { return applyCrop(canvas, ir.getType(), x, y, w, h); }); } function applyCrop(image, type, x, y, w, h) { var canvas = Canvas.create(w, h); var context = Canvas.get2dContext(canvas); context.drawImage(image, -x, -y); return ImageResult.fromCanvas(canvas, type); } function resize$1(ir, w, h) { return ir.toCanvas().then(function (canvas) { return ImageResizerCanvas.scale(canvas, w, h).then(function (newCanvas) { return ImageResult.fromCanvas(newCanvas, ir.getType()); }); }); } var ImageTools = { rotate: rotate, flip: flip, crop: crop, resize: resize$1 }; var BinaryReader = function () { function BinaryReader(ar) { this.littleEndian = false; this._dv = new DataView(ar); } BinaryReader.prototype.readByteAt = function (idx) { return this._dv.getUint8(idx); }; BinaryReader.prototype.read = function (idx, size) { if (idx + size > this.length()) { return null; } var mv = this.littleEndian ? 0 : -8 * (size - 1); for (var i = 0, sum = 0; i < size; i++) { sum |= this.readByteAt(idx + i) << Math.abs(mv + i * 8); } return sum; }; BinaryReader.prototype.BYTE = function (idx) { return this.read(idx, 1); }; BinaryReader.prototype.SHORT = function (idx) { return this.read(idx, 2); }; BinaryReader.prototype.LONG = function (idx) { return this.read(idx, 4); }; BinaryReader.prototype.SLONG = function (idx) { var num = this.read(idx, 4); return num > 2147483647 ? num - 4294967296 : num; }; BinaryReader.prototype.CHAR = function (idx) { return String.fromCharCode(this.read(idx, 1)); }; BinaryReader.prototype.STRING = function (idx, count) { return this.asArray('CHAR', idx, count).join(''); }; BinaryReader.prototype.SEGMENT = function (idx, size) { var ar = this._dv.buffer; switch (arguments.length) { case 2: return ar.slice(idx, idx + size); case 1: return ar.slice(idx); default: return ar; } }; BinaryReader.prototype.asArray = function (type, idx, count) { var values = []; for (var i = 0; i < count; i++) { values[i] = this[type](idx + i); } return values; }; BinaryReader.prototype.length = function () { return this._dv ? this._dv.byteLength : 0; }; return BinaryReader; }(); var tags = { tiff: { 274: 'Orientation', 270: 'ImageDescription', 271: 'Make', 272: 'Model', 305: 'Software', 34665: 'ExifIFDPointer', 34853: 'GPSInfoIFDPointer' }, exif: { 36864: 'ExifVersion', 40961: 'ColorSpace', 40962: 'PixelXDimension', 40963: 'PixelYDimension', 36867: 'DateTimeOriginal', 33434: 'ExposureTime', 33437: 'FNumber', 34855: 'ISOSpeedRatings', 37377: 'ShutterSpeedValue', 37378: 'ApertureValue', 37383: 'MeteringMode', 37384: 'LightSource', 37385: 'Flash', 37386: 'FocalLength', 41986: 'ExposureMode', 41987: 'WhiteBalance', 41990: 'SceneCaptureType', 41988: 'DigitalZoomRatio', 41992: 'Contrast', 41993: 'Saturation', 41994: 'Sharpness' }, gps: { 0: 'GPSVersionID', 1: 'GPSLatitudeRef', 2: 'GPSLatitude', 3: 'GPSLongitudeRef', 4: 'GPSLongitude' }, thumb: { 513: 'JPEGInterchangeFormat', 514: 'JPEGInterchangeFormatLength' } }; var tagDescs = { 'ColorSpace': { 1: 'sRGB', 0: 'Uncalibrated' }, 'MeteringMode': { 0: 'Unknown', 1: 'Average', 2: 'CenterWeightedAverage', 3: 'Spot', 4: 'MultiSpot', 5: 'Pattern', 6: 'Partial', 255: 'Other' }, 'LightSource': { 1: 'Daylight', 2: 'Fliorescent', 3: 'Tungsten', 4: 'Flash', 9: 'Fine weather', 10: 'Cloudy weather', 11: 'Shade', 12: 'Daylight fluorescent (D 5700 - 7100K)', 13: 'Day white fluorescent (N 4600 -5400K)', 14: 'Cool white fluorescent (W 3900 - 4500K)', 15: 'White fluorescent (WW 3200 - 3700K)', 17: 'Standard light A', 18: 'Standard light B', 19: 'Standard light C', 20: 'D55', 21: 'D65', 22: 'D75', 23: 'D50', 24: 'ISO studio tungsten', 255: 'Other' }, 'Flash': { 0: 'Flash did not fire', 1: 'Flash fired', 5: 'Strobe return light not detected', 7: 'Strobe return light detected', 9: 'Flash fired, compulsory flash mode', 13: 'Flash fired, compulsory flash mode, return light not detected', 15: 'Flash fired, compulsory flash mode, return light detected', 16: 'Flash did not fire, compulsory flash mode', 24: 'Flash did not fire, auto mode', 25: 'Flash fired, auto mode', 29: 'Flash fired, auto mode, return light not detected', 31: 'Flash fired, auto mode, return light detected', 32: 'No flash function', 65: 'Flash fired, red-eye reduction mode', 69: 'Flash fired, red-eye reduction mode, return light not detected', 71: 'Flash fired, red-eye reduction mode, return light detected', 73: 'Flash fired, compulsory flash mode, red-eye reduction mode', 77: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected', 79: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light detected', 89: 'Flash fired, auto mode, red-eye reduction mode', 93: 'Flash fired, auto mode, return light not detected, red-eye reduction mode', 95: 'Flash fired, auto mode, return light detected, red-eye reduction mode' }, 'ExposureMode': { 0: 'Auto exposure', 1: 'Manual exposure', 2: 'Auto bracket' }, 'WhiteBalance': { 0: 'Auto white balance', 1: 'Manual white balance' }, 'SceneCaptureType': { 0: 'Standard', 1: 'Landscape', 2: 'Portrait', 3: 'Night scene' }, 'Contrast': { 0: 'Normal', 1: 'Soft', 2: 'Hard' }, 'Saturation': { 0: 'Normal', 1: 'Low saturation', 2: 'High saturation' }, 'Sharpness': { 0: 'Normal', 1: 'Soft', 2: 'Hard' }, 'GPSLatitudeRef': { N: 'North latitude', S: 'South latitude' }, 'GPSLongitudeRef': { E: 'East longitude', W: 'West longitude' } }; var ExifReader = function () { function ExifReader(ar) { this._offsets = { tiffHeader: 10, IFD0: null, IFD1: null, exifIFD: null, gpsIFD: null }; this._tiffTags = {}; var self = this; self._reader = new BinaryReader(ar); self._idx = self._offsets.tiffHeader; if (self.SHORT(0) !== 65505 || self.STRING(4, 5).toUpperCase() !== 'EXIF\0') { throw new Error('Exif data cannot be read or not available.'); } self._reader.littleEndian = self.SHORT(self._idx) == 18761; if (self.SHORT(self._idx += 2) !== 42) { throw new Error('Invalid Exif data.'); } self._offsets.IFD0 = self._offsets.tiffHeader + self.LONG(self._idx += 2); self._tiffTags = self.extractTags(self._offsets.IFD0, tags.tiff); if ('ExifIFDPointer' in self._tiffTags) { self._offsets.exifIFD = self._offsets.tiffHeader + self._tiffTags.ExifIFDPointer; delete self._tiffTags.ExifIFDPointer; } if ('GPSInfoIFDPointer' in self._tiffTags) { self._offsets.gpsIFD = self._offsets.tiffHeader + self._tiffTags.GPSInfoIFDPointer; delete self._tiffTags.GPSInfoIFDPointer; } var IFD1Offset = self.LONG(self._offsets.IFD0 + self.SHORT(self._offsets.IFD0) * 12 + 2); if (IFD1Offset) { self._offsets.IFD1 = self._offsets.tiffHeader + IFD1Offset; } } ExifReader.prototype.BYTE = function (idx) { return this._reader.BYTE(idx); }; ExifReader.prototype.SHORT = function (idx) { return this._reader.SHORT(idx); }; ExifReader.prototype.LONG = function (idx) { return this._reader.LONG(idx); }; ExifReader.prototype.SLONG = function (idx) { return this._reader.SLONG(idx); }; ExifReader.prototype.CHAR = function (idx) { return this._reader.CHAR(idx); }; ExifReader.prototype.STRING = function (idx, count) { return this._reader.STRING(idx, count); }; ExifReader.prototype.SEGMENT = function (idx, size) { return this._reader.SEGMENT(idx, size); }; ExifReader.prototype.asArray = function (type, idx, count) { var values = []; for (var i = 0; i < count; i++) { values[i] = this[type](idx + i); } return values; }; ExifReader.prototype.length = function () { return this._reader.length(); }; ExifReader.prototype.UNDEFINED = function () { return this.BYTE.apply(this, arguments); }; ExifReader.prototype.RATIONAL = function (idx) { return this.LONG(idx) / this.LONG(idx + 4); }; ExifReader.prototype.SRATIONAL = function (idx) { return this.SLONG(idx) / this.SLONG(idx + 4); }; ExifReader.prototype.ASCII = function (idx) { return this.CHAR(idx); }; ExifReader.prototype.TIFF = function () { return this._tiffTags; }; ExifReader.prototype.EXIF = function () { var self = this; var Exif = null; if (self._offsets.exifIFD) { try { Exif = self.extractTags(self._offsets.exifIFD, tags.exif); } catch (ex) { return null; } if (Exif.ExifVersion && Array.isArray(Exif.ExifVersion)) { for (var i = 0, exifVersion = ''; i < Exif.ExifVersion.length; i++) { exifVersion += String.fromCharCode(Exif.ExifVersion[i]); } Exif.ExifVersion = exifVersion; } } return Exif; }; ExifReader.prototype.GPS = function () { var self = this; var GPS = null; if (self._offsets.gpsIFD) { try { GPS = self.extractTags(self._offsets.gpsIFD, tags.gps); } catch (ex) { return null; } if (GPS.GPSVersionID && Array.isArray(GPS.GPSVersionID)) { GPS.GPSVersionID = GPS.GPSVersionID.join('.'); } } return GPS; }; ExifReader.prototype.thumb = function () { var self = this; if (self._offsets.IFD1) { try { var IFD1Tags = self.extractTags(self._offsets.IFD1, tags.thumb); if ('JPEGInterchangeFormat' in IFD1Tags) { return self.SEGMENT(self._offsets.tiffHeader + IFD1Tags.JPEGInterchangeFormat, IFD1Tags.JPEGInterchangeFormatLength); } } catch (ex) { } } return null; }; ExifReader.prototype.extractTags = function (IFD_offset, tags2extract) { var self = this; var length, i, tag, type, count, size, offset, value, values = [], hash = {}; var types = { 1: 'BYTE', 7: 'UNDEFINED', 2: 'ASCII', 3: 'SHORT', 4: 'LONG', 5: 'RATIONAL', 9: 'SLONG', 10: 'SRATIONAL' }; var sizes = { 'BYTE': 1, 'UNDEFINED': 1, 'ASCII': 1, 'SHORT': 2, 'LONG': 4, 'RATIONAL': 8, 'SLONG': 4, 'SRATIONAL': 8 }; length = self.SHORT(IFD_offset); for (i = 0; i < length; i++) { values = []; offset = IFD_offset + 2 + i * 12; tag = tags2extract[self.SHORT(offset)]; if (tag === undefined) { continue; } type = types[self.SHORT(offset += 2)]; count = self.LONG(offset += 2); size = sizes[type]; if (!size) { throw new Error('Invalid Exif data.'); } offset += 4; if (size * count > 4) { offset = self.LONG(offset) + self._offsets.tiffHeader; } if (offset + size * count >= self.length()) { throw new Error('Invalid Exif data.'); } if (type === 'ASCII') { hash[tag] = self.STRING(offset, count).replace(/\0$/, '').trim(); continue; } else { values = self.asArray(type, offset, count); value = count == 1 ? values[0] : values; if (tagDescs.hasOwnProperty(tag) && typeof value != 'object') { hash[tag] = tagDescs[tag][value]; } else { hash[tag] = value; } } } return hash; }; return ExifReader; }(); var extractFrom = function (blob) { return Conversions.blobToArrayBuffer(blob).then(function (ar) { try { var br = new BinaryReader(ar); if (br.SHORT(0) === 65496) { var headers = extractHeaders(br); var app1 = headers.filter(function (header) { return header.name === 'APP1'; }); var meta = {}; if (app1.length) { var exifReader = new ExifReader(app1[0].segment); meta = { tiff: exifReader.TIFF(), exif: exifReader.EXIF(), gps: exifReader.GPS(), thumb: exifReader.thumb() }; } else { return Promise.reject('Headers did not include required information'); } meta.rawHeaders = headers; return meta; } return Promise.reject('Image was not a jpeg'); } catch (ex) { return Promise.reject('Unsupported format or not an image: ' + blob.type + ' (Exception: ' + ex.message + ')'); } }); }; var extractHeaders = function (br) { var headers = [], idx, marker, length = 0; idx = 2; while (idx <= br.length()) { marker = br.SHORT(idx); if (marker >= 65488 && marker <= 65495) { idx += 2; continue; } if (marker === 65498 || marker === 65497) { break; } length = br.SHORT(idx + 2) + 2; if (marker >= 65505 && marker <= 65519) { headers.push({ hex: marker, name: 'APP' + (marker & 15), start: idx, length: length, segment: br.SEGMENT(idx, length) }); } idx += length; } return headers; }; var JPEGMeta = { extractFrom: extractFrom }; var invert = function (ir) { return Filters.invert(ir); }; var sharpen = function (ir) { return Filters.sharpen(ir); }; var emboss = function (ir) { return Filters.emboss(ir); }; var gamma = function (ir, value) { return Filters.gamma(ir, value); }; var exposure = function (ir, value) { return Filters.exposure(ir, value); }; var colorize = function (ir, adjustR, adjustG, adjustB) { return Filters.colorize(ir, adjustR, adjustG, adjustB); }; var brightness = function (ir, adjust) { return Filters.brightness(ir, adjust); }; var hue = function (ir, adjust) { return Filters.hue(ir, adjust); }; var saturate = function (ir, adjust) { return Filters.saturate(ir, adjust); }; var contrast = function (ir, adjust) { return Filters.contrast(ir, adjust); }; var grayscale = function (ir, adjust) { return Filters.grayscale(ir, adjust); }; var sepia = function (ir, adjust) { return Filters.sepia(ir, adjust); }; var flip$1 = function (ir, axis) { return ImageTools.flip(ir, axis); }; var crop$1 = function (ir, x, y, w, h) { return ImageTools.crop(ir, x, y, w, h); }; var resize$2 = function (ir, w, h) { return ImageTools.resize(ir, w, h); }; var rotate$1 = function (ir, angle) { return ImageTools.rotate(ir, angle); }; var exifRotate = function (ir) { var ROTATE_90 = 6; var ROTATE_180 = 3; var ROTATE_270 = 8; var checkRotation = function (data) { var orientation = data.tiff.Orientation; switch (orientation) { case ROTATE_90: return rotate$1(ir, 90); case ROTATE_180: return rotate$1(ir, 180); case ROTATE_270: return rotate$1(ir, 270); default: return ir; } }; var notJpeg = function () { return ir; }; return ir.toBlob().then(JPEGMeta.extractFrom).then(checkRotation, notJpeg); }; var ImageTransformations = { invert: invert, sharpen: sharpen, emboss: emboss, brightness: brightness, hue: hue, saturate: saturate, contrast: contrast, grayscale: grayscale, sepia: sepia, colorize: colorize, gamma: gamma, exposure: exposure, flip: flip$1, crop: crop$1, resize: resize$2, rotate: rotate$1, exifRotate: exifRotate }; var blobToImageResult = function (blob) { return ImageResult.fromBlob(blob); }; var fromBlobAndUrlSync$1 = function (blob, uri) { return ImageResult.fromBlobAndUrlSync(blob, uri); }; var imageToImageResult = function (image) { return ImageResult.fromImage(image); }; var imageResultToBlob = function (ir, type, quality) { if (type === undefined && quality === undefined) { return imageResultToOriginalBlob(ir); } else { return ir.toAdjustedBlob(type, quality); } }; var imageResultToOriginalBlob = function (ir) { return ir.toBlob(); }; var imageResultToDataURL = function (ir) { return ir.toDataURL(); }; var ResultConversions = { blobToImageResult: blobToImageResult, fromBlobAndUrlSync: fromBlobAndUrlSync$1, imageToImageResult: imageToImageResult, imageResultToBlob: imageResultToBlob, imageResultToOriginalBlob: imageResultToOriginalBlob, imageResultToDataURL: imageResultToDataURL }; var url = function () { return Global$1.getOrDie('URL'); }; var createObjectURL = function (blob) { return url().createObjectURL(blob); }; var revokeObjectURL = function (u) { url().revokeObjectURL(u); }; var URL = { createObjectURL: createObjectURL, revokeObjectURL: revokeObjectURL }; var global$2 = tinymce.util.Tools.resolve('tinymce.util.Delay'); var global$3 = tinymce.util.Tools.resolve('tinymce.util.Promise'); var global$4 = tinymce.util.Tools.resolve('tinymce.util.URI'); var getToolbarItems = function (editor) { return editor.getParam('imagetools_toolbar', 'rotateleft rotateright | flipv fliph | crop editimage imageoptions'); }; var getProxyUrl = function (editor) { return editor.getParam('imagetools_proxy'); }; var getCorsHosts = function (editor) { return editor.getParam('imagetools_cors_hosts', [], 'string[]'); }; var getCredentialsHosts = function (editor) { return editor.getParam('imagetools_credentials_hosts', [], 'string[]'); }; var getApiKey = function (editor) { return editor.getParam('api_key', editor.getParam('imagetools_api_key', '', 'string'), 'string'); }; var getUploadTimeout = function (editor) { return editor.getParam('images_upload_timeout', 30000, 'number'); }; var shouldReuseFilename = function (editor) { return editor.getParam('images_reuse_filename', false, 'boolean'); }; var global$5 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var global$6 = tinymce.util.Tools.resolve('tinymce.ui.Factory'); function UndoStack () { var data = []; var index = -1; function add(state) { var removed; removed = data.splice(++index); data.push(state); return { state: state, removed: removed }; } function undo() { if (canUndo()) { return data[--index]; } } function redo() { if (canRedo()) { return data[++index]; } } function canUndo() { return index > 0; } function canRedo() { return index !== -1 && index < data.length - 1; } return { data: data, add: add, undo: undo, redo: redo, canUndo: canUndo, canRedo: canRedo }; } var global$7 = tinymce.util.Tools.resolve('tinymce.geom.Rect'); var loadImage = function (image) { return new global$3(function (resolve) { var loaded = function () { image.removeEventListener('load', loaded); resolve(image); }; if (image.complete) { resolve(image); } else { image.addEventListener('load', loaded); } }); }; var LoadImage = { loadImage: loadImage }; var global$8 = tinymce.util.Tools.resolve('tinymce.dom.DomQuery'); var global$9 = tinymce.util.Tools.resolve('tinymce.util.Observable'); var global$a = tinymce.util.Tools.resolve('tinymce.util.VK'); var count = 0; function CropRect (currentRect, viewPortRect, clampRect, containerElm, action) { var instance; var handles; var dragHelpers; var blockers; var prefix = 'mce-'; var id = prefix + 'crid-' + count++; handles = [ { name: 'move', xMul: 0, yMul: 0, deltaX: 1, deltaY: 1, deltaW: 0, deltaH: 0, label: 'Crop Mask' }, { name: 'nw', xMul: 0, yMul: 0, deltaX: 1, deltaY: 1, deltaW: -1, deltaH: -1, label: 'Top Left Crop Handle' }, { name: 'ne', xMul: 1, yMul: 0, deltaX: 0, deltaY: 1, deltaW: 1, deltaH: -1, label: 'Top Right Crop Handle' }, { name: 'sw', xMul: 0, yMul: 1, deltaX: 1, deltaY: 0, deltaW: -1, deltaH: 1, label: 'Bottom Left Crop Handle' }, { name: 'se', xMul: 1, yMul: 1, deltaX: 0, deltaY: 0, deltaW: 1, deltaH: 1, label: 'Bottom Right Crop Handle' } ]; blockers = [ 'top', 'right', 'bottom', 'left' ]; function getAbsoluteRect(outerRect, relativeRect) { return { x: relativeRect.x + outerRect.x, y: relativeRect.y + outerRect.y, w: relativeRect.w, h: relativeRect.h }; } function getRelativeRect(outerRect, innerRect) { return { x: innerRect.x - outerRect.x, y: innerRect.y - outerRect.y, w: innerRect.w, h: innerRect.h }; } function getInnerRect() { return getRelativeRect(clampRect, currentRect); } function moveRect(handle, startRect, deltaX, deltaY) { var x, y, w, h, rect; x = startRect.x; y = startRect.y; w = startRect.w; h = startRect.h; x += deltaX * handle.deltaX; y += deltaY * handle.deltaY; w += deltaX * handle.deltaW; h += deltaY * handle.deltaH; if (w < 20) { w = 20; } if (h < 20) { h = 20; } rect = currentRect = global$7.clamp({ x: x, y: y, w: w, h: h }, clampRect, handle.name === 'move'); rect = getRelativeRect(clampRect, rect); instance.fire('updateRect', { rect: rect }); setInnerRect(rect); } function render() { function createDragHelper(handle) { var startRect; var DragHelper = global$6.get('DragHelper'); return new DragHelper(id, { document: containerElm.ownerDocument, handle: id + '-' + handle.name, start: function () { startRect = currentRect; }, drag: function (e) { moveRect(handle, startRect, e.deltaX, e.deltaY); } }); } global$8('<div id="' + id + '" class="' + prefix + 'croprect-container"' + ' role="grid" aria-dropeffect="execute">').appendTo(containerElm); global$1.each(blockers, function (blocker) { global$8('#' + id, containerElm).append('<div id="' + id + '-' + blocker + '"class="' + prefix + 'croprect-block" style="display: none" data-mce-bogus="all">'); }); global$1.each(handles, function (handle) { global$8('#' + id, containerElm).append('<div id="' + id + '-' + handle.name + '" class="' + prefix + 'croprect-handle ' + prefix + 'croprect-handle-' + handle.name + '"' + 'style="display: none" data-mce-bogus="all" role="gridcell" tabindex="-1"' + ' aria-label="' + handle.label + '" aria-grabbed="false">'); }); dragHelpers = global$1.map(handles, createDragHelper); repaint(currentRect); global$8(containerElm).on('focusin focusout', function (e) { global$8(e.target).attr('aria-grabbed', e.type === 'focus'); }); global$8(containerElm).on('keydown', function (e) { var activeHandle; global$1.each(handles, function (handle) { if (e.target.id === id + '-' + handle.name) { activeHandle = handle; return false; } }); function moveAndBlock(evt, handle, startRect, deltaX, deltaY) { evt.stopPropagation(); evt.preventDefault(); moveRect(activeHandle, startRect, deltaX, deltaY); } switch (e.keyCode) { case global$a.LEFT: moveAndBlock(e, activeHandle, currentRect, -10, 0); break; case global$a.RIGHT: moveAndBlock(e, activeHandle, currentRect, 10, 0); break; case global$a.UP: moveAndBlock(e, activeHandle, currentRect, 0, -10); break; case global$a.DOWN: moveAndBlock(e, activeHandle, currentRect, 0, 10); break; case global$a.ENTER: case global$a.SPACEBAR: e.preventDefault(); action(); break; } }); } function toggleVisibility(state) { var selectors; selectors = global$1.map(handles, function (handle) { return '#' + id + '-' + handle.name; }).concat(global$1.map(blockers, function (blocker) { return '#' + id + '-' + blocker; })).join(','); if (state) { global$8(selectors, containerElm).show(); } else { global$8(selectors, containerElm).hide(); } } function repaint(rect) { function updateElementRect(name, rect) { if (rect.h < 0) { rect.h = 0; } if (rect.w < 0) { rect.w = 0; } global$8('#' + id + '-' + name, containerElm).css({ left: rect.x, top: rect.y, width: rect.w, height: rect.h }); } global$1.each(handles, function (handle) { global$8('#' + id + '-' + handle.name, containerElm).css({ left: rect.w * handle.xMul + rect.x, top: rect.h * handle.yMul + rect.y }); }); updateElementRect('top', { x: viewPortRect.x, y: viewPortRect.y, w: viewPortRect.w, h: rect.y - viewPortRect.y }); updateElementRect('right', { x: rect.x + rect.w, y: rect.y, w: viewPortRect.w - rect.x - rect.w + viewPortRect.x, h: rect.h }); updateElementRect('bottom', { x: viewPortRect.x, y: rect.y + rect.h, w: viewPortRect.w, h: viewPortRect.h - rect.y - rect.h + viewPortRect.y }); updateElementRect('left', { x: viewPortRect.x, y: rect.y, w: rect.x - viewPortRect.x, h: rect.h }); updateElementRect('move', rect); } function setRect(rect) { currentRect = rect; repaint(currentRect); } function setViewPortRect(rect) { viewPortRect = rect; repaint(currentRect); } function setInnerRect(rect) { setRect(getAbsoluteRect(clampRect, rect)); } function setClampRect(rect) { clampRect = rect; repaint(currentRect); } function destroy() { global$1.each(dragHelpers, function (helper) { helper.destroy(); }); dragHelpers = []; } render(); instance = global$1.extend({ toggleVisibility: toggleVisibility, setClampRect: setClampRect, setRect: setRect, getInnerRect: getInnerRect, setInnerRect: setInnerRect, setViewPortRect: setViewPortRect, destroy: destroy }, global$9); return instance; } var create$2 = function (settings) { var Control = global$6.get('Control'); var ImagePanel = Control.extend({ Defaults: { classes: 'imagepanel' }, selection: function (rect) { if (arguments.length) { this.state.set('rect', rect); return this; } return this.state.get('rect'); }, imageSize: function () { var viewRect = this.state.get('viewRect'); return { w: viewRect.w, h: viewRect.h }; }, toggleCropRect: function (state) { this.state.set('cropEnabled', state); }, imageSrc: function (url) { var self = this, img = new domGlobals.Image(); img.src = url; LoadImage.loadImage(img).then(function () { var rect, $img; var lastRect = self.state.get('viewRect'); $img = self.$el.find('img'); if ($img[0]) { $img.replaceWith(img); } else { var bg = domGlobals.document.createElement('div'); bg.className = 'mce-imagepanel-bg'; self.getEl().appendChild(bg); self.getEl().appendChild(img); } rect = { x: 0, y: 0, w: img.naturalWidth, h: img.naturalHeight }; self.state.set('viewRect', rect); self.state.set('rect', global$7.inflate(rect, -20, -20)); if (!lastRect || lastRect.w !== rect.w || lastRect.h !== rect.h) { self.zoomFit(); } self.repaintImage(); self.fire('load'); }); }, zoom: function (value) { if (arguments.length) { this.state.set('zoom', value); return this; } return this.state.get('zoom'); }, postRender: function () { this.imageSrc(this.settings.imageSrc); return this._super(); }, zoomFit: function () { var self = this; var $img, pw, ph, w, h, zoom, padding; padding = 10; $img = self.$el.find('img'); pw = self.getEl().clientWidth; ph = self.getEl().clientHeight; w = $img[0].naturalWidth; h = $img[0].naturalHeight; zoom = Math.min((pw - padding) / w, (ph - padding) / h); if (zoom >= 1) { zoom = 1; } self.zoom(zoom); }, repaintImage: function () { var x, y, w, h, pw, ph, $img, $bg, zoom, rect, elm; elm = this.getEl(); zoom = this.zoom(); rect = this.state.get('rect'); $img = this.$el.find('img'); $bg = this.$el.find('.mce-imagepanel-bg'); pw = elm.offsetWidth; ph = elm.offsetHeight; w = $img[0].naturalWidth * zoom; h = $img[0].naturalHeight * zoom; x = Math.max(0, pw / 2 - w / 2); y = Math.max(0, ph / 2 - h / 2); $img.css({ left: x, top: y, width: w, height: h }); $bg.css({ left: x, top: y, width: w, height: h }); if (this.cropRect) { this.cropRect.setRect({ x: rect.x * zoom + x, y: rect.y * zoom + y, w: rect.w * zoom, h: rect.h * zoom }); this.cropRect.setClampRect({ x: x, y: y, w: w, h: h }); this.cropRect.setViewPortRect({ x: 0, y: 0, w: pw, h: ph }); } }, bindStates: function () { var self = this; function setupCropRect(rect) { self.cropRect = CropRect(rect, self.state.get('viewRect'), self.state.get('viewRect'), self.getEl(), function () { self.fire('crop'); }); self.cropRect.on('updateRect', function (e) { var rect = e.rect; var zoom = self.zoom(); rect = { x: Math.round(rect.x / zoom), y: Math.round(rect.y / zoom), w: Math.round(rect.w / zoom), h: Math.round(rect.h / zoom) }; self.state.set('rect', rect); }); self.on('remove', self.cropRect.destroy); } self.state.on('change:cropEnabled', function (e) { self.cropRect.toggleVisibility(e.value); self.repaintImage(); }); self.state.on('change:zoom', function () { self.repaintImage(); }); self.state.on('change:rect', function (e) { var rect = e.value; if (!self.cropRect) { setupCropRect(rect); } self.cropRect.setRect(rect); }); } }); return new ImagePanel(settings); }; var ImagePanel = { create: create$2 }; function createState(blob) { return { blob: blob, url: URL.createObjectURL(blob) }; } function destroyState(state) { if (state) { URL.revokeObjectURL(state.url); } } function destroyStates(states) { global$1.each(states, destroyState); } function open(editor, currentState, resolve, reject) { var win, undoStack = UndoStack(), mainPanel, filtersPanel, tempState, cropPanel, resizePanel, flipRotatePanel, imagePanel, sidePanel, mainViewContainer, invertPanel, brightnessPanel, huePanel, saturatePanel, contrastPanel, grayscalePanel, sepiaPanel, colorizePanel, sharpenPanel, embossPanel, gammaPanel, exposurePanel, panels, width, height, ratioW, ratioH; var reverseIfRtl = function (items) { return editor.rtl ? items.reverse() : items; }; function recalcSize(e) { var widthCtrl, heightCtrl, newWidth, newHeight; widthCtrl = win.find('#w')[0]; heightCtrl = win.find('#h')[0]; newWidth = parseInt(widthCtrl.value(), 10); newHeight = parseInt(heightCtrl.value(), 10); if (win.find('#constrain')[0].checked() && width && height && newWidth && newHeight) { if (e.control.settings.name === 'w') { newHeight = Math.round(newWidth * ratioW); heightCtrl.value(newHeight); } else { newWidth = Math.round(newHeight * ratioH); widthCtrl.value(newWidth); } } width = newWidth; height = newHeight; } function floatToPercent(value) { return Math.round(value * 100) + '%'; } function updateButtonUndoStates() { win.find('#undo').disabled(!undoStack.canUndo()); win.find('#redo').disabled(!undoStack.canRedo()); win.statusbar.find('#save').disabled(!undoStack.canUndo()); } function disableUndoRedo() { win.find('#undo').disabled(true); win.find('#redo').disabled(true); } function displayState(state) { if (state) { imagePanel.imageSrc(state.url); } } function switchPanel(targetPanel) { return function () { var hidePanels = global$1.grep(panels, function (panel) { return panel.settings.name !== targetPanel; }); global$1.each(hidePanels, function (panel) { panel.hide(); }); targetPanel.show(); targetPanel.focus(); }; } function addTempState(blob) { tempState = createState(blob); displayState(tempState); } function addBlobState(blob) { currentState = createState(blob); displayState(currentState); destroyStates(undoStack.add(currentState).removed); updateButtonUndoStates(); } function crop() { var rect = imagePanel.selection(); ResultConversions.blobToImageResult(currentState.blob).then(function (ir) { ImageTransformations.crop(ir, rect.x, rect.y, rect.w, rect.h).then(imageResultToBlob).then(function (blob) { addBlobState(blob); cancel(); }); }); } var tempAction = function (fn) { var args = [].slice.call(arguments, 1); return function () { var state = tempState || currentState; ResultConversions.blobToImageResult(state.blob).then(function (ir) { fn.apply(this, [ir].concat(args)).then(imageResultToBlob).then(addTempState); }); }; }; function action(fn) { var arg = []; for (var _i = 1; _i < arguments.length; _i++) { arg[_i - 1] = arguments[_i]; } var args = [].slice.call(arguments, 1); return function () { ResultConversions.blobToImageResult(currentState.blob).then(function (ir) { fn.apply(this, [ir].concat(args)).then(imageResultToBlob).then(addBlobState); }); }; } function cancel() { displayState(currentState); destroyState(tempState); switchPanel(mainPanel)(); updateButtonUndoStates(); } function waitForTempState(times, applyCall) { if (tempState) { applyCall(); } else { setTimeout(function () { if (times-- > 0) { waitForTempState(times, applyCall); } else { editor.windowManager.alert('Error: failed to apply image operation.'); } }, 10); } } function applyTempState() { if (tempState) { addBlobState(tempState.blob); cancel(); } else { waitForTempState(100, applyTempState); } } function zoomIn() { var zoom = imagePanel.zoom(); if (zoom < 2) { zoom += 0.1; } imagePanel.zoom(zoom); } function zoomOut() { var zoom = imagePanel.zoom(); if (zoom > 0.1) { zoom -= 0.1; } imagePanel.zoom(zoom); } function undo() { currentState = undoStack.undo(); displayState(currentState); updateButtonUndoStates(); } function redo() { currentState = undoStack.redo(); displayState(currentState); updateButtonUndoStates(); } function save() { resolve(currentState.blob); win.close(); } function createPanel(items) { return global$6.create('Form', { layout: 'flex', direction: 'row', labelGap: 5, border: '0 0 1 0', align: 'center', pack: 'center', padding: '0 10 0 10', spacing: 5, flex: 0, minHeight: 60, defaults: { classes: 'imagetool', type: 'button' }, items: items }); } var imageResultToBlob = function (ir) { return ir.toBlob(); }; function createFilterPanel(title, filter) { return createPanel(reverseIfRtl([ { text: 'Back', onclick: cancel }, { type: 'spacer', flex: 1 }, { text: 'Apply', subtype: 'primary', onclick: applyTempState } ])).hide().on('show', function () { disableUndoRedo(); ResultConversions.blobToImageResult(currentState.blob).then(function (ir) { return filter(ir); }).then(imageResultToBlob).then(function (blob) { var newTempState = createState(blob); displayState(newTempState); destroyState(tempState); tempState = newTempState; }); }); } function createVariableFilterPanel(title, filter, value, min, max) { function update(value) { ResultConversions.blobToImageResult(currentState.blob).then(function (ir) { return filter(ir, value); }).then(imageResultToBlob).then(function (blob) { var newTempState = createState(blob); displayState(newTempState); destroyState(tempState); tempState = newTempState; }); } return createPanel(reverseIfRtl([ { text: 'Back', onclick: cancel }, { type: 'spacer', flex: 1 }, { type: 'slider', flex: 1, ondragend: function (e) { update(e.value); }, minValue: editor.rtl ? max : min, maxValue: editor.rtl ? min : max, value: value, previewFilter: floatToPercent }, { type: 'spacer', flex: 1 }, { text: 'Apply', subtype: 'primary', onclick: applyTempState } ])).hide().on('show', function () { this.find('slider').value(value); disableUndoRedo(); }); } function createRgbFilterPanel(title, filter) { function update() { var r, g, b; r = win.find('#r')[0].value(); g = win.find('#g')[0].value(); b = win.find('#b')[0].value(); ResultConversions.blobToImageResult(currentState.blob).then(function (ir) { return filter(ir, r, g, b); }).then(imageResultToBlob).then(function (blob) { var newTempState = createState(blob); displayState(newTempState); destroyState(tempState); tempState = newTempState; }); } var min = editor.rtl ? 2 : 0; var max = editor.rtl ? 0 : 2; return createPanel(reverseIfRtl([ { text: 'Back', onclick: cancel }, { type: 'spacer', flex: 1 }, { type: 'slider', label: 'R', name: 'r', minValue: min, value: 1, maxValue: max, ondragend: update, previewFilter: floatToPercent }, { type: 'slider', label: 'G', name: 'g', minValue: min, value: 1, maxValue: max, ondragend: update, previewFilter: floatToPercent }, { type: 'slider', label: 'B', name: 'b', minValue: min, value: 1, maxValue: max, ondragend: update, previewFilter: floatToPercent }, { type: 'spacer', flex: 1 }, { text: 'Apply', subtype: 'primary', onclick: applyTempState } ])).hide().on('show', function () { win.find('#r,#g,#b').value(1); disableUndoRedo(); }); } cropPanel = createPanel(reverseIfRtl([ { text: 'Back', onclick: cancel }, { type: 'spacer', flex: 1 }, { text: 'Apply', subtype: 'primary', onclick: crop } ])).hide().on('show hide', function (e) { imagePanel.toggleCropRect(e.type === 'show'); }).on('show', disableUndoRedo); function toggleConstrain(e) { if (e.control.value() === true) { ratioW = height / width; ratioH = width / height; } } resizePanel = createPanel(reverseIfRtl([ { text: 'Back', onclick: cancel }, { type: 'spacer', flex: 1 }, { type: 'textbox', name: 'w', label: 'Width', size: 4, onkeyup: recalcSize }, { type: 'textbox', name: 'h', label: 'Height', size: 4, onkeyup: recalcSize }, { type: 'checkbox', name: 'constrain', text: 'Constrain proportions', checked: true, onchange: toggleConstrain }, { type: 'spacer', flex: 1 }, { text: 'Apply', subtype: 'primary', onclick: 'submit' } ])).hide().on('submit', function (e) { var width = parseInt(win.find('#w').value(), 10), height = parseInt(win.find('#h').value(), 10); e.preventDefault(); action(ImageTransformations.resize, width, height)(); cancel(); }).on('show', disableUndoRedo); flipRotatePanel = createPanel(reverseIfRtl([ { text: 'Back', onclick: cancel }, { type: 'spacer', flex: 1 }, { icon: 'fliph', tooltip: 'Flip horizontally', onclick: tempAction(ImageTransformations.flip, 'h') }, { icon: 'flipv', tooltip: 'Flip vertically', onclick: tempAction(ImageTransformations.flip, 'v') }, { icon: 'rotateleft', tooltip: 'Rotate counterclockwise', onclick: tempAction(ImageTransformations.rotate, -90) }, { icon: 'rotateright', tooltip: 'Rotate clockwise', onclick: tempAction(ImageTransformations.rotate, 90) }, { type: 'spacer', flex: 1 }, { text: 'Apply', subtype: 'primary', onclick: applyTempState } ])).hide().on('show', disableUndoRedo); invertPanel = createFilterPanel('Invert', ImageTransformations.invert); sharpenPanel = createFilterPanel('Sharpen', ImageTransformations.sharpen); embossPanel = createFilterPanel('Emboss', ImageTransformations.emboss); brightnessPanel = createVariableFilterPanel('Brightness', ImageTransformations.brightness, 0, -1, 1); huePanel = createVariableFilterPanel('Hue', ImageTransformations.hue, 180, 0, 360); saturatePanel = createVariableFilterPanel('Saturate', ImageTransformations.saturate, 0, -1, 1); contrastPanel = createVariableFilterPanel('Contrast', ImageTransformations.contrast, 0, -1, 1); grayscalePanel = createVariableFilterPanel('Grayscale', ImageTransformations.grayscale, 0, 0, 1); sepiaPanel = createVariableFilterPanel('Sepia', ImageTransformations.sepia, 0, 0, 1); colorizePanel = createRgbFilterPanel('Colorize', ImageTransformations.colorize); gammaPanel = createVariableFilterPanel('Gamma', ImageTransformations.gamma, 0, -1, 1); exposurePanel = createVariableFilterPanel('Exposure', ImageTransformations.exposure, 1, 0, 2); filtersPanel = createPanel(reverseIfRtl([ { text: 'Back', onclick: cancel }, { type: 'spacer', flex: 1 }, { text: 'hue', icon: 'hue', onclick: switchPanel(huePanel) }, { text: 'saturate', icon: 'saturate', onclick: switchPanel(saturatePanel) }, { text: 'sepia', icon: 'sepia', onclick: switchPanel(sepiaPanel) }, { text: 'emboss', icon: 'emboss', onclick: switchPanel(embossPanel) }, { text: 'exposure', icon: 'exposure', onclick: switchPanel(exposurePanel) }, { type: 'spacer', flex: 1 } ])).hide(); mainPanel = createPanel(reverseIfRtl([ { tooltip: 'Crop', icon: 'crop', onclick: switchPanel(cropPanel) }, { tooltip: 'Resize', icon: 'resize2', onclick: switchPanel(resizePanel) }, { tooltip: 'Orientation', icon: 'orientation', onclick: switchPanel(flipRotatePanel) }, { tooltip: 'Brightness', icon: 'sun', onclick: switchPanel(brightnessPanel) }, { tooltip: 'Sharpen', icon: 'sharpen', onclick: switchPanel(sharpenPanel) }, { tooltip: 'Contrast', icon: 'contrast', onclick: switchPanel(contrastPanel) }, { tooltip: 'Color levels', icon: 'drop', onclick: switchPanel(colorizePanel) }, { tooltip: 'Gamma', icon: 'gamma', onclick: switchPanel(gammaPanel) }, { tooltip: 'Invert', icon: 'invert', onclick: switchPanel(invertPanel) } ])); imagePanel = ImagePanel.create({ flex: 1, imageSrc: currentState.url }); sidePanel = global$6.create('Container', { layout: 'flex', direction: 'column', pack: 'start', border: '0 1 0 0', padding: 5, spacing: 5, items: [ { type: 'button', icon: 'undo', tooltip: 'Undo', name: 'undo', onclick: undo }, { type: 'button', icon: 'redo', tooltip: 'Redo', name: 'redo', onclick: redo }, { type: 'button', icon: 'zoomin', tooltip: 'Zoom in', onclick: zoomIn }, { type: 'button', icon: 'zoomout', tooltip: 'Zoom out', onclick: zoomOut } ] }); mainViewContainer = global$6.create('Container', { type: 'container', layout: 'flex', direction: 'row', align: 'stretch', flex: 1, items: reverseIfRtl([ sidePanel, imagePanel ]) }); panels = [ mainPanel, cropPanel, resizePanel, flipRotatePanel, filtersPanel, invertPanel, brightnessPanel, huePanel, saturatePanel, contrastPanel, grayscalePanel, sepiaPanel, colorizePanel, sharpenPanel, embossPanel, gammaPanel, exposurePanel ]; win = editor.windowManager.open({ layout: 'flex', direction: 'column', align: 'stretch', minWidth: Math.min(global$5.DOM.getViewPort().w, 800), minHeight: Math.min(global$5.DOM.getViewPort().h, 650), title: 'Edit image', items: panels.concat([mainViewContainer]), buttons: reverseIfRtl([ { text: 'Save', name: 'save', subtype: 'primary', onclick: save }, { text: 'Cancel', onclick: 'close' } ]) }); win.on('close', function () { reject(); destroyStates(undoStack.data); undoStack = null; tempState = null; }); undoStack.add(currentState); updateButtonUndoStates(); imagePanel.on('load', function () { width = imagePanel.imageSize().w; height = imagePanel.imageSize().h; ratioW = height / width; ratioH = width / height; win.find('#w').value(width); win.find('#h').value(height); }); imagePanel.on('crop', crop); } function edit(editor, imageResult) { return new global$3(function (resolve, reject) { return imageResult.toBlob().then(function (blob) { open(editor, createState(blob), resolve, reject); }); }); } var Dialog = { edit: edit }; function getImageSize(img) { var width, height; function isPxValue(value) { return /^[0-9\.]+px$/.test(value); } width = img.style.width; height = img.style.height; if (width || height) { if (isPxValue(width) && isPxValue(height)) { return { w: parseInt(width, 10), h: parseInt(height, 10) }; } return null; } width = img.width; height = img.height; if (width && height) { return { w: parseInt(width, 10), h: parseInt(height, 10) }; } return null; } function setImageSize(img, size) { var width, height; if (size) { width = img.style.width; height = img.style.height; if (width || height) { img.style.width = size.w + 'px'; img.style.height = size.h + 'px'; img.removeAttribute('data-mce-style'); } width = img.width; height = img.height; if (width || height) { img.setAttribute('width', size.w); img.setAttribute('height', size.h); } } } function getNaturalImageSize(img) { return { w: img.naturalWidth, h: img.naturalHeight }; } var ImageSize$1 = { getImageSize: getImageSize, setImageSize: setImageSize, getNaturalImageSize: getNaturalImageSize }; var typeOf = function (x) { if (x === null) return 'null'; var t = typeof x; if (t === 'object' && Array.prototype.isPrototypeOf(x)) return 'array'; if (t === 'object' && String.prototype.isPrototypeOf(x)) return 'string'; return t; }; var isType = function (type) { return function (value) { return typeOf(value) === type; }; }; var isFunction = isType('function'); var find = function (xs, pred) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { return Option.some(x); } } return Option.none(); }; var slice = Array.prototype.slice; var from$1 = isFunction(Array.from) ? Array.from : function (x) { return slice.call(x); }; function XMLHttpRequest () { var f = Global$1.getOrDie('XMLHttpRequest'); return new f(); } var isValue = function (obj) { return obj !== null && obj !== undefined; }; var traverse = function (json, path) { var value; value = path.reduce(function (result, key) { return isValue(result) ? result[key] : undefined; }, json); return isValue(value) ? value : null; }; var requestUrlAsBlob = function (url, headers, withCredentials) { return new global$3(function (resolve) { var xhr; xhr = XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { resolve({ status: xhr.status, blob: this.response }); } }; xhr.open('GET', url, true); xhr.withCredentials = withCredentials; global$1.each(headers, function (value, key) { xhr.setRequestHeader(key, value); }); xhr.responseType = 'blob'; xhr.send(); }); }; var readBlob = function (blob) { return new global$3(function (resolve) { var fr = FileReader(); fr.onload = function (e) { var data = e.target; resolve(data.result); }; fr.readAsText(blob); }); }; var parseJson = function (text) { var json; try { json = JSON.parse(text); } catch (ex) { } return json; }; var Utils = { traverse: traverse, readBlob: readBlob, requestUrlAsBlob: requestUrlAsBlob, parseJson: parseJson }; var friendlyHttpErrors = [ { code: 404, message: 'Could not find Image Proxy' }, { code: 403, message: 'Rejected request' }, { code: 0, message: 'Incorrect Image Proxy URL' } ]; var friendlyServiceErrors = [ { type: 'key_missing', message: 'The request did not include an api key.' }, { type: 'key_not_found', message: 'The provided api key could not be found.' }, { type: 'domain_not_trusted', message: 'The api key is not valid for the request origins.' } ]; var isServiceErrorCode = function (code) { return code === 400 || code === 403 || code === 500; }; var getHttpErrorMsg = function (status) { var message = find(friendlyHttpErrors, function (error) { return status === error.code; }).fold(constant('Unknown ImageProxy error'), function (error) { return error.message; }); return 'ImageProxy HTTP error: ' + message; }; var handleHttpError = function (status) { var message = getHttpErrorMsg(status); return global$3.reject(message); }; var getServiceErrorMsg = function (type) { return find(friendlyServiceErrors, function (error) { return error.type === type; }).fold(constant('Unknown service error'), function (error) { return error.message; }); }; var getServiceError = function (text) { var serviceError = Utils.parseJson(text); var errorType = Utils.traverse(serviceError, [ 'error', 'type' ]); var errorMsg = errorType ? getServiceErrorMsg(errorType) : 'Invalid JSON in service error message'; return 'ImageProxy Service error: ' + errorMsg; }; var handleServiceError = function (status, blob) { return Utils.readBlob(blob).then(function (text) { var serviceError = getServiceError(text); return global$3.reject(serviceError); }); }; var handleServiceErrorResponse = function (status, blob) { return isServiceErrorCode(status) ? handleServiceError(status, blob) : handleHttpError(status); }; var Errors = { handleServiceErrorResponse: handleServiceErrorResponse, handleHttpError: handleHttpError, getHttpErrorMsg: getHttpErrorMsg, getServiceErrorMsg: getServiceErrorMsg }; var appendApiKey = function (url, apiKey) { var separator = url.indexOf('?') === -1 ? '?' : '&'; if (/[?&]apiKey=/.test(url) || !apiKey) { return url; } else { return url + separator + 'apiKey=' + encodeURIComponent(apiKey); } }; var requestServiceBlob = function (url, apiKey) { var headers = { 'Content-Type': 'application/json;charset=UTF-8', 'tiny-api-key': apiKey }; return Utils.requestUrlAsBlob(appendApiKey(url, apiKey), headers, false).then(function (result) { return result.status < 200 || result.status >= 300 ? Errors.handleServiceErrorResponse(result.status, result.blob) : global$3.resolve(result.blob); }); }; function requestBlob(url, withCredentials) { return Utils.requestUrlAsBlob(url, {}, withCredentials).then(function (result) { return result.status < 200 || result.status >= 300 ? Errors.handleHttpError(result.status) : global$3.resolve(result.blob); }); } var getUrl = function (url, apiKey, withCredentials) { return apiKey ? requestServiceBlob(url, apiKey) : requestBlob(url, withCredentials); }; var Proxy = { getUrl: getUrl }; var count$1 = 0; var isEditableImage = function (editor, img) { var selectorMatched = editor.dom.is(img, 'img:not([data-mce-object],[data-mce-placeholder])'); return selectorMatched && (isLocalImage(editor, img) || isCorsImage(editor, img) || editor.settings.imagetools_proxy); }; var displayError = function (editor, error) { editor.notificationManager.open({ text: error, type: 'error' }); }; var getSelectedImage = function (editor) { return editor.selection.getNode(); }; var extractFilename = function (editor, url) { var m = url.match(/\/([^\/\?]+)?\.(?:jpeg|jpg|png|gif)(?:\?|$)/i); if (m) { return editor.dom.encode(m[1]); } return null; }; var createId = function () { return 'imagetools' + count$1++; }; var isLocalImage = function (editor, img) { var url = img.src; return url.indexOf('data:') === 0 || url.indexOf('blob:') === 0 || new global$4(url).host === editor.documentBaseURI.host; }; var isCorsImage = function (editor, img) { return global$1.inArray(getCorsHosts(editor), new global$4(img.src).host) !== -1; }; var isCorsWithCredentialsImage = function (editor, img) { return global$1.inArray(getCredentialsHosts(editor), new global$4(img.src).host) !== -1; }; var imageToBlob$2 = function (editor, img) { var src = img.src, apiKey; if (isCorsImage(editor, img)) { return Proxy.getUrl(img.src, null, isCorsWithCredentialsImage(editor, img)); } if (!isLocalImage(editor, img)) { src = getProxyUrl(editor); src += (src.indexOf('?') === -1 ? '?' : '&') + 'url=' + encodeURIComponent(img.src); apiKey = getApiKey(editor); return Proxy.getUrl(src, apiKey, false); } return BlobConversions.imageToBlob(img); }; var findSelectedBlob = function (editor) { var blobInfo; blobInfo = editor.editorUpload.blobCache.getByUri(getSelectedImage(editor).src); if (blobInfo) { return global$3.resolve(blobInfo.blob()); } return imageToBlob$2(editor, getSelectedImage(editor)); }; var startTimedUpload = function (editor, imageUploadTimerState) { var imageUploadTimer = global$2.setEditorTimeout(editor, function () { editor.editorUpload.uploadImagesAuto(); }, getUploadTimeout(editor)); imageUploadTimerState.set(imageUploadTimer); }; var cancelTimedUpload = function (imageUploadTimerState) { clearTimeout(imageUploadTimerState.get()); }; var updateSelectedImage = function (editor, ir, uploadImmediately, imageUploadTimerState, size) { return ir.toBlob().then(function (blob) { var uri, name, blobCache, blobInfo, selectedImage; blobCache = editor.editorUpload.blobCache; selectedImage = getSelectedImage(editor); uri = selectedImage.src; if (shouldReuseFilename(editor)) { blobInfo = blobCache.getByUri(uri); if (blobInfo) { uri = blobInfo.uri(); name = blobInfo.name(); } else { name = extractFilename(editor, uri); } } blobInfo = blobCache.create({ id: createId(), blob: blob, base64: ir.toBase64(), uri: uri, name: name }); blobCache.add(blobInfo); editor.undoManager.transact(function () { function imageLoadedHandler() { editor.$(selectedImage).off('load', imageLoadedHandler); editor.nodeChanged(); if (uploadImmediately) { editor.editorUpload.uploadImagesAuto(); } else { cancelTimedUpload(imageUploadTimerState); startTimedUpload(editor, imageUploadTimerState); } } editor.$(selectedImage).on('load', imageLoadedHandler); if (size) { editor.$(selectedImage).attr({ width: size.w, height: size.h }); } editor.$(selectedImage).attr({ src: blobInfo.blobUri() }).removeAttr('data-mce-src'); }); return blobInfo; }); }; var selectedImageOperation = function (editor, imageUploadTimerState, fn, size) { return function () { return editor._scanForImages().then(curry(findSelectedBlob, editor)).then(ResultConversions.blobToImageResult).then(fn).then(function (imageResult) { return updateSelectedImage(editor, imageResult, false, imageUploadTimerState, size); }, function (error) { displayError(editor, error); }); }; }; var rotate$2 = function (editor, imageUploadTimerState, angle) { return function () { var size = ImageSize$1.getImageSize(getSelectedImage(editor)); var flippedSize = size ? { w: size.h, h: size.w } : null; return selectedImageOperation(editor, imageUploadTimerState, function (imageResult) { return ImageTransformations.rotate(imageResult, angle); }, flippedSize)(); }; }; var flip$2 = function (editor, imageUploadTimerState, axis) { return function () { return selectedImageOperation(editor, imageUploadTimerState, function (imageResult) { return ImageTransformations.flip(imageResult, axis); })(); }; }; var editImageDialog = function (editor, imageUploadTimerState) { return function () { var img = getSelectedImage(editor), originalSize = ImageSize$1.getNaturalImageSize(img); var handleDialogBlob = function (blob) { return new global$3(function (resolve) { BlobConversions.blobToImage(blob).then(function (newImage) { var newSize = ImageSize$1.getNaturalImageSize(newImage); if (originalSize.w !== newSize.w || originalSize.h !== newSize.h) { if (ImageSize$1.getImageSize(img)) { ImageSize$1.setImageSize(img, newSize); } } URL.revokeObjectURL(newImage.src); resolve(blob); }); }); }; var openDialog = function (editor, imageResult) { return Dialog.edit(editor, imageResult).then(handleDialogBlob).then(ResultConversions.blobToImageResult).then(function (imageResult) { return updateSelectedImage(editor, imageResult, true, imageUploadTimerState); }, function () { }); }; findSelectedBlob(editor).then(ResultConversions.blobToImageResult).then(curry(openDialog, editor), function (error) { displayError(editor, error); }); }; }; var Actions = { rotate: rotate$2, flip: flip$2, editImageDialog: editImageDialog, isEditableImage: isEditableImage, cancelTimedUpload: cancelTimedUpload }; var register = function (editor, imageUploadTimerState) { global$1.each({ mceImageRotateLeft: Actions.rotate(editor, imageUploadTimerState, -90), mceImageRotateRight: Actions.rotate(editor, imageUploadTimerState, 90), mceImageFlipVertical: Actions.flip(editor, imageUploadTimerState, 'v'), mceImageFlipHorizontal: Actions.flip(editor, imageUploadTimerState, 'h'), mceEditImage: Actions.editImageDialog(editor, imageUploadTimerState) }, function (fn, cmd) { editor.addCommand(cmd, fn); }); }; var Commands = { register: register }; var setup = function (editor, imageUploadTimerState, lastSelectedImageState) { editor.on('NodeChange', function (e) { var lastSelectedImage = lastSelectedImageState.get(); if (lastSelectedImage && lastSelectedImage.src !== e.element.src) { Actions.cancelTimedUpload(imageUploadTimerState); editor.editorUpload.uploadImagesAuto(); lastSelectedImageState.set(null); } if (Actions.isEditableImage(editor, e.element)) { lastSelectedImageState.set(e.element); } }); }; var UploadSelectedImage = { setup: setup }; var register$1 = function (editor) { editor.addButton('rotateleft', { title: 'Rotate counterclockwise', cmd: 'mceImageRotateLeft' }); editor.addButton('rotateright', { title: 'Rotate clockwise', cmd: 'mceImageRotateRight' }); editor.addButton('flipv', { title: 'Flip vertically', cmd: 'mceImageFlipVertical' }); editor.addButton('fliph', { title: 'Flip horizontally', cmd: 'mceImageFlipHorizontal' }); editor.addButton('editimage', { title: 'Edit image', cmd: 'mceEditImage' }); editor.addButton('imageoptions', { title: 'Image options', icon: 'options', cmd: 'mceImage' }); }; var Buttons = { register: register$1 }; var register$2 = function (editor) { editor.addContextToolbar(curry(Actions.isEditableImage, editor), getToolbarItems(editor)); }; var ContextToolbar = { register: register$2 }; global.add('imagetools', function (editor) { var imageUploadTimerState = Cell(0); var lastSelectedImageState = Cell(null); Commands.register(editor, imageUploadTimerState); Buttons.register(editor); ContextToolbar.register(editor); UploadSelectedImage.setup(editor, imageUploadTimerState, lastSelectedImageState); }); function Plugin () { } return Plugin; }(window)); })(); (function () { var importcss = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var global$2 = tinymce.util.Tools.resolve('tinymce.EditorManager'); var global$3 = tinymce.util.Tools.resolve('tinymce.Env'); var global$4 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var shouldMergeClasses = function (editor) { return editor.getParam('importcss_merge_classes'); }; var shouldImportExclusive = function (editor) { return editor.getParam('importcss_exclusive'); }; var getSelectorConverter = function (editor) { return editor.getParam('importcss_selector_converter'); }; var getSelectorFilter = function (editor) { return editor.getParam('importcss_selector_filter'); }; var getCssGroups = function (editor) { return editor.getParam('importcss_groups'); }; var shouldAppend = function (editor) { return editor.getParam('importcss_append'); }; var getFileFilter = function (editor) { return editor.getParam('importcss_file_filter'); }; var Settings = { shouldMergeClasses: shouldMergeClasses, shouldImportExclusive: shouldImportExclusive, getSelectorConverter: getSelectorConverter, getSelectorFilter: getSelectorFilter, getCssGroups: getCssGroups, shouldAppend: shouldAppend, getFileFilter: getFileFilter }; var removeCacheSuffix = function (url) { var cacheSuffix = global$3.cacheSuffix; if (typeof url === 'string') { url = url.replace('?' + cacheSuffix, '').replace('&' + cacheSuffix, ''); } return url; }; var isSkinContentCss = function (editor, href) { var settings = editor.settings, skin = settings.skin !== false ? settings.skin || 'lightgray' : false; if (skin) { var skinUrl = settings.skin_url ? editor.documentBaseURI.toAbsolute(settings.skin_url) : global$2.baseURL + '/skins/' + skin; return href === skinUrl + '/content' + (editor.inline ? '.inline' : '') + '.min.css'; } return false; }; var compileFilter = function (filter) { if (typeof filter === 'string') { return function (value) { return value.indexOf(filter) !== -1; }; } else if (filter instanceof RegExp) { return function (value) { return filter.test(value); }; } return filter; }; var getSelectors = function (editor, doc, fileFilter) { var selectors = [], contentCSSUrls = {}; function append(styleSheet, imported) { var href = styleSheet.href, rules; href = removeCacheSuffix(href); if (!href || !fileFilter(href, imported) || isSkinContentCss(editor, href)) { return; } global$4.each(styleSheet.imports, function (styleSheet) { append(styleSheet, true); }); try { rules = styleSheet.cssRules || styleSheet.rules; } catch (e) { } global$4.each(rules, function (cssRule) { if (cssRule.styleSheet) { append(cssRule.styleSheet, true); } else if (cssRule.selectorText) { global$4.each(cssRule.selectorText.split(','), function (selector) { selectors.push(global$4.trim(selector)); }); } }); } global$4.each(editor.contentCSS, function (url) { contentCSSUrls[url] = true; }); if (!fileFilter) { fileFilter = function (href, imported) { return imported || contentCSSUrls[href]; }; } try { global$4.each(doc.styleSheets, function (styleSheet) { append(styleSheet); }); } catch (e) { } return selectors; }; var defaultConvertSelectorToFormat = function (editor, selectorText) { var format; var selector = /^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(selectorText); if (!selector) { return; } var elementName = selector[1]; var classes = selector[2].substr(1).split('.').join(' '); var inlineSelectorElements = global$4.makeMap('a,img'); if (selector[1]) { format = { title: selectorText }; if (editor.schema.getTextBlockElements()[elementName]) { format.block = elementName; } else if (editor.schema.getBlockElements()[elementName] || inlineSelectorElements[elementName.toLowerCase()]) { format.selector = elementName; } else { format.inline = elementName; } } else if (selector[2]) { format = { inline: 'span', title: selectorText.substr(1), classes: classes }; } if (Settings.shouldMergeClasses(editor) !== false) { format.classes = classes; } else { format.attributes = { class: classes }; } return format; }; var getGroupsBySelector = function (groups, selector) { return global$4.grep(groups, function (group) { return !group.filter || group.filter(selector); }); }; var compileUserDefinedGroups = function (groups) { return global$4.map(groups, function (group) { return global$4.extend({}, group, { original: group, selectors: {}, filter: compileFilter(group.filter), item: { text: group.title, menu: [] } }); }); }; var isExclusiveMode = function (editor, group) { return group === null || Settings.shouldImportExclusive(editor) !== false; }; var isUniqueSelector = function (editor, selector, group, globallyUniqueSelectors) { return !(isExclusiveMode(editor, group) ? selector in globallyUniqueSelectors : selector in group.selectors); }; var markUniqueSelector = function (editor, selector, group, globallyUniqueSelectors) { if (isExclusiveMode(editor, group)) { globallyUniqueSelectors[selector] = true; } else { group.selectors[selector] = true; } }; var convertSelectorToFormat = function (editor, plugin, selector, group) { var selectorConverter; if (group && group.selector_converter) { selectorConverter = group.selector_converter; } else if (Settings.getSelectorConverter(editor)) { selectorConverter = Settings.getSelectorConverter(editor); } else { selectorConverter = function () { return defaultConvertSelectorToFormat(editor, selector); }; } return selectorConverter.call(plugin, selector, group); }; var setup = function (editor) { editor.on('renderFormatsMenu', function (e) { var globallyUniqueSelectors = {}; var selectorFilter = compileFilter(Settings.getSelectorFilter(editor)), ctrl = e.control; var groups = compileUserDefinedGroups(Settings.getCssGroups(editor)); var processSelector = function (selector, group) { if (isUniqueSelector(editor, selector, group, globallyUniqueSelectors)) { markUniqueSelector(editor, selector, group, globallyUniqueSelectors); var format = convertSelectorToFormat(editor, editor.plugins.importcss, selector, group); if (format) { var formatName = format.name || global$1.DOM.uniqueId(); editor.formatter.register(formatName, format); return global$4.extend({}, ctrl.settings.itemDefaults, { text: format.title, format: formatName }); } } return null; }; if (!Settings.shouldAppend(editor)) { ctrl.items().remove(); } global$4.each(getSelectors(editor, e.doc || editor.getDoc(), compileFilter(Settings.getFileFilter(editor))), function (selector) { if (selector.indexOf('.mce-') === -1) { if (!selectorFilter || selectorFilter(selector)) { var selectorGroups = getGroupsBySelector(groups, selector); if (selectorGroups.length > 0) { global$4.each(selectorGroups, function (group) { var menuItem = processSelector(selector, group); if (menuItem) { group.item.menu.push(menuItem); } }); } else { var menuItem = processSelector(selector, null); if (menuItem) { ctrl.add(menuItem); } } } } }); global$4.each(groups, function (group) { if (group.item.menu.length > 0) { ctrl.add(group.item); } }); e.control.renderNew(); }); }; var ImportCss = { defaultConvertSelectorToFormat: defaultConvertSelectorToFormat, setup: setup }; var get = function (editor) { var convertSelectorToFormat = function (selectorText) { return ImportCss.defaultConvertSelectorToFormat(editor, selectorText); }; return { convertSelectorToFormat: convertSelectorToFormat }; }; var Api = { get: get }; global.add('importcss', function (editor) { ImportCss.setup(editor); return Api.get(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var insertdatetime = (function () { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var getDateFormat = function (editor) { return editor.getParam('insertdatetime_dateformat', editor.translate('%Y-%m-%d')); }; var getTimeFormat = function (editor) { return editor.getParam('insertdatetime_timeformat', editor.translate('%H:%M:%S')); }; var getFormats = function (editor) { return editor.getParam('insertdatetime_formats', [ '%H:%M:%S', '%Y-%m-%d', '%I:%M:%S %p', '%D' ]); }; var getDefaultDateTime = function (editor) { var formats = getFormats(editor); return formats.length > 0 ? formats[0] : getTimeFormat(editor); }; var shouldInsertTimeElement = function (editor) { return editor.getParam('insertdatetime_element', false); }; var Settings = { getDateFormat: getDateFormat, getTimeFormat: getTimeFormat, getFormats: getFormats, getDefaultDateTime: getDefaultDateTime, shouldInsertTimeElement: shouldInsertTimeElement }; var daysShort = 'Sun Mon Tue Wed Thu Fri Sat Sun'.split(' '); var daysLong = 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday'.split(' '); var monthsShort = 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' '); var monthsLong = 'January February March April May June July August September October November December'.split(' '); var addZeros = function (value, len) { value = '' + value; if (value.length < len) { for (var i = 0; i < len - value.length; i++) { value = '0' + value; } } return value; }; var getDateTime = function (editor, fmt, date) { date = date || new Date(); fmt = fmt.replace('%D', '%m/%d/%Y'); fmt = fmt.replace('%r', '%I:%M:%S %p'); fmt = fmt.replace('%Y', '' + date.getFullYear()); fmt = fmt.replace('%y', '' + date.getYear()); fmt = fmt.replace('%m', addZeros(date.getMonth() + 1, 2)); fmt = fmt.replace('%d', addZeros(date.getDate(), 2)); fmt = fmt.replace('%H', '' + addZeros(date.getHours(), 2)); fmt = fmt.replace('%M', '' + addZeros(date.getMinutes(), 2)); fmt = fmt.replace('%S', '' + addZeros(date.getSeconds(), 2)); fmt = fmt.replace('%I', '' + ((date.getHours() + 11) % 12 + 1)); fmt = fmt.replace('%p', '' + (date.getHours() < 12 ? 'AM' : 'PM')); fmt = fmt.replace('%B', '' + editor.translate(monthsLong[date.getMonth()])); fmt = fmt.replace('%b', '' + editor.translate(monthsShort[date.getMonth()])); fmt = fmt.replace('%A', '' + editor.translate(daysLong[date.getDay()])); fmt = fmt.replace('%a', '' + editor.translate(daysShort[date.getDay()])); fmt = fmt.replace('%%', '%'); return fmt; }; var updateElement = function (editor, timeElm, computerTime, userTime) { var newTimeElm = editor.dom.create('time', { datetime: computerTime }, userTime); timeElm.parentNode.insertBefore(newTimeElm, timeElm); editor.dom.remove(timeElm); editor.selection.select(newTimeElm, true); editor.selection.collapse(false); }; var insertDateTime = function (editor, format) { if (Settings.shouldInsertTimeElement(editor)) { var userTime = getDateTime(editor, format); var computerTime = void 0; if (/%[HMSIp]/.test(format)) { computerTime = getDateTime(editor, '%Y-%m-%dT%H:%M'); } else { computerTime = getDateTime(editor, '%Y-%m-%d'); } var timeElm = editor.dom.getParent(editor.selection.getStart(), 'time'); if (timeElm) { updateElement(editor, timeElm, computerTime, userTime); } else { editor.insertContent('<time datetime="' + computerTime + '">' + userTime + '</time>'); } } else { editor.insertContent(getDateTime(editor, format)); } }; var Actions = { insertDateTime: insertDateTime, getDateTime: getDateTime }; var register = function (editor) { editor.addCommand('mceInsertDate', function () { Actions.insertDateTime(editor, Settings.getDateFormat(editor)); }); editor.addCommand('mceInsertTime', function () { Actions.insertDateTime(editor, Settings.getTimeFormat(editor)); }); }; var Commands = { register: register }; var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var createMenuItems = function (editor, lastFormatState) { var formats = Settings.getFormats(editor); return global$1.map(formats, function (fmt) { return { text: Actions.getDateTime(editor, fmt), onclick: function () { lastFormatState.set(fmt); Actions.insertDateTime(editor, fmt); } }; }); }; var register$1 = function (editor, lastFormatState) { var menuItems = createMenuItems(editor, lastFormatState); editor.addButton('insertdatetime', { type: 'splitbutton', title: 'Insert date/time', menu: menuItems, onclick: function () { var lastFormat = lastFormatState.get(); Actions.insertDateTime(editor, lastFormat ? lastFormat : Settings.getDefaultDateTime(editor)); } }); editor.addMenuItem('insertdatetime', { icon: 'date', text: 'Date/time', menu: menuItems, context: 'insert' }); }; var Buttons = { register: register$1 }; global.add('insertdatetime', function (editor) { var lastFormatState = Cell(null); Commands.register(editor); Buttons.register(editor, lastFormatState); }); function Plugin () { } return Plugin; }()); })(); (function () { var legacyoutput = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var overrideFormats = function (editor) { var alignElements = 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', fontSizes = global$1.explode(editor.settings.font_size_style_values), schema = editor.schema; editor.formatter.register({ alignleft: { selector: alignElements, attributes: { align: 'left' } }, aligncenter: { selector: alignElements, attributes: { align: 'center' } }, alignright: { selector: alignElements, attributes: { align: 'right' } }, alignjustify: { selector: alignElements, attributes: { align: 'justify' } }, bold: [ { inline: 'b', remove: 'all' }, { inline: 'strong', remove: 'all' }, { inline: 'span', styles: { fontWeight: 'bold' } } ], italic: [ { inline: 'i', remove: 'all' }, { inline: 'em', remove: 'all' }, { inline: 'span', styles: { fontStyle: 'italic' } } ], underline: [ { inline: 'u', remove: 'all' }, { inline: 'span', styles: { textDecoration: 'underline' }, exact: true } ], strikethrough: [ { inline: 'strike', remove: 'all' }, { inline: 'span', styles: { textDecoration: 'line-through' }, exact: true } ], fontname: { inline: 'font', attributes: { face: '%value' } }, fontsize: { inline: 'font', attributes: { size: function (vars) { return global$1.inArray(fontSizes, vars.value) + 1; } } }, forecolor: { inline: 'font', attributes: { color: '%value' } }, hilitecolor: { inline: 'font', styles: { backgroundColor: '%value' } } }); global$1.each('b,i,u,strike'.split(','), function (name) { schema.addValidElements(name + '[*]'); }); if (!schema.getElementRule('font')) { schema.addValidElements('font[face|size|color|style]'); } global$1.each(alignElements.split(','), function (name) { var rule = schema.getElementRule(name); if (rule) { if (!rule.attributes.align) { rule.attributes.align = {}; rule.attributesOrder.push('align'); } } }); }; var setup = function (editor) { editor.settings.inline_styles = false; editor.on('init', function () { overrideFormats(editor); }); }; var Formats = { setup: setup }; var register = function (editor) { editor.addButton('fontsizeselect', function () { var items = [], defaultFontsizeFormats = '8pt=1 10pt=2 12pt=3 14pt=4 18pt=5 24pt=6 36pt=7'; var fontsizeFormats = editor.settings.fontsizeFormats || defaultFontsizeFormats; editor.$.each(fontsizeFormats.split(' '), function (i, item) { var text = item, value = item; var values = item.split('='); if (values.length > 1) { text = values[0]; value = values[1]; } items.push({ text: text, value: value }); }); return { type: 'listbox', text: 'Font Sizes', tooltip: 'Font Sizes', values: items, fixedWidth: true, onPostRender: function () { var self = this; editor.on('NodeChange', function () { var fontElm; fontElm = editor.dom.getParent(editor.selection.getNode(), 'font'); if (fontElm) { self.value(fontElm.size); } else { self.value(''); } }); }, onclick: function (e) { if (e.control.settings.value) { editor.execCommand('FontSize', false, e.control.settings.value); } } }; }); editor.addButton('fontselect', function () { function createFormats(formats) { formats = formats.replace(/;$/, '').split(';'); var i = formats.length; while (i--) { formats[i] = formats[i].split('='); } return formats; } 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'; var items = [], fonts = createFormats(editor.settings.font_formats || defaultFontsFormats); editor.$.each(fonts, function (i, font) { items.push({ text: { raw: font[0] }, value: font[1], textStyle: font[1].indexOf('dings') === -1 ? 'font-family:' + font[1] : '' }); }); return { type: 'listbox', text: 'Font Family', tooltip: 'Font Family', values: items, fixedWidth: true, onPostRender: function () { var self = this; editor.on('NodeChange', function () { var fontElm; fontElm = editor.dom.getParent(editor.selection.getNode(), 'font'); if (fontElm) { self.value(fontElm.face); } else { self.value(''); } }); }, onselect: function (e) { if (e.control.settings.value) { editor.execCommand('FontName', false, e.control.settings.value); } } }; }); }; var Buttons = { register: register }; global.add('legacyoutput', function (editor) { Formats.setup(editor); Buttons.register(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var link = (function (domGlobals) { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.util.VK'); var assumeExternalTargets = function (editorSettings) { return typeof editorSettings.link_assume_external_targets === 'boolean' ? editorSettings.link_assume_external_targets : false; }; var hasContextToolbar = function (editorSettings) { return typeof editorSettings.link_context_toolbar === 'boolean' ? editorSettings.link_context_toolbar : false; }; var getLinkList = function (editorSettings) { return editorSettings.link_list; }; var hasDefaultLinkTarget = function (editorSettings) { return typeof editorSettings.default_link_target === 'string'; }; var getDefaultLinkTarget = function (editorSettings) { return editorSettings.default_link_target; }; var getTargetList = function (editorSettings) { return editorSettings.target_list; }; var setTargetList = function (editor, list) { editor.settings.target_list = list; }; var shouldShowTargetList = function (editorSettings) { return getTargetList(editorSettings) !== false; }; var getRelList = function (editorSettings) { return editorSettings.rel_list; }; var hasRelList = function (editorSettings) { return getRelList(editorSettings) !== undefined; }; var getLinkClassList = function (editorSettings) { return editorSettings.link_class_list; }; var hasLinkClassList = function (editorSettings) { return getLinkClassList(editorSettings) !== undefined; }; var shouldShowLinkTitle = function (editorSettings) { return editorSettings.link_title !== false; }; var allowUnsafeLinkTarget = function (editorSettings) { return typeof editorSettings.allow_unsafe_link_target === 'boolean' ? editorSettings.allow_unsafe_link_target : false; }; var Settings = { assumeExternalTargets: assumeExternalTargets, hasContextToolbar: hasContextToolbar, getLinkList: getLinkList, hasDefaultLinkTarget: hasDefaultLinkTarget, getDefaultLinkTarget: getDefaultLinkTarget, getTargetList: getTargetList, setTargetList: setTargetList, shouldShowTargetList: shouldShowTargetList, getRelList: getRelList, hasRelList: hasRelList, getLinkClassList: getLinkClassList, hasLinkClassList: hasLinkClassList, shouldShowLinkTitle: shouldShowLinkTitle, allowUnsafeLinkTarget: allowUnsafeLinkTarget }; var global$2 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var global$3 = tinymce.util.Tools.resolve('tinymce.Env'); var appendClickRemove = function (link, evt) { domGlobals.document.body.appendChild(link); link.dispatchEvent(evt); domGlobals.document.body.removeChild(link); }; var open = function (url) { if (!global$3.ie || global$3.ie > 10) { var link = domGlobals.document.createElement('a'); link.target = '_blank'; link.href = url; link.rel = 'noreferrer noopener'; var evt = domGlobals.document.createEvent('MouseEvents'); evt.initMouseEvent('click', true, true, domGlobals.window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); appendClickRemove(link, evt); } else { var win = domGlobals.window.open('', '_blank'); if (win) { win.opener = null; var doc = win.document; doc.open(); doc.write('<meta http-equiv="refresh" content="0; url=' + global$2.DOM.encode(url) + '">'); doc.close(); } } }; var OpenUrl = { open: open }; var global$4 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var toggleTargetRules = function (rel, isUnsafe) { var rules = ['noopener']; var newRel = rel ? rel.split(/\s+/) : []; var toString = function (rel) { return global$4.trim(rel.sort().join(' ')); }; var addTargetRules = function (rel) { rel = removeTargetRules(rel); return rel.length ? rel.concat(rules) : rules; }; var removeTargetRules = function (rel) { return rel.filter(function (val) { return global$4.inArray(rules, val) === -1; }); }; newRel = isUnsafe ? addTargetRules(newRel) : removeTargetRules(newRel); return newRel.length ? toString(newRel) : null; }; var trimCaretContainers = function (text) { return text.replace(/\uFEFF/g, ''); }; var getAnchorElement = function (editor, selectedElm) { selectedElm = selectedElm || editor.selection.getNode(); if (isImageFigure(selectedElm)) { return editor.dom.select('a[href]', selectedElm)[0]; } else { return editor.dom.getParent(selectedElm, 'a[href]'); } }; var getAnchorText = function (selection, anchorElm) { var text = anchorElm ? anchorElm.innerText || anchorElm.textContent : selection.getContent({ format: 'text' }); return trimCaretContainers(text); }; var isLink = function (elm) { return elm && elm.nodeName === 'A' && elm.href; }; var hasLinks = function (elements) { return global$4.grep(elements, isLink).length > 0; }; var isOnlyTextSelected = function (html) { if (/</.test(html) && (!/^<a [^>]+>[^<]+<\/a>$/.test(html) || html.indexOf('href=') === -1)) { return false; } return true; }; var isImageFigure = function (node) { return node && node.nodeName === 'FIGURE' && /\bimage\b/i.test(node.className); }; var link = function (editor, attachState) { return function (data) { editor.undoManager.transact(function () { var selectedElm = editor.selection.getNode(); var anchorElm = getAnchorElement(editor, selectedElm); var linkAttrs = { href: data.href, target: data.target ? data.target : null, rel: data.rel ? data.rel : null, class: data.class ? data.class : null, title: data.title ? data.title : null }; if (!Settings.hasRelList(editor.settings) && Settings.allowUnsafeLinkTarget(editor.settings) === false) { linkAttrs.rel = toggleTargetRules(linkAttrs.rel, linkAttrs.target === '_blank'); } if (data.href === attachState.href) { attachState.attach(); attachState = {}; } if (anchorElm) { editor.focus(); if (data.hasOwnProperty('text')) { if ('innerText' in anchorElm) { anchorElm.innerText = data.text; } else { anchorElm.textContent = data.text; } } editor.dom.setAttribs(anchorElm, linkAttrs); editor.selection.select(anchorElm); editor.undoManager.add(); } else { if (isImageFigure(selectedElm)) { linkImageFigure(editor, selectedElm, linkAttrs); } else if (data.hasOwnProperty('text')) { editor.insertContent(editor.dom.createHTML('a', linkAttrs, editor.dom.encode(data.text))); } else { editor.execCommand('mceInsertLink', false, linkAttrs); } } }); }; }; var unlink = function (editor) { return function () { editor.undoManager.transact(function () { var node = editor.selection.getNode(); if (isImageFigure(node)) { unlinkImageFigure(editor, node); } else { editor.execCommand('unlink'); } }); }; }; var unlinkImageFigure = function (editor, fig) { var a, img; img = editor.dom.select('img', fig)[0]; if (img) { a = editor.dom.getParents(img, 'a[href]', fig)[0]; if (a) { a.parentNode.insertBefore(img, a); editor.dom.remove(a); } } }; var linkImageFigure = function (editor, fig, attrs) { var a, img; img = editor.dom.select('img', fig)[0]; if (img) { a = editor.dom.create('a', attrs); img.parentNode.insertBefore(a, img); a.appendChild(img); } }; var Utils = { link: link, unlink: unlink, isLink: isLink, hasLinks: hasLinks, isOnlyTextSelected: isOnlyTextSelected, getAnchorElement: getAnchorElement, getAnchorText: getAnchorText, toggleTargetRules: toggleTargetRules }; var global$5 = tinymce.util.Tools.resolve('tinymce.util.Delay'); var global$6 = tinymce.util.Tools.resolve('tinymce.util.XHR'); var attachState = {}; var createLinkList = function (editor, callback) { var linkList = Settings.getLinkList(editor.settings); if (typeof linkList === 'string') { global$6.send({ url: linkList, success: function (text) { callback(editor, JSON.parse(text)); } }); } else if (typeof linkList === 'function') { linkList(function (list) { callback(editor, list); }); } else { callback(editor, linkList); } }; var buildListItems = function (inputList, itemCallback, startItems) { var appendItems = function (values, output) { output = output || []; global$4.each(values, function (item) { var menuItem = { text: item.text || item.title }; if (item.menu) { menuItem.menu = appendItems(item.menu); } else { menuItem.value = item.value; if (itemCallback) { itemCallback(menuItem); } } output.push(menuItem); }); return output; }; return appendItems(inputList, startItems || []); }; var delayedConfirm = function (editor, message, callback) { var rng = editor.selection.getRng(); global$5.setEditorTimeout(editor, function () { editor.windowManager.confirm(message, function (state) { editor.selection.setRng(rng); callback(state); }); }); }; var showDialog = function (editor, linkList) { var data = {}; var selection = editor.selection; var dom = editor.dom; var anchorElm, initialText; var win, onlyText, textListCtrl, linkListCtrl, relListCtrl, targetListCtrl, classListCtrl, linkTitleCtrl, value; var linkListChangeHandler = function (e) { var textCtrl = win.find('#text'); if (!textCtrl.value() || e.lastControl && textCtrl.value() === e.lastControl.text()) { textCtrl.value(e.control.text()); } win.find('#href').value(e.control.value()); }; var buildAnchorListControl = function (url) { var anchorList = []; global$4.each(editor.dom.select('a:not([href])'), function (anchor) { var id = anchor.name || anchor.id; if (id) { anchorList.push({ text: id, value: '#' + id, selected: url.indexOf('#' + id) !== -1 }); } }); if (anchorList.length) { anchorList.unshift({ text: 'None', value: '' }); return { name: 'anchor', type: 'listbox', label: 'Anchors', values: anchorList, onselect: linkListChangeHandler }; } }; var updateText = function () { if (!initialText && onlyText && !data.text) { this.parent().parent().find('#text')[0].value(this.value()); } }; var urlChange = function (e) { var meta = e.meta || {}; if (linkListCtrl) { linkListCtrl.value(editor.convertURL(this.value(), 'href')); } global$4.each(e.meta, function (value, key) { var inp = win.find('#' + key); if (key === 'text') { if (initialText.length === 0) { inp.value(value); data.text = value; } } else { inp.value(value); } }); if (meta.attach) { attachState = { href: this.value(), attach: meta.attach }; } if (!meta.text) { updateText.call(this); } }; var onBeforeCall = function (e) { e.meta = win.toJSON(); }; onlyText = Utils.isOnlyTextSelected(selection.getContent()); anchorElm = Utils.getAnchorElement(editor); data.text = initialText = Utils.getAnchorText(editor.selection, anchorElm); data.href = anchorElm ? dom.getAttrib(anchorElm, 'href') : ''; if (anchorElm) { data.target = dom.getAttrib(anchorElm, 'target'); } else if (Settings.hasDefaultLinkTarget(editor.settings)) { data.target = Settings.getDefaultLinkTarget(editor.settings); } if (value = dom.getAttrib(anchorElm, 'rel')) { data.rel = value; } if (value = dom.getAttrib(anchorElm, 'class')) { data.class = value; } if (value = dom.getAttrib(anchorElm, 'title')) { data.title = value; } if (onlyText) { textListCtrl = { name: 'text', type: 'textbox', size: 40, label: 'Text to display', onchange: function () { data.text = this.value(); } }; } if (linkList) { linkListCtrl = { type: 'listbox', label: 'Link list', values: buildListItems(linkList, function (item) { item.value = editor.convertURL(item.value || item.url, 'href'); }, [{ text: 'None', value: '' }]), onselect: linkListChangeHandler, value: editor.convertURL(data.href, 'href'), onPostRender: function () { linkListCtrl = this; } }; } if (Settings.shouldShowTargetList(editor.settings)) { if (Settings.getTargetList(editor.settings) === undefined) { Settings.setTargetList(editor, [ { text: 'None', value: '' }, { text: 'New window', value: '_blank' } ]); } targetListCtrl = { name: 'target', type: 'listbox', label: 'Target', values: buildListItems(Settings.getTargetList(editor.settings)) }; } if (Settings.hasRelList(editor.settings)) { relListCtrl = { name: 'rel', type: 'listbox', label: 'Rel', values: buildListItems(Settings.getRelList(editor.settings), function (item) { if (Settings.allowUnsafeLinkTarget(editor.settings) === false) { item.value = Utils.toggleTargetRules(item.value, data.target === '_blank'); } }) }; } if (Settings.hasLinkClassList(editor.settings)) { classListCtrl = { name: 'class', type: 'listbox', label: 'Class', values: buildListItems(Settings.getLinkClassList(editor.settings), function (item) { if (item.value) { item.textStyle = function () { return editor.formatter.getCssText({ inline: 'a', classes: [item.value] }); }; } }) }; } if (Settings.shouldShowLinkTitle(editor.settings)) { linkTitleCtrl = { name: 'title', type: 'textbox', label: 'Title', value: data.title }; } win = editor.windowManager.open({ title: 'Insert link', data: data, body: [ { name: 'href', type: 'filepicker', filetype: 'file', size: 40, autofocus: true, label: 'Url', onchange: urlChange, onkeyup: updateText, onpaste: updateText, onbeforecall: onBeforeCall }, textListCtrl, linkTitleCtrl, buildAnchorListControl(data.href), linkListCtrl, relListCtrl, targetListCtrl, classListCtrl ], onSubmit: function (e) { var assumeExternalTargets = Settings.assumeExternalTargets(editor.settings); var insertLink = Utils.link(editor, attachState); var removeLink = Utils.unlink(editor); var resultData = global$4.extend({}, data, e.data); var href = resultData.href; if (!href) { removeLink(); return; } if (!onlyText || resultData.text === initialText) { delete resultData.text; } if (href.indexOf('@') > 0 && href.indexOf('//') === -1 && href.indexOf('mailto:') === -1) { delayedConfirm(editor, 'The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?', function (state) { if (state) { resultData.href = 'mailto:' + href; } insertLink(resultData); }); return; } if (assumeExternalTargets === true && !/^\w+:/i.test(href) || assumeExternalTargets === false && /^\s*www[\.|\d\.]/i.test(href)) { delayedConfirm(editor, 'The URL you entered seems to be an external link. Do you want to add the required http:// prefix?', function (state) { if (state) { resultData.href = 'http://' + href; } insertLink(resultData); }); return; } insertLink(resultData); } }); }; var open$1 = function (editor) { createLinkList(editor, showDialog); }; var Dialog = { open: open$1 }; var getLink = function (editor, elm) { return editor.dom.getParent(elm, 'a[href]'); }; var getSelectedLink = function (editor) { return getLink(editor, editor.selection.getStart()); }; var getHref = function (elm) { var href = elm.getAttribute('data-mce-href'); return href ? href : elm.getAttribute('href'); }; var isContextMenuVisible = function (editor) { var contextmenu = editor.plugins.contextmenu; return contextmenu ? contextmenu.isContextMenuVisible() : false; }; var hasOnlyAltModifier = function (e) { return e.altKey === true && e.shiftKey === false && e.ctrlKey === false && e.metaKey === false; }; var gotoLink = function (editor, a) { if (a) { var href = getHref(a); if (/^#/.test(href)) { var targetEl = editor.$(href); if (targetEl.length) { editor.selection.scrollIntoView(targetEl[0], true); } } else { OpenUrl.open(a.href); } } }; var openDialog = function (editor) { return function () { Dialog.open(editor); }; }; var gotoSelectedLink = function (editor) { return function () { gotoLink(editor, getSelectedLink(editor)); }; }; var leftClickedOnAHref = function (editor) { return function (elm) { var sel, rng, node; if (Settings.hasContextToolbar(editor.settings) && !isContextMenuVisible(editor) && Utils.isLink(elm)) { sel = editor.selection; rng = sel.getRng(); node = rng.startContainer; if (node.nodeType === 3 && sel.isCollapsed() && rng.startOffset > 0 && rng.startOffset < node.data.length) { return true; } } return false; }; }; var setupGotoLinks = function (editor) { editor.on('click', function (e) { var link = getLink(editor, e.target); if (link && global$1.metaKeyPressed(e)) { e.preventDefault(); gotoLink(editor, link); } }); editor.on('keydown', function (e) { var link = getSelectedLink(editor); if (link && e.keyCode === 13 && hasOnlyAltModifier(e)) { e.preventDefault(); gotoLink(editor, link); } }); }; var toggleActiveState = function (editor) { return function () { var self = this; editor.on('nodechange', function (e) { self.active(!editor.readonly && !!Utils.getAnchorElement(editor, e.element)); }); }; }; var toggleViewLinkState = function (editor) { return function () { var self = this; var toggleVisibility = function (e) { if (Utils.hasLinks(e.parents)) { self.show(); } else { self.hide(); } }; if (!Utils.hasLinks(editor.dom.getParents(editor.selection.getStart()))) { self.hide(); } editor.on('nodechange', toggleVisibility); self.on('remove', function () { editor.off('nodechange', toggleVisibility); }); }; }; var Actions = { openDialog: openDialog, gotoSelectedLink: gotoSelectedLink, leftClickedOnAHref: leftClickedOnAHref, setupGotoLinks: setupGotoLinks, toggleActiveState: toggleActiveState, toggleViewLinkState: toggleViewLinkState }; var register = function (editor) { editor.addCommand('mceLink', Actions.openDialog(editor)); }; var Commands = { register: register }; var setup = function (editor) { editor.addShortcut('Meta+K', '', Actions.openDialog(editor)); }; var Keyboard = { setup: setup }; var setupButtons = function (editor) { editor.addButton('link', { active: false, icon: 'link', tooltip: 'Insert/edit link', onclick: Actions.openDialog(editor), onpostrender: Actions.toggleActiveState(editor) }); editor.addButton('unlink', { active: false, icon: 'unlink', tooltip: 'Remove link', onclick: Utils.unlink(editor), onpostrender: Actions.toggleActiveState(editor) }); if (editor.addContextToolbar) { editor.addButton('openlink', { icon: 'newtab', tooltip: 'Open link', onclick: Actions.gotoSelectedLink(editor) }); } }; var setupMenuItems = function (editor) { editor.addMenuItem('openlink', { text: 'Open link', icon: 'newtab', onclick: Actions.gotoSelectedLink(editor), onPostRender: Actions.toggleViewLinkState(editor), prependToContext: true }); editor.addMenuItem('link', { icon: 'link', text: 'Link', shortcut: 'Meta+K', onclick: Actions.openDialog(editor), stateSelector: 'a[href]', context: 'insert', prependToContext: true }); editor.addMenuItem('unlink', { icon: 'unlink', text: 'Remove link', onclick: Utils.unlink(editor), stateSelector: 'a[href]' }); }; var setupContextToolbars = function (editor) { if (editor.addContextToolbar) { editor.addContextToolbar(Actions.leftClickedOnAHref(editor), 'openlink | link unlink'); } }; var Controls = { setupButtons: setupButtons, setupMenuItems: setupMenuItems, setupContextToolbars: setupContextToolbars }; global.add('link', function (editor) { Controls.setupButtons(editor); Controls.setupMenuItems(editor); Controls.setupContextToolbars(editor); Actions.setupGotoLinks(editor); Commands.register(editor); Keyboard.setup(editor); }); function Plugin () { } return Plugin; }(window)); })(); (function () { var lists = (function (domGlobals) { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.dom.RangeUtils'); var global$2 = tinymce.util.Tools.resolve('tinymce.dom.TreeWalker'); var global$3 = tinymce.util.Tools.resolve('tinymce.util.VK'); var global$4 = tinymce.util.Tools.resolve('tinymce.dom.BookmarkManager'); var global$5 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var global$6 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var isTextNode = function (node) { return node && node.nodeType === 3; }; var isListNode = function (node) { return node && /^(OL|UL|DL)$/.test(node.nodeName); }; var isOlUlNode = function (node) { return node && /^(OL|UL)$/.test(node.nodeName); }; var isListItemNode = function (node) { return node && /^(LI|DT|DD)$/.test(node.nodeName); }; var isDlItemNode = function (node) { return node && /^(DT|DD)$/.test(node.nodeName); }; var isTableCellNode = function (node) { return node && /^(TH|TD)$/.test(node.nodeName); }; var isBr = function (node) { return node && node.nodeName === 'BR'; }; var isFirstChild = function (node) { return node.parentNode.firstChild === node; }; var isLastChild = function (node) { return node.parentNode.lastChild === node; }; var isTextBlock = function (editor, node) { return node && !!editor.schema.getTextBlockElements()[node.nodeName]; }; var isBlock = function (node, blockElements) { return node && node.nodeName in blockElements; }; var isBogusBr = function (dom, node) { if (!isBr(node)) { return false; } if (dom.isBlock(node.nextSibling) && !isBr(node.previousSibling)) { return true; } return false; }; var isEmpty = function (dom, elm, keepBookmarks) { var empty = dom.isEmpty(elm); if (keepBookmarks && dom.select('span[data-mce-type=bookmark]', elm).length > 0) { return false; } return empty; }; var isChildOfBody = function (dom, elm) { return dom.isChildOf(elm, dom.getRoot()); }; var NodeType = { isTextNode: isTextNode, isListNode: isListNode, isOlUlNode: isOlUlNode, isDlItemNode: isDlItemNode, isListItemNode: isListItemNode, isTableCellNode: isTableCellNode, isBr: isBr, isFirstChild: isFirstChild, isLastChild: isLastChild, isTextBlock: isTextBlock, isBlock: isBlock, isBogusBr: isBogusBr, isEmpty: isEmpty, isChildOfBody: isChildOfBody }; var getNormalizedPoint = function (container, offset) { if (NodeType.isTextNode(container)) { return { container: container, offset: offset }; } var node = global$1.getNode(container, offset); if (NodeType.isTextNode(node)) { return { container: node, offset: offset >= container.childNodes.length ? node.data.length : 0 }; } else if (node.previousSibling && NodeType.isTextNode(node.previousSibling)) { return { container: node.previousSibling, offset: node.previousSibling.data.length }; } else if (node.nextSibling && NodeType.isTextNode(node.nextSibling)) { return { container: node.nextSibling, offset: 0 }; } return { container: container, offset: offset }; }; var normalizeRange = function (rng) { var outRng = rng.cloneRange(); var rangeStart = getNormalizedPoint(rng.startContainer, rng.startOffset); outRng.setStart(rangeStart.container, rangeStart.offset); var rangeEnd = getNormalizedPoint(rng.endContainer, rng.endOffset); outRng.setEnd(rangeEnd.container, rangeEnd.offset); return outRng; }; var Range = { getNormalizedPoint: getNormalizedPoint, normalizeRange: normalizeRange }; var DOM = global$6.DOM; var createBookmark = function (rng) { var bookmark = {}; var setupEndPoint = function (start) { var offsetNode, container, offset; container = rng[start ? 'startContainer' : 'endContainer']; offset = rng[start ? 'startOffset' : 'endOffset']; if (container.nodeType === 1) { offsetNode = DOM.create('span', { 'data-mce-type': 'bookmark' }); if (container.hasChildNodes()) { offset = Math.min(offset, container.childNodes.length - 1); if (start) { container.insertBefore(offsetNode, container.childNodes[offset]); } else { DOM.insertAfter(offsetNode, container.childNodes[offset]); } } else { container.appendChild(offsetNode); } container = offsetNode; offset = 0; } bookmark[start ? 'startContainer' : 'endContainer'] = container; bookmark[start ? 'startOffset' : 'endOffset'] = offset; }; setupEndPoint(true); if (!rng.collapsed) { setupEndPoint(); } return bookmark; }; var resolveBookmark = function (bookmark) { function restoreEndPoint(start) { var container, offset, node; var nodeIndex = function (container) { var node = container.parentNode.firstChild, idx = 0; while (node) { if (node === container) { return idx; } if (node.nodeType !== 1 || node.getAttribute('data-mce-type') !== 'bookmark') { idx++; } node = node.nextSibling; } return -1; }; container = node = bookmark[start ? 'startContainer' : 'endContainer']; offset = bookmark[start ? 'startOffset' : 'endOffset']; if (!container) { return; } if (container.nodeType === 1) { offset = nodeIndex(container); container = container.parentNode; DOM.remove(node); if (!container.hasChildNodes() && DOM.isBlock(container)) { container.appendChild(DOM.create('br')); } } bookmark[start ? 'startContainer' : 'endContainer'] = container; bookmark[start ? 'startOffset' : 'endOffset'] = offset; } restoreEndPoint(true); restoreEndPoint(); var rng = DOM.createRng(); rng.setStart(bookmark.startContainer, bookmark.startOffset); if (bookmark.endContainer) { rng.setEnd(bookmark.endContainer, bookmark.endOffset); } return Range.normalizeRange(rng); }; var Bookmark = { createBookmark: createBookmark, resolveBookmark: resolveBookmark }; var constant = function (value) { return function () { return value; }; }; var not = function (f) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return !f.apply(null, args); }; }; var never = constant(false); var always = constant(true); var never$1 = never; var always$1 = always; var none = function () { return NONE; }; var NONE = function () { var eq = function (o) { return o.isNone(); }; var call = function (thunk) { return thunk(); }; var id = function (n) { return n; }; var noop = function () { }; var nul = function () { return null; }; var undef = function () { return undefined; }; var me = { fold: function (n, s) { return n(); }, is: never$1, isSome: never$1, isNone: always$1, getOr: id, getOrThunk: call, getOrDie: function (msg) { throw new Error(msg || 'error: getOrDie called on none.'); }, getOrNull: nul, getOrUndefined: undef, or: id, orThunk: call, map: none, ap: none, each: noop, bind: none, flatten: none, exists: never$1, forall: always$1, filter: none, equals: eq, equals_: eq, toArray: function () { return []; }, toString: constant('none()') }; if (Object.freeze) Object.freeze(me); return me; }(); var some = function (a) { var constant_a = function () { return a; }; var self = function () { return me; }; var map = function (f) { return some(f(a)); }; var bind = function (f) { return f(a); }; var me = { fold: function (n, s) { return s(a); }, is: function (v) { return a === v; }, isSome: always$1, isNone: never$1, getOr: constant_a, getOrThunk: constant_a, getOrDie: constant_a, getOrNull: constant_a, getOrUndefined: constant_a, or: self, orThunk: self, map: map, ap: function (optfab) { return optfab.fold(none, function (fab) { return some(fab(a)); }); }, each: function (f) { f(a); }, bind: bind, flatten: constant_a, exists: bind, forall: bind, filter: function (f) { return f(a) ? me : NONE; }, equals: function (o) { return o.is(a); }, equals_: function (o, elementEq) { return o.fold(never$1, function (b) { return elementEq(a, b); }); }, toArray: function () { return [a]; }, toString: function () { return 'some(' + a + ')'; } }; return me; }; var from = function (value) { return value === null || value === undefined ? NONE : some(value); }; var Option = { some: some, none: none, from: from }; var typeOf = function (x) { if (x === null) return 'null'; var t = typeof x; if (t === 'object' && Array.prototype.isPrototypeOf(x)) return 'array'; if (t === 'object' && String.prototype.isPrototypeOf(x)) return 'string'; return t; }; var isType = function (type) { return function (value) { return typeOf(value) === type; }; }; var isString = isType('string'); var isBoolean = isType('boolean'); var isFunction = isType('function'); var isNumber = isType('number'); var map = function (xs, f) { var len = xs.length; var r = new Array(len); for (var i = 0; i < len; i++) { var x = xs[i]; r[i] = f(x, i, xs); } return r; }; var each = function (xs, f) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; f(x, i, xs); } }; var filter = function (xs, pred) { var r = []; for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { r.push(x); } } return r; }; var groupBy = function (xs, f) { if (xs.length === 0) { return []; } else { var wasType = f(xs[0]); var r = []; var group = []; for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; var type = f(x); if (type !== wasType) { r.push(group); group = []; } wasType = type; group.push(x); } if (group.length !== 0) { r.push(group); } return r; } }; var foldl = function (xs, f, acc) { each(xs, function (x) { acc = f(acc, x); }); return acc; }; var find = function (xs, pred) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { return Option.some(x); } } return Option.none(); }; var push = Array.prototype.push; var flatten = function (xs) { var r = []; for (var i = 0, len = xs.length; i < len; ++i) { if (!Array.prototype.isPrototypeOf(xs[i])) throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs); push.apply(r, xs[i]); } return r; }; var bind = function (xs, f) { var output = map(xs, f); return flatten(output); }; var slice = Array.prototype.slice; var reverse = function (xs) { var r = slice.call(xs, 0); r.reverse(); return r; }; var head = function (xs) { return xs.length === 0 ? Option.none() : Option.some(xs[0]); }; var last = function (xs) { return xs.length === 0 ? Option.none() : Option.some(xs[xs.length - 1]); }; var from$1 = isFunction(Array.from) ? Array.from : function (x) { return slice.call(x); }; var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')(); var path = function (parts, scope) { var o = scope !== undefined && scope !== null ? scope : Global; for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i) o = o[parts[i]]; return o; }; var resolve = function (p, scope) { var parts = p.split('.'); return path(parts, scope); }; var unsafe = function (name, scope) { return resolve(name, scope); }; var getOrDie = function (name, scope) { var actual = unsafe(name, scope); if (actual === undefined || actual === null) throw name + ' not available on this browser'; return actual; }; var Global$1 = { getOrDie: getOrDie }; var htmlElement = function (scope) { return Global$1.getOrDie('HTMLElement', scope); }; var isPrototypeOf = function (x) { var scope = resolve('ownerDocument.defaultView', x); return htmlElement(scope).prototype.isPrototypeOf(x); }; var HTMLElement = { isPrototypeOf: isPrototypeOf }; var global$7 = tinymce.util.Tools.resolve('tinymce.dom.DomQuery'); var getParentList = function (editor) { var selectionStart = editor.selection.getStart(true); return editor.dom.getParent(selectionStart, 'OL,UL,DL', getClosestListRootElm(editor, selectionStart)); }; var isParentListSelected = function (parentList, selectedBlocks) { return parentList && selectedBlocks.length === 1 && selectedBlocks[0] === parentList; }; var findSubLists = function (parentList) { return global$5.grep(parentList.querySelectorAll('ol,ul,dl'), function (elm) { return NodeType.isListNode(elm); }); }; var getSelectedSubLists = function (editor) { var parentList = getParentList(editor); var selectedBlocks = editor.selection.getSelectedBlocks(); if (isParentListSelected(parentList, selectedBlocks)) { return findSubLists(parentList); } else { return global$5.grep(selectedBlocks, function (elm) { return NodeType.isListNode(elm) && parentList !== elm; }); } }; var findParentListItemsNodes = function (editor, elms) { var listItemsElms = global$5.map(elms, function (elm) { var parentLi = editor.dom.getParent(elm, 'li,dd,dt', getClosestListRootElm(editor, elm)); return parentLi ? parentLi : elm; }); return global$7.unique(listItemsElms); }; var getSelectedListItems = function (editor) { var selectedBlocks = editor.selection.getSelectedBlocks(); return global$5.grep(findParentListItemsNodes(editor, selectedBlocks), function (block) { return NodeType.isListItemNode(block); }); }; var getSelectedDlItems = function (editor) { return filter(getSelectedListItems(editor), NodeType.isDlItemNode); }; var getClosestListRootElm = function (editor, elm) { var parentTableCell = editor.dom.getParents(elm, 'TD,TH'); var root = parentTableCell.length > 0 ? parentTableCell[0] : editor.getBody(); return root; }; var findLastParentListNode = function (editor, elm) { var parentLists = editor.dom.getParents(elm, 'ol,ul', getClosestListRootElm(editor, elm)); return last(parentLists); }; var getSelectedLists = function (editor) { var firstList = findLastParentListNode(editor, editor.selection.getStart()); var subsequentLists = filter(editor.selection.getSelectedBlocks(), NodeType.isOlUlNode); return firstList.toArray().concat(subsequentLists); }; var getSelectedListRoots = function (editor) { var selectedLists = getSelectedLists(editor); return getUniqueListRoots(editor, selectedLists); }; var getUniqueListRoots = function (editor, lists) { var listRoots = map(lists, function (list) { return findLastParentListNode(editor, list).getOr(list); }); return global$7.unique(listRoots); }; var isList = function (editor) { var list = getParentList(editor); return HTMLElement.isPrototypeOf(list); }; var Selection = { isList: isList, getParentList: getParentList, getSelectedSubLists: getSelectedSubLists, getSelectedListItems: getSelectedListItems, getClosestListRootElm: getClosestListRootElm, getSelectedDlItems: getSelectedDlItems, getSelectedListRoots: getSelectedListRoots }; var fromHtml = function (html, scope) { var doc = scope || domGlobals.document; var div = doc.createElement('div'); div.innerHTML = html; if (!div.hasChildNodes() || div.childNodes.length > 1) { domGlobals.console.error('HTML does not have a single root node', html); throw new Error('HTML must have a single root node'); } return fromDom(div.childNodes[0]); }; var fromTag = function (tag, scope) { var doc = scope || domGlobals.document; var node = doc.createElement(tag); return fromDom(node); }; var fromText = function (text, scope) { var doc = scope || domGlobals.document; var node = doc.createTextNode(text); return fromDom(node); }; var fromDom = function (node) { if (node === null || node === undefined) { throw new Error('Node cannot be null or undefined'); } return { dom: constant(node) }; }; var fromPoint = function (docElm, x, y) { var doc = docElm.dom(); return Option.from(doc.elementFromPoint(x, y)).map(fromDom); }; var Element = { fromHtml: fromHtml, fromTag: fromTag, fromText: fromText, fromDom: fromDom, fromPoint: fromPoint }; var liftN = function (arr, f) { var r = []; for (var i = 0; i < arr.length; i++) { var x = arr[i]; if (x.isSome()) { r.push(x.getOrDie()); } else { return Option.none(); } } return Option.some(f.apply(null, r)); }; var fromElements = function (elements, scope) { var doc = scope || domGlobals.document; var fragment = doc.createDocumentFragment(); each(elements, function (element) { fragment.appendChild(element.dom()); }); return Element.fromDom(fragment); }; var Immutable = function () { var fields = []; for (var _i = 0; _i < arguments.length; _i++) { fields[_i] = arguments[_i]; } return function () { var values = []; for (var _i = 0; _i < arguments.length; _i++) { values[_i] = arguments[_i]; } if (fields.length !== values.length) { throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments'); } var struct = {}; each(fields, function (name, i) { struct[name] = constant(values[i]); }); return struct; }; }; var keys = Object.keys; var each$1 = function (obj, f) { var props = keys(obj); for (var k = 0, len = props.length; k < len; k++) { var i = props[k]; var x = obj[i]; f(x, i, obj); } }; var node = function () { var f = Global$1.getOrDie('Node'); return f; }; var compareDocumentPosition = function (a, b, match) { return (a.compareDocumentPosition(b) & match) !== 0; }; var documentPositionPreceding = function (a, b) { return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_PRECEDING); }; var documentPositionContainedBy = function (a, b) { return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_CONTAINED_BY); }; var Node = { documentPositionPreceding: documentPositionPreceding, documentPositionContainedBy: documentPositionContainedBy }; var cached = function (f) { var called = false; var r; return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (!called) { called = true; r = f.apply(null, args); } return r; }; }; var firstMatch = function (regexes, s) { for (var i = 0; i < regexes.length; i++) { var x = regexes[i]; if (x.test(s)) return x; } return undefined; }; var find$1 = function (regexes, agent) { var r = firstMatch(regexes, agent); if (!r) return { major: 0, minor: 0 }; var group = function (i) { return Number(agent.replace(r, '$' + i)); }; return nu(group(1), group(2)); }; var detect = function (versionRegexes, agent) { var cleanedAgent = String(agent).toLowerCase(); if (versionRegexes.length === 0) return unknown(); return find$1(versionRegexes, cleanedAgent); }; var unknown = function () { return nu(0, 0); }; var nu = function (major, minor) { return { major: major, minor: minor }; }; var Version = { nu: nu, detect: detect, unknown: unknown }; var edge = 'Edge'; var chrome = 'Chrome'; var ie = 'IE'; var opera = 'Opera'; var firefox = 'Firefox'; var safari = 'Safari'; var isBrowser = function (name, current) { return function () { return current === name; }; }; var unknown$1 = function () { return nu$1({ current: undefined, version: Version.unknown() }); }; var nu$1 = function (info) { var current = info.current; var version = info.version; return { current: current, version: version, isEdge: isBrowser(edge, current), isChrome: isBrowser(chrome, current), isIE: isBrowser(ie, current), isOpera: isBrowser(opera, current), isFirefox: isBrowser(firefox, current), isSafari: isBrowser(safari, current) }; }; var Browser = { unknown: unknown$1, nu: nu$1, edge: constant(edge), chrome: constant(chrome), ie: constant(ie), opera: constant(opera), firefox: constant(firefox), safari: constant(safari) }; var windows = 'Windows'; var ios = 'iOS'; var android = 'Android'; var linux = 'Linux'; var osx = 'OSX'; var solaris = 'Solaris'; var freebsd = 'FreeBSD'; var isOS = function (name, current) { return function () { return current === name; }; }; var unknown$2 = function () { return nu$2({ current: undefined, version: Version.unknown() }); }; var nu$2 = function (info) { var current = info.current; var version = info.version; return { current: current, version: version, isWindows: isOS(windows, current), isiOS: isOS(ios, current), isAndroid: isOS(android, current), isOSX: isOS(osx, current), isLinux: isOS(linux, current), isSolaris: isOS(solaris, current), isFreeBSD: isOS(freebsd, current) }; }; var OperatingSystem = { unknown: unknown$2, nu: nu$2, windows: constant(windows), ios: constant(ios), android: constant(android), linux: constant(linux), osx: constant(osx), solaris: constant(solaris), freebsd: constant(freebsd) }; var DeviceType = function (os, browser, userAgent) { var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true; var isiPhone = os.isiOS() && !isiPad; var isAndroid3 = os.isAndroid() && os.version.major === 3; var isAndroid4 = os.isAndroid() && os.version.major === 4; var isTablet = isiPad || isAndroid3 || isAndroid4 && /mobile/i.test(userAgent) === true; var isTouch = os.isiOS() || os.isAndroid(); var isPhone = isTouch && !isTablet; var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false; return { isiPad: constant(isiPad), isiPhone: constant(isiPhone), isTablet: constant(isTablet), isPhone: constant(isPhone), isTouch: constant(isTouch), isAndroid: os.isAndroid, isiOS: os.isiOS, isWebView: constant(iOSwebview) }; }; var detect$1 = function (candidates, userAgent) { var agent = String(userAgent).toLowerCase(); return find(candidates, function (candidate) { return candidate.search(agent); }); }; var detectBrowser = function (browsers, userAgent) { return detect$1(browsers, userAgent).map(function (browser) { var version = Version.detect(browser.versionRegexes, userAgent); return { current: browser.name, version: version }; }); }; var detectOs = function (oses, userAgent) { return detect$1(oses, userAgent).map(function (os) { var version = Version.detect(os.versionRegexes, userAgent); return { current: os.name, version: version }; }); }; var UaString = { detectBrowser: detectBrowser, detectOs: detectOs }; var contains = function (str, substr) { return str.indexOf(substr) !== -1; }; var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/; var checkContains = function (target) { return function (uastring) { return contains(uastring, target); }; }; var browsers = [ { name: 'Edge', versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/], search: function (uastring) { var monstrosity = contains(uastring, 'edge/') && contains(uastring, 'chrome') && contains(uastring, 'safari') && contains(uastring, 'applewebkit'); return monstrosity; } }, { name: 'Chrome', versionRegexes: [ /.*?chrome\/([0-9]+)\.([0-9]+).*/, normalVersionRegex ], search: function (uastring) { return contains(uastring, 'chrome') && !contains(uastring, 'chromeframe'); } }, { name: 'IE', versionRegexes: [ /.*?msie\ ?([0-9]+)\.([0-9]+).*/, /.*?rv:([0-9]+)\.([0-9]+).*/ ], search: function (uastring) { return contains(uastring, 'msie') || contains(uastring, 'trident'); } }, { name: 'Opera', versionRegexes: [ normalVersionRegex, /.*?opera\/([0-9]+)\.([0-9]+).*/ ], search: checkContains('opera') }, { name: 'Firefox', versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/], search: checkContains('firefox') }, { name: 'Safari', versionRegexes: [ normalVersionRegex, /.*?cpu os ([0-9]+)_([0-9]+).*/ ], search: function (uastring) { return (contains(uastring, 'safari') || contains(uastring, 'mobile/')) && contains(uastring, 'applewebkit'); } } ]; var oses = [ { name: 'Windows', search: checkContains('win'), versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/] }, { name: 'iOS', search: function (uastring) { return contains(uastring, 'iphone') || contains(uastring, 'ipad'); }, versionRegexes: [ /.*?version\/\ ?([0-9]+)\.([0-9]+).*/, /.*cpu os ([0-9]+)_([0-9]+).*/, /.*cpu iphone os ([0-9]+)_([0-9]+).*/ ] }, { name: 'Android', search: checkContains('android'), versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/] }, { name: 'OSX', search: checkContains('os x'), versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/] }, { name: 'Linux', search: checkContains('linux'), versionRegexes: [] }, { name: 'Solaris', search: checkContains('sunos'), versionRegexes: [] }, { name: 'FreeBSD', search: checkContains('freebsd'), versionRegexes: [] } ]; var PlatformInfo = { browsers: constant(browsers), oses: constant(oses) }; var detect$2 = function (userAgent) { var browsers = PlatformInfo.browsers(); var oses = PlatformInfo.oses(); var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu); var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu); var deviceType = DeviceType(os, browser, userAgent); return { browser: browser, os: os, deviceType: deviceType }; }; var PlatformDetection = { detect: detect$2 }; var detect$3 = cached(function () { var userAgent = domGlobals.navigator.userAgent; return PlatformDetection.detect(userAgent); }); var PlatformDetection$1 = { detect: detect$3 }; var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE; var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE; var COMMENT = domGlobals.Node.COMMENT_NODE; var DOCUMENT = domGlobals.Node.DOCUMENT_NODE; var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE; var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE; var ELEMENT = domGlobals.Node.ELEMENT_NODE; var TEXT = domGlobals.Node.TEXT_NODE; var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE; var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE; var ENTITY = domGlobals.Node.ENTITY_NODE; var NOTATION = domGlobals.Node.NOTATION_NODE; var ELEMENT$1 = ELEMENT; var is = function (element, selector) { var elem = element.dom(); if (elem.nodeType !== ELEMENT$1) { return false; } else if (elem.matches !== undefined) { return elem.matches(selector); } else if (elem.msMatchesSelector !== undefined) { return elem.msMatchesSelector(selector); } else if (elem.webkitMatchesSelector !== undefined) { return elem.webkitMatchesSelector(selector); } else if (elem.mozMatchesSelector !== undefined) { return elem.mozMatchesSelector(selector); } else { throw new Error('Browser lacks native selectors'); } }; var eq = function (e1, e2) { return e1.dom() === e2.dom(); }; var regularContains = function (e1, e2) { var d1 = e1.dom(); var d2 = e2.dom(); return d1 === d2 ? false : d1.contains(d2); }; var ieContains = function (e1, e2) { return Node.documentPositionContainedBy(e1.dom(), e2.dom()); }; var browser = PlatformDetection$1.detect().browser; var contains$1 = browser.isIE() ? ieContains : regularContains; var is$1 = is; var parent = function (element) { var dom = element.dom(); return Option.from(dom.parentNode).map(Element.fromDom); }; var children = function (element) { var dom = element.dom(); return map(dom.childNodes, Element.fromDom); }; var child = function (element, index) { var cs = element.dom().childNodes; return Option.from(cs[index]).map(Element.fromDom); }; var firstChild = function (element) { return child(element, 0); }; var lastChild = function (element) { return child(element, element.dom().childNodes.length - 1); }; var spot = Immutable('element', 'offset'); var before = function (marker, element) { var parent$1 = parent(marker); parent$1.each(function (v) { v.dom().insertBefore(element.dom(), marker.dom()); }); }; var append = function (parent, element) { parent.dom().appendChild(element.dom()); }; var before$1 = function (marker, elements) { each(elements, function (x) { before(marker, x); }); }; var append$1 = function (parent, elements) { each(elements, function (x) { append(parent, x); }); }; var remove = function (element) { var dom = element.dom(); if (dom.parentNode !== null) { dom.parentNode.removeChild(dom); } }; var name = function (element) { var r = element.dom().nodeName; return r.toLowerCase(); }; var rawSet = function (dom, key, value) { if (isString(value) || isBoolean(value) || isNumber(value)) { dom.setAttribute(key, value + ''); } else { domGlobals.console.error('Invalid call to Attr.set. Key ', key, ':: Value ', value, ':: Element ', dom); throw new Error('Attribute value was not simple'); } }; var setAll = function (element, attrs) { var dom = element.dom(); each$1(attrs, function (v, k) { rawSet(dom, k, v); }); }; var clone = function (element) { return foldl(element.dom().attributes, function (acc, attr) { acc[attr.name] = attr.value; return acc; }, {}); }; var isSupported = function (dom) { return dom.style !== undefined; }; var internalSet = function (dom, property, value) { if (!isString(value)) { domGlobals.console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom); throw new Error('CSS value must be a string: ' + value); } if (isSupported(dom)) { dom.style.setProperty(property, value); } }; var set = function (element, property, value) { var dom = element.dom(); internalSet(dom, property, value); }; var clone$1 = function (original, isDeep) { return Element.fromDom(original.dom().cloneNode(isDeep)); }; var deep = function (original) { return clone$1(original, true); }; var shallowAs = function (original, tag) { var nu = Element.fromTag(tag); var attributes = clone(original); setAll(nu, attributes); return nu; }; var mutate = function (original, tag) { var nu = shallowAs(original, tag); before(original, nu); var children$1 = children(original); append$1(nu, children$1); remove(original); return nu; }; var joinSegment = function (parent, child) { append(parent.item, child.list); }; var joinSegments = function (segments) { for (var i = 1; i < segments.length; i++) { joinSegment(segments[i - 1], segments[i]); } }; var appendSegments = function (head$1, tail) { liftN([ last(head$1), head(tail) ], joinSegment); }; var createSegment = function (scope, listType) { var segment = { list: Element.fromTag(listType, scope), item: Element.fromTag('li', scope) }; append(segment.list, segment.item); return segment; }; var createSegments = function (scope, entry, size) { var segments = []; for (var i = 0; i < size; i++) { segments.push(createSegment(scope, entry.listType)); } return segments; }; var populateSegments = function (segments, entry) { for (var i = 0; i < segments.length - 1; i++) { set(segments[i].item, 'list-style-type', 'none'); } last(segments).each(function (segment) { setAll(segment.list, entry.listAttributes); setAll(segment.item, entry.itemAttributes); append$1(segment.item, entry.content); }); }; var normalizeSegment = function (segment, entry) { if (name(segment.list) !== entry.listType) { segment.list = mutate(segment.list, entry.listType); } setAll(segment.list, entry.listAttributes); }; var createItem = function (scope, attr, content) { var item = Element.fromTag('li', scope); setAll(item, attr); append$1(item, content); return item; }; var appendItem = function (segment, item) { append(segment.list, item); segment.item = item; }; var writeShallow = function (scope, cast, entry) { var newCast = cast.slice(0, entry.depth); last(newCast).each(function (segment) { var item = createItem(scope, entry.itemAttributes, entry.content); appendItem(segment, item); normalizeSegment(segment, entry); }); return newCast; }; var writeDeep = function (scope, cast, entry) { var segments = createSegments(scope, entry, entry.depth - cast.length); joinSegments(segments); populateSegments(segments, entry); appendSegments(cast, segments); return cast.concat(segments); }; var composeList = function (scope, entries) { var cast = foldl(entries, function (cast, entry) { return entry.depth > cast.length ? writeDeep(scope, cast, entry) : writeShallow(scope, cast, entry); }, []); return head(cast).map(function (segment) { return segment.list; }); }; var isList$1 = function (el) { return is$1(el, 'OL,UL'); }; var hasFirstChildList = function (el) { return firstChild(el).map(isList$1).getOr(false); }; var hasLastChildList = function (el) { return lastChild(el).map(isList$1).getOr(false); }; var isIndented = function (entry) { return entry.depth > 0; }; var isSelected = function (entry) { return entry.isSelected; }; var cloneItemContent = function (li) { var children$1 = children(li); var content = hasLastChildList(li) ? children$1.slice(0, -1) : children$1; return map(content, deep); }; var createEntry = function (li, depth, isSelected) { return parent(li).map(function (list) { return { depth: depth, isSelected: isSelected, content: cloneItemContent(li), itemAttributes: clone(li), listAttributes: clone(list), listType: name(list) }; }); }; var indentEntry = function (indentation, entry) { switch (indentation) { case 'Indent': entry.depth++; break; case 'Outdent': entry.depth--; break; case 'Flatten': entry.depth = 0; } }; var hasOwnProperty = Object.prototype.hasOwnProperty; var shallow = function (old, nu) { return nu; }; var baseMerge = function (merger) { return function () { var objects = new Array(arguments.length); for (var i = 0; i < objects.length; i++) objects[i] = arguments[i]; if (objects.length === 0) throw new Error('Can\'t merge zero objects'); var ret = {}; for (var j = 0; j < objects.length; j++) { var curObject = objects[j]; for (var key in curObject) if (hasOwnProperty.call(curObject, key)) { ret[key] = merger(ret[key], curObject[key]); } } return ret; }; }; var merge = baseMerge(shallow); var cloneListProperties = function (target, source) { target.listType = source.listType; target.listAttributes = merge({}, source.listAttributes); }; var previousSiblingEntry = function (entries, start) { var depth = entries[start].depth; for (var i = start - 1; i >= 0; i--) { if (entries[i].depth === depth) { return Option.some(entries[i]); } if (entries[i].depth < depth) { break; } } return Option.none(); }; var normalizeEntries = function (entries) { each(entries, function (entry, i) { previousSiblingEntry(entries, i).each(function (matchingEntry) { cloneListProperties(entry, matchingEntry); }); }); }; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var parseItem = function (depth, itemSelection, selectionState, item) { return firstChild(item).filter(isList$1).fold(function () { itemSelection.each(function (selection) { if (eq(selection.start, item)) { selectionState.set(true); } }); var currentItemEntry = createEntry(item, depth, selectionState.get()); itemSelection.each(function (selection) { if (eq(selection.end, item)) { selectionState.set(false); } }); var childListEntries = lastChild(item).filter(isList$1).map(function (list) { return parseList(depth, itemSelection, selectionState, list); }).getOr([]); return currentItemEntry.toArray().concat(childListEntries); }, function (list) { return parseList(depth, itemSelection, selectionState, list); }); }; var parseList = function (depth, itemSelection, selectionState, list) { return bind(children(list), function (element) { var parser = isList$1(element) ? parseList : parseItem; var newDepth = depth + 1; return parser(newDepth, itemSelection, selectionState, element); }); }; var parseLists = function (lists, itemSelection) { var selectionState = Cell(false); var initialDepth = 0; return map(lists, function (list) { return { sourceList: list, entries: parseList(initialDepth, itemSelection, selectionState, list) }; }); }; var global$8 = tinymce.util.Tools.resolve('tinymce.Env'); var createTextBlock = function (editor, contentNode) { var dom = editor.dom; var blockElements = editor.schema.getBlockElements(); var fragment = dom.createFragment(); var node, textBlock, blockName, hasContentNode; if (editor.settings.forced_root_block) { blockName = editor.settings.forced_root_block; } if (blockName) { textBlock = dom.create(blockName); if (textBlock.tagName === editor.settings.forced_root_block) { dom.setAttribs(textBlock, editor.settings.forced_root_block_attrs); } if (!NodeType.isBlock(contentNode.firstChild, blockElements)) { fragment.appendChild(textBlock); } } if (contentNode) { while (node = contentNode.firstChild) { var nodeName = node.nodeName; if (!hasContentNode && (nodeName !== 'SPAN' || node.getAttribute('data-mce-type') !== 'bookmark')) { hasContentNode = true; } if (NodeType.isBlock(node, blockElements)) { fragment.appendChild(node); textBlock = null; } else { if (blockName) { if (!textBlock) { textBlock = dom.create(blockName); fragment.appendChild(textBlock); } textBlock.appendChild(node); } else { fragment.appendChild(node); } } } } if (!editor.settings.forced_root_block) { fragment.appendChild(dom.create('br')); } else { if (!hasContentNode && (!global$8.ie || global$8.ie > 10)) { textBlock.appendChild(dom.create('br', { 'data-mce-bogus': '1' })); } } return fragment; }; var outdentedComposer = function (editor, entries) { return map(entries, function (entry) { var content = fromElements(entry.content); return Element.fromDom(createTextBlock(editor, content.dom())); }); }; var indentedComposer = function (editor, entries) { normalizeEntries(entries); return composeList(editor.contentDocument, entries).toArray(); }; var composeEntries = function (editor, entries) { return bind(groupBy(entries, isIndented), function (entries) { var groupIsIndented = head(entries).map(isIndented).getOr(false); return groupIsIndented ? indentedComposer(editor, entries) : outdentedComposer(editor, entries); }); }; var indentSelectedEntries = function (entries, indentation) { each(filter(entries, isSelected), function (entry) { return indentEntry(indentation, entry); }); }; var getItemSelection = function (editor) { var selectedListItems = map(Selection.getSelectedListItems(editor), Element.fromDom); return liftN([ find(selectedListItems, not(hasFirstChildList)), find(reverse(selectedListItems), not(hasFirstChildList)) ], function (start, end) { return { start: start, end: end }; }); }; var listsIndentation = function (editor, lists, indentation) { var entrySets = parseLists(lists, getItemSelection(editor)); each(entrySets, function (entrySet) { indentSelectedEntries(entrySet.entries, indentation); before$1(entrySet.sourceList, composeEntries(editor, entrySet.entries)); remove(entrySet.sourceList); }); }; var DOM$1 = global$6.DOM; var splitList = function (editor, ul, li) { var tmpRng, fragment, bookmarks, node, newBlock; var removeAndKeepBookmarks = function (targetNode) { global$5.each(bookmarks, function (node) { targetNode.parentNode.insertBefore(node, li.parentNode); }); DOM$1.remove(targetNode); }; bookmarks = DOM$1.select('span[data-mce-type="bookmark"]', ul); newBlock = createTextBlock(editor, li); tmpRng = DOM$1.createRng(); tmpRng.setStartAfter(li); tmpRng.setEndAfter(ul); fragment = tmpRng.extractContents(); for (node = fragment.firstChild; node; node = node.firstChild) { if (node.nodeName === 'LI' && editor.dom.isEmpty(node)) { DOM$1.remove(node); break; } } if (!editor.dom.isEmpty(fragment)) { DOM$1.insertAfter(fragment, ul); } DOM$1.insertAfter(newBlock, ul); if (NodeType.isEmpty(editor.dom, li.parentNode)) { removeAndKeepBookmarks(li.parentNode); } DOM$1.remove(li); if (NodeType.isEmpty(editor.dom, ul)) { DOM$1.remove(ul); } }; var SplitList = { splitList: splitList }; var outdentDlItem = function (editor, item) { if (is$1(item, 'DD')) { mutate(item, 'DT'); } else if (is$1(item, 'DT')) { parent(item).each(function (dl) { return SplitList.splitList(editor, dl.dom(), item.dom()); }); } }; var indentDlItem = function (item) { if (is$1(item, 'DT')) { mutate(item, 'DD'); } }; var dlIndentation = function (editor, indentation, dlItems) { if (indentation === 'Indent') { each(dlItems, indentDlItem); } else { each(dlItems, function (item) { return outdentDlItem(editor, item); }); } }; var selectionIndentation = function (editor, indentation) { var lists = map(Selection.getSelectedListRoots(editor), Element.fromDom); var dlItems = map(Selection.getSelectedDlItems(editor), Element.fromDom); var isHandled = false; if (lists.length || dlItems.length) { var bookmark = editor.selection.getBookmark(); listsIndentation(editor, lists, indentation); dlIndentation(editor, indentation, dlItems); editor.selection.moveToBookmark(bookmark); editor.selection.setRng(Range.normalizeRange(editor.selection.getRng())); editor.nodeChanged(); isHandled = true; } return isHandled; }; var indentListSelection = function (editor) { return selectionIndentation(editor, 'Indent'); }; var outdentListSelection = function (editor) { return selectionIndentation(editor, 'Outdent'); }; var flattenListSelection = function (editor) { return selectionIndentation(editor, 'Flatten'); }; var updateListStyle = function (dom, el, detail) { var type = detail['list-style-type'] ? detail['list-style-type'] : null; dom.setStyle(el, 'list-style-type', type); }; var setAttribs = function (elm, attrs) { global$5.each(attrs, function (value, key) { elm.setAttribute(key, value); }); }; var updateListAttrs = function (dom, el, detail) { setAttribs(el, detail['list-attributes']); global$5.each(dom.select('li', el), function (li) { setAttribs(li, detail['list-item-attributes']); }); }; var updateListWithDetails = function (dom, el, detail) { updateListStyle(dom, el, detail); updateListAttrs(dom, el, detail); }; var removeStyles = function (dom, element, styles) { global$5.each(styles, function (style) { var _a; return dom.setStyle(element, (_a = {}, _a[style] = '', _a)); }); }; var getEndPointNode = function (editor, rng, start, root) { var container, offset; container = rng[start ? 'startContainer' : 'endContainer']; offset = rng[start ? 'startOffset' : 'endOffset']; if (container.nodeType === 1) { container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container; } if (!start && NodeType.isBr(container.nextSibling)) { container = container.nextSibling; } while (container.parentNode !== root) { if (NodeType.isTextBlock(editor, container)) { return container; } if (/^(TD|TH)$/.test(container.parentNode.nodeName)) { return container; } container = container.parentNode; } return container; }; var getSelectedTextBlocks = function (editor, rng, root) { var textBlocks = [], dom = editor.dom; var startNode = getEndPointNode(editor, rng, true, root); var endNode = getEndPointNode(editor, rng, false, root); var block; var siblings = []; for (var node = startNode; node; node = node.nextSibling) { siblings.push(node); if (node === endNode) { break; } } global$5.each(siblings, function (node) { if (NodeType.isTextBlock(editor, node)) { textBlocks.push(node); block = null; return; } if (dom.isBlock(node) || NodeType.isBr(node)) { if (NodeType.isBr(node)) { dom.remove(node); } block = null; return; } var nextSibling = node.nextSibling; if (global$4.isBookmarkNode(node)) { if (NodeType.isTextBlock(editor, nextSibling) || !nextSibling && node.parentNode === root) { block = null; return; } } if (!block) { block = dom.create('p'); node.parentNode.insertBefore(block, node); textBlocks.push(block); } block.appendChild(node); }); return textBlocks; }; var hasCompatibleStyle = function (dom, sib, detail) { var sibStyle = dom.getStyle(sib, 'list-style-type'); var detailStyle = detail ? detail['list-style-type'] : ''; detailStyle = detailStyle === null ? '' : detailStyle; return sibStyle === detailStyle; }; var applyList = function (editor, listName, detail) { if (detail === void 0) { detail = {}; } var rng = editor.selection.getRng(true); var bookmark; var listItemName = 'LI'; var root = Selection.getClosestListRootElm(editor, editor.selection.getStart(true)); var dom = editor.dom; if (dom.getContentEditable(editor.selection.getNode()) === 'false') { return; } listName = listName.toUpperCase(); if (listName === 'DL') { listItemName = 'DT'; } bookmark = Bookmark.createBookmark(rng); global$5.each(getSelectedTextBlocks(editor, rng, root), function (block) { var listBlock, sibling; sibling = block.previousSibling; if (sibling && NodeType.isListNode(sibling) && sibling.nodeName === listName && hasCompatibleStyle(dom, sibling, detail)) { listBlock = sibling; block = dom.rename(block, listItemName); sibling.appendChild(block); } else { listBlock = dom.create(listName); block.parentNode.insertBefore(listBlock, block); listBlock.appendChild(block); block = dom.rename(block, listItemName); } removeStyles(dom, block, [ 'margin', 'margin-right', 'margin-bottom', 'margin-left', 'margin-top', 'padding', 'padding-right', 'padding-bottom', 'padding-left', 'padding-top' ]); updateListWithDetails(dom, listBlock, detail); mergeWithAdjacentLists(editor.dom, listBlock); }); editor.selection.setRng(Bookmark.resolveBookmark(bookmark)); }; var isValidLists = function (list1, list2) { return list1 && list2 && NodeType.isListNode(list1) && list1.nodeName === list2.nodeName; }; var hasSameListStyle = function (dom, list1, list2) { var targetStyle = dom.getStyle(list1, 'list-style-type', true); var style = dom.getStyle(list2, 'list-style-type', true); return targetStyle === style; }; var hasSameClasses = function (elm1, elm2) { return elm1.className === elm2.className; }; var shouldMerge = function (dom, list1, list2) { return isValidLists(list1, list2) && hasSameListStyle(dom, list1, list2) && hasSameClasses(list1, list2); }; var mergeWithAdjacentLists = function (dom, listBlock) { var sibling, node; sibling = listBlock.nextSibling; if (shouldMerge(dom, listBlock, sibling)) { while (node = sibling.firstChild) { listBlock.appendChild(node); } dom.remove(sibling); } sibling = listBlock.previousSibling; if (shouldMerge(dom, listBlock, sibling)) { while (node = sibling.lastChild) { listBlock.insertBefore(node, listBlock.firstChild); } dom.remove(sibling); } }; var updateList = function (dom, list, listName, detail) { if (list.nodeName !== listName) { var newList = dom.rename(list, listName); updateListWithDetails(dom, newList, detail); } else { updateListWithDetails(dom, list, detail); } }; var toggleMultipleLists = function (editor, parentList, lists, listName, detail) { if (parentList.nodeName === listName && !hasListStyleDetail(detail)) { flattenListSelection(editor); } else { var bookmark = Bookmark.createBookmark(editor.selection.getRng(true)); global$5.each([parentList].concat(lists), function (elm) { updateList(editor.dom, elm, listName, detail); }); editor.selection.setRng(Bookmark.resolveBookmark(bookmark)); } }; var hasListStyleDetail = function (detail) { return 'list-style-type' in detail; }; var toggleSingleList = function (editor, parentList, listName, detail) { if (parentList === editor.getBody()) { return; } if (parentList) { if (parentList.nodeName === listName && !hasListStyleDetail(detail)) { flattenListSelection(editor); } else { var bookmark = Bookmark.createBookmark(editor.selection.getRng(true)); updateListWithDetails(editor.dom, parentList, detail); mergeWithAdjacentLists(editor.dom, editor.dom.rename(parentList, listName)); editor.selection.setRng(Bookmark.resolveBookmark(bookmark)); } } else { applyList(editor, listName, detail); } }; var toggleList = function (editor, listName, detail) { var parentList = Selection.getParentList(editor); var selectedSubLists = Selection.getSelectedSubLists(editor); detail = detail ? detail : {}; if (parentList && selectedSubLists.length > 0) { toggleMultipleLists(editor, parentList, selectedSubLists, listName, detail); } else { toggleSingleList(editor, parentList, listName, detail); } }; var ToggleList = { toggleList: toggleList, mergeWithAdjacentLists: mergeWithAdjacentLists }; var DOM$2 = global$6.DOM; var normalizeList = function (dom, ul) { var sibling; var parentNode = ul.parentNode; if (parentNode.nodeName === 'LI' && parentNode.firstChild === ul) { sibling = parentNode.previousSibling; if (sibling && sibling.nodeName === 'LI') { sibling.appendChild(ul); if (NodeType.isEmpty(dom, parentNode)) { DOM$2.remove(parentNode); } } else { DOM$2.setStyle(parentNode, 'listStyleType', 'none'); } } if (NodeType.isListNode(parentNode)) { sibling = parentNode.previousSibling; if (sibling && sibling.nodeName === 'LI') { sibling.appendChild(ul); } } }; var normalizeLists = function (dom, element) { global$5.each(global$5.grep(dom.select('ol,ul', element)), function (ul) { normalizeList(dom, ul); }); }; var NormalizeLists = { normalizeList: normalizeList, normalizeLists: normalizeLists }; var findNextCaretContainer = function (editor, rng, isForward, root) { var node = rng.startContainer; var offset = rng.startOffset; var nonEmptyBlocks, walker; if (node.nodeType === 3 && (isForward ? offset < node.data.length : offset > 0)) { return node; } nonEmptyBlocks = editor.schema.getNonEmptyElements(); if (node.nodeType === 1) { node = global$1.getNode(node, offset); } walker = new global$2(node, root); if (isForward) { if (NodeType.isBogusBr(editor.dom, node)) { walker.next(); } } while (node = walker[isForward ? 'next' : 'prev2']()) { if (node.nodeName === 'LI' && !node.hasChildNodes()) { return node; } if (nonEmptyBlocks[node.nodeName]) { return node; } if (node.nodeType === 3 && node.data.length > 0) { return node; } } }; var hasOnlyOneBlockChild = function (dom, elm) { var childNodes = elm.childNodes; return childNodes.length === 1 && !NodeType.isListNode(childNodes[0]) && dom.isBlock(childNodes[0]); }; var unwrapSingleBlockChild = function (dom, elm) { if (hasOnlyOneBlockChild(dom, elm)) { dom.remove(elm.firstChild, true); } }; var moveChildren = function (dom, fromElm, toElm) { var node, targetElm; targetElm = hasOnlyOneBlockChild(dom, toElm) ? toElm.firstChild : toElm; unwrapSingleBlockChild(dom, fromElm); if (!NodeType.isEmpty(dom, fromElm, true)) { while (node = fromElm.firstChild) { targetElm.appendChild(node); } } }; var mergeLiElements = function (dom, fromElm, toElm) { var node, listNode; var ul = fromElm.parentNode; if (!NodeType.isChildOfBody(dom, fromElm) || !NodeType.isChildOfBody(dom, toElm)) { return; } if (NodeType.isListNode(toElm.lastChild)) { listNode = toElm.lastChild; } if (ul === toElm.lastChild) { if (NodeType.isBr(ul.previousSibling)) { dom.remove(ul.previousSibling); } } node = toElm.lastChild; if (node && NodeType.isBr(node) && fromElm.hasChildNodes()) { dom.remove(node); } if (NodeType.isEmpty(dom, toElm, true)) { dom.$(toElm).empty(); } moveChildren(dom, fromElm, toElm); if (listNode) { toElm.appendChild(listNode); } var contains = contains$1(Element.fromDom(toElm), Element.fromDom(fromElm)); var nestedLists = contains ? dom.getParents(fromElm, NodeType.isListNode, toElm) : []; dom.remove(fromElm); each(nestedLists, function (list) { if (NodeType.isEmpty(dom, list) && list !== dom.getRoot()) { dom.remove(list); } }); }; var mergeIntoEmptyLi = function (editor, fromLi, toLi) { editor.dom.$(toLi).empty(); mergeLiElements(editor.dom, fromLi, toLi); editor.selection.setCursorLocation(toLi); }; var mergeForward = function (editor, rng, fromLi, toLi) { var dom = editor.dom; if (dom.isEmpty(toLi)) { mergeIntoEmptyLi(editor, fromLi, toLi); } else { var bookmark = Bookmark.createBookmark(rng); mergeLiElements(dom, fromLi, toLi); editor.selection.setRng(Bookmark.resolveBookmark(bookmark)); } }; var mergeBackward = function (editor, rng, fromLi, toLi) { var bookmark = Bookmark.createBookmark(rng); mergeLiElements(editor.dom, fromLi, toLi); var resolvedBookmark = Bookmark.resolveBookmark(bookmark); editor.selection.setRng(resolvedBookmark); }; var backspaceDeleteFromListToListCaret = function (editor, isForward) { var dom = editor.dom, selection = editor.selection; var selectionStartElm = selection.getStart(); var root = Selection.getClosestListRootElm(editor, selectionStartElm); var li = dom.getParent(selection.getStart(), 'LI', root); var ul, rng, otherLi; if (li) { ul = li.parentNode; if (ul === editor.getBody() && NodeType.isEmpty(dom, ul)) { return true; } rng = Range.normalizeRange(selection.getRng(true)); otherLi = dom.getParent(findNextCaretContainer(editor, rng, isForward, root), 'LI', root); if (otherLi && otherLi !== li) { if (isForward) { mergeForward(editor, rng, otherLi, li); } else { mergeBackward(editor, rng, li, otherLi); } return true; } else if (!otherLi) { if (!isForward) { flattenListSelection(editor); return true; } } } return false; }; var removeBlock = function (dom, block, root) { var parentBlock = dom.getParent(block.parentNode, dom.isBlock, root); dom.remove(block); if (parentBlock && dom.isEmpty(parentBlock)) { dom.remove(parentBlock); } }; var backspaceDeleteIntoListCaret = function (editor, isForward) { var dom = editor.dom; var selectionStartElm = editor.selection.getStart(); var root = Selection.getClosestListRootElm(editor, selectionStartElm); var block = dom.getParent(selectionStartElm, dom.isBlock, root); if (block && dom.isEmpty(block)) { var rng = Range.normalizeRange(editor.selection.getRng(true)); var otherLi_1 = dom.getParent(findNextCaretContainer(editor, rng, isForward, root), 'LI', root); if (otherLi_1) { editor.undoManager.transact(function () { removeBlock(dom, block, root); ToggleList.mergeWithAdjacentLists(dom, otherLi_1.parentNode); editor.selection.select(otherLi_1, true); editor.selection.collapse(isForward); }); return true; } } return false; }; var backspaceDeleteCaret = function (editor, isForward) { return backspaceDeleteFromListToListCaret(editor, isForward) || backspaceDeleteIntoListCaret(editor, isForward); }; var backspaceDeleteRange = function (editor) { var selectionStartElm = editor.selection.getStart(); var root = Selection.getClosestListRootElm(editor, selectionStartElm); var startListParent = editor.dom.getParent(selectionStartElm, 'LI,DT,DD', root); if (startListParent || Selection.getSelectedListItems(editor).length > 0) { editor.undoManager.transact(function () { editor.execCommand('Delete'); NormalizeLists.normalizeLists(editor.dom, editor.getBody()); }); return true; } return false; }; var backspaceDelete = function (editor, isForward) { return editor.selection.isCollapsed() ? backspaceDeleteCaret(editor, isForward) : backspaceDeleteRange(editor); }; var setup = function (editor) { editor.on('keydown', function (e) { if (e.keyCode === global$3.BACKSPACE) { if (backspaceDelete(editor, false)) { e.preventDefault(); } } else if (e.keyCode === global$3.DELETE) { if (backspaceDelete(editor, true)) { e.preventDefault(); } } }); }; var Delete = { setup: setup, backspaceDelete: backspaceDelete }; var get = function (editor) { return { backspaceDelete: function (isForward) { Delete.backspaceDelete(editor, isForward); } }; }; var Api = { get: get }; var queryListCommandState = function (editor, listName) { return function () { var parentList = editor.dom.getParent(editor.selection.getStart(), 'UL,OL,DL'); return parentList && parentList.nodeName === listName; }; }; var register = function (editor) { editor.on('BeforeExecCommand', function (e) { var cmd = e.command.toLowerCase(); if (cmd === 'indent') { indentListSelection(editor); } else if (cmd === 'outdent') { outdentListSelection(editor); } }); editor.addCommand('InsertUnorderedList', function (ui, detail) { ToggleList.toggleList(editor, 'UL', detail); }); editor.addCommand('InsertOrderedList', function (ui, detail) { ToggleList.toggleList(editor, 'OL', detail); }); editor.addCommand('InsertDefinitionList', function (ui, detail) { ToggleList.toggleList(editor, 'DL', detail); }); editor.addCommand('RemoveList', function () { flattenListSelection(editor); }); editor.addQueryStateHandler('InsertUnorderedList', queryListCommandState(editor, 'UL')); editor.addQueryStateHandler('InsertOrderedList', queryListCommandState(editor, 'OL')); editor.addQueryStateHandler('InsertDefinitionList', queryListCommandState(editor, 'DL')); }; var Commands = { register: register }; var shouldIndentOnTab = function (editor) { return editor.getParam('lists_indent_on_tab', true); }; var Settings = { shouldIndentOnTab: shouldIndentOnTab }; var setupTabKey = function (editor) { editor.on('keydown', function (e) { if (e.keyCode !== global$3.TAB || global$3.metaKeyPressed(e)) { return; } editor.undoManager.transact(function () { if (e.shiftKey ? outdentListSelection(editor) : indentListSelection(editor)) { e.preventDefault(); } }); }); }; var setup$1 = function (editor) { if (Settings.shouldIndentOnTab(editor)) { setupTabKey(editor); } Delete.setup(editor); }; var Keyboard = { setup: setup$1 }; var findIndex = function (list, predicate) { for (var index = 0; index < list.length; index++) { var element = list[index]; if (predicate(element)) { return index; } } return -1; }; var listState = function (editor, listName) { return function (e) { var ctrl = e.control; editor.on('NodeChange', function (e) { var tableCellIndex = findIndex(e.parents, NodeType.isTableCellNode); var parents = tableCellIndex !== -1 ? e.parents.slice(0, tableCellIndex) : e.parents; var lists = global$5.grep(parents, NodeType.isListNode); ctrl.active(lists.length > 0 && lists[0].nodeName === listName); }); }; }; var register$1 = function (editor) { var hasPlugin = function (editor, plugin) { var plugins = editor.settings.plugins ? editor.settings.plugins : ''; return global$5.inArray(plugins.split(/[ ,]/), plugin) !== -1; }; if (!hasPlugin(editor, 'advlist')) { editor.addButton('numlist', { active: false, title: 'Numbered list', cmd: 'InsertOrderedList', onPostRender: listState(editor, 'OL') }); editor.addButton('bullist', { active: false, title: 'Bullet list', cmd: 'InsertUnorderedList', onPostRender: listState(editor, 'UL') }); } editor.addButton('indent', { icon: 'indent', title: 'Increase indent', cmd: 'Indent' }); }; var Buttons = { register: register$1 }; global.add('lists', function (editor) { Keyboard.setup(editor); Buttons.register(editor); Commands.register(editor); return Api.get(editor); }); function Plugin () { } return Plugin; }(window)); })(); (function () { var media = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.Env'); var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var getScripts = function (editor) { return editor.getParam('media_scripts'); }; var getAudioTemplateCallback = function (editor) { return editor.getParam('audio_template_callback'); }; var getVideoTemplateCallback = function (editor) { return editor.getParam('video_template_callback'); }; var hasLiveEmbeds = function (editor) { return editor.getParam('media_live_embeds', true); }; var shouldFilterHtml = function (editor) { return editor.getParam('media_filter_html', true); }; var getUrlResolver = function (editor) { return editor.getParam('media_url_resolver'); }; var hasAltSource = function (editor) { return editor.getParam('media_alt_source', true); }; var hasPoster = function (editor) { return editor.getParam('media_poster', true); }; var hasDimensions = function (editor) { return editor.getParam('media_dimensions', true); }; var Settings = { getScripts: getScripts, getAudioTemplateCallback: getAudioTemplateCallback, getVideoTemplateCallback: getVideoTemplateCallback, hasLiveEmbeds: hasLiveEmbeds, shouldFilterHtml: shouldFilterHtml, getUrlResolver: getUrlResolver, hasAltSource: hasAltSource, hasPoster: hasPoster, hasDimensions: hasDimensions }; var global$3 = tinymce.util.Tools.resolve('tinymce.html.SaxParser'); var global$4 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var getVideoScriptMatch = function (prefixes, src) { if (prefixes) { for (var i = 0; i < prefixes.length; i++) { if (src.indexOf(prefixes[i].filter) !== -1) { return prefixes[i]; } } } }; var VideoScript = { getVideoScriptMatch: getVideoScriptMatch }; var trimPx = function (value) { return value.replace(/px$/, ''); }; var addPx = function (value) { return /^[0-9.]+$/.test(value) ? value + 'px' : value; }; var getSize = function (name) { return function (elm) { return elm ? trimPx(elm.style[name]) : ''; }; }; var setSize = function (name) { return function (elm, value) { if (elm) { elm.style[name] = addPx(value); } }; }; var Size = { getMaxWidth: getSize('maxWidth'), getMaxHeight: getSize('maxHeight'), setMaxWidth: setSize('maxWidth'), setMaxHeight: setSize('maxHeight') }; var DOM = global$4.DOM; var getEphoxEmbedIri = function (elm) { return DOM.getAttrib(elm, 'data-ephox-embed-iri'); }; var isEphoxEmbed = function (html) { var fragment = DOM.createFragment(html); return getEphoxEmbedIri(fragment.firstChild) !== ''; }; var htmlToDataSax = function (prefixes, html) { var data = {}; global$3({ validate: false, allow_conditional_comments: true, special: 'script,noscript', start: function (name, attrs) { if (!data.source1 && name === 'param') { data.source1 = attrs.map.movie; } if (name === 'iframe' || name === 'object' || name === 'embed' || name === 'video' || name === 'audio') { if (!data.type) { data.type = name; } data = global$2.extend(attrs.map, data); } if (name === 'script') { var videoScript = VideoScript.getVideoScriptMatch(prefixes, attrs.map.src); if (!videoScript) { return; } data = { type: 'script', source1: attrs.map.src, width: videoScript.width, height: videoScript.height }; } if (name === 'source') { if (!data.source1) { data.source1 = attrs.map.src; } else if (!data.source2) { data.source2 = attrs.map.src; } } if (name === 'img' && !data.poster) { data.poster = attrs.map.src; } } }).parse(html); data.source1 = data.source1 || data.src || data.data; data.source2 = data.source2 || ''; data.poster = data.poster || ''; return data; }; var ephoxEmbedHtmlToData = function (html) { var fragment = DOM.createFragment(html); var div = fragment.firstChild; return { type: 'ephox-embed-iri', source1: getEphoxEmbedIri(div), source2: '', poster: '', width: Size.getMaxWidth(div), height: Size.getMaxHeight(div) }; }; var htmlToData = function (prefixes, html) { return isEphoxEmbed(html) ? ephoxEmbedHtmlToData(html) : htmlToDataSax(prefixes, html); }; var HtmlToData = { htmlToData: htmlToData }; var global$5 = tinymce.util.Tools.resolve('tinymce.util.Promise'); var guess = function (url) { var mimes = { mp3: 'audio/mpeg', wav: 'audio/wav', mp4: 'video/mp4', webm: 'video/webm', ogg: 'video/ogg', swf: 'application/x-shockwave-flash' }; var fileEnd = url.toLowerCase().split('.').pop(); var mime = mimes[fileEnd]; return mime ? mime : ''; }; var Mime = { guess: guess }; var global$6 = tinymce.util.Tools.resolve('tinymce.html.Writer'); var global$7 = tinymce.util.Tools.resolve('tinymce.html.Schema'); var DOM$1 = global$4.DOM; var setAttributes = function (attrs, updatedAttrs) { var name; var i; var value; var attr; for (name in updatedAttrs) { value = '' + updatedAttrs[name]; if (attrs.map[name]) { i = attrs.length; while (i--) { attr = attrs[i]; if (attr.name === name) { if (value) { attrs.map[name] = value; attr.value = value; } else { delete attrs.map[name]; attrs.splice(i, 1); } } } } else if (value) { attrs.push({ name: name, value: value }); attrs.map[name] = value; } } }; var normalizeHtml = function (html) { var writer = global$6(); var parser = global$3(writer); parser.parse(html); return writer.getContent(); }; var updateHtmlSax = function (html, data, updateAll) { var writer = global$6(); var sourceCount = 0; var hasImage; global$3({ validate: false, allow_conditional_comments: true, special: 'script,noscript', comment: function (text) { writer.comment(text); }, cdata: function (text) { writer.cdata(text); }, text: function (text, raw) { writer.text(text, raw); }, start: function (name, attrs, empty) { switch (name) { case 'video': case 'object': case 'embed': case 'img': case 'iframe': if (data.height !== undefined && data.width !== undefined) { setAttributes(attrs, { width: data.width, height: data.height }); } break; } if (updateAll) { switch (name) { case 'video': setAttributes(attrs, { poster: data.poster, src: '' }); if (data.source2) { setAttributes(attrs, { src: '' }); } break; case 'iframe': setAttributes(attrs, { src: data.source1 }); break; case 'source': sourceCount++; if (sourceCount <= 2) { setAttributes(attrs, { src: data['source' + sourceCount], type: data['source' + sourceCount + 'mime'] }); if (!data['source' + sourceCount]) { return; } } break; case 'img': if (!data.poster) { return; } hasImage = true; break; } } writer.start(name, attrs, empty); }, end: function (name) { if (name === 'video' && updateAll) { for (var index = 1; index <= 2; index++) { if (data['source' + index]) { var attrs = []; attrs.map = {}; if (sourceCount < index) { setAttributes(attrs, { src: data['source' + index], type: data['source' + index + 'mime'] }); writer.start('source', attrs, true); } } } } if (data.poster && name === 'object' && updateAll && !hasImage) { var imgAttrs = []; imgAttrs.map = {}; setAttributes(imgAttrs, { src: data.poster, width: data.width, height: data.height }); writer.start('img', imgAttrs, true); } writer.end(name); } }, global$7({})).parse(html); return writer.getContent(); }; var isEphoxEmbed$1 = function (html) { var fragment = DOM$1.createFragment(html); return DOM$1.getAttrib(fragment.firstChild, 'data-ephox-embed-iri') !== ''; }; var updateEphoxEmbed = function (html, data) { var fragment = DOM$1.createFragment(html); var div = fragment.firstChild; Size.setMaxWidth(div, data.width); Size.setMaxHeight(div, data.height); return normalizeHtml(div.outerHTML); }; var updateHtml = function (html, data, updateAll) { return isEphoxEmbed$1(html) ? updateEphoxEmbed(html, data) : updateHtmlSax(html, data, updateAll); }; var UpdateHtml = { updateHtml: updateHtml }; var urlPatterns = [ { regex: /youtu\.be\/([\w\-_\?&=.]+)/i, type: 'iframe', w: 560, h: 314, url: '//www.youtube.com/embed/$1', allowFullscreen: true }, { regex: /youtube\.com(.+)v=([^&]+)(&([a-z0-9&=\-_]+))?/i, type: 'iframe', w: 560, h: 314, url: '//www.youtube.com/embed/$2?$4', allowFullscreen: true }, { regex: /youtube.com\/embed\/([a-z0-9\?&=\-_]+)/i, type: 'iframe', w: 560, h: 314, url: '//www.youtube.com/embed/$1', allowFullscreen: true }, { regex: /vimeo\.com\/([0-9]+)/, type: 'iframe', w: 425, h: 350, url: '//player.vimeo.com/video/$1?title=0&byline=0&portrait=0&color=8dc7dc', allowFullscreen: true }, { regex: /vimeo\.com\/(.*)\/([0-9]+)/, type: 'iframe', w: 425, h: 350, url: '//player.vimeo.com/video/$2?title=0&byline=0', allowFullscreen: true }, { regex: /maps\.google\.([a-z]{2,3})\/maps\/(.+)msid=(.+)/, type: 'iframe', w: 425, h: 350, url: '//maps.google.com/maps/ms?msid=$2&output=embed"', allowFullscreen: false }, { regex: /dailymotion\.com\/video\/([^_]+)/, type: 'iframe', w: 480, h: 270, url: '//www.dailymotion.com/embed/video/$1', allowFullscreen: true }, { regex: /dai\.ly\/([^_]+)/, type: 'iframe', w: 480, h: 270, url: '//www.dailymotion.com/embed/video/$1', allowFullscreen: true } ]; var getUrl = function (pattern, url) { var match = pattern.regex.exec(url); var newUrl = pattern.url; var _loop_1 = function (i) { newUrl = newUrl.replace('$' + i, function () { return match[i] ? match[i] : ''; }); }; for (var i = 0; i < match.length; i++) { _loop_1(i); } return newUrl.replace(/\?$/, ''); }; var matchPattern = function (url) { var pattern = urlPatterns.filter(function (pattern) { return pattern.regex.test(url); }); if (pattern.length > 0) { return global$2.extend({}, pattern[0], { url: getUrl(pattern[0], url) }); } else { return null; } }; var getIframeHtml = function (data) { var allowFullscreen = data.allowFullscreen ? ' allowFullscreen="1"' : ''; return '<iframe src="' + data.source1 + '" width="' + data.width + '" height="' + data.height + '"' + allowFullscreen + '></iframe>'; }; var getFlashHtml = function (data) { var html = '<object data="' + data.source1 + '" width="' + data.width + '" height="' + data.height + '" type="application/x-shockwave-flash">'; if (data.poster) { html += '<img src="' + data.poster + '" width="' + data.width + '" height="' + data.height + '" />'; } html += '</object>'; return html; }; var getAudioHtml = function (data, audioTemplateCallback) { if (audioTemplateCallback) { return audioTemplateCallback(data); } else { return '<audio controls="controls" src="' + data.source1 + '">' + (data.source2 ? '\n<source src="' + data.source2 + '"' + (data.source2mime ? ' type="' + data.source2mime + '"' : '') + ' />\n' : '') + '</audio>'; } }; var getVideoHtml = function (data, videoTemplateCallback) { if (videoTemplateCallback) { return videoTemplateCallback(data); } else { return '<video width="' + data.width + '" height="' + data.height + '"' + (data.poster ? ' poster="' + data.poster + '"' : '') + ' controls="controls">\n' + '<source src="' + data.source1 + '"' + (data.source1mime ? ' type="' + data.source1mime + '"' : '') + ' />\n' + (data.source2 ? '<source src="' + data.source2 + '"' + (data.source2mime ? ' type="' + data.source2mime + '"' : '') + ' />\n' : '') + '</video>'; } }; var getScriptHtml = function (data) { return '<script src="' + data.source1 + '"></script>'; }; var dataToHtml = function (editor, dataIn) { var data = global$2.extend({}, dataIn); if (!data.source1) { global$2.extend(data, HtmlToData.htmlToData(Settings.getScripts(editor), data.embed)); if (!data.source1) { return ''; } } if (!data.source2) { data.source2 = ''; } if (!data.poster) { data.poster = ''; } data.source1 = editor.convertURL(data.source1, 'source'); data.source2 = editor.convertURL(data.source2, 'source'); data.source1mime = Mime.guess(data.source1); data.source2mime = Mime.guess(data.source2); data.poster = editor.convertURL(data.poster, 'poster'); var pattern = matchPattern(data.source1); if (pattern) { data.source1 = pattern.url; data.type = pattern.type; data.allowFullscreen = pattern.allowFullscreen; data.width = data.width || pattern.w; data.height = data.height || pattern.h; } if (data.embed) { return UpdateHtml.updateHtml(data.embed, data, true); } else { var videoScript = VideoScript.getVideoScriptMatch(Settings.getScripts(editor), data.source1); if (videoScript) { data.type = 'script'; data.width = videoScript.width; data.height = videoScript.height; } var audioTemplateCallback = Settings.getAudioTemplateCallback(editor); var videoTemplateCallback = Settings.getVideoTemplateCallback(editor); data.width = data.width || 300; data.height = data.height || 150; global$2.each(data, function (value, key) { data[key] = editor.dom.encode(value); }); if (data.type === 'iframe') { return getIframeHtml(data); } else if (data.source1mime === 'application/x-shockwave-flash') { return getFlashHtml(data); } else if (data.source1mime.indexOf('audio') !== -1) { return getAudioHtml(data, audioTemplateCallback); } else if (data.type === 'script') { return getScriptHtml(data); } else { return getVideoHtml(data, videoTemplateCallback); } } }; var DataToHtml = { dataToHtml: dataToHtml }; var cache = {}; var embedPromise = function (data, dataToHtml, handler) { return new global$5(function (res, rej) { var wrappedResolve = function (response) { if (response.html) { cache[data.source1] = response; } return res({ url: data.source1, html: response.html ? response.html : dataToHtml(data) }); }; if (cache[data.source1]) { wrappedResolve(cache[data.source1]); } else { handler({ url: data.source1 }, wrappedResolve, rej); } }); }; var defaultPromise = function (data, dataToHtml) { return new global$5(function (res) { res({ html: dataToHtml(data), url: data.source1 }); }); }; var loadedData = function (editor) { return function (data) { return DataToHtml.dataToHtml(editor, data); }; }; var getEmbedHtml = function (editor, data) { var embedHandler = Settings.getUrlResolver(editor); return embedHandler ? embedPromise(data, loadedData(editor), embedHandler) : defaultPromise(data, loadedData(editor)); }; var isCached = function (url) { return cache.hasOwnProperty(url); }; var Service = { getEmbedHtml: getEmbedHtml, isCached: isCached }; var doSyncSize = function (widthCtrl, heightCtrl) { widthCtrl.state.set('oldVal', widthCtrl.value()); heightCtrl.state.set('oldVal', heightCtrl.value()); }; var doSizeControls = function (win, f) { var widthCtrl = win.find('#width')[0]; var heightCtrl = win.find('#height')[0]; var constrained = win.find('#constrain')[0]; if (widthCtrl && heightCtrl && constrained) { f(widthCtrl, heightCtrl, constrained.checked()); } }; var doUpdateSize = function (widthCtrl, heightCtrl, isContrained) { var oldWidth = widthCtrl.state.get('oldVal'); var oldHeight = heightCtrl.state.get('oldVal'); var newWidth = widthCtrl.value(); var newHeight = heightCtrl.value(); if (isContrained && oldWidth && oldHeight && newWidth && newHeight) { if (newWidth !== oldWidth) { newHeight = Math.round(newWidth / oldWidth * newHeight); if (!isNaN(newHeight)) { heightCtrl.value(newHeight); } } else { newWidth = Math.round(newHeight / oldHeight * newWidth); if (!isNaN(newWidth)) { widthCtrl.value(newWidth); } } } doSyncSize(widthCtrl, heightCtrl); }; var syncSize = function (win) { doSizeControls(win, doSyncSize); }; var updateSize = function (win) { doSizeControls(win, doUpdateSize); }; var createUi = function (onChange) { var recalcSize = function () { onChange(function (win) { updateSize(win); }); }; return { type: 'container', label: 'Dimensions', layout: 'flex', align: 'center', spacing: 5, items: [ { name: 'width', type: 'textbox', maxLength: 5, size: 5, onchange: recalcSize, ariaLabel: 'Width' }, { type: 'label', text: 'x' }, { name: 'height', type: 'textbox', maxLength: 5, size: 5, onchange: recalcSize, ariaLabel: 'Height' }, { name: 'constrain', type: 'checkbox', checked: true, text: 'Constrain proportions' } ] }; }; var SizeManager = { createUi: createUi, syncSize: syncSize, updateSize: updateSize }; var embedChange = global$1.ie && global$1.ie <= 8 ? 'onChange' : 'onInput'; var handleError = function (editor) { return function (error) { var errorMessage = error && error.msg ? 'Media embed handler error: ' + error.msg : 'Media embed handler threw unknown error.'; editor.notificationManager.open({ type: 'error', text: errorMessage }); }; }; var getData = function (editor) { var element = editor.selection.getNode(); var dataEmbed = element.getAttribute('data-ephox-embed-iri'); if (dataEmbed) { return { 'source1': dataEmbed, 'data-ephox-embed-iri': dataEmbed, 'width': Size.getMaxWidth(element), 'height': Size.getMaxHeight(element) }; } return element.getAttribute('data-mce-object') ? HtmlToData.htmlToData(Settings.getScripts(editor), editor.serializer.serialize(element, { selection: true })) : {}; }; var getSource = function (editor) { var elm = editor.selection.getNode(); if (elm.getAttribute('data-mce-object') || elm.getAttribute('data-ephox-embed-iri')) { return editor.selection.getContent(); } }; var addEmbedHtml = function (win, editor) { return function (response) { var html = response.html; var embed = win.find('#embed')[0]; var data = global$2.extend(HtmlToData.htmlToData(Settings.getScripts(editor), html), { source1: response.url }); win.fromJSON(data); if (embed) { embed.value(html); SizeManager.updateSize(win); } }; }; var selectPlaceholder = function (editor, beforeObjects) { var i; var y; var afterObjects = editor.dom.select('img[data-mce-object]'); for (i = 0; i < beforeObjects.length; i++) { for (y = afterObjects.length - 1; y >= 0; y--) { if (beforeObjects[i] === afterObjects[y]) { afterObjects.splice(y, 1); } } } editor.selection.select(afterObjects[0]); }; var handleInsert = function (editor, html) { var beforeObjects = editor.dom.select('img[data-mce-object]'); editor.insertContent(html); selectPlaceholder(editor, beforeObjects); editor.nodeChanged(); }; var submitForm = function (win, editor) { var data = win.toJSON(); data.embed = UpdateHtml.updateHtml(data.embed, data); if (data.embed && Service.isCached(data.source1)) { handleInsert(editor, data.embed); } else { Service.getEmbedHtml(editor, data).then(function (response) { handleInsert(editor, response.html); }).catch(handleError(editor)); } }; var populateMeta = function (win, meta) { global$2.each(meta, function (value, key) { win.find('#' + key).value(value); }); }; var showDialog = function (editor) { var win; var data; var generalFormItems = [{ name: 'source1', type: 'filepicker', filetype: 'media', size: 40, autofocus: true, label: 'Source', onpaste: function () { setTimeout(function () { Service.getEmbedHtml(editor, win.toJSON()).then(addEmbedHtml(win, editor)).catch(handleError(editor)); }, 1); }, onchange: function (e) { Service.getEmbedHtml(editor, win.toJSON()).then(addEmbedHtml(win, editor)).catch(handleError(editor)); populateMeta(win, e.meta); }, onbeforecall: function (e) { e.meta = win.toJSON(); } }]; var advancedFormItems = []; var reserialise = function (update) { update(win); data = win.toJSON(); win.find('#embed').value(UpdateHtml.updateHtml(data.embed, data)); }; if (Settings.hasAltSource(editor)) { advancedFormItems.push({ name: 'source2', type: 'filepicker', filetype: 'media', size: 40, label: 'Alternative source' }); } if (Settings.hasPoster(editor)) { advancedFormItems.push({ name: 'poster', type: 'filepicker', filetype: 'image', size: 40, label: 'Poster' }); } if (Settings.hasDimensions(editor)) { var control = SizeManager.createUi(reserialise); generalFormItems.push(control); } data = getData(editor); var embedTextBox = { id: 'mcemediasource', type: 'textbox', flex: 1, name: 'embed', value: getSource(editor), multiline: true, rows: 5, label: 'Source' }; var updateValueOnChange = function () { data = global$2.extend({}, HtmlToData.htmlToData(Settings.getScripts(editor), this.value())); this.parent().parent().fromJSON(data); }; embedTextBox[embedChange] = updateValueOnChange; var body = [ { title: 'General', type: 'form', items: generalFormItems }, { title: 'Embed', type: 'container', layout: 'flex', direction: 'column', align: 'stretch', padding: 10, spacing: 10, items: [ { type: 'label', text: 'Paste your embed code below:', forId: 'mcemediasource' }, embedTextBox ] } ]; if (advancedFormItems.length > 0) { body.push({ title: 'Advanced', type: 'form', items: advancedFormItems }); } win = editor.windowManager.open({ title: 'Insert/edit media', data: data, bodyType: 'tabpanel', body: body, onSubmit: function () { SizeManager.updateSize(win); submitForm(win, editor); } }); SizeManager.syncSize(win); }; var Dialog = { showDialog: showDialog }; var get = function (editor) { var showDialog = function () { Dialog.showDialog(editor); }; return { showDialog: showDialog }; }; var Api = { get: get }; var register = function (editor) { var showDialog = function () { Dialog.showDialog(editor); }; editor.addCommand('mceMedia', showDialog); }; var Commands = { register: register }; var global$8 = tinymce.util.Tools.resolve('tinymce.html.Node'); var sanitize = function (editor, html) { if (Settings.shouldFilterHtml(editor) === false) { return html; } var writer = global$6(); var blocked; global$3({ validate: false, allow_conditional_comments: false, special: 'script,noscript', comment: function (text) { writer.comment(text); }, cdata: function (text) { writer.cdata(text); }, text: function (text, raw) { writer.text(text, raw); }, start: function (name, attrs, empty) { blocked = true; if (name === 'script' || name === 'noscript') { return; } for (var i = 0; i < attrs.length; i++) { if (attrs[i].name.indexOf('on') === 0) { return; } if (attrs[i].name === 'style') { attrs[i].value = editor.dom.serializeStyle(editor.dom.parseStyle(attrs[i].value), name); } } writer.start(name, attrs, empty); blocked = false; }, end: function (name) { if (blocked) { return; } writer.end(name); } }, global$7({})).parse(html); return writer.getContent(); }; var Sanitize = { sanitize: sanitize }; var createPlaceholderNode = function (editor, node) { var placeHolder; var name = node.name; placeHolder = new global$8('img', 1); placeHolder.shortEnded = true; retainAttributesAndInnerHtml(editor, node, placeHolder); placeHolder.attr({ 'width': node.attr('width') || '300', 'height': node.attr('height') || (name === 'audio' ? '30' : '150'), 'style': node.attr('style'), 'src': global$1.transparentSrc, 'data-mce-object': name, 'class': 'mce-object mce-object-' + name }); return placeHolder; }; var createPreviewIframeNode = function (editor, node) { var previewWrapper; var previewNode; var shimNode; var name = node.name; previewWrapper = new global$8('span', 1); previewWrapper.attr({ 'contentEditable': 'false', 'style': node.attr('style'), 'data-mce-object': name, 'class': 'mce-preview-object mce-object-' + name }); retainAttributesAndInnerHtml(editor, node, previewWrapper); previewNode = new global$8(name, 1); previewNode.attr({ src: node.attr('src'), allowfullscreen: node.attr('allowfullscreen'), style: node.attr('style'), class: node.attr('class'), width: node.attr('width'), height: node.attr('height'), frameborder: '0' }); shimNode = new global$8('span', 1); shimNode.attr('class', 'mce-shim'); previewWrapper.append(previewNode); previewWrapper.append(shimNode); return previewWrapper; }; var retainAttributesAndInnerHtml = function (editor, sourceNode, targetNode) { var attrName; var attrValue; var attribs; var ai; var innerHtml; attribs = sourceNode.attributes; ai = attribs.length; while (ai--) { attrName = attribs[ai].name; attrValue = attribs[ai].value; if (attrName !== 'width' && attrName !== 'height' && attrName !== 'style') { if (attrName === 'data' || attrName === 'src') { attrValue = editor.convertURL(attrValue, attrName); } targetNode.attr('data-mce-p-' + attrName, attrValue); } } innerHtml = sourceNode.firstChild && sourceNode.firstChild.value; if (innerHtml) { targetNode.attr('data-mce-html', escape(Sanitize.sanitize(editor, innerHtml))); targetNode.firstChild = null; } }; var isWithinEphoxEmbed = function (node) { while (node = node.parent) { if (node.attr('data-ephox-embed-iri')) { return true; } } return false; }; var placeHolderConverter = function (editor) { return function (nodes) { var i = nodes.length; var node; var videoScript; while (i--) { node = nodes[i]; if (!node.parent) { continue; } if (node.parent.attr('data-mce-object')) { continue; } if (node.name === 'script') { videoScript = VideoScript.getVideoScriptMatch(Settings.getScripts(editor), node.attr('src')); if (!videoScript) { continue; } } if (videoScript) { if (videoScript.width) { node.attr('width', videoScript.width.toString()); } if (videoScript.height) { node.attr('height', videoScript.height.toString()); } } if (node.name === 'iframe' && Settings.hasLiveEmbeds(editor) && global$1.ceFalse) { if (!isWithinEphoxEmbed(node)) { node.replace(createPreviewIframeNode(editor, node)); } } else { if (!isWithinEphoxEmbed(node)) { node.replace(createPlaceholderNode(editor, node)); } } } }; }; var Nodes = { createPreviewIframeNode: createPreviewIframeNode, createPlaceholderNode: createPlaceholderNode, placeHolderConverter: placeHolderConverter }; var setup = function (editor) { editor.on('preInit', function () { var specialElements = editor.schema.getSpecialElements(); global$2.each('video audio iframe object'.split(' '), function (name) { specialElements[name] = new RegExp('</' + name + '[^>]*>', 'gi'); }); var boolAttrs = editor.schema.getBoolAttrs(); global$2.each('webkitallowfullscreen mozallowfullscreen allowfullscreen'.split(' '), function (name) { boolAttrs[name] = {}; }); editor.parser.addNodeFilter('iframe,video,audio,object,embed,script', Nodes.placeHolderConverter(editor)); editor.serializer.addAttributeFilter('data-mce-object', function (nodes, name) { var i = nodes.length; var node; var realElm; var ai; var attribs; var innerHtml; var innerNode; var realElmName; var className; while (i--) { node = nodes[i]; if (!node.parent) { continue; } realElmName = node.attr(name); realElm = new global$8(realElmName, 1); if (realElmName !== 'audio' && realElmName !== 'script') { className = node.attr('class'); if (className && className.indexOf('mce-preview-object') !== -1) { realElm.attr({ width: node.firstChild.attr('width'), height: node.firstChild.attr('height') }); } else { realElm.attr({ width: node.attr('width'), height: node.attr('height') }); } } realElm.attr({ style: node.attr('style') }); attribs = node.attributes; ai = attribs.length; while (ai--) { var attrName = attribs[ai].name; if (attrName.indexOf('data-mce-p-') === 0) { realElm.attr(attrName.substr(11), attribs[ai].value); } } if (realElmName === 'script') { realElm.attr('type', 'text/javascript'); } innerHtml = node.attr('data-mce-html'); if (innerHtml) { innerNode = new global$8('#text', 3); innerNode.raw = true; innerNode.value = Sanitize.sanitize(editor, unescape(innerHtml)); realElm.append(innerNode); } node.replace(realElm); } }); }); editor.on('setContent', function () { editor.$('span.mce-preview-object').each(function (index, elm) { var $elm = editor.$(elm); if ($elm.find('span.mce-shim', elm).length === 0) { $elm.append('<span class="mce-shim"></span>'); } }); }); }; var FilterContent = { setup: setup }; var setup$1 = function (editor) { editor.on('ResolveName', function (e) { var name; if (e.target.nodeType === 1 && (name = e.target.getAttribute('data-mce-object'))) { e.name = name; } }); }; var ResolveName = { setup: setup$1 }; var setup$2 = function (editor) { editor.on('click keyup', function () { var selectedNode = editor.selection.getNode(); if (selectedNode && editor.dom.hasClass(selectedNode, 'mce-preview-object')) { if (editor.dom.getAttrib(selectedNode, 'data-mce-selected')) { selectedNode.setAttribute('data-mce-selected', '2'); } } }); editor.on('ObjectSelected', function (e) { var objectType = e.target.getAttribute('data-mce-object'); if (objectType === 'audio' || objectType === 'script') { e.preventDefault(); } }); editor.on('objectResized', function (e) { var target = e.target; var html; if (target.getAttribute('data-mce-object')) { html = target.getAttribute('data-mce-html'); if (html) { html = unescape(html); target.setAttribute('data-mce-html', escape(UpdateHtml.updateHtml(html, { width: e.width, height: e.height }))); } } }); }; var Selection = { setup: setup$2 }; var register$1 = function (editor) { editor.addButton('media', { tooltip: 'Insert/edit media', cmd: 'mceMedia', stateSelector: [ 'img[data-mce-object]', 'span[data-mce-object]', 'div[data-ephox-embed-iri]' ] }); editor.addMenuItem('media', { icon: 'media', text: 'Media', cmd: 'mceMedia', context: 'insert', prependToContext: true }); }; var Buttons = { register: register$1 }; global.add('media', function (editor) { Commands.register(editor); Buttons.register(editor); ResolveName.setup(editor); FilterContent.setup(editor); Selection.setup(editor); return Api.get(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var nonbreaking = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var stringRepeat = function (string, repeats) { var str = ''; for (var index = 0; index < repeats; index++) { str += string; } return str; }; var isVisualCharsEnabled = function (editor) { return editor.plugins.visualchars ? editor.plugins.visualchars.isEnabled() : false; }; var insertNbsp = function (editor, times) { var nbsp = isVisualCharsEnabled(editor) ? '<span class="mce-nbsp"> </span>' : ' '; editor.insertContent(stringRepeat(nbsp, times)); editor.dom.setAttrib(editor.dom.select('span.mce-nbsp'), 'data-mce-bogus', '1'); }; var Actions = { insertNbsp: insertNbsp }; var register = function (editor) { editor.addCommand('mceNonBreaking', function () { Actions.insertNbsp(editor, 1); }); }; var Commands = { register: register }; var global$1 = tinymce.util.Tools.resolve('tinymce.util.VK'); var getKeyboardSpaces = function (editor) { var spaces = editor.getParam('nonbreaking_force_tab', 0); if (typeof spaces === 'boolean') { return spaces === true ? 3 : 0; } else { return spaces; } }; var Settings = { getKeyboardSpaces: getKeyboardSpaces }; var setup = function (editor) { var spaces = Settings.getKeyboardSpaces(editor); if (spaces > 0) { editor.on('keydown', function (e) { if (e.keyCode === global$1.TAB && !e.isDefaultPrevented()) { if (e.shiftKey) { return; } e.preventDefault(); e.stopImmediatePropagation(); Actions.insertNbsp(editor, spaces); } }); } }; var Keyboard = { setup: setup }; var register$1 = function (editor) { editor.addButton('nonbreaking', { title: 'Nonbreaking space', cmd: 'mceNonBreaking' }); editor.addMenuItem('nonbreaking', { icon: 'nonbreaking', text: 'Nonbreaking space', cmd: 'mceNonBreaking', context: 'insert' }); }; var Buttons = { register: register$1 }; global.add('nonbreaking', function (editor) { Commands.register(editor); Buttons.register(editor); Keyboard.setup(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var noneditable = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var getNonEditableClass = function (editor) { return editor.getParam('noneditable_noneditable_class', 'mceNonEditable'); }; var getEditableClass = function (editor) { return editor.getParam('noneditable_editable_class', 'mceEditable'); }; var getNonEditableRegExps = function (editor) { var nonEditableRegExps = editor.getParam('noneditable_regexp', []); if (nonEditableRegExps && nonEditableRegExps.constructor === RegExp) { return [nonEditableRegExps]; } else { return nonEditableRegExps; } }; var Settings = { getNonEditableClass: getNonEditableClass, getEditableClass: getEditableClass, getNonEditableRegExps: getNonEditableRegExps }; var hasClass = function (checkClassName) { return function (node) { return (' ' + node.attr('class') + ' ').indexOf(checkClassName) !== -1; }; }; var replaceMatchWithSpan = function (editor, content, cls) { return function (match) { var args = arguments, index = args[args.length - 2]; var prevChar = index > 0 ? content.charAt(index - 1) : ''; if (prevChar === '"') { return match; } if (prevChar === '>') { var findStartTagIndex = content.lastIndexOf('<', index); if (findStartTagIndex !== -1) { var tagHtml = content.substring(findStartTagIndex, index); if (tagHtml.indexOf('contenteditable="false"') !== -1) { return match; } } } return '<span class="' + cls + '" data-mce-content="' + editor.dom.encode(args[0]) + '">' + editor.dom.encode(typeof args[1] === 'string' ? args[1] : args[0]) + '</span>'; }; }; var convertRegExpsToNonEditable = function (editor, nonEditableRegExps, e) { var i = nonEditableRegExps.length, content = e.content; if (e.format === 'raw') { return; } while (i--) { content = content.replace(nonEditableRegExps[i], replaceMatchWithSpan(editor, content, Settings.getNonEditableClass(editor))); } e.content = content; }; var setup = function (editor) { var editClass, nonEditClass; var contentEditableAttrName = 'contenteditable'; editClass = ' ' + global$1.trim(Settings.getEditableClass(editor)) + ' '; nonEditClass = ' ' + global$1.trim(Settings.getNonEditableClass(editor)) + ' '; var hasEditClass = hasClass(editClass); var hasNonEditClass = hasClass(nonEditClass); var nonEditableRegExps = Settings.getNonEditableRegExps(editor); editor.on('PreInit', function () { if (nonEditableRegExps.length > 0) { editor.on('BeforeSetContent', function (e) { convertRegExpsToNonEditable(editor, nonEditableRegExps, e); }); } editor.parser.addAttributeFilter('class', function (nodes) { var i = nodes.length, node; while (i--) { node = nodes[i]; if (hasEditClass(node)) { node.attr(contentEditableAttrName, 'true'); } else if (hasNonEditClass(node)) { node.attr(contentEditableAttrName, 'false'); } } }); editor.serializer.addAttributeFilter(contentEditableAttrName, function (nodes) { var i = nodes.length, node; while (i--) { node = nodes[i]; if (!hasEditClass(node) && !hasNonEditClass(node)) { continue; } if (nonEditableRegExps.length > 0 && node.attr('data-mce-content')) { node.name = '#text'; node.type = 3; node.raw = true; node.value = node.attr('data-mce-content'); } else { node.attr(contentEditableAttrName, null); } } }); }); }; var FilterContent = { setup: setup }; global.add('noneditable', function (editor) { FilterContent.setup(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var pagebreak = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.Env'); var getSeparatorHtml = function (editor) { return editor.getParam('pagebreak_separator', '<!-- pagebreak -->'); }; var shouldSplitBlock = function (editor) { return editor.getParam('pagebreak_split_block', false); }; var Settings = { getSeparatorHtml: getSeparatorHtml, shouldSplitBlock: shouldSplitBlock }; var getPageBreakClass = function () { return 'mce-pagebreak'; }; var getPlaceholderHtml = function () { return '<img src="' + global$1.transparentSrc + '" class="' + getPageBreakClass() + '" data-mce-resize="false" data-mce-placeholder />'; }; var setup = function (editor) { var separatorHtml = Settings.getSeparatorHtml(editor); var pageBreakSeparatorRegExp = new RegExp(separatorHtml.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g, function (a) { return '\\' + a; }), 'gi'); editor.on('BeforeSetContent', function (e) { e.content = e.content.replace(pageBreakSeparatorRegExp, getPlaceholderHtml()); }); editor.on('PreInit', function () { editor.serializer.addNodeFilter('img', function (nodes) { var i = nodes.length, node, className; while (i--) { node = nodes[i]; className = node.attr('class'); if (className && className.indexOf('mce-pagebreak') !== -1) { var parentNode = node.parent; if (editor.schema.getBlockElements()[parentNode.name] && Settings.shouldSplitBlock(editor)) { parentNode.type = 3; parentNode.value = separatorHtml; parentNode.raw = true; node.remove(); continue; } node.type = 3; node.value = separatorHtml; node.raw = true; } } }); }); }; var FilterContent = { setup: setup, getPlaceholderHtml: getPlaceholderHtml, getPageBreakClass: getPageBreakClass }; var register = function (editor) { editor.addCommand('mcePageBreak', function () { if (editor.settings.pagebreak_split_block) { editor.insertContent('<p>' + FilterContent.getPlaceholderHtml() + '</p>'); } else { editor.insertContent(FilterContent.getPlaceholderHtml()); } }); }; var Commands = { register: register }; var setup$1 = function (editor) { editor.on('ResolveName', function (e) { if (e.target.nodeName === 'IMG' && editor.dom.hasClass(e.target, FilterContent.getPageBreakClass())) { e.name = 'pagebreak'; } }); }; var ResolveName = { setup: setup$1 }; var register$1 = function (editor) { editor.addButton('pagebreak', { title: 'Page break', cmd: 'mcePageBreak' }); editor.addMenuItem('pagebreak', { text: 'Page break', icon: 'pagebreak', cmd: 'mcePageBreak', context: 'insert' }); }; var Buttons = { register: register$1 }; global.add('pagebreak', function (editor) { Commands.register(editor); Buttons.register(editor); FilterContent.setup(editor); ResolveName.setup(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var paste = (function (domGlobals) { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var hasProPlugin = function (editor) { if (/(^|[ ,])powerpaste([, ]|$)/.test(editor.settings.plugins) && global.get('powerpaste')) { if (typeof domGlobals.window.console !== 'undefined' && domGlobals.window.console.log) { domGlobals.window.console.log('PowerPaste is incompatible with Paste plugin! Remove \'paste\' from the \'plugins\' option.'); } return true; } else { return false; } }; var DetectProPlugin = { hasProPlugin: hasProPlugin }; var get = function (clipboard, quirks) { return { clipboard: clipboard, quirks: quirks }; }; var Api = { get: get }; var firePastePreProcess = function (editor, html, internal, isWordHtml) { return editor.fire('PastePreProcess', { content: html, internal: internal, wordContent: isWordHtml }); }; var firePastePostProcess = function (editor, node, internal, isWordHtml) { return editor.fire('PastePostProcess', { node: node, internal: internal, wordContent: isWordHtml }); }; var firePastePlainTextToggle = function (editor, state) { return editor.fire('PastePlainTextToggle', { state: state }); }; var firePaste = function (editor, ieFake) { return editor.fire('paste', { ieFake: ieFake }); }; var Events = { firePastePreProcess: firePastePreProcess, firePastePostProcess: firePastePostProcess, firePastePlainTextToggle: firePastePlainTextToggle, firePaste: firePaste }; var shouldPlainTextInform = function (editor) { return editor.getParam('paste_plaintext_inform', true); }; var shouldBlockDrop = function (editor) { return editor.getParam('paste_block_drop', false); }; var shouldPasteDataImages = function (editor) { return editor.getParam('paste_data_images', false); }; var shouldFilterDrop = function (editor) { return editor.getParam('paste_filter_drop', true); }; var getPreProcess = function (editor) { return editor.getParam('paste_preprocess'); }; var getPostProcess = function (editor) { return editor.getParam('paste_postprocess'); }; var getWebkitStyles = function (editor) { return editor.getParam('paste_webkit_styles'); }; var shouldRemoveWebKitStyles = function (editor) { return editor.getParam('paste_remove_styles_if_webkit', true); }; var shouldMergeFormats = function (editor) { return editor.getParam('paste_merge_formats', true); }; var isSmartPasteEnabled = function (editor) { return editor.getParam('smart_paste', true); }; var isPasteAsTextEnabled = function (editor) { return editor.getParam('paste_as_text', false); }; var getRetainStyleProps = function (editor) { return editor.getParam('paste_retain_style_properties'); }; var getWordValidElements = function (editor) { var defaultValidElements = '-strong/b,-em/i,-u,-span,-p,-ol,-ul,-li,-h1,-h2,-h3,-h4,-h5,-h6,' + '-p/div,-a[href|name],sub,sup,strike,br,del,table[width],tr,' + 'td[colspan|rowspan|width],th[colspan|rowspan|width],thead,tfoot,tbody'; return editor.getParam('paste_word_valid_elements', defaultValidElements); }; var shouldConvertWordFakeLists = function (editor) { return editor.getParam('paste_convert_word_fake_lists', true); }; var shouldUseDefaultFilters = function (editor) { return editor.getParam('paste_enable_default_filters', true); }; var Settings = { shouldPlainTextInform: shouldPlainTextInform, shouldBlockDrop: shouldBlockDrop, shouldPasteDataImages: shouldPasteDataImages, shouldFilterDrop: shouldFilterDrop, getPreProcess: getPreProcess, getPostProcess: getPostProcess, getWebkitStyles: getWebkitStyles, shouldRemoveWebKitStyles: shouldRemoveWebKitStyles, shouldMergeFormats: shouldMergeFormats, isSmartPasteEnabled: isSmartPasteEnabled, isPasteAsTextEnabled: isPasteAsTextEnabled, getRetainStyleProps: getRetainStyleProps, getWordValidElements: getWordValidElements, shouldConvertWordFakeLists: shouldConvertWordFakeLists, shouldUseDefaultFilters: shouldUseDefaultFilters }; var shouldInformUserAboutPlainText = function (editor, userIsInformedState) { return userIsInformedState.get() === false && Settings.shouldPlainTextInform(editor); }; var displayNotification = function (editor, message) { editor.notificationManager.open({ text: editor.translate(message), type: 'info' }); }; var togglePlainTextPaste = function (editor, clipboard, userIsInformedState) { if (clipboard.pasteFormat.get() === 'text') { clipboard.pasteFormat.set('html'); Events.firePastePlainTextToggle(editor, false); } else { clipboard.pasteFormat.set('text'); Events.firePastePlainTextToggle(editor, true); if (shouldInformUserAboutPlainText(editor, userIsInformedState)) { displayNotification(editor, 'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.'); userIsInformedState.set(true); } } editor.focus(); }; var Actions = { togglePlainTextPaste: togglePlainTextPaste }; var register = function (editor, clipboard, userIsInformedState) { editor.addCommand('mceTogglePlainTextPaste', function () { Actions.togglePlainTextPaste(editor, clipboard, userIsInformedState); }); editor.addCommand('mceInsertClipboardContent', function (ui, value) { if (value.content) { clipboard.pasteHtml(value.content, value.internal); } if (value.text) { clipboard.pasteText(value.text); } }); }; var Commands = { register: register }; var global$1 = tinymce.util.Tools.resolve('tinymce.Env'); var global$2 = tinymce.util.Tools.resolve('tinymce.util.Delay'); var global$3 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var global$4 = tinymce.util.Tools.resolve('tinymce.util.VK'); var internalMimeType = 'x-tinymce/html'; var internalMark = '<!-- ' + internalMimeType + ' -->'; var mark = function (html) { return internalMark + html; }; var unmark = function (html) { return html.replace(internalMark, ''); }; var isMarked = function (html) { return html.indexOf(internalMark) !== -1; }; var InternalHtml = { mark: mark, unmark: unmark, isMarked: isMarked, internalHtmlMime: function () { return internalMimeType; } }; var global$5 = tinymce.util.Tools.resolve('tinymce.html.Entities'); var isPlainText = function (text) { return !/<(?:\/?(?!(?:div|p|br|span)>)\w+|(?:(?!(?:span style="white-space:\s?pre;?">)|br\s?\/>))\w+\s[^>]+)>/i.test(text); }; var toBRs = function (text) { return text.replace(/\r?\n/g, '<br>'); }; var openContainer = function (rootTag, rootAttrs) { var key; var attrs = []; var tag = '<' + rootTag; if (typeof rootAttrs === 'object') { for (key in rootAttrs) { if (rootAttrs.hasOwnProperty(key)) { attrs.push(key + '="' + global$5.encodeAllRaw(rootAttrs[key]) + '"'); } } if (attrs.length) { tag += ' ' + attrs.join(' '); } } return tag + '>'; }; var toBlockElements = function (text, rootTag, rootAttrs) { var blocks = text.split(/\n\n/); var tagOpen = openContainer(rootTag, rootAttrs); var tagClose = '</' + rootTag + '>'; var paragraphs = global$3.map(blocks, function (p) { return p.split(/\n/).join('<br />'); }); var stitch = function (p) { return tagOpen + p + tagClose; }; return paragraphs.length === 1 ? paragraphs[0] : global$3.map(paragraphs, stitch).join(''); }; var convert = function (text, rootTag, rootAttrs) { return rootTag ? toBlockElements(text, rootTag, rootAttrs) : toBRs(text); }; var Newlines = { isPlainText: isPlainText, convert: convert, toBRs: toBRs, toBlockElements: toBlockElements }; var global$6 = tinymce.util.Tools.resolve('tinymce.html.DomParser'); var global$7 = tinymce.util.Tools.resolve('tinymce.html.Node'); var global$8 = tinymce.util.Tools.resolve('tinymce.html.Schema'); var global$9 = tinymce.util.Tools.resolve('tinymce.html.Serializer'); function filter(content, items) { global$3.each(items, function (v) { if (v.constructor === RegExp) { content = content.replace(v, ''); } else { content = content.replace(v[0], v[1]); } }); return content; } function innerText(html) { var schema = global$8(); var domParser = global$6({}, schema); var text = ''; var shortEndedElements = schema.getShortEndedElements(); var ignoreElements = global$3.makeMap('script noscript style textarea video audio iframe object', ' '); var blockElements = schema.getBlockElements(); function walk(node) { var name = node.name, currentNode = node; if (name === 'br') { text += '\n'; return; } if (name === 'wbr') { return; } if (shortEndedElements[name]) { text += ' '; } if (ignoreElements[name]) { text += ' '; return; } if (node.type === 3) { text += node.value; } if (!node.shortEnded) { if (node = node.firstChild) { do { walk(node); } while (node = node.next); } } if (blockElements[name] && currentNode.next) { text += '\n'; if (name === 'p') { text += '\n'; } } } html = filter(html, [/<!\[[^\]]+\]>/g]); walk(domParser.parse(html)); return text; } function trimHtml(html) { function trimSpaces(all, s1, s2) { if (!s1 && !s2) { return ' '; } return '\xA0'; } html = filter(html, [ /^[\s\S]*<body[^>]*>\s*|\s*<\/body[^>]*>[\s\S]*$/ig, /<!--StartFragment-->|<!--EndFragment-->/g, [ /( ?)<span class="Apple-converted-space">\u00a0<\/span>( ?)/g, trimSpaces ], /<br class="Apple-interchange-newline">/g, /<br>$/i ]); return html; } function createIdGenerator(prefix) { var count = 0; return function () { return prefix + count++; }; } var isMsEdge = function () { return domGlobals.navigator.userAgent.indexOf(' Edge/') !== -1; }; var Utils = { filter: filter, innerText: innerText, trimHtml: trimHtml, createIdGenerator: createIdGenerator, isMsEdge: isMsEdge }; function isWordContent(content) { return /<font face="Times New Roman"|class="?Mso|style="[^"]*\bmso-|style='[^'']*\bmso-|w:WordDocument/i.test(content) || /class="OutlineElement/.test(content) || /id="?docs\-internal\-guid\-/.test(content); } function isNumericList(text) { var found, patterns; patterns = [ /^[IVXLMCD]{1,2}\.[ \u00a0]/, /^[ivxlmcd]{1,2}\.[ \u00a0]/, /^[a-z]{1,2}[\.\)][ \u00a0]/, /^[A-Z]{1,2}[\.\)][ \u00a0]/, /^[0-9]+\.[ \u00a0]/, /^[\u3007\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d]+\.[ \u00a0]/, /^[\u58f1\u5f10\u53c2\u56db\u4f0d\u516d\u4e03\u516b\u4e5d\u62fe]+\.[ \u00a0]/ ]; text = text.replace(/^[\u00a0 ]+/, ''); global$3.each(patterns, function (pattern) { if (pattern.test(text)) { found = true; return false; } }); return found; } function isBulletList(text) { return /^[\s\u00a0]*[\u2022\u00b7\u00a7\u25CF]\s*/.test(text); } function convertFakeListsToProperLists(node) { var currentListNode, prevListNode, lastLevel = 1; function getText(node) { var txt = ''; if (node.type === 3) { return node.value; } if (node = node.firstChild) { do { txt += getText(node); } while (node = node.next); } return txt; } function trimListStart(node, regExp) { if (node.type === 3) { if (regExp.test(node.value)) { node.value = node.value.replace(regExp, ''); return false; } } if (node = node.firstChild) { do { if (!trimListStart(node, regExp)) { return false; } } while (node = node.next); } return true; } function removeIgnoredNodes(node) { if (node._listIgnore) { node.remove(); return; } if (node = node.firstChild) { do { removeIgnoredNodes(node); } while (node = node.next); } } function convertParagraphToLi(paragraphNode, listName, start) { var level = paragraphNode._listLevel || lastLevel; if (level !== lastLevel) { if (level < lastLevel) { if (currentListNode) { currentListNode = currentListNode.parent.parent; } } else { prevListNode = currentListNode; currentListNode = null; } } if (!currentListNode || currentListNode.name !== listName) { prevListNode = prevListNode || currentListNode; currentListNode = new global$7(listName, 1); if (start > 1) { currentListNode.attr('start', '' + start); } paragraphNode.wrap(currentListNode); } else { currentListNode.append(paragraphNode); } paragraphNode.name = 'li'; if (level > lastLevel && prevListNode) { prevListNode.lastChild.append(currentListNode); } lastLevel = level; removeIgnoredNodes(paragraphNode); trimListStart(paragraphNode, /^\u00a0+/); trimListStart(paragraphNode, /^\s*([\u2022\u00b7\u00a7\u25CF]|\w+\.)/); trimListStart(paragraphNode, /^\u00a0+/); } var elements = []; var child = node.firstChild; while (typeof child !== 'undefined' && child !== null) { elements.push(child); child = child.walk(); if (child !== null) { while (typeof child !== 'undefined' && child.parent !== node) { child = child.walk(); } } } for (var i = 0; i < elements.length; i++) { node = elements[i]; if (node.name === 'p' && node.firstChild) { var nodeText = getText(node); if (isBulletList(nodeText)) { convertParagraphToLi(node, 'ul'); continue; } if (isNumericList(nodeText)) { var matches = /([0-9]+)\./.exec(nodeText); var start = 1; if (matches) { start = parseInt(matches[1], 10); } convertParagraphToLi(node, 'ol', start); continue; } if (node._listLevel) { convertParagraphToLi(node, 'ul', 1); continue; } currentListNode = null; } else { prevListNode = currentListNode; currentListNode = null; } } } function filterStyles(editor, validStyles, node, styleValue) { var outputStyles = {}, matches; var styles = editor.dom.parseStyle(styleValue); global$3.each(styles, function (value, name) { switch (name) { case 'mso-list': matches = /\w+ \w+([0-9]+)/i.exec(styleValue); if (matches) { node._listLevel = parseInt(matches[1], 10); } if (/Ignore/i.test(value) && node.firstChild) { node._listIgnore = true; node.firstChild._listIgnore = true; } break; case 'horiz-align': name = 'text-align'; break; case 'vert-align': name = 'vertical-align'; break; case 'font-color': case 'mso-foreground': name = 'color'; break; case 'mso-background': case 'mso-highlight': name = 'background'; break; case 'font-weight': case 'font-style': if (value !== 'normal') { outputStyles[name] = value; } return; case 'mso-element': if (/^(comment|comment-list)$/i.test(value)) { node.remove(); return; } break; } if (name.indexOf('mso-comment') === 0) { node.remove(); return; } if (name.indexOf('mso-') === 0) { return; } if (Settings.getRetainStyleProps(editor) === 'all' || validStyles && validStyles[name]) { outputStyles[name] = value; } }); if (/(bold)/i.test(outputStyles['font-weight'])) { delete outputStyles['font-weight']; node.wrap(new global$7('b', 1)); } if (/(italic)/i.test(outputStyles['font-style'])) { delete outputStyles['font-style']; node.wrap(new global$7('i', 1)); } outputStyles = editor.dom.serializeStyle(outputStyles, node.name); if (outputStyles) { return outputStyles; } return null; } var filterWordContent = function (editor, content) { var retainStyleProperties, validStyles; retainStyleProperties = Settings.getRetainStyleProps(editor); if (retainStyleProperties) { validStyles = global$3.makeMap(retainStyleProperties.split(/[, ]/)); } content = Utils.filter(content, [ /<br class="?Apple-interchange-newline"?>/gi, /<b[^>]+id="?docs-internal-[^>]*>/gi, /<!--[\s\S]+?-->/gi, /<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi, [ /<(\/?)s>/gi, '<$1strike>' ], [ / /gi, '\xA0' ], [ /<span\s+style\s*=\s*"\s*mso-spacerun\s*:\s*yes\s*;?\s*"\s*>([\s\u00a0]*)<\/span>/gi, function (str, spaces) { return spaces.length > 0 ? spaces.replace(/./, ' ').slice(Math.floor(spaces.length / 2)).split('').join('\xA0') : ''; } ] ]); var validElements = Settings.getWordValidElements(editor); var schema = global$8({ valid_elements: validElements, valid_children: '-li[p]' }); global$3.each(schema.elements, function (rule) { if (!rule.attributes.class) { rule.attributes.class = {}; rule.attributesOrder.push('class'); } if (!rule.attributes.style) { rule.attributes.style = {}; rule.attributesOrder.push('style'); } }); var domParser = global$6({}, schema); domParser.addAttributeFilter('style', function (nodes) { var i = nodes.length, node; while (i--) { node = nodes[i]; node.attr('style', filterStyles(editor, validStyles, node, node.attr('style'))); if (node.name === 'span' && node.parent && !node.attributes.length) { node.unwrap(); } } }); domParser.addAttributeFilter('class', function (nodes) { var i = nodes.length, node, className; while (i--) { node = nodes[i]; className = node.attr('class'); if (/^(MsoCommentReference|MsoCommentText|msoDel)$/i.test(className)) { node.remove(); } node.attr('class', null); } }); domParser.addNodeFilter('del', function (nodes) { var i = nodes.length; while (i--) { nodes[i].remove(); } }); domParser.addNodeFilter('a', function (nodes) { var i = nodes.length, node, href, name; while (i--) { node = nodes[i]; href = node.attr('href'); name = node.attr('name'); if (href && href.indexOf('#_msocom_') !== -1) { node.remove(); continue; } if (href && href.indexOf('file://') === 0) { href = href.split('#')[1]; if (href) { href = '#' + href; } } if (!href && !name) { node.unwrap(); } else { if (name && !/^_?(?:toc|edn|ftn)/i.test(name)) { node.unwrap(); continue; } node.attr({ href: href, name: name }); } } }); var rootNode = domParser.parse(content); if (Settings.shouldConvertWordFakeLists(editor)) { convertFakeListsToProperLists(rootNode); } content = global$9({ validate: editor.settings.validate }, schema).serialize(rootNode); return content; }; var preProcess = function (editor, content) { return Settings.shouldUseDefaultFilters(editor) ? filterWordContent(editor, content) : content; }; var WordFilter = { preProcess: preProcess, isWordContent: isWordContent }; var processResult = function (content, cancelled) { return { content: content, cancelled: cancelled }; }; var postProcessFilter = function (editor, html, internal, isWordHtml) { var tempBody = editor.dom.create('div', { style: 'display:none' }, html); var postProcessArgs = Events.firePastePostProcess(editor, tempBody, internal, isWordHtml); return processResult(postProcessArgs.node.innerHTML, postProcessArgs.isDefaultPrevented()); }; var filterContent = function (editor, content, internal, isWordHtml) { var preProcessArgs = Events.firePastePreProcess(editor, content, internal, isWordHtml); if (editor.hasEventListeners('PastePostProcess') && !preProcessArgs.isDefaultPrevented()) { return postProcessFilter(editor, preProcessArgs.content, internal, isWordHtml); } else { return processResult(preProcessArgs.content, preProcessArgs.isDefaultPrevented()); } }; var process = function (editor, html, internal) { var isWordHtml = WordFilter.isWordContent(html); var content = isWordHtml ? WordFilter.preProcess(editor, html) : html; return filterContent(editor, content, internal, isWordHtml); }; var ProcessFilters = { process: process }; var removeMeta = function (editor, html) { var body = editor.dom.create('body', {}, html); global$3.each(body.querySelectorAll('meta'), function (elm) { return elm.parentNode.removeChild(elm); }); return body.innerHTML; }; var pasteHtml = function (editor, html) { editor.insertContent(removeMeta(editor, html), { merge: Settings.shouldMergeFormats(editor), paste: true }); return true; }; var isAbsoluteUrl = function (url) { return /^https?:\/\/[\w\?\-\/+=.&%@~#]+$/i.test(url); }; var isImageUrl = function (url) { return isAbsoluteUrl(url) && /.(gif|jpe?g|png)$/.test(url); }; var createImage = function (editor, url, pasteHtmlFn) { editor.undoManager.extra(function () { pasteHtmlFn(editor, url); }, function () { editor.insertContent('<img src="' + url + '">'); }); return true; }; var createLink = function (editor, url, pasteHtmlFn) { editor.undoManager.extra(function () { pasteHtmlFn(editor, url); }, function () { editor.execCommand('mceInsertLink', false, url); }); return true; }; var linkSelection = function (editor, html, pasteHtmlFn) { return editor.selection.isCollapsed() === false && isAbsoluteUrl(html) ? createLink(editor, html, pasteHtmlFn) : false; }; var insertImage = function (editor, html, pasteHtmlFn) { return isImageUrl(html) ? createImage(editor, html, pasteHtmlFn) : false; }; var smartInsertContent = function (editor, html) { global$3.each([ linkSelection, insertImage, pasteHtml ], function (action) { return action(editor, html, pasteHtml) !== true; }); }; var insertContent = function (editor, html) { if (Settings.isSmartPasteEnabled(editor) === false) { pasteHtml(editor, html); } else { smartInsertContent(editor, html); } }; var SmartPaste = { isImageUrl: isImageUrl, isAbsoluteUrl: isAbsoluteUrl, insertContent: insertContent }; var constant = function (value) { return function () { return value; }; }; function curry(fn) { var initialArgs = []; for (var _i = 1; _i < arguments.length; _i++) { initialArgs[_i - 1] = arguments[_i]; } return function () { var restArgs = []; for (var _i = 0; _i < arguments.length; _i++) { restArgs[_i] = arguments[_i]; } var all = initialArgs.concat(restArgs); return fn.apply(null, all); }; } var never = constant(false); var always = constant(true); var never$1 = never; var always$1 = always; var none = function () { return NONE; }; var NONE = function () { var eq = function (o) { return o.isNone(); }; var call = function (thunk) { return thunk(); }; var id = function (n) { return n; }; var noop = function () { }; var nul = function () { return null; }; var undef = function () { return undefined; }; var me = { fold: function (n, s) { return n(); }, is: never$1, isSome: never$1, isNone: always$1, getOr: id, getOrThunk: call, getOrDie: function (msg) { throw new Error(msg || 'error: getOrDie called on none.'); }, getOrNull: nul, getOrUndefined: undef, or: id, orThunk: call, map: none, ap: none, each: noop, bind: none, flatten: none, exists: never$1, forall: always$1, filter: none, equals: eq, equals_: eq, toArray: function () { return []; }, toString: constant('none()') }; if (Object.freeze) Object.freeze(me); return me; }(); var some = function (a) { var constant_a = function () { return a; }; var self = function () { return me; }; var map = function (f) { return some(f(a)); }; var bind = function (f) { return f(a); }; var me = { fold: function (n, s) { return s(a); }, is: function (v) { return a === v; }, isSome: always$1, isNone: never$1, getOr: constant_a, getOrThunk: constant_a, getOrDie: constant_a, getOrNull: constant_a, getOrUndefined: constant_a, or: self, orThunk: self, map: map, ap: function (optfab) { return optfab.fold(none, function (fab) { return some(fab(a)); }); }, each: function (f) { f(a); }, bind: bind, flatten: constant_a, exists: bind, forall: bind, filter: function (f) { return f(a) ? me : NONE; }, equals: function (o) { return o.is(a); }, equals_: function (o, elementEq) { return o.fold(never$1, function (b) { return elementEq(a, b); }); }, toArray: function () { return [a]; }, toString: function () { return 'some(' + a + ')'; } }; return me; }; var from = function (value) { return value === null || value === undefined ? NONE : some(value); }; var Option = { some: some, none: none, from: from }; var typeOf = function (x) { if (x === null) return 'null'; var t = typeof x; if (t === 'object' && Array.prototype.isPrototypeOf(x)) return 'array'; if (t === 'object' && String.prototype.isPrototypeOf(x)) return 'string'; return t; }; var isType = function (type) { return function (value) { return typeOf(value) === type; }; }; var isFunction = isType('function'); var map = function (xs, f) { var len = xs.length; var r = new Array(len); for (var i = 0; i < len; i++) { var x = xs[i]; r[i] = f(x, i, xs); } return r; }; var each = function (xs, f) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; f(x, i, xs); } }; var filter$1 = function (xs, pred) { var r = []; for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { r.push(x); } } return r; }; var slice = Array.prototype.slice; var from$1 = isFunction(Array.from) ? Array.from : function (x) { return slice.call(x); }; var nu = function (baseFn) { var data = Option.none(); var callbacks = []; var map = function (f) { return nu(function (nCallback) { get(function (data) { nCallback(f(data)); }); }); }; var get = function (nCallback) { if (isReady()) call(nCallback); else callbacks.push(nCallback); }; var set = function (x) { data = Option.some(x); run(callbacks); callbacks = []; }; var isReady = function () { return data.isSome(); }; var run = function (cbs) { each(cbs, call); }; var call = function (cb) { data.each(function (x) { domGlobals.setTimeout(function () { cb(x); }, 0); }); }; baseFn(set); return { get: get, map: map, isReady: isReady }; }; var pure = function (a) { return nu(function (callback) { callback(a); }); }; var LazyValue = { nu: nu, pure: pure }; var bounce = function (f) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var me = this; domGlobals.setTimeout(function () { f.apply(me, args); }, 0); }; }; var nu$1 = function (baseFn) { var get = function (callback) { baseFn(bounce(callback)); }; var map = function (fab) { return nu$1(function (callback) { get(function (a) { var value = fab(a); callback(value); }); }); }; var bind = function (aFutureB) { return nu$1(function (callback) { get(function (a) { aFutureB(a).get(callback); }); }); }; var anonBind = function (futureB) { return nu$1(function (callback) { get(function (a) { futureB.get(callback); }); }); }; var toLazy = function () { return LazyValue.nu(get); }; var toCached = function () { var cache = null; return nu$1(function (callback) { if (cache === null) { cache = toLazy(); } cache.get(callback); }); }; return { map: map, bind: bind, anonBind: anonBind, toLazy: toLazy, toCached: toCached, get: get }; }; var pure$1 = function (a) { return nu$1(function (callback) { callback(a); }); }; var Future = { nu: nu$1, pure: pure$1 }; var par = function (asyncValues, nu) { return nu(function (callback) { var r = []; var count = 0; var cb = function (i) { return function (value) { r[i] = value; count++; if (count >= asyncValues.length) { callback(r); } }; }; if (asyncValues.length === 0) { callback([]); } else { each(asyncValues, function (asyncValue, i) { asyncValue.get(cb(i)); }); } }); }; var par$1 = function (futures) { return par(futures, Future.nu); }; var mapM = function (array, fn) { var futures = map(array, fn); return par$1(futures); }; var pasteHtml$1 = function (editor, html, internalFlag) { var internal = internalFlag ? internalFlag : InternalHtml.isMarked(html); var args = ProcessFilters.process(editor, InternalHtml.unmark(html), internal); if (args.cancelled === false) { SmartPaste.insertContent(editor, args.content); } }; var pasteText = function (editor, text) { text = editor.dom.encode(text).replace(/\r\n/g, '\n'); text = Newlines.convert(text, editor.settings.forced_root_block, editor.settings.forced_root_block_attrs); pasteHtml$1(editor, text, false); }; var getDataTransferItems = function (dataTransfer) { var items = {}; var mceInternalUrlPrefix = 'data:text/mce-internal,'; if (dataTransfer) { if (dataTransfer.getData) { var legacyText = dataTransfer.getData('Text'); if (legacyText && legacyText.length > 0) { if (legacyText.indexOf(mceInternalUrlPrefix) === -1) { items['text/plain'] = legacyText; } } } if (dataTransfer.types) { for (var i = 0; i < dataTransfer.types.length; i++) { var contentType = dataTransfer.types[i]; try { items[contentType] = dataTransfer.getData(contentType); } catch (ex) { items[contentType] = ''; } } } } return items; }; var getClipboardContent = function (editor, clipboardEvent) { var content = getDataTransferItems(clipboardEvent.clipboardData || editor.getDoc().dataTransfer); return Utils.isMsEdge() ? global$3.extend(content, { 'text/html': '' }) : content; }; var hasContentType = function (clipboardContent, mimeType) { return mimeType in clipboardContent && clipboardContent[mimeType].length > 0; }; var hasHtmlOrText = function (content) { return hasContentType(content, 'text/html') || hasContentType(content, 'text/plain'); }; var getBase64FromUri = function (uri) { var idx; idx = uri.indexOf(','); if (idx !== -1) { return uri.substr(idx + 1); } return null; }; var isValidDataUriImage = function (settings, imgElm) { return settings.images_dataimg_filter ? settings.images_dataimg_filter(imgElm) : true; }; var extractFilename = function (editor, str) { var m = str.match(/([\s\S]+?)\.(?:jpeg|jpg|png|gif)$/i); return m ? editor.dom.encode(m[1]) : null; }; var uniqueId = Utils.createIdGenerator('mceclip'); var pasteImage = function (editor, imageItem) { var base64 = getBase64FromUri(imageItem.uri); var id = uniqueId(); var name = editor.settings.images_reuse_filename && imageItem.blob.name ? extractFilename(editor, imageItem.blob.name) : id; var img = new domGlobals.Image(); img.src = imageItem.uri; if (isValidDataUriImage(editor.settings, img)) { var blobCache = editor.editorUpload.blobCache; var blobInfo = void 0, existingBlobInfo = void 0; existingBlobInfo = blobCache.findFirst(function (cachedBlobInfo) { return cachedBlobInfo.base64() === base64; }); if (!existingBlobInfo) { blobInfo = blobCache.create(id, imageItem.blob, base64, name); blobCache.add(blobInfo); } else { blobInfo = existingBlobInfo; } pasteHtml$1(editor, '<img src="' + blobInfo.blobUri() + '">', false); } else { pasteHtml$1(editor, '<img src="' + imageItem.uri + '">', false); } }; var isClipboardEvent = function (event) { return event.type === 'paste'; }; var readBlobsAsDataUris = function (items) { return mapM(items, function (item) { return Future.nu(function (resolve) { var blob = item.getAsFile ? item.getAsFile() : item; var reader = new window.FileReader(); reader.onload = function () { resolve({ blob: blob, uri: reader.result }); }; reader.readAsDataURL(blob); }); }); }; var getImagesFromDataTransfer = function (dataTransfer) { var items = dataTransfer.items ? map(from$1(dataTransfer.items), function (item) { return item.getAsFile(); }) : []; var files = dataTransfer.files ? from$1(dataTransfer.files) : []; var images = filter$1(items.length > 0 ? items : files, function (file) { return /^image\/(jpeg|png|gif|bmp)$/.test(file.type); }); return images; }; var pasteImageData = function (editor, e, rng) { var dataTransfer = isClipboardEvent(e) ? e.clipboardData : e.dataTransfer; if (editor.settings.paste_data_images && dataTransfer) { var images = getImagesFromDataTransfer(dataTransfer); if (images.length > 0) { e.preventDefault(); readBlobsAsDataUris(images).get(function (blobResults) { if (rng) { editor.selection.setRng(rng); } each(blobResults, function (result) { pasteImage(editor, result); }); }); return true; } } return false; }; var isBrokenAndroidClipboardEvent = function (e) { var clipboardData = e.clipboardData; return domGlobals.navigator.userAgent.indexOf('Android') !== -1 && clipboardData && clipboardData.items && clipboardData.items.length === 0; }; var isKeyboardPasteEvent = function (e) { return global$4.metaKeyPressed(e) && e.keyCode === 86 || e.shiftKey && e.keyCode === 45; }; var registerEventHandlers = function (editor, pasteBin, pasteFormat) { var keyboardPasteTimeStamp = 0; var keyboardPastePlainTextState; editor.on('keydown', function (e) { function removePasteBinOnKeyUp(e) { if (isKeyboardPasteEvent(e) && !e.isDefaultPrevented()) { pasteBin.remove(); } } if (isKeyboardPasteEvent(e) && !e.isDefaultPrevented()) { keyboardPastePlainTextState = e.shiftKey && e.keyCode === 86; if (keyboardPastePlainTextState && global$1.webkit && domGlobals.navigator.userAgent.indexOf('Version/') !== -1) { return; } e.stopImmediatePropagation(); keyboardPasteTimeStamp = new Date().getTime(); if (global$1.ie && keyboardPastePlainTextState) { e.preventDefault(); Events.firePaste(editor, true); return; } pasteBin.remove(); pasteBin.create(); editor.once('keyup', removePasteBinOnKeyUp); editor.once('paste', function () { editor.off('keyup', removePasteBinOnKeyUp); }); } }); function insertClipboardContent(clipboardContent, isKeyBoardPaste, plainTextMode, internal) { var content, isPlainTextHtml; if (hasContentType(clipboardContent, 'text/html')) { content = clipboardContent['text/html']; } else { content = pasteBin.getHtml(); internal = internal ? internal : InternalHtml.isMarked(content); if (pasteBin.isDefaultContent(content)) { plainTextMode = true; } } content = Utils.trimHtml(content); pasteBin.remove(); isPlainTextHtml = internal === false && Newlines.isPlainText(content); if (!content.length || isPlainTextHtml) { plainTextMode = true; } if (plainTextMode) { if (hasContentType(clipboardContent, 'text/plain') && isPlainTextHtml) { content = clipboardContent['text/plain']; } else { content = Utils.innerText(content); } } if (pasteBin.isDefaultContent(content)) { if (!isKeyBoardPaste) { editor.windowManager.alert('Please use Ctrl+V/Cmd+V keyboard shortcuts to paste contents.'); } return; } if (plainTextMode) { pasteText(editor, content); } else { pasteHtml$1(editor, content, internal); } } var getLastRng = function () { return pasteBin.getLastRng() || editor.selection.getRng(); }; editor.on('paste', function (e) { var clipboardTimer = new Date().getTime(); var clipboardContent = getClipboardContent(editor, e); var clipboardDelay = new Date().getTime() - clipboardTimer; var isKeyBoardPaste = new Date().getTime() - keyboardPasteTimeStamp - clipboardDelay < 1000; var plainTextMode = pasteFormat.get() === 'text' || keyboardPastePlainTextState; var internal = hasContentType(clipboardContent, InternalHtml.internalHtmlMime()); keyboardPastePlainTextState = false; if (e.isDefaultPrevented() || isBrokenAndroidClipboardEvent(e)) { pasteBin.remove(); return; } if (!hasHtmlOrText(clipboardContent) && pasteImageData(editor, e, getLastRng())) { pasteBin.remove(); return; } if (!isKeyBoardPaste) { e.preventDefault(); } if (global$1.ie && (!isKeyBoardPaste || e.ieFake) && !hasContentType(clipboardContent, 'text/html')) { pasteBin.create(); editor.dom.bind(pasteBin.getEl(), 'paste', function (e) { e.stopPropagation(); }); editor.getDoc().execCommand('Paste', false, null); clipboardContent['text/html'] = pasteBin.getHtml(); } if (hasContentType(clipboardContent, 'text/html')) { e.preventDefault(); if (!internal) { internal = InternalHtml.isMarked(clipboardContent['text/html']); } insertClipboardContent(clipboardContent, isKeyBoardPaste, plainTextMode, internal); } else { global$2.setEditorTimeout(editor, function () { insertClipboardContent(clipboardContent, isKeyBoardPaste, plainTextMode, internal); }, 0); } }); }; var registerEventsAndFilters = function (editor, pasteBin, pasteFormat) { registerEventHandlers(editor, pasteBin, pasteFormat); var src; editor.parser.addNodeFilter('img', function (nodes, name, args) { var isPasteInsert = function (args) { return args.data && args.data.paste === true; }; var remove = function (node) { if (!node.attr('data-mce-object') && src !== global$1.transparentSrc) { node.remove(); } }; var isWebKitFakeUrl = function (src) { return src.indexOf('webkit-fake-url') === 0; }; var isDataUri = function (src) { return src.indexOf('data:') === 0; }; if (!editor.settings.paste_data_images && isPasteInsert(args)) { var i = nodes.length; while (i--) { src = nodes[i].attributes.map.src; if (!src) { continue; } if (isWebKitFakeUrl(src)) { remove(nodes[i]); } else if (!editor.settings.allow_html_data_urls && isDataUri(src)) { remove(nodes[i]); } } } }); }; var getPasteBinParent = function (editor) { return global$1.ie && editor.inline ? domGlobals.document.body : editor.getBody(); }; var isExternalPasteBin = function (editor) { return getPasteBinParent(editor) !== editor.getBody(); }; var delegatePasteEvents = function (editor, pasteBinElm, pasteBinDefaultContent) { if (isExternalPasteBin(editor)) { editor.dom.bind(pasteBinElm, 'paste keyup', function (e) { if (!isDefault(editor, pasteBinDefaultContent)) { editor.fire('paste'); } }); } }; var create = function (editor, lastRngCell, pasteBinDefaultContent) { var dom = editor.dom, body = editor.getBody(); var pasteBinElm; lastRngCell.set(editor.selection.getRng()); pasteBinElm = editor.dom.add(getPasteBinParent(editor), 'div', { 'id': 'mcepastebin', 'class': 'mce-pastebin', 'contentEditable': true, 'data-mce-bogus': 'all', 'style': 'position: fixed; top: 50%; width: 10px; height: 10px; overflow: hidden; opacity: 0' }, pasteBinDefaultContent); if (global$1.ie || global$1.gecko) { dom.setStyle(pasteBinElm, 'left', dom.getStyle(body, 'direction', true) === 'rtl' ? 65535 : -65535); } dom.bind(pasteBinElm, 'beforedeactivate focusin focusout', function (e) { e.stopPropagation(); }); delegatePasteEvents(editor, pasteBinElm, pasteBinDefaultContent); pasteBinElm.focus(); editor.selection.select(pasteBinElm, true); }; var remove = function (editor, lastRngCell) { if (getEl(editor)) { var pasteBinClone = void 0; var lastRng = lastRngCell.get(); while (pasteBinClone = editor.dom.get('mcepastebin')) { editor.dom.remove(pasteBinClone); editor.dom.unbind(pasteBinClone); } if (lastRng) { editor.selection.setRng(lastRng); } } lastRngCell.set(null); }; var getEl = function (editor) { return editor.dom.get('mcepastebin'); }; var getHtml = function (editor) { var pasteBinElm, pasteBinClones, i, dirtyWrappers, cleanWrapper; var copyAndRemove = function (toElm, fromElm) { toElm.appendChild(fromElm); editor.dom.remove(fromElm, true); }; pasteBinClones = global$3.grep(getPasteBinParent(editor).childNodes, function (elm) { return elm.id === 'mcepastebin'; }); pasteBinElm = pasteBinClones.shift(); global$3.each(pasteBinClones, function (pasteBinClone) { copyAndRemove(pasteBinElm, pasteBinClone); }); dirtyWrappers = editor.dom.select('div[id=mcepastebin]', pasteBinElm); for (i = dirtyWrappers.length - 1; i >= 0; i--) { cleanWrapper = editor.dom.create('div'); pasteBinElm.insertBefore(cleanWrapper, dirtyWrappers[i]); copyAndRemove(cleanWrapper, dirtyWrappers[i]); } return pasteBinElm ? pasteBinElm.innerHTML : ''; }; var getLastRng = function (lastRng) { return lastRng.get(); }; var isDefaultContent = function (pasteBinDefaultContent, content) { return content === pasteBinDefaultContent; }; var isPasteBin = function (elm) { return elm && elm.id === 'mcepastebin'; }; var isDefault = function (editor, pasteBinDefaultContent) { var pasteBinElm = getEl(editor); return isPasteBin(pasteBinElm) && isDefaultContent(pasteBinDefaultContent, pasteBinElm.innerHTML); }; var PasteBin = function (editor) { var lastRng = Cell(null); var pasteBinDefaultContent = '%MCEPASTEBIN%'; return { create: function () { return create(editor, lastRng, pasteBinDefaultContent); }, remove: function () { return remove(editor, lastRng); }, getEl: function () { return getEl(editor); }, getHtml: function () { return getHtml(editor); }, getLastRng: function () { return getLastRng(lastRng); }, isDefault: function () { return isDefault(editor, pasteBinDefaultContent); }, isDefaultContent: function (content) { return isDefaultContent(pasteBinDefaultContent, content); } }; }; var Clipboard = function (editor, pasteFormat) { var pasteBin = PasteBin(editor); editor.on('preInit', function () { return registerEventsAndFilters(editor, pasteBin, pasteFormat); }); return { pasteFormat: pasteFormat, pasteHtml: function (html, internalFlag) { return pasteHtml$1(editor, html, internalFlag); }, pasteText: function (text) { return pasteText(editor, text); }, pasteImageData: function (e, rng) { return pasteImageData(editor, e, rng); }, getDataTransferItems: getDataTransferItems, hasHtmlOrText: hasHtmlOrText, hasContentType: hasContentType }; }; var noop = function () { }; var hasWorkingClipboardApi = function (clipboardData) { return global$1.iOS === false && clipboardData !== undefined && typeof clipboardData.setData === 'function' && Utils.isMsEdge() !== true; }; var setHtml5Clipboard = function (clipboardData, html, text) { if (hasWorkingClipboardApi(clipboardData)) { try { clipboardData.clearData(); clipboardData.setData('text/html', html); clipboardData.setData('text/plain', text); clipboardData.setData(InternalHtml.internalHtmlMime(), html); return true; } catch (e) { return false; } } else { return false; } }; var setClipboardData = function (evt, data, fallback, done) { if (setHtml5Clipboard(evt.clipboardData, data.html, data.text)) { evt.preventDefault(); done(); } else { fallback(data.html, done); } }; var fallback = function (editor) { return function (html, done) { var markedHtml = InternalHtml.mark(html); var outer = editor.dom.create('div', { 'contenteditable': 'false', 'data-mce-bogus': 'all' }); var inner = editor.dom.create('div', { contenteditable: 'true' }, markedHtml); editor.dom.setStyles(outer, { position: 'fixed', top: '0', left: '-3000px', width: '1000px', overflow: 'hidden' }); outer.appendChild(inner); editor.dom.add(editor.getBody(), outer); var range = editor.selection.getRng(); inner.focus(); var offscreenRange = editor.dom.createRng(); offscreenRange.selectNodeContents(inner); editor.selection.setRng(offscreenRange); setTimeout(function () { editor.selection.setRng(range); outer.parentNode.removeChild(outer); done(); }, 0); }; }; var getData = function (editor) { return { html: editor.selection.getContent({ contextual: true }), text: editor.selection.getContent({ format: 'text' }) }; }; var isTableSelection = function (editor) { return !!editor.dom.getParent(editor.selection.getStart(), 'td[data-mce-selected],th[data-mce-selected]', editor.getBody()); }; var hasSelectedContent = function (editor) { return !editor.selection.isCollapsed() || isTableSelection(editor); }; var cut = function (editor) { return function (evt) { if (hasSelectedContent(editor)) { setClipboardData(evt, getData(editor), fallback(editor), function () { setTimeout(function () { editor.execCommand('Delete'); }, 0); }); } }; }; var copy = function (editor) { return function (evt) { if (hasSelectedContent(editor)) { setClipboardData(evt, getData(editor), fallback(editor), noop); } }; }; var register$1 = function (editor) { editor.on('cut', cut(editor)); editor.on('copy', copy(editor)); }; var CutCopy = { register: register$1 }; var global$a = tinymce.util.Tools.resolve('tinymce.dom.RangeUtils'); var getCaretRangeFromEvent = function (editor, e) { return global$a.getCaretRangeFromPoint(e.clientX, e.clientY, editor.getDoc()); }; var isPlainTextFileUrl = function (content) { var plainTextContent = content['text/plain']; return plainTextContent ? plainTextContent.indexOf('file://') === 0 : false; }; var setFocusedRange = function (editor, rng) { editor.focus(); editor.selection.setRng(rng); }; var setup = function (editor, clipboard, draggingInternallyState) { if (Settings.shouldBlockDrop(editor)) { editor.on('dragend dragover draggesture dragdrop drop drag', function (e) { e.preventDefault(); e.stopPropagation(); }); } if (!Settings.shouldPasteDataImages(editor)) { editor.on('drop', function (e) { var dataTransfer = e.dataTransfer; if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) { e.preventDefault(); } }); } editor.on('drop', function (e) { var dropContent, rng; rng = getCaretRangeFromEvent(editor, e); if (e.isDefaultPrevented() || draggingInternallyState.get()) { return; } dropContent = clipboard.getDataTransferItems(e.dataTransfer); var internal = clipboard.hasContentType(dropContent, InternalHtml.internalHtmlMime()); if ((!clipboard.hasHtmlOrText(dropContent) || isPlainTextFileUrl(dropContent)) && clipboard.pasteImageData(e, rng)) { return; } if (rng && Settings.shouldFilterDrop(editor)) { var content_1 = dropContent['mce-internal'] || dropContent['text/html'] || dropContent['text/plain']; if (content_1) { e.preventDefault(); global$2.setEditorTimeout(editor, function () { editor.undoManager.transact(function () { if (dropContent['mce-internal']) { editor.execCommand('Delete'); } setFocusedRange(editor, rng); content_1 = Utils.trimHtml(content_1); if (!dropContent['text/html']) { clipboard.pasteText(content_1); } else { clipboard.pasteHtml(content_1, internal); } }); }); } } }); editor.on('dragstart', function (e) { draggingInternallyState.set(true); }); editor.on('dragover dragend', function (e) { if (Settings.shouldPasteDataImages(editor) && draggingInternallyState.get() === false) { e.preventDefault(); setFocusedRange(editor, getCaretRangeFromEvent(editor, e)); } if (e.type === 'dragend') { draggingInternallyState.set(false); } }); }; var DragDrop = { setup: setup }; var setup$1 = function (editor) { var plugin = editor.plugins.paste; var preProcess = Settings.getPreProcess(editor); if (preProcess) { editor.on('PastePreProcess', function (e) { preProcess.call(plugin, plugin, e); }); } var postProcess = Settings.getPostProcess(editor); if (postProcess) { editor.on('PastePostProcess', function (e) { postProcess.call(plugin, plugin, e); }); } }; var PrePostProcess = { setup: setup$1 }; function addPreProcessFilter(editor, filterFunc) { editor.on('PastePreProcess', function (e) { e.content = filterFunc(editor, e.content, e.internal, e.wordContent); }); } function addPostProcessFilter(editor, filterFunc) { editor.on('PastePostProcess', function (e) { filterFunc(editor, e.node); }); } function removeExplorerBrElementsAfterBlocks(editor, html) { if (!WordFilter.isWordContent(html)) { return html; } var blockElements = []; global$3.each(editor.schema.getBlockElements(), function (block, blockName) { blockElements.push(blockName); }); var explorerBlocksRegExp = new RegExp('(?:<br> [\\s\\r\\n]+|<br>)*(<\\/?(' + blockElements.join('|') + ')[^>]*>)(?:<br> [\\s\\r\\n]+|<br>)*', 'g'); html = Utils.filter(html, [[ explorerBlocksRegExp, '$1' ]]); html = Utils.filter(html, [ [ /<br><br>/g, '<BR><BR>' ], [ /<br>/g, ' ' ], [ /<BR><BR>/g, '<br>' ] ]); return html; } function removeWebKitStyles(editor, content, internal, isWordHtml) { if (isWordHtml || internal) { return content; } var webKitStylesSetting = Settings.getWebkitStyles(editor); var webKitStyles; if (Settings.shouldRemoveWebKitStyles(editor) === false || webKitStylesSetting === 'all') { return content; } if (webKitStylesSetting) { webKitStyles = webKitStylesSetting.split(/[, ]/); } if (webKitStyles) { var dom_1 = editor.dom, node_1 = editor.selection.getNode(); content = content.replace(/(<[^>]+) style="([^"]*)"([^>]*>)/gi, function (all, before, value, after) { var inputStyles = dom_1.parseStyle(dom_1.decode(value)); var outputStyles = {}; if (webKitStyles === 'none') { return before + after; } for (var i = 0; i < webKitStyles.length; i++) { var inputValue = inputStyles[webKitStyles[i]], currentValue = dom_1.getStyle(node_1, webKitStyles[i], true); if (/color/.test(webKitStyles[i])) { inputValue = dom_1.toHex(inputValue); currentValue = dom_1.toHex(currentValue); } if (currentValue !== inputValue) { outputStyles[webKitStyles[i]] = inputValue; } } outputStyles = dom_1.serializeStyle(outputStyles, 'span'); if (outputStyles) { return before + ' style="' + outputStyles + '"' + after; } return before + after; }); } else { content = content.replace(/(<[^>]+) style="([^"]*)"([^>]*>)/gi, '$1$3'); } content = content.replace(/(<[^>]+) data-mce-style="([^"]+)"([^>]*>)/gi, function (all, before, value, after) { return before + ' style="' + value + '"' + after; }); return content; } function removeUnderlineAndFontInAnchor(editor, root) { editor.$('a', root).find('font,u').each(function (i, node) { editor.dom.remove(node, true); }); } var setup$2 = function (editor) { if (global$1.webkit) { addPreProcessFilter(editor, removeWebKitStyles); } if (global$1.ie) { addPreProcessFilter(editor, removeExplorerBrElementsAfterBlocks); addPostProcessFilter(editor, removeUnderlineAndFontInAnchor); } }; var Quirks = { setup: setup$2 }; var stateChange = function (editor, clipboard, e) { var ctrl = e.control; ctrl.active(clipboard.pasteFormat.get() === 'text'); editor.on('PastePlainTextToggle', function (e) { ctrl.active(e.state); }); }; var register$2 = function (editor, clipboard) { var postRender = curry(stateChange, editor, clipboard); editor.addButton('pastetext', { active: false, icon: 'pastetext', tooltip: 'Paste as text', cmd: 'mceTogglePlainTextPaste', onPostRender: postRender }); editor.addMenuItem('pastetext', { text: 'Paste as text', selectable: true, active: clipboard.pasteFormat, cmd: 'mceTogglePlainTextPaste', onPostRender: postRender }); }; var Buttons = { register: register$2 }; global.add('paste', function (editor) { if (DetectProPlugin.hasProPlugin(editor) === false) { var userIsInformedState = Cell(false); var draggingInternallyState = Cell(false); var pasteFormat = Cell(Settings.isPasteAsTextEnabled(editor) ? 'text' : 'html'); var clipboard = Clipboard(editor, pasteFormat); var quirks = Quirks.setup(editor); Buttons.register(editor, clipboard); Commands.register(editor, clipboard, userIsInformedState); PrePostProcess.setup(editor); CutCopy.register(editor); DragDrop.setup(editor, clipboard, draggingInternallyState); return Api.get(clipboard, quirks); } }); function Plugin () { } return Plugin; }(window)); })(); (function () { var preview = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.Env'); var getPreviewDialogWidth = function (editor) { return parseInt(editor.getParam('plugin_preview_width', '650'), 10); }; var getPreviewDialogHeight = function (editor) { return parseInt(editor.getParam('plugin_preview_height', '500'), 10); }; var getContentStyle = function (editor) { return editor.getParam('content_style', ''); }; var Settings = { getPreviewDialogWidth: getPreviewDialogWidth, getPreviewDialogHeight: getPreviewDialogHeight, getContentStyle: getContentStyle }; var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var getPreviewHtml = function (editor) { var previewHtml; var headHtml = ''; var encode = editor.dom.encode; var contentStyle = Settings.getContentStyle(editor); headHtml += '<base href="' + encode(editor.documentBaseURI.getURI()) + '">'; if (contentStyle) { headHtml += '<style type="text/css">' + contentStyle + '</style>'; } global$2.each(editor.contentCSS, function (url) { headHtml += '<link type="text/css" rel="stylesheet" href="' + encode(editor.documentBaseURI.toAbsolute(url)) + '">'; }); var bodyId = editor.settings.body_id || 'tinymce'; if (bodyId.indexOf('=') !== -1) { bodyId = editor.getParam('body_id', '', 'hash'); bodyId = bodyId[editor.id] || bodyId; } var bodyClass = editor.settings.body_class || ''; if (bodyClass.indexOf('=') !== -1) { bodyClass = editor.getParam('body_class', '', 'hash'); bodyClass = bodyClass[editor.id] || ''; } var preventClicksOnLinksScript = '<script>' + 'document.addEventListener && document.addEventListener("click", function(e) {' + 'for (var elm = e.target; elm; elm = elm.parentNode) {' + 'if (elm.nodeName === "A") {' + 'e.preventDefault();' + '}' + '}' + '}, false);' + '</script> '; var dirAttr = editor.settings.directionality ? ' dir="' + editor.settings.directionality + '"' : ''; previewHtml = '<!DOCTYPE html>' + '<html>' + '<head>' + headHtml + '</head>' + '<body id="' + encode(bodyId) + '" class="mce-content-body ' + encode(bodyClass) + '"' + encode(dirAttr) + '>' + editor.getContent() + preventClicksOnLinksScript + '</body>' + '</html>'; return previewHtml; }; var injectIframeContent = function (editor, iframe, sandbox) { var previewHtml = getPreviewHtml(editor); if (!sandbox) { var doc = iframe.contentWindow.document; doc.open(); doc.write(previewHtml); doc.close(); } else { iframe.src = 'data:text/html;charset=utf-8,' + encodeURIComponent(previewHtml); } }; var IframeContent = { getPreviewHtml: getPreviewHtml, injectIframeContent: injectIframeContent }; var open = function (editor) { var sandbox = !global$1.ie; var dialogHtml = '<iframe src="" frameborder="0"' + (sandbox ? ' sandbox="allow-scripts"' : '') + '></iframe>'; var dialogWidth = Settings.getPreviewDialogWidth(editor); var dialogHeight = Settings.getPreviewDialogHeight(editor); editor.windowManager.open({ title: 'Preview', width: dialogWidth, height: dialogHeight, html: dialogHtml, buttons: { text: 'Close', onclick: function (e) { e.control.parent().parent().close(); } }, onPostRender: function (e) { var iframeElm = e.control.getEl('body').firstChild; IframeContent.injectIframeContent(editor, iframeElm, sandbox); } }); }; var Dialog = { open: open }; var register = function (editor) { editor.addCommand('mcePreview', function () { Dialog.open(editor); }); }; var Commands = { register: register }; var register$1 = function (editor) { editor.addButton('preview', { title: 'Preview', cmd: 'mcePreview' }); editor.addMenuItem('preview', { text: 'Preview', cmd: 'mcePreview', context: 'view' }); }; var Buttons = { register: register$1 }; global.add('preview', function (editor) { Commands.register(editor); Buttons.register(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var print = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var register = function (editor) { editor.addCommand('mcePrint', function () { editor.getWin().print(); }); }; var Commands = { register: register }; var register$1 = function (editor) { editor.addButton('print', { title: 'Print', cmd: 'mcePrint' }); editor.addMenuItem('print', { text: 'Print', cmd: 'mcePrint', icon: 'print' }); }; var Buttons = { register: register$1 }; global.add('print', function (editor) { Commands.register(editor); Buttons.register(editor); editor.addShortcut('Meta+P', '', 'mcePrint'); }); function Plugin () { } return Plugin; }()); })(); (function () { var save = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var enableWhenDirty = function (editor) { return editor.getParam('save_enablewhendirty', true); }; var hasOnSaveCallback = function (editor) { return !!editor.getParam('save_onsavecallback'); }; var hasOnCancelCallback = function (editor) { return !!editor.getParam('save_oncancelcallback'); }; var Settings = { enableWhenDirty: enableWhenDirty, hasOnSaveCallback: hasOnSaveCallback, hasOnCancelCallback: hasOnCancelCallback }; var displayErrorMessage = function (editor, message) { editor.notificationManager.open({ text: editor.translate(message), type: 'error' }); }; var save = function (editor) { var formObj; formObj = global$1.DOM.getParent(editor.id, 'form'); if (Settings.enableWhenDirty(editor) && !editor.isDirty()) { return; } editor.save(); if (Settings.hasOnSaveCallback(editor)) { editor.execCallback('save_onsavecallback', editor); editor.nodeChanged(); return; } if (formObj) { editor.setDirty(false); if (!formObj.onsubmit || formObj.onsubmit()) { if (typeof formObj.submit === 'function') { formObj.submit(); } else { displayErrorMessage(editor, 'Error: Form submit field collision.'); } } editor.nodeChanged(); } else { displayErrorMessage(editor, 'Error: No form element found.'); } }; var cancel = function (editor) { var h = global$2.trim(editor.startContent); if (Settings.hasOnCancelCallback(editor)) { editor.execCallback('save_oncancelcallback', editor); return; } editor.setContent(h); editor.undoManager.clear(); editor.nodeChanged(); }; var Actions = { save: save, cancel: cancel }; var register = function (editor) { editor.addCommand('mceSave', function () { Actions.save(editor); }); editor.addCommand('mceCancel', function () { Actions.cancel(editor); }); }; var Commands = { register: register }; var stateToggle = function (editor) { return function (e) { var ctrl = e.control; editor.on('nodeChange dirty', function () { ctrl.disabled(Settings.enableWhenDirty(editor) && !editor.isDirty()); }); }; }; var register$1 = function (editor) { editor.addButton('save', { icon: 'save', text: 'Save', cmd: 'mceSave', disabled: true, onPostRender: stateToggle(editor) }); editor.addButton('cancel', { text: 'Cancel', icon: false, cmd: 'mceCancel', disabled: true, onPostRender: stateToggle(editor) }); editor.addShortcut('Meta+S', '', 'mceSave'); }; var Buttons = { register: register$1 }; global.add('save', function (editor) { Buttons.register(editor); Commands.register(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var searchreplace = (function () { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); function isContentEditableFalse(node) { return node && node.nodeType === 1 && node.contentEditable === 'false'; } function findAndReplaceDOMText(regex, node, replacementNode, captureGroup, schema) { var m; var matches = []; var text, count = 0, doc; var blockElementsMap, hiddenTextElementsMap, shortEndedElementsMap; doc = node.ownerDocument; blockElementsMap = schema.getBlockElements(); hiddenTextElementsMap = schema.getWhiteSpaceElements(); shortEndedElementsMap = schema.getShortEndedElements(); function getMatchIndexes(m, captureGroup) { captureGroup = captureGroup || 0; if (!m[0]) { throw new Error('findAndReplaceDOMText cannot handle zero-length matches'); } var index = m.index; if (captureGroup > 0) { var cg = m[captureGroup]; if (!cg) { throw new Error('Invalid capture group'); } index += m[0].indexOf(cg); m[0] = cg; } return [ index, index + m[0].length, [m[0]] ]; } function getText(node) { var txt; if (node.nodeType === 3) { return node.data; } if (hiddenTextElementsMap[node.nodeName] && !blockElementsMap[node.nodeName]) { return ''; } txt = ''; if (isContentEditableFalse(node)) { return '\n'; } if (blockElementsMap[node.nodeName] || shortEndedElementsMap[node.nodeName]) { txt += '\n'; } if (node = node.firstChild) { do { txt += getText(node); } while (node = node.nextSibling); } return txt; } function stepThroughMatches(node, matches, replaceFn) { var startNode, endNode, startNodeIndex, endNodeIndex, innerNodes = [], atIndex = 0, curNode = node, matchLocation = matches.shift(), matchIndex = 0; out: while (true) { if (blockElementsMap[curNode.nodeName] || shortEndedElementsMap[curNode.nodeName] || isContentEditableFalse(curNode)) { atIndex++; } if (curNode.nodeType === 3) { if (!endNode && curNode.length + atIndex >= matchLocation[1]) { endNode = curNode; endNodeIndex = matchLocation[1] - atIndex; } else if (startNode) { innerNodes.push(curNode); } if (!startNode && curNode.length + atIndex > matchLocation[0]) { startNode = curNode; startNodeIndex = matchLocation[0] - atIndex; } atIndex += curNode.length; } if (startNode && endNode) { curNode = replaceFn({ startNode: startNode, startNodeIndex: startNodeIndex, endNode: endNode, endNodeIndex: endNodeIndex, innerNodes: innerNodes, match: matchLocation[2], matchIndex: matchIndex }); atIndex -= endNode.length - endNodeIndex; startNode = null; endNode = null; innerNodes = []; matchLocation = matches.shift(); matchIndex++; if (!matchLocation) { break; } } else if ((!hiddenTextElementsMap[curNode.nodeName] || blockElementsMap[curNode.nodeName]) && curNode.firstChild) { if (!isContentEditableFalse(curNode)) { curNode = curNode.firstChild; continue; } } else if (curNode.nextSibling) { curNode = curNode.nextSibling; continue; } while (true) { if (curNode.nextSibling) { curNode = curNode.nextSibling; break; } else if (curNode.parentNode !== node) { curNode = curNode.parentNode; } else { break out; } } } } function genReplacer(nodeName) { var makeReplacementNode; if (typeof nodeName !== 'function') { var stencilNode_1 = nodeName.nodeType ? nodeName : doc.createElement(nodeName); makeReplacementNode = function (fill, matchIndex) { var clone = stencilNode_1.cloneNode(false); clone.setAttribute('data-mce-index', matchIndex); if (fill) { clone.appendChild(doc.createTextNode(fill)); } return clone; }; } else { makeReplacementNode = nodeName; } return function (range) { var before; var after; var parentNode; var startNode = range.startNode; var endNode = range.endNode; var matchIndex = range.matchIndex; if (startNode === endNode) { var node_1 = startNode; parentNode = node_1.parentNode; if (range.startNodeIndex > 0) { before = doc.createTextNode(node_1.data.substring(0, range.startNodeIndex)); parentNode.insertBefore(before, node_1); } var el = makeReplacementNode(range.match[0], matchIndex); parentNode.insertBefore(el, node_1); if (range.endNodeIndex < node_1.length) { after = doc.createTextNode(node_1.data.substring(range.endNodeIndex)); parentNode.insertBefore(after, node_1); } node_1.parentNode.removeChild(node_1); return el; } before = doc.createTextNode(startNode.data.substring(0, range.startNodeIndex)); after = doc.createTextNode(endNode.data.substring(range.endNodeIndex)); var elA = makeReplacementNode(startNode.data.substring(range.startNodeIndex), matchIndex); for (var i = 0, l = range.innerNodes.length; i < l; ++i) { var innerNode = range.innerNodes[i]; var innerEl = makeReplacementNode(innerNode.data, matchIndex); innerNode.parentNode.replaceChild(innerEl, innerNode); } var elB = makeReplacementNode(endNode.data.substring(0, range.endNodeIndex), matchIndex); parentNode = startNode.parentNode; parentNode.insertBefore(before, startNode); parentNode.insertBefore(elA, startNode); parentNode.removeChild(startNode); parentNode = endNode.parentNode; parentNode.insertBefore(elB, endNode); parentNode.insertBefore(after, endNode); parentNode.removeChild(endNode); return elB; }; } text = getText(node); if (!text) { return; } if (regex.global) { while (m = regex.exec(text)) { matches.push(getMatchIndexes(m, captureGroup)); } } else { m = text.match(regex); matches.push(getMatchIndexes(m, captureGroup)); } if (matches.length) { count = matches.length; stepThroughMatches(node, matches, genReplacer(replacementNode)); } return count; } var FindReplaceText = { findAndReplaceDOMText: findAndReplaceDOMText }; var getElmIndex = function (elm) { var value = elm.getAttribute('data-mce-index'); if (typeof value === 'number') { return '' + value; } return value; }; var markAllMatches = function (editor, currentIndexState, regex) { var node, marker; marker = editor.dom.create('span', { 'data-mce-bogus': 1 }); marker.className = 'mce-match-marker'; node = editor.getBody(); done(editor, currentIndexState, false); return FindReplaceText.findAndReplaceDOMText(regex, node, marker, false, editor.schema); }; var unwrap = function (node) { var parentNode = node.parentNode; if (node.firstChild) { parentNode.insertBefore(node.firstChild, node); } node.parentNode.removeChild(node); }; var findSpansByIndex = function (editor, index) { var nodes; var spans = []; nodes = global$1.toArray(editor.getBody().getElementsByTagName('span')); if (nodes.length) { for (var i = 0; i < nodes.length; i++) { var nodeIndex = getElmIndex(nodes[i]); if (nodeIndex === null || !nodeIndex.length) { continue; } if (nodeIndex === index.toString()) { spans.push(nodes[i]); } } } return spans; }; var moveSelection = function (editor, currentIndexState, forward) { var testIndex = currentIndexState.get(); var dom = editor.dom; forward = forward !== false; if (forward) { testIndex++; } else { testIndex--; } dom.removeClass(findSpansByIndex(editor, currentIndexState.get()), 'mce-match-marker-selected'); var spans = findSpansByIndex(editor, testIndex); if (spans.length) { dom.addClass(findSpansByIndex(editor, testIndex), 'mce-match-marker-selected'); editor.selection.scrollIntoView(spans[0]); return testIndex; } return -1; }; var removeNode = function (dom, node) { var parent = node.parentNode; dom.remove(node); if (dom.isEmpty(parent)) { dom.remove(parent); } }; var find = function (editor, currentIndexState, text, matchCase, wholeWord) { text = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); text = text.replace(/\s/g, '[^\\S\\r\\n]'); text = wholeWord ? '\\b' + text + '\\b' : text; var count = markAllMatches(editor, currentIndexState, new RegExp(text, matchCase ? 'g' : 'gi')); if (count) { currentIndexState.set(-1); currentIndexState.set(moveSelection(editor, currentIndexState, true)); } return count; }; var next = function (editor, currentIndexState) { var index = moveSelection(editor, currentIndexState, true); if (index !== -1) { currentIndexState.set(index); } }; var prev = function (editor, currentIndexState) { var index = moveSelection(editor, currentIndexState, false); if (index !== -1) { currentIndexState.set(index); } }; var isMatchSpan = function (node) { var matchIndex = getElmIndex(node); return matchIndex !== null && matchIndex.length > 0; }; var replace = function (editor, currentIndexState, text, forward, all) { var i, nodes, node, matchIndex, currentMatchIndex, nextIndex = currentIndexState.get(), hasMore; forward = forward !== false; node = editor.getBody(); nodes = global$1.grep(global$1.toArray(node.getElementsByTagName('span')), isMatchSpan); for (i = 0; i < nodes.length; i++) { var nodeIndex = getElmIndex(nodes[i]); matchIndex = currentMatchIndex = parseInt(nodeIndex, 10); if (all || matchIndex === currentIndexState.get()) { if (text.length) { nodes[i].firstChild.nodeValue = text; unwrap(nodes[i]); } else { removeNode(editor.dom, nodes[i]); } while (nodes[++i]) { matchIndex = parseInt(getElmIndex(nodes[i]), 10); if (matchIndex === currentMatchIndex) { removeNode(editor.dom, nodes[i]); } else { i--; break; } } if (forward) { nextIndex--; } } else if (currentMatchIndex > currentIndexState.get()) { nodes[i].setAttribute('data-mce-index', currentMatchIndex - 1); } } currentIndexState.set(nextIndex); if (forward) { hasMore = hasNext(editor, currentIndexState); next(editor, currentIndexState); } else { hasMore = hasPrev(editor, currentIndexState); prev(editor, currentIndexState); } return !all && hasMore; }; var done = function (editor, currentIndexState, keepEditorSelection) { var i, nodes, startContainer, endContainer; nodes = global$1.toArray(editor.getBody().getElementsByTagName('span')); for (i = 0; i < nodes.length; i++) { var nodeIndex = getElmIndex(nodes[i]); if (nodeIndex !== null && nodeIndex.length) { if (nodeIndex === currentIndexState.get().toString()) { if (!startContainer) { startContainer = nodes[i].firstChild; } endContainer = nodes[i].firstChild; } unwrap(nodes[i]); } } if (startContainer && endContainer) { var rng = editor.dom.createRng(); rng.setStart(startContainer, 0); rng.setEnd(endContainer, endContainer.data.length); if (keepEditorSelection !== false) { editor.selection.setRng(rng); } return rng; } }; var hasNext = function (editor, currentIndexState) { return findSpansByIndex(editor, currentIndexState.get() + 1).length > 0; }; var hasPrev = function (editor, currentIndexState) { return findSpansByIndex(editor, currentIndexState.get() - 1).length > 0; }; var Actions = { done: done, find: find, next: next, prev: prev, replace: replace, hasNext: hasNext, hasPrev: hasPrev }; var get = function (editor, currentIndexState) { var done = function (keepEditorSelection) { return Actions.done(editor, currentIndexState, keepEditorSelection); }; var find = function (text, matchCase, wholeWord) { return Actions.find(editor, currentIndexState, text, matchCase, wholeWord); }; var next = function () { return Actions.next(editor, currentIndexState); }; var prev = function () { return Actions.prev(editor, currentIndexState); }; var replace = function (text, forward, all) { return Actions.replace(editor, currentIndexState, text, forward, all); }; return { done: done, find: find, next: next, prev: prev, replace: replace }; }; var Api = { get: get }; var open = function (editor, currentIndexState) { var last = {}, selectedText; editor.undoManager.add(); selectedText = global$1.trim(editor.selection.getContent({ format: 'text' })); function updateButtonStates() { win.statusbar.find('#next').disabled(Actions.hasNext(editor, currentIndexState) === false); win.statusbar.find('#prev').disabled(Actions.hasPrev(editor, currentIndexState) === false); } function notFoundAlert() { editor.windowManager.alert('Could not find the specified string.', function () { win.find('#find')[0].focus(); }); } var win = editor.windowManager.open({ layout: 'flex', pack: 'center', align: 'center', onClose: function () { editor.focus(); Actions.done(editor, currentIndexState); editor.undoManager.add(); }, onSubmit: function (e) { var count, caseState, text, wholeWord; e.preventDefault(); caseState = win.find('#case').checked(); wholeWord = win.find('#words').checked(); text = win.find('#find').value(); if (!text.length) { Actions.done(editor, currentIndexState, false); win.statusbar.items().slice(1).disabled(true); return; } if (last.text === text && last.caseState === caseState && last.wholeWord === wholeWord) { if (!Actions.hasNext(editor, currentIndexState)) { notFoundAlert(); return; } Actions.next(editor, currentIndexState); updateButtonStates(); return; } count = Actions.find(editor, currentIndexState, text, caseState, wholeWord); if (!count) { notFoundAlert(); } win.statusbar.items().slice(1).disabled(count === 0); updateButtonStates(); last = { text: text, caseState: caseState, wholeWord: wholeWord }; }, buttons: [ { text: 'Find', subtype: 'primary', onclick: function () { win.submit(); } }, { text: 'Replace', disabled: true, onclick: function () { if (!Actions.replace(editor, currentIndexState, win.find('#replace').value())) { win.statusbar.items().slice(1).disabled(true); currentIndexState.set(-1); last = {}; } } }, { text: 'Replace all', disabled: true, onclick: function () { Actions.replace(editor, currentIndexState, win.find('#replace').value(), true, true); win.statusbar.items().slice(1).disabled(true); last = {}; } }, { type: 'spacer', flex: 1 }, { text: 'Prev', name: 'prev', disabled: true, onclick: function () { Actions.prev(editor, currentIndexState); updateButtonStates(); } }, { text: 'Next', name: 'next', disabled: true, onclick: function () { Actions.next(editor, currentIndexState); updateButtonStates(); } } ], title: 'Find and replace', items: { type: 'form', padding: 20, labelGap: 30, spacing: 10, items: [ { type: 'textbox', name: 'find', size: 40, label: 'Find', value: selectedText }, { type: 'textbox', name: 'replace', size: 40, label: 'Replace with' }, { type: 'checkbox', name: 'case', text: 'Match case', label: ' ' }, { type: 'checkbox', name: 'words', text: 'Whole words', label: ' ' } ] } }); }; var Dialog = { open: open }; var register = function (editor, currentIndexState) { editor.addCommand('SearchReplace', function () { Dialog.open(editor, currentIndexState); }); }; var Commands = { register: register }; var showDialog = function (editor, currentIndexState) { return function () { Dialog.open(editor, currentIndexState); }; }; var register$1 = function (editor, currentIndexState) { editor.addMenuItem('searchreplace', { text: 'Find and replace', shortcut: 'Meta+F', onclick: showDialog(editor, currentIndexState), separator: 'before', context: 'edit' }); editor.addButton('searchreplace', { tooltip: 'Find and replace', onclick: showDialog(editor, currentIndexState) }); editor.shortcuts.add('Meta+F', '', showDialog(editor, currentIndexState)); }; var Buttons = { register: register$1 }; global.add('searchreplace', function (editor) { var currentIndexState = Cell(-1); Commands.register(editor, currentIndexState); Buttons.register(editor, currentIndexState); return Api.get(editor, currentIndexState); }); function Plugin () { } return Plugin; }()); })(); (function () { var spellchecker = (function (domGlobals) { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var hasProPlugin = function (editor) { if (/(^|[ ,])tinymcespellchecker([, ]|$)/.test(editor.settings.plugins) && global.get('tinymcespellchecker')) { if (typeof domGlobals.window.console !== 'undefined' && domGlobals.window.console.log) { domGlobals.window.console.log('Spell Checker Pro is incompatible with Spell Checker plugin! ' + 'Remove \'spellchecker\' from the \'plugins\' option.'); } return true; } else { return false; } }; var DetectProPlugin = { hasProPlugin: hasProPlugin }; var getLanguages = function (editor) { var defaultLanguages = 'English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr_FR,German=de,Italian=it,Polish=pl,Portuguese=pt_BR,Spanish=es,Swedish=sv'; return editor.getParam('spellchecker_languages', defaultLanguages); }; var getLanguage = function (editor) { var defaultLanguage = editor.getParam('language', 'en'); return editor.getParam('spellchecker_language', defaultLanguage); }; var getRpcUrl = function (editor) { return editor.getParam('spellchecker_rpc_url'); }; var getSpellcheckerCallback = function (editor) { return editor.getParam('spellchecker_callback'); }; var getSpellcheckerWordcharPattern = function (editor) { var defaultPattern = new RegExp('[^' + '\\s!"#$%&()*+,-./:;<=>?@[\\]^_{|}`' + '\xA7\xA9\xAB\xAE\xB1\xB6\xB7\xB8\xBB' + '\xBC\xBD\xBE\xBF\xD7\xF7\xA4\u201D\u201C\u201E\xA0\u2002\u2003\u2009' + ']+', 'g'); return editor.getParam('spellchecker_wordchar_pattern', defaultPattern); }; var Settings = { getLanguages: getLanguages, getLanguage: getLanguage, getRpcUrl: getRpcUrl, getSpellcheckerCallback: getSpellcheckerCallback, getSpellcheckerWordcharPattern: getSpellcheckerWordcharPattern }; var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var global$2 = tinymce.util.Tools.resolve('tinymce.util.URI'); var global$3 = tinymce.util.Tools.resolve('tinymce.util.XHR'); var fireSpellcheckStart = function (editor) { return editor.fire('SpellcheckStart'); }; var fireSpellcheckEnd = function (editor) { return editor.fire('SpellcheckEnd'); }; var Events = { fireSpellcheckStart: fireSpellcheckStart, fireSpellcheckEnd: fireSpellcheckEnd }; function isContentEditableFalse(node) { return node && node.nodeType === 1 && node.contentEditable === 'false'; } var DomTextMatcher = function (node, editor) { var m, matches = [], text; var dom = editor.dom; var blockElementsMap, hiddenTextElementsMap, shortEndedElementsMap; blockElementsMap = editor.schema.getBlockElements(); hiddenTextElementsMap = editor.schema.getWhiteSpaceElements(); shortEndedElementsMap = editor.schema.getShortEndedElements(); function createMatch(m, data) { if (!m[0]) { throw new Error('findAndReplaceDOMText cannot handle zero-length matches'); } return { start: m.index, end: m.index + m[0].length, text: m[0], data: data }; } function getText(node) { var txt; if (node.nodeType === 3) { return node.data; } if (hiddenTextElementsMap[node.nodeName] && !blockElementsMap[node.nodeName]) { return ''; } if (isContentEditableFalse(node)) { return '\n'; } txt = ''; if (blockElementsMap[node.nodeName] || shortEndedElementsMap[node.nodeName]) { txt += '\n'; } if (node = node.firstChild) { do { txt += getText(node); } while (node = node.nextSibling); } return txt; } function stepThroughMatches(node, matches, replaceFn) { var startNode, endNode, startNodeIndex, endNodeIndex, innerNodes = [], atIndex = 0, curNode = node, matchLocation, matchIndex = 0; matches = matches.slice(0); matches.sort(function (a, b) { return a.start - b.start; }); matchLocation = matches.shift(); out: while (true) { if (blockElementsMap[curNode.nodeName] || shortEndedElementsMap[curNode.nodeName] || isContentEditableFalse(curNode)) { atIndex++; } if (curNode.nodeType === 3) { if (!endNode && curNode.length + atIndex >= matchLocation.end) { endNode = curNode; endNodeIndex = matchLocation.end - atIndex; } else if (startNode) { innerNodes.push(curNode); } if (!startNode && curNode.length + atIndex > matchLocation.start) { startNode = curNode; startNodeIndex = matchLocation.start - atIndex; } atIndex += curNode.length; } if (startNode && endNode) { curNode = replaceFn({ startNode: startNode, startNodeIndex: startNodeIndex, endNode: endNode, endNodeIndex: endNodeIndex, innerNodes: innerNodes, match: matchLocation.text, matchIndex: matchIndex }); atIndex -= endNode.length - endNodeIndex; startNode = null; endNode = null; innerNodes = []; matchLocation = matches.shift(); matchIndex++; if (!matchLocation) { break; } } else if ((!hiddenTextElementsMap[curNode.nodeName] || blockElementsMap[curNode.nodeName]) && curNode.firstChild) { if (!isContentEditableFalse(curNode)) { curNode = curNode.firstChild; continue; } } else if (curNode.nextSibling) { curNode = curNode.nextSibling; continue; } while (true) { if (curNode.nextSibling) { curNode = curNode.nextSibling; break; } else if (curNode.parentNode !== node) { curNode = curNode.parentNode; } else { break out; } } } } function genReplacer(callback) { function makeReplacementNode(fill, matchIndex) { var match = matches[matchIndex]; if (!match.stencil) { match.stencil = callback(match); } var clone = match.stencil.cloneNode(false); clone.setAttribute('data-mce-index', matchIndex); if (fill) { clone.appendChild(dom.doc.createTextNode(fill)); } return clone; } return function (range) { var before; var after; var parentNode; var startNode = range.startNode; var endNode = range.endNode; var matchIndex = range.matchIndex; var doc = dom.doc; if (startNode === endNode) { var node_1 = startNode; parentNode = node_1.parentNode; if (range.startNodeIndex > 0) { before = doc.createTextNode(node_1.data.substring(0, range.startNodeIndex)); parentNode.insertBefore(before, node_1); } var el = makeReplacementNode(range.match, matchIndex); parentNode.insertBefore(el, node_1); if (range.endNodeIndex < node_1.length) { after = doc.createTextNode(node_1.data.substring(range.endNodeIndex)); parentNode.insertBefore(after, node_1); } node_1.parentNode.removeChild(node_1); return el; } before = doc.createTextNode(startNode.data.substring(0, range.startNodeIndex)); after = doc.createTextNode(endNode.data.substring(range.endNodeIndex)); var elA = makeReplacementNode(startNode.data.substring(range.startNodeIndex), matchIndex); for (var i = 0, l = range.innerNodes.length; i < l; ++i) { var innerNode = range.innerNodes[i]; var innerEl = makeReplacementNode(innerNode.data, matchIndex); innerNode.parentNode.replaceChild(innerEl, innerNode); } var elB = makeReplacementNode(endNode.data.substring(0, range.endNodeIndex), matchIndex); parentNode = startNode.parentNode; parentNode.insertBefore(before, startNode); parentNode.insertBefore(elA, startNode); parentNode.removeChild(startNode); parentNode = endNode.parentNode; parentNode.insertBefore(elB, endNode); parentNode.insertBefore(after, endNode); parentNode.removeChild(endNode); return elB; }; } function unwrapElement(element) { var parentNode = element.parentNode; parentNode.insertBefore(element.firstChild, element); element.parentNode.removeChild(element); } function hasClass(elm) { return elm.className.indexOf('mce-spellchecker-word') !== -1; } function getWrappersByIndex(index) { var elements = node.getElementsByTagName('*'), wrappers = []; index = typeof index === 'number' ? '' + index : null; for (var i = 0; i < elements.length; i++) { var element = elements[i], dataIndex = element.getAttribute('data-mce-index'); if (dataIndex !== null && dataIndex.length && hasClass(element)) { if (dataIndex === index || index === null) { wrappers.push(element); } } } return wrappers; } function indexOf(match) { var i = matches.length; while (i--) { if (matches[i] === match) { return i; } } return -1; } function filter(callback) { var filteredMatches = []; each(function (match, i) { if (callback(match, i)) { filteredMatches.push(match); } }); matches = filteredMatches; return this; } function each(callback) { for (var i = 0, l = matches.length; i < l; i++) { if (callback(matches[i], i) === false) { break; } } return this; } function wrap(callback) { if (matches.length) { stepThroughMatches(node, matches, genReplacer(callback)); } return this; } function find(regex, data) { if (text && regex.global) { while (m = regex.exec(text)) { matches.push(createMatch(m, data)); } } return this; } function unwrap(match) { var i; var elements = getWrappersByIndex(match ? indexOf(match) : null); i = elements.length; while (i--) { unwrapElement(elements[i]); } return this; } function matchFromElement(element) { return matches[element.getAttribute('data-mce-index')]; } function elementFromMatch(match) { return getWrappersByIndex(indexOf(match))[0]; } function add(start, length, data) { matches.push({ start: start, end: start + length, text: text.substr(start, length), data: data }); return this; } function rangeFromMatch(match) { var wrappers = getWrappersByIndex(indexOf(match)); var rng = editor.dom.createRng(); rng.setStartBefore(wrappers[0]); rng.setEndAfter(wrappers[wrappers.length - 1]); return rng; } function replace(match, text) { var rng = rangeFromMatch(match); rng.deleteContents(); if (text.length > 0) { rng.insertNode(editor.dom.doc.createTextNode(text)); } return rng; } function reset() { matches.splice(0, matches.length); unwrap(); return this; } text = getText(node); return { text: text, matches: matches, each: each, filter: filter, reset: reset, matchFromElement: matchFromElement, elementFromMatch: elementFromMatch, find: find, add: add, wrap: wrap, unwrap: unwrap, replace: replace, rangeFromMatch: rangeFromMatch, indexOf: indexOf }; }; var getTextMatcher = function (editor, textMatcherState) { if (!textMatcherState.get()) { var textMatcher = DomTextMatcher(editor.getBody(), editor); textMatcherState.set(textMatcher); } return textMatcherState.get(); }; var isEmpty = function (obj) { for (var _ in obj) { return false; } return true; }; var defaultSpellcheckCallback = function (editor, pluginUrl, currentLanguageState) { return function (method, text, doneCallback, errorCallback) { var data = { method: method, lang: currentLanguageState.get() }; var postData = ''; data[method === 'addToDictionary' ? 'word' : 'text'] = text; global$1.each(data, function (value, key) { if (postData) { postData += '&'; } postData += key + '=' + encodeURIComponent(value); }); global$3.send({ url: new global$2(pluginUrl).toAbsolute(Settings.getRpcUrl(editor)), type: 'post', content_type: 'application/x-www-form-urlencoded', data: postData, success: function (result) { result = JSON.parse(result); if (!result) { var message = editor.translate('Server response wasn\'t proper JSON.'); errorCallback(message); } else if (result.error) { errorCallback(result.error); } else { doneCallback(result); } }, error: function () { var message = editor.translate('The spelling service was not found: (') + Settings.getRpcUrl(editor) + editor.translate(')'); errorCallback(message); } }); }; }; var sendRpcCall = function (editor, pluginUrl, currentLanguageState, name, data, successCallback, errorCallback) { var userSpellcheckCallback = Settings.getSpellcheckerCallback(editor); var spellCheckCallback = userSpellcheckCallback ? userSpellcheckCallback : defaultSpellcheckCallback(editor, pluginUrl, currentLanguageState); spellCheckCallback.call(editor.plugins.spellchecker, name, data, successCallback, errorCallback); }; var spellcheck = function (editor, pluginUrl, startedState, textMatcherState, lastSuggestionsState, currentLanguageState) { if (finish(editor, startedState, textMatcherState)) { return; } var errorCallback = function (message) { editor.notificationManager.open({ text: message, type: 'error' }); editor.setProgressState(false); finish(editor, startedState, textMatcherState); }; var successCallback = function (data) { markErrors(editor, startedState, textMatcherState, lastSuggestionsState, data); }; editor.setProgressState(true); sendRpcCall(editor, pluginUrl, currentLanguageState, 'spellcheck', getTextMatcher(editor, textMatcherState).text, successCallback, errorCallback); editor.focus(); }; var checkIfFinished = function (editor, startedState, textMatcherState) { if (!editor.dom.select('span.mce-spellchecker-word').length) { finish(editor, startedState, textMatcherState); } }; var addToDictionary = function (editor, pluginUrl, startedState, textMatcherState, currentLanguageState, word, spans) { editor.setProgressState(true); sendRpcCall(editor, pluginUrl, currentLanguageState, 'addToDictionary', word, function () { editor.setProgressState(false); editor.dom.remove(spans, true); checkIfFinished(editor, startedState, textMatcherState); }, function (message) { editor.notificationManager.open({ text: message, type: 'error' }); editor.setProgressState(false); }); }; var ignoreWord = function (editor, startedState, textMatcherState, word, spans, all) { editor.selection.collapse(); if (all) { global$1.each(editor.dom.select('span.mce-spellchecker-word'), function (span) { if (span.getAttribute('data-mce-word') === word) { editor.dom.remove(span, true); } }); } else { editor.dom.remove(spans, true); } checkIfFinished(editor, startedState, textMatcherState); }; var finish = function (editor, startedState, textMatcherState) { var bookmark = editor.selection.getBookmark(); getTextMatcher(editor, textMatcherState).reset(); editor.selection.moveToBookmark(bookmark); textMatcherState.set(null); if (startedState.get()) { startedState.set(false); Events.fireSpellcheckEnd(editor); return true; } }; var getElmIndex = function (elm) { var value = elm.getAttribute('data-mce-index'); if (typeof value === 'number') { return '' + value; } return value; }; var findSpansByIndex = function (editor, index) { var nodes; var spans = []; nodes = global$1.toArray(editor.getBody().getElementsByTagName('span')); if (nodes.length) { for (var i = 0; i < nodes.length; i++) { var nodeIndex = getElmIndex(nodes[i]); if (nodeIndex === null || !nodeIndex.length) { continue; } if (nodeIndex === index.toString()) { spans.push(nodes[i]); } } } return spans; }; var markErrors = function (editor, startedState, textMatcherState, lastSuggestionsState, data) { var suggestions, hasDictionarySupport; if (typeof data !== 'string' && data.words) { hasDictionarySupport = !!data.dictionary; suggestions = data.words; } else { suggestions = data; } editor.setProgressState(false); if (isEmpty(suggestions)) { var message = editor.translate('No misspellings found.'); editor.notificationManager.open({ text: message, type: 'info' }); startedState.set(false); return; } lastSuggestionsState.set({ suggestions: suggestions, hasDictionarySupport: hasDictionarySupport }); var bookmark = editor.selection.getBookmark(); getTextMatcher(editor, textMatcherState).find(Settings.getSpellcheckerWordcharPattern(editor)).filter(function (match) { return !!suggestions[match.text]; }).wrap(function (match) { return editor.dom.create('span', { 'class': 'mce-spellchecker-word', 'data-mce-bogus': 1, 'data-mce-word': match.text }); }); editor.selection.moveToBookmark(bookmark); startedState.set(true); Events.fireSpellcheckStart(editor); }; var Actions = { spellcheck: spellcheck, checkIfFinished: checkIfFinished, addToDictionary: addToDictionary, ignoreWord: ignoreWord, findSpansByIndex: findSpansByIndex, getElmIndex: getElmIndex, markErrors: markErrors }; var get = function (editor, startedState, lastSuggestionsState, textMatcherState, currentLanguageState, url) { var getLanguage = function () { return currentLanguageState.get(); }; var getWordCharPattern = function () { return Settings.getSpellcheckerWordcharPattern(editor); }; var markErrors = function (data) { Actions.markErrors(editor, startedState, textMatcherState, lastSuggestionsState, data); }; var getTextMatcher = function () { return textMatcherState.get(); }; return { getTextMatcher: getTextMatcher, getWordCharPattern: getWordCharPattern, markErrors: markErrors, getLanguage: getLanguage }; }; var Api = { get: get }; var register = function (editor, pluginUrl, startedState, textMatcherState, lastSuggestionsState, currentLanguageState) { editor.addCommand('mceSpellCheck', function () { Actions.spellcheck(editor, pluginUrl, startedState, textMatcherState, lastSuggestionsState, currentLanguageState); }); }; var Commands = { register: register }; var buildMenuItems = function (listName, languageValues) { var items = []; global$1.each(languageValues, function (languageValue) { items.push({ selectable: true, text: languageValue.name, data: languageValue.value }); }); return items; }; var updateSelection = function (editor, currentLanguageState) { return function (e) { var selectedLanguage = currentLanguageState.get(); e.control.items().each(function (ctrl) { ctrl.active(ctrl.settings.data === selectedLanguage); }); }; }; var getItems = function (editor) { return global$1.map(Settings.getLanguages(editor).split(','), function (langPair) { langPair = langPair.split('='); return { name: langPair[0], value: langPair[1] }; }); }; var register$1 = function (editor, pluginUrl, startedState, textMatcherState, currentLanguageState, lastSuggestionsState) { var languageMenuItems = buildMenuItems('Language', getItems(editor)); var startSpellchecking = function () { Actions.spellcheck(editor, pluginUrl, startedState, textMatcherState, lastSuggestionsState, currentLanguageState); }; var buttonArgs = { tooltip: 'Spellcheck', onclick: startSpellchecking, onPostRender: function (e) { var ctrl = e.control; editor.on('SpellcheckStart SpellcheckEnd', function () { ctrl.active(startedState.get()); }); } }; if (languageMenuItems.length > 1) { buttonArgs.type = 'splitbutton'; buttonArgs.menu = languageMenuItems; buttonArgs.onshow = updateSelection(editor, currentLanguageState); buttonArgs.onselect = function (e) { currentLanguageState.set(e.control.settings.data); }; } editor.addButton('spellchecker', buttonArgs); editor.addMenuItem('spellchecker', { text: 'Spellcheck', context: 'tools', onclick: startSpellchecking, selectable: true, onPostRender: function () { var self = this; self.active(startedState.get()); editor.on('SpellcheckStart SpellcheckEnd', function () { self.active(startedState.get()); }); } }); }; var Buttons = { register: register$1 }; var global$4 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var global$5 = tinymce.util.Tools.resolve('tinymce.ui.Factory'); var suggestionsMenu; var showSuggestions = function (editor, pluginUrl, lastSuggestionsState, startedState, textMatcherState, currentLanguageState, word, spans) { var items = [], suggestions = lastSuggestionsState.get().suggestions[word]; global$1.each(suggestions, function (suggestion) { items.push({ text: suggestion, onclick: function () { editor.insertContent(editor.dom.encode(suggestion)); editor.dom.remove(spans); Actions.checkIfFinished(editor, startedState, textMatcherState); } }); }); items.push({ text: '-' }); var hasDictionarySupport = lastSuggestionsState.get().hasDictionarySupport; if (hasDictionarySupport) { items.push({ text: 'Add to Dictionary', onclick: function () { Actions.addToDictionary(editor, pluginUrl, startedState, textMatcherState, currentLanguageState, word, spans); } }); } items.push.apply(items, [ { text: 'Ignore', onclick: function () { Actions.ignoreWord(editor, startedState, textMatcherState, word, spans); } }, { text: 'Ignore all', onclick: function () { Actions.ignoreWord(editor, startedState, textMatcherState, word, spans, true); } } ]); suggestionsMenu = global$5.create('menu', { items: items, context: 'contextmenu', onautohide: function (e) { if (e.target.className.indexOf('spellchecker') !== -1) { e.preventDefault(); } }, onhide: function () { suggestionsMenu.remove(); suggestionsMenu = null; } }); suggestionsMenu.renderTo(domGlobals.document.body); var pos = global$4.DOM.getPos(editor.getContentAreaContainer()); var targetPos = editor.dom.getPos(spans[0]); var root = editor.dom.getRoot(); if (root.nodeName === 'BODY') { targetPos.x -= root.ownerDocument.documentElement.scrollLeft || root.scrollLeft; targetPos.y -= root.ownerDocument.documentElement.scrollTop || root.scrollTop; } else { targetPos.x -= root.scrollLeft; targetPos.y -= root.scrollTop; } pos.x += targetPos.x; pos.y += targetPos.y; suggestionsMenu.moveTo(pos.x, pos.y + spans[0].offsetHeight); }; var setup = function (editor, pluginUrl, lastSuggestionsState, startedState, textMatcherState, currentLanguageState) { editor.on('click', function (e) { var target = e.target; if (target.className === 'mce-spellchecker-word') { e.preventDefault(); var spans = Actions.findSpansByIndex(editor, Actions.getElmIndex(target)); if (spans.length > 0) { var rng = editor.dom.createRng(); rng.setStartBefore(spans[0]); rng.setEndAfter(spans[spans.length - 1]); editor.selection.setRng(rng); showSuggestions(editor, pluginUrl, lastSuggestionsState, startedState, textMatcherState, currentLanguageState, target.getAttribute('data-mce-word'), spans); } } }); }; var SuggestionsMenu = { setup: setup }; global.add('spellchecker', function (editor, pluginUrl) { if (DetectProPlugin.hasProPlugin(editor) === false) { var startedState = Cell(false); var currentLanguageState = Cell(Settings.getLanguage(editor)); var textMatcherState = Cell(null); var lastSuggestionsState = Cell(null); Buttons.register(editor, pluginUrl, startedState, textMatcherState, currentLanguageState, lastSuggestionsState); SuggestionsMenu.setup(editor, pluginUrl, lastSuggestionsState, startedState, textMatcherState, currentLanguageState); Commands.register(editor, pluginUrl, startedState, textMatcherState, lastSuggestionsState, currentLanguageState); return Api.get(editor, startedState, lastSuggestionsState, textMatcherState, currentLanguageState, pluginUrl); } }); function Plugin () { } return Plugin; }(window)); })(); (function () { var tabfocus = (function (domGlobals) { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var global$2 = tinymce.util.Tools.resolve('tinymce.EditorManager'); var global$3 = tinymce.util.Tools.resolve('tinymce.Env'); var global$4 = tinymce.util.Tools.resolve('tinymce.util.Delay'); var global$5 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var global$6 = tinymce.util.Tools.resolve('tinymce.util.VK'); var getTabFocusElements = function (editor) { return editor.getParam('tabfocus_elements', ':prev,:next'); }; var getTabFocus = function (editor) { return editor.getParam('tab_focus', getTabFocusElements(editor)); }; var Settings = { getTabFocus: getTabFocus }; var DOM = global$1.DOM; var tabCancel = function (e) { if (e.keyCode === global$6.TAB && !e.ctrlKey && !e.altKey && !e.metaKey) { e.preventDefault(); } }; var setup = function (editor) { function tabHandler(e) { var x, el, v, i; if (e.keyCode !== global$6.TAB || e.ctrlKey || e.altKey || e.metaKey || e.isDefaultPrevented()) { return; } function find(direction) { el = DOM.select(':input:enabled,*[tabindex]:not(iframe)'); function canSelectRecursive(e) { return e.nodeName === 'BODY' || e.type !== 'hidden' && e.style.display !== 'none' && e.style.visibility !== 'hidden' && canSelectRecursive(e.parentNode); } function canSelect(el) { return /INPUT|TEXTAREA|BUTTON/.test(el.tagName) && global$2.get(e.id) && el.tabIndex !== -1 && canSelectRecursive(el); } global$5.each(el, function (e, i) { if (e.id === editor.id) { x = i; return false; } }); if (direction > 0) { for (i = x + 1; i < el.length; i++) { if (canSelect(el[i])) { return el[i]; } } } else { for (i = x - 1; i >= 0; i--) { if (canSelect(el[i])) { return el[i]; } } } return null; } v = global$5.explode(Settings.getTabFocus(editor)); if (v.length === 1) { v[1] = v[0]; v[0] = ':prev'; } if (e.shiftKey) { if (v[0] === ':prev') { el = find(-1); } else { el = DOM.get(v[0]); } } else { if (v[1] === ':next') { el = find(1); } else { el = DOM.get(v[1]); } } if (el) { var focusEditor = global$2.get(el.id || el.name); if (el.id && focusEditor) { focusEditor.focus(); } else { global$4.setTimeout(function () { if (!global$3.webkit) { domGlobals.window.focus(); } el.focus(); }, 10); } e.preventDefault(); } } editor.on('init', function () { if (editor.inline) { DOM.setAttrib(editor.getBody(), 'tabIndex', null); } editor.on('keyup', tabCancel); if (global$3.gecko) { editor.on('keypress keydown', tabHandler); } else { editor.on('keydown', tabHandler); } }); }; var Keyboard = { setup: setup }; global.add('tabfocus', function (editor) { Keyboard.setup(editor); }); function Plugin () { } return Plugin; }(window)); })(); (function () { var table = (function (domGlobals) { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var noop = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } }; var compose = function (fa, fb) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return fa(fb.apply(null, args)); }; }; var constant = function (value) { return function () { return value; }; }; var identity = function (x) { return x; }; function curry(fn) { var initialArgs = []; for (var _i = 1; _i < arguments.length; _i++) { initialArgs[_i - 1] = arguments[_i]; } return function () { var restArgs = []; for (var _i = 0; _i < arguments.length; _i++) { restArgs[_i] = arguments[_i]; } var all = initialArgs.concat(restArgs); return fn.apply(null, all); }; } var not = function (f) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return !f.apply(null, args); }; }; var die = function (msg) { return function () { throw new Error(msg); }; }; var apply = function (f) { return f(); }; var never = constant(false); var always = constant(true); var never$1 = never; var always$1 = always; var none = function () { return NONE; }; var NONE = function () { var eq = function (o) { return o.isNone(); }; var call = function (thunk) { return thunk(); }; var id = function (n) { return n; }; var noop = function () { }; var nul = function () { return null; }; var undef = function () { return undefined; }; var me = { fold: function (n, s) { return n(); }, is: never$1, isSome: never$1, isNone: always$1, getOr: id, getOrThunk: call, getOrDie: function (msg) { throw new Error(msg || 'error: getOrDie called on none.'); }, getOrNull: nul, getOrUndefined: undef, or: id, orThunk: call, map: none, ap: none, each: noop, bind: none, flatten: none, exists: never$1, forall: always$1, filter: none, equals: eq, equals_: eq, toArray: function () { return []; }, toString: constant('none()') }; if (Object.freeze) Object.freeze(me); return me; }(); var some = function (a) { var constant_a = function () { return a; }; var self = function () { return me; }; var map = function (f) { return some(f(a)); }; var bind = function (f) { return f(a); }; var me = { fold: function (n, s) { return s(a); }, is: function (v) { return a === v; }, isSome: always$1, isNone: never$1, getOr: constant_a, getOrThunk: constant_a, getOrDie: constant_a, getOrNull: constant_a, getOrUndefined: constant_a, or: self, orThunk: self, map: map, ap: function (optfab) { return optfab.fold(none, function (fab) { return some(fab(a)); }); }, each: function (f) { f(a); }, bind: bind, flatten: constant_a, exists: bind, forall: bind, filter: function (f) { return f(a) ? me : NONE; }, equals: function (o) { return o.is(a); }, equals_: function (o, elementEq) { return o.fold(never$1, function (b) { return elementEq(a, b); }); }, toArray: function () { return [a]; }, toString: function () { return 'some(' + a + ')'; } }; return me; }; var from = function (value) { return value === null || value === undefined ? NONE : some(value); }; var Option = { some: some, none: none, from: from }; var typeOf = function (x) { if (x === null) return 'null'; var t = typeof x; if (t === 'object' && Array.prototype.isPrototypeOf(x)) return 'array'; if (t === 'object' && String.prototype.isPrototypeOf(x)) return 'string'; return t; }; var isType = function (type) { return function (value) { return typeOf(value) === type; }; }; var isString = isType('string'); var isArray = isType('array'); var isBoolean = isType('boolean'); var isFunction = isType('function'); var isNumber = isType('number'); var rawIndexOf = function () { var pIndexOf = Array.prototype.indexOf; var fastIndex = function (xs, x) { return pIndexOf.call(xs, x); }; var slowIndex = function (xs, x) { return slowIndexOf(xs, x); }; return pIndexOf === undefined ? slowIndex : fastIndex; }(); var contains = function (xs, x) { return rawIndexOf(xs, x) > -1; }; var exists = function (xs, pred) { return findIndex(xs, pred).isSome(); }; var map = function (xs, f) { var len = xs.length; var r = new Array(len); for (var i = 0; i < len; i++) { var x = xs[i]; r[i] = f(x, i, xs); } return r; }; var each = function (xs, f) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; f(x, i, xs); } }; var eachr = function (xs, f) { for (var i = xs.length - 1; i >= 0; i--) { var x = xs[i]; f(x, i, xs); } }; var filter = function (xs, pred) { var r = []; for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { r.push(x); } } return r; }; var groupBy = function (xs, f) { if (xs.length === 0) { return []; } else { var wasType = f(xs[0]); var r = []; var group = []; for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; var type = f(x); if (type !== wasType) { r.push(group); group = []; } wasType = type; group.push(x); } if (group.length !== 0) { r.push(group); } return r; } }; var foldr = function (xs, f, acc) { eachr(xs, function (x) { acc = f(acc, x); }); return acc; }; var foldl = function (xs, f, acc) { each(xs, function (x) { acc = f(acc, x); }); return acc; }; var find = function (xs, pred) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { return Option.some(x); } } return Option.none(); }; var findIndex = function (xs, pred) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { return Option.some(i); } } return Option.none(); }; var slowIndexOf = function (xs, x) { for (var i = 0, len = xs.length; i < len; ++i) { if (xs[i] === x) { return i; } } return -1; }; var push = Array.prototype.push; var flatten = function (xs) { var r = []; for (var i = 0, len = xs.length; i < len; ++i) { if (!Array.prototype.isPrototypeOf(xs[i])) throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs); push.apply(r, xs[i]); } return r; }; var bind = function (xs, f) { var output = map(xs, f); return flatten(output); }; var forall = function (xs, pred) { for (var i = 0, len = xs.length; i < len; ++i) { var x = xs[i]; if (pred(x, i, xs) !== true) { return false; } } return true; }; var slice = Array.prototype.slice; var reverse = function (xs) { var r = slice.call(xs, 0); r.reverse(); return r; }; var sort = function (xs, comparator) { var copy = slice.call(xs, 0); copy.sort(comparator); return copy; }; var last = function (xs) { return xs.length === 0 ? Option.none() : Option.some(xs[xs.length - 1]); }; var from$1 = isFunction(Array.from) ? Array.from : function (x) { return slice.call(x); }; var keys = Object.keys; var each$1 = function (obj, f) { var props = keys(obj); for (var k = 0, len = props.length; k < len; k++) { var i = props[k]; var x = obj[i]; f(x, i, obj); } }; var map$1 = function (obj, f) { return tupleMap(obj, function (x, i, obj) { return { k: i, v: f(x, i, obj) }; }); }; var tupleMap = function (obj, f) { var r = {}; each$1(obj, function (x, i) { var tuple = f(x, i, obj); r[tuple.k] = tuple.v; }); return r; }; var Immutable = function () { var fields = []; for (var _i = 0; _i < arguments.length; _i++) { fields[_i] = arguments[_i]; } return function () { var values = []; for (var _i = 0; _i < arguments.length; _i++) { values[_i] = arguments[_i]; } if (fields.length !== values.length) { throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments'); } var struct = {}; each(fields, function (name, i) { struct[name] = constant(values[i]); }); return struct; }; }; var sort$1 = function (arr) { return arr.slice(0).sort(); }; var reqMessage = function (required, keys) { throw new Error('All required keys (' + sort$1(required).join(', ') + ') were not specified. Specified keys were: ' + sort$1(keys).join(', ') + '.'); }; var unsuppMessage = function (unsupported) { throw new Error('Unsupported keys for object: ' + sort$1(unsupported).join(', ')); }; var validateStrArr = function (label, array) { if (!isArray(array)) throw new Error('The ' + label + ' fields must be an array. Was: ' + array + '.'); each(array, function (a) { if (!isString(a)) throw new Error('The value ' + a + ' in the ' + label + ' fields was not a string.'); }); }; var invalidTypeMessage = function (incorrect, type) { throw new Error('All values need to be of type: ' + type + '. Keys (' + sort$1(incorrect).join(', ') + ') were not.'); }; var checkDupes = function (everything) { var sorted = sort$1(everything); var dupe = find(sorted, function (s, i) { return i < sorted.length - 1 && s === sorted[i + 1]; }); dupe.each(function (d) { throw new Error('The field: ' + d + ' occurs more than once in the combined fields: [' + sorted.join(', ') + '].'); }); }; var MixedBag = function (required, optional) { var everything = required.concat(optional); if (everything.length === 0) throw new Error('You must specify at least one required or optional field.'); validateStrArr('required', required); validateStrArr('optional', optional); checkDupes(everything); return function (obj) { var keys$1 = keys(obj); var allReqd = forall(required, function (req) { return contains(keys$1, req); }); if (!allReqd) reqMessage(required, keys$1); var unsupported = filter(keys$1, function (key) { return !contains(everything, key); }); if (unsupported.length > 0) unsuppMessage(unsupported); var r = {}; each(required, function (req) { r[req] = constant(obj[req]); }); each(optional, function (opt) { r[opt] = constant(Object.prototype.hasOwnProperty.call(obj, opt) ? Option.some(obj[opt]) : Option.none()); }); return r; }; }; var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE; var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE; var COMMENT = domGlobals.Node.COMMENT_NODE; var DOCUMENT = domGlobals.Node.DOCUMENT_NODE; var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE; var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE; var ELEMENT = domGlobals.Node.ELEMENT_NODE; var TEXT = domGlobals.Node.TEXT_NODE; var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE; var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE; var ENTITY = domGlobals.Node.ENTITY_NODE; var NOTATION = domGlobals.Node.NOTATION_NODE; var name = function (element) { var r = element.dom().nodeName; return r.toLowerCase(); }; var type = function (element) { return element.dom().nodeType; }; var isType$1 = function (t) { return function (element) { return type(element) === t; }; }; var isComment = function (element) { return type(element) === COMMENT || name(element) === '#comment'; }; var isElement = isType$1(ELEMENT); var isText = isType$1(TEXT); var isDocument = isType$1(DOCUMENT); var rawSet = function (dom, key, value) { if (isString(value) || isBoolean(value) || isNumber(value)) { dom.setAttribute(key, value + ''); } else { domGlobals.console.error('Invalid call to Attr.set. Key ', key, ':: Value ', value, ':: Element ', dom); throw new Error('Attribute value was not simple'); } }; var set = function (element, key, value) { rawSet(element.dom(), key, value); }; var setAll = function (element, attrs) { var dom = element.dom(); each$1(attrs, function (v, k) { rawSet(dom, k, v); }); }; var get = function (element, key) { var v = element.dom().getAttribute(key); return v === null ? undefined : v; }; var has = function (element, key) { var dom = element.dom(); return dom && dom.hasAttribute ? dom.hasAttribute(key) : false; }; var remove = function (element, key) { element.dom().removeAttribute(key); }; var clone = function (element) { return foldl(element.dom().attributes, function (acc, attr) { acc[attr.name] = attr.value; return acc; }, {}); }; var checkRange = function (str, substr, start) { if (substr === '') return true; if (str.length < substr.length) return false; var x = str.substr(start, start + substr.length); return x === substr; }; var contains$1 = function (str, substr) { return str.indexOf(substr) !== -1; }; var endsWith = function (str, suffix) { return checkRange(str, suffix, str.length - suffix.length); }; var trim = function (str) { return str.replace(/^\s+|\s+$/g, ''); }; var isSupported = function (dom) { return dom.style !== undefined; }; var cached = function (f) { var called = false; var r; return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (!called) { called = true; r = f.apply(null, args); } return r; }; }; var fromHtml = function (html, scope) { var doc = scope || domGlobals.document; var div = doc.createElement('div'); div.innerHTML = html; if (!div.hasChildNodes() || div.childNodes.length > 1) { domGlobals.console.error('HTML does not have a single root node', html); throw new Error('HTML must have a single root node'); } return fromDom(div.childNodes[0]); }; var fromTag = function (tag, scope) { var doc = scope || domGlobals.document; var node = doc.createElement(tag); return fromDom(node); }; var fromText = function (text, scope) { var doc = scope || domGlobals.document; var node = doc.createTextNode(text); return fromDom(node); }; var fromDom = function (node) { if (node === null || node === undefined) { throw new Error('Node cannot be null or undefined'); } return { dom: constant(node) }; }; var fromPoint = function (docElm, x, y) { var doc = docElm.dom(); return Option.from(doc.elementFromPoint(x, y)).map(fromDom); }; var Element = { fromHtml: fromHtml, fromTag: fromTag, fromText: fromText, fromDom: fromDom, fromPoint: fromPoint }; var inBody = function (element) { var dom = isText(element) ? element.dom().parentNode : element.dom(); return dom !== undefined && dom !== null && dom.ownerDocument.body.contains(dom); }; var body = cached(function () { return getBody(Element.fromDom(domGlobals.document)); }); var getBody = function (doc) { var b = doc.dom().body; if (b === null || b === undefined) { throw new Error('Body is not available yet'); } return Element.fromDom(b); }; var internalSet = function (dom, property, value) { if (!isString(value)) { domGlobals.console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom); throw new Error('CSS value must be a string: ' + value); } if (isSupported(dom)) { dom.style.setProperty(property, value); } }; var internalRemove = function (dom, property) { if (isSupported(dom)) { dom.style.removeProperty(property); } }; var set$1 = function (element, property, value) { var dom = element.dom(); internalSet(dom, property, value); }; var setAll$1 = function (element, css) { var dom = element.dom(); each$1(css, function (v, k) { internalSet(dom, k, v); }); }; var get$1 = function (element, property) { var dom = element.dom(); var styles = domGlobals.window.getComputedStyle(dom); var r = styles.getPropertyValue(property); var v = r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r; return v === null ? undefined : v; }; var getUnsafeProperty = function (dom, property) { return isSupported(dom) ? dom.style.getPropertyValue(property) : ''; }; var getRaw = function (element, property) { var dom = element.dom(); var raw = getUnsafeProperty(dom, property); return Option.from(raw).filter(function (r) { return r.length > 0; }); }; var remove$1 = function (element, property) { var dom = element.dom(); internalRemove(dom, property); if (has(element, 'style') && trim(get(element, 'style')) === '') { remove(element, 'style'); } }; var copy = function (source, target) { var sourceDom = source.dom(); var targetDom = target.dom(); if (isSupported(sourceDom) && isSupported(targetDom)) { targetDom.style.cssText = sourceDom.style.cssText; } }; var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')(); var path = function (parts, scope) { var o = scope !== undefined && scope !== null ? scope : Global; for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i) o = o[parts[i]]; return o; }; var resolve = function (p, scope) { var parts = p.split('.'); return path(parts, scope); }; var unsafe = function (name, scope) { return resolve(name, scope); }; var getOrDie = function (name, scope) { var actual = unsafe(name, scope); if (actual === undefined || actual === null) throw name + ' not available on this browser'; return actual; }; var Global$1 = { getOrDie: getOrDie }; var node = function () { var f = Global$1.getOrDie('Node'); return f; }; var compareDocumentPosition = function (a, b, match) { return (a.compareDocumentPosition(b) & match) !== 0; }; var documentPositionPreceding = function (a, b) { return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_PRECEDING); }; var documentPositionContainedBy = function (a, b) { return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_CONTAINED_BY); }; var Node = { documentPositionPreceding: documentPositionPreceding, documentPositionContainedBy: documentPositionContainedBy }; var firstMatch = function (regexes, s) { for (var i = 0; i < regexes.length; i++) { var x = regexes[i]; if (x.test(s)) return x; } return undefined; }; var find$1 = function (regexes, agent) { var r = firstMatch(regexes, agent); if (!r) return { major: 0, minor: 0 }; var group = function (i) { return Number(agent.replace(r, '$' + i)); }; return nu(group(1), group(2)); }; var detect = function (versionRegexes, agent) { var cleanedAgent = String(agent).toLowerCase(); if (versionRegexes.length === 0) return unknown(); return find$1(versionRegexes, cleanedAgent); }; var unknown = function () { return nu(0, 0); }; var nu = function (major, minor) { return { major: major, minor: minor }; }; var Version = { nu: nu, detect: detect, unknown: unknown }; var edge = 'Edge'; var chrome = 'Chrome'; var ie = 'IE'; var opera = 'Opera'; var firefox = 'Firefox'; var safari = 'Safari'; var isBrowser = function (name, current) { return function () { return current === name; }; }; var unknown$1 = function () { return nu$1({ current: undefined, version: Version.unknown() }); }; var nu$1 = function (info) { var current = info.current; var version = info.version; return { current: current, version: version, isEdge: isBrowser(edge, current), isChrome: isBrowser(chrome, current), isIE: isBrowser(ie, current), isOpera: isBrowser(opera, current), isFirefox: isBrowser(firefox, current), isSafari: isBrowser(safari, current) }; }; var Browser = { unknown: unknown$1, nu: nu$1, edge: constant(edge), chrome: constant(chrome), ie: constant(ie), opera: constant(opera), firefox: constant(firefox), safari: constant(safari) }; var windows = 'Windows'; var ios = 'iOS'; var android = 'Android'; var linux = 'Linux'; var osx = 'OSX'; var solaris = 'Solaris'; var freebsd = 'FreeBSD'; var isOS = function (name, current) { return function () { return current === name; }; }; var unknown$2 = function () { return nu$2({ current: undefined, version: Version.unknown() }); }; var nu$2 = function (info) { var current = info.current; var version = info.version; return { current: current, version: version, isWindows: isOS(windows, current), isiOS: isOS(ios, current), isAndroid: isOS(android, current), isOSX: isOS(osx, current), isLinux: isOS(linux, current), isSolaris: isOS(solaris, current), isFreeBSD: isOS(freebsd, current) }; }; var OperatingSystem = { unknown: unknown$2, nu: nu$2, windows: constant(windows), ios: constant(ios), android: constant(android), linux: constant(linux), osx: constant(osx), solaris: constant(solaris), freebsd: constant(freebsd) }; var DeviceType = function (os, browser, userAgent) { var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true; var isiPhone = os.isiOS() && !isiPad; var isAndroid3 = os.isAndroid() && os.version.major === 3; var isAndroid4 = os.isAndroid() && os.version.major === 4; var isTablet = isiPad || isAndroid3 || isAndroid4 && /mobile/i.test(userAgent) === true; var isTouch = os.isiOS() || os.isAndroid(); var isPhone = isTouch && !isTablet; var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false; return { isiPad: constant(isiPad), isiPhone: constant(isiPhone), isTablet: constant(isTablet), isPhone: constant(isPhone), isTouch: constant(isTouch), isAndroid: os.isAndroid, isiOS: os.isiOS, isWebView: constant(iOSwebview) }; }; var detect$1 = function (candidates, userAgent) { var agent = String(userAgent).toLowerCase(); return find(candidates, function (candidate) { return candidate.search(agent); }); }; var detectBrowser = function (browsers, userAgent) { return detect$1(browsers, userAgent).map(function (browser) { var version = Version.detect(browser.versionRegexes, userAgent); return { current: browser.name, version: version }; }); }; var detectOs = function (oses, userAgent) { return detect$1(oses, userAgent).map(function (os) { var version = Version.detect(os.versionRegexes, userAgent); return { current: os.name, version: version }; }); }; var UaString = { detectBrowser: detectBrowser, detectOs: detectOs }; var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/; var checkContains = function (target) { return function (uastring) { return contains$1(uastring, target); }; }; var browsers = [ { name: 'Edge', versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/], search: function (uastring) { var monstrosity = contains$1(uastring, 'edge/') && contains$1(uastring, 'chrome') && contains$1(uastring, 'safari') && contains$1(uastring, 'applewebkit'); return monstrosity; } }, { name: 'Chrome', versionRegexes: [ /.*?chrome\/([0-9]+)\.([0-9]+).*/, normalVersionRegex ], search: function (uastring) { return contains$1(uastring, 'chrome') && !contains$1(uastring, 'chromeframe'); } }, { name: 'IE', versionRegexes: [ /.*?msie\ ?([0-9]+)\.([0-9]+).*/, /.*?rv:([0-9]+)\.([0-9]+).*/ ], search: function (uastring) { return contains$1(uastring, 'msie') || contains$1(uastring, 'trident'); } }, { name: 'Opera', versionRegexes: [ normalVersionRegex, /.*?opera\/([0-9]+)\.([0-9]+).*/ ], search: checkContains('opera') }, { name: 'Firefox', versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/], search: checkContains('firefox') }, { name: 'Safari', versionRegexes: [ normalVersionRegex, /.*?cpu os ([0-9]+)_([0-9]+).*/ ], search: function (uastring) { return (contains$1(uastring, 'safari') || contains$1(uastring, 'mobile/')) && contains$1(uastring, 'applewebkit'); } } ]; var oses = [ { name: 'Windows', search: checkContains('win'), versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/] }, { name: 'iOS', search: function (uastring) { return contains$1(uastring, 'iphone') || contains$1(uastring, 'ipad'); }, versionRegexes: [ /.*?version\/\ ?([0-9]+)\.([0-9]+).*/, /.*cpu os ([0-9]+)_([0-9]+).*/, /.*cpu iphone os ([0-9]+)_([0-9]+).*/ ] }, { name: 'Android', search: checkContains('android'), versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/] }, { name: 'OSX', search: checkContains('os x'), versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/] }, { name: 'Linux', search: checkContains('linux'), versionRegexes: [] }, { name: 'Solaris', search: checkContains('sunos'), versionRegexes: [] }, { name: 'FreeBSD', search: checkContains('freebsd'), versionRegexes: [] } ]; var PlatformInfo = { browsers: constant(browsers), oses: constant(oses) }; var detect$2 = function (userAgent) { var browsers = PlatformInfo.browsers(); var oses = PlatformInfo.oses(); var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu); var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu); var deviceType = DeviceType(os, browser, userAgent); return { browser: browser, os: os, deviceType: deviceType }; }; var PlatformDetection = { detect: detect$2 }; var detect$3 = cached(function () { var userAgent = domGlobals.navigator.userAgent; return PlatformDetection.detect(userAgent); }); var PlatformDetection$1 = { detect: detect$3 }; var ELEMENT$1 = ELEMENT; var DOCUMENT$1 = DOCUMENT; var is = function (element, selector) { var elem = element.dom(); if (elem.nodeType !== ELEMENT$1) { return false; } else if (elem.matches !== undefined) { return elem.matches(selector); } else if (elem.msMatchesSelector !== undefined) { return elem.msMatchesSelector(selector); } else if (elem.webkitMatchesSelector !== undefined) { return elem.webkitMatchesSelector(selector); } else if (elem.mozMatchesSelector !== undefined) { return elem.mozMatchesSelector(selector); } else { throw new Error('Browser lacks native selectors'); } }; var bypassSelector = function (dom) { return dom.nodeType !== ELEMENT$1 && dom.nodeType !== DOCUMENT$1 || dom.childElementCount === 0; }; var all = function (selector, scope) { var base = scope === undefined ? domGlobals.document : scope.dom(); return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), Element.fromDom); }; var one = function (selector, scope) { var base = scope === undefined ? domGlobals.document : scope.dom(); return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom); }; var eq = function (e1, e2) { return e1.dom() === e2.dom(); }; var regularContains = function (e1, e2) { var d1 = e1.dom(); var d2 = e2.dom(); return d1 === d2 ? false : d1.contains(d2); }; var ieContains = function (e1, e2) { return Node.documentPositionContainedBy(e1.dom(), e2.dom()); }; var browser = PlatformDetection$1.detect().browser; var contains$2 = browser.isIE() ? ieContains : regularContains; var is$1 = is; var owner = function (element) { return Element.fromDom(element.dom().ownerDocument); }; var defaultView = function (element) { var el = element.dom(); var defView = el.ownerDocument.defaultView; return Element.fromDom(defView); }; var parent = function (element) { var dom = element.dom(); return Option.from(dom.parentNode).map(Element.fromDom); }; var parents = function (element, isRoot) { var stop = isFunction(isRoot) ? isRoot : constant(false); var dom = element.dom(); var ret = []; while (dom.parentNode !== null && dom.parentNode !== undefined) { var rawParent = dom.parentNode; var p = Element.fromDom(rawParent); ret.push(p); if (stop(p) === true) { break; } else { dom = rawParent; } } return ret; }; var prevSibling = function (element) { var dom = element.dom(); return Option.from(dom.previousSibling).map(Element.fromDom); }; var nextSibling = function (element) { var dom = element.dom(); return Option.from(dom.nextSibling).map(Element.fromDom); }; var children = function (element) { var dom = element.dom(); return map(dom.childNodes, Element.fromDom); }; var child = function (element, index) { var cs = element.dom().childNodes; return Option.from(cs[index]).map(Element.fromDom); }; var firstChild = function (element) { return child(element, 0); }; var spot = Immutable('element', 'offset'); var before = function (marker, element) { var parent$1 = parent(marker); parent$1.each(function (v) { v.dom().insertBefore(element.dom(), marker.dom()); }); }; var after = function (marker, element) { var sibling = nextSibling(marker); sibling.fold(function () { var parent$1 = parent(marker); parent$1.each(function (v) { append(v, element); }); }, function (v) { before(v, element); }); }; var prepend = function (parent, element) { var firstChild$1 = firstChild(parent); firstChild$1.fold(function () { append(parent, element); }, function (v) { parent.dom().insertBefore(element.dom(), v.dom()); }); }; var append = function (parent, element) { parent.dom().appendChild(element.dom()); }; var wrap = function (element, wrapper) { before(element, wrapper); append(wrapper, element); }; var before$1 = function (marker, elements) { each(elements, function (x) { before(marker, x); }); }; var after$1 = function (marker, elements) { each(elements, function (x, i) { var e = i === 0 ? marker : elements[i - 1]; after(e, x); }); }; var append$1 = function (parent, elements) { each(elements, function (x) { append(parent, x); }); }; var empty = function (element) { element.dom().textContent = ''; each(children(element), function (rogue) { remove$2(rogue); }); }; var remove$2 = function (element) { var dom = element.dom(); if (dom.parentNode !== null) { dom.parentNode.removeChild(dom); } }; var unwrap = function (wrapper) { var children$1 = children(wrapper); if (children$1.length > 0) { before$1(wrapper, children$1); } remove$2(wrapper); }; var dimensions = Immutable('width', 'height'); var grid = Immutable('rows', 'columns'); var address = Immutable('row', 'column'); var coords = Immutable('x', 'y'); var detail = Immutable('element', 'rowspan', 'colspan'); var detailnew = Immutable('element', 'rowspan', 'colspan', 'isNew'); var extended = Immutable('element', 'rowspan', 'colspan', 'row', 'column'); var rowdata = Immutable('element', 'cells', 'section'); var elementnew = Immutable('element', 'isNew'); var rowdatanew = Immutable('element', 'cells', 'section', 'isNew'); var rowcells = Immutable('cells', 'section'); var rowdetails = Immutable('details', 'section'); var bounds = Immutable('startRow', 'startCol', 'finishRow', 'finishCol'); var Structs = { dimensions: dimensions, grid: grid, address: address, coords: coords, extended: extended, detail: detail, detailnew: detailnew, rowdata: rowdata, elementnew: elementnew, rowdatanew: rowdatanew, rowcells: rowcells, rowdetails: rowdetails, bounds: bounds }; var ancestors = function (scope, predicate, isRoot) { return filter(parents(scope, isRoot), predicate); }; var children$1 = function (scope, predicate) { return filter(children(scope), predicate); }; var descendants = function (scope, predicate) { var result = []; each(children(scope), function (x) { if (predicate(x)) { result = result.concat([x]); } result = result.concat(descendants(x, predicate)); }); return result; }; var ancestors$1 = function (scope, selector, isRoot) { return ancestors(scope, function (e) { return is(e, selector); }, isRoot); }; var children$2 = function (scope, selector) { return children$1(scope, function (e) { return is(e, selector); }); }; var descendants$1 = function (scope, selector) { return all(selector, scope); }; function ClosestOrAncestor (is, ancestor, scope, a, isRoot) { return is(scope, a) ? Option.some(scope) : isFunction(isRoot) && isRoot(scope) ? Option.none() : ancestor(scope, a, isRoot); } var ancestor = function (scope, predicate, isRoot) { var element = scope.dom(); var stop = isFunction(isRoot) ? isRoot : constant(false); while (element.parentNode) { element = element.parentNode; var el = Element.fromDom(element); if (predicate(el)) { return Option.some(el); } else if (stop(el)) { break; } } return Option.none(); }; var closest = function (scope, predicate, isRoot) { var is = function (s) { return predicate(s); }; return ClosestOrAncestor(is, ancestor, scope, predicate, isRoot); }; var child$1 = function (scope, predicate) { var result = find(scope.dom().childNodes, compose(predicate, Element.fromDom)); return result.map(Element.fromDom); }; var descendant = function (scope, predicate) { var descend = function (node) { for (var i = 0; i < node.childNodes.length; i++) { if (predicate(Element.fromDom(node.childNodes[i]))) { return Option.some(Element.fromDom(node.childNodes[i])); } var res = descend(node.childNodes[i]); if (res.isSome()) { return res; } } return Option.none(); }; return descend(scope.dom()); }; var ancestor$1 = function (scope, selector, isRoot) { return ancestor(scope, function (e) { return is(e, selector); }, isRoot); }; var child$2 = function (scope, selector) { return child$1(scope, function (e) { return is(e, selector); }); }; var descendant$1 = function (scope, selector) { return one(selector, scope); }; var closest$1 = function (scope, selector, isRoot) { return ClosestOrAncestor(is, ancestor$1, scope, selector, isRoot); }; var firstLayer = function (scope, selector) { return filterFirstLayer(scope, selector, constant(true)); }; var filterFirstLayer = function (scope, selector, predicate) { return bind(children(scope), function (x) { return is(x, selector) ? predicate(x) ? [x] : [] : filterFirstLayer(x, selector, predicate); }); }; var LayerSelector = { firstLayer: firstLayer, filterFirstLayer: filterFirstLayer }; var lookup = function (tags, element, _isRoot) { var isRoot = _isRoot !== undefined ? _isRoot : constant(false); if (isRoot(element)) { return Option.none(); } if (contains(tags, name(element))) { return Option.some(element); } var isRootOrUpperTable = function (elm) { return is(elm, 'table') || isRoot(elm); }; return ancestor$1(element, tags.join(','), isRootOrUpperTable); }; var cell = function (element, isRoot) { return lookup([ 'td', 'th' ], element, isRoot); }; var cells = function (ancestor) { return LayerSelector.firstLayer(ancestor, 'th,td'); }; var notCell = function (element, isRoot) { return lookup([ 'caption', 'tr', 'tbody', 'tfoot', 'thead' ], element, isRoot); }; var neighbours = function (selector, element) { return parent(element).map(function (parent) { return children$2(parent, selector); }); }; var neighbourCells = curry(neighbours, 'th,td'); var neighbourRows = curry(neighbours, 'tr'); var firstCell = function (ancestor) { return descendant$1(ancestor, 'th,td'); }; var table = function (element, isRoot) { return closest$1(element, 'table', isRoot); }; var row = function (element, isRoot) { return lookup(['tr'], element, isRoot); }; var rows = function (ancestor) { return LayerSelector.firstLayer(ancestor, 'tr'); }; var attr = function (element, property) { return parseInt(get(element, property), 10); }; var grid$1 = function (element, rowProp, colProp) { var rowsCount = attr(element, rowProp); var cols = attr(element, colProp); return Structs.grid(rowsCount, cols); }; var TableLookup = { cell: cell, firstCell: firstCell, cells: cells, neighbourCells: neighbourCells, table: table, row: row, rows: rows, notCell: notCell, neighbourRows: neighbourRows, attr: attr, grid: grid$1 }; var fromTable = function (table) { var rows = TableLookup.rows(table); return map(rows, function (row) { var element = row; var parent$1 = parent(element); var parentSection = parent$1.map(function (p) { var parentName = name(p); return parentName === 'tfoot' || parentName === 'thead' || parentName === 'tbody' ? parentName : 'tbody'; }).getOr('tbody'); var cells = map(TableLookup.cells(row), function (cell) { var rowspan = has(cell, 'rowspan') ? parseInt(get(cell, 'rowspan'), 10) : 1; var colspan = has(cell, 'colspan') ? parseInt(get(cell, 'colspan'), 10) : 1; return Structs.detail(cell, rowspan, colspan); }); return Structs.rowdata(element, cells, parentSection); }); }; var fromPastedRows = function (rows, example) { return map(rows, function (row) { var cells = map(TableLookup.cells(row), function (cell) { var rowspan = has(cell, 'rowspan') ? parseInt(get(cell, 'rowspan'), 10) : 1; var colspan = has(cell, 'colspan') ? parseInt(get(cell, 'colspan'), 10) : 1; return Structs.detail(cell, rowspan, colspan); }); return Structs.rowdata(row, cells, example.section()); }); }; var DetailsList = { fromTable: fromTable, fromPastedRows: fromPastedRows }; var key = function (row, column) { return row + ',' + column; }; var getAt = function (warehouse, row, column) { var raw = warehouse.access()[key(row, column)]; return raw !== undefined ? Option.some(raw) : Option.none(); }; var findItem = function (warehouse, item, comparator) { var filtered = filterItems(warehouse, function (detail) { return comparator(item, detail.element()); }); return filtered.length > 0 ? Option.some(filtered[0]) : Option.none(); }; var filterItems = function (warehouse, predicate) { var all = bind(warehouse.all(), function (r) { return r.cells(); }); return filter(all, predicate); }; var generate = function (list) { var access = {}; var cells = []; var maxRows = list.length; var maxColumns = 0; each(list, function (details, r) { var currentRow = []; each(details.cells(), function (detail, c) { var start = 0; while (access[key(r, start)] !== undefined) { start++; } var current = Structs.extended(detail.element(), detail.rowspan(), detail.colspan(), r, start); for (var i = 0; i < detail.colspan(); i++) { for (var j = 0; j < detail.rowspan(); j++) { var cr = r + j; var cc = start + i; var newpos = key(cr, cc); access[newpos] = current; maxColumns = Math.max(maxColumns, cc + 1); } } currentRow.push(current); }); cells.push(Structs.rowdata(details.element(), currentRow, details.section())); }); var grid = Structs.grid(maxRows, maxColumns); return { grid: constant(grid), access: constant(access), all: constant(cells) }; }; var justCells = function (warehouse) { var rows = map(warehouse.all(), function (w) { return w.cells(); }); return flatten(rows); }; var Warehouse = { generate: generate, getAt: getAt, findItem: findItem, filterItems: filterItems, justCells: justCells }; var statsStruct = Immutable('minRow', 'minCol', 'maxRow', 'maxCol'); var findSelectedStats = function (house, isSelected) { var totalColumns = house.grid().columns(); var totalRows = house.grid().rows(); var minRow = totalRows; var minCol = totalColumns; var maxRow = 0; var maxCol = 0; each$1(house.access(), function (detail) { if (isSelected(detail)) { var startRow = detail.row(); var endRow = startRow + detail.rowspan() - 1; var startCol = detail.column(); var endCol = startCol + detail.colspan() - 1; if (startRow < minRow) { minRow = startRow; } else if (endRow > maxRow) { maxRow = endRow; } if (startCol < minCol) { minCol = startCol; } else if (endCol > maxCol) { maxCol = endCol; } } }); return statsStruct(minRow, minCol, maxRow, maxCol); }; var makeCell = function (list, seenSelected, rowIndex) { var row = list[rowIndex].element(); var td = Element.fromTag('td'); append(td, Element.fromTag('br')); var f = seenSelected ? append : prepend; f(row, td); }; var fillInGaps = function (list, house, stats, isSelected) { var totalColumns = house.grid().columns(); var totalRows = house.grid().rows(); for (var i = 0; i < totalRows; i++) { var seenSelected = false; for (var j = 0; j < totalColumns; j++) { if (!(i < stats.minRow() || i > stats.maxRow() || j < stats.minCol() || j > stats.maxCol())) { var needCell = Warehouse.getAt(house, i, j).filter(isSelected).isNone(); if (needCell) { makeCell(list, seenSelected, i); } else { seenSelected = true; } } } } }; var clean = function (table, stats) { var emptyRows = filter(LayerSelector.firstLayer(table, 'tr'), function (row) { return row.dom().childElementCount === 0; }); each(emptyRows, remove$2); if (stats.minCol() === stats.maxCol() || stats.minRow() === stats.maxRow()) { each(LayerSelector.firstLayer(table, 'th,td'), function (cell) { remove(cell, 'rowspan'); remove(cell, 'colspan'); }); } remove(table, 'width'); remove(table, 'height'); remove$1(table, 'width'); remove$1(table, 'height'); }; var extract = function (table, selectedSelector) { var isSelected = function (detail) { return is(detail.element(), selectedSelector); }; var list = DetailsList.fromTable(table); var house = Warehouse.generate(list); var stats = findSelectedStats(house, isSelected); var selector = 'th:not(' + selectedSelector + ')' + ',td:not(' + selectedSelector + ')'; var unselectedCells = LayerSelector.filterFirstLayer(table, 'th,td', function (cell) { return is(cell, selector); }); each(unselectedCells, remove$2); fillInGaps(list, house, stats, isSelected); clean(table, stats); return table; }; var CopySelected = { extract: extract }; function NodeValue (is, name) { var get = function (element) { if (!is(element)) { throw new Error('Can only get ' + name + ' value of a ' + name + ' node'); } return getOption(element).getOr(''); }; var getOptionIE10 = function (element) { try { return getOptionSafe(element); } catch (e) { return Option.none(); } }; var getOptionSafe = function (element) { return is(element) ? Option.from(element.dom().nodeValue) : Option.none(); }; var browser = PlatformDetection$1.detect().browser; var getOption = browser.isIE() && browser.version.major === 10 ? getOptionIE10 : getOptionSafe; var set = function (element, value) { if (!is(element)) { throw new Error('Can only set raw ' + name + ' value of a ' + name + ' node'); } element.dom().nodeValue = value; }; return { get: get, getOption: getOption, set: set }; } var api = NodeValue(isText, 'text'); var get$2 = function (element) { return api.get(element); }; var getOption = function (element) { return api.getOption(element); }; var set$2 = function (element, value) { api.set(element, value); }; var getEnd = function (element) { return name(element) === 'img' ? 1 : getOption(element).fold(function () { return children(element).length; }, function (v) { return v.length; }); }; var NBSP = '\xA0'; var isTextNodeWithCursorPosition = function (el) { return getOption(el).filter(function (text) { return text.trim().length !== 0 || text.indexOf(NBSP) > -1; }).isSome(); }; var elementsWithCursorPosition = [ 'img', 'br' ]; var isCursorPosition = function (elem) { var hasCursorPosition = isTextNodeWithCursorPosition(elem); return hasCursorPosition || contains(elementsWithCursorPosition, name(elem)); }; var first = function (element) { return descendant(element, isCursorPosition); }; var last$1 = function (element) { return descendantRtl(element, isCursorPosition); }; var descendantRtl = function (scope, predicate) { var descend = function (element) { var children$1 = children(element); for (var i = children$1.length - 1; i >= 0; i--) { var child = children$1[i]; if (predicate(child)) { return Option.some(child); } var res = descend(child); if (res.isSome()) { return res; } } return Option.none(); }; return descend(scope); }; var clone$1 = function (original, isDeep) { return Element.fromDom(original.dom().cloneNode(isDeep)); }; var shallow = function (original) { return clone$1(original, false); }; var deep = function (original) { return clone$1(original, true); }; var shallowAs = function (original, tag) { var nu = Element.fromTag(tag); var attributes = clone(original); setAll(nu, attributes); return nu; }; var copy$1 = function (original, tag) { var nu = shallowAs(original, tag); var cloneChildren = children(deep(original)); append$1(nu, cloneChildren); return nu; }; var createCell = function () { var td = Element.fromTag('td'); append(td, Element.fromTag('br')); return td; }; var replace = function (cell, tag, attrs) { var replica = copy$1(cell, tag); each$1(attrs, function (v, k) { if (v === null) { remove(replica, k); } else { set(replica, k, v); } }); return replica; }; var pasteReplace = function (cellContent) { return cellContent; }; var newRow = function (doc) { return function () { return Element.fromTag('tr', doc.dom()); }; }; var cloneFormats = function (oldCell, newCell, formats) { var first$1 = first(oldCell); return first$1.map(function (firstText) { var formatSelector = formats.join(','); var parents = ancestors$1(firstText, formatSelector, function (element) { return eq(element, oldCell); }); return foldr(parents, function (last, parent) { var clonedFormat = shallow(parent); remove(clonedFormat, 'contenteditable'); append(last, clonedFormat); return clonedFormat; }, newCell); }).getOr(newCell); }; var cellOperations = function (mutate, doc, formatsToClone) { var newCell = function (prev) { var docu = owner(prev.element()); var td = Element.fromTag(name(prev.element()), docu.dom()); var formats = formatsToClone.getOr([ 'strong', 'em', 'b', 'i', 'span', 'font', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'div' ]); var lastNode = formats.length > 0 ? cloneFormats(prev.element(), td, formats) : td; append(lastNode, Element.fromTag('br')); copy(prev.element(), td); remove$1(td, 'height'); if (prev.colspan() !== 1) { remove$1(prev.element(), 'width'); } mutate(prev.element(), td); return td; }; return { row: newRow(doc), cell: newCell, replace: replace, gap: createCell }; }; var paste = function (doc) { return { row: newRow(doc), cell: createCell, replace: pasteReplace, gap: createCell }; }; var TableFill = { cellOperations: cellOperations, paste: paste }; var fromHtml$1 = function (html, scope) { var doc = scope || domGlobals.document; var div = doc.createElement('div'); div.innerHTML = html; return children(Element.fromDom(div)); }; var TagBoundaries = [ 'body', 'p', 'div', 'article', 'aside', 'figcaption', 'figure', 'footer', 'header', 'nav', 'section', 'ol', 'ul', 'li', 'table', 'thead', 'tbody', 'tfoot', 'caption', 'tr', 'td', 'th', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'pre', 'address' ]; function DomUniverse () { var clone$1 = function (element) { return Element.fromDom(element.dom().cloneNode(false)); }; var document = function (element) { return element.dom().ownerDocument; }; var isBoundary = function (element) { if (!isElement(element)) return false; if (name(element) === 'body') return true; return contains(TagBoundaries, name(element)); }; var isEmptyTag = function (element) { if (!isElement(element)) return false; return contains([ 'br', 'img', 'hr', 'input' ], name(element)); }; var comparePosition = function (element, other) { return element.dom().compareDocumentPosition(other.dom()); }; var copyAttributesTo = function (source, destination) { var as = clone(source); setAll(destination, as); }; return { up: constant({ selector: ancestor$1, closest: closest$1, predicate: ancestor, all: parents }), down: constant({ selector: descendants$1, predicate: descendants }), styles: constant({ get: get$1, getRaw: getRaw, set: set$1, remove: remove$1 }), attrs: constant({ get: get, set: set, remove: remove, copyTo: copyAttributesTo }), insert: constant({ before: before, after: after, afterAll: after$1, append: append, appendAll: append$1, prepend: prepend, wrap: wrap }), remove: constant({ unwrap: unwrap, remove: remove$2 }), create: constant({ nu: Element.fromTag, clone: clone$1, text: Element.fromText }), query: constant({ comparePosition: comparePosition, prevSibling: prevSibling, nextSibling: nextSibling }), property: constant({ children: children, name: name, parent: parent, document: document, isText: isText, isComment: isComment, isElement: isElement, getText: get$2, setText: set$2, isBoundary: isBoundary, isEmptyTag: isEmptyTag }), eq: eq, is: is$1 }; } var leftRight = Immutable('left', 'right'); var bisect = function (universe, parent, child) { var children = universe.property().children(parent); var index = findIndex(children, curry(universe.eq, child)); return index.map(function (ind) { return { before: constant(children.slice(0, ind)), after: constant(children.slice(ind + 1)) }; }); }; var breakToRight = function (universe, parent, child) { return bisect(universe, parent, child).map(function (parts) { var second = universe.create().clone(parent); universe.insert().appendAll(second, parts.after()); universe.insert().after(parent, second); return leftRight(parent, second); }); }; var breakToLeft = function (universe, parent, child) { return bisect(universe, parent, child).map(function (parts) { var prior = universe.create().clone(parent); universe.insert().appendAll(prior, parts.before().concat([child])); universe.insert().appendAll(parent, parts.after()); universe.insert().before(parent, prior); return leftRight(prior, parent); }); }; var breakPath = function (universe, item, isTop, breaker) { var result = Immutable('first', 'second', 'splits'); var next = function (child, group, splits) { var fallback = result(child, Option.none(), splits); if (isTop(child)) return result(child, group, splits); else { return universe.property().parent(child).bind(function (parent) { return breaker(universe, parent, child).map(function (breakage) { var extra = [{ first: breakage.left, second: breakage.right }]; var nextChild = isTop(parent) ? parent : breakage.left(); return next(nextChild, Option.some(breakage.right()), splits.concat(extra)); }).getOr(fallback); }); } }; return next(item, Option.none(), []); }; var Breaker = { breakToLeft: breakToLeft, breakToRight: breakToRight, breakPath: breakPath }; var all$1 = function (universe, look, elements, f) { var head = elements[0]; var tail = elements.slice(1); return f(universe, look, head, tail); }; var oneAll = function (universe, look, elements) { return elements.length > 0 ? all$1(universe, look, elements, unsafeOne) : Option.none(); }; var unsafeOne = function (universe, look, head, tail) { var start = look(universe, head); return foldr(tail, function (b, a) { var current = look(universe, a); return commonElement(universe, b, current); }, start); }; var commonElement = function (universe, start, end) { return start.bind(function (s) { return end.filter(curry(universe.eq, s)); }); }; var Shared = { oneAll: oneAll }; var eq$1 = function (universe, item) { return curry(universe.eq, item); }; var unsafeSubset = function (universe, common, ps1, ps2) { var children = universe.property().children(common); if (universe.eq(common, ps1[0])) return Option.some([ps1[0]]); if (universe.eq(common, ps2[0])) return Option.some([ps2[0]]); var finder = function (ps) { var topDown = reverse(ps); var index = findIndex(topDown, eq$1(universe, common)).getOr(-1); var item = index < topDown.length - 1 ? topDown[index + 1] : topDown[index]; return findIndex(children, eq$1(universe, item)); }; var startIndex = finder(ps1); var endIndex = finder(ps2); return startIndex.bind(function (sIndex) { return endIndex.map(function (eIndex) { var first = Math.min(sIndex, eIndex); var last = Math.max(sIndex, eIndex); return children.slice(first, last + 1); }); }); }; var ancestors$2 = function (universe, start, end, _isRoot) { var isRoot = _isRoot !== undefined ? _isRoot : constant(false); var ps1 = [start].concat(universe.up().all(start)); var ps2 = [end].concat(universe.up().all(end)); var prune = function (path) { var index = findIndex(path, isRoot); return index.fold(function () { return path; }, function (ind) { return path.slice(0, ind + 1); }); }; var pruned1 = prune(ps1); var pruned2 = prune(ps2); var shared = find(pruned1, function (x) { return exists(pruned2, eq$1(universe, x)); }); return { firstpath: constant(pruned1), secondpath: constant(pruned2), shared: constant(shared) }; }; var subset = function (universe, start, end) { var ancs = ancestors$2(universe, start, end); return ancs.shared().bind(function (shared) { return unsafeSubset(universe, shared, ancs.firstpath(), ancs.secondpath()); }); }; var Subset = { subset: subset, ancestors: ancestors$2 }; var sharedOne = function (universe, look, elements) { return Shared.oneAll(universe, look, elements); }; var subset$1 = function (universe, start, finish) { return Subset.subset(universe, start, finish); }; var ancestors$3 = function (universe, start, finish, _isRoot) { return Subset.ancestors(universe, start, finish, _isRoot); }; var breakToLeft$1 = function (universe, parent, child) { return Breaker.breakToLeft(universe, parent, child); }; var breakToRight$1 = function (universe, parent, child) { return Breaker.breakToRight(universe, parent, child); }; var breakPath$1 = function (universe, child, isTop, breaker) { return Breaker.breakPath(universe, child, isTop, breaker); }; var Parent = { sharedOne: sharedOne, subset: subset$1, ancestors: ancestors$3, breakToLeft: breakToLeft$1, breakToRight: breakToRight$1, breakPath: breakPath$1 }; var universe = DomUniverse(); var sharedOne$1 = function (look, elements) { return Parent.sharedOne(universe, function (universe, element) { return look(element); }, elements); }; var subset$2 = function (start, finish) { return Parent.subset(universe, start, finish); }; var ancestors$4 = function (start, finish, _isRoot) { return Parent.ancestors(universe, start, finish, _isRoot); }; var breakToLeft$2 = function (parent, child) { return Parent.breakToLeft(universe, parent, child); }; var breakToRight$2 = function (parent, child) { return Parent.breakToRight(universe, parent, child); }; var breakPath$2 = function (child, isTop, breaker) { return Parent.breakPath(universe, child, isTop, function (u, p, c) { return breaker(p, c); }); }; var DomParent = { sharedOne: sharedOne$1, subset: subset$2, ancestors: ancestors$4, breakToLeft: breakToLeft$2, breakToRight: breakToRight$2, breakPath: breakPath$2 }; var inSelection = function (bounds, detail) { var leftEdge = detail.column(); var rightEdge = detail.column() + detail.colspan() - 1; var topEdge = detail.row(); var bottomEdge = detail.row() + detail.rowspan() - 1; return leftEdge <= bounds.finishCol() && rightEdge >= bounds.startCol() && (topEdge <= bounds.finishRow() && bottomEdge >= bounds.startRow()); }; var isWithin = function (bounds, detail) { return detail.column() >= bounds.startCol() && detail.column() + detail.colspan() - 1 <= bounds.finishCol() && detail.row() >= bounds.startRow() && detail.row() + detail.rowspan() - 1 <= bounds.finishRow(); }; var isRectangular = function (warehouse, bounds) { var isRect = true; var detailIsWithin = curry(isWithin, bounds); for (var i = bounds.startRow(); i <= bounds.finishRow(); i++) { for (var j = bounds.startCol(); j <= bounds.finishCol(); j++) { isRect = isRect && Warehouse.getAt(warehouse, i, j).exists(detailIsWithin); } } return isRect ? Option.some(bounds) : Option.none(); }; var CellBounds = { inSelection: inSelection, isWithin: isWithin, isRectangular: isRectangular }; var getBounds = function (detailA, detailB) { return Structs.bounds(Math.min(detailA.row(), detailB.row()), Math.min(detailA.column(), detailB.column()), Math.max(detailA.row() + detailA.rowspan() - 1, detailB.row() + detailB.rowspan() - 1), Math.max(detailA.column() + detailA.colspan() - 1, detailB.column() + detailB.colspan() - 1)); }; var getAnyBox = function (warehouse, startCell, finishCell) { var startCoords = Warehouse.findItem(warehouse, startCell, eq); var finishCoords = Warehouse.findItem(warehouse, finishCell, eq); return startCoords.bind(function (sc) { return finishCoords.map(function (fc) { return getBounds(sc, fc); }); }); }; var getBox = function (warehouse, startCell, finishCell) { return getAnyBox(warehouse, startCell, finishCell).bind(function (bounds) { return CellBounds.isRectangular(warehouse, bounds); }); }; var CellGroup = { getAnyBox: getAnyBox, getBox: getBox }; var moveBy = function (warehouse, cell, row, column) { return Warehouse.findItem(warehouse, cell, eq).bind(function (detail) { var startRow = row > 0 ? detail.row() + detail.rowspan() - 1 : detail.row(); var startCol = column > 0 ? detail.column() + detail.colspan() - 1 : detail.column(); var dest = Warehouse.getAt(warehouse, startRow + row, startCol + column); return dest.map(function (d) { return d.element(); }); }); }; var intercepts = function (warehouse, start, finish) { return CellGroup.getAnyBox(warehouse, start, finish).map(function (bounds) { var inside = Warehouse.filterItems(warehouse, curry(CellBounds.inSelection, bounds)); return map(inside, function (detail) { return detail.element(); }); }); }; var parentCell = function (warehouse, innerCell) { var isContainedBy = function (c1, c2) { return contains$2(c2, c1); }; return Warehouse.findItem(warehouse, innerCell, isContainedBy).bind(function (detail) { return detail.element(); }); }; var CellFinder = { moveBy: moveBy, intercepts: intercepts, parentCell: parentCell }; var moveBy$1 = function (cell, deltaRow, deltaColumn) { return TableLookup.table(cell).bind(function (table) { var warehouse = getWarehouse(table); return CellFinder.moveBy(warehouse, cell, deltaRow, deltaColumn); }); }; var intercepts$1 = function (table, first, last) { var warehouse = getWarehouse(table); return CellFinder.intercepts(warehouse, first, last); }; var nestedIntercepts = function (table, first, firstTable, last, lastTable) { var warehouse = getWarehouse(table); var startCell = eq(table, firstTable) ? first : CellFinder.parentCell(warehouse, first); var lastCell = eq(table, lastTable) ? last : CellFinder.parentCell(warehouse, last); return CellFinder.intercepts(warehouse, startCell, lastCell); }; var getBox$1 = function (table, first, last) { var warehouse = getWarehouse(table); return CellGroup.getBox(warehouse, first, last); }; var getWarehouse = function (table) { var list = DetailsList.fromTable(table); return Warehouse.generate(list); }; var TablePositions = { moveBy: moveBy$1, intercepts: intercepts$1, nestedIntercepts: nestedIntercepts, getBox: getBox$1 }; var lookupTable = function (container, isRoot) { return ancestor$1(container, 'table'); }; var identified = MixedBag([ 'boxes', 'start', 'finish' ], []); var identify = function (start, finish, isRoot) { var getIsRoot = function (rootTable) { return function (element) { return isRoot(element) || eq(element, rootTable); }; }; if (eq(start, finish)) { return Option.some(identified({ boxes: Option.some([start]), start: start, finish: finish })); } else { return lookupTable(start, isRoot).bind(function (startTable) { return lookupTable(finish, isRoot).bind(function (finishTable) { if (eq(startTable, finishTable)) { return Option.some(identified({ boxes: TablePositions.intercepts(startTable, start, finish), start: start, finish: finish })); } else if (contains$2(startTable, finishTable)) { var ancestorCells = ancestors$1(finish, 'td,th', getIsRoot(startTable)); var finishCell = ancestorCells.length > 0 ? ancestorCells[ancestorCells.length - 1] : finish; return Option.some(identified({ boxes: TablePositions.nestedIntercepts(startTable, start, startTable, finish, finishTable), start: start, finish: finishCell })); } else if (contains$2(finishTable, startTable)) { var ancestorCells = ancestors$1(start, 'td,th', getIsRoot(finishTable)); var startCell = ancestorCells.length > 0 ? ancestorCells[ancestorCells.length - 1] : start; return Option.some(identified({ boxes: TablePositions.nestedIntercepts(finishTable, start, startTable, finish, finishTable), start: start, finish: startCell })); } else { return DomParent.ancestors(start, finish).shared().bind(function (lca) { return closest$1(lca, 'table', isRoot).bind(function (lcaTable) { var finishAncestorCells = ancestors$1(finish, 'td,th', getIsRoot(lcaTable)); var finishCell = finishAncestorCells.length > 0 ? finishAncestorCells[finishAncestorCells.length - 1] : finish; var startAncestorCells = ancestors$1(start, 'td,th', getIsRoot(lcaTable)); var startCell = startAncestorCells.length > 0 ? startAncestorCells[startAncestorCells.length - 1] : start; return Option.some(identified({ boxes: TablePositions.nestedIntercepts(lcaTable, start, startTable, finish, finishTable), start: startCell, finish: finishCell })); }); }); } }); }); } }; var retrieve = function (container, selector) { var sels = descendants$1(container, selector); return sels.length > 0 ? Option.some(sels) : Option.none(); }; var getLast = function (boxes, lastSelectedSelector) { return find(boxes, function (box) { return is(box, lastSelectedSelector); }); }; var getEdges = function (container, firstSelectedSelector, lastSelectedSelector) { return descendant$1(container, firstSelectedSelector).bind(function (first) { return descendant$1(container, lastSelectedSelector).bind(function (last) { return DomParent.sharedOne(lookupTable, [ first, last ]).map(function (tbl) { return { first: constant(first), last: constant(last), table: constant(tbl) }; }); }); }); }; var expandTo = function (finish, firstSelectedSelector) { return ancestor$1(finish, 'table').bind(function (table) { return descendant$1(table, firstSelectedSelector).bind(function (start) { return identify(start, finish).bind(function (identified) { return identified.boxes().map(function (boxes) { return { boxes: constant(boxes), start: constant(identified.start()), finish: constant(identified.finish()) }; }); }); }); }); }; var shiftSelection = function (boxes, deltaRow, deltaColumn, firstSelectedSelector, lastSelectedSelector) { return getLast(boxes, lastSelectedSelector).bind(function (last) { return TablePositions.moveBy(last, deltaRow, deltaColumn).bind(function (finish) { return expandTo(finish, firstSelectedSelector); }); }); }; var CellSelection = { identify: identify, retrieve: retrieve, shiftSelection: shiftSelection, getEdges: getEdges }; var retrieve$1 = function (container, selector) { return CellSelection.retrieve(container, selector); }; var retrieveBox = function (container, firstSelectedSelector, lastSelectedSelector) { return CellSelection.getEdges(container, firstSelectedSelector, lastSelectedSelector).bind(function (edges) { var isRoot = function (ancestor) { return eq(container, ancestor); }; var firstAncestor = ancestor$1(edges.first(), 'thead,tfoot,tbody,table', isRoot); var lastAncestor = ancestor$1(edges.last(), 'thead,tfoot,tbody,table', isRoot); return firstAncestor.bind(function (fA) { return lastAncestor.bind(function (lA) { return eq(fA, lA) ? TablePositions.getBox(edges.table(), edges.first(), edges.last()) : Option.none(); }); }); }); }; var TableSelection = { retrieve: retrieve$1, retrieveBox: retrieveBox }; var selected = 'data-mce-selected'; var selectedSelector = 'td[' + selected + '],th[' + selected + ']'; var attributeSelector = '[' + selected + ']'; var firstSelected = 'data-mce-first-selected'; var firstSelectedSelector = 'td[' + firstSelected + '],th[' + firstSelected + ']'; var lastSelected = 'data-mce-last-selected'; var lastSelectedSelector = 'td[' + lastSelected + '],th[' + lastSelected + ']'; var Ephemera = { selected: constant(selected), selectedSelector: constant(selectedSelector), attributeSelector: constant(attributeSelector), firstSelected: constant(firstSelected), firstSelectedSelector: constant(firstSelectedSelector), lastSelected: constant(lastSelected), lastSelectedSelector: constant(lastSelectedSelector) }; var generate$1 = function (cases) { if (!isArray(cases)) { throw new Error('cases must be an array'); } if (cases.length === 0) { throw new Error('there must be at least one case'); } var constructors = []; var adt = {}; each(cases, function (acase, count) { var keys$1 = keys(acase); if (keys$1.length !== 1) { throw new Error('one and only one name per case'); } var key = keys$1[0]; var value = acase[key]; if (adt[key] !== undefined) { throw new Error('duplicate key detected:' + key); } else if (key === 'cata') { throw new Error('cannot have a case named cata (sorry)'); } else if (!isArray(value)) { throw new Error('case arguments must be an array'); } constructors.push(key); adt[key] = function () { var argLength = arguments.length; if (argLength !== value.length) { throw new Error('Wrong number of arguments to case ' + key + '. Expected ' + value.length + ' (' + value + '), got ' + argLength); } var args = new Array(argLength); for (var i = 0; i < args.length; i++) args[i] = arguments[i]; var match = function (branches) { var branchKeys = keys(branches); if (constructors.length !== branchKeys.length) { throw new Error('Wrong number of arguments to match. Expected: ' + constructors.join(',') + '\nActual: ' + branchKeys.join(',')); } var allReqd = forall(constructors, function (reqKey) { return contains(branchKeys, reqKey); }); if (!allReqd) throw new Error('Not all branches were specified when using match. Specified: ' + branchKeys.join(', ') + '\nRequired: ' + constructors.join(', ')); return branches[key].apply(null, args); }; return { fold: function () { if (arguments.length !== cases.length) { throw new Error('Wrong number of arguments to fold. Expected ' + cases.length + ', got ' + arguments.length); } var target = arguments[count]; return target.apply(null, args); }, match: match, log: function (label) { domGlobals.console.log(label, { constructors: constructors, constructor: key, params: args }); } }; }; }); return adt; }; var Adt = { generate: generate$1 }; var type$1 = Adt.generate([ { none: [] }, { multiple: ['elements'] }, { single: ['selection'] } ]); var cata = function (subject, onNone, onMultiple, onSingle) { return subject.fold(onNone, onMultiple, onSingle); }; var SelectionTypes = { cata: cata, none: type$1.none, multiple: type$1.multiple, single: type$1.single }; var selection = function (cell, selections) { return SelectionTypes.cata(selections.get(), constant([]), identity, constant([cell])); }; var unmergable = function (cell, selections) { var hasSpan = function (elem) { return has(elem, 'rowspan') && parseInt(get(elem, 'rowspan'), 10) > 1 || has(elem, 'colspan') && parseInt(get(elem, 'colspan'), 10) > 1; }; var candidates = selection(cell, selections); return candidates.length > 0 && forall(candidates, hasSpan) ? Option.some(candidates) : Option.none(); }; var mergable = function (table, selections) { return SelectionTypes.cata(selections.get(), Option.none, function (cells, _env) { if (cells.length === 0) { return Option.none(); } return TableSelection.retrieveBox(table, Ephemera.firstSelectedSelector(), Ephemera.lastSelectedSelector()).bind(function (bounds) { return cells.length > 1 ? Option.some({ bounds: constant(bounds), cells: constant(cells) }) : Option.none(); }); }, Option.none); }; var CellOperations = { mergable: mergable, unmergable: unmergable, selection: selection }; var noMenu = function (cell) { return { element: constant(cell), mergable: Option.none, unmergable: Option.none, selection: constant([cell]) }; }; var forMenu = function (selections, table, cell) { return { element: constant(cell), mergable: constant(CellOperations.mergable(table, selections)), unmergable: constant(CellOperations.unmergable(cell, selections)), selection: constant(CellOperations.selection(cell, selections)) }; }; var notCell$1 = function (element) { return noMenu(element); }; var paste$1 = Immutable('element', 'clipboard', 'generators'); var pasteRows = function (selections, table, cell, clipboard, generators) { return { element: constant(cell), mergable: Option.none, unmergable: Option.none, selection: constant(CellOperations.selection(cell, selections)), clipboard: constant(clipboard), generators: constant(generators) }; }; var TableTargets = { noMenu: noMenu, forMenu: forMenu, notCell: notCell$1, paste: paste$1, pasteRows: pasteRows }; var extractSelected = function (cells) { return TableLookup.table(cells[0]).map(deep).map(function (replica) { return [CopySelected.extract(replica, Ephemera.attributeSelector())]; }); }; var serializeElements = function (editor, elements) { return map(elements, function (elm) { return editor.selection.serializer.serialize(elm.dom(), {}); }).join(''); }; var getTextContent = function (elements) { return map(elements, function (element) { return element.dom().innerText; }).join(''); }; var registerEvents = function (editor, selections, actions, cellSelection) { editor.on('BeforeGetContent', function (e) { var multiCellContext = function (cells) { e.preventDefault(); extractSelected(cells).each(function (elements) { e.content = e.format === 'text' ? getTextContent(elements) : serializeElements(editor, elements); }); }; if (e.selection === true) { SelectionTypes.cata(selections.get(), noop, multiCellContext, noop); } }); editor.on('BeforeSetContent', function (e) { if (e.selection === true && e.paste === true) { var cellOpt = Option.from(editor.dom.getParent(editor.selection.getStart(), 'th,td')); cellOpt.each(function (domCell) { var cell = Element.fromDom(domCell); TableLookup.table(cell).each(function (table) { var elements = filter(fromHtml$1(e.content), function (content) { return name(content) !== 'meta'; }); if (elements.length === 1 && name(elements[0]) === 'table') { e.preventDefault(); var doc = Element.fromDom(editor.getDoc()); var generators = TableFill.paste(doc); var targets = TableTargets.paste(cell, elements[0], generators); actions.pasteCells(table, targets).each(function (rng) { editor.selection.setRng(rng); editor.focus(); cellSelection.clear(table); }); } }); }); } }); }; var Clipboard = { registerEvents: registerEvents }; function Dimension (name, getOffset) { var set = function (element, h) { if (!isNumber(h) && !h.match(/^[0-9]+$/)) { throw new Error(name + '.set accepts only positive integer values. Value was ' + h); } var dom = element.dom(); if (isSupported(dom)) { dom.style[name] = h + 'px'; } }; var get = function (element) { var r = getOffset(element); if (r <= 0 || r === null) { var css = get$1(element, name); return parseFloat(css) || 0; } return r; }; var getOuter = get; var aggregate = function (element, properties) { return foldl(properties, function (acc, property) { var val = get$1(element, property); var value = val === undefined ? 0 : parseInt(val, 10); return isNaN(value) ? acc : acc + value; }, 0); }; var max = function (element, value, properties) { var cumulativeInclusions = aggregate(element, properties); var absoluteMax = value > cumulativeInclusions ? value - cumulativeInclusions : 0; return absoluteMax; }; return { set: set, get: get, getOuter: getOuter, aggregate: aggregate, max: max }; } var api$1 = Dimension('height', function (element) { var dom = element.dom(); return inBody(element) ? dom.getBoundingClientRect().height : dom.offsetHeight; }); var get$3 = function (element) { return api$1.get(element); }; var getOuter = function (element) { return api$1.getOuter(element); }; var api$2 = Dimension('width', function (element) { return element.dom().offsetWidth; }); var get$4 = function (element) { return api$2.get(element); }; var getOuter$1 = function (element) { return api$2.getOuter(element); }; var platform = PlatformDetection$1.detect(); var needManualCalc = function () { return platform.browser.isIE() || platform.browser.isEdge(); }; var toNumber = function (px, fallback) { var num = parseFloat(px); return isNaN(num) ? fallback : num; }; var getProp = function (elm, name, fallback) { return toNumber(get$1(elm, name), fallback); }; var getCalculatedHeight = function (cell) { var paddingTop = getProp(cell, 'padding-top', 0); var paddingBottom = getProp(cell, 'padding-bottom', 0); var borderTop = getProp(cell, 'border-top-width', 0); var borderBottom = getProp(cell, 'border-bottom-width', 0); var height = cell.dom().getBoundingClientRect().height; var boxSizing = get$1(cell, 'box-sizing'); var borders = borderTop + borderBottom; return boxSizing === 'border-box' ? height : height - paddingTop - paddingBottom - borders; }; var getWidth = function (cell) { return getProp(cell, 'width', get$4(cell)); }; var getHeight = function (cell) { return needManualCalc() ? getCalculatedHeight(cell) : getProp(cell, 'height', get$3(cell)); }; var RuntimeSize = { getWidth: getWidth, getHeight: getHeight }; var genericSizeRegex = /(\d+(\.\d+)?)(\w|%)*/; var percentageBasedSizeRegex = /(\d+(\.\d+)?)%/; var pixelBasedSizeRegex = /(\d+(\.\d+)?)px|em/; var setPixelWidth = function (cell, amount) { set$1(cell, 'width', amount + 'px'); }; var setPercentageWidth = function (cell, amount) { set$1(cell, 'width', amount + '%'); }; var setHeight = function (cell, amount) { set$1(cell, 'height', amount + 'px'); }; var getHeightValue = function (cell) { return getRaw(cell, 'height').getOrThunk(function () { return RuntimeSize.getHeight(cell) + 'px'; }); }; var convert = function (cell, number, getter, setter) { var newSize = TableLookup.table(cell).map(function (table) { var total = getter(table); return Math.floor(number / 100 * total); }).getOr(number); setter(cell, newSize); return newSize; }; var normalizePixelSize = function (value, cell, getter, setter) { var number = parseInt(value, 10); return endsWith(value, '%') && name(cell) !== 'table' ? convert(cell, number, getter, setter) : number; }; var getTotalHeight = function (cell) { var value = getHeightValue(cell); if (!value) { return get$3(cell); } return normalizePixelSize(value, cell, get$3, setHeight); }; var get$5 = function (cell, type, f) { var v = f(cell); var span = getSpan(cell, type); return v / span; }; var getSpan = function (cell, type) { return has(cell, type) ? parseInt(get(cell, type), 10) : 1; }; var getRawWidth = function (element) { var cssWidth = getRaw(element, 'width'); return cssWidth.fold(function () { return Option.from(get(element, 'width')); }, function (width) { return Option.some(width); }); }; var normalizePercentageWidth = function (cellWidth, tableSize) { return cellWidth / tableSize.pixelWidth() * 100; }; var choosePercentageSize = function (element, width, tableSize) { if (percentageBasedSizeRegex.test(width)) { var percentMatch = percentageBasedSizeRegex.exec(width); return parseFloat(percentMatch[1]); } else { var intWidth = get$4(element); return normalizePercentageWidth(intWidth, tableSize); } }; var getPercentageWidth = function (cell, tableSize) { var width = getRawWidth(cell); return width.fold(function () { var intWidth = get$4(cell); return normalizePercentageWidth(intWidth, tableSize); }, function (w) { return choosePercentageSize(cell, w, tableSize); }); }; var normalizePixelWidth = function (cellWidth, tableSize) { return cellWidth / 100 * tableSize.pixelWidth(); }; var choosePixelSize = function (element, width, tableSize) { if (pixelBasedSizeRegex.test(width)) { var pixelMatch = pixelBasedSizeRegex.exec(width); return parseInt(pixelMatch[1], 10); } else if (percentageBasedSizeRegex.test(width)) { var percentMatch = percentageBasedSizeRegex.exec(width); var floatWidth = parseFloat(percentMatch[1]); return normalizePixelWidth(floatWidth, tableSize); } else { return get$4(element); } }; var getPixelWidth = function (cell, tableSize) { var width = getRawWidth(cell); return width.fold(function () { return get$4(cell); }, function (w) { return choosePixelSize(cell, w, tableSize); }); }; var getHeight$1 = function (cell) { return get$5(cell, 'rowspan', getTotalHeight); }; var getGenericWidth = function (cell) { var width = getRawWidth(cell); return width.bind(function (w) { if (genericSizeRegex.test(w)) { var match = genericSizeRegex.exec(w); return Option.some({ width: constant(match[1]), unit: constant(match[3]) }); } else { return Option.none(); } }); }; var setGenericWidth = function (cell, amount, unit) { set$1(cell, 'width', amount + unit); }; var Sizes = { percentageBasedSizeRegex: constant(percentageBasedSizeRegex), pixelBasedSizeRegex: constant(pixelBasedSizeRegex), setPixelWidth: setPixelWidth, setPercentageWidth: setPercentageWidth, setHeight: setHeight, getPixelWidth: getPixelWidth, getPercentageWidth: getPercentageWidth, getGenericWidth: getGenericWidth, setGenericWidth: setGenericWidth, getHeight: getHeight$1, getRawWidth: getRawWidth }; var halve = function (main, other) { var width = Sizes.getGenericWidth(main); width.each(function (w) { var newWidth = w.width() / 2; Sizes.setGenericWidth(main, newWidth, w.unit()); Sizes.setGenericWidth(other, newWidth, w.unit()); }); }; var CellMutations = { halve: halve }; var attached = function (element, scope) { var doc = scope || Element.fromDom(domGlobals.document.documentElement); return ancestor(element, curry(eq, doc)).isSome(); }; var windowOf = function (element) { var dom = element.dom(); if (dom === dom.window && element instanceof domGlobals.Window) { return element; } return isDocument(element) ? dom.defaultView || dom.parentWindow : null; }; var r = function (left, top) { var translate = function (x, y) { return r(left + x, top + y); }; return { left: constant(left), top: constant(top), translate: translate }; }; var Position = r; var boxPosition = function (dom) { var box = dom.getBoundingClientRect(); return Position(box.left, box.top); }; var firstDefinedOrZero = function (a, b) { return a !== undefined ? a : b !== undefined ? b : 0; }; var absolute = function (element) { var doc = element.dom().ownerDocument; var body = doc.body; var win = windowOf(Element.fromDom(doc)); var html = doc.documentElement; var scrollTop = firstDefinedOrZero(win.pageYOffset, html.scrollTop); var scrollLeft = firstDefinedOrZero(win.pageXOffset, html.scrollLeft); var clientTop = firstDefinedOrZero(html.clientTop, body.clientTop); var clientLeft = firstDefinedOrZero(html.clientLeft, body.clientLeft); return viewport(element).translate(scrollLeft - clientLeft, scrollTop - clientTop); }; var viewport = function (element) { var dom = element.dom(); var doc = dom.ownerDocument; var body = doc.body; var html = Element.fromDom(doc.documentElement); if (body === dom) { return Position(body.offsetLeft, body.offsetTop); } if (!attached(element, html)) { return Position(0, 0); } return boxPosition(dom); }; var rowInfo = Immutable('row', 'y'); var colInfo = Immutable('col', 'x'); var rtlEdge = function (cell) { var pos = absolute(cell); return pos.left() + getOuter$1(cell); }; var ltrEdge = function (cell) { return absolute(cell).left(); }; var getLeftEdge = function (index, cell) { return colInfo(index, ltrEdge(cell)); }; var getRightEdge = function (index, cell) { return colInfo(index, rtlEdge(cell)); }; var getTop = function (cell) { return absolute(cell).top(); }; var getTopEdge = function (index, cell) { return rowInfo(index, getTop(cell)); }; var getBottomEdge = function (index, cell) { return rowInfo(index, getTop(cell) + getOuter(cell)); }; var findPositions = function (getInnerEdge, getOuterEdge, array) { if (array.length === 0) { return []; } var lines = map(array.slice(1), function (cellOption, index) { return cellOption.map(function (cell) { return getInnerEdge(index, cell); }); }); var lastLine = array[array.length - 1].map(function (cell) { return getOuterEdge(array.length - 1, cell); }); return lines.concat([lastLine]); }; var negate = function (step, _table) { return -step; }; var height = { delta: identity, positions: curry(findPositions, getTopEdge, getBottomEdge), edge: getTop }; var ltr = { delta: identity, edge: ltrEdge, positions: curry(findPositions, getLeftEdge, getRightEdge) }; var rtl = { delta: negate, edge: rtlEdge, positions: curry(findPositions, getRightEdge, getLeftEdge) }; var BarPositions = { height: height, rtl: rtl, ltr: ltr }; var ResizeDirection = { ltr: BarPositions.ltr, rtl: BarPositions.rtl }; function TableDirection (directionAt) { var auto = function (table) { return directionAt(table).isRtl() ? ResizeDirection.rtl : ResizeDirection.ltr; }; var delta = function (amount, table) { return auto(table).delta(amount, table); }; var positions = function (cols, table) { return auto(table).positions(cols); }; var edge = function (cell) { return auto(cell).edge(cell); }; return { delta: delta, edge: edge, positions: positions }; } var getGridSize = function (table) { var input = DetailsList.fromTable(table); var warehouse = Warehouse.generate(input); return warehouse.grid(); }; var TableGridSize = { getGridSize: getGridSize }; var hasOwnProperty = Object.prototype.hasOwnProperty; var shallow$1 = function (old, nu) { return nu; }; var baseMerge = function (merger) { return function () { var objects = new Array(arguments.length); for (var i = 0; i < objects.length; i++) objects[i] = arguments[i]; if (objects.length === 0) throw new Error('Can\'t merge zero objects'); var ret = {}; for (var j = 0; j < objects.length; j++) { var curObject = objects[j]; for (var key in curObject) if (hasOwnProperty.call(curObject, key)) { ret[key] = merger(ret[key], curObject[key]); } } return ret; }; }; var merge = baseMerge(shallow$1); var cat = function (arr) { var r = []; var push = function (x) { r.push(x); }; for (var i = 0; i < arr.length; i++) { arr[i].each(push); } return r; }; var findMap = function (arr, f) { for (var i = 0; i < arr.length; i++) { var r = f(arr[i], i); if (r.isSome()) { return r; } } return Option.none(); }; var setIfNot = function (element, property, value, ignore) { if (value === ignore) { remove(element, property); } else { set(element, property, value); } }; var render = function (table, grid) { var newRows = []; var newCells = []; var renderSection = function (gridSection, sectionName) { var section = child$2(table, sectionName).getOrThunk(function () { var tb = Element.fromTag(sectionName, owner(table).dom()); append(table, tb); return tb; }); empty(section); var rows = map(gridSection, function (row) { if (row.isNew()) { newRows.push(row.element()); } var tr = row.element(); empty(tr); each(row.cells(), function (cell) { if (cell.isNew()) { newCells.push(cell.element()); } setIfNot(cell.element(), 'colspan', cell.colspan(), 1); setIfNot(cell.element(), 'rowspan', cell.rowspan(), 1); append(tr, cell.element()); }); return tr; }); append$1(section, rows); }; var removeSection = function (sectionName) { child$2(table, sectionName).each(remove$2); }; var renderOrRemoveSection = function (gridSection, sectionName) { if (gridSection.length > 0) { renderSection(gridSection, sectionName); } else { removeSection(sectionName); } }; var headSection = []; var bodySection = []; var footSection = []; each(grid, function (row) { switch (row.section()) { case 'thead': headSection.push(row); break; case 'tbody': bodySection.push(row); break; case 'tfoot': footSection.push(row); break; } }); renderOrRemoveSection(headSection, 'thead'); renderOrRemoveSection(bodySection, 'tbody'); renderOrRemoveSection(footSection, 'tfoot'); return { newRows: constant(newRows), newCells: constant(newCells) }; }; var copy$2 = function (grid) { var rows = map(grid, function (row) { var tr = shallow(row.element()); each(row.cells(), function (cell) { var clonedCell = deep(cell.element()); setIfNot(clonedCell, 'colspan', cell.colspan(), 1); setIfNot(clonedCell, 'rowspan', cell.rowspan(), 1); append(tr, clonedCell); }); return tr; }); return rows; }; var Redraw = { render: render, copy: copy$2 }; var read = function (element, attr) { var value = get(element, attr); return value === undefined || value === '' ? [] : value.split(' '); }; var add = function (element, attr, id) { var old = read(element, attr); var nu = old.concat([id]); set(element, attr, nu.join(' ')); return true; }; var remove$3 = function (element, attr, id) { var nu = filter(read(element, attr), function (v) { return v !== id; }); if (nu.length > 0) { set(element, attr, nu.join(' ')); } else { remove(element, attr); } return false; }; var supports = function (element) { return element.dom().classList !== undefined; }; var get$6 = function (element) { return read(element, 'class'); }; var add$1 = function (element, clazz) { return add(element, 'class', clazz); }; var remove$4 = function (element, clazz) { return remove$3(element, 'class', clazz); }; var add$2 = function (element, clazz) { if (supports(element)) { element.dom().classList.add(clazz); } else { add$1(element, clazz); } }; var cleanClass = function (element) { var classList = supports(element) ? element.dom().classList : get$6(element); if (classList.length === 0) { remove(element, 'class'); } }; var remove$5 = function (element, clazz) { if (supports(element)) { var classList = element.dom().classList; classList.remove(clazz); } else { remove$4(element, clazz); } cleanClass(element); }; var has$1 = function (element, clazz) { return supports(element) && element.dom().classList.contains(clazz); }; var repeat = function (repititions, f) { var r = []; for (var i = 0; i < repititions; i++) { r.push(f(i)); } return r; }; var range = function (start, end) { var r = []; for (var i = start; i < end; i++) { r.push(i); } return r; }; var unique = function (xs, comparator) { var result = []; each(xs, function (x, i) { if (i < xs.length - 1 && !comparator(x, xs[i + 1])) { result.push(x); } else if (i === xs.length - 1) { result.push(x); } }); return result; }; var deduce = function (xs, index) { if (index < 0 || index >= xs.length - 1) { return Option.none(); } var current = xs[index].fold(function () { var rest = reverse(xs.slice(0, index)); return findMap(rest, function (a, i) { return a.map(function (aa) { return { value: aa, delta: i + 1 }; }); }); }, function (c) { return Option.some({ value: c, delta: 0 }); }); var next = xs[index + 1].fold(function () { var rest = xs.slice(index + 1); return findMap(rest, function (a, i) { return a.map(function (aa) { return { value: aa, delta: i + 1 }; }); }); }, function (n) { return Option.some({ value: n, delta: 1 }); }); return current.bind(function (c) { return next.map(function (n) { var extras = n.delta + c.delta; return Math.abs(n.value - c.value) / extras; }); }); }; var Util = { repeat: repeat, range: range, unique: unique, deduce: deduce }; var columns = function (warehouse) { var grid = warehouse.grid(); var cols = Util.range(0, grid.columns()); var rowsArr = Util.range(0, grid.rows()); return map(cols, function (col) { var getBlock = function () { return bind(rowsArr, function (r) { return Warehouse.getAt(warehouse, r, col).filter(function (detail) { return detail.column() === col; }).fold(constant([]), function (detail) { return [detail]; }); }); }; var isSingle = function (detail) { return detail.colspan() === 1; }; var getFallback = function () { return Warehouse.getAt(warehouse, 0, col); }; return decide(getBlock, isSingle, getFallback); }); }; var decide = function (getBlock, isSingle, getFallback) { var inBlock = getBlock(); var singleInBlock = find(inBlock, isSingle); var detailOption = singleInBlock.orThunk(function () { return Option.from(inBlock[0]).orThunk(getFallback); }); return detailOption.map(function (detail) { return detail.element(); }); }; var rows$1 = function (warehouse) { var grid = warehouse.grid(); var rowsArr = Util.range(0, grid.rows()); var cols = Util.range(0, grid.columns()); return map(rowsArr, function (row) { var getBlock = function () { return bind(cols, function (c) { return Warehouse.getAt(warehouse, row, c).filter(function (detail) { return detail.row() === row; }).fold(constant([]), function (detail) { return [detail]; }); }); }; var isSingle = function (detail) { return detail.rowspan() === 1; }; var getFallback = function () { return Warehouse.getAt(warehouse, row, 0); }; return decide(getBlock, isSingle, getFallback); }); }; var Blocks = { columns: columns, rows: rows$1 }; var css = function (namespace) { var dashNamespace = namespace.replace(/\./g, '-'); var resolve = function (str) { return dashNamespace + '-' + str; }; return { resolve: resolve }; }; var styles = css('ephox-snooker'); var Styles = { resolve: styles.resolve }; var col = function (column, x, y, w, h) { var blocker = Element.fromTag('div'); setAll$1(blocker, { position: 'absolute', left: x - w / 2 + 'px', top: y + 'px', height: h + 'px', width: w + 'px' }); setAll(blocker, { 'data-column': column, 'role': 'presentation' }); return blocker; }; var row$1 = function (r, x, y, w, h) { var blocker = Element.fromTag('div'); setAll$1(blocker, { position: 'absolute', left: x + 'px', top: y - h / 2 + 'px', height: h + 'px', width: w + 'px' }); setAll(blocker, { 'data-row': r, 'role': 'presentation' }); return blocker; }; var Bar = { col: col, row: row$1 }; var resizeBar = Styles.resolve('resizer-bar'); var resizeRowBar = Styles.resolve('resizer-rows'); var resizeColBar = Styles.resolve('resizer-cols'); var BAR_THICKNESS = 7; var clear = function (wire) { var previous = descendants$1(wire.parent(), '.' + resizeBar); each(previous, remove$2); }; var drawBar = function (wire, positions, create) { var origin = wire.origin(); each(positions, function (cpOption, i) { cpOption.each(function (cp) { var bar = create(origin, cp); add$2(bar, resizeBar); append(wire.parent(), bar); }); }); }; var refreshCol = function (wire, colPositions, position, tableHeight) { drawBar(wire, colPositions, function (origin, cp) { var colBar = Bar.col(cp.col(), cp.x() - origin.left(), position.top() - origin.top(), BAR_THICKNESS, tableHeight); add$2(colBar, resizeColBar); return colBar; }); }; var refreshRow = function (wire, rowPositions, position, tableWidth) { drawBar(wire, rowPositions, function (origin, cp) { var rowBar = Bar.row(cp.row(), position.left() - origin.left(), cp.y() - origin.top(), tableWidth, BAR_THICKNESS); add$2(rowBar, resizeRowBar); return rowBar; }); }; var refreshGrid = function (wire, table, rows, cols, hdirection, vdirection) { var position = absolute(table); var rowPositions = rows.length > 0 ? hdirection.positions(rows, table) : []; refreshRow(wire, rowPositions, position, getOuter$1(table)); var colPositions = cols.length > 0 ? vdirection.positions(cols, table) : []; refreshCol(wire, colPositions, position, getOuter(table)); }; var refresh = function (wire, table, hdirection, vdirection) { clear(wire); var list = DetailsList.fromTable(table); var warehouse = Warehouse.generate(list); var rows = Blocks.rows(warehouse); var cols = Blocks.columns(warehouse); refreshGrid(wire, table, rows, cols, hdirection, vdirection); }; var each$2 = function (wire, f) { var bars = descendants$1(wire.parent(), '.' + resizeBar); each(bars, f); }; var hide = function (wire) { each$2(wire, function (bar) { set$1(bar, 'display', 'none'); }); }; var show = function (wire) { each$2(wire, function (bar) { set$1(bar, 'display', 'block'); }); }; var isRowBar = function (element) { return has$1(element, resizeRowBar); }; var isColBar = function (element) { return has$1(element, resizeColBar); }; var Bars = { refresh: refresh, hide: hide, show: show, destroy: clear, isRowBar: isRowBar, isColBar: isColBar }; var addCell = function (gridRow, index, cell) { var cells = gridRow.cells(); var before = cells.slice(0, index); var after = cells.slice(index); var newCells = before.concat([cell]).concat(after); return setCells(gridRow, newCells); }; var mutateCell = function (gridRow, index, cell) { var cells = gridRow.cells(); cells[index] = cell; }; var setCells = function (gridRow, cells) { return Structs.rowcells(cells, gridRow.section()); }; var mapCells = function (gridRow, f) { var cells = gridRow.cells(); var r = map(cells, f); return Structs.rowcells(r, gridRow.section()); }; var getCell = function (gridRow, index) { return gridRow.cells()[index]; }; var getCellElement = function (gridRow, index) { return getCell(gridRow, index).element(); }; var cellLength = function (gridRow) { return gridRow.cells().length; }; var GridRow = { addCell: addCell, setCells: setCells, mutateCell: mutateCell, getCell: getCell, getCellElement: getCellElement, mapCells: mapCells, cellLength: cellLength }; var getColumn = function (grid, index) { return map(grid, function (row) { return GridRow.getCell(row, index); }); }; var getRow = function (grid, index) { return grid[index]; }; var findDiff = function (xs, comp) { if (xs.length === 0) { return 0; } var first = xs[0]; var index = findIndex(xs, function (x) { return !comp(first.element(), x.element()); }); return index.fold(function () { return xs.length; }, function (ind) { return ind; }); }; var subgrid = function (grid, row, column, comparator) { var restOfRow = getRow(grid, row).cells().slice(column); var endColIndex = findDiff(restOfRow, comparator); var restOfColumn = getColumn(grid, column).slice(row); var endRowIndex = findDiff(restOfColumn, comparator); return { colspan: constant(endColIndex), rowspan: constant(endRowIndex) }; }; var TableGrid = { subgrid: subgrid }; var toDetails = function (grid, comparator) { var seen = map(grid, function (row, ri) { return map(row.cells(), function (col, ci) { return false; }); }); var updateSeen = function (ri, ci, rowspan, colspan) { for (var r = ri; r < ri + rowspan; r++) { for (var c = ci; c < ci + colspan; c++) { seen[r][c] = true; } } }; return map(grid, function (row, ri) { var details = bind(row.cells(), function (cell, ci) { if (seen[ri][ci] === false) { var result = TableGrid.subgrid(grid, ri, ci, comparator); updateSeen(ri, ci, result.rowspan(), result.colspan()); return [Structs.detailnew(cell.element(), result.rowspan(), result.colspan(), cell.isNew())]; } else { return []; } }); return Structs.rowdetails(details, row.section()); }); }; var toGrid = function (warehouse, generators, isNew) { var grid = []; for (var i = 0; i < warehouse.grid().rows(); i++) { var rowCells = []; for (var j = 0; j < warehouse.grid().columns(); j++) { var element = Warehouse.getAt(warehouse, i, j).map(function (item) { return Structs.elementnew(item.element(), isNew); }).getOrThunk(function () { return Structs.elementnew(generators.gap(), true); }); rowCells.push(element); } var row = Structs.rowcells(rowCells, warehouse.all()[i].section()); grid.push(row); } return grid; }; var Transitions = { toDetails: toDetails, toGrid: toGrid }; var fromWarehouse = function (warehouse, generators) { return Transitions.toGrid(warehouse, generators, false); }; var deriveRows = function (rendered, generators) { var findRow = function (details) { var rowOfCells = findMap(details, function (detail) { return parent(detail.element()).map(function (row) { var isNew = parent(row).isNone(); return Structs.elementnew(row, isNew); }); }); return rowOfCells.getOrThunk(function () { return Structs.elementnew(generators.row(), true); }); }; return map(rendered, function (details) { var row = findRow(details.details()); return Structs.rowdatanew(row.element(), details.details(), details.section(), row.isNew()); }); }; var toDetailList = function (grid, generators) { var rendered = Transitions.toDetails(grid, eq); return deriveRows(rendered, generators); }; var findInWarehouse = function (warehouse, element) { var all = flatten(map(warehouse.all(), function (r) { return r.cells(); })); return find(all, function (e) { return eq(element, e.element()); }); }; var run = function (operation, extract, adjustment, postAction, genWrappers) { return function (wire, table, target, generators, direction) { var input = DetailsList.fromTable(table); var warehouse = Warehouse.generate(input); var output = extract(warehouse, target).map(function (info) { var model = fromWarehouse(warehouse, generators); var result = operation(model, info, eq, genWrappers(generators)); var grid = toDetailList(result.grid(), generators); return { grid: constant(grid), cursor: result.cursor }; }); return output.fold(function () { return Option.none(); }, function (out) { var newElements = Redraw.render(table, out.grid()); adjustment(table, out.grid(), direction); postAction(table); Bars.refresh(wire, table, BarPositions.height, direction); return Option.some({ cursor: out.cursor, newRows: newElements.newRows, newCells: newElements.newCells }); }); }; }; var onCell = function (warehouse, target) { return TableLookup.cell(target.element()).bind(function (cell) { return findInWarehouse(warehouse, cell); }); }; var onPaste = function (warehouse, target) { return TableLookup.cell(target.element()).bind(function (cell) { return findInWarehouse(warehouse, cell).map(function (details) { return merge(details, { generators: target.generators, clipboard: target.clipboard }); }); }); }; var onPasteRows = function (warehouse, target) { var details = map(target.selection(), function (cell) { return TableLookup.cell(cell).bind(function (lc) { return findInWarehouse(warehouse, lc); }); }); var cells = cat(details); return cells.length > 0 ? Option.some(merge({ cells: cells }, { generators: target.generators, clipboard: target.clipboard })) : Option.none(); }; var onMergable = function (warehouse, target) { return target.mergable(); }; var onUnmergable = function (warehouse, target) { return target.unmergable(); }; var onCells = function (warehouse, target) { var details = map(target.selection(), function (cell) { return TableLookup.cell(cell).bind(function (lc) { return findInWarehouse(warehouse, lc); }); }); var cells = cat(details); return cells.length > 0 ? Option.some(cells) : Option.none(); }; var RunOperation = { run: run, toDetailList: toDetailList, onCell: onCell, onCells: onCells, onPaste: onPaste, onPasteRows: onPasteRows, onMergable: onMergable, onUnmergable: onUnmergable }; var value = function (o) { var is = function (v) { return o === v; }; var or = function (opt) { return value(o); }; var orThunk = function (f) { return value(o); }; var map = function (f) { return value(f(o)); }; var mapError = function (f) { return value(o); }; var each = function (f) { f(o); }; var bind = function (f) { return f(o); }; var fold = function (_, onValue) { return onValue(o); }; var exists = function (f) { return f(o); }; var forall = function (f) { return f(o); }; var toOption = function () { return Option.some(o); }; return { is: is, isValue: always, isError: never, getOr: constant(o), getOrThunk: constant(o), getOrDie: constant(o), or: or, orThunk: orThunk, fold: fold, map: map, mapError: mapError, each: each, bind: bind, exists: exists, forall: forall, toOption: toOption }; }; var error = function (message) { var getOrThunk = function (f) { return f(); }; var getOrDie = function () { return die(String(message))(); }; var or = function (opt) { return opt; }; var orThunk = function (f) { return f(); }; var map = function (f) { return error(message); }; var mapError = function (f) { return error(f(message)); }; var bind = function (f) { return error(message); }; var fold = function (onError, _) { return onError(message); }; return { is: never, isValue: never, isError: always, getOr: identity, getOrThunk: getOrThunk, getOrDie: getOrDie, or: or, orThunk: orThunk, fold: fold, map: map, mapError: mapError, each: noop, bind: bind, exists: never, forall: always, toOption: Option.none }; }; var Result = { value: value, error: error }; var measure = function (startAddress, gridA, gridB) { if (startAddress.row() >= gridA.length || startAddress.column() > GridRow.cellLength(gridA[0])) { return Result.error('invalid start address out of table bounds, row: ' + startAddress.row() + ', column: ' + startAddress.column()); } var rowRemainder = gridA.slice(startAddress.row()); var colRemainder = rowRemainder[0].cells().slice(startAddress.column()); var colRequired = GridRow.cellLength(gridB[0]); var rowRequired = gridB.length; return Result.value({ rowDelta: constant(rowRemainder.length - rowRequired), colDelta: constant(colRemainder.length - colRequired) }); }; var measureWidth = function (gridA, gridB) { var colLengthA = GridRow.cellLength(gridA[0]); var colLengthB = GridRow.cellLength(gridB[0]); return { rowDelta: constant(0), colDelta: constant(colLengthA - colLengthB) }; }; var fill = function (cells, generator) { return map(cells, function () { return Structs.elementnew(generator.cell(), true); }); }; var rowFill = function (grid, amount, generator) { return grid.concat(Util.repeat(amount, function (_row) { return GridRow.setCells(grid[grid.length - 1], fill(grid[grid.length - 1].cells(), generator)); })); }; var colFill = function (grid, amount, generator) { return map(grid, function (row) { return GridRow.setCells(row, row.cells().concat(fill(Util.range(0, amount), generator))); }); }; var tailor = function (gridA, delta, generator) { var fillCols = delta.colDelta() < 0 ? colFill : identity; var fillRows = delta.rowDelta() < 0 ? rowFill : identity; var modifiedCols = fillCols(gridA, Math.abs(delta.colDelta()), generator); var tailoredGrid = fillRows(modifiedCols, Math.abs(delta.rowDelta()), generator); return tailoredGrid; }; var Fitment = { measure: measure, measureWidth: measureWidth, tailor: tailor }; var merge$1 = function (grid, bounds, comparator, substitution) { if (grid.length === 0) { return grid; } for (var i = bounds.startRow(); i <= bounds.finishRow(); i++) { for (var j = bounds.startCol(); j <= bounds.finishCol(); j++) { GridRow.mutateCell(grid[i], j, Structs.elementnew(substitution(), false)); } } return grid; }; var unmerge = function (grid, target, comparator, substitution) { var first = true; for (var i = 0; i < grid.length; i++) { for (var j = 0; j < GridRow.cellLength(grid[0]); j++) { var current = GridRow.getCellElement(grid[i], j); var isToReplace = comparator(current, target); if (isToReplace === true && first === false) { GridRow.mutateCell(grid[i], j, Structs.elementnew(substitution(), true)); } else if (isToReplace === true) { first = false; } } } return grid; }; var uniqueCells = function (row, comparator) { return foldl(row, function (rest, cell) { return exists(rest, function (currentCell) { return comparator(currentCell.element(), cell.element()); }) ? rest : rest.concat([cell]); }, []); }; var splitRows = function (grid, index, comparator, substitution) { if (index > 0 && index < grid.length) { var rowPrevCells = grid[index - 1].cells(); var cells = uniqueCells(rowPrevCells, comparator); each(cells, function (cell) { var replacement = Option.none(); var _loop_1 = function (i) { var _loop_2 = function (j) { var current = grid[i].cells()[j]; var isToReplace = comparator(current.element(), cell.element()); if (isToReplace) { if (replacement.isNone()) { replacement = Option.some(substitution()); } replacement.each(function (sub) { GridRow.mutateCell(grid[i], j, Structs.elementnew(sub, true)); }); } }; for (var j = 0; j < GridRow.cellLength(grid[0]); j++) { _loop_2(j); } }; for (var i = index; i < grid.length; i++) { _loop_1(i); } }); } return grid; }; var MergingOperations = { merge: merge$1, unmerge: unmerge, splitRows: splitRows }; var isSpanning = function (grid, row, col, comparator) { var candidate = GridRow.getCell(grid[row], col); var matching = curry(comparator, candidate.element()); var currentRow = grid[row]; return grid.length > 1 && GridRow.cellLength(currentRow) > 1 && (col > 0 && matching(GridRow.getCellElement(currentRow, col - 1)) || col < currentRow.length - 1 && matching(GridRow.getCellElement(currentRow, col + 1)) || row > 0 && matching(GridRow.getCellElement(grid[row - 1], col)) || row < grid.length - 1 && matching(GridRow.getCellElement(grid[row + 1], col))); }; var mergeTables = function (startAddress, gridA, gridB, generator, comparator) { var startRow = startAddress.row(); var startCol = startAddress.column(); var mergeHeight = gridB.length; var mergeWidth = GridRow.cellLength(gridB[0]); var endRow = startRow + mergeHeight; var endCol = startCol + mergeWidth; for (var r = startRow; r < endRow; r++) { for (var c = startCol; c < endCol; c++) { if (isSpanning(gridA, r, c, comparator)) { MergingOperations.unmerge(gridA, GridRow.getCellElement(gridA[r], c), comparator, generator.cell); } var newCell = GridRow.getCellElement(gridB[r - startRow], c - startCol); var replacement = generator.replace(newCell); GridRow.mutateCell(gridA[r], c, Structs.elementnew(replacement, true)); } } return gridA; }; var merge$2 = function (startAddress, gridA, gridB, generator, comparator) { var result = Fitment.measure(startAddress, gridA, gridB); return result.map(function (delta) { var fittedGrid = Fitment.tailor(gridA, delta, generator); return mergeTables(startAddress, fittedGrid, gridB, generator, comparator); }); }; var insert = function (index, gridA, gridB, generator, comparator) { MergingOperations.splitRows(gridA, index, comparator, generator.cell); var delta = Fitment.measureWidth(gridB, gridA); var fittedNewGrid = Fitment.tailor(gridB, delta, generator); var secondDelta = Fitment.measureWidth(gridA, fittedNewGrid); var fittedOldGrid = Fitment.tailor(gridA, secondDelta, generator); return fittedOldGrid.slice(0, index).concat(fittedNewGrid).concat(fittedOldGrid.slice(index, fittedOldGrid.length)); }; var TableMerge = { merge: merge$2, insert: insert }; var insertRowAt = function (grid, index, example, comparator, substitution) { var before = grid.slice(0, index); var after = grid.slice(index); var between = GridRow.mapCells(grid[example], function (ex, c) { var withinSpan = index > 0 && index < grid.length && comparator(GridRow.getCellElement(grid[index - 1], c), GridRow.getCellElement(grid[index], c)); var ret = withinSpan ? GridRow.getCell(grid[index], c) : Structs.elementnew(substitution(ex.element(), comparator), true); return ret; }); return before.concat([between]).concat(after); }; var insertColumnAt = function (grid, index, example, comparator, substitution) { return map(grid, function (row) { var withinSpan = index > 0 && index < GridRow.cellLength(row) && comparator(GridRow.getCellElement(row, index - 1), GridRow.getCellElement(row, index)); var sub = withinSpan ? GridRow.getCell(row, index) : Structs.elementnew(substitution(GridRow.getCellElement(row, example), comparator), true); return GridRow.addCell(row, index, sub); }); }; var splitCellIntoColumns = function (grid, exampleRow, exampleCol, comparator, substitution) { var index = exampleCol + 1; return map(grid, function (row, i) { var isTargetCell = i === exampleRow; var sub = isTargetCell ? Structs.elementnew(substitution(GridRow.getCellElement(row, exampleCol), comparator), true) : GridRow.getCell(row, exampleCol); return GridRow.addCell(row, index, sub); }); }; var splitCellIntoRows = function (grid, exampleRow, exampleCol, comparator, substitution) { var index = exampleRow + 1; var before = grid.slice(0, index); var after = grid.slice(index); var between = GridRow.mapCells(grid[exampleRow], function (ex, i) { var isTargetCell = i === exampleCol; return isTargetCell ? Structs.elementnew(substitution(ex.element(), comparator), true) : ex; }); return before.concat([between]).concat(after); }; var deleteColumnsAt = function (grid, start, finish) { var rows = map(grid, function (row) { var cells = row.cells().slice(0, start).concat(row.cells().slice(finish + 1)); return Structs.rowcells(cells, row.section()); }); return filter(rows, function (row) { return row.cells().length > 0; }); }; var deleteRowsAt = function (grid, start, finish) { return grid.slice(0, start).concat(grid.slice(finish + 1)); }; var ModificationOperations = { insertRowAt: insertRowAt, insertColumnAt: insertColumnAt, splitCellIntoColumns: splitCellIntoColumns, splitCellIntoRows: splitCellIntoRows, deleteRowsAt: deleteRowsAt, deleteColumnsAt: deleteColumnsAt }; var get$7 = function (element) { return element.dom().textContent; }; var replaceIn = function (grid, targets, comparator, substitution) { var isTarget = function (cell) { return exists(targets, function (target) { return comparator(cell.element(), target.element()); }); }; return map(grid, function (row) { return GridRow.mapCells(row, function (cell) { return isTarget(cell) ? Structs.elementnew(substitution(cell.element(), comparator), true) : cell; }); }); }; var notStartRow = function (grid, rowIndex, colIndex, comparator) { return GridRow.getCellElement(grid[rowIndex], colIndex) !== undefined && (rowIndex > 0 && comparator(GridRow.getCellElement(grid[rowIndex - 1], colIndex), GridRow.getCellElement(grid[rowIndex], colIndex))); }; var notStartColumn = function (row, index, comparator) { return index > 0 && comparator(GridRow.getCellElement(row, index - 1), GridRow.getCellElement(row, index)); }; var replaceColumn = function (grid, index, comparator, substitution) { var targets = bind(grid, function (row, i) { var alreadyAdded = notStartRow(grid, i, index, comparator) || notStartColumn(row, index, comparator); return alreadyAdded ? [] : [GridRow.getCell(row, index)]; }); return replaceIn(grid, targets, comparator, substitution); }; var replaceRow = function (grid, index, comparator, substitution) { var targetRow = grid[index]; var targets = bind(targetRow.cells(), function (item, i) { var alreadyAdded = notStartRow(grid, index, i, comparator) || notStartColumn(targetRow, i, comparator); return alreadyAdded ? [] : [item]; }); return replaceIn(grid, targets, comparator, substitution); }; var sortTableRows = function (grid, index, comparator, ascending) { var grouped = groupBy(grid, function (row) { return name(GridRow.getCell(row, index).element()); }); var sortGroup = function (group) { var texted = map(group, function (row) { var cell = GridRow.getCell(row, index); var text = get$7(cell.element()); return { row: row, text: text }; }); var sorted = sort(texted, function (rowA, rowB) { var compared = comparator(rowA.text, rowB.text); return ascending ? compared : compared * -1; }); return map(sorted, function (sortedRow) { return sortedRow.row; }); }; return bind(grouped, function (group) { return name(GridRow.getCell(group[0], index).element()) === 'th' ? group : sortGroup(group); }); }; var sortTableColumns = function (grid, index, comparator, ascending) { var targetRow = grid[index].cells(); var targetReferences = map(targetRow, function (cell) { return get$7(cell.element()); }); var zip = function (row) { var zippedCells = map(row.cells(), function (cell, i) { return { cell: cell, reference: targetRow[i], referenceText: targetReferences[i] }; }); return { zippedCells: zippedCells, section: row.section() }; }; var unzip = function (row) { var grouped = groupBy(row.zippedCells, function (zippedCell) { return name(zippedCell.reference.element()); }); var sorted = bind(grouped, function (group) { return name(group[0].reference.element()) === 'th' ? group : sort(group, function (cellA, cellB) { var compared = comparator(cellA.referenceText, cellB.referenceText); return ascending ? compared : compared * -1; }); }); var unzippedCells = map(sorted, function (sortedCell) { return sortedCell.cell; }); return Structs.rowcells(unzippedCells, row.section); }; var zippedGrid = map(grid, zip); var unzipped = map(zippedGrid, unzip); return unzipped; }; var TransformOperations = { replaceColumn: replaceColumn, replaceRow: replaceRow, sortTableRows: sortTableRows, sortTableColumns: sortTableColumns }; var none$1 = function () { return folder(function (n, o, l, m, r) { return n(); }); }; var only = function (index) { return folder(function (n, o, l, m, r) { return o(index); }); }; var left = function (index, next) { return folder(function (n, o, l, m, r) { return l(index, next); }); }; var middle = function (prev, index, next) { return folder(function (n, o, l, m, r) { return m(prev, index, next); }); }; var right = function (prev, index) { return folder(function (n, o, l, m, r) { return r(prev, index); }); }; var folder = function (fold) { return { fold: fold }; }; var ColumnContext = { none: none$1, only: only, left: left, middle: middle, right: right }; var neighbours$1 = function (input, index) { if (input.length === 0) { return ColumnContext.none(); } if (input.length === 1) { return ColumnContext.only(0); } if (index === 0) { return ColumnContext.left(0, 1); } if (index === input.length - 1) { return ColumnContext.right(index - 1, index); } if (index > 0 && index < input.length - 1) { return ColumnContext.middle(index - 1, index, index + 1); } return ColumnContext.none(); }; var determine = function (input, column, step, tableSize) { var result = input.slice(0); var context = neighbours$1(input, column); var zero = function (array) { return map(array, constant(0)); }; var onNone = constant(zero(result)); var onOnly = function (index) { return tableSize.singleColumnWidth(result[index], step); }; var onChange = function (index, next) { if (step >= 0) { var newNext = Math.max(tableSize.minCellWidth(), result[next] - step); return zero(result.slice(0, index)).concat([ step, newNext - result[next] ]).concat(zero(result.slice(next + 1))); } else { var newThis = Math.max(tableSize.minCellWidth(), result[index] + step); var diffx = result[index] - newThis; return zero(result.slice(0, index)).concat([ newThis - result[index], diffx ]).concat(zero(result.slice(next + 1))); } }; var onLeft = onChange; var onMiddle = function (prev, index, next) { return onChange(index, next); }; var onRight = function (prev, index) { if (step >= 0) { return zero(result.slice(0, index)).concat([step]); } else { var size = Math.max(tableSize.minCellWidth(), result[index] + step); return zero(result.slice(0, index)).concat([size - result[index]]); } }; return context.fold(onNone, onOnly, onLeft, onMiddle, onRight); }; var Deltas = { determine: determine }; var getSpan$1 = function (cell, type) { return has(cell, type) && parseInt(get(cell, type), 10) > 1; }; var hasColspan = function (cell) { return getSpan$1(cell, 'colspan'); }; var hasRowspan = function (cell) { return getSpan$1(cell, 'rowspan'); }; var getInt = function (element, property) { return parseInt(get$1(element, property), 10); }; var CellUtils = { hasColspan: hasColspan, hasRowspan: hasRowspan, minWidth: constant(10), minHeight: constant(10), getInt: getInt }; var getRaw$1 = function (cell, property, getter) { return getRaw(cell, property).fold(function () { return getter(cell) + 'px'; }, function (raw) { return raw; }); }; var getRawW = function (cell) { return getRaw$1(cell, 'width', Sizes.getPixelWidth); }; var getRawH = function (cell) { return getRaw$1(cell, 'height', Sizes.getHeight); }; var getWidthFrom = function (warehouse, direction, getWidth, fallback, tableSize) { var columns = Blocks.columns(warehouse); var backups = map(columns, function (cellOption) { return cellOption.map(direction.edge); }); return map(columns, function (cellOption, c) { var columnCell = cellOption.filter(not(CellUtils.hasColspan)); return columnCell.fold(function () { var deduced = Util.deduce(backups, c); return fallback(deduced); }, function (cell) { return getWidth(cell, tableSize); }); }); }; var getDeduced = function (deduced) { return deduced.map(function (d) { return d + 'px'; }).getOr(''); }; var getRawWidths = function (warehouse, direction) { return getWidthFrom(warehouse, direction, getRawW, getDeduced); }; var getPercentageWidths = function (warehouse, direction, tableSize) { return getWidthFrom(warehouse, direction, Sizes.getPercentageWidth, function (deduced) { return deduced.fold(function () { return tableSize.minCellWidth(); }, function (cellWidth) { return cellWidth / tableSize.pixelWidth() * 100; }); }, tableSize); }; var getPixelWidths = function (warehouse, direction, tableSize) { return getWidthFrom(warehouse, direction, Sizes.getPixelWidth, function (deduced) { return deduced.getOrThunk(tableSize.minCellWidth); }, tableSize); }; var getHeightFrom = function (warehouse, direction, getHeight, fallback) { var rows = Blocks.rows(warehouse); var backups = map(rows, function (cellOption) { return cellOption.map(direction.edge); }); return map(rows, function (cellOption, c) { var rowCell = cellOption.filter(not(CellUtils.hasRowspan)); return rowCell.fold(function () { var deduced = Util.deduce(backups, c); return fallback(deduced); }, function (cell) { return getHeight(cell); }); }); }; var getPixelHeights = function (warehouse, direction) { return getHeightFrom(warehouse, direction, Sizes.getHeight, function (deduced) { return deduced.getOrThunk(CellUtils.minHeight); }); }; var getRawHeights = function (warehouse, direction) { return getHeightFrom(warehouse, direction, getRawH, getDeduced); }; var ColumnSizes = { getRawWidths: getRawWidths, getPixelWidths: getPixelWidths, getPercentageWidths: getPercentageWidths, getPixelHeights: getPixelHeights, getRawHeights: getRawHeights }; var total = function (start, end, measures) { var r = 0; for (var i = start; i < end; i++) { r += measures[i] !== undefined ? measures[i] : 0; } return r; }; var recalculateWidth = function (warehouse, widths) { var all = Warehouse.justCells(warehouse); return map(all, function (cell) { var width = total(cell.column(), cell.column() + cell.colspan(), widths); return { element: cell.element, width: constant(width), colspan: cell.colspan }; }); }; var recalculateHeight = function (warehouse, heights) { var all = Warehouse.justCells(warehouse); return map(all, function (cell) { var height = total(cell.row(), cell.row() + cell.rowspan(), heights); return { element: cell.element, height: constant(height), rowspan: cell.rowspan }; }); }; var matchRowHeight = function (warehouse, heights) { return map(warehouse.all(), function (row, i) { return { element: row.element, height: constant(heights[i]) }; }); }; var Recalculations = { recalculateWidth: recalculateWidth, recalculateHeight: recalculateHeight, matchRowHeight: matchRowHeight }; var percentageSize = function (width, element) { var floatWidth = parseFloat(width); var pixelWidth = get$4(element); var getCellDelta = function (delta) { return delta / pixelWidth * 100; }; var singleColumnWidth = function (w, _delta) { return [100 - w]; }; var minCellWidth = function () { return CellUtils.minWidth() / pixelWidth * 100; }; var setTableWidth = function (table, _newWidths, delta) { var total = floatWidth + delta; Sizes.setPercentageWidth(table, total); }; return { width: constant(floatWidth), pixelWidth: constant(pixelWidth), getWidths: ColumnSizes.getPercentageWidths, getCellDelta: getCellDelta, singleColumnWidth: singleColumnWidth, minCellWidth: minCellWidth, setElementWidth: Sizes.setPercentageWidth, setTableWidth: setTableWidth }; }; var pixelSize = function (width) { var intWidth = parseInt(width, 10); var getCellDelta = identity; var singleColumnWidth = function (w, delta) { var newNext = Math.max(CellUtils.minWidth(), w + delta); return [newNext - w]; }; var setTableWidth = function (table, newWidths, _delta) { var total = foldr(newWidths, function (b, a) { return b + a; }, 0); Sizes.setPixelWidth(table, total); }; return { width: constant(intWidth), pixelWidth: constant(intWidth), getWidths: ColumnSizes.getPixelWidths, getCellDelta: getCellDelta, singleColumnWidth: singleColumnWidth, minCellWidth: CellUtils.minWidth, setElementWidth: Sizes.setPixelWidth, setTableWidth: setTableWidth }; }; var chooseSize = function (element, width) { if (Sizes.percentageBasedSizeRegex().test(width)) { var percentMatch = Sizes.percentageBasedSizeRegex().exec(width); return percentageSize(percentMatch[1], element); } else if (Sizes.pixelBasedSizeRegex().test(width)) { var pixelMatch = Sizes.pixelBasedSizeRegex().exec(width); return pixelSize(pixelMatch[1]); } else { var fallbackWidth = get$4(element); return pixelSize(fallbackWidth); } }; var getTableSize = function (element) { var width = Sizes.getRawWidth(element); return width.fold(function () { var fallbackWidth = get$4(element); return pixelSize(fallbackWidth); }, function (w) { return chooseSize(element, w); }); }; var TableSize = { getTableSize: getTableSize }; var getWarehouse$1 = function (list) { return Warehouse.generate(list); }; var sumUp = function (newSize) { return foldr(newSize, function (b, a) { return b + a; }, 0); }; var getTableWarehouse = function (table) { var list = DetailsList.fromTable(table); return getWarehouse$1(list); }; var adjustWidth = function (table, delta, index, direction) { var tableSize = TableSize.getTableSize(table); var step = tableSize.getCellDelta(delta); var warehouse = getTableWarehouse(table); var widths = tableSize.getWidths(warehouse, direction, tableSize); var deltas = Deltas.determine(widths, index, step, tableSize); var newWidths = map(deltas, function (dx, i) { return dx + widths[i]; }); var newSizes = Recalculations.recalculateWidth(warehouse, newWidths); each(newSizes, function (cell) { tableSize.setElementWidth(cell.element(), cell.width()); }); if (index === warehouse.grid().columns() - 1) { tableSize.setTableWidth(table, newWidths, step); } }; var adjustHeight = function (table, delta, index, direction) { var warehouse = getTableWarehouse(table); var heights = ColumnSizes.getPixelHeights(warehouse, direction); var newHeights = map(heights, function (dy, i) { return index === i ? Math.max(delta + dy, CellUtils.minHeight()) : dy; }); var newCellSizes = Recalculations.recalculateHeight(warehouse, newHeights); var newRowSizes = Recalculations.matchRowHeight(warehouse, newHeights); each(newRowSizes, function (row) { Sizes.setHeight(row.element(), row.height()); }); each(newCellSizes, function (cell) { Sizes.setHeight(cell.element(), cell.height()); }); var total = sumUp(newHeights); Sizes.setHeight(table, total); }; var adjustWidthTo = function (table, list, direction) { var tableSize = TableSize.getTableSize(table); var warehouse = getWarehouse$1(list); var widths = tableSize.getWidths(warehouse, direction, tableSize); var newSizes = Recalculations.recalculateWidth(warehouse, widths); each(newSizes, function (cell) { tableSize.setElementWidth(cell.element(), cell.width()); }); var total = foldr(widths, function (b, a) { return a + b; }, 0); if (newSizes.length > 0) { tableSize.setTableWidth(table, total); } }; var Adjustments = { adjustWidth: adjustWidth, adjustHeight: adjustHeight, adjustWidthTo: adjustWidthTo }; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var base = function (handleUnsupported, required) { return baseWith(handleUnsupported, required, { validate: isFunction, label: 'function' }); }; var baseWith = function (handleUnsupported, required, pred) { if (required.length === 0) throw new Error('You must specify at least one required field.'); validateStrArr('required', required); checkDupes(required); return function (obj) { var keys$1 = keys(obj); var allReqd = forall(required, function (req) { return contains(keys$1, req); }); if (!allReqd) reqMessage(required, keys$1); handleUnsupported(required, keys$1); var invalidKeys = filter(required, function (key) { return !pred.validate(obj[key], key); }); if (invalidKeys.length > 0) invalidTypeMessage(invalidKeys, pred.label); return obj; }; }; var handleExact = function (required, keys) { var unsupported = filter(keys, function (key) { return !contains(required, key); }); if (unsupported.length > 0) unsuppMessage(unsupported); }; var exactly = function (required) { return base(handleExact, required); }; var elementToData = function (element) { var colspan = has(element, 'colspan') ? parseInt(get(element, 'colspan'), 10) : 1; var rowspan = has(element, 'rowspan') ? parseInt(get(element, 'rowspan'), 10) : 1; return { element: constant(element), colspan: constant(colspan), rowspan: constant(rowspan) }; }; var modification = function (generators, _toData) { contract(generators); var position = Cell(Option.none()); var toData = _toData !== undefined ? _toData : elementToData; var nu = function (data) { return generators.cell(data); }; var nuFrom = function (element) { var data = toData(element); return nu(data); }; var add = function (element) { var replacement = nuFrom(element); if (position.get().isNone()) { position.set(Option.some(replacement)); } recent = Option.some({ item: element, replacement: replacement }); return replacement; }; var recent = Option.none(); var getOrInit = function (element, comparator) { return recent.fold(function () { return add(element); }, function (p) { return comparator(element, p.item) ? p.replacement : add(element); }); }; return { getOrInit: getOrInit, cursor: position.get }; }; var transform = function (scope, tag) { return function (generators) { var position = Cell(Option.none()); contract(generators); var list = []; var find$1 = function (element, comparator) { return find(list, function (x) { return comparator(x.item, element); }); }; var makeNew = function (element) { var cell = generators.replace(element, tag, { scope: scope }); list.push({ item: element, sub: cell }); if (position.get().isNone()) { position.set(Option.some(cell)); } return cell; }; var replaceOrInit = function (element, comparator) { return find$1(element, comparator).fold(function () { return makeNew(element); }, function (p) { return comparator(element, p.item) ? p.sub : makeNew(element); }); }; return { replaceOrInit: replaceOrInit, cursor: position.get }; }; }; var merging = function (generators) { contract(generators); var position = Cell(Option.none()); var combine = function (cell) { if (position.get().isNone()) { position.set(Option.some(cell)); } return function () { var raw = generators.cell({ element: constant(cell), colspan: constant(1), rowspan: constant(1) }); remove$1(raw, 'width'); remove$1(cell, 'width'); return raw; }; }; return { combine: combine, cursor: position.get }; }; var contract = exactly([ 'cell', 'row', 'replace', 'gap' ]); var Generators = { modification: modification, transform: transform, merging: merging }; var blockList = [ 'body', 'p', 'div', 'article', 'aside', 'figcaption', 'figure', 'footer', 'header', 'nav', 'section', 'ol', 'ul', 'table', 'thead', 'tfoot', 'tbody', 'caption', 'tr', 'td', 'th', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'pre', 'address' ]; var isList = function (universe, item) { var tagName = universe.property().name(item); return contains([ 'ol', 'ul' ], tagName); }; var isBlock = function (universe, item) { var tagName = universe.property().name(item); return contains(blockList, tagName); }; var isFormatting = function (universe, item) { var tagName = universe.property().name(item); return contains([ 'address', 'pre', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ], tagName); }; var isHeading = function (universe, item) { var tagName = universe.property().name(item); return contains([ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ], tagName); }; var isContainer = function (universe, item) { return contains([ 'div', 'li', 'td', 'th', 'blockquote', 'body', 'caption' ], universe.property().name(item)); }; var isEmptyTag = function (universe, item) { return contains([ 'br', 'img', 'hr', 'input' ], universe.property().name(item)); }; var isFrame = function (universe, item) { return universe.property().name(item) === 'iframe'; }; var isInline = function (universe, item) { return !(isBlock(universe, item) || isEmptyTag(universe, item)) && universe.property().name(item) !== 'li'; }; var Structure = { isBlock: isBlock, isList: isList, isFormatting: isFormatting, isHeading: isHeading, isContainer: isContainer, isEmptyTag: isEmptyTag, isFrame: isFrame, isInline: isInline }; var universe$1 = DomUniverse(); var isBlock$1 = function (element) { return Structure.isBlock(universe$1, element); }; var isList$1 = function (element) { return Structure.isList(universe$1, element); }; var isFormatting$1 = function (element) { return Structure.isFormatting(universe$1, element); }; var isHeading$1 = function (element) { return Structure.isHeading(universe$1, element); }; var isContainer$1 = function (element) { return Structure.isContainer(universe$1, element); }; var isEmptyTag$1 = function (element) { return Structure.isEmptyTag(universe$1, element); }; var isFrame$1 = function (element) { return Structure.isFrame(universe$1, element); }; var isInline$1 = function (element) { return Structure.isInline(universe$1, element); }; var DomStructure = { isBlock: isBlock$1, isList: isList$1, isFormatting: isFormatting$1, isHeading: isHeading$1, isContainer: isContainer$1, isEmptyTag: isEmptyTag$1, isFrame: isFrame$1, isInline: isInline$1 }; var merge$3 = function (cells) { var isBr = function (el) { return name(el) === 'br'; }; var advancedBr = function (children) { return forall(children, function (c) { return isBr(c) || isText(c) && get$2(c).trim().length === 0; }); }; var isListItem = function (el) { return name(el) === 'li' || ancestor(el, DomStructure.isList).isSome(); }; var siblingIsBlock = function (el) { return nextSibling(el).map(function (rightSibling) { if (DomStructure.isBlock(rightSibling)) { return true; } if (DomStructure.isEmptyTag(rightSibling)) { return name(rightSibling) === 'img' ? false : true; } }).getOr(false); }; var markCell = function (cell) { return last$1(cell).bind(function (rightEdge) { var rightSiblingIsBlock = siblingIsBlock(rightEdge); return parent(rightEdge).map(function (parent) { return rightSiblingIsBlock === true || isListItem(parent) || isBr(rightEdge) || DomStructure.isBlock(parent) && !eq(cell, parent) ? [] : [Element.fromTag('br')]; }); }).getOr([]); }; var markContent = function () { var content = bind(cells, function (cell) { var children$1 = children(cell); return advancedBr(children$1) ? [] : children$1.concat(markCell(cell)); }); return content.length === 0 ? [Element.fromTag('br')] : content; }; var contents = markContent(); empty(cells[0]); append$1(cells[0], contents); }; var TableContent = { merge: merge$3 }; var prune = function (table) { var cells = TableLookup.cells(table); if (cells.length === 0) { remove$2(table); } }; var outcome = Immutable('grid', 'cursor'); var elementFromGrid = function (grid, row, column) { return findIn(grid, row, column).orThunk(function () { return findIn(grid, 0, 0); }); }; var findIn = function (grid, row, column) { return Option.from(grid[row]).bind(function (r) { return Option.from(r.cells()[column]).bind(function (c) { return Option.from(c.element()); }); }); }; var bundle = function (grid, row, column) { return outcome(grid, findIn(grid, row, column)); }; var uniqueRows = function (details) { return foldl(details, function (rest, detail) { return exists(rest, function (currentDetail) { return currentDetail.row() === detail.row(); }) ? rest : rest.concat([detail]); }, []).sort(function (detailA, detailB) { return detailA.row() - detailB.row(); }); }; var uniqueColumns = function (details) { return foldl(details, function (rest, detail) { return exists(rest, function (currentDetail) { return currentDetail.column() === detail.column(); }) ? rest : rest.concat([detail]); }, []).sort(function (detailA, detailB) { return detailA.column() - detailB.column(); }); }; var insertRowBefore = function (grid, detail, comparator, genWrappers) { var example = detail.row(); var targetIndex = detail.row(); var newGrid = ModificationOperations.insertRowAt(grid, targetIndex, example, comparator, genWrappers.getOrInit); return bundle(newGrid, targetIndex, detail.column()); }; var insertRowsBefore = function (grid, details, comparator, genWrappers) { var example = details[0].row(); var targetIndex = details[0].row(); var rows = uniqueRows(details); var newGrid = foldl(rows, function (newG, _row) { return ModificationOperations.insertRowAt(newG, targetIndex, example, comparator, genWrappers.getOrInit); }, grid); return bundle(newGrid, targetIndex, details[0].column()); }; var insertRowAfter = function (grid, detail, comparator, genWrappers) { var example = detail.row(); var targetIndex = detail.row() + detail.rowspan(); var newGrid = ModificationOperations.insertRowAt(grid, targetIndex, example, comparator, genWrappers.getOrInit); return bundle(newGrid, targetIndex, detail.column()); }; var insertRowsAfter = function (grid, details, comparator, genWrappers) { var rows = uniqueRows(details); var example = rows[rows.length - 1].row(); var targetIndex = rows[rows.length - 1].row() + rows[rows.length - 1].rowspan(); var newGrid = foldl(rows, function (newG, _row) { return ModificationOperations.insertRowAt(newG, targetIndex, example, comparator, genWrappers.getOrInit); }, grid); return bundle(newGrid, targetIndex, details[0].column()); }; var insertColumnBefore = function (grid, detail, comparator, genWrappers) { var example = detail.column(); var targetIndex = detail.column(); var newGrid = ModificationOperations.insertColumnAt(grid, targetIndex, example, comparator, genWrappers.getOrInit); return bundle(newGrid, detail.row(), targetIndex); }; var insertColumnsBefore = function (grid, details, comparator, genWrappers) { var columns = uniqueColumns(details); var example = columns[0].column(); var targetIndex = columns[0].column(); var newGrid = foldl(columns, function (newG, _row) { return ModificationOperations.insertColumnAt(newG, targetIndex, example, comparator, genWrappers.getOrInit); }, grid); return bundle(newGrid, details[0].row(), targetIndex); }; var insertColumnAfter = function (grid, detail, comparator, genWrappers) { var example = detail.column(); var targetIndex = detail.column() + detail.colspan(); var newGrid = ModificationOperations.insertColumnAt(grid, targetIndex, example, comparator, genWrappers.getOrInit); return bundle(newGrid, detail.row(), targetIndex); }; var insertColumnsAfter = function (grid, details, comparator, genWrappers) { var example = details[details.length - 1].column(); var targetIndex = details[details.length - 1].column() + details[details.length - 1].colspan(); var columns = uniqueColumns(details); var newGrid = foldl(columns, function (newG, _row) { return ModificationOperations.insertColumnAt(newG, targetIndex, example, comparator, genWrappers.getOrInit); }, grid); return bundle(newGrid, details[0].row(), targetIndex); }; var makeRowHeader = function (grid, detail, comparator, genWrappers) { var newGrid = TransformOperations.replaceRow(grid, detail.row(), comparator, genWrappers.replaceOrInit); return bundle(newGrid, detail.row(), detail.column()); }; var makeColumnHeader = function (grid, detail, comparator, genWrappers) { var newGrid = TransformOperations.replaceColumn(grid, detail.column(), comparator, genWrappers.replaceOrInit); return bundle(newGrid, detail.row(), detail.column()); }; var unmakeRowHeader = function (grid, detail, comparator, genWrappers) { var newGrid = TransformOperations.replaceRow(grid, detail.row(), comparator, genWrappers.replaceOrInit); return bundle(newGrid, detail.row(), detail.column()); }; var unmakeColumnHeader = function (grid, detail, comparator, genWrappers) { var newGrid = TransformOperations.replaceColumn(grid, detail.column(), comparator, genWrappers.replaceOrInit); return bundle(newGrid, detail.row(), detail.column()); }; var splitCellIntoColumns$1 = function (grid, detail, comparator, genWrappers) { var newGrid = ModificationOperations.splitCellIntoColumns(grid, detail.row(), detail.column(), comparator, genWrappers.getOrInit); return bundle(newGrid, detail.row(), detail.column()); }; var splitCellIntoRows$1 = function (grid, detail, comparator, genWrappers) { var newGrid = ModificationOperations.splitCellIntoRows(grid, detail.row(), detail.column(), comparator, genWrappers.getOrInit); return bundle(newGrid, detail.row(), detail.column()); }; var eraseColumns = function (grid, details, comparator, _genWrappers) { var columns = uniqueColumns(details); var newGrid = ModificationOperations.deleteColumnsAt(grid, columns[0].column(), columns[columns.length - 1].column()); var cursor = elementFromGrid(newGrid, details[0].row(), details[0].column()); return outcome(newGrid, cursor); }; var eraseRows = function (grid, details, comparator, _genWrappers) { var rows = uniqueRows(details); var newGrid = ModificationOperations.deleteRowsAt(grid, rows[0].row(), rows[rows.length - 1].row()); var cursor = elementFromGrid(newGrid, details[0].row(), details[0].column()); return outcome(newGrid, cursor); }; var mergeCells = function (grid, mergable, comparator, _genWrappers) { var cells = mergable.cells(); TableContent.merge(cells); var newGrid = MergingOperations.merge(grid, mergable.bounds(), comparator, constant(cells[0])); return outcome(newGrid, Option.from(cells[0])); }; var unmergeCells = function (grid, unmergable, comparator, genWrappers) { var newGrid = foldr(unmergable, function (b, cell) { return MergingOperations.unmerge(b, cell, comparator, genWrappers.combine(cell)); }, grid); return outcome(newGrid, Option.from(unmergable[0])); }; var pasteCells = function (grid, pasteDetails, comparator, _genWrappers) { var gridify = function (table, generators) { var list = DetailsList.fromTable(table); var wh = Warehouse.generate(list); return Transitions.toGrid(wh, generators, true); }; var gridB = gridify(pasteDetails.clipboard(), pasteDetails.generators()); var startAddress = Structs.address(pasteDetails.row(), pasteDetails.column()); var mergedGrid = TableMerge.merge(startAddress, grid, gridB, pasteDetails.generators(), comparator); return mergedGrid.fold(function () { return outcome(grid, Option.some(pasteDetails.element())); }, function (nuGrid) { var cursor = elementFromGrid(nuGrid, pasteDetails.row(), pasteDetails.column()); return outcome(nuGrid, cursor); }); }; var gridifyRows = function (rows, generators, example) { var pasteDetails = DetailsList.fromPastedRows(rows, example); var wh = Warehouse.generate(pasteDetails); return Transitions.toGrid(wh, generators, true); }; var pasteRowsBefore = function (grid, pasteDetails, comparator, _genWrappers) { var example = grid[pasteDetails.cells[0].row()]; var index = pasteDetails.cells[0].row(); var gridB = gridifyRows(pasteDetails.clipboard(), pasteDetails.generators(), example); var mergedGrid = TableMerge.insert(index, grid, gridB, pasteDetails.generators(), comparator); var cursor = elementFromGrid(mergedGrid, pasteDetails.cells[0].row(), pasteDetails.cells[0].column()); return outcome(mergedGrid, cursor); }; var pasteRowsAfter = function (grid, pasteDetails, comparator, _genWrappers) { var example = grid[pasteDetails.cells[0].row()]; var index = pasteDetails.cells[pasteDetails.cells.length - 1].row() + pasteDetails.cells[pasteDetails.cells.length - 1].rowspan(); var gridB = gridifyRows(pasteDetails.clipboard(), pasteDetails.generators(), example); var mergedGrid = TableMerge.insert(index, grid, gridB, pasteDetails.generators(), comparator); var cursor = elementFromGrid(mergedGrid, pasteDetails.cells[0].row(), pasteDetails.cells[0].column()); return outcome(mergedGrid, cursor); }; var sortRows = function (grid, detail, sortComparator, ascending) { var newGrid = TransformOperations.sortTableRows(grid, detail.column(), sortComparator, ascending); return bundle(newGrid, detail.row(), detail.column()); }; var sortColumns = function (grid, detail, sortComparator, ascending) { var newGrid = TransformOperations.sortTableColumns(grid, detail.row(), sortComparator, ascending); return bundle(newGrid, detail.row(), detail.column()); }; var runSort = function (sortF) { return function (wire, table, target, generators, direction, sortComparator, ascending) { var operation = function (grid, detail, _comparator, _generators) { return sortF(grid, detail, sortComparator, ascending); }; var wrappedOperation = RunOperation.run(operation, RunOperation.onCell, noop, noop, Generators.modification); return wrappedOperation(wire, table, target, generators, direction); }; }; var resize = Adjustments.adjustWidthTo; var TableOperations = { insertRowBefore: RunOperation.run(insertRowBefore, RunOperation.onCell, noop, noop, Generators.modification), insertRowsBefore: RunOperation.run(insertRowsBefore, RunOperation.onCells, noop, noop, Generators.modification), insertRowAfter: RunOperation.run(insertRowAfter, RunOperation.onCell, noop, noop, Generators.modification), insertRowsAfter: RunOperation.run(insertRowsAfter, RunOperation.onCells, noop, noop, Generators.modification), insertColumnBefore: RunOperation.run(insertColumnBefore, RunOperation.onCell, resize, noop, Generators.modification), insertColumnsBefore: RunOperation.run(insertColumnsBefore, RunOperation.onCells, resize, noop, Generators.modification), insertColumnAfter: RunOperation.run(insertColumnAfter, RunOperation.onCell, resize, noop, Generators.modification), insertColumnsAfter: RunOperation.run(insertColumnsAfter, RunOperation.onCells, resize, noop, Generators.modification), splitCellIntoColumns: RunOperation.run(splitCellIntoColumns$1, RunOperation.onCell, resize, noop, Generators.modification), splitCellIntoRows: RunOperation.run(splitCellIntoRows$1, RunOperation.onCell, noop, noop, Generators.modification), eraseColumns: RunOperation.run(eraseColumns, RunOperation.onCells, resize, prune, Generators.modification), eraseRows: RunOperation.run(eraseRows, RunOperation.onCells, noop, prune, Generators.modification), makeColumnHeader: RunOperation.run(makeColumnHeader, RunOperation.onCell, noop, noop, Generators.transform('row', 'th')), unmakeColumnHeader: RunOperation.run(unmakeColumnHeader, RunOperation.onCell, noop, noop, Generators.transform(null, 'td')), makeRowHeader: RunOperation.run(makeRowHeader, RunOperation.onCell, noop, noop, Generators.transform('col', 'th')), unmakeRowHeader: RunOperation.run(unmakeRowHeader, RunOperation.onCell, noop, noop, Generators.transform(null, 'td')), mergeCells: RunOperation.run(mergeCells, RunOperation.onMergable, noop, noop, Generators.merging), unmergeCells: RunOperation.run(unmergeCells, RunOperation.onUnmergable, resize, noop, Generators.merging), pasteCells: RunOperation.run(pasteCells, RunOperation.onPaste, resize, noop, Generators.modification), pasteRowsBefore: RunOperation.run(pasteRowsBefore, RunOperation.onPasteRows, noop, noop, Generators.modification), pasteRowsAfter: RunOperation.run(pasteRowsAfter, RunOperation.onPasteRows, noop, noop, Generators.modification), sortRows: runSort(sortRows), sortColumns: runSort(sortColumns) }; var getBody$1 = function (editor) { return Element.fromDom(editor.getBody()); }; var getPixelWidth$1 = function (elm) { return elm.getBoundingClientRect().width; }; var getPixelHeight = function (elm) { return elm.getBoundingClientRect().height; }; var getIsRoot = function (editor) { return function (element) { return eq(element, getBody$1(editor)); }; }; var removePxSuffix = function (size) { return size ? size.replace(/px$/, '') : ''; }; var addSizeSuffix = function (size) { if (/^[0-9]+$/.test(size)) { size += 'px'; } return size; }; var removeDataStyle = function (table) { var dataStyleCells = descendants$1(table, 'td[data-mce-style],th[data-mce-style]'); remove(table, 'data-mce-style'); each(dataStyleCells, function (cell) { remove(cell, 'data-mce-style'); }); }; var getDirection = function (element) { return get$1(element, 'direction') === 'rtl' ? 'rtl' : 'ltr'; }; var ltr$1 = { isRtl: constant(false) }; var rtl$1 = { isRtl: constant(true) }; var directionAt = function (element) { var dir = getDirection(element); return dir === 'rtl' ? rtl$1 : ltr$1; }; var Direction = { directionAt: directionAt }; var defaultTableToolbar = [ 'tableprops', 'tabledelete', '|', 'tableinsertrowbefore', 'tableinsertrowafter', 'tabledeleterow', '|', 'tableinsertcolbefore', 'tableinsertcolafter', 'tabledeletecol' ]; var defaultStyles = { 'border-collapse': 'collapse', 'width': '100%' }; var defaultAttributes = { border: '1' }; var getDefaultAttributes = function (editor) { return editor.getParam('table_default_attributes', defaultAttributes, 'object'); }; var getDefaultStyles = function (editor) { return editor.getParam('table_default_styles', defaultStyles, 'object'); }; var hasTableResizeBars = function (editor) { return editor.getParam('table_resize_bars', true, 'boolean'); }; var hasTabNavigation = function (editor) { return editor.getParam('table_tab_navigation', true, 'boolean'); }; var hasAdvancedCellTab = function (editor) { return editor.getParam('table_cell_advtab', true, 'boolean'); }; var hasAdvancedRowTab = function (editor) { return editor.getParam('table_row_advtab', true, 'boolean'); }; var hasAdvancedTableTab = function (editor) { return editor.getParam('table_advtab', true, 'boolean'); }; var hasAppearanceOptions = function (editor) { return editor.getParam('table_appearance_options', true, 'boolean'); }; var hasTableGrid = function (editor) { return editor.getParam('table_grid', true, 'boolean'); }; var shouldStyleWithCss = function (editor) { return editor.getParam('table_style_by_css', false, 'boolean'); }; var getCellClassList = function (editor) { return editor.getParam('table_cell_class_list', [], 'array'); }; var getRowClassList = function (editor) { return editor.getParam('table_row_class_list', [], 'array'); }; var getTableClassList = function (editor) { return editor.getParam('table_class_list', [], 'array'); }; var getColorPickerCallback = function (editor) { return editor.getParam('color_picker_callback'); }; var isPixelsForced = function (editor) { return editor.getParam('table_responsive_width') === false; }; var getCloneElements = function (editor) { var cloneElements = editor.getParam('table_clone_elements'); if (isString(cloneElements)) { return Option.some(cloneElements.split(/[ ,]/)); } else if (Array.isArray(cloneElements)) { return Option.some(cloneElements); } else { return Option.none(); } }; var hasObjectResizing = function (editor) { var objectResizing = editor.getParam('object_resizing', true); return objectResizing === 'table' || objectResizing; }; var getToolbar = function (editor) { var toolbar = editor.getParam('table_toolbar', defaultTableToolbar); if (toolbar === '' || toolbar === false) { return []; } else if (isString(toolbar)) { return toolbar.split(/[ ,]/); } else if (isArray(toolbar)) { return toolbar; } else { return []; } }; var fireNewRow = function (editor, row) { return editor.fire('newrow', { node: row }); }; var fireNewCell = function (editor, cell) { return editor.fire('newcell', { node: cell }); }; var fireObjectResizeStart = function (editor, target, width, height) { editor.fire('ObjectResizeStart', { target: target, width: width, height: height }); }; var fireObjectResized = function (editor, target, width, height) { editor.fire('ObjectResized', { target: target, width: width, height: height }); }; var TableActions = function (editor, lazyWire) { var isTableBody = function (editor) { return name(getBody$1(editor)) === 'table'; }; var lastRowGuard = function (table) { var size = TableGridSize.getGridSize(table); return isTableBody(editor) === false || size.rows() > 1; }; var lastColumnGuard = function (table) { var size = TableGridSize.getGridSize(table); return isTableBody(editor) === false || size.columns() > 1; }; var cloneFormats = getCloneElements(editor); var execute = function (operation, guard, mutate, lazyWire) { return function (table, target) { removeDataStyle(table); var wire = lazyWire(); var doc = Element.fromDom(editor.getDoc()); var direction = TableDirection(Direction.directionAt); var generators = TableFill.cellOperations(mutate, doc, cloneFormats); return guard(table) ? operation(wire, table, target, generators, direction).bind(function (result) { each(result.newRows(), function (row) { fireNewRow(editor, row.dom()); }); each(result.newCells(), function (cell) { fireNewCell(editor, cell.dom()); }); return result.cursor().map(function (cell) { var rng = editor.dom.createRng(); rng.setStart(cell.dom(), 0); rng.setEnd(cell.dom(), 0); return rng; }); }) : Option.none(); }; }; var deleteRow = execute(TableOperations.eraseRows, lastRowGuard, noop, lazyWire); var deleteColumn = execute(TableOperations.eraseColumns, lastColumnGuard, noop, lazyWire); var insertRowsBefore = execute(TableOperations.insertRowsBefore, always, noop, lazyWire); var insertRowsAfter = execute(TableOperations.insertRowsAfter, always, noop, lazyWire); var insertColumnsBefore = execute(TableOperations.insertColumnsBefore, always, CellMutations.halve, lazyWire); var insertColumnsAfter = execute(TableOperations.insertColumnsAfter, always, CellMutations.halve, lazyWire); var mergeCells = execute(TableOperations.mergeCells, always, noop, lazyWire); var unmergeCells = execute(TableOperations.unmergeCells, always, noop, lazyWire); var pasteRowsBefore = execute(TableOperations.pasteRowsBefore, always, noop, lazyWire); var pasteRowsAfter = execute(TableOperations.pasteRowsAfter, always, noop, lazyWire); var pasteCells = execute(TableOperations.pasteCells, always, noop, lazyWire); return { deleteRow: deleteRow, deleteColumn: deleteColumn, insertRowsBefore: insertRowsBefore, insertRowsAfter: insertRowsAfter, insertColumnsBefore: insertColumnsBefore, insertColumnsAfter: insertColumnsAfter, mergeCells: mergeCells, unmergeCells: unmergeCells, pasteRowsBefore: pasteRowsBefore, pasteRowsAfter: pasteRowsAfter, pasteCells: pasteCells }; }; var copyRows = function (table, target, generators) { var list = DetailsList.fromTable(table); var house = Warehouse.generate(list); var details = RunOperation.onCells(house, target); return details.map(function (selectedCells) { var grid = Transitions.toGrid(house, generators, false); var slicedGrid = grid.slice(selectedCells[0].row(), selectedCells[selectedCells.length - 1].row() + selectedCells[selectedCells.length - 1].rowspan()); var slicedDetails = RunOperation.toDetailList(slicedGrid, generators); return Redraw.copy(slicedDetails); }); }; var CopyRows = { copyRows: copyRows }; var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var getTDTHOverallStyle = function (dom, elm, name) { var cells = dom.select('td,th', elm); var firstChildStyle; var checkChildren = function (firstChildStyle, elms) { for (var i = 0; i < elms.length; i++) { var currentStyle = dom.getStyle(elms[i], name); if (typeof firstChildStyle === 'undefined') { firstChildStyle = currentStyle; } if (firstChildStyle !== currentStyle) { return ''; } } return firstChildStyle; }; firstChildStyle = checkChildren(firstChildStyle, cells); return firstChildStyle; }; var applyAlign = function (editor, elm, name) { if (name) { editor.formatter.apply('align' + name, {}, elm); } }; var applyVAlign = function (editor, elm, name) { if (name) { editor.formatter.apply('valign' + name, {}, elm); } }; var unApplyAlign = function (editor, elm) { global$1.each('left center right'.split(' '), function (name) { editor.formatter.remove('align' + name, {}, elm); }); }; var unApplyVAlign = function (editor, elm) { global$1.each('top middle bottom'.split(' '), function (name) { editor.formatter.remove('valign' + name, {}, elm); }); }; var Styles$1 = { applyAlign: applyAlign, applyVAlign: applyVAlign, unApplyAlign: unApplyAlign, unApplyVAlign: unApplyVAlign, getTDTHOverallStyle: getTDTHOverallStyle }; var buildListItems = function (inputList, itemCallback, startItems) { var appendItems = function (values, output) { output = output || []; global$1.each(values, function (item) { var menuItem = { text: item.text || item.title }; if (item.menu) { menuItem.menu = appendItems(item.menu); } else { menuItem.value = item.value; if (itemCallback) { itemCallback(menuItem); } } output.push(menuItem); }); return output; }; return appendItems(inputList, startItems || []); }; function styleFieldHasFocus(e) { return e.control.rootControl.find('#style')[0].getEl().isEqualNode(domGlobals.document.activeElement); } var syncAdvancedStyleFields = function (editor, evt) { if (styleFieldHasFocus(evt)) { updateAdvancedFields(editor, evt); } else { updateStyleField(editor, evt); } }; var updateStyleField = function (editor, evt) { var dom = editor.dom; var rootControl = evt.control.rootControl; var data = rootControl.toJSON(); var css = dom.parseStyle(data.style); css['border-style'] = data.borderStyle; css['border-color'] = data.borderColor; css['background-color'] = data.backgroundColor; css.width = data.width ? addSizeSuffix(data.width) : ''; css.height = data.height ? addSizeSuffix(data.height) : ''; rootControl.find('#style').value(dom.serializeStyle(dom.parseStyle(dom.serializeStyle(css)))); }; var updateAdvancedFields = function (editor, evt) { var dom = editor.dom; var rootControl = evt.control.rootControl; var data = rootControl.toJSON(); var css = dom.parseStyle(data.style); rootControl.find('#borderStyle').value(css['border-style'] || ''); rootControl.find('#borderColor').value(css['border-color'] || ''); rootControl.find('#backgroundColor').value(css['background-color'] || ''); rootControl.find('#width').value(css.width || ''); rootControl.find('#height').value(css.height || ''); }; var extractAdvancedStyles = function (dom, elm) { var css = dom.parseStyle(dom.getAttrib(elm, 'style')); var data = {}; if (css['border-style']) { data.borderStyle = css['border-style']; } if (css['border-color']) { data.borderColor = css['border-color']; } if (css['background-color']) { data.backgroundColor = css['background-color']; } data.style = dom.serializeStyle(css); return data; }; var createStyleForm = function (editor) { var createColorPickAction = function () { var colorPickerCallback = getColorPickerCallback(editor); if (colorPickerCallback) { return function (evt) { return colorPickerCallback.call(editor, function (value) { evt.control.value(value).fire('change'); }, evt.control.value()); }; } }; return { title: 'Advanced', type: 'form', defaults: { onchange: curry(updateStyleField, editor) }, items: [ { label: 'Style', name: 'style', type: 'textbox', onchange: curry(updateAdvancedFields, editor) }, { type: 'form', padding: 0, formItemDefaults: { layout: 'grid', alignH: [ 'start', 'right' ] }, defaults: { size: 7 }, items: [ { label: 'Border style', type: 'listbox', name: 'borderStyle', width: 90, onselect: curry(updateStyleField, editor), values: [ { text: 'Select...', value: '' }, { text: 'Solid', value: 'solid' }, { text: 'Dotted', value: 'dotted' }, { text: 'Dashed', value: 'dashed' }, { text: 'Double', value: 'double' }, { text: 'Groove', value: 'groove' }, { text: 'Ridge', value: 'ridge' }, { text: 'Inset', value: 'inset' }, { text: 'Outset', value: 'outset' }, { text: 'None', value: 'none' }, { text: 'Hidden', value: 'hidden' } ] }, { label: 'Border color', type: 'colorbox', name: 'borderColor', onaction: createColorPickAction() }, { label: 'Background color', type: 'colorbox', name: 'backgroundColor', onaction: createColorPickAction() } ] } ] }; }; var Helpers = { createStyleForm: createStyleForm, buildListItems: buildListItems, updateStyleField: updateStyleField, extractAdvancedStyles: extractAdvancedStyles, updateAdvancedFields: updateAdvancedFields, syncAdvancedStyleFields: syncAdvancedStyleFields }; var updateStyles = function (elm, cssText) { delete elm.dataset.mceStyle; elm.style.cssText += ';' + cssText; }; var extractDataFromElement = function (editor, elm) { var dom = editor.dom; var data = { width: dom.getStyle(elm, 'width') || dom.getAttrib(elm, 'width'), height: dom.getStyle(elm, 'height') || dom.getAttrib(elm, 'height'), scope: dom.getAttrib(elm, 'scope'), class: dom.getAttrib(elm, 'class'), type: elm.nodeName.toLowerCase(), style: '', align: '', valign: '' }; global$1.each('left center right'.split(' '), function (name) { if (editor.formatter.matchNode(elm, 'align' + name)) { data.align = name; } }); global$1.each('top middle bottom'.split(' '), function (name) { if (editor.formatter.matchNode(elm, 'valign' + name)) { data.valign = name; } }); if (hasAdvancedCellTab(editor)) { global$1.extend(data, Helpers.extractAdvancedStyles(dom, elm)); } return data; }; var onSubmitCellForm = function (editor, cells, evt) { var dom = editor.dom; var data; function setAttrib(elm, name, value) { if (cells.length === 1 || value) { dom.setAttrib(elm, name, value); } } function setStyle(elm, name, value) { if (cells.length === 1 || value) { dom.setStyle(elm, name, value); } } if (hasAdvancedCellTab(editor)) { Helpers.syncAdvancedStyleFields(editor, evt); } data = evt.control.rootControl.toJSON(); editor.undoManager.transact(function () { global$1.each(cells, function (cellElm) { setAttrib(cellElm, 'scope', data.scope); if (cells.length === 1) { setAttrib(cellElm, 'style', data.style); } else { updateStyles(cellElm, data.style); } setAttrib(cellElm, 'class', data.class); setStyle(cellElm, 'width', addSizeSuffix(data.width)); setStyle(cellElm, 'height', addSizeSuffix(data.height)); if (data.type && cellElm.nodeName.toLowerCase() !== data.type) { cellElm = dom.rename(cellElm, data.type); } if (cells.length === 1) { Styles$1.unApplyAlign(editor, cellElm); Styles$1.unApplyVAlign(editor, cellElm); } if (data.align) { Styles$1.applyAlign(editor, cellElm, data.align); } if (data.valign) { Styles$1.applyVAlign(editor, cellElm, data.valign); } }); editor.focus(); }); }; var open = function (editor) { var cellElm, data, classListCtrl, cells = []; cells = editor.dom.select('td[data-mce-selected],th[data-mce-selected]'); cellElm = editor.dom.getParent(editor.selection.getStart(), 'td,th'); if (!cells.length && cellElm) { cells.push(cellElm); } cellElm = cellElm || cells[0]; if (!cellElm) { return; } if (cells.length > 1) { data = { width: '', height: '', scope: '', class: '', align: '', valign: '', style: '', type: cellElm.nodeName.toLowerCase() }; } else { data = extractDataFromElement(editor, cellElm); } if (getCellClassList(editor).length > 0) { classListCtrl = { name: 'class', type: 'listbox', label: 'Class', values: Helpers.buildListItems(getCellClassList(editor), function (item) { if (item.value) { item.textStyle = function () { return editor.formatter.getCssText({ block: 'td', classes: [item.value] }); }; } }) }; } var generalCellForm = { type: 'form', layout: 'flex', direction: 'column', labelGapCalc: 'children', padding: 0, items: [ { type: 'form', layout: 'grid', columns: 2, labelGapCalc: false, padding: 0, defaults: { type: 'textbox', maxWidth: 50 }, items: [ { label: 'Width', name: 'width', onchange: curry(Helpers.updateStyleField, editor) }, { label: 'Height', name: 'height', onchange: curry(Helpers.updateStyleField, editor) }, { label: 'Cell type', name: 'type', type: 'listbox', text: 'None', minWidth: 90, maxWidth: null, values: [ { text: 'Cell', value: 'td' }, { text: 'Header cell', value: 'th' } ] }, { label: 'Scope', name: 'scope', type: 'listbox', text: 'None', minWidth: 90, maxWidth: null, values: [ { text: 'None', value: '' }, { text: 'Row', value: 'row' }, { text: 'Column', value: 'col' }, { text: 'Row group', value: 'rowgroup' }, { text: 'Column group', value: 'colgroup' } ] }, { label: 'H Align', name: 'align', type: 'listbox', text: 'None', minWidth: 90, maxWidth: null, values: [ { text: 'None', value: '' }, { text: 'Left', value: 'left' }, { text: 'Center', value: 'center' }, { text: 'Right', value: 'right' } ] }, { label: 'V Align', name: 'valign', type: 'listbox', text: 'None', minWidth: 90, maxWidth: null, values: [ { text: 'None', value: '' }, { text: 'Top', value: 'top' }, { text: 'Middle', value: 'middle' }, { text: 'Bottom', value: 'bottom' } ] } ] }, classListCtrl ] }; if (hasAdvancedCellTab(editor)) { editor.windowManager.open({ title: 'Cell properties', bodyType: 'tabpanel', data: data, body: [ { title: 'General', type: 'form', items: generalCellForm }, Helpers.createStyleForm(editor) ], onsubmit: curry(onSubmitCellForm, editor, cells) }); } else { editor.windowManager.open({ title: 'Cell properties', data: data, body: generalCellForm, onsubmit: curry(onSubmitCellForm, editor, cells) }); } }; var CellDialog = { open: open }; var extractDataFromElement$1 = function (editor, elm) { var dom = editor.dom; var data = { height: dom.getStyle(elm, 'height') || dom.getAttrib(elm, 'height'), scope: dom.getAttrib(elm, 'scope'), class: dom.getAttrib(elm, 'class'), align: '', style: '', type: elm.parentNode.nodeName.toLowerCase() }; global$1.each('left center right'.split(' '), function (name) { if (editor.formatter.matchNode(elm, 'align' + name)) { data.align = name; } }); if (hasAdvancedRowTab(editor)) { global$1.extend(data, Helpers.extractAdvancedStyles(dom, elm)); } return data; }; var switchRowType = function (dom, rowElm, toType) { var tableElm = dom.getParent(rowElm, 'table'); var oldParentElm = rowElm.parentNode; var parentElm = dom.select(toType, tableElm)[0]; if (!parentElm) { parentElm = dom.create(toType); if (tableElm.firstChild) { if (tableElm.firstChild.nodeName === 'CAPTION') { dom.insertAfter(parentElm, tableElm.firstChild); } else { tableElm.insertBefore(parentElm, tableElm.firstChild); } } else { tableElm.appendChild(parentElm); } } parentElm.appendChild(rowElm); if (!oldParentElm.hasChildNodes()) { dom.remove(oldParentElm); } }; function onSubmitRowForm(editor, rows, oldData, evt) { var dom = editor.dom; function setAttrib(elm, name, value) { if (rows.length === 1 || value) { dom.setAttrib(elm, name, value); } } function setStyle(elm, name, value) { if (rows.length === 1 || value) { dom.setStyle(elm, name, value); } } if (hasAdvancedRowTab(editor)) { Helpers.syncAdvancedStyleFields(editor, evt); } var data = evt.control.rootControl.toJSON(); editor.undoManager.transact(function () { global$1.each(rows, function (rowElm) { setAttrib(rowElm, 'scope', data.scope); setAttrib(rowElm, 'style', data.style); setAttrib(rowElm, 'class', data.class); setStyle(rowElm, 'height', addSizeSuffix(data.height)); if (data.type !== rowElm.parentNode.nodeName.toLowerCase()) { switchRowType(editor.dom, rowElm, data.type); } if (data.align !== oldData.align) { Styles$1.unApplyAlign(editor, rowElm); Styles$1.applyAlign(editor, rowElm, data.align); } }); editor.focus(); }); } var open$1 = function (editor) { var dom = editor.dom; var tableElm, cellElm, rowElm, classListCtrl, data; var rows = []; var generalRowForm; tableElm = dom.getParent(editor.selection.getStart(), 'table'); cellElm = dom.getParent(editor.selection.getStart(), 'td,th'); global$1.each(tableElm.rows, function (row) { global$1.each(row.cells, function (cell) { if (dom.getAttrib(cell, 'data-mce-selected') || cell === cellElm) { rows.push(row); return false; } }); }); rowElm = rows[0]; if (!rowElm) { return; } if (rows.length > 1) { data = { height: '', scope: '', style: '', class: '', align: '', type: rowElm.parentNode.nodeName.toLowerCase() }; } else { data = extractDataFromElement$1(editor, rowElm); } if (getRowClassList(editor).length > 0) { classListCtrl = { name: 'class', type: 'listbox', label: 'Class', values: Helpers.buildListItems(getRowClassList(editor), function (item) { if (item.value) { item.textStyle = function () { return editor.formatter.getCssText({ block: 'tr', classes: [item.value] }); }; } }) }; } generalRowForm = { type: 'form', columns: 2, padding: 0, defaults: { type: 'textbox' }, items: [ { type: 'listbox', name: 'type', label: 'Row type', text: 'Header', maxWidth: null, values: [ { text: 'Header', value: 'thead' }, { text: 'Body', value: 'tbody' }, { text: 'Footer', value: 'tfoot' } ] }, { type: 'listbox', name: 'align', label: 'Alignment', text: 'None', maxWidth: null, values: [ { text: 'None', value: '' }, { text: 'Left', value: 'left' }, { text: 'Center', value: 'center' }, { text: 'Right', value: 'right' } ] }, { label: 'Height', name: 'height' }, classListCtrl ] }; if (hasAdvancedRowTab(editor)) { editor.windowManager.open({ title: 'Row properties', data: data, bodyType: 'tabpanel', body: [ { title: 'General', type: 'form', items: generalRowForm }, Helpers.createStyleForm(editor) ], onsubmit: curry(onSubmitRowForm, editor, rows, data) }); } else { editor.windowManager.open({ title: 'Row properties', data: data, body: generalRowForm, onsubmit: curry(onSubmitRowForm, editor, rows, data) }); } }; var RowDialog = { open: open$1 }; var global$2 = tinymce.util.Tools.resolve('tinymce.Env'); var DefaultRenderOptions = { styles: { 'border-collapse': 'collapse', 'width': '100%' }, attributes: { border: '1' }, percentages: true }; var makeTable = function () { return Element.fromTag('table'); }; var tableBody = function () { return Element.fromTag('tbody'); }; var tableRow = function () { return Element.fromTag('tr'); }; var tableHeaderCell = function () { return Element.fromTag('th'); }; var tableCell = function () { return Element.fromTag('td'); }; var render$1 = function (rows, columns, rowHeaders, columnHeaders, renderOpts) { if (renderOpts === void 0) { renderOpts = DefaultRenderOptions; } var table = makeTable(); setAll$1(table, renderOpts.styles); setAll(table, renderOpts.attributes); var tbody = tableBody(); append(table, tbody); var trs = []; for (var i = 0; i < rows; i++) { var tr = tableRow(); for (var j = 0; j < columns; j++) { var td = i < rowHeaders || j < columnHeaders ? tableHeaderCell() : tableCell(); if (j < columnHeaders) { set(td, 'scope', 'row'); } if (i < rowHeaders) { set(td, 'scope', 'col'); } append(td, Element.fromTag('br')); if (renderOpts.percentages) { set$1(td, 'width', 100 / columns + '%'); } append(tr, td); } trs.push(tr); } append$1(tbody, trs); return table; }; var get$8 = function (element) { return element.dom().innerHTML; }; var getOuter$2 = function (element) { var container = Element.fromTag('div'); var clone = Element.fromDom(element.dom().cloneNode(true)); append(container, clone); return get$8(container); }; var placeCaretInCell = function (editor, cell) { editor.selection.select(cell.dom(), true); editor.selection.collapse(true); }; var selectFirstCellInTable = function (editor, tableElm) { descendant$1(tableElm, 'td,th').each(curry(placeCaretInCell, editor)); }; var fireEvents = function (editor, table) { each(descendants$1(table, 'tr'), function (row) { fireNewRow(editor, row.dom()); each(descendants$1(row, 'th,td'), function (cell) { fireNewCell(editor, cell.dom()); }); }); }; var isPercentage = function (width) { return isString(width) && width.indexOf('%') !== -1; }; var insert$1 = function (editor, columns, rows) { var defaultStyles = getDefaultStyles(editor); var options = { styles: defaultStyles, attributes: getDefaultAttributes(editor), percentages: isPercentage(defaultStyles.width) && !isPixelsForced(editor) }; var table = render$1(rows, columns, 0, 0, options); set(table, 'data-mce-id', '__mce'); var html = getOuter$2(table); editor.insertContent(html); return descendant$1(getBody$1(editor), 'table[data-mce-id="__mce"]').map(function (table) { if (isPixelsForced(editor)) { set$1(table, 'width', get$1(table, 'width')); } remove(table, 'data-mce-id'); fireEvents(editor, table); selectFirstCellInTable(editor, table); return table.dom(); }).getOr(null); }; var InsertTable = { insert: insert$1 }; function styleTDTH(dom, elm, name, value) { if (elm.tagName === 'TD' || elm.tagName === 'TH') { dom.setStyle(elm, name, value); } else { if (elm.children) { for (var i = 0; i < elm.children.length; i++) { styleTDTH(dom, elm.children[i], name, value); } } } } var extractDataFromElement$2 = function (editor, tableElm) { var dom = editor.dom; var data = { width: dom.getStyle(tableElm, 'width') || dom.getAttrib(tableElm, 'width'), height: dom.getStyle(tableElm, 'height') || dom.getAttrib(tableElm, 'height'), cellspacing: dom.getStyle(tableElm, 'border-spacing') || dom.getAttrib(tableElm, 'cellspacing'), cellpadding: dom.getAttrib(tableElm, 'data-mce-cell-padding') || dom.getAttrib(tableElm, 'cellpadding') || Styles$1.getTDTHOverallStyle(editor.dom, tableElm, 'padding'), border: dom.getAttrib(tableElm, 'data-mce-border') || dom.getAttrib(tableElm, 'border') || Styles$1.getTDTHOverallStyle(editor.dom, tableElm, 'border'), borderColor: dom.getAttrib(tableElm, 'data-mce-border-color'), caption: !!dom.select('caption', tableElm)[0], class: dom.getAttrib(tableElm, 'class') }; global$1.each('left center right'.split(' '), function (name) { if (editor.formatter.matchNode(tableElm, 'align' + name)) { data.align = name; } }); if (hasAdvancedTableTab(editor)) { global$1.extend(data, Helpers.extractAdvancedStyles(dom, tableElm)); } return data; }; var applyDataToElement = function (editor, tableElm, data) { var dom = editor.dom; var attrs = {}; var styles = {}; attrs.class = data.class; styles.height = addSizeSuffix(data.height); if (dom.getAttrib(tableElm, 'width') && !shouldStyleWithCss(editor)) { attrs.width = removePxSuffix(data.width); } else { styles.width = addSizeSuffix(data.width); } if (shouldStyleWithCss(editor)) { styles['border-width'] = addSizeSuffix(data.border); styles['border-spacing'] = addSizeSuffix(data.cellspacing); global$1.extend(attrs, { 'data-mce-border-color': data.borderColor, 'data-mce-cell-padding': data.cellpadding, 'data-mce-border': data.border }); } else { global$1.extend(attrs, { border: data.border, cellpadding: data.cellpadding, cellspacing: data.cellspacing }); } if (shouldStyleWithCss(editor)) { if (tableElm.children) { for (var i = 0; i < tableElm.children.length; i++) { styleTDTH(dom, tableElm.children[i], { 'border-width': addSizeSuffix(data.border), 'border-color': data.borderColor, 'padding': addSizeSuffix(data.cellpadding) }); } } } if (data.style) { global$1.extend(styles, dom.parseStyle(data.style)); } else { styles = global$1.extend({}, dom.parseStyle(dom.getAttrib(tableElm, 'style')), styles); } attrs.style = dom.serializeStyle(styles); dom.setAttribs(tableElm, attrs); }; var onSubmitTableForm = function (editor, tableElm, evt) { var dom = editor.dom; var captionElm; var data; if (hasAdvancedTableTab(editor)) { Helpers.syncAdvancedStyleFields(editor, evt); } data = evt.control.rootControl.toJSON(); if (data.class === false) { delete data.class; } editor.undoManager.transact(function () { if (!tableElm) { tableElm = InsertTable.insert(editor, data.cols || 1, data.rows || 1); } applyDataToElement(editor, tableElm, data); captionElm = dom.select('caption', tableElm)[0]; if (captionElm && !data.caption) { dom.remove(captionElm); } if (!captionElm && data.caption) { captionElm = dom.create('caption'); captionElm.innerHTML = !global$2.ie ? '<br data-mce-bogus="1"/>' : '\xA0'; tableElm.insertBefore(captionElm, tableElm.firstChild); } Styles$1.unApplyAlign(editor, tableElm); if (data.align) { Styles$1.applyAlign(editor, tableElm, data.align); } editor.focus(); editor.addVisual(); }); }; var open$2 = function (editor, isProps) { var dom = editor.dom; var tableElm, colsCtrl, rowsCtrl, classListCtrl, data = {}, generalTableForm; if (isProps === true) { tableElm = dom.getParent(editor.selection.getStart(), 'table'); if (tableElm) { data = extractDataFromElement$2(editor, tableElm); } } else { colsCtrl = { label: 'Cols', name: 'cols' }; rowsCtrl = { label: 'Rows', name: 'rows' }; } if (getTableClassList(editor).length > 0) { if (data.class) { data.class = data.class.replace(/\s*mce\-item\-table\s*/g, ''); } classListCtrl = { name: 'class', type: 'listbox', label: 'Class', values: Helpers.buildListItems(getTableClassList(editor), function (item) { if (item.value) { item.textStyle = function () { return editor.formatter.getCssText({ block: 'table', classes: [item.value] }); }; } }) }; } generalTableForm = { type: 'form', layout: 'flex', direction: 'column', labelGapCalc: 'children', padding: 0, items: [ { type: 'form', labelGapCalc: false, padding: 0, layout: 'grid', columns: 2, defaults: { type: 'textbox', maxWidth: 50 }, items: hasAppearanceOptions(editor) ? [ colsCtrl, rowsCtrl, { label: 'Width', name: 'width', onchange: curry(Helpers.updateStyleField, editor) }, { label: 'Height', name: 'height', onchange: curry(Helpers.updateStyleField, editor) }, { label: 'Cell spacing', name: 'cellspacing' }, { label: 'Cell padding', name: 'cellpadding' }, { label: 'Border', name: 'border' }, { label: 'Caption', name: 'caption', type: 'checkbox' } ] : [ colsCtrl, rowsCtrl, { label: 'Width', name: 'width', onchange: curry(Helpers.updateStyleField, editor) }, { label: 'Height', name: 'height', onchange: curry(Helpers.updateStyleField, editor) } ] }, { label: 'Alignment', name: 'align', type: 'listbox', text: 'None', values: [ { text: 'None', value: '' }, { text: 'Left', value: 'left' }, { text: 'Center', value: 'center' }, { text: 'Right', value: 'right' } ] }, classListCtrl ] }; if (hasAdvancedTableTab(editor)) { editor.windowManager.open({ title: 'Table properties', data: data, bodyType: 'tabpanel', body: [ { title: 'General', type: 'form', items: generalTableForm }, Helpers.createStyleForm(editor) ], onsubmit: curry(onSubmitTableForm, editor, tableElm) }); } else { editor.windowManager.open({ title: 'Table properties', data: data, body: generalTableForm, onsubmit: curry(onSubmitTableForm, editor, tableElm) }); } }; var TableDialog = { open: open$2 }; var each$3 = global$1.each; var registerCommands = function (editor, actions, cellSelection, selections, clipboardRows) { var isRoot = getIsRoot(editor); var eraseTable = function () { getSelectionStartCell().orThunk(getSelectionStartCaption).each(function (cellOrCaption) { var table = TableLookup.table(cellOrCaption, isRoot); table.filter(not(isRoot)).each(function (table) { var cursor = Element.fromText(''); after(table, cursor); remove$2(table); var rng = editor.dom.createRng(); rng.setStart(cursor.dom(), 0); rng.setEnd(cursor.dom(), 0); editor.selection.setRng(rng); }); }); }; var getSelectionStartFromSelector = function (selector) { return function () { return Option.from(editor.dom.getParent(editor.selection.getStart(), selector)).map(Element.fromDom); }; }; var getSelectionStartCaption = getSelectionStartFromSelector('caption'); var getSelectionStartCell = getSelectionStartFromSelector('th,td'); var getTableFromCell = function (cell) { return TableLookup.table(cell, isRoot); }; var getSize = function (table) { return { width: getPixelWidth$1(table.dom()), height: getPixelWidth$1(table.dom()) }; }; var resizeChange = function (editor, oldSize, table) { var newSize = getSize(table); if (oldSize.width !== newSize.width || oldSize.height !== newSize.height) { fireObjectResizeStart(editor, table.dom(), oldSize.width, oldSize.height); fireObjectResized(editor, table.dom(), newSize.width, newSize.height); } }; var actOnSelection = function (execute) { getSelectionStartCell().each(function (cell) { getTableFromCell(cell).each(function (table) { var targets = TableTargets.forMenu(selections, table, cell); var beforeSize = getSize(table); execute(table, targets).each(function (rng) { resizeChange(editor, beforeSize, table); editor.selection.setRng(rng); editor.focus(); cellSelection.clear(table); removeDataStyle(table); }); }); }); }; var copyRowSelection = function (execute) { return getSelectionStartCell().bind(function (cell) { return getTableFromCell(cell).bind(function (table) { var doc = Element.fromDom(editor.getDoc()); var targets = TableTargets.forMenu(selections, table, cell); var generators = TableFill.cellOperations(noop, doc, Option.none()); return CopyRows.copyRows(table, targets, generators); }); }); }; var pasteOnSelection = function (execute) { clipboardRows.get().each(function (rows) { var clonedRows = map(rows, function (row) { return deep(row); }); getSelectionStartCell().each(function (cell) { getTableFromCell(cell).each(function (table) { var doc = Element.fromDom(editor.getDoc()); var generators = TableFill.paste(doc); var targets = TableTargets.pasteRows(selections, table, cell, clonedRows, generators); execute(table, targets).each(function (rng) { editor.selection.setRng(rng); editor.focus(); cellSelection.clear(table); }); }); }); }); }; each$3({ mceTableSplitCells: function () { actOnSelection(actions.unmergeCells); }, mceTableMergeCells: function () { actOnSelection(actions.mergeCells); }, mceTableInsertRowBefore: function () { actOnSelection(actions.insertRowsBefore); }, mceTableInsertRowAfter: function () { actOnSelection(actions.insertRowsAfter); }, mceTableInsertColBefore: function () { actOnSelection(actions.insertColumnsBefore); }, mceTableInsertColAfter: function () { actOnSelection(actions.insertColumnsAfter); }, mceTableDeleteCol: function () { actOnSelection(actions.deleteColumn); }, mceTableDeleteRow: function () { actOnSelection(actions.deleteRow); }, mceTableCutRow: function (grid) { clipboardRows.set(copyRowSelection()); actOnSelection(actions.deleteRow); }, mceTableCopyRow: function (grid) { clipboardRows.set(copyRowSelection()); }, mceTablePasteRowBefore: function (grid) { pasteOnSelection(actions.pasteRowsBefore); }, mceTablePasteRowAfter: function (grid) { pasteOnSelection(actions.pasteRowsAfter); }, mceTableDelete: eraseTable }, function (func, name) { editor.addCommand(name, func); }); each$3({ mceInsertTable: curry(TableDialog.open, editor), mceTableProps: curry(TableDialog.open, editor, true), mceTableRowProps: curry(RowDialog.open, editor), mceTableCellProps: curry(CellDialog.open, editor) }, function (func, name) { editor.addCommand(name, function (ui, val) { func(val); }); }); }; var Commands = { registerCommands: registerCommands }; var only$1 = function (element) { var parent = Option.from(element.dom().documentElement).map(Element.fromDom).getOr(element); return { parent: constant(parent), view: constant(element), origin: constant(Position(0, 0)) }; }; var detached = function (editable, chrome) { var origin = curry(absolute, chrome); return { parent: constant(chrome), view: constant(editable), origin: origin }; }; var body$1 = function (editable, chrome) { return { parent: constant(chrome), view: constant(editable), origin: constant(Position(0, 0)) }; }; var ResizeWire = { only: only$1, detached: detached, body: body$1 }; function Event (fields) { var struct = Immutable.apply(null, fields); var handlers = []; var bind = function (handler) { if (handler === undefined) { throw 'Event bind error: undefined handler'; } handlers.push(handler); }; var unbind = function (handler) { handlers = filter(handlers, function (h) { return h !== handler; }); }; var trigger = function () { var event = struct.apply(null, arguments); each(handlers, function (handler) { handler(event); }); }; return { bind: bind, unbind: unbind, trigger: trigger }; } var create = function (typeDefs) { var registry = map$1(typeDefs, function (event) { return { bind: event.bind, unbind: event.unbind }; }); var trigger = map$1(typeDefs, function (event) { return event.trigger; }); return { registry: registry, trigger: trigger }; }; var Events = { create: create }; var mode = exactly([ 'compare', 'extract', 'mutate', 'sink' ]); var sink = exactly([ 'element', 'start', 'stop', 'destroy' ]); var api$3 = exactly([ 'forceDrop', 'drop', 'move', 'delayDrop' ]); var DragApis = { mode: mode, sink: sink, api: api$3 }; var styles$1 = css('ephox-dragster'); var Styles$2 = { resolve: styles$1.resolve }; function Blocker (options) { var settings = merge({ 'layerClass': Styles$2.resolve('blocker') }, options); var div = Element.fromTag('div'); set(div, 'role', 'presentation'); setAll$1(div, { position: 'fixed', left: '0px', top: '0px', width: '100%', height: '100%' }); add$2(div, Styles$2.resolve('blocker')); add$2(div, settings.layerClass); var element = function () { return div; }; var destroy = function () { remove$2(div); }; return { element: element, destroy: destroy }; } var mkEvent = function (target, x, y, stop, prevent, kill, raw) { return { target: constant(target), x: constant(x), y: constant(y), stop: stop, prevent: prevent, kill: kill, raw: constant(raw) }; }; var handle = function (filter, handler) { return function (rawEvent) { if (!filter(rawEvent)) { return; } var target = Element.fromDom(rawEvent.target); var stop = function () { rawEvent.stopPropagation(); }; var prevent = function () { rawEvent.preventDefault(); }; var kill = compose(prevent, stop); var evt = mkEvent(target, rawEvent.clientX, rawEvent.clientY, stop, prevent, kill, rawEvent); handler(evt); }; }; var binder = function (element, event, filter, handler, useCapture) { var wrapped = handle(filter, handler); element.dom().addEventListener(event, wrapped, useCapture); return { unbind: curry(unbind, element, event, wrapped, useCapture) }; }; var bind$1 = function (element, event, filter, handler) { return binder(element, event, filter, handler, false); }; var unbind = function (element, event, handler, useCapture) { element.dom().removeEventListener(event, handler, useCapture); }; var filter$1 = constant(true); var bind$2 = function (element, event, handler) { return bind$1(element, event, filter$1, handler); }; var compare = function (old, nu) { return Position(nu.left() - old.left(), nu.top() - old.top()); }; var extract$1 = function (event) { return Option.some(Position(event.x(), event.y())); }; var mutate = function (mutation, info) { mutation.mutate(info.left(), info.top()); }; var sink$1 = function (dragApi, settings) { var blocker = Blocker(settings); var mdown = bind$2(blocker.element(), 'mousedown', dragApi.forceDrop); var mup = bind$2(blocker.element(), 'mouseup', dragApi.drop); var mmove = bind$2(blocker.element(), 'mousemove', dragApi.move); var mout = bind$2(blocker.element(), 'mouseout', dragApi.delayDrop); var destroy = function () { blocker.destroy(); mup.unbind(); mmove.unbind(); mout.unbind(); mdown.unbind(); }; var start = function (parent) { append(parent, blocker.element()); }; var stop = function () { remove$2(blocker.element()); }; return DragApis.sink({ element: blocker.element, start: start, stop: stop, destroy: destroy }); }; var MouseDrag = DragApis.mode({ compare: compare, extract: extract$1, sink: sink$1, mutate: mutate }); function InDrag () { var previous = Option.none(); var reset = function () { previous = Option.none(); }; var update = function (mode, nu) { var result = previous.map(function (old) { return mode.compare(old, nu); }); previous = Option.some(nu); return result; }; var onEvent = function (event, mode) { var dataOption = mode.extract(event); dataOption.each(function (data) { var offset = update(mode, data); offset.each(function (d) { events.trigger.move(d); }); }); }; var events = Events.create({ move: Event(['info']) }); return { onEvent: onEvent, reset: reset, events: events.registry }; } function NoDrag (anchor) { var onEvent = function (event, mode) { }; return { onEvent: onEvent, reset: noop }; } function Movement () { var noDragState = NoDrag(); var inDragState = InDrag(); var dragState = noDragState; var on = function () { dragState.reset(); dragState = inDragState; }; var off = function () { dragState.reset(); dragState = noDragState; }; var onEvent = function (event, mode) { dragState.onEvent(event, mode); }; var isOn = function () { return dragState === inDragState; }; return { on: on, off: off, isOn: isOn, onEvent: onEvent, events: inDragState.events }; } var last$2 = function (fn, rate) { var timer = null; var cancel = function () { if (timer !== null) { domGlobals.clearTimeout(timer); timer = null; } }; var throttle = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (timer !== null) domGlobals.clearTimeout(timer); timer = domGlobals.setTimeout(function () { fn.apply(null, args); timer = null; }, rate); }; return { cancel: cancel, throttle: throttle }; }; var setup = function (mutation, mode, settings) { var active = false; var events = Events.create({ start: Event([]), stop: Event([]) }); var movement = Movement(); var drop = function () { sink.stop(); if (movement.isOn()) { movement.off(); events.trigger.stop(); } }; var throttledDrop = last$2(drop, 200); var go = function (parent) { sink.start(parent); movement.on(); events.trigger.start(); }; var mousemove = function (event, ui) { throttledDrop.cancel(); movement.onEvent(event, mode); }; movement.events.move.bind(function (event) { mode.mutate(mutation, event.info()); }); var on = function () { active = true; }; var off = function () { active = false; }; var runIfActive = function (f) { return function () { var args = Array.prototype.slice.call(arguments, 0); if (active) { return f.apply(null, args); } }; }; var sink = mode.sink(DragApis.api({ forceDrop: drop, drop: runIfActive(drop), move: runIfActive(mousemove), delayDrop: runIfActive(throttledDrop.throttle) }), settings); var destroy = function () { sink.destroy(); }; return { element: sink.element, go: go, on: on, off: off, destroy: destroy, events: events.registry }; }; var Dragging = { setup: setup }; var transform$1 = function (mutation, options) { var settings = options !== undefined ? options : {}; var mode = settings.mode !== undefined ? settings.mode : MouseDrag; return Dragging.setup(mutation, mode, options); }; var Dragger = { transform: transform$1 }; var closest$2 = function (scope, selector, isRoot) { return closest$1(scope, selector, isRoot).isSome(); }; function Mutation () { var events = Events.create({ drag: Event([ 'xDelta', 'yDelta' ]) }); var mutate = function (x, y) { events.trigger.drag(x, y); }; return { mutate: mutate, events: events.registry }; } function BarMutation () { var events = Events.create({ drag: Event([ 'xDelta', 'yDelta', 'target' ]) }); var target = Option.none(); var delegate = Mutation(); delegate.events.drag.bind(function (event) { target.each(function (t) { events.trigger.drag(event.xDelta(), event.yDelta(), t); }); }); var assign = function (t) { target = Option.some(t); }; var get = function () { return target; }; return { assign: assign, get: get, mutate: delegate.mutate, events: events.registry }; } var resizeBarDragging = Styles.resolve('resizer-bar-dragging'); function BarManager (wire, direction, hdirection) { var mutation = BarMutation(); var resizing = Dragger.transform(mutation, {}); var hoverTable = Option.none(); var getResizer = function (element, type) { return Option.from(get(element, type)); }; mutation.events.drag.bind(function (event) { getResizer(event.target(), 'data-row').each(function (_dataRow) { var currentRow = CellUtils.getInt(event.target(), 'top'); set$1(event.target(), 'top', currentRow + event.yDelta() + 'px'); }); getResizer(event.target(), 'data-column').each(function (_dataCol) { var currentCol = CellUtils.getInt(event.target(), 'left'); set$1(event.target(), 'left', currentCol + event.xDelta() + 'px'); }); }); var getDelta = function (target, dir) { var newX = CellUtils.getInt(target, dir); var oldX = parseInt(get(target, 'data-initial-' + dir), 10); return newX - oldX; }; resizing.events.stop.bind(function () { mutation.get().each(function (target) { hoverTable.each(function (table) { getResizer(target, 'data-row').each(function (row) { var delta = getDelta(target, 'top'); remove(target, 'data-initial-top'); events.trigger.adjustHeight(table, delta, parseInt(row, 10)); }); getResizer(target, 'data-column').each(function (column) { var delta = getDelta(target, 'left'); remove(target, 'data-initial-left'); events.trigger.adjustWidth(table, delta, parseInt(column, 10)); }); Bars.refresh(wire, table, hdirection, direction); }); }); }); var handler = function (target, dir) { events.trigger.startAdjust(); mutation.assign(target); set(target, 'data-initial-' + dir, parseInt(get$1(target, dir), 10)); add$2(target, resizeBarDragging); set$1(target, 'opacity', '0.2'); resizing.go(wire.parent()); }; var mousedown = bind$2(wire.parent(), 'mousedown', function (event) { if (Bars.isRowBar(event.target())) { handler(event.target(), 'top'); } if (Bars.isColBar(event.target())) { handler(event.target(), 'left'); } }); var isRoot = function (e) { return eq(e, wire.view()); }; var mouseover = bind$2(wire.view(), 'mouseover', function (event) { if (name(event.target()) === 'table' || closest$2(event.target(), 'table', isRoot)) { hoverTable = name(event.target()) === 'table' ? Option.some(event.target()) : ancestor$1(event.target(), 'table', isRoot); hoverTable.each(function (ht) { Bars.refresh(wire, ht, hdirection, direction); }); } else if (inBody(event.target())) { Bars.destroy(wire); } }); var destroy = function () { mousedown.unbind(); mouseover.unbind(); resizing.destroy(); Bars.destroy(wire); }; var refresh = function (tbl) { Bars.refresh(wire, tbl, hdirection, direction); }; var events = Events.create({ adjustHeight: Event([ 'table', 'delta', 'row' ]), adjustWidth: Event([ 'table', 'delta', 'column' ]), startAdjust: Event([]) }); return { destroy: destroy, refresh: refresh, on: resizing.on, off: resizing.off, hideBars: curry(Bars.hide, wire), showBars: curry(Bars.show, wire), events: events.registry }; } function TableResize (wire, vdirection) { var hdirection = BarPositions.height; var manager = BarManager(wire, vdirection, hdirection); var events = Events.create({ beforeResize: Event(['table']), afterResize: Event(['table']), startDrag: Event([]) }); manager.events.adjustHeight.bind(function (event) { events.trigger.beforeResize(event.table()); var delta = hdirection.delta(event.delta()); Adjustments.adjustHeight(event.table(), delta, event.row(), hdirection); events.trigger.afterResize(event.table()); }); manager.events.startAdjust.bind(function (event) { events.trigger.startDrag(); }); manager.events.adjustWidth.bind(function (event) { events.trigger.beforeResize(event.table()); var delta = vdirection.delta(event.delta(), event.table()); Adjustments.adjustWidth(event.table(), delta, event.column(), vdirection); events.trigger.afterResize(event.table()); }); return { on: manager.on, off: manager.off, hideBars: manager.hideBars, showBars: manager.showBars, destroy: manager.destroy, events: events.registry }; } var createContainer = function () { var container = Element.fromTag('div'); setAll$1(container, { position: 'static', height: '0', width: '0', padding: '0', margin: '0', border: '0' }); append(body(), container); return container; }; var get$9 = function (editor, container) { return editor.inline ? ResizeWire.body(getBody$1(editor), createContainer()) : ResizeWire.only(Element.fromDom(editor.getDoc())); }; var remove$6 = function (editor, wire) { if (editor.inline) { remove$2(wire.parent()); } }; var TableWire = { get: get$9, remove: remove$6 }; var ResizeHandler = function (editor) { var selectionRng = Option.none(); var resize = Option.none(); var wire = Option.none(); var percentageBasedSizeRegex = /(\d+(\.\d+)?)%/; var startW, startRawW; var isTable = function (elm) { return elm.nodeName === 'TABLE'; }; var getRawWidth = function (elm) { return editor.dom.getStyle(elm, 'width') || editor.dom.getAttrib(elm, 'width'); }; var lazyResize = function () { return resize; }; var lazyWire = function () { return wire.getOr(ResizeWire.only(Element.fromDom(editor.getBody()))); }; var destroy = function () { resize.each(function (sz) { sz.destroy(); }); wire.each(function (w) { TableWire.remove(editor, w); }); }; editor.on('init', function () { var direction = TableDirection(Direction.directionAt); var rawWire = TableWire.get(editor); wire = Option.some(rawWire); if (hasObjectResizing(editor) && hasTableResizeBars(editor)) { var sz = TableResize(rawWire, direction); sz.on(); sz.events.startDrag.bind(function (event) { selectionRng = Option.some(editor.selection.getRng()); }); sz.events.beforeResize.bind(function (event) { var rawTable = event.table().dom(); fireObjectResizeStart(editor, rawTable, getPixelWidth$1(rawTable), getPixelHeight(rawTable)); }); sz.events.afterResize.bind(function (event) { var table = event.table(); var rawTable = table.dom(); removeDataStyle(table); selectionRng.each(function (rng) { editor.selection.setRng(rng); editor.focus(); }); fireObjectResized(editor, rawTable, getPixelWidth$1(rawTable), getPixelHeight(rawTable)); editor.undoManager.add(); }); resize = Option.some(sz); } }); editor.on('ObjectResizeStart', function (e) { var targetElm = e.target; if (isTable(targetElm)) { startW = e.width; startRawW = getRawWidth(targetElm); } }); editor.on('ObjectResized', function (e) { var targetElm = e.target; if (isTable(targetElm)) { var table = targetElm; if (percentageBasedSizeRegex.test(startRawW)) { var percentW = parseFloat(percentageBasedSizeRegex.exec(startRawW)[1]); var targetPercentW = e.width * percentW / startW; editor.dom.setStyle(table, 'width', targetPercentW + '%'); } else { var newCellSizes_1 = []; global$1.each(table.rows, function (row) { global$1.each(row.cells, function (cell) { var width = editor.dom.getStyle(cell, 'width', true); newCellSizes_1.push({ cell: cell, width: width }); }); }); global$1.each(newCellSizes_1, function (newCellSize) { editor.dom.setStyle(newCellSize.cell, 'width', newCellSize.width); editor.dom.setAttrib(newCellSize.cell, 'width', null); }); } } }); return { lazyResize: lazyResize, lazyWire: lazyWire, destroy: destroy }; }; var folder$1 = function (fold) { return { fold: fold }; }; var none$2 = function (current) { return folder$1(function (n, f, m, l) { return n(current); }); }; var first$1 = function (current) { return folder$1(function (n, f, m, l) { return f(current); }); }; var middle$1 = function (current, target) { return folder$1(function (n, f, m, l) { return m(current, target); }); }; var last$3 = function (current) { return folder$1(function (n, f, m, l) { return l(current); }); }; var CellLocation = { none: none$2, first: first$1, middle: middle$1, last: last$3 }; var detect$4 = function (current, isRoot) { return TableLookup.table(current, isRoot).bind(function (table) { var all = TableLookup.cells(table); var index = findIndex(all, function (x) { return eq(current, x); }); return index.map(function (ind) { return { index: constant(ind), all: constant(all) }; }); }); }; var next = function (current, isRoot) { var detection = detect$4(current, isRoot); return detection.fold(function () { return CellLocation.none(current); }, function (info) { return info.index() + 1 < info.all().length ? CellLocation.middle(current, info.all()[info.index() + 1]) : CellLocation.last(current); }); }; var prev = function (current, isRoot) { var detection = detect$4(current, isRoot); return detection.fold(function () { return CellLocation.none(); }, function (info) { return info.index() - 1 >= 0 ? CellLocation.middle(current, info.all()[info.index() - 1]) : CellLocation.first(current); }); }; var CellNavigation = { next: next, prev: prev }; var adt = Adt.generate([ { before: ['element'] }, { on: [ 'element', 'offset' ] }, { after: ['element'] } ]); var cata$1 = function (subject, onBefore, onOn, onAfter) { return subject.fold(onBefore, onOn, onAfter); }; var getStart = function (situ) { return situ.fold(identity, identity, identity); }; var before$2 = adt.before; var on = adt.on; var after$2 = adt.after; var Situ = { before: before$2, on: on, after: after$2, cata: cata$1, getStart: getStart }; var type$2 = Adt.generate([ { domRange: ['rng'] }, { relative: [ 'startSitu', 'finishSitu' ] }, { exact: [ 'start', 'soffset', 'finish', 'foffset' ] } ]); var range$1 = Immutable('start', 'soffset', 'finish', 'foffset'); var getStart$1 = function (selection) { return selection.match({ domRange: function (rng) { return Element.fromDom(rng.startContainer); }, relative: function (startSitu, finishSitu) { return Situ.getStart(startSitu); }, exact: function (start, soffset, finish, foffset) { return start; } }); }; var getWin = function (selection) { var start = getStart$1(selection); return defaultView(start); }; var relative = type$2.relative; var exact = type$2.exact; var makeRange = function (start, soffset, finish, foffset) { var doc = owner(start); var rng = doc.dom().createRange(); rng.setStart(start.dom(), soffset); rng.setEnd(finish.dom(), foffset); return rng; }; var after$3 = function (start, soffset, finish, foffset) { var r = makeRange(start, soffset, finish, foffset); var same = eq(start, finish) && soffset === foffset; return r.collapsed && !same; }; var selectNodeContents = function (win, element) { var rng = win.document.createRange(); selectNodeContentsUsing(rng, element); return rng; }; var selectNodeContentsUsing = function (rng, element) { rng.selectNodeContents(element.dom()); }; var setStart = function (rng, situ) { situ.fold(function (e) { rng.setStartBefore(e.dom()); }, function (e, o) { rng.setStart(e.dom(), o); }, function (e) { rng.setStartAfter(e.dom()); }); }; var setFinish = function (rng, situ) { situ.fold(function (e) { rng.setEndBefore(e.dom()); }, function (e, o) { rng.setEnd(e.dom(), o); }, function (e) { rng.setEndAfter(e.dom()); }); }; var relativeToNative = function (win, startSitu, finishSitu) { var range = win.document.createRange(); setStart(range, startSitu); setFinish(range, finishSitu); return range; }; var exactToNative = function (win, start, soffset, finish, foffset) { var rng = win.document.createRange(); rng.setStart(start.dom(), soffset); rng.setEnd(finish.dom(), foffset); return rng; }; var toRect = function (rect) { return { left: constant(rect.left), top: constant(rect.top), right: constant(rect.right), bottom: constant(rect.bottom), width: constant(rect.width), height: constant(rect.height) }; }; var getFirstRect = function (rng) { var rects = rng.getClientRects(); var rect = rects.length > 0 ? rects[0] : rng.getBoundingClientRect(); return rect.width > 0 || rect.height > 0 ? Option.some(rect).map(toRect) : Option.none(); }; var adt$1 = Adt.generate([ { ltr: [ 'start', 'soffset', 'finish', 'foffset' ] }, { rtl: [ 'start', 'soffset', 'finish', 'foffset' ] } ]); var fromRange = function (win, type, range) { return type(Element.fromDom(range.startContainer), range.startOffset, Element.fromDom(range.endContainer), range.endOffset); }; var getRanges = function (win, selection) { return selection.match({ domRange: function (rng) { return { ltr: constant(rng), rtl: Option.none }; }, relative: function (startSitu, finishSitu) { return { ltr: cached(function () { return relativeToNative(win, startSitu, finishSitu); }), rtl: cached(function () { return Option.some(relativeToNative(win, finishSitu, startSitu)); }) }; }, exact: function (start, soffset, finish, foffset) { return { ltr: cached(function () { return exactToNative(win, start, soffset, finish, foffset); }), rtl: cached(function () { return Option.some(exactToNative(win, finish, foffset, start, soffset)); }) }; } }); }; var doDiagnose = function (win, ranges) { var rng = ranges.ltr(); if (rng.collapsed) { var reversed = ranges.rtl().filter(function (rev) { return rev.collapsed === false; }); return reversed.map(function (rev) { return adt$1.rtl(Element.fromDom(rev.endContainer), rev.endOffset, Element.fromDom(rev.startContainer), rev.startOffset); }).getOrThunk(function () { return fromRange(win, adt$1.ltr, rng); }); } else { return fromRange(win, adt$1.ltr, rng); } }; var diagnose = function (win, selection) { var ranges = getRanges(win, selection); return doDiagnose(win, ranges); }; var asLtrRange = function (win, selection) { var diagnosis = diagnose(win, selection); return diagnosis.match({ ltr: function (start, soffset, finish, foffset) { var rng = win.document.createRange(); rng.setStart(start.dom(), soffset); rng.setEnd(finish.dom(), foffset); return rng; }, rtl: function (start, soffset, finish, foffset) { var rng = win.document.createRange(); rng.setStart(finish.dom(), foffset); rng.setEnd(start.dom(), soffset); return rng; } }); }; var searchForPoint = function (rectForOffset, x, y, maxX, length) { if (length === 0) { return 0; } else if (x === maxX) { return length - 1; } var xDelta = maxX; for (var i = 1; i < length; i++) { var rect = rectForOffset(i); var curDeltaX = Math.abs(x - rect.left); if (y <= rect.bottom) { if (y < rect.top || curDeltaX > xDelta) { return i - 1; } else { xDelta = curDeltaX; } } } return 0; }; var inRect = function (rect, x, y) { return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom; }; var locateOffset = function (doc, textnode, x, y, rect) { var rangeForOffset = function (o) { var r = doc.dom().createRange(); r.setStart(textnode.dom(), o); r.collapse(true); return r; }; var rectForOffset = function (o) { var r = rangeForOffset(o); return r.getBoundingClientRect(); }; var length = get$2(textnode).length; var offset = searchForPoint(rectForOffset, x, y, rect.right, length); return rangeForOffset(offset); }; var locate = function (doc, node, x, y) { var r = doc.dom().createRange(); r.selectNode(node.dom()); var rects = r.getClientRects(); var foundRect = findMap(rects, function (rect) { return inRect(rect, x, y) ? Option.some(rect) : Option.none(); }); return foundRect.map(function (rect) { return locateOffset(doc, node, x, y, rect); }); }; var searchInChildren = function (doc, node, x, y) { var r = doc.dom().createRange(); var nodes = children(node); return findMap(nodes, function (n) { r.selectNode(n.dom()); return inRect(r.getBoundingClientRect(), x, y) ? locateNode(doc, n, x, y) : Option.none(); }); }; var locateNode = function (doc, node, x, y) { var locator = isText(node) ? locate : searchInChildren; return locator(doc, node, x, y); }; var locate$1 = function (doc, node, x, y) { var r = doc.dom().createRange(); r.selectNode(node.dom()); var rect = r.getBoundingClientRect(); var boundedX = Math.max(rect.left, Math.min(rect.right, x)); var boundedY = Math.max(rect.top, Math.min(rect.bottom, y)); return locateNode(doc, node, boundedX, boundedY); }; var COLLAPSE_TO_LEFT = true; var COLLAPSE_TO_RIGHT = false; var getCollapseDirection = function (rect, x) { return x - rect.left < rect.right - x ? COLLAPSE_TO_LEFT : COLLAPSE_TO_RIGHT; }; var createCollapsedNode = function (doc, target, collapseDirection) { var r = doc.dom().createRange(); r.selectNode(target.dom()); r.collapse(collapseDirection); return r; }; var locateInElement = function (doc, node, x) { var cursorRange = doc.dom().createRange(); cursorRange.selectNode(node.dom()); var rect = cursorRange.getBoundingClientRect(); var collapseDirection = getCollapseDirection(rect, x); var f = collapseDirection === COLLAPSE_TO_LEFT ? first : last$1; return f(node).map(function (target) { return createCollapsedNode(doc, target, collapseDirection); }); }; var locateInEmpty = function (doc, node, x) { var rect = node.dom().getBoundingClientRect(); var collapseDirection = getCollapseDirection(rect, x); return Option.some(createCollapsedNode(doc, node, collapseDirection)); }; var search = function (doc, node, x) { var f = children(node).length === 0 ? locateInEmpty : locateInElement; return f(doc, node, x); }; var caretPositionFromPoint = function (doc, x, y) { return Option.from(doc.dom().caretPositionFromPoint(x, y)).bind(function (pos) { if (pos.offsetNode === null) { return Option.none(); } var r = doc.dom().createRange(); r.setStart(pos.offsetNode, pos.offset); r.collapse(); return Option.some(r); }); }; var caretRangeFromPoint = function (doc, x, y) { return Option.from(doc.dom().caretRangeFromPoint(x, y)); }; var searchTextNodes = function (doc, node, x, y) { var r = doc.dom().createRange(); r.selectNode(node.dom()); var rect = r.getBoundingClientRect(); var boundedX = Math.max(rect.left, Math.min(rect.right, x)); var boundedY = Math.max(rect.top, Math.min(rect.bottom, y)); return locate$1(doc, node, boundedX, boundedY); }; var searchFromPoint = function (doc, x, y) { return Element.fromPoint(doc, x, y).bind(function (elem) { var fallback = function () { return search(doc, elem, x); }; return children(elem).length === 0 ? fallback() : searchTextNodes(doc, elem, x, y).orThunk(fallback); }); }; var availableSearch = document.caretPositionFromPoint ? caretPositionFromPoint : document.caretRangeFromPoint ? caretRangeFromPoint : searchFromPoint; var fromPoint$1 = function (win, x, y) { var doc = Element.fromDom(win.document); return availableSearch(doc, x, y).map(function (rng) { return range$1(Element.fromDom(rng.startContainer), rng.startOffset, Element.fromDom(rng.endContainer), rng.endOffset); }); }; var beforeSpecial = function (element, offset) { var name$1 = name(element); if ('input' === name$1) { return Situ.after(element); } else if (!contains([ 'br', 'img' ], name$1)) { return Situ.on(element, offset); } else { return offset === 0 ? Situ.before(element) : Situ.after(element); } }; var preprocessRelative = function (startSitu, finishSitu) { var start = startSitu.fold(Situ.before, beforeSpecial, Situ.after); var finish = finishSitu.fold(Situ.before, beforeSpecial, Situ.after); return relative(start, finish); }; var preprocessExact = function (start, soffset, finish, foffset) { var startSitu = beforeSpecial(start, soffset); var finishSitu = beforeSpecial(finish, foffset); return relative(startSitu, finishSitu); }; var preprocess = function (selection) { return selection.match({ domRange: function (rng) { var start = Element.fromDom(rng.startContainer); var finish = Element.fromDom(rng.endContainer); return preprocessExact(start, rng.startOffset, finish, rng.endOffset); }, relative: preprocessRelative, exact: preprocessExact }); }; var doSetNativeRange = function (win, rng) { Option.from(win.getSelection()).each(function (selection) { selection.removeAllRanges(); selection.addRange(rng); }); }; var doSetRange = function (win, start, soffset, finish, foffset) { var rng = exactToNative(win, start, soffset, finish, foffset); doSetNativeRange(win, rng); }; var setLegacyRtlRange = function (win, selection, start, soffset, finish, foffset) { selection.collapse(start.dom(), soffset); selection.extend(finish.dom(), foffset); }; var setRangeFromRelative = function (win, relative) { return diagnose(win, relative).match({ ltr: function (start, soffset, finish, foffset) { doSetRange(win, start, soffset, finish, foffset); }, rtl: function (start, soffset, finish, foffset) { var selection = win.getSelection(); if (selection.setBaseAndExtent) { selection.setBaseAndExtent(start.dom(), soffset, finish.dom(), foffset); } else if (selection.extend) { try { setLegacyRtlRange(win, selection, start, soffset, finish, foffset); } catch (e) { doSetRange(win, finish, foffset, start, soffset); } } else { doSetRange(win, finish, foffset, start, soffset); } } }); }; var setExact = function (win, start, soffset, finish, foffset) { var relative = preprocessExact(start, soffset, finish, foffset); setRangeFromRelative(win, relative); }; var setRelative = function (win, startSitu, finishSitu) { var relative = preprocessRelative(startSitu, finishSitu); setRangeFromRelative(win, relative); }; var toNative = function (selection) { var win = getWin(selection).dom(); var getDomRange = function (start, soffset, finish, foffset) { return exactToNative(win, start, soffset, finish, foffset); }; var filtered = preprocess(selection); return diagnose(win, filtered).match({ ltr: getDomRange, rtl: getDomRange }); }; var readRange = function (selection) { if (selection.rangeCount > 0) { var firstRng = selection.getRangeAt(0); var lastRng = selection.getRangeAt(selection.rangeCount - 1); return Option.some(range$1(Element.fromDom(firstRng.startContainer), firstRng.startOffset, Element.fromDom(lastRng.endContainer), lastRng.endOffset)); } else { return Option.none(); } }; var doGetExact = function (selection) { var anchor = Element.fromDom(selection.anchorNode); var focus = Element.fromDom(selection.focusNode); return after$3(anchor, selection.anchorOffset, focus, selection.focusOffset) ? Option.some(range$1(anchor, selection.anchorOffset, focus, selection.focusOffset)) : readRange(selection); }; var setToElement = function (win, element) { var rng = selectNodeContents(win, element); doSetNativeRange(win, rng); }; var getExact = function (win) { return Option.from(win.getSelection()).filter(function (sel) { return sel.rangeCount > 0; }).bind(doGetExact); }; var get$a = function (win) { return getExact(win).map(function (range) { return exact(range.start(), range.soffset(), range.finish(), range.foffset()); }); }; var getFirstRect$1 = function (win, selection) { var rng = asLtrRange(win, selection); return getFirstRect(rng); }; var getAtPoint = function (win, x, y) { return fromPoint$1(win, x, y); }; var clear$1 = function (win) { var selection = win.getSelection(); selection.removeAllRanges(); }; var global$3 = tinymce.util.Tools.resolve('tinymce.util.VK'); var forward = function (editor, isRoot, cell, lazyWire) { return go(editor, isRoot, CellNavigation.next(cell), lazyWire); }; var backward = function (editor, isRoot, cell, lazyWire) { return go(editor, isRoot, CellNavigation.prev(cell), lazyWire); }; var getCellFirstCursorPosition = function (editor, cell) { var selection = exact(cell, 0, cell, 0); return toNative(selection); }; var getNewRowCursorPosition = function (editor, table) { var rows = descendants$1(table, 'tr'); return last(rows).bind(function (last) { return descendant$1(last, 'td,th').map(function (first) { return getCellFirstCursorPosition(editor, first); }); }); }; var go = function (editor, isRoot, cell, actions, lazyWire) { return cell.fold(Option.none, Option.none, function (current, next) { return first(next).map(function (cell) { return getCellFirstCursorPosition(editor, cell); }); }, function (current) { return TableLookup.table(current, isRoot).bind(function (table) { var targets = TableTargets.noMenu(current); editor.undoManager.transact(function () { actions.insertRowsAfter(table, targets); }); return getNewRowCursorPosition(editor, table); }); }); }; var rootElements = [ 'table', 'li', 'dl' ]; var handle$1 = function (event, editor, actions, lazyWire) { if (event.keyCode === global$3.TAB) { var body_1 = getBody$1(editor); var isRoot_1 = function (element) { var name$1 = name(element); return eq(element, body_1) || contains(rootElements, name$1); }; var rng = editor.selection.getRng(); if (rng.collapsed) { var start = Element.fromDom(rng.startContainer); TableLookup.cell(start, isRoot_1).each(function (cell) { event.preventDefault(); var navigation = event.shiftKey ? backward : forward; var rng = navigation(editor, isRoot_1, cell, actions, lazyWire); rng.each(function (range) { editor.selection.setRng(range); }); }); } } }; var TabContext = { handle: handle$1 }; var response = Immutable('selection', 'kill'); var Responses = { response: response }; var isKey = function (key) { return function (keycode) { return keycode === key; }; }; var isUp = isKey(38); var isDown = isKey(40); var isNavigation = function (keycode) { return keycode >= 37 && keycode <= 40; }; var SelectionKeys = { ltr: { isBackward: isKey(37), isForward: isKey(39) }, rtl: { isBackward: isKey(39), isForward: isKey(37) }, isUp: isUp, isDown: isDown, isNavigation: isNavigation }; var convertToRange = function (win, selection) { var rng = asLtrRange(win, selection); return { start: constant(Element.fromDom(rng.startContainer)), soffset: constant(rng.startOffset), finish: constant(Element.fromDom(rng.endContainer)), foffset: constant(rng.endOffset) }; }; var makeSitus = function (start, soffset, finish, foffset) { return { start: constant(Situ.on(start, soffset)), finish: constant(Situ.on(finish, foffset)) }; }; var Util$1 = { convertToRange: convertToRange, makeSitus: makeSitus }; var isSafari = PlatformDetection$1.detect().browser.isSafari(); var get$b = function (_DOC) { var doc = _DOC !== undefined ? _DOC.dom() : domGlobals.document; var x = doc.body.scrollLeft || doc.documentElement.scrollLeft; var y = doc.body.scrollTop || doc.documentElement.scrollTop; return Position(x, y); }; var by = function (x, y, _DOC) { var doc = _DOC !== undefined ? _DOC.dom() : domGlobals.document; var win = doc.defaultView; win.scrollBy(x, y); }; function WindowBridge (win) { var elementFromPoint = function (x, y) { return Element.fromPoint(Element.fromDom(win.document), x, y); }; var getRect = function (element) { return element.dom().getBoundingClientRect(); }; var getRangedRect = function (start, soffset, finish, foffset) { var sel = exact(start, soffset, finish, foffset); return getFirstRect$1(win, sel).map(function (structRect) { return map$1(structRect, apply); }); }; var getSelection = function () { return get$a(win).map(function (exactAdt) { return Util$1.convertToRange(win, exactAdt); }); }; var fromSitus = function (situs) { var relative$1 = relative(situs.start(), situs.finish()); return Util$1.convertToRange(win, relative$1); }; var situsFromPoint = function (x, y) { return getAtPoint(win, x, y).map(function (exact) { return { start: constant(Situ.on(exact.start(), exact.soffset())), finish: constant(Situ.on(exact.finish(), exact.foffset())) }; }); }; var clearSelection = function () { clear$1(win); }; var selectContents = function (element) { setToElement(win, element); }; var setSelection = function (sel) { setExact(win, sel.start(), sel.soffset(), sel.finish(), sel.foffset()); }; var setRelativeSelection = function (start, finish) { setRelative(win, start, finish); }; var getInnerHeight = function () { return win.innerHeight; }; var getScrollY = function () { var pos = get$b(Element.fromDom(win.document)); return pos.top(); }; var scrollBy = function (x, y) { by(x, y, Element.fromDom(win.document)); }; return { elementFromPoint: elementFromPoint, getRect: getRect, getRangedRect: getRangedRect, getSelection: getSelection, fromSitus: fromSitus, situsFromPoint: situsFromPoint, clearSelection: clearSelection, setSelection: setSelection, setRelativeSelection: setRelativeSelection, selectContents: selectContents, getInnerHeight: getInnerHeight, getScrollY: getScrollY, scrollBy: scrollBy }; } var sync = function (container, isRoot, start, soffset, finish, foffset, selectRange) { if (!(eq(start, finish) && soffset === foffset)) { return closest$1(start, 'td,th', isRoot).bind(function (s) { return closest$1(finish, 'td,th', isRoot).bind(function (f) { return detect$5(container, isRoot, s, f, selectRange); }); }); } else { return Option.none(); } }; var detect$5 = function (container, isRoot, start, finish, selectRange) { if (!eq(start, finish)) { return CellSelection.identify(start, finish, isRoot).bind(function (cellSel) { var boxes = cellSel.boxes().getOr([]); if (boxes.length > 0) { selectRange(container, boxes, cellSel.start(), cellSel.finish()); return Option.some(Responses.response(Option.some(Util$1.makeSitus(start, 0, start, getEnd(start))), true)); } else { return Option.none(); } }); } else { return Option.none(); } }; var update = function (rows, columns, container, selected, annotations) { var updateSelection = function (newSels) { annotations.clear(container); annotations.selectRange(container, newSels.boxes(), newSels.start(), newSels.finish()); return newSels.boxes(); }; return CellSelection.shiftSelection(selected, rows, columns, annotations.firstSelectedSelector(), annotations.lastSelectedSelector()).map(updateSelection); }; var KeySelection = { sync: sync, detect: detect$5, update: update }; var nu$3 = MixedBag([ 'left', 'top', 'right', 'bottom' ], []); var moveDown = function (caret, amount) { return nu$3({ left: caret.left(), top: caret.top() + amount, right: caret.right(), bottom: caret.bottom() + amount }); }; var moveUp = function (caret, amount) { return nu$3({ left: caret.left(), top: caret.top() - amount, right: caret.right(), bottom: caret.bottom() - amount }); }; var moveBottomTo = function (caret, bottom) { var height = caret.bottom() - caret.top(); return nu$3({ left: caret.left(), top: bottom - height, right: caret.right(), bottom: bottom }); }; var moveTopTo = function (caret, top) { var height = caret.bottom() - caret.top(); return nu$3({ left: caret.left(), top: top, right: caret.right(), bottom: top + height }); }; var translate = function (caret, xDelta, yDelta) { return nu$3({ left: caret.left() + xDelta, top: caret.top() + yDelta, right: caret.right() + xDelta, bottom: caret.bottom() + yDelta }); }; var getTop$1 = function (caret) { return caret.top(); }; var getBottom = function (caret) { return caret.bottom(); }; var toString = function (caret) { return '(' + caret.left() + ', ' + caret.top() + ') -> (' + caret.right() + ', ' + caret.bottom() + ')'; }; var Carets = { nu: nu$3, moveUp: moveUp, moveDown: moveDown, moveBottomTo: moveBottomTo, moveTopTo: moveTopTo, getTop: getTop$1, getBottom: getBottom, translate: translate, toString: toString }; var getPartialBox = function (bridge, element, offset) { if (offset >= 0 && offset < getEnd(element)) return bridge.getRangedRect(element, offset, element, offset + 1); else if (offset > 0) return bridge.getRangedRect(element, offset - 1, element, offset); return Option.none(); }; var toCaret = function (rect) { return Carets.nu({ left: rect.left, top: rect.top, right: rect.right, bottom: rect.bottom }); }; var getElemBox = function (bridge, element) { return Option.some(bridge.getRect(element)); }; var getBoxAt = function (bridge, element, offset) { if (isElement(element)) return getElemBox(bridge, element).map(toCaret); else if (isText(element)) return getPartialBox(bridge, element, offset).map(toCaret); else return Option.none(); }; var getEntireBox = function (bridge, element) { if (isElement(element)) return getElemBox(bridge, element).map(toCaret); else if (isText(element)) return bridge.getRangedRect(element, 0, element, getEnd(element)).map(toCaret); else return Option.none(); }; var Rectangles = { getBoxAt: getBoxAt, getEntireBox: getEntireBox }; var traverse = Immutable('item', 'mode'); var backtrack = function (universe, item, _direction, transition) { if (transition === void 0) { transition = sidestep; } return universe.property().parent(item).map(function (p) { return traverse(p, transition); }); }; var sidestep = function (universe, item, direction, transition) { if (transition === void 0) { transition = advance; } return direction.sibling(universe, item).map(function (p) { return traverse(p, transition); }); }; var advance = function (universe, item, direction, transition) { if (transition === void 0) { transition = advance; } var children = universe.property().children(item); var result = direction.first(children); return result.map(function (r) { return traverse(r, transition); }); }; var successors = [ { current: backtrack, next: sidestep, fallback: Option.none() }, { current: sidestep, next: advance, fallback: Option.some(backtrack) }, { current: advance, next: advance, fallback: Option.some(sidestep) } ]; var go$1 = function (universe, item, mode, direction, rules) { if (rules === void 0) { rules = successors; } var ruleOpt = find(rules, function (succ) { return succ.current === mode; }); return ruleOpt.bind(function (rule) { return rule.current(universe, item, direction, rule.next).orThunk(function () { return rule.fallback.bind(function (fb) { return go$1(universe, item, fb, direction); }); }); }); }; var left$1 = function () { var sibling = function (universe, item) { return universe.query().prevSibling(item); }; var first = function (children) { return children.length > 0 ? Option.some(children[children.length - 1]) : Option.none(); }; return { sibling: sibling, first: first }; }; var right$1 = function () { var sibling = function (universe, item) { return universe.query().nextSibling(item); }; var first = function (children) { return children.length > 0 ? Option.some(children[0]) : Option.none(); }; return { sibling: sibling, first: first }; }; var Walkers = { left: left$1, right: right$1 }; var hone = function (universe, item, predicate, mode, direction, isRoot) { var next = go$1(universe, item, mode, direction); return next.bind(function (n) { if (isRoot(n.item())) return Option.none(); else return predicate(n.item()) ? Option.some(n.item()) : hone(universe, n.item(), predicate, n.mode(), direction, isRoot); }); }; var left$2 = function (universe, item, predicate, isRoot) { return hone(universe, item, predicate, sidestep, Walkers.left(), isRoot); }; var right$2 = function (universe, item, predicate, isRoot) { return hone(universe, item, predicate, sidestep, Walkers.right(), isRoot); }; var isLeaf = function (universe) { return function (element) { return universe.property().children(element).length === 0; }; }; var before$3 = function (universe, item, isRoot) { return seekLeft(universe, item, isLeaf(universe), isRoot); }; var after$4 = function (universe, item, isRoot) { return seekRight(universe, item, isLeaf(universe), isRoot); }; var seekLeft = left$2; var seekRight = right$2; var universe$2 = DomUniverse(); var before$4 = function (element, isRoot) { return before$3(universe$2, element, isRoot); }; var after$5 = function (element, isRoot) { return after$4(universe$2, element, isRoot); }; var seekLeft$1 = function (element, predicate, isRoot) { return seekLeft(universe$2, element, predicate, isRoot); }; var seekRight$1 = function (element, predicate, isRoot) { return seekRight(universe$2, element, predicate, isRoot); }; var JUMP_SIZE = 5; var NUM_RETRIES = 100; var adt$2 = Adt.generate([ { 'none': [] }, { 'retry': ['caret'] } ]); var isOutside = function (caret, box) { return caret.left() < box.left() || Math.abs(box.right() - caret.left()) < 1 || caret.left() > box.right(); }; var inOutsideBlock = function (bridge, element, caret) { return closest(element, DomStructure.isBlock).fold(constant(false), function (cell) { return Rectangles.getEntireBox(bridge, cell).exists(function (box) { return isOutside(caret, box); }); }); }; var adjustDown = function (bridge, element, guessBox, original, caret) { var lowerCaret = Carets.moveDown(caret, JUMP_SIZE); if (Math.abs(guessBox.bottom() - original.bottom()) < 1) return adt$2.retry(lowerCaret); else if (guessBox.top() > caret.bottom()) return adt$2.retry(lowerCaret); else if (guessBox.top() === caret.bottom()) return adt$2.retry(Carets.moveDown(caret, 1)); else return inOutsideBlock(bridge, element, caret) ? adt$2.retry(Carets.translate(lowerCaret, JUMP_SIZE, 0)) : adt$2.none(); }; var adjustUp = function (bridge, element, guessBox, original, caret) { var higherCaret = Carets.moveUp(caret, JUMP_SIZE); if (Math.abs(guessBox.top() - original.top()) < 1) return adt$2.retry(higherCaret); else if (guessBox.bottom() < caret.top()) return adt$2.retry(higherCaret); else if (guessBox.bottom() === caret.top()) return adt$2.retry(Carets.moveUp(caret, 1)); else return inOutsideBlock(bridge, element, caret) ? adt$2.retry(Carets.translate(higherCaret, JUMP_SIZE, 0)) : adt$2.none(); }; var upMovement = { point: Carets.getTop, adjuster: adjustUp, move: Carets.moveUp, gather: before$4 }; var downMovement = { point: Carets.getBottom, adjuster: adjustDown, move: Carets.moveDown, gather: after$5 }; var isAtTable = function (bridge, x, y) { return bridge.elementFromPoint(x, y).filter(function (elm) { return name(elm) === 'table'; }).isSome(); }; var adjustForTable = function (bridge, movement, original, caret, numRetries) { return adjustTil(bridge, movement, original, movement.move(caret, JUMP_SIZE), numRetries); }; var adjustTil = function (bridge, movement, original, caret, numRetries) { if (numRetries === 0) return Option.some(caret); if (isAtTable(bridge, caret.left(), movement.point(caret))) return adjustForTable(bridge, movement, original, caret, numRetries - 1); return bridge.situsFromPoint(caret.left(), movement.point(caret)).bind(function (guess) { return guess.start().fold(Option.none, function (element, offset) { return Rectangles.getEntireBox(bridge, element, offset).bind(function (guessBox) { return movement.adjuster(bridge, element, guessBox, original, caret).fold(Option.none, function (newCaret) { return adjustTil(bridge, movement, original, newCaret, numRetries - 1); }); }).orThunk(function () { return Option.some(caret); }); }, Option.none); }); }; var ieTryDown = function (bridge, caret) { return bridge.situsFromPoint(caret.left(), caret.bottom() + JUMP_SIZE); }; var ieTryUp = function (bridge, caret) { return bridge.situsFromPoint(caret.left(), caret.top() - JUMP_SIZE); }; var checkScroll = function (movement, adjusted, bridge) { if (movement.point(adjusted) > bridge.getInnerHeight()) return Option.some(movement.point(adjusted) - bridge.getInnerHeight()); else if (movement.point(adjusted) < 0) return Option.some(-movement.point(adjusted)); else return Option.none(); }; var retry = function (movement, bridge, caret) { var moved = movement.move(caret, JUMP_SIZE); var adjusted = adjustTil(bridge, movement, caret, moved, NUM_RETRIES).getOr(moved); return checkScroll(movement, adjusted, bridge).fold(function () { return bridge.situsFromPoint(adjusted.left(), movement.point(adjusted)); }, function (delta) { bridge.scrollBy(0, delta); return bridge.situsFromPoint(adjusted.left(), movement.point(adjusted) - delta); }); }; var Retries = { tryUp: curry(retry, upMovement), tryDown: curry(retry, downMovement), ieTryUp: ieTryUp, ieTryDown: ieTryDown, getJumpSize: constant(JUMP_SIZE) }; var adt$3 = Adt.generate([ { 'none': ['message'] }, { 'success': [] }, { 'failedUp': ['cell'] }, { 'failedDown': ['cell'] } ]); var isOverlapping = function (bridge, before, after) { var beforeBounds = bridge.getRect(before); var afterBounds = bridge.getRect(after); return afterBounds.right > beforeBounds.left && afterBounds.left < beforeBounds.right; }; var verify = function (bridge, before, beforeOffset, after, afterOffset, failure, isRoot) { return closest$1(after, 'td,th', isRoot).bind(function (afterCell) { return closest$1(before, 'td,th', isRoot).map(function (beforeCell) { if (!eq(afterCell, beforeCell)) { return DomParent.sharedOne(isRow, [ afterCell, beforeCell ]).fold(function () { return isOverlapping(bridge, beforeCell, afterCell) ? adt$3.success() : failure(beforeCell); }, function (sharedRow) { return failure(beforeCell); }); } else { return eq(after, afterCell) && getEnd(afterCell) === afterOffset ? failure(beforeCell) : adt$3.none('in same cell'); } }); }).getOr(adt$3.none('default')); }; var isRow = function (elem) { return closest$1(elem, 'tr'); }; var cata$2 = function (subject, onNone, onSuccess, onFailedUp, onFailedDown) { return subject.fold(onNone, onSuccess, onFailedUp, onFailedDown); }; var BeforeAfter = { verify: verify, cata: cata$2, adt: adt$3 }; var point = Immutable('element', 'offset'); var delta = Immutable('element', 'deltaOffset'); var range$2 = Immutable('element', 'start', 'finish'); var points = Immutable('begin', 'end'); var text = Immutable('element', 'text'); var inAncestor = Immutable('ancestor', 'descendants', 'element', 'index'); var inParent = Immutable('parent', 'children', 'element', 'index'); var indexInParent = function (element) { return parent(element).bind(function (parent) { var children$1 = children(parent); return indexOf(children$1, element).map(function (index) { return inParent(parent, children$1, element, index); }); }); }; var indexOf = function (elements, element) { return findIndex(elements, curry(eq, element)); }; var isBr = function (elem) { return name(elem) === 'br'; }; var gatherer = function (cand, gather, isRoot) { return gather(cand, isRoot).bind(function (target) { return isText(target) && get$2(target).trim().length === 0 ? gatherer(target, gather, isRoot) : Option.some(target); }); }; var handleBr = function (isRoot, element, direction) { return direction.traverse(element).orThunk(function () { return gatherer(element, direction.gather, isRoot); }).map(direction.relative); }; var findBr = function (element, offset) { return child(element, offset).filter(isBr).orThunk(function () { return child(element, offset - 1).filter(isBr); }); }; var handleParent = function (isRoot, element, offset, direction) { return findBr(element, offset).bind(function (br) { return direction.traverse(br).fold(function () { return gatherer(br, direction.gather, isRoot).map(direction.relative); }, function (adjacent) { return indexInParent(adjacent).map(function (info) { return Situ.on(info.parent(), info.index()); }); }); }); }; var tryBr = function (isRoot, element, offset, direction) { var target = isBr(element) ? handleBr(isRoot, element, direction) : handleParent(isRoot, element, offset, direction); return target.map(function (tgt) { return { start: constant(tgt), finish: constant(tgt) }; }); }; var process = function (analysis) { return BeforeAfter.cata(analysis, function (message) { return Option.none(); }, function () { return Option.none(); }, function (cell) { return Option.some(point(cell, 0)); }, function (cell) { return Option.some(point(cell, getEnd(cell))); }); }; var BrTags = { tryBr: tryBr, process: process }; var MAX_RETRIES = 20; var platform$1 = PlatformDetection$1.detect(); var findSpot = function (bridge, isRoot, direction) { return bridge.getSelection().bind(function (sel) { return BrTags.tryBr(isRoot, sel.finish(), sel.foffset(), direction).fold(function () { return Option.some(point(sel.finish(), sel.foffset())); }, function (brNeighbour) { var range = bridge.fromSitus(brNeighbour); var analysis = BeforeAfter.verify(bridge, sel.finish(), sel.foffset(), range.finish(), range.foffset(), direction.failure, isRoot); return BrTags.process(analysis); }); }); }; var scan = function (bridge, isRoot, element, offset, direction, numRetries) { if (numRetries === 0) return Option.none(); return tryCursor(bridge, isRoot, element, offset, direction).bind(function (situs) { var range = bridge.fromSitus(situs); var analysis = BeforeAfter.verify(bridge, element, offset, range.finish(), range.foffset(), direction.failure, isRoot); return BeforeAfter.cata(analysis, function () { return Option.none(); }, function () { return Option.some(situs); }, function (cell) { if (eq(element, cell) && offset === 0) return tryAgain(bridge, element, offset, Carets.moveUp, direction); else return scan(bridge, isRoot, cell, 0, direction, numRetries - 1); }, function (cell) { if (eq(element, cell) && offset === getEnd(cell)) return tryAgain(bridge, element, offset, Carets.moveDown, direction); else return scan(bridge, isRoot, cell, getEnd(cell), direction, numRetries - 1); }); }); }; var tryAgain = function (bridge, element, offset, move, direction) { return Rectangles.getBoxAt(bridge, element, offset).bind(function (box) { return tryAt(bridge, direction, move(box, Retries.getJumpSize())); }); }; var tryAt = function (bridge, direction, box) { if (platform$1.browser.isChrome() || platform$1.browser.isSafari() || platform$1.browser.isFirefox() || platform$1.browser.isEdge()) return direction.otherRetry(bridge, box); else if (platform$1.browser.isIE()) return direction.ieRetry(bridge, box); else return Option.none(); }; var tryCursor = function (bridge, isRoot, element, offset, direction) { return Rectangles.getBoxAt(bridge, element, offset).bind(function (box) { return tryAt(bridge, direction, box); }); }; var handle$2 = function (bridge, isRoot, direction) { return findSpot(bridge, isRoot, direction).bind(function (spot) { return scan(bridge, isRoot, spot.element(), spot.offset(), direction, MAX_RETRIES).map(bridge.fromSitus); }); }; var TableKeys = { handle: handle$2 }; var ancestor$2 = function (scope, predicate, isRoot) { return ancestor(scope, predicate, isRoot).isSome(); }; var detection = PlatformDetection$1.detect(); var inSameTable = function (elem, table) { return ancestor$2(elem, function (e) { return parent(e).exists(function (p) { return eq(p, table); }); }); }; var simulate = function (bridge, isRoot, direction, initial, anchor) { return closest$1(initial, 'td,th', isRoot).bind(function (start) { return closest$1(start, 'table', isRoot).bind(function (table) { if (!inSameTable(anchor, table)) return Option.none(); return TableKeys.handle(bridge, isRoot, direction).bind(function (range) { return closest$1(range.finish(), 'td,th', isRoot).map(function (finish) { return { start: constant(start), finish: constant(finish), range: constant(range) }; }); }); }); }); }; var navigate = function (bridge, isRoot, direction, initial, anchor, precheck) { if (detection.browser.isIE()) { return Option.none(); } else { return precheck(initial, isRoot).orThunk(function () { return simulate(bridge, isRoot, direction, initial, anchor).map(function (info) { var range = info.range(); return Responses.response(Option.some(Util$1.makeSitus(range.start(), range.soffset(), range.finish(), range.foffset())), true); }); }); } }; var firstUpCheck = function (initial, isRoot) { return closest$1(initial, 'tr', isRoot).bind(function (startRow) { return closest$1(startRow, 'table', isRoot).bind(function (table) { var rows = descendants$1(table, 'tr'); if (eq(startRow, rows[0])) { return seekLeft$1(table, function (element) { return last$1(element).isSome(); }, isRoot).map(function (last) { var lastOffset = getEnd(last); return Responses.response(Option.some(Util$1.makeSitus(last, lastOffset, last, lastOffset)), true); }); } else { return Option.none(); } }); }); }; var lastDownCheck = function (initial, isRoot) { return closest$1(initial, 'tr', isRoot).bind(function (startRow) { return closest$1(startRow, 'table', isRoot).bind(function (table) { var rows = descendants$1(table, 'tr'); if (eq(startRow, rows[rows.length - 1])) { return seekRight$1(table, function (element) { return first(element).isSome(); }, isRoot).map(function (first) { return Responses.response(Option.some(Util$1.makeSitus(first, 0, first, 0)), true); }); } else { return Option.none(); } }); }); }; var select = function (bridge, container, isRoot, direction, initial, anchor, selectRange) { return simulate(bridge, isRoot, direction, initial, anchor).bind(function (info) { return KeySelection.detect(container, isRoot, info.start(), info.finish(), selectRange); }); }; var VerticalMovement = { navigate: navigate, select: select, firstUpCheck: firstUpCheck, lastDownCheck: lastDownCheck }; var findCell = function (target, isRoot) { return closest$1(target, 'td,th', isRoot); }; function MouseSelection (bridge, container, isRoot, annotations) { var cursor = Option.none(); var clearState = function () { cursor = Option.none(); }; var mousedown = function (event) { annotations.clear(container); cursor = findCell(event.target(), isRoot); }; var mouseover = function (event) { cursor.each(function (start) { annotations.clear(container); findCell(event.target(), isRoot).each(function (finish) { CellSelection.identify(start, finish, isRoot).each(function (cellSel) { var boxes = cellSel.boxes().getOr([]); if (boxes.length > 1 || boxes.length === 1 && !eq(start, finish)) { annotations.selectRange(container, boxes, cellSel.start(), cellSel.finish()); bridge.selectContents(finish); } }); }); }); }; var mouseup = function () { cursor.each(clearState); }; return { mousedown: mousedown, mouseover: mouseover, mouseup: mouseup }; } var KeyDirection = { down: { traverse: nextSibling, gather: after$5, relative: Situ.before, otherRetry: Retries.tryDown, ieRetry: Retries.ieTryDown, failure: BeforeAfter.adt.failedDown }, up: { traverse: prevSibling, gather: before$4, relative: Situ.before, otherRetry: Retries.tryUp, ieRetry: Retries.ieTryUp, failure: BeforeAfter.adt.failedUp } }; var rc = Immutable('rows', 'cols'); var mouse = function (win, container, isRoot, annotations) { var bridge = WindowBridge(win); var handlers = MouseSelection(bridge, container, isRoot, annotations); return { mousedown: handlers.mousedown, mouseover: handlers.mouseover, mouseup: handlers.mouseup }; }; var keyboard = function (win, container, isRoot, annotations) { var bridge = WindowBridge(win); var clearToNavigate = function () { annotations.clear(container); return Option.none(); }; var keydown = function (event, start, soffset, finish, foffset, direction) { var keycode = event.raw().which; var shiftKey = event.raw().shiftKey === true; var handler = CellSelection.retrieve(container, annotations.selectedSelector()).fold(function () { if (SelectionKeys.isDown(keycode) && shiftKey) { return curry(VerticalMovement.select, bridge, container, isRoot, KeyDirection.down, finish, start, annotations.selectRange); } else if (SelectionKeys.isUp(keycode) && shiftKey) { return curry(VerticalMovement.select, bridge, container, isRoot, KeyDirection.up, finish, start, annotations.selectRange); } else if (SelectionKeys.isDown(keycode)) { return curry(VerticalMovement.navigate, bridge, isRoot, KeyDirection.down, finish, start, VerticalMovement.lastDownCheck); } else if (SelectionKeys.isUp(keycode)) { return curry(VerticalMovement.navigate, bridge, isRoot, KeyDirection.up, finish, start, VerticalMovement.firstUpCheck); } else { return Option.none; } }, function (selected) { var update = function (attempts) { return function () { var navigation = findMap(attempts, function (delta) { return KeySelection.update(delta.rows(), delta.cols(), container, selected, annotations); }); return navigation.fold(function () { return CellSelection.getEdges(container, annotations.firstSelectedSelector(), annotations.lastSelectedSelector()).map(function (edges) { var relative = SelectionKeys.isDown(keycode) || direction.isForward(keycode) ? Situ.after : Situ.before; bridge.setRelativeSelection(Situ.on(edges.first(), 0), relative(edges.table())); annotations.clear(container); return Responses.response(Option.none(), true); }); }, function (_) { return Option.some(Responses.response(Option.none(), true)); }); }; }; if (SelectionKeys.isDown(keycode) && shiftKey) return update([rc(+1, 0)]); else if (SelectionKeys.isUp(keycode) && shiftKey) return update([rc(-1, 0)]); else if (direction.isBackward(keycode) && shiftKey) return update([ rc(0, -1), rc(-1, 0) ]); else if (direction.isForward(keycode) && shiftKey) return update([ rc(0, +1), rc(+1, 0) ]); else if (SelectionKeys.isNavigation(keycode) && shiftKey === false) return clearToNavigate; else return Option.none; }); return handler(); }; var keyup = function (event, start, soffset, finish, foffset) { return CellSelection.retrieve(container, annotations.selectedSelector()).fold(function () { var keycode = event.raw().which; var shiftKey = event.raw().shiftKey === true; if (shiftKey === false) return Option.none(); if (SelectionKeys.isNavigation(keycode)) return KeySelection.sync(container, isRoot, start, soffset, finish, foffset, annotations.selectRange); else return Option.none(); }, Option.none); }; return { keydown: keydown, keyup: keyup }; }; var InputHandlers = { mouse: mouse, keyboard: keyboard }; var remove$7 = function (element, classes) { each(classes, function (x) { remove$5(element, x); }); }; var addClass = function (clazz) { return function (element) { add$2(element, clazz); }; }; var removeClasses = function (classes) { return function (element) { remove$7(element, classes); }; }; var byClass = function (ephemera) { var addSelectionClass = addClass(ephemera.selected()); var removeSelectionClasses = removeClasses([ ephemera.selected(), ephemera.lastSelected(), ephemera.firstSelected() ]); var clear = function (container) { var sels = descendants$1(container, ephemera.selectedSelector()); each(sels, removeSelectionClasses); }; var selectRange = function (container, cells, start, finish) { clear(container); each(cells, addSelectionClass); add$2(start, ephemera.firstSelected()); add$2(finish, ephemera.lastSelected()); }; return { clear: clear, selectRange: selectRange, selectedSelector: ephemera.selectedSelector, firstSelectedSelector: ephemera.firstSelectedSelector, lastSelectedSelector: ephemera.lastSelectedSelector }; }; var byAttr = function (ephemera) { var removeSelectionAttributes = function (element) { remove(element, ephemera.selected()); remove(element, ephemera.firstSelected()); remove(element, ephemera.lastSelected()); }; var addSelectionAttribute = function (element) { set(element, ephemera.selected(), '1'); }; var clear = function (container) { var sels = descendants$1(container, ephemera.selectedSelector()); each(sels, removeSelectionAttributes); }; var selectRange = function (container, cells, start, finish) { clear(container); each(cells, addSelectionAttribute); set(start, ephemera.firstSelected(), '1'); set(finish, ephemera.lastSelected(), '1'); }; return { clear: clear, selectRange: selectRange, selectedSelector: ephemera.selectedSelector, firstSelectedSelector: ephemera.firstSelectedSelector, lastSelectedSelector: ephemera.lastSelectedSelector }; }; var SelectionAnnotation = { byClass: byClass, byAttr: byAttr }; var hasInternalTarget = function (e) { return has$1(Element.fromDom(e.target), 'ephox-snooker-resizer-bar') === false; }; function CellSelection$1 (editor, lazyResize) { var handlerStruct = MixedBag([ 'mousedown', 'mouseover', 'mouseup', 'keyup', 'keydown' ], []); var handlers = Option.none(); var annotations = SelectionAnnotation.byAttr(Ephemera); editor.on('init', function (e) { var win = editor.getWin(); var body = getBody$1(editor); var isRoot = getIsRoot(editor); var syncSelection = function () { var sel = editor.selection; var start = Element.fromDom(sel.getStart()); var end = Element.fromDom(sel.getEnd()); var shared = DomParent.sharedOne(TableLookup.table, [ start, end ]); shared.fold(function () { annotations.clear(body); }, noop); }; var mouseHandlers = InputHandlers.mouse(win, body, isRoot, annotations); var keyHandlers = InputHandlers.keyboard(win, body, isRoot, annotations); var hasShiftKey = function (event) { return event.raw().shiftKey === true; }; var handleResponse = function (event, response) { if (!hasShiftKey(event)) { return; } if (response.kill()) { event.kill(); } response.selection().each(function (ns) { var relative$1 = relative(ns.start(), ns.finish()); var rng = asLtrRange(win, relative$1); editor.selection.setRng(rng); }); }; var keyup = function (event) { var wrappedEvent = wrapEvent(event); if (wrappedEvent.raw().shiftKey && SelectionKeys.isNavigation(wrappedEvent.raw().which)) { var rng = editor.selection.getRng(); var start = Element.fromDom(rng.startContainer); var end = Element.fromDom(rng.endContainer); keyHandlers.keyup(wrappedEvent, start, rng.startOffset, end, rng.endOffset).each(function (response) { handleResponse(wrappedEvent, response); }); } }; var keydown = function (event) { var wrappedEvent = wrapEvent(event); lazyResize().each(function (resize) { resize.hideBars(); }); var rng = editor.selection.getRng(); var startContainer = Element.fromDom(editor.selection.getStart()); var start = Element.fromDom(rng.startContainer); var end = Element.fromDom(rng.endContainer); var direction = Direction.directionAt(startContainer).isRtl() ? SelectionKeys.rtl : SelectionKeys.ltr; keyHandlers.keydown(wrappedEvent, start, rng.startOffset, end, rng.endOffset, direction).each(function (response) { handleResponse(wrappedEvent, response); }); lazyResize().each(function (resize) { resize.showBars(); }); }; var isMouseEvent = function (event) { return event.hasOwnProperty('x') && event.hasOwnProperty('y'); }; var wrapEvent = function (event) { var target = Element.fromDom(event.target); var stop = function () { event.stopPropagation(); }; var prevent = function () { event.preventDefault(); }; var kill = compose(prevent, stop); return { target: constant(target), x: constant(isMouseEvent(event) ? event.x : null), y: constant(isMouseEvent(event) ? event.y : null), stop: stop, prevent: prevent, kill: kill, raw: constant(event) }; }; var isLeftMouse = function (raw) { return raw.button === 0; }; var isLeftButtonPressed = function (raw) { if (raw.buttons === undefined) { return true; } return (raw.buttons & 1) !== 0; }; var mouseDown = function (e) { if (isLeftMouse(e) && hasInternalTarget(e)) { mouseHandlers.mousedown(wrapEvent(e)); } }; var mouseOver = function (e) { if (isLeftButtonPressed(e) && hasInternalTarget(e)) { mouseHandlers.mouseover(wrapEvent(e)); } }; var mouseUp = function (e) { if (isLeftMouse(e) && hasInternalTarget(e)) { mouseHandlers.mouseup(wrapEvent(e)); } }; editor.on('mousedown', mouseDown); editor.on('mouseover', mouseOver); editor.on('mouseup', mouseUp); editor.on('keyup', keyup); editor.on('keydown', keydown); editor.on('nodechange', syncSelection); handlers = Option.some(handlerStruct({ mousedown: mouseDown, mouseover: mouseOver, mouseup: mouseUp, keyup: keyup, keydown: keydown })); }); var destroy = function () { handlers.each(function (handlers) { }); }; return { clear: annotations.clear, destroy: destroy }; } var Selections = function (editor) { var get = function () { var body = getBody$1(editor); return TableSelection.retrieve(body, Ephemera.selectedSelector()).fold(function () { if (editor.selection.getStart() === undefined) { return SelectionTypes.none(); } else { return SelectionTypes.single(editor.selection); } }, function (cells) { return SelectionTypes.multiple(cells); }); }; return { get: get }; }; var each$4 = global$1.each; var addButtons = function (editor) { var menuItems = []; each$4('inserttable tableprops deletetable | cell row column'.split(' '), function (name) { if (name === '|') { menuItems.push({ text: '-' }); } else { menuItems.push(editor.menuItems[name]); } }); editor.addButton('table', { type: 'menubutton', title: 'Table', menu: menuItems }); function cmd(command) { return function () { editor.execCommand(command); }; } editor.addButton('tableprops', { title: 'Table properties', onclick: cmd('mceTableProps'), icon: 'table' }); editor.addButton('tabledelete', { title: 'Delete table', onclick: cmd('mceTableDelete') }); editor.addButton('tablecellprops', { title: 'Cell properties', onclick: cmd('mceTableCellProps') }); editor.addButton('tablemergecells', { title: 'Merge cells', onclick: cmd('mceTableMergeCells') }); editor.addButton('tablesplitcells', { title: 'Split cell', onclick: cmd('mceTableSplitCells') }); editor.addButton('tableinsertrowbefore', { title: 'Insert row before', onclick: cmd('mceTableInsertRowBefore') }); editor.addButton('tableinsertrowafter', { title: 'Insert row after', onclick: cmd('mceTableInsertRowAfter') }); editor.addButton('tabledeleterow', { title: 'Delete row', onclick: cmd('mceTableDeleteRow') }); editor.addButton('tablerowprops', { title: 'Row properties', onclick: cmd('mceTableRowProps') }); editor.addButton('tablecutrow', { title: 'Cut row', onclick: cmd('mceTableCutRow') }); editor.addButton('tablecopyrow', { title: 'Copy row', onclick: cmd('mceTableCopyRow') }); editor.addButton('tablepasterowbefore', { title: 'Paste row before', onclick: cmd('mceTablePasteRowBefore') }); editor.addButton('tablepasterowafter', { title: 'Paste row after', onclick: cmd('mceTablePasteRowAfter') }); editor.addButton('tableinsertcolbefore', { title: 'Insert column before', onclick: cmd('mceTableInsertColBefore') }); editor.addButton('tableinsertcolafter', { title: 'Insert column after', onclick: cmd('mceTableInsertColAfter') }); editor.addButton('tabledeletecol', { title: 'Delete column', onclick: cmd('mceTableDeleteCol') }); }; var addToolbars = function (editor) { var isTable = function (table) { var selectorMatched = editor.dom.is(table, 'table') && editor.getBody().contains(table); return selectorMatched; }; var toolbar = getToolbar(editor); if (toolbar.length > 0) { editor.addContextToolbar(isTable, toolbar.join(' ')); } }; var Buttons = { addButtons: addButtons, addToolbars: addToolbars }; var addMenuItems = function (editor, selections) { var targets = Option.none(); var tableCtrls = []; var cellCtrls = []; var mergeCtrls = []; var unmergeCtrls = []; var noTargetDisable = function (ctrl) { ctrl.disabled(true); }; var ctrlEnable = function (ctrl) { ctrl.disabled(false); }; var pushTable = function () { var self = this; tableCtrls.push(self); targets.fold(function () { noTargetDisable(self); }, function (targets) { ctrlEnable(self); }); }; var pushCell = function () { var self = this; cellCtrls.push(self); targets.fold(function () { noTargetDisable(self); }, function (targets) { ctrlEnable(self); }); }; var pushMerge = function () { var self = this; mergeCtrls.push(self); targets.fold(function () { noTargetDisable(self); }, function (targets) { self.disabled(targets.mergable().isNone()); }); }; var pushUnmerge = function () { var self = this; unmergeCtrls.push(self); targets.fold(function () { noTargetDisable(self); }, function (targets) { self.disabled(targets.unmergable().isNone()); }); }; var setDisabledCtrls = function () { targets.fold(function () { each(tableCtrls, noTargetDisable); each(cellCtrls, noTargetDisable); each(mergeCtrls, noTargetDisable); each(unmergeCtrls, noTargetDisable); }, function (targets) { each(tableCtrls, ctrlEnable); each(cellCtrls, ctrlEnable); each(mergeCtrls, function (mergeCtrl) { mergeCtrl.disabled(targets.mergable().isNone()); }); each(unmergeCtrls, function (unmergeCtrl) { unmergeCtrl.disabled(targets.unmergable().isNone()); }); }); }; editor.on('init', function () { editor.on('nodechange', function (e) { var cellOpt = Option.from(editor.dom.getParent(editor.selection.getStart(), 'th,td')); targets = cellOpt.bind(function (cellDom) { var cell = Element.fromDom(cellDom); var table = TableLookup.table(cell); return table.map(function (table) { return TableTargets.forMenu(selections, table, cell); }); }); setDisabledCtrls(); }); }); var generateTableGrid = function () { var html = ''; html = '<table role="grid" class="mce-grid mce-grid-border" aria-readonly="true">'; for (var y = 0; y < 10; y++) { html += '<tr>'; for (var x = 0; x < 10; x++) { html += '<td role="gridcell" tabindex="-1"><a id="mcegrid' + (y * 10 + x) + '" href="#" ' + 'data-mce-x="' + x + '" data-mce-y="' + y + '"></a></td>'; } html += '</tr>'; } html += '</table>'; html += '<div class="mce-text-center" role="presentation">1 x 1</div>'; return html; }; var selectGrid = function (editor, tx, ty, control) { var table = control.getEl().getElementsByTagName('table')[0]; var x, y, focusCell, cell, active; var rtl = control.isRtl() || control.parent().rel === 'tl-tr'; table.nextSibling.innerHTML = tx + 1 + ' x ' + (ty + 1); if (rtl) { tx = 9 - tx; } for (y = 0; y < 10; y++) { for (x = 0; x < 10; x++) { cell = table.rows[y].childNodes[x].firstChild; active = (rtl ? x >= tx : x <= tx) && y <= ty; editor.dom.toggleClass(cell, 'mce-active', active); if (active) { focusCell = cell; } } } return focusCell.parentNode; }; var insertTable = hasTableGrid(editor) === false ? { text: 'Table', icon: 'table', context: 'table', onclick: cmd('mceInsertTable') } : { text: 'Table', icon: 'table', context: 'table', ariaHideMenu: true, onclick: function (e) { if (e.aria) { this.parent().hideAll(); e.stopImmediatePropagation(); editor.execCommand('mceInsertTable'); } }, onshow: function () { selectGrid(editor, 0, 0, this.menu.items()[0]); }, onhide: function () { var elements = this.menu.items()[0].getEl().getElementsByTagName('a'); editor.dom.removeClass(elements, 'mce-active'); editor.dom.addClass(elements[0], 'mce-active'); }, menu: [{ type: 'container', html: generateTableGrid(), onPostRender: function () { this.lastX = this.lastY = 0; }, onmousemove: function (e) { var target = e.target; var x, y; if (target.tagName.toUpperCase() === 'A') { x = parseInt(target.getAttribute('data-mce-x'), 10); y = parseInt(target.getAttribute('data-mce-y'), 10); if (this.isRtl() || this.parent().rel === 'tl-tr') { x = 9 - x; } if (x !== this.lastX || y !== this.lastY) { selectGrid(editor, x, y, e.control); this.lastX = x; this.lastY = y; } } }, onclick: function (e) { var self = this; if (e.target.tagName.toUpperCase() === 'A') { e.preventDefault(); e.stopPropagation(); self.parent().cancel(); editor.undoManager.transact(function () { InsertTable.insert(editor, self.lastX + 1, self.lastY + 1); }); editor.addVisual(); } } }] }; function cmd(command) { return function () { editor.execCommand(command); }; } var tableProperties = { text: 'Table properties', context: 'table', onPostRender: pushTable, onclick: cmd('mceTableProps') }; var deleteTable = { text: 'Delete table', context: 'table', onPostRender: pushTable, cmd: 'mceTableDelete' }; var row = { text: 'Row', context: 'table', menu: [ { text: 'Insert row before', onclick: cmd('mceTableInsertRowBefore'), onPostRender: pushCell }, { text: 'Insert row after', onclick: cmd('mceTableInsertRowAfter'), onPostRender: pushCell }, { text: 'Delete row', onclick: cmd('mceTableDeleteRow'), onPostRender: pushCell }, { text: 'Row properties', onclick: cmd('mceTableRowProps'), onPostRender: pushCell }, { text: '-' }, { text: 'Cut row', onclick: cmd('mceTableCutRow'), onPostRender: pushCell }, { text: 'Copy row', onclick: cmd('mceTableCopyRow'), onPostRender: pushCell }, { text: 'Paste row before', onclick: cmd('mceTablePasteRowBefore'), onPostRender: pushCell }, { text: 'Paste row after', onclick: cmd('mceTablePasteRowAfter'), onPostRender: pushCell } ] }; var column = { text: 'Column', context: 'table', menu: [ { text: 'Insert column before', onclick: cmd('mceTableInsertColBefore'), onPostRender: pushCell }, { text: 'Insert column after', onclick: cmd('mceTableInsertColAfter'), onPostRender: pushCell }, { text: 'Delete column', onclick: cmd('mceTableDeleteCol'), onPostRender: pushCell } ] }; var cell = { separator: 'before', text: 'Cell', context: 'table', menu: [ { text: 'Cell properties', onclick: cmd('mceTableCellProps'), onPostRender: pushCell }, { text: 'Merge cells', onclick: cmd('mceTableMergeCells'), onPostRender: pushMerge }, { text: 'Split cell', onclick: cmd('mceTableSplitCells'), onPostRender: pushUnmerge } ] }; editor.addMenuItem('inserttable', insertTable); editor.addMenuItem('tableprops', tableProperties); editor.addMenuItem('deletetable', deleteTable); editor.addMenuItem('row', row); editor.addMenuItem('column', column); editor.addMenuItem('cell', cell); }; var MenuItems = { addMenuItems: addMenuItems }; var getClipboardRows = function (clipboardRows) { return clipboardRows.get().fold(function () { return; }, function (rows) { return map(rows, function (row) { return row.dom(); }); }); }; var setClipboardRows = function (rows, clipboardRows) { var sugarRows = map(rows, Element.fromDom); clipboardRows.set(Option.from(sugarRows)); }; var getApi = function (editor, clipboardRows) { return { insertTable: function (columns, rows) { return InsertTable.insert(editor, columns, rows); }, setClipboardRows: function (rows) { return setClipboardRows(rows, clipboardRows); }, getClipboardRows: function () { return getClipboardRows(clipboardRows); } }; }; function Plugin(editor) { var resizeHandler = ResizeHandler(editor); var cellSelection = CellSelection$1(editor, resizeHandler.lazyResize); var actions = TableActions(editor, resizeHandler.lazyWire); var selections = Selections(editor); var clipboardRows = Cell(Option.none()); Commands.registerCommands(editor, actions, cellSelection, selections, clipboardRows); Clipboard.registerEvents(editor, selections, actions, cellSelection); MenuItems.addMenuItems(editor, selections); Buttons.addButtons(editor); Buttons.addToolbars(editor); editor.on('PreInit', function () { editor.serializer.addTempAttr(Ephemera.firstSelected()); editor.serializer.addTempAttr(Ephemera.lastSelected()); }); if (hasTabNavigation(editor)) { editor.on('keydown', function (e) { TabContext.handle(e, editor, actions, resizeHandler.lazyWire); }); } editor.on('remove', function () { resizeHandler.destroy(); cellSelection.destroy(); }); return getApi(editor, clipboardRows); } global.add('table', Plugin); function Plugin$1 () { } return Plugin$1; }(window)); })(); (function () { var template = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); function curry(fn) { var initialArgs = []; for (var _i = 1; _i < arguments.length; _i++) { initialArgs[_i - 1] = arguments[_i]; } return function () { var restArgs = []; for (var _i = 0; _i < arguments.length; _i++) { restArgs[_i] = arguments[_i]; } var all = initialArgs.concat(restArgs); return fn.apply(null, all); }; } var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var global$2 = tinymce.util.Tools.resolve('tinymce.util.XHR'); var global$3 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var getCreationDateClasses = function (editor) { return editor.getParam('template_cdate_classes', 'cdate'); }; var getModificationDateClasses = function (editor) { return editor.getParam('template_mdate_classes', 'mdate'); }; var getSelectedContentClasses = function (editor) { return editor.getParam('template_selected_content_classes', 'selcontent'); }; var getPreviewReplaceValues = function (editor) { return editor.getParam('template_preview_replace_values'); }; var getTemplateReplaceValues = function (editor) { return editor.getParam('template_replace_values'); }; var getTemplates = function (editorSettings) { return editorSettings.templates; }; var getCdateFormat = function (editor) { return editor.getParam('template_cdate_format', editor.getLang('template.cdate_format')); }; var getMdateFormat = function (editor) { return editor.getParam('template_mdate_format', editor.getLang('template.mdate_format')); }; var getDialogWidth = function (editor) { return editor.getParam('template_popup_width', 600); }; var getDialogHeight = function (editor) { return Math.min(global$3.DOM.getViewPort().h, editor.getParam('template_popup_height', 500)); }; var Settings = { getCreationDateClasses: getCreationDateClasses, getModificationDateClasses: getModificationDateClasses, getSelectedContentClasses: getSelectedContentClasses, getPreviewReplaceValues: getPreviewReplaceValues, getTemplateReplaceValues: getTemplateReplaceValues, getTemplates: getTemplates, getCdateFormat: getCdateFormat, getMdateFormat: getMdateFormat, getDialogWidth: getDialogWidth, getDialogHeight: getDialogHeight }; var addZeros = function (value, len) { value = '' + value; if (value.length < len) { for (var i = 0; i < len - value.length; i++) { value = '0' + value; } } return value; }; var getDateTime = function (editor, fmt, date) { var daysShort = 'Sun Mon Tue Wed Thu Fri Sat Sun'.split(' '); var daysLong = 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday'.split(' '); var monthsShort = 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' '); var monthsLong = 'January February March April May June July August September October November December'.split(' '); date = date || new Date(); fmt = fmt.replace('%D', '%m/%d/%Y'); fmt = fmt.replace('%r', '%I:%M:%S %p'); fmt = fmt.replace('%Y', '' + date.getFullYear()); fmt = fmt.replace('%y', '' + date.getYear()); fmt = fmt.replace('%m', addZeros(date.getMonth() + 1, 2)); fmt = fmt.replace('%d', addZeros(date.getDate(), 2)); fmt = fmt.replace('%H', '' + addZeros(date.getHours(), 2)); fmt = fmt.replace('%M', '' + addZeros(date.getMinutes(), 2)); fmt = fmt.replace('%S', '' + addZeros(date.getSeconds(), 2)); fmt = fmt.replace('%I', '' + ((date.getHours() + 11) % 12 + 1)); fmt = fmt.replace('%p', '' + (date.getHours() < 12 ? 'AM' : 'PM')); fmt = fmt.replace('%B', '' + editor.translate(monthsLong[date.getMonth()])); fmt = fmt.replace('%b', '' + editor.translate(monthsShort[date.getMonth()])); fmt = fmt.replace('%A', '' + editor.translate(daysLong[date.getDay()])); fmt = fmt.replace('%a', '' + editor.translate(daysShort[date.getDay()])); fmt = fmt.replace('%%', '%'); return fmt; }; var DateTimeHelper = { getDateTime: getDateTime }; var createTemplateList = function (editorSettings, callback) { return function () { var templateList = Settings.getTemplates(editorSettings); if (typeof templateList === 'function') { templateList(callback); return; } if (typeof templateList === 'string') { global$2.send({ url: templateList, success: function (text) { callback(JSON.parse(text)); } }); } else { callback(templateList); } }; }; var replaceTemplateValues = function (editor, html, templateValues) { global$1.each(templateValues, function (v, k) { if (typeof v === 'function') { v = v(k); } html = html.replace(new RegExp('\\{\\$' + k + '\\}', 'g'), v); }); return html; }; var replaceVals = function (editor, e) { var dom = editor.dom, vl = Settings.getTemplateReplaceValues(editor); global$1.each(dom.select('*', e), function (e) { global$1.each(vl, function (v, k) { if (dom.hasClass(e, k)) { if (typeof vl[k] === 'function') { vl[k](e); } } }); }); }; var hasClass = function (n, c) { return new RegExp('\\b' + c + '\\b', 'g').test(n.className); }; var insertTemplate = function (editor, ui, html) { var el; var n; var dom = editor.dom; var sel = editor.selection.getContent(); html = replaceTemplateValues(editor, html, Settings.getTemplateReplaceValues(editor)); el = dom.create('div', null, html); n = dom.select('.mceTmpl', el); if (n && n.length > 0) { el = dom.create('div', null); el.appendChild(n[0].cloneNode(true)); } global$1.each(dom.select('*', el), function (n) { if (hasClass(n, Settings.getCreationDateClasses(editor).replace(/\s+/g, '|'))) { n.innerHTML = DateTimeHelper.getDateTime(editor, Settings.getCdateFormat(editor)); } if (hasClass(n, Settings.getModificationDateClasses(editor).replace(/\s+/g, '|'))) { n.innerHTML = DateTimeHelper.getDateTime(editor, Settings.getMdateFormat(editor)); } if (hasClass(n, Settings.getSelectedContentClasses(editor).replace(/\s+/g, '|'))) { n.innerHTML = sel; } }); replaceVals(editor, el); editor.execCommand('mceInsertContent', false, el.innerHTML); editor.addVisual(); }; var Templates = { createTemplateList: createTemplateList, replaceTemplateValues: replaceTemplateValues, replaceVals: replaceVals, insertTemplate: insertTemplate }; var register = function (editor) { editor.addCommand('mceInsertTemplate', curry(Templates.insertTemplate, editor)); }; var Commands = { register: register }; var setup = function (editor) { editor.on('PreProcess', function (o) { var dom = editor.dom, dateFormat = Settings.getMdateFormat(editor); global$1.each(dom.select('div', o.node), function (e) { if (dom.hasClass(e, 'mceTmpl')) { global$1.each(dom.select('*', e), function (e) { if (dom.hasClass(e, editor.getParam('template_mdate_classes', 'mdate').replace(/\s+/g, '|'))) { e.innerHTML = DateTimeHelper.getDateTime(editor, dateFormat); } }); Templates.replaceVals(editor, e); } }); }); }; var FilterContent = { setup: setup }; var insertIframeHtml = function (editor, win, html) { if (html.indexOf('<html>') === -1) { var contentCssLinks_1 = ''; global$1.each(editor.contentCSS, function (url) { contentCssLinks_1 += '<link type="text/css" rel="stylesheet" href="' + editor.documentBaseURI.toAbsolute(url) + '">'; }); var bodyClass = editor.settings.body_class || ''; if (bodyClass.indexOf('=') !== -1) { bodyClass = editor.getParam('body_class', '', 'hash'); bodyClass = bodyClass[editor.id] || ''; } html = '<!DOCTYPE html>' + '<html>' + '<head>' + contentCssLinks_1 + '</head>' + '<body class="' + bodyClass + '">' + html + '</body>' + '</html>'; } html = Templates.replaceTemplateValues(editor, html, Settings.getPreviewReplaceValues(editor)); var doc = win.find('iframe')[0].getEl().contentWindow.document; doc.open(); doc.write(html); doc.close(); }; var open = function (editor, templateList) { var win; var values = []; var templateHtml; if (!templateList || templateList.length === 0) { var message = editor.translate('No templates defined.'); editor.notificationManager.open({ text: message, type: 'info' }); return; } global$1.each(templateList, function (template) { values.push({ selected: !values.length, text: template.title, value: { url: template.url, content: template.content, description: template.description } }); }); var onSelectTemplate = function (e) { var value = e.control.value(); if (value.url) { global$2.send({ url: value.url, success: function (html) { templateHtml = html; insertIframeHtml(editor, win, templateHtml); } }); } else { templateHtml = value.content; insertIframeHtml(editor, win, templateHtml); } win.find('#description')[0].text(e.control.value().description); }; win = editor.windowManager.open({ title: 'Insert template', layout: 'flex', direction: 'column', align: 'stretch', padding: 15, spacing: 10, items: [ { type: 'form', flex: 0, padding: 0, items: [{ type: 'container', label: 'Templates', items: { type: 'listbox', label: 'Templates', name: 'template', values: values, onselect: onSelectTemplate } }] }, { type: 'label', name: 'description', label: 'Description', text: '\xA0' }, { type: 'iframe', flex: 1, border: 1 } ], onsubmit: function () { Templates.insertTemplate(editor, false, templateHtml); }, minWidth: Settings.getDialogWidth(editor), minHeight: Settings.getDialogHeight(editor) }); win.find('listbox')[0].fire('select'); }; var Dialog = { open: open }; var showDialog = function (editor) { return function (templates) { Dialog.open(editor, templates); }; }; var register$1 = function (editor) { editor.addButton('template', { title: 'Insert template', onclick: Templates.createTemplateList(editor.settings, showDialog(editor)) }); editor.addMenuItem('template', { text: 'Template', onclick: Templates.createTemplateList(editor.settings, showDialog(editor)), icon: 'template', context: 'insert' }); }; var Buttons = { register: register$1 }; global.add('template', function (editor) { Buttons.register(editor); Commands.register(editor); FilterContent.setup(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var textcolor = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var getCurrentColor = function (editor, format) { var color; editor.dom.getParents(editor.selection.getStart(), function (elm) { var value; if (value = elm.style[format === 'forecolor' ? 'color' : 'background-color']) { color = color ? color : value; } }); return color; }; var mapColors = function (colorMap) { var i; var colors = []; for (i = 0; i < colorMap.length; i += 2) { colors.push({ text: colorMap[i + 1], color: '#' + colorMap[i] }); } return colors; }; var applyFormat = function (editor, format, value) { editor.undoManager.transact(function () { editor.focus(); editor.formatter.apply(format, { value: value }); editor.nodeChanged(); }); }; var removeFormat = function (editor, format) { editor.undoManager.transact(function () { editor.focus(); editor.formatter.remove(format, { value: null }, null, true); editor.nodeChanged(); }); }; var TextColor = { getCurrentColor: getCurrentColor, mapColors: mapColors, applyFormat: applyFormat, removeFormat: removeFormat }; var register = function (editor) { editor.addCommand('mceApplyTextcolor', function (format, value) { TextColor.applyFormat(editor, format, value); }); editor.addCommand('mceRemoveTextcolor', function (format) { TextColor.removeFormat(editor, format); }); }; var Commands = { register: register }; var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var defaultColorMap = [ '000000', 'Black', '993300', 'Burnt orange', '333300', 'Dark olive', '003300', 'Dark green', '003366', 'Dark azure', '000080', 'Navy Blue', '333399', 'Indigo', '333333', 'Very dark gray', '800000', 'Maroon', 'FF6600', 'Orange', '808000', 'Olive', '008000', 'Green', '008080', 'Teal', '0000FF', 'Blue', '666699', 'Grayish blue', '808080', 'Gray', 'FF0000', 'Red', 'FF9900', 'Amber', '99CC00', 'Yellow green', '339966', 'Sea green', '33CCCC', 'Turquoise', '3366FF', 'Royal blue', '800080', 'Purple', '999999', 'Medium gray', 'FF00FF', 'Magenta', 'FFCC00', 'Gold', 'FFFF00', 'Yellow', '00FF00', 'Lime', '00FFFF', 'Aqua', '00CCFF', 'Sky blue', '993366', 'Red violet', 'FFFFFF', 'White', 'FF99CC', 'Pink', 'FFCC99', 'Peach', 'FFFF99', 'Light yellow', 'CCFFCC', 'Pale green', 'CCFFFF', 'Pale cyan', '99CCFF', 'Light sky blue', 'CC99FF', 'Plum' ]; var getTextColorMap = function (editor) { return editor.getParam('textcolor_map', defaultColorMap); }; var getForeColorMap = function (editor) { return editor.getParam('forecolor_map', getTextColorMap(editor)); }; var getBackColorMap = function (editor) { return editor.getParam('backcolor_map', getTextColorMap(editor)); }; var getTextColorRows = function (editor) { return editor.getParam('textcolor_rows', 5); }; var getTextColorCols = function (editor) { return editor.getParam('textcolor_cols', 8); }; var getForeColorRows = function (editor) { return editor.getParam('forecolor_rows', getTextColorRows(editor)); }; var getBackColorRows = function (editor) { return editor.getParam('backcolor_rows', getTextColorRows(editor)); }; var getForeColorCols = function (editor) { return editor.getParam('forecolor_cols', getTextColorCols(editor)); }; var getBackColorCols = function (editor) { return editor.getParam('backcolor_cols', getTextColorCols(editor)); }; var getColorPickerCallback = function (editor) { return editor.getParam('color_picker_callback', null); }; var hasColorPicker = function (editor) { return typeof getColorPickerCallback(editor) === 'function'; }; var Settings = { getForeColorMap: getForeColorMap, getBackColorMap: getBackColorMap, getForeColorRows: getForeColorRows, getBackColorRows: getBackColorRows, getForeColorCols: getForeColorCols, getBackColorCols: getBackColorCols, getColorPickerCallback: getColorPickerCallback, hasColorPicker: hasColorPicker }; var global$3 = tinymce.util.Tools.resolve('tinymce.util.I18n'); var getHtml = function (cols, rows, colorMap, hasColorPicker) { var colors, color, html, last, x, y, i, count = 0; var id = global$1.DOM.uniqueId('mcearia'); var getColorCellHtml = function (color, title) { var isNoColor = color === 'transparent'; return '<td class="mce-grid-cell' + (isNoColor ? ' mce-colorbtn-trans' : '') + '">' + '<div id="' + id + '-' + count++ + '"' + ' data-mce-color="' + (color ? color : '') + '"' + ' role="option"' + ' tabIndex="-1"' + ' style="' + (color ? 'background-color: ' + color : '') + '"' + ' title="' + global$3.translate(title) + '">' + (isNoColor ? '×' : '') + '</div>' + '</td>'; }; colors = TextColor.mapColors(colorMap); colors.push({ text: global$3.translate('No color'), color: 'transparent' }); html = '<table class="mce-grid mce-grid-border mce-colorbutton-grid" role="list" cellspacing="0"><tbody>'; last = colors.length - 1; for (y = 0; y < rows; y++) { html += '<tr>'; for (x = 0; x < cols; x++) { i = y * cols + x; if (i > last) { html += '<td></td>'; } else { color = colors[i]; html += getColorCellHtml(color.color, color.text); } } html += '</tr>'; } if (hasColorPicker) { html += '<tr>' + '<td colspan="' + cols + '" class="mce-custom-color-btn">' + '<div id="' + id + '-c" class="mce-widget mce-btn mce-btn-small mce-btn-flat" ' + 'role="button" tabindex="-1" aria-labelledby="' + id + '-c" style="width: 100%">' + '<button type="button" role="presentation" tabindex="-1">' + global$3.translate('Custom...') + '</button>' + '</div>' + '</td>' + '</tr>'; html += '<tr>'; for (x = 0; x < cols; x++) { html += getColorCellHtml('', 'Custom color'); } html += '</tr>'; } html += '</tbody></table>'; return html; }; var ColorPickerHtml = { getHtml: getHtml }; var setDivColor = function setDivColor(div, value) { div.style.background = value; div.setAttribute('data-mce-color', value); }; var onButtonClick = function (editor) { return function (e) { var ctrl = e.control; if (ctrl._color) { editor.execCommand('mceApplyTextcolor', ctrl.settings.format, ctrl._color); } else { editor.execCommand('mceRemoveTextcolor', ctrl.settings.format); } }; }; var onPanelClick = function (editor, cols) { return function (e) { var buttonCtrl = this.parent(); var value; var currentColor = TextColor.getCurrentColor(editor, buttonCtrl.settings.format); var selectColor = function (value) { editor.execCommand('mceApplyTextcolor', buttonCtrl.settings.format, value); buttonCtrl.hidePanel(); buttonCtrl.color(value); }; var resetColor = function () { editor.execCommand('mceRemoveTextcolor', buttonCtrl.settings.format); buttonCtrl.hidePanel(); buttonCtrl.resetColor(); }; if (global$1.DOM.getParent(e.target, '.mce-custom-color-btn')) { buttonCtrl.hidePanel(); var colorPickerCallback = Settings.getColorPickerCallback(editor); colorPickerCallback.call(editor, function (value) { var tableElm = buttonCtrl.panel.getEl().getElementsByTagName('table')[0]; var customColorCells, div, i; customColorCells = global$2.map(tableElm.rows[tableElm.rows.length - 1].childNodes, function (elm) { return elm.firstChild; }); for (i = 0; i < customColorCells.length; i++) { div = customColorCells[i]; if (!div.getAttribute('data-mce-color')) { break; } } if (i === cols) { for (i = 0; i < cols - 1; i++) { setDivColor(customColorCells[i], customColorCells[i + 1].getAttribute('data-mce-color')); } } setDivColor(div, value); selectColor(value); }, currentColor); } value = e.target.getAttribute('data-mce-color'); if (value) { if (this.lastId) { global$1.DOM.get(this.lastId).setAttribute('aria-selected', 'false'); } e.target.setAttribute('aria-selected', true); this.lastId = e.target.id; if (value === 'transparent') { resetColor(); } else { selectColor(value); } } else if (value !== null) { buttonCtrl.hidePanel(); } }; }; var renderColorPicker = function (editor, foreColor) { return function () { var cols = foreColor ? Settings.getForeColorCols(editor) : Settings.getBackColorCols(editor); var rows = foreColor ? Settings.getForeColorRows(editor) : Settings.getBackColorRows(editor); var colorMap = foreColor ? Settings.getForeColorMap(editor) : Settings.getBackColorMap(editor); var hasColorPicker = Settings.hasColorPicker(editor); return ColorPickerHtml.getHtml(cols, rows, colorMap, hasColorPicker); }; }; var register$1 = function (editor) { editor.addButton('forecolor', { type: 'colorbutton', tooltip: 'Text color', format: 'forecolor', panel: { role: 'application', ariaRemember: true, html: renderColorPicker(editor, true), onclick: onPanelClick(editor, Settings.getForeColorCols(editor)) }, onclick: onButtonClick(editor) }); editor.addButton('backcolor', { type: 'colorbutton', tooltip: 'Background color', format: 'hilitecolor', panel: { role: 'application', ariaRemember: true, html: renderColorPicker(editor, false), onclick: onPanelClick(editor, Settings.getBackColorCols(editor)) }, onclick: onButtonClick(editor) }); }; var Buttons = { register: register$1 }; global.add('textcolor', function (editor) { Commands.register(editor); Buttons.register(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var textpattern = (function (domGlobals) { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var constant = function (value) { return function () { return value; }; }; var never = constant(false); var always = constant(true); var never$1 = never; var always$1 = always; var none = function () { return NONE; }; var NONE = function () { var eq = function (o) { return o.isNone(); }; var call = function (thunk) { return thunk(); }; var id = function (n) { return n; }; var noop = function () { }; var nul = function () { return null; }; var undef = function () { return undefined; }; var me = { fold: function (n, s) { return n(); }, is: never$1, isSome: never$1, isNone: always$1, getOr: id, getOrThunk: call, getOrDie: function (msg) { throw new Error(msg || 'error: getOrDie called on none.'); }, getOrNull: nul, getOrUndefined: undef, or: id, orThunk: call, map: none, ap: none, each: noop, bind: none, flatten: none, exists: never$1, forall: always$1, filter: none, equals: eq, equals_: eq, toArray: function () { return []; }, toString: constant('none()') }; if (Object.freeze) Object.freeze(me); return me; }(); var some = function (a) { var constant_a = function () { return a; }; var self = function () { return me; }; var map = function (f) { return some(f(a)); }; var bind = function (f) { return f(a); }; var me = { fold: function (n, s) { return s(a); }, is: function (v) { return a === v; }, isSome: always$1, isNone: never$1, getOr: constant_a, getOrThunk: constant_a, getOrDie: constant_a, getOrNull: constant_a, getOrUndefined: constant_a, or: self, orThunk: self, map: map, ap: function (optfab) { return optfab.fold(none, function (fab) { return some(fab(a)); }); }, each: function (f) { f(a); }, bind: bind, flatten: constant_a, exists: bind, forall: bind, filter: function (f) { return f(a) ? me : NONE; }, equals: function (o) { return o.is(a); }, equals_: function (o, elementEq) { return o.fold(never$1, function (b) { return elementEq(a, b); }); }, toArray: function () { return [a]; }, toString: function () { return 'some(' + a + ')'; } }; return me; }; var from = function (value) { return value === null || value === undefined ? NONE : some(value); }; var Option = { some: some, none: none, from: from }; var typeOf = function (x) { if (x === null) return 'null'; var t = typeof x; if (t === 'object' && Array.prototype.isPrototypeOf(x)) return 'array'; if (t === 'object' && String.prototype.isPrototypeOf(x)) return 'string'; return t; }; var isType = function (type) { return function (value) { return typeOf(value) === type; }; }; var isFunction = isType('function'); var filter = function (xs, pred) { var r = []; for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { r.push(x); } } return r; }; var slice = Array.prototype.slice; var sort = function (xs, comparator) { var copy = slice.call(xs, 0); copy.sort(comparator); return copy; }; var from$1 = isFunction(Array.from) ? Array.from : function (x) { return slice.call(x); }; var hasOwnProperty = Object.hasOwnProperty; var get = function (obj, key) { return has(obj, key) ? Option.from(obj[key]) : Option.none(); }; var has = function (obj, key) { return hasOwnProperty.call(obj, key); }; var isInlinePattern = function (pattern) { return has(pattern, 'start') && has(pattern, 'end'); }; var isBlockPattern = function (pattern) { return !has(pattern, 'end') && !has(pattern, 'replacement'); }; var isReplacementPattern = function (pattern) { return has(pattern, 'replacement'); }; var sortPatterns = function (patterns) { return sort(patterns, function (a, b) { if (a.start.length === b.start.length) { return 0; } return a.start.length > b.start.length ? -1 : 1; }); }; var createPatternSet = function (patterns) { return { inlinePatterns: sortPatterns(filter(patterns, isInlinePattern)), blockPatterns: sortPatterns(filter(patterns, isBlockPattern)), replacementPatterns: filter(patterns, isReplacementPattern) }; }; var get$1 = function (patternsState) { var setPatterns = function (newPatterns) { patternsState.set(createPatternSet(newPatterns)); }; var getPatterns = function () { return patternsState.get().inlinePatterns.concat(patternsState.get().blockPatterns, patternsState.get().replacementPatterns); }; return { setPatterns: setPatterns, getPatterns: getPatterns }; }; var Api = { get: get$1 }; var defaultPatterns = [ { start: '*', end: '*', format: 'italic' }, { start: '**', end: '**', format: 'bold' }, { start: '***', end: '***', format: [ 'bold', 'italic' ] }, { start: '#', format: 'h1' }, { start: '##', format: 'h2' }, { start: '###', format: 'h3' }, { start: '####', format: 'h4' }, { start: '#####', format: 'h5' }, { start: '######', format: 'h6' }, { start: '1. ', cmd: 'InsertOrderedList' }, { start: '* ', cmd: 'InsertUnorderedList' }, { start: '- ', cmd: 'InsertUnorderedList' } ]; var getPatternSet = function (editorSettings) { var patterns = get(editorSettings, 'textpattern_patterns').getOr(defaultPatterns); return createPatternSet(patterns); }; var global$1 = tinymce.util.Tools.resolve('tinymce.util.Delay'); var global$2 = tinymce.util.Tools.resolve('tinymce.util.VK'); var global$3 = tinymce.util.Tools.resolve('tinymce.dom.TreeWalker'); var global$4 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var findPattern = function (patterns, text) { for (var i = 0; i < patterns.length; i++) { var pattern = patterns[i]; if (text.indexOf(pattern.start) !== 0) { continue; } if (pattern.end && text.lastIndexOf(pattern.end) !== text.length - pattern.end.length) { continue; } return pattern; } }; var isMatchingPattern = function (pattern, text, offset, delta) { var textEnd = text.substr(offset - pattern.end.length - delta, pattern.end.length); return textEnd === pattern.end; }; var hasContent = function (offset, delta, pattern) { return offset - delta - pattern.end.length - pattern.start.length > 0; }; var findEndPattern = function (patterns, text, offset, delta) { var pattern, i; for (i = 0; i < patterns.length; i++) { pattern = patterns[i]; if (pattern.end !== undefined && isMatchingPattern(pattern, text, offset, delta) && hasContent(offset, delta, pattern)) { return pattern; } } }; var findInlinePattern = function (patterns, rng, space) { if (rng.collapsed === false) { return; } var container = rng.startContainer; var text = container.data; var delta = space === true ? 1 : 0; if (container.nodeType !== 3) { return; } var endPattern = findEndPattern(patterns, text, rng.startOffset, delta); if (endPattern === undefined) { return; } var endOffset = text.lastIndexOf(endPattern.end, rng.startOffset - delta); var startOffset = text.lastIndexOf(endPattern.start, endOffset - endPattern.end.length); endOffset = text.indexOf(endPattern.end, startOffset + endPattern.start.length); if (startOffset === -1) { return; } var patternRng = domGlobals.document.createRange(); patternRng.setStart(container, startOffset); patternRng.setEnd(container, endOffset + endPattern.end.length); var startPattern = findPattern(patterns, patternRng.toString()); if (endPattern === undefined || startPattern !== endPattern || container.data.length <= endPattern.start.length + endPattern.end.length) { return; } return { pattern: endPattern, startOffset: startOffset, endOffset: endOffset }; }; var findReplacementPattern = function (patterns, startSearch, text) { for (var i = 0; i < patterns.length; i++) { var index = text.lastIndexOf(patterns[i].start, startSearch); if (index !== -1) { return Option.some({ pattern: patterns[i], startOffset: index }); } } return Option.none(); }; var isText = function (node) { return node && node.nodeType === 3; }; var setSelection = function (editor, textNode, offset) { var newRng = editor.dom.createRng(); newRng.setStart(textNode, offset); newRng.setEnd(textNode, offset); editor.selection.setRng(newRng); }; var splitContainer = function (container, pattern, endOffset, startOffset) { container = startOffset > 0 ? container.splitText(startOffset) : container; container.splitText(endOffset - startOffset + pattern.end.length); container.deleteData(0, pattern.start.length); container.deleteData(container.data.length - pattern.end.length, pattern.end.length); return container; }; var splitAndApply = function (editor, container, found, inline) { var formatArray = global$4.isArray(found.pattern.format) ? found.pattern.format : [found.pattern.format]; var validFormats = global$4.grep(formatArray, function (formatName) { var format = editor.formatter.get(formatName); return format && format[0].inline; }); if (validFormats.length !== 0) { editor.undoManager.transact(function () { container = splitContainer(container, found.pattern, found.endOffset, found.startOffset); if (inline) { editor.selection.setCursorLocation(container.nextSibling, 1); } formatArray.forEach(function (format) { editor.formatter.apply(format, {}, container); }); }); return container; } }; var applyInlinePattern = function (editor, patterns, inline) { var rng = editor.selection.getRng(); return Option.from(findInlinePattern(patterns, rng, inline)).map(function (foundPattern) { return splitAndApply(editor, rng.startContainer, foundPattern, inline); }); }; var applyInlinePatternSpace = function (editor, patterns) { applyInlinePattern(editor, patterns, true).each(function (wrappedTextNode) { var lastChar = wrappedTextNode.data.slice(-1); if (/[\u00a0 ]/.test(lastChar)) { wrappedTextNode.deleteData(wrappedTextNode.data.length - 1, 1); var lastCharNode = editor.dom.doc.createTextNode(lastChar); editor.dom.insertAfter(lastCharNode, wrappedTextNode.parentNode); setSelection(editor, lastCharNode, 1); } }); }; var applyInlinePatternEnter = function (editor, patterns) { applyInlinePattern(editor, patterns, false).each(function (wrappedTextNode) { setSelection(editor, wrappedTextNode, wrappedTextNode.data.length); }); }; var applyBlockPattern = function (editor, patterns) { var selection, dom, container, firstTextNode, node, format, textBlockElm, pattern, walker, rng, offset; selection = editor.selection; dom = editor.dom; if (!selection.isCollapsed()) { return; } textBlockElm = dom.getParent(selection.getStart(), 'p'); if (textBlockElm) { walker = new global$3(textBlockElm, textBlockElm); while (node = walker.next()) { if (isText(node)) { firstTextNode = node; break; } } if (firstTextNode) { pattern = findPattern(patterns, firstTextNode.data); if (!pattern) { return; } rng = selection.getRng(true); container = rng.startContainer; offset = rng.startOffset; if (firstTextNode === container) { offset = Math.max(0, offset - pattern.start.length); } if (global$4.trim(firstTextNode.data).length === pattern.start.length) { return; } if (pattern.format) { format = editor.formatter.get(pattern.format); if (format && format[0].block) { firstTextNode.deleteData(0, pattern.start.length); editor.formatter.apply(pattern.format, {}, firstTextNode); rng.setStart(container, offset); rng.collapse(true); selection.setRng(rng); } } if (pattern.cmd) { editor.undoManager.transact(function () { firstTextNode.deleteData(0, pattern.start.length); editor.execCommand(pattern.cmd); }); } } } }; var selectionInsertText = function (editor, string) { var rng = editor.selection.getRng(); var container = rng.startContainer; if (isText(container)) { var offset = rng.startOffset; container.insertData(offset, string); setSelection(editor, container, offset + string.length); } else { var newNode = editor.dom.doc.createTextNode(string); rng.insertNode(newNode); setSelection(editor, newNode, newNode.length); } }; var applyReplacement = function (editor, target, match) { target.deleteData(match.startOffset, match.pattern.start.length); editor.insertContent(match.pattern.replacement); Option.from(target.nextSibling).filter(isText).each(function (nextSibling) { nextSibling.insertData(0, target.data); editor.dom.remove(target); }); }; var extractChar = function (node, match) { var offset = match.startOffset + match.pattern.start.length; var char = node.data.slice(offset, offset + 1); node.deleteData(offset, 1); return char; }; var applyReplacementPattern = function (editor, patterns, inline) { var rng = editor.selection.getRng(); var container = rng.startContainer; if (rng.collapsed && isText(container)) { findReplacementPattern(patterns, rng.startOffset, container.data).each(function (match) { var char = inline ? Option.some(extractChar(container, match)) : Option.none(); applyReplacement(editor, container, match); char.each(function (ch) { return selectionInsertText(editor, ch); }); }); } }; var applyReplacementPatternSpace = function (editor, patterns) { applyReplacementPattern(editor, patterns, true); }; var applyReplacementPatternEnter = function (editor, patterns) { applyReplacementPattern(editor, patterns, false); }; var handleEnter = function (editor, patternSet) { applyReplacementPatternEnter(editor, patternSet.replacementPatterns); applyInlinePatternEnter(editor, patternSet.inlinePatterns); applyBlockPattern(editor, patternSet.blockPatterns); }; var handleInlineKey = function (editor, patternSet) { applyReplacementPatternSpace(editor, patternSet.replacementPatterns); applyInlinePatternSpace(editor, patternSet.inlinePatterns); }; var checkKeyEvent = function (codes, event, predicate) { for (var i = 0; i < codes.length; i++) { if (predicate(codes[i], event)) { return true; } } }; var checkKeyCode = function (codes, event) { return checkKeyEvent(codes, event, function (code, event) { return code === event.keyCode && global$2.modifierPressed(event) === false; }); }; var checkCharCode = function (chars, event) { return checkKeyEvent(chars, event, function (chr, event) { return chr.charCodeAt(0) === event.charCode; }); }; var KeyHandler = { handleEnter: handleEnter, handleInlineKey: handleInlineKey, checkCharCode: checkCharCode, checkKeyCode: checkKeyCode }; var setup = function (editor, patternsState) { var charCodes = [ ',', '.', ';', ':', '!', '?' ]; var keyCodes = [32]; editor.on('keydown', function (e) { if (e.keyCode === 13 && !global$2.modifierPressed(e)) { KeyHandler.handleEnter(editor, patternsState.get()); } }, true); editor.on('keyup', function (e) { if (KeyHandler.checkKeyCode(keyCodes, e)) { KeyHandler.handleInlineKey(editor, patternsState.get()); } }); editor.on('keypress', function (e) { if (KeyHandler.checkCharCode(charCodes, e)) { global$1.setEditorTimeout(editor, function () { KeyHandler.handleInlineKey(editor, patternsState.get()); }); } }); }; var Keyboard = { setup: setup }; global.add('textpattern', function (editor) { var patternsState = Cell(getPatternSet(editor.settings)); Keyboard.setup(editor, patternsState); return Api.get(patternsState); }); function Plugin () { } return Plugin; }(window)); })(); (function () { var toc = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var global$2 = tinymce.util.Tools.resolve('tinymce.util.I18n'); var global$3 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var getTocClass = function (editor) { return editor.getParam('toc_class', 'mce-toc'); }; var getTocHeader = function (editor) { var tagName = editor.getParam('toc_header', 'h2'); return /^h[1-6]$/.test(tagName) ? tagName : 'h2'; }; var getTocDepth = function (editor) { var depth = parseInt(editor.getParam('toc_depth', '3'), 10); return depth >= 1 && depth <= 9 ? depth : 3; }; var Settings = { getTocClass: getTocClass, getTocHeader: getTocHeader, getTocDepth: getTocDepth }; var create = function (prefix) { var counter = 0; return function () { var guid = new Date().getTime().toString(32); return prefix + guid + (counter++).toString(32); }; }; var Guid = { create: create }; var tocId = Guid.create('mcetoc_'); var generateSelector = function generateSelector(depth) { var i; var selector = []; for (i = 1; i <= depth; i++) { selector.push('h' + i); } return selector.join(','); }; var hasHeaders = function (editor) { return readHeaders(editor).length > 0; }; var readHeaders = function (editor) { var tocClass = Settings.getTocClass(editor); var headerTag = Settings.getTocHeader(editor); var selector = generateSelector(Settings.getTocDepth(editor)); var headers = editor.$(selector); if (headers.length && /^h[1-9]$/i.test(headerTag)) { headers = headers.filter(function (i, el) { return !editor.dom.hasClass(el.parentNode, tocClass); }); } return global$3.map(headers, function (h) { return { id: h.id ? h.id : tocId(), level: parseInt(h.nodeName.replace(/^H/i, ''), 10), title: editor.$.text(h), element: h }; }); }; var getMinLevel = function (headers) { var i, minLevel = 9; for (i = 0; i < headers.length; i++) { if (headers[i].level < minLevel) { minLevel = headers[i].level; } if (minLevel === 1) { return minLevel; } } return minLevel; }; var generateTitle = function (tag, title) { var openTag = '<' + tag + ' contenteditable="true">'; var closeTag = '</' + tag + '>'; return openTag + global$1.DOM.encode(title) + closeTag; }; var generateTocHtml = function (editor) { var html = generateTocContentHtml(editor); return '<div class="' + editor.dom.encode(Settings.getTocClass(editor)) + '" contenteditable="false">' + html + '</div>'; }; var generateTocContentHtml = function (editor) { var html = ''; var headers = readHeaders(editor); var prevLevel = getMinLevel(headers) - 1; var i, ii, h, nextLevel; if (!headers.length) { return ''; } html += generateTitle(Settings.getTocHeader(editor), global$2.translate('Table of Contents')); for (i = 0; i < headers.length; i++) { h = headers[i]; h.element.id = h.id; nextLevel = headers[i + 1] && headers[i + 1].level; if (prevLevel === h.level) { html += '<li>'; } else { for (ii = prevLevel; ii < h.level; ii++) { html += '<ul><li>'; } } html += '<a href="#' + h.id + '">' + h.title + '</a>'; if (nextLevel === h.level || !nextLevel) { html += '</li>'; if (!nextLevel) { html += '</ul>'; } } else { for (ii = h.level; ii > nextLevel; ii--) { html += '</li></ul><li>'; } } prevLevel = h.level; } return html; }; var isEmptyOrOffscren = function (editor, nodes) { return !nodes.length || editor.dom.getParents(nodes[0], '.mce-offscreen-selection').length > 0; }; var insertToc = function (editor) { var tocClass = Settings.getTocClass(editor); var $tocElm = editor.$('.' + tocClass); if (isEmptyOrOffscren(editor, $tocElm)) { editor.insertContent(generateTocHtml(editor)); } else { updateToc(editor); } }; var updateToc = function (editor) { var tocClass = Settings.getTocClass(editor); var $tocElm = editor.$('.' + tocClass); if ($tocElm.length) { editor.undoManager.transact(function () { $tocElm.html(generateTocContentHtml(editor)); }); } }; var Toc = { hasHeaders: hasHeaders, insertToc: insertToc, updateToc: updateToc }; var register = function (editor) { editor.addCommand('mceInsertToc', function () { Toc.insertToc(editor); }); editor.addCommand('mceUpdateToc', function () { Toc.updateToc(editor); }); }; var Commands = { register: register }; var setup = function (editor) { var $ = editor.$, tocClass = Settings.getTocClass(editor); editor.on('PreProcess', function (e) { var $tocElm = $('.' + tocClass, e.node); if ($tocElm.length) { $tocElm.removeAttr('contentEditable'); $tocElm.find('[contenteditable]').removeAttr('contentEditable'); } }); editor.on('SetContent', function () { var $tocElm = $('.' + tocClass); if ($tocElm.length) { $tocElm.attr('contentEditable', false); $tocElm.children(':first-child').attr('contentEditable', true); } }); }; var FilterContent = { setup: setup }; var toggleState = function (editor) { return function (e) { var ctrl = e.control; editor.on('LoadContent SetContent change', function () { ctrl.disabled(editor.readonly || !Toc.hasHeaders(editor)); }); }; }; var isToc = function (editor) { return function (elm) { return elm && editor.dom.is(elm, '.' + Settings.getTocClass(editor)) && editor.getBody().contains(elm); }; }; var register$1 = function (editor) { editor.addButton('toc', { tooltip: 'Table of Contents', cmd: 'mceInsertToc', icon: 'toc', onPostRender: toggleState(editor) }); editor.addButton('tocupdate', { tooltip: 'Update', cmd: 'mceUpdateToc', icon: 'reload' }); editor.addMenuItem('toc', { text: 'Table of Contents', context: 'insert', cmd: 'mceInsertToc', onPostRender: toggleState(editor) }); editor.addContextToolbar(isToc(editor), 'tocupdate'); }; var Buttons = { register: register$1 }; global.add('toc', function (editor) { Commands.register(editor); Buttons.register(editor); FilterContent.setup(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var visualblocks = (function () { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var fireVisualBlocks = function (editor, state) { editor.fire('VisualBlocks', { state: state }); }; var Events = { fireVisualBlocks: fireVisualBlocks }; var isEnabledByDefault = function (editor) { return editor.getParam('visualblocks_default_state', false); }; var getContentCss = function (editor) { return editor.settings.visualblocks_content_css; }; var Settings = { isEnabledByDefault: isEnabledByDefault, getContentCss: getContentCss }; var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var cssId = global$1.DOM.uniqueId(); var load = function (doc, url) { var linkElements = global$2.toArray(doc.getElementsByTagName('link')); var matchingLinkElms = global$2.grep(linkElements, function (head) { return head.id === cssId; }); if (matchingLinkElms.length === 0) { var linkElm = global$1.DOM.create('link', { id: cssId, rel: 'stylesheet', href: url }); doc.getElementsByTagName('head')[0].appendChild(linkElm); } }; var LoadCss = { load: load }; var toggleVisualBlocks = function (editor, pluginUrl, enabledState) { var dom = editor.dom; var contentCss = Settings.getContentCss(editor); LoadCss.load(editor.getDoc(), contentCss ? contentCss : pluginUrl + '/css/visualblocks.css'); dom.toggleClass(editor.getBody(), 'mce-visualblocks'); enabledState.set(!enabledState.get()); Events.fireVisualBlocks(editor, enabledState.get()); }; var VisualBlocks = { toggleVisualBlocks: toggleVisualBlocks }; var register = function (editor, pluginUrl, enabledState) { editor.addCommand('mceVisualBlocks', function () { VisualBlocks.toggleVisualBlocks(editor, pluginUrl, enabledState); }); }; var Commands = { register: register }; var setup = function (editor, pluginUrl, enabledState) { editor.on('PreviewFormats AfterPreviewFormats', function (e) { if (enabledState.get()) { editor.dom.toggleClass(editor.getBody(), 'mce-visualblocks', e.type === 'afterpreviewformats'); } }); editor.on('init', function () { if (Settings.isEnabledByDefault(editor)) { VisualBlocks.toggleVisualBlocks(editor, pluginUrl, enabledState); } }); editor.on('remove', function () { editor.dom.removeClass(editor.getBody(), 'mce-visualblocks'); }); }; var Bindings = { setup: setup }; var toggleActiveState = function (editor, enabledState) { return function (e) { var ctrl = e.control; ctrl.active(enabledState.get()); editor.on('VisualBlocks', function (e) { ctrl.active(e.state); }); }; }; var register$1 = function (editor, enabledState) { editor.addButton('visualblocks', { active: false, title: 'Show blocks', cmd: 'mceVisualBlocks', onPostRender: toggleActiveState(editor, enabledState) }); editor.addMenuItem('visualblocks', { text: 'Show blocks', cmd: 'mceVisualBlocks', onPostRender: toggleActiveState(editor, enabledState), selectable: true, context: 'view', prependToContext: true }); }; var Buttons = { register: register$1 }; global.add('visualblocks', function (editor, pluginUrl) { var enabledState = Cell(false); Commands.register(editor, pluginUrl, enabledState); Buttons.register(editor, enabledState); Bindings.setup(editor, pluginUrl, enabledState); }); function Plugin () { } return Plugin; }()); })(); (function () { var visualchars = (function (domGlobals) { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var get = function (toggleState) { var isEnabled = function () { return toggleState.get(); }; return { isEnabled: isEnabled }; }; var Api = { get: get }; var fireVisualChars = function (editor, state) { return editor.fire('VisualChars', { state: state }); }; var Events = { fireVisualChars: fireVisualChars }; var charMap = { '\xA0': 'nbsp', '\xAD': 'shy' }; var charMapToRegExp = function (charMap, global) { var key, regExp = ''; for (key in charMap) { regExp += key; } return new RegExp('[' + regExp + ']', global ? 'g' : ''); }; var charMapToSelector = function (charMap) { var key, selector = ''; for (key in charMap) { if (selector) { selector += ','; } selector += 'span.mce-' + charMap[key]; } return selector; }; var Data = { charMap: charMap, regExp: charMapToRegExp(charMap), regExpGlobal: charMapToRegExp(charMap, true), selector: charMapToSelector(charMap), charMapToRegExp: charMapToRegExp, charMapToSelector: charMapToSelector }; var constant = function (value) { return function () { return value; }; }; var never = constant(false); var always = constant(true); var never$1 = never; var always$1 = always; var none = function () { return NONE; }; var NONE = function () { var eq = function (o) { return o.isNone(); }; var call = function (thunk) { return thunk(); }; var id = function (n) { return n; }; var noop = function () { }; var nul = function () { return null; }; var undef = function () { return undefined; }; var me = { fold: function (n, s) { return n(); }, is: never$1, isSome: never$1, isNone: always$1, getOr: id, getOrThunk: call, getOrDie: function (msg) { throw new Error(msg || 'error: getOrDie called on none.'); }, getOrNull: nul, getOrUndefined: undef, or: id, orThunk: call, map: none, ap: none, each: noop, bind: none, flatten: none, exists: never$1, forall: always$1, filter: none, equals: eq, equals_: eq, toArray: function () { return []; }, toString: constant('none()') }; if (Object.freeze) Object.freeze(me); return me; }(); var some = function (a) { var constant_a = function () { return a; }; var self = function () { return me; }; var map = function (f) { return some(f(a)); }; var bind = function (f) { return f(a); }; var me = { fold: function (n, s) { return s(a); }, is: function (v) { return a === v; }, isSome: always$1, isNone: never$1, getOr: constant_a, getOrThunk: constant_a, getOrDie: constant_a, getOrNull: constant_a, getOrUndefined: constant_a, or: self, orThunk: self, map: map, ap: function (optfab) { return optfab.fold(none, function (fab) { return some(fab(a)); }); }, each: function (f) { f(a); }, bind: bind, flatten: constant_a, exists: bind, forall: bind, filter: function (f) { return f(a) ? me : NONE; }, equals: function (o) { return o.is(a); }, equals_: function (o, elementEq) { return o.fold(never$1, function (b) { return elementEq(a, b); }); }, toArray: function () { return [a]; }, toString: function () { return 'some(' + a + ')'; } }; return me; }; var from = function (value) { return value === null || value === undefined ? NONE : some(value); }; var Option = { some: some, none: none, from: from }; var typeOf = function (x) { if (x === null) return 'null'; var t = typeof x; if (t === 'object' && Array.prototype.isPrototypeOf(x)) return 'array'; if (t === 'object' && String.prototype.isPrototypeOf(x)) return 'string'; return t; }; var isType = function (type) { return function (value) { return typeOf(value) === type; }; }; var isFunction = isType('function'); var map = function (xs, f) { var len = xs.length; var r = new Array(len); for (var i = 0; i < len; i++) { var x = xs[i]; r[i] = f(x, i, xs); } return r; }; var each = function (xs, f) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; f(x, i, xs); } }; var slice = Array.prototype.slice; var from$1 = isFunction(Array.from) ? Array.from : function (x) { return slice.call(x); }; var fromHtml = function (html, scope) { var doc = scope || domGlobals.document; var div = doc.createElement('div'); div.innerHTML = html; if (!div.hasChildNodes() || div.childNodes.length > 1) { domGlobals.console.error('HTML does not have a single root node', html); throw new Error('HTML must have a single root node'); } return fromDom(div.childNodes[0]); }; var fromTag = function (tag, scope) { var doc = scope || domGlobals.document; var node = doc.createElement(tag); return fromDom(node); }; var fromText = function (text, scope) { var doc = scope || domGlobals.document; var node = doc.createTextNode(text); return fromDom(node); }; var fromDom = function (node) { if (node === null || node === undefined) { throw new Error('Node cannot be null or undefined'); } return { dom: constant(node) }; }; var fromPoint = function (docElm, x, y) { var doc = docElm.dom(); return Option.from(doc.elementFromPoint(x, y)).map(fromDom); }; var Element = { fromHtml: fromHtml, fromTag: fromTag, fromText: fromText, fromDom: fromDom, fromPoint: fromPoint }; var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE; var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE; var COMMENT = domGlobals.Node.COMMENT_NODE; var DOCUMENT = domGlobals.Node.DOCUMENT_NODE; var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE; var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE; var ELEMENT = domGlobals.Node.ELEMENT_NODE; var TEXT = domGlobals.Node.TEXT_NODE; var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE; var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE; var ENTITY = domGlobals.Node.ENTITY_NODE; var NOTATION = domGlobals.Node.NOTATION_NODE; var type = function (element) { return element.dom().nodeType; }; var value = function (element) { return element.dom().nodeValue; }; var isType$1 = function (t) { return function (element) { return type(element) === t; }; }; var isText = isType$1(TEXT); var wrapCharWithSpan = function (value) { return '<span data-mce-bogus="1" class="mce-' + Data.charMap[value] + '">' + value + '</span>'; }; var Html = { wrapCharWithSpan: wrapCharWithSpan }; var isMatch = function (n) { return isText(n) && value(n) !== undefined && Data.regExp.test(value(n)); }; var filterDescendants = function (scope, predicate) { var result = []; var dom = scope.dom(); var children = map(dom.childNodes, Element.fromDom); each(children, function (x) { if (predicate(x)) { result = result.concat([x]); } result = result.concat(filterDescendants(x, predicate)); }); return result; }; var findParentElm = function (elm, rootElm) { while (elm.parentNode) { if (elm.parentNode === rootElm) { return elm; } elm = elm.parentNode; } }; var replaceWithSpans = function (html) { return html.replace(Data.regExpGlobal, Html.wrapCharWithSpan); }; var Nodes = { isMatch: isMatch, filterDescendants: filterDescendants, findParentElm: findParentElm, replaceWithSpans: replaceWithSpans }; var show = function (editor, rootElm) { var node, div; var nodeList = Nodes.filterDescendants(Element.fromDom(rootElm), Nodes.isMatch); each(nodeList, function (n) { var withSpans = Nodes.replaceWithSpans(value(n)); div = editor.dom.create('div', null, withSpans); while (node = div.lastChild) { editor.dom.insertAfter(node, n.dom()); } editor.dom.remove(n.dom()); }); }; var hide = function (editor, body) { var nodeList = editor.dom.select(Data.selector, body); each(nodeList, function (node) { editor.dom.remove(node, 1); }); }; var toggle = function (editor) { var body = editor.getBody(); var bookmark = editor.selection.getBookmark(); var parentNode = Nodes.findParentElm(editor.selection.getNode(), body); parentNode = parentNode !== undefined ? parentNode : body; hide(editor, parentNode); show(editor, parentNode); editor.selection.moveToBookmark(bookmark); }; var VisualChars = { show: show, hide: hide, toggle: toggle }; var toggleVisualChars = function (editor, toggleState) { var body = editor.getBody(); var selection = editor.selection; var bookmark; toggleState.set(!toggleState.get()); Events.fireVisualChars(editor, toggleState.get()); bookmark = selection.getBookmark(); if (toggleState.get() === true) { VisualChars.show(editor, body); } else { VisualChars.hide(editor, body); } selection.moveToBookmark(bookmark); }; var Actions = { toggleVisualChars: toggleVisualChars }; var register = function (editor, toggleState) { editor.addCommand('mceVisualChars', function () { Actions.toggleVisualChars(editor, toggleState); }); }; var Commands = { register: register }; var global$1 = tinymce.util.Tools.resolve('tinymce.util.Delay'); var setup = function (editor, toggleState) { var debouncedToggle = global$1.debounce(function () { VisualChars.toggle(editor); }, 300); if (editor.settings.forced_root_block !== false) { editor.on('keydown', function (e) { if (toggleState.get() === true) { e.keyCode === 13 ? VisualChars.toggle(editor) : debouncedToggle(); } }); } }; var Keyboard = { setup: setup }; var isEnabledByDefault = function (editor) { return editor.getParam('visualchars_default_state', false); }; var Settings = { isEnabledByDefault: isEnabledByDefault }; var setup$1 = function (editor, toggleState) { editor.on('init', function () { var valueForToggling = !Settings.isEnabledByDefault(editor); toggleState.set(valueForToggling); Actions.toggleVisualChars(editor, toggleState); }); }; var Bindings = { setup: setup$1 }; var toggleActiveState = function (editor) { return function (e) { var ctrl = e.control; editor.on('VisualChars', function (e) { ctrl.active(e.state); }); }; }; var register$1 = function (editor) { editor.addButton('visualchars', { active: false, title: 'Show invisible characters', cmd: 'mceVisualChars', onPostRender: toggleActiveState(editor) }); editor.addMenuItem('visualchars', { text: 'Show invisible characters', cmd: 'mceVisualChars', onPostRender: toggleActiveState(editor), selectable: true, context: 'view', prependToContext: true }); }; global.add('visualchars', function (editor) { var toggleState = Cell(false); Commands.register(editor, toggleState); register$1(editor); Keyboard.setup(editor, toggleState); Bindings.setup(editor, toggleState); return Api.get(toggleState); }); function Plugin () { } return Plugin; }(window)); })(); (function () { var wordcount = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.dom.TreeWalker'); var global$2 = tinymce.util.Tools.resolve('tinymce.Env'); var regExps = { aletter: '[A-Za-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05F3\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u10a0-\u10c5\u10d0-\u10fa\u10fc\u1100-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1a00-\u1a16\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bc0-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u24B6-\u24E9\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2d00-\u2d25\u2d30-\u2d65\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005\u303b\u303c\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790\ua791\ua7a0-\ua7a9\ua7fa-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uffa0-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]', midnumlet: '[-\'\\.\u2018\u2019\u2024\uFE52\uFF07\uFF0E]', midletter: '[:\xB7\xB7\u05F4\u2027\uFE13\uFE55\uFF1A]', midnum: '[\xB1+*/,;;\u0589\u060C\u060D\u066C\u07F8\u2044\uFE10\uFE14\uFE50\uFE54\uFF0C\uFF1B]', numeric: '[0-9\u0660-\u0669\u066B\u06f0-\u06f9\u07c0-\u07c9\u0966-\u096f\u09e6-\u09ef\u0a66-\u0a6f\u0ae6-\u0aef\u0b66-\u0b6f\u0be6-\u0bef\u0c66-\u0c6f\u0ce6-\u0cef\u0d66-\u0d6f\u0e50-\u0e59\u0ed0-\u0ed9\u0f20-\u0f29\u1040-\u1049\u1090-\u1099\u17e0-\u17e9\u1810-\u1819\u1946-\u194f\u19d0-\u19d9\u1a80-\u1a89\u1a90-\u1a99\u1b50-\u1b59\u1bb0-\u1bb9\u1c40-\u1c49\u1c50-\u1c59\ua620-\ua629\ua8d0-\ua8d9\ua900-\ua909\ua9d0-\ua9d9\uaa50-\uaa59\uabf0-\uabf9]', cr: '\\r', lf: '\\n', newline: '[\x0B\f\x85\u2028\u2029]', extend: '[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065f\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0c01-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d02\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f\u109a-\u109d\u135d-\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b6-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u192b\u1930-\u193b\u19b0-\u19c0\u19c8\u19c9\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f\u1b00-\u1b04\u1b34-\u1b44\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1baa\u1be6-\u1bf3\u1c24-\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2\u1dc0-\u1de6\u1dfc-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\uA672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa7b\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe3-\uabea\uabec\uabed\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]', format: '[\xAD\u0600-\u0603\u06DD\u070F\u17b4\u17b5\u200E\u200F\u202A-\u202E\u2060-\u2064\u206A-\u206F\uFEFF\uFFF9-\uFFFB]', katakana: '[\u3031-\u3035\u309B\u309C\u30A0-\u30fa\u30fc-\u30ff\u31f0-\u31ff\u32D0-\u32FE\u3300-\u3357\uff66-\uff9d]', extendnumlet: '[=_\u203f\u2040\u2054\ufe33\ufe34\ufe4d-\ufe4f\uff3f\u2200-\u22FF<>]', punctuation: '[!-#%-*,-\\/:;?@\\[-\\]_{}\xA1\xAB\xB7\xBB\xBF;\xB7\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1361-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u3008\u3009\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30\u2E31\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uff3f\uFF5B\uFF5D\uFF5F-\uFF65]' }; var characterIndices = { ALETTER: 0, MIDNUMLET: 1, MIDLETTER: 2, MIDNUM: 3, NUMERIC: 4, CR: 5, LF: 6, NEWLINE: 7, EXTEND: 8, FORMAT: 9, KATAKANA: 10, EXTENDNUMLET: 11, AT: 12, OTHER: 13 }; var SETS = [ new RegExp(regExps.aletter), new RegExp(regExps.midnumlet), new RegExp(regExps.midletter), new RegExp(regExps.midnum), new RegExp(regExps.numeric), new RegExp(regExps.cr), new RegExp(regExps.lf), new RegExp(regExps.newline), new RegExp(regExps.extend), new RegExp(regExps.format), new RegExp(regExps.katakana), new RegExp(regExps.extendnumlet), new RegExp('@') ]; var EMPTY_STRING = ''; var PUNCTUATION = new RegExp('^' + regExps.punctuation + '$'); var WHITESPACE = /^\s+$/; var UnicodeData = { characterIndices: characterIndices, SETS: SETS, EMPTY_STRING: EMPTY_STRING, PUNCTUATION: PUNCTUATION, WHITESPACE: WHITESPACE }; var constant = function (value) { return function () { return value; }; }; var never = constant(false); var always = constant(true); var never$1 = never; var always$1 = always; var none = function () { return NONE; }; var NONE = function () { var eq = function (o) { return o.isNone(); }; var call = function (thunk) { return thunk(); }; var id = function (n) { return n; }; var noop = function () { }; var nul = function () { return null; }; var undef = function () { return undefined; }; var me = { fold: function (n, s) { return n(); }, is: never$1, isSome: never$1, isNone: always$1, getOr: id, getOrThunk: call, getOrDie: function (msg) { throw new Error(msg || 'error: getOrDie called on none.'); }, getOrNull: nul, getOrUndefined: undef, or: id, orThunk: call, map: none, ap: none, each: noop, bind: none, flatten: none, exists: never$1, forall: always$1, filter: none, equals: eq, equals_: eq, toArray: function () { return []; }, toString: constant('none()') }; if (Object.freeze) Object.freeze(me); return me; }(); var typeOf = function (x) { if (x === null) return 'null'; var t = typeof x; if (t === 'object' && Array.prototype.isPrototypeOf(x)) return 'array'; if (t === 'object' && String.prototype.isPrototypeOf(x)) return 'string'; return t; }; var isType = function (type) { return function (value) { return typeOf(value) === type; }; }; var isFunction = isType('function'); var map = function (xs, f) { var len = xs.length; var r = new Array(len); for (var i = 0; i < len; i++) { var x = xs[i]; r[i] = f(x, i, xs); } return r; }; var slice = Array.prototype.slice; var from = isFunction(Array.from) ? Array.from : function (x) { return slice.call(x); }; var SETS$1 = UnicodeData.SETS; var OTHER = UnicodeData.characterIndices.OTHER; var getType = function (char) { var j, set, type = OTHER; var setsLength = SETS$1.length; for (j = 0; j < setsLength; ++j) { set = SETS$1[j]; if (set && set.test(char)) { type = j; break; } } return type; }; var memoize = function (func) { var cache = {}; return function (char) { if (cache[char]) { return cache[char]; } else { var result = func(char); cache[char] = result; return result; } }; }; var classify = function (string) { var memoized = memoize(getType); return map(string.split(''), memoized); }; var StringMapper = { classify: classify }; var ci = UnicodeData.characterIndices; var isWordBoundary = function (map, index) { var prevType; var type = map[index]; var nextType = map[index + 1]; var nextNextType; if (index < 0 || index > map.length - 1 && index !== 0) { return false; } if (type === ci.ALETTER && nextType === ci.ALETTER) { return false; } nextNextType = map[index + 2]; if (type === ci.ALETTER && (nextType === ci.MIDLETTER || nextType === ci.MIDNUMLET || nextType === ci.AT) && nextNextType === ci.ALETTER) { return false; } prevType = map[index - 1]; if ((type === ci.MIDLETTER || type === ci.MIDNUMLET || nextType === ci.AT) && nextType === ci.ALETTER && prevType === ci.ALETTER) { return false; } if ((type === ci.NUMERIC || type === ci.ALETTER) && (nextType === ci.NUMERIC || nextType === ci.ALETTER)) { return false; } if ((type === ci.MIDNUM || type === ci.MIDNUMLET) && nextType === ci.NUMERIC && prevType === ci.NUMERIC) { return false; } if (type === ci.NUMERIC && (nextType === ci.MIDNUM || nextType === ci.MIDNUMLET) && nextNextType === ci.NUMERIC) { return false; } if (type === ci.EXTEND || type === ci.FORMAT || prevType === ci.EXTEND || prevType === ci.FORMAT || nextType === ci.EXTEND || nextType === ci.FORMAT) { return false; } if (type === ci.CR && nextType === ci.LF) { return false; } if (type === ci.NEWLINE || type === ci.CR || type === ci.LF) { return true; } if (nextType === ci.NEWLINE || nextType === ci.CR || nextType === ci.LF) { return true; } if (type === ci.KATAKANA && nextType === ci.KATAKANA) { return false; } if (nextType === ci.EXTENDNUMLET && (type === ci.ALETTER || type === ci.NUMERIC || type === ci.KATAKANA || type === ci.EXTENDNUMLET)) { return false; } if (type === ci.EXTENDNUMLET && (nextType === ci.ALETTER || nextType === ci.NUMERIC || nextType === ci.KATAKANA)) { return false; } if (type === ci.AT) { return false; } return true; }; var WordBoundary = { isWordBoundary: isWordBoundary }; var EMPTY_STRING$1 = UnicodeData.EMPTY_STRING; var WHITESPACE$1 = UnicodeData.WHITESPACE; var PUNCTUATION$1 = UnicodeData.PUNCTUATION; var isProtocol = function (word) { return word === 'http' || word === 'https'; }; var findWordEnd = function (str, index) { var i; for (i = index; i < str.length; ++i) { var chr = str.charAt(i); if (WHITESPACE$1.test(chr)) { break; } } return i; }; var extractUrl = function (word, str, index) { var endIndex = findWordEnd(str, index + 1); var peakedWord = str.substring(index + 1, endIndex); if (peakedWord.substr(0, 3) === '://') { return { word: word + peakedWord, index: endIndex }; } return { word: word, index: index }; }; var doGetWords = function (str, options) { var i = 0; var map = StringMapper.classify(str); var len = map.length; var word = []; var words = []; var chr; var includePunctuation; var includeWhitespace; if (!options) { options = {}; } if (options.ignoreCase) { str = str.toLowerCase(); } includePunctuation = options.includePunctuation; includeWhitespace = options.includeWhitespace; for (; i < len; ++i) { chr = str.charAt(i); word.push(chr); if (WordBoundary.isWordBoundary(map, i)) { word = word.join(EMPTY_STRING$1); if (word && (includeWhitespace || !WHITESPACE$1.test(word)) && (includePunctuation || !PUNCTUATION$1.test(word))) { if (isProtocol(word)) { var obj = extractUrl(word, str, i); words.push(obj.word); i = obj.index; } else { words.push(word); } } word = []; } } return words; }; var getWords = function (str, options) { return doGetWords(str.replace(/\ufeff/g, ''), options); }; var WordGetter = { getWords: getWords }; var getText = function (node, schema) { var blockElements = schema.getBlockElements(); var shortEndedElements = schema.getShortEndedElements(); var whiteSpaceElements = schema.getWhiteSpaceElements(); var isSeparator = function (node) { return blockElements[node.nodeName] || shortEndedElements[node.nodeName] || whiteSpaceElements[node.nodeName]; }; var txt = ''; var treeWalker = new global$1(node, node); while (node = treeWalker.next()) { if (node.nodeType === 3) { txt += node.data; } else if (isSeparator(node)) { txt += ' '; } } return txt; }; var innerText = function (node, schema) { return global$2.ie ? getText(node, schema) : node.innerText; }; var getTextContent = function (editor) { return editor.removed ? '' : innerText(editor.getBody(), editor.schema); }; var getCount = function (editor) { return WordGetter.getWords(getTextContent(editor)).length; }; var WordCount = { getCount: getCount }; var get = function (editor) { var getCount = function () { return WordCount.getCount(editor); }; return { getCount: getCount }; }; var Api = { get: get }; var global$3 = tinymce.util.Tools.resolve('tinymce.util.Delay'); var global$4 = tinymce.util.Tools.resolve('tinymce.util.I18n'); var setup = function (editor) { var wordsToText = function (editor) { return global$4.translate([ '{0} words', WordCount.getCount(editor) ]); }; var update = function () { editor.theme.panel.find('#wordcount').text(wordsToText(editor)); }; editor.on('init', function () { var statusbar = editor.theme.panel && editor.theme.panel.find('#statusbar')[0]; var debouncedUpdate = global$3.debounce(update, 300); if (statusbar) { global$3.setEditorTimeout(editor, function () { statusbar.insert({ type: 'label', name: 'wordcount', text: wordsToText(editor), classes: 'wordcount', disabled: editor.settings.readonly }, 0); editor.on('setcontent beforeaddundo undo redo keyup', debouncedUpdate); }, 0); } }); }; var Statusbar = { setup: setup }; global.add('wordcount', function (editor) { Statusbar.setup(editor); return Api.get(editor); }); function Plugin () { } return Plugin; }()); })(); (function () { var inlite = (function (domGlobals) { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.ThemeManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.Env'); var global$2 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var global$3 = tinymce.util.Tools.resolve('tinymce.util.Delay'); var flatten = function (arr) { return arr.reduce(function (results, item) { return Array.isArray(item) ? results.concat(flatten(item)) : results.concat(item); }, []); }; var DeepFlatten = { flatten: flatten }; var result = function (id, rect) { return { id: id, rect: rect }; }; var match = function (editor, matchers) { for (var i = 0; i < matchers.length; i++) { var f = matchers[i]; var result_1 = f(editor); if (result_1) { return result_1; } } return null; }; var Matcher = { match: match, result: result }; var fromClientRect = function (clientRect) { return { x: clientRect.left, y: clientRect.top, w: clientRect.width, h: clientRect.height }; }; var toClientRect = function (geomRect) { return { left: geomRect.x, top: geomRect.y, width: geomRect.w, height: geomRect.h, right: geomRect.x + geomRect.w, bottom: geomRect.y + geomRect.h }; }; var Convert = { fromClientRect: fromClientRect, toClientRect: toClientRect }; var toAbsolute = function (rect) { var vp = global$2.DOM.getViewPort(); return { x: rect.x + vp.x, y: rect.y + vp.y, w: rect.w, h: rect.h }; }; var measureElement = function (elm) { var clientRect = elm.getBoundingClientRect(); return toAbsolute({ x: clientRect.left, y: clientRect.top, w: Math.max(elm.clientWidth, elm.offsetWidth), h: Math.max(elm.clientHeight, elm.offsetHeight) }); }; var getElementRect = function (editor, elm) { return measureElement(elm); }; var getPageAreaRect = function (editor) { return measureElement(editor.getElement().ownerDocument.body); }; var getContentAreaRect = function (editor) { return measureElement(editor.getContentAreaContainer() || editor.getBody()); }; var getSelectionRect = function (editor) { var clientRect = editor.selection.getBoundingClientRect(); return clientRect ? toAbsolute(Convert.fromClientRect(clientRect)) : null; }; var Measure = { getElementRect: getElementRect, getPageAreaRect: getPageAreaRect, getContentAreaRect: getContentAreaRect, getSelectionRect: getSelectionRect }; var element = function (element, predicateIds) { return function (editor) { for (var i = 0; i < predicateIds.length; i++) { if (predicateIds[i].predicate(element)) { var result = Matcher.result(predicateIds[i].id, Measure.getElementRect(editor, element)); return result; } } return null; }; }; var parent = function (elements, predicateIds) { return function (editor) { for (var i = 0; i < elements.length; i++) { for (var x = 0; x < predicateIds.length; x++) { if (predicateIds[x].predicate(elements[i])) { return Matcher.result(predicateIds[x].id, Measure.getElementRect(editor, elements[i])); } } } return null; }; }; var ElementMatcher = { element: element, parent: parent }; var global$4 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var create = function (id, predicate) { return { id: id, predicate: predicate }; }; var fromContextToolbars = function (toolbars) { return global$4.map(toolbars, function (toolbar) { return create(toolbar.id, toolbar.predicate); }); }; var PredicateId = { create: create, fromContextToolbars: fromContextToolbars }; var textSelection = function (id) { return function (editor) { if (!editor.selection.isCollapsed()) { var result = Matcher.result(id, Measure.getSelectionRect(editor)); return result; } return null; }; }; var emptyTextBlock = function (elements, id) { return function (editor) { var i; var textBlockElementsMap = editor.schema.getTextBlockElements(); for (i = 0; i < elements.length; i++) { if (elements[i].nodeName === 'TABLE') { return null; } } for (i = 0; i < elements.length; i++) { if (elements[i].nodeName in textBlockElementsMap) { if (editor.dom.isEmpty(elements[i])) { return Matcher.result(id, Measure.getSelectionRect(editor)); } return null; } } return null; }; }; var SelectionMatcher = { textSelection: textSelection, emptyTextBlock: emptyTextBlock }; var fireSkinLoaded = function (editor) { editor.fire('SkinLoaded'); }; var fireBeforeRenderUI = function (editor) { return editor.fire('BeforeRenderUI'); }; var Events = { fireSkinLoaded: fireSkinLoaded, fireBeforeRenderUI: fireBeforeRenderUI }; var global$5 = tinymce.util.Tools.resolve('tinymce.EditorManager'); var isType = function (type) { return function (value) { return typeof value === type; }; }; var isArray = function (value) { return Array.isArray(value); }; var isNull = function (value) { return value === null; }; var isObject = function (predicate) { return function (value) { return !isNull(value) && !isArray(value) && predicate(value); }; }; var isString = function (value) { return isType('string')(value); }; var isNumber = function (value) { return isType('number')(value); }; var isFunction = function (value) { return isType('function')(value); }; var isBoolean = function (value) { return isType('boolean')(value); }; var Type = { isString: isString, isNumber: isNumber, isBoolean: isBoolean, isFunction: isFunction, isObject: isObject(isType('object')), isNull: isNull, isArray: isArray }; var validDefaultOrDie = function (value, predicate) { if (predicate(value)) { return true; } throw new Error('Default value doesn\'t match requested type.'); }; var getByTypeOr = function (predicate) { return function (editor, name, defaultValue) { var settings = editor.settings; validDefaultOrDie(defaultValue, predicate); return name in settings && predicate(settings[name]) ? settings[name] : defaultValue; }; }; var splitNoEmpty = function (str, delim) { return str.split(delim).filter(function (item) { return item.length > 0; }); }; var itemsToArray = function (value, defaultValue) { var stringToItemsArray = function (value) { return typeof value === 'string' ? splitNoEmpty(value, /[ ,]/) : value; }; var boolToItemsArray = function (value, defaultValue) { return value === false ? [] : defaultValue; }; if (Type.isArray(value)) { return value; } else if (Type.isString(value)) { return stringToItemsArray(value); } else if (Type.isBoolean(value)) { return boolToItemsArray(value, defaultValue); } return defaultValue; }; var getToolbarItemsOr = function (predicate) { return function (editor, name, defaultValue) { var value = name in editor.settings ? editor.settings[name] : defaultValue; validDefaultOrDie(defaultValue, predicate); return itemsToArray(value, defaultValue); }; }; var EditorSettings = { getStringOr: getByTypeOr(Type.isString), getBoolOr: getByTypeOr(Type.isBoolean), getNumberOr: getByTypeOr(Type.isNumber), getHandlerOr: getByTypeOr(Type.isFunction), getToolbarItemsOr: getToolbarItemsOr(Type.isArray) }; var global$6 = tinymce.util.Tools.resolve('tinymce.geom.Rect'); var result$1 = function (rect, position) { return { rect: rect, position: position }; }; var moveTo = function (rect, toRect) { return { x: toRect.x, y: toRect.y, w: rect.w, h: rect.h }; }; var calcByPositions = function (testPositions1, testPositions2, targetRect, contentAreaRect, panelRect) { var relPos, relRect, outputPanelRect; var paddedContentRect = { x: contentAreaRect.x, y: contentAreaRect.y, w: contentAreaRect.w + (contentAreaRect.w < panelRect.w + targetRect.w ? panelRect.w : 0), h: contentAreaRect.h + (contentAreaRect.h < panelRect.h + targetRect.h ? panelRect.h : 0) }; relPos = global$6.findBestRelativePosition(panelRect, targetRect, paddedContentRect, testPositions1); targetRect = global$6.clamp(targetRect, paddedContentRect); if (relPos) { relRect = global$6.relativePosition(panelRect, targetRect, relPos); outputPanelRect = moveTo(panelRect, relRect); return result$1(outputPanelRect, relPos); } targetRect = global$6.intersect(paddedContentRect, targetRect); if (targetRect) { relPos = global$6.findBestRelativePosition(panelRect, targetRect, paddedContentRect, testPositions2); if (relPos) { relRect = global$6.relativePosition(panelRect, targetRect, relPos); outputPanelRect = moveTo(panelRect, relRect); return result$1(outputPanelRect, relPos); } outputPanelRect = moveTo(panelRect, targetRect); return result$1(outputPanelRect, relPos); } return null; }; var calcInsert = function (targetRect, contentAreaRect, panelRect) { return calcByPositions([ 'cr-cl', 'cl-cr' ], [ 'bc-tc', 'bl-tl', 'br-tr' ], targetRect, contentAreaRect, panelRect); }; var calc = function (targetRect, contentAreaRect, panelRect) { return calcByPositions([ 'tc-bc', 'bc-tc', 'tl-bl', 'bl-tl', 'tr-br', 'br-tr', 'cr-cl', 'cl-cr' ], [ 'bc-tc', 'bl-tl', 'br-tr', 'cr-cl' ], targetRect, contentAreaRect, panelRect); }; var userConstrain = function (handler, targetRect, contentAreaRect, panelRect) { var userConstrainedPanelRect; if (typeof handler === 'function') { userConstrainedPanelRect = handler({ elementRect: Convert.toClientRect(targetRect), contentAreaRect: Convert.toClientRect(contentAreaRect), panelRect: Convert.toClientRect(panelRect) }); return Convert.fromClientRect(userConstrainedPanelRect); } return panelRect; }; var defaultHandler = function (rects) { return rects.panelRect; }; var Layout = { calcInsert: calcInsert, calc: calc, userConstrain: userConstrain, defaultHandler: defaultHandler }; var toAbsoluteUrl = function (editor, url) { return editor.documentBaseURI.toAbsolute(url); }; var urlFromName = function (name) { var prefix = global$5.baseURL + '/skins/'; return name ? prefix + name : prefix + 'lightgray'; }; var getTextSelectionToolbarItems = function (editor) { return EditorSettings.getToolbarItemsOr(editor, 'selection_toolbar', [ 'bold', 'italic', '|', 'quicklink', 'h2', 'h3', 'blockquote' ]); }; var getInsertToolbarItems = function (editor) { return EditorSettings.getToolbarItemsOr(editor, 'insert_toolbar', [ 'quickimage', 'quicktable' ]); }; var getPositionHandler = function (editor) { return EditorSettings.getHandlerOr(editor, 'inline_toolbar_position_handler', Layout.defaultHandler); }; var getSkinUrl = function (editor) { var settings = editor.settings; return settings.skin_url ? toAbsoluteUrl(editor, settings.skin_url) : urlFromName(settings.skin); }; var isSkinDisabled = function (editor) { return editor.settings.skin === false; }; var Settings = { getTextSelectionToolbarItems: getTextSelectionToolbarItems, getInsertToolbarItems: getInsertToolbarItems, getPositionHandler: getPositionHandler, getSkinUrl: getSkinUrl, isSkinDisabled: isSkinDisabled }; var fireSkinLoaded$1 = function (editor, callback) { var done = function () { editor._skinLoaded = true; Events.fireSkinLoaded(editor); callback(); }; if (editor.initialized) { done(); } else { editor.on('init', done); } }; var load = function (editor, callback) { var skinUrl = Settings.getSkinUrl(editor); var done = function () { fireSkinLoaded$1(editor, callback); }; if (Settings.isSkinDisabled(editor)) { done(); } else { global$2.DOM.styleSheetLoader.load(skinUrl + '/skin.min.css', done); editor.contentCSS.push(skinUrl + '/content.inline.min.css'); } }; var SkinLoader = { load: load }; var getSelectionElements = function (editor) { var node = editor.selection.getNode(); var elms = editor.dom.getParents(node, '*'); return elms; }; var createToolbar = function (editor, selector, id, items) { var selectorPredicate = function (elm) { return editor.dom.is(elm, selector); }; return { predicate: selectorPredicate, id: id, items: items }; }; var getToolbars = function (editor) { var contextToolbars = editor.contextToolbars; return DeepFlatten.flatten([ contextToolbars ? contextToolbars : [], createToolbar(editor, 'img', 'image', 'alignleft aligncenter alignright') ]); }; var findMatchResult = function (editor, toolbars) { var result, elements, contextToolbarsPredicateIds; elements = getSelectionElements(editor); contextToolbarsPredicateIds = PredicateId.fromContextToolbars(toolbars); result = Matcher.match(editor, [ ElementMatcher.element(elements[0], contextToolbarsPredicateIds), SelectionMatcher.textSelection('text'), SelectionMatcher.emptyTextBlock(elements, 'insert'), ElementMatcher.parent(elements, contextToolbarsPredicateIds) ]); return result && result.rect ? result : null; }; var editorHasFocus = function (editor) { return domGlobals.document.activeElement === editor.getBody(); }; var togglePanel = function (editor, panel) { var toggle = function () { var toolbars = getToolbars(editor); var result = findMatchResult(editor, toolbars); if (result) { panel.show(editor, result.id, result.rect, toolbars); } else { panel.hide(); } }; return function () { if (!editor.removed && editorHasFocus(editor)) { toggle(); } }; }; var repositionPanel = function (editor, panel) { return function () { var toolbars = getToolbars(editor); var result = findMatchResult(editor, toolbars); if (result) { panel.reposition(editor, result.id, result.rect); } }; }; var ignoreWhenFormIsVisible = function (editor, panel, f) { return function () { if (!editor.removed && !panel.inForm()) { f(); } }; }; var bindContextualToolbarsEvents = function (editor, panel) { var throttledTogglePanel = global$3.throttle(togglePanel(editor, panel), 0); var throttledTogglePanelWhenNotInForm = global$3.throttle(ignoreWhenFormIsVisible(editor, panel, togglePanel(editor, panel)), 0); var reposition = repositionPanel(editor, panel); editor.on('blur hide ObjectResizeStart', panel.hide); editor.on('click', throttledTogglePanel); editor.on('nodeChange mouseup', throttledTogglePanelWhenNotInForm); editor.on('ResizeEditor keyup', throttledTogglePanel); editor.on('ResizeWindow', reposition); global$2.DOM.bind(global$1.container, 'scroll', reposition); editor.on('remove', function () { global$2.DOM.unbind(global$1.container, 'scroll', reposition); panel.remove(); }); editor.shortcuts.add('Alt+F10,F10', '', panel.focus); }; var overrideLinkShortcut = function (editor, panel) { editor.shortcuts.remove('meta+k'); editor.shortcuts.add('meta+k', '', function () { var toolbars = getToolbars(editor); var result = Matcher.match(editor, [SelectionMatcher.textSelection('quicklink')]); if (result) { panel.show(editor, result.id, result.rect, toolbars); } }); }; var renderInlineUI = function (editor, panel) { SkinLoader.load(editor, function () { bindContextualToolbarsEvents(editor, panel); overrideLinkShortcut(editor, panel); }); return {}; }; var fail = function (message) { throw new Error(message); }; var renderUI = function (editor, panel) { return editor.inline ? renderInlineUI(editor, panel) : fail('inlite theme only supports inline mode.'); }; var Render = { renderUI: renderUI }; var noop = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } }; var constant = function (value) { return function () { return value; }; }; var never = constant(false); var always = constant(true); var never$1 = never; var always$1 = always; var none = function () { return NONE; }; var NONE = function () { var eq = function (o) { return o.isNone(); }; var call = function (thunk) { return thunk(); }; var id = function (n) { return n; }; var noop = function () { }; var nul = function () { return null; }; var undef = function () { return undefined; }; var me = { fold: function (n, s) { return n(); }, is: never$1, isSome: never$1, isNone: always$1, getOr: id, getOrThunk: call, getOrDie: function (msg) { throw new Error(msg || 'error: getOrDie called on none.'); }, getOrNull: nul, getOrUndefined: undef, or: id, orThunk: call, map: none, ap: none, each: noop, bind: none, flatten: none, exists: never$1, forall: always$1, filter: none, equals: eq, equals_: eq, toArray: function () { return []; }, toString: constant('none()') }; if (Object.freeze) Object.freeze(me); return me; }(); var some = function (a) { var constant_a = function () { return a; }; var self = function () { return me; }; var map = function (f) { return some(f(a)); }; var bind = function (f) { return f(a); }; var me = { fold: function (n, s) { return s(a); }, is: function (v) { return a === v; }, isSome: always$1, isNone: never$1, getOr: constant_a, getOrThunk: constant_a, getOrDie: constant_a, getOrNull: constant_a, getOrUndefined: constant_a, or: self, orThunk: self, map: map, ap: function (optfab) { return optfab.fold(none, function (fab) { return some(fab(a)); }); }, each: function (f) { f(a); }, bind: bind, flatten: constant_a, exists: bind, forall: bind, filter: function (f) { return f(a) ? me : NONE; }, equals: function (o) { return o.is(a); }, equals_: function (o, elementEq) { return o.fold(never$1, function (b) { return elementEq(a, b); }); }, toArray: function () { return [a]; }, toString: function () { return 'some(' + a + ')'; } }; return me; }; var from = function (value) { return value === null || value === undefined ? NONE : some(value); }; var Option = { some: some, none: none, from: from }; var typeOf = function (x) { if (x === null) return 'null'; var t = typeof x; if (t === 'object' && Array.prototype.isPrototypeOf(x)) return 'array'; if (t === 'object' && String.prototype.isPrototypeOf(x)) return 'string'; return t; }; var isType$1 = function (type) { return function (value) { return typeOf(value) === type; }; }; var isFunction$1 = isType$1('function'); var isNumber$1 = isType$1('number'); var rawIndexOf = function () { var pIndexOf = Array.prototype.indexOf; var fastIndex = function (xs, x) { return pIndexOf.call(xs, x); }; var slowIndex = function (xs, x) { return slowIndexOf(xs, x); }; return pIndexOf === undefined ? slowIndex : fastIndex; }(); var indexOf = function (xs, x) { var r = rawIndexOf(xs, x); return r === -1 ? Option.none() : Option.some(r); }; var exists = function (xs, pred) { return findIndex(xs, pred).isSome(); }; var map = function (xs, f) { var len = xs.length; var r = new Array(len); for (var i = 0; i < len; i++) { var x = xs[i]; r[i] = f(x, i, xs); } return r; }; var each = function (xs, f) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; f(x, i, xs); } }; var filter = function (xs, pred) { var r = []; for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { r.push(x); } } return r; }; var foldl = function (xs, f, acc) { each(xs, function (x) { acc = f(acc, x); }); return acc; }; var find = function (xs, pred) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { return Option.some(x); } } return Option.none(); }; var findIndex = function (xs, pred) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { return Option.some(i); } } return Option.none(); }; var slowIndexOf = function (xs, x) { for (var i = 0, len = xs.length; i < len; ++i) { if (xs[i] === x) { return i; } } return -1; }; var push = Array.prototype.push; var flatten$1 = function (xs) { var r = []; for (var i = 0, len = xs.length; i < len; ++i) { if (!Array.prototype.isPrototypeOf(xs[i])) throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs); push.apply(r, xs[i]); } return r; }; var slice = Array.prototype.slice; var from$1 = isFunction$1(Array.from) ? Array.from : function (x) { return slice.call(x); }; var count = 0; var funcs = { id: function () { return 'mceu_' + count++; }, create: function (name, attrs, children) { var elm = domGlobals.document.createElement(name); global$2.DOM.setAttribs(elm, attrs); if (typeof children === 'string') { elm.innerHTML = children; } else { global$4.each(children, function (child) { if (child.nodeType) { elm.appendChild(child); } }); } return elm; }, createFragment: function (html) { return global$2.DOM.createFragment(html); }, getWindowSize: function () { return global$2.DOM.getViewPort(); }, getSize: function (elm) { var width, height; if (elm.getBoundingClientRect) { var rect = elm.getBoundingClientRect(); width = Math.max(rect.width || rect.right - rect.left, elm.offsetWidth); height = Math.max(rect.height || rect.bottom - rect.bottom, elm.offsetHeight); } else { width = elm.offsetWidth; height = elm.offsetHeight; } return { width: width, height: height }; }, getPos: function (elm, root) { return global$2.DOM.getPos(elm, root || funcs.getContainer()); }, getContainer: function () { return global$1.container ? global$1.container : domGlobals.document.body; }, getViewPort: function (win) { return global$2.DOM.getViewPort(win); }, get: function (id) { return domGlobals.document.getElementById(id); }, addClass: function (elm, cls) { return global$2.DOM.addClass(elm, cls); }, removeClass: function (elm, cls) { return global$2.DOM.removeClass(elm, cls); }, hasClass: function (elm, cls) { return global$2.DOM.hasClass(elm, cls); }, toggleClass: function (elm, cls, state) { return global$2.DOM.toggleClass(elm, cls, state); }, css: function (elm, name, value) { return global$2.DOM.setStyle(elm, name, value); }, getRuntimeStyle: function (elm, name) { return global$2.DOM.getStyle(elm, name, true); }, on: function (target, name, callback, scope) { return global$2.DOM.bind(target, name, callback, scope); }, off: function (target, name, callback) { return global$2.DOM.unbind(target, name, callback); }, fire: function (target, name, args) { return global$2.DOM.fire(target, name, args); }, innerHtml: function (elm, html) { global$2.DOM.setHTML(elm, html); } }; var global$7 = tinymce.util.Tools.resolve('tinymce.dom.DomQuery'); var global$8 = tinymce.util.Tools.resolve('tinymce.util.Class'); var global$9 = tinymce.util.Tools.resolve('tinymce.util.EventDispatcher'); var BoxUtils = { parseBox: function (value) { var len; var radix = 10; if (!value) { return; } if (typeof value === 'number') { value = value || 0; return { top: value, left: value, bottom: value, right: value }; } value = value.split(' '); len = value.length; if (len === 1) { value[1] = value[2] = value[3] = value[0]; } else if (len === 2) { value[2] = value[0]; value[3] = value[1]; } else if (len === 3) { value[3] = value[1]; } return { top: parseInt(value[0], radix) || 0, right: parseInt(value[1], radix) || 0, bottom: parseInt(value[2], radix) || 0, left: parseInt(value[3], radix) || 0 }; }, measureBox: function (elm, prefix) { function getStyle(name) { var defaultView = elm.ownerDocument.defaultView; if (defaultView) { var computedStyle = defaultView.getComputedStyle(elm, null); if (computedStyle) { name = name.replace(/[A-Z]/g, function (a) { return '-' + a; }); return computedStyle.getPropertyValue(name); } else { return null; } } return elm.currentStyle[name]; } function getSide(name) { var val = parseFloat(getStyle(name)); return isNaN(val) ? 0 : val; } return { top: getSide(prefix + 'TopWidth'), right: getSide(prefix + 'RightWidth'), bottom: getSide(prefix + 'BottomWidth'), left: getSide(prefix + 'LeftWidth') }; } }; function noop$1() { } function ClassList(onchange) { this.cls = []; this.cls._map = {}; this.onchange = onchange || noop$1; this.prefix = ''; } global$4.extend(ClassList.prototype, { add: function (cls) { if (cls && !this.contains(cls)) { this.cls._map[cls] = true; this.cls.push(cls); this._change(); } return this; }, remove: function (cls) { if (this.contains(cls)) { var i = void 0; for (i = 0; i < this.cls.length; i++) { if (this.cls[i] === cls) { break; } } this.cls.splice(i, 1); delete this.cls._map[cls]; this._change(); } return this; }, toggle: function (cls, state) { var curState = this.contains(cls); if (curState !== state) { if (curState) { this.remove(cls); } else { this.add(cls); } this._change(); } return this; }, contains: function (cls) { return !!this.cls._map[cls]; }, _change: function () { delete this.clsValue; this.onchange.call(this); } }); ClassList.prototype.toString = function () { var value; if (this.clsValue) { return this.clsValue; } value = ''; for (var i = 0; i < this.cls.length; i++) { if (i > 0) { value += ' '; } value += this.prefix + this.cls[i]; } return value; }; function unique(array) { var uniqueItems = []; var i = array.length, item; while (i--) { item = array[i]; if (!item.__checked) { uniqueItems.push(item); item.__checked = 1; } } i = uniqueItems.length; while (i--) { delete uniqueItems[i].__checked; } return uniqueItems; } var expression = /^([\w\\*]+)?(?:#([\w\-\\]+))?(?:\.([\w\\\.]+))?(?:\[\@?([\w\\]+)([\^\$\*!~]?=)([\w\\]+)\])?(?:\:(.+))?/i; var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g; var whiteSpace = /^\s*|\s*$/g; var Collection; var Selector = global$8.extend({ init: function (selector) { var match = this.match; function compileNameFilter(name) { if (name) { name = name.toLowerCase(); return function (item) { return name === '*' || item.type === name; }; } } function compileIdFilter(id) { if (id) { return function (item) { return item._name === id; }; } } function compileClassesFilter(classes) { if (classes) { classes = classes.split('.'); return function (item) { var i = classes.length; while (i--) { if (!item.classes.contains(classes[i])) { return false; } } return true; }; } } function compileAttrFilter(name, cmp, check) { if (name) { return function (item) { var value = item[name] ? item[name]() : ''; 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; }; } } function compilePsuedoFilter(name) { var notSelectors; if (name) { name = /(?:not\((.+)\))|(.+)/i.exec(name); if (!name[1]) { name = name[2]; return function (item, index, length) { 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; }; } notSelectors = parseChunks(name[1], []); return function (item) { return !match(item, notSelectors); }; } } function compile(selector, filters, direct) { var parts; function add(filter) { if (filter) { filters.push(filter); } } parts = expression.exec(selector.replace(whiteSpace, '')); add(compileNameFilter(parts[1])); add(compileIdFilter(parts[2])); add(compileClassesFilter(parts[3])); add(compileAttrFilter(parts[4], parts[5], parts[6])); add(compilePsuedoFilter(parts[7])); filters.pseudo = !!parts[7]; filters.direct = direct; return filters; } function parseChunks(selector, selectors) { var parts = []; var extra, matches, i; do { chunker.exec(''); matches = chunker.exec(selector); if (matches) { selector = matches[3]; parts.push(matches[1]); if (matches[2]) { extra = matches[3]; break; } } } while (matches); if (extra) { parseChunks(extra, selectors); } selector = []; for (i = 0; i < parts.length; i++) { if (parts[i] !== '>') { selector.push(compile(parts[i], [], parts[i - 1] === '>')); } } selectors.push(selector); return selectors; } this._selectors = parseChunks(selector, []); }, match: function (control, selectors) { var i, l, si, sl, selector, fi, fl, filters, index, length, siblings, count, item; selectors = selectors || this._selectors; for (i = 0, l = selectors.length; i < l; i++) { selector = selectors[i]; sl = selector.length; item = control; count = 0; for (si = sl - 1; si >= 0; si--) { filters = selector[si]; while (item) { if (filters.pseudo) { siblings = item.parent().items(); index = length = siblings.length; while (index--) { if (siblings[index] === item) { break; } } } for (fi = 0, fl = filters.length; fi < fl; fi++) { if (!filters[fi](item, index, length)) { fi = fl + 1; break; } } if (fi === fl) { count++; break; } else { if (si === sl - 1) { break; } } item = item.parent(); } } if (count === sl) { return true; } } return false; }, find: function (container) { var matches = [], i, l; var selectors = this._selectors; function collect(items, selector, index) { var i, l, fi, fl, item; var filters = selector[index]; for (i = 0, l = items.length; i < l; i++) { item = items[i]; for (fi = 0, fl = filters.length; fi < fl; fi++) { if (!filters[fi](item, i, l)) { fi = fl + 1; break; } } if (fi === fl) { if (index === selector.length - 1) { matches.push(item); } else { if (item.items) { collect(item.items(), selector, index + 1); } } } else if (filters.direct) { return; } if (item.items) { collect(item.items(), selector, index); } } } if (container.items) { for (i = 0, l = selectors.length; i < l; i++) { collect(container.items(), selectors[i], 0); } if (l > 1) { matches = unique(matches); } } if (!Collection) { Collection = Selector.Collection; } return new Collection(matches); } }); var Collection$1, proto; var push$1 = Array.prototype.push, slice$1 = Array.prototype.slice; proto = { length: 0, init: function (items) { if (items) { this.add(items); } }, add: function (items) { var self = this; if (!global$4.isArray(items)) { if (items instanceof Collection$1) { self.add(items.toArray()); } else { push$1.call(self, items); } } else { push$1.apply(self, items); } return self; }, set: function (items) { var self = this; var len = self.length; var i; self.length = 0; self.add(items); for (i = self.length; i < len; i++) { delete self[i]; } return self; }, filter: function (selector) { var self = this; var i, l; var matches = []; var item, match; if (typeof selector === 'string') { selector = new Selector(selector); match = function (item) { return selector.match(item); }; } else { match = selector; } for (i = 0, l = self.length; i < l; i++) { item = self[i]; if (match(item)) { matches.push(item); } } return new Collection$1(matches); }, slice: function () { return new Collection$1(slice$1.apply(this, arguments)); }, eq: function (index) { return index === -1 ? this.slice(index) : this.slice(index, +index + 1); }, each: function (callback) { global$4.each(this, callback); return this; }, toArray: function () { return global$4.toArray(this); }, indexOf: function (ctrl) { var self = this; var i = self.length; while (i--) { if (self[i] === ctrl) { break; } } return i; }, reverse: function () { return new Collection$1(global$4.toArray(this).reverse()); }, hasClass: function (cls) { return this[0] ? this[0].classes.contains(cls) : false; }, prop: function (name, value) { var self = this; var item; if (value !== undefined) { self.each(function (item) { if (item[name]) { item[name](value); } }); return self; } item = self[0]; if (item && item[name]) { return item[name](); } }, exec: function (name) { var self = this, args = global$4.toArray(arguments).slice(1); self.each(function (item) { if (item[name]) { item[name].apply(item, args); } }); return self; }, remove: function () { var i = this.length; while (i--) { this[i].remove(); } return this; }, addClass: function (cls) { return this.each(function (item) { item.classes.add(cls); }); }, removeClass: function (cls) { return this.each(function (item) { item.classes.remove(cls); }); } }; global$4.each('fire on off show hide append prepend before after reflow'.split(' '), function (name) { proto[name] = function () { var args = global$4.toArray(arguments); this.each(function (ctrl) { if (name in ctrl) { ctrl[name].apply(ctrl, args); } }); return this; }; }); global$4.each('text name disabled active selected checked visible parent value data'.split(' '), function (name) { proto[name] = function (value) { return this.prop(name, value); }; }); Collection$1 = global$8.extend(proto); Selector.Collection = Collection$1; var Collection$2 = Collection$1; var Binding = function (settings) { this.create = settings.create; }; Binding.create = function (model, name) { return new Binding({ create: function (otherModel, otherName) { var bindings; var fromSelfToOther = function (e) { otherModel.set(otherName, e.value); }; var fromOtherToSelf = function (e) { model.set(name, e.value); }; otherModel.on('change:' + otherName, fromOtherToSelf); model.on('change:' + name, fromSelfToOther); bindings = otherModel._bindings; if (!bindings) { bindings = otherModel._bindings = []; otherModel.on('destroy', function () { var i = bindings.length; while (i--) { bindings[i](); } }); } bindings.push(function () { model.off('change:' + name, fromSelfToOther); }); return model.get(name); } }); }; var global$a = tinymce.util.Tools.resolve('tinymce.util.Observable'); function isNode(node) { return node.nodeType > 0; } function isEqual(a, b) { var k, checked; if (a === b) { return true; } if (a === null || b === null) { return a === b; } if (typeof a !== 'object' || typeof b !== 'object') { return a === b; } if (global$4.isArray(b)) { if (a.length !== b.length) { return false; } k = a.length; while (k--) { if (!isEqual(a[k], b[k])) { return false; } } } if (isNode(a) || isNode(b)) { return a === b; } checked = {}; for (k in b) { if (!isEqual(a[k], b[k])) { return false; } checked[k] = true; } for (k in a) { if (!checked[k] && !isEqual(a[k], b[k])) { return false; } } return true; } var ObservableObject = global$8.extend({ Mixins: [global$a], init: function (data) { var name, value; data = data || {}; for (name in data) { value = data[name]; if (value instanceof Binding) { data[name] = value.create(this, name); } } this.data = data; }, set: function (name, value) { var key, args; var oldValue = this.data[name]; if (value instanceof Binding) { value = value.create(this, name); } if (typeof name === 'object') { for (key in name) { this.set(key, name[key]); } return this; } if (!isEqual(oldValue, value)) { this.data[name] = value; args = { target: this, name: name, value: value, oldValue: oldValue }; this.fire('change:' + name, args); this.fire('change', args); } return this; }, get: function (name) { return this.data[name]; }, has: function (name) { return name in this.data; }, bind: function (name) { return Binding.create(this, name); }, destroy: function () { this.fire('destroy'); } }); var dirtyCtrls = {}, animationFrameRequested; var ReflowQueue = { add: function (ctrl) { var parent = ctrl.parent(); if (parent) { if (!parent._layout || parent._layout.isNative()) { return; } if (!dirtyCtrls[parent._id]) { dirtyCtrls[parent._id] = parent; } if (!animationFrameRequested) { animationFrameRequested = true; global$3.requestAnimationFrame(function () { var id, ctrl; animationFrameRequested = false; for (id in dirtyCtrls) { ctrl = dirtyCtrls[id]; if (ctrl.state.get('rendered')) { ctrl.reflow(); } } dirtyCtrls = {}; }, domGlobals.document.body); } } }, remove: function (ctrl) { if (dirtyCtrls[ctrl._id]) { delete dirtyCtrls[ctrl._id]; } } }; var getUiContainerDelta = function (ctrl) { var uiContainer = getUiContainer(ctrl); if (uiContainer && global$2.DOM.getStyle(uiContainer, 'position', true) !== 'static') { var containerPos = global$2.DOM.getPos(uiContainer); var dx = uiContainer.scrollLeft - containerPos.x; var dy = uiContainer.scrollTop - containerPos.y; return Option.some({ x: dx, y: dy }); } else { return Option.none(); } }; var setUiContainer = function (editor, ctrl) { var uiContainer = global$2.DOM.select(editor.settings.ui_container)[0]; ctrl.getRoot().uiContainer = uiContainer; }; var getUiContainer = function (ctrl) { return ctrl ? ctrl.getRoot().uiContainer : null; }; var inheritUiContainer = function (fromCtrl, toCtrl) { return toCtrl.uiContainer = getUiContainer(fromCtrl); }; var UiContainer = { getUiContainerDelta: getUiContainerDelta, setUiContainer: setUiContainer, getUiContainer: getUiContainer, inheritUiContainer: inheritUiContainer }; var hasMouseWheelEventSupport = 'onmousewheel' in domGlobals.document; var hasWheelEventSupport = false; var classPrefix = 'mce-'; var Control, idCounter = 0; var proto$1 = { Statics: { classPrefix: classPrefix }, isRtl: function () { return Control.rtl; }, classPrefix: classPrefix, init: function (settings) { var self = this; var classes, defaultClasses; function applyClasses(classes) { var i; classes = classes.split(' '); for (i = 0; i < classes.length; i++) { self.classes.add(classes[i]); } } self.settings = settings = global$4.extend({}, self.Defaults, settings); self._id = settings.id || 'mceu_' + idCounter++; self._aria = { role: settings.role }; self._elmCache = {}; self.$ = global$7; self.state = new ObservableObject({ visible: true, active: false, disabled: false, value: '' }); self.data = new ObservableObject(settings.data); self.classes = new ClassList(function () { if (self.state.get('rendered')) { self.getEl().className = this.toString(); } }); self.classes.prefix = self.classPrefix; classes = settings.classes; if (classes) { if (self.Defaults) { defaultClasses = self.Defaults.classes; if (defaultClasses && classes !== defaultClasses) { applyClasses(defaultClasses); } } applyClasses(classes); } global$4.each('title text name visible disabled active value'.split(' '), function (name) { if (name in settings) { self[name](settings[name]); } }); self.on('click', function () { if (self.disabled()) { return false; } }); self.settings = settings; self.borderBox = BoxUtils.parseBox(settings.border); self.paddingBox = BoxUtils.parseBox(settings.padding); self.marginBox = BoxUtils.parseBox(settings.margin); if (settings.hidden) { self.hide(); } }, Properties: 'parent,name', getContainerElm: function () { var uiContainer = UiContainer.getUiContainer(this); return uiContainer ? uiContainer : funcs.getContainer(); }, getParentCtrl: function (elm) { var ctrl; var lookup = this.getRoot().controlIdLookup; while (elm && lookup) { ctrl = lookup[elm.id]; if (ctrl) { break; } elm = elm.parentNode; } return ctrl; }, initLayoutRect: function () { var self = this; var settings = self.settings; var borderBox, layoutRect; var elm = self.getEl(); var width, height, minWidth, minHeight, autoResize; var startMinWidth, startMinHeight, initialSize; borderBox = self.borderBox = self.borderBox || BoxUtils.measureBox(elm, 'border'); self.paddingBox = self.paddingBox || BoxUtils.measureBox(elm, 'padding'); self.marginBox = self.marginBox || BoxUtils.measureBox(elm, 'margin'); initialSize = funcs.getSize(elm); startMinWidth = settings.minWidth; startMinHeight = settings.minHeight; minWidth = startMinWidth || initialSize.width; minHeight = startMinHeight || initialSize.height; width = settings.width; height = settings.height; autoResize = settings.autoResize; autoResize = typeof autoResize !== 'undefined' ? autoResize : !width && !height; width = width || minWidth; height = height || minHeight; var deltaW = borderBox.left + borderBox.right; var deltaH = borderBox.top + borderBox.bottom; var maxW = settings.maxWidth || 65535; var maxH = settings.maxHeight || 65535; self._layoutRect = layoutRect = { x: settings.x || 0, y: settings.y || 0, w: width, h: height, deltaW: deltaW, deltaH: deltaH, contentW: width - deltaW, contentH: height - deltaH, innerW: width - deltaW, innerH: height - deltaH, startMinWidth: startMinWidth || 0, startMinHeight: startMinHeight || 0, minW: Math.min(minWidth, maxW), minH: Math.min(minHeight, maxH), maxW: maxW, maxH: maxH, autoResize: autoResize, scrollW: 0 }; self._lastLayoutRect = {}; return layoutRect; }, layoutRect: function (newRect) { var self = this; var curRect = self._layoutRect, lastLayoutRect, size, deltaWidth, deltaHeight, repaintControls; if (!curRect) { curRect = self.initLayoutRect(); } if (newRect) { deltaWidth = curRect.deltaW; deltaHeight = curRect.deltaH; if (newRect.x !== undefined) { curRect.x = newRect.x; } if (newRect.y !== undefined) { curRect.y = newRect.y; } if (newRect.minW !== undefined) { curRect.minW = newRect.minW; } if (newRect.minH !== undefined) { curRect.minH = newRect.minH; } size = newRect.w; if (size !== undefined) { size = size < curRect.minW ? curRect.minW : size; size = size > curRect.maxW ? curRect.maxW : size; curRect.w = size; curRect.innerW = size - deltaWidth; } size = newRect.h; if (size !== undefined) { size = size < curRect.minH ? curRect.minH : size; size = size > curRect.maxH ? curRect.maxH : size; curRect.h = size; curRect.innerH = size - deltaHeight; } size = newRect.innerW; if (size !== undefined) { size = size < curRect.minW - deltaWidth ? curRect.minW - deltaWidth : size; size = size > curRect.maxW - deltaWidth ? curRect.maxW - deltaWidth : size; curRect.innerW = size; curRect.w = size + deltaWidth; } size = newRect.innerH; if (size !== undefined) { size = size < curRect.minH - deltaHeight ? curRect.minH - deltaHeight : size; size = size > curRect.maxH - deltaHeight ? curRect.maxH - deltaHeight : size; curRect.innerH = size; curRect.h = size + deltaHeight; } if (newRect.contentW !== undefined) { curRect.contentW = newRect.contentW; } if (newRect.contentH !== undefined) { curRect.contentH = newRect.contentH; } lastLayoutRect = self._lastLayoutRect; if (lastLayoutRect.x !== curRect.x || lastLayoutRect.y !== curRect.y || lastLayoutRect.w !== curRect.w || lastLayoutRect.h !== curRect.h) { repaintControls = Control.repaintControls; if (repaintControls) { if (repaintControls.map && !repaintControls.map[self._id]) { repaintControls.push(self); repaintControls.map[self._id] = true; } } lastLayoutRect.x = curRect.x; lastLayoutRect.y = curRect.y; lastLayoutRect.w = curRect.w; lastLayoutRect.h = curRect.h; } return self; } return curRect; }, repaint: function () { var self = this; var style, bodyStyle, bodyElm, rect, borderBox; var borderW, borderH, lastRepaintRect, round, value; round = !domGlobals.document.createRange ? Math.round : function (value) { return value; }; style = self.getEl().style; rect = self._layoutRect; lastRepaintRect = self._lastRepaintRect || {}; borderBox = self.borderBox; borderW = borderBox.left + borderBox.right; borderH = borderBox.top + borderBox.bottom; if (rect.x !== lastRepaintRect.x) { style.left = round(rect.x) + 'px'; lastRepaintRect.x = rect.x; } if (rect.y !== lastRepaintRect.y) { style.top = round(rect.y) + 'px'; lastRepaintRect.y = rect.y; } if (rect.w !== lastRepaintRect.w) { value = round(rect.w - borderW); style.width = (value >= 0 ? value : 0) + 'px'; lastRepaintRect.w = rect.w; } if (rect.h !== lastRepaintRect.h) { value = round(rect.h - borderH); style.height = (value >= 0 ? value : 0) + 'px'; lastRepaintRect.h = rect.h; } if (self._hasBody && rect.innerW !== lastRepaintRect.innerW) { value = round(rect.innerW); bodyElm = self.getEl('body'); if (bodyElm) { bodyStyle = bodyElm.style; bodyStyle.width = (value >= 0 ? value : 0) + 'px'; } lastRepaintRect.innerW = rect.innerW; } if (self._hasBody && rect.innerH !== lastRepaintRect.innerH) { value = round(rect.innerH); bodyElm = bodyElm || self.getEl('body'); if (bodyElm) { bodyStyle = bodyStyle || bodyElm.style; bodyStyle.height = (value >= 0 ? value : 0) + 'px'; } lastRepaintRect.innerH = rect.innerH; } self._lastRepaintRect = lastRepaintRect; self.fire('repaint', {}, false); }, updateLayoutRect: function () { var self = this; self.parent()._lastRect = null; funcs.css(self.getEl(), { width: '', height: '' }); self._layoutRect = self._lastRepaintRect = self._lastLayoutRect = null; self.initLayoutRect(); }, on: function (name, callback) { var self = this; function resolveCallbackName(name) { var callback, scope; if (typeof name !== 'string') { return name; } return function (e) { if (!callback) { self.parentsAndSelf().each(function (ctrl) { var callbacks = ctrl.settings.callbacks; if (callbacks && (callback = callbacks[name])) { scope = ctrl; return false; } }); } if (!callback) { e.action = name; this.fire('execute', e); return; } return callback.call(scope, e); }; } getEventDispatcher(self).on(name, resolveCallbackName(callback)); return self; }, off: function (name, callback) { getEventDispatcher(this).off(name, callback); return this; }, fire: function (name, args, bubble) { var self = this; args = args || {}; if (!args.control) { args.control = self; } args = getEventDispatcher(self).fire(name, args); if (bubble !== false && self.parent) { var parent = self.parent(); while (parent && !args.isPropagationStopped()) { parent.fire(name, args, false); parent = parent.parent(); } } return args; }, hasEventListeners: function (name) { return getEventDispatcher(this).has(name); }, parents: function (selector) { var self = this; var ctrl, parents = new Collection$2(); for (ctrl = self.parent(); ctrl; ctrl = ctrl.parent()) { parents.add(ctrl); } if (selector) { parents = parents.filter(selector); } return parents; }, parentsAndSelf: function (selector) { return new Collection$2(this).add(this.parents(selector)); }, next: function () { var parentControls = this.parent().items(); return parentControls[parentControls.indexOf(this) + 1]; }, prev: function () { var parentControls = this.parent().items(); return parentControls[parentControls.indexOf(this) - 1]; }, innerHtml: function (html) { this.$el.html(html); return this; }, getEl: function (suffix) { var id = suffix ? this._id + '-' + suffix : this._id; if (!this._elmCache[id]) { this._elmCache[id] = global$7('#' + id)[0]; } return this._elmCache[id]; }, show: function () { return this.visible(true); }, hide: function () { return this.visible(false); }, focus: function () { try { this.getEl().focus(); } catch (ex) { } return this; }, blur: function () { this.getEl().blur(); return this; }, aria: function (name, value) { var self = this, elm = self.getEl(self.ariaTarget); if (typeof value === 'undefined') { return self._aria[name]; } self._aria[name] = value; if (self.state.get('rendered')) { elm.setAttribute(name === 'role' ? name : 'aria-' + name, value); } return self; }, encode: function (text, translate) { if (translate !== false) { text = this.translate(text); } return (text || '').replace(/[&<>"]/g, function (match) { return '&#' + match.charCodeAt(0) + ';'; }); }, translate: function (text) { return Control.translate ? Control.translate(text) : text; }, before: function (items) { var self = this, parent = self.parent(); if (parent) { parent.insert(items, parent.items().indexOf(self), true); } return self; }, after: function (items) { var self = this, parent = self.parent(); if (parent) { parent.insert(items, parent.items().indexOf(self)); } return self; }, remove: function () { var self = this; var elm = self.getEl(); var parent = self.parent(); var newItems, i; if (self.items) { var controls = self.items().toArray(); i = controls.length; while (i--) { controls[i].remove(); } } if (parent && parent.items) { newItems = []; parent.items().each(function (item) { if (item !== self) { newItems.push(item); } }); parent.items().set(newItems); parent._lastRect = null; } if (self._eventsRoot && self._eventsRoot === self) { global$7(elm).off(); } var lookup = self.getRoot().controlIdLookup; if (lookup) { delete lookup[self._id]; } if (elm && elm.parentNode) { elm.parentNode.removeChild(elm); } self.state.set('rendered', false); self.state.destroy(); self.fire('remove'); return self; }, renderBefore: function (elm) { global$7(elm).before(this.renderHtml()); this.postRender(); return this; }, renderTo: function (elm) { global$7(elm || this.getContainerElm()).append(this.renderHtml()); this.postRender(); return this; }, preRender: function () { }, render: function () { }, renderHtml: function () { return '<div id="' + this._id + '" class="' + this.classes + '"></div>'; }, postRender: function () { var self = this; var settings = self.settings; var elm, box, parent, name, parentEventsRoot; self.$el = global$7(self.getEl()); self.state.set('rendered', true); for (name in settings) { if (name.indexOf('on') === 0) { self.on(name.substr(2), settings[name]); } } if (self._eventsRoot) { for (parent = self.parent(); !parentEventsRoot && parent; parent = parent.parent()) { parentEventsRoot = parent._eventsRoot; } if (parentEventsRoot) { for (name in parentEventsRoot._nativeEvents) { self._nativeEvents[name] = true; } } } bindPendingEvents(self); if (settings.style) { elm = self.getEl(); if (elm) { elm.setAttribute('style', settings.style); elm.style.cssText = settings.style; } } if (self.settings.border) { box = self.borderBox; self.$el.css({ 'border-top-width': box.top, 'border-right-width': box.right, 'border-bottom-width': box.bottom, 'border-left-width': box.left }); } var root = self.getRoot(); if (!root.controlIdLookup) { root.controlIdLookup = {}; } root.controlIdLookup[self._id] = self; for (var key in self._aria) { self.aria(key, self._aria[key]); } if (self.state.get('visible') === false) { self.getEl().style.display = 'none'; } self.bindStates(); self.state.on('change:visible', function (e) { var state = e.value; var parentCtrl; if (self.state.get('rendered')) { self.getEl().style.display = state === false ? 'none' : ''; self.getEl().getBoundingClientRect(); } parentCtrl = self.parent(); if (parentCtrl) { parentCtrl._lastRect = null; } self.fire(state ? 'show' : 'hide'); ReflowQueue.add(self); }); self.fire('postrender', {}, false); }, bindStates: function () { }, scrollIntoView: function (align) { function getOffset(elm, rootElm) { var x, y, parent = elm; x = y = 0; while (parent && parent !== rootElm && parent.nodeType) { x += parent.offsetLeft || 0; y += parent.offsetTop || 0; parent = parent.offsetParent; } return { x: x, y: y }; } var elm = this.getEl(), parentElm = elm.parentNode; var x, y, width, height, parentWidth, parentHeight; var pos = getOffset(elm, parentElm); x = pos.x; y = pos.y; width = elm.offsetWidth; height = elm.offsetHeight; parentWidth = parentElm.clientWidth; parentHeight = parentElm.clientHeight; if (align === 'end') { x -= parentWidth - width; y -= parentHeight - height; } else if (align === 'center') { x -= parentWidth / 2 - width / 2; y -= parentHeight / 2 - height / 2; } parentElm.scrollLeft = x; parentElm.scrollTop = y; return this; }, getRoot: function () { var ctrl = this, rootControl; var parents = []; while (ctrl) { if (ctrl.rootControl) { rootControl = ctrl.rootControl; break; } parents.push(ctrl); rootControl = ctrl; ctrl = ctrl.parent(); } if (!rootControl) { rootControl = this; } var i = parents.length; while (i--) { parents[i].rootControl = rootControl; } return rootControl; }, reflow: function () { ReflowQueue.remove(this); var parent = this.parent(); if (parent && parent._layout && !parent._layout.isNative()) { parent.reflow(); } return this; } }; global$4.each('text title visible disabled active value'.split(' '), function (name) { proto$1[name] = function (value) { if (arguments.length === 0) { return this.state.get(name); } if (typeof value !== 'undefined') { this.state.set(name, value); } return this; }; }); Control = global$8.extend(proto$1); function getEventDispatcher(obj) { if (!obj._eventDispatcher) { obj._eventDispatcher = new global$9({ scope: obj, toggleEvent: function (name, state) { if (state && global$9.isNative(name)) { if (!obj._nativeEvents) { obj._nativeEvents = {}; } obj._nativeEvents[name] = true; if (obj.state.get('rendered')) { bindPendingEvents(obj); } } } }); } return obj._eventDispatcher; } function bindPendingEvents(eventCtrl) { var i, l, parents, eventRootCtrl, nativeEvents, name; function delegate(e) { var control = eventCtrl.getParentCtrl(e.target); if (control) { control.fire(e.type, e); } } function mouseLeaveHandler() { var ctrl = eventRootCtrl._lastHoverCtrl; if (ctrl) { ctrl.fire('mouseleave', { target: ctrl.getEl() }); ctrl.parents().each(function (ctrl) { ctrl.fire('mouseleave', { target: ctrl.getEl() }); }); eventRootCtrl._lastHoverCtrl = null; } } function mouseEnterHandler(e) { var ctrl = eventCtrl.getParentCtrl(e.target), lastCtrl = eventRootCtrl._lastHoverCtrl, idx = 0, i, parents, lastParents; if (ctrl !== lastCtrl) { eventRootCtrl._lastHoverCtrl = ctrl; parents = ctrl.parents().toArray().reverse(); parents.push(ctrl); if (lastCtrl) { lastParents = lastCtrl.parents().toArray().reverse(); lastParents.push(lastCtrl); for (idx = 0; idx < lastParents.length; idx++) { if (parents[idx] !== lastParents[idx]) { break; } } for (i = lastParents.length - 1; i >= idx; i--) { lastCtrl = lastParents[i]; lastCtrl.fire('mouseleave', { target: lastCtrl.getEl() }); } } for (i = idx; i < parents.length; i++) { ctrl = parents[i]; ctrl.fire('mouseenter', { target: ctrl.getEl() }); } } } function fixWheelEvent(e) { e.preventDefault(); if (e.type === 'mousewheel') { e.deltaY = -1 / 40 * e.wheelDelta; if (e.wheelDeltaX) { e.deltaX = -1 / 40 * e.wheelDeltaX; } } else { e.deltaX = 0; e.deltaY = e.detail; } e = eventCtrl.fire('wheel', e); } nativeEvents = eventCtrl._nativeEvents; if (nativeEvents) { parents = eventCtrl.parents().toArray(); parents.unshift(eventCtrl); for (i = 0, l = parents.length; !eventRootCtrl && i < l; i++) { eventRootCtrl = parents[i]._eventsRoot; } if (!eventRootCtrl) { eventRootCtrl = parents[parents.length - 1] || eventCtrl; } eventCtrl._eventsRoot = eventRootCtrl; for (l = i, i = 0; i < l; i++) { parents[i]._eventsRoot = eventRootCtrl; } var eventRootDelegates = eventRootCtrl._delegates; if (!eventRootDelegates) { eventRootDelegates = eventRootCtrl._delegates = {}; } for (name in nativeEvents) { if (!nativeEvents) { return false; } if (name === 'wheel' && !hasWheelEventSupport) { if (hasMouseWheelEventSupport) { global$7(eventCtrl.getEl()).on('mousewheel', fixWheelEvent); } else { global$7(eventCtrl.getEl()).on('DOMMouseScroll', fixWheelEvent); } continue; } if (name === 'mouseenter' || name === 'mouseleave') { if (!eventRootCtrl._hasMouseEnter) { global$7(eventRootCtrl.getEl()).on('mouseleave', mouseLeaveHandler).on('mouseover', mouseEnterHandler); eventRootCtrl._hasMouseEnter = 1; } } else if (!eventRootDelegates[name]) { global$7(eventRootCtrl.getEl()).on(name, delegate); eventRootDelegates[name] = true; } nativeEvents[name] = false; } } } var Control$1 = Control; var isStatic = function (elm) { return funcs.getRuntimeStyle(elm, 'position') === 'static'; }; var isFixed = function (ctrl) { return ctrl.state.get('fixed'); }; function calculateRelativePosition(ctrl, targetElm, rel) { var ctrlElm, pos, x, y, selfW, selfH, targetW, targetH, viewport, size; viewport = getWindowViewPort(); pos = funcs.getPos(targetElm, UiContainer.getUiContainer(ctrl)); x = pos.x; y = pos.y; if (isFixed(ctrl) && isStatic(domGlobals.document.body)) { x -= viewport.x; y -= viewport.y; } ctrlElm = ctrl.getEl(); size = funcs.getSize(ctrlElm); selfW = size.width; selfH = size.height; size = funcs.getSize(targetElm); targetW = size.width; targetH = size.height; rel = (rel || '').split(''); if (rel[0] === 'b') { y += targetH; } if (rel[1] === 'r') { x += targetW; } if (rel[0] === 'c') { y += Math.round(targetH / 2); } if (rel[1] === 'c') { x += Math.round(targetW / 2); } if (rel[3] === 'b') { y -= selfH; } if (rel[4] === 'r') { x -= selfW; } if (rel[3] === 'c') { y -= Math.round(selfH / 2); } if (rel[4] === 'c') { x -= Math.round(selfW / 2); } return { x: x, y: y, w: selfW, h: selfH }; } var getUiContainerViewPort = function (customUiContainer) { return { x: 0, y: 0, w: customUiContainer.scrollWidth - 1, h: customUiContainer.scrollHeight - 1 }; }; var getWindowViewPort = function () { var win = domGlobals.window; var x = Math.max(win.pageXOffset, domGlobals.document.body.scrollLeft, domGlobals.document.documentElement.scrollLeft); var y = Math.max(win.pageYOffset, domGlobals.document.body.scrollTop, domGlobals.document.documentElement.scrollTop); var w = win.innerWidth || domGlobals.document.documentElement.clientWidth; var h = win.innerHeight || domGlobals.document.documentElement.clientHeight; return { x: x, y: y, w: w, h: h }; }; var getViewPortRect = function (ctrl) { var customUiContainer = UiContainer.getUiContainer(ctrl); return customUiContainer && !isFixed(ctrl) ? getUiContainerViewPort(customUiContainer) : getWindowViewPort(); }; var Movable = { testMoveRel: function (elm, rels) { var viewPortRect = getViewPortRect(this); for (var i = 0; i < rels.length; i++) { var pos = calculateRelativePosition(this, elm, rels[i]); if (isFixed(this)) { if (pos.x > 0 && pos.x + pos.w < viewPortRect.w && pos.y > 0 && pos.y + pos.h < viewPortRect.h) { return rels[i]; } } else { 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) { return rels[i]; } } } return rels[0]; }, moveRel: function (elm, rel) { if (typeof rel !== 'string') { rel = this.testMoveRel(elm, rel); } var pos = calculateRelativePosition(this, elm, rel); return this.moveTo(pos.x, pos.y); }, moveBy: function (dx, dy) { var self = this, rect = self.layoutRect(); self.moveTo(rect.x + dx, rect.y + dy); return self; }, moveTo: function (x, y) { var self = this; function constrain(value, max, size) { if (value < 0) { return 0; } if (value + size > max) { value = max - size; return value < 0 ? 0 : value; } return value; } if (self.settings.constrainToViewport) { var viewPortRect = getViewPortRect(this); var layoutRect = self.layoutRect(); x = constrain(x, viewPortRect.w + viewPortRect.x, layoutRect.w); y = constrain(y, viewPortRect.h + viewPortRect.y, layoutRect.h); } var uiContainer = UiContainer.getUiContainer(self); if (uiContainer && isStatic(uiContainer) && !isFixed(self)) { x -= uiContainer.scrollLeft; y -= uiContainer.scrollTop; } if (uiContainer) { x += 1; y += 1; } if (self.state.get('rendered')) { self.layoutRect({ x: x, y: y }).repaint(); } else { self.settings.x = x; self.settings.y = y; } self.fire('move', { x: x, y: y }); return self; } }; var Tooltip = Control$1.extend({ Mixins: [Movable], Defaults: { classes: 'widget tooltip tooltip-n' }, renderHtml: function () { var self = this, prefix = self.classPrefix; 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>'; }, bindStates: function () { var self = this; self.state.on('change:text', function (e) { self.getEl().lastChild.innerHTML = self.encode(e.value); }); return self._super(); }, repaint: function () { var self = this; var style, rect; style = self.getEl().style; rect = self._layoutRect; style.left = rect.x + 'px'; style.top = rect.y + 'px'; style.zIndex = 65535 + 65535; } }); var Widget = Control$1.extend({ init: function (settings) { var self = this; self._super(settings); settings = self.settings; self.canFocus = true; if (settings.tooltip && Widget.tooltips !== false) { self.on('mouseenter', function (e) { var tooltip = self.tooltip().moveTo(-65535); if (e.control === self) { var rel = tooltip.text(settings.tooltip).show().testMoveRel(self.getEl(), [ 'bc-tc', 'bc-tl', 'bc-tr' ]); tooltip.classes.toggle('tooltip-n', rel === 'bc-tc'); tooltip.classes.toggle('tooltip-nw', rel === 'bc-tl'); tooltip.classes.toggle('tooltip-ne', rel === 'bc-tr'); tooltip.moveRel(self.getEl(), rel); } else { tooltip.hide(); } }); self.on('mouseleave mousedown click', function () { self.tooltip().remove(); self._tooltip = null; }); } self.aria('label', settings.ariaLabel || settings.tooltip); }, tooltip: function () { if (!this._tooltip) { this._tooltip = new Tooltip({ type: 'tooltip' }); UiContainer.inheritUiContainer(this, this._tooltip); this._tooltip.renderTo(); } return this._tooltip; }, postRender: function () { var self = this, settings = self.settings; self._super(); if (!self.parent() && (settings.width || settings.height)) { self.initLayoutRect(); self.repaint(); } if (settings.autofocus) { self.focus(); } }, bindStates: function () { var self = this; function disable(state) { self.aria('disabled', state); self.classes.toggle('disabled', state); } function active(state) { self.aria('pressed', state); self.classes.toggle('active', state); } self.state.on('change:disabled', function (e) { disable(e.value); }); self.state.on('change:active', function (e) { active(e.value); }); if (self.state.get('disabled')) { disable(true); } if (self.state.get('active')) { active(true); } return self._super(); }, remove: function () { this._super(); if (this._tooltip) { this._tooltip.remove(); this._tooltip = null; } } }); var Progress = Widget.extend({ Defaults: { value: 0 }, init: function (settings) { var self = this; self._super(settings); self.classes.add('progress'); if (!self.settings.filter) { self.settings.filter = function (value) { return Math.round(value); }; } }, renderHtml: function () { var self = this, id = self._id, prefix = this.classPrefix; 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>'; }, postRender: function () { var self = this; self._super(); self.value(self.settings.value); return self; }, bindStates: function () { var self = this; function setValue(value) { value = self.settings.filter(value); self.getEl().lastChild.innerHTML = value + '%'; self.getEl().firstChild.firstChild.style.width = value + '%'; } self.state.on('change:value', function (e) { setValue(e.value); }); setValue(self.state.get('value')); return self._super(); } }); var updateLiveRegion = function (ctx, text) { ctx.getEl().lastChild.textContent = text + (ctx.progressBar ? ' ' + ctx.progressBar.value() + '%' : ''); }; var Notification = Control$1.extend({ Mixins: [Movable], Defaults: { classes: 'widget notification' }, init: function (settings) { var self = this; self._super(settings); self.maxWidth = settings.maxWidth; if (settings.text) { self.text(settings.text); } if (settings.icon) { self.icon = settings.icon; } if (settings.color) { self.color = settings.color; } if (settings.type) { self.classes.add('notification-' + settings.type); } if (settings.timeout && (settings.timeout < 0 || settings.timeout > 0) && !settings.closeButton) { self.closeButton = false; } else { self.classes.add('has-close'); self.closeButton = true; } if (settings.progressBar) { self.progressBar = new Progress(); } self.on('click', function (e) { if (e.target.className.indexOf(self.classPrefix + 'close') !== -1) { self.close(); } }); }, renderHtml: function () { var self = this; var prefix = self.classPrefix; var icon = '', closeButton = '', progressBar = '', notificationStyle = ''; if (self.icon) { icon = '<i class="' + prefix + 'ico' + ' ' + prefix + 'i-' + self.icon + '"></i>'; } notificationStyle = ' style="max-width: ' + self.maxWidth + 'px;' + (self.color ? 'background-color: ' + self.color + ';"' : '"'); if (self.closeButton) { closeButton = '<button type="button" class="' + prefix + 'close" aria-hidden="true">\xD7</button>'; } if (self.progressBar) { progressBar = self.progressBar.renderHtml(); } 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>'; }, postRender: function () { var self = this; global$3.setTimeout(function () { self.$el.addClass(self.classPrefix + 'in'); updateLiveRegion(self, self.state.get('text')); }, 100); return self._super(); }, bindStates: function () { var self = this; self.state.on('change:text', function (e) { self.getEl().firstChild.innerHTML = e.value; updateLiveRegion(self, e.value); }); if (self.progressBar) { self.progressBar.bindStates(); self.progressBar.state.on('change:value', function (e) { updateLiveRegion(self, self.state.get('text')); }); } return self._super(); }, close: function () { var self = this; if (!self.fire('close').isDefaultPrevented()) { self.remove(); } return self; }, repaint: function () { var self = this; var style, rect; style = self.getEl().style; rect = self._layoutRect; style.left = rect.x + 'px'; style.top = rect.y + 'px'; style.zIndex = 65535 - 1; } }); function NotificationManagerImpl (editor) { var getEditorContainer = function (editor) { return editor.inline ? editor.getElement() : editor.getContentAreaContainer(); }; var getContainerWidth = function () { var container = getEditorContainer(editor); return funcs.getSize(container).width; }; var prePositionNotifications = function (notifications) { each(notifications, function (notification) { notification.moveTo(0, 0); }); }; var positionNotifications = function (notifications) { if (notifications.length > 0) { var firstItem = notifications.slice(0, 1)[0]; var container = getEditorContainer(editor); firstItem.moveRel(container, 'tc-tc'); each(notifications, function (notification, index) { if (index > 0) { notification.moveRel(notifications[index - 1].getEl(), 'bc-tc'); } }); } }; var reposition = function (notifications) { prePositionNotifications(notifications); positionNotifications(notifications); }; var open = function (args, closeCallback) { var extendedArgs = global$4.extend(args, { maxWidth: getContainerWidth() }); var notif = new Notification(extendedArgs); notif.args = extendedArgs; if (extendedArgs.timeout > 0) { notif.timer = setTimeout(function () { notif.close(); closeCallback(); }, extendedArgs.timeout); } notif.on('close', function () { closeCallback(); }); notif.renderTo(); return notif; }; var close = function (notification) { notification.close(); }; var getArgs = function (notification) { return notification.args; }; return { open: open, close: close, reposition: reposition, getArgs: getArgs }; } function getDocumentSize(doc) { var documentElement, body, scrollWidth, clientWidth; var offsetWidth, scrollHeight, clientHeight, offsetHeight; var max = Math.max; documentElement = doc.documentElement; body = doc.body; scrollWidth = max(documentElement.scrollWidth, body.scrollWidth); clientWidth = max(documentElement.clientWidth, body.clientWidth); offsetWidth = max(documentElement.offsetWidth, body.offsetWidth); scrollHeight = max(documentElement.scrollHeight, body.scrollHeight); clientHeight = max(documentElement.clientHeight, body.clientHeight); offsetHeight = max(documentElement.offsetHeight, body.offsetHeight); return { width: scrollWidth < offsetWidth ? clientWidth : scrollWidth, height: scrollHeight < offsetHeight ? clientHeight : scrollHeight }; } function updateWithTouchData(e) { var keys, i; if (e.changedTouches) { keys = 'screenX screenY pageX pageY clientX clientY'.split(' '); for (i = 0; i < keys.length; i++) { e[keys[i]] = e.changedTouches[0][keys[i]]; } } } function DragHelper (id, settings) { var $eventOverlay; var doc = settings.document || domGlobals.document; var downButton; var start, stop, drag, startX, startY; settings = settings || {}; var handleElement = doc.getElementById(settings.handle || id); start = function (e) { var docSize = getDocumentSize(doc); var handleElm, cursor; updateWithTouchData(e); e.preventDefault(); downButton = e.button; handleElm = handleElement; startX = e.screenX; startY = e.screenY; if (domGlobals.window.getComputedStyle) { cursor = domGlobals.window.getComputedStyle(handleElm, null).getPropertyValue('cursor'); } else { cursor = handleElm.runtimeStyle.cursor; } $eventOverlay = global$7('<div></div>').css({ position: 'absolute', top: 0, left: 0, width: docSize.width, height: docSize.height, zIndex: 2147483647, opacity: 0.0001, cursor: cursor }).appendTo(doc.body); global$7(doc).on('mousemove touchmove', drag).on('mouseup touchend', stop); settings.start(e); }; drag = function (e) { updateWithTouchData(e); if (e.button !== downButton) { return stop(e); } e.deltaX = e.screenX - startX; e.deltaY = e.screenY - startY; e.preventDefault(); settings.drag(e); }; stop = function (e) { updateWithTouchData(e); global$7(doc).off('mousemove touchmove', drag).off('mouseup touchend', stop); $eventOverlay.remove(); if (settings.stop) { settings.stop(e); } }; this.destroy = function () { global$7(handleElement).off(); }; global$7(handleElement).on('mousedown touchstart', start); } var global$b = tinymce.util.Tools.resolve('tinymce.ui.Factory'); var hasTabstopData = function (elm) { return elm.getAttribute('data-mce-tabstop') ? true : false; }; function KeyboardNavigation (settings) { var root = settings.root; var focusedElement, focusedControl; function isElement(node) { return node && node.nodeType === 1; } try { focusedElement = domGlobals.document.activeElement; } catch (ex) { focusedElement = domGlobals.document.body; } focusedControl = root.getParentCtrl(focusedElement); function getRole(elm) { elm = elm || focusedElement; if (isElement(elm)) { return elm.getAttribute('role'); } return null; } function getParentRole(elm) { var role, parent = elm || focusedElement; while (parent = parent.parentNode) { if (role = getRole(parent)) { return role; } } } function getAriaProp(name) { var elm = focusedElement; if (isElement(elm)) { return elm.getAttribute('aria-' + name); } } function isTextInputElement(elm) { var tagName = elm.tagName.toUpperCase(); return tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT'; } function canFocus(elm) { if (isTextInputElement(elm) && !elm.hidden) { return true; } if (hasTabstopData(elm)) { return true; } if (/^(button|menuitem|checkbox|tab|menuitemcheckbox|option|gridcell|slider)$/.test(getRole(elm))) { return true; } return false; } function getFocusElements(elm) { var elements = []; function collect(elm) { if (elm.nodeType !== 1 || elm.style.display === 'none' || elm.disabled) { return; } if (canFocus(elm)) { elements.push(elm); } for (var i = 0; i < elm.childNodes.length; i++) { collect(elm.childNodes[i]); } } collect(elm || root.getEl()); return elements; } function getNavigationRoot(targetControl) { var navigationRoot, controls; targetControl = targetControl || focusedControl; controls = targetControl.parents().toArray(); controls.unshift(targetControl); for (var i = 0; i < controls.length; i++) { navigationRoot = controls[i]; if (navigationRoot.settings.ariaRoot) { break; } } return navigationRoot; } function focusFirst(targetControl) { var navigationRoot = getNavigationRoot(targetControl); var focusElements = getFocusElements(navigationRoot.getEl()); if (navigationRoot.settings.ariaRemember && 'lastAriaIndex' in navigationRoot) { moveFocusToIndex(navigationRoot.lastAriaIndex, focusElements); } else { moveFocusToIndex(0, focusElements); } } function moveFocusToIndex(idx, elements) { if (idx < 0) { idx = elements.length - 1; } else if (idx >= elements.length) { idx = 0; } if (elements[idx]) { elements[idx].focus(); } return idx; } function moveFocus(dir, elements) { var idx = -1; var navigationRoot = getNavigationRoot(); elements = elements || getFocusElements(navigationRoot.getEl()); for (var i = 0; i < elements.length; i++) { if (elements[i] === focusedElement) { idx = i; } } idx += dir; navigationRoot.lastAriaIndex = moveFocusToIndex(idx, elements); } function left() { var parentRole = getParentRole(); if (parentRole === 'tablist') { moveFocus(-1, getFocusElements(focusedElement.parentNode)); } else if (focusedControl.parent().submenu) { cancel(); } else { moveFocus(-1); } } function right() { var role = getRole(), parentRole = getParentRole(); if (parentRole === 'tablist') { moveFocus(1, getFocusElements(focusedElement.parentNode)); } else if (role === 'menuitem' && parentRole === 'menu' && getAriaProp('haspopup')) { enter(); } else { moveFocus(1); } } function up() { moveFocus(-1); } function down() { var role = getRole(), parentRole = getParentRole(); if (role === 'menuitem' && parentRole === 'menubar') { enter(); } else if (role === 'button' && getAriaProp('haspopup')) { enter({ key: 'down' }); } else { moveFocus(1); } } function tab(e) { var parentRole = getParentRole(); if (parentRole === 'tablist') { var elm = getFocusElements(focusedControl.getEl('body'))[0]; if (elm) { elm.focus(); } } else { moveFocus(e.shiftKey ? -1 : 1); } } function cancel() { focusedControl.fire('cancel'); } function enter(aria) { aria = aria || {}; focusedControl.fire('click', { target: focusedElement, aria: aria }); } root.on('keydown', function (e) { function handleNonTabOrEscEvent(e, handler) { if (isTextInputElement(focusedElement) || hasTabstopData(focusedElement)) { return; } if (getRole(focusedElement) === 'slider') { return; } if (handler(e) !== false) { e.preventDefault(); } } if (e.isDefaultPrevented()) { return; } switch (e.keyCode) { case 37: handleNonTabOrEscEvent(e, left); break; case 39: handleNonTabOrEscEvent(e, right); break; case 38: handleNonTabOrEscEvent(e, up); break; case 40: handleNonTabOrEscEvent(e, down); break; case 27: cancel(); break; case 14: case 13: case 32: handleNonTabOrEscEvent(e, enter); break; case 9: tab(e); e.preventDefault(); break; } }); root.on('focusin', function (e) { focusedElement = e.target; focusedControl = e.control; }); return { focusFirst: focusFirst }; } var selectorCache = {}; var Container = Control$1.extend({ init: function (settings) { var self = this; self._super(settings); settings = self.settings; if (settings.fixed) { self.state.set('fixed', true); } self._items = new Collection$2(); if (self.isRtl()) { self.classes.add('rtl'); } self.bodyClasses = new ClassList(function () { if (self.state.get('rendered')) { self.getEl('body').className = this.toString(); } }); self.bodyClasses.prefix = self.classPrefix; self.classes.add('container'); self.bodyClasses.add('container-body'); if (settings.containerCls) { self.classes.add(settings.containerCls); } self._layout = global$b.create((settings.layout || '') + 'layout'); if (self.settings.items) { self.add(self.settings.items); } else { self.add(self.render()); } self._hasBody = true; }, items: function () { return this._items; }, find: function (selector) { selector = selectorCache[selector] = selectorCache[selector] || new Selector(selector); return selector.find(this); }, add: function (items) { var self = this; self.items().add(self.create(items)).parent(self); return self; }, focus: function (keyboard) { var self = this; var focusCtrl, keyboardNav, items; if (keyboard) { keyboardNav = self.keyboardNav || self.parents().eq(-1)[0].keyboardNav; if (keyboardNav) { keyboardNav.focusFirst(self); return; } } items = self.find('*'); if (self.statusbar) { items.add(self.statusbar.items()); } items.each(function (ctrl) { if (ctrl.settings.autofocus) { focusCtrl = null; return false; } if (ctrl.canFocus) { focusCtrl = focusCtrl || ctrl; } }); if (focusCtrl) { focusCtrl.focus(); } return self; }, replace: function (oldItem, newItem) { var ctrlElm; var items = this.items(); var i = items.length; while (i--) { if (items[i] === oldItem) { items[i] = newItem; break; } } if (i >= 0) { ctrlElm = newItem.getEl(); if (ctrlElm) { ctrlElm.parentNode.removeChild(ctrlElm); } ctrlElm = oldItem.getEl(); if (ctrlElm) { ctrlElm.parentNode.removeChild(ctrlElm); } } newItem.parent(this); }, create: function (items) { var self = this; var settings; var ctrlItems = []; if (!global$4.isArray(items)) { items = [items]; } global$4.each(items, function (item) { if (item) { if (!(item instanceof Control$1)) { if (typeof item === 'string') { item = { type: item }; } settings = global$4.extend({}, self.settings.defaults, item); item.type = settings.type = settings.type || item.type || self.settings.defaultType || (settings.defaults ? settings.defaults.type : null); item = global$b.create(settings); } ctrlItems.push(item); } }); return ctrlItems; }, renderNew: function () { var self = this; self.items().each(function (ctrl, index) { var containerElm; ctrl.parent(self); if (!ctrl.state.get('rendered')) { containerElm = self.getEl('body'); if (containerElm.hasChildNodes() && index <= containerElm.childNodes.length - 1) { global$7(containerElm.childNodes[index]).before(ctrl.renderHtml()); } else { global$7(containerElm).append(ctrl.renderHtml()); } ctrl.postRender(); ReflowQueue.add(ctrl); } }); self._layout.applyClasses(self.items().filter(':visible')); self._lastRect = null; return self; }, append: function (items) { return this.add(items).renderNew(); }, prepend: function (items) { var self = this; self.items().set(self.create(items).concat(self.items().toArray())); return self.renderNew(); }, insert: function (items, index, before) { var self = this; var curItems, beforeItems, afterItems; items = self.create(items); curItems = self.items(); if (!before && index < curItems.length - 1) { index += 1; } if (index >= 0 && index < curItems.length) { beforeItems = curItems.slice(0, index).toArray(); afterItems = curItems.slice(index).toArray(); curItems.set(beforeItems.concat(items, afterItems)); } return self.renderNew(); }, fromJSON: function (data) { var self = this; for (var name in data) { self.find('#' + name).value(data[name]); } return self; }, toJSON: function () { var self = this, data = {}; self.find('*').each(function (ctrl) { var name = ctrl.name(), value = ctrl.value(); if (name && typeof value !== 'undefined') { data[name] = value; } }); return data; }, renderHtml: function () { var self = this, layout = self._layout, role = this.settings.role; self.preRender(); layout.preRender(self); 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>'; }, postRender: function () { var self = this; var box; self.items().exec('postRender'); self._super(); self._layout.postRender(self); self.state.set('rendered', true); if (self.settings.style) { self.$el.css(self.settings.style); } if (self.settings.border) { box = self.borderBox; self.$el.css({ 'border-top-width': box.top, 'border-right-width': box.right, 'border-bottom-width': box.bottom, 'border-left-width': box.left }); } if (!self.parent()) { self.keyboardNav = KeyboardNavigation({ root: self }); } return self; }, initLayoutRect: function () { var self = this, layoutRect = self._super(); self._layout.recalc(self); return layoutRect; }, recalc: function () { var self = this; var rect = self._layoutRect; var lastRect = self._lastRect; if (!lastRect || lastRect.w !== rect.w || lastRect.h !== rect.h) { self._layout.recalc(self); rect = self.layoutRect(); self._lastRect = { x: rect.x, y: rect.y, w: rect.w, h: rect.h }; return true; } }, reflow: function () { var i; ReflowQueue.remove(this); if (this.visible()) { Control$1.repaintControls = []; Control$1.repaintControls.map = {}; this.recalc(); i = Control$1.repaintControls.length; while (i--) { Control$1.repaintControls[i].repaint(); } if (this.settings.layout !== 'flow' && this.settings.layout !== 'stack') { this.repaint(); } Control$1.repaintControls = []; } return this; } }); var Scrollable = { init: function () { var self = this; self.on('repaint', self.renderScroll); }, renderScroll: function () { var self = this, margin = 2; function repaintScroll() { var hasScrollH, hasScrollV, bodyElm; function repaintAxis(axisName, posName, sizeName, contentSizeName, hasScroll, ax) { var containerElm, scrollBarElm, scrollThumbElm; var containerSize, scrollSize, ratio, rect; var posNameLower, sizeNameLower; scrollBarElm = self.getEl('scroll' + axisName); if (scrollBarElm) { posNameLower = posName.toLowerCase(); sizeNameLower = sizeName.toLowerCase(); global$7(self.getEl('absend')).css(posNameLower, self.layoutRect()[contentSizeName] - 1); if (!hasScroll) { global$7(scrollBarElm).css('display', 'none'); return; } global$7(scrollBarElm).css('display', 'block'); containerElm = self.getEl('body'); scrollThumbElm = self.getEl('scroll' + axisName + 't'); containerSize = containerElm['client' + sizeName] - margin * 2; containerSize -= hasScrollH && hasScrollV ? scrollBarElm['client' + ax] : 0; scrollSize = containerElm['scroll' + sizeName]; ratio = containerSize / scrollSize; rect = {}; rect[posNameLower] = containerElm['offset' + posName] + margin; rect[sizeNameLower] = containerSize; global$7(scrollBarElm).css(rect); rect = {}; rect[posNameLower] = containerElm['scroll' + posName] * ratio; rect[sizeNameLower] = containerSize * ratio; global$7(scrollThumbElm).css(rect); } } bodyElm = self.getEl('body'); hasScrollH = bodyElm.scrollWidth > bodyElm.clientWidth; hasScrollV = bodyElm.scrollHeight > bodyElm.clientHeight; repaintAxis('h', 'Left', 'Width', 'contentW', hasScrollH, 'Height'); repaintAxis('v', 'Top', 'Height', 'contentH', hasScrollV, 'Width'); } function addScroll() { function addScrollAxis(axisName, posName, sizeName, deltaPosName, ax) { var scrollStart; var axisId = self._id + '-scroll' + axisName, prefix = self.classPrefix; global$7(self.getEl()).append('<div id="' + axisId + '" class="' + prefix + 'scrollbar ' + prefix + 'scrollbar-' + axisName + '">' + '<div id="' + axisId + 't" class="' + prefix + 'scrollbar-thumb"></div>' + '</div>'); self.draghelper = new DragHelper(axisId + 't', { start: function () { scrollStart = self.getEl('body')['scroll' + posName]; global$7('#' + axisId).addClass(prefix + 'active'); }, drag: function (e) { var ratio, hasScrollH, hasScrollV, containerSize; var layoutRect = self.layoutRect(); hasScrollH = layoutRect.contentW > layoutRect.innerW; hasScrollV = layoutRect.contentH > layoutRect.innerH; containerSize = self.getEl('body')['client' + sizeName] - margin * 2; containerSize -= hasScrollH && hasScrollV ? self.getEl('scroll' + axisName)['client' + ax] : 0; ratio = containerSize / self.getEl('body')['scroll' + sizeName]; self.getEl('body')['scroll' + posName] = scrollStart + e['delta' + deltaPosName] / ratio; }, stop: function () { global$7('#' + axisId).removeClass(prefix + 'active'); } }); } self.classes.add('scroll'); addScrollAxis('v', 'Top', 'Height', 'Y', 'Width'); addScrollAxis('h', 'Left', 'Width', 'X', 'Height'); } if (self.settings.autoScroll) { if (!self._hasScroll) { self._hasScroll = true; addScroll(); self.on('wheel', function (e) { var bodyEl = self.getEl('body'); bodyEl.scrollLeft += (e.deltaX || 0) * 10; bodyEl.scrollTop += e.deltaY * 10; repaintScroll(); }); global$7(self.getEl('body')).on('scroll', repaintScroll); } repaintScroll(); } } }; var Panel = Container.extend({ Defaults: { layout: 'fit', containerCls: 'panel' }, Mixins: [Scrollable], renderHtml: function () { var self = this; var layout = self._layout; var innerHtml = self.settings.html; self.preRender(); layout.preRender(self); if (typeof innerHtml === 'undefined') { innerHtml = '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + layout.renderHtml(self) + '</div>'; } else { if (typeof innerHtml === 'function') { innerHtml = innerHtml.call(self); } self._hasBody = false; } return '<div id="' + self._id + '" class="' + self.classes + '" hidefocus="1" tabindex="-1" role="group">' + (self._preBodyHtml || '') + innerHtml + '</div>'; } }); var Resizable = { resizeToContent: function () { this._layoutRect.autoResize = true; this._lastRect = null; this.reflow(); }, resizeTo: function (w, h) { if (w <= 1 || h <= 1) { var rect = funcs.getWindowSize(); w = w <= 1 ? w * rect.w : w; h = h <= 1 ? h * rect.h : h; } this._layoutRect.autoResize = false; return this.layoutRect({ minW: w, minH: h, w: w, h: h }).reflow(); }, resizeBy: function (dw, dh) { var self = this, rect = self.layoutRect(); return self.resizeTo(rect.w + dw, rect.h + dh); } }; var documentClickHandler, documentScrollHandler, windowResizeHandler; var visiblePanels = []; var zOrder = []; var hasModal; function isChildOf(ctrl, parent) { while (ctrl) { if (ctrl === parent) { return true; } ctrl = ctrl.parent(); } } function skipOrHidePanels(e) { var i = visiblePanels.length; while (i--) { var panel = visiblePanels[i], clickCtrl = panel.getParentCtrl(e.target); if (panel.settings.autohide) { if (clickCtrl) { if (isChildOf(clickCtrl, panel) || panel.parent() === clickCtrl) { continue; } } e = panel.fire('autohide', { target: e.target }); if (!e.isDefaultPrevented()) { panel.hide(); } } } } function bindDocumentClickHandler() { if (!documentClickHandler) { documentClickHandler = function (e) { if (e.button === 2) { return; } skipOrHidePanels(e); }; global$7(domGlobals.document).on('click touchstart', documentClickHandler); } } function bindDocumentScrollHandler() { if (!documentScrollHandler) { documentScrollHandler = function () { var i; i = visiblePanels.length; while (i--) { repositionPanel$1(visiblePanels[i]); } }; global$7(domGlobals.window).on('scroll', documentScrollHandler); } } function bindWindowResizeHandler() { if (!windowResizeHandler) { var docElm_1 = domGlobals.document.documentElement; var clientWidth_1 = docElm_1.clientWidth, clientHeight_1 = docElm_1.clientHeight; windowResizeHandler = function () { if (!domGlobals.document.all || clientWidth_1 !== docElm_1.clientWidth || clientHeight_1 !== docElm_1.clientHeight) { clientWidth_1 = docElm_1.clientWidth; clientHeight_1 = docElm_1.clientHeight; FloatPanel.hideAll(); } }; global$7(domGlobals.window).on('resize', windowResizeHandler); } } function repositionPanel$1(panel) { var scrollY = funcs.getViewPort().y; function toggleFixedChildPanels(fixed, deltaY) { var parent; for (var i = 0; i < visiblePanels.length; i++) { if (visiblePanels[i] !== panel) { parent = visiblePanels[i].parent(); while (parent && (parent = parent.parent())) { if (parent === panel) { visiblePanels[i].fixed(fixed).moveBy(0, deltaY).repaint(); } } } } } if (panel.settings.autofix) { if (!panel.state.get('fixed')) { panel._autoFixY = panel.layoutRect().y; if (panel._autoFixY < scrollY) { panel.fixed(true).layoutRect({ y: 0 }).repaint(); toggleFixedChildPanels(true, scrollY - panel._autoFixY); } } else { if (panel._autoFixY > scrollY) { panel.fixed(false).layoutRect({ y: panel._autoFixY }).repaint(); toggleFixedChildPanels(false, panel._autoFixY - scrollY); } } } } function addRemove(add, ctrl) { var i, zIndex = FloatPanel.zIndex || 65535, topModal; if (add) { zOrder.push(ctrl); } else { i = zOrder.length; while (i--) { if (zOrder[i] === ctrl) { zOrder.splice(i, 1); } } } if (zOrder.length) { for (i = 0; i < zOrder.length; i++) { if (zOrder[i].modal) { zIndex++; topModal = zOrder[i]; } zOrder[i].getEl().style.zIndex = zIndex; zOrder[i].zIndex = zIndex; zIndex++; } } var modalBlockEl = global$7('#' + ctrl.classPrefix + 'modal-block', ctrl.getContainerElm())[0]; if (topModal) { global$7(modalBlockEl).css('z-index', topModal.zIndex - 1); } else if (modalBlockEl) { modalBlockEl.parentNode.removeChild(modalBlockEl); hasModal = false; } FloatPanel.currentZIndex = zIndex; } var FloatPanel = Panel.extend({ Mixins: [ Movable, Resizable ], init: function (settings) { var self = this; self._super(settings); self._eventsRoot = self; self.classes.add('floatpanel'); if (settings.autohide) { bindDocumentClickHandler(); bindWindowResizeHandler(); visiblePanels.push(self); } if (settings.autofix) { bindDocumentScrollHandler(); self.on('move', function () { repositionPanel$1(this); }); } self.on('postrender show', function (e) { if (e.control === self) { var $modalBlockEl_1; var prefix_1 = self.classPrefix; if (self.modal && !hasModal) { $modalBlockEl_1 = global$7('#' + prefix_1 + 'modal-block', self.getContainerElm()); if (!$modalBlockEl_1[0]) { $modalBlockEl_1 = global$7('<div id="' + prefix_1 + 'modal-block" class="' + prefix_1 + 'reset ' + prefix_1 + 'fade"></div>').appendTo(self.getContainerElm()); } global$3.setTimeout(function () { $modalBlockEl_1.addClass(prefix_1 + 'in'); global$7(self.getEl()).addClass(prefix_1 + 'in'); }); hasModal = true; } addRemove(true, self); } }); self.on('show', function () { self.parents().each(function (ctrl) { if (ctrl.state.get('fixed')) { self.fixed(true); return false; } }); }); if (settings.popover) { self._preBodyHtml = '<div class="' + self.classPrefix + 'arrow"></div>'; self.classes.add('popover').add('bottom').add(self.isRtl() ? 'end' : 'start'); } self.aria('label', settings.ariaLabel); self.aria('labelledby', self._id); self.aria('describedby', self.describedBy || self._id + '-none'); }, fixed: function (state) { var self = this; if (self.state.get('fixed') !== state) { if (self.state.get('rendered')) { var viewport = funcs.getViewPort(); if (state) { self.layoutRect().y -= viewport.y; } else { self.layoutRect().y += viewport.y; } } self.classes.toggle('fixed', state); self.state.set('fixed', state); } return self; }, show: function () { var self = this; var i; var state = self._super(); i = visiblePanels.length; while (i--) { if (visiblePanels[i] === self) { break; } } if (i === -1) { visiblePanels.push(self); } return state; }, hide: function () { removeVisiblePanel(this); addRemove(false, this); return this._super(); }, hideAll: function () { FloatPanel.hideAll(); }, close: function () { var self = this; if (!self.fire('close').isDefaultPrevented()) { self.remove(); addRemove(false, self); } return self; }, remove: function () { removeVisiblePanel(this); this._super(); }, postRender: function () { var self = this; if (self.settings.bodyRole) { this.getEl('body').setAttribute('role', self.settings.bodyRole); } return self._super(); } }); FloatPanel.hideAll = function () { var i = visiblePanels.length; while (i--) { var panel = visiblePanels[i]; if (panel && panel.settings.autohide) { panel.hide(); visiblePanels.splice(i, 1); } } }; function removeVisiblePanel(panel) { var i; i = visiblePanels.length; while (i--) { if (visiblePanels[i] === panel) { visiblePanels.splice(i, 1); } } i = zOrder.length; while (i--) { if (zOrder[i] === panel) { zOrder.splice(i, 1); } } } var windows = []; var oldMetaValue = ''; function toggleFullScreenState(state) { var noScaleMetaValue = 'width=device-width,initial-scale=1.0,user-scalable=0,minimum-scale=1.0,maximum-scale=1.0'; var viewport = global$7('meta[name=viewport]')[0], contentValue; if (global$1.overrideViewPort === false) { return; } if (!viewport) { viewport = domGlobals.document.createElement('meta'); viewport.setAttribute('name', 'viewport'); domGlobals.document.getElementsByTagName('head')[0].appendChild(viewport); } contentValue = viewport.getAttribute('content'); if (contentValue && typeof oldMetaValue !== 'undefined') { oldMetaValue = contentValue; } viewport.setAttribute('content', state ? noScaleMetaValue : oldMetaValue); } function toggleBodyFullScreenClasses(classPrefix, state) { if (checkFullscreenWindows() && state === false) { global$7([ domGlobals.document.documentElement, domGlobals.document.body ]).removeClass(classPrefix + 'fullscreen'); } } function checkFullscreenWindows() { for (var i = 0; i < windows.length; i++) { if (windows[i]._fullscreen) { return true; } } return false; } function handleWindowResize() { if (!global$1.desktop) { var lastSize_1 = { w: domGlobals.window.innerWidth, h: domGlobals.window.innerHeight }; global$3.setInterval(function () { var w = domGlobals.window.innerWidth, h = domGlobals.window.innerHeight; if (lastSize_1.w !== w || lastSize_1.h !== h) { lastSize_1 = { w: w, h: h }; global$7(domGlobals.window).trigger('resize'); } }, 100); } function reposition() { var i; var rect = funcs.getWindowSize(); var layoutRect; for (i = 0; i < windows.length; i++) { layoutRect = windows[i].layoutRect(); 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)); } } global$7(domGlobals.window).on('resize', reposition); } var Window = FloatPanel.extend({ modal: true, Defaults: { border: 1, layout: 'flex', containerCls: 'panel', role: 'dialog', callbacks: { submit: function () { this.fire('submit', { data: this.toJSON() }); }, close: function () { this.close(); } } }, init: function (settings) { var self = this; self._super(settings); if (self.isRtl()) { self.classes.add('rtl'); } self.classes.add('window'); self.bodyClasses.add('window-body'); self.state.set('fixed', true); if (settings.buttons) { self.statusbar = new Panel({ layout: 'flex', border: '1 0 0 0', spacing: 3, padding: 10, align: 'center', pack: self.isRtl() ? 'start' : 'end', defaults: { type: 'button' }, items: settings.buttons }); self.statusbar.classes.add('foot'); self.statusbar.parent(self); } self.on('click', function (e) { var closeClass = self.classPrefix + 'close'; if (funcs.hasClass(e.target, closeClass) || funcs.hasClass(e.target.parentNode, closeClass)) { self.close(); } }); self.on('cancel', function () { self.close(); }); self.on('move', function (e) { if (e.control === self) { FloatPanel.hideAll(); } }); self.aria('describedby', self.describedBy || self._id + '-none'); self.aria('label', settings.title); self._fullscreen = false; }, recalc: function () { var self = this; var statusbar = self.statusbar; var layoutRect, width, x, needsRecalc; if (self._fullscreen) { self.layoutRect(funcs.getWindowSize()); self.layoutRect().contentH = self.layoutRect().innerH; } self._super(); layoutRect = self.layoutRect(); if (self.settings.title && !self._fullscreen) { width = layoutRect.headerW; if (width > layoutRect.w) { x = layoutRect.x - Math.max(0, width / 2); self.layoutRect({ w: width, x: x }); needsRecalc = true; } } if (statusbar) { statusbar.layoutRect({ w: self.layoutRect().innerW }).recalc(); width = statusbar.layoutRect().minW + layoutRect.deltaW; if (width > layoutRect.w) { x = layoutRect.x - Math.max(0, width - layoutRect.w); self.layoutRect({ w: width, x: x }); needsRecalc = true; } } if (needsRecalc) { self.recalc(); } }, initLayoutRect: function () { var self = this; var layoutRect = self._super(); var deltaH = 0, headEl; if (self.settings.title && !self._fullscreen) { headEl = self.getEl('head'); var size = funcs.getSize(headEl); layoutRect.headerW = size.width; layoutRect.headerH = size.height; deltaH += layoutRect.headerH; } if (self.statusbar) { deltaH += self.statusbar.layoutRect().h; } layoutRect.deltaH += deltaH; layoutRect.minH += deltaH; layoutRect.h += deltaH; var rect = funcs.getWindowSize(); layoutRect.x = self.settings.x || Math.max(0, rect.w / 2 - layoutRect.w / 2); layoutRect.y = self.settings.y || Math.max(0, rect.h / 2 - layoutRect.h / 2); return layoutRect; }, renderHtml: function () { var self = this, layout = self._layout, id = self._id, prefix = self.classPrefix; var settings = self.settings; var headerHtml = '', footerHtml = '', html = settings.html; self.preRender(); layout.preRender(self); if (settings.title) { 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>'; } if (settings.url) { html = '<iframe src="' + settings.url + '" tabindex="-1"></iframe>'; } if (typeof html === 'undefined') { html = layout.renderHtml(self); } if (self.statusbar) { footerHtml = self.statusbar.renderHtml(); } 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>'; }, fullscreen: function (state) { var self = this; var documentElement = domGlobals.document.documentElement; var slowRendering; var prefix = self.classPrefix; var layoutRect; if (state !== self._fullscreen) { global$7(domGlobals.window).on('resize', function () { var time; if (self._fullscreen) { if (!slowRendering) { time = new Date().getTime(); var rect = funcs.getWindowSize(); self.moveTo(0, 0).resizeTo(rect.w, rect.h); if (new Date().getTime() - time > 50) { slowRendering = true; } } else { if (!self._timer) { self._timer = global$3.setTimeout(function () { var rect = funcs.getWindowSize(); self.moveTo(0, 0).resizeTo(rect.w, rect.h); self._timer = 0; }, 50); } } } }); layoutRect = self.layoutRect(); self._fullscreen = state; if (!state) { self.borderBox = BoxUtils.parseBox(self.settings.border); self.getEl('head').style.display = ''; layoutRect.deltaH += layoutRect.headerH; global$7([ documentElement, domGlobals.document.body ]).removeClass(prefix + 'fullscreen'); self.classes.remove('fullscreen'); self.moveTo(self._initial.x, self._initial.y).resizeTo(self._initial.w, self._initial.h); } else { self._initial = { x: layoutRect.x, y: layoutRect.y, w: layoutRect.w, h: layoutRect.h }; self.borderBox = BoxUtils.parseBox('0'); self.getEl('head').style.display = 'none'; layoutRect.deltaH -= layoutRect.headerH + 2; global$7([ documentElement, domGlobals.document.body ]).addClass(prefix + 'fullscreen'); self.classes.add('fullscreen'); var rect = funcs.getWindowSize(); self.moveTo(0, 0).resizeTo(rect.w, rect.h); } } return self.reflow(); }, postRender: function () { var self = this; var startPos; setTimeout(function () { self.classes.add('in'); self.fire('open'); }, 0); self._super(); if (self.statusbar) { self.statusbar.postRender(); } self.focus(); this.dragHelper = new DragHelper(self._id + '-dragh', { start: function () { startPos = { x: self.layoutRect().x, y: self.layoutRect().y }; }, drag: function (e) { self.moveTo(startPos.x + e.deltaX, startPos.y + e.deltaY); } }); self.on('submit', function (e) { if (!e.isDefaultPrevented()) { self.close(); } }); windows.push(self); toggleFullScreenState(true); }, submit: function () { return this.fire('submit', { data: this.toJSON() }); }, remove: function () { var self = this; var i; self.dragHelper.destroy(); self._super(); if (self.statusbar) { this.statusbar.remove(); } toggleBodyFullScreenClasses(self.classPrefix, false); i = windows.length; while (i--) { if (windows[i] === self) { windows.splice(i, 1); } } toggleFullScreenState(windows.length > 0); }, getContentWindow: function () { var ifr = this.getEl().getElementsByTagName('iframe')[0]; return ifr ? ifr.contentWindow : null; } }); handleWindowResize(); var MessageBox = Window.extend({ init: function (settings) { settings = { border: 1, padding: 20, layout: 'flex', pack: 'center', align: 'center', containerCls: 'panel', autoScroll: true, buttons: { type: 'button', text: 'Ok', action: 'ok' }, items: { type: 'label', multiline: true, maxWidth: 500, maxHeight: 200 } }; this._super(settings); }, Statics: { OK: 1, OK_CANCEL: 2, YES_NO: 3, YES_NO_CANCEL: 4, msgBox: function (settings) { var buttons; var callback = settings.callback || function () { }; function createButton(text, status, primary) { return { type: 'button', text: text, subtype: primary ? 'primary' : '', onClick: function (e) { e.control.parents()[1].close(); callback(status); } }; } switch (settings.buttons) { case MessageBox.OK_CANCEL: buttons = [ createButton('Ok', true, true), createButton('Cancel', false) ]; break; case MessageBox.YES_NO: case MessageBox.YES_NO_CANCEL: buttons = [ createButton('Yes', 1, true), createButton('No', 0) ]; if (settings.buttons === MessageBox.YES_NO_CANCEL) { buttons.push(createButton('Cancel', -1)); } break; default: buttons = [createButton('Ok', true, true)]; break; } return new Window({ padding: 20, x: settings.x, y: settings.y, minWidth: 300, minHeight: 100, layout: 'flex', pack: 'center', align: 'center', buttons: buttons, title: settings.title, role: 'alertdialog', items: { type: 'label', multiline: true, maxWidth: 500, maxHeight: 200, text: settings.text }, onPostRender: function () { this.aria('describedby', this.items()[0]._id); }, onClose: settings.onClose, onCancel: function () { callback(false); } }).renderTo(domGlobals.document.body).reflow(); }, alert: function (settings, callback) { if (typeof settings === 'string') { settings = { text: settings }; } settings.callback = callback; return MessageBox.msgBox(settings); }, confirm: function (settings, callback) { if (typeof settings === 'string') { settings = { text: settings }; } settings.callback = callback; settings.buttons = MessageBox.OK_CANCEL; return MessageBox.msgBox(settings); } } }); function WindowManagerImpl (editor) { var open = function (args, params, closeCallback) { var win; args.title = args.title || ' '; args.url = args.url || args.file; if (args.url) { args.width = parseInt(args.width || 320, 10); args.height = parseInt(args.height || 240, 10); } if (args.body) { args.items = { defaults: args.defaults, type: args.bodyType || 'form', items: args.body, data: args.data, callbacks: args.commands }; } if (!args.url && !args.buttons) { args.buttons = [ { text: 'Ok', subtype: 'primary', onclick: function () { win.find('form')[0].submit(); } }, { text: 'Cancel', onclick: function () { win.close(); } } ]; } win = new Window(args); win.on('close', function () { closeCallback(win); }); if (args.data) { win.on('postRender', function () { this.find('*').each(function (ctrl) { var name = ctrl.name(); if (name in args.data) { ctrl.value(args.data[name]); } }); }); } win.features = args || {}; win.params = params || {}; win = win.renderTo(domGlobals.document.body).reflow(); return win; }; var alert = function (message, choiceCallback, closeCallback) { var win; win = MessageBox.alert(message, function () { choiceCallback(); }); win.on('close', function () { closeCallback(win); }); return win; }; var confirm = function (message, choiceCallback, closeCallback) { var win; win = MessageBox.confirm(message, function (state) { choiceCallback(state); }); win.on('close', function () { closeCallback(win); }); return win; }; var close = function (window) { window.close(); }; var getParams = function (window) { return window.params; }; var setParams = function (window, params) { window.params = params; }; return { open: open, alert: alert, confirm: confirm, close: close, getParams: getParams, setParams: setParams }; } var get = function (editor, panel) { var renderUI = function () { return Render.renderUI(editor, panel); }; return { renderUI: renderUI, getNotificationManagerImpl: function () { return NotificationManagerImpl(editor); }, getWindowManagerImpl: function () { return WindowManagerImpl(editor); } }; }; var ThemeApi = { get: get }; var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')(); var path = function (parts, scope) { var o = scope !== undefined && scope !== null ? scope : Global; for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i) o = o[parts[i]]; return o; }; var resolve = function (p, scope) { var parts = p.split('.'); return path(parts, scope); }; var unsafe = function (name, scope) { return resolve(name, scope); }; var getOrDie = function (name, scope) { var actual = unsafe(name, scope); if (actual === undefined || actual === null) throw name + ' not available on this browser'; return actual; }; var Global$1 = { getOrDie: getOrDie }; function FileReader () { var f = Global$1.getOrDie('FileReader'); return new f(); } var global$c = tinymce.util.Tools.resolve('tinymce.util.Promise'); var blobToBase64 = function (blob) { return new global$c(function (resolve) { var reader = FileReader(); reader.onloadend = function () { resolve(reader.result.split(',')[1]); }; reader.readAsDataURL(blob); }); }; var Conversions = { blobToBase64: blobToBase64 }; var pickFile = function () { return new global$c(function (resolve) { var fileInput; fileInput = domGlobals.document.createElement('input'); fileInput.type = 'file'; fileInput.style.position = 'fixed'; fileInput.style.left = 0; fileInput.style.top = 0; fileInput.style.opacity = 0.001; domGlobals.document.body.appendChild(fileInput); fileInput.onchange = function (e) { resolve(Array.prototype.slice.call(e.target.files)); }; fileInput.click(); fileInput.parentNode.removeChild(fileInput); }); }; var Picker = { pickFile: pickFile }; var count$1 = 0; var seed = function () { var rnd = function () { return Math.round(Math.random() * 4294967295).toString(36); }; return 's' + Date.now().toString(36) + rnd() + rnd() + rnd(); }; var uuid = function (prefix) { return prefix + count$1++ + seed(); }; var Uuid = { uuid: uuid }; var create$1 = function (dom, rng) { var bookmark = {}; function setupEndPoint(start) { var offsetNode, container, offset; container = rng[start ? 'startContainer' : 'endContainer']; offset = rng[start ? 'startOffset' : 'endOffset']; if (container.nodeType === 1) { offsetNode = dom.create('span', { 'data-mce-type': 'bookmark' }); if (container.hasChildNodes()) { offset = Math.min(offset, container.childNodes.length - 1); if (start) { container.insertBefore(offsetNode, container.childNodes[offset]); } else { dom.insertAfter(offsetNode, container.childNodes[offset]); } } else { container.appendChild(offsetNode); } container = offsetNode; offset = 0; } bookmark[start ? 'startContainer' : 'endContainer'] = container; bookmark[start ? 'startOffset' : 'endOffset'] = offset; } setupEndPoint(true); if (!rng.collapsed) { setupEndPoint(); } return bookmark; }; var resolve$1 = function (dom, bookmark) { function restoreEndPoint(start) { var container, offset, node; function nodeIndex(container) { var node = container.parentNode.firstChild, idx = 0; while (node) { if (node === container) { return idx; } if (node.nodeType !== 1 || node.getAttribute('data-mce-type') !== 'bookmark') { idx++; } node = node.nextSibling; } return -1; } container = node = bookmark[start ? 'startContainer' : 'endContainer']; offset = bookmark[start ? 'startOffset' : 'endOffset']; if (!container) { return; } if (container.nodeType === 1) { offset = nodeIndex(container); container = container.parentNode; dom.remove(node); } bookmark[start ? 'startContainer' : 'endContainer'] = container; bookmark[start ? 'startOffset' : 'endOffset'] = offset; } restoreEndPoint(true); restoreEndPoint(); var rng = dom.createRng(); rng.setStart(bookmark.startContainer, bookmark.startOffset); if (bookmark.endContainer) { rng.setEnd(bookmark.endContainer, bookmark.endOffset); } return rng; }; var Bookmark = { create: create$1, resolve: resolve$1 }; var global$d = tinymce.util.Tools.resolve('tinymce.dom.TreeWalker'); var global$e = tinymce.util.Tools.resolve('tinymce.dom.RangeUtils'); var getSelectedElements = function (rootElm, startNode, endNode) { var walker, node; var elms = []; walker = new global$d(startNode, rootElm); for (node = startNode; node; node = walker.next()) { if (node.nodeType === 1) { elms.push(node); } if (node === endNode) { break; } } return elms; }; var unwrapElements = function (editor, elms) { var bookmark, dom, selection; dom = editor.dom; selection = editor.selection; bookmark = Bookmark.create(dom, selection.getRng()); global$4.each(elms, function (elm) { editor.dom.remove(elm, true); }); selection.setRng(Bookmark.resolve(dom, bookmark)); }; var isLink = function (elm) { return elm.nodeName === 'A' && elm.hasAttribute('href'); }; var getParentAnchorOrSelf = function (dom, elm) { var anchorElm = dom.getParent(elm, isLink); return anchorElm ? anchorElm : elm; }; var getSelectedAnchors = function (editor) { var startElm, endElm, rootElm, anchorElms, selection, dom, rng; selection = editor.selection; dom = editor.dom; rng = selection.getRng(); startElm = getParentAnchorOrSelf(dom, global$e.getNode(rng.startContainer, rng.startOffset)); endElm = global$e.getNode(rng.endContainer, rng.endOffset); rootElm = editor.getBody(); anchorElms = global$4.grep(getSelectedElements(rootElm, startElm, endElm), isLink); return anchorElms; }; var unlinkSelection = function (editor) { unwrapElements(editor, getSelectedAnchors(editor)); }; var Unlink = { unlinkSelection: unlinkSelection }; var createTableHtml = function (cols, rows) { var x, y, html; html = '<table data-mce-id="mce" style="width: 100%">'; html += '<tbody>'; for (y = 0; y < rows; y++) { html += '<tr>'; for (x = 0; x < cols; x++) { html += '<td><br></td>'; } html += '</tr>'; } html += '</tbody>'; html += '</table>'; return html; }; var getInsertedElement = function (editor) { var elms = editor.dom.select('*[data-mce-id]'); return elms[0]; }; var insertTableHtml = function (editor, cols, rows) { editor.undoManager.transact(function () { var tableElm, cellElm; editor.insertContent(createTableHtml(cols, rows)); tableElm = getInsertedElement(editor); tableElm.removeAttribute('data-mce-id'); cellElm = editor.dom.select('td,th', tableElm); editor.selection.setCursorLocation(cellElm[0], 0); }); }; var insertTable = function (editor, cols, rows) { editor.plugins.table ? editor.plugins.table.insertTable(cols, rows) : insertTableHtml(editor, cols, rows); }; var formatBlock = function (editor, formatName) { editor.execCommand('FormatBlock', false, formatName); }; var insertBlob = function (editor, base64, blob) { var blobCache, blobInfo; blobCache = editor.editorUpload.blobCache; blobInfo = blobCache.create(Uuid.uuid('mceu'), blob, base64); blobCache.add(blobInfo); editor.insertContent(editor.dom.createHTML('img', { src: blobInfo.blobUri() })); }; var collapseSelectionToEnd = function (editor) { editor.selection.collapse(false); }; var unlink = function (editor) { editor.focus(); Unlink.unlinkSelection(editor); collapseSelectionToEnd(editor); }; var changeHref = function (editor, elm, url) { editor.focus(); editor.dom.setAttrib(elm, 'href', url); collapseSelectionToEnd(editor); }; var insertLink = function (editor, url) { editor.execCommand('mceInsertLink', false, { href: url }); collapseSelectionToEnd(editor); }; var updateOrInsertLink = function (editor, url) { var elm = editor.dom.getParent(editor.selection.getStart(), 'a[href]'); elm ? changeHref(editor, elm, url) : insertLink(editor, url); }; var createLink = function (editor, url) { url.trim().length === 0 ? unlink(editor) : updateOrInsertLink(editor, url); }; var Actions = { insertTable: insertTable, formatBlock: formatBlock, insertBlob: insertBlob, createLink: createLink, unlink: unlink }; var addHeaderButtons = function (editor) { var formatBlock = function (name) { return function () { Actions.formatBlock(editor, name); }; }; for (var i = 1; i < 6; i++) { var name = 'h' + i; editor.addButton(name, { text: name.toUpperCase(), tooltip: 'Heading ' + i, stateSelector: name, onclick: formatBlock(name), onPostRender: function () { var span = this.getEl().firstChild.firstChild; span.style.fontWeight = 'bold'; } }); } }; var addToEditor = function (editor, panel) { editor.addButton('quicklink', { icon: 'link', tooltip: 'Insert/Edit link', stateSelector: 'a[href]', onclick: function () { panel.showForm(editor, 'quicklink'); } }); editor.addButton('quickimage', { icon: 'image', tooltip: 'Insert image', onclick: function () { Picker.pickFile().then(function (files) { var blob = files[0]; Conversions.blobToBase64(blob).then(function (base64) { Actions.insertBlob(editor, base64, blob); }); }); } }); editor.addButton('quicktable', { icon: 'table', tooltip: 'Insert table', onclick: function () { panel.hide(); Actions.insertTable(editor, 2, 2); } }); addHeaderButtons(editor); }; var Buttons = { addToEditor: addToEditor }; var getUiContainerDelta$1 = function () { var uiContainer = global$1.container; if (uiContainer && global$2.DOM.getStyle(uiContainer, 'position', true) !== 'static') { var containerPos = global$2.DOM.getPos(uiContainer); var dx = containerPos.x - uiContainer.scrollLeft; var dy = containerPos.y - uiContainer.scrollTop; return Option.some({ x: dx, y: dy }); } else { return Option.none(); } }; var UiContainer$1 = { getUiContainerDelta: getUiContainerDelta$1 }; var isDomainLike = function (href) { 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()); }; var isAbsolute = function (href) { return /^https?:\/\//.test(href.trim()); }; var UrlType = { isDomainLike: isDomainLike, isAbsolute: isAbsolute }; var focusFirstTextBox = function (form) { form.find('textbox').eq(0).each(function (ctrl) { ctrl.focus(); }); }; var createForm = function (name, spec) { var form = global$b.create(global$4.extend({ type: 'form', layout: 'flex', direction: 'row', padding: 5, name: name, spacing: 3 }, spec)); form.on('show', function () { focusFirstTextBox(form); }); return form; }; var toggleVisibility = function (ctrl, state) { return state ? ctrl.show() : ctrl.hide(); }; var askAboutPrefix = function (editor, href) { return new global$c(function (resolve) { editor.windowManager.confirm('The URL you entered seems to be an external link. Do you want to add the required http:// prefix?', function (result) { var output = result === true ? 'http://' + href : href; resolve(output); }); }); }; var convertLinkToAbsolute = function (editor, href) { return !UrlType.isAbsolute(href) && UrlType.isDomainLike(href) ? askAboutPrefix(editor, href) : global$c.resolve(href); }; var createQuickLinkForm = function (editor, hide) { var attachState = {}; var unlink = function () { editor.focus(); Actions.unlink(editor); hide(); }; var onChangeHandler = function (e) { var meta = e.meta; if (meta && meta.attach) { attachState = { href: this.value(), attach: meta.attach }; } }; var onShowHandler = function (e) { if (e.control === this) { var elm = void 0, linkurl = ''; elm = editor.dom.getParent(editor.selection.getStart(), 'a[href]'); if (elm) { linkurl = editor.dom.getAttrib(elm, 'href'); } this.fromJSON({ linkurl: linkurl }); toggleVisibility(this.find('#unlink'), elm); this.find('#linkurl')[0].focus(); } }; return createForm('quicklink', { items: [ { type: 'button', name: 'unlink', icon: 'unlink', onclick: unlink, tooltip: 'Remove link' }, { type: 'filepicker', name: 'linkurl', placeholder: 'Paste or type a link', filetype: 'file', onchange: onChangeHandler }, { type: 'button', icon: 'checkmark', subtype: 'primary', tooltip: 'Ok', onclick: 'submit' } ], onshow: onShowHandler, onsubmit: function (e) { convertLinkToAbsolute(editor, e.data.linkurl).then(function (url) { editor.undoManager.transact(function () { if (url === attachState.href) { attachState.attach(); attachState = {}; } Actions.createLink(editor, url); }); hide(); }); } }); }; var Forms = { createQuickLinkForm: createQuickLinkForm }; var getSelectorStateResult = function (itemName, item) { var result = function (selector, handler) { return { selector: selector, handler: handler }; }; var activeHandler = function (state) { item.active(state); }; var disabledHandler = function (state) { item.disabled(state); }; if (item.settings.stateSelector) { return result(item.settings.stateSelector, activeHandler); } if (item.settings.disabledStateSelector) { return result(item.settings.disabledStateSelector, disabledHandler); } return null; }; var bindSelectorChanged = function (editor, itemName, item) { return function () { var result = getSelectorStateResult(itemName, item); if (result !== null) { editor.selection.selectorChanged(result.selector, result.handler); } }; }; var itemsToArray$1 = function (items) { if (Type.isArray(items)) { return items; } else if (Type.isString(items)) { return items.split(/[ ,]/); } return []; }; var create$2 = function (editor, name, items) { var toolbarItems = []; var buttonGroup; if (!items) { return; } global$4.each(itemsToArray$1(items), function (item) { if (item === '|') { buttonGroup = null; } else { if (editor.buttons[item]) { if (!buttonGroup) { buttonGroup = { type: 'buttongroup', items: [] }; toolbarItems.push(buttonGroup); } var button = editor.buttons[item]; if (Type.isFunction(button)) { button = button(); } button.type = button.type || 'button'; button = global$b.create(button); button.on('postRender', bindSelectorChanged(editor, item, button)); buttonGroup.items.push(button); } } }); return global$b.create({ type: 'toolbar', layout: 'flow', name: name, items: toolbarItems }); }; var Toolbar = { create: create$2 }; var create$3 = function () { var panel, currentRect; var createToolbars = function (editor, toolbars) { return global$4.map(toolbars, function (toolbar) { return Toolbar.create(editor, toolbar.id, toolbar.items); }); }; var hasToolbarItems = function (toolbar) { return toolbar.items().length > 0; }; var create = function (editor, toolbars) { var items = createToolbars(editor, toolbars).concat([ Toolbar.create(editor, 'text', Settings.getTextSelectionToolbarItems(editor)), Toolbar.create(editor, 'insert', Settings.getInsertToolbarItems(editor)), Forms.createQuickLinkForm(editor, hide) ]); return global$b.create({ type: 'floatpanel', role: 'dialog', classes: 'tinymce tinymce-inline arrow', ariaLabel: 'Inline toolbar', layout: 'flex', direction: 'column', align: 'stretch', autohide: false, autofix: true, fixed: true, border: 1, items: global$4.grep(items, hasToolbarItems), oncancel: function () { editor.focus(); } }); }; var showPanel = function (panel) { if (panel) { panel.show(); } }; var movePanelTo = function (panel, pos) { panel.moveTo(pos.x, pos.y); }; var togglePositionClass = function (panel, relPos) { relPos = relPos ? relPos.substr(0, 2) : ''; global$4.each({ t: 'down', b: 'up', c: 'center' }, function (cls, pos) { panel.classes.toggle('arrow-' + cls, pos === relPos.substr(0, 1)); }); if (relPos === 'cr') { panel.classes.toggle('arrow-left', true); panel.classes.toggle('arrow-right', false); } else if (relPos === 'cl') { panel.classes.toggle('arrow-left', false); panel.classes.toggle('arrow-right', true); } else { global$4.each({ l: 'left', r: 'right' }, function (cls, pos) { panel.classes.toggle('arrow-' + cls, pos === relPos.substr(1, 1)); }); } }; var showToolbar = function (panel, id) { var toolbars = panel.items().filter('#' + id); if (toolbars.length > 0) { toolbars[0].show(); panel.reflow(); return true; } return false; }; var repositionPanelAt = function (panel, id, editor, targetRect) { var contentAreaRect, panelRect, result, userConstainHandler; userConstainHandler = Settings.getPositionHandler(editor); contentAreaRect = Measure.getContentAreaRect(editor); panelRect = global$2.DOM.getRect(panel.getEl()); if (id === 'insert') { result = Layout.calcInsert(targetRect, contentAreaRect, panelRect); } else { result = Layout.calc(targetRect, contentAreaRect, panelRect); } if (result) { var delta = UiContainer$1.getUiContainerDelta().getOr({ x: 0, y: 0 }); var transposedPanelRect = { x: result.rect.x - delta.x, y: result.rect.y - delta.y, w: result.rect.w, h: result.rect.h }; currentRect = targetRect; movePanelTo(panel, Layout.userConstrain(userConstainHandler, targetRect, contentAreaRect, transposedPanelRect)); togglePositionClass(panel, result.position); return true; } else { return false; } }; var showPanelAt = function (panel, id, editor, targetRect) { showPanel(panel); panel.items().hide(); if (!showToolbar(panel, id)) { hide(); return; } if (repositionPanelAt(panel, id, editor, targetRect) === false) { hide(); } }; var hasFormVisible = function () { return panel.items().filter('form:visible').length > 0; }; var showForm = function (editor, id) { if (panel) { panel.items().hide(); if (!showToolbar(panel, id)) { hide(); return; } var contentAreaRect = void 0, panelRect = void 0, result = void 0, userConstainHandler = void 0; showPanel(panel); panel.items().hide(); showToolbar(panel, id); userConstainHandler = Settings.getPositionHandler(editor); contentAreaRect = Measure.getContentAreaRect(editor); panelRect = global$2.DOM.getRect(panel.getEl()); result = Layout.calc(currentRect, contentAreaRect, panelRect); if (result) { panelRect = result.rect; movePanelTo(panel, Layout.userConstrain(userConstainHandler, currentRect, contentAreaRect, panelRect)); togglePositionClass(panel, result.position); } } }; var show = function (editor, id, targetRect, toolbars) { if (!panel) { Events.fireBeforeRenderUI(editor); panel = create(editor, toolbars); panel.renderTo().reflow().moveTo(targetRect.x, targetRect.y); editor.nodeChanged(); } showPanelAt(panel, id, editor, targetRect); }; var reposition = function (editor, id, targetRect) { if (panel) { repositionPanelAt(panel, id, editor, targetRect); } }; var hide = function () { if (panel) { panel.hide(); } }; var focus = function () { if (panel) { panel.find('toolbar:visible').eq(0).each(function (item) { item.focus(true); }); } }; var remove = function () { if (panel) { panel.remove(); panel = null; } }; var inForm = function () { return panel && panel.visible() && hasFormVisible(); }; return { show: show, showForm: showForm, reposition: reposition, inForm: inForm, hide: hide, focus: focus, remove: remove }; }; var Layout$1 = global$8.extend({ Defaults: { firstControlClass: 'first', lastControlClass: 'last' }, init: function (settings) { this.settings = global$4.extend({}, this.Defaults, settings); }, preRender: function (container) { container.bodyClasses.add(this.settings.containerClass); }, applyClasses: function (items) { var self = this; var settings = self.settings; var firstClass, lastClass, firstItem, lastItem; firstClass = settings.firstControlClass; lastClass = settings.lastControlClass; items.each(function (item) { item.classes.remove(firstClass).remove(lastClass).add(settings.controlClass); if (item.visible()) { if (!firstItem) { firstItem = item; } lastItem = item; } }); if (firstItem) { firstItem.classes.add(firstClass); } if (lastItem) { lastItem.classes.add(lastClass); } }, renderHtml: function (container) { var self = this; var html = ''; self.applyClasses(container.items()); container.items().each(function (item) { html += item.renderHtml(); }); return html; }, recalc: function () { }, postRender: function () { }, isNative: function () { return false; } }); var AbsoluteLayout = Layout$1.extend({ Defaults: { containerClass: 'abs-layout', controlClass: 'abs-layout-item' }, recalc: function (container) { container.items().filter(':visible').each(function (ctrl) { var settings = ctrl.settings; ctrl.layoutRect({ x: settings.x, y: settings.y, w: settings.w, h: settings.h }); if (ctrl.recalc) { ctrl.recalc(); } }); }, renderHtml: function (container) { return '<div id="' + container._id + '-absend" class="' + container.classPrefix + 'abs-end"></div>' + this._super(container); } }); var Button = Widget.extend({ Defaults: { classes: 'widget btn', role: 'button' }, init: function (settings) { var self = this; var size; self._super(settings); settings = self.settings; size = self.settings.size; self.on('click mousedown', function (e) { e.preventDefault(); }); self.on('touchstart', function (e) { self.fire('click', e); e.preventDefault(); }); if (settings.subtype) { self.classes.add(settings.subtype); } if (size) { self.classes.add('btn-' + size); } if (settings.icon) { self.icon(settings.icon); } }, icon: function (icon) { if (!arguments.length) { return this.state.get('icon'); } this.state.set('icon', icon); return this; }, repaint: function () { var btnElm = this.getEl().firstChild; var btnStyle; if (btnElm) { btnStyle = btnElm.style; btnStyle.width = btnStyle.height = '100%'; } this._super(); }, renderHtml: function () { var self = this, id = self._id, prefix = self.classPrefix; var icon = self.state.get('icon'), image; var text = self.state.get('text'); var textHtml = ''; var ariaPressed; var settings = self.settings; image = settings.image; if (image) { icon = 'none'; if (typeof image !== 'string') { image = domGlobals.window.getSelection ? image[0] : image[1]; } image = ' style="background-image: url(\'' + image + '\')"'; } else { image = ''; } if (text) { self.classes.add('btn-has-text'); textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>'; } icon = icon ? prefix + 'ico ' + prefix + 'i-' + icon : ''; ariaPressed = typeof settings.active === 'boolean' ? ' aria-pressed="' + settings.active + '"' : ''; 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>'; }, bindStates: function () { var self = this, $ = self.$, textCls = self.classPrefix + 'txt'; function setButtonText(text) { var $span = $('span.' + textCls, self.getEl()); if (text) { if (!$span[0]) { $('button:first', self.getEl()).append('<span class="' + textCls + '"></span>'); $span = $('span.' + textCls, self.getEl()); } $span.html(self.encode(text)); } else { $span.remove(); } self.classes.toggle('btn-has-text', !!text); } self.state.on('change:text', function (e) { setButtonText(e.value); }); self.state.on('change:icon', function (e) { var icon = e.value; var prefix = self.classPrefix; self.settings.icon = icon; icon = icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : ''; var btnElm = self.getEl().firstChild; var iconElm = btnElm.getElementsByTagName('i')[0]; if (icon) { if (!iconElm || iconElm !== btnElm.firstChild) { iconElm = domGlobals.document.createElement('i'); btnElm.insertBefore(iconElm, btnElm.firstChild); } iconElm.className = icon; } else if (iconElm) { btnElm.removeChild(iconElm); } setButtonText(self.state.get('text')); }); return self._super(); } }); var BrowseButton = Button.extend({ init: function (settings) { var self = this; settings = global$4.extend({ text: 'Browse...', multiple: false, accept: null }, settings); self._super(settings); self.classes.add('browsebutton'); if (settings.multiple) { self.classes.add('multiple'); } }, postRender: function () { var self = this; var input = funcs.create('input', { type: 'file', id: self._id + '-browse', accept: self.settings.accept }); self._super(); global$7(input).on('change', function (e) { var files = e.target.files; self.value = function () { if (!files.length) { return null; } else if (self.settings.multiple) { return files; } else { return files[0]; } }; e.preventDefault(); if (files.length) { self.fire('change', e); } }); global$7(input).on('click', function (e) { e.stopPropagation(); }); global$7(self.getEl('button')).on('click', function (e) { e.stopPropagation(); input.click(); }); self.getEl().appendChild(input); }, remove: function () { global$7(this.getEl('button')).off(); global$7(this.getEl('input')).off(); this._super(); } }); var ButtonGroup = Container.extend({ Defaults: { defaultType: 'button', role: 'group' }, renderHtml: function () { var self = this, layout = self._layout; self.classes.add('btn-group'); self.preRender(); layout.preRender(self); return '<div id="' + self._id + '" class="' + self.classes + '">' + '<div id="' + self._id + '-body">' + (self.settings.html || '') + layout.renderHtml(self) + '</div>' + '</div>'; } }); var Checkbox = Widget.extend({ Defaults: { classes: 'checkbox', role: 'checkbox', checked: false }, init: function (settings) { var self = this; self._super(settings); self.on('click mousedown', function (e) { e.preventDefault(); }); self.on('click', function (e) { e.preventDefault(); if (!self.disabled()) { self.checked(!self.checked()); } }); self.checked(self.settings.checked); }, checked: function (state) { if (!arguments.length) { return this.state.get('checked'); } this.state.set('checked', state); return this; }, value: function (state) { if (!arguments.length) { return this.checked(); } return this.checked(state); }, renderHtml: function () { var self = this, id = self._id, prefix = self.classPrefix; 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>'; }, bindStates: function () { var self = this; function checked(state) { self.classes.toggle('checked', state); self.aria('checked', state); } self.state.on('change:text', function (e) { self.getEl('al').firstChild.data = self.translate(e.value); }); self.state.on('change:checked change:value', function (e) { self.fire('change'); checked(e.value); }); self.state.on('change:icon', function (e) { var icon = e.value; var prefix = self.classPrefix; if (typeof icon === 'undefined') { return self.settings.icon; } self.settings.icon = icon; icon = icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : ''; var btnElm = self.getEl().firstChild; var iconElm = btnElm.getElementsByTagName('i')[0]; if (icon) { if (!iconElm || iconElm !== btnElm.firstChild) { iconElm = domGlobals.document.createElement('i'); btnElm.insertBefore(iconElm, btnElm.firstChild); } iconElm.className = icon; } else if (iconElm) { btnElm.removeChild(iconElm); } }); if (self.state.get('checked')) { checked(true); } return self._super(); } }); var global$f = tinymce.util.Tools.resolve('tinymce.util.VK'); var ComboBox = Widget.extend({ init: function (settings) { var self = this; self._super(settings); settings = self.settings; self.classes.add('combobox'); self.subinput = true; self.ariaTarget = 'inp'; settings.menu = settings.menu || settings.values; if (settings.menu) { settings.icon = 'caret'; } self.on('click', function (e) { var elm = e.target; var root = self.getEl(); if (!global$7.contains(root, elm) && elm !== root) { return; } while (elm && elm !== root) { if (elm.id && elm.id.indexOf('-open') !== -1) { self.fire('action'); if (settings.menu) { self.showMenu(); if (e.aria) { self.menu.items()[0].focus(); } } } elm = elm.parentNode; } }); self.on('keydown', function (e) { var rootControl; if (e.keyCode === 13 && e.target.nodeName === 'INPUT') { e.preventDefault(); self.parents().reverse().each(function (ctrl) { if (ctrl.toJSON) { rootControl = ctrl; return false; } }); self.fire('submit', { data: rootControl.toJSON() }); } }); self.on('keyup', function (e) { if (e.target.nodeName === 'INPUT') { var oldValue = self.state.get('value'); var newValue = e.target.value; if (newValue !== oldValue) { self.state.set('value', newValue); self.fire('autocomplete', e); } } }); self.on('mouseover', function (e) { var tooltip = self.tooltip().moveTo(-65535); if (self.statusLevel() && e.target.className.indexOf(self.classPrefix + 'status') !== -1) { var statusMessage = self.statusMessage() || 'Ok'; var rel = tooltip.text(statusMessage).show().testMoveRel(e.target, [ 'bc-tc', 'bc-tl', 'bc-tr' ]); tooltip.classes.toggle('tooltip-n', rel === 'bc-tc'); tooltip.classes.toggle('tooltip-nw', rel === 'bc-tl'); tooltip.classes.toggle('tooltip-ne', rel === 'bc-tr'); tooltip.moveRel(e.target, rel); } }); }, statusLevel: function (value) { if (arguments.length > 0) { this.state.set('statusLevel', value); } return this.state.get('statusLevel'); }, statusMessage: function (value) { if (arguments.length > 0) { this.state.set('statusMessage', value); } return this.state.get('statusMessage'); }, showMenu: function () { var self = this; var settings = self.settings; var menu; if (!self.menu) { menu = settings.menu || []; if (menu.length) { menu = { type: 'menu', items: menu }; } else { menu.type = menu.type || 'menu'; } self.menu = global$b.create(menu).parent(self).renderTo(self.getContainerElm()); self.fire('createmenu'); self.menu.reflow(); self.menu.on('cancel', function (e) { if (e.control === self.menu) { self.focus(); } }); self.menu.on('show hide', function (e) { e.control.items().each(function (ctrl) { ctrl.active(ctrl.value() === self.value()); }); }).fire('show'); self.menu.on('select', function (e) { self.value(e.control.value()); }); self.on('focusin', function (e) { if (e.target.tagName.toUpperCase() === 'INPUT') { self.menu.hide(); } }); self.aria('expanded', true); } self.menu.show(); self.menu.layoutRect({ w: self.layoutRect().w }); self.menu.moveRel(self.getEl(), self.isRtl() ? [ 'br-tr', 'tr-br' ] : [ 'bl-tl', 'tl-bl' ]); }, focus: function () { this.getEl('inp').focus(); }, repaint: function () { var self = this, elm = self.getEl(), openElm = self.getEl('open'), rect = self.layoutRect(); var width, lineHeight, innerPadding = 0; var inputElm = elm.firstChild; if (self.statusLevel() && self.statusLevel() !== 'none') { innerPadding = parseInt(funcs.getRuntimeStyle(inputElm, 'padding-right'), 10) - parseInt(funcs.getRuntimeStyle(inputElm, 'padding-left'), 10); } if (openElm) { width = rect.w - funcs.getSize(openElm).width - 10; } else { width = rect.w - 10; } var doc = domGlobals.document; if (doc.all && (!doc.documentMode || doc.documentMode <= 8)) { lineHeight = self.layoutRect().h - 2 + 'px'; } global$7(inputElm).css({ width: width - innerPadding, lineHeight: lineHeight }); self._super(); return self; }, postRender: function () { var self = this; global$7(this.getEl('inp')).on('change', function (e) { self.state.set('value', e.target.value); self.fire('change', e); }); return self._super(); }, renderHtml: function () { var self = this, id = self._id, settings = self.settings, prefix = self.classPrefix; var value = self.state.get('value') || ''; var icon, text, openBtnHtml = '', extraAttrs = '', statusHtml = ''; if ('spellcheck' in settings) { extraAttrs += ' spellcheck="' + settings.spellcheck + '"'; } if (settings.maxLength) { extraAttrs += ' maxlength="' + settings.maxLength + '"'; } if (settings.size) { extraAttrs += ' size="' + settings.size + '"'; } if (settings.subtype) { extraAttrs += ' type="' + settings.subtype + '"'; } statusHtml = '<i id="' + id + '-status" class="mce-status mce-ico" style="display: none"></i>'; if (self.disabled()) { extraAttrs += ' disabled="disabled"'; } icon = settings.icon; if (icon && icon !== 'caret') { icon = prefix + 'ico ' + prefix + 'i-' + settings.icon; } text = self.state.get('text'); if (icon || text) { 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>'; self.classes.add('has-open'); } 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>'; }, value: function (value) { if (arguments.length) { this.state.set('value', value); return this; } if (this.state.get('rendered')) { this.state.set('value', this.getEl('inp').value); } return this.state.get('value'); }, showAutoComplete: function (items, term) { var self = this; if (items.length === 0) { self.hideMenu(); return; } var insert = function (value, title) { return function () { self.fire('selectitem', { title: title, value: value }); }; }; if (self.menu) { self.menu.items().remove(); } else { self.menu = global$b.create({ type: 'menu', classes: 'combobox-menu', layout: 'flow' }).parent(self).renderTo(); } global$4.each(items, function (item) { self.menu.add({ text: item.title, url: item.previewUrl, match: term, classes: 'menu-item-ellipsis', onclick: insert(item.value, item.title) }); }); self.menu.renderNew(); self.hideMenu(); self.menu.on('cancel', function (e) { if (e.control.parent() === self.menu) { e.stopPropagation(); self.focus(); self.hideMenu(); } }); self.menu.on('select', function () { self.focus(); }); var maxW = self.layoutRect().w; self.menu.layoutRect({ w: maxW, minW: 0, maxW: maxW }); self.menu.repaint(); self.menu.reflow(); self.menu.show(); self.menu.moveRel(self.getEl(), self.isRtl() ? [ 'br-tr', 'tr-br' ] : [ 'bl-tl', 'tl-bl' ]); }, hideMenu: function () { if (this.menu) { this.menu.hide(); } }, bindStates: function () { var self = this; self.state.on('change:value', function (e) { if (self.getEl('inp').value !== e.value) { self.getEl('inp').value = e.value; } }); self.state.on('change:disabled', function (e) { self.getEl('inp').disabled = e.value; }); self.state.on('change:statusLevel', function (e) { var statusIconElm = self.getEl('status'); var prefix = self.classPrefix, value = e.value; funcs.css(statusIconElm, 'display', value === 'none' ? 'none' : ''); funcs.toggleClass(statusIconElm, prefix + 'i-checkmark', value === 'ok'); funcs.toggleClass(statusIconElm, prefix + 'i-warning', value === 'warn'); funcs.toggleClass(statusIconElm, prefix + 'i-error', value === 'error'); self.classes.toggle('has-status', value !== 'none'); self.repaint(); }); funcs.on(self.getEl('status'), 'mouseleave', function () { self.tooltip().hide(); }); self.on('cancel', function (e) { if (self.menu && self.menu.visible()) { e.stopPropagation(); self.hideMenu(); } }); var focusIdx = function (idx, menu) { if (menu && menu.items().length > 0) { menu.items().eq(idx)[0].focus(); } }; self.on('keydown', function (e) { var keyCode = e.keyCode; if (e.target.nodeName === 'INPUT') { if (keyCode === global$f.DOWN) { e.preventDefault(); self.fire('autocomplete'); focusIdx(0, self.menu); } else if (keyCode === global$f.UP) { e.preventDefault(); focusIdx(-1, self.menu); } } }); return self._super(); }, remove: function () { global$7(this.getEl('inp')).off(); if (this.menu) { this.menu.remove(); } this._super(); } }); var ColorBox = ComboBox.extend({ init: function (settings) { var self = this; settings.spellcheck = false; if (settings.onaction) { settings.icon = 'none'; } self._super(settings); self.classes.add('colorbox'); self.on('change keyup postrender', function () { self.repaintColor(self.value()); }); }, repaintColor: function (value) { var openElm = this.getEl('open'); var elm = openElm ? openElm.getElementsByTagName('i')[0] : null; if (elm) { try { elm.style.background = value; } catch (ex) { } } }, bindStates: function () { var self = this; self.state.on('change:value', function (e) { if (self.state.get('rendered')) { self.repaintColor(e.value); } }); return self._super(); } }); var PanelButton = Button.extend({ showPanel: function () { var self = this, settings = self.settings; self.classes.add('opened'); if (!self.panel) { var panelSettings = settings.panel; if (panelSettings.type) { panelSettings = { layout: 'grid', items: panelSettings }; } panelSettings.role = panelSettings.role || 'dialog'; panelSettings.popover = true; panelSettings.autohide = true; panelSettings.ariaRoot = true; self.panel = new FloatPanel(panelSettings).on('hide', function () { self.classes.remove('opened'); }).on('cancel', function (e) { e.stopPropagation(); self.focus(); self.hidePanel(); }).parent(self).renderTo(self.getContainerElm()); self.panel.fire('show'); self.panel.reflow(); } else { self.panel.show(); } var rtlRels = [ 'bc-tc', 'bc-tl', 'bc-tr' ]; var ltrRels = [ 'bc-tc', 'bc-tr', 'bc-tl', 'tc-bc', 'tc-br', 'tc-bl' ]; var rel = self.panel.testMoveRel(self.getEl(), settings.popoverAlign || (self.isRtl() ? rtlRels : ltrRels)); self.panel.classes.toggle('start', rel.substr(-1) === 'l'); self.panel.classes.toggle('end', rel.substr(-1) === 'r'); var isTop = rel.substr(0, 1) === 't'; self.panel.classes.toggle('bottom', !isTop); self.panel.classes.toggle('top', isTop); self.panel.moveRel(self.getEl(), rel); }, hidePanel: function () { var self = this; if (self.panel) { self.panel.hide(); } }, postRender: function () { var self = this; self.aria('haspopup', true); self.on('click', function (e) { if (e.control === self) { if (self.panel && self.panel.visible()) { self.hidePanel(); } else { self.showPanel(); self.panel.focus(!!e.aria); } } }); return self._super(); }, remove: function () { if (this.panel) { this.panel.remove(); this.panel = null; } return this._super(); } }); var DOM = global$2.DOM; var ColorButton = PanelButton.extend({ init: function (settings) { this._super(settings); this.classes.add('splitbtn'); this.classes.add('colorbutton'); }, color: function (color) { if (color) { this._color = color; this.getEl('preview').style.backgroundColor = color; return this; } return this._color; }, resetColor: function () { this._color = null; this.getEl('preview').style.backgroundColor = null; return this; }, renderHtml: function () { var self = this, id = self._id, prefix = self.classPrefix, text = self.state.get('text'); var icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : ''; var image = self.settings.image ? ' style="background-image: url(\'' + self.settings.image + '\')"' : ''; var textHtml = ''; if (text) { self.classes.add('btn-has-text'); textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>'; } 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>'; }, postRender: function () { var self = this, onClickHandler = self.settings.onclick; self.on('click', function (e) { if (e.aria && e.aria.key === 'down') { return; } if (e.control === self && !DOM.getParent(e.target, '.' + self.classPrefix + 'open')) { e.stopImmediatePropagation(); onClickHandler.call(self, e); } }); delete self.settings.onclick; return self._super(); } }); var global$g = tinymce.util.Tools.resolve('tinymce.util.Color'); var ColorPicker = Widget.extend({ Defaults: { classes: 'widget colorpicker' }, init: function (settings) { this._super(settings); }, postRender: function () { var self = this; var color = self.color(); var hsv, hueRootElm, huePointElm, svRootElm, svPointElm; hueRootElm = self.getEl('h'); huePointElm = self.getEl('hp'); svRootElm = self.getEl('sv'); svPointElm = self.getEl('svp'); function getPos(elm, event) { var pos = funcs.getPos(elm); var x, y; x = event.pageX - pos.x; y = event.pageY - pos.y; x = Math.max(0, Math.min(x / elm.clientWidth, 1)); y = Math.max(0, Math.min(y / elm.clientHeight, 1)); return { x: x, y: y }; } function updateColor(hsv, hueUpdate) { var hue = (360 - hsv.h) / 360; funcs.css(huePointElm, { top: hue * 100 + '%' }); if (!hueUpdate) { funcs.css(svPointElm, { left: hsv.s + '%', top: 100 - hsv.v + '%' }); } svRootElm.style.background = global$g({ s: 100, v: 100, h: hsv.h }).toHex(); self.color().parse({ s: hsv.s, v: hsv.v, h: hsv.h }); } function updateSaturationAndValue(e) { var pos; pos = getPos(svRootElm, e); hsv.s = pos.x * 100; hsv.v = (1 - pos.y) * 100; updateColor(hsv); self.fire('change'); } function updateHue(e) { var pos; pos = getPos(hueRootElm, e); hsv = color.toHsv(); hsv.h = (1 - pos.y) * 360; updateColor(hsv, true); self.fire('change'); } self._repaint = function () { hsv = color.toHsv(); updateColor(hsv); }; self._super(); self._svdraghelper = new DragHelper(self._id + '-sv', { start: updateSaturationAndValue, drag: updateSaturationAndValue }); self._hdraghelper = new DragHelper(self._id + '-h', { start: updateHue, drag: updateHue }); self._repaint(); }, rgb: function () { return this.color().toRgb(); }, value: function (value) { var self = this; if (arguments.length) { self.color().parse(value); if (self._rendered) { self._repaint(); } } else { return self.color().toHex(); } }, color: function () { if (!this._color) { this._color = global$g(); } return this._color; }, renderHtml: function () { var self = this; var id = self._id; var prefix = self.classPrefix; var hueHtml; var stops = '#ff0000,#ff0080,#ff00ff,#8000ff,#0000ff,#0080ff,#00ffff,#00ff80,#00ff00,#80ff00,#ffff00,#ff8000,#ff0000'; function getOldIeFallbackHtml() { var i, l, html = '', gradientPrefix, stopsList; gradientPrefix = 'filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='; stopsList = stops.split(','); for (i = 0, l = stopsList.length - 1; i < l; i++) { 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>'; } return html; } var gradientCssText = 'background: -ms-linear-gradient(top,' + stops + ');' + 'background: linear-gradient(to bottom,' + stops + ');'; hueHtml = '<div id="' + id + '-h" class="' + prefix + 'colorpicker-h" style="' + gradientCssText + '">' + getOldIeFallbackHtml() + '<div id="' + id + '-hp" class="' + prefix + 'colorpicker-h-marker"></div>' + '</div>'; 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>'; } }); var DropZone = Widget.extend({ init: function (settings) { var self = this; settings = global$4.extend({ height: 100, text: 'Drop an image here', multiple: false, accept: null }, settings); self._super(settings); self.classes.add('dropzone'); if (settings.multiple) { self.classes.add('multiple'); } }, renderHtml: function () { var self = this; var attrs, elm; var cfg = self.settings; attrs = { id: self._id, hidefocus: '1' }; elm = funcs.create('div', attrs, '<span>' + this.translate(cfg.text) + '</span>'); if (cfg.height) { funcs.css(elm, 'height', cfg.height + 'px'); } if (cfg.width) { funcs.css(elm, 'width', cfg.width + 'px'); } elm.className = self.classes; return elm.outerHTML; }, postRender: function () { var self = this; var toggleDragClass = function (e) { e.preventDefault(); self.classes.toggle('dragenter'); self.getEl().className = self.classes; }; var filter = function (files) { var accept = self.settings.accept; if (typeof accept !== 'string') { return files; } var re = new RegExp('(' + accept.split(/\s*,\s*/).join('|') + ')$', 'i'); return global$4.grep(files, function (file) { return re.test(file.name); }); }; self._super(); self.$el.on('dragover', function (e) { e.preventDefault(); }); self.$el.on('dragenter', toggleDragClass); self.$el.on('dragleave', toggleDragClass); self.$el.on('drop', function (e) { e.preventDefault(); if (self.state.get('disabled')) { return; } var files = filter(e.dataTransfer.files); self.value = function () { if (!files.length) { return null; } else if (self.settings.multiple) { return files; } else { return files[0]; } }; if (files.length) { self.fire('change', e); } }); }, remove: function () { this.$el.off(); this._super(); } }); var Path = Widget.extend({ init: function (settings) { var self = this; if (!settings.delimiter) { settings.delimiter = '\xBB'; } self._super(settings); self.classes.add('path'); self.canFocus = true; self.on('click', function (e) { var index; var target = e.target; if (index = target.getAttribute('data-index')) { self.fire('select', { value: self.row()[index], index: index }); } }); self.row(self.settings.row); }, focus: function () { var self = this; self.getEl().firstChild.focus(); return self; }, row: function (row) { if (!arguments.length) { return this.state.get('row'); } this.state.set('row', row); return this; }, renderHtml: function () { var self = this; return '<div id="' + self._id + '" class="' + self.classes + '">' + self._getDataPathHtml(self.state.get('row')) + '</div>'; }, bindStates: function () { var self = this; self.state.on('change:row', function (e) { self.innerHtml(self._getDataPathHtml(e.value)); }); return self._super(); }, _getDataPathHtml: function (data) { var self = this; var parts = data || []; var i, l, html = ''; var prefix = self.classPrefix; for (i = 0, l = parts.length; i < l; i++) { 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>'; } if (!html) { html = '<div class="' + prefix + 'path-item">\xA0</div>'; } return html; } }); var ElementPath = Path.extend({ postRender: function () { var self = this, editor = self.settings.editor; function isHidden(elm) { if (elm.nodeType === 1) { if (elm.nodeName === 'BR' || !!elm.getAttribute('data-mce-bogus')) { return true; } if (elm.getAttribute('data-mce-type') === 'bookmark') { return true; } } return false; } if (editor.settings.elementpath !== false) { self.on('select', function (e) { editor.focus(); editor.selection.select(this.row()[e.index].element); editor.nodeChanged(); }); editor.on('nodeChange', function (e) { var outParents = []; var parents = e.parents; var i = parents.length; while (i--) { if (parents[i].nodeType === 1 && !isHidden(parents[i])) { var args = editor.fire('ResolveName', { name: parents[i].nodeName.toLowerCase(), target: parents[i] }); if (!args.isDefaultPrevented()) { outParents.push({ name: args.name, element: parents[i] }); } if (args.isPropagationStopped()) { break; } } } self.row(outParents); }); } return self._super(); } }); var FormItem = Container.extend({ Defaults: { layout: 'flex', align: 'center', defaults: { flex: 1 } }, renderHtml: function () { var self = this, layout = self._layout, prefix = self.classPrefix; self.classes.add('formitem'); layout.preRender(self); 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>'; } }); var Form = Container.extend({ Defaults: { containerCls: 'form', layout: 'flex', direction: 'column', align: 'stretch', flex: 1, padding: 15, labelGap: 30, spacing: 10, callbacks: { submit: function () { this.submit(); } } }, preRender: function () { var self = this, items = self.items(); if (!self.settings.formItemDefaults) { self.settings.formItemDefaults = { layout: 'flex', autoResize: 'overflow', defaults: { flex: 1 } }; } items.each(function (ctrl) { var formItem; var label = ctrl.settings.label; if (label) { formItem = new FormItem(global$4.extend({ items: { type: 'label', id: ctrl._id + '-l', text: label, flex: 0, forId: ctrl._id, disabled: ctrl.disabled() } }, self.settings.formItemDefaults)); formItem.type = 'formitem'; ctrl.aria('labelledby', ctrl._id + '-l'); if (typeof ctrl.settings.flex === 'undefined') { ctrl.settings.flex = 1; } self.replace(ctrl, formItem); formItem.add(ctrl); } }); }, submit: function () { return this.fire('submit', { data: this.toJSON() }); }, postRender: function () { var self = this; self._super(); self.fromJSON(self.settings.data); }, bindStates: function () { var self = this; self._super(); function recalcLabels() { var maxLabelWidth = 0; var labels = []; var i, labelGap, items; if (self.settings.labelGapCalc === false) { return; } if (self.settings.labelGapCalc === 'children') { items = self.find('formitem'); } else { items = self.items(); } items.filter('formitem').each(function (item) { var labelCtrl = item.items()[0], labelWidth = labelCtrl.getEl().clientWidth; maxLabelWidth = labelWidth > maxLabelWidth ? labelWidth : maxLabelWidth; labels.push(labelCtrl); }); labelGap = self.settings.labelGap || 0; i = labels.length; while (i--) { labels[i].settings.minWidth = maxLabelWidth + labelGap; } } self.on('show', recalcLabels); recalcLabels(); } }); var FieldSet = Form.extend({ Defaults: { containerCls: 'fieldset', layout: 'flex', direction: 'column', align: 'stretch', flex: 1, padding: '25 15 5 15', labelGap: 30, spacing: 10, border: 1 }, renderHtml: function () { var self = this, layout = self._layout, prefix = self.classPrefix; self.preRender(); layout.preRender(self); 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>'; } }); var unique$1 = 0; var generate = function (prefix) { var date = new Date(); var time = date.getTime(); var random = Math.floor(Math.random() * 1000000000); unique$1++; return prefix + '_' + random + unique$1 + String(time); }; var fromHtml = function (html, scope) { var doc = scope || domGlobals.document; var div = doc.createElement('div'); div.innerHTML = html; if (!div.hasChildNodes() || div.childNodes.length > 1) { domGlobals.console.error('HTML does not have a single root node', html); throw new Error('HTML must have a single root node'); } return fromDom(div.childNodes[0]); }; var fromTag = function (tag, scope) { var doc = scope || domGlobals.document; var node = doc.createElement(tag); return fromDom(node); }; var fromText = function (text, scope) { var doc = scope || domGlobals.document; var node = doc.createTextNode(text); return fromDom(node); }; var fromDom = function (node) { if (node === null || node === undefined) { throw new Error('Node cannot be null or undefined'); } return { dom: constant(node) }; }; var fromPoint = function (docElm, x, y) { var doc = docElm.dom(); return Option.from(doc.elementFromPoint(x, y)).map(fromDom); }; var Element = { fromHtml: fromHtml, fromTag: fromTag, fromText: fromText, fromDom: fromDom, fromPoint: fromPoint }; var cached = function (f) { var called = false; var r; return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (!called) { called = true; r = f.apply(null, args); } return r; }; }; var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE; var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE; var COMMENT = domGlobals.Node.COMMENT_NODE; var DOCUMENT = domGlobals.Node.DOCUMENT_NODE; var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE; var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE; var ELEMENT = domGlobals.Node.ELEMENT_NODE; var TEXT = domGlobals.Node.TEXT_NODE; var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE; var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE; var ENTITY = domGlobals.Node.ENTITY_NODE; var NOTATION = domGlobals.Node.NOTATION_NODE; var Immutable = function () { var fields = []; for (var _i = 0; _i < arguments.length; _i++) { fields[_i] = arguments[_i]; } return function () { var values = []; for (var _i = 0; _i < arguments.length; _i++) { values[_i] = arguments[_i]; } if (fields.length !== values.length) { throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments'); } var struct = {}; each(fields, function (name, i) { struct[name] = constant(values[i]); }); return struct; }; }; var node = function () { var f = Global$1.getOrDie('Node'); return f; }; var compareDocumentPosition = function (a, b, match) { return (a.compareDocumentPosition(b) & match) !== 0; }; var documentPositionPreceding = function (a, b) { return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_PRECEDING); }; var documentPositionContainedBy = function (a, b) { return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_CONTAINED_BY); }; var Node = { documentPositionPreceding: documentPositionPreceding, documentPositionContainedBy: documentPositionContainedBy }; var firstMatch = function (regexes, s) { for (var i = 0; i < regexes.length; i++) { var x = regexes[i]; if (x.test(s)) return x; } return undefined; }; var find$1 = function (regexes, agent) { var r = firstMatch(regexes, agent); if (!r) return { major: 0, minor: 0 }; var group = function (i) { return Number(agent.replace(r, '$' + i)); }; return nu(group(1), group(2)); }; var detect = function (versionRegexes, agent) { var cleanedAgent = String(agent).toLowerCase(); if (versionRegexes.length === 0) return unknown(); return find$1(versionRegexes, cleanedAgent); }; var unknown = function () { return nu(0, 0); }; var nu = function (major, minor) { return { major: major, minor: minor }; }; var Version = { nu: nu, detect: detect, unknown: unknown }; var edge = 'Edge'; var chrome = 'Chrome'; var ie = 'IE'; var opera = 'Opera'; var firefox = 'Firefox'; var safari = 'Safari'; var isBrowser = function (name, current) { return function () { return current === name; }; }; var unknown$1 = function () { return nu$1({ current: undefined, version: Version.unknown() }); }; var nu$1 = function (info) { var current = info.current; var version = info.version; return { current: current, version: version, isEdge: isBrowser(edge, current), isChrome: isBrowser(chrome, current), isIE: isBrowser(ie, current), isOpera: isBrowser(opera, current), isFirefox: isBrowser(firefox, current), isSafari: isBrowser(safari, current) }; }; var Browser = { unknown: unknown$1, nu: nu$1, edge: constant(edge), chrome: constant(chrome), ie: constant(ie), opera: constant(opera), firefox: constant(firefox), safari: constant(safari) }; var windows$1 = 'Windows'; var ios = 'iOS'; var android = 'Android'; var linux = 'Linux'; var osx = 'OSX'; var solaris = 'Solaris'; var freebsd = 'FreeBSD'; var isOS = function (name, current) { return function () { return current === name; }; }; var unknown$2 = function () { return nu$2({ current: undefined, version: Version.unknown() }); }; var nu$2 = function (info) { var current = info.current; var version = info.version; return { current: current, version: version, isWindows: isOS(windows$1, current), isiOS: isOS(ios, current), isAndroid: isOS(android, current), isOSX: isOS(osx, current), isLinux: isOS(linux, current), isSolaris: isOS(solaris, current), isFreeBSD: isOS(freebsd, current) }; }; var OperatingSystem = { unknown: unknown$2, nu: nu$2, windows: constant(windows$1), ios: constant(ios), android: constant(android), linux: constant(linux), osx: constant(osx), solaris: constant(solaris), freebsd: constant(freebsd) }; var DeviceType = function (os, browser, userAgent) { var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true; var isiPhone = os.isiOS() && !isiPad; var isAndroid3 = os.isAndroid() && os.version.major === 3; var isAndroid4 = os.isAndroid() && os.version.major === 4; var isTablet = isiPad || isAndroid3 || isAndroid4 && /mobile/i.test(userAgent) === true; var isTouch = os.isiOS() || os.isAndroid(); var isPhone = isTouch && !isTablet; var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false; return { isiPad: constant(isiPad), isiPhone: constant(isiPhone), isTablet: constant(isTablet), isPhone: constant(isPhone), isTouch: constant(isTouch), isAndroid: os.isAndroid, isiOS: os.isiOS, isWebView: constant(iOSwebview) }; }; var detect$1 = function (candidates, userAgent) { var agent = String(userAgent).toLowerCase(); return find(candidates, function (candidate) { return candidate.search(agent); }); }; var detectBrowser = function (browsers, userAgent) { return detect$1(browsers, userAgent).map(function (browser) { var version = Version.detect(browser.versionRegexes, userAgent); return { current: browser.name, version: version }; }); }; var detectOs = function (oses, userAgent) { return detect$1(oses, userAgent).map(function (os) { var version = Version.detect(os.versionRegexes, userAgent); return { current: os.name, version: version }; }); }; var UaString = { detectBrowser: detectBrowser, detectOs: detectOs }; var contains = function (str, substr) { return str.indexOf(substr) !== -1; }; var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/; var checkContains = function (target) { return function (uastring) { return contains(uastring, target); }; }; var browsers = [ { name: 'Edge', versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/], search: function (uastring) { var monstrosity = contains(uastring, 'edge/') && contains(uastring, 'chrome') && contains(uastring, 'safari') && contains(uastring, 'applewebkit'); return monstrosity; } }, { name: 'Chrome', versionRegexes: [ /.*?chrome\/([0-9]+)\.([0-9]+).*/, normalVersionRegex ], search: function (uastring) { return contains(uastring, 'chrome') && !contains(uastring, 'chromeframe'); } }, { name: 'IE', versionRegexes: [ /.*?msie\ ?([0-9]+)\.([0-9]+).*/, /.*?rv:([0-9]+)\.([0-9]+).*/ ], search: function (uastring) { return contains(uastring, 'msie') || contains(uastring, 'trident'); } }, { name: 'Opera', versionRegexes: [ normalVersionRegex, /.*?opera\/([0-9]+)\.([0-9]+).*/ ], search: checkContains('opera') }, { name: 'Firefox', versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/], search: checkContains('firefox') }, { name: 'Safari', versionRegexes: [ normalVersionRegex, /.*?cpu os ([0-9]+)_([0-9]+).*/ ], search: function (uastring) { return (contains(uastring, 'safari') || contains(uastring, 'mobile/')) && contains(uastring, 'applewebkit'); } } ]; var oses = [ { name: 'Windows', search: checkContains('win'), versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/] }, { name: 'iOS', search: function (uastring) { return contains(uastring, 'iphone') || contains(uastring, 'ipad'); }, versionRegexes: [ /.*?version\/\ ?([0-9]+)\.([0-9]+).*/, /.*cpu os ([0-9]+)_([0-9]+).*/, /.*cpu iphone os ([0-9]+)_([0-9]+).*/ ] }, { name: 'Android', search: checkContains('android'), versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/] }, { name: 'OSX', search: checkContains('os x'), versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/] }, { name: 'Linux', search: checkContains('linux'), versionRegexes: [] }, { name: 'Solaris', search: checkContains('sunos'), versionRegexes: [] }, { name: 'FreeBSD', search: checkContains('freebsd'), versionRegexes: [] } ]; var PlatformInfo = { browsers: constant(browsers), oses: constant(oses) }; var detect$2 = function (userAgent) { var browsers = PlatformInfo.browsers(); var oses = PlatformInfo.oses(); var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu); var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu); var deviceType = DeviceType(os, browser, userAgent); return { browser: browser, os: os, deviceType: deviceType }; }; var PlatformDetection = { detect: detect$2 }; var detect$3 = cached(function () { var userAgent = domGlobals.navigator.userAgent; return PlatformDetection.detect(userAgent); }); var PlatformDetection$1 = { detect: detect$3 }; var ELEMENT$1 = ELEMENT; var DOCUMENT$1 = DOCUMENT; var bypassSelector = function (dom) { return dom.nodeType !== ELEMENT$1 && dom.nodeType !== DOCUMENT$1 || dom.childElementCount === 0; }; var all = function (selector, scope) { var base = scope === undefined ? domGlobals.document : scope.dom(); return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), Element.fromDom); }; var one = function (selector, scope) { var base = scope === undefined ? domGlobals.document : scope.dom(); return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom); }; var regularContains = function (e1, e2) { var d1 = e1.dom(); var d2 = e2.dom(); return d1 === d2 ? false : d1.contains(d2); }; var ieContains = function (e1, e2) { return Node.documentPositionContainedBy(e1.dom(), e2.dom()); }; var browser = PlatformDetection$1.detect().browser; var contains$1 = browser.isIE() ? ieContains : regularContains; var spot = Immutable('element', 'offset'); var descendants = function (scope, selector) { return all(selector, scope); }; var trim = global$4.trim; var hasContentEditableState = function (value) { return function (node) { if (node && node.nodeType === 1) { if (node.contentEditable === value) { return true; } if (node.getAttribute('data-mce-contenteditable') === value) { return true; } } return false; }; }; var isContentEditableTrue = hasContentEditableState('true'); var isContentEditableFalse = hasContentEditableState('false'); var create$4 = function (type, title, url, level, attach) { return { type: type, title: title, url: url, level: level, attach: attach }; }; var isChildOfContentEditableTrue = function (node) { while (node = node.parentNode) { var value = node.contentEditable; if (value && value !== 'inherit') { return isContentEditableTrue(node); } } return false; }; var select = function (selector, root) { return map(descendants(Element.fromDom(root), selector), function (element) { return element.dom(); }); }; var getElementText = function (elm) { return elm.innerText || elm.textContent; }; var getOrGenerateId = function (elm) { return elm.id ? elm.id : generate('h'); }; var isAnchor = function (elm) { return elm && elm.nodeName === 'A' && (elm.id || elm.name); }; var isValidAnchor = function (elm) { return isAnchor(elm) && isEditable(elm); }; var isHeader = function (elm) { return elm && /^(H[1-6])$/.test(elm.nodeName); }; var isEditable = function (elm) { return isChildOfContentEditableTrue(elm) && !isContentEditableFalse(elm); }; var isValidHeader = function (elm) { return isHeader(elm) && isEditable(elm); }; var getLevel = function (elm) { return isHeader(elm) ? parseInt(elm.nodeName.substr(1), 10) : 0; }; var headerTarget = function (elm) { var headerId = getOrGenerateId(elm); var attach = function () { elm.id = headerId; }; return create$4('header', getElementText(elm), '#' + headerId, getLevel(elm), attach); }; var anchorTarget = function (elm) { var anchorId = elm.id || elm.name; var anchorText = getElementText(elm); return create$4('anchor', anchorText ? anchorText : '#' + anchorId, '#' + anchorId, 0, noop); }; var getHeaderTargets = function (elms) { return map(filter(elms, isValidHeader), headerTarget); }; var getAnchorTargets = function (elms) { return map(filter(elms, isValidAnchor), anchorTarget); }; var getTargetElements = function (elm) { var elms = select('h1,h2,h3,h4,h5,h6,a:not([href])', elm); return elms; }; var hasTitle = function (target) { return trim(target.title).length > 0; }; var find$2 = function (elm) { var elms = getTargetElements(elm); return filter(getHeaderTargets(elms).concat(getAnchorTargets(elms)), hasTitle); }; var LinkTargets = { find: find$2 }; var getActiveEditor = function () { return window.tinymce ? window.tinymce.activeEditor : global$5.activeEditor; }; var history = {}; var HISTORY_LENGTH = 5; var clearHistory = function () { history = {}; }; var toMenuItem = function (target) { return { title: target.title, value: { title: { raw: target.title }, url: target.url, attach: target.attach } }; }; var toMenuItems = function (targets) { return global$4.map(targets, toMenuItem); }; var staticMenuItem = function (title, url) { return { title: title, value: { title: title, url: url, attach: noop } }; }; var isUniqueUrl = function (url, targets) { var foundTarget = exists(targets, function (target) { return target.url === url; }); return !foundTarget; }; var getSetting = function (editorSettings, name, defaultValue) { var value = name in editorSettings ? editorSettings[name] : defaultValue; return value === false ? null : value; }; var createMenuItems = function (term, targets, fileType, editorSettings) { var separator = { title: '-' }; var fromHistoryMenuItems = function (history) { var historyItems = history.hasOwnProperty(fileType) ? history[fileType] : []; var uniqueHistory = filter(historyItems, function (url) { return isUniqueUrl(url, targets); }); return global$4.map(uniqueHistory, function (url) { return { title: url, value: { title: url, url: url, attach: noop } }; }); }; var fromMenuItems = function (type) { var filteredTargets = filter(targets, function (target) { return target.type === type; }); return toMenuItems(filteredTargets); }; var anchorMenuItems = function () { var anchorMenuItems = fromMenuItems('anchor'); var topAnchor = getSetting(editorSettings, 'anchor_top', '#top'); var bottomAchor = getSetting(editorSettings, 'anchor_bottom', '#bottom'); if (topAnchor !== null) { anchorMenuItems.unshift(staticMenuItem('<top>', topAnchor)); } if (bottomAchor !== null) { anchorMenuItems.push(staticMenuItem('<bottom>', bottomAchor)); } return anchorMenuItems; }; var join = function (items) { return foldl(items, function (a, b) { var bothEmpty = a.length === 0 || b.length === 0; return bothEmpty ? a.concat(b) : a.concat(separator, b); }, []); }; if (editorSettings.typeahead_urls === false) { return []; } return fileType === 'file' ? join([ filterByQuery(term, fromHistoryMenuItems(history)), filterByQuery(term, fromMenuItems('header')), filterByQuery(term, anchorMenuItems()) ]) : filterByQuery(term, fromHistoryMenuItems(history)); }; var addToHistory = function (url, fileType) { var items = history[fileType]; if (!/^https?/.test(url)) { return; } if (items) { if (indexOf(items, url).isNone()) { history[fileType] = items.slice(0, HISTORY_LENGTH).concat(url); } } else { history[fileType] = [url]; } }; var filterByQuery = function (term, menuItems) { var lowerCaseTerm = term.toLowerCase(); var result = global$4.grep(menuItems, function (item) { return item.title.toLowerCase().indexOf(lowerCaseTerm) !== -1; }); return result.length === 1 && result[0].title === term ? [] : result; }; var getTitle = function (linkDetails) { var title = linkDetails.title; return title.raw ? title.raw : title; }; var setupAutoCompleteHandler = function (ctrl, editorSettings, bodyElm, fileType) { var autocomplete = function (term) { var linkTargets = LinkTargets.find(bodyElm); var menuItems = createMenuItems(term, linkTargets, fileType, editorSettings); ctrl.showAutoComplete(menuItems, term); }; ctrl.on('autocomplete', function () { autocomplete(ctrl.value()); }); ctrl.on('selectitem', function (e) { var linkDetails = e.value; ctrl.value(linkDetails.url); var title = getTitle(linkDetails); if (fileType === 'image') { ctrl.fire('change', { meta: { alt: title, attach: linkDetails.attach } }); } else { ctrl.fire('change', { meta: { text: title, attach: linkDetails.attach } }); } ctrl.focus(); }); ctrl.on('click', function (e) { if (ctrl.value().length === 0 && e.target.nodeName === 'INPUT') { autocomplete(''); } }); ctrl.on('PostRender', function () { ctrl.getRoot().on('submit', function (e) { if (!e.isDefaultPrevented()) { addToHistory(ctrl.value(), fileType); } }); }); }; var statusToUiState = function (result) { var status = result.status, message = result.message; if (status === 'valid') { return { status: 'ok', message: message }; } else if (status === 'unknown') { return { status: 'warn', message: message }; } else if (status === 'invalid') { return { status: 'warn', message: message }; } else { return { status: 'none', message: '' }; } }; var setupLinkValidatorHandler = function (ctrl, editorSettings, fileType) { var validatorHandler = editorSettings.filepicker_validator_handler; if (validatorHandler) { var validateUrl_1 = function (url) { if (url.length === 0) { ctrl.statusLevel('none'); return; } validatorHandler({ url: url, type: fileType }, function (result) { var uiState = statusToUiState(result); ctrl.statusMessage(uiState.message); ctrl.statusLevel(uiState.status); }); }; ctrl.state.on('change:value', function (e) { validateUrl_1(e.value); }); } }; var FilePicker = ComboBox.extend({ Statics: { clearHistory: clearHistory }, init: function (settings) { var self = this, editor = getActiveEditor(), editorSettings = editor.settings; var actionCallback, fileBrowserCallback, fileBrowserCallbackTypes; var fileType = settings.filetype; settings.spellcheck = false; fileBrowserCallbackTypes = editorSettings.file_picker_types || editorSettings.file_browser_callback_types; if (fileBrowserCallbackTypes) { fileBrowserCallbackTypes = global$4.makeMap(fileBrowserCallbackTypes, /[, ]/); } if (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[fileType]) { fileBrowserCallback = editorSettings.file_picker_callback; if (fileBrowserCallback && (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[fileType])) { actionCallback = function () { var meta = self.fire('beforecall').meta; meta = global$4.extend({ filetype: fileType }, meta); fileBrowserCallback.call(editor, function (value, meta) { self.value(value).fire('change', { meta: meta }); }, self.value(), meta); }; } else { fileBrowserCallback = editorSettings.file_browser_callback; if (fileBrowserCallback && (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[fileType])) { actionCallback = function () { fileBrowserCallback(self.getEl('inp').id, self.value(), fileType, window); }; } } } if (actionCallback) { settings.icon = 'browse'; settings.onaction = actionCallback; } self._super(settings); self.classes.add('filepicker'); setupAutoCompleteHandler(self, editorSettings, editor.getBody(), fileType); setupLinkValidatorHandler(self, editorSettings, fileType); } }); var FitLayout = AbsoluteLayout.extend({ recalc: function (container) { var contLayoutRect = container.layoutRect(), paddingBox = container.paddingBox; container.items().filter(':visible').each(function (ctrl) { ctrl.layoutRect({ x: paddingBox.left, y: paddingBox.top, w: contLayoutRect.innerW - paddingBox.right - paddingBox.left, h: contLayoutRect.innerH - paddingBox.top - paddingBox.bottom }); if (ctrl.recalc) { ctrl.recalc(); } }); } }); var FlexLayout = AbsoluteLayout.extend({ recalc: function (container) { var i, l, items, contLayoutRect, contPaddingBox, contSettings, align, pack, spacing, totalFlex, availableSpace, direction; var ctrl, ctrlLayoutRect, ctrlSettings, flex; var maxSizeItems = []; var size, maxSize, ratio, rect, pos, maxAlignEndPos; var sizeName, minSizeName, posName, maxSizeName, beforeName, innerSizeName, deltaSizeName, contentSizeName; var alignAxisName, alignInnerSizeName, alignSizeName, alignMinSizeName, alignBeforeName, alignAfterName; var alignDeltaSizeName, alignContentSizeName; var max = Math.max, min = Math.min; items = container.items().filter(':visible'); contLayoutRect = container.layoutRect(); contPaddingBox = container.paddingBox; contSettings = container.settings; direction = container.isRtl() ? contSettings.direction || 'row-reversed' : contSettings.direction; align = contSettings.align; pack = container.isRtl() ? contSettings.pack || 'end' : contSettings.pack; spacing = contSettings.spacing || 0; if (direction === 'row-reversed' || direction === 'column-reverse') { items = items.set(items.toArray().reverse()); direction = direction.split('-')[0]; } if (direction === 'column') { posName = 'y'; sizeName = 'h'; minSizeName = 'minH'; maxSizeName = 'maxH'; innerSizeName = 'innerH'; beforeName = 'top'; deltaSizeName = 'deltaH'; contentSizeName = 'contentH'; alignBeforeName = 'left'; alignSizeName = 'w'; alignAxisName = 'x'; alignInnerSizeName = 'innerW'; alignMinSizeName = 'minW'; alignAfterName = 'right'; alignDeltaSizeName = 'deltaW'; alignContentSizeName = 'contentW'; } else { posName = 'x'; sizeName = 'w'; minSizeName = 'minW'; maxSizeName = 'maxW'; innerSizeName = 'innerW'; beforeName = 'left'; deltaSizeName = 'deltaW'; contentSizeName = 'contentW'; alignBeforeName = 'top'; alignSizeName = 'h'; alignAxisName = 'y'; alignInnerSizeName = 'innerH'; alignMinSizeName = 'minH'; alignAfterName = 'bottom'; alignDeltaSizeName = 'deltaH'; alignContentSizeName = 'contentH'; } availableSpace = contLayoutRect[innerSizeName] - contPaddingBox[beforeName] - contPaddingBox[beforeName]; maxAlignEndPos = totalFlex = 0; for (i = 0, l = items.length; i < l; i++) { ctrl = items[i]; ctrlLayoutRect = ctrl.layoutRect(); ctrlSettings = ctrl.settings; flex = ctrlSettings.flex; availableSpace -= i < l - 1 ? spacing : 0; if (flex > 0) { totalFlex += flex; if (ctrlLayoutRect[maxSizeName]) { maxSizeItems.push(ctrl); } ctrlLayoutRect.flex = flex; } availableSpace -= ctrlLayoutRect[minSizeName]; size = contPaddingBox[alignBeforeName] + ctrlLayoutRect[alignMinSizeName] + contPaddingBox[alignAfterName]; if (size > maxAlignEndPos) { maxAlignEndPos = size; } } rect = {}; if (availableSpace < 0) { rect[minSizeName] = contLayoutRect[minSizeName] - availableSpace + contLayoutRect[deltaSizeName]; } else { rect[minSizeName] = contLayoutRect[innerSizeName] - availableSpace + contLayoutRect[deltaSizeName]; } rect[alignMinSizeName] = maxAlignEndPos + contLayoutRect[alignDeltaSizeName]; rect[contentSizeName] = contLayoutRect[innerSizeName] - availableSpace; rect[alignContentSizeName] = maxAlignEndPos; rect.minW = min(rect.minW, contLayoutRect.maxW); rect.minH = min(rect.minH, contLayoutRect.maxH); rect.minW = max(rect.minW, contLayoutRect.startMinWidth); rect.minH = max(rect.minH, contLayoutRect.startMinHeight); if (contLayoutRect.autoResize && (rect.minW !== contLayoutRect.minW || rect.minH !== contLayoutRect.minH)) { rect.w = rect.minW; rect.h = rect.minH; container.layoutRect(rect); this.recalc(container); if (container._lastRect === null) { var parentCtrl = container.parent(); if (parentCtrl) { parentCtrl._lastRect = null; parentCtrl.recalc(); } } return; } ratio = availableSpace / totalFlex; for (i = 0, l = maxSizeItems.length; i < l; i++) { ctrl = maxSizeItems[i]; ctrlLayoutRect = ctrl.layoutRect(); maxSize = ctrlLayoutRect[maxSizeName]; size = ctrlLayoutRect[minSizeName] + ctrlLayoutRect.flex * ratio; if (size > maxSize) { availableSpace -= ctrlLayoutRect[maxSizeName] - ctrlLayoutRect[minSizeName]; totalFlex -= ctrlLayoutRect.flex; ctrlLayoutRect.flex = 0; ctrlLayoutRect.maxFlexSize = maxSize; } else { ctrlLayoutRect.maxFlexSize = 0; } } ratio = availableSpace / totalFlex; pos = contPaddingBox[beforeName]; rect = {}; if (totalFlex === 0) { if (pack === 'end') { pos = availableSpace + contPaddingBox[beforeName]; } else if (pack === 'center') { pos = Math.round(contLayoutRect[innerSizeName] / 2 - (contLayoutRect[innerSizeName] - availableSpace) / 2) + contPaddingBox[beforeName]; if (pos < 0) { pos = contPaddingBox[beforeName]; } } else if (pack === 'justify') { pos = contPaddingBox[beforeName]; spacing = Math.floor(availableSpace / (items.length - 1)); } } rect[alignAxisName] = contPaddingBox[alignBeforeName]; for (i = 0, l = items.length; i < l; i++) { ctrl = items[i]; ctrlLayoutRect = ctrl.layoutRect(); size = ctrlLayoutRect.maxFlexSize || ctrlLayoutRect[minSizeName]; if (align === 'center') { rect[alignAxisName] = Math.round(contLayoutRect[alignInnerSizeName] / 2 - ctrlLayoutRect[alignSizeName] / 2); } else if (align === 'stretch') { rect[alignSizeName] = max(ctrlLayoutRect[alignMinSizeName] || 0, contLayoutRect[alignInnerSizeName] - contPaddingBox[alignBeforeName] - contPaddingBox[alignAfterName]); rect[alignAxisName] = contPaddingBox[alignBeforeName]; } else if (align === 'end') { rect[alignAxisName] = contLayoutRect[alignInnerSizeName] - ctrlLayoutRect[alignSizeName] - contPaddingBox.top; } if (ctrlLayoutRect.flex > 0) { size += ctrlLayoutRect.flex * ratio; } rect[sizeName] = size; rect[posName] = pos; ctrl.layoutRect(rect); if (ctrl.recalc) { ctrl.recalc(); } pos += size + spacing; } } }); var FlowLayout = Layout$1.extend({ Defaults: { containerClass: 'flow-layout', controlClass: 'flow-layout-item', endClass: 'break' }, recalc: function (container) { container.items().filter(':visible').each(function (ctrl) { if (ctrl.recalc) { ctrl.recalc(); } }); }, isNative: function () { return true; } }); var descendant = function (scope, selector) { return one(selector, scope); }; var toggleFormat = function (editor, fmt) { return function () { editor.execCommand('mceToggleFormat', false, fmt); }; }; var addFormatChangedListener = function (editor, name, changed) { var handler = function (state) { changed(state, name); }; if (editor.formatter) { editor.formatter.formatChanged(name, handler); } else { editor.on('init', function () { editor.formatter.formatChanged(name, handler); }); } }; var postRenderFormatToggle = function (editor, name) { return function (e) { addFormatChangedListener(editor, name, function (state) { e.control.active(state); }); }; }; var register = function (editor) { var alignFormats = [ 'alignleft', 'aligncenter', 'alignright', 'alignjustify' ]; var defaultAlign = 'alignleft'; var alignMenuItems = [ { text: 'Left', icon: 'alignleft', onclick: toggleFormat(editor, 'alignleft') }, { text: 'Center', icon: 'aligncenter', onclick: toggleFormat(editor, 'aligncenter') }, { text: 'Right', icon: 'alignright', onclick: toggleFormat(editor, 'alignright') }, { text: 'Justify', icon: 'alignjustify', onclick: toggleFormat(editor, 'alignjustify') } ]; editor.addMenuItem('align', { text: 'Align', menu: alignMenuItems }); editor.addButton('align', { type: 'menubutton', icon: defaultAlign, menu: alignMenuItems, onShowMenu: function (e) { var menu = e.control.menu; global$4.each(alignFormats, function (formatName, idx) { menu.items().eq(idx).each(function (item) { return item.active(editor.formatter.match(formatName)); }); }); }, onPostRender: function (e) { var ctrl = e.control; global$4.each(alignFormats, function (formatName, idx) { addFormatChangedListener(editor, formatName, function (state) { ctrl.icon(defaultAlign); if (state) { ctrl.icon(formatName); } }); }); } }); global$4.each({ alignleft: [ 'Align left', 'JustifyLeft' ], aligncenter: [ 'Align center', 'JustifyCenter' ], alignright: [ 'Align right', 'JustifyRight' ], alignjustify: [ 'Justify', 'JustifyFull' ], alignnone: [ 'No alignment', 'JustifyNone' ] }, function (item, name) { editor.addButton(name, { active: false, tooltip: item[0], cmd: item[1], onPostRender: postRenderFormatToggle(editor, name) }); }); }; var Align = { register: register }; var getFirstFont = function (fontFamily) { return fontFamily ? fontFamily.split(',')[0] : ''; }; var findMatchingValue = function (items, fontFamily) { var font = fontFamily ? fontFamily.toLowerCase() : ''; var value; global$4.each(items, function (item) { if (item.value.toLowerCase() === font) { value = item.value; } }); global$4.each(items, function (item) { if (!value && getFirstFont(item.value).toLowerCase() === getFirstFont(font).toLowerCase()) { value = item.value; } }); return value; }; var createFontNameListBoxChangeHandler = function (editor, items) { return function () { var self = this; self.state.set('value', null); editor.on('init nodeChange', function (e) { var fontFamily = editor.queryCommandValue('FontName'); var match = findMatchingValue(items, fontFamily); self.value(match ? match : null); if (!match && fontFamily) { self.text(getFirstFont(fontFamily)); } }); }; }; var createFormats = function (formats) { formats = formats.replace(/;$/, '').split(';'); var i = formats.length; while (i--) { formats[i] = formats[i].split('='); } return formats; }; var getFontItems = function (editor) { 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'; var fonts = createFormats(editor.settings.font_formats || defaultFontsFormats); return global$4.map(fonts, function (font) { return { text: { raw: font[0] }, value: font[1], textStyle: font[1].indexOf('dings') === -1 ? 'font-family:' + font[1] : '' }; }); }; var registerButtons = function (editor) { editor.addButton('fontselect', function () { var items = getFontItems(editor); return { type: 'listbox', text: 'Font Family', tooltip: 'Font Family', values: items, fixedWidth: true, onPostRender: createFontNameListBoxChangeHandler(editor, items), onselect: function (e) { if (e.control.settings.value) { editor.execCommand('FontName', false, e.control.settings.value); } } }; }); }; var register$1 = function (editor) { registerButtons(editor); }; var FontSelect = { register: register$1 }; var round = function (number, precision) { var factor = Math.pow(10, precision); return Math.round(number * factor) / factor; }; var toPt = function (fontSize, precision) { if (/[0-9.]+px$/.test(fontSize)) { return round(parseInt(fontSize, 10) * 72 / 96, precision || 0) + 'pt'; } return fontSize; }; var findMatchingValue$1 = function (items, pt, px) { var value; global$4.each(items, function (item) { if (item.value === px) { value = px; } else if (item.value === pt) { value = pt; } }); return value; }; var createFontSizeListBoxChangeHandler = function (editor, items) { return function () { var self = this; editor.on('init nodeChange', function (e) { var px, pt, precision, match; px = editor.queryCommandValue('FontSize'); if (px) { for (precision = 3; !match && precision >= 0; precision--) { pt = toPt(px, precision); match = findMatchingValue$1(items, pt, px); } } self.value(match ? match : null); if (!match) { self.text(pt); } }); }; }; var getFontSizeItems = function (editor) { var defaultFontsizeFormats = '8pt 10pt 12pt 14pt 18pt 24pt 36pt'; var fontsizeFormats = editor.settings.fontsize_formats || defaultFontsizeFormats; return global$4.map(fontsizeFormats.split(' '), function (item) { var text = item, value = item; var values = item.split('='); if (values.length > 1) { text = values[0]; value = values[1]; } return { text: text, value: value }; }); }; var registerButtons$1 = function (editor) { editor.addButton('fontsizeselect', function () { var items = getFontSizeItems(editor); return { type: 'listbox', text: 'Font Sizes', tooltip: 'Font Sizes', values: items, fixedWidth: true, onPostRender: createFontSizeListBoxChangeHandler(editor, items), onclick: function (e) { if (e.control.settings.value) { editor.execCommand('FontSize', false, e.control.settings.value); } } }; }); }; var register$2 = function (editor) { registerButtons$1(editor); }; var FontSizeSelect = { register: register$2 }; var hideMenuObjects = function (editor, menu) { var count = menu.length; global$4.each(menu, function (item) { if (item.menu) { item.hidden = hideMenuObjects(editor, item.menu) === 0; } var formatName = item.format; if (formatName) { item.hidden = !editor.formatter.canApply(formatName); } if (item.hidden) { count--; } }); return count; }; var hideFormatMenuItems = function (editor, menu) { var count = menu.items().length; menu.items().each(function (item) { if (item.menu) { item.visible(hideFormatMenuItems(editor, item.menu) > 0); } if (!item.menu && item.settings.menu) { item.visible(hideMenuObjects(editor, item.settings.menu) > 0); } var formatName = item.settings.format; if (formatName) { item.visible(editor.formatter.canApply(formatName)); } if (!item.visible()) { count--; } }); return count; }; var createFormatMenu = function (editor) { var count = 0; var newFormats = []; var defaultStyleFormats = [ { title: 'Headings', items: [ { title: 'Heading 1', format: 'h1' }, { title: 'Heading 2', format: 'h2' }, { title: 'Heading 3', format: 'h3' }, { title: 'Heading 4', format: 'h4' }, { title: 'Heading 5', format: 'h5' }, { title: 'Heading 6', format: 'h6' } ] }, { title: 'Inline', items: [ { title: 'Bold', icon: 'bold', format: 'bold' }, { title: 'Italic', icon: 'italic', format: 'italic' }, { title: 'Underline', icon: 'underline', format: 'underline' }, { title: 'Strikethrough', icon: 'strikethrough', format: 'strikethrough' }, { title: 'Superscript', icon: 'superscript', format: 'superscript' }, { title: 'Subscript', icon: 'subscript', format: 'subscript' }, { title: 'Code', icon: 'code', format: 'code' } ] }, { title: 'Blocks', items: [ { title: 'Paragraph', format: 'p' }, { title: 'Blockquote', format: 'blockquote' }, { title: 'Div', format: 'div' }, { title: 'Pre', format: 'pre' } ] }, { title: 'Alignment', items: [ { title: 'Left', icon: 'alignleft', format: 'alignleft' }, { title: 'Center', icon: 'aligncenter', format: 'aligncenter' }, { title: 'Right', icon: 'alignright', format: 'alignright' }, { title: 'Justify', icon: 'alignjustify', format: 'alignjustify' } ] } ]; var createMenu = function (formats) { var menu = []; if (!formats) { return; } global$4.each(formats, function (format) { var menuItem = { text: format.title, icon: format.icon }; if (format.items) { menuItem.menu = createMenu(format.items); } else { var formatName = format.format || 'custom' + count++; if (!format.format) { format.name = formatName; newFormats.push(format); } menuItem.format = formatName; menuItem.cmd = format.cmd; } menu.push(menuItem); }); return menu; }; var createStylesMenu = function () { var menu; if (editor.settings.style_formats_merge) { if (editor.settings.style_formats) { menu = createMenu(defaultStyleFormats.concat(editor.settings.style_formats)); } else { menu = createMenu(defaultStyleFormats); } } else { menu = createMenu(editor.settings.style_formats || defaultStyleFormats); } return menu; }; editor.on('init', function () { global$4.each(newFormats, function (format) { editor.formatter.register(format.name, format); }); }); return { type: 'menu', items: createStylesMenu(), onPostRender: function (e) { editor.fire('renderFormatsMenu', { control: e.control }); }, itemDefaults: { preview: true, textStyle: function () { if (this.settings.format) { return editor.formatter.getCssText(this.settings.format); } }, onPostRender: function () { var self = this; self.parent().on('show', function () { var formatName, command; formatName = self.settings.format; if (formatName) { self.disabled(!editor.formatter.canApply(formatName)); self.active(editor.formatter.match(formatName)); } command = self.settings.cmd; if (command) { self.active(editor.queryCommandState(command)); } }); }, onclick: function () { if (this.settings.format) { toggleFormat(editor, this.settings.format)(); } if (this.settings.cmd) { editor.execCommand(this.settings.cmd); } } } }; }; var registerMenuItems = function (editor, formatMenu) { editor.addMenuItem('formats', { text: 'Formats', menu: formatMenu }); }; var registerButtons$2 = function (editor, formatMenu) { editor.addButton('styleselect', { type: 'menubutton', text: 'Formats', menu: formatMenu, onShowMenu: function () { if (editor.settings.style_formats_autohide) { hideFormatMenuItems(editor, this.menu); } } }); }; var register$3 = function (editor) { var formatMenu = createFormatMenu(editor); registerMenuItems(editor, formatMenu); registerButtons$2(editor, formatMenu); }; var Formats = { register: register$3 }; var defaultBlocks = 'Paragraph=p;' + 'Heading 1=h1;' + 'Heading 2=h2;' + 'Heading 3=h3;' + 'Heading 4=h4;' + 'Heading 5=h5;' + 'Heading 6=h6;' + 'Preformatted=pre'; var createFormats$1 = function (formats) { formats = formats.replace(/;$/, '').split(';'); var i = formats.length; while (i--) { formats[i] = formats[i].split('='); } return formats; }; var createListBoxChangeHandler = function (editor, items, formatName) { return function () { var self = this; editor.on('nodeChange', function (e) { var formatter = editor.formatter; var value = null; global$4.each(e.parents, function (node) { global$4.each(items, function (item) { if (formatName) { if (formatter.matchNode(node, formatName, { value: item.value })) { value = item.value; } } else { if (formatter.matchNode(node, item.value)) { value = item.value; } } if (value) { return false; } }); if (value) { return false; } }); self.value(value); }); }; }; var lazyFormatSelectBoxItems = function (editor, blocks) { return function () { var items = []; global$4.each(blocks, function (block) { items.push({ text: block[0], value: block[1], textStyle: function () { return editor.formatter.getCssText(block[1]); } }); }); return { type: 'listbox', text: blocks[0][0], values: items, fixedWidth: true, onselect: function (e) { if (e.control) { var fmt = e.control.value(); toggleFormat(editor, fmt)(); } }, onPostRender: createListBoxChangeHandler(editor, items) }; }; }; var buildMenuItems = function (editor, blocks) { return global$4.map(blocks, function (block) { return { text: block[0], onclick: toggleFormat(editor, block[1]), textStyle: function () { return editor.formatter.getCssText(block[1]); } }; }); }; var register$4 = function (editor) { var blocks = createFormats$1(editor.settings.block_formats || defaultBlocks); editor.addMenuItem('blockformats', { text: 'Blocks', menu: buildMenuItems(editor, blocks) }); editor.addButton('formatselect', lazyFormatSelectBoxItems(editor, blocks)); }; var FormatSelect = { register: register$4 }; var createCustomMenuItems = function (editor, names) { var items, nameList; if (typeof names === 'string') { nameList = names.split(' '); } else if (global$4.isArray(names)) { return flatten$1(global$4.map(names, function (names) { return createCustomMenuItems(editor, names); })); } items = global$4.grep(nameList, function (name) { return name === '|' || name in editor.menuItems; }); return global$4.map(items, function (name) { return name === '|' ? { text: '-' } : editor.menuItems[name]; }); }; var isSeparator = function (menuItem) { return menuItem && menuItem.text === '-'; }; var trimMenuItems = function (menuItems) { var menuItems2 = filter(menuItems, function (menuItem, i, menuItems) { return !isSeparator(menuItem) || !isSeparator(menuItems[i - 1]); }); return filter(menuItems2, function (menuItem, i, menuItems) { return !isSeparator(menuItem) || i > 0 && i < menuItems.length - 1; }); }; var createContextMenuItems = function (editor, context) { var outputMenuItems = [{ text: '-' }]; var menuItems = global$4.grep(editor.menuItems, function (menuItem) { return menuItem.context === context; }); global$4.each(menuItems, function (menuItem) { if (menuItem.separator === 'before') { outputMenuItems.push({ text: '|' }); } if (menuItem.prependToContext) { outputMenuItems.unshift(menuItem); } else { outputMenuItems.push(menuItem); } if (menuItem.separator === 'after') { outputMenuItems.push({ text: '|' }); } }); return outputMenuItems; }; var createInsertMenu = function (editor) { var insertButtonItems = editor.settings.insert_button_items; if (insertButtonItems) { return trimMenuItems(createCustomMenuItems(editor, insertButtonItems)); } else { return trimMenuItems(createContextMenuItems(editor, 'insert')); } }; var registerButtons$3 = function (editor) { editor.addButton('insert', { type: 'menubutton', icon: 'insert', menu: [], oncreatemenu: function () { this.menu.add(createInsertMenu(editor)); this.menu.renderNew(); } }); }; var register$5 = function (editor) { registerButtons$3(editor); }; var InsertButton = { register: register$5 }; var registerFormatButtons = function (editor) { global$4.each({ bold: 'Bold', italic: 'Italic', underline: 'Underline', strikethrough: 'Strikethrough', subscript: 'Subscript', superscript: 'Superscript' }, function (text, name) { editor.addButton(name, { active: false, tooltip: text, onPostRender: postRenderFormatToggle(editor, name), onclick: toggleFormat(editor, name) }); }); }; var registerCommandButtons = function (editor) { global$4.each({ outdent: [ 'Decrease indent', 'Outdent' ], indent: [ 'Increase indent', 'Indent' ], cut: [ 'Cut', 'Cut' ], copy: [ 'Copy', 'Copy' ], paste: [ 'Paste', 'Paste' ], help: [ 'Help', 'mceHelp' ], selectall: [ 'Select all', 'SelectAll' ], visualaid: [ 'Visual aids', 'mceToggleVisualAid' ], newdocument: [ 'New document', 'mceNewDocument' ], removeformat: [ 'Clear formatting', 'RemoveFormat' ], remove: [ 'Remove', 'Delete' ] }, function (item, name) { editor.addButton(name, { tooltip: item[0], cmd: item[1] }); }); }; var registerCommandToggleButtons = function (editor) { global$4.each({ blockquote: [ 'Blockquote', 'mceBlockQuote' ], subscript: [ 'Subscript', 'Subscript' ], superscript: [ 'Superscript', 'Superscript' ] }, function (item, name) { editor.addButton(name, { active: false, tooltip: item[0], cmd: item[1], onPostRender: postRenderFormatToggle(editor, name) }); }); }; var registerButtons$4 = function (editor) { registerFormatButtons(editor); registerCommandButtons(editor); registerCommandToggleButtons(editor); }; var registerMenuItems$1 = function (editor) { global$4.each({ bold: [ 'Bold', 'Bold', 'Meta+B' ], italic: [ 'Italic', 'Italic', 'Meta+I' ], underline: [ 'Underline', 'Underline', 'Meta+U' ], strikethrough: [ 'Strikethrough', 'Strikethrough' ], subscript: [ 'Subscript', 'Subscript' ], superscript: [ 'Superscript', 'Superscript' ], removeformat: [ 'Clear formatting', 'RemoveFormat' ], newdocument: [ 'New document', 'mceNewDocument' ], cut: [ 'Cut', 'Cut', 'Meta+X' ], copy: [ 'Copy', 'Copy', 'Meta+C' ], paste: [ 'Paste', 'Paste', 'Meta+V' ], selectall: [ 'Select all', 'SelectAll', 'Meta+A' ] }, function (item, name) { editor.addMenuItem(name, { text: item[0], icon: name, shortcut: item[2], cmd: item[1] }); }); editor.addMenuItem('codeformat', { text: 'Code', icon: 'code', onclick: toggleFormat(editor, 'code') }); }; var register$6 = function (editor) { registerButtons$4(editor); registerMenuItems$1(editor); }; var SimpleControls = { register: register$6 }; var toggleUndoRedoState = function (editor, type) { return function () { var self = this; var checkState = function () { var typeFn = type === 'redo' ? 'hasRedo' : 'hasUndo'; return editor.undoManager ? editor.undoManager[typeFn]() : false; }; self.disabled(!checkState()); editor.on('Undo Redo AddUndo TypingUndo ClearUndos SwitchMode', function () { self.disabled(editor.readonly || !checkState()); }); }; }; var registerMenuItems$2 = function (editor) { editor.addMenuItem('undo', { text: 'Undo', icon: 'undo', shortcut: 'Meta+Z', onPostRender: toggleUndoRedoState(editor, 'undo'), cmd: 'undo' }); editor.addMenuItem('redo', { text: 'Redo', icon: 'redo', shortcut: 'Meta+Y', onPostRender: toggleUndoRedoState(editor, 'redo'), cmd: 'redo' }); }; var registerButtons$5 = function (editor) { editor.addButton('undo', { tooltip: 'Undo', onPostRender: toggleUndoRedoState(editor, 'undo'), cmd: 'undo' }); editor.addButton('redo', { tooltip: 'Redo', onPostRender: toggleUndoRedoState(editor, 'redo'), cmd: 'redo' }); }; var register$7 = function (editor) { registerMenuItems$2(editor); registerButtons$5(editor); }; var UndoRedo = { register: register$7 }; var toggleVisualAidState = function (editor) { return function () { var self = this; editor.on('VisualAid', function (e) { self.active(e.hasVisual); }); self.active(editor.hasVisual); }; }; var registerMenuItems$3 = function (editor) { editor.addMenuItem('visualaid', { text: 'Visual aids', selectable: true, onPostRender: toggleVisualAidState(editor), cmd: 'mceToggleVisualAid' }); }; var register$8 = function (editor) { registerMenuItems$3(editor); }; var VisualAid = { register: register$8 }; var setupEnvironment = function () { Widget.tooltips = !global$1.iOS; Control$1.translate = function (text) { return global$5.translate(text); }; }; var setupUiContainer = function (editor) { if (editor.settings.ui_container) { global$1.container = descendant(Element.fromDom(domGlobals.document.body), editor.settings.ui_container).fold(constant(null), function (elm) { return elm.dom(); }); } }; var setupRtlMode = function (editor) { if (editor.rtl) { Control$1.rtl = true; } }; var setupHideFloatPanels = function (editor) { editor.on('mousedown progressstate', function () { FloatPanel.hideAll(); }); }; var setup = function (editor) { setupRtlMode(editor); setupHideFloatPanels(editor); setupUiContainer(editor); setupEnvironment(); FormatSelect.register(editor); Align.register(editor); SimpleControls.register(editor); UndoRedo.register(editor); FontSizeSelect.register(editor); FontSelect.register(editor); Formats.register(editor); VisualAid.register(editor); InsertButton.register(editor); }; var FormatControls = { setup: setup }; var GridLayout = AbsoluteLayout.extend({ recalc: function (container) { var settings, rows, cols, items, contLayoutRect, width, height, rect, ctrlLayoutRect, ctrl, x, y, posX, posY, ctrlSettings, contPaddingBox, align, spacingH, spacingV, alignH, alignV, maxX, maxY; var colWidths = []; var rowHeights = []; var ctrlMinWidth, ctrlMinHeight, availableWidth, availableHeight, reverseRows, idx; settings = container.settings; items = container.items().filter(':visible'); contLayoutRect = container.layoutRect(); cols = settings.columns || Math.ceil(Math.sqrt(items.length)); rows = Math.ceil(items.length / cols); spacingH = settings.spacingH || settings.spacing || 0; spacingV = settings.spacingV || settings.spacing || 0; alignH = settings.alignH || settings.align; alignV = settings.alignV || settings.align; contPaddingBox = container.paddingBox; reverseRows = 'reverseRows' in settings ? settings.reverseRows : container.isRtl(); if (alignH && typeof alignH === 'string') { alignH = [alignH]; } if (alignV && typeof alignV === 'string') { alignV = [alignV]; } for (x = 0; x < cols; x++) { colWidths.push(0); } for (y = 0; y < rows; y++) { rowHeights.push(0); } for (y = 0; y < rows; y++) { for (x = 0; x < cols; x++) { ctrl = items[y * cols + x]; if (!ctrl) { break; } ctrlLayoutRect = ctrl.layoutRect(); ctrlMinWidth = ctrlLayoutRect.minW; ctrlMinHeight = ctrlLayoutRect.minH; colWidths[x] = ctrlMinWidth > colWidths[x] ? ctrlMinWidth : colWidths[x]; rowHeights[y] = ctrlMinHeight > rowHeights[y] ? ctrlMinHeight : rowHeights[y]; } } availableWidth = contLayoutRect.innerW - contPaddingBox.left - contPaddingBox.right; for (maxX = 0, x = 0; x < cols; x++) { maxX += colWidths[x] + (x > 0 ? spacingH : 0); availableWidth -= (x > 0 ? spacingH : 0) + colWidths[x]; } availableHeight = contLayoutRect.innerH - contPaddingBox.top - contPaddingBox.bottom; for (maxY = 0, y = 0; y < rows; y++) { maxY += rowHeights[y] + (y > 0 ? spacingV : 0); availableHeight -= (y > 0 ? spacingV : 0) + rowHeights[y]; } maxX += contPaddingBox.left + contPaddingBox.right; maxY += contPaddingBox.top + contPaddingBox.bottom; rect = {}; rect.minW = maxX + (contLayoutRect.w - contLayoutRect.innerW); rect.minH = maxY + (contLayoutRect.h - contLayoutRect.innerH); rect.contentW = rect.minW - contLayoutRect.deltaW; rect.contentH = rect.minH - contLayoutRect.deltaH; rect.minW = Math.min(rect.minW, contLayoutRect.maxW); rect.minH = Math.min(rect.minH, contLayoutRect.maxH); rect.minW = Math.max(rect.minW, contLayoutRect.startMinWidth); rect.minH = Math.max(rect.minH, contLayoutRect.startMinHeight); if (contLayoutRect.autoResize && (rect.minW !== contLayoutRect.minW || rect.minH !== contLayoutRect.minH)) { rect.w = rect.minW; rect.h = rect.minH; container.layoutRect(rect); this.recalc(container); if (container._lastRect === null) { var parentCtrl = container.parent(); if (parentCtrl) { parentCtrl._lastRect = null; parentCtrl.recalc(); } } return; } if (contLayoutRect.autoResize) { rect = container.layoutRect(rect); rect.contentW = rect.minW - contLayoutRect.deltaW; rect.contentH = rect.minH - contLayoutRect.deltaH; } var flexV; if (settings.packV === 'start') { flexV = 0; } else { flexV = availableHeight > 0 ? Math.floor(availableHeight / rows) : 0; } var totalFlex = 0; var flexWidths = settings.flexWidths; if (flexWidths) { for (x = 0; x < flexWidths.length; x++) { totalFlex += flexWidths[x]; } } else { totalFlex = cols; } var ratio = availableWidth / totalFlex; for (x = 0; x < cols; x++) { colWidths[x] += flexWidths ? flexWidths[x] * ratio : ratio; } posY = contPaddingBox.top; for (y = 0; y < rows; y++) { posX = contPaddingBox.left; height = rowHeights[y] + flexV; for (x = 0; x < cols; x++) { if (reverseRows) { idx = y * cols + cols - 1 - x; } else { idx = y * cols + x; } ctrl = items[idx]; if (!ctrl) { break; } ctrlSettings = ctrl.settings; ctrlLayoutRect = ctrl.layoutRect(); width = Math.max(colWidths[x], ctrlLayoutRect.startMinWidth); ctrlLayoutRect.x = posX; ctrlLayoutRect.y = posY; align = ctrlSettings.alignH || (alignH ? alignH[x] || alignH[0] : null); if (align === 'center') { ctrlLayoutRect.x = posX + width / 2 - ctrlLayoutRect.w / 2; } else if (align === 'right') { ctrlLayoutRect.x = posX + width - ctrlLayoutRect.w; } else if (align === 'stretch') { ctrlLayoutRect.w = width; } align = ctrlSettings.alignV || (alignV ? alignV[x] || alignV[0] : null); if (align === 'center') { ctrlLayoutRect.y = posY + height / 2 - ctrlLayoutRect.h / 2; } else if (align === 'bottom') { ctrlLayoutRect.y = posY + height - ctrlLayoutRect.h; } else if (align === 'stretch') { ctrlLayoutRect.h = height; } ctrl.layoutRect(ctrlLayoutRect); posX += width + spacingH; if (ctrl.recalc) { ctrl.recalc(); } } posY += height + spacingV; } } }); var Iframe = Widget.extend({ renderHtml: function () { var self = this; self.classes.add('iframe'); self.canFocus = false; return '<iframe id="' + self._id + '" class="' + self.classes + '" tabindex="-1" src="' + (self.settings.url || 'javascript:\'\'') + '" frameborder="0"></iframe>'; }, src: function (src) { this.getEl().src = src; }, html: function (html, callback) { var self = this, body = this.getEl().contentWindow.document.body; if (!body) { global$3.setTimeout(function () { self.html(html); }); } else { body.innerHTML = html; if (callback) { callback(); } } return this; } }); var InfoBox = Widget.extend({ init: function (settings) { var self = this; self._super(settings); self.classes.add('widget').add('infobox'); self.canFocus = false; }, severity: function (level) { this.classes.remove('error'); this.classes.remove('warning'); this.classes.remove('success'); this.classes.add(level); }, help: function (state) { this.state.set('help', state); }, renderHtml: function () { var self = this, prefix = self.classPrefix; 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>'; }, bindStates: function () { var self = this; self.state.on('change:text', function (e) { self.getEl('body').firstChild.data = self.encode(e.value); if (self.state.get('rendered')) { self.updateLayoutRect(); } }); self.state.on('change:help', function (e) { self.classes.toggle('has-help', e.value); if (self.state.get('rendered')) { self.updateLayoutRect(); } }); return self._super(); } }); var Label = Widget.extend({ init: function (settings) { var self = this; self._super(settings); self.classes.add('widget').add('label'); self.canFocus = false; if (settings.multiline) { self.classes.add('autoscroll'); } if (settings.strong) { self.classes.add('strong'); } }, initLayoutRect: function () { var self = this, layoutRect = self._super(); if (self.settings.multiline) { var size = funcs.getSize(self.getEl()); if (size.width > layoutRect.maxW) { layoutRect.minW = layoutRect.maxW; self.classes.add('multiline'); } self.getEl().style.width = layoutRect.minW + 'px'; layoutRect.startMinH = layoutRect.h = layoutRect.minH = Math.min(layoutRect.maxH, funcs.getSize(self.getEl()).height); } return layoutRect; }, repaint: function () { var self = this; if (!self.settings.multiline) { self.getEl().style.lineHeight = self.layoutRect().h + 'px'; } return self._super(); }, severity: function (level) { this.classes.remove('error'); this.classes.remove('warning'); this.classes.remove('success'); this.classes.add(level); }, renderHtml: function () { var self = this; var targetCtrl, forName, forId = self.settings.forId; var text = self.settings.html ? self.settings.html : self.encode(self.state.get('text')); if (!forId && (forName = self.settings.forName)) { targetCtrl = self.getRoot().find('#' + forName)[0]; if (targetCtrl) { forId = targetCtrl._id; } } if (forId) { return '<label id="' + self._id + '" class="' + self.classes + '"' + (forId ? ' for="' + forId + '"' : '') + '>' + text + '</label>'; } return '<span id="' + self._id + '" class="' + self.classes + '">' + text + '</span>'; }, bindStates: function () { var self = this; self.state.on('change:text', function (e) { self.innerHtml(self.encode(e.value)); if (self.state.get('rendered')) { self.updateLayoutRect(); } }); return self._super(); } }); var Toolbar$1 = Container.extend({ Defaults: { role: 'toolbar', layout: 'flow' }, init: function (settings) { var self = this; self._super(settings); self.classes.add('toolbar'); }, postRender: function () { var self = this; self.items().each(function (ctrl) { ctrl.classes.add('toolbar-item'); }); return self._super(); } }); var MenuBar = Toolbar$1.extend({ Defaults: { role: 'menubar', containerCls: 'menubar', ariaRoot: true, defaults: { type: 'menubutton' } } }); function isChildOf$1(node, parent) { while (node) { if (parent === node) { return true; } node = node.parentNode; } return false; } var MenuButton = Button.extend({ init: function (settings) { var self = this; self._renderOpen = true; self._super(settings); settings = self.settings; self.classes.add('menubtn'); if (settings.fixedWidth) { self.classes.add('fixed-width'); } self.aria('haspopup', true); self.state.set('menu', settings.menu || self.render()); }, showMenu: function (toggle) { var self = this; var menu; if (self.menu && self.menu.visible() && toggle !== false) { return self.hideMenu(); } if (!self.menu) { menu = self.state.get('menu') || []; self.classes.add('opened'); if (menu.length) { menu = { type: 'menu', animate: true, items: menu }; } else { menu.type = menu.type || 'menu'; menu.animate = true; } if (!menu.renderTo) { self.menu = global$b.create(menu).parent(self).renderTo(); } else { self.menu = menu.parent(self).show().renderTo(); } self.fire('createmenu'); self.menu.reflow(); self.menu.on('cancel', function (e) { if (e.control.parent() === self.menu) { e.stopPropagation(); self.focus(); self.hideMenu(); } }); self.menu.on('select', function () { self.focus(); }); self.menu.on('show hide', function (e) { if (e.type === 'hide' && e.control.parent() === self) { self.classes.remove('opened-under'); } if (e.control === self.menu) { self.activeMenu(e.type === 'show'); self.classes.toggle('opened', e.type === 'show'); } self.aria('expanded', e.type === 'show'); }).fire('show'); } self.menu.show(); self.menu.layoutRect({ w: self.layoutRect().w }); self.menu.repaint(); self.menu.moveRel(self.getEl(), self.isRtl() ? [ 'br-tr', 'tr-br' ] : [ 'bl-tl', 'tl-bl' ]); var menuLayoutRect = self.menu.layoutRect(); var selfBottom = self.$el.offset().top + self.layoutRect().h; if (selfBottom > menuLayoutRect.y && selfBottom < menuLayoutRect.y + menuLayoutRect.h) { self.classes.add('opened-under'); } self.fire('showmenu'); }, hideMenu: function () { var self = this; if (self.menu) { self.menu.items().each(function (item) { if (item.hideMenu) { item.hideMenu(); } }); self.menu.hide(); } }, activeMenu: function (state) { this.classes.toggle('active', state); }, renderHtml: function () { var self = this, id = self._id, prefix = self.classPrefix; var icon = self.settings.icon, image; var text = self.state.get('text'); var textHtml = ''; image = self.settings.image; if (image) { icon = 'none'; if (typeof image !== 'string') { image = domGlobals.window.getSelection ? image[0] : image[1]; } image = ' style="background-image: url(\'' + image + '\')"'; } else { image = ''; } if (text) { self.classes.add('btn-has-text'); textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>'; } icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + icon : ''; self.aria('role', self.parent() instanceof MenuBar ? 'menuitem' : 'button'); 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>'; }, postRender: function () { var self = this; self.on('click', function (e) { if (e.control === self && isChildOf$1(e.target, self.getEl())) { self.focus(); self.showMenu(!e.aria); if (e.aria) { self.menu.items().filter(':visible')[0].focus(); } } }); self.on('mouseenter', function (e) { var overCtrl = e.control; var parent = self.parent(); var hasVisibleSiblingMenu; if (overCtrl && parent && overCtrl instanceof MenuButton && overCtrl.parent() === parent) { parent.items().filter('MenuButton').each(function (ctrl) { if (ctrl.hideMenu && ctrl !== overCtrl) { if (ctrl.menu && ctrl.menu.visible()) { hasVisibleSiblingMenu = true; } ctrl.hideMenu(); } }); if (hasVisibleSiblingMenu) { overCtrl.focus(); overCtrl.showMenu(); } } }); return self._super(); }, bindStates: function () { var self = this; self.state.on('change:menu', function () { if (self.menu) { self.menu.remove(); } self.menu = null; }); return self._super(); }, remove: function () { this._super(); if (this.menu) { this.menu.remove(); } } }); function Throbber (elm, inline) { var self = this; var state; var classPrefix = Control$1.classPrefix; var timer; self.show = function (time, callback) { function render() { if (state) { global$7(elm).append('<div class="' + classPrefix + 'throbber' + (inline ? ' ' + classPrefix + 'throbber-inline' : '') + '"></div>'); if (callback) { callback(); } } } self.hide(); state = true; if (time) { timer = global$3.setTimeout(render, time); } else { render(); } return self; }; self.hide = function () { var child = elm.lastChild; global$3.clearTimeout(timer); if (child && child.className.indexOf('throbber') !== -1) { child.parentNode.removeChild(child); } state = false; return self; }; } var Menu = FloatPanel.extend({ Defaults: { defaultType: 'menuitem', border: 1, layout: 'stack', role: 'application', bodyRole: 'menu', ariaRoot: true }, init: function (settings) { var self = this; settings.autohide = true; settings.constrainToViewport = true; if (typeof settings.items === 'function') { settings.itemsFactory = settings.items; settings.items = []; } if (settings.itemDefaults) { var items = settings.items; var i = items.length; while (i--) { items[i] = global$4.extend({}, settings.itemDefaults, items[i]); } } self._super(settings); self.classes.add('menu'); if (settings.animate && global$1.ie !== 11) { self.classes.add('animate'); } }, repaint: function () { this.classes.toggle('menu-align', true); this._super(); this.getEl().style.height = ''; this.getEl('body').style.height = ''; return this; }, cancel: function () { var self = this; self.hideAll(); self.fire('select'); }, load: function () { var self = this; var time, factory; function hideThrobber() { if (self.throbber) { self.throbber.hide(); self.throbber = null; } } factory = self.settings.itemsFactory; if (!factory) { return; } if (!self.throbber) { self.throbber = new Throbber(self.getEl('body'), true); if (self.items().length === 0) { self.throbber.show(); self.fire('loading'); } else { self.throbber.show(100, function () { self.items().remove(); self.fire('loading'); }); } self.on('hide close', hideThrobber); } self.requestTime = time = new Date().getTime(); self.settings.itemsFactory(function (items) { if (items.length === 0) { self.hide(); return; } if (self.requestTime !== time) { return; } self.getEl().style.width = ''; self.getEl('body').style.width = ''; hideThrobber(); self.items().remove(); self.getEl('body').innerHTML = ''; self.add(items); self.renderNew(); self.fire('loaded'); }); }, hideAll: function () { var self = this; this.find('menuitem').exec('hideMenu'); return self._super(); }, preRender: function () { var self = this; self.items().each(function (ctrl) { var settings = ctrl.settings; if (settings.icon || settings.image || settings.selectable) { self._hasIcons = true; return false; } }); if (self.settings.itemsFactory) { self.on('postrender', function () { if (self.settings.itemsFactory) { self.load(); } }); } self.on('show hide', function (e) { if (e.control === self) { if (e.type === 'show') { global$3.setTimeout(function () { self.classes.add('in'); }, 0); } else { self.classes.remove('in'); } } }); return self._super(); } }); var ListBox = MenuButton.extend({ init: function (settings) { var self = this; var values, selected, selectedText, lastItemCtrl; function setSelected(menuValues) { for (var i = 0; i < menuValues.length; i++) { selected = menuValues[i].selected || settings.value === menuValues[i].value; if (selected) { selectedText = selectedText || menuValues[i].text; self.state.set('value', menuValues[i].value); return true; } if (menuValues[i].menu) { if (setSelected(menuValues[i].menu)) { return true; } } } } self._super(settings); settings = self.settings; self._values = values = settings.values; if (values) { if (typeof settings.value !== 'undefined') { setSelected(values); } if (!selected && values.length > 0) { selectedText = values[0].text; self.state.set('value', values[0].value); } self.state.set('menu', values); } self.state.set('text', settings.text || selectedText); self.classes.add('listbox'); self.on('select', function (e) { var ctrl = e.control; if (lastItemCtrl) { e.lastControl = lastItemCtrl; } if (settings.multiple) { ctrl.active(!ctrl.active()); } else { self.value(e.control.value()); } lastItemCtrl = ctrl; }); }, value: function (value) { if (arguments.length === 0) { return this.state.get('value'); } if (typeof value === 'undefined') { return this; } function valueExists(values) { return exists(values, function (a) { return a.menu ? valueExists(a.menu) : a.value === value; }); } if (this.settings.values) { if (valueExists(this.settings.values)) { this.state.set('value', value); } else if (value === null) { this.state.set('value', null); } } else { this.state.set('value', value); } return this; }, bindStates: function () { var self = this; function activateMenuItemsByValue(menu, value) { if (menu instanceof Menu) { menu.items().each(function (ctrl) { if (!ctrl.hasMenus()) { ctrl.active(ctrl.value() === value); } }); } } function getSelectedItem(menuValues, value) { var selectedItem; if (!menuValues) { return; } for (var i = 0; i < menuValues.length; i++) { if (menuValues[i].value === value) { return menuValues[i]; } if (menuValues[i].menu) { selectedItem = getSelectedItem(menuValues[i].menu, value); if (selectedItem) { return selectedItem; } } } } self.on('show', function (e) { activateMenuItemsByValue(e.control, self.value()); }); self.state.on('change:value', function (e) { var selectedItem = getSelectedItem(self.state.get('menu'), e.value); if (selectedItem) { self.text(selectedItem.text); } else { self.text(self.settings.text); } }); return self._super(); } }); var toggleTextStyle = function (ctrl, state) { var textStyle = ctrl._textStyle; if (textStyle) { var textElm = ctrl.getEl('text'); textElm.setAttribute('style', textStyle); if (state) { textElm.style.color = ''; textElm.style.backgroundColor = ''; } } }; var MenuItem = Widget.extend({ Defaults: { border: 0, role: 'menuitem' }, init: function (settings) { var self = this; var text; self._super(settings); settings = self.settings; self.classes.add('menu-item'); if (settings.menu) { self.classes.add('menu-item-expand'); } if (settings.preview) { self.classes.add('menu-item-preview'); } text = self.state.get('text'); if (text === '-' || text === '|') { self.classes.add('menu-item-sep'); self.aria('role', 'separator'); self.state.set('text', '-'); } if (settings.selectable) { self.aria('role', 'menuitemcheckbox'); self.classes.add('menu-item-checkbox'); settings.icon = 'selected'; } if (!settings.preview && !settings.selectable) { self.classes.add('menu-item-normal'); } self.on('mousedown', function (e) { e.preventDefault(); }); if (settings.menu && !settings.ariaHideMenu) { self.aria('haspopup', true); } }, hasMenus: function () { return !!this.settings.menu; }, showMenu: function () { var self = this; var settings = self.settings; var menu; var parent = self.parent(); parent.items().each(function (ctrl) { if (ctrl !== self) { ctrl.hideMenu(); } }); if (settings.menu) { menu = self.menu; if (!menu) { menu = settings.menu; if (menu.length) { menu = { type: 'menu', items: menu }; } else { menu.type = menu.type || 'menu'; } if (parent.settings.itemDefaults) { menu.itemDefaults = parent.settings.itemDefaults; } menu = self.menu = global$b.create(menu).parent(self).renderTo(); menu.reflow(); menu.on('cancel', function (e) { e.stopPropagation(); self.focus(); menu.hide(); }); menu.on('show hide', function (e) { if (e.control.items) { e.control.items().each(function (ctrl) { ctrl.active(ctrl.settings.selected); }); } }).fire('show'); menu.on('hide', function (e) { if (e.control === menu) { self.classes.remove('selected'); } }); menu.submenu = true; } else { menu.show(); } menu._parentMenu = parent; menu.classes.add('menu-sub'); var rel = menu.testMoveRel(self.getEl(), self.isRtl() ? [ 'tl-tr', 'bl-br', 'tr-tl', 'br-bl' ] : [ 'tr-tl', 'br-bl', 'tl-tr', 'bl-br' ]); menu.moveRel(self.getEl(), rel); menu.rel = rel; rel = 'menu-sub-' + rel; menu.classes.remove(menu._lastRel).add(rel); menu._lastRel = rel; self.classes.add('selected'); self.aria('expanded', true); } }, hideMenu: function () { var self = this; if (self.menu) { self.menu.items().each(function (item) { if (item.hideMenu) { item.hideMenu(); } }); self.menu.hide(); self.aria('expanded', false); } return self; }, renderHtml: function () { var self = this; var id = self._id; var settings = self.settings; var prefix = self.classPrefix; var text = self.state.get('text'); var icon = self.settings.icon, image = '', shortcut = settings.shortcut; var url = self.encode(settings.url), iconHtml = ''; function convertShortcut(shortcut) { var i, value, replace = {}; if (global$1.mac) { replace = { alt: '⌥', ctrl: '⌘', shift: '⇧', meta: '⌘' }; } else { replace = { meta: 'Ctrl' }; } shortcut = shortcut.split('+'); for (i = 0; i < shortcut.length; i++) { value = replace[shortcut[i].toLowerCase()]; if (value) { shortcut[i] = value; } } return shortcut.join('+'); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } function markMatches(text) { var match = settings.match || ''; return match ? text.replace(new RegExp(escapeRegExp(match), 'gi'), function (match) { return '!mce~match[' + match + ']mce~match!'; }) : text; } function boldMatches(text) { return text.replace(new RegExp(escapeRegExp('!mce~match['), 'g'), '<b>').replace(new RegExp(escapeRegExp(']mce~match!'), 'g'), '</b>'); } if (icon) { self.parent().classes.add('menu-has-icons'); } if (settings.image) { image = ' style="background-image: url(\'' + settings.image + '\')"'; } if (shortcut) { shortcut = convertShortcut(shortcut); } icon = prefix + 'ico ' + prefix + 'i-' + (self.settings.icon || 'none'); iconHtml = text !== '-' ? '<i class="' + icon + '"' + image + '></i>\xA0' : ''; text = boldMatches(self.encode(markMatches(text))); url = boldMatches(self.encode(markMatches(url))); 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>'; }, postRender: function () { var self = this, settings = self.settings; var textStyle = settings.textStyle; if (typeof textStyle === 'function') { textStyle = textStyle.call(this); } if (textStyle) { var textElm = self.getEl('text'); if (textElm) { textElm.setAttribute('style', textStyle); self._textStyle = textStyle; } } self.on('mouseenter click', function (e) { if (e.control === self) { if (!settings.menu && e.type === 'click') { self.fire('select'); global$3.requestAnimationFrame(function () { self.parent().hideAll(); }); } else { self.showMenu(); if (e.aria) { self.menu.focus(true); } } } }); self._super(); return self; }, hover: function () { var self = this; self.parent().items().each(function (ctrl) { ctrl.classes.remove('selected'); }); self.classes.toggle('selected', true); return self; }, active: function (state) { toggleTextStyle(this, state); if (typeof state !== 'undefined') { this.aria('checked', state); } return this._super(state); }, remove: function () { this._super(); if (this.menu) { this.menu.remove(); } } }); var Radio = Checkbox.extend({ Defaults: { classes: 'radio', role: 'radio' } }); var ResizeHandle = Widget.extend({ renderHtml: function () { var self = this, prefix = self.classPrefix; self.classes.add('resizehandle'); if (self.settings.direction === 'both') { self.classes.add('resizehandle-both'); } self.canFocus = false; return '<div id="' + self._id + '" class="' + self.classes + '">' + '<i class="' + prefix + 'ico ' + prefix + 'i-resize"></i>' + '</div>'; }, postRender: function () { var self = this; self._super(); self.resizeDragHelper = new DragHelper(this._id, { start: function () { self.fire('ResizeStart'); }, drag: function (e) { if (self.settings.direction !== 'both') { e.deltaX = 0; } self.fire('Resize', e); }, stop: function () { self.fire('ResizeEnd'); } }); }, remove: function () { if (this.resizeDragHelper) { this.resizeDragHelper.destroy(); } return this._super(); } }); function createOptions(options) { var strOptions = ''; if (options) { for (var i = 0; i < options.length; i++) { strOptions += '<option value="' + options[i] + '">' + options[i] + '</option>'; } } return strOptions; } var SelectBox = Widget.extend({ Defaults: { classes: 'selectbox', role: 'selectbox', options: [] }, init: function (settings) { var self = this; self._super(settings); if (self.settings.size) { self.size = self.settings.size; } if (self.settings.options) { self._options = self.settings.options; } self.on('keydown', function (e) { var rootControl; if (e.keyCode === 13) { e.preventDefault(); self.parents().reverse().each(function (ctrl) { if (ctrl.toJSON) { rootControl = ctrl; return false; } }); self.fire('submit', { data: rootControl.toJSON() }); } }); }, options: function (state) { if (!arguments.length) { return this.state.get('options'); } this.state.set('options', state); return this; }, renderHtml: function () { var self = this; var options, size = ''; options = createOptions(self._options); if (self.size) { size = ' size = "' + self.size + '"'; } return '<select id="' + self._id + '" class="' + self.classes + '"' + size + '>' + options + '</select>'; }, bindStates: function () { var self = this; self.state.on('change:options', function (e) { self.getEl().innerHTML = createOptions(e.value); }); return self._super(); } }); function constrain(value, minVal, maxVal) { if (value < minVal) { value = minVal; } if (value > maxVal) { value = maxVal; } return value; } function setAriaProp(el, name, value) { el.setAttribute('aria-' + name, value); } function updateSliderHandle(ctrl, value) { var maxHandlePos, shortSizeName, sizeName, stylePosName, styleValue, handleEl; if (ctrl.settings.orientation === 'v') { stylePosName = 'top'; sizeName = 'height'; shortSizeName = 'h'; } else { stylePosName = 'left'; sizeName = 'width'; shortSizeName = 'w'; } handleEl = ctrl.getEl('handle'); maxHandlePos = (ctrl.layoutRect()[shortSizeName] || 100) - funcs.getSize(handleEl)[sizeName]; styleValue = maxHandlePos * ((value - ctrl._minValue) / (ctrl._maxValue - ctrl._minValue)) + 'px'; handleEl.style[stylePosName] = styleValue; handleEl.style.height = ctrl.layoutRect().h + 'px'; setAriaProp(handleEl, 'valuenow', value); setAriaProp(handleEl, 'valuetext', '' + ctrl.settings.previewFilter(value)); setAriaProp(handleEl, 'valuemin', ctrl._minValue); setAriaProp(handleEl, 'valuemax', ctrl._maxValue); } var Slider = Widget.extend({ init: function (settings) { var self = this; if (!settings.previewFilter) { settings.previewFilter = function (value) { return Math.round(value * 100) / 100; }; } self._super(settings); self.classes.add('slider'); if (settings.orientation === 'v') { self.classes.add('vertical'); } self._minValue = isNumber$1(settings.minValue) ? settings.minValue : 0; self._maxValue = isNumber$1(settings.maxValue) ? settings.maxValue : 100; self._initValue = self.state.get('value'); }, renderHtml: function () { var self = this, id = self._id, prefix = self.classPrefix; return '<div id="' + id + '" class="' + self.classes + '">' + '<div id="' + id + '-handle" class="' + prefix + 'slider-handle" role="slider" tabindex="-1"></div>' + '</div>'; }, reset: function () { this.value(this._initValue).repaint(); }, postRender: function () { var self = this; var minValue, maxValue, screenCordName, stylePosName, sizeName, shortSizeName; function toFraction(min, max, val) { return (val + min) / (max - min); } function fromFraction(min, max, val) { return val * (max - min) - min; } function handleKeyboard(minValue, maxValue) { function alter(delta) { var value; value = self.value(); value = fromFraction(minValue, maxValue, toFraction(minValue, maxValue, value) + delta * 0.05); value = constrain(value, minValue, maxValue); self.value(value); self.fire('dragstart', { value: value }); self.fire('drag', { value: value }); self.fire('dragend', { value: value }); } self.on('keydown', function (e) { switch (e.keyCode) { case 37: case 38: alter(-1); break; case 39: case 40: alter(1); break; } }); } function handleDrag(minValue, maxValue, handleEl) { var startPos, startHandlePos, maxHandlePos, handlePos, value; self._dragHelper = new DragHelper(self._id, { handle: self._id + '-handle', start: function (e) { startPos = e[screenCordName]; startHandlePos = parseInt(self.getEl('handle').style[stylePosName], 10); maxHandlePos = (self.layoutRect()[shortSizeName] || 100) - funcs.getSize(handleEl)[sizeName]; self.fire('dragstart', { value: value }); }, drag: function (e) { var delta = e[screenCordName] - startPos; handlePos = constrain(startHandlePos + delta, 0, maxHandlePos); handleEl.style[stylePosName] = handlePos + 'px'; value = minValue + handlePos / maxHandlePos * (maxValue - minValue); self.value(value); self.tooltip().text('' + self.settings.previewFilter(value)).show().moveRel(handleEl, 'bc tc'); self.fire('drag', { value: value }); }, stop: function () { self.tooltip().hide(); self.fire('dragend', { value: value }); } }); } minValue = self._minValue; maxValue = self._maxValue; if (self.settings.orientation === 'v') { screenCordName = 'screenY'; stylePosName = 'top'; sizeName = 'height'; shortSizeName = 'h'; } else { screenCordName = 'screenX'; stylePosName = 'left'; sizeName = 'width'; shortSizeName = 'w'; } self._super(); handleKeyboard(minValue, maxValue); handleDrag(minValue, maxValue, self.getEl('handle')); }, repaint: function () { this._super(); updateSliderHandle(this, this.value()); }, bindStates: function () { var self = this; self.state.on('change:value', function (e) { updateSliderHandle(self, e.value); }); return self._super(); } }); var Spacer = Widget.extend({ renderHtml: function () { var self = this; self.classes.add('spacer'); self.canFocus = false; return '<div id="' + self._id + '" class="' + self.classes + '"></div>'; } }); var SplitButton = MenuButton.extend({ Defaults: { classes: 'widget btn splitbtn', role: 'button' }, repaint: function () { var self = this; var elm = self.getEl(); var rect = self.layoutRect(); var mainButtonElm, menuButtonElm; self._super(); mainButtonElm = elm.firstChild; menuButtonElm = elm.lastChild; global$7(mainButtonElm).css({ width: rect.w - funcs.getSize(menuButtonElm).width, height: rect.h - 2 }); global$7(menuButtonElm).css({ height: rect.h - 2 }); return self; }, activeMenu: function (state) { var self = this; global$7(self.getEl().lastChild).toggleClass(self.classPrefix + 'active', state); }, renderHtml: function () { var self = this; var id = self._id; var prefix = self.classPrefix; var image; var icon = self.state.get('icon'); var text = self.state.get('text'); var settings = self.settings; var textHtml = '', ariaPressed; image = settings.image; if (image) { icon = 'none'; if (typeof image !== 'string') { image = domGlobals.window.getSelection ? image[0] : image[1]; } image = ' style="background-image: url(\'' + image + '\')"'; } else { image = ''; } icon = settings.icon ? prefix + 'ico ' + prefix + 'i-' + icon : ''; if (text) { self.classes.add('btn-has-text'); textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>'; } ariaPressed = typeof settings.active === 'boolean' ? ' aria-pressed="' + settings.active + '"' : ''; 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>'; }, postRender: function () { var self = this, onClickHandler = self.settings.onclick; self.on('click', function (e) { var node = e.target; if (e.control === this) { while (node) { if (e.aria && e.aria.key !== 'down' || node.nodeName === 'BUTTON' && node.className.indexOf('open') === -1) { e.stopImmediatePropagation(); if (onClickHandler) { onClickHandler.call(this, e); } return; } node = node.parentNode; } } }); delete self.settings.onclick; return self._super(); } }); var StackLayout = FlowLayout.extend({ Defaults: { containerClass: 'stack-layout', controlClass: 'stack-layout-item', endClass: 'break' }, isNative: function () { return true; } }); var TabPanel = Panel.extend({ Defaults: { layout: 'absolute', defaults: { type: 'panel' } }, activateTab: function (idx) { var activeTabElm; if (this.activeTabId) { activeTabElm = this.getEl(this.activeTabId); global$7(activeTabElm).removeClass(this.classPrefix + 'active'); activeTabElm.setAttribute('aria-selected', 'false'); } this.activeTabId = 't' + idx; activeTabElm = this.getEl('t' + idx); activeTabElm.setAttribute('aria-selected', 'true'); global$7(activeTabElm).addClass(this.classPrefix + 'active'); this.items()[idx].show().fire('showtab'); this.reflow(); this.items().each(function (item, i) { if (idx !== i) { item.hide(); } }); }, renderHtml: function () { var self = this; var layout = self._layout; var tabsHtml = ''; var prefix = self.classPrefix; self.preRender(); layout.preRender(self); self.items().each(function (ctrl, i) { var id = self._id + '-t' + i; ctrl.aria('role', 'tabpanel'); ctrl.aria('labelledby', id); 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>'; }); 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>'; }, postRender: function () { var self = this; self._super(); self.settings.activeTab = self.settings.activeTab || 0; self.activateTab(self.settings.activeTab); this.on('click', function (e) { var targetParent = e.target.parentNode; if (targetParent && targetParent.id === self._id + '-head') { var i = targetParent.childNodes.length; while (i--) { if (targetParent.childNodes[i] === e.target) { self.activateTab(i); } } } }); }, initLayoutRect: function () { var self = this; var rect, minW, minH; minW = funcs.getSize(self.getEl('head')).width; minW = minW < 0 ? 0 : minW; minH = 0; self.items().each(function (item) { minW = Math.max(minW, item.layoutRect().minW); minH = Math.max(minH, item.layoutRect().minH); }); self.items().each(function (ctrl) { ctrl.settings.x = 0; ctrl.settings.y = 0; ctrl.settings.w = minW; ctrl.settings.h = minH; ctrl.layoutRect({ x: 0, y: 0, w: minW, h: minH }); }); var headH = funcs.getSize(self.getEl('head')).height; self.settings.minWidth = minW; self.settings.minHeight = minH + headH; rect = self._super(); rect.deltaH += headH; rect.innerH = rect.h - rect.deltaH; return rect; } }); var TextBox = Widget.extend({ init: function (settings) { var self = this; self._super(settings); self.classes.add('textbox'); if (settings.multiline) { self.classes.add('multiline'); } else { self.on('keydown', function (e) { var rootControl; if (e.keyCode === 13) { e.preventDefault(); self.parents().reverse().each(function (ctrl) { if (ctrl.toJSON) { rootControl = ctrl; return false; } }); self.fire('submit', { data: rootControl.toJSON() }); } }); self.on('keyup', function (e) { self.state.set('value', e.target.value); }); } }, repaint: function () { var self = this; var style, rect, borderBox, borderW, borderH = 0, lastRepaintRect; style = self.getEl().style; rect = self._layoutRect; lastRepaintRect = self._lastRepaintRect || {}; var doc = domGlobals.document; if (!self.settings.multiline && doc.all && (!doc.documentMode || doc.documentMode <= 8)) { style.lineHeight = rect.h - borderH + 'px'; } borderBox = self.borderBox; borderW = borderBox.left + borderBox.right + 8; borderH = borderBox.top + borderBox.bottom + (self.settings.multiline ? 8 : 0); if (rect.x !== lastRepaintRect.x) { style.left = rect.x + 'px'; lastRepaintRect.x = rect.x; } if (rect.y !== lastRepaintRect.y) { style.top = rect.y + 'px'; lastRepaintRect.y = rect.y; } if (rect.w !== lastRepaintRect.w) { style.width = rect.w - borderW + 'px'; lastRepaintRect.w = rect.w; } if (rect.h !== lastRepaintRect.h) { style.height = rect.h - borderH + 'px'; lastRepaintRect.h = rect.h; } self._lastRepaintRect = lastRepaintRect; self.fire('repaint', {}, false); return self; }, renderHtml: function () { var self = this; var settings = self.settings; var attrs, elm; attrs = { id: self._id, hidefocus: '1' }; global$4.each([ 'rows', 'spellcheck', 'maxLength', 'size', 'readonly', 'min', 'max', 'step', 'list', 'pattern', 'placeholder', 'required', 'multiple' ], function (name) { attrs[name] = settings[name]; }); if (self.disabled()) { attrs.disabled = 'disabled'; } if (settings.subtype) { attrs.type = settings.subtype; } elm = funcs.create(settings.multiline ? 'textarea' : 'input', attrs); elm.value = self.state.get('value'); elm.className = self.classes.toString(); return elm.outerHTML; }, value: function (value) { if (arguments.length) { this.state.set('value', value); return this; } if (this.state.get('rendered')) { this.state.set('value', this.getEl().value); } return this.state.get('value'); }, postRender: function () { var self = this; self.getEl().value = self.state.get('value'); self._super(); self.$el.on('change', function (e) { self.state.set('value', e.target.value); self.fire('change', e); }); }, bindStates: function () { var self = this; self.state.on('change:value', function (e) { if (self.getEl().value !== e.value) { self.getEl().value = e.value; } }); self.state.on('change:disabled', function (e) { self.getEl().disabled = e.value; }); return self._super(); }, remove: function () { this.$el.off(); this._super(); } }); var getApi = function () { return { Selector: Selector, Collection: Collection$2, ReflowQueue: ReflowQueue, Control: Control$1, Factory: global$b, KeyboardNavigation: KeyboardNavigation, Container: Container, DragHelper: DragHelper, Scrollable: Scrollable, Panel: Panel, Movable: Movable, Resizable: Resizable, FloatPanel: FloatPanel, Window: Window, MessageBox: MessageBox, Tooltip: Tooltip, Widget: Widget, Progress: Progress, Notification: Notification, Layout: Layout$1, AbsoluteLayout: AbsoluteLayout, Button: Button, ButtonGroup: ButtonGroup, Checkbox: Checkbox, ComboBox: ComboBox, ColorBox: ColorBox, PanelButton: PanelButton, ColorButton: ColorButton, ColorPicker: ColorPicker, Path: Path, ElementPath: ElementPath, FormItem: FormItem, Form: Form, FieldSet: FieldSet, FilePicker: FilePicker, FitLayout: FitLayout, FlexLayout: FlexLayout, FlowLayout: FlowLayout, FormatControls: FormatControls, GridLayout: GridLayout, Iframe: Iframe, InfoBox: InfoBox, Label: Label, Toolbar: Toolbar$1, MenuBar: MenuBar, MenuButton: MenuButton, MenuItem: MenuItem, Throbber: Throbber, Menu: Menu, ListBox: ListBox, Radio: Radio, ResizeHandle: ResizeHandle, SelectBox: SelectBox, Slider: Slider, Spacer: Spacer, SplitButton: SplitButton, StackLayout: StackLayout, TabPanel: TabPanel, TextBox: TextBox, DropZone: DropZone, BrowseButton: BrowseButton }; }; var appendTo = function (target) { if (target.ui) { global$4.each(getApi(), function (ref, key) { target.ui[key] = ref; }); } else { target.ui = getApi(); } }; var registerToFactory = function () { global$4.each(getApi(), function (ref, key) { global$b.add(key, ref); }); }; var Api = { appendTo: appendTo, registerToFactory: registerToFactory }; Api.registerToFactory(); Api.appendTo(window.tinymce ? window.tinymce : {}); global.add('inlite', function (editor) { var panel = create$3(); FormatControls.setup(editor); Buttons.addToEditor(editor, panel); return ThemeApi.get(editor, panel); }); function Theme () { } return Theme; }(window)); })(); (function () { var mobile = (function (domGlobals) { 'use strict'; var noop = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } }; var compose = function (fa, fb) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return fa(fb.apply(null, args)); }; }; var constant = function (value) { return function () { return value; }; }; var identity = function (x) { return x; }; function curry(fn) { var initialArgs = []; for (var _i = 1; _i < arguments.length; _i++) { initialArgs[_i - 1] = arguments[_i]; } return function () { var restArgs = []; for (var _i = 0; _i < arguments.length; _i++) { restArgs[_i] = arguments[_i]; } var all = initialArgs.concat(restArgs); return fn.apply(null, all); }; } var not = function (f) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return !f.apply(null, args); }; }; var die = function (msg) { return function () { throw new Error(msg); }; }; var apply = function (f) { return f(); }; var never = constant(false); var always = constant(true); var typeOf = function (x) { if (x === null) return 'null'; var t = typeof x; if (t === 'object' && Array.prototype.isPrototypeOf(x)) return 'array'; if (t === 'object' && String.prototype.isPrototypeOf(x)) return 'string'; return t; }; var isType = function (type) { return function (value) { return typeOf(value) === type; }; }; var isString = isType('string'); var isObject = isType('object'); var isArray = isType('array'); var isBoolean = isType('boolean'); var isFunction = isType('function'); var isNumber = isType('number'); var hasOwnProperty = Object.prototype.hasOwnProperty; var shallow = function (old, nu) { return nu; }; var deep = function (old, nu) { var bothObjects = isObject(old) && isObject(nu); return bothObjects ? deepMerge(old, nu) : nu; }; var baseMerge = function (merger) { return function () { var objects = new Array(arguments.length); for (var i = 0; i < objects.length; i++) objects[i] = arguments[i]; if (objects.length === 0) throw new Error('Can\'t merge zero objects'); var ret = {}; for (var j = 0; j < objects.length; j++) { var curObject = objects[j]; for (var key in curObject) if (hasOwnProperty.call(curObject, key)) { ret[key] = merger(ret[key], curObject[key]); } } return ret; }; }; var deepMerge = baseMerge(deep); var merge = baseMerge(shallow); var never$1 = never; var always$1 = always; var none = function () { return NONE; }; var NONE = function () { var eq = function (o) { return o.isNone(); }; var call = function (thunk) { return thunk(); }; var id = function (n) { return n; }; var noop = function () { }; var nul = function () { return null; }; var undef = function () { return undefined; }; var me = { fold: function (n, s) { return n(); }, is: never$1, isSome: never$1, isNone: always$1, getOr: id, getOrThunk: call, getOrDie: function (msg) { throw new Error(msg || 'error: getOrDie called on none.'); }, getOrNull: nul, getOrUndefined: undef, or: id, orThunk: call, map: none, ap: none, each: noop, bind: none, flatten: none, exists: never$1, forall: always$1, filter: none, equals: eq, equals_: eq, toArray: function () { return []; }, toString: constant('none()') }; if (Object.freeze) Object.freeze(me); return me; }(); var some = function (a) { var constant_a = function () { return a; }; var self = function () { return me; }; var map = function (f) { return some(f(a)); }; var bind = function (f) { return f(a); }; var me = { fold: function (n, s) { return s(a); }, is: function (v) { return a === v; }, isSome: always$1, isNone: never$1, getOr: constant_a, getOrThunk: constant_a, getOrDie: constant_a, getOrNull: constant_a, getOrUndefined: constant_a, or: self, orThunk: self, map: map, ap: function (optfab) { return optfab.fold(none, function (fab) { return some(fab(a)); }); }, each: function (f) { f(a); }, bind: bind, flatten: constant_a, exists: bind, forall: bind, filter: function (f) { return f(a) ? me : NONE; }, equals: function (o) { return o.is(a); }, equals_: function (o, elementEq) { return o.fold(never$1, function (b) { return elementEq(a, b); }); }, toArray: function () { return [a]; }, toString: function () { return 'some(' + a + ')'; } }; return me; }; var from = function (value) { return value === null || value === undefined ? NONE : some(value); }; var Option = { some: some, none: none, from: from }; var keys = Object.keys; var each = function (obj, f) { var props = keys(obj); for (var k = 0, len = props.length; k < len; k++) { var i = props[k]; var x = obj[i]; f(x, i, obj); } }; var map = function (obj, f) { return tupleMap(obj, function (x, i, obj) { return { k: i, v: f(x, i, obj) }; }); }; var tupleMap = function (obj, f) { var r = {}; each(obj, function (x, i) { var tuple = f(x, i, obj); r[tuple.k] = tuple.v; }); return r; }; var mapToArray = function (obj, f) { var r = []; each(obj, function (value, name) { r.push(f(value, name)); }); return r; }; var touchstart = constant('touchstart'); var touchmove = constant('touchmove'); var touchend = constant('touchend'); var mousedown = constant('mousedown'); var mousemove = constant('mousemove'); var mouseup = constant('mouseup'); var mouseover = constant('mouseover'); var keydown = constant('keydown'); var input = constant('input'); var change = constant('change'); var click = constant('click'); var transitionend = constant('transitionend'); var selectstart = constant('selectstart'); var cached = function (f) { var called = false; var r; return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (!called) { called = true; r = f.apply(null, args); } return r; }; }; var firstMatch = function (regexes, s) { for (var i = 0; i < regexes.length; i++) { var x = regexes[i]; if (x.test(s)) return x; } return undefined; }; var find = function (regexes, agent) { var r = firstMatch(regexes, agent); if (!r) return { major: 0, minor: 0 }; var group = function (i) { return Number(agent.replace(r, '$' + i)); }; return nu(group(1), group(2)); }; var detect = function (versionRegexes, agent) { var cleanedAgent = String(agent).toLowerCase(); if (versionRegexes.length === 0) return unknown(); return find(versionRegexes, cleanedAgent); }; var unknown = function () { return nu(0, 0); }; var nu = function (major, minor) { return { major: major, minor: minor }; }; var Version = { nu: nu, detect: detect, unknown: unknown }; var edge = 'Edge'; var chrome = 'Chrome'; var ie = 'IE'; var opera = 'Opera'; var firefox = 'Firefox'; var safari = 'Safari'; var isBrowser = function (name, current) { return function () { return current === name; }; }; var unknown$1 = function () { return nu$1({ current: undefined, version: Version.unknown() }); }; var nu$1 = function (info) { var current = info.current; var version = info.version; return { current: current, version: version, isEdge: isBrowser(edge, current), isChrome: isBrowser(chrome, current), isIE: isBrowser(ie, current), isOpera: isBrowser(opera, current), isFirefox: isBrowser(firefox, current), isSafari: isBrowser(safari, current) }; }; var Browser = { unknown: unknown$1, nu: nu$1, edge: constant(edge), chrome: constant(chrome), ie: constant(ie), opera: constant(opera), firefox: constant(firefox), safari: constant(safari) }; var windows = 'Windows'; var ios = 'iOS'; var android = 'Android'; var linux = 'Linux'; var osx = 'OSX'; var solaris = 'Solaris'; var freebsd = 'FreeBSD'; var isOS = function (name, current) { return function () { return current === name; }; }; var unknown$2 = function () { return nu$2({ current: undefined, version: Version.unknown() }); }; var nu$2 = function (info) { var current = info.current; var version = info.version; return { current: current, version: version, isWindows: isOS(windows, current), isiOS: isOS(ios, current), isAndroid: isOS(android, current), isOSX: isOS(osx, current), isLinux: isOS(linux, current), isSolaris: isOS(solaris, current), isFreeBSD: isOS(freebsd, current) }; }; var OperatingSystem = { unknown: unknown$2, nu: nu$2, windows: constant(windows), ios: constant(ios), android: constant(android), linux: constant(linux), osx: constant(osx), solaris: constant(solaris), freebsd: constant(freebsd) }; var DeviceType = function (os, browser, userAgent) { var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true; var isiPhone = os.isiOS() && !isiPad; var isAndroid3 = os.isAndroid() && os.version.major === 3; var isAndroid4 = os.isAndroid() && os.version.major === 4; var isTablet = isiPad || isAndroid3 || isAndroid4 && /mobile/i.test(userAgent) === true; var isTouch = os.isiOS() || os.isAndroid(); var isPhone = isTouch && !isTablet; var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false; return { isiPad: constant(isiPad), isiPhone: constant(isiPhone), isTablet: constant(isTablet), isPhone: constant(isPhone), isTouch: constant(isTouch), isAndroid: os.isAndroid, isiOS: os.isiOS, isWebView: constant(iOSwebview) }; }; var rawIndexOf = function () { var pIndexOf = Array.prototype.indexOf; var fastIndex = function (xs, x) { return pIndexOf.call(xs, x); }; var slowIndex = function (xs, x) { return slowIndexOf(xs, x); }; return pIndexOf === undefined ? slowIndex : fastIndex; }(); var contains = function (xs, x) { return rawIndexOf(xs, x) > -1; }; var exists = function (xs, pred) { return findIndex(xs, pred).isSome(); }; var map$1 = function (xs, f) { var len = xs.length; var r = new Array(len); for (var i = 0; i < len; i++) { var x = xs[i]; r[i] = f(x, i, xs); } return r; }; var each$1 = function (xs, f) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; f(x, i, xs); } }; var eachr = function (xs, f) { for (var i = xs.length - 1; i >= 0; i--) { var x = xs[i]; f(x, i, xs); } }; var filter = function (xs, pred) { var r = []; for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { r.push(x); } } return r; }; var foldr = function (xs, f, acc) { eachr(xs, function (x) { acc = f(acc, x); }); return acc; }; var foldl = function (xs, f, acc) { each$1(xs, function (x) { acc = f(acc, x); }); return acc; }; var find$1 = function (xs, pred) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { return Option.some(x); } } return Option.none(); }; var findIndex = function (xs, pred) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { return Option.some(i); } } return Option.none(); }; var slowIndexOf = function (xs, x) { for (var i = 0, len = xs.length; i < len; ++i) { if (xs[i] === x) { return i; } } return -1; }; var push = Array.prototype.push; var flatten = function (xs) { var r = []; for (var i = 0, len = xs.length; i < len; ++i) { if (!Array.prototype.isPrototypeOf(xs[i])) throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs); push.apply(r, xs[i]); } return r; }; var bind = function (xs, f) { var output = map$1(xs, f); return flatten(output); }; var forall = function (xs, pred) { for (var i = 0, len = xs.length; i < len; ++i) { var x = xs[i]; if (pred(x, i, xs) !== true) { return false; } } return true; }; var slice = Array.prototype.slice; var reverse = function (xs) { var r = slice.call(xs, 0); r.reverse(); return r; }; var difference = function (a1, a2) { return filter(a1, function (x) { return !contains(a2, x); }); }; var pure = function (x) { return [x]; }; var from$1 = isFunction(Array.from) ? Array.from : function (x) { return slice.call(x); }; var detect$1 = function (candidates, userAgent) { var agent = String(userAgent).toLowerCase(); return find$1(candidates, function (candidate) { return candidate.search(agent); }); }; var detectBrowser = function (browsers, userAgent) { return detect$1(browsers, userAgent).map(function (browser) { var version = Version.detect(browser.versionRegexes, userAgent); return { current: browser.name, version: version }; }); }; var detectOs = function (oses, userAgent) { return detect$1(oses, userAgent).map(function (os) { var version = Version.detect(os.versionRegexes, userAgent); return { current: os.name, version: version }; }); }; var UaString = { detectBrowser: detectBrowser, detectOs: detectOs }; var checkRange = function (str, substr, start) { if (substr === '') return true; if (str.length < substr.length) return false; var x = str.substr(start, start + substr.length); return x === substr; }; var supplant = function (str, obj) { var isStringOrNumber = function (a) { var t = typeof a; return t === 'string' || t === 'number'; }; return str.replace(/\$\{([^{}]*)\}/g, function (fullMatch, key) { var value = obj[key]; return isStringOrNumber(value) ? value.toString() : fullMatch; }); }; var contains$1 = function (str, substr) { return str.indexOf(substr) !== -1; }; var endsWith = function (str, suffix) { return checkRange(str, suffix, str.length - suffix.length); }; var trim = function (str) { return str.replace(/^\s+|\s+$/g, ''); }; var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/; var checkContains = function (target) { return function (uastring) { return contains$1(uastring, target); }; }; var browsers = [ { name: 'Edge', versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/], search: function (uastring) { var monstrosity = contains$1(uastring, 'edge/') && contains$1(uastring, 'chrome') && contains$1(uastring, 'safari') && contains$1(uastring, 'applewebkit'); return monstrosity; } }, { name: 'Chrome', versionRegexes: [ /.*?chrome\/([0-9]+)\.([0-9]+).*/, normalVersionRegex ], search: function (uastring) { return contains$1(uastring, 'chrome') && !contains$1(uastring, 'chromeframe'); } }, { name: 'IE', versionRegexes: [ /.*?msie\ ?([0-9]+)\.([0-9]+).*/, /.*?rv:([0-9]+)\.([0-9]+).*/ ], search: function (uastring) { return contains$1(uastring, 'msie') || contains$1(uastring, 'trident'); } }, { name: 'Opera', versionRegexes: [ normalVersionRegex, /.*?opera\/([0-9]+)\.([0-9]+).*/ ], search: checkContains('opera') }, { name: 'Firefox', versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/], search: checkContains('firefox') }, { name: 'Safari', versionRegexes: [ normalVersionRegex, /.*?cpu os ([0-9]+)_([0-9]+).*/ ], search: function (uastring) { return (contains$1(uastring, 'safari') || contains$1(uastring, 'mobile/')) && contains$1(uastring, 'applewebkit'); } } ]; var oses = [ { name: 'Windows', search: checkContains('win'), versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/] }, { name: 'iOS', search: function (uastring) { return contains$1(uastring, 'iphone') || contains$1(uastring, 'ipad'); }, versionRegexes: [ /.*?version\/\ ?([0-9]+)\.([0-9]+).*/, /.*cpu os ([0-9]+)_([0-9]+).*/, /.*cpu iphone os ([0-9]+)_([0-9]+).*/ ] }, { name: 'Android', search: checkContains('android'), versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/] }, { name: 'OSX', search: checkContains('os x'), versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/] }, { name: 'Linux', search: checkContains('linux'), versionRegexes: [] }, { name: 'Solaris', search: checkContains('sunos'), versionRegexes: [] }, { name: 'FreeBSD', search: checkContains('freebsd'), versionRegexes: [] } ]; var PlatformInfo = { browsers: constant(browsers), oses: constant(oses) }; var detect$2 = function (userAgent) { var browsers = PlatformInfo.browsers(); var oses = PlatformInfo.oses(); var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu); var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu); var deviceType = DeviceType(os, browser, userAgent); return { browser: browser, os: os, deviceType: deviceType }; }; var PlatformDetection = { detect: detect$2 }; var detect$3 = cached(function () { var userAgent = domGlobals.navigator.userAgent; return PlatformDetection.detect(userAgent); }); var PlatformDetection$1 = { detect: detect$3 }; var alloy = { tap: constant('alloy.tap') }; var focus = constant('alloy.focus'); var postBlur = constant('alloy.blur.post'); var receive = constant('alloy.receive'); var execute = constant('alloy.execute'); var focusItem = constant('alloy.focus.item'); var tap = alloy.tap; var tapOrClick = PlatformDetection$1.detect().deviceType.isTouch() ? alloy.tap : click; var longpress = constant('alloy.longpress'); var systemInit = constant('alloy.system.init'); var windowScroll = constant('alloy.system.scroll'); var attachedToDom = constant('alloy.system.attached'); var detachedFromDom = constant('alloy.system.detached'); var emit = function (component, event) { dispatchWith(component, component.element(), event, {}); }; var emitWith = function (component, event, properties) { dispatchWith(component, component.element(), event, properties); }; var emitExecute = function (component) { emit(component, execute()); }; var dispatch = function (component, target, event) { dispatchWith(component, target, event, {}); }; var dispatchWith = function (component, target, event, properties) { var data = deepMerge({ target: target }, properties); component.getSystem().triggerEvent(event, target, map(data, constant)); }; var dispatchEvent = function (component, target, event, simulatedEvent) { component.getSystem().triggerEvent(event, target, simulatedEvent.event()); }; var dispatchFocus = function (component, target) { component.getSystem().triggerFocus(target, component.element()); }; var fromHtml = function (html, scope) { var doc = scope || domGlobals.document; var div = doc.createElement('div'); div.innerHTML = html; if (!div.hasChildNodes() || div.childNodes.length > 1) { domGlobals.console.error('HTML does not have a single root node', html); throw new Error('HTML must have a single root node'); } return fromDom(div.childNodes[0]); }; var fromTag = function (tag, scope) { var doc = scope || domGlobals.document; var node = doc.createElement(tag); return fromDom(node); }; var fromText = function (text, scope) { var doc = scope || domGlobals.document; var node = doc.createTextNode(text); return fromDom(node); }; var fromDom = function (node) { if (node === null || node === undefined) { throw new Error('Node cannot be null or undefined'); } return { dom: constant(node) }; }; var fromPoint = function (docElm, x, y) { var doc = docElm.dom(); return Option.from(doc.elementFromPoint(x, y)).map(fromDom); }; var Element = { fromHtml: fromHtml, fromTag: fromTag, fromText: fromText, fromDom: fromDom, fromPoint: fromPoint }; var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE; var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE; var COMMENT = domGlobals.Node.COMMENT_NODE; var DOCUMENT = domGlobals.Node.DOCUMENT_NODE; var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE; var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE; var ELEMENT = domGlobals.Node.ELEMENT_NODE; var TEXT = domGlobals.Node.TEXT_NODE; var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE; var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE; var ENTITY = domGlobals.Node.ENTITY_NODE; var NOTATION = domGlobals.Node.NOTATION_NODE; var name = function (element) { var r = element.dom().nodeName; return r.toLowerCase(); }; var type = function (element) { return element.dom().nodeType; }; var isType$1 = function (t) { return function (element) { return type(element) === t; }; }; var isElement = isType$1(ELEMENT); var isText = isType$1(TEXT); var inBody = function (element) { var dom = isText(element) ? element.dom().parentNode : element.dom(); return dom !== undefined && dom !== null && dom.ownerDocument.body.contains(dom); }; var body = cached(function () { return getBody(Element.fromDom(domGlobals.document)); }); var getBody = function (doc) { var b = doc.dom().body; if (b === null || b === undefined) { throw new Error('Body is not available yet'); } return Element.fromDom(b); }; var Immutable = function () { var fields = []; for (var _i = 0; _i < arguments.length; _i++) { fields[_i] = arguments[_i]; } return function () { var values = []; for (var _i = 0; _i < arguments.length; _i++) { values[_i] = arguments[_i]; } if (fields.length !== values.length) { throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments'); } var struct = {}; each$1(fields, function (name, i) { struct[name] = constant(values[i]); }); return struct; }; }; var sort = function (arr) { return arr.slice(0).sort(); }; var reqMessage = function (required, keys) { throw new Error('All required keys (' + sort(required).join(', ') + ') were not specified. Specified keys were: ' + sort(keys).join(', ') + '.'); }; var unsuppMessage = function (unsupported) { throw new Error('Unsupported keys for object: ' + sort(unsupported).join(', ')); }; var validateStrArr = function (label, array) { if (!isArray(array)) throw new Error('The ' + label + ' fields must be an array. Was: ' + array + '.'); each$1(array, function (a) { if (!isString(a)) throw new Error('The value ' + a + ' in the ' + label + ' fields was not a string.'); }); }; var invalidTypeMessage = function (incorrect, type) { throw new Error('All values need to be of type: ' + type + '. Keys (' + sort(incorrect).join(', ') + ') were not.'); }; var checkDupes = function (everything) { var sorted = sort(everything); var dupe = find$1(sorted, function (s, i) { return i < sorted.length - 1 && s === sorted[i + 1]; }); dupe.each(function (d) { throw new Error('The field: ' + d + ' occurs more than once in the combined fields: [' + sorted.join(', ') + '].'); }); }; var MixedBag = function (required, optional) { var everything = required.concat(optional); if (everything.length === 0) throw new Error('You must specify at least one required or optional field.'); validateStrArr('required', required); validateStrArr('optional', optional); checkDupes(everything); return function (obj) { var keys$1 = keys(obj); var allReqd = forall(required, function (req) { return contains(keys$1, req); }); if (!allReqd) reqMessage(required, keys$1); var unsupported = filter(keys$1, function (key) { return !contains(everything, key); }); if (unsupported.length > 0) unsuppMessage(unsupported); var r = {}; each$1(required, function (req) { r[req] = constant(obj[req]); }); each$1(optional, function (opt) { r[opt] = constant(Object.prototype.hasOwnProperty.call(obj, opt) ? Option.some(obj[opt]) : Option.none()); }); return r; }; }; var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')(); var path = function (parts, scope) { var o = scope !== undefined && scope !== null ? scope : Global; for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i) o = o[parts[i]]; return o; }; var resolve = function (p, scope) { var parts = p.split('.'); return path(parts, scope); }; var unsafe = function (name, scope) { return resolve(name, scope); }; var getOrDie = function (name, scope) { var actual = unsafe(name, scope); if (actual === undefined || actual === null) throw name + ' not available on this browser'; return actual; }; var Global$1 = { getOrDie: getOrDie }; var node = function () { var f = Global$1.getOrDie('Node'); return f; }; var compareDocumentPosition = function (a, b, match) { return (a.compareDocumentPosition(b) & match) !== 0; }; var documentPositionPreceding = function (a, b) { return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_PRECEDING); }; var documentPositionContainedBy = function (a, b) { return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_CONTAINED_BY); }; var Node = { documentPositionPreceding: documentPositionPreceding, documentPositionContainedBy: documentPositionContainedBy }; var ELEMENT$1 = ELEMENT; var DOCUMENT$1 = DOCUMENT; var is = function (element, selector) { var elem = element.dom(); if (elem.nodeType !== ELEMENT$1) { return false; } else if (elem.matches !== undefined) { return elem.matches(selector); } else if (elem.msMatchesSelector !== undefined) { return elem.msMatchesSelector(selector); } else if (elem.webkitMatchesSelector !== undefined) { return elem.webkitMatchesSelector(selector); } else if (elem.mozMatchesSelector !== undefined) { return elem.mozMatchesSelector(selector); } else { throw new Error('Browser lacks native selectors'); } }; var bypassSelector = function (dom) { return dom.nodeType !== ELEMENT$1 && dom.nodeType !== DOCUMENT$1 || dom.childElementCount === 0; }; var all = function (selector, scope) { var base = scope === undefined ? domGlobals.document : scope.dom(); return bypassSelector(base) ? [] : map$1(base.querySelectorAll(selector), Element.fromDom); }; var one = function (selector, scope) { var base = scope === undefined ? domGlobals.document : scope.dom(); return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom); }; var eq = function (e1, e2) { return e1.dom() === e2.dom(); }; var regularContains = function (e1, e2) { var d1 = e1.dom(); var d2 = e2.dom(); return d1 === d2 ? false : d1.contains(d2); }; var ieContains = function (e1, e2) { return Node.documentPositionContainedBy(e1.dom(), e2.dom()); }; var browser = PlatformDetection$1.detect().browser; var contains$2 = browser.isIE() ? ieContains : regularContains; var owner = function (element) { return Element.fromDom(element.dom().ownerDocument); }; var defaultView = function (element) { var el = element.dom(); var defView = el.ownerDocument.defaultView; return Element.fromDom(defView); }; var parent = function (element) { var dom = element.dom(); return Option.from(dom.parentNode).map(Element.fromDom); }; var parents = function (element, isRoot) { var stop = isFunction(isRoot) ? isRoot : constant(false); var dom = element.dom(); var ret = []; while (dom.parentNode !== null && dom.parentNode !== undefined) { var rawParent = dom.parentNode; var p = Element.fromDom(rawParent); ret.push(p); if (stop(p) === true) { break; } else { dom = rawParent; } } return ret; }; var siblings = function (element) { var filterSelf = function (elements) { return filter(elements, function (x) { return !eq(element, x); }); }; return parent(element).map(children).map(filterSelf).getOr([]); }; var nextSibling = function (element) { var dom = element.dom(); return Option.from(dom.nextSibling).map(Element.fromDom); }; var children = function (element) { var dom = element.dom(); return map$1(dom.childNodes, Element.fromDom); }; var child = function (element, index) { var cs = element.dom().childNodes; return Option.from(cs[index]).map(Element.fromDom); }; var firstChild = function (element) { return child(element, 0); }; var spot = Immutable('element', 'offset'); var before = function (marker, element) { var parent$1 = parent(marker); parent$1.each(function (v) { v.dom().insertBefore(element.dom(), marker.dom()); }); }; var after = function (marker, element) { var sibling = nextSibling(marker); sibling.fold(function () { var parent$1 = parent(marker); parent$1.each(function (v) { append(v, element); }); }, function (v) { before(v, element); }); }; var prepend = function (parent, element) { var firstChild$1 = firstChild(parent); firstChild$1.fold(function () { append(parent, element); }, function (v) { parent.dom().insertBefore(element.dom(), v.dom()); }); }; var append = function (parent, element) { parent.dom().appendChild(element.dom()); }; var append$1 = function (parent, elements) { each$1(elements, function (x) { append(parent, x); }); }; var empty = function (element) { element.dom().textContent = ''; each$1(children(element), function (rogue) { remove(rogue); }); }; var remove = function (element) { var dom = element.dom(); if (dom.parentNode !== null) { dom.parentNode.removeChild(dom); } }; var fireDetaching = function (component) { emit(component, detachedFromDom()); var children = component.components(); each$1(children, fireDetaching); }; var fireAttaching = function (component) { var children = component.components(); each$1(children, fireAttaching); emit(component, attachedToDom()); }; var attach = function (parent, child) { attachWith(parent, child, append); }; var attachWith = function (parent, child, insertion) { parent.getSystem().addToWorld(child); insertion(parent.element(), child.element()); if (inBody(parent.element())) { fireAttaching(child); } parent.syncComponents(); }; var doDetach = function (component) { fireDetaching(component); remove(component.element()); component.getSystem().removeFromWorld(component); }; var detach = function (component) { var parent$1 = parent(component.element()).bind(function (p) { return component.getSystem().getByDom(p).fold(Option.none, Option.some); }); doDetach(component); parent$1.each(function (p) { p.syncComponents(); }); }; var detachChildren = function (component) { var subs = component.components(); each$1(subs, doDetach); empty(component.element()); component.syncComponents(); }; var attachSystem = function (element, guiSystem) { append(element, guiSystem.element()); var children$1 = children(guiSystem.element()); each$1(children$1, function (child) { guiSystem.getByDom(child).each(fireAttaching); }); }; var detachSystem = function (guiSystem) { var children$1 = children(guiSystem.element()); each$1(children$1, function (child) { guiSystem.getByDom(child).each(fireDetaching); }); remove(guiSystem.element()); }; var value = function (o) { var is = function (v) { return o === v; }; var or = function (opt) { return value(o); }; var orThunk = function (f) { return value(o); }; var map = function (f) { return value(f(o)); }; var mapError = function (f) { return value(o); }; var each = function (f) { f(o); }; var bind = function (f) { return f(o); }; var fold = function (_, onValue) { return onValue(o); }; var exists = function (f) { return f(o); }; var forall = function (f) { return f(o); }; var toOption = function () { return Option.some(o); }; return { is: is, isValue: always, isError: never, getOr: constant(o), getOrThunk: constant(o), getOrDie: constant(o), or: or, orThunk: orThunk, fold: fold, map: map, mapError: mapError, each: each, bind: bind, exists: exists, forall: forall, toOption: toOption }; }; var error = function (message) { var getOrThunk = function (f) { return f(); }; var getOrDie = function () { return die(String(message))(); }; var or = function (opt) { return opt; }; var orThunk = function (f) { return f(); }; var map = function (f) { return error(message); }; var mapError = function (f) { return error(f(message)); }; var bind = function (f) { return error(message); }; var fold = function (onError, _) { return onError(message); }; return { is: never, isValue: never, isError: always, getOr: identity, getOrThunk: getOrThunk, getOrDie: getOrDie, or: or, orThunk: orThunk, fold: fold, map: map, mapError: mapError, each: noop, bind: bind, exists: never, forall: always, toOption: Option.none }; }; var Result = { value: value, error: error }; var generate = function (cases) { if (!isArray(cases)) { throw new Error('cases must be an array'); } if (cases.length === 0) { throw new Error('there must be at least one case'); } var constructors = []; var adt = {}; each$1(cases, function (acase, count) { var keys$1 = keys(acase); if (keys$1.length !== 1) { throw new Error('one and only one name per case'); } var key = keys$1[0]; var value = acase[key]; if (adt[key] !== undefined) { throw new Error('duplicate key detected:' + key); } else if (key === 'cata') { throw new Error('cannot have a case named cata (sorry)'); } else if (!isArray(value)) { throw new Error('case arguments must be an array'); } constructors.push(key); adt[key] = function () { var argLength = arguments.length; if (argLength !== value.length) { throw new Error('Wrong number of arguments to case ' + key + '. Expected ' + value.length + ' (' + value + '), got ' + argLength); } var args = new Array(argLength); for (var i = 0; i < args.length; i++) args[i] = arguments[i]; var match = function (branches) { var branchKeys = keys(branches); if (constructors.length !== branchKeys.length) { throw new Error('Wrong number of arguments to match. Expected: ' + constructors.join(',') + '\nActual: ' + branchKeys.join(',')); } var allReqd = forall(constructors, function (reqKey) { return contains(branchKeys, reqKey); }); if (!allReqd) throw new Error('Not all branches were specified when using match. Specified: ' + branchKeys.join(', ') + '\nRequired: ' + constructors.join(', ')); return branches[key].apply(null, args); }; return { fold: function () { if (arguments.length !== cases.length) { throw new Error('Wrong number of arguments to fold. Expected ' + cases.length + ', got ' + arguments.length); } var target = arguments[count]; return target.apply(null, args); }, match: match, log: function (label) { domGlobals.console.log(label, { constructors: constructors, constructor: key, params: args }); } }; }; }); return adt; }; var Adt = { generate: generate }; var adt = Adt.generate([ { strict: [] }, { defaultedThunk: ['fallbackThunk'] }, { asOption: [] }, { asDefaultedOptionThunk: ['fallbackThunk'] }, { mergeWithThunk: ['baseThunk'] } ]); var defaulted = function (fallback) { return adt.defaultedThunk(constant(fallback)); }; var mergeWith = function (base) { return adt.mergeWithThunk(constant(base)); }; var strict = adt.strict; var asOption = adt.asOption; var defaultedThunk = adt.defaultedThunk; var mergeWithThunk = adt.mergeWithThunk; var comparison = Adt.generate([ { bothErrors: [ 'error1', 'error2' ] }, { firstError: [ 'error1', 'value2' ] }, { secondError: [ 'value1', 'error2' ] }, { bothValues: [ 'value1', 'value2' ] } ]); var partition = function (results) { var errors = []; var values = []; each$1(results, function (result) { result.fold(function (err) { errors.push(err); }, function (value) { values.push(value); }); }); return { errors: errors, values: values }; }; var mergeValues = function (values, base) { return Result.value(deepMerge.apply(undefined, [base].concat(values))); }; var mergeErrors = function (errors) { return compose(Result.error, flatten)(errors); }; var consolidateObj = function (objects, base) { var partitions = partition(objects); return partitions.errors.length > 0 ? mergeErrors(partitions.errors) : mergeValues(partitions.values, base); }; var consolidateArr = function (objects) { var partitions = partition(objects); return partitions.errors.length > 0 ? mergeErrors(partitions.errors) : Result.value(partitions.values); }; var ResultCombine = { consolidateObj: consolidateObj, consolidateArr: consolidateArr }; var narrow = function (obj, fields) { var r = {}; each$1(fields, function (field) { if (obj[field] !== undefined && obj.hasOwnProperty(field)) { r[field] = obj[field]; } }); return r; }; var exclude = function (obj, fields) { var r = {}; each(obj, function (v, k) { if (!contains(fields, k)) { r[k] = v; } }); return r; }; var readOpt = function (key) { return function (obj) { return obj.hasOwnProperty(key) ? Option.from(obj[key]) : Option.none(); }; }; var readOr = function (key, fallback) { return function (obj) { return readOpt(key)(obj).getOr(fallback); }; }; var readOptFrom = function (obj, key) { return readOpt(key)(obj); }; var hasKey = function (obj, key) { return obj.hasOwnProperty(key) && obj[key] !== undefined && obj[key] !== null; }; var wrap = function (key, value) { var r = {}; r[key] = value; return r; }; var wrapAll = function (keyvalues) { var r = {}; each$1(keyvalues, function (kv) { r[kv.key] = kv.value; }); return r; }; var narrow$1 = function (obj, fields) { return narrow(obj, fields); }; var exclude$1 = function (obj, fields) { return exclude(obj, fields); }; var readOpt$1 = function (key) { return readOpt(key); }; var readOr$1 = function (key, fallback) { return readOr(key, fallback); }; var readOptFrom$1 = function (obj, key) { return readOptFrom(obj, key); }; var wrap$1 = function (key, value) { return wrap(key, value); }; var wrapAll$1 = function (keyvalues) { return wrapAll(keyvalues); }; var consolidate = function (objs, base) { return ResultCombine.consolidateObj(objs, base); }; var hasKey$1 = function (obj, key) { return hasKey(obj, key); }; var typeAdt = Adt.generate([ { setOf: [ 'validator', 'valueType' ] }, { arrOf: ['valueType'] }, { objOf: ['fields'] }, { itemOf: ['validator'] }, { choiceOf: [ 'key', 'branches' ] }, { thunk: ['description'] }, { func: [ 'args', 'outputSchema' ] } ]); var fieldAdt = Adt.generate([ { field: [ 'name', 'presence', 'type' ] }, { state: ['name'] } ]); var json = function () { return Global$1.getOrDie('JSON'); }; var parse = function (text) { return json().parse(text); }; var stringify = function (obj, replacer, space) { return json().stringify(obj, replacer, space); }; var Json = { parse: parse, stringify: stringify }; var formatObj = function (input) { return isObject(input) && keys(input).length > 100 ? ' removed due to size' : Json.stringify(input, null, 2); }; var formatErrors = function (errors) { var es = errors.length > 10 ? errors.slice(0, 10).concat([{ path: [], getErrorInfo: function () { return '... (only showing first ten failures)'; } }]) : errors; return map$1(es, function (e) { return 'Failed path: (' + e.path.join(' > ') + ')\n' + e.getErrorInfo(); }); }; var nu$3 = function (path, getErrorInfo) { return Result.error([{ path: path, getErrorInfo: getErrorInfo }]); }; var missingStrict = function (path, key, obj) { return nu$3(path, function () { return 'Could not find valid *strict* value for "' + key + '" in ' + formatObj(obj); }); }; var missingKey = function (path, key) { return nu$3(path, function () { return 'Choice schema did not contain choice key: "' + key + '"'; }); }; var missingBranch = function (path, branches, branch) { return nu$3(path, function () { return 'The chosen schema: "' + branch + '" did not exist in branches: ' + formatObj(branches); }); }; var unsupportedFields = function (path, unsupported) { return nu$3(path, function () { return 'There are unsupported fields: [' + unsupported.join(', ') + '] specified'; }); }; var custom = function (path, err) { return nu$3(path, function () { return err; }); }; var adt$1 = Adt.generate([ { field: [ 'key', 'okey', 'presence', 'prop' ] }, { state: [ 'okey', 'instantiator' ] } ]); var strictAccess = function (path, obj, key) { return readOptFrom(obj, key).fold(function () { return missingStrict(path, key, obj); }, Result.value); }; var fallbackAccess = function (obj, key, fallbackThunk) { var v = readOptFrom(obj, key).fold(function () { return fallbackThunk(obj); }, identity); return Result.value(v); }; var optionAccess = function (obj, key) { return Result.value(readOptFrom(obj, key)); }; var optionDefaultedAccess = function (obj, key, fallback) { var opt = readOptFrom(obj, key).map(function (val) { return val === true ? fallback(obj) : val; }); return Result.value(opt); }; var cExtractOne = function (path, obj, field, strength) { return field.fold(function (key, okey, presence, prop) { var bundle = function (av) { return prop.extract(path.concat([key]), strength, av).map(function (res) { return wrap(okey, strength(res)); }); }; var bundleAsOption = function (optValue) { return optValue.fold(function () { var outcome = wrap(okey, strength(Option.none())); return Result.value(outcome); }, function (ov) { return prop.extract(path.concat([key]), strength, ov).map(function (res) { return wrap(okey, strength(Option.some(res))); }); }); }; return function () { return presence.fold(function () { return strictAccess(path, obj, key).bind(bundle); }, function (fallbackThunk) { return fallbackAccess(obj, key, fallbackThunk).bind(bundle); }, function () { return optionAccess(obj, key).bind(bundleAsOption); }, function (fallbackThunk) { return optionDefaultedAccess(obj, key, fallbackThunk).bind(bundleAsOption); }, function (baseThunk) { var base = baseThunk(obj); return fallbackAccess(obj, key, constant({})).map(function (v) { return deepMerge(base, v); }).bind(bundle); }); }(); }, function (okey, instantiator) { var state = instantiator(obj); return Result.value(wrap(okey, strength(state))); }); }; var cExtract = function (path, obj, fields, strength) { var results = map$1(fields, function (field) { return cExtractOne(path, obj, field, strength); }); return ResultCombine.consolidateObj(results, {}); }; var value$1 = function (validator) { var extract = function (path, strength, val) { return validator(val, strength).fold(function (err) { return custom(path, err); }, Result.value); }; var toString = function () { return 'val'; }; var toDsl = function () { return typeAdt.itemOf(validator); }; return { extract: extract, toString: toString, toDsl: toDsl }; }; var getSetKeys = function (obj) { var keys$1 = keys(obj); return filter(keys$1, function (k) { return hasKey$1(obj, k); }); }; var objOfOnly = function (fields) { var delegate = objOf(fields); var fieldNames = foldr(fields, function (acc, f) { return f.fold(function (key) { return deepMerge(acc, wrap$1(key, true)); }, constant(acc)); }, {}); var extract = function (path, strength, o) { var keys = isBoolean(o) ? [] : getSetKeys(o); var extra = filter(keys, function (k) { return !hasKey$1(fieldNames, k); }); return extra.length === 0 ? delegate.extract(path, strength, o) : unsupportedFields(path, extra); }; return { extract: extract, toString: delegate.toString, toDsl: delegate.toDsl }; }; var objOf = function (fields) { var extract = function (path, strength, o) { return cExtract(path, o, fields, strength); }; var toString = function () { var fieldStrings = map$1(fields, function (field) { return field.fold(function (key, okey, presence, prop) { return key + ' -> ' + prop.toString(); }, function (okey, instantiator) { return 'state(' + okey + ')'; }); }); return 'obj{\n' + fieldStrings.join('\n') + '}'; }; var toDsl = function () { return typeAdt.objOf(map$1(fields, function (f) { return f.fold(function (key, okey, presence, prop) { return fieldAdt.field(key, presence, prop); }, function (okey, instantiator) { return fieldAdt.state(okey); }); })); }; return { extract: extract, toString: toString, toDsl: toDsl }; }; var arrOf = function (prop) { var extract = function (path, strength, array) { var results = map$1(array, function (a, i) { return prop.extract(path.concat(['[' + i + ']']), strength, a); }); return ResultCombine.consolidateArr(results); }; var toString = function () { return 'array(' + prop.toString() + ')'; }; var toDsl = function () { return typeAdt.arrOf(prop); }; return { extract: extract, toString: toString, toDsl: toDsl }; }; var setOf = function (validator, prop) { var validateKeys = function (path, keys) { return arrOf(value$1(validator)).extract(path, identity, keys); }; var extract = function (path, strength, o) { var keys$1 = keys(o); return validateKeys(path, keys$1).bind(function (validKeys) { var schema = map$1(validKeys, function (vk) { return adt$1.field(vk, vk, strict(), prop); }); return objOf(schema).extract(path, strength, o); }); }; var toString = function () { return 'setOf(' + prop.toString() + ')'; }; var toDsl = function () { return typeAdt.setOf(validator, prop); }; return { extract: extract, toString: toString, toDsl: toDsl }; }; var anyValue = constant(value$1(Result.value)); var state = adt$1.state; var field = adt$1.field; var chooseFrom = function (path, strength, input, branches, ch) { var fields = readOptFrom$1(branches, ch); return fields.fold(function () { return missingBranch(path, branches, ch); }, function (fs) { return objOf(fs).extract(path.concat(['branch: ' + ch]), strength, input); }); }; var choose = function (key, branches) { var extract = function (path, strength, input) { var choice = readOptFrom$1(input, key); return choice.fold(function () { return missingKey(path, key); }, function (chosen) { return chooseFrom(path, strength, input, branches, chosen); }); }; var toString = function () { return 'chooseOn(' + key + '). Possible values: ' + keys(branches); }; var toDsl = function () { return typeAdt.choiceOf(key, branches); }; return { extract: extract, toString: toString, toDsl: toDsl }; }; var _anyValue = value$1(Result.value); var valueOf = function (validator) { return value$1(function (v) { return validator(v); }); }; var extract = function (label, prop, strength, obj) { return prop.extract([label], strength, obj).fold(function (errs) { return Result.error({ input: obj, errors: errs }); }, Result.value); }; var asStruct = function (label, prop, obj) { return extract(label, prop, constant, obj); }; var asRaw = function (label, prop, obj) { return extract(label, prop, identity, obj); }; var getOrDie$1 = function (extraction) { return extraction.fold(function (errInfo) { throw new Error(formatError(errInfo)); }, identity); }; var asRawOrDie = function (label, prop, obj) { return getOrDie$1(asRaw(label, prop, obj)); }; var asStructOrDie = function (label, prop, obj) { return getOrDie$1(asStruct(label, prop, obj)); }; var formatError = function (errInfo) { return 'Errors: \n' + formatErrors(errInfo.errors) + '\n\nInput object: ' + formatObj(errInfo.input); }; var choose$1 = function (key, branches) { return choose(key, branches); }; var anyValue$1 = constant(_anyValue); var typedValue = function (validator, expectedType) { return value$1(function (a) { var actualType = typeof a; return validator(a) ? Result.value(a) : Result.error('Expected type: ' + expectedType + ' but got: ' + actualType); }); }; var functionProcessor = typedValue(isFunction, 'function'); var strict$1 = function (key) { return field(key, key, strict(), anyValue()); }; var strictOf = function (key, schema) { return field(key, key, strict(), schema); }; var strictFunction = function (key) { return strictOf(key, functionProcessor); }; var forbid = function (key, message) { return field(key, key, asOption(), value$1(function (v) { return Result.error('The field: ' + key + ' is forbidden. ' + message); })); }; var strictObjOf = function (key, objSchema) { return field(key, key, strict(), objOf(objSchema)); }; var option = function (key) { return field(key, key, asOption(), anyValue()); }; var optionOf = function (key, schema) { return field(key, key, asOption(), schema); }; var optionObjOf = function (key, objSchema) { return field(key, key, asOption(), objOf(objSchema)); }; var optionObjOfOnly = function (key, objSchema) { return field(key, key, asOption(), objOfOnly(objSchema)); }; var defaulted$1 = function (key, fallback) { return field(key, key, defaulted(fallback), anyValue()); }; var defaultedOf = function (key, fallback, schema) { return field(key, key, defaulted(fallback), schema); }; var defaultedObjOf = function (key, fallback, objSchema) { return field(key, key, defaulted(fallback), objOf(objSchema)); }; var state$1 = function (okey, instantiator) { return state(okey, instantiator); }; var isSource = function (component, simulatedEvent) { return eq(component.element(), simulatedEvent.event().target()); }; var nu$4 = function (parts) { if (!hasKey$1(parts, 'can') && !hasKey$1(parts, 'abort') && !hasKey$1(parts, 'run')) { throw new Error('EventHandler defined by: ' + Json.stringify(parts, null, 2) + ' does not have can, abort, or run!'); } return asRawOrDie('Extracting event.handler', objOfOnly([ defaulted$1('can', constant(true)), defaulted$1('abort', constant(false)), defaulted$1('run', noop) ]), parts); }; var all$1 = function (handlers, f) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return foldl(handlers, function (acc, handler) { return acc && f(handler).apply(undefined, args); }, true); }; }; var any = function (handlers, f) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return foldl(handlers, function (acc, handler) { return acc || f(handler).apply(undefined, args); }, false); }; }; var read = function (handler) { return isFunction(handler) ? { can: constant(true), abort: constant(false), run: handler } : handler; }; var fuse = function (handlers) { var can = all$1(handlers, function (handler) { return handler.can; }); var abort = any(handlers, function (handler) { return handler.abort; }); var run = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } each$1(handlers, function (handler) { handler.run.apply(undefined, args); }); }; return nu$4({ can: can, abort: abort, run: run }); }; var derive = function (configs) { return wrapAll$1(configs); }; var abort = function (name, predicate) { return { key: name, value: nu$4({ abort: predicate }) }; }; var can = function (name, predicate) { return { key: name, value: nu$4({ can: predicate }) }; }; var run = function (name, handler) { return { key: name, value: nu$4({ run: handler }) }; }; var runActionExtra = function (name, action, extra) { return { key: name, value: nu$4({ run: function (component) { action.apply(undefined, [component].concat(extra)); } }) }; }; var runOnName = function (name) { return function (handler) { return run(name, handler); }; }; var runOnSourceName = function (name) { return function (handler) { return { key: name, value: nu$4({ run: function (component, simulatedEvent) { if (isSource(component, simulatedEvent)) { handler(component, simulatedEvent); } } }) }; }; }; var redirectToUid = function (name, uid) { return run(name, function (component, simulatedEvent) { component.getSystem().getByUid(uid).each(function (redirectee) { dispatchEvent(redirectee, redirectee.element(), name, simulatedEvent); }); }); }; var redirectToPart = function (name, detail, partName) { var uid = detail.partUids()[partName]; return redirectToUid(name, uid); }; var runWithTarget = function (name, f) { return run(name, function (component, simulatedEvent) { var ev = simulatedEvent.event(); component.getSystem().getByDom(ev.target()).each(function (target) { f(component, target, simulatedEvent); }); }); }; var cutter = function (name) { return run(name, function (component, simulatedEvent) { simulatedEvent.cut(); }); }; var stopper = function (name) { return run(name, function (component, simulatedEvent) { simulatedEvent.stop(); }); }; var runOnAttached = runOnSourceName(attachedToDom()); var runOnDetached = runOnSourceName(detachedFromDom()); var runOnInit = runOnSourceName(systemInit()); var runOnExecute = runOnName(execute()); var markAsBehaviourApi = function (f, apiName, apiFunction) { var delegate = apiFunction.toString(); var endIndex = delegate.indexOf(')') + 1; var openBracketIndex = delegate.indexOf('('); var parameters = delegate.substring(openBracketIndex + 1, endIndex - 1).split(/,\s*/); f.toFunctionAnnotation = function () { return { name: apiName, parameters: cleanParameters(parameters.slice(0, 1).concat(parameters.slice(3))) }; }; return f; }; var cleanParameters = function (parameters) { return map$1(parameters, function (p) { return endsWith(p, '/*') ? p.substring(0, p.length - '/*'.length) : p; }); }; var markAsExtraApi = function (f, extraName) { var delegate = f.toString(); var endIndex = delegate.indexOf(')') + 1; var openBracketIndex = delegate.indexOf('('); var parameters = delegate.substring(openBracketIndex + 1, endIndex - 1).split(/,\s*/); f.toFunctionAnnotation = function () { return { name: extraName, parameters: cleanParameters(parameters) }; }; return f; }; var markAsSketchApi = function (f, apiFunction) { var delegate = apiFunction.toString(); var endIndex = delegate.indexOf(')') + 1; var openBracketIndex = delegate.indexOf('('); var parameters = delegate.substring(openBracketIndex + 1, endIndex - 1).split(/,\s*/); f.toFunctionAnnotation = function () { return { name: 'OVERRIDE', parameters: cleanParameters(parameters.slice(1)) }; }; return f; }; var nu$5 = MixedBag(['tag'], [ 'classes', 'attributes', 'styles', 'value', 'innerHtml', 'domChildren', 'defChildren' ]); var defToStr = function (defn) { var raw = defToRaw(defn); return Json.stringify(raw, null, 2); }; var defToRaw = function (defn) { return { tag: defn.tag(), classes: defn.classes().getOr([]), attributes: defn.attributes().getOr({}), styles: defn.styles().getOr({}), value: defn.value().getOr('<none>'), innerHtml: defn.innerHtml().getOr('<none>'), defChildren: defn.defChildren().fold(function () { return '<none>'; }, function (d) { return Json.stringify(d, null, 2); }), domChildren: defn.domChildren().fold(function () { return '<none>'; }, function (children) { return children.length === 0 ? '0 children, but still specified' : String(children.length); }) }; }; var fields = [ 'classes', 'attributes', 'styles', 'value', 'innerHtml', 'defChildren', 'domChildren' ]; var nu$6 = MixedBag([], fields); var clashingOptArrays = function (key, oArr1, oArr2) { return oArr1.fold(function () { return oArr2.fold(function () { return {}; }, function (arr2) { return wrap$1(key, arr2); }); }, function (arr1) { return oArr2.fold(function () { return wrap$1(key, arr1); }, function (arr2) { return wrap$1(key, arr2); }); }); }; var merge$1 = function (defnA, mod) { var raw = deepMerge({ tag: defnA.tag(), classes: mod.classes().getOr([]).concat(defnA.classes().getOr([])), attributes: merge(defnA.attributes().getOr({}), mod.attributes().getOr({})), styles: merge(defnA.styles().getOr({}), mod.styles().getOr({})) }, mod.innerHtml().or(defnA.innerHtml()).map(function (innerHtml) { return wrap$1('innerHtml', innerHtml); }).getOr({}), clashingOptArrays('domChildren', mod.domChildren(), defnA.domChildren()), clashingOptArrays('defChildren', mod.defChildren(), defnA.defChildren()), mod.value().or(defnA.value()).map(function (value) { return wrap$1('value', value); }).getOr({})); return nu$5(raw); }; var executeEvent = function (bConfig, bState, executor) { return runOnExecute(function (component) { executor(component, bConfig, bState); }); }; var loadEvent = function (bConfig, bState, f) { return runOnInit(function (component, simulatedEvent) { f(component, bConfig, bState); }); }; var create = function (schema, name, active, apis, extra, state) { var configSchema = objOfOnly(schema); var schemaSchema = optionObjOf(name, [optionObjOfOnly('config', schema)]); return doCreate(configSchema, schemaSchema, name, active, apis, extra, state); }; var createModes = function (modes, name, active, apis, extra, state) { var configSchema = modes; var schemaSchema = optionObjOf(name, [optionOf('config', modes)]); return doCreate(configSchema, schemaSchema, name, active, apis, extra, state); }; var wrapApi = function (bName, apiFunction, apiName) { var f = function (component) { var rest = []; for (var _i = 1; _i < arguments.length; _i++) { rest[_i - 1] = arguments[_i]; } var args = [component].concat(rest); return component.config({ name: constant(bName) }).fold(function () { throw new Error('We could not find any behaviour configuration for: ' + bName + '. Using API: ' + apiName); }, function (info) { var rest = Array.prototype.slice.call(args, 1); return apiFunction.apply(undefined, [ component, info.config, info.state ].concat(rest)); }); }; return markAsBehaviourApi(f, apiName, apiFunction); }; var revokeBehaviour = function (name) { return { key: name, value: undefined }; }; var doCreate = function (configSchema, schemaSchema, name, active, apis, extra, state) { var getConfig = function (info) { return hasKey$1(info, name) ? info[name]() : Option.none(); }; var wrappedApis = map(apis, function (apiF, apiName) { return wrapApi(name, apiF, apiName); }); var wrappedExtra = map(extra, function (extraF, extraName) { return markAsExtraApi(extraF, extraName); }); var me = deepMerge(wrappedExtra, wrappedApis, { revoke: curry(revokeBehaviour, name), config: function (spec) { var prepared = asStructOrDie(name + '-config', configSchema, spec); return { key: name, value: { config: prepared, me: me, configAsRaw: cached(function () { return asRawOrDie(name + '-config', configSchema, spec); }), initialConfig: spec, state: state } }; }, schema: function () { return schemaSchema; }, exhibit: function (info, base) { return getConfig(info).bind(function (behaviourInfo) { return readOptFrom$1(active, 'exhibit').map(function (exhibitor) { return exhibitor(base, behaviourInfo.config, behaviourInfo.state); }); }).getOr(nu$6({})); }, name: function () { return name; }, handlers: function (info) { return getConfig(info).bind(function (behaviourInfo) { return readOptFrom$1(active, 'events').map(function (events) { return events(behaviourInfo.config, behaviourInfo.state); }); }).getOr({}); } }); return me; }; var base = function (handleUnsupported, required) { return baseWith(handleUnsupported, required, { validate: isFunction, label: 'function' }); }; var baseWith = function (handleUnsupported, required, pred) { if (required.length === 0) throw new Error('You must specify at least one required field.'); validateStrArr('required', required); checkDupes(required); return function (obj) { var keys$1 = keys(obj); var allReqd = forall(required, function (req) { return contains(keys$1, req); }); if (!allReqd) reqMessage(required, keys$1); handleUnsupported(required, keys$1); var invalidKeys = filter(required, function (key) { return !pred.validate(obj[key], key); }); if (invalidKeys.length > 0) invalidTypeMessage(invalidKeys, pred.label); return obj; }; }; var handleExact = function (required, keys) { var unsupported = filter(keys, function (key) { return !contains(required, key); }); if (unsupported.length > 0) unsuppMessage(unsupported); }; var allowExtra = noop; var exactly = function (required) { return base(handleExact, required); }; var ensure = function (required) { return base(allowExtra, required); }; var NoState = { init: function () { return nu$7({ readState: function () { return 'No State required'; } }); } }; var nu$7 = function (spec) { ensure(['readState'])(spec); return spec; }; var derive$1 = function (capabilities) { return wrapAll$1(capabilities); }; var simpleSchema = objOfOnly([ strict$1('fields'), strict$1('name'), defaulted$1('active', {}), defaulted$1('apis', {}), defaulted$1('state', NoState), defaulted$1('extra', {}) ]); var create$1 = function (data) { var value = asRawOrDie('Creating behaviour: ' + data.name, simpleSchema, data); return create(value.fields, value.name, value.active, value.apis, value.extra, value.state); }; var modeSchema = objOfOnly([ strict$1('branchKey'), strict$1('branches'), strict$1('name'), defaulted$1('active', {}), defaulted$1('apis', {}), defaulted$1('state', NoState), defaulted$1('extra', {}) ]); var createModes$1 = function (data) { var value = asRawOrDie('Creating behaviour: ' + data.name, modeSchema, data); return createModes(choose$1(value.branchKey, value.branches), value.name, value.active, value.apis, value.extra, value.state); }; var revoke = constant(undefined); var rawSet = function (dom, key, value) { if (isString(value) || isBoolean(value) || isNumber(value)) { dom.setAttribute(key, value + ''); } else { domGlobals.console.error('Invalid call to Attr.set. Key ', key, ':: Value ', value, ':: Element ', dom); throw new Error('Attribute value was not simple'); } }; var set = function (element, key, value) { rawSet(element.dom(), key, value); }; var setAll = function (element, attrs) { var dom = element.dom(); each(attrs, function (v, k) { rawSet(dom, k, v); }); }; var get = function (element, key) { var v = element.dom().getAttribute(key); return v === null ? undefined : v; }; var has = function (element, key) { var dom = element.dom(); return dom && dom.hasAttribute ? dom.hasAttribute(key) : false; }; var remove$1 = function (element, key) { element.dom().removeAttribute(key); }; var read$1 = function (element, attr) { var value = get(element, attr); return value === undefined || value === '' ? [] : value.split(' '); }; var add = function (element, attr, id) { var old = read$1(element, attr); var nu = old.concat([id]); set(element, attr, nu.join(' ')); return true; }; var remove$2 = function (element, attr, id) { var nu = filter(read$1(element, attr), function (v) { return v !== id; }); if (nu.length > 0) { set(element, attr, nu.join(' ')); } else { remove$1(element, attr); } return false; }; var supports = function (element) { return element.dom().classList !== undefined; }; var get$1 = function (element) { return read$1(element, 'class'); }; var add$1 = function (element, clazz) { return add(element, 'class', clazz); }; var remove$3 = function (element, clazz) { return remove$2(element, 'class', clazz); }; var toggle = function (element, clazz) { if (contains(get$1(element), clazz)) { return remove$3(element, clazz); } else { return add$1(element, clazz); } }; var add$2 = function (element, clazz) { if (supports(element)) { element.dom().classList.add(clazz); } else { add$1(element, clazz); } }; var cleanClass = function (element) { var classList = supports(element) ? element.dom().classList : get$1(element); if (classList.length === 0) { remove$1(element, 'class'); } }; var remove$4 = function (element, clazz) { if (supports(element)) { var classList = element.dom().classList; classList.remove(clazz); } else { remove$3(element, clazz); } cleanClass(element); }; var toggle$1 = function (element, clazz) { return supports(element) ? element.dom().classList.toggle(clazz) : toggle(element, clazz); }; var has$1 = function (element, clazz) { return supports(element) && element.dom().classList.contains(clazz); }; var swap = function (element, addCls, removeCls) { remove$4(element, removeCls); add$2(element, addCls); }; var toAlpha = function (component, swapConfig, swapState) { swap(component.element(), swapConfig.alpha(), swapConfig.omega()); }; var toOmega = function (component, swapConfig, swapState) { swap(component.element(), swapConfig.omega(), swapConfig.alpha()); }; var clear = function (component, swapConfig, swapState) { remove$4(component.element(), swapConfig.alpha()); remove$4(component.element(), swapConfig.omega()); }; var isAlpha = function (component, swapConfig, swapState) { return has$1(component.element(), swapConfig.alpha()); }; var isOmega = function (component, swapConfig, swapState) { return has$1(component.element(), swapConfig.omega()); }; var SwapApis = /*#__PURE__*/Object.freeze({ toAlpha: toAlpha, toOmega: toOmega, isAlpha: isAlpha, isOmega: isOmega, clear: clear }); var SwapSchema = [ strict$1('alpha'), strict$1('omega') ]; var Swapping = create$1({ fields: SwapSchema, name: 'swapping', apis: SwapApis }); var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; function ClosestOrAncestor (is, ancestor, scope, a, isRoot) { return is(scope, a) ? Option.some(scope) : isFunction(isRoot) && isRoot(scope) ? Option.none() : ancestor(scope, a, isRoot); } var ancestor = function (scope, predicate, isRoot) { var element = scope.dom(); var stop = isFunction(isRoot) ? isRoot : constant(false); while (element.parentNode) { element = element.parentNode; var el = Element.fromDom(element); if (predicate(el)) { return Option.some(el); } else if (stop(el)) { break; } } return Option.none(); }; var closest = function (scope, predicate, isRoot) { var is = function (s) { return predicate(s); }; return ClosestOrAncestor(is, ancestor, scope, predicate, isRoot); }; var descendant = function (scope, predicate) { var descend = function (node) { for (var i = 0; i < node.childNodes.length; i++) { if (predicate(Element.fromDom(node.childNodes[i]))) { return Option.some(Element.fromDom(node.childNodes[i])); } var res = descend(node.childNodes[i]); if (res.isSome()) { return res; } } return Option.none(); }; return descend(scope.dom()); }; var focus$1 = function (element) { element.dom().focus(); }; var blur = function (element) { element.dom().blur(); }; var hasFocus = function (element) { var doc = owner(element).dom(); return element.dom() === doc.activeElement; }; var active = function (_DOC) { var doc = _DOC !== undefined ? _DOC.dom() : domGlobals.document; return Option.from(doc.activeElement).map(Element.fromDom); }; var search = function (element) { return active(owner(element)).filter(function (e) { return element.dom().contains(e.dom()); }); }; var global = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var global$1 = tinymce.util.Tools.resolve('tinymce.ThemeManager'); var openLink = function (target) { var link = domGlobals.document.createElement('a'); link.target = '_blank'; link.href = target.href; link.rel = 'noreferrer noopener'; var nuEvt = domGlobals.document.createEvent('MouseEvents'); nuEvt.initMouseEvent('click', true, true, domGlobals.window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); domGlobals.document.body.appendChild(link); link.dispatchEvent(nuEvt); domGlobals.document.body.removeChild(link); }; var TinyCodeDupe = { openLink: openLink }; var isSkinDisabled = function (editor) { return editor.settings.skin === false; }; var readOnlyOnInit = function (editor) { return false; }; var formatChanged = 'formatChanged'; var orientationChanged = 'orientationChanged'; var dropupDismissed = 'dropupDismissed'; var TinyChannels = { formatChanged: constant(formatChanged), orientationChanged: constant(orientationChanged), dropupDismissed: constant(dropupDismissed) }; var fromHtml$1 = function (html, scope) { var doc = scope || domGlobals.document; var div = doc.createElement('div'); div.innerHTML = html; return children(Element.fromDom(div)); }; var get$2 = function (element) { return element.dom().innerHTML; }; var set$1 = function (element, content) { var owner$1 = owner(element); var docDom = owner$1.dom(); var fragment = Element.fromDom(docDom.createDocumentFragment()); var contentElements = fromHtml$1(content, docDom); append$1(fragment, contentElements); empty(element); append(element, fragment); }; var getOuter = function (element) { var container = Element.fromTag('div'); var clone = Element.fromDom(element.dom().cloneNode(true)); append(container, clone); return get$2(container); }; var clone = function (original, isDeep) { return Element.fromDom(original.dom().cloneNode(isDeep)); }; var shallow$1 = function (original) { return clone(original, false); }; var getHtml = function (element) { var clone = shallow$1(element); return getOuter(clone); }; var element = function (elem) { return getHtml(elem); }; var chooseChannels = function (channels, message) { return message.universal() ? channels : filter(channels, function (ch) { return contains(message.channels(), ch); }); }; var events = function (receiveConfig) { return derive([run(receive(), function (component, message) { var channelMap = receiveConfig.channels(); var channels = keys(channelMap); var targetChannels = chooseChannels(channels, message); each$1(targetChannels, function (ch) { var channelInfo = channelMap[ch](); var channelSchema = channelInfo.schema(); var data = asStructOrDie('channel[' + ch + '] data\nReceiver: ' + element(component.element()), channelSchema, message.data()); channelInfo.onReceive()(component, data); }); })]); }; var ActiveReceiving = /*#__PURE__*/Object.freeze({ events: events }); var cat = function (arr) { var r = []; var push = function (x) { r.push(x); }; for (var i = 0; i < arr.length; i++) { arr[i].each(push); } return r; }; var findMap = function (arr, f) { for (var i = 0; i < arr.length; i++) { var r = f(arr[i], i); if (r.isSome()) { return r; } } return Option.none(); }; var unknown$3 = 'unknown'; var eventsMonitored = []; var path$1 = [ 'alloy/data/Fields', 'alloy/debugging/Debugging' ]; var getTrace = function () { var err = new Error(); if (err.stack !== undefined) { var lines = err.stack.split('\n'); return find$1(lines, function (line) { return line.indexOf('alloy') > 0 && !exists(path$1, function (p) { return line.indexOf(p) > -1; }); }).getOr(unknown$3); } else { return unknown$3; } }; var ignoreEvent = { logEventCut: noop, logEventStopped: noop, logNoParent: noop, logEventNoHandlers: noop, logEventResponse: noop, write: noop }; var monitorEvent = function (eventName, initialTarget, f) { var logger = eventsMonitored === '*' || contains(eventsMonitored, eventName) ? function () { var sequence = []; return { logEventCut: function (name, target, purpose) { sequence.push({ outcome: 'cut', target: target, purpose: purpose }); }, logEventStopped: function (name, target, purpose) { sequence.push({ outcome: 'stopped', target: target, purpose: purpose }); }, logNoParent: function (name, target, purpose) { sequence.push({ outcome: 'no-parent', target: target, purpose: purpose }); }, logEventNoHandlers: function (name, target) { sequence.push({ outcome: 'no-handlers-left', target: target }); }, logEventResponse: function (name, target, purpose) { sequence.push({ outcome: 'response', purpose: purpose, target: target }); }, write: function () { if (contains([ 'mousemove', 'mouseover', 'mouseout', systemInit() ], eventName)) { return; } domGlobals.console.log(eventName, { event: eventName, target: initialTarget.dom(), sequence: map$1(sequence, function (s) { if (!contains([ 'cut', 'stopped', 'response' ], s.outcome)) { return s.outcome; } else { return '{' + s.purpose + '} ' + s.outcome + ' at (' + element(s.target) + ')'; } }) }); } }; }() : ignoreEvent; var output = f(logger); logger.write(); return output; }; var menuFields = constant([ strict$1('menu'), strict$1('selectedMenu') ]); var itemFields = constant([ strict$1('item'), strict$1('selectedItem') ]); var schema = constant(objOfOnly(itemFields().concat(menuFields()))); var itemSchema = constant(objOfOnly(itemFields())); var _initSize = strictObjOf('initSize', [ strict$1('numColumns'), strict$1('numRows') ]); var itemMarkers = function () { return strictOf('markers', itemSchema()); }; var tieredMenuMarkers = function () { return strictObjOf('markers', [strict$1('backgroundMenu')].concat(menuFields()).concat(itemFields())); }; var markers = function (required) { return strictObjOf('markers', map$1(required, strict$1)); }; var onPresenceHandler = function (label, fieldName, presence) { var trace = getTrace(); return field(fieldName, fieldName, presence, valueOf(function (f) { return Result.value(function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return f.apply(undefined, args); }); })); }; var onHandler = function (fieldName) { return onPresenceHandler('onHandler', fieldName, defaulted(noop)); }; var onKeyboardHandler = function (fieldName) { return onPresenceHandler('onKeyboardHandler', fieldName, defaulted(Option.none)); }; var onStrictHandler = function (fieldName) { return onPresenceHandler('onHandler', fieldName, strict()); }; var onStrictKeyboardHandler = function (fieldName) { return onPresenceHandler('onKeyboardHandler', fieldName, strict()); }; var output = function (name, value) { return state$1(name, constant(value)); }; var snapshot = function (name) { return state$1(name, identity); }; var initSize = constant(_initSize); var ReceivingSchema = [strictOf('channels', setOf(Result.value, objOfOnly([ onStrictHandler('onReceive'), defaulted$1('schema', anyValue$1()) ])))]; var Receiving = create$1({ fields: ReceivingSchema, name: 'receiving', active: ActiveReceiving }); var updateAriaState = function (component, toggleConfig) { var pressed = isOn(component, toggleConfig); var ariaInfo = toggleConfig.aria(); ariaInfo.update()(component, ariaInfo, pressed); }; var toggle$2 = function (component, toggleConfig, toggleState) { toggle$1(component.element(), toggleConfig.toggleClass()); updateAriaState(component, toggleConfig); }; var on = function (component, toggleConfig, toggleState) { add$2(component.element(), toggleConfig.toggleClass()); updateAriaState(component, toggleConfig); }; var off = function (component, toggleConfig, toggleState) { remove$4(component.element(), toggleConfig.toggleClass()); updateAriaState(component, toggleConfig); }; var isOn = function (component, toggleConfig) { return has$1(component.element(), toggleConfig.toggleClass()); }; var onLoad = function (component, toggleConfig, toggleState) { var api = toggleConfig.selected() ? on : off; api(component, toggleConfig, toggleState); }; var ToggleApis = /*#__PURE__*/Object.freeze({ onLoad: onLoad, toggle: toggle$2, isOn: isOn, on: on, off: off }); var exhibit = function (base, toggleConfig, toggleState) { return nu$6({}); }; var events$1 = function (toggleConfig, toggleState) { var execute = executeEvent(toggleConfig, toggleState, toggle$2); var load = loadEvent(toggleConfig, toggleState, onLoad); return derive(flatten([ toggleConfig.toggleOnExecute() ? [execute] : [], [load] ])); }; var ActiveToggle = /*#__PURE__*/Object.freeze({ exhibit: exhibit, events: events$1 }); var updatePressed = function (component, ariaInfo, status) { set(component.element(), 'aria-pressed', status); if (ariaInfo.syncWithExpanded()) { updateExpanded(component, ariaInfo, status); } }; var updateSelected = function (component, ariaInfo, status) { set(component.element(), 'aria-selected', status); }; var updateChecked = function (component, ariaInfo, status) { set(component.element(), 'aria-checked', status); }; var updateExpanded = function (component, ariaInfo, status) { set(component.element(), 'aria-expanded', status); }; var ToggleSchema = [ defaulted$1('selected', false), strict$1('toggleClass'), defaulted$1('toggleOnExecute', true), defaultedOf('aria', { mode: 'none' }, choose$1('mode', { pressed: [ defaulted$1('syncWithExpanded', false), output('update', updatePressed) ], checked: [output('update', updateChecked)], expanded: [output('update', updateExpanded)], selected: [output('update', updateSelected)], none: [output('update', noop)] })) ]; var Toggling = create$1({ fields: ToggleSchema, name: 'toggling', active: ActiveToggle, apis: ToggleApis }); var format = function (command, update) { return Receiving.config({ channels: wrap$1(TinyChannels.formatChanged(), { onReceive: function (button, data) { if (data.command === command) { update(button, data.state); } } }) }); }; var orientation = function (onReceive) { return Receiving.config({ channels: wrap$1(TinyChannels.orientationChanged(), { onReceive: onReceive }) }); }; var receive$1 = function (channel, onReceive) { return { key: channel, value: { onReceive: onReceive } }; }; var Receivers = { format: format, orientation: orientation, receive: receive$1 }; var prefix = 'tinymce-mobile'; var resolve$1 = function (p) { return prefix + '-' + p; }; var Styles = { resolve: resolve$1, prefix: constant(prefix) }; var events$2 = function (optAction) { var executeHandler = function (action) { return run(execute(), function (component, simulatedEvent) { action(component); simulatedEvent.stop(); }); }; var onClick = function (component, simulatedEvent) { simulatedEvent.stop(); emitExecute(component); }; var onMousedown = function (component, simulatedEvent) { simulatedEvent.cut(); }; var pointerEvents = PlatformDetection$1.detect().deviceType.isTouch() ? [run(tap(), onClick)] : [ run(click(), onClick), run(mousedown(), onMousedown) ]; return derive(flatten([ optAction.map(executeHandler).toArray(), pointerEvents ])); }; var focus$2 = function (component, focusConfig) { if (!focusConfig.ignore()) { focus$1(component.element()); focusConfig.onFocus()(component); } }; var blur$1 = function (component, focusConfig) { if (!focusConfig.ignore()) { blur(component.element()); } }; var isFocused = function (component) { return hasFocus(component.element()); }; var FocusApis = /*#__PURE__*/Object.freeze({ focus: focus$2, blur: blur$1, isFocused: isFocused }); var exhibit$1 = function (base, focusConfig) { if (focusConfig.ignore()) { return nu$6({}); } else { return nu$6({ attributes: { tabindex: '-1' } }); } }; var events$3 = function (focusConfig) { return derive([run(focus(), function (component, simulatedEvent) { focus$2(component, focusConfig); simulatedEvent.stop(); })]); }; var ActiveFocus = /*#__PURE__*/Object.freeze({ exhibit: exhibit$1, events: events$3 }); var FocusSchema = [ onHandler('onFocus'), defaulted$1('ignore', false) ]; var Focusing = create$1({ fields: FocusSchema, name: 'focusing', active: ActiveFocus, apis: FocusApis }); var isSupported = function (dom) { return dom.style !== undefined; }; var internalSet = function (dom, property, value) { if (!isString(value)) { domGlobals.console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom); throw new Error('CSS value must be a string: ' + value); } if (isSupported(dom)) { dom.style.setProperty(property, value); } }; var internalRemove = function (dom, property) { if (isSupported(dom)) { dom.style.removeProperty(property); } }; var set$2 = function (element, property, value) { var dom = element.dom(); internalSet(dom, property, value); }; var setAll$1 = function (element, css) { var dom = element.dom(); each(css, function (v, k) { internalSet(dom, k, v); }); }; var get$3 = function (element, property) { var dom = element.dom(); var styles = domGlobals.window.getComputedStyle(dom); var r = styles.getPropertyValue(property); var v = r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r; return v === null ? undefined : v; }; var getUnsafeProperty = function (dom, property) { return isSupported(dom) ? dom.style.getPropertyValue(property) : ''; }; var getRaw = function (element, property) { var dom = element.dom(); var raw = getUnsafeProperty(dom, property); return Option.from(raw).filter(function (r) { return r.length > 0; }); }; var remove$5 = function (element, property) { var dom = element.dom(); internalRemove(dom, property); if (has(element, 'style') && trim(get(element, 'style')) === '') { remove$1(element, 'style'); } }; var reflow = function (e) { return e.dom().offsetWidth; }; function Dimension (name, getOffset) { var set = function (element, h) { if (!isNumber(h) && !h.match(/^[0-9]+$/)) { throw new Error(name + '.set accepts only positive integer values. Value was ' + h); } var dom = element.dom(); if (isSupported(dom)) { dom.style[name] = h + 'px'; } }; var get = function (element) { var r = getOffset(element); if (r <= 0 || r === null) { var css = get$3(element, name); return parseFloat(css) || 0; } return r; }; var getOuter = get; var aggregate = function (element, properties) { return foldl(properties, function (acc, property) { var val = get$3(element, property); var value = val === undefined ? 0 : parseInt(val, 10); return isNaN(value) ? acc : acc + value; }, 0); }; var max = function (element, value, properties) { var cumulativeInclusions = aggregate(element, properties); var absoluteMax = value > cumulativeInclusions ? value - cumulativeInclusions : 0; return absoluteMax; }; return { set: set, get: get, getOuter: getOuter, aggregate: aggregate, max: max }; } var api = Dimension('height', function (element) { var dom = element.dom(); return inBody(element) ? dom.getBoundingClientRect().height : dom.offsetHeight; }); var get$4 = function (element) { return api.get(element); }; var ancestors = function (scope, predicate, isRoot) { return filter(parents(scope, isRoot), predicate); }; var siblings$1 = function (scope, predicate) { return filter(siblings(scope), predicate); }; var all$2 = function (selector) { return all(selector); }; var ancestors$1 = function (scope, selector, isRoot) { return ancestors(scope, function (e) { return is(e, selector); }, isRoot); }; var siblings$2 = function (scope, selector) { return siblings$1(scope, function (e) { return is(e, selector); }); }; var descendants = function (scope, selector) { return all(selector, scope); }; var first = function (selector) { return one(selector); }; var ancestor$1 = function (scope, selector, isRoot) { return ancestor(scope, function (e) { return is(e, selector); }, isRoot); }; var descendant$1 = function (scope, selector) { return one(selector, scope); }; var closest$1 = function (scope, selector, isRoot) { return ClosestOrAncestor(is, ancestor$1, scope, selector, isRoot); }; var BACKSPACE = function () { return [8]; }; var TAB = function () { return [9]; }; var ENTER = function () { return [13]; }; var ESCAPE = function () { return [27]; }; var SPACE = function () { return [32]; }; var LEFT = function () { return [37]; }; var UP = function () { return [38]; }; var RIGHT = function () { return [39]; }; var DOWN = function () { return [40]; }; var cyclePrev = function (values, index, predicate) { var before = reverse(values.slice(0, index)); var after = reverse(values.slice(index + 1)); return find$1(before.concat(after), predicate); }; var tryPrev = function (values, index, predicate) { var before = reverse(values.slice(0, index)); return find$1(before, predicate); }; var cycleNext = function (values, index, predicate) { var before = values.slice(0, index); var after = values.slice(index + 1); return find$1(after.concat(before), predicate); }; var tryNext = function (values, index, predicate) { var after = values.slice(index + 1); return find$1(after, predicate); }; var inSet = function (keys) { return function (event) { var raw = event.raw(); return contains(keys, raw.which); }; }; var and = function (preds) { return function (event) { return forall(preds, function (pred) { return pred(event); }); }; }; var isShift = function (event) { var raw = event.raw(); return raw.shiftKey === true; }; var isControl = function (event) { var raw = event.raw(); return raw.ctrlKey === true; }; var isNotShift = not(isShift); var rule = function (matches, action) { return { matches: matches, classification: action }; }; var choose$2 = function (transitions, event) { var transition = find$1(transitions, function (t) { return t.matches(event); }); return transition.map(function (t) { return t.classification; }); }; var cycleBy = function (value, delta, min, max) { var r = value + delta; if (r > max) { return min; } else { return r < min ? max : r; } }; var cap = function (value, min, max) { if (value <= min) { return min; } else { return value >= max ? max : value; } }; var dehighlightAll = function (component, hConfig, hState) { var highlighted = descendants(component.element(), '.' + hConfig.highlightClass()); each$1(highlighted, function (h) { remove$4(h, hConfig.highlightClass()); component.getSystem().getByDom(h).each(function (target) { hConfig.onDehighlight()(component, target); }); }); }; var dehighlight = function (component, hConfig, hState, target) { var wasHighlighted = isHighlighted(component, hConfig, hState, target); remove$4(target.element(), hConfig.highlightClass()); if (wasHighlighted) { hConfig.onDehighlight()(component, target); } }; var highlight = function (component, hConfig, hState, target) { var wasHighlighted = isHighlighted(component, hConfig, hState, target); dehighlightAll(component, hConfig, hState); add$2(target.element(), hConfig.highlightClass()); if (!wasHighlighted) { hConfig.onHighlight()(component, target); } }; var highlightFirst = function (component, hConfig, hState) { getFirst(component, hConfig, hState).each(function (firstComp) { highlight(component, hConfig, hState, firstComp); }); }; var highlightLast = function (component, hConfig, hState) { getLast(component, hConfig, hState).each(function (lastComp) { highlight(component, hConfig, hState, lastComp); }); }; var highlightAt = function (component, hConfig, hState, index) { getByIndex(component, hConfig, hState, index).fold(function (err) { throw new Error(err); }, function (firstComp) { highlight(component, hConfig, hState, firstComp); }); }; var highlightBy = function (component, hConfig, hState, predicate) { var items = descendants(component.element(), '.' + hConfig.itemClass()); var itemComps = cat(map$1(items, function (i) { return component.getSystem().getByDom(i).toOption(); })); var targetComp = find$1(itemComps, predicate); targetComp.each(function (c) { highlight(component, hConfig, hState, c); }); }; var isHighlighted = function (component, hConfig, hState, queryTarget) { return has$1(queryTarget.element(), hConfig.highlightClass()); }; var getHighlighted = function (component, hConfig, hState) { return descendant$1(component.element(), '.' + hConfig.highlightClass()).bind(function (e) { return component.getSystem().getByDom(e).toOption(); }); }; var getByIndex = function (component, hConfig, hState, index) { var items = descendants(component.element(), '.' + hConfig.itemClass()); return Option.from(items[index]).fold(function () { return Result.error('No element found with index ' + index); }, component.getSystem().getByDom); }; var getFirst = function (component, hConfig, hState) { return descendant$1(component.element(), '.' + hConfig.itemClass()).bind(function (e) { return component.getSystem().getByDom(e).toOption(); }); }; var getLast = function (component, hConfig, hState) { var items = descendants(component.element(), '.' + hConfig.itemClass()); var last = items.length > 0 ? Option.some(items[items.length - 1]) : Option.none(); return last.bind(function (c) { return component.getSystem().getByDom(c).toOption(); }); }; var getDelta = function (component, hConfig, hState, delta) { var items = descendants(component.element(), '.' + hConfig.itemClass()); var current = findIndex(items, function (item) { return has$1(item, hConfig.highlightClass()); }); return current.bind(function (selected) { var dest = cycleBy(selected, delta, 0, items.length - 1); return component.getSystem().getByDom(items[dest]).toOption(); }); }; var getPrevious = function (component, hConfig, hState) { return getDelta(component, hConfig, hState, -1); }; var getNext = function (component, hConfig, hState) { return getDelta(component, hConfig, hState, +1); }; var HighlightApis = /*#__PURE__*/Object.freeze({ dehighlightAll: dehighlightAll, dehighlight: dehighlight, highlight: highlight, highlightFirst: highlightFirst, highlightLast: highlightLast, highlightAt: highlightAt, highlightBy: highlightBy, isHighlighted: isHighlighted, getHighlighted: getHighlighted, getFirst: getFirst, getLast: getLast, getPrevious: getPrevious, getNext: getNext }); var HighlightSchema = [ strict$1('highlightClass'), strict$1('itemClass'), onHandler('onHighlight'), onHandler('onDehighlight') ]; var Highlighting = create$1({ fields: HighlightSchema, name: 'highlighting', apis: HighlightApis }); var dom = function () { var get = function (component) { return search(component.element()); }; var set = function (component, focusee) { component.getSystem().triggerFocus(focusee, component.element()); }; return { get: get, set: set }; }; var highlights = function () { var get = function (component) { return Highlighting.getHighlighted(component).map(function (item) { return item.element(); }); }; var set = function (component, element) { component.getSystem().getByDom(element).fold(noop, function (item) { Highlighting.highlight(component, item); }); }; return { get: get, set: set }; }; var typical = function (infoSchema, stateInit, getRules, getEvents, getApis, optFocusIn) { var schema = function () { return infoSchema.concat([ defaulted$1('focusManager', dom()), output('handler', me), output('state', stateInit) ]); }; var processKey = function (component, simulatedEvent, keyingConfig, keyingState) { var rules = getRules(component, simulatedEvent, keyingConfig, keyingState); return choose$2(rules, simulatedEvent.event()).bind(function (rule) { return rule(component, simulatedEvent, keyingConfig, keyingState); }); }; var toEvents = function (keyingConfig, keyingState) { var otherEvents = getEvents(keyingConfig, keyingState); var keyEvents = derive(optFocusIn.map(function (focusIn) { return run(focus(), function (component, simulatedEvent) { focusIn(component, keyingConfig, keyingState, simulatedEvent); simulatedEvent.stop(); }); }).toArray().concat([run(keydown(), function (component, simulatedEvent) { processKey(component, simulatedEvent, keyingConfig, keyingState).each(function (_) { simulatedEvent.stop(); }); })])); return deepMerge(otherEvents, keyEvents); }; var me = { schema: schema, processKey: processKey, toEvents: toEvents, toApis: getApis }; return me; }; var create$2 = function (cyclicField) { var schema = [ option('onEscape'), option('onEnter'), defaulted$1('selector', '[data-alloy-tabstop="true"]'), defaulted$1('firstTabstop', 0), defaulted$1('useTabstopAt', constant(true)), option('visibilitySelector') ].concat([cyclicField]); var isVisible = function (tabbingConfig, element) { var target = tabbingConfig.visibilitySelector().bind(function (sel) { return closest$1(element, sel); }).getOr(element); return get$4(target) > 0; }; var findInitial = function (component, tabbingConfig) { var tabstops = descendants(component.element(), tabbingConfig.selector()); var visibles = filter(tabstops, function (elem) { return isVisible(tabbingConfig, elem); }); return Option.from(visibles[tabbingConfig.firstTabstop()]); }; var findCurrent = function (component, tabbingConfig) { return tabbingConfig.focusManager().get(component).bind(function (elem) { return closest$1(elem, tabbingConfig.selector()); }); }; var isTabstop = function (tabbingConfig, element) { return isVisible(tabbingConfig, element) && tabbingConfig.useTabstopAt()(element); }; var focusIn = function (component, tabbingConfig) { findInitial(component, tabbingConfig).each(function (target) { tabbingConfig.focusManager().set(component, target); }); }; var goFromTabstop = function (component, tabstops, stopIndex, tabbingConfig, cycle) { return cycle(tabstops, stopIndex, function (elem) { return isTabstop(tabbingConfig, elem); }).fold(function () { return tabbingConfig.cyclic() ? Option.some(true) : Option.none(); }, function (target) { tabbingConfig.focusManager().set(component, target); return Option.some(true); }); }; var go = function (component, simulatedEvent, tabbingConfig, cycle) { var tabstops = descendants(component.element(), tabbingConfig.selector()); return findCurrent(component, tabbingConfig).bind(function (tabstop) { var optStopIndex = findIndex(tabstops, curry(eq, tabstop)); return optStopIndex.bind(function (stopIndex) { return goFromTabstop(component, tabstops, stopIndex, tabbingConfig, cycle); }); }); }; var goBackwards = function (component, simulatedEvent, tabbingConfig, tabbingState) { var navigate = tabbingConfig.cyclic() ? cyclePrev : tryPrev; return go(component, simulatedEvent, tabbingConfig, navigate); }; var goForwards = function (component, simulatedEvent, tabbingConfig, tabbingState) { var navigate = tabbingConfig.cyclic() ? cycleNext : tryNext; return go(component, simulatedEvent, tabbingConfig, navigate); }; var execute = function (component, simulatedEvent, tabbingConfig, tabbingState) { return tabbingConfig.onEnter().bind(function (f) { return f(component, simulatedEvent); }); }; var exit = function (component, simulatedEvent, tabbingConfig, tabbingState) { return tabbingConfig.onEscape().bind(function (f) { return f(component, simulatedEvent); }); }; var getRules = constant([ rule(and([ isShift, inSet(TAB()) ]), goBackwards), rule(inSet(TAB()), goForwards), rule(inSet(ESCAPE()), exit), rule(and([ isNotShift, inSet(ENTER()) ]), execute) ]); var getEvents = constant({}); var getApis = constant({}); return typical(schema, NoState.init, getRules, getEvents, getApis, Option.some(focusIn)); }; var AcyclicType = create$2(state$1('cyclic', constant(false))); var CyclicType = create$2(state$1('cyclic', constant(true))); var inside = function (target) { return name(target) === 'input' && get(target, 'type') !== 'radio' || name(target) === 'textarea'; }; var doDefaultExecute = function (component, simulatedEvent, focused) { dispatch(component, focused, execute()); return Option.some(true); }; var defaultExecute = function (component, simulatedEvent, focused) { return inside(focused) && inSet(SPACE())(simulatedEvent.event()) ? Option.none() : doDefaultExecute(component, simulatedEvent, focused); }; var schema$1 = [ defaulted$1('execute', defaultExecute), defaulted$1('useSpace', false), defaulted$1('useEnter', true), defaulted$1('useControlEnter', false), defaulted$1('useDown', false) ]; var execute$1 = function (component, simulatedEvent, executeConfig) { return executeConfig.execute()(component, simulatedEvent, component.element()); }; var getRules = function (component, simulatedEvent, executeConfig, executeState) { var spaceExec = executeConfig.useSpace() && !inside(component.element()) ? SPACE() : []; var enterExec = executeConfig.useEnter() ? ENTER() : []; var downExec = executeConfig.useDown() ? DOWN() : []; var execKeys = spaceExec.concat(enterExec).concat(downExec); return [rule(inSet(execKeys), execute$1)].concat(executeConfig.useControlEnter() ? [rule(and([ isControl, inSet(ENTER()) ]), execute$1)] : []); }; var getEvents = constant({}); var getApis = constant({}); var ExecutionType = typical(schema$1, NoState.init, getRules, getEvents, getApis, Option.none()); var flatgrid = function (spec) { var dimensions = Cell(Option.none()); var setGridSize = function (numRows, numColumns) { dimensions.set(Option.some({ numRows: constant(numRows), numColumns: constant(numColumns) })); }; var getNumRows = function () { return dimensions.get().map(function (d) { return d.numRows(); }); }; var getNumColumns = function () { return dimensions.get().map(function (d) { return d.numColumns(); }); }; return nu$7({ readState: constant({}), setGridSize: setGridSize, getNumRows: getNumRows, getNumColumns: getNumColumns }); }; var init = function (spec) { return spec.state()(spec); }; var KeyingState = /*#__PURE__*/Object.freeze({ flatgrid: flatgrid, init: init }); var onDirection = function (isLtr, isRtl) { return function (element) { return getDirection(element) === 'rtl' ? isRtl : isLtr; }; }; var getDirection = function (element) { return get$3(element, 'direction') === 'rtl' ? 'rtl' : 'ltr'; }; var useH = function (movement) { return function (component, simulatedEvent, config, state) { var move = movement(component.element()); return use(move, component, simulatedEvent, config, state); }; }; var west = function (moveLeft, moveRight) { var movement = onDirection(moveLeft, moveRight); return useH(movement); }; var east = function (moveLeft, moveRight) { var movement = onDirection(moveRight, moveLeft); return useH(movement); }; var useV = function (move) { return function (component, simulatedEvent, config, state) { return use(move, component, simulatedEvent, config, state); }; }; var use = function (move, component, simulatedEvent, config, state) { var outcome = config.focusManager().get(component).bind(function (focused) { return move(component.element(), focused, config, state); }); return outcome.map(function (newFocus) { config.focusManager().set(component, newFocus); return true; }); }; var north = useV; var south = useV; var move = useV; var isHidden = function (dom) { return dom.offsetWidth <= 0 && dom.offsetHeight <= 0; }; var isVisible = function (element) { var dom = element.dom(); return !isHidden(dom); }; var indexInfo = MixedBag([ 'index', 'candidates' ], []); var locate = function (candidates, predicate) { return findIndex(candidates, predicate).map(function (index) { return indexInfo({ index: index, candidates: candidates }); }); }; var locateVisible = function (container, current, selector) { var filter = isVisible; return locateIn(container, current, selector, filter); }; var locateIn = function (container, current, selector, filter$1) { var predicate = curry(eq, current); var candidates = descendants(container, selector); var visible = filter(candidates, isVisible); return locate(visible, predicate); }; var findIndex$1 = function (elements, target) { return findIndex(elements, function (elem) { return eq(target, elem); }); }; var withGrid = function (values, index, numCols, f) { var oldRow = Math.floor(index / numCols); var oldColumn = index % numCols; return f(oldRow, oldColumn).bind(function (address) { var newIndex = address.row() * numCols + address.column(); return newIndex >= 0 && newIndex < values.length ? Option.some(values[newIndex]) : Option.none(); }); }; var cycleHorizontal = function (values, index, numRows, numCols, delta) { return withGrid(values, index, numCols, function (oldRow, oldColumn) { var onLastRow = oldRow === numRows - 1; var colsInRow = onLastRow ? values.length - oldRow * numCols : numCols; var newColumn = cycleBy(oldColumn, delta, 0, colsInRow - 1); return Option.some({ row: constant(oldRow), column: constant(newColumn) }); }); }; var cycleVertical = function (values, index, numRows, numCols, delta) { return withGrid(values, index, numCols, function (oldRow, oldColumn) { var newRow = cycleBy(oldRow, delta, 0, numRows - 1); var onLastRow = newRow === numRows - 1; var colsInRow = onLastRow ? values.length - newRow * numCols : numCols; var newCol = cap(oldColumn, 0, colsInRow - 1); return Option.some({ row: constant(newRow), column: constant(newCol) }); }); }; var cycleRight = function (values, index, numRows, numCols) { return cycleHorizontal(values, index, numRows, numCols, +1); }; var cycleLeft = function (values, index, numRows, numCols) { return cycleHorizontal(values, index, numRows, numCols, -1); }; var cycleUp = function (values, index, numRows, numCols) { return cycleVertical(values, index, numRows, numCols, -1); }; var cycleDown = function (values, index, numRows, numCols) { return cycleVertical(values, index, numRows, numCols, +1); }; var schema$2 = [ strict$1('selector'), defaulted$1('execute', defaultExecute), onKeyboardHandler('onEscape'), defaulted$1('captureTab', false), initSize() ]; var focusIn = function (component, gridConfig, gridState) { descendant$1(component.element(), gridConfig.selector()).each(function (first) { gridConfig.focusManager().set(component, first); }); }; var findCurrent = function (component, gridConfig) { return gridConfig.focusManager().get(component).bind(function (elem) { return closest$1(elem, gridConfig.selector()); }); }; var execute$2 = function (component, simulatedEvent, gridConfig, gridState) { return findCurrent(component, gridConfig).bind(function (focused) { return gridConfig.execute()(component, simulatedEvent, focused); }); }; var doMove = function (cycle) { return function (element, focused, gridConfig, gridState) { return locateVisible(element, focused, gridConfig.selector()).bind(function (identified) { return cycle(identified.candidates(), identified.index(), gridState.getNumRows().getOr(gridConfig.initSize().numRows()), gridState.getNumColumns().getOr(gridConfig.initSize().numColumns())); }); }; }; var handleTab = function (component, simulatedEvent, gridConfig, gridState) { return gridConfig.captureTab() ? Option.some(true) : Option.none(); }; var doEscape = function (component, simulatedEvent, gridConfig, gridState) { return gridConfig.onEscape()(component, simulatedEvent); }; var moveLeft = doMove(cycleLeft); var moveRight = doMove(cycleRight); var moveNorth = doMove(cycleUp); var moveSouth = doMove(cycleDown); var getRules$1 = constant([ rule(inSet(LEFT()), west(moveLeft, moveRight)), rule(inSet(RIGHT()), east(moveLeft, moveRight)), rule(inSet(UP()), north(moveNorth)), rule(inSet(DOWN()), south(moveSouth)), rule(and([ isShift, inSet(TAB()) ]), handleTab), rule(and([ isNotShift, inSet(TAB()) ]), handleTab), rule(inSet(ESCAPE()), doEscape), rule(inSet(SPACE().concat(ENTER())), execute$2) ]); var getEvents$1 = constant({}); var getApis$1 = {}; var FlatgridType = typical(schema$2, flatgrid, getRules$1, getEvents$1, getApis$1, Option.some(focusIn)); var horizontal = function (container, selector, current, delta) { return locateVisible(container, current, selector).bind(function (identified) { var index = identified.index(); var candidates = identified.candidates(); var newIndex = cycleBy(index, delta, 0, candidates.length - 1); return Option.from(candidates[newIndex]); }); }; var schema$3 = [ strict$1('selector'), defaulted$1('getInitial', Option.none), defaulted$1('execute', defaultExecute), defaulted$1('executeOnMove', false), defaulted$1('allowVertical', true) ]; var findCurrent$1 = function (component, flowConfig) { return flowConfig.focusManager().get(component).bind(function (elem) { return closest$1(elem, flowConfig.selector()); }); }; var execute$3 = function (component, simulatedEvent, flowConfig) { return findCurrent$1(component, flowConfig).bind(function (focused) { return flowConfig.execute()(component, simulatedEvent, focused); }); }; var focusIn$1 = function (component, flowConfig) { flowConfig.getInitial()(component).or(descendant$1(component.element(), flowConfig.selector())).each(function (first) { flowConfig.focusManager().set(component, first); }); }; var moveLeft$1 = function (element, focused, info) { return horizontal(element, info.selector(), focused, -1); }; var moveRight$1 = function (element, focused, info) { return horizontal(element, info.selector(), focused, +1); }; var doMove$1 = function (movement) { return function (component, simulatedEvent, flowConfig) { return movement(component, simulatedEvent, flowConfig).bind(function () { return flowConfig.executeOnMove() ? execute$3(component, simulatedEvent, flowConfig) : Option.some(true); }); }; }; var getRules$2 = function (_component, _se, flowConfig, _flowState) { var westMovers = LEFT().concat(flowConfig.allowVertical() ? UP() : []); var eastMovers = RIGHT().concat(flowConfig.allowVertical() ? DOWN() : []); return [ rule(inSet(westMovers), doMove$1(west(moveLeft$1, moveRight$1))), rule(inSet(eastMovers), doMove$1(east(moveLeft$1, moveRight$1))), rule(inSet(ENTER()), execute$3), rule(inSet(SPACE()), execute$3) ]; }; var getEvents$2 = constant({}); var getApis$2 = constant({}); var FlowType = typical(schema$3, NoState.init, getRules$2, getEvents$2, getApis$2, Option.some(focusIn$1)); var outcome = MixedBag([ 'rowIndex', 'columnIndex', 'cell' ], []); var toCell = function (matrix, rowIndex, columnIndex) { return Option.from(matrix[rowIndex]).bind(function (row) { return Option.from(row[columnIndex]).map(function (cell) { return outcome({ rowIndex: rowIndex, columnIndex: columnIndex, cell: cell }); }); }); }; var cycleHorizontal$1 = function (matrix, rowIndex, startCol, deltaCol) { var row = matrix[rowIndex]; var colsInRow = row.length; var newColIndex = cycleBy(startCol, deltaCol, 0, colsInRow - 1); return toCell(matrix, rowIndex, newColIndex); }; var cycleVertical$1 = function (matrix, colIndex, startRow, deltaRow) { var nextRowIndex = cycleBy(startRow, deltaRow, 0, matrix.length - 1); var colsInNextRow = matrix[nextRowIndex].length; var nextColIndex = cap(colIndex, 0, colsInNextRow - 1); return toCell(matrix, nextRowIndex, nextColIndex); }; var moveHorizontal = function (matrix, rowIndex, startCol, deltaCol) { var row = matrix[rowIndex]; var colsInRow = row.length; var newColIndex = cap(startCol + deltaCol, 0, colsInRow - 1); return toCell(matrix, rowIndex, newColIndex); }; var moveVertical = function (matrix, colIndex, startRow, deltaRow) { var nextRowIndex = cap(startRow + deltaRow, 0, matrix.length - 1); var colsInNextRow = matrix[nextRowIndex].length; var nextColIndex = cap(colIndex, 0, colsInNextRow - 1); return toCell(matrix, nextRowIndex, nextColIndex); }; var cycleRight$1 = function (matrix, startRow, startCol) { return cycleHorizontal$1(matrix, startRow, startCol, +1); }; var cycleLeft$1 = function (matrix, startRow, startCol) { return cycleHorizontal$1(matrix, startRow, startCol, -1); }; var cycleUp$1 = function (matrix, startRow, startCol) { return cycleVertical$1(matrix, startCol, startRow, -1); }; var cycleDown$1 = function (matrix, startRow, startCol) { return cycleVertical$1(matrix, startCol, startRow, +1); }; var moveLeft$2 = function (matrix, startRow, startCol) { return moveHorizontal(matrix, startRow, startCol, -1); }; var moveRight$2 = function (matrix, startRow, startCol) { return moveHorizontal(matrix, startRow, startCol, +1); }; var moveUp = function (matrix, startRow, startCol) { return moveVertical(matrix, startCol, startRow, -1); }; var moveDown = function (matrix, startRow, startCol) { return moveVertical(matrix, startCol, startRow, +1); }; var schema$4 = [ strictObjOf('selectors', [ strict$1('row'), strict$1('cell') ]), defaulted$1('cycles', true), defaulted$1('previousSelector', Option.none), defaulted$1('execute', defaultExecute) ]; var focusIn$2 = function (component, matrixConfig) { var focused = matrixConfig.previousSelector()(component).orThunk(function () { var selectors = matrixConfig.selectors(); return descendant$1(component.element(), selectors.cell()); }); focused.each(function (cell) { matrixConfig.focusManager().set(component, cell); }); }; var execute$4 = function (component, simulatedEvent, matrixConfig) { return search(component.element()).bind(function (focused) { return matrixConfig.execute()(component, simulatedEvent, focused); }); }; var toMatrix = function (rows, matrixConfig) { return map$1(rows, function (row) { return descendants(row, matrixConfig.selectors().cell()); }); }; var doMove$2 = function (ifCycle, ifMove) { return function (element, focused, matrixConfig) { var move = matrixConfig.cycles() ? ifCycle : ifMove; return closest$1(focused, matrixConfig.selectors().row()).bind(function (inRow) { var cellsInRow = descendants(inRow, matrixConfig.selectors().cell()); return findIndex$1(cellsInRow, focused).bind(function (colIndex) { var allRows = descendants(element, matrixConfig.selectors().row()); return findIndex$1(allRows, inRow).bind(function (rowIndex) { var matrix = toMatrix(allRows, matrixConfig); return move(matrix, rowIndex, colIndex).map(function (next) { return next.cell(); }); }); }); }); }; }; var moveLeft$3 = doMove$2(cycleLeft$1, moveLeft$2); var moveRight$3 = doMove$2(cycleRight$1, moveRight$2); var moveNorth$1 = doMove$2(cycleUp$1, moveUp); var moveSouth$1 = doMove$2(cycleDown$1, moveDown); var getRules$3 = constant([ rule(inSet(LEFT()), west(moveLeft$3, moveRight$3)), rule(inSet(RIGHT()), east(moveLeft$3, moveRight$3)), rule(inSet(UP()), north(moveNorth$1)), rule(inSet(DOWN()), south(moveSouth$1)), rule(inSet(SPACE().concat(ENTER())), execute$4) ]); var getEvents$3 = constant({}); var getApis$3 = constant({}); var MatrixType = typical(schema$4, NoState.init, getRules$3, getEvents$3, getApis$3, Option.some(focusIn$2)); var schema$5 = [ strict$1('selector'), defaulted$1('execute', defaultExecute), defaulted$1('moveOnTab', false) ]; var execute$5 = function (component, simulatedEvent, menuConfig) { return menuConfig.focusManager().get(component).bind(function (focused) { return menuConfig.execute()(component, simulatedEvent, focused); }); }; var focusIn$3 = function (component, menuConfig) { descendant$1(component.element(), menuConfig.selector()).each(function (first) { menuConfig.focusManager().set(component, first); }); }; var moveUp$1 = function (element, focused, info) { return horizontal(element, info.selector(), focused, -1); }; var moveDown$1 = function (element, focused, info) { return horizontal(element, info.selector(), focused, +1); }; var fireShiftTab = function (component, simulatedEvent, menuConfig) { return menuConfig.moveOnTab() ? move(moveUp$1)(component, simulatedEvent, menuConfig) : Option.none(); }; var fireTab = function (component, simulatedEvent, menuConfig) { return menuConfig.moveOnTab() ? move(moveDown$1)(component, simulatedEvent, menuConfig) : Option.none(); }; var getRules$4 = constant([ rule(inSet(UP()), move(moveUp$1)), rule(inSet(DOWN()), move(moveDown$1)), rule(and([ isShift, inSet(TAB()) ]), fireShiftTab), rule(and([ isNotShift, inSet(TAB()) ]), fireTab), rule(inSet(ENTER()), execute$5), rule(inSet(SPACE()), execute$5) ]); var getEvents$4 = constant({}); var getApis$4 = constant({}); var MenuType = typical(schema$5, NoState.init, getRules$4, getEvents$4, getApis$4, Option.some(focusIn$3)); var schema$6 = [ onKeyboardHandler('onSpace'), onKeyboardHandler('onEnter'), onKeyboardHandler('onShiftEnter'), onKeyboardHandler('onLeft'), onKeyboardHandler('onRight'), onKeyboardHandler('onTab'), onKeyboardHandler('onShiftTab'), onKeyboardHandler('onUp'), onKeyboardHandler('onDown'), onKeyboardHandler('onEscape'), option('focusIn') ]; var getRules$5 = function (component, simulatedEvent, specialInfo) { return [ rule(inSet(SPACE()), specialInfo.onSpace()), rule(and([ isNotShift, inSet(ENTER()) ]), specialInfo.onEnter()), rule(and([ isShift, inSet(ENTER()) ]), specialInfo.onShiftEnter()), rule(and([ isShift, inSet(TAB()) ]), specialInfo.onShiftTab()), rule(and([ isNotShift, inSet(TAB()) ]), specialInfo.onTab()), rule(inSet(UP()), specialInfo.onUp()), rule(inSet(DOWN()), specialInfo.onDown()), rule(inSet(LEFT()), specialInfo.onLeft()), rule(inSet(RIGHT()), specialInfo.onRight()), rule(inSet(SPACE()), specialInfo.onSpace()), rule(inSet(ESCAPE()), specialInfo.onEscape()) ]; }; var focusIn$4 = function (component, specialInfo) { return specialInfo.focusIn().bind(function (f) { return f(component, specialInfo); }); }; var getEvents$5 = function () { return {}; }; var getApis$5 = function () { return {}; }; var SpecialType = typical(schema$6, NoState.init, getRules$5, getEvents$5, getApis$5, Option.some(focusIn$4)); var acyclic = AcyclicType.schema(); var cyclic = CyclicType.schema(); var flow = FlowType.schema(); var flatgrid$1 = FlatgridType.schema(); var matrix = MatrixType.schema(); var execution = ExecutionType.schema(); var menu = MenuType.schema(); var special = SpecialType.schema(); var KeyboardBranches = /*#__PURE__*/Object.freeze({ acyclic: acyclic, cyclic: cyclic, flow: flow, flatgrid: flatgrid$1, matrix: matrix, execution: execution, menu: menu, special: special }); var Keying = createModes$1({ branchKey: 'mode', branches: KeyboardBranches, name: 'keying', active: { events: function (keyingConfig, keyingState) { var handler = keyingConfig.handler(); return handler.toEvents(keyingConfig, keyingState); } }, apis: { focusIn: function (component) { component.getSystem().triggerFocus(component.element(), component.element()); }, setGridSize: function (component, keyConfig, keyState, numRows, numColumns) { if (!hasKey$1(keyState, 'setGridSize')) { domGlobals.console.error('Layout does not support setGridSize'); } else { keyState.setGridSize(numRows, numColumns); } } }, state: KeyingState }); var field$1 = function (name, forbidden) { return defaultedObjOf(name, {}, map$1(forbidden, function (f) { return forbid(f.name(), 'Cannot configure ' + f.name() + ' for ' + name); }).concat([state$1('dump', identity)])); }; var get$5 = function (data) { return data.dump(); }; var _placeholder = 'placeholder'; var adt$2 = Adt.generate([ { single: [ 'required', 'valueThunk' ] }, { multiple: [ 'required', 'valueThunks' ] } ]); var subPlaceholder = function (owner, detail, compSpec, placeholders) { if (owner.exists(function (o) { return o !== compSpec.owner; })) { return adt$2.single(true, constant(compSpec)); } return readOptFrom$1(placeholders, compSpec.name).fold(function () { throw new Error('Unknown placeholder component: ' + compSpec.name + '\nKnown: [' + keys(placeholders) + ']\nNamespace: ' + owner.getOr('none') + '\nSpec: ' + Json.stringify(compSpec, null, 2)); }, function (newSpec) { return newSpec.replace(); }); }; var scan = function (owner, detail, compSpec, placeholders) { if (compSpec.uiType === _placeholder) { return subPlaceholder(owner, detail, compSpec, placeholders); } else { return adt$2.single(false, constant(compSpec)); } }; var substitute = function (owner, detail, compSpec, placeholders) { var base = scan(owner, detail, compSpec, placeholders); return base.fold(function (req, valueThunk) { var value = valueThunk(detail, compSpec.config, compSpec.validated); var childSpecs = readOptFrom$1(value, 'components').getOr([]); var substituted = bind(childSpecs, function (c) { return substitute(owner, detail, c, placeholders); }); return [deepMerge(value, { components: substituted })]; }, function (req, valuesThunk) { var values = valuesThunk(detail, compSpec.config, compSpec.validated); return values; }); }; var substituteAll = function (owner, detail, components, placeholders) { return bind(components, function (c) { return substitute(owner, detail, c, placeholders); }); }; var oneReplace = function (label, replacements) { var called = false; var used = function () { return called; }; var replace = function () { if (called === true) { throw new Error('Trying to use the same placeholder more than once: ' + label); } called = true; return replacements; }; var required = function () { return replacements.fold(function (req, _) { return req; }, function (req, _) { return req; }); }; return { name: constant(label), required: required, used: used, replace: replace }; }; var substitutePlaces = function (owner, detail, components, placeholders) { var ps = map(placeholders, function (ph, name) { return oneReplace(name, ph); }); var outcome = substituteAll(owner, detail, components, ps); each(ps, function (p) { if (p.used() === false && p.required()) { throw new Error('Placeholder: ' + p.name() + ' was not found in components list\nNamespace: ' + owner.getOr('none') + '\nComponents: ' + Json.stringify(detail.components(), null, 2)); } }); return outcome; }; var single = adt$2.single; var multiple = adt$2.multiple; var placeholder = constant(_placeholder); var unique = 0; var generate$1 = function (prefix) { var date = new Date(); var time = date.getTime(); var random = Math.floor(Math.random() * 1000000000); unique++; return prefix + '_' + random + unique + String(time); }; var adt$3 = Adt.generate([ { required: ['data'] }, { external: ['data'] }, { optional: ['data'] }, { group: ['data'] } ]); var fFactory = defaulted$1('factory', { sketch: identity }); var fSchema = defaulted$1('schema', []); var fName = strict$1('name'); var fPname = field('pname', 'pname', defaultedThunk(function (typeSpec) { return '<alloy.' + generate$1(typeSpec.name) + '>'; }), anyValue$1()); var fDefaults = defaulted$1('defaults', constant({})); var fOverrides = defaulted$1('overrides', constant({})); var requiredSpec = objOf([ fFactory, fSchema, fName, fPname, fDefaults, fOverrides ]); var optionalSpec = objOf([ fFactory, fSchema, fName, fPname, fDefaults, fOverrides ]); var groupSpec = objOf([ fFactory, fSchema, fName, strict$1('unit'), fPname, fDefaults, fOverrides ]); var asNamedPart = function (part) { return part.fold(Option.some, Option.none, Option.some, Option.some); }; var name$1 = function (part) { var get = function (data) { return data.name(); }; return part.fold(get, get, get, get); }; var convert = function (adtConstructor, partSchema) { return function (spec) { var data = asStructOrDie('Converting part type', partSchema, spec); return adtConstructor(data); }; }; var required = convert(adt$3.required, requiredSpec); var optional = convert(adt$3.optional, optionalSpec); var group = convert(adt$3.group, groupSpec); var original = constant('entirety'); var combine = function (detail, data, partSpec, partValidated) { var spec = partSpec; return deepMerge(data.defaults()(detail, partSpec, partValidated), partSpec, { uid: detail.partUids()[data.name()] }, data.overrides()(detail, partSpec, partValidated), { 'debug.sketcher': wrap$1('part-' + data.name(), spec) }); }; var subs = function (owner, detail, parts) { var internals = {}; var externals = {}; each$1(parts, function (part) { part.fold(function (data) { internals[data.pname()] = single(true, function (detail, partSpec, partValidated) { return data.factory().sketch(combine(detail, data, partSpec, partValidated)); }); }, function (data) { var partSpec = detail.parts()[data.name()](); externals[data.name()] = constant(combine(detail, data, partSpec[original()]())); }, function (data) { internals[data.pname()] = single(false, function (detail, partSpec, partValidated) { return data.factory().sketch(combine(detail, data, partSpec, partValidated)); }); }, function (data) { internals[data.pname()] = multiple(true, function (detail, _partSpec, _partValidated) { var units = detail[data.name()](); return map$1(units, function (u) { return data.factory().sketch(deepMerge(data.defaults()(detail, u), u, data.overrides()(detail, u))); }); }); }); }); return { internals: constant(internals), externals: constant(externals) }; }; var generate$2 = function (owner, parts) { var r = {}; each$1(parts, function (part) { asNamedPart(part).each(function (np) { var g = doGenerateOne(owner, np.pname()); r[np.name()] = function (config) { var validated = asRawOrDie('Part: ' + np.name() + ' in ' + owner, objOf(np.schema()), config); return deepMerge(g, { config: config, validated: validated }); }; }); }); return r; }; var doGenerateOne = function (owner, pname) { return { uiType: placeholder(), owner: owner, name: pname }; }; var generateOne = function (owner, pname, config) { return { uiType: placeholder(), owner: owner, name: pname, config: config, validated: {} }; }; var schemas = function (parts) { return bind(parts, function (part) { return part.fold(Option.none, Option.some, Option.none, Option.none).map(function (data) { return strictObjOf(data.name(), data.schema().concat([snapshot(original())])); }).toArray(); }); }; var names = function (parts) { return map$1(parts, name$1); }; var substitutes = function (owner, detail, parts) { return subs(owner, detail, parts); }; var components = function (owner, detail, internals) { return substitutePlaces(Option.some(owner), detail, detail.components(), internals); }; var getPart = function (component, detail, partKey) { var uid = detail.partUids()[partKey]; return component.getSystem().getByUid(uid).toOption(); }; var getPartOrDie = function (component, detail, partKey) { return getPart(component, detail, partKey).getOrDie('Could not find part: ' + partKey); }; var getAllParts = function (component, detail) { var system = component.getSystem(); return map(detail.partUids(), function (pUid, k) { return constant(system.getByUid(pUid)); }); }; var defaultUids = function (baseUid, partTypes) { var partNames = names(partTypes); return wrapAll$1(map$1(partNames, function (pn) { return { key: pn, value: baseUid + '-' + pn }; })); }; var defaultUidsSchema = function (partTypes) { return field('partUids', 'partUids', mergeWithThunk(function (spec) { return defaultUids(spec.uid, partTypes); }), anyValue$1()); }; var premadeTag = generate$1('alloy-premade'); var _apiConfig = generate$1('api'); var premade = function (comp) { return wrap$1(premadeTag, comp); }; var getPremade = function (spec) { return readOptFrom$1(spec, premadeTag); }; var makeApi = function (f) { return markAsSketchApi(function (component) { var rest = []; for (var _i = 1; _i < arguments.length; _i++) { rest[_i - 1] = arguments[_i]; } var spi = component.config(_apiConfig); return f.apply(undefined, [spi].concat([component].concat(rest))); }, f); }; var apiConfig = constant(_apiConfig); var prefix$1 = constant('alloy-id-'); var idAttr = constant('data-alloy-id'); var prefix$2 = prefix$1(); var idAttr$1 = idAttr(); var write = function (label, elem) { var id = generate$1(prefix$2 + label); set(elem, idAttr$1, id); return id; }; var writeOnly = function (elem, uid) { set(elem, idAttr$1, uid); }; var read$2 = function (elem) { var id = isElement(elem) ? get(elem, idAttr$1) : null; return Option.from(id); }; var generate$3 = function (prefix) { return generate$1(prefix); }; var base$1 = function (label, partSchemas, partUidsSchemas, spec) { var ps = partSchemas.length > 0 ? [strictObjOf('parts', partSchemas)] : []; return ps.concat([ strict$1('uid'), defaulted$1('dom', {}), defaulted$1('components', []), snapshot('originalSpec'), defaulted$1('debug.sketcher', {}) ]).concat(partUidsSchemas); }; var asStructOrDie$1 = function (label, schema, spec, partSchemas, partUidsSchemas) { var baseS = base$1(label, partSchemas, partUidsSchemas, spec); return asStructOrDie(label + ' [SpecSchema]', objOfOnly(baseS.concat(schema)), spec); }; var single$1 = function (owner, schema, factory, spec) { var specWithUid = supplyUid(spec); var detail = asStructOrDie$1(owner, schema, specWithUid, [], []); return deepMerge(factory(detail, specWithUid), { 'debug.sketcher': wrap$1(owner, spec) }); }; var composite = function (owner, schema, partTypes, factory, spec) { var specWithUid = supplyUid(spec); var partSchemas = schemas(partTypes); var partUidsSchema = defaultUidsSchema(partTypes); var detail = asStructOrDie$1(owner, schema, specWithUid, partSchemas, [partUidsSchema]); var subs = substitutes(owner, detail, partTypes); var components$1 = components(owner, detail, subs.internals()); return deepMerge(factory(detail, components$1, specWithUid, subs.externals()), { 'debug.sketcher': wrap$1(owner, spec) }); }; var supplyUid = function (spec) { return deepMerge({ uid: generate$3('uid') }, spec); }; function isSketchSpec(spec) { return spec.uid !== undefined; } var singleSchema = objOfOnly([ strict$1('name'), strict$1('factory'), strict$1('configFields'), defaulted$1('apis', {}), defaulted$1('extraApis', {}) ]); var compositeSchema = objOfOnly([ strict$1('name'), strict$1('factory'), strict$1('configFields'), strict$1('partFields'), defaulted$1('apis', {}), defaulted$1('extraApis', {}) ]); var single$2 = function (rawConfig) { var config = asRawOrDie('Sketcher for ' + rawConfig.name, singleSchema, rawConfig); var sketch = function (spec) { return single$1(config.name, config.configFields, config.factory, spec); }; var apis = map(config.apis, makeApi); var extraApis = map(config.extraApis, function (f, k) { return markAsExtraApi(f, k); }); return deepMerge({ name: constant(config.name), partFields: constant([]), configFields: constant(config.configFields), sketch: sketch }, apis, extraApis); }; var composite$1 = function (rawConfig) { var config = asRawOrDie('Sketcher for ' + rawConfig.name, compositeSchema, rawConfig); var sketch = function (spec) { return composite(config.name, config.configFields, config.partFields, config.factory, spec); }; var parts = generate$2(config.name, config.partFields); var apis = map(config.apis, makeApi); var extraApis = map(config.extraApis, function (f, k) { return markAsExtraApi(f, k); }); return deepMerge({ name: constant(config.name), partFields: constant(config.partFields), configFields: constant(config.configFields), sketch: sketch, parts: constant(parts) }, apis, extraApis); }; var factory = function (detail) { var events = events$2(detail.action()); var optType = readOptFrom$1(detail.dom(), 'attributes').bind(readOpt$1('type')); var optTag = readOptFrom$1(detail.dom(), 'tag'); return { uid: detail.uid(), dom: detail.dom(), components: detail.components(), events: events, behaviours: deepMerge(derive$1([ Focusing.config({}), Keying.config({ mode: 'execution', useSpace: true, useEnter: true }) ]), get$5(detail.buttonBehaviours())), domModification: { attributes: deepMerge(optType.fold(function () { return optTag.is('button') ? { type: 'button' } : {}; }, function (t) { return {}; }), { role: detail.role().getOr('button') }) }, eventOrder: detail.eventOrder() }; }; var Button = single$2({ name: 'Button', factory: factory, configFields: [ defaulted$1('uid', undefined), strict$1('dom'), defaulted$1('components', []), field$1('buttonBehaviours', [ Focusing, Keying ]), option('action'), option('role'), defaulted$1('eventOrder', {}) ] }); var exhibit$2 = function (base, unselectConfig) { return nu$6({ styles: { '-webkit-user-select': 'none', 'user-select': 'none', '-ms-user-select': 'none', '-moz-user-select': '-moz-none' }, attributes: { unselectable: 'on' } }); }; var events$4 = function (unselectConfig) { return derive([abort(selectstart(), constant(true))]); }; var ActiveUnselecting = /*#__PURE__*/Object.freeze({ events: events$4, exhibit: exhibit$2 }); var Unselecting = create$1({ fields: [], name: 'unselecting', active: ActiveUnselecting }); var getAttrs = function (elem) { var attributes = elem.dom().attributes !== undefined ? elem.dom().attributes : []; return foldl(attributes, function (b, attr) { if (attr.name === 'class') { return b; } else { return deepMerge(b, wrap$1(attr.name, attr.value)); } }, {}); }; var getClasses = function (elem) { return Array.prototype.slice.call(elem.dom().classList, 0); }; var fromHtml$2 = function (html) { var elem = Element.fromHtml(html); var children$1 = children(elem); var attrs = getAttrs(elem); var classes = getClasses(elem); var contents = children$1.length === 0 ? {} : { innerHtml: get$2(elem) }; return deepMerge({ tag: name(elem), classes: classes, attributes: attrs }, contents); }; var dom$1 = function (rawHtml) { var html = supplant(rawHtml, { prefix: Styles.prefix() }); return fromHtml$2(html); }; var spec = function (rawHtml) { var sDom = dom$1(rawHtml); return { dom: sDom }; }; var forToolbarCommand = function (editor, command) { return forToolbar(command, function () { editor.execCommand(command); }, {}); }; var getToggleBehaviours = function (command) { return derive$1([ Toggling.config({ toggleClass: Styles.resolve('toolbar-button-selected'), toggleOnExecute: false, aria: { mode: 'pressed' } }), Receivers.format(command, function (button, status) { var toggle = status ? Toggling.on : Toggling.off; toggle(button); }) ]); }; var forToolbarStateCommand = function (editor, command) { var extraBehaviours = getToggleBehaviours(command); return forToolbar(command, function () { editor.execCommand(command); }, extraBehaviours); }; var forToolbarStateAction = function (editor, clazz, command, action) { var extraBehaviours = getToggleBehaviours(command); return forToolbar(clazz, action, extraBehaviours); }; var forToolbar = function (clazz, action, extraBehaviours) { return Button.sketch({ dom: dom$1('<span class="${prefix}-toolbar-button ${prefix}-icon-' + clazz + ' ${prefix}-icon"></span>'), action: action, buttonBehaviours: deepMerge(derive$1([Unselecting.config({})]), extraBehaviours) }); }; var Buttons = { forToolbar: forToolbar, forToolbarCommand: forToolbarCommand, forToolbarStateAction: forToolbarStateAction, forToolbarStateCommand: forToolbarStateCommand }; var r = function (left, top) { var translate = function (x, y) { return r(left + x, top + y); }; return { left: constant(left), top: constant(top), translate: translate }; }; var Position = r; var reduceBy = function (value, min, max, step) { if (value < min) { return value; } else if (value > max) { return max; } else if (value === min) { return min - 1; } else { return Math.max(min, value - step); } }; var increaseBy = function (value, min, max, step) { if (value > max) { return value; } else if (value < min) { return min; } else if (value === max) { return max + 1; } else { return Math.min(max, value + step); } }; var capValue = function (value, min, max) { return Math.max(min, Math.min(max, value)); }; var snapValueOfX = function (bounds, value, min, max, step, snapStart) { return snapStart.fold(function () { var initValue = value - min; var extraValue = Math.round(initValue / step) * step; return capValue(min + extraValue, min - 1, max + 1); }, function (start) { var remainder = (value - start) % step; var adjustment = Math.round(remainder / step); var rawSteps = Math.floor((value - start) / step); var maxSteps = Math.floor((max - start) / step); var numSteps = Math.min(maxSteps, rawSteps + adjustment); var r = start + numSteps * step; return Math.max(start, r); }); }; var findValueOfX = function (bounds, min, max, xValue, step, snapToGrid, snapStart) { var range = max - min; if (xValue < bounds.left) { return min - 1; } else if (xValue > bounds.right) { return max + 1; } else { var xOffset = Math.min(bounds.right, Math.max(xValue, bounds.left)) - bounds.left; var newValue = capValue(xOffset / bounds.width * range + min, min - 1, max + 1); var roundedValue = Math.round(newValue); return snapToGrid && newValue >= min && newValue <= max ? snapValueOfX(bounds, newValue, min, max, step, snapStart) : roundedValue; } }; var _changeEvent = 'slider.change.value'; var isTouch = PlatformDetection$1.detect().deviceType.isTouch(); var getEventSource = function (simulatedEvent) { var evt = simulatedEvent.event().raw(); if (isTouch) { var touchEvent = evt; return touchEvent.touches !== undefined && touchEvent.touches.length === 1 ? Option.some(touchEvent.touches[0]).map(function (t) { return Position(t.clientX, t.clientY); }) : Option.none(); } else { var mouseEvent = evt; return mouseEvent.clientX !== undefined ? Option.some(mouseEvent).map(function (me) { return Position(me.clientX, me.clientY); }) : Option.none(); } }; var getEventX = function (simulatedEvent) { var spot = getEventSource(simulatedEvent); return spot.map(function (s) { return s.left(); }); }; var fireChange = function (component, value) { emitWith(component, _changeEvent, { value: value }); }; var setToRedge = function (redge, detail) { fireChange(redge, detail.max() + 1); }; var setToLedge = function (ledge, detail) { fireChange(ledge, detail.min() - 1); }; var setToX = function (spectrum, spectrumBounds, detail, xValue) { var value = findValueOfX(spectrumBounds, detail.min(), detail.max(), xValue, detail.stepSize(), detail.snapToGrid(), detail.snapStart()); fireChange(spectrum, value); }; var setXFromEvent = function (spectrum, detail, spectrumBounds, simulatedEvent) { return getEventX(simulatedEvent).map(function (xValue) { setToX(spectrum, spectrumBounds, detail, xValue); return xValue; }); }; var moveLeft$4 = function (spectrum, detail) { var newValue = reduceBy(detail.value().get(), detail.min(), detail.max(), detail.stepSize()); fireChange(spectrum, newValue); }; var moveRight$4 = function (spectrum, detail) { var newValue = increaseBy(detail.value().get(), detail.min(), detail.max(), detail.stepSize()); fireChange(spectrum, newValue); }; var changeEvent = function () { return _changeEvent; }; var platform = PlatformDetection$1.detect(); var isTouch$1 = platform.deviceType.isTouch(); var edgePart = function (name, action) { return optional({ name: '' + name + '-edge', overrides: function (detail) { var touchEvents = derive([runActionExtra(touchstart(), action, [detail])]); var mouseEvents = derive([ runActionExtra(mousedown(), action, [detail]), runActionExtra(mousemove(), function (l, det) { if (det.mouseIsDown().get()) { action(l, det); } }, [detail]) ]); return { events: isTouch$1 ? touchEvents : mouseEvents }; } }); }; var ledgePart = edgePart('left', setToLedge); var redgePart = edgePart('right', setToRedge); var thumbPart = required({ name: 'thumb', defaults: constant({ dom: { styles: { position: 'absolute' } } }), overrides: function (detail) { return { events: derive([ redirectToPart(touchstart(), detail, 'spectrum'), redirectToPart(touchmove(), detail, 'spectrum'), redirectToPart(touchend(), detail, 'spectrum') ]) }; } }); var spectrumPart = required({ schema: [state$1('mouseIsDown', function () { return Cell(false); })], name: 'spectrum', overrides: function (detail) { var moveToX = function (spectrum, simulatedEvent) { var domElem = spectrum.element().dom(); var spectrumBounds = domElem.getBoundingClientRect(); setXFromEvent(spectrum, detail, spectrumBounds, simulatedEvent); }; var touchEvents = derive([ run(touchstart(), moveToX), run(touchmove(), moveToX) ]); var mouseEvents = derive([ run(mousedown(), moveToX), run(mousemove(), function (spectrum, se) { if (detail.mouseIsDown().get()) { moveToX(spectrum, se); } }) ]); return { behaviours: derive$1(isTouch$1 ? [] : [ Keying.config({ mode: 'special', onLeft: function (spectrum) { moveLeft$4(spectrum, detail); return Option.some(true); }, onRight: function (spectrum) { moveRight$4(spectrum, detail); return Option.some(true); } }), Focusing.config({}) ]), events: isTouch$1 ? touchEvents : mouseEvents }; } }); var SliderParts = [ ledgePart, redgePart, thumbPart, spectrumPart ]; var onLoad$1 = function (component, repConfig, repState) { repConfig.store().manager().onLoad(component, repConfig, repState); }; var onUnload = function (component, repConfig, repState) { repConfig.store().manager().onUnload(component, repConfig, repState); }; var setValue = function (component, repConfig, repState, data) { repConfig.store().manager().setValue(component, repConfig, repState, data); }; var getValue = function (component, repConfig, repState) { return repConfig.store().manager().getValue(component, repConfig, repState); }; var RepresentApis = /*#__PURE__*/Object.freeze({ onLoad: onLoad$1, onUnload: onUnload, setValue: setValue, getValue: getValue }); var events$5 = function (repConfig, repState) { var es = repConfig.resetOnDom() ? [ runOnAttached(function (comp, se) { onLoad$1(comp, repConfig, repState); }), runOnDetached(function (comp, se) { onUnload(comp, repConfig, repState); }) ] : [loadEvent(repConfig, repState, onLoad$1)]; return derive(es); }; var ActiveRepresenting = /*#__PURE__*/Object.freeze({ events: events$5 }); var memory = function () { var data = Cell(null); var readState = function () { return { mode: 'memory', value: data.get() }; }; var isNotSet = function () { return data.get() === null; }; var clear = function () { data.set(null); }; return nu$7({ set: data.set, get: data.get, isNotSet: isNotSet, clear: clear, readState: readState }); }; var manual = function () { var readState = function () { }; return nu$7({ readState: readState }); }; var dataset = function () { var data = Cell({}); var readState = function () { return { mode: 'dataset', dataset: data.get() }; }; return nu$7({ readState: readState, set: data.set, get: data.get }); }; var init$1 = function (spec) { return spec.store().manager().state(spec); }; var RepresentState = /*#__PURE__*/Object.freeze({ memory: memory, dataset: dataset, manual: manual, init: init$1 }); var setValue$1 = function (component, repConfig, repState, data) { var dataKey = repConfig.store().getDataKey(); repState.set({}); repConfig.store().setData()(component, data); repConfig.onSetValue()(component, data); }; var getValue$1 = function (component, repConfig, repState) { var key = repConfig.store().getDataKey()(component); var dataset = repState.get(); return readOptFrom$1(dataset, key).fold(function () { return repConfig.store().getFallbackEntry()(key); }, function (data) { return data; }); }; var onLoad$2 = function (component, repConfig, repState) { repConfig.store().initialValue().each(function (data) { setValue$1(component, repConfig, repState, data); }); }; var onUnload$1 = function (component, repConfig, repState) { repState.set({}); }; var DatasetStore = [ option('initialValue'), strict$1('getFallbackEntry'), strict$1('getDataKey'), strict$1('setData'), output('manager', { setValue: setValue$1, getValue: getValue$1, onLoad: onLoad$2, onUnload: onUnload$1, state: dataset }) ]; var getValue$2 = function (component, repConfig, repState) { return repConfig.store().getValue()(component); }; var setValue$2 = function (component, repConfig, repState, data) { repConfig.store().setValue()(component, data); repConfig.onSetValue()(component, data); }; var onLoad$3 = function (component, repConfig, repState) { repConfig.store().initialValue().each(function (data) { repConfig.store().setValue()(component, data); }); }; var ManualStore = [ strict$1('getValue'), defaulted$1('setValue', noop), option('initialValue'), output('manager', { setValue: setValue$2, getValue: getValue$2, onLoad: onLoad$3, onUnload: noop, state: NoState.init }) ]; var setValue$3 = function (component, repConfig, repState, data) { repState.set(data); repConfig.onSetValue()(component, data); }; var getValue$3 = function (component, repConfig, repState) { return repState.get(); }; var onLoad$4 = function (component, repConfig, repState) { repConfig.store().initialValue().each(function (initVal) { if (repState.isNotSet()) { repState.set(initVal); } }); }; var onUnload$2 = function (component, repConfig, repState) { repState.clear(); }; var MemoryStore = [ option('initialValue'), output('manager', { setValue: setValue$3, getValue: getValue$3, onLoad: onLoad$4, onUnload: onUnload$2, state: memory }) ]; var RepresentSchema = [ defaultedOf('store', { mode: 'memory' }, choose$1('mode', { memory: MemoryStore, manual: ManualStore, dataset: DatasetStore })), onHandler('onSetValue'), defaulted$1('resetOnDom', false) ]; var Representing = create$1({ fields: RepresentSchema, name: 'representing', active: ActiveRepresenting, apis: RepresentApis, extra: { setValueFrom: function (component, source) { var value = Representing.getValue(source); Representing.setValue(component, value); } }, state: RepresentState }); var isTouch$2 = PlatformDetection$1.detect().deviceType.isTouch(); var SliderSchema = [ strict$1('min'), strict$1('max'), defaulted$1('stepSize', 1), defaulted$1('onChange', noop), defaulted$1('onInit', noop), defaulted$1('onDragStart', noop), defaulted$1('onDragEnd', noop), defaulted$1('snapToGrid', false), option('snapStart'), strict$1('getInitialValue'), field$1('sliderBehaviours', [ Keying, Representing ]), state$1('value', function (spec) { return Cell(spec.min); }) ].concat(!isTouch$2 ? [state$1('mouseIsDown', function () { return Cell(false); })] : []); var api$1 = Dimension('width', function (element) { return element.dom().offsetWidth; }); var set$3 = function (element, h) { api$1.set(element, h); }; var get$6 = function (element) { return api$1.get(element); }; var isTouch$3 = PlatformDetection$1.detect().deviceType.isTouch(); var sketch = function (detail, components, spec, externals) { var range = detail.max() - detail.min(); var getXCentre = function (component) { var rect = component.element().dom().getBoundingClientRect(); return (rect.left + rect.right) / 2; }; var getThumb = function (component) { return getPartOrDie(component, detail, 'thumb'); }; var getXOffset = function (slider, spectrumBounds, detail) { var v = detail.value().get(); if (v < detail.min()) { return getPart(slider, detail, 'left-edge').fold(function () { return 0; }, function (ledge) { return getXCentre(ledge) - spectrumBounds.left; }); } else if (v > detail.max()) { return getPart(slider, detail, 'right-edge').fold(function () { return spectrumBounds.width; }, function (redge) { return getXCentre(redge) - spectrumBounds.left; }); } else { return (detail.value().get() - detail.min()) / range * spectrumBounds.width; } }; var getXPos = function (slider) { var spectrum = getPartOrDie(slider, detail, 'spectrum'); var spectrumBounds = spectrum.element().dom().getBoundingClientRect(); var sliderBounds = slider.element().dom().getBoundingClientRect(); var xOffset = getXOffset(slider, spectrumBounds, detail); return spectrumBounds.left - sliderBounds.left + xOffset; }; var refresh = function (component) { var pos = getXPos(component); var thumb = getThumb(component); var thumbRadius = get$6(thumb.element()) / 2; set$2(thumb.element(), 'left', pos - thumbRadius + 'px'); }; var changeValue = function (component, newValue) { var oldValue = detail.value().get(); var thumb = getThumb(component); if (oldValue !== newValue || getRaw(thumb.element(), 'left').isNone()) { detail.value().set(newValue); refresh(component); detail.onChange()(component, thumb, newValue); return Option.some(true); } else { return Option.none(); } }; var resetToMin = function (slider) { changeValue(slider, detail.min()); }; var resetToMax = function (slider) { changeValue(slider, detail.max()); }; var uiEventsArr = isTouch$3 ? [ run(touchstart(), function (slider, simulatedEvent) { detail.onDragStart()(slider, getThumb(slider)); }), run(touchend(), function (slider, simulatedEvent) { detail.onDragEnd()(slider, getThumb(slider)); }) ] : [ run(mousedown(), function (slider, simulatedEvent) { simulatedEvent.stop(); detail.onDragStart()(slider, getThumb(slider)); detail.mouseIsDown().set(true); }), run(mouseup(), function (slider, simulatedEvent) { detail.onDragEnd()(slider, getThumb(slider)); detail.mouseIsDown().set(false); }) ]; return { uid: detail.uid(), dom: detail.dom(), components: components, behaviours: deepMerge(derive$1(flatten([ !isTouch$3 ? [Keying.config({ mode: 'special', focusIn: function (slider) { return getPart(slider, detail, 'spectrum').map(Keying.focusIn).map(constant(true)); } })] : [], [Representing.config({ store: { mode: 'manual', getValue: function (_) { return detail.value().get(); } } })] ])), get$5(detail.sliderBehaviours())), events: derive([ run(changeEvent(), function (slider, simulatedEvent) { changeValue(slider, simulatedEvent.event().value()); }), runOnAttached(function (slider, simulatedEvent) { detail.value().set(detail.getInitialValue()()); var thumb = getThumb(slider); refresh(slider); detail.onInit()(slider, thumb, detail.value().get()); }) ].concat(uiEventsArr)), apis: { resetToMin: resetToMin, resetToMax: resetToMax, refresh: refresh }, domModification: { styles: { position: 'relative' } } }; }; var Slider = composite$1({ name: 'Slider', configFields: SliderSchema, partFields: SliderParts, factory: sketch, apis: { resetToMin: function (apis, slider) { apis.resetToMin(slider); }, resetToMax: function (apis, slider) { apis.resetToMax(slider); }, refresh: function (apis, slider) { apis.refresh(slider); } } }); var button = function (realm, clazz, makeItems) { return Buttons.forToolbar(clazz, function () { var items = makeItems(); realm.setContextToolbar([{ label: clazz + ' group', items: items }]); }, {}); }; var BLACK = -1; var makeSlider = function (spec$1) { var getColor = function (hue) { if (hue < 0) { return 'black'; } else if (hue > 360) { return 'white'; } else { return 'hsl(' + hue + ', 100%, 50%)'; } }; var onInit = function (slider, thumb, value) { var color = getColor(value); set$2(thumb.element(), 'background-color', color); }; var onChange = function (slider, thumb, value) { var color = getColor(value); set$2(thumb.element(), 'background-color', color); spec$1.onChange(slider, thumb, color); }; return Slider.sketch({ dom: dom$1('<div class="${prefix}-slider ${prefix}-hue-slider-container"></div>'), components: [ Slider.parts()['left-edge'](spec('<div class="${prefix}-hue-slider-black"></div>')), Slider.parts().spectrum({ dom: dom$1('<div class="${prefix}-slider-gradient-container"></div>'), components: [spec('<div class="${prefix}-slider-gradient"></div>')], behaviours: derive$1([Toggling.config({ toggleClass: Styles.resolve('thumb-active') })]) }), Slider.parts()['right-edge'](spec('<div class="${prefix}-hue-slider-white"></div>')), Slider.parts().thumb({ dom: dom$1('<div class="${prefix}-slider-thumb"></div>'), behaviours: derive$1([Toggling.config({ toggleClass: Styles.resolve('thumb-active') })]) }) ], onChange: onChange, onDragStart: function (slider, thumb) { Toggling.on(thumb); }, onDragEnd: function (slider, thumb) { Toggling.off(thumb); }, onInit: onInit, stepSize: 10, min: 0, max: 360, getInitialValue: spec$1.getInitialValue, sliderBehaviours: derive$1([Receivers.orientation(Slider.refresh)]) }); }; var makeItems = function (spec) { return [makeSlider(spec)]; }; var sketch$1 = function (realm, editor) { var spec = { onChange: function (slider, thumb, color) { editor.undoManager.transact(function () { editor.formatter.apply('forecolor', { value: color }); editor.nodeChanged(); }); }, getInitialValue: function () { return BLACK; } }; return button(realm, 'color', function () { return makeItems(spec); }); }; var ColorSlider = { makeItems: makeItems, sketch: sketch$1 }; var schema$7 = objOfOnly([ strict$1('getInitialValue'), strict$1('onChange'), strict$1('category'), strict$1('sizes') ]); var sketch$2 = function (rawSpec) { var spec$1 = asRawOrDie('SizeSlider', schema$7, rawSpec); var isValidValue = function (valueIndex) { return valueIndex >= 0 && valueIndex < spec$1.sizes.length; }; var onChange = function (slider, thumb, valueIndex) { if (isValidValue(valueIndex)) { spec$1.onChange(valueIndex); } }; return Slider.sketch({ dom: { tag: 'div', classes: [ Styles.resolve('slider-' + spec$1.category + '-size-container'), Styles.resolve('slider'), Styles.resolve('slider-size-container') ] }, onChange: onChange, onDragStart: function (slider, thumb) { Toggling.on(thumb); }, onDragEnd: function (slider, thumb) { Toggling.off(thumb); }, min: 0, max: spec$1.sizes.length - 1, stepSize: 1, getInitialValue: spec$1.getInitialValue, snapToGrid: true, sliderBehaviours: derive$1([Receivers.orientation(Slider.refresh)]), components: [ Slider.parts().spectrum({ dom: dom$1('<div class="${prefix}-slider-size-container"></div>'), components: [spec('<div class="${prefix}-slider-size-line"></div>')] }), Slider.parts().thumb({ dom: dom$1('<div class="${prefix}-slider-thumb"></div>'), behaviours: derive$1([Toggling.config({ toggleClass: Styles.resolve('thumb-active') })]) }) ] }); }; var SizeSlider = { sketch: sketch$2 }; var candidates = [ '9px', '10px', '11px', '12px', '14px', '16px', '18px', '20px', '24px', '32px', '36px' ]; var defaultSize = 'medium'; var defaultIndex = 2; var indexToSize = function (index) { return Option.from(candidates[index]); }; var sizeToIndex = function (size) { return findIndex(candidates, function (v) { return v === size; }); }; var getRawOrComputed = function (isRoot, rawStart) { var optStart = isElement(rawStart) ? Option.some(rawStart) : parent(rawStart); return optStart.map(function (start) { var inline = closest(start, function (elem) { return getRaw(elem, 'font-size').isSome(); }, isRoot).bind(function (elem) { return getRaw(elem, 'font-size'); }); return inline.getOrThunk(function () { return get$3(start, 'font-size'); }); }).getOr(''); }; var getSize = function (editor) { var node = editor.selection.getStart(); var elem = Element.fromDom(node); var root = Element.fromDom(editor.getBody()); var isRoot = function (e) { return eq(root, e); }; var elemSize = getRawOrComputed(isRoot, elem); return find$1(candidates, function (size) { return elemSize === size; }).getOr(defaultSize); }; var applySize = function (editor, value) { var currentValue = getSize(editor); if (currentValue !== value) { editor.execCommand('fontSize', false, value); } }; var get$7 = function (editor) { var size = getSize(editor); return sizeToIndex(size).getOr(defaultIndex); }; var apply$1 = function (editor, index) { indexToSize(index).each(function (size) { applySize(editor, size); }); }; var FontSizes = { candidates: constant(candidates), get: get$7, apply: apply$1 }; var sizes = FontSizes.candidates(); var makeSlider$1 = function (spec) { return SizeSlider.sketch({ onChange: spec.onChange, sizes: sizes, category: 'font', getInitialValue: spec.getInitialValue }); }; var makeItems$1 = function (spec$1) { return [ spec('<span class="${prefix}-toolbar-button ${prefix}-icon-small-font ${prefix}-icon"></span>'), makeSlider$1(spec$1), spec('<span class="${prefix}-toolbar-button ${prefix}-icon-large-font ${prefix}-icon"></span>') ]; }; var sketch$3 = function (realm, editor) { var spec = { onChange: function (value) { FontSizes.apply(editor, value); }, getInitialValue: function () { return FontSizes.get(editor); } }; return button(realm, 'font-size', function () { return makeItems$1(spec); }); }; var record = function (spec) { var uid = isSketchSpec(spec) && hasKey$1(spec, 'uid') ? spec.uid : generate$3('memento'); var get = function (anyInSystem) { return anyInSystem.getSystem().getByUid(uid).getOrDie(); }; var getOpt = function (anyInSystem) { return anyInSystem.getSystem().getByUid(uid).fold(Option.none, Option.some); }; var asSpec = function () { return deepMerge(spec, { uid: uid }); }; return { get: get, getOpt: getOpt, asSpec: asSpec }; }; function create$3(width, height) { return resize(domGlobals.document.createElement('canvas'), width, height); } function clone$1(canvas) { var tCanvas, ctx; tCanvas = create$3(canvas.width, canvas.height); ctx = get2dContext(tCanvas); ctx.drawImage(canvas, 0, 0); return tCanvas; } function get2dContext(canvas) { return canvas.getContext('2d'); } function get3dContext(canvas) { var gl = null; try { gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); } catch (e) { } if (!gl) { gl = null; } return gl; } function resize(canvas, width, height) { canvas.width = width; canvas.height = height; return canvas; } var Canvas = { create: create$3, clone: clone$1, resize: resize, get2dContext: get2dContext, get3dContext: get3dContext }; function getWidth(image) { return image.naturalWidth || image.width; } function getHeight(image) { return image.naturalHeight || image.height; } var ImageSize = { getWidth: getWidth, getHeight: getHeight }; var promise = function () { var Promise = function (fn) { if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new'); if (typeof fn !== 'function') throw new TypeError('not a function'); this._state = null; this._value = null; this._deferreds = []; doResolve(fn, bind(resolve, this), bind(reject, this)); }; var asap = Promise.immediateFn || typeof window.setImmediate === 'function' && window.setImmediate || function (fn) { domGlobals.setTimeout(fn, 1); }; function bind(fn, thisArg) { return function () { fn.apply(thisArg, arguments); }; } var isArray = Array.isArray || function (value) { return Object.prototype.toString.call(value) === '[object Array]'; }; function handle(deferred) { var me = this; if (this._state === null) { this._deferreds.push(deferred); return; } asap(function () { var cb = me._state ? deferred.onFulfilled : deferred.onRejected; if (cb === null) { (me._state ? deferred.resolve : deferred.reject)(me._value); return; } var ret; try { ret = cb(me._value); } catch (e) { deferred.reject(e); return; } deferred.resolve(ret); }); } function resolve(newValue) { try { if (newValue === this) throw new TypeError('A promise cannot be resolved with itself.'); if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { var then = newValue.then; if (typeof then === 'function') { doResolve(bind(then, newValue), bind(resolve, this), bind(reject, this)); return; } } this._state = true; this._value = newValue; finale.call(this); } catch (e) { reject.call(this, e); } } function reject(newValue) { this._state = false; this._value = newValue; finale.call(this); } function finale() { for (var i = 0, len = this._deferreds.length; i < len; i++) { handle.call(this, this._deferreds[i]); } this._deferreds = null; } function Handler(onFulfilled, onRejected, resolve, reject) { this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; this.onRejected = typeof onRejected === 'function' ? onRejected : null; this.resolve = resolve; this.reject = reject; } function doResolve(fn, onFulfilled, onRejected) { var done = false; try { fn(function (value) { if (done) return; done = true; onFulfilled(value); }, function (reason) { if (done) return; done = true; onRejected(reason); }); } catch (ex) { if (done) return; done = true; onRejected(ex); } } Promise.prototype['catch'] = function (onRejected) { return this.then(null, onRejected); }; Promise.prototype.then = function (onFulfilled, onRejected) { var me = this; return new Promise(function (resolve, reject) { handle.call(me, new Handler(onFulfilled, onRejected, resolve, reject)); }); }; Promise.all = function () { var args = Array.prototype.slice.call(arguments.length === 1 && isArray(arguments[0]) ? arguments[0] : arguments); return new Promise(function (resolve, reject) { if (args.length === 0) return resolve([]); var remaining = args.length; function res(i, val) { try { if (val && (typeof val === 'object' || typeof val === 'function')) { var then = val.then; if (typeof then === 'function') { then.call(val, function (val) { res(i, val); }, reject); return; } } args[i] = val; if (--remaining === 0) { resolve(args); } } catch (ex) { reject(ex); } } for (var i = 0; i < args.length; i++) { res(i, args[i]); } }); }; Promise.resolve = function (value) { if (value && typeof value === 'object' && value.constructor === Promise) { return value; } return new Promise(function (resolve) { resolve(value); }); }; Promise.reject = function (value) { return new Promise(function (resolve, reject) { reject(value); }); }; Promise.race = function (values) { return new Promise(function (resolve, reject) { for (var i = 0, len = values.length; i < len; i++) { values[i].then(resolve, reject); } }); }; return Promise; }; var Promise = window.Promise ? window.Promise : promise(); function Blob (parts, properties) { var f = Global$1.getOrDie('Blob'); return new f(parts, properties); } function FileReader () { var f = Global$1.getOrDie('FileReader'); return new f(); } function Uint8Array (arr) { var f = Global$1.getOrDie('Uint8Array'); return new f(arr); } var requestAnimationFrame = function (callback) { var f = Global$1.getOrDie('requestAnimationFrame'); f(callback); }; var atob = function (base64) { var f = Global$1.getOrDie('atob'); return f(base64); }; var Window = { atob: atob, requestAnimationFrame: requestAnimationFrame }; function imageToBlob(image) { var src = image.src; if (src.indexOf('data:') === 0) { return dataUriToBlob(src); } return anyUriToBlob(src); } function blobToImage(blob) { return new Promise(function (resolve, reject) { var blobUrl = domGlobals.URL.createObjectURL(blob); var image = new domGlobals.Image(); var removeListeners = function () { image.removeEventListener('load', loaded); image.removeEventListener('error', error); }; function loaded() { removeListeners(); resolve(image); } function error() { removeListeners(); reject('Unable to load data of type ' + blob.type + ': ' + blobUrl); } image.addEventListener('load', loaded); image.addEventListener('error', error); image.src = blobUrl; if (image.complete) { loaded(); } }); } function anyUriToBlob(url) { return new Promise(function (resolve, reject) { var xhr = new domGlobals.XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'blob'; xhr.onload = function () { if (this.status == 200) { resolve(this.response); } }; xhr.onerror = function () { var _this = this; var corsError = function () { var obj = new Error('No access to download image'); obj.code = 18; obj.name = 'SecurityError'; return obj; }; var genericError = function () { return new Error('Error ' + _this.status + ' downloading image'); }; reject(this.status === 0 ? corsError() : genericError()); }; xhr.send(); }); } function dataUriToBlobSync(uri) { var data = uri.split(','); var matches = /data:([^;]+)/.exec(data[0]); if (!matches) return Option.none(); var mimetype = matches[1]; var base64 = data[1]; var sliceSize = 1024; var byteCharacters = Window.atob(base64); var bytesLength = byteCharacters.length; var slicesCount = Math.ceil(bytesLength / sliceSize); var byteArrays = new Array(slicesCount); for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) { var begin = sliceIndex * sliceSize; var end = Math.min(begin + sliceSize, bytesLength); var bytes = new Array(end - begin); for (var offset = begin, i = 0; offset < end; ++i, ++offset) { bytes[i] = byteCharacters[offset].charCodeAt(0); } byteArrays[sliceIndex] = Uint8Array(bytes); } return Option.some(Blob(byteArrays, { type: mimetype })); } function dataUriToBlob(uri) { return new Promise(function (resolve, reject) { dataUriToBlobSync(uri).fold(function () { reject('uri is not base64: ' + uri); }, resolve); }); } function uriToBlob(url) { if (url.indexOf('blob:') === 0) { return anyUriToBlob(url); } if (url.indexOf('data:') === 0) { return dataUriToBlob(url); } return null; } function canvasToBlob(canvas, type, quality) { type = type || 'image/png'; if (domGlobals.HTMLCanvasElement.prototype.toBlob) { return new Promise(function (resolve) { canvas.toBlob(function (blob) { resolve(blob); }, type, quality); }); } else { return dataUriToBlob(canvas.toDataURL(type, quality)); } } function canvasToDataURL(getCanvas, type, quality) { type = type || 'image/png'; return getCanvas.then(function (canvas) { return canvas.toDataURL(type, quality); }); } function blobToCanvas(blob) { return blobToImage(blob).then(function (image) { revokeImageUrl(image); var context, canvas; canvas = Canvas.create(ImageSize.getWidth(image), ImageSize.getHeight(image)); context = Canvas.get2dContext(canvas); context.drawImage(image, 0, 0); return canvas; }); } function blobToDataUri(blob) { return new Promise(function (resolve) { var reader = FileReader(); reader.onloadend = function () { resolve(reader.result); }; reader.readAsDataURL(blob); }); } function blobToArrayBuffer(blob) { return new Promise(function (resolve) { var reader = FileReader(); reader.onloadend = function () { resolve(reader.result); }; reader.readAsArrayBuffer(blob); }); } function blobToBase64(blob) { return blobToDataUri(blob).then(function (dataUri) { return dataUri.split(',')[1]; }); } function revokeImageUrl(image) { domGlobals.URL.revokeObjectURL(image.src); } var Conversions = { blobToImage: blobToImage, imageToBlob: imageToBlob, blobToArrayBuffer: blobToArrayBuffer, blobToDataUri: blobToDataUri, blobToBase64: blobToBase64, dataUriToBlobSync: dataUriToBlobSync, canvasToBlob: canvasToBlob, canvasToDataURL: canvasToDataURL, blobToCanvas: blobToCanvas, uriToBlob: uriToBlob }; var blobToImage$1 = function (image) { return Conversions.blobToImage(image); }; var imageToBlob$1 = function (blob) { return Conversions.imageToBlob(blob); }; var blobToDataUri$1 = function (blob) { return Conversions.blobToDataUri(blob); }; var blobToBase64$1 = function (blob) { return Conversions.blobToBase64(blob); }; var dataUriToBlobSync$1 = function (uri) { return Conversions.dataUriToBlobSync(uri); }; var uriToBlob$1 = function (uri) { return Option.from(Conversions.uriToBlob(uri)); }; var BlobConversions = { blobToImage: blobToImage$1, imageToBlob: imageToBlob$1, blobToDataUri: blobToDataUri$1, blobToBase64: blobToBase64$1, dataUriToBlobSync: dataUriToBlobSync$1, uriToBlob: uriToBlob$1 }; var addImage = function (editor, blob) { BlobConversions.blobToBase64(blob).then(function (base64) { editor.undoManager.transact(function () { var cache = editor.editorUpload.blobCache; var info = cache.create(generate$1('mceu'), blob, base64); cache.add(info); var img = editor.dom.createHTML('img', { src: info.blobUri() }); editor.insertContent(img); }); }); }; var extractBlob = function (simulatedEvent) { var event = simulatedEvent.event(); var files = event.raw().target.files || event.raw().dataTransfer.files; return Option.from(files[0]); }; var sketch$4 = function (editor) { var pickerDom = { tag: 'input', attributes: { accept: 'image/*', type: 'file', title: '' }, styles: { visibility: 'hidden', position: 'absolute' } }; var memPicker = record({ dom: pickerDom, events: derive([ cutter(click()), run(change(), function (picker, simulatedEvent) { extractBlob(simulatedEvent).each(function (blob) { addImage(editor, blob); }); }) ]) }); return Button.sketch({ dom: dom$1('<span class="${prefix}-toolbar-button ${prefix}-icon-image ${prefix}-icon"></span>'), components: [memPicker.asSpec()], action: function (button) { var picker = memPicker.get(button); picker.element().dom().click(); } }); }; var get$8 = function (element) { return element.dom().textContent; }; var set$4 = function (element, value) { element.dom().textContent = value; }; var isNotEmpty = function (val) { return val.length > 0; }; var defaultToEmpty = function (str) { return str === undefined || str === null ? '' : str; }; var noLink = function (editor) { var text = editor.selection.getContent({ format: 'text' }); return { url: '', text: text, title: '', target: '', link: Option.none() }; }; var fromLink = function (link) { var text = get$8(link); var url = get(link, 'href'); var title = get(link, 'title'); var target = get(link, 'target'); return { url: defaultToEmpty(url), text: text !== url ? defaultToEmpty(text) : '', title: defaultToEmpty(title), target: defaultToEmpty(target), link: Option.some(link) }; }; var getInfo = function (editor) { return query(editor).fold(function () { return noLink(editor); }, function (link) { return fromLink(link); }); }; var wasSimple = function (link) { var prevHref = get(link, 'href'); var prevText = get$8(link); return prevHref === prevText; }; var getTextToApply = function (link, url, info) { return info.text.filter(isNotEmpty).fold(function () { return wasSimple(link) ? Option.some(url) : Option.none(); }, Option.some); }; var unlinkIfRequired = function (editor, info) { var activeLink = info.link.bind(identity); activeLink.each(function (link) { editor.execCommand('unlink'); }); }; var getAttrs$1 = function (url, info) { var attrs = {}; attrs.href = url; info.title.filter(isNotEmpty).each(function (title) { attrs.title = title; }); info.target.filter(isNotEmpty).each(function (target) { attrs.target = target; }); return attrs; }; var applyInfo = function (editor, info) { info.url.filter(isNotEmpty).fold(function () { unlinkIfRequired(editor, info); }, function (url) { var attrs = getAttrs$1(url, info); var activeLink = info.link.bind(identity); activeLink.fold(function () { var text = info.text.filter(isNotEmpty).getOr(url); editor.insertContent(editor.dom.createHTML('a', attrs, editor.dom.encode(text))); }, function (link) { var text = getTextToApply(link, url, info); setAll(link, attrs); text.each(function (newText) { set$4(link, newText); }); }); }); }; var query = function (editor) { var start = Element.fromDom(editor.selection.getStart()); return closest$1(start, 'a'); }; var LinkBridge = { getInfo: getInfo, applyInfo: applyInfo, query: query }; var platform$1 = PlatformDetection$1.detect(); var preserve = function (f, editor) { var rng = editor.selection.getRng(); f(); editor.selection.setRng(rng); }; var forAndroid = function (editor, f) { var wrapper = platform$1.os.isAndroid() ? preserve : apply; wrapper(f, editor); }; var RangePreserver = { forAndroid: forAndroid }; var events$6 = function (name, eventHandlers) { var events = derive(eventHandlers); return create$1({ fields: [strict$1('enabled')], name: name, active: { events: constant(events) } }); }; var config = function (name, eventHandlers) { var me = events$6(name, eventHandlers); return { key: name, value: { config: {}, me: me, configAsRaw: constant({}), initialConfig: {}, state: NoState } }; }; var getCurrent = function (component, composeConfig, composeState) { return composeConfig.find()(component); }; var ComposeApis = /*#__PURE__*/Object.freeze({ getCurrent: getCurrent }); var ComposeSchema = [strict$1('find')]; var Composing = create$1({ fields: ComposeSchema, name: 'composing', apis: ComposeApis }); var factory$1 = function (detail) { return { uid: detail.uid(), dom: deepMerge({ tag: 'div', attributes: { role: 'presentation' } }, detail.dom()), components: detail.components(), behaviours: get$5(detail.containerBehaviours()), events: detail.events(), domModification: detail.domModification(), eventOrder: detail.eventOrder() }; }; var Container = single$2({ name: 'Container', factory: factory$1, configFields: [ defaulted$1('components', []), field$1('containerBehaviours', []), defaulted$1('events', {}), defaulted$1('domModification', {}), defaulted$1('eventOrder', {}) ] }); var factory$2 = function (detail) { return { uid: detail.uid(), dom: detail.dom(), behaviours: deepMerge(derive$1([ Representing.config({ store: { mode: 'memory', initialValue: detail.getInitialValue()() } }), Composing.config({ find: Option.some }) ]), get$5(detail.dataBehaviours())), events: derive([runOnAttached(function (component, simulatedEvent) { Representing.setValue(component, detail.getInitialValue()()); })]) }; }; var DataField = single$2({ name: 'DataField', factory: factory$2, configFields: [ strict$1('uid'), strict$1('dom'), strict$1('getInitialValue'), field$1('dataBehaviours', [ Representing, Composing ]) ] }); var get$9 = function (element) { return element.dom().value; }; var set$5 = function (element, value) { if (value === undefined) { throw new Error('Value.set was undefined'); } element.dom().value = value; }; var schema$8 = constant([ option('data'), defaulted$1('inputAttributes', {}), defaulted$1('inputStyles', {}), defaulted$1('type', 'input'), defaulted$1('tag', 'input'), defaulted$1('inputClasses', []), onHandler('onSetValue'), defaulted$1('styles', {}), option('placeholder'), defaulted$1('eventOrder', {}), field$1('inputBehaviours', [ Representing, Focusing ]), defaulted$1('selectOnFocus', true) ]); var focusBehaviours = function (detail) { return derive$1([Focusing.config({ onFocus: detail.selectOnFocus() === false ? noop : function (component) { var input = component.element(); var value = get$9(input); input.dom().setSelectionRange(0, value.length); } })]); }; var behaviours = function (detail) { return deepMerge(derive$1([Representing.config({ store: { mode: 'manual', initialValue: detail.data().getOr(undefined), getValue: function (input) { return get$9(input.element()); }, setValue: function (input, data) { var current = get$9(input.element()); if (current !== data) { set$5(input.element(), data); } } }, onSetValue: detail.onSetValue() })]), focusBehaviours(detail), get$5(detail.inputBehaviours())); }; var dom$2 = function (detail) { return { tag: detail.tag(), attributes: deepMerge(wrapAll$1([{ key: 'type', value: detail.type() }].concat(detail.placeholder().map(function (pc) { return { key: 'placeholder', value: pc }; }).toArray())), detail.inputAttributes()), styles: detail.inputStyles(), classes: detail.inputClasses() }; }; var factory$3 = function (detail, spec) { return { uid: detail.uid(), dom: dom$2(detail), components: [], behaviours: behaviours(detail), eventOrder: detail.eventOrder() }; }; var Input = single$2({ name: 'Input', configFields: schema$8(), factory: factory$3 }); var exhibit$3 = function (base, tabConfig) { return nu$6({ attributes: wrapAll$1([{ key: tabConfig.tabAttr(), value: 'true' }]) }); }; var ActiveTabstopping = /*#__PURE__*/Object.freeze({ exhibit: exhibit$3 }); var TabstopSchema = [defaulted$1('tabAttr', 'data-alloy-tabstop')]; var Tabstopping = create$1({ fields: TabstopSchema, name: 'tabstopping', active: ActiveTabstopping }); var clearInputBehaviour = 'input-clearing'; var field$2 = function (name, placeholder) { var inputSpec = record(Input.sketch({ placeholder: placeholder, onSetValue: function (input$1, data) { emit(input$1, input()); }, inputBehaviours: derive$1([ Composing.config({ find: Option.some }), Tabstopping.config({}), Keying.config({ mode: 'execution' }) ]), selectOnFocus: false })); var buttonSpec = record(Button.sketch({ dom: dom$1('<button class="${prefix}-input-container-x ${prefix}-icon-cancel-circle ${prefix}-icon"></button>'), action: function (button) { var input = inputSpec.get(button); Representing.setValue(input, ''); } })); return { name: name, spec: Container.sketch({ dom: dom$1('<div class="${prefix}-input-container"></div>'), components: [ inputSpec.asSpec(), buttonSpec.asSpec() ], containerBehaviours: derive$1([ Toggling.config({ toggleClass: Styles.resolve('input-container-empty') }), Composing.config({ find: function (comp) { return Option.some(inputSpec.get(comp)); } }), config(clearInputBehaviour, [run(input(), function (iContainer) { var input = inputSpec.get(iContainer); var val = Representing.getValue(input); var f = val.length > 0 ? Toggling.off : Toggling.on; f(iContainer); })]) ]) }) }; }; var hidden = function (name) { return { name: name, spec: DataField.sketch({ dom: { tag: 'span', styles: { display: 'none' } }, getInitialValue: function () { return Option.none(); } }) }; }; var nativeDisabled = [ 'input', 'button', 'textarea' ]; var onLoad$5 = function (component, disableConfig, disableState) { if (disableConfig.disabled()) { disable(component, disableConfig, disableState); } }; var hasNative = function (component) { return contains(nativeDisabled, name(component.element())); }; var nativeIsDisabled = function (component) { return has(component.element(), 'disabled'); }; var nativeDisable = function (component) { set(component.element(), 'disabled', 'disabled'); }; var nativeEnable = function (component) { remove$1(component.element(), 'disabled'); }; var ariaIsDisabled = function (component) { return get(component.element(), 'aria-disabled') === 'true'; }; var ariaDisable = function (component) { set(component.element(), 'aria-disabled', 'true'); }; var ariaEnable = function (component) { set(component.element(), 'aria-disabled', 'false'); }; var disable = function (component, disableConfig, disableState) { disableConfig.disableClass().each(function (disableClass) { add$2(component.element(), disableClass); }); var f = hasNative(component) ? nativeDisable : ariaDisable; f(component); }; var enable = function (component, disableConfig, disableState) { disableConfig.disableClass().each(function (disableClass) { remove$4(component.element(), disableClass); }); var f = hasNative(component) ? nativeEnable : ariaEnable; f(component); }; var isDisabled = function (component) { return hasNative(component) ? nativeIsDisabled(component) : ariaIsDisabled(component); }; var DisableApis = /*#__PURE__*/Object.freeze({ enable: enable, disable: disable, isDisabled: isDisabled, onLoad: onLoad$5 }); var exhibit$4 = function (base, disableConfig, disableState) { return nu$6({ classes: disableConfig.disabled() ? disableConfig.disableClass().map(pure).getOr([]) : [] }); }; var events$7 = function (disableConfig, disableState) { return derive([ abort(execute(), function (component, simulatedEvent) { return isDisabled(component); }), loadEvent(disableConfig, disableState, onLoad$5) ]); }; var ActiveDisable = /*#__PURE__*/Object.freeze({ exhibit: exhibit$4, events: events$7 }); var DisableSchema = [ defaulted$1('disabled', false), option('disableClass') ]; var Disabling = create$1({ fields: DisableSchema, name: 'disabling', active: ActiveDisable, apis: DisableApis }); var owner$1 = 'form'; var schema$9 = [field$1('formBehaviours', [Representing])]; var getPartName = function (name) { return '<alloy.field.' + name + '>'; }; var sketch$5 = function (fSpec) { var parts = function () { var record = []; var field = function (name, config) { record.push(name); return generateOne(owner$1, getPartName(name), config); }; return { field: field, record: function () { return record; } }; }(); var spec = fSpec(parts); var partNames = parts.record(); var fieldParts = map$1(partNames, function (n) { return required({ name: n, pname: getPartName(n) }); }); return composite(owner$1, schema$9, fieldParts, make, spec); }; var make = function (detail, components, spec) { return deepMerge({ 'debug.sketcher': { Form: spec }, 'uid': detail.uid(), 'dom': detail.dom(), 'components': components, 'behaviours': deepMerge(derive$1([Representing.config({ store: { mode: 'manual', getValue: function (form) { var optPs = getAllParts(form, detail); return map(optPs, function (optPThunk, pName) { return optPThunk().bind(Composing.getCurrent).map(Representing.getValue); }); }, setValue: function (form, values) { each(values, function (newValue, key) { getPart(form, detail, key).each(function (wrapper) { Composing.getCurrent(wrapper).each(function (field) { Representing.setValue(field, newValue); }); }); }); } } })]), get$5(detail.formBehaviours())), 'apis': { getField: function (form, key) { return getPart(form, detail, key).bind(Composing.getCurrent); } } }); }; var Form = { getField: makeApi(function (apis, component, key) { return apis.getField(component, key); }), sketch: sketch$5 }; var api$2 = function () { var subject = Cell(Option.none()); var revoke = function () { subject.get().each(function (s) { s.destroy(); }); }; var clear = function () { revoke(); subject.set(Option.none()); }; var set = function (s) { revoke(); subject.set(Option.some(s)); }; var run = function (f) { subject.get().each(f); }; var isSet = function () { return subject.get().isSome(); }; return { clear: clear, isSet: isSet, set: set, run: run }; }; var value$2 = function () { var subject = Cell(Option.none()); var clear = function () { subject.set(Option.none()); }; var set = function (s) { subject.set(Option.some(s)); }; var on = function (f) { subject.get().each(f); }; var isSet = function () { return subject.get().isSome(); }; return { clear: clear, set: set, isSet: isSet, on: on }; }; var SWIPING_LEFT = 1; var SWIPING_RIGHT = -1; var SWIPING_NONE = 0; var init$2 = function (xValue) { return { xValue: xValue, points: [] }; }; var move$1 = function (model, xValue) { if (xValue === model.xValue) { return model; } var currentDirection = xValue - model.xValue > 0 ? SWIPING_LEFT : SWIPING_RIGHT; var newPoint = { direction: currentDirection, xValue: xValue }; var priorPoints = function () { if (model.points.length === 0) { return []; } else { var prev = model.points[model.points.length - 1]; return prev.direction === currentDirection ? model.points.slice(0, model.points.length - 1) : model.points; } }(); return { xValue: xValue, points: priorPoints.concat([newPoint]) }; }; var complete = function (model) { if (model.points.length === 0) { return SWIPING_NONE; } else { var firstDirection = model.points[0].direction; var lastDirection = model.points[model.points.length - 1].direction; return firstDirection === SWIPING_RIGHT && lastDirection === SWIPING_RIGHT ? SWIPING_RIGHT : firstDirection === SWIPING_LEFT && lastDirection === SWIPING_LEFT ? SWIPING_LEFT : SWIPING_NONE; } }; var SwipingModel = { init: init$2, move: move$1, complete: complete }; var sketch$6 = function (rawSpec) { var navigateEvent = 'navigateEvent'; var wrapperAdhocEvents = 'serializer-wrapper-events'; var formAdhocEvents = 'form-events'; var schema = objOf([ strict$1('fields'), defaulted$1('maxFieldIndex', rawSpec.fields.length - 1), strict$1('onExecute'), strict$1('getInitialValue'), state$1('state', function () { return { dialogSwipeState: value$2(), currentScreen: Cell(0) }; }) ]); var spec$1 = asRawOrDie('SerialisedDialog', schema, rawSpec); var navigationButton = function (direction, directionName, enabled) { return Button.sketch({ dom: dom$1('<span class="${prefix}-icon-' + directionName + ' ${prefix}-icon"></span>'), action: function (button) { emitWith(button, navigateEvent, { direction: direction }); }, buttonBehaviours: derive$1([Disabling.config({ disableClass: Styles.resolve('toolbar-navigation-disabled'), disabled: !enabled })]) }); }; var reposition = function (dialog, message) { descendant$1(dialog.element(), '.' + Styles.resolve('serialised-dialog-chain')).each(function (parent) { set$2(parent, 'left', -spec$1.state.currentScreen.get() * message.width + 'px'); }); }; var navigate = function (dialog, direction) { var screens = descendants(dialog.element(), '.' + Styles.resolve('serialised-dialog-screen')); descendant$1(dialog.element(), '.' + Styles.resolve('serialised-dialog-chain')).each(function (parent) { if (spec$1.state.currentScreen.get() + direction >= 0 && spec$1.state.currentScreen.get() + direction < screens.length) { getRaw(parent, 'left').each(function (left) { var currentLeft = parseInt(left, 10); var w = get$6(screens[0]); set$2(parent, 'left', currentLeft - direction * w + 'px'); }); spec$1.state.currentScreen.set(spec$1.state.currentScreen.get() + direction); } }); }; var focusInput = function (dialog) { var inputs = descendants(dialog.element(), 'input'); var optInput = Option.from(inputs[spec$1.state.currentScreen.get()]); optInput.each(function (input) { dialog.getSystem().getByDom(input).each(function (inputComp) { dispatchFocus(dialog, inputComp.element()); }); }); var dotitems = memDots.get(dialog); Highlighting.highlightAt(dotitems, spec$1.state.currentScreen.get()); }; var resetState = function () { spec$1.state.currentScreen.set(0); spec$1.state.dialogSwipeState.clear(); }; var memForm = record(Form.sketch(function (parts) { return { dom: dom$1('<div class="${prefix}-serialised-dialog"></div>'), components: [Container.sketch({ dom: dom$1('<div class="${prefix}-serialised-dialog-chain" style="left: 0px; position: absolute;"></div>'), components: map$1(spec$1.fields, function (field, i) { return i <= spec$1.maxFieldIndex ? Container.sketch({ dom: dom$1('<div class="${prefix}-serialised-dialog-screen"></div>'), components: flatten([ [navigationButton(-1, 'previous', i > 0)], [parts.field(field.name, field.spec)], [navigationButton(+1, 'next', i < spec$1.maxFieldIndex)] ]) }) : parts.field(field.name, field.spec); }) })], formBehaviours: derive$1([ Receivers.orientation(function (dialog, message) { reposition(dialog, message); }), Keying.config({ mode: 'special', focusIn: function (dialog) { focusInput(dialog); }, onTab: function (dialog) { navigate(dialog, +1); return Option.some(true); }, onShiftTab: function (dialog) { navigate(dialog, -1); return Option.some(true); } }), config(formAdhocEvents, [ runOnAttached(function (dialog, simulatedEvent) { resetState(); var dotitems = memDots.get(dialog); Highlighting.highlightFirst(dotitems); spec$1.getInitialValue(dialog).each(function (v) { Representing.setValue(dialog, v); }); }), runOnExecute(spec$1.onExecute), run(transitionend(), function (dialog, simulatedEvent) { var event = simulatedEvent.event(); if (event.raw().propertyName === 'left') { focusInput(dialog); } }), run(navigateEvent, function (dialog, simulatedEvent) { var event = simulatedEvent.event(); var direction = event.direction(); navigate(dialog, direction); }) ]) ]) }; })); var memDots = record({ dom: dom$1('<div class="${prefix}-dot-container"></div>'), behaviours: derive$1([Highlighting.config({ highlightClass: Styles.resolve('dot-active'), itemClass: Styles.resolve('dot-item') })]), components: bind(spec$1.fields, function (_f, i) { return i <= spec$1.maxFieldIndex ? [spec('<div class="${prefix}-dot-item ${prefix}-icon-full-dot ${prefix}-icon"></div>')] : []; }) }); return { dom: dom$1('<div class="${prefix}-serializer-wrapper"></div>'), components: [ memForm.asSpec(), memDots.asSpec() ], behaviours: derive$1([ Keying.config({ mode: 'special', focusIn: function (wrapper) { var form = memForm.get(wrapper); Keying.focusIn(form); } }), config(wrapperAdhocEvents, [ run(touchstart(), function (wrapper, simulatedEvent) { var event = simulatedEvent.event(); spec$1.state.dialogSwipeState.set(SwipingModel.init(event.touches[0].clientX)); }), run(touchmove(), function (wrapper, simulatedEvent) { var event = simulatedEvent.event(); spec$1.state.dialogSwipeState.on(function (state) { simulatedEvent.event().prevent(); spec$1.state.dialogSwipeState.set(SwipingModel.move(state, event.raw().touches[0].clientX)); }); }), run(touchend(), function (wrapper) { spec$1.state.dialogSwipeState.on(function (state) { var dialog = memForm.get(wrapper); var direction = -1 * SwipingModel.complete(state); navigate(dialog, direction); }); }) ]) ]) }; }; var getGroups = cached(function (realm, editor) { return [{ label: 'the link group', items: [sketch$6({ fields: [ field$2('url', 'Type or paste URL'), field$2('text', 'Link text'), field$2('title', 'Link title'), field$2('target', 'Link target'), hidden('link') ], maxFieldIndex: [ 'url', 'text', 'title', 'target' ].length - 1, getInitialValue: function () { return Option.some(LinkBridge.getInfo(editor)); }, onExecute: function (dialog) { var info = Representing.getValue(dialog); LinkBridge.applyInfo(editor, info); realm.restoreToolbar(); editor.focus(); } })] }]; }); var sketch$7 = function (realm, editor) { return Buttons.forToolbarStateAction(editor, 'link', 'link', function () { var groups = getGroups(realm, editor); realm.setContextToolbar(groups); RangePreserver.forAndroid(editor, function () { realm.focusToolbar(); }); LinkBridge.query(editor).each(function (link) { editor.selection.select(link.dom()); }); }); }; var DefaultStyleFormats = [ { title: 'Headings', items: [ { title: 'Heading 1', format: 'h1' }, { title: 'Heading 2', format: 'h2' }, { title: 'Heading 3', format: 'h3' }, { title: 'Heading 4', format: 'h4' }, { title: 'Heading 5', format: 'h5' }, { title: 'Heading 6', format: 'h6' } ] }, { title: 'Inline', items: [ { title: 'Bold', icon: 'bold', format: 'bold' }, { title: 'Italic', icon: 'italic', format: 'italic' }, { title: 'Underline', icon: 'underline', format: 'underline' }, { title: 'Strikethrough', icon: 'strikethrough', format: 'strikethrough' }, { title: 'Superscript', icon: 'superscript', format: 'superscript' }, { title: 'Subscript', icon: 'subscript', format: 'subscript' }, { title: 'Code', icon: 'code', format: 'code' } ] }, { title: 'Blocks', items: [ { title: 'Paragraph', format: 'p' }, { title: 'Blockquote', format: 'blockquote' }, { title: 'Div', format: 'div' }, { title: 'Pre', format: 'pre' } ] }, { title: 'Alignment', items: [ { title: 'Left', icon: 'alignleft', format: 'alignleft' }, { title: 'Center', icon: 'aligncenter', format: 'aligncenter' }, { title: 'Right', icon: 'alignright', format: 'alignright' }, { title: 'Justify', icon: 'alignjustify', format: 'alignjustify' } ] } ]; var isRecursive = function (component, originator, target) { return eq(originator, component.element()) && !eq(originator, target); }; var events$8 = derive([can(focus(), function (component, simulatedEvent) { var originator = simulatedEvent.event().originator(); var target = simulatedEvent.event().target(); if (isRecursive(component, originator, target)) { domGlobals.console.warn(focus() + ' did not get interpreted by the desired target. ' + '\nOriginator: ' + element(originator) + '\nTarget: ' + element(target) + '\nCheck the ' + focus() + ' event handlers'); return false; } else { return true; } })]); var DefaultEvents = /*#__PURE__*/Object.freeze({ events: events$8 }); var make$1 = identity; var SystemApi = exactly([ 'debugInfo', 'triggerFocus', 'triggerEvent', 'triggerEscape', 'addToWorld', 'removeFromWorld', 'addToGui', 'removeFromGui', 'build', 'getByUid', 'getByDom', 'broadcast', 'broadcastOn', 'isConnected' ]); var NoContextApi = function (getComp) { var fail = function (event) { return function () { throw new Error('The component must be in a context to send: ' + event + '\n' + element(getComp().element()) + ' is not in context.'); }; }; return SystemApi({ debugInfo: constant('fake'), triggerEvent: fail('triggerEvent'), triggerFocus: fail('triggerFocus'), triggerEscape: fail('triggerEscape'), build: fail('build'), addToWorld: fail('addToWorld'), removeFromWorld: fail('removeFromWorld'), addToGui: fail('addToGui'), removeFromGui: fail('removeFromGui'), getByUid: fail('getByUid'), getByDom: fail('getByDom'), broadcast: fail('broadcast'), broadcastOn: fail('broadcastOn'), isConnected: constant(false) }); }; var generateFrom = function (spec, all) { var schema = map$1(all, function (a) { return optionObjOf(a.name(), [ strict$1('config'), defaulted$1('state', NoState) ]); }); var validated = asStruct('component.behaviours', objOf(schema), spec.behaviours).fold(function (errInfo) { throw new Error(formatError(errInfo) + '\nComplete spec:\n' + Json.stringify(spec, null, 2)); }, function (v) { return v; }); return { list: all, data: map(validated, function (optBlobThunk) { var optBlob = optBlobThunk(); var output = optBlob.map(function (blob) { return { config: blob.config(), state: blob.state().init(blob.config()) }; }); return function () { return output; }; }) }; }; var getBehaviours = function (bData) { return bData.list; }; var getData = function (bData) { return bData.data; }; var byInnerKey = function (data, tuple) { var r = {}; each(data, function (detail, key) { each(detail, function (value, indexKey) { var chain = readOr$1(indexKey, [])(r); r[indexKey] = chain.concat([tuple(key, value)]); }); }); return r; }; var concat = function (chain, aspect) { var values = bind(chain, function (c) { return c.modification().getOr([]); }); return Result.value(wrap$1(aspect, values)); }; var onlyOne = function (chain, aspect) { if (chain.length > 1) { return Result.error('Multiple behaviours have tried to change DOM "' + aspect + '". The guilty behaviours are: ' + Json.stringify(map$1(chain, function (b) { return b.name(); })) + '. At this stage, this ' + 'is not supported. Future releases might provide strategies for resolving this.'); } else if (chain.length === 0) { return Result.value({}); } else { return Result.value(chain[0].modification().fold(function () { return {}; }, function (m) { return wrap$1(aspect, m); })); } }; var duplicate = function (aspect, k, obj, behaviours) { return Result.error('Mulitple behaviours have tried to change the _' + k + '_ "' + aspect + '"' + '. The guilty behaviours are: ' + Json.stringify(bind(behaviours, function (b) { return b.modification().getOr({})[k] !== undefined ? [b.name()] : []; }), null, 2) + '. This is not currently supported.'); }; var objSafeMerge = function (chain, aspect) { var y = foldl(chain, function (acc, c) { var obj = c.modification().getOr({}); return acc.bind(function (accRest) { var parts = mapToArray(obj, function (v, k) { return accRest[k] !== undefined ? duplicate(aspect, k, obj, chain) : Result.value(wrap$1(k, v)); }); return consolidate(parts, accRest); }); }, Result.value({})); return y.map(function (yValue) { return wrap$1(aspect, yValue); }); }; var mergeTypes = { classes: concat, attributes: objSafeMerge, styles: objSafeMerge, domChildren: onlyOne, defChildren: onlyOne, innerHtml: onlyOne, value: onlyOne }; var combine$1 = function (info, baseMod, behaviours, base) { var modsByBehaviour = deepMerge({}, baseMod); each$1(behaviours, function (behaviour) { modsByBehaviour[behaviour.name()] = behaviour.exhibit(info, base); }); var nameAndMod = function (name, modification) { return { name: function () { return name; }, modification: modification }; }; var byAspect = byInnerKey(modsByBehaviour, nameAndMod); var usedAspect = map(byAspect, function (values, aspect) { return bind(values, function (value) { return value.modification().fold(function () { return []; }, function (v) { return [value]; }); }); }); var modifications = mapToArray(usedAspect, function (values, aspect) { return readOptFrom$1(mergeTypes, aspect).fold(function () { return Result.error('Unknown field type: ' + aspect); }, function (merger) { return merger(values, aspect); }); }); var consolidated = consolidate(modifications, {}); return consolidated.map(nu$6); }; var sortKeys = function (label, keyName, array, order) { var sliced = array.slice(0); try { var sorted = sliced.sort(function (a, b) { var aKey = a[keyName](); var bKey = b[keyName](); var aIndex = order.indexOf(aKey); var bIndex = order.indexOf(bKey); if (aIndex === -1) { throw new Error('The ordering for ' + label + ' does not have an entry for ' + aKey + '.\nOrder specified: ' + Json.stringify(order, null, 2)); } if (bIndex === -1) { throw new Error('The ordering for ' + label + ' does not have an entry for ' + bKey + '.\nOrder specified: ' + Json.stringify(order, null, 2)); } if (aIndex < bIndex) { return -1; } else if (bIndex < aIndex) { return 1; } else { return 0; } }); return Result.value(sorted); } catch (err) { return Result.error([err]); } }; var uncurried = function (handler, purpose) { return { handler: handler, purpose: constant(purpose) }; }; var curried = function (handler, purpose) { return { cHandler: handler, purpose: constant(purpose) }; }; var curryArgs = function (descHandler, extraArgs) { return curried(curry.apply(undefined, [descHandler.handler].concat(extraArgs)), descHandler.purpose()); }; var getCurried = function (descHandler) { return descHandler.cHandler; }; var behaviourTuple = function (name, handler) { return { name: constant(name), handler: constant(handler) }; }; var nameToHandlers = function (behaviours, info) { var r = {}; each$1(behaviours, function (behaviour) { r[behaviour.name()] = behaviour.handlers(info); }); return r; }; var groupByEvents = function (info, behaviours, base) { var behaviourEvents = deepMerge(base, nameToHandlers(behaviours, info)); return byInnerKey(behaviourEvents, behaviourTuple); }; var combine$2 = function (info, eventOrder, behaviours, base) { var byEventName = groupByEvents(info, behaviours, base); return combineGroups(byEventName, eventOrder); }; var assemble = function (rawHandler) { var handler = read(rawHandler); return function (component, simulatedEvent) { var rest = []; for (var _i = 2; _i < arguments.length; _i++) { rest[_i - 2] = arguments[_i]; } var args = [ component, simulatedEvent ].concat(rest); if (handler.abort.apply(undefined, args)) { simulatedEvent.stop(); } else if (handler.can.apply(undefined, args)) { handler.run.apply(undefined, args); } }; }; var missingOrderError = function (eventName, tuples) { return Result.error(['The event (' + eventName + ') has more than one behaviour that listens to it.\nWhen this occurs, you must ' + 'specify an event ordering for the behaviours in your spec (e.g. [ "listing", "toggling" ]).\nThe behaviours that ' + 'can trigger it are: ' + Json.stringify(map$1(tuples, function (c) { return c.name(); }), null, 2)]); }; var fuse$1 = function (tuples, eventOrder, eventName) { var order = eventOrder[eventName]; if (!order) { return missingOrderError(eventName, tuples); } else { return sortKeys('Event: ' + eventName, 'name', tuples, order).map(function (sortedTuples) { var handlers = map$1(sortedTuples, function (tuple) { return tuple.handler(); }); return fuse(handlers); }); } }; var combineGroups = function (byEventName, eventOrder) { var r = mapToArray(byEventName, function (tuples, eventName) { var combined = tuples.length === 1 ? Result.value(tuples[0].handler()) : fuse$1(tuples, eventOrder, eventName); return combined.map(function (handler) { var assembled = assemble(handler); var purpose = tuples.length > 1 ? filter(eventOrder, function (o) { return contains(tuples, function (t) { return t.name() === o; }); }).join(' > ') : tuples[0].name(); return wrap$1(eventName, uncurried(assembled, purpose)); }); }); return consolidate(r, {}); }; var toInfo = function (spec) { return asStruct('custom.definition', objOfOnly([ field('dom', 'dom', strict(), objOfOnly([ strict$1('tag'), defaulted$1('styles', {}), defaulted$1('classes', []), defaulted$1('attributes', {}), option('value'), option('innerHtml') ])), strict$1('components'), strict$1('uid'), defaulted$1('events', {}), defaulted$1('apis', constant({})), field('eventOrder', 'eventOrder', mergeWith({ 'alloy.execute': [ 'disabling', 'alloy.base.behaviour', 'toggling' ], 'alloy.focus': [ 'alloy.base.behaviour', 'focusing', 'keying' ], 'alloy.system.init': [ 'alloy.base.behaviour', 'disabling', 'toggling', 'representing' ], 'input': [ 'alloy.base.behaviour', 'representing', 'streaming', 'invalidating' ], 'alloy.system.detached': [ 'alloy.base.behaviour', 'representing' ] }), anyValue$1()), option('domModification'), snapshot('originalSpec'), defaulted$1('debug.sketcher', 'unknown') ]), spec); }; var getUid = function (detail) { return wrap$1(idAttr(), detail.uid()); }; var toDefinition = function (detail) { var base = { tag: detail.dom().tag(), classes: detail.dom().classes(), attributes: deepMerge(getUid(detail), detail.dom().attributes()), styles: detail.dom().styles(), domChildren: map$1(detail.components(), function (comp) { return comp.element(); }) }; return nu$5(deepMerge(base, detail.dom().innerHtml().map(function (h) { return wrap$1('innerHtml', h); }).getOr({}), detail.dom().value().map(function (h) { return wrap$1('value', h); }).getOr({}))); }; var toModification = function (detail) { return detail.domModification().fold(function () { return nu$6({}); }, nu$6); }; var toEvents = function (info) { return info.events(); }; var add$3 = function (element, classes) { each$1(classes, function (x) { add$2(element, x); }); }; var remove$6 = function (element, classes) { each$1(classes, function (x) { remove$4(element, x); }); }; var getChildren = function (definition) { if (definition.domChildren().isSome() && definition.defChildren().isSome()) { throw new Error('Cannot specify children and child specs! Must be one or the other.\nDef: ' + defToStr(definition)); } else { return definition.domChildren().fold(function () { var defChildren = definition.defChildren().getOr([]); return map$1(defChildren, renderDef); }, function (domChildren) { return domChildren; }); } }; var renderToDom = function (definition) { var subject = Element.fromTag(definition.tag()); setAll(subject, definition.attributes().getOr({})); add$3(subject, definition.classes().getOr([])); setAll$1(subject, definition.styles().getOr({})); set$1(subject, definition.innerHtml().getOr('')); var children = getChildren(definition); append$1(subject, children); definition.value().each(function (value) { set$5(subject, value); }); return subject; }; var renderDef = function (spec) { var definition = nu$5(spec); return renderToDom(definition); }; var getBehaviours$1 = function (spec) { var behaviours = readOptFrom$1(spec, 'behaviours').getOr({}); var keys$1 = filter(keys(behaviours), function (k) { return behaviours[k] !== undefined; }); return map$1(keys$1, function (k) { return behaviours[k].me; }); }; var generateFrom$1 = function (spec, all) { return generateFrom(spec, all); }; var generate$4 = function (spec) { var all = getBehaviours$1(spec); return generateFrom$1(spec, all); }; var ComponentApi = exactly([ 'getSystem', 'config', 'hasConfigured', 'spec', 'connect', 'disconnect', 'element', 'syncComponents', 'readState', 'components', 'events' ]); var getDomDefinition = function (info, bList, bData) { var definition = toDefinition(info); var baseModification = { 'alloy.base.modification': toModification(info) }; var modification = combine$1(bData, baseModification, bList, definition).getOrDie(); return merge$1(definition, modification); }; var getEvents$6 = function (info, bList, bData) { var baseEvents = { 'alloy.base.behaviour': toEvents(info) }; return combine$2(bData, info.eventOrder(), bList, baseEvents).getOrDie(); }; var build = function (spec) { var getMe = function () { return me; }; var systemApi = Cell(NoContextApi(getMe)); var info = getOrDie$1(toInfo(deepMerge(spec, { behaviours: undefined }))); var bBlob = generate$4(spec); var bList = getBehaviours(bBlob); var bData = getData(bBlob); var modDefinition = getDomDefinition(info, bList, bData); var item = renderToDom(modDefinition); var events = getEvents$6(info, bList, bData); var subcomponents = Cell(info.components()); var connect = function (newApi) { systemApi.set(newApi); }; var disconnect = function () { systemApi.set(NoContextApi(getMe)); }; var syncComponents = function () { var children$1 = children(item); var subs = bind(children$1, function (child) { return systemApi.get().getByDom(child).fold(function () { return []; }, function (c) { return [c]; }); }); subcomponents.set(subs); }; var config = function (behaviour) { if (behaviour === apiConfig()) { return info.apis(); } else if (isString(behaviour)) { throw new Error('Invalid input: only API constant is allowed'); } var b = bData; var f = isFunction(b[behaviour.name()]) ? b[behaviour.name()] : function () { throw new Error('Could not find ' + behaviour.name() + ' in ' + Json.stringify(spec, null, 2)); }; return f(); }; var hasConfigured = function (behaviour) { return isFunction(bData[behaviour.name()]); }; var readState = function (behaviourName) { return bData[behaviourName]().map(function (b) { return b.state.readState(); }).getOr('not enabled'); }; var me = ComponentApi({ getSystem: systemApi.get, config: config, hasConfigured: hasConfigured, spec: constant(spec), readState: readState, connect: connect, disconnect: disconnect, element: constant(item), syncComponents: syncComponents, components: subcomponents.get, events: constant(events) }); return me; }; var buildSubcomponents = function (spec) { var components = readOr$1('components', [])(spec); return map$1(components, build$1); }; var buildFromSpec = function (userSpec) { var spec = make$1(userSpec); var components = buildSubcomponents(spec); var completeSpec = deepMerge(DefaultEvents, spec, wrap$1('components', components)); return Result.value(build(completeSpec)); }; var text = function (textContent) { var element = Element.fromText(textContent); return external({ element: element }); }; var external = function (spec) { var extSpec = asStructOrDie('external.component', objOfOnly([ strict$1('element'), option('uid') ]), spec); var systemApi = Cell(NoContextApi()); var connect = function (newApi) { systemApi.set(newApi); }; var disconnect = function () { systemApi.set(NoContextApi(function () { return me; })); }; extSpec.uid().each(function (uid) { writeOnly(extSpec.element(), uid); }); var me = ComponentApi({ getSystem: systemApi.get, config: Option.none, hasConfigured: constant(false), connect: connect, disconnect: disconnect, element: constant(extSpec.element()), spec: constant(spec), readState: constant('No state'), syncComponents: noop, components: constant([]), events: constant({}) }); return premade(me); }; var build$1 = function (spec) { return getPremade(spec).fold(function () { var userSpecWithUid = deepMerge({ uid: generate$3('') }, spec); return buildFromSpec(userSpecWithUid).getOrDie(); }, function (prebuilt) { return prebuilt; }); }; var premade$1 = premade; var hoverEvent = 'alloy.item-hover'; var focusEvent = 'alloy.item-focus'; var onHover = function (item) { if (search(item.element()).isNone() || Focusing.isFocused(item)) { if (!Focusing.isFocused(item)) { Focusing.focus(item); } emitWith(item, hoverEvent, { item: item }); } }; var onFocus = function (item) { emitWith(item, focusEvent, { item: item }); }; var hover = constant(hoverEvent); var focus$3 = constant(focusEvent); var builder = function (detail) { return { dom: deepMerge(detail.dom(), { attributes: { role: detail.toggling().isSome() ? 'menuitemcheckbox' : 'menuitem' } }), behaviours: deepMerge(derive$1([ detail.toggling().fold(Toggling.revoke, function (tConfig) { return Toggling.config(deepMerge({ aria: { mode: 'checked' } }, tConfig)); }), Focusing.config({ ignore: detail.ignoreFocus(), onFocus: function (component) { onFocus(component); } }), Keying.config({ mode: 'execution' }), Representing.config({ store: { mode: 'memory', initialValue: detail.data() } }) ]), detail.itemBehaviours()), events: derive([ runWithTarget(tapOrClick(), emitExecute), cutter(mousedown()), run(mouseover(), onHover), run(focusItem(), Focusing.focus) ]), components: detail.components(), domModification: detail.domModification(), eventOrder: detail.eventOrder() }; }; var schema$a = [ strict$1('data'), strict$1('components'), strict$1('dom'), option('toggling'), defaulted$1('itemBehaviours', {}), defaulted$1('ignoreFocus', false), defaulted$1('domModification', {}), output('builder', builder), defaulted$1('eventOrder', {}) ]; var builder$1 = function (detail) { return { dom: detail.dom(), components: detail.components(), events: derive([stopper(focusItem())]) }; }; var schema$b = [ strict$1('dom'), strict$1('components'), output('builder', builder$1) ]; var owner$2 = function () { return 'item-widget'; }; var parts = constant([required({ name: 'widget', overrides: function (detail) { return { behaviours: derive$1([Representing.config({ store: { mode: 'manual', getValue: function (component) { return detail.data(); }, setValue: function () { } } })]) }; } })]); var builder$2 = function (detail) { var subs = substitutes(owner$2(), detail, parts()); var components$1 = components(owner$2(), detail, subs.internals()); var focusWidget = function (component) { return getPart(component, detail, 'widget').map(function (widget) { Keying.focusIn(widget); return widget; }); }; var onHorizontalArrow = function (component, simulatedEvent) { return inside(simulatedEvent.event().target()) ? Option.none() : function () { if (detail.autofocus()) { simulatedEvent.setSource(component.element()); return Option.none(); } else { return Option.none(); } }(); }; return deepMerge({ dom: detail.dom(), components: components$1, domModification: detail.domModification(), events: derive([ runOnExecute(function (component, simulatedEvent) { focusWidget(component).each(function (widget) { simulatedEvent.stop(); }); }), run(mouseover(), onHover), run(focusItem(), function (component, simulatedEvent) { if (detail.autofocus()) { focusWidget(component); } else { Focusing.focus(component); } }) ]), behaviours: derive$1([ Representing.config({ store: { mode: 'memory', initialValue: detail.data() } }), Focusing.config({ onFocus: function (component) { onFocus(component); } }), Keying.config({ mode: 'special', focusIn: detail.autofocus() ? function (component) { focusWidget(component); } : revoke(), onLeft: onHorizontalArrow, onRight: onHorizontalArrow, onEscape: function (component, simulatedEvent) { if (!Focusing.isFocused(component) && !detail.autofocus()) { Focusing.focus(component); return Option.some(true); } else if (detail.autofocus()) { simulatedEvent.setSource(component.element()); return Option.none(); } else { return Option.none(); } } }) ]) }); }; var schema$c = [ strict$1('uid'), strict$1('data'), strict$1('components'), strict$1('dom'), defaulted$1('autofocus', false), defaulted$1('domModification', {}), defaultUidsSchema(parts()), output('builder', builder$2) ]; var itemSchema$1 = choose$1('type', { widget: schema$c, item: schema$a, separator: schema$b }); var configureGrid = function (detail, movementInfo) { return { mode: 'flatgrid', selector: '.' + detail.markers().item(), initSize: { numColumns: movementInfo.initSize().numColumns(), numRows: movementInfo.initSize().numRows() }, focusManager: detail.focusManager() }; }; var configureMenu = function (detail, movementInfo) { return { mode: 'menu', selector: '.' + detail.markers().item(), moveOnTab: movementInfo.moveOnTab(), focusManager: detail.focusManager() }; }; var parts$1 = constant([group({ factory: { sketch: function (spec) { var itemInfo = asStructOrDie('menu.spec item', itemSchema$1, spec); return itemInfo.builder()(itemInfo); } }, name: 'items', unit: 'item', defaults: function (detail, u) { var fallbackUid = generate$3(''); return deepMerge({ uid: fallbackUid }, u); }, overrides: function (detail, u) { return { type: u.type, ignoreFocus: detail.fakeFocus(), domModification: { classes: [detail.markers().item()] } }; } })]); var schema$d = constant([ strict$1('value'), strict$1('items'), strict$1('dom'), strict$1('components'), defaulted$1('eventOrder', {}), field$1('menuBehaviours', [ Highlighting, Representing, Composing, Keying ]), defaultedOf('movement', { mode: 'menu', moveOnTab: true }, choose$1('mode', { grid: [ initSize(), output('config', configureGrid) ], menu: [ defaulted$1('moveOnTab', true), output('config', configureMenu) ] })), itemMarkers(), defaulted$1('fakeFocus', false), defaulted$1('focusManager', dom()), onHandler('onHighlight') ]); var focus$4 = constant('alloy.menu-focus'); var make$2 = function (detail, components, spec, externals) { return deepMerge({ dom: deepMerge(detail.dom(), { attributes: { role: 'menu' } }), uid: detail.uid(), behaviours: deepMerge(derive$1([ Highlighting.config({ highlightClass: detail.markers().selectedItem(), itemClass: detail.markers().item(), onHighlight: detail.onHighlight() }), Representing.config({ store: { mode: 'memory', initialValue: detail.value() } }), Composing.config({ find: Option.some }), Keying.config(detail.movement().config()(detail, detail.movement())) ]), get$5(detail.menuBehaviours())), events: derive([ run(focus$3(), function (menu, simulatedEvent) { var event = simulatedEvent.event(); menu.getSystem().getByDom(event.target()).each(function (item) { Highlighting.highlight(menu, item); simulatedEvent.stop(); emitWith(menu, focus$4(), { menu: menu, item: item }); }); }), run(hover(), function (menu, simulatedEvent) { var item = simulatedEvent.event().item(); Highlighting.highlight(menu, item); }) ]), components: components, eventOrder: detail.eventOrder() }); }; var Menu = composite$1({ name: 'Menu', configFields: schema$d(), partFields: parts$1(), factory: make$2 }); var preserve$1 = function (f, container) { var ownerDoc = owner(container); var refocus = active(ownerDoc).bind(function (focused) { var hasFocus = function (elem) { return eq(focused, elem); }; return hasFocus(container) ? Option.some(container) : descendant(container, hasFocus); }); var result = f(container); refocus.each(function (oldFocus) { active(ownerDoc).filter(function (newFocus) { return eq(newFocus, oldFocus); }).fold(function () { focus$1(oldFocus); }, noop); }); return result; }; var set$6 = function (component, replaceConfig, replaceState, data) { detachChildren(component); preserve$1(function () { var children = map$1(data, component.getSystem().build); each$1(children, function (l) { attach(component, l); }); }, component.element()); }; var insert = function (component, replaceConfig, insertion, childSpec) { var child = component.getSystem().build(childSpec); attachWith(component, child, insertion); }; var append$2 = function (component, replaceConfig, replaceState, appendee) { insert(component, replaceConfig, append, appendee); }; var prepend$1 = function (component, replaceConfig, replaceState, prependee) { insert(component, replaceConfig, prepend, prependee); }; var remove$7 = function (component, replaceConfig, replaceState, removee) { var children = contents(component, replaceConfig); var foundChild = find$1(children, function (child) { return eq(removee.element(), child.element()); }); foundChild.each(detach); }; var contents = function (component, replaceConfig) { return component.components(); }; var ReplaceApis = /*#__PURE__*/Object.freeze({ append: append$2, prepend: prepend$1, remove: remove$7, set: set$6, contents: contents }); var Replacing = create$1({ fields: [], name: 'replacing', apis: ReplaceApis }); var transpose = function (obj) { return tupleMap(obj, function (v, k) { return { k: v, v: k }; }); }; var trace = function (items, byItem, byMenu, finish) { return readOptFrom$1(byMenu, finish).bind(function (triggerItem) { return readOptFrom$1(items, triggerItem).bind(function (triggerMenu) { var rest = trace(items, byItem, byMenu, triggerMenu); return Option.some([triggerMenu].concat(rest)); }); }).getOr([]); }; var generate$5 = function (menus, expansions) { var items = {}; each(menus, function (menuItems, menu) { each$1(menuItems, function (item) { items[item] = menu; }); }); var byItem = expansions; var byMenu = transpose(expansions); var menuPaths = map(byMenu, function (_triggerItem, submenu) { return [submenu].concat(trace(items, byItem, byMenu, submenu)); }); return map(items, function (menu) { return readOptFrom$1(menuPaths, menu).getOr([menu]); }); }; var init$3 = function () { var expansions = Cell({}); var menus = Cell({}); var paths = Cell({}); var primary = Cell(Option.none()); var directory = Cell({}); var clear = function () { expansions.set({}); menus.set({}); paths.set({}); primary.set(Option.none()); }; var isClear = function () { return primary.get().isNone(); }; var setContents = function (sPrimary, sMenus, sExpansions, dir) { primary.set(Option.some(sPrimary)); expansions.set(sExpansions); menus.set(sMenus); directory.set(dir); var sPaths = generate$5(dir, sExpansions); paths.set(sPaths); }; var expand = function (itemValue) { return readOptFrom$1(expansions.get(), itemValue).map(function (menu) { var current = readOptFrom$1(paths.get(), itemValue).getOr([]); return [menu].concat(current); }); }; var collapse = function (itemValue) { return readOptFrom$1(paths.get(), itemValue).bind(function (path) { return path.length > 1 ? Option.some(path.slice(1)) : Option.none(); }); }; var refresh = function (itemValue) { return readOptFrom$1(paths.get(), itemValue); }; var lookupMenu = function (menuValue) { return readOptFrom$1(menus.get(), menuValue); }; var otherMenus = function (path) { var menuValues = directory.get(); return difference(keys(menuValues), path); }; var getPrimary = function () { return primary.get().bind(lookupMenu); }; var getMenus = function () { return menus.get(); }; return { setContents: setContents, expand: expand, refresh: refresh, collapse: collapse, lookupMenu: lookupMenu, otherMenus: otherMenus, getPrimary: getPrimary, getMenus: getMenus, clear: clear, isClear: isClear }; }; var LayeredState = { init: init$3 }; var make$3 = function (detail, rawUiSpec) { var buildMenus = function (container, menus) { return map(menus, function (spec, name) { var data = Menu.sketch(deepMerge(spec, { value: name, items: spec.items, markers: narrow$1(rawUiSpec.markers, [ 'item', 'selectedItem' ]), fakeFocus: detail.fakeFocus(), onHighlight: detail.onHighlight(), focusManager: detail.fakeFocus() ? highlights() : dom() })); return container.getSystem().build(data); }); }; var layeredState = LayeredState.init(); var setup = function (container) { var componentMap = buildMenus(container, detail.data().menus()); var directory = toDirectory(container); layeredState.setContents(detail.data().primary(), componentMap, detail.data().expansions(), directory); return layeredState.getPrimary(); }; var getItemValue = function (item) { return Representing.getValue(item).value; }; var toDirectory = function (container) { return map(detail.data().menus(), function (data, menuName) { return bind(data.items, function (item) { return item.type === 'separator' ? [] : [item.data.value]; }); }); }; var setActiveMenu = function (container, menu) { Highlighting.highlight(container, menu); Highlighting.getHighlighted(menu).orThunk(function () { return Highlighting.getFirst(menu); }).each(function (item) { dispatch(container, item.element(), focusItem()); }); }; var getMenus = function (state, menuValues) { return cat(map$1(menuValues, state.lookupMenu)); }; var updateMenuPath = function (container, state, path) { return Option.from(path[0]).bind(state.lookupMenu).map(function (activeMenu) { var rest = getMenus(state, path.slice(1)); each$1(rest, function (r) { add$2(r.element(), detail.markers().backgroundMenu()); }); if (!inBody(activeMenu.element())) { Replacing.append(container, premade$1(activeMenu)); } remove$6(activeMenu.element(), [detail.markers().backgroundMenu()]); setActiveMenu(container, activeMenu); var others = getMenus(state, state.otherMenus(path)); each$1(others, function (o) { remove$6(o.element(), [detail.markers().backgroundMenu()]); if (!detail.stayInDom()) { Replacing.remove(container, o); } }); return activeMenu; }); }; var expandRight = function (container, item) { var value = getItemValue(item); return layeredState.expand(value).bind(function (path) { Option.from(path[0]).bind(layeredState.lookupMenu).each(function (activeMenu) { if (!inBody(activeMenu.element())) { Replacing.append(container, premade$1(activeMenu)); } detail.onOpenSubmenu()(container, item, activeMenu); Highlighting.highlightFirst(activeMenu); }); return updateMenuPath(container, layeredState, path); }); }; var collapseLeft = function (container, item) { var value = getItemValue(item); return layeredState.collapse(value).bind(function (path) { return updateMenuPath(container, layeredState, path).map(function (activeMenu) { detail.onCollapseMenu()(container, item, activeMenu); return activeMenu; }); }); }; var updateView = function (container, item) { var value = getItemValue(item); return layeredState.refresh(value).bind(function (path) { return updateMenuPath(container, layeredState, path); }); }; var onRight = function (container, item) { return inside(item.element()) ? Option.none() : expandRight(container, item); }; var onLeft = function (container, item) { return inside(item.element()) ? Option.none() : collapseLeft(container, item); }; var onEscape = function (container, item) { return collapseLeft(container, item).orThunk(function () { return detail.onEscape()(container, item).map(function () { return container; }); }); }; var keyOnItem = function (f) { return function (container, simulatedEvent) { return closest$1(simulatedEvent.getSource(), '.' + detail.markers().item()).bind(function (target) { return container.getSystem().getByDom(target).toOption().bind(function (item) { return f(container, item).map(function () { return true; }); }); }); }; }; var events = derive([ run(focus$4(), function (sandbox, simulatedEvent) { var menu = simulatedEvent.event().menu(); Highlighting.highlight(sandbox, menu); }), runOnExecute(function (component, simulatedEvent) { var target = simulatedEvent.event().target(); component.getSystem().getByDom(target).each(function (item) { var itemValue = getItemValue(item); if (itemValue.indexOf('collapse-item') === 0) { collapseLeft(component, item); } expandRight(component, item).fold(function () { detail.onExecute()(component, item); }, function () { }); }); }), runOnAttached(function (container, simulatedEvent) { setup(container).each(function (primary) { Replacing.append(container, premade$1(primary)); if (detail.openImmediately()) { setActiveMenu(container, primary); detail.onOpenMenu()(container, primary); } }); }) ].concat(detail.navigateOnHover() ? [run(hover(), function (sandbox, simulatedEvent) { var item = simulatedEvent.event().item(); updateView(sandbox, item); expandRight(sandbox, item); detail.onHover()(sandbox, item); })] : [])); var collapseMenuApi = function (container) { Highlighting.getHighlighted(container).each(function (currentMenu) { Highlighting.getHighlighted(currentMenu).each(function (currentItem) { collapseLeft(container, currentItem); }); }); }; return { uid: detail.uid(), dom: detail.dom(), behaviours: deepMerge(derive$1([ Keying.config({ mode: 'special', onRight: keyOnItem(onRight), onLeft: keyOnItem(onLeft), onEscape: keyOnItem(onEscape), focusIn: function (container, keyInfo) { layeredState.getPrimary().each(function (primary) { dispatch(container, primary.element(), focusItem()); }); } }), Highlighting.config({ highlightClass: detail.markers().selectedMenu(), itemClass: detail.markers().menu() }), Composing.config({ find: function (container) { return Highlighting.getHighlighted(container); } }), Replacing.config({}) ]), get$5(detail.tmenuBehaviours())), eventOrder: detail.eventOrder(), apis: { collapseMenu: collapseMenuApi }, events: events }; }; var collapseItem = constant('collapse-item'); var tieredData = function (primary, menus, expansions) { return { primary: primary, menus: menus, expansions: expansions }; }; var singleData = function (name, menu) { return { primary: name, menus: wrap$1(name, menu), expansions: {} }; }; var collapseItem$1 = function (text) { return { value: generate$1(collapseItem()), text: text }; }; var tieredMenu = single$2({ name: 'TieredMenu', configFields: [ onStrictKeyboardHandler('onExecute'), onStrictKeyboardHandler('onEscape'), onStrictHandler('onOpenMenu'), onStrictHandler('onOpenSubmenu'), onHandler('onCollapseMenu'), defaulted$1('openImmediately', true), strictObjOf('data', [ strict$1('primary'), strict$1('menus'), strict$1('expansions') ]), defaulted$1('fakeFocus', false), onHandler('onHighlight'), onHandler('onHover'), tieredMenuMarkers(), strict$1('dom'), defaulted$1('navigateOnHover', true), defaulted$1('stayInDom', false), field$1('tmenuBehaviours', [ Keying, Highlighting, Composing, Replacing ]), defaulted$1('eventOrder', {}) ], apis: { collapseMenu: function (apis, tmenu) { apis.collapseMenu(tmenu); } }, factory: make$3, extraApis: { tieredData: tieredData, singleData: singleData, collapseItem: collapseItem$1 } }); var findRoute = function (component, transConfig, transState, route) { return readOptFrom$1(transConfig.routes(), route.start()).map(apply).bind(function (sConfig) { return readOptFrom$1(sConfig, route.destination()).map(apply); }); }; var getTransition = function (comp, transConfig, transState) { var route = getCurrentRoute(comp, transConfig, transState); return route.bind(function (r) { return getTransitionOf(comp, transConfig, transState, r); }); }; var getTransitionOf = function (comp, transConfig, transState, route) { return findRoute(comp, transConfig, transState, route).bind(function (r) { return r.transition().map(function (t) { return { transition: constant(t), route: constant(r) }; }); }); }; var disableTransition = function (comp, transConfig, transState) { getTransition(comp, transConfig, transState).each(function (routeTransition) { var t = routeTransition.transition(); remove$4(comp.element(), t.transitionClass()); remove$1(comp.element(), transConfig.destinationAttr()); }); }; var getNewRoute = function (comp, transConfig, transState, destination) { return { start: constant(get(comp.element(), transConfig.stateAttr())), destination: constant(destination) }; }; var getCurrentRoute = function (comp, transConfig, transState) { var el = comp.element(); return has(el, transConfig.destinationAttr()) ? Option.some({ start: constant(get(comp.element(), transConfig.stateAttr())), destination: constant(get(comp.element(), transConfig.destinationAttr())) }) : Option.none(); }; var jumpTo = function (comp, transConfig, transState, destination) { disableTransition(comp, transConfig, transState); if (has(comp.element(), transConfig.stateAttr()) && get(comp.element(), transConfig.stateAttr()) !== destination) { transConfig.onFinish()(comp, destination); } set(comp.element(), transConfig.stateAttr(), destination); }; var fasttrack = function (comp, transConfig, transState, destination) { if (has(comp.element(), transConfig.destinationAttr())) { set(comp.element(), transConfig.stateAttr(), get(comp.element(), transConfig.destinationAttr())); remove$1(comp.element(), transConfig.destinationAttr()); } }; var progressTo = function (comp, transConfig, transState, destination) { fasttrack(comp, transConfig, transState, destination); var route = getNewRoute(comp, transConfig, transState, destination); getTransitionOf(comp, transConfig, transState, route).fold(function () { jumpTo(comp, transConfig, transState, destination); }, function (routeTransition) { disableTransition(comp, transConfig, transState); var t = routeTransition.transition(); add$2(comp.element(), t.transitionClass()); set(comp.element(), transConfig.destinationAttr(), destination); }); }; var getState = function (comp, transConfig, transState) { var e = comp.element(); return has(e, transConfig.stateAttr()) ? Option.some(get(e, transConfig.stateAttr())) : Option.none(); }; var TransitionApis = /*#__PURE__*/Object.freeze({ findRoute: findRoute, disableTransition: disableTransition, getCurrentRoute: getCurrentRoute, jumpTo: jumpTo, progressTo: progressTo, getState: getState }); var events$9 = function (transConfig, transState) { return derive([ run(transitionend(), function (component, simulatedEvent) { var raw = simulatedEvent.event().raw(); getCurrentRoute(component, transConfig, transState).each(function (route) { findRoute(component, transConfig, transState, route).each(function (rInfo) { rInfo.transition().each(function (rTransition) { if (raw.propertyName === rTransition.property()) { jumpTo(component, transConfig, transState, route.destination()); transConfig.onTransition()(component, route); } }); }); }); }), runOnAttached(function (comp, se) { jumpTo(comp, transConfig, transState, transConfig.initialState()); }) ]); }; var ActiveTransitioning = /*#__PURE__*/Object.freeze({ events: events$9 }); var TransitionSchema = [ defaulted$1('destinationAttr', 'data-transitioning-destination'), defaulted$1('stateAttr', 'data-transitioning-state'), strict$1('initialState'), onHandler('onTransition'), onHandler('onFinish'), strictOf('routes', setOf(Result.value, setOf(Result.value, objOfOnly([optionObjOfOnly('transition', [ strict$1('property'), strict$1('transitionClass') ])])))) ]; var createRoutes = function (routes) { var r = {}; each(routes, function (v, k) { var waypoints = k.split('<->'); r[waypoints[0]] = wrap$1(waypoints[1], v); r[waypoints[1]] = wrap$1(waypoints[0], v); }); return r; }; var createBistate = function (first, second, transitions) { return wrapAll$1([ { key: first, value: wrap$1(second, transitions) }, { key: second, value: wrap$1(first, transitions) } ]); }; var createTristate = function (first, second, third, transitions) { return wrapAll$1([ { key: first, value: wrapAll$1([ { key: second, value: transitions }, { key: third, value: transitions } ]) }, { key: second, value: wrapAll$1([ { key: first, value: transitions }, { key: third, value: transitions } ]) }, { key: third, value: wrapAll$1([ { key: first, value: transitions }, { key: second, value: transitions } ]) } ]); }; var Transitioning = create$1({ fields: TransitionSchema, name: 'transitioning', active: ActiveTransitioning, apis: TransitionApis, extra: { createRoutes: createRoutes, createBistate: createBistate, createTristate: createTristate } }); var scrollable = Styles.resolve('scrollable'); var register = function (element) { add$2(element, scrollable); }; var deregister = function (element) { remove$4(element, scrollable); }; var Scrollable = { register: register, deregister: deregister, scrollable: constant(scrollable) }; var getValue$4 = function (item) { return readOptFrom$1(item, 'format').getOr(item.title); }; var convert$1 = function (formats, memMenuThunk) { var mainMenu = makeMenu('Styles', [].concat(map$1(formats.items, function (k) { return makeItem(getValue$4(k), k.title, k.isSelected(), k.getPreview(), hasKey$1(formats.expansions, getValue$4(k))); })), memMenuThunk, false); var submenus = map(formats.menus, function (menuItems, menuName) { var items = map$1(menuItems, function (item) { return makeItem(getValue$4(item), item.title, item.isSelected !== undefined ? item.isSelected() : false, item.getPreview !== undefined ? item.getPreview() : '', hasKey$1(formats.expansions, getValue$4(item))); }); return makeMenu(menuName, items, memMenuThunk, true); }); var menus = deepMerge(submenus, wrap$1('styles', mainMenu)); var tmenu = tieredMenu.tieredData('styles', menus, formats.expansions); return { tmenu: tmenu }; }; var makeItem = function (value, text, selected, preview, isMenu) { return { data: { value: value, text: text }, type: 'item', dom: { tag: 'div', classes: isMenu ? [Styles.resolve('styles-item-is-menu')] : [] }, toggling: { toggleOnExecute: false, toggleClass: Styles.resolve('format-matches'), selected: selected }, itemBehaviours: derive$1(isMenu ? [] : [Receivers.format(value, function (comp, status) { var toggle = status ? Toggling.on : Toggling.off; toggle(comp); })]), components: [{ dom: { tag: 'div', attributes: { style: preview }, innerHtml: text } }] }; }; var makeMenu = function (value, items, memMenuThunk, collapsable) { return { value: value, dom: { tag: 'div' }, components: [ Button.sketch({ dom: { tag: 'div', classes: [Styles.resolve('styles-collapser')] }, components: collapsable ? [ { dom: { tag: 'span', classes: [Styles.resolve('styles-collapse-icon')] } }, text(value) ] : [text(value)], action: function (item) { if (collapsable) { var comp = memMenuThunk().get(item); tieredMenu.collapseMenu(comp); } } }), { dom: { tag: 'div', classes: [Styles.resolve('styles-menu-items-container')] }, components: [Menu.parts().items({})], behaviours: derive$1([config('adhoc-scrollable-menu', [ runOnAttached(function (component, simulatedEvent) { set$2(component.element(), 'overflow-y', 'auto'); set$2(component.element(), '-webkit-overflow-scrolling', 'touch'); Scrollable.register(component.element()); }), runOnDetached(function (component) { remove$5(component.element(), 'overflow-y'); remove$5(component.element(), '-webkit-overflow-scrolling'); Scrollable.deregister(component.element()); }) ])]) } ], items: items, menuBehaviours: derive$1([Transitioning.config({ initialState: 'after', routes: Transitioning.createTristate('before', 'current', 'after', { transition: { property: 'transform', transitionClass: 'transitioning' } }) })]) }; }; var sketch$8 = function (settings) { var dataset = convert$1(settings.formats, function () { return memMenu; }); var memMenu = record(tieredMenu.sketch({ dom: { tag: 'div', classes: [Styles.resolve('styles-menu')] }, components: [], fakeFocus: true, stayInDom: true, onExecute: function (tmenu, item) { var v = Representing.getValue(item); settings.handle(item, v.value); return Option.none(); }, onEscape: function () { return Option.none(); }, onOpenMenu: function (container, menu) { var w = get$6(container.element()); set$3(menu.element(), w); Transitioning.jumpTo(menu, 'current'); }, onOpenSubmenu: function (container, item, submenu) { var w = get$6(container.element()); var menu = ancestor$1(item.element(), '[role="menu"]').getOrDie('hacky'); var menuComp = container.getSystem().getByDom(menu).getOrDie(); set$3(submenu.element(), w); Transitioning.progressTo(menuComp, 'before'); Transitioning.jumpTo(submenu, 'after'); Transitioning.progressTo(submenu, 'current'); }, onCollapseMenu: function (container, item, menu) { var submenu = ancestor$1(item.element(), '[role="menu"]').getOrDie('hacky'); var submenuComp = container.getSystem().getByDom(submenu).getOrDie(); Transitioning.progressTo(submenuComp, 'after'); Transitioning.progressTo(menu, 'current'); }, navigateOnHover: false, openImmediately: true, data: dataset.tmenu, markers: { backgroundMenu: Styles.resolve('styles-background-menu'), menu: Styles.resolve('styles-menu'), selectedMenu: Styles.resolve('styles-selected-menu'), item: Styles.resolve('styles-item'), selectedItem: Styles.resolve('styles-selected-item') } })); return memMenu.asSpec(); }; var StylesMenu = { sketch: sketch$8 }; var getFromExpandingItem = function (item) { var newItem = deepMerge(exclude$1(item, ['items']), { menu: true }); var rest = expand(item.items); var newMenus = deepMerge(rest.menus, wrap$1(item.title, rest.items)); var newExpansions = deepMerge(rest.expansions, wrap$1(item.title, item.title)); return { item: newItem, menus: newMenus, expansions: newExpansions }; }; var getFromItem = function (item) { return hasKey$1(item, 'items') ? getFromExpandingItem(item) : { item: item, menus: {}, expansions: {} }; }; var expand = function (items) { return foldr(items, function (acc, item) { var newData = getFromItem(item); return { menus: deepMerge(acc.menus, newData.menus), items: [newData.item].concat(acc.items), expansions: deepMerge(acc.expansions, newData.expansions) }; }, { menus: {}, expansions: {}, items: [] }); }; var StyleConversions = { expand: expand }; var register$1 = function (editor, settings) { var isSelectedFor = function (format) { return function () { return editor.formatter.match(format); }; }; var getPreview = function (format) { return function () { var styles = editor.formatter.getCssText(format); return styles; }; }; var enrichSupported = function (item) { return deepMerge(item, { isSelected: isSelectedFor(item.format), getPreview: getPreview(item.format) }); }; var enrichMenu = function (item) { return deepMerge(item, { isSelected: constant(false), getPreview: constant('') }); }; var enrichCustom = function (item) { var formatName = generate$1(item.title); var newItem = deepMerge(item, { format: formatName, isSelected: isSelectedFor(formatName), getPreview: getPreview(formatName) }); editor.formatter.register(formatName, newItem); return newItem; }; var formats = readOptFrom$1(settings, 'style_formats').getOr(DefaultStyleFormats); var doEnrich = function (items) { return map$1(items, function (item) { if (hasKey$1(item, 'items')) { var newItems = doEnrich(item.items); return deepMerge(enrichMenu(item), { items: newItems }); } else if (hasKey$1(item, 'format')) { return enrichSupported(item); } else { return enrichCustom(item); } }); }; return doEnrich(formats); }; var prune = function (editor, formats) { var doPrune = function (items) { return bind(items, function (item) { if (item.items !== undefined) { var newItems = doPrune(item.items); return newItems.length > 0 ? [item] : []; } else { var keep = hasKey$1(item, 'format') ? editor.formatter.canApply(item.format) : true; return keep ? [item] : []; } }); }; var prunedItems = doPrune(formats); return StyleConversions.expand(prunedItems); }; var ui = function (editor, formats, onDone) { var pruned = prune(editor, formats); return StylesMenu.sketch({ formats: pruned, handle: function (item, value) { editor.undoManager.transact(function () { if (Toggling.isOn(item)) { editor.formatter.remove(value); } else { editor.formatter.apply(value); } }); onDone(); } }); }; var StyleFormats = { register: register$1, ui: ui }; var defaults = [ 'undo', 'bold', 'italic', 'link', 'image', 'bullist', 'styleselect' ]; var extract$1 = function (rawToolbar) { var toolbar = rawToolbar.replace(/\|/g, ' ').trim(); return toolbar.length > 0 ? toolbar.split(/\s+/) : []; }; var identifyFromArray = function (toolbar) { return bind(toolbar, function (item) { return isArray(item) ? identifyFromArray(item) : extract$1(item); }); }; var identify = function (settings) { var toolbar = settings.toolbar !== undefined ? settings.toolbar : defaults; return isArray(toolbar) ? identifyFromArray(toolbar) : extract$1(toolbar); }; var setup = function (realm, editor) { var commandSketch = function (name) { return function () { return Buttons.forToolbarCommand(editor, name); }; }; var stateCommandSketch = function (name) { return function () { return Buttons.forToolbarStateCommand(editor, name); }; }; var actionSketch = function (name, query, action) { return function () { return Buttons.forToolbarStateAction(editor, name, query, action); }; }; var undo = commandSketch('undo'); var redo = commandSketch('redo'); var bold = stateCommandSketch('bold'); var italic = stateCommandSketch('italic'); var underline = stateCommandSketch('underline'); var removeformat = commandSketch('removeformat'); var link = function () { return sketch$7(realm, editor); }; var unlink = actionSketch('unlink', 'link', function () { editor.execCommand('unlink', null, false); }); var image = function () { return sketch$4(editor); }; var bullist = actionSketch('unordered-list', 'ul', function () { editor.execCommand('InsertUnorderedList', null, false); }); var numlist = actionSketch('ordered-list', 'ol', function () { editor.execCommand('InsertOrderedList', null, false); }); var fontsizeselect = function () { return sketch$3(realm, editor); }; var forecolor = function () { return ColorSlider.sketch(realm, editor); }; var styleFormats = StyleFormats.register(editor, editor.settings); var styleFormatsMenu = function () { return StyleFormats.ui(editor, styleFormats, function () { editor.fire('scrollIntoView'); }); }; var styleselect = function () { return Buttons.forToolbar('style-formats', function (button) { editor.fire('toReading'); realm.dropup().appear(styleFormatsMenu, Toggling.on, button); }, derive$1([ Toggling.config({ toggleClass: Styles.resolve('toolbar-button-selected'), toggleOnExecute: false, aria: { mode: 'pressed' } }), Receiving.config({ channels: wrapAll$1([ Receivers.receive(TinyChannels.orientationChanged(), Toggling.off), Receivers.receive(TinyChannels.dropupDismissed(), Toggling.off) ]) }) ])); }; var feature = function (prereq, sketch) { return { isSupported: function () { return prereq.forall(function (p) { return hasKey$1(editor.buttons, p); }); }, sketch: sketch }; }; return { undo: feature(Option.none(), undo), redo: feature(Option.none(), redo), bold: feature(Option.none(), bold), italic: feature(Option.none(), italic), underline: feature(Option.none(), underline), removeformat: feature(Option.none(), removeformat), link: feature(Option.none(), link), unlink: feature(Option.none(), unlink), image: feature(Option.none(), image), bullist: feature(Option.some('bullist'), bullist), numlist: feature(Option.some('numlist'), numlist), fontsizeselect: feature(Option.none(), fontsizeselect), forecolor: feature(Option.none(), forecolor), styleselect: feature(Option.none(), styleselect) }; }; var detect$4 = function (settings, features) { var itemNames = identify(settings); var present = {}; return bind(itemNames, function (iName) { var r = !hasKey$1(present, iName) && hasKey$1(features, iName) && features[iName].isSupported() ? [features[iName].sketch()] : []; present[iName] = true; return r; }); }; var Features = { identify: identify, setup: setup, detect: detect$4 }; var mkEvent = function (target, x, y, stop, prevent, kill, raw) { return { target: constant(target), x: constant(x), y: constant(y), stop: stop, prevent: prevent, kill: kill, raw: constant(raw) }; }; var handle = function (filter, handler) { return function (rawEvent) { if (!filter(rawEvent)) { return; } var target = Element.fromDom(rawEvent.target); var stop = function () { rawEvent.stopPropagation(); }; var prevent = function () { rawEvent.preventDefault(); }; var kill = compose(prevent, stop); var evt = mkEvent(target, rawEvent.clientX, rawEvent.clientY, stop, prevent, kill, rawEvent); handler(evt); }; }; var binder = function (element, event, filter, handler, useCapture) { var wrapped = handle(filter, handler); element.dom().addEventListener(event, wrapped, useCapture); return { unbind: curry(unbind, element, event, wrapped, useCapture) }; }; var bind$1 = function (element, event, filter, handler) { return binder(element, event, filter, handler, false); }; var capture = function (element, event, filter, handler) { return binder(element, event, filter, handler, true); }; var unbind = function (element, event, handler, useCapture) { element.dom().removeEventListener(event, handler, useCapture); }; var filter$1 = constant(true); var bind$2 = function (element, event, handler) { return bind$1(element, event, filter$1, handler); }; var capture$1 = function (element, event, handler) { return capture(element, event, filter$1, handler); }; var INTERVAL = 50; var INSURANCE = 1000 / INTERVAL; var get$a = function (outerWindow) { var isPortrait = outerWindow.matchMedia('(orientation: portrait)').matches; return { isPortrait: constant(isPortrait) }; }; var getActualWidth = function (outerWindow) { var isIos = PlatformDetection$1.detect().os.isiOS(); var isPortrait = get$a(outerWindow).isPortrait(); return isIos && !isPortrait ? outerWindow.screen.height : outerWindow.screen.width; }; var onChange = function (outerWindow, listeners) { var win = Element.fromDom(outerWindow); var poller = null; var change = function () { clearInterval(poller); var orientation = get$a(outerWindow); listeners.onChange(orientation); onAdjustment(function () { listeners.onReady(orientation); }); }; var orientationHandle = bind$2(win, 'orientationchange', change); var onAdjustment = function (f) { clearInterval(poller); var flag = outerWindow.innerHeight; var insurance = 0; poller = setInterval(function () { if (flag !== outerWindow.innerHeight) { clearInterval(poller); f(Option.some(outerWindow.innerHeight)); } else if (insurance > INSURANCE) { clearInterval(poller); f(Option.none()); } insurance++; }, INTERVAL); }; var destroy = function () { orientationHandle.unbind(); }; return { onAdjustment: onAdjustment, destroy: destroy }; }; var Orientation = { get: get$a, onChange: onChange, getActualWidth: getActualWidth }; function DelayedFunction (fun, delay) { var ref = null; var schedule = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } ref = domGlobals.setTimeout(function () { fun.apply(null, args); ref = null; }, delay); }; var cancel = function () { if (ref !== null) { domGlobals.clearTimeout(ref); ref = null; } }; return { cancel: cancel, schedule: schedule }; } var SIGNIFICANT_MOVE = 5; var LONGPRESS_DELAY = 400; var getTouch = function (event) { var raw = event.raw(); if (raw.touches === undefined || raw.touches.length !== 1) { return Option.none(); } return Option.some(raw.touches[0]); }; var isFarEnough = function (touch, data) { var distX = Math.abs(touch.clientX - data.x()); var distY = Math.abs(touch.clientY - data.y()); return distX > SIGNIFICANT_MOVE || distY > SIGNIFICANT_MOVE; }; var monitor = function (settings) { var startData = Cell(Option.none()); var longpress$1 = DelayedFunction(function (event) { startData.set(Option.none()); settings.triggerEvent(longpress(), event); }, LONGPRESS_DELAY); var handleTouchstart = function (event) { getTouch(event).each(function (touch) { longpress$1.cancel(); var data = { x: constant(touch.clientX), y: constant(touch.clientY), target: event.target }; longpress$1.schedule(event); startData.set(Option.some(data)); }); return Option.none(); }; var handleTouchmove = function (event) { longpress$1.cancel(); getTouch(event).each(function (touch) { startData.get().each(function (data) { if (isFarEnough(touch, data)) { startData.set(Option.none()); } }); }); return Option.none(); }; var handleTouchend = function (event) { longpress$1.cancel(); var isSame = function (data) { return eq(data.target(), event.target()); }; return startData.get().filter(isSame).map(function (data) { return settings.triggerEvent(tap(), event); }); }; var handlers = wrapAll$1([ { key: touchstart(), value: handleTouchstart }, { key: touchmove(), value: handleTouchmove }, { key: touchend(), value: handleTouchend } ]); var fireIfReady = function (event, type) { return readOptFrom$1(handlers, type).bind(function (handler) { return handler(event); }); }; return { fireIfReady: fireIfReady }; }; var monitor$1 = function (editorApi) { var tapEvent = monitor({ triggerEvent: function (type, evt) { editorApi.onTapContent(evt); } }); var onTouchend = function () { return bind$2(editorApi.body(), 'touchend', function (evt) { tapEvent.fireIfReady(evt, 'touchend'); }); }; var onTouchmove = function () { return bind$2(editorApi.body(), 'touchmove', function (evt) { tapEvent.fireIfReady(evt, 'touchmove'); }); }; var fireTouchstart = function (evt) { tapEvent.fireIfReady(evt, 'touchstart'); }; return { fireTouchstart: fireTouchstart, onTouchend: onTouchend, onTouchmove: onTouchmove }; }; var TappingEvent = { monitor: monitor$1 }; var isAndroid6 = PlatformDetection$1.detect().os.version.major >= 6; var initEvents = function (editorApi, toolstrip, alloy) { var tapping = TappingEvent.monitor(editorApi); var outerDoc = owner(toolstrip); var isRanged = function (sel) { return !eq(sel.start(), sel.finish()) || sel.soffset() !== sel.foffset(); }; var hasRangeInUi = function () { return active(outerDoc).filter(function (input) { return name(input) === 'input'; }).exists(function (input) { return input.dom().selectionStart !== input.dom().selectionEnd; }); }; var updateMargin = function () { var rangeInContent = editorApi.doc().dom().hasFocus() && editorApi.getSelection().exists(isRanged); alloy.getByDom(toolstrip).each((rangeInContent || hasRangeInUi()) === true ? Toggling.on : Toggling.off); }; var listeners = [ bind$2(editorApi.body(), 'touchstart', function (evt) { editorApi.onTouchContent(); tapping.fireTouchstart(evt); }), tapping.onTouchmove(), tapping.onTouchend(), bind$2(toolstrip, 'touchstart', function (evt) { editorApi.onTouchToolstrip(); }), editorApi.onToReading(function () { blur(editorApi.body()); }), editorApi.onToEditing(noop), editorApi.onScrollToCursor(function (tinyEvent) { tinyEvent.preventDefault(); editorApi.getCursorBox().each(function (bounds) { var cWin = editorApi.win(); var isOutside = bounds.top() > cWin.innerHeight || bounds.bottom() > cWin.innerHeight; var cScrollBy = isOutside ? bounds.bottom() - cWin.innerHeight + 50 : 0; if (cScrollBy !== 0) { cWin.scrollTo(cWin.pageXOffset, cWin.pageYOffset + cScrollBy); } }); }) ].concat(isAndroid6 === true ? [] : [ bind$2(Element.fromDom(editorApi.win()), 'blur', function () { alloy.getByDom(toolstrip).each(Toggling.off); }), bind$2(outerDoc, 'select', updateMargin), bind$2(editorApi.doc(), 'selectionchange', updateMargin) ]); var destroy = function () { each$1(listeners, function (l) { l.unbind(); }); }; return { destroy: destroy }; }; var AndroidEvents = { initEvents: initEvents }; var safeParse = function (element, attribute) { var parsed = parseInt(get(element, attribute), 10); return isNaN(parsed) ? 0 : parsed; }; var DataAttributes = { safeParse: safeParse }; function NodeValue (is, name) { var get = function (element) { if (!is(element)) { throw new Error('Can only get ' + name + ' value of a ' + name + ' node'); } return getOption(element).getOr(''); }; var getOptionIE10 = function (element) { try { return getOptionSafe(element); } catch (e) { return Option.none(); } }; var getOptionSafe = function (element) { return is(element) ? Option.from(element.dom().nodeValue) : Option.none(); }; var browser = PlatformDetection$1.detect().browser; var getOption = browser.isIE() && browser.version.major === 10 ? getOptionIE10 : getOptionSafe; var set = function (element, value) { if (!is(element)) { throw new Error('Can only set raw ' + name + ' value of a ' + name + ' node'); } element.dom().nodeValue = value; }; return { get: get, getOption: getOption, set: set }; } var api$3 = NodeValue(isText, 'text'); var get$b = function (element) { return api$3.get(element); }; var getOption = function (element) { return api$3.getOption(element); }; var getEnd = function (element) { return name(element) === 'img' ? 1 : getOption(element).fold(function () { return children(element).length; }, function (v) { return v.length; }); }; var NBSP = '\xA0'; var isTextNodeWithCursorPosition = function (el) { return getOption(el).filter(function (text) { return text.trim().length !== 0 || text.indexOf(NBSP) > -1; }).isSome(); }; var elementsWithCursorPosition = [ 'img', 'br' ]; var isCursorPosition = function (elem) { var hasCursorPosition = isTextNodeWithCursorPosition(elem); return hasCursorPosition || contains(elementsWithCursorPosition, name(elem)); }; var adt$4 = Adt.generate([ { before: ['element'] }, { on: [ 'element', 'offset' ] }, { after: ['element'] } ]); var cata = function (subject, onBefore, onOn, onAfter) { return subject.fold(onBefore, onOn, onAfter); }; var getStart = function (situ) { return situ.fold(identity, identity, identity); }; var before$1 = adt$4.before; var on$1 = adt$4.on; var after$1 = adt$4.after; var Situ = { before: before$1, on: on$1, after: after$1, cata: cata, getStart: getStart }; var type$1 = Adt.generate([ { domRange: ['rng'] }, { relative: [ 'startSitu', 'finishSitu' ] }, { exact: [ 'start', 'soffset', 'finish', 'foffset' ] } ]); var range = Immutable('start', 'soffset', 'finish', 'foffset'); var relative = type$1.relative; var exact = type$1.exact; var makeRange = function (start, soffset, finish, foffset) { var doc = owner(start); var rng = doc.dom().createRange(); rng.setStart(start.dom(), soffset); rng.setEnd(finish.dom(), foffset); return rng; }; var after$2 = function (start, soffset, finish, foffset) { var r = makeRange(start, soffset, finish, foffset); var same = eq(start, finish) && soffset === foffset; return r.collapsed && !same; }; var setStart = function (rng, situ) { situ.fold(function (e) { rng.setStartBefore(e.dom()); }, function (e, o) { rng.setStart(e.dom(), o); }, function (e) { rng.setStartAfter(e.dom()); }); }; var setFinish = function (rng, situ) { situ.fold(function (e) { rng.setEndBefore(e.dom()); }, function (e, o) { rng.setEnd(e.dom(), o); }, function (e) { rng.setEndAfter(e.dom()); }); }; var relativeToNative = function (win, startSitu, finishSitu) { var range = win.document.createRange(); setStart(range, startSitu); setFinish(range, finishSitu); return range; }; var exactToNative = function (win, start, soffset, finish, foffset) { var rng = win.document.createRange(); rng.setStart(start.dom(), soffset); rng.setEnd(finish.dom(), foffset); return rng; }; var toRect = function (rect) { return { left: constant(rect.left), top: constant(rect.top), right: constant(rect.right), bottom: constant(rect.bottom), width: constant(rect.width), height: constant(rect.height) }; }; var getFirstRect = function (rng) { var rects = rng.getClientRects(); var rect = rects.length > 0 ? rects[0] : rng.getBoundingClientRect(); return rect.width > 0 || rect.height > 0 ? Option.some(rect).map(toRect) : Option.none(); }; var adt$5 = Adt.generate([ { ltr: [ 'start', 'soffset', 'finish', 'foffset' ] }, { rtl: [ 'start', 'soffset', 'finish', 'foffset' ] } ]); var fromRange = function (win, type, range) { return type(Element.fromDom(range.startContainer), range.startOffset, Element.fromDom(range.endContainer), range.endOffset); }; var getRanges = function (win, selection) { return selection.match({ domRange: function (rng) { return { ltr: constant(rng), rtl: Option.none }; }, relative: function (startSitu, finishSitu) { return { ltr: cached(function () { return relativeToNative(win, startSitu, finishSitu); }), rtl: cached(function () { return Option.some(relativeToNative(win, finishSitu, startSitu)); }) }; }, exact: function (start, soffset, finish, foffset) { return { ltr: cached(function () { return exactToNative(win, start, soffset, finish, foffset); }), rtl: cached(function () { return Option.some(exactToNative(win, finish, foffset, start, soffset)); }) }; } }); }; var doDiagnose = function (win, ranges) { var rng = ranges.ltr(); if (rng.collapsed) { var reversed = ranges.rtl().filter(function (rev) { return rev.collapsed === false; }); return reversed.map(function (rev) { return adt$5.rtl(Element.fromDom(rev.endContainer), rev.endOffset, Element.fromDom(rev.startContainer), rev.startOffset); }).getOrThunk(function () { return fromRange(win, adt$5.ltr, rng); }); } else { return fromRange(win, adt$5.ltr, rng); } }; var diagnose = function (win, selection) { var ranges = getRanges(win, selection); return doDiagnose(win, ranges); }; var asLtrRange = function (win, selection) { var diagnosis = diagnose(win, selection); return diagnosis.match({ ltr: function (start, soffset, finish, foffset) { var rng = win.document.createRange(); rng.setStart(start.dom(), soffset); rng.setEnd(finish.dom(), foffset); return rng; }, rtl: function (start, soffset, finish, foffset) { var rng = win.document.createRange(); rng.setStart(finish.dom(), foffset); rng.setEnd(start.dom(), soffset); return rng; } }); }; var searchForPoint = function (rectForOffset, x, y, maxX, length) { if (length === 0) { return 0; } else if (x === maxX) { return length - 1; } var xDelta = maxX; for (var i = 1; i < length; i++) { var rect = rectForOffset(i); var curDeltaX = Math.abs(x - rect.left); if (y <= rect.bottom) { if (y < rect.top || curDeltaX > xDelta) { return i - 1; } else { xDelta = curDeltaX; } } } return 0; }; var inRect = function (rect, x, y) { return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom; }; var locateOffset = function (doc, textnode, x, y, rect) { var rangeForOffset = function (o) { var r = doc.dom().createRange(); r.setStart(textnode.dom(), o); r.collapse(true); return r; }; var rectForOffset = function (o) { var r = rangeForOffset(o); return r.getBoundingClientRect(); }; var length = get$b(textnode).length; var offset = searchForPoint(rectForOffset, x, y, rect.right, length); return rangeForOffset(offset); }; var locate$1 = function (doc, node, x, y) { var r = doc.dom().createRange(); r.selectNode(node.dom()); var rects = r.getClientRects(); var foundRect = findMap(rects, function (rect) { return inRect(rect, x, y) ? Option.some(rect) : Option.none(); }); return foundRect.map(function (rect) { return locateOffset(doc, node, x, y, rect); }); }; var searchInChildren = function (doc, node, x, y) { var r = doc.dom().createRange(); var nodes = children(node); return findMap(nodes, function (n) { r.selectNode(n.dom()); return inRect(r.getBoundingClientRect(), x, y) ? locateNode(doc, n, x, y) : Option.none(); }); }; var locateNode = function (doc, node, x, y) { var locator = isText(node) ? locate$1 : searchInChildren; return locator(doc, node, x, y); }; var locate$2 = function (doc, node, x, y) { var r = doc.dom().createRange(); r.selectNode(node.dom()); var rect = r.getBoundingClientRect(); var boundedX = Math.max(rect.left, Math.min(rect.right, x)); var boundedY = Math.max(rect.top, Math.min(rect.bottom, y)); return locateNode(doc, node, boundedX, boundedY); }; var first$1 = function (element) { return descendant(element, isCursorPosition); }; var last = function (element) { return descendantRtl(element, isCursorPosition); }; var descendantRtl = function (scope, predicate) { var descend = function (element) { var children$1 = children(element); for (var i = children$1.length - 1; i >= 0; i--) { var child = children$1[i]; if (predicate(child)) { return Option.some(child); } var res = descend(child); if (res.isSome()) { return res; } } return Option.none(); }; return descend(scope); }; var COLLAPSE_TO_LEFT = true; var COLLAPSE_TO_RIGHT = false; var getCollapseDirection = function (rect, x) { return x - rect.left < rect.right - x ? COLLAPSE_TO_LEFT : COLLAPSE_TO_RIGHT; }; var createCollapsedNode = function (doc, target, collapseDirection) { var r = doc.dom().createRange(); r.selectNode(target.dom()); r.collapse(collapseDirection); return r; }; var locateInElement = function (doc, node, x) { var cursorRange = doc.dom().createRange(); cursorRange.selectNode(node.dom()); var rect = cursorRange.getBoundingClientRect(); var collapseDirection = getCollapseDirection(rect, x); var f = collapseDirection === COLLAPSE_TO_LEFT ? first$1 : last; return f(node).map(function (target) { return createCollapsedNode(doc, target, collapseDirection); }); }; var locateInEmpty = function (doc, node, x) { var rect = node.dom().getBoundingClientRect(); var collapseDirection = getCollapseDirection(rect, x); return Option.some(createCollapsedNode(doc, node, collapseDirection)); }; var search$1 = function (doc, node, x) { var f = children(node).length === 0 ? locateInEmpty : locateInElement; return f(doc, node, x); }; var caretPositionFromPoint = function (doc, x, y) { return Option.from(doc.dom().caretPositionFromPoint(x, y)).bind(function (pos) { if (pos.offsetNode === null) { return Option.none(); } var r = doc.dom().createRange(); r.setStart(pos.offsetNode, pos.offset); r.collapse(); return Option.some(r); }); }; var caretRangeFromPoint = function (doc, x, y) { return Option.from(doc.dom().caretRangeFromPoint(x, y)); }; var searchTextNodes = function (doc, node, x, y) { var r = doc.dom().createRange(); r.selectNode(node.dom()); var rect = r.getBoundingClientRect(); var boundedX = Math.max(rect.left, Math.min(rect.right, x)); var boundedY = Math.max(rect.top, Math.min(rect.bottom, y)); return locate$2(doc, node, boundedX, boundedY); }; var searchFromPoint = function (doc, x, y) { return Element.fromPoint(doc, x, y).bind(function (elem) { var fallback = function () { return search$1(doc, elem, x); }; return children(elem).length === 0 ? fallback() : searchTextNodes(doc, elem, x, y).orThunk(fallback); }); }; var availableSearch = document.caretPositionFromPoint ? caretPositionFromPoint : document.caretRangeFromPoint ? caretRangeFromPoint : searchFromPoint; var beforeSpecial = function (element, offset) { var name$1 = name(element); if ('input' === name$1) { return Situ.after(element); } else if (!contains([ 'br', 'img' ], name$1)) { return Situ.on(element, offset); } else { return offset === 0 ? Situ.before(element) : Situ.after(element); } }; var preprocessExact = function (start, soffset, finish, foffset) { var startSitu = beforeSpecial(start, soffset); var finishSitu = beforeSpecial(finish, foffset); return relative(startSitu, finishSitu); }; var doSetNativeRange = function (win, rng) { Option.from(win.getSelection()).each(function (selection) { selection.removeAllRanges(); selection.addRange(rng); }); }; var doSetRange = function (win, start, soffset, finish, foffset) { var rng = exactToNative(win, start, soffset, finish, foffset); doSetNativeRange(win, rng); }; var setLegacyRtlRange = function (win, selection, start, soffset, finish, foffset) { selection.collapse(start.dom(), soffset); selection.extend(finish.dom(), foffset); }; var setRangeFromRelative = function (win, relative) { return diagnose(win, relative).match({ ltr: function (start, soffset, finish, foffset) { doSetRange(win, start, soffset, finish, foffset); }, rtl: function (start, soffset, finish, foffset) { var selection = win.getSelection(); if (selection.setBaseAndExtent) { selection.setBaseAndExtent(start.dom(), soffset, finish.dom(), foffset); } else if (selection.extend) { try { setLegacyRtlRange(win, selection, start, soffset, finish, foffset); } catch (e) { doSetRange(win, finish, foffset, start, soffset); } } else { doSetRange(win, finish, foffset, start, soffset); } } }); }; var setExact = function (win, start, soffset, finish, foffset) { var relative = preprocessExact(start, soffset, finish, foffset); setRangeFromRelative(win, relative); }; var readRange = function (selection) { if (selection.rangeCount > 0) { var firstRng = selection.getRangeAt(0); var lastRng = selection.getRangeAt(selection.rangeCount - 1); return Option.some(range(Element.fromDom(firstRng.startContainer), firstRng.startOffset, Element.fromDom(lastRng.endContainer), lastRng.endOffset)); } else { return Option.none(); } }; var doGetExact = function (selection) { var anchor = Element.fromDom(selection.anchorNode); var focus = Element.fromDom(selection.focusNode); return after$2(anchor, selection.anchorOffset, focus, selection.focusOffset) ? Option.some(range(anchor, selection.anchorOffset, focus, selection.focusOffset)) : readRange(selection); }; var getExact = function (win) { return Option.from(win.getSelection()).filter(function (sel) { return sel.rangeCount > 0; }).bind(doGetExact); }; var get$c = function (win) { return getExact(win).map(function (range) { return exact(range.start(), range.soffset(), range.finish(), range.foffset()); }); }; var getFirstRect$1 = function (win, selection) { var rng = asLtrRange(win, selection); return getFirstRect(rng); }; var clear$1 = function (win) { var selection = win.getSelection(); selection.removeAllRanges(); }; var COLLAPSED_WIDTH = 2; var collapsedRect = function (rect) { return { left: rect.left, top: rect.top, right: rect.right, bottom: rect.bottom, width: constant(COLLAPSED_WIDTH), height: rect.height }; }; var toRect$1 = function (rawRect) { return { left: constant(rawRect.left), top: constant(rawRect.top), right: constant(rawRect.right), bottom: constant(rawRect.bottom), width: constant(rawRect.width), height: constant(rawRect.height) }; }; var getRectsFromRange = function (range) { if (!range.collapsed) { return map$1(range.getClientRects(), toRect$1); } else { var start_1 = Element.fromDom(range.startContainer); return parent(start_1).bind(function (parent) { var selection = exact(start_1, range.startOffset, parent, getEnd(parent)); var optRect = getFirstRect$1(range.startContainer.ownerDocument.defaultView, selection); return optRect.map(collapsedRect).map(pure); }).getOr([]); } }; var getRectangles = function (cWin) { var sel = cWin.getSelection(); return sel !== undefined && sel.rangeCount > 0 ? getRectsFromRange(sel.getRangeAt(0)) : []; }; var Rectangles = { getRectangles: getRectangles }; var autocompleteHack = function () { return function (f) { setTimeout(function () { f(); }, 0); }; }; var resume = function (cWin) { cWin.focus(); var iBody = Element.fromDom(cWin.document.body); var inInput = active().exists(function (elem) { return contains([ 'input', 'textarea' ], name(elem)); }); var transaction = inInput ? autocompleteHack() : apply; transaction(function () { active().each(blur); focus$1(iBody); }); }; var ResumeEditing = { resume: resume }; var EXTRA_SPACING = 50; var data = 'data-' + Styles.resolve('last-outer-height'); var setLastHeight = function (cBody, value) { set(cBody, data, value); }; var getLastHeight = function (cBody) { return DataAttributes.safeParse(cBody, data); }; var getBoundsFrom = function (rect) { return { top: constant(rect.top()), bottom: constant(rect.top() + rect.height()) }; }; var getBounds = function (cWin) { var rects = Rectangles.getRectangles(cWin); return rects.length > 0 ? Option.some(rects[0]).map(getBoundsFrom) : Option.none(); }; var findDelta = function (outerWindow, cBody) { var last = getLastHeight(cBody); var current = outerWindow.innerHeight; return last > current ? Option.some(last - current) : Option.none(); }; var calculate = function (cWin, bounds, delta) { var isOutside = bounds.top() > cWin.innerHeight || bounds.bottom() > cWin.innerHeight; return isOutside ? Math.min(delta, bounds.bottom() - cWin.innerHeight + EXTRA_SPACING) : 0; }; var setup$1 = function (outerWindow, cWin) { var cBody = Element.fromDom(cWin.document.body); var toEditing = function () { ResumeEditing.resume(cWin); }; var onResize = bind$2(Element.fromDom(outerWindow), 'resize', function () { findDelta(outerWindow, cBody).each(function (delta) { getBounds(cWin).each(function (bounds) { var cScrollBy = calculate(cWin, bounds, delta); if (cScrollBy !== 0) { cWin.scrollTo(cWin.pageXOffset, cWin.pageYOffset + cScrollBy); } }); }); setLastHeight(cBody, outerWindow.innerHeight); }); setLastHeight(cBody, outerWindow.innerHeight); var destroy = function () { onResize.unbind(); }; return { toEditing: toEditing, destroy: destroy }; }; var AndroidSetup = { setup: setup$1 }; var getBodyFromFrame = function (frame) { return Option.some(Element.fromDom(frame.dom().contentWindow.document.body)); }; var getDocFromFrame = function (frame) { return Option.some(Element.fromDom(frame.dom().contentWindow.document)); }; var getWinFromFrame = function (frame) { return Option.from(frame.dom().contentWindow); }; var getSelectionFromFrame = function (frame) { var optWin = getWinFromFrame(frame); return optWin.bind(getExact); }; var getFrame = function (editor) { return editor.getFrame(); }; var getOrDerive = function (name, f) { return function (editor) { var g = editor[name].getOrThunk(function () { var frame = getFrame(editor); return function () { return f(frame); }; }); return g(); }; }; var getOrListen = function (editor, doc, name, type) { return editor[name].getOrThunk(function () { return function (handler) { return bind$2(doc, type, handler); }; }); }; var toRect$2 = function (rect) { return { left: constant(rect.left), top: constant(rect.top), right: constant(rect.right), bottom: constant(rect.bottom), width: constant(rect.width), height: constant(rect.height) }; }; var getActiveApi = function (editor) { var frame = getFrame(editor); var tryFallbackBox = function (win) { var isCollapsed = function (sel) { return eq(sel.start(), sel.finish()) && sel.soffset() === sel.foffset(); }; var toStartRect = function (sel) { var rect = sel.start().dom().getBoundingClientRect(); return rect.width > 0 || rect.height > 0 ? Option.some(rect).map(toRect$2) : Option.none(); }; return getExact(win).filter(isCollapsed).bind(toStartRect); }; return getBodyFromFrame(frame).bind(function (body) { return getDocFromFrame(frame).bind(function (doc) { return getWinFromFrame(frame).map(function (win) { var html = Element.fromDom(doc.dom().documentElement); var getCursorBox = editor.getCursorBox.getOrThunk(function () { return function () { return get$c(win).bind(function (sel) { return getFirstRect$1(win, sel).orThunk(function () { return tryFallbackBox(win); }); }); }; }); var setSelection = editor.setSelection.getOrThunk(function () { return function (start, soffset, finish, foffset) { setExact(win, start, soffset, finish, foffset); }; }); var clearSelection = editor.clearSelection.getOrThunk(function () { return function () { clear$1(win); }; }); return { body: constant(body), doc: constant(doc), win: constant(win), html: constant(html), getSelection: curry(getSelectionFromFrame, frame), setSelection: setSelection, clearSelection: clearSelection, frame: constant(frame), onKeyup: getOrListen(editor, doc, 'onKeyup', 'keyup'), onNodeChanged: getOrListen(editor, doc, 'onNodeChanged', 'selectionchange'), onDomChanged: editor.onDomChanged, onScrollToCursor: editor.onScrollToCursor, onScrollToElement: editor.onScrollToElement, onToReading: editor.onToReading, onToEditing: editor.onToEditing, onToolbarScrollStart: editor.onToolbarScrollStart, onTouchContent: editor.onTouchContent, onTapContent: editor.onTapContent, onTouchToolstrip: editor.onTouchToolstrip, getCursorBox: getCursorBox }; }); }); }); }; var PlatformEditor = { getBody: getOrDerive('getBody', getBodyFromFrame), getDoc: getOrDerive('getDoc', getDocFromFrame), getWin: getOrDerive('getWin', getWinFromFrame), getSelection: getOrDerive('getSelection', getSelectionFromFrame), getFrame: getFrame, getActiveApi: getActiveApi }; var attr = 'data-ephox-mobile-fullscreen-style'; var siblingStyles = 'display:none!important;'; var ancestorPosition = 'position:absolute!important;'; var ancestorStyles = 'top:0!important;left:0!important;margin:0!important;padding:0!important;width:100%!important;height:100%!important;overflow:visible!important;'; var bgFallback = 'background-color:rgb(255,255,255)!important;'; var isAndroid = PlatformDetection$1.detect().os.isAndroid(); var matchColor = function (editorBody) { var color = get$3(editorBody, 'background-color'); return color !== undefined && color !== '' ? 'background-color:' + color + '!important' : bgFallback; }; var clobberStyles = function (container, editorBody) { var gatherSibilings = function (element) { var siblings = siblings$2(element, '*'); return siblings; }; var clobber = function (clobberStyle) { return function (element) { var styles = get(element, 'style'); var backup = styles === undefined ? 'no-styles' : styles.trim(); if (backup === clobberStyle) { return; } else { set(element, attr, backup); set(element, 'style', clobberStyle); } }; }; var ancestors = ancestors$1(container, '*'); var siblings = bind(ancestors, gatherSibilings); var bgColor = matchColor(editorBody); each$1(siblings, clobber(siblingStyles)); each$1(ancestors, clobber(ancestorPosition + ancestorStyles + bgColor)); var containerStyles = isAndroid === true ? '' : ancestorPosition; clobber(containerStyles + ancestorStyles + bgColor)(container); }; var restoreStyles = function () { var clobberedEls = all$2('[' + attr + ']'); each$1(clobberedEls, function (element) { var restore = get(element, attr); if (restore !== 'no-styles') { set(element, 'style', restore); } else { remove$1(element, 'style'); } remove$1(element, attr); }); }; var Thor = { clobberStyles: clobberStyles, restoreStyles: restoreStyles }; var tag = function () { var head = first('head').getOrDie(); var nu = function () { var meta = Element.fromTag('meta'); set(meta, 'name', 'viewport'); append(head, meta); return meta; }; var element = first('meta[name="viewport"]').getOrThunk(nu); var backup = get(element, 'content'); var maximize = function () { set(element, 'content', 'width=device-width, initial-scale=1.0, user-scalable=no, maximum-scale=1.0'); }; var restore = function () { if (backup !== undefined && backup !== null && backup.length > 0) { set(element, 'content', backup); } else { set(element, 'content', 'user-scalable=yes'); } }; return { maximize: maximize, restore: restore }; }; var MetaViewport = { tag: tag }; var create$4 = function (platform, mask) { var meta = MetaViewport.tag(); var androidApi = api$2(); var androidEvents = api$2(); var enter = function () { mask.hide(); add$2(platform.container, Styles.resolve('fullscreen-maximized')); add$2(platform.container, Styles.resolve('android-maximized')); meta.maximize(); add$2(platform.body, Styles.resolve('android-scroll-reload')); androidApi.set(AndroidSetup.setup(platform.win, PlatformEditor.getWin(platform.editor).getOrDie('no'))); PlatformEditor.getActiveApi(platform.editor).each(function (editorApi) { Thor.clobberStyles(platform.container, editorApi.body()); androidEvents.set(AndroidEvents.initEvents(editorApi, platform.toolstrip, platform.alloy)); }); }; var exit = function () { meta.restore(); mask.show(); remove$4(platform.container, Styles.resolve('fullscreen-maximized')); remove$4(platform.container, Styles.resolve('android-maximized')); Thor.restoreStyles(); remove$4(platform.body, Styles.resolve('android-scroll-reload')); androidEvents.clear(); androidApi.clear(); }; return { enter: enter, exit: exit }; }; var AndroidMode = { create: create$4 }; var first$2 = function (fn, rate) { var timer = null; var cancel = function () { if (timer !== null) { domGlobals.clearTimeout(timer); timer = null; } }; var throttle = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (timer === null) { timer = domGlobals.setTimeout(function () { fn.apply(null, args); timer = null; }, rate); } }; return { cancel: cancel, throttle: throttle }; }; var last$1 = function (fn, rate) { var timer = null; var cancel = function () { if (timer !== null) { domGlobals.clearTimeout(timer); timer = null; } }; var throttle = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (timer !== null) domGlobals.clearTimeout(timer); timer = domGlobals.setTimeout(function () { fn.apply(null, args); timer = null; }, rate); }; return { cancel: cancel, throttle: throttle }; }; var sketch$9 = function (onView, translate) { var memIcon = record(Container.sketch({ dom: dom$1('<div aria-hidden="true" class="${prefix}-mask-tap-icon"></div>'), containerBehaviours: derive$1([Toggling.config({ toggleClass: Styles.resolve('mask-tap-icon-selected'), toggleOnExecute: false })]) })); var onViewThrottle = first$2(onView, 200); return Container.sketch({ dom: dom$1('<div class="${prefix}-disabled-mask"></div>'), components: [Container.sketch({ dom: dom$1('<div class="${prefix}-content-container"></div>'), components: [Button.sketch({ dom: dom$1('<div class="${prefix}-content-tap-section"></div>'), components: [memIcon.asSpec()], action: function (button) { onViewThrottle.throttle(); }, buttonBehaviours: derive$1([Toggling.config({ toggleClass: Styles.resolve('mask-tap-icon-selected') })]) })] })] }); }; var TapToEditMask = { sketch: sketch$9 }; var MobileSchema = objOf([ strictObjOf('editor', [ strict$1('getFrame'), option('getBody'), option('getDoc'), option('getWin'), option('getSelection'), option('setSelection'), option('clearSelection'), option('cursorSaver'), option('onKeyup'), option('onNodeChanged'), option('getCursorBox'), strict$1('onDomChanged'), defaulted$1('onTouchContent', noop), defaulted$1('onTapContent', noop), defaulted$1('onTouchToolstrip', noop), defaulted$1('onScrollToCursor', constant({ unbind: noop })), defaulted$1('onScrollToElement', constant({ unbind: noop })), defaulted$1('onToEditing', constant({ unbind: noop })), defaulted$1('onToReading', constant({ unbind: noop })), defaulted$1('onToolbarScrollStart', identity) ]), strict$1('socket'), strict$1('toolstrip'), strict$1('dropup'), strict$1('toolbar'), strict$1('container'), strict$1('alloy'), state$1('win', function (spec) { return owner(spec.socket).dom().defaultView; }), state$1('body', function (spec) { return Element.fromDom(spec.socket.dom().ownerDocument.body); }), defaulted$1('translate', identity), defaulted$1('setReadOnly', noop), defaulted$1('readOnlyOnInit', constant(true)) ]); var produce = function (raw) { var mobile = asRawOrDie('Getting AndroidWebapp schema', MobileSchema, raw); set$2(mobile.toolstrip, 'width', '100%'); var onTap = function () { mobile.setReadOnly(mobile.readOnlyOnInit()); mode.enter(); }; var mask = build$1(TapToEditMask.sketch(onTap, mobile.translate)); mobile.alloy.add(mask); var maskApi = { show: function () { mobile.alloy.add(mask); }, hide: function () { mobile.alloy.remove(mask); } }; append(mobile.container, mask.element()); var mode = AndroidMode.create(mobile, maskApi); return { setReadOnly: mobile.setReadOnly, refreshStructure: noop, enter: mode.enter, exit: mode.exit, destroy: noop }; }; var AndroidWebapp = { produce: produce }; var schema$e = constant([ defaulted$1('shell', true), field$1('toolbarBehaviours', [Replacing]) ]); var enhanceGroups = function (detail) { return { behaviours: derive$1([Replacing.config({})]) }; }; var parts$2 = constant([optional({ name: 'groups', overrides: enhanceGroups })]); var factory$4 = function (detail, components, spec, _externals) { var setGroups = function (toolbar, groups) { getGroupContainer(toolbar).fold(function () { domGlobals.console.error('Toolbar was defined to not be a shell, but no groups container was specified in components'); throw new Error('Toolbar was defined to not be a shell, but no groups container was specified in components'); }, function (container) { Replacing.set(container, groups); }); }; var getGroupContainer = function (component) { return detail.shell() ? Option.some(component) : getPart(component, detail, 'groups'); }; var extra = detail.shell() ? { behaviours: [Replacing.config({})], components: [] } : { behaviours: [], components: components }; return { uid: detail.uid(), dom: detail.dom(), components: extra.components, behaviours: deepMerge(derive$1(extra.behaviours), get$5(detail.toolbarBehaviours())), apis: { setGroups: setGroups }, domModification: { attributes: { role: 'group' } } }; }; var Toolbar = composite$1({ name: 'Toolbar', configFields: schema$e(), partFields: parts$2(), factory: factory$4, apis: { setGroups: function (apis, toolbar, groups) { apis.setGroups(toolbar, groups); } } }); var schema$f = constant([ strict$1('items'), markers(['itemClass']), field$1('tgroupBehaviours', [Keying]) ]); var parts$3 = constant([group({ name: 'items', unit: 'item', overrides: function (detail) { return { domModification: { classes: [detail.markers().itemClass()] } }; } })]); var factory$5 = function (detail, components, spec, _externals) { return deepMerge({ dom: { attributes: { role: 'toolbar' } } }, { 'uid': detail.uid(), 'dom': detail.dom(), 'components': components, 'behaviours': deepMerge(derive$1([Keying.config({ mode: 'flow', selector: '.' + detail.markers().itemClass() })]), get$5(detail.tgroupBehaviours())), 'debug.sketcher': spec['debug.sketcher'] }); }; var ToolbarGroup = composite$1({ name: 'ToolbarGroup', configFields: schema$f(), partFields: parts$3(), factory: factory$5 }); var dataHorizontal = 'data-' + Styles.resolve('horizontal-scroll'); var canScrollVertically = function (container) { container.dom().scrollTop = 1; var result = container.dom().scrollTop !== 0; container.dom().scrollTop = 0; return result; }; var canScrollHorizontally = function (container) { container.dom().scrollLeft = 1; var result = container.dom().scrollLeft !== 0; container.dom().scrollLeft = 0; return result; }; var hasVerticalScroll = function (container) { return container.dom().scrollTop > 0 || canScrollVertically(container); }; var hasHorizontalScroll = function (container) { return container.dom().scrollLeft > 0 || canScrollHorizontally(container); }; var markAsHorizontal = function (container) { set(container, dataHorizontal, 'true'); }; var hasScroll = function (container) { return get(container, dataHorizontal) === 'true' ? hasHorizontalScroll(container) : hasVerticalScroll(container); }; var exclusive = function (scope, selector) { return bind$2(scope, 'touchmove', function (event) { closest$1(event.target(), selector).filter(hasScroll).fold(function () { event.raw().preventDefault(); }, noop); }); }; var Scrollables = { exclusive: exclusive, markAsHorizontal: markAsHorizontal }; function ScrollingToolbar () { var makeGroup = function (gSpec) { var scrollClass = gSpec.scrollable === true ? '${prefix}-toolbar-scrollable-group' : ''; return { dom: dom$1('<div aria-label="' + gSpec.label + '" class="${prefix}-toolbar-group ' + scrollClass + '"></div>'), tgroupBehaviours: derive$1([config('adhoc-scrollable-toolbar', gSpec.scrollable === true ? [runOnInit(function (component, simulatedEvent) { set$2(component.element(), 'overflow-x', 'auto'); Scrollables.markAsHorizontal(component.element()); Scrollable.register(component.element()); })] : [])]), components: [Container.sketch({ components: [ToolbarGroup.parts().items({})] })], markers: { itemClass: Styles.resolve('toolbar-group-item') }, items: gSpec.items }; }; var toolbar = build$1(Toolbar.sketch({ dom: dom$1('<div class="${prefix}-toolbar"></div>'), components: [Toolbar.parts().groups({})], toolbarBehaviours: derive$1([ Toggling.config({ toggleClass: Styles.resolve('context-toolbar'), toggleOnExecute: false, aria: { mode: 'none' } }), Keying.config({ mode: 'cyclic' }) ]), shell: true })); var wrapper = build$1(Container.sketch({ dom: { classes: [Styles.resolve('toolstrip')] }, components: [premade$1(toolbar)], containerBehaviours: derive$1([Toggling.config({ toggleClass: Styles.resolve('android-selection-context-toolbar'), toggleOnExecute: false })]) })); var resetGroups = function () { Toolbar.setGroups(toolbar, initGroups.get()); Toggling.off(toolbar); }; var initGroups = Cell([]); var setGroups = function (gs) { initGroups.set(gs); resetGroups(); }; var createGroups = function (gs) { return map$1(gs, compose(ToolbarGroup.sketch, makeGroup)); }; var refresh = function () { }; var setContextToolbar = function (gs) { Toggling.on(toolbar); Toolbar.setGroups(toolbar, gs); }; var restoreToolbar = function () { if (Toggling.isOn(toolbar)) { resetGroups(); } }; var focus = function () { Keying.focusIn(toolbar); }; return { wrapper: constant(wrapper), toolbar: constant(toolbar), createGroups: createGroups, setGroups: setGroups, setContextToolbar: setContextToolbar, restoreToolbar: restoreToolbar, refresh: refresh, focus: focus }; } var makeEditSwitch = function (webapp) { return build$1(Button.sketch({ dom: dom$1('<div class="${prefix}-mask-edit-icon ${prefix}-icon"></div>'), action: function () { webapp.run(function (w) { w.setReadOnly(false); }); } })); }; var makeSocket = function () { return build$1(Container.sketch({ dom: dom$1('<div class="${prefix}-editor-socket"></div>'), components: [], containerBehaviours: derive$1([Replacing.config({})]) })); }; var showEdit = function (socket, switchToEdit) { Replacing.append(socket, premade$1(switchToEdit)); }; var hideEdit = function (socket, switchToEdit) { Replacing.remove(socket, switchToEdit); }; var updateMode = function (socket, switchToEdit, readOnly, root) { var swap = readOnly === true ? Swapping.toAlpha : Swapping.toOmega; swap(root); var f = readOnly ? showEdit : hideEdit; f(socket, switchToEdit); }; var CommonRealm = { makeEditSwitch: makeEditSwitch, makeSocket: makeSocket, updateMode: updateMode }; var getAnimationRoot = function (component, slideConfig) { return slideConfig.getAnimationRoot().fold(function () { return component.element(); }, function (get) { return get(component); }); }; var getDimensionProperty = function (slideConfig) { return slideConfig.dimension().property(); }; var getDimension = function (slideConfig, elem) { return slideConfig.dimension().getDimension()(elem); }; var disableTransitions = function (component, slideConfig) { var root = getAnimationRoot(component, slideConfig); remove$6(root, [ slideConfig.shrinkingClass(), slideConfig.growingClass() ]); }; var setShrunk = function (component, slideConfig) { remove$4(component.element(), slideConfig.openClass()); add$2(component.element(), slideConfig.closedClass()); set$2(component.element(), getDimensionProperty(slideConfig), '0px'); reflow(component.element()); }; var measureTargetSize = function (component, slideConfig) { setGrown(component, slideConfig); var expanded = getDimension(slideConfig, component.element()); setShrunk(component, slideConfig); return expanded; }; var setGrown = function (component, slideConfig) { remove$4(component.element(), slideConfig.closedClass()); add$2(component.element(), slideConfig.openClass()); remove$5(component.element(), getDimensionProperty(slideConfig)); }; var doImmediateShrink = function (component, slideConfig, slideState) { slideState.setCollapsed(); set$2(component.element(), getDimensionProperty(slideConfig), getDimension(slideConfig, component.element())); reflow(component.element()); disableTransitions(component, slideConfig); setShrunk(component, slideConfig); slideConfig.onStartShrink()(component); slideConfig.onShrunk()(component); }; var doStartShrink = function (component, slideConfig, slideState) { slideState.setCollapsed(); set$2(component.element(), getDimensionProperty(slideConfig), getDimension(slideConfig, component.element())); reflow(component.element()); var root = getAnimationRoot(component, slideConfig); add$2(root, slideConfig.shrinkingClass()); setShrunk(component, slideConfig); slideConfig.onStartShrink()(component); }; var doStartGrow = function (component, slideConfig, slideState) { var fullSize = measureTargetSize(component, slideConfig); var root = getAnimationRoot(component, slideConfig); add$2(root, slideConfig.growingClass()); setGrown(component, slideConfig); set$2(component.element(), getDimensionProperty(slideConfig), fullSize); slideState.setExpanded(); slideConfig.onStartGrow()(component); }; var grow = function (component, slideConfig, slideState) { if (!slideState.isExpanded()) { doStartGrow(component, slideConfig, slideState); } }; var shrink = function (component, slideConfig, slideState) { if (slideState.isExpanded()) { doStartShrink(component, slideConfig, slideState); } }; var immediateShrink = function (component, slideConfig, slideState) { if (slideState.isExpanded()) { doImmediateShrink(component, slideConfig, slideState); } }; var hasGrown = function (component, slideConfig, slideState) { return slideState.isExpanded(); }; var hasShrunk = function (component, slideConfig, slideState) { return slideState.isCollapsed(); }; var isGrowing = function (component, slideConfig, slideState) { var root = getAnimationRoot(component, slideConfig); return has$1(root, slideConfig.growingClass()) === true; }; var isShrinking = function (component, slideConfig, slideState) { var root = getAnimationRoot(component, slideConfig); return has$1(root, slideConfig.shrinkingClass()) === true; }; var isTransitioning = function (component, slideConfig, slideState) { return isGrowing(component, slideConfig, slideState) === true || isShrinking(component, slideConfig, slideState) === true; }; var toggleGrow = function (component, slideConfig, slideState) { var f = slideState.isExpanded() ? doStartShrink : doStartGrow; f(component, slideConfig, slideState); }; var SlidingApis = /*#__PURE__*/Object.freeze({ grow: grow, shrink: shrink, immediateShrink: immediateShrink, hasGrown: hasGrown, hasShrunk: hasShrunk, isGrowing: isGrowing, isShrinking: isShrinking, isTransitioning: isTransitioning, toggleGrow: toggleGrow, disableTransitions: disableTransitions }); var exhibit$5 = function (base, slideConfig) { var expanded = slideConfig.expanded(); return expanded ? nu$6({ classes: [slideConfig.openClass()], styles: {} }) : nu$6({ classes: [slideConfig.closedClass()], styles: wrap$1(slideConfig.dimension().property(), '0px') }); }; var events$a = function (slideConfig, slideState) { return derive([run(transitionend(), function (component, simulatedEvent) { var raw = simulatedEvent.event().raw(); if (raw.propertyName === slideConfig.dimension().property()) { disableTransitions(component, slideConfig); if (slideState.isExpanded()) { remove$5(component.element(), slideConfig.dimension().property()); } var notify = slideState.isExpanded() ? slideConfig.onGrown() : slideConfig.onShrunk(); notify(component); } })]); }; var ActiveSliding = /*#__PURE__*/Object.freeze({ exhibit: exhibit$5, events: events$a }); var SlidingSchema = [ strict$1('closedClass'), strict$1('openClass'), strict$1('shrinkingClass'), strict$1('growingClass'), option('getAnimationRoot'), onHandler('onShrunk'), onHandler('onStartShrink'), onHandler('onGrown'), onHandler('onStartGrow'), defaulted$1('expanded', false), strictOf('dimension', choose$1('property', { width: [ output('property', 'width'), output('getDimension', function (elem) { return get$6(elem) + 'px'; }) ], height: [ output('property', 'height'), output('getDimension', function (elem) { return get$4(elem) + 'px'; }) ] })) ]; var init$4 = function (spec) { var state = Cell(spec.expanded()); var readState = function () { return 'expanded: ' + state.get(); }; return nu$7({ isExpanded: function () { return state.get() === true; }, isCollapsed: function () { return state.get() === false; }, setCollapsed: curry(state.set, false), setExpanded: curry(state.set, true), readState: readState }); }; var SlidingState = /*#__PURE__*/Object.freeze({ init: init$4 }); var Sliding = create$1({ fields: SlidingSchema, name: 'sliding', active: ActiveSliding, apis: SlidingApis, state: SlidingState }); var build$2 = function (refresh, scrollIntoView) { var dropup = build$1(Container.sketch({ dom: { tag: 'div', classes: [Styles.resolve('dropup')] }, components: [], containerBehaviours: derive$1([ Replacing.config({}), Sliding.config({ closedClass: Styles.resolve('dropup-closed'), openClass: Styles.resolve('dropup-open'), shrinkingClass: Styles.resolve('dropup-shrinking'), growingClass: Styles.resolve('dropup-growing'), dimension: { property: 'height' }, onShrunk: function (component) { refresh(); scrollIntoView(); Replacing.set(component, []); }, onGrown: function (component) { refresh(); scrollIntoView(); } }), Receivers.orientation(function (component, data) { disappear(noop); }) ]) })); var appear = function (menu, update, component) { if (Sliding.hasShrunk(dropup) === true && Sliding.isTransitioning(dropup) === false) { domGlobals.window.requestAnimationFrame(function () { update(component); Replacing.set(dropup, [menu()]); Sliding.grow(dropup); }); } }; var disappear = function (onReadyToShrink) { domGlobals.window.requestAnimationFrame(function () { onReadyToShrink(); Sliding.shrink(dropup); }); }; return { appear: appear, disappear: disappear, component: constant(dropup), element: dropup.element }; }; var isDangerous = function (event) { var keyEv = event.raw(); return keyEv.which === BACKSPACE()[0] && !contains([ 'input', 'textarea' ], name(event.target())); }; var isFirefox = PlatformDetection$1.detect().browser.isFirefox(); var settingsSchema = objOfOnly([ strictFunction('triggerEvent'), strictFunction('broadcastEvent'), defaulted$1('stopBackspace', true) ]); var bindFocus = function (container, handler) { if (isFirefox) { return capture$1(container, 'focus', handler); } else { return bind$2(container, 'focusin', handler); } }; var bindBlur = function (container, handler) { if (isFirefox) { return capture$1(container, 'blur', handler); } else { return bind$2(container, 'focusout', handler); } }; var setup$2 = function (container, rawSettings) { var settings = asRawOrDie('Getting GUI events settings', settingsSchema, rawSettings); var pointerEvents = PlatformDetection$1.detect().deviceType.isTouch() ? [ 'touchstart', 'touchmove', 'touchend', 'gesturestart' ] : [ 'mousedown', 'mouseup', 'mouseover', 'mousemove', 'mouseout', 'click' ]; var tapEvent = monitor(settings); var simpleEvents = map$1(pointerEvents.concat([ 'selectstart', 'input', 'contextmenu', 'change', 'transitionend', 'drag', 'dragstart', 'dragend', 'dragenter', 'dragleave', 'dragover', 'drop' ]), function (type) { return bind$2(container, type, function (event) { tapEvent.fireIfReady(event, type).each(function (tapStopped) { if (tapStopped) { event.kill(); } }); var stopped = settings.triggerEvent(type, event); if (stopped) { event.kill(); } }); }); var onKeydown = bind$2(container, 'keydown', function (event) { var stopped = settings.triggerEvent('keydown', event); if (stopped) { event.kill(); } else if (settings.stopBackspace === true && isDangerous(event)) { event.prevent(); } }); var onFocusIn = bindFocus(container, function (event) { var stopped = settings.triggerEvent('focusin', event); if (stopped) { event.kill(); } }); var onFocusOut = bindBlur(container, function (event) { var stopped = settings.triggerEvent('focusout', event); if (stopped) { event.kill(); } domGlobals.setTimeout(function () { settings.triggerEvent(postBlur(), event); }, 0); }); var defaultView$1 = defaultView(container); var onWindowScroll = bind$2(defaultView$1, 'scroll', function (event) { var stopped = settings.broadcastEvent(windowScroll(), event); if (stopped) { event.kill(); } }); var unbind = function () { each$1(simpleEvents, function (e) { e.unbind(); }); onKeydown.unbind(); onFocusIn.unbind(); onFocusOut.unbind(); onWindowScroll.unbind(); }; return { unbind: unbind }; }; var derive$2 = function (rawEvent, rawTarget) { var source = readOptFrom$1(rawEvent, 'target').map(function (getTarget) { return getTarget(); }).getOr(rawTarget); return Cell(source); }; var fromSource = function (event, source) { var stopper = Cell(false); var cutter = Cell(false); var stop = function () { stopper.set(true); }; var cut = function () { cutter.set(true); }; return { stop: stop, cut: cut, isStopped: stopper.get, isCut: cutter.get, event: constant(event), setSource: source.set, getSource: source.get }; }; var fromExternal = function (event) { var stopper = Cell(false); var stop = function () { stopper.set(true); }; return { stop: stop, cut: noop, isStopped: stopper.get, isCut: constant(false), event: constant(event), setSource: die('Cannot set source of a broadcasted event'), getSource: die('Cannot get source of a broadcasted event') }; }; var adt$6 = Adt.generate([ { stopped: [] }, { resume: ['element'] }, { complete: [] } ]); var doTriggerHandler = function (lookup, eventType, rawEvent, target, source, logger) { var handler = lookup(eventType, target); var simulatedEvent = fromSource(rawEvent, source); return handler.fold(function () { logger.logEventNoHandlers(eventType, target); return adt$6.complete(); }, function (handlerInfo) { var descHandler = handlerInfo.descHandler(); var eventHandler = getCurried(descHandler); eventHandler(simulatedEvent); if (simulatedEvent.isStopped()) { logger.logEventStopped(eventType, handlerInfo.element(), descHandler.purpose()); return adt$6.stopped(); } else if (simulatedEvent.isCut()) { logger.logEventCut(eventType, handlerInfo.element(), descHandler.purpose()); return adt$6.complete(); } else { return parent(handlerInfo.element()).fold(function () { logger.logNoParent(eventType, handlerInfo.element(), descHandler.purpose()); return adt$6.complete(); }, function (parent) { logger.logEventResponse(eventType, handlerInfo.element(), descHandler.purpose()); return adt$6.resume(parent); }); } }); }; var doTriggerOnUntilStopped = function (lookup, eventType, rawEvent, rawTarget, source, logger) { return doTriggerHandler(lookup, eventType, rawEvent, rawTarget, source, logger).fold(function () { return true; }, function (parent) { return doTriggerOnUntilStopped(lookup, eventType, rawEvent, parent, source, logger); }, function () { return false; }); }; var triggerHandler = function (lookup, eventType, rawEvent, target, logger) { var source = derive$2(rawEvent, target); return doTriggerHandler(lookup, eventType, rawEvent, target, source, logger); }; var broadcast = function (listeners, rawEvent, logger) { var simulatedEvent = fromExternal(rawEvent); each$1(listeners, function (listener) { var descHandler = listener.descHandler(); var handler = getCurried(descHandler); handler(simulatedEvent); }); return simulatedEvent.isStopped(); }; var triggerUntilStopped = function (lookup, eventType, rawEvent, logger) { var rawTarget = rawEvent.target(); return triggerOnUntilStopped(lookup, eventType, rawEvent, rawTarget, logger); }; var triggerOnUntilStopped = function (lookup, eventType, rawEvent, rawTarget, logger) { var source = derive$2(rawEvent, rawTarget); return doTriggerOnUntilStopped(lookup, eventType, rawEvent, rawTarget, source, logger); }; var closest$2 = function (target, transform, isRoot) { var delegate = closest(target, function (elem) { return transform(elem).isSome(); }, isRoot); return delegate.bind(transform); }; var eventHandler = Immutable('element', 'descHandler'); var broadcastHandler = function (id, handler) { return { id: constant(id), descHandler: constant(handler) }; }; function EventRegistry () { var registry = {}; var registerId = function (extraArgs, id, events) { each(events, function (v, k) { var handlers = registry[k] !== undefined ? registry[k] : {}; handlers[id] = curryArgs(v, extraArgs); registry[k] = handlers; }); }; var findHandler = function (handlers, elem) { return read$2(elem).fold(function () { return Option.none(); }, function (id) { var reader = readOpt$1(id); return handlers.bind(reader).map(function (descHandler) { return eventHandler(elem, descHandler); }); }); }; var filterByType = function (type) { return readOptFrom$1(registry, type).map(function (handlers) { return mapToArray(handlers, function (f, id) { return broadcastHandler(id, f); }); }).getOr([]); }; var find = function (isAboveRoot, type, target) { var readType = readOpt$1(type); var handlers = readType(registry); return closest$2(target, function (elem) { return findHandler(handlers, elem); }, isAboveRoot); }; var unregisterId = function (id) { each(registry, function (handlersById, eventName) { if (handlersById.hasOwnProperty(id)) { delete handlersById[id]; } }); }; return { registerId: registerId, unregisterId: unregisterId, filterByType: filterByType, find: find }; } function Registry () { var events = EventRegistry(); var components = {}; var readOrTag = function (component) { var elem = component.element(); return read$2(elem).fold(function () { return write('uid-', component.element()); }, function (uid) { return uid; }); }; var failOnDuplicate = function (component, tagId) { var conflict = components[tagId]; if (conflict === component) { unregister(component); } else { throw new Error('The tagId "' + tagId + '" is already used by: ' + element(conflict.element()) + '\nCannot use it for: ' + element(component.element()) + '\n' + 'The conflicting element is' + (inBody(conflict.element()) ? ' ' : ' not ') + 'already in the DOM'); } }; var register = function (component) { var tagId = readOrTag(component); if (hasKey$1(components, tagId)) { failOnDuplicate(component, tagId); } var extraArgs = [component]; events.registerId(extraArgs, tagId, component.events()); components[tagId] = component; }; var unregister = function (component) { read$2(component.element()).each(function (tagId) { components[tagId] = undefined; events.unregisterId(tagId); }); }; var filter = function (type) { return events.filterByType(type); }; var find = function (isAboveRoot, type, target) { return events.find(isAboveRoot, type, target); }; var getById = function (id) { return readOpt$1(id)(components); }; return { find: find, filter: filter, register: register, unregister: unregister, getById: getById }; } var takeover = function (root) { var isAboveRoot = function (el) { return parent(root.element()).fold(function () { return true; }, function (parent) { return eq(el, parent); }); }; var registry = Registry(); var lookup = function (eventName, target) { return registry.find(isAboveRoot, eventName, target); }; var domEvents = setup$2(root.element(), { triggerEvent: function (eventName, event) { return monitorEvent(eventName, event.target(), function (logger) { return triggerUntilStopped(lookup, eventName, event, logger); }); }, broadcastEvent: function (eventName, event) { var listeners = registry.filter(eventName); return broadcast(listeners, event); } }); var systemApi = SystemApi({ debugInfo: constant('real'), triggerEvent: function (eventName, target, data) { monitorEvent(eventName, target, function (logger) { triggerOnUntilStopped(lookup, eventName, data, target, logger); }); }, triggerFocus: function (target, originator) { read$2(target).fold(function () { focus$1(target); }, function (_alloyId) { monitorEvent(focus(), target, function (logger) { triggerHandler(lookup, focus(), { originator: constant(originator), kill: noop, prevent: noop, target: constant(target) }, target, logger); }); }); }, triggerEscape: function (comp, simulatedEvent) { systemApi.triggerEvent('keydown', comp.element(), simulatedEvent.event()); }, getByUid: function (uid) { return getByUid(uid); }, getByDom: function (elem) { return getByDom(elem); }, build: build$1, addToGui: function (c) { add(c); }, removeFromGui: function (c) { remove$1(c); }, addToWorld: function (c) { addToWorld(c); }, removeFromWorld: function (c) { removeFromWorld(c); }, broadcast: function (message) { broadcast$1(message); }, broadcastOn: function (channels, message) { broadcastOn(channels, message); }, isConnected: constant(true) }); var addToWorld = function (component) { component.connect(systemApi); if (!isText(component.element())) { registry.register(component); each$1(component.components(), addToWorld); systemApi.triggerEvent(systemInit(), component.element(), { target: constant(component.element()) }); } }; var removeFromWorld = function (component) { if (!isText(component.element())) { each$1(component.components(), removeFromWorld); registry.unregister(component); } component.disconnect(); }; var add = function (component) { attach(root, component); }; var remove$1 = function (component) { detach(component); }; var destroy = function () { domEvents.unbind(); remove(root.element()); }; var broadcastData = function (data) { var receivers = registry.filter(receive()); each$1(receivers, function (receiver) { var descHandler = receiver.descHandler(); var handler = getCurried(descHandler); handler(data); }); }; var broadcast$1 = function (message) { broadcastData({ universal: constant(true), data: constant(message) }); }; var broadcastOn = function (channels, message) { broadcastData({ universal: constant(false), channels: constant(channels), data: constant(message) }); }; var getByUid = function (uid) { return registry.getById(uid).fold(function () { return Result.error(new Error('Could not find component with uid: "' + uid + '" in system.')); }, Result.value); }; var getByDom = function (elem) { var uid = read$2(elem).getOr('not found'); return getByUid(uid); }; addToWorld(root); return { root: constant(root), element: root.element, destroy: destroy, add: add, remove: remove$1, getByUid: getByUid, getByDom: getByDom, addToWorld: addToWorld, removeFromWorld: removeFromWorld, broadcast: broadcast$1, broadcastOn: broadcastOn }; }; var READ_ONLY_MODE_CLASS = constant(Styles.resolve('readonly-mode')); var EDIT_MODE_CLASS = constant(Styles.resolve('edit-mode')); function OuterContainer (spec) { var root = build$1(Container.sketch({ dom: { classes: [Styles.resolve('outer-container')].concat(spec.classes) }, containerBehaviours: derive$1([Swapping.config({ alpha: READ_ONLY_MODE_CLASS(), omega: EDIT_MODE_CLASS() })]) })); return takeover(root); } function AndroidRealm (scrollIntoView) { var alloy = OuterContainer({ classes: [Styles.resolve('android-container')] }); var toolbar = ScrollingToolbar(); var webapp = api$2(); var switchToEdit = CommonRealm.makeEditSwitch(webapp); var socket = CommonRealm.makeSocket(); var dropup = build$2(noop, scrollIntoView); alloy.add(toolbar.wrapper()); alloy.add(socket); alloy.add(dropup.component()); var setToolbarGroups = function (rawGroups) { var groups = toolbar.createGroups(rawGroups); toolbar.setGroups(groups); }; var setContextToolbar = function (rawGroups) { var groups = toolbar.createGroups(rawGroups); toolbar.setContextToolbar(groups); }; var focusToolbar = function () { toolbar.focus(); }; var restoreToolbar = function () { toolbar.restoreToolbar(); }; var init = function (spec) { webapp.set(AndroidWebapp.produce(spec)); }; var exit = function () { webapp.run(function (w) { w.exit(); Replacing.remove(socket, switchToEdit); }); }; var updateMode = function (readOnly) { CommonRealm.updateMode(socket, switchToEdit, readOnly, alloy.root()); }; return { system: constant(alloy), element: alloy.element, init: init, exit: exit, setToolbarGroups: setToolbarGroups, setContextToolbar: setContextToolbar, focusToolbar: focusToolbar, restoreToolbar: restoreToolbar, updateMode: updateMode, socket: constant(socket), dropup: constant(dropup) }; } var input$1 = function (parent, operation) { var input = Element.fromTag('input'); setAll$1(input, { opacity: '0', position: 'absolute', top: '-1000px', left: '-1000px' }); append(parent, input); focus$1(input); operation(input); remove(input); }; var CaptureBin = { input: input$1 }; var refreshInput = function (input) { var start = input.dom().selectionStart; var end = input.dom().selectionEnd; var dir = input.dom().selectionDirection; setTimeout(function () { input.dom().setSelectionRange(start, end, dir); focus$1(input); }, 50); }; var refresh = function (winScope) { var sel = winScope.getSelection(); if (sel.rangeCount > 0) { var br = sel.getRangeAt(0); var r = winScope.document.createRange(); r.setStart(br.startContainer, br.startOffset); r.setEnd(br.endContainer, br.endOffset); sel.removeAllRanges(); sel.addRange(r); } }; var CursorRefresh = { refreshInput: refreshInput, refresh: refresh }; var resume$1 = function (cWin, frame) { active().each(function (active) { if (!eq(active, frame)) { blur(active); } }); cWin.focus(); focus$1(Element.fromDom(cWin.document.body)); CursorRefresh.refresh(cWin); }; var ResumeEditing$1 = { resume: resume$1 }; var stubborn = function (outerBody, cWin, page, frame) { var toEditing = function () { ResumeEditing$1.resume(cWin, frame); }; var toReading = function () { CaptureBin.input(outerBody, blur); }; var captureInput = bind$2(page, 'keydown', function (evt) { if (!contains([ 'input', 'textarea' ], name(evt.target()))) { toEditing(); } }); var onToolbarTouch = function () { }; var destroy = function () { captureInput.unbind(); }; return { toReading: toReading, toEditing: toEditing, onToolbarTouch: onToolbarTouch, destroy: destroy }; }; var timid = function (outerBody, cWin, page, frame) { var dismissKeyboard = function () { blur(frame); }; var onToolbarTouch = function () { dismissKeyboard(); }; var toReading = function () { dismissKeyboard(); }; var toEditing = function () { ResumeEditing$1.resume(cWin, frame); }; return { toReading: toReading, toEditing: toEditing, onToolbarTouch: onToolbarTouch, destroy: noop }; }; var IosKeyboard = { stubborn: stubborn, timid: timid }; var initEvents$1 = function (editorApi, iosApi, toolstrip, socket, dropup) { var saveSelectionFirst = function () { iosApi.run(function (api) { api.highlightSelection(); }); }; var refreshIosSelection = function () { iosApi.run(function (api) { api.refreshSelection(); }); }; var scrollToY = function (yTop, height) { var y = yTop - socket.dom().scrollTop; iosApi.run(function (api) { api.scrollIntoView(y, y + height); }); }; var scrollToElement = function (target) { scrollToY(iosApi, socket); }; var scrollToCursor = function () { editorApi.getCursorBox().each(function (box) { scrollToY(box.top(), box.height()); }); }; var clearSelection = function () { iosApi.run(function (api) { api.clearSelection(); }); }; var clearAndRefresh = function () { clearSelection(); refreshThrottle.throttle(); }; var refreshView = function () { scrollToCursor(); iosApi.run(function (api) { api.syncHeight(); }); }; var reposition = function () { var toolbarHeight = get$4(toolstrip); iosApi.run(function (api) { api.setViewportOffset(toolbarHeight); }); refreshIosSelection(); refreshView(); }; var toEditing = function () { iosApi.run(function (api) { api.toEditing(); }); }; var toReading = function () { iosApi.run(function (api) { api.toReading(); }); }; var onToolbarTouch = function (event) { iosApi.run(function (api) { api.onToolbarTouch(event); }); }; var tapping = TappingEvent.monitor(editorApi); var refreshThrottle = last$1(refreshView, 300); var listeners = [ editorApi.onKeyup(clearAndRefresh), editorApi.onNodeChanged(refreshIosSelection), editorApi.onDomChanged(refreshThrottle.throttle), editorApi.onDomChanged(refreshIosSelection), editorApi.onScrollToCursor(function (tinyEvent) { tinyEvent.preventDefault(); refreshThrottle.throttle(); }), editorApi.onScrollToElement(function (event) { scrollToElement(event.element()); }), editorApi.onToEditing(toEditing), editorApi.onToReading(toReading), bind$2(editorApi.doc(), 'touchend', function (touchEvent) { if (eq(editorApi.html(), touchEvent.target()) || eq(editorApi.body(), touchEvent.target())) ; }), bind$2(toolstrip, 'transitionend', function (transitionEvent) { if (transitionEvent.raw().propertyName === 'height') { reposition(); } }), capture$1(toolstrip, 'touchstart', function (touchEvent) { saveSelectionFirst(); onToolbarTouch(touchEvent); editorApi.onTouchToolstrip(); }), bind$2(editorApi.body(), 'touchstart', function (evt) { clearSelection(); editorApi.onTouchContent(); tapping.fireTouchstart(evt); }), tapping.onTouchmove(), tapping.onTouchend(), bind$2(editorApi.body(), 'click', function (event) { event.kill(); }), bind$2(toolstrip, 'touchmove', function () { editorApi.onToolbarScrollStart(); }) ]; var destroy = function () { each$1(listeners, function (l) { l.unbind(); }); }; return { destroy: destroy }; }; var IosEvents = { initEvents: initEvents$1 }; function FakeSelection (win, frame) { var doc = win.document; var container = Element.fromTag('div'); add$2(container, Styles.resolve('unfocused-selections')); append(Element.fromDom(doc.documentElement), container); var onTouch = bind$2(container, 'touchstart', function (event) { event.prevent(); ResumeEditing$1.resume(win, frame); clear(); }); var make = function (rectangle) { var span = Element.fromTag('span'); add$3(span, [ Styles.resolve('layer-editor'), Styles.resolve('unfocused-selection') ]); setAll$1(span, { left: rectangle.left() + 'px', top: rectangle.top() + 'px', width: rectangle.width() + 'px', height: rectangle.height() + 'px' }); return span; }; var update = function () { clear(); var rectangles = Rectangles.getRectangles(win); var spans = map$1(rectangles, make); append$1(container, spans); }; var clear = function () { empty(container); }; var destroy = function () { onTouch.unbind(); remove(container); }; var isActive = function () { return children(container).length > 0; }; return { update: update, isActive: isActive, destroy: destroy, clear: clear }; } var nu$8 = function (baseFn) { var data = Option.none(); var callbacks = []; var map = function (f) { return nu$8(function (nCallback) { get(function (data) { nCallback(f(data)); }); }); }; var get = function (nCallback) { if (isReady()) call(nCallback); else callbacks.push(nCallback); }; var set = function (x) { data = Option.some(x); run(callbacks); callbacks = []; }; var isReady = function () { return data.isSome(); }; var run = function (cbs) { each$1(cbs, call); }; var call = function (cb) { data.each(function (x) { domGlobals.setTimeout(function () { cb(x); }, 0); }); }; baseFn(set); return { get: get, map: map, isReady: isReady }; }; var pure$1 = function (a) { return nu$8(function (callback) { callback(a); }); }; var LazyValue = { nu: nu$8, pure: pure$1 }; var bounce = function (f) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var me = this; domGlobals.setTimeout(function () { f.apply(me, args); }, 0); }; }; var nu$9 = function (baseFn) { var get = function (callback) { baseFn(bounce(callback)); }; var map = function (fab) { return nu$9(function (callback) { get(function (a) { var value = fab(a); callback(value); }); }); }; var bind = function (aFutureB) { return nu$9(function (callback) { get(function (a) { aFutureB(a).get(callback); }); }); }; var anonBind = function (futureB) { return nu$9(function (callback) { get(function (a) { futureB.get(callback); }); }); }; var toLazy = function () { return LazyValue.nu(get); }; var toCached = function () { var cache = null; return nu$9(function (callback) { if (cache === null) { cache = toLazy(); } cache.get(callback); }); }; return { map: map, bind: bind, anonBind: anonBind, toLazy: toLazy, toCached: toCached, get: get }; }; var pure$2 = function (a) { return nu$9(function (callback) { callback(a); }); }; var Future = { nu: nu$9, pure: pure$2 }; var adjust = function (value, destination, amount) { if (Math.abs(value - destination) <= amount) { return Option.none(); } else if (value < destination) { return Option.some(value + amount); } else { return Option.some(value - amount); } }; var create$5 = function () { var interval = null; var animate = function (getCurrent, destination, amount, increment, doFinish, rate) { var finished = false; var finish = function (v) { finished = true; doFinish(v); }; clearInterval(interval); var abort = function (v) { clearInterval(interval); finish(v); }; interval = setInterval(function () { var value = getCurrent(); adjust(value, destination, amount).fold(function () { clearInterval(interval); finish(destination); }, function (s) { increment(s, abort); if (!finished) { var newValue = getCurrent(); if (newValue !== s || Math.abs(newValue - destination) > Math.abs(value - destination)) { clearInterval(interval); finish(destination); } } }); }, rate); }; return { animate: animate }; }; var SmoothAnimation = { create: create$5, adjust: adjust }; var findDevice = function (deviceWidth, deviceHeight) { var devices = [ { width: 320, height: 480, keyboard: { portrait: 300, landscape: 240 } }, { width: 320, height: 568, keyboard: { portrait: 300, landscape: 240 } }, { width: 375, height: 667, keyboard: { portrait: 305, landscape: 240 } }, { width: 414, height: 736, keyboard: { portrait: 320, landscape: 240 } }, { width: 768, height: 1024, keyboard: { portrait: 320, landscape: 400 } }, { width: 1024, height: 1366, keyboard: { portrait: 380, landscape: 460 } } ]; return findMap(devices, function (device) { return deviceWidth <= device.width && deviceHeight <= device.height ? Option.some(device.keyboard) : Option.none(); }).getOr({ portrait: deviceHeight / 5, landscape: deviceWidth / 4 }); }; var Devices = { findDevice: findDevice }; var softKeyboardLimits = function (outerWindow) { return Devices.findDevice(outerWindow.screen.width, outerWindow.screen.height); }; var accountableKeyboardHeight = function (outerWindow) { var portrait = Orientation.get(outerWindow).isPortrait(); var limits = softKeyboardLimits(outerWindow); var keyboard = portrait ? limits.portrait : limits.landscape; var visualScreenHeight = portrait ? outerWindow.screen.height : outerWindow.screen.width; return visualScreenHeight - outerWindow.innerHeight > keyboard ? 0 : keyboard; }; var getGreenzone = function (socket, dropup) { var outerWindow = owner(socket).dom().defaultView; var viewportHeight = get$4(socket) + get$4(dropup); var acc = accountableKeyboardHeight(outerWindow); return viewportHeight - acc; }; var updatePadding = function (contentBody, socket, dropup) { var greenzoneHeight = getGreenzone(socket, dropup); var deltaHeight = get$4(socket) + get$4(dropup) - greenzoneHeight; set$2(contentBody, 'padding-bottom', deltaHeight + 'px'); }; var DeviceZones = { getGreenzone: getGreenzone, updatePadding: updatePadding }; var fixture = Adt.generate([ { fixed: [ 'element', 'property', 'offsetY' ] }, { scroller: [ 'element', 'offsetY' ] } ]); var yFixedData = 'data-' + Styles.resolve('position-y-fixed'); var yFixedProperty = 'data-' + Styles.resolve('y-property'); var yScrollingData = 'data-' + Styles.resolve('scrolling'); var windowSizeData = 'data-' + Styles.resolve('last-window-height'); var getYFixedData = function (element) { return DataAttributes.safeParse(element, yFixedData); }; var getYFixedProperty = function (element) { return get(element, yFixedProperty); }; var getLastWindowSize = function (element) { return DataAttributes.safeParse(element, windowSizeData); }; var classifyFixed = function (element, offsetY) { var prop = getYFixedProperty(element); return fixture.fixed(element, prop, offsetY); }; var classifyScrolling = function (element, offsetY) { return fixture.scroller(element, offsetY); }; var classify = function (element) { var offsetY = getYFixedData(element); var classifier = get(element, yScrollingData) === 'true' ? classifyScrolling : classifyFixed; return classifier(element, offsetY); }; var findFixtures = function (container) { var candidates = descendants(container, '[' + yFixedData + ']'); return map$1(candidates, classify); }; var takeoverToolbar = function (toolbar) { var oldToolbarStyle = get(toolbar, 'style'); setAll$1(toolbar, { position: 'absolute', top: '0px' }); set(toolbar, yFixedData, '0px'); set(toolbar, yFixedProperty, 'top'); var restore = function () { set(toolbar, 'style', oldToolbarStyle || ''); remove$1(toolbar, yFixedData); remove$1(toolbar, yFixedProperty); }; return { restore: restore }; }; var takeoverViewport = function (toolbarHeight, height, viewport) { var oldViewportStyle = get(viewport, 'style'); Scrollable.register(viewport); setAll$1(viewport, { position: 'absolute', height: height + 'px', width: '100%', top: toolbarHeight + 'px' }); set(viewport, yFixedData, toolbarHeight + 'px'); set(viewport, yScrollingData, 'true'); set(viewport, yFixedProperty, 'top'); var restore = function () { Scrollable.deregister(viewport); set(viewport, 'style', oldViewportStyle || ''); remove$1(viewport, yFixedData); remove$1(viewport, yScrollingData); remove$1(viewport, yFixedProperty); }; return { restore: restore }; }; var takeoverDropup = function (dropup, toolbarHeight, viewportHeight) { var oldDropupStyle = get(dropup, 'style'); setAll$1(dropup, { position: 'absolute', bottom: '0px' }); set(dropup, yFixedData, '0px'); set(dropup, yFixedProperty, 'bottom'); var restore = function () { set(dropup, 'style', oldDropupStyle || ''); remove$1(dropup, yFixedData); remove$1(dropup, yFixedProperty); }; return { restore: restore }; }; var deriveViewportHeight = function (viewport, toolbarHeight, dropupHeight) { var outerWindow = owner(viewport).dom().defaultView; var winH = outerWindow.innerHeight; set(viewport, windowSizeData, winH + 'px'); return winH - toolbarHeight - dropupHeight; }; var takeover$1 = function (viewport, contentBody, toolbar, dropup) { var outerWindow = owner(viewport).dom().defaultView; var toolbarSetup = takeoverToolbar(toolbar); var toolbarHeight = get$4(toolbar); var dropupHeight = get$4(dropup); var viewportHeight = deriveViewportHeight(viewport, toolbarHeight, dropupHeight); var viewportSetup = takeoverViewport(toolbarHeight, viewportHeight, viewport); var dropupSetup = takeoverDropup(dropup, toolbarHeight, viewportHeight); var isActive = true; var restore = function () { isActive = false; toolbarSetup.restore(); viewportSetup.restore(); dropupSetup.restore(); }; var isExpanding = function () { var currentWinHeight = outerWindow.innerHeight; var lastWinHeight = getLastWindowSize(viewport); return currentWinHeight > lastWinHeight; }; var refresh = function () { if (isActive) { var newToolbarHeight = get$4(toolbar); var dropupHeight_1 = get$4(dropup); var newHeight = deriveViewportHeight(viewport, newToolbarHeight, dropupHeight_1); set(viewport, yFixedData, newToolbarHeight + 'px'); set$2(viewport, 'height', newHeight + 'px'); set$2(dropup, 'bottom', -(newToolbarHeight + newHeight + dropupHeight_1) + 'px'); DeviceZones.updatePadding(contentBody, viewport, dropup); } }; var setViewportOffset = function (newYOffset) { var offsetPx = newYOffset + 'px'; set(viewport, yFixedData, offsetPx); refresh(); }; DeviceZones.updatePadding(contentBody, viewport, dropup); return { setViewportOffset: setViewportOffset, isExpanding: isExpanding, isShrinking: not(isExpanding), refresh: refresh, restore: restore }; }; var IosViewport = { findFixtures: findFixtures, takeover: takeover$1, getYFixedData: getYFixedData }; var animator = SmoothAnimation.create(); var ANIMATION_STEP = 15; var NUM_TOP_ANIMATION_FRAMES = 10; var ANIMATION_RATE = 10; var lastScroll = 'data-' + Styles.resolve('last-scroll-top'); var getTop = function (element) { var raw = getRaw(element, 'top').getOr('0'); return parseInt(raw, 10); }; var getScrollTop = function (element) { return parseInt(element.dom().scrollTop, 10); }; var moveScrollAndTop = function (element, destination, finalTop) { return Future.nu(function (callback) { var getCurrent = curry(getScrollTop, element); var update = function (newScroll) { element.dom().scrollTop = newScroll; set$2(element, 'top', getTop(element) + ANIMATION_STEP + 'px'); }; var finish = function () { element.dom().scrollTop = destination; set$2(element, 'top', finalTop + 'px'); callback(destination); }; animator.animate(getCurrent, destination, ANIMATION_STEP, update, finish, ANIMATION_RATE); }); }; var moveOnlyScroll = function (element, destination) { return Future.nu(function (callback) { var getCurrent = curry(getScrollTop, element); set(element, lastScroll, getCurrent()); var update = function (newScroll, abort) { var previous = DataAttributes.safeParse(element, lastScroll); if (previous !== element.dom().scrollTop) { abort(element.dom().scrollTop); } else { element.dom().scrollTop = newScroll; set(element, lastScroll, newScroll); } }; var finish = function () { element.dom().scrollTop = destination; set(element, lastScroll, destination); callback(destination); }; var distance = Math.abs(destination - getCurrent()); var step = Math.ceil(distance / NUM_TOP_ANIMATION_FRAMES); animator.animate(getCurrent, destination, step, update, finish, ANIMATION_RATE); }); }; var moveOnlyTop = function (element, destination) { return Future.nu(function (callback) { var getCurrent = curry(getTop, element); var update = function (newTop) { set$2(element, 'top', newTop + 'px'); }; var finish = function () { update(destination); callback(destination); }; var distance = Math.abs(destination - getCurrent()); var step = Math.ceil(distance / NUM_TOP_ANIMATION_FRAMES); animator.animate(getCurrent, destination, step, update, finish, ANIMATION_RATE); }); }; var updateTop = function (element, amount) { var newTop = amount + IosViewport.getYFixedData(element) + 'px'; set$2(element, 'top', newTop); }; var moveWindowScroll = function (toolbar, viewport, destY) { var outerWindow = owner(toolbar).dom().defaultView; return Future.nu(function (callback) { updateTop(toolbar, destY); updateTop(viewport, destY); outerWindow.scrollTo(0, destY); callback(destY); }); }; var IosScrolling = { moveScrollAndTop: moveScrollAndTop, moveOnlyScroll: moveOnlyScroll, moveOnlyTop: moveOnlyTop, moveWindowScroll: moveWindowScroll }; function BackgroundActivity (doAction) { var action = Cell(LazyValue.pure({})); var start = function (value) { var future = LazyValue.nu(function (callback) { return doAction(value).get(callback); }); action.set(future); }; var idle = function (g) { action.get().get(function () { g(); }); }; return { start: start, idle: idle }; } var scrollIntoView = function (cWin, socket, dropup, top, bottom) { var greenzone = DeviceZones.getGreenzone(socket, dropup); var refreshCursor = curry(CursorRefresh.refresh, cWin); if (top > greenzone || bottom > greenzone) { IosScrolling.moveOnlyScroll(socket, socket.dom().scrollTop - greenzone + bottom).get(refreshCursor); } else if (top < 0) { IosScrolling.moveOnlyScroll(socket, socket.dom().scrollTop + top).get(refreshCursor); } }; var Greenzone = { scrollIntoView: scrollIntoView }; var par = function (asyncValues, nu) { return nu(function (callback) { var r = []; var count = 0; var cb = function (i) { return function (value) { r[i] = value; count++; if (count >= asyncValues.length) { callback(r); } }; }; if (asyncValues.length === 0) { callback([]); } else { each$1(asyncValues, function (asyncValue, i) { asyncValue.get(cb(i)); }); } }); }; var par$1 = function (futures) { return par(futures, Future.nu); }; var updateFixed = function (element, property, winY, offsetY) { var destination = winY + offsetY; set$2(element, property, destination + 'px'); return Future.pure(offsetY); }; var updateScrollingFixed = function (element, winY, offsetY) { var destTop = winY + offsetY; var oldProp = getRaw(element, 'top').getOr(offsetY); var delta = destTop - parseInt(oldProp, 10); var destScroll = element.dom().scrollTop + delta; return IosScrolling.moveScrollAndTop(element, destScroll, destTop); }; var updateFixture = function (fixture, winY) { return fixture.fold(function (element, property, offsetY) { return updateFixed(element, property, winY, offsetY); }, function (element, offsetY) { return updateScrollingFixed(element, winY, offsetY); }); }; var updatePositions = function (container, winY) { var fixtures = IosViewport.findFixtures(container); var updates = map$1(fixtures, function (fixture) { return updateFixture(fixture, winY); }); return par$1(updates); }; var IosUpdates = { updatePositions: updatePositions }; var VIEW_MARGIN = 5; var register$2 = function (toolstrip, socket, container, outerWindow, structure, cWin) { var scroller = BackgroundActivity(function (y) { return IosScrolling.moveWindowScroll(toolstrip, socket, y); }); var scrollBounds = function () { var rects = Rectangles.getRectangles(cWin); return Option.from(rects[0]).bind(function (rect) { var viewTop = rect.top() - socket.dom().scrollTop; var outside = viewTop > outerWindow.innerHeight + VIEW_MARGIN || viewTop < -VIEW_MARGIN; return outside ? Option.some({ top: constant(viewTop), bottom: constant(viewTop + rect.height()) }) : Option.none(); }); }; var scrollThrottle = last$1(function () { scroller.idle(function () { IosUpdates.updatePositions(container, outerWindow.pageYOffset).get(function () { var extraScroll = scrollBounds(); extraScroll.each(function (extra) { socket.dom().scrollTop = socket.dom().scrollTop + extra.top(); }); scroller.start(0); structure.refresh(); }); }); }, 1000); var onScroll = bind$2(Element.fromDom(outerWindow), 'scroll', function () { if (outerWindow.pageYOffset < 0) { return; } scrollThrottle.throttle(); }); IosUpdates.updatePositions(container, outerWindow.pageYOffset).get(identity); return { unbind: onScroll.unbind }; }; var setup$3 = function (bag) { var cWin = bag.cWin(); var ceBody = bag.ceBody(); var socket = bag.socket(); var toolstrip = bag.toolstrip(); var toolbar = bag.toolbar(); var contentElement = bag.contentElement(); var keyboardType = bag.keyboardType(); var outerWindow = bag.outerWindow(); var dropup = bag.dropup(); var structure = IosViewport.takeover(socket, ceBody, toolstrip, dropup); var keyboardModel = keyboardType(bag.outerBody(), cWin, body(), contentElement, toolstrip, toolbar); var toEditing = function () { keyboardModel.toEditing(); clearSelection(); }; var toReading = function () { keyboardModel.toReading(); }; var onToolbarTouch = function (event) { keyboardModel.onToolbarTouch(event); }; var onOrientation = Orientation.onChange(outerWindow, { onChange: noop, onReady: structure.refresh }); onOrientation.onAdjustment(function () { structure.refresh(); }); var onResize = bind$2(Element.fromDom(outerWindow), 'resize', function () { if (structure.isExpanding()) { structure.refresh(); } }); var onScroll = register$2(toolstrip, socket, bag.outerBody(), outerWindow, structure, cWin); var unfocusedSelection = FakeSelection(cWin, contentElement); var refreshSelection = function () { if (unfocusedSelection.isActive()) { unfocusedSelection.update(); } }; var highlightSelection = function () { unfocusedSelection.update(); }; var clearSelection = function () { unfocusedSelection.clear(); }; var scrollIntoView = function (top, bottom) { Greenzone.scrollIntoView(cWin, socket, dropup, top, bottom); }; var syncHeight = function () { set$2(contentElement, 'height', contentElement.dom().contentWindow.document.body.scrollHeight + 'px'); }; var setViewportOffset = function (newYOffset) { structure.setViewportOffset(newYOffset); IosScrolling.moveOnlyTop(socket, newYOffset).get(identity); }; var destroy = function () { structure.restore(); onOrientation.destroy(); onScroll.unbind(); onResize.unbind(); keyboardModel.destroy(); unfocusedSelection.destroy(); CaptureBin.input(body(), blur); }; return { toEditing: toEditing, toReading: toReading, onToolbarTouch: onToolbarTouch, refreshSelection: refreshSelection, clearSelection: clearSelection, highlightSelection: highlightSelection, scrollIntoView: scrollIntoView, updateToolbarPadding: noop, setViewportOffset: setViewportOffset, syncHeight: syncHeight, refreshStructure: structure.refresh, destroy: destroy }; }; var IosSetup = { setup: setup$3 }; var create$6 = function (platform, mask) { var meta = MetaViewport.tag(); var priorState = value$2(); var scrollEvents = value$2(); var iosApi = api$2(); var iosEvents = api$2(); var enter = function () { mask.hide(); var doc = Element.fromDom(domGlobals.document); PlatformEditor.getActiveApi(platform.editor).each(function (editorApi) { priorState.set({ socketHeight: getRaw(platform.socket, 'height'), iframeHeight: getRaw(editorApi.frame(), 'height'), outerScroll: domGlobals.document.body.scrollTop }); scrollEvents.set({ exclusives: Scrollables.exclusive(doc, '.' + Scrollable.scrollable()) }); add$2(platform.container, Styles.resolve('fullscreen-maximized')); Thor.clobberStyles(platform.container, editorApi.body()); meta.maximize(); set$2(platform.socket, 'overflow', 'scroll'); set$2(platform.socket, '-webkit-overflow-scrolling', 'touch'); focus$1(editorApi.body()); var setupBag = MixedBag([ 'cWin', 'ceBody', 'socket', 'toolstrip', 'toolbar', 'dropup', 'contentElement', 'cursor', 'keyboardType', 'isScrolling', 'outerWindow', 'outerBody' ], []); iosApi.set(IosSetup.setup(setupBag({ cWin: editorApi.win(), ceBody: editorApi.body(), socket: platform.socket, toolstrip: platform.toolstrip, toolbar: platform.toolbar, dropup: platform.dropup.element(), contentElement: editorApi.frame(), cursor: noop, outerBody: platform.body, outerWindow: platform.win, keyboardType: IosKeyboard.stubborn, isScrolling: function () { var scrollValue = scrollEvents; return scrollValue.get().exists(function (s) { return s.socket.isScrolling(); }); } }))); iosApi.run(function (api) { api.syncHeight(); }); iosEvents.set(IosEvents.initEvents(editorApi, iosApi, platform.toolstrip, platform.socket, platform.dropup)); }); }; var exit = function () { meta.restore(); iosEvents.clear(); iosApi.clear(); mask.show(); priorState.on(function (s) { s.socketHeight.each(function (h) { set$2(platform.socket, 'height', h); }); s.iframeHeight.each(function (h) { set$2(platform.editor.getFrame(), 'height', h); }); domGlobals.document.body.scrollTop = s.scrollTop; }); priorState.clear(); scrollEvents.on(function (s) { s.exclusives.unbind(); }); scrollEvents.clear(); remove$4(platform.container, Styles.resolve('fullscreen-maximized')); Thor.restoreStyles(); Scrollable.deregister(platform.toolbar); remove$5(platform.socket, 'overflow'); remove$5(platform.socket, '-webkit-overflow-scrolling'); blur(platform.editor.getFrame()); PlatformEditor.getActiveApi(platform.editor).each(function (editorApi) { editorApi.clearSelection(); }); }; var refreshStructure = function () { iosApi.run(function (api) { api.refreshStructure(); }); }; return { enter: enter, refreshStructure: refreshStructure, exit: exit }; }; var IosMode = { create: create$6 }; var produce$1 = function (raw) { var mobile = asRawOrDie('Getting IosWebapp schema', MobileSchema, raw); set$2(mobile.toolstrip, 'width', '100%'); set$2(mobile.container, 'position', 'relative'); var onView = function () { mobile.setReadOnly(mobile.readOnlyOnInit()); mode.enter(); }; var mask = build$1(TapToEditMask.sketch(onView, mobile.translate)); mobile.alloy.add(mask); var maskApi = { show: function () { mobile.alloy.add(mask); }, hide: function () { mobile.alloy.remove(mask); } }; var mode = IosMode.create(mobile, maskApi); return { setReadOnly: mobile.setReadOnly, refreshStructure: mode.refreshStructure, enter: mode.enter, exit: mode.exit, destroy: noop }; }; var IosWebapp = { produce: produce$1 }; function IosRealm (scrollIntoView) { var alloy = OuterContainer({ classes: [Styles.resolve('ios-container')] }); var toolbar = ScrollingToolbar(); var webapp = api$2(); var switchToEdit = CommonRealm.makeEditSwitch(webapp); var socket = CommonRealm.makeSocket(); var dropup = build$2(function () { webapp.run(function (w) { w.refreshStructure(); }); }, scrollIntoView); alloy.add(toolbar.wrapper()); alloy.add(socket); alloy.add(dropup.component()); var setToolbarGroups = function (rawGroups) { var groups = toolbar.createGroups(rawGroups); toolbar.setGroups(groups); }; var setContextToolbar = function (rawGroups) { var groups = toolbar.createGroups(rawGroups); toolbar.setContextToolbar(groups); }; var focusToolbar = function () { toolbar.focus(); }; var restoreToolbar = function () { toolbar.restoreToolbar(); }; var init = function (spec) { webapp.set(IosWebapp.produce(spec)); }; var exit = function () { webapp.run(function (w) { Replacing.remove(socket, switchToEdit); w.exit(); }); }; var updateMode = function (readOnly) { CommonRealm.updateMode(socket, switchToEdit, readOnly, alloy.root()); }; return { system: constant(alloy), element: alloy.element, init: init, exit: exit, setToolbarGroups: setToolbarGroups, setContextToolbar: setContextToolbar, focusToolbar: focusToolbar, restoreToolbar: restoreToolbar, updateMode: updateMode, socket: constant(socket), dropup: constant(dropup) }; } var global$2 = tinymce.util.Tools.resolve('tinymce.EditorManager'); var derive$3 = function (editor) { var base = readOptFrom$1(editor.settings, 'skin_url').fold(function () { return global$2.baseURL + '/skins/' + 'lightgray'; }, function (url) { return url; }); return { content: base + '/content.mobile.min.css', ui: base + '/skin.mobile.min.css' }; }; var CssUrls = { derive: derive$3 }; var fontSizes = [ 'x-small', 'small', 'medium', 'large', 'x-large' ]; var fireChange$1 = function (realm, command, state) { realm.system().broadcastOn([TinyChannels.formatChanged()], { command: command, state: state }); }; var init$5 = function (realm, editor) { var allFormats = keys(editor.formatter.get()); each$1(allFormats, function (command) { editor.formatter.formatChanged(command, function (state) { fireChange$1(realm, command, state); }); }); each$1([ 'ul', 'ol' ], function (command) { editor.selection.selectorChanged(command, function (state, data) { fireChange$1(realm, command, state); }); }); }; var FormatChangers = { init: init$5, fontSizes: constant(fontSizes) }; var fireSkinLoaded = function (editor) { var done = function () { editor._skinLoaded = true; editor.fire('SkinLoaded'); }; return function () { if (editor.initialized) { done(); } else { editor.on('init', done); } }; }; var SkinLoaded = { fireSkinLoaded: fireSkinLoaded }; var READING = constant('toReading'); var EDITING = constant('toEditing'); global$1.add('mobile', function (editor) { var renderUI = function (args) { var cssUrls = CssUrls.derive(editor); if (isSkinDisabled(editor) === false) { editor.contentCSS.push(cssUrls.content); global.DOM.styleSheetLoader.load(cssUrls.ui, SkinLoaded.fireSkinLoaded(editor)); } else { SkinLoaded.fireSkinLoaded(editor)(); } var doScrollIntoView = function () { editor.fire('scrollIntoView'); }; var wrapper = Element.fromTag('div'); var realm = PlatformDetection$1.detect().os.isAndroid() ? AndroidRealm(doScrollIntoView) : IosRealm(doScrollIntoView); var original = Element.fromDom(args.targetNode); after(original, wrapper); attachSystem(wrapper, realm.system()); var findFocusIn = function (elem) { return search(elem).bind(function (focused) { return realm.system().getByDom(focused).toOption(); }); }; var outerWindow = args.targetNode.ownerDocument.defaultView; var orientation = Orientation.onChange(outerWindow, { onChange: function () { var alloy = realm.system(); alloy.broadcastOn([TinyChannels.orientationChanged()], { width: Orientation.getActualWidth(outerWindow) }); }, onReady: noop }); var setReadOnly = function (dynamicGroup, readOnlyGroups, mainGroups, ro) { if (ro === false) { editor.selection.collapse(); } var toolbars = configureToolbar(dynamicGroup, readOnlyGroups, mainGroups); realm.setToolbarGroups(ro === true ? toolbars.readOnly : toolbars.main); editor.setMode(ro === true ? 'readonly' : 'design'); editor.fire(ro === true ? READING() : EDITING()); realm.updateMode(ro); }; var configureToolbar = function (dynamicGroup, readOnlyGroups, mainGroups) { var dynamic = dynamicGroup.get(); var toolbars = { readOnly: dynamic.backToMask.concat(readOnlyGroups.get()), main: dynamic.backToMask.concat(mainGroups.get()) }; return toolbars; }; var bindHandler = function (label, handler) { editor.on(label, handler); return { unbind: function () { editor.off(label); } }; }; editor.on('init', function () { realm.init({ editor: { getFrame: function () { return Element.fromDom(editor.contentAreaContainer.querySelector('iframe')); }, onDomChanged: function () { return { unbind: noop }; }, onToReading: function (handler) { return bindHandler(READING(), handler); }, onToEditing: function (handler) { return bindHandler(EDITING(), handler); }, onScrollToCursor: function (handler) { editor.on('scrollIntoView', function (tinyEvent) { handler(tinyEvent); }); var unbind = function () { editor.off('scrollIntoView'); orientation.destroy(); }; return { unbind: unbind }; }, onTouchToolstrip: function () { hideDropup(); }, onTouchContent: function () { var toolbar = Element.fromDom(editor.editorContainer.querySelector('.' + Styles.resolve('toolbar'))); findFocusIn(toolbar).each(emitExecute); realm.restoreToolbar(); hideDropup(); }, onTapContent: function (evt) { var target = evt.target(); if (name(target) === 'img') { editor.selection.select(target.dom()); evt.kill(); } else if (name(target) === 'a') { var component = realm.system().getByDom(Element.fromDom(editor.editorContainer)); component.each(function (container) { if (Swapping.isAlpha(container)) { TinyCodeDupe.openLink(target.dom()); } }); } } }, container: Element.fromDom(editor.editorContainer), socket: Element.fromDom(editor.contentAreaContainer), toolstrip: Element.fromDom(editor.editorContainer.querySelector('.' + Styles.resolve('toolstrip'))), toolbar: Element.fromDom(editor.editorContainer.querySelector('.' + Styles.resolve('toolbar'))), dropup: realm.dropup(), alloy: realm.system(), translate: noop, setReadOnly: function (ro) { setReadOnly(dynamicGroup, readOnlyGroups, mainGroups, ro); }, readOnlyOnInit: function () { return readOnlyOnInit(editor); } }); var hideDropup = function () { realm.dropup().disappear(function () { realm.system().broadcastOn([TinyChannels.dropupDismissed()], {}); }); }; var backToMaskGroup = { label: 'The first group', scrollable: false, items: [Buttons.forToolbar('back', function () { editor.selection.collapse(); realm.exit(); }, {})] }; var backToReadOnlyGroup = { label: 'Back to read only', scrollable: false, items: [Buttons.forToolbar('readonly-back', function () { setReadOnly(dynamicGroup, readOnlyGroups, mainGroups, true); }, {})] }; var readOnlyGroup = { label: 'The read only mode group', scrollable: true, items: [] }; var features = Features.setup(realm, editor); var items = Features.detect(editor.settings, features); var actionGroup = { label: 'the action group', scrollable: true, items: items }; var extraGroup = { label: 'The extra group', scrollable: false, items: [] }; var mainGroups = Cell([ actionGroup, extraGroup ]); var readOnlyGroups = Cell([ readOnlyGroup, extraGroup ]); var dynamicGroup = Cell({ backToMask: [backToMaskGroup], backToReadOnly: [backToReadOnlyGroup] }); FormatChangers.init(realm, editor); }); editor.on('remove', function () { realm.exit(); }); editor.on('detach', function () { detachSystem(realm.system()); realm.system().destroy(); remove(wrapper); }); return { iframeContainer: realm.socket().element().dom(), editorContainer: realm.element().dom() }; }; return { getNotificationManagerImpl: function () { return { open: constant({ progressBar: { value: noop }, close: noop }), close: noop, reposition: noop, getArgs: identity }; }, renderUI: renderUI }; }); function Theme () { } return Theme; }(window)); })(); (function () { var modern = (function (domGlobals) { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.ThemeManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.EditorManager'); var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var isBrandingEnabled = function (editor) { return editor.getParam('branding', true, 'boolean'); }; var hasMenubar = function (editor) { return getMenubar(editor) !== false; }; var getMenubar = function (editor) { return editor.getParam('menubar'); }; var hasStatusbar = function (editor) { return editor.getParam('statusbar', true, 'boolean'); }; var getToolbarSize = function (editor) { return editor.getParam('toolbar_items_size'); }; var isReadOnly = function (editor) { return editor.getParam('readonly', false, 'boolean'); }; var getFixedToolbarContainer = function (editor) { return editor.getParam('fixed_toolbar_container'); }; var getInlineToolbarPositionHandler = function (editor) { return editor.getParam('inline_toolbar_position_handler'); }; var getMenu = function (editor) { return editor.getParam('menu'); }; var getRemovedMenuItems = function (editor) { return editor.getParam('removed_menuitems', ''); }; var getMinWidth = function (editor) { return editor.getParam('min_width', 100, 'number'); }; var getMinHeight = function (editor) { return editor.getParam('min_height', 100, 'number'); }; var getMaxWidth = function (editor) { return editor.getParam('max_width', 65535, 'number'); }; var getMaxHeight = function (editor) { return editor.getParam('max_height', 65535, 'number'); }; var isSkinDisabled = function (editor) { return editor.settings.skin === false; }; var isInline = function (editor) { return editor.getParam('inline', false, 'boolean'); }; var getResize = function (editor) { var resize = editor.getParam('resize', 'vertical'); if (resize === false) { return 'none'; } else if (resize === 'both') { return 'both'; } else { return 'vertical'; } }; var getSkinUrl = function (editor) { var settings = editor.settings; var skin = settings.skin; var skinUrl = settings.skin_url; if (skin !== false) { var skinName = skin ? skin : 'lightgray'; if (skinUrl) { skinUrl = editor.documentBaseURI.toAbsolute(skinUrl); } else { skinUrl = global$1.baseURL + '/skins/' + skinName; } } return skinUrl; }; var getIndexedToolbars = function (settings, defaultToolbar) { var toolbars = []; for (var i = 1; i < 10; i++) { var toolbar = settings['toolbar' + i]; if (!toolbar) { break; } toolbars.push(toolbar); } var mainToolbar = settings.toolbar ? [settings.toolbar] : [defaultToolbar]; return toolbars.length > 0 ? toolbars : mainToolbar; }; var getToolbars = function (editor) { var toolbar = editor.getParam('toolbar'); var defaultToolbar = 'undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image'; if (toolbar === false) { return []; } else if (global$2.isArray(toolbar)) { return global$2.grep(toolbar, function (toolbar) { return toolbar.length > 0; }); } else { return getIndexedToolbars(editor.settings, defaultToolbar); } }; var global$3 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var global$4 = tinymce.util.Tools.resolve('tinymce.ui.Factory'); var global$5 = tinymce.util.Tools.resolve('tinymce.util.I18n'); var fireSkinLoaded = function (editor) { return editor.fire('SkinLoaded'); }; var fireResizeEditor = function (editor) { return editor.fire('ResizeEditor'); }; var fireBeforeRenderUI = function (editor) { return editor.fire('BeforeRenderUI'); }; var Events = { fireSkinLoaded: fireSkinLoaded, fireResizeEditor: fireResizeEditor, fireBeforeRenderUI: fireBeforeRenderUI }; var focus = function (panel, type) { return function () { var item = panel.find(type)[0]; if (item) { item.focus(true); } }; }; var addKeys = function (editor, panel) { editor.shortcuts.add('Alt+F9', '', focus(panel, 'menubar')); editor.shortcuts.add('Alt+F10,F10', '', focus(panel, 'toolbar')); editor.shortcuts.add('Alt+F11', '', focus(panel, 'elementpath')); panel.on('cancel', function () { editor.focus(); }); }; var A11y = { addKeys: addKeys }; var global$6 = tinymce.util.Tools.resolve('tinymce.geom.Rect'); var global$7 = tinymce.util.Tools.resolve('tinymce.util.Delay'); var noop = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } }; var constant = function (value) { return function () { return value; }; }; var never = constant(false); var always = constant(true); var never$1 = never; var always$1 = always; var none = function () { return NONE; }; var NONE = function () { var eq = function (o) { return o.isNone(); }; var call = function (thunk) { return thunk(); }; var id = function (n) { return n; }; var noop = function () { }; var nul = function () { return null; }; var undef = function () { return undefined; }; var me = { fold: function (n, s) { return n(); }, is: never$1, isSome: never$1, isNone: always$1, getOr: id, getOrThunk: call, getOrDie: function (msg) { throw new Error(msg || 'error: getOrDie called on none.'); }, getOrNull: nul, getOrUndefined: undef, or: id, orThunk: call, map: none, ap: none, each: noop, bind: none, flatten: none, exists: never$1, forall: always$1, filter: none, equals: eq, equals_: eq, toArray: function () { return []; }, toString: constant('none()') }; if (Object.freeze) Object.freeze(me); return me; }(); var some = function (a) { var constant_a = function () { return a; }; var self = function () { return me; }; var map = function (f) { return some(f(a)); }; var bind = function (f) { return f(a); }; var me = { fold: function (n, s) { return s(a); }, is: function (v) { return a === v; }, isSome: always$1, isNone: never$1, getOr: constant_a, getOrThunk: constant_a, getOrDie: constant_a, getOrNull: constant_a, getOrUndefined: constant_a, or: self, orThunk: self, map: map, ap: function (optfab) { return optfab.fold(none, function (fab) { return some(fab(a)); }); }, each: function (f) { f(a); }, bind: bind, flatten: constant_a, exists: bind, forall: bind, filter: function (f) { return f(a) ? me : NONE; }, equals: function (o) { return o.is(a); }, equals_: function (o, elementEq) { return o.fold(never$1, function (b) { return elementEq(a, b); }); }, toArray: function () { return [a]; }, toString: function () { return 'some(' + a + ')'; } }; return me; }; var from = function (value) { return value === null || value === undefined ? NONE : some(value); }; var Option = { some: some, none: none, from: from }; var getUiContainerDelta = function (ctrl) { var uiContainer = getUiContainer(ctrl); if (uiContainer && global$3.DOM.getStyle(uiContainer, 'position', true) !== 'static') { var containerPos = global$3.DOM.getPos(uiContainer); var dx = uiContainer.scrollLeft - containerPos.x; var dy = uiContainer.scrollTop - containerPos.y; return Option.some({ x: dx, y: dy }); } else { return Option.none(); } }; var setUiContainer = function (editor, ctrl) { var uiContainer = global$3.DOM.select(editor.settings.ui_container)[0]; ctrl.getRoot().uiContainer = uiContainer; }; var getUiContainer = function (ctrl) { return ctrl ? ctrl.getRoot().uiContainer : null; }; var inheritUiContainer = function (fromCtrl, toCtrl) { return toCtrl.uiContainer = getUiContainer(fromCtrl); }; var UiContainer = { getUiContainerDelta: getUiContainerDelta, setUiContainer: setUiContainer, getUiContainer: getUiContainer, inheritUiContainer: inheritUiContainer }; var createToolbar = function (editor, items, size) { var toolbarItems = []; var buttonGroup; if (!items) { return; } global$2.each(items.split(/[ ,]/), function (item) { var itemName; var bindSelectorChanged = function () { var selection = editor.selection; if (item.settings.stateSelector) { selection.selectorChanged(item.settings.stateSelector, function (state) { item.active(state); }, true); } if (item.settings.disabledStateSelector) { selection.selectorChanged(item.settings.disabledStateSelector, function (state) { item.disabled(state); }); } }; if (item === '|') { buttonGroup = null; } else { if (!buttonGroup) { buttonGroup = { type: 'buttongroup', items: [] }; toolbarItems.push(buttonGroup); } if (editor.buttons[item]) { itemName = item; item = editor.buttons[itemName]; if (typeof item === 'function') { item = item(); } item.type = item.type || 'button'; item.size = size; item = global$4.create(item); buttonGroup.items.push(item); if (editor.initialized) { bindSelectorChanged(); } else { editor.on('init', bindSelectorChanged); } } } }); return { type: 'toolbar', layout: 'flow', items: toolbarItems }; }; var createToolbars = function (editor, size) { var toolbars = []; var addToolbar = function (items) { if (items) { toolbars.push(createToolbar(editor, items, size)); } }; global$2.each(getToolbars(editor), function (toolbar) { addToolbar(toolbar); }); if (toolbars.length) { return { type: 'panel', layout: 'stack', classes: 'toolbar-grp', ariaRoot: true, ariaRemember: true, items: toolbars }; } }; var Toolbar = { createToolbar: createToolbar, createToolbars: createToolbars }; var DOM = global$3.DOM; var toClientRect = function (geomRect) { return { left: geomRect.x, top: geomRect.y, width: geomRect.w, height: geomRect.h, right: geomRect.x + geomRect.w, bottom: geomRect.y + geomRect.h }; }; var hideAllFloatingPanels = function (editor) { global$2.each(editor.contextToolbars, function (toolbar) { if (toolbar.panel) { toolbar.panel.hide(); } }); }; var movePanelTo = function (panel, pos) { panel.moveTo(pos.left, pos.top); }; var togglePositionClass = function (panel, relPos, predicate) { relPos = relPos ? relPos.substr(0, 2) : ''; global$2.each({ t: 'down', b: 'up' }, function (cls, pos) { panel.classes.toggle('arrow-' + cls, predicate(pos, relPos.substr(0, 1))); }); global$2.each({ l: 'left', r: 'right' }, function (cls, pos) { panel.classes.toggle('arrow-' + cls, predicate(pos, relPos.substr(1, 1))); }); }; var userConstrain = function (handler, x, y, elementRect, contentAreaRect, panelRect) { panelRect = toClientRect({ x: x, y: y, w: panelRect.w, h: panelRect.h }); if (handler) { panelRect = handler({ elementRect: toClientRect(elementRect), contentAreaRect: toClientRect(contentAreaRect), panelRect: panelRect }); } return panelRect; }; var addContextualToolbars = function (editor) { var scrollContainer; var getContextToolbars = function () { return editor.contextToolbars || []; }; var getElementRect = function (elm) { var pos, targetRect, root; pos = DOM.getPos(editor.getContentAreaContainer()); targetRect = editor.dom.getRect(elm); root = editor.dom.getRoot(); if (root.nodeName === 'BODY') { targetRect.x -= root.ownerDocument.documentElement.scrollLeft || root.scrollLeft; targetRect.y -= root.ownerDocument.documentElement.scrollTop || root.scrollTop; } targetRect.x += pos.x; targetRect.y += pos.y; return targetRect; }; var reposition = function (match, shouldShow) { var relPos, panelRect, elementRect, contentAreaRect, panel, relRect, testPositions, smallElementWidthThreshold; var handler = getInlineToolbarPositionHandler(editor); if (editor.removed) { return; } if (!match || !match.toolbar.panel) { hideAllFloatingPanels(editor); return; } testPositions = [ 'bc-tc', 'tc-bc', 'tl-bl', 'bl-tl', 'tr-br', 'br-tr' ]; panel = match.toolbar.panel; if (shouldShow) { panel.show(); } elementRect = getElementRect(match.element); panelRect = DOM.getRect(panel.getEl()); contentAreaRect = DOM.getRect(editor.getContentAreaContainer() || editor.getBody()); var delta = UiContainer.getUiContainerDelta(panel).getOr({ x: 0, y: 0 }); elementRect.x += delta.x; elementRect.y += delta.y; panelRect.x += delta.x; panelRect.y += delta.y; contentAreaRect.x += delta.x; contentAreaRect.y += delta.y; smallElementWidthThreshold = 25; if (DOM.getStyle(match.element, 'display', true) !== 'inline') { var clientRect = match.element.getBoundingClientRect(); elementRect.w = clientRect.width; elementRect.h = clientRect.height; } if (!editor.inline) { contentAreaRect.w = editor.getDoc().documentElement.offsetWidth; } if (editor.selection.controlSelection.isResizable(match.element) && elementRect.w < smallElementWidthThreshold) { elementRect = global$6.inflate(elementRect, 0, 8); } relPos = global$6.findBestRelativePosition(panelRect, elementRect, contentAreaRect, testPositions); elementRect = global$6.clamp(elementRect, contentAreaRect); if (relPos) { relRect = global$6.relativePosition(panelRect, elementRect, relPos); movePanelTo(panel, userConstrain(handler, relRect.x, relRect.y, elementRect, contentAreaRect, panelRect)); } else { contentAreaRect.h += panelRect.h; elementRect = global$6.intersect(contentAreaRect, elementRect); if (elementRect) { relPos = global$6.findBestRelativePosition(panelRect, elementRect, contentAreaRect, [ 'bc-tc', 'bl-tl', 'br-tr' ]); if (relPos) { relRect = global$6.relativePosition(panelRect, elementRect, relPos); movePanelTo(panel, userConstrain(handler, relRect.x, relRect.y, elementRect, contentAreaRect, panelRect)); } else { movePanelTo(panel, userConstrain(handler, elementRect.x, elementRect.y, elementRect, contentAreaRect, panelRect)); } } else { panel.hide(); } } togglePositionClass(panel, relPos, function (pos1, pos2) { return pos1 === pos2; }); }; var repositionHandler = function (show) { return function () { var execute = function () { if (editor.selection) { reposition(findFrontMostMatch(editor.selection.getNode()), show); } }; global$7.requestAnimationFrame(execute); }; }; var bindScrollEvent = function (panel) { if (!scrollContainer) { var reposition_1 = repositionHandler(true); var uiContainer_1 = UiContainer.getUiContainer(panel); scrollContainer = editor.selection.getScrollContainer() || editor.getWin(); DOM.bind(scrollContainer, 'scroll', reposition_1); DOM.bind(uiContainer_1, 'scroll', reposition_1); editor.on('remove', function () { DOM.unbind(scrollContainer, 'scroll', reposition_1); DOM.unbind(uiContainer_1, 'scroll', reposition_1); }); } }; var showContextToolbar = function (match) { var panel; if (match.toolbar.panel) { match.toolbar.panel.show(); reposition(match); return; } panel = global$4.create({ type: 'floatpanel', role: 'dialog', classes: 'tinymce tinymce-inline arrow', ariaLabel: 'Inline toolbar', layout: 'flex', direction: 'column', align: 'stretch', autohide: false, autofix: true, fixed: true, border: 1, items: Toolbar.createToolbar(editor, match.toolbar.items), oncancel: function () { editor.focus(); } }); UiContainer.setUiContainer(editor, panel); bindScrollEvent(panel); match.toolbar.panel = panel; panel.renderTo().reflow(); reposition(match); }; var hideAllContextToolbars = function () { global$2.each(getContextToolbars(), function (toolbar) { if (toolbar.panel) { toolbar.panel.hide(); } }); }; var findFrontMostMatch = function (targetElm) { var i, y, parentsAndSelf; var toolbars = getContextToolbars(); parentsAndSelf = editor.$(targetElm).parents().add(targetElm); for (i = parentsAndSelf.length - 1; i >= 0; i--) { for (y = toolbars.length - 1; y >= 0; y--) { if (toolbars[y].predicate(parentsAndSelf[i])) { return { toolbar: toolbars[y], element: parentsAndSelf[i] }; } } } return null; }; editor.on('click keyup setContent ObjectResized', function (e) { if (e.type === 'setcontent' && !e.selection) { return; } global$7.setEditorTimeout(editor, function () { var match; match = findFrontMostMatch(editor.selection.getNode()); if (match) { hideAllContextToolbars(); showContextToolbar(match); } else { hideAllContextToolbars(); } }); }); editor.on('blur hide contextmenu', hideAllContextToolbars); editor.on('ObjectResizeStart', function () { var match = findFrontMostMatch(editor.selection.getNode()); if (match && match.toolbar.panel) { match.toolbar.panel.hide(); } }); editor.on('ResizeEditor ResizeWindow', repositionHandler(true)); editor.on('nodeChange', repositionHandler(false)); editor.on('remove', function () { global$2.each(getContextToolbars(), function (toolbar) { if (toolbar.panel) { toolbar.panel.remove(); } }); editor.contextToolbars = {}; }); editor.shortcuts.add('ctrl+F9', '', function () { var match = findFrontMostMatch(editor.selection.getNode()); if (match && match.toolbar.panel) { match.toolbar.panel.items()[0].focus(); } }); }; var ContextToolbars = { addContextualToolbars: addContextualToolbars }; var typeOf = function (x) { if (x === null) return 'null'; var t = typeof x; if (t === 'object' && Array.prototype.isPrototypeOf(x)) return 'array'; if (t === 'object' && String.prototype.isPrototypeOf(x)) return 'string'; return t; }; var isType = function (type) { return function (value) { return typeOf(value) === type; }; }; var isFunction = isType('function'); var isNumber = isType('number'); var rawIndexOf = function () { var pIndexOf = Array.prototype.indexOf; var fastIndex = function (xs, x) { return pIndexOf.call(xs, x); }; var slowIndex = function (xs, x) { return slowIndexOf(xs, x); }; return pIndexOf === undefined ? slowIndex : fastIndex; }(); var indexOf = function (xs, x) { var r = rawIndexOf(xs, x); return r === -1 ? Option.none() : Option.some(r); }; var exists = function (xs, pred) { return findIndex(xs, pred).isSome(); }; var map = function (xs, f) { var len = xs.length; var r = new Array(len); for (var i = 0; i < len; i++) { var x = xs[i]; r[i] = f(x, i, xs); } return r; }; var each = function (xs, f) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; f(x, i, xs); } }; var filter = function (xs, pred) { var r = []; for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { r.push(x); } } return r; }; var foldl = function (xs, f, acc) { each(xs, function (x) { acc = f(acc, x); }); return acc; }; var find = function (xs, pred) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { return Option.some(x); } } return Option.none(); }; var findIndex = function (xs, pred) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; if (pred(x, i, xs)) { return Option.some(i); } } return Option.none(); }; var slowIndexOf = function (xs, x) { for (var i = 0, len = xs.length; i < len; ++i) { if (xs[i] === x) { return i; } } return -1; }; var push = Array.prototype.push; var flatten = function (xs) { var r = []; for (var i = 0, len = xs.length; i < len; ++i) { if (!Array.prototype.isPrototypeOf(xs[i])) throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs); push.apply(r, xs[i]); } return r; }; var slice = Array.prototype.slice; var from$1 = isFunction(Array.from) ? Array.from : function (x) { return slice.call(x); }; var defaultMenus = { file: { title: 'File', items: 'newdocument restoredraft | preview | print' }, edit: { title: 'Edit', items: 'undo redo | cut copy paste pastetext | selectall' }, view: { title: 'View', items: 'code | visualaid visualchars visualblocks | spellchecker | preview fullscreen' }, insert: { title: 'Insert', items: 'image link media template codesample inserttable | charmap hr | pagebreak nonbreaking anchor toc | insertdatetime' }, format: { title: 'Format', items: 'bold italic underline strikethrough superscript subscript codeformat | blockformats align | removeformat' }, tools: { title: 'Tools', items: 'spellchecker spellcheckerlanguage | a11ycheck code' }, table: { title: 'Table' }, help: { title: 'Help' } }; var delimiterMenuNamePair = function () { return { name: '|', item: { text: '|' } }; }; var createMenuNameItemPair = function (name, item) { var menuItem = item ? { name: name, item: item } : null; return name === '|' ? delimiterMenuNamePair() : menuItem; }; var hasItemName = function (namedMenuItems, name) { return findIndex(namedMenuItems, function (namedMenuItem) { return namedMenuItem.name === name; }).isSome(); }; var isSeparator = function (namedMenuItem) { return namedMenuItem && namedMenuItem.item.text === '|'; }; var cleanupMenu = function (namedMenuItems, removedMenuItems) { var menuItemsPass1 = filter(namedMenuItems, function (namedMenuItem) { return removedMenuItems.hasOwnProperty(namedMenuItem.name) === false; }); var menuItemsPass2 = filter(menuItemsPass1, function (namedMenuItem, i, namedMenuItems) { return !isSeparator(namedMenuItem) || !isSeparator(namedMenuItems[i - 1]); }); return filter(menuItemsPass2, function (namedMenuItem, i, namedMenuItems) { return !isSeparator(namedMenuItem) || i > 0 && i < namedMenuItems.length - 1; }); }; var createMenu = function (editorMenuItems, menus, removedMenuItems, context) { var menuButton, menu, namedMenuItems, isUserDefined; if (menus) { menu = menus[context]; isUserDefined = true; } else { menu = defaultMenus[context]; } if (menu) { menuButton = { text: menu.title }; namedMenuItems = []; global$2.each((menu.items || '').split(/[ ,]/), function (name) { var namedMenuItem = createMenuNameItemPair(name, editorMenuItems[name]); if (namedMenuItem) { namedMenuItems.push(namedMenuItem); } }); if (!isUserDefined) { global$2.each(editorMenuItems, function (item, name) { if (item.context === context && !hasItemName(namedMenuItems, name)) { if (item.separator === 'before') { namedMenuItems.push(delimiterMenuNamePair()); } if (item.prependToContext) { namedMenuItems.unshift(createMenuNameItemPair(name, item)); } else { namedMenuItems.push(createMenuNameItemPair(name, item)); } if (item.separator === 'after') { namedMenuItems.push(delimiterMenuNamePair()); } } }); } menuButton.menu = map(cleanupMenu(namedMenuItems, removedMenuItems), function (menuItem) { return menuItem.item; }); if (!menuButton.menu.length) { return null; } } return menuButton; }; var getDefaultMenubar = function (editor) { var name; var defaultMenuBar = []; var menu = getMenu(editor); if (menu) { for (name in menu) { defaultMenuBar.push(name); } } else { for (name in defaultMenus) { defaultMenuBar.push(name); } } return defaultMenuBar; }; var createMenuButtons = function (editor) { var menuButtons = []; var defaultMenuBar = getDefaultMenubar(editor); var removedMenuItems = global$2.makeMap(getRemovedMenuItems(editor).split(/[ ,]/)); var menubar = getMenubar(editor); var enabledMenuNames = typeof menubar === 'string' ? menubar.split(/[ ,]/) : defaultMenuBar; for (var i = 0; i < enabledMenuNames.length; i++) { var menuItems = enabledMenuNames[i]; var menu = createMenu(editor.menuItems, getMenu(editor), removedMenuItems, menuItems); if (menu) { menuButtons.push(menu); } } return menuButtons; }; var Menubar = { createMenuButtons: createMenuButtons }; var DOM$1 = global$3.DOM; var getSize = function (elm) { return { width: elm.clientWidth, height: elm.clientHeight }; }; var resizeTo = function (editor, width, height) { var containerElm, iframeElm, containerSize, iframeSize; containerElm = editor.getContainer(); iframeElm = editor.getContentAreaContainer().firstChild; containerSize = getSize(containerElm); iframeSize = getSize(iframeElm); if (width !== null) { width = Math.max(getMinWidth(editor), width); width = Math.min(getMaxWidth(editor), width); DOM$1.setStyle(containerElm, 'width', width + (containerSize.width - iframeSize.width)); DOM$1.setStyle(iframeElm, 'width', width); } height = Math.max(getMinHeight(editor), height); height = Math.min(getMaxHeight(editor), height); DOM$1.setStyle(iframeElm, 'height', height); Events.fireResizeEditor(editor); }; var resizeBy = function (editor, dw, dh) { var elm = editor.getContentAreaContainer(); resizeTo(editor, elm.clientWidth + dw, elm.clientHeight + dh); }; var Resize = { resizeTo: resizeTo, resizeBy: resizeBy }; var global$8 = tinymce.util.Tools.resolve('tinymce.Env'); var api = function (elm) { return { element: function () { return elm; } }; }; var trigger = function (sidebar, panel, callbackName) { var callback = sidebar.settings[callbackName]; if (callback) { callback(api(panel.getEl('body'))); } }; var hidePanels = function (name, container, sidebars) { global$2.each(sidebars, function (sidebar) { var panel = container.items().filter('#' + sidebar.name)[0]; if (panel && panel.visible() && sidebar.name !== name) { trigger(sidebar, panel, 'onhide'); panel.visible(false); } }); }; var deactivateButtons = function (toolbar) { toolbar.items().each(function (ctrl) { ctrl.active(false); }); }; var findSidebar = function (sidebars, name) { return global$2.grep(sidebars, function (sidebar) { return sidebar.name === name; })[0]; }; var showPanel = function (editor, name, sidebars) { return function (e) { var btnCtrl = e.control; var container = btnCtrl.parents().filter('panel')[0]; var panel = container.find('#' + name)[0]; var sidebar = findSidebar(sidebars, name); hidePanels(name, container, sidebars); deactivateButtons(btnCtrl.parent()); if (panel && panel.visible()) { trigger(sidebar, panel, 'onhide'); panel.hide(); btnCtrl.active(false); } else { if (panel) { panel.show(); trigger(sidebar, panel, 'onshow'); } else { panel = global$4.create({ type: 'container', name: name, layout: 'stack', classes: 'sidebar-panel', html: '' }); container.prepend(panel); trigger(sidebar, panel, 'onrender'); trigger(sidebar, panel, 'onshow'); } btnCtrl.active(true); } Events.fireResizeEditor(editor); }; }; var isModernBrowser = function () { return !global$8.ie || global$8.ie >= 11; }; var hasSidebar = function (editor) { return isModernBrowser() && editor.sidebars ? editor.sidebars.length > 0 : false; }; var createSidebar = function (editor) { var buttons = global$2.map(editor.sidebars, function (sidebar) { var settings = sidebar.settings; return { type: 'button', icon: settings.icon, image: settings.image, tooltip: settings.tooltip, onclick: showPanel(editor, sidebar.name, editor.sidebars) }; }); return { type: 'panel', name: 'sidebar', layout: 'stack', classes: 'sidebar', items: [{ type: 'toolbar', layout: 'stack', classes: 'sidebar-toolbar', items: buttons }] }; }; var Sidebar = { hasSidebar: hasSidebar, createSidebar: createSidebar }; var fireSkinLoaded$1 = function (editor) { var done = function () { editor._skinLoaded = true; Events.fireSkinLoaded(editor); }; return function () { if (editor.initialized) { done(); } else { editor.on('init', done); } }; }; var SkinLoaded = { fireSkinLoaded: fireSkinLoaded$1 }; var DOM$2 = global$3.DOM; var switchMode = function (panel) { return function (e) { panel.find('*').disabled(e.mode === 'readonly'); }; }; var editArea = function (border) { return { type: 'panel', name: 'iframe', layout: 'stack', classes: 'edit-area', border: border, html: '' }; }; var editAreaContainer = function (editor) { return { type: 'panel', layout: 'stack', classes: 'edit-aria-container', border: '1 0 0 0', items: [ editArea('0'), Sidebar.createSidebar(editor) ] }; }; var render = function (editor, theme, args) { var panel, resizeHandleCtrl, startSize; if (isSkinDisabled(editor) === false && args.skinUiCss) { DOM$2.styleSheetLoader.load(args.skinUiCss, SkinLoaded.fireSkinLoaded(editor)); } else { SkinLoaded.fireSkinLoaded(editor)(); } panel = theme.panel = global$4.create({ type: 'panel', role: 'application', classes: 'tinymce', style: 'visibility: hidden', layout: 'stack', border: 1, items: [ { type: 'container', classes: 'top-part', items: [ hasMenubar(editor) === false ? null : { type: 'menubar', border: '0 0 1 0', items: Menubar.createMenuButtons(editor) }, Toolbar.createToolbars(editor, getToolbarSize(editor)) ] }, Sidebar.hasSidebar(editor) ? editAreaContainer(editor) : editArea('1 0 0 0') ] }); UiContainer.setUiContainer(editor, panel); if (getResize(editor) !== 'none') { resizeHandleCtrl = { type: 'resizehandle', direction: getResize(editor), onResizeStart: function () { var elm = editor.getContentAreaContainer().firstChild; startSize = { width: elm.clientWidth, height: elm.clientHeight }; }, onResize: function (e) { if (getResize(editor) === 'both') { Resize.resizeTo(editor, startSize.width + e.deltaX, startSize.height + e.deltaY); } else { Resize.resizeTo(editor, null, startSize.height + e.deltaY); } } }; } if (hasStatusbar(editor)) { var linkHtml = '<a href="https://www.tiny.cloud/?utm_campaign=editor_referral&utm_medium=poweredby&utm_source=tinymce" rel="noopener" target="_blank" role="presentation" tabindex="-1">Tiny</a>'; var html = global$5.translate([ 'Powered by {0}', linkHtml ]); var brandingLabel = isBrandingEnabled(editor) ? { type: 'label', classes: 'branding', html: ' ' + html } : null; panel.add({ type: 'panel', name: 'statusbar', classes: 'statusbar', layout: 'flow', border: '1 0 0 0', ariaRoot: true, items: [ { type: 'elementpath', editor: editor }, resizeHandleCtrl, brandingLabel ] }); } Events.fireBeforeRenderUI(editor); editor.on('SwitchMode', switchMode(panel)); panel.renderBefore(args.targetNode).reflow(); if (isReadOnly(editor)) { editor.setMode('readonly'); } if (args.width) { DOM$2.setStyle(panel.getEl(), 'width', args.width); } editor.on('remove', function () { panel.remove(); panel = null; }); A11y.addKeys(editor, panel); ContextToolbars.addContextualToolbars(editor); return { iframeContainer: panel.find('#iframe')[0].getEl(), editorContainer: panel.getEl() }; }; var Iframe = { render: render }; var global$9 = tinymce.util.Tools.resolve('tinymce.dom.DomQuery'); var count = 0; var funcs = { id: function () { return 'mceu_' + count++; }, create: function (name, attrs, children) { var elm = domGlobals.document.createElement(name); global$3.DOM.setAttribs(elm, attrs); if (typeof children === 'string') { elm.innerHTML = children; } else { global$2.each(children, function (child) { if (child.nodeType) { elm.appendChild(child); } }); } return elm; }, createFragment: function (html) { return global$3.DOM.createFragment(html); }, getWindowSize: function () { return global$3.DOM.getViewPort(); }, getSize: function (elm) { var width, height; if (elm.getBoundingClientRect) { var rect = elm.getBoundingClientRect(); width = Math.max(rect.width || rect.right - rect.left, elm.offsetWidth); height = Math.max(rect.height || rect.bottom - rect.bottom, elm.offsetHeight); } else { width = elm.offsetWidth; height = elm.offsetHeight; } return { width: width, height: height }; }, getPos: function (elm, root) { return global$3.DOM.getPos(elm, root || funcs.getContainer()); }, getContainer: function () { return global$8.container ? global$8.container : domGlobals.document.body; }, getViewPort: function (win) { return global$3.DOM.getViewPort(win); }, get: function (id) { return domGlobals.document.getElementById(id); }, addClass: function (elm, cls) { return global$3.DOM.addClass(elm, cls); }, removeClass: function (elm, cls) { return global$3.DOM.removeClass(elm, cls); }, hasClass: function (elm, cls) { return global$3.DOM.hasClass(elm, cls); }, toggleClass: function (elm, cls, state) { return global$3.DOM.toggleClass(elm, cls, state); }, css: function (elm, name, value) { return global$3.DOM.setStyle(elm, name, value); }, getRuntimeStyle: function (elm, name) { return global$3.DOM.getStyle(elm, name, true); }, on: function (target, name, callback, scope) { return global$3.DOM.bind(target, name, callback, scope); }, off: function (target, name, callback) { return global$3.DOM.unbind(target, name, callback); }, fire: function (target, name, args) { return global$3.DOM.fire(target, name, args); }, innerHtml: function (elm, html) { global$3.DOM.setHTML(elm, html); } }; var isStatic = function (elm) { return funcs.getRuntimeStyle(elm, 'position') === 'static'; }; var isFixed = function (ctrl) { return ctrl.state.get('fixed'); }; function calculateRelativePosition(ctrl, targetElm, rel) { var ctrlElm, pos, x, y, selfW, selfH, targetW, targetH, viewport, size; viewport = getWindowViewPort(); pos = funcs.getPos(targetElm, UiContainer.getUiContainer(ctrl)); x = pos.x; y = pos.y; if (isFixed(ctrl) && isStatic(domGlobals.document.body)) { x -= viewport.x; y -= viewport.y; } ctrlElm = ctrl.getEl(); size = funcs.getSize(ctrlElm); selfW = size.width; selfH = size.height; size = funcs.getSize(targetElm); targetW = size.width; targetH = size.height; rel = (rel || '').split(''); if (rel[0] === 'b') { y += targetH; } if (rel[1] === 'r') { x += targetW; } if (rel[0] === 'c') { y += Math.round(targetH / 2); } if (rel[1] === 'c') { x += Math.round(targetW / 2); } if (rel[3] === 'b') { y -= selfH; } if (rel[4] === 'r') { x -= selfW; } if (rel[3] === 'c') { y -= Math.round(selfH / 2); } if (rel[4] === 'c') { x -= Math.round(selfW / 2); } return { x: x, y: y, w: selfW, h: selfH }; } var getUiContainerViewPort = function (customUiContainer) { return { x: 0, y: 0, w: customUiContainer.scrollWidth - 1, h: customUiContainer.scrollHeight - 1 }; }; var getWindowViewPort = function () { var win = domGlobals.window; var x = Math.max(win.pageXOffset, domGlobals.document.body.scrollLeft, domGlobals.document.documentElement.scrollLeft); var y = Math.max(win.pageYOffset, domGlobals.document.body.scrollTop, domGlobals.document.documentElement.scrollTop); var w = win.innerWidth || domGlobals.document.documentElement.clientWidth; var h = win.innerHeight || domGlobals.document.documentElement.clientHeight; return { x: x, y: y, w: w, h: h }; }; var getViewPortRect = function (ctrl) { var customUiContainer = UiContainer.getUiContainer(ctrl); return customUiContainer && !isFixed(ctrl) ? getUiContainerViewPort(customUiContainer) : getWindowViewPort(); }; var Movable = { testMoveRel: function (elm, rels) { var viewPortRect = getViewPortRect(this); for (var i = 0; i < rels.length; i++) { var pos = calculateRelativePosition(this, elm, rels[i]); if (isFixed(this)) { if (pos.x > 0 && pos.x + pos.w < viewPortRect.w && pos.y > 0 && pos.y + pos.h < viewPortRect.h) { return rels[i]; } } else { 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) { return rels[i]; } } } return rels[0]; }, moveRel: function (elm, rel) { if (typeof rel !== 'string') { rel = this.testMoveRel(elm, rel); } var pos = calculateRelativePosition(this, elm, rel); return this.moveTo(pos.x, pos.y); }, moveBy: function (dx, dy) { var self = this, rect = self.layoutRect(); self.moveTo(rect.x + dx, rect.y + dy); return self; }, moveTo: function (x, y) { var self = this; function constrain(value, max, size) { if (value < 0) { return 0; } if (value + size > max) { value = max - size; return value < 0 ? 0 : value; } return value; } if (self.settings.constrainToViewport) { var viewPortRect = getViewPortRect(this); var layoutRect = self.layoutRect(); x = constrain(x, viewPortRect.w + viewPortRect.x, layoutRect.w); y = constrain(y, viewPortRect.h + viewPortRect.y, layoutRect.h); } var uiContainer = UiContainer.getUiContainer(self); if (uiContainer && isStatic(uiContainer) && !isFixed(self)) { x -= uiContainer.scrollLeft; y -= uiContainer.scrollTop; } if (uiContainer) { x += 1; y += 1; } if (self.state.get('rendered')) { self.layoutRect({ x: x, y: y }).repaint(); } else { self.settings.x = x; self.settings.y = y; } self.fire('move', { x: x, y: y }); return self; } }; var global$a = tinymce.util.Tools.resolve('tinymce.util.Class'); var global$b = tinymce.util.Tools.resolve('tinymce.util.EventDispatcher'); var BoxUtils = { parseBox: function (value) { var len; var radix = 10; if (!value) { return; } if (typeof value === 'number') { value = value || 0; return { top: value, left: value, bottom: value, right: value }; } value = value.split(' '); len = value.length; if (len === 1) { value[1] = value[2] = value[3] = value[0]; } else if (len === 2) { value[2] = value[0]; value[3] = value[1]; } else if (len === 3) { value[3] = value[1]; } return { top: parseInt(value[0], radix) || 0, right: parseInt(value[1], radix) || 0, bottom: parseInt(value[2], radix) || 0, left: parseInt(value[3], radix) || 0 }; }, measureBox: function (elm, prefix) { function getStyle(name) { var defaultView = elm.ownerDocument.defaultView; if (defaultView) { var computedStyle = defaultView.getComputedStyle(elm, null); if (computedStyle) { name = name.replace(/[A-Z]/g, function (a) { return '-' + a; }); return computedStyle.getPropertyValue(name); } else { return null; } } return elm.currentStyle[name]; } function getSide(name) { var val = parseFloat(getStyle(name)); return isNaN(val) ? 0 : val; } return { top: getSide(prefix + 'TopWidth'), right: getSide(prefix + 'RightWidth'), bottom: getSide(prefix + 'BottomWidth'), left: getSide(prefix + 'LeftWidth') }; } }; function noop$1() { } function ClassList(onchange) { this.cls = []; this.cls._map = {}; this.onchange = onchange || noop$1; this.prefix = ''; } global$2.extend(ClassList.prototype, { add: function (cls) { if (cls && !this.contains(cls)) { this.cls._map[cls] = true; this.cls.push(cls); this._change(); } return this; }, remove: function (cls) { if (this.contains(cls)) { var i = void 0; for (i = 0; i < this.cls.length; i++) { if (this.cls[i] === cls) { break; } } this.cls.splice(i, 1); delete this.cls._map[cls]; this._change(); } return this; }, toggle: function (cls, state) { var curState = this.contains(cls); if (curState !== state) { if (curState) { this.remove(cls); } else { this.add(cls); } this._change(); } return this; }, contains: function (cls) { return !!this.cls._map[cls]; }, _change: function () { delete this.clsValue; this.onchange.call(this); } }); ClassList.prototype.toString = function () { var value; if (this.clsValue) { return this.clsValue; } value = ''; for (var i = 0; i < this.cls.length; i++) { if (i > 0) { value += ' '; } value += this.prefix + this.cls[i]; } return value; }; function unique(array) { var uniqueItems = []; var i = array.length, item; while (i--) { item = array[i]; if (!item.__checked) { uniqueItems.push(item); item.__checked = 1; } } i = uniqueItems.length; while (i--) { delete uniqueItems[i].__checked; } return uniqueItems; } var expression = /^([\w\\*]+)?(?:#([\w\-\\]+))?(?:\.([\w\\\.]+))?(?:\[\@?([\w\\]+)([\^\$\*!~]?=)([\w\\]+)\])?(?:\:(.+))?/i; var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g; var whiteSpace = /^\s*|\s*$/g; var Collection; var Selector = global$a.extend({ init: function (selector) { var match = this.match; function compileNameFilter(name) { if (name) { name = name.toLowerCase(); return function (item) { return name === '*' || item.type === name; }; } } function compileIdFilter(id) { if (id) { return function (item) { return item._name === id; }; } } function compileClassesFilter(classes) { if (classes) { classes = classes.split('.'); return function (item) { var i = classes.length; while (i--) { if (!item.classes.contains(classes[i])) { return false; } } return true; }; } } function compileAttrFilter(name, cmp, check) { if (name) { return function (item) { var value = item[name] ? item[name]() : ''; 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; }; } } function compilePsuedoFilter(name) { var notSelectors; if (name) { name = /(?:not\((.+)\))|(.+)/i.exec(name); if (!name[1]) { name = name[2]; return function (item, index, length) { 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; }; } notSelectors = parseChunks(name[1], []); return function (item) { return !match(item, notSelectors); }; } } function compile(selector, filters, direct) { var parts; function add(filter) { if (filter) { filters.push(filter); } } parts = expression.exec(selector.replace(whiteSpace, '')); add(compileNameFilter(parts[1])); add(compileIdFilter(parts[2])); add(compileClassesFilter(parts[3])); add(compileAttrFilter(parts[4], parts[5], parts[6])); add(compilePsuedoFilter(parts[7])); filters.pseudo = !!parts[7]; filters.direct = direct; return filters; } function parseChunks(selector, selectors) { var parts = []; var extra, matches, i; do { chunker.exec(''); matches = chunker.exec(selector); if (matches) { selector = matches[3]; parts.push(matches[1]); if (matches[2]) { extra = matches[3]; break; } } } while (matches); if (extra) { parseChunks(extra, selectors); } selector = []; for (i = 0; i < parts.length; i++) { if (parts[i] !== '>') { selector.push(compile(parts[i], [], parts[i - 1] === '>')); } } selectors.push(selector); return selectors; } this._selectors = parseChunks(selector, []); }, match: function (control, selectors) { var i, l, si, sl, selector, fi, fl, filters, index, length, siblings, count, item; selectors = selectors || this._selectors; for (i = 0, l = selectors.length; i < l; i++) { selector = selectors[i]; sl = selector.length; item = control; count = 0; for (si = sl - 1; si >= 0; si--) { filters = selector[si]; while (item) { if (filters.pseudo) { siblings = item.parent().items(); index = length = siblings.length; while (index--) { if (siblings[index] === item) { break; } } } for (fi = 0, fl = filters.length; fi < fl; fi++) { if (!filters[fi](item, index, length)) { fi = fl + 1; break; } } if (fi === fl) { count++; break; } else { if (si === sl - 1) { break; } } item = item.parent(); } } if (count === sl) { return true; } } return false; }, find: function (container) { var matches = [], i, l; var selectors = this._selectors; function collect(items, selector, index) { var i, l, fi, fl, item; var filters = selector[index]; for (i = 0, l = items.length; i < l; i++) { item = items[i]; for (fi = 0, fl = filters.length; fi < fl; fi++) { if (!filters[fi](item, i, l)) { fi = fl + 1; break; } } if (fi === fl) { if (index === selector.length - 1) { matches.push(item); } else { if (item.items) { collect(item.items(), selector, index + 1); } } } else if (filters.direct) { return; } if (item.items) { collect(item.items(), selector, index); } } } if (container.items) { for (i = 0, l = selectors.length; i < l; i++) { collect(container.items(), selectors[i], 0); } if (l > 1) { matches = unique(matches); } } if (!Collection) { Collection = Selector.Collection; } return new Collection(matches); } }); var Collection$1, proto; var push$1 = Array.prototype.push, slice$1 = Array.prototype.slice; proto = { length: 0, init: function (items) { if (items) { this.add(items); } }, add: function (items) { var self = this; if (!global$2.isArray(items)) { if (items instanceof Collection$1) { self.add(items.toArray()); } else { push$1.call(self, items); } } else { push$1.apply(self, items); } return self; }, set: function (items) { var self = this; var len = self.length; var i; self.length = 0; self.add(items); for (i = self.length; i < len; i++) { delete self[i]; } return self; }, filter: function (selector) { var self = this; var i, l; var matches = []; var item, match; if (typeof selector === 'string') { selector = new Selector(selector); match = function (item) { return selector.match(item); }; } else { match = selector; } for (i = 0, l = self.length; i < l; i++) { item = self[i]; if (match(item)) { matches.push(item); } } return new Collection$1(matches); }, slice: function () { return new Collection$1(slice$1.apply(this, arguments)); }, eq: function (index) { return index === -1 ? this.slice(index) : this.slice(index, +index + 1); }, each: function (callback) { global$2.each(this, callback); return this; }, toArray: function () { return global$2.toArray(this); }, indexOf: function (ctrl) { var self = this; var i = self.length; while (i--) { if (self[i] === ctrl) { break; } } return i; }, reverse: function () { return new Collection$1(global$2.toArray(this).reverse()); }, hasClass: function (cls) { return this[0] ? this[0].classes.contains(cls) : false; }, prop: function (name, value) { var self = this; var item; if (value !== undefined) { self.each(function (item) { if (item[name]) { item[name](value); } }); return self; } item = self[0]; if (item && item[name]) { return item[name](); } }, exec: function (name) { var self = this, args = global$2.toArray(arguments).slice(1); self.each(function (item) { if (item[name]) { item[name].apply(item, args); } }); return self; }, remove: function () { var i = this.length; while (i--) { this[i].remove(); } return this; }, addClass: function (cls) { return this.each(function (item) { item.classes.add(cls); }); }, removeClass: function (cls) { return this.each(function (item) { item.classes.remove(cls); }); } }; global$2.each('fire on off show hide append prepend before after reflow'.split(' '), function (name) { proto[name] = function () { var args = global$2.toArray(arguments); this.each(function (ctrl) { if (name in ctrl) { ctrl[name].apply(ctrl, args); } }); return this; }; }); global$2.each('text name disabled active selected checked visible parent value data'.split(' '), function (name) { proto[name] = function (value) { return this.prop(name, value); }; }); Collection$1 = global$a.extend(proto); Selector.Collection = Collection$1; var Collection$2 = Collection$1; var Binding = function (settings) { this.create = settings.create; }; Binding.create = function (model, name) { return new Binding({ create: function (otherModel, otherName) { var bindings; var fromSelfToOther = function (e) { otherModel.set(otherName, e.value); }; var fromOtherToSelf = function (e) { model.set(name, e.value); }; otherModel.on('change:' + otherName, fromOtherToSelf); model.on('change:' + name, fromSelfToOther); bindings = otherModel._bindings; if (!bindings) { bindings = otherModel._bindings = []; otherModel.on('destroy', function () { var i = bindings.length; while (i--) { bindings[i](); } }); } bindings.push(function () { model.off('change:' + name, fromSelfToOther); }); return model.get(name); } }); }; var global$c = tinymce.util.Tools.resolve('tinymce.util.Observable'); function isNode(node) { return node.nodeType > 0; } function isEqual(a, b) { var k, checked; if (a === b) { return true; } if (a === null || b === null) { return a === b; } if (typeof a !== 'object' || typeof b !== 'object') { return a === b; } if (global$2.isArray(b)) { if (a.length !== b.length) { return false; } k = a.length; while (k--) { if (!isEqual(a[k], b[k])) { return false; } } } if (isNode(a) || isNode(b)) { return a === b; } checked = {}; for (k in b) { if (!isEqual(a[k], b[k])) { return false; } checked[k] = true; } for (k in a) { if (!checked[k] && !isEqual(a[k], b[k])) { return false; } } return true; } var ObservableObject = global$a.extend({ Mixins: [global$c], init: function (data) { var name, value; data = data || {}; for (name in data) { value = data[name]; if (value instanceof Binding) { data[name] = value.create(this, name); } } this.data = data; }, set: function (name, value) { var key, args; var oldValue = this.data[name]; if (value instanceof Binding) { value = value.create(this, name); } if (typeof name === 'object') { for (key in name) { this.set(key, name[key]); } return this; } if (!isEqual(oldValue, value)) { this.data[name] = value; args = { target: this, name: name, value: value, oldValue: oldValue }; this.fire('change:' + name, args); this.fire('change', args); } return this; }, get: function (name) { return this.data[name]; }, has: function (name) { return name in this.data; }, bind: function (name) { return Binding.create(this, name); }, destroy: function () { this.fire('destroy'); } }); var dirtyCtrls = {}, animationFrameRequested; var ReflowQueue = { add: function (ctrl) { var parent = ctrl.parent(); if (parent) { if (!parent._layout || parent._layout.isNative()) { return; } if (!dirtyCtrls[parent._id]) { dirtyCtrls[parent._id] = parent; } if (!animationFrameRequested) { animationFrameRequested = true; global$7.requestAnimationFrame(function () { var id, ctrl; animationFrameRequested = false; for (id in dirtyCtrls) { ctrl = dirtyCtrls[id]; if (ctrl.state.get('rendered')) { ctrl.reflow(); } } dirtyCtrls = {}; }, domGlobals.document.body); } } }, remove: function (ctrl) { if (dirtyCtrls[ctrl._id]) { delete dirtyCtrls[ctrl._id]; } } }; var hasMouseWheelEventSupport = 'onmousewheel' in domGlobals.document; var hasWheelEventSupport = false; var classPrefix = 'mce-'; var Control, idCounter = 0; var proto$1 = { Statics: { classPrefix: classPrefix }, isRtl: function () { return Control.rtl; }, classPrefix: classPrefix, init: function (settings) { var self = this; var classes, defaultClasses; function applyClasses(classes) { var i; classes = classes.split(' '); for (i = 0; i < classes.length; i++) { self.classes.add(classes[i]); } } self.settings = settings = global$2.extend({}, self.Defaults, settings); self._id = settings.id || 'mceu_' + idCounter++; self._aria = { role: settings.role }; self._elmCache = {}; self.$ = global$9; self.state = new ObservableObject({ visible: true, active: false, disabled: false, value: '' }); self.data = new ObservableObject(settings.data); self.classes = new ClassList(function () { if (self.state.get('rendered')) { self.getEl().className = this.toString(); } }); self.classes.prefix = self.classPrefix; classes = settings.classes; if (classes) { if (self.Defaults) { defaultClasses = self.Defaults.classes; if (defaultClasses && classes !== defaultClasses) { applyClasses(defaultClasses); } } applyClasses(classes); } global$2.each('title text name visible disabled active value'.split(' '), function (name) { if (name in settings) { self[name](settings[name]); } }); self.on('click', function () { if (self.disabled()) { return false; } }); self.settings = settings; self.borderBox = BoxUtils.parseBox(settings.border); self.paddingBox = BoxUtils.parseBox(settings.padding); self.marginBox = BoxUtils.parseBox(settings.margin); if (settings.hidden) { self.hide(); } }, Properties: 'parent,name', getContainerElm: function () { var uiContainer = UiContainer.getUiContainer(this); return uiContainer ? uiContainer : funcs.getContainer(); }, getParentCtrl: function (elm) { var ctrl; var lookup = this.getRoot().controlIdLookup; while (elm && lookup) { ctrl = lookup[elm.id]; if (ctrl) { break; } elm = elm.parentNode; } return ctrl; }, initLayoutRect: function () { var self = this; var settings = self.settings; var borderBox, layoutRect; var elm = self.getEl(); var width, height, minWidth, minHeight, autoResize; var startMinWidth, startMinHeight, initialSize; borderBox = self.borderBox = self.borderBox || BoxUtils.measureBox(elm, 'border'); self.paddingBox = self.paddingBox || BoxUtils.measureBox(elm, 'padding'); self.marginBox = self.marginBox || BoxUtils.measureBox(elm, 'margin'); initialSize = funcs.getSize(elm); startMinWidth = settings.minWidth; startMinHeight = settings.minHeight; minWidth = startMinWidth || initialSize.width; minHeight = startMinHeight || initialSize.height; width = settings.width; height = settings.height; autoResize = settings.autoResize; autoResize = typeof autoResize !== 'undefined' ? autoResize : !width && !height; width = width || minWidth; height = height || minHeight; var deltaW = borderBox.left + borderBox.right; var deltaH = borderBox.top + borderBox.bottom; var maxW = settings.maxWidth || 65535; var maxH = settings.maxHeight || 65535; self._layoutRect = layoutRect = { x: settings.x || 0, y: settings.y || 0, w: width, h: height, deltaW: deltaW, deltaH: deltaH, contentW: width - deltaW, contentH: height - deltaH, innerW: width - deltaW, innerH: height - deltaH, startMinWidth: startMinWidth || 0, startMinHeight: startMinHeight || 0, minW: Math.min(minWidth, maxW), minH: Math.min(minHeight, maxH), maxW: maxW, maxH: maxH, autoResize: autoResize, scrollW: 0 }; self._lastLayoutRect = {}; return layoutRect; }, layoutRect: function (newRect) { var self = this; var curRect = self._layoutRect, lastLayoutRect, size, deltaWidth, deltaHeight, repaintControls; if (!curRect) { curRect = self.initLayoutRect(); } if (newRect) { deltaWidth = curRect.deltaW; deltaHeight = curRect.deltaH; if (newRect.x !== undefined) { curRect.x = newRect.x; } if (newRect.y !== undefined) { curRect.y = newRect.y; } if (newRect.minW !== undefined) { curRect.minW = newRect.minW; } if (newRect.minH !== undefined) { curRect.minH = newRect.minH; } size = newRect.w; if (size !== undefined) { size = size < curRect.minW ? curRect.minW : size; size = size > curRect.maxW ? curRect.maxW : size; curRect.w = size; curRect.innerW = size - deltaWidth; } size = newRect.h; if (size !== undefined) { size = size < curRect.minH ? curRect.minH : size; size = size > curRect.maxH ? curRect.maxH : size; curRect.h = size; curRect.innerH = size - deltaHeight; } size = newRect.innerW; if (size !== undefined) { size = size < curRect.minW - deltaWidth ? curRect.minW - deltaWidth : size; size = size > curRect.maxW - deltaWidth ? curRect.maxW - deltaWidth : size; curRect.innerW = size; curRect.w = size + deltaWidth; } size = newRect.innerH; if (size !== undefined) { size = size < curRect.minH - deltaHeight ? curRect.minH - deltaHeight : size; size = size > curRect.maxH - deltaHeight ? curRect.maxH - deltaHeight : size; curRect.innerH = size; curRect.h = size + deltaHeight; } if (newRect.contentW !== undefined) { curRect.contentW = newRect.contentW; } if (newRect.contentH !== undefined) { curRect.contentH = newRect.contentH; } lastLayoutRect = self._lastLayoutRect; if (lastLayoutRect.x !== curRect.x || lastLayoutRect.y !== curRect.y || lastLayoutRect.w !== curRect.w || lastLayoutRect.h !== curRect.h) { repaintControls = Control.repaintControls; if (repaintControls) { if (repaintControls.map && !repaintControls.map[self._id]) { repaintControls.push(self); repaintControls.map[self._id] = true; } } lastLayoutRect.x = curRect.x; lastLayoutRect.y = curRect.y; lastLayoutRect.w = curRect.w; lastLayoutRect.h = curRect.h; } return self; } return curRect; }, repaint: function () { var self = this; var style, bodyStyle, bodyElm, rect, borderBox; var borderW, borderH, lastRepaintRect, round, value; round = !domGlobals.document.createRange ? Math.round : function (value) { return value; }; style = self.getEl().style; rect = self._layoutRect; lastRepaintRect = self._lastRepaintRect || {}; borderBox = self.borderBox; borderW = borderBox.left + borderBox.right; borderH = borderBox.top + borderBox.bottom; if (rect.x !== lastRepaintRect.x) { style.left = round(rect.x) + 'px'; lastRepaintRect.x = rect.x; } if (rect.y !== lastRepaintRect.y) { style.top = round(rect.y) + 'px'; lastRepaintRect.y = rect.y; } if (rect.w !== lastRepaintRect.w) { value = round(rect.w - borderW); style.width = (value >= 0 ? value : 0) + 'px'; lastRepaintRect.w = rect.w; } if (rect.h !== lastRepaintRect.h) { value = round(rect.h - borderH); style.height = (value >= 0 ? value : 0) + 'px'; lastRepaintRect.h = rect.h; } if (self._hasBody && rect.innerW !== lastRepaintRect.innerW) { value = round(rect.innerW); bodyElm = self.getEl('body'); if (bodyElm) { bodyStyle = bodyElm.style; bodyStyle.width = (value >= 0 ? value : 0) + 'px'; } lastRepaintRect.innerW = rect.innerW; } if (self._hasBody && rect.innerH !== lastRepaintRect.innerH) { value = round(rect.innerH); bodyElm = bodyElm || self.getEl('body'); if (bodyElm) { bodyStyle = bodyStyle || bodyElm.style; bodyStyle.height = (value >= 0 ? value : 0) + 'px'; } lastRepaintRect.innerH = rect.innerH; } self._lastRepaintRect = lastRepaintRect; self.fire('repaint', {}, false); }, updateLayoutRect: function () { var self = this; self.parent()._lastRect = null; funcs.css(self.getEl(), { width: '', height: '' }); self._layoutRect = self._lastRepaintRect = self._lastLayoutRect = null; self.initLayoutRect(); }, on: function (name, callback) { var self = this; function resolveCallbackName(name) { var callback, scope; if (typeof name !== 'string') { return name; } return function (e) { if (!callback) { self.parentsAndSelf().each(function (ctrl) { var callbacks = ctrl.settings.callbacks; if (callbacks && (callback = callbacks[name])) { scope = ctrl; return false; } }); } if (!callback) { e.action = name; this.fire('execute', e); return; } return callback.call(scope, e); }; } getEventDispatcher(self).on(name, resolveCallbackName(callback)); return self; }, off: function (name, callback) { getEventDispatcher(this).off(name, callback); return this; }, fire: function (name, args, bubble) { var self = this; args = args || {}; if (!args.control) { args.control = self; } args = getEventDispatcher(self).fire(name, args); if (bubble !== false && self.parent) { var parent = self.parent(); while (parent && !args.isPropagationStopped()) { parent.fire(name, args, false); parent = parent.parent(); } } return args; }, hasEventListeners: function (name) { return getEventDispatcher(this).has(name); }, parents: function (selector) { var self = this; var ctrl, parents = new Collection$2(); for (ctrl = self.parent(); ctrl; ctrl = ctrl.parent()) { parents.add(ctrl); } if (selector) { parents = parents.filter(selector); } return parents; }, parentsAndSelf: function (selector) { return new Collection$2(this).add(this.parents(selector)); }, next: function () { var parentControls = this.parent().items(); return parentControls[parentControls.indexOf(this) + 1]; }, prev: function () { var parentControls = this.parent().items(); return parentControls[parentControls.indexOf(this) - 1]; }, innerHtml: function (html) { this.$el.html(html); return this; }, getEl: function (suffix) { var id = suffix ? this._id + '-' + suffix : this._id; if (!this._elmCache[id]) { this._elmCache[id] = global$9('#' + id)[0]; } return this._elmCache[id]; }, show: function () { return this.visible(true); }, hide: function () { return this.visible(false); }, focus: function () { try { this.getEl().focus(); } catch (ex) { } return this; }, blur: function () { this.getEl().blur(); return this; }, aria: function (name, value) { var self = this, elm = self.getEl(self.ariaTarget); if (typeof value === 'undefined') { return self._aria[name]; } self._aria[name] = value; if (self.state.get('rendered')) { elm.setAttribute(name === 'role' ? name : 'aria-' + name, value); } return self; }, encode: function (text, translate) { if (translate !== false) { text = this.translate(text); } return (text || '').replace(/[&<>"]/g, function (match) { return '&#' + match.charCodeAt(0) + ';'; }); }, translate: function (text) { return Control.translate ? Control.translate(text) : text; }, before: function (items) { var self = this, parent = self.parent(); if (parent) { parent.insert(items, parent.items().indexOf(self), true); } return self; }, after: function (items) { var self = this, parent = self.parent(); if (parent) { parent.insert(items, parent.items().indexOf(self)); } return self; }, remove: function () { var self = this; var elm = self.getEl(); var parent = self.parent(); var newItems, i; if (self.items) { var controls = self.items().toArray(); i = controls.length; while (i--) { controls[i].remove(); } } if (parent && parent.items) { newItems = []; parent.items().each(function (item) { if (item !== self) { newItems.push(item); } }); parent.items().set(newItems); parent._lastRect = null; } if (self._eventsRoot && self._eventsRoot === self) { global$9(elm).off(); } var lookup = self.getRoot().controlIdLookup; if (lookup) { delete lookup[self._id]; } if (elm && elm.parentNode) { elm.parentNode.removeChild(elm); } self.state.set('rendered', false); self.state.destroy(); self.fire('remove'); return self; }, renderBefore: function (elm) { global$9(elm).before(this.renderHtml()); this.postRender(); return this; }, renderTo: function (elm) { global$9(elm || this.getContainerElm()).append(this.renderHtml()); this.postRender(); return this; }, preRender: function () { }, render: function () { }, renderHtml: function () { return '<div id="' + this._id + '" class="' + this.classes + '"></div>'; }, postRender: function () { var self = this; var settings = self.settings; var elm, box, parent, name, parentEventsRoot; self.$el = global$9(self.getEl()); self.state.set('rendered', true); for (name in settings) { if (name.indexOf('on') === 0) { self.on(name.substr(2), settings[name]); } } if (self._eventsRoot) { for (parent = self.parent(); !parentEventsRoot && parent; parent = parent.parent()) { parentEventsRoot = parent._eventsRoot; } if (parentEventsRoot) { for (name in parentEventsRoot._nativeEvents) { self._nativeEvents[name] = true; } } } bindPendingEvents(self); if (settings.style) { elm = self.getEl(); if (elm) { elm.setAttribute('style', settings.style); elm.style.cssText = settings.style; } } if (self.settings.border) { box = self.borderBox; self.$el.css({ 'border-top-width': box.top, 'border-right-width': box.right, 'border-bottom-width': box.bottom, 'border-left-width': box.left }); } var root = self.getRoot(); if (!root.controlIdLookup) { root.controlIdLookup = {}; } root.controlIdLookup[self._id] = self; for (var key in self._aria) { self.aria(key, self._aria[key]); } if (self.state.get('visible') === false) { self.getEl().style.display = 'none'; } self.bindStates(); self.state.on('change:visible', function (e) { var state = e.value; var parentCtrl; if (self.state.get('rendered')) { self.getEl().style.display = state === false ? 'none' : ''; self.getEl().getBoundingClientRect(); } parentCtrl = self.parent(); if (parentCtrl) { parentCtrl._lastRect = null; } self.fire(state ? 'show' : 'hide'); ReflowQueue.add(self); }); self.fire('postrender', {}, false); }, bindStates: function () { }, scrollIntoView: function (align) { function getOffset(elm, rootElm) { var x, y, parent = elm; x = y = 0; while (parent && parent !== rootElm && parent.nodeType) { x += parent.offsetLeft || 0; y += parent.offsetTop || 0; parent = parent.offsetParent; } return { x: x, y: y }; } var elm = this.getEl(), parentElm = elm.parentNode; var x, y, width, height, parentWidth, parentHeight; var pos = getOffset(elm, parentElm); x = pos.x; y = pos.y; width = elm.offsetWidth; height = elm.offsetHeight; parentWidth = parentElm.clientWidth; parentHeight = parentElm.clientHeight; if (align === 'end') { x -= parentWidth - width; y -= parentHeight - height; } else if (align === 'center') { x -= parentWidth / 2 - width / 2; y -= parentHeight / 2 - height / 2; } parentElm.scrollLeft = x; parentElm.scrollTop = y; return this; }, getRoot: function () { var ctrl = this, rootControl; var parents = []; while (ctrl) { if (ctrl.rootControl) { rootControl = ctrl.rootControl; break; } parents.push(ctrl); rootControl = ctrl; ctrl = ctrl.parent(); } if (!rootControl) { rootControl = this; } var i = parents.length; while (i--) { parents[i].rootControl = rootControl; } return rootControl; }, reflow: function () { ReflowQueue.remove(this); var parent = this.parent(); if (parent && parent._layout && !parent._layout.isNative()) { parent.reflow(); } return this; } }; global$2.each('text title visible disabled active value'.split(' '), function (name) { proto$1[name] = function (value) { if (arguments.length === 0) { return this.state.get(name); } if (typeof value !== 'undefined') { this.state.set(name, value); } return this; }; }); Control = global$a.extend(proto$1); function getEventDispatcher(obj) { if (!obj._eventDispatcher) { obj._eventDispatcher = new global$b({ scope: obj, toggleEvent: function (name, state) { if (state && global$b.isNative(name)) { if (!obj._nativeEvents) { obj._nativeEvents = {}; } obj._nativeEvents[name] = true; if (obj.state.get('rendered')) { bindPendingEvents(obj); } } } }); } return obj._eventDispatcher; } function bindPendingEvents(eventCtrl) { var i, l, parents, eventRootCtrl, nativeEvents, name; function delegate(e) { var control = eventCtrl.getParentCtrl(e.target); if (control) { control.fire(e.type, e); } } function mouseLeaveHandler() { var ctrl = eventRootCtrl._lastHoverCtrl; if (ctrl) { ctrl.fire('mouseleave', { target: ctrl.getEl() }); ctrl.parents().each(function (ctrl) { ctrl.fire('mouseleave', { target: ctrl.getEl() }); }); eventRootCtrl._lastHoverCtrl = null; } } function mouseEnterHandler(e) { var ctrl = eventCtrl.getParentCtrl(e.target), lastCtrl = eventRootCtrl._lastHoverCtrl, idx = 0, i, parents, lastParents; if (ctrl !== lastCtrl) { eventRootCtrl._lastHoverCtrl = ctrl; parents = ctrl.parents().toArray().reverse(); parents.push(ctrl); if (lastCtrl) { lastParents = lastCtrl.parents().toArray().reverse(); lastParents.push(lastCtrl); for (idx = 0; idx < lastParents.length; idx++) { if (parents[idx] !== lastParents[idx]) { break; } } for (i = lastParents.length - 1; i >= idx; i--) { lastCtrl = lastParents[i]; lastCtrl.fire('mouseleave', { target: lastCtrl.getEl() }); } } for (i = idx; i < parents.length; i++) { ctrl = parents[i]; ctrl.fire('mouseenter', { target: ctrl.getEl() }); } } } function fixWheelEvent(e) { e.preventDefault(); if (e.type === 'mousewheel') { e.deltaY = -1 / 40 * e.wheelDelta; if (e.wheelDeltaX) { e.deltaX = -1 / 40 * e.wheelDeltaX; } } else { e.deltaX = 0; e.deltaY = e.detail; } e = eventCtrl.fire('wheel', e); } nativeEvents = eventCtrl._nativeEvents; if (nativeEvents) { parents = eventCtrl.parents().toArray(); parents.unshift(eventCtrl); for (i = 0, l = parents.length; !eventRootCtrl && i < l; i++) { eventRootCtrl = parents[i]._eventsRoot; } if (!eventRootCtrl) { eventRootCtrl = parents[parents.length - 1] || eventCtrl; } eventCtrl._eventsRoot = eventRootCtrl; for (l = i, i = 0; i < l; i++) { parents[i]._eventsRoot = eventRootCtrl; } var eventRootDelegates = eventRootCtrl._delegates; if (!eventRootDelegates) { eventRootDelegates = eventRootCtrl._delegates = {}; } for (name in nativeEvents) { if (!nativeEvents) { return false; } if (name === 'wheel' && !hasWheelEventSupport) { if (hasMouseWheelEventSupport) { global$9(eventCtrl.getEl()).on('mousewheel', fixWheelEvent); } else { global$9(eventCtrl.getEl()).on('DOMMouseScroll', fixWheelEvent); } continue; } if (name === 'mouseenter' || name === 'mouseleave') { if (!eventRootCtrl._hasMouseEnter) { global$9(eventRootCtrl.getEl()).on('mouseleave', mouseLeaveHandler).on('mouseover', mouseEnterHandler); eventRootCtrl._hasMouseEnter = 1; } } else if (!eventRootDelegates[name]) { global$9(eventRootCtrl.getEl()).on(name, delegate); eventRootDelegates[name] = true; } nativeEvents[name] = false; } } } var Control$1 = Control; var hasTabstopData = function (elm) { return elm.getAttribute('data-mce-tabstop') ? true : false; }; function KeyboardNavigation (settings) { var root = settings.root; var focusedElement, focusedControl; function isElement(node) { return node && node.nodeType === 1; } try { focusedElement = domGlobals.document.activeElement; } catch (ex) { focusedElement = domGlobals.document.body; } focusedControl = root.getParentCtrl(focusedElement); function getRole(elm) { elm = elm || focusedElement; if (isElement(elm)) { return elm.getAttribute('role'); } return null; } function getParentRole(elm) { var role, parent = elm || focusedElement; while (parent = parent.parentNode) { if (role = getRole(parent)) { return role; } } } function getAriaProp(name) { var elm = focusedElement; if (isElement(elm)) { return elm.getAttribute('aria-' + name); } } function isTextInputElement(elm) { var tagName = elm.tagName.toUpperCase(); return tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT'; } function canFocus(elm) { if (isTextInputElement(elm) && !elm.hidden) { return true; } if (hasTabstopData(elm)) { return true; } if (/^(button|menuitem|checkbox|tab|menuitemcheckbox|option|gridcell|slider)$/.test(getRole(elm))) { return true; } return false; } function getFocusElements(elm) { var elements = []; function collect(elm) { if (elm.nodeType !== 1 || elm.style.display === 'none' || elm.disabled) { return; } if (canFocus(elm)) { elements.push(elm); } for (var i = 0; i < elm.childNodes.length; i++) { collect(elm.childNodes[i]); } } collect(elm || root.getEl()); return elements; } function getNavigationRoot(targetControl) { var navigationRoot, controls; targetControl = targetControl || focusedControl; controls = targetControl.parents().toArray(); controls.unshift(targetControl); for (var i = 0; i < controls.length; i++) { navigationRoot = controls[i]; if (navigationRoot.settings.ariaRoot) { break; } } return navigationRoot; } function focusFirst(targetControl) { var navigationRoot = getNavigationRoot(targetControl); var focusElements = getFocusElements(navigationRoot.getEl()); if (navigationRoot.settings.ariaRemember && 'lastAriaIndex' in navigationRoot) { moveFocusToIndex(navigationRoot.lastAriaIndex, focusElements); } else { moveFocusToIndex(0, focusElements); } } function moveFocusToIndex(idx, elements) { if (idx < 0) { idx = elements.length - 1; } else if (idx >= elements.length) { idx = 0; } if (elements[idx]) { elements[idx].focus(); } return idx; } function moveFocus(dir, elements) { var idx = -1; var navigationRoot = getNavigationRoot(); elements = elements || getFocusElements(navigationRoot.getEl()); for (var i = 0; i < elements.length; i++) { if (elements[i] === focusedElement) { idx = i; } } idx += dir; navigationRoot.lastAriaIndex = moveFocusToIndex(idx, elements); } function left() { var parentRole = getParentRole(); if (parentRole === 'tablist') { moveFocus(-1, getFocusElements(focusedElement.parentNode)); } else if (focusedControl.parent().submenu) { cancel(); } else { moveFocus(-1); } } function right() { var role = getRole(), parentRole = getParentRole(); if (parentRole === 'tablist') { moveFocus(1, getFocusElements(focusedElement.parentNode)); } else if (role === 'menuitem' && parentRole === 'menu' && getAriaProp('haspopup')) { enter(); } else { moveFocus(1); } } function up() { moveFocus(-1); } function down() { var role = getRole(), parentRole = getParentRole(); if (role === 'menuitem' && parentRole === 'menubar') { enter(); } else if (role === 'button' && getAriaProp('haspopup')) { enter({ key: 'down' }); } else { moveFocus(1); } } function tab(e) { var parentRole = getParentRole(); if (parentRole === 'tablist') { var elm = getFocusElements(focusedControl.getEl('body'))[0]; if (elm) { elm.focus(); } } else { moveFocus(e.shiftKey ? -1 : 1); } } function cancel() { focusedControl.fire('cancel'); } function enter(aria) { aria = aria || {}; focusedControl.fire('click', { target: focusedElement, aria: aria }); } root.on('keydown', function (e) { function handleNonTabOrEscEvent(e, handler) { if (isTextInputElement(focusedElement) || hasTabstopData(focusedElement)) { return; } if (getRole(focusedElement) === 'slider') { return; } if (handler(e) !== false) { e.preventDefault(); } } if (e.isDefaultPrevented()) { return; } switch (e.keyCode) { case 37: handleNonTabOrEscEvent(e, left); break; case 39: handleNonTabOrEscEvent(e, right); break; case 38: handleNonTabOrEscEvent(e, up); break; case 40: handleNonTabOrEscEvent(e, down); break; case 27: cancel(); break; case 14: case 13: case 32: handleNonTabOrEscEvent(e, enter); break; case 9: tab(e); e.preventDefault(); break; } }); root.on('focusin', function (e) { focusedElement = e.target; focusedControl = e.control; }); return { focusFirst: focusFirst }; } var selectorCache = {}; var Container = Control$1.extend({ init: function (settings) { var self = this; self._super(settings); settings = self.settings; if (settings.fixed) { self.state.set('fixed', true); } self._items = new Collection$2(); if (self.isRtl()) { self.classes.add('rtl'); } self.bodyClasses = new ClassList(function () { if (self.state.get('rendered')) { self.getEl('body').className = this.toString(); } }); self.bodyClasses.prefix = self.classPrefix; self.classes.add('container'); self.bodyClasses.add('container-body'); if (settings.containerCls) { self.classes.add(settings.containerCls); } self._layout = global$4.create((settings.layout || '') + 'layout'); if (self.settings.items) { self.add(self.settings.items); } else { self.add(self.render()); } self._hasBody = true; }, items: function () { return this._items; }, find: function (selector) { selector = selectorCache[selector] = selectorCache[selector] || new Selector(selector); return selector.find(this); }, add: function (items) { var self = this; self.items().add(self.create(items)).parent(self); return self; }, focus: function (keyboard) { var self = this; var focusCtrl, keyboardNav, items; if (keyboard) { keyboardNav = self.keyboardNav || self.parents().eq(-1)[0].keyboardNav; if (keyboardNav) { keyboardNav.focusFirst(self); return; } } items = self.find('*'); if (self.statusbar) { items.add(self.statusbar.items()); } items.each(function (ctrl) { if (ctrl.settings.autofocus) { focusCtrl = null; return false; } if (ctrl.canFocus) { focusCtrl = focusCtrl || ctrl; } }); if (focusCtrl) { focusCtrl.focus(); } return self; }, replace: function (oldItem, newItem) { var ctrlElm; var items = this.items(); var i = items.length; while (i--) { if (items[i] === oldItem) { items[i] = newItem; break; } } if (i >= 0) { ctrlElm = newItem.getEl(); if (ctrlElm) { ctrlElm.parentNode.removeChild(ctrlElm); } ctrlElm = oldItem.getEl(); if (ctrlElm) { ctrlElm.parentNode.removeChild(ctrlElm); } } newItem.parent(this); }, create: function (items) { var self = this; var settings; var ctrlItems = []; if (!global$2.isArray(items)) { items = [items]; } global$2.each(items, function (item) { if (item) { if (!(item instanceof Control$1)) { if (typeof item === 'string') { item = { type: item }; } settings = global$2.extend({}, self.settings.defaults, item); item.type = settings.type = settings.type || item.type || self.settings.defaultType || (settings.defaults ? settings.defaults.type : null); item = global$4.create(settings); } ctrlItems.push(item); } }); return ctrlItems; }, renderNew: function () { var self = this; self.items().each(function (ctrl, index) { var containerElm; ctrl.parent(self); if (!ctrl.state.get('rendered')) { containerElm = self.getEl('body'); if (containerElm.hasChildNodes() && index <= containerElm.childNodes.length - 1) { global$9(containerElm.childNodes[index]).before(ctrl.renderHtml()); } else { global$9(containerElm).append(ctrl.renderHtml()); } ctrl.postRender(); ReflowQueue.add(ctrl); } }); self._layout.applyClasses(self.items().filter(':visible')); self._lastRect = null; return self; }, append: function (items) { return this.add(items).renderNew(); }, prepend: function (items) { var self = this; self.items().set(self.create(items).concat(self.items().toArray())); return self.renderNew(); }, insert: function (items, index, before) { var self = this; var curItems, beforeItems, afterItems; items = self.create(items); curItems = self.items(); if (!before && index < curItems.length - 1) { index += 1; } if (index >= 0 && index < curItems.length) { beforeItems = curItems.slice(0, index).toArray(); afterItems = curItems.slice(index).toArray(); curItems.set(beforeItems.concat(items, afterItems)); } return self.renderNew(); }, fromJSON: function (data) { var self = this; for (var name in data) { self.find('#' + name).value(data[name]); } return self; }, toJSON: function () { var self = this, data = {}; self.find('*').each(function (ctrl) { var name = ctrl.name(), value = ctrl.value(); if (name && typeof value !== 'undefined') { data[name] = value; } }); return data; }, renderHtml: function () { var self = this, layout = self._layout, role = this.settings.role; self.preRender(); layout.preRender(self); 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>'; }, postRender: function () { var self = this; var box; self.items().exec('postRender'); self._super(); self._layout.postRender(self); self.state.set('rendered', true); if (self.settings.style) { self.$el.css(self.settings.style); } if (self.settings.border) { box = self.borderBox; self.$el.css({ 'border-top-width': box.top, 'border-right-width': box.right, 'border-bottom-width': box.bottom, 'border-left-width': box.left }); } if (!self.parent()) { self.keyboardNav = KeyboardNavigation({ root: self }); } return self; }, initLayoutRect: function () { var self = this, layoutRect = self._super(); self._layout.recalc(self); return layoutRect; }, recalc: function () { var self = this; var rect = self._layoutRect; var lastRect = self._lastRect; if (!lastRect || lastRect.w !== rect.w || lastRect.h !== rect.h) { self._layout.recalc(self); rect = self.layoutRect(); self._lastRect = { x: rect.x, y: rect.y, w: rect.w, h: rect.h }; return true; } }, reflow: function () { var i; ReflowQueue.remove(this); if (this.visible()) { Control$1.repaintControls = []; Control$1.repaintControls.map = {}; this.recalc(); i = Control$1.repaintControls.length; while (i--) { Control$1.repaintControls[i].repaint(); } if (this.settings.layout !== 'flow' && this.settings.layout !== 'stack') { this.repaint(); } Control$1.repaintControls = []; } return this; } }); function getDocumentSize(doc) { var documentElement, body, scrollWidth, clientWidth; var offsetWidth, scrollHeight, clientHeight, offsetHeight; var max = Math.max; documentElement = doc.documentElement; body = doc.body; scrollWidth = max(documentElement.scrollWidth, body.scrollWidth); clientWidth = max(documentElement.clientWidth, body.clientWidth); offsetWidth = max(documentElement.offsetWidth, body.offsetWidth); scrollHeight = max(documentElement.scrollHeight, body.scrollHeight); clientHeight = max(documentElement.clientHeight, body.clientHeight); offsetHeight = max(documentElement.offsetHeight, body.offsetHeight); return { width: scrollWidth < offsetWidth ? clientWidth : scrollWidth, height: scrollHeight < offsetHeight ? clientHeight : scrollHeight }; } function updateWithTouchData(e) { var keys, i; if (e.changedTouches) { keys = 'screenX screenY pageX pageY clientX clientY'.split(' '); for (i = 0; i < keys.length; i++) { e[keys[i]] = e.changedTouches[0][keys[i]]; } } } function DragHelper (id, settings) { var $eventOverlay; var doc = settings.document || domGlobals.document; var downButton; var start, stop, drag, startX, startY; settings = settings || {}; var handleElement = doc.getElementById(settings.handle || id); start = function (e) { var docSize = getDocumentSize(doc); var handleElm, cursor; updateWithTouchData(e); e.preventDefault(); downButton = e.button; handleElm = handleElement; startX = e.screenX; startY = e.screenY; if (domGlobals.window.getComputedStyle) { cursor = domGlobals.window.getComputedStyle(handleElm, null).getPropertyValue('cursor'); } else { cursor = handleElm.runtimeStyle.cursor; } $eventOverlay = global$9('<div></div>').css({ position: 'absolute', top: 0, left: 0, width: docSize.width, height: docSize.height, zIndex: 2147483647, opacity: 0.0001, cursor: cursor }).appendTo(doc.body); global$9(doc).on('mousemove touchmove', drag).on('mouseup touchend', stop); settings.start(e); }; drag = function (e) { updateWithTouchData(e); if (e.button !== downButton) { return stop(e); } e.deltaX = e.screenX - startX; e.deltaY = e.screenY - startY; e.preventDefault(); settings.drag(e); }; stop = function (e) { updateWithTouchData(e); global$9(doc).off('mousemove touchmove', drag).off('mouseup touchend', stop); $eventOverlay.remove(); if (settings.stop) { settings.stop(e); } }; this.destroy = function () { global$9(handleElement).off(); }; global$9(handleElement).on('mousedown touchstart', start); } var Scrollable = { init: function () { var self = this; self.on('repaint', self.renderScroll); }, renderScroll: function () { var self = this, margin = 2; function repaintScroll() { var hasScrollH, hasScrollV, bodyElm; function repaintAxis(axisName, posName, sizeName, contentSizeName, hasScroll, ax) { var containerElm, scrollBarElm, scrollThumbElm; var containerSize, scrollSize, ratio, rect; var posNameLower, sizeNameLower; scrollBarElm = self.getEl('scroll' + axisName); if (scrollBarElm) { posNameLower = posName.toLowerCase(); sizeNameLower = sizeName.toLowerCase(); global$9(self.getEl('absend')).css(posNameLower, self.layoutRect()[contentSizeName] - 1); if (!hasScroll) { global$9(scrollBarElm).css('display', 'none'); return; } global$9(scrollBarElm).css('display', 'block'); containerElm = self.getEl('body'); scrollThumbElm = self.getEl('scroll' + axisName + 't'); containerSize = containerElm['client' + sizeName] - margin * 2; containerSize -= hasScrollH && hasScrollV ? scrollBarElm['client' + ax] : 0; scrollSize = containerElm['scroll' + sizeName]; ratio = containerSize / scrollSize; rect = {}; rect[posNameLower] = containerElm['offset' + posName] + margin; rect[sizeNameLower] = containerSize; global$9(scrollBarElm).css(rect); rect = {}; rect[posNameLower] = containerElm['scroll' + posName] * ratio; rect[sizeNameLower] = containerSize * ratio; global$9(scrollThumbElm).css(rect); } } bodyElm = self.getEl('body'); hasScrollH = bodyElm.scrollWidth > bodyElm.clientWidth; hasScrollV = bodyElm.scrollHeight > bodyElm.clientHeight; repaintAxis('h', 'Left', 'Width', 'contentW', hasScrollH, 'Height'); repaintAxis('v', 'Top', 'Height', 'contentH', hasScrollV, 'Width'); } function addScroll() { function addScrollAxis(axisName, posName, sizeName, deltaPosName, ax) { var scrollStart; var axisId = self._id + '-scroll' + axisName, prefix = self.classPrefix; global$9(self.getEl()).append('<div id="' + axisId + '" class="' + prefix + 'scrollbar ' + prefix + 'scrollbar-' + axisName + '">' + '<div id="' + axisId + 't" class="' + prefix + 'scrollbar-thumb"></div>' + '</div>'); self.draghelper = new DragHelper(axisId + 't', { start: function () { scrollStart = self.getEl('body')['scroll' + posName]; global$9('#' + axisId).addClass(prefix + 'active'); }, drag: function (e) { var ratio, hasScrollH, hasScrollV, containerSize; var layoutRect = self.layoutRect(); hasScrollH = layoutRect.contentW > layoutRect.innerW; hasScrollV = layoutRect.contentH > layoutRect.innerH; containerSize = self.getEl('body')['client' + sizeName] - margin * 2; containerSize -= hasScrollH && hasScrollV ? self.getEl('scroll' + axisName)['client' + ax] : 0; ratio = containerSize / self.getEl('body')['scroll' + sizeName]; self.getEl('body')['scroll' + posName] = scrollStart + e['delta' + deltaPosName] / ratio; }, stop: function () { global$9('#' + axisId).removeClass(prefix + 'active'); } }); } self.classes.add('scroll'); addScrollAxis('v', 'Top', 'Height', 'Y', 'Width'); addScrollAxis('h', 'Left', 'Width', 'X', 'Height'); } if (self.settings.autoScroll) { if (!self._hasScroll) { self._hasScroll = true; addScroll(); self.on('wheel', function (e) { var bodyEl = self.getEl('body'); bodyEl.scrollLeft += (e.deltaX || 0) * 10; bodyEl.scrollTop += e.deltaY * 10; repaintScroll(); }); global$9(self.getEl('body')).on('scroll', repaintScroll); } repaintScroll(); } } }; var Panel = Container.extend({ Defaults: { layout: 'fit', containerCls: 'panel' }, Mixins: [Scrollable], renderHtml: function () { var self = this; var layout = self._layout; var innerHtml = self.settings.html; self.preRender(); layout.preRender(self); if (typeof innerHtml === 'undefined') { innerHtml = '<div id="' + self._id + '-body" class="' + self.bodyClasses + '">' + layout.renderHtml(self) + '</div>'; } else { if (typeof innerHtml === 'function') { innerHtml = innerHtml.call(self); } self._hasBody = false; } return '<div id="' + self._id + '" class="' + self.classes + '" hidefocus="1" tabindex="-1" role="group">' + (self._preBodyHtml || '') + innerHtml + '</div>'; } }); var Resizable = { resizeToContent: function () { this._layoutRect.autoResize = true; this._lastRect = null; this.reflow(); }, resizeTo: function (w, h) { if (w <= 1 || h <= 1) { var rect = funcs.getWindowSize(); w = w <= 1 ? w * rect.w : w; h = h <= 1 ? h * rect.h : h; } this._layoutRect.autoResize = false; return this.layoutRect({ minW: w, minH: h, w: w, h: h }).reflow(); }, resizeBy: function (dw, dh) { var self = this, rect = self.layoutRect(); return self.resizeTo(rect.w + dw, rect.h + dh); } }; var documentClickHandler, documentScrollHandler, windowResizeHandler; var visiblePanels = []; var zOrder = []; var hasModal; function isChildOf(ctrl, parent) { while (ctrl) { if (ctrl === parent) { return true; } ctrl = ctrl.parent(); } } function skipOrHidePanels(e) { var i = visiblePanels.length; while (i--) { var panel = visiblePanels[i], clickCtrl = panel.getParentCtrl(e.target); if (panel.settings.autohide) { if (clickCtrl) { if (isChildOf(clickCtrl, panel) || panel.parent() === clickCtrl) { continue; } } e = panel.fire('autohide', { target: e.target }); if (!e.isDefaultPrevented()) { panel.hide(); } } } } function bindDocumentClickHandler() { if (!documentClickHandler) { documentClickHandler = function (e) { if (e.button === 2) { return; } skipOrHidePanels(e); }; global$9(domGlobals.document).on('click touchstart', documentClickHandler); } } function bindDocumentScrollHandler() { if (!documentScrollHandler) { documentScrollHandler = function () { var i; i = visiblePanels.length; while (i--) { repositionPanel(visiblePanels[i]); } }; global$9(domGlobals.window).on('scroll', documentScrollHandler); } } function bindWindowResizeHandler() { if (!windowResizeHandler) { var docElm_1 = domGlobals.document.documentElement; var clientWidth_1 = docElm_1.clientWidth, clientHeight_1 = docElm_1.clientHeight; windowResizeHandler = function () { if (!domGlobals.document.all || clientWidth_1 !== docElm_1.clientWidth || clientHeight_1 !== docElm_1.clientHeight) { clientWidth_1 = docElm_1.clientWidth; clientHeight_1 = docElm_1.clientHeight; FloatPanel.hideAll(); } }; global$9(domGlobals.window).on('resize', windowResizeHandler); } } function repositionPanel(panel) { var scrollY = funcs.getViewPort().y; function toggleFixedChildPanels(fixed, deltaY) { var parent; for (var i = 0; i < visiblePanels.length; i++) { if (visiblePanels[i] !== panel) { parent = visiblePanels[i].parent(); while (parent && (parent = parent.parent())) { if (parent === panel) { visiblePanels[i].fixed(fixed).moveBy(0, deltaY).repaint(); } } } } } if (panel.settings.autofix) { if (!panel.state.get('fixed')) { panel._autoFixY = panel.layoutRect().y; if (panel._autoFixY < scrollY) { panel.fixed(true).layoutRect({ y: 0 }).repaint(); toggleFixedChildPanels(true, scrollY - panel._autoFixY); } } else { if (panel._autoFixY > scrollY) { panel.fixed(false).layoutRect({ y: panel._autoFixY }).repaint(); toggleFixedChildPanels(false, panel._autoFixY - scrollY); } } } } function addRemove(add, ctrl) { var i, zIndex = FloatPanel.zIndex || 65535, topModal; if (add) { zOrder.push(ctrl); } else { i = zOrder.length; while (i--) { if (zOrder[i] === ctrl) { zOrder.splice(i, 1); } } } if (zOrder.length) { for (i = 0; i < zOrder.length; i++) { if (zOrder[i].modal) { zIndex++; topModal = zOrder[i]; } zOrder[i].getEl().style.zIndex = zIndex; zOrder[i].zIndex = zIndex; zIndex++; } } var modalBlockEl = global$9('#' + ctrl.classPrefix + 'modal-block', ctrl.getContainerElm())[0]; if (topModal) { global$9(modalBlockEl).css('z-index', topModal.zIndex - 1); } else if (modalBlockEl) { modalBlockEl.parentNode.removeChild(modalBlockEl); hasModal = false; } FloatPanel.currentZIndex = zIndex; } var FloatPanel = Panel.extend({ Mixins: [ Movable, Resizable ], init: function (settings) { var self = this; self._super(settings); self._eventsRoot = self; self.classes.add('floatpanel'); if (settings.autohide) { bindDocumentClickHandler(); bindWindowResizeHandler(); visiblePanels.push(self); } if (settings.autofix) { bindDocumentScrollHandler(); self.on('move', function () { repositionPanel(this); }); } self.on('postrender show', function (e) { if (e.control === self) { var $modalBlockEl_1; var prefix_1 = self.classPrefix; if (self.modal && !hasModal) { $modalBlockEl_1 = global$9('#' + prefix_1 + 'modal-block', self.getContainerElm()); if (!$modalBlockEl_1[0]) { $modalBlockEl_1 = global$9('<div id="' + prefix_1 + 'modal-block" class="' + prefix_1 + 'reset ' + prefix_1 + 'fade"></div>').appendTo(self.getContainerElm()); } global$7.setTimeout(function () { $modalBlockEl_1.addClass(prefix_1 + 'in'); global$9(self.getEl()).addClass(prefix_1 + 'in'); }); hasModal = true; } addRemove(true, self); } }); self.on('show', function () { self.parents().each(function (ctrl) { if (ctrl.state.get('fixed')) { self.fixed(true); return false; } }); }); if (settings.popover) { self._preBodyHtml = '<div class="' + self.classPrefix + 'arrow"></div>'; self.classes.add('popover').add('bottom').add(self.isRtl() ? 'end' : 'start'); } self.aria('label', settings.ariaLabel); self.aria('labelledby', self._id); self.aria('describedby', self.describedBy || self._id + '-none'); }, fixed: function (state) { var self = this; if (self.state.get('fixed') !== state) { if (self.state.get('rendered')) { var viewport = funcs.getViewPort(); if (state) { self.layoutRect().y -= viewport.y; } else { self.layoutRect().y += viewport.y; } } self.classes.toggle('fixed', state); self.state.set('fixed', state); } return self; }, show: function () { var self = this; var i; var state = self._super(); i = visiblePanels.length; while (i--) { if (visiblePanels[i] === self) { break; } } if (i === -1) { visiblePanels.push(self); } return state; }, hide: function () { removeVisiblePanel(this); addRemove(false, this); return this._super(); }, hideAll: function () { FloatPanel.hideAll(); }, close: function () { var self = this; if (!self.fire('close').isDefaultPrevented()) { self.remove(); addRemove(false, self); } return self; }, remove: function () { removeVisiblePanel(this); this._super(); }, postRender: function () { var self = this; if (self.settings.bodyRole) { this.getEl('body').setAttribute('role', self.settings.bodyRole); } return self._super(); } }); FloatPanel.hideAll = function () { var i = visiblePanels.length; while (i--) { var panel = visiblePanels[i]; if (panel && panel.settings.autohide) { panel.hide(); visiblePanels.splice(i, 1); } } }; function removeVisiblePanel(panel) { var i; i = visiblePanels.length; while (i--) { if (visiblePanels[i] === panel) { visiblePanels.splice(i, 1); } } i = zOrder.length; while (i--) { if (zOrder[i] === panel) { zOrder.splice(i, 1); } } } var isFixed$1 = function (inlineToolbarContainer, editor) { return !!(inlineToolbarContainer && !editor.settings.ui_container); }; var render$1 = function (editor, theme, args) { var panel, inlineToolbarContainer; var DOM = global$3.DOM; var fixedToolbarContainer = getFixedToolbarContainer(editor); if (fixedToolbarContainer) { inlineToolbarContainer = DOM.select(fixedToolbarContainer)[0]; } var reposition = function () { if (panel && panel.moveRel && panel.visible() && !panel._fixed) { var scrollContainer = editor.selection.getScrollContainer(), body = editor.getBody(); var deltaX = 0, deltaY = 0; if (scrollContainer) { var bodyPos = DOM.getPos(body), scrollContainerPos = DOM.getPos(scrollContainer); deltaX = Math.max(0, scrollContainerPos.x - bodyPos.x); deltaY = Math.max(0, scrollContainerPos.y - bodyPos.y); } panel.fixed(false).moveRel(body, editor.rtl ? [ 'tr-br', 'br-tr' ] : [ 'tl-bl', 'bl-tl', 'tr-br' ]).moveBy(deltaX, deltaY); } }; var show = function () { if (panel) { panel.show(); reposition(); DOM.addClass(editor.getBody(), 'mce-edit-focus'); } }; var hide = function () { if (panel) { panel.hide(); FloatPanel.hideAll(); DOM.removeClass(editor.getBody(), 'mce-edit-focus'); } }; var render = function () { if (panel) { if (!panel.visible()) { show(); } return; } panel = theme.panel = global$4.create({ type: inlineToolbarContainer ? 'panel' : 'floatpanel', role: 'application', classes: 'tinymce tinymce-inline', layout: 'flex', direction: 'column', align: 'stretch', autohide: false, autofix: true, fixed: isFixed$1(inlineToolbarContainer, editor), border: 1, items: [ hasMenubar(editor) === false ? null : { type: 'menubar', border: '0 0 1 0', items: Menubar.createMenuButtons(editor) }, Toolbar.createToolbars(editor, getToolbarSize(editor)) ] }); UiContainer.setUiContainer(editor, panel); Events.fireBeforeRenderUI(editor); if (inlineToolbarContainer) { panel.renderTo(inlineToolbarContainer).reflow(); } else { panel.renderTo().reflow(); } A11y.addKeys(editor, panel); show(); ContextToolbars.addContextualToolbars(editor); editor.on('nodeChange', reposition); editor.on('ResizeWindow', reposition); editor.on('activate', show); editor.on('deactivate', hide); editor.nodeChanged(); }; editor.settings.content_editable = true; editor.on('focus', function () { if (isSkinDisabled(editor) === false && args.skinUiCss) { DOM.styleSheetLoader.load(args.skinUiCss, render, render); } else { render(); } }); editor.on('blur hide', hide); editor.on('remove', function () { if (panel) { panel.remove(); panel = null; } }); if (isSkinDisabled(editor) === false && args.skinUiCss) { DOM.styleSheetLoader.load(args.skinUiCss, SkinLoaded.fireSkinLoaded(editor)); } else { SkinLoaded.fireSkinLoaded(editor)(); } return {}; }; var Inline = { render: render$1 }; function Throbber (elm, inline) { var self = this; var state; var classPrefix = Control$1.classPrefix; var timer; self.show = function (time, callback) { function render() { if (state) { global$9(elm).append('<div class="' + classPrefix + 'throbber' + (inline ? ' ' + classPrefix + 'throbber-inline' : '') + '"></div>'); if (callback) { callback(); } } } self.hide(); state = true; if (time) { timer = global$7.setTimeout(render, time); } else { render(); } return self; }; self.hide = function () { var child = elm.lastChild; global$7.clearTimeout(timer); if (child && child.className.indexOf('throbber') !== -1) { child.parentNode.removeChild(child); } state = false; return self; }; } var setup = function (editor, theme) { var throbber; editor.on('ProgressState', function (e) { throbber = throbber || new Throbber(theme.panel.getEl('body')); if (e.state) { throbber.show(e.time); } else { throbber.hide(); } }); }; var ProgressState = { setup: setup }; var renderUI = function (editor, theme, args) { var skinUrl = getSkinUrl(editor); if (skinUrl) { args.skinUiCss = skinUrl + '/skin.min.css'; editor.contentCSS.push(skinUrl + '/content' + (editor.inline ? '.inline' : '') + '.min.css'); } ProgressState.setup(editor, theme); return isInline(editor) ? Inline.render(editor, theme, args) : Iframe.render(editor, theme, args); }; var Render = { renderUI: renderUI }; var Tooltip = Control$1.extend({ Mixins: [Movable], Defaults: { classes: 'widget tooltip tooltip-n' }, renderHtml: function () { var self = this, prefix = self.classPrefix; 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>'; }, bindStates: function () { var self = this; self.state.on('change:text', function (e) { self.getEl().lastChild.innerHTML = self.encode(e.value); }); return self._super(); }, repaint: function () { var self = this; var style, rect; style = self.getEl().style; rect = self._layoutRect; style.left = rect.x + 'px'; style.top = rect.y + 'px'; style.zIndex = 65535 + 65535; } }); var Widget = Control$1.extend({ init: function (settings) { var self = this; self._super(settings); settings = self.settings; self.canFocus = true; if (settings.tooltip && Widget.tooltips !== false) { self.on('mouseenter', function (e) { var tooltip = self.tooltip().moveTo(-65535); if (e.control === self) { var rel = tooltip.text(settings.tooltip).show().testMoveRel(self.getEl(), [ 'bc-tc', 'bc-tl', 'bc-tr' ]); tooltip.classes.toggle('tooltip-n', rel === 'bc-tc'); tooltip.classes.toggle('tooltip-nw', rel === 'bc-tl'); tooltip.classes.toggle('tooltip-ne', rel === 'bc-tr'); tooltip.moveRel(self.getEl(), rel); } else { tooltip.hide(); } }); self.on('mouseleave mousedown click', function () { self.tooltip().remove(); self._tooltip = null; }); } self.aria('label', settings.ariaLabel || settings.tooltip); }, tooltip: function () { if (!this._tooltip) { this._tooltip = new Tooltip({ type: 'tooltip' }); UiContainer.inheritUiContainer(this, this._tooltip); this._tooltip.renderTo(); } return this._tooltip; }, postRender: function () { var self = this, settings = self.settings; self._super(); if (!self.parent() && (settings.width || settings.height)) { self.initLayoutRect(); self.repaint(); } if (settings.autofocus) { self.focus(); } }, bindStates: function () { var self = this; function disable(state) { self.aria('disabled', state); self.classes.toggle('disabled', state); } function active(state) { self.aria('pressed', state); self.classes.toggle('active', state); } self.state.on('change:disabled', function (e) { disable(e.value); }); self.state.on('change:active', function (e) { active(e.value); }); if (self.state.get('disabled')) { disable(true); } if (self.state.get('active')) { active(true); } return self._super(); }, remove: function () { this._super(); if (this._tooltip) { this._tooltip.remove(); this._tooltip = null; } } }); var Progress = Widget.extend({ Defaults: { value: 0 }, init: function (settings) { var self = this; self._super(settings); self.classes.add('progress'); if (!self.settings.filter) { self.settings.filter = function (value) { return Math.round(value); }; } }, renderHtml: function () { var self = this, id = self._id, prefix = this.classPrefix; 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>'; }, postRender: function () { var self = this; self._super(); self.value(self.settings.value); return self; }, bindStates: function () { var self = this; function setValue(value) { value = self.settings.filter(value); self.getEl().lastChild.innerHTML = value + '%'; self.getEl().firstChild.firstChild.style.width = value + '%'; } self.state.on('change:value', function (e) { setValue(e.value); }); setValue(self.state.get('value')); return self._super(); } }); var updateLiveRegion = function (ctx, text) { ctx.getEl().lastChild.textContent = text + (ctx.progressBar ? ' ' + ctx.progressBar.value() + '%' : ''); }; var Notification = Control$1.extend({ Mixins: [Movable], Defaults: { classes: 'widget notification' }, init: function (settings) { var self = this; self._super(settings); self.maxWidth = settings.maxWidth; if (settings.text) { self.text(settings.text); } if (settings.icon) { self.icon = settings.icon; } if (settings.color) { self.color = settings.color; } if (settings.type) { self.classes.add('notification-' + settings.type); } if (settings.timeout && (settings.timeout < 0 || settings.timeout > 0) && !settings.closeButton) { self.closeButton = false; } else { self.classes.add('has-close'); self.closeButton = true; } if (settings.progressBar) { self.progressBar = new Progress(); } self.on('click', function (e) { if (e.target.className.indexOf(self.classPrefix + 'close') !== -1) { self.close(); } }); }, renderHtml: function () { var self = this; var prefix = self.classPrefix; var icon = '', closeButton = '', progressBar = '', notificationStyle = ''; if (self.icon) { icon = '<i class="' + prefix + 'ico' + ' ' + prefix + 'i-' + self.icon + '"></i>'; } notificationStyle = ' style="max-width: ' + self.maxWidth + 'px;' + (self.color ? 'background-color: ' + self.color + ';"' : '"'); if (self.closeButton) { closeButton = '<button type="button" class="' + prefix + 'close" aria-hidden="true">\xD7</button>'; } if (self.progressBar) { progressBar = self.progressBar.renderHtml(); } 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>'; }, postRender: function () { var self = this; global$7.setTimeout(function () { self.$el.addClass(self.classPrefix + 'in'); updateLiveRegion(self, self.state.get('text')); }, 100); return self._super(); }, bindStates: function () { var self = this; self.state.on('change:text', function (e) { self.getEl().firstChild.innerHTML = e.value; updateLiveRegion(self, e.value); }); if (self.progressBar) { self.progressBar.bindStates(); self.progressBar.state.on('change:value', function (e) { updateLiveRegion(self, self.state.get('text')); }); } return self._super(); }, close: function () { var self = this; if (!self.fire('close').isDefaultPrevented()) { self.remove(); } return self; }, repaint: function () { var self = this; var style, rect; style = self.getEl().style; rect = self._layoutRect; style.left = rect.x + 'px'; style.top = rect.y + 'px'; style.zIndex = 65535 - 1; } }); function NotificationManagerImpl (editor) { var getEditorContainer = function (editor) { return editor.inline ? editor.getElement() : editor.getContentAreaContainer(); }; var getContainerWidth = function () { var container = getEditorContainer(editor); return funcs.getSize(container).width; }; var prePositionNotifications = function (notifications) { each(notifications, function (notification) { notification.moveTo(0, 0); }); }; var positionNotifications = function (notifications) { if (notifications.length > 0) { var firstItem = notifications.slice(0, 1)[0]; var container = getEditorContainer(editor); firstItem.moveRel(container, 'tc-tc'); each(notifications, function (notification, index) { if (index > 0) { notification.moveRel(notifications[index - 1].getEl(), 'bc-tc'); } }); } }; var reposition = function (notifications) { prePositionNotifications(notifications); positionNotifications(notifications); }; var open = function (args, closeCallback) { var extendedArgs = global$2.extend(args, { maxWidth: getContainerWidth() }); var notif = new Notification(extendedArgs); notif.args = extendedArgs; if (extendedArgs.timeout > 0) { notif.timer = setTimeout(function () { notif.close(); closeCallback(); }, extendedArgs.timeout); } notif.on('close', function () { closeCallback(); }); notif.renderTo(); return notif; }; var close = function (notification) { notification.close(); }; var getArgs = function (notification) { return notification.args; }; return { open: open, close: close, reposition: reposition, getArgs: getArgs }; } var windows = []; var oldMetaValue = ''; function toggleFullScreenState(state) { var noScaleMetaValue = 'width=device-width,initial-scale=1.0,user-scalable=0,minimum-scale=1.0,maximum-scale=1.0'; var viewport = global$9('meta[name=viewport]')[0], contentValue; if (global$8.overrideViewPort === false) { return; } if (!viewport) { viewport = domGlobals.document.createElement('meta'); viewport.setAttribute('name', 'viewport'); domGlobals.document.getElementsByTagName('head')[0].appendChild(viewport); } contentValue = viewport.getAttribute('content'); if (contentValue && typeof oldMetaValue !== 'undefined') { oldMetaValue = contentValue; } viewport.setAttribute('content', state ? noScaleMetaValue : oldMetaValue); } function toggleBodyFullScreenClasses(classPrefix, state) { if (checkFullscreenWindows() && state === false) { global$9([ domGlobals.document.documentElement, domGlobals.document.body ]).removeClass(classPrefix + 'fullscreen'); } } function checkFullscreenWindows() { for (var i = 0; i < windows.length; i++) { if (windows[i]._fullscreen) { return true; } } return false; } function handleWindowResize() { if (!global$8.desktop) { var lastSize_1 = { w: domGlobals.window.innerWidth, h: domGlobals.window.innerHeight }; global$7.setInterval(function () { var w = domGlobals.window.innerWidth, h = domGlobals.window.innerHeight; if (lastSize_1.w !== w || lastSize_1.h !== h) { lastSize_1 = { w: w, h: h }; global$9(domGlobals.window).trigger('resize'); } }, 100); } function reposition() { var i; var rect = funcs.getWindowSize(); var layoutRect; for (i = 0; i < windows.length; i++) { layoutRect = windows[i].layoutRect(); 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)); } } global$9(domGlobals.window).on('resize', reposition); } var Window = FloatPanel.extend({ modal: true, Defaults: { border: 1, layout: 'flex', containerCls: 'panel', role: 'dialog', callbacks: { submit: function () { this.fire('submit', { data: this.toJSON() }); }, close: function () { this.close(); } } }, init: function (settings) { var self = this; self._super(settings); if (self.isRtl()) { self.classes.add('rtl'); } self.classes.add('window'); self.bodyClasses.add('window-body'); self.state.set('fixed', true); if (settings.buttons) { self.statusbar = new Panel({ layout: 'flex', border: '1 0 0 0', spacing: 3, padding: 10, align: 'center', pack: self.isRtl() ? 'start' : 'end', defaults: { type: 'button' }, items: settings.buttons }); self.statusbar.classes.add('foot'); self.statusbar.parent(self); } self.on('click', function (e) { var closeClass = self.classPrefix + 'close'; if (funcs.hasClass(e.target, closeClass) || funcs.hasClass(e.target.parentNode, closeClass)) { self.close(); } }); self.on('cancel', function () { self.close(); }); self.on('move', function (e) { if (e.control === self) { FloatPanel.hideAll(); } }); self.aria('describedby', self.describedBy || self._id + '-none'); self.aria('label', settings.title); self._fullscreen = false; }, recalc: function () { var self = this; var statusbar = self.statusbar; var layoutRect, width, x, needsRecalc; if (self._fullscreen) { self.layoutRect(funcs.getWindowSize()); self.layoutRect().contentH = self.layoutRect().innerH; } self._super(); layoutRect = self.layoutRect(); if (self.settings.title && !self._fullscreen) { width = layoutRect.headerW; if (width > layoutRect.w) { x = layoutRect.x - Math.max(0, width / 2); self.layoutRect({ w: width, x: x }); needsRecalc = true; } } if (statusbar) { statusbar.layoutRect({ w: self.layoutRect().innerW }).recalc(); width = statusbar.layoutRect().minW + layoutRect.deltaW; if (width > layoutRect.w) { x = layoutRect.x - Math.max(0, width - layoutRect.w); self.layoutRect({ w: width, x: x }); needsRecalc = true; } } if (needsRecalc) { self.recalc(); } }, initLayoutRect: function () { var self = this; var layoutRect = self._super(); var deltaH = 0, headEl; if (self.settings.title && !self._fullscreen) { headEl = self.getEl('head'); var size = funcs.getSize(headEl); layoutRect.headerW = size.width; layoutRect.headerH = size.height; deltaH += layoutRect.headerH; } if (self.statusbar) { deltaH += self.statusbar.layoutRect().h; } layoutRect.deltaH += deltaH; layoutRect.minH += deltaH; layoutRect.h += deltaH; var rect = funcs.getWindowSize(); layoutRect.x = self.settings.x || Math.max(0, rect.w / 2 - layoutRect.w / 2); layoutRect.y = self.settings.y || Math.max(0, rect.h / 2 - layoutRect.h / 2); return layoutRect; }, renderHtml: function () { var self = this, layout = self._layout, id = self._id, prefix = self.classPrefix; var settings = self.settings; var headerHtml = '', footerHtml = '', html = settings.html; self.preRender(); layout.preRender(self); if (settings.title) { 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>'; } if (settings.url) { html = '<iframe src="' + settings.url + '" tabindex="-1"></iframe>'; } if (typeof html === 'undefined') { html = layout.renderHtml(self); } if (self.statusbar) { footerHtml = self.statusbar.renderHtml(); } 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>'; }, fullscreen: function (state) { var self = this; var documentElement = domGlobals.document.documentElement; var slowRendering; var prefix = self.classPrefix; var layoutRect; if (state !== self._fullscreen) { global$9(domGlobals.window).on('resize', function () { var time; if (self._fullscreen) { if (!slowRendering) { time = new Date().getTime(); var rect = funcs.getWindowSize(); self.moveTo(0, 0).resizeTo(rect.w, rect.h); if (new Date().getTime() - time > 50) { slowRendering = true; } } else { if (!self._timer) { self._timer = global$7.setTimeout(function () { var rect = funcs.getWindowSize(); self.moveTo(0, 0).resizeTo(rect.w, rect.h); self._timer = 0; }, 50); } } } }); layoutRect = self.layoutRect(); self._fullscreen = state; if (!state) { self.borderBox = BoxUtils.parseBox(self.settings.border); self.getEl('head').style.display = ''; layoutRect.deltaH += layoutRect.headerH; global$9([ documentElement, domGlobals.document.body ]).removeClass(prefix + 'fullscreen'); self.classes.remove('fullscreen'); self.moveTo(self._initial.x, self._initial.y).resizeTo(self._initial.w, self._initial.h); } else { self._initial = { x: layoutRect.x, y: layoutRect.y, w: layoutRect.w, h: layoutRect.h }; self.borderBox = BoxUtils.parseBox('0'); self.getEl('head').style.display = 'none'; layoutRect.deltaH -= layoutRect.headerH + 2; global$9([ documentElement, domGlobals.document.body ]).addClass(prefix + 'fullscreen'); self.classes.add('fullscreen'); var rect = funcs.getWindowSize(); self.moveTo(0, 0).resizeTo(rect.w, rect.h); } } return self.reflow(); }, postRender: function () { var self = this; var startPos; setTimeout(function () { self.classes.add('in'); self.fire('open'); }, 0); self._super(); if (self.statusbar) { self.statusbar.postRender(); } self.focus(); this.dragHelper = new DragHelper(self._id + '-dragh', { start: function () { startPos = { x: self.layoutRect().x, y: self.layoutRect().y }; }, drag: function (e) { self.moveTo(startPos.x + e.deltaX, startPos.y + e.deltaY); } }); self.on('submit', function (e) { if (!e.isDefaultPrevented()) { self.close(); } }); windows.push(self); toggleFullScreenState(true); }, submit: function () { return this.fire('submit', { data: this.toJSON() }); }, remove: function () { var self = this; var i; self.dragHelper.destroy(); self._super(); if (self.statusbar) { this.statusbar.remove(); } toggleBodyFullScreenClasses(self.classPrefix, false); i = windows.length; while (i--) { if (windows[i] === self) { windows.splice(i, 1); } } toggleFullScreenState(windows.length > 0); }, getContentWindow: function () { var ifr = this.getEl().getElementsByTagName('iframe')[0]; return ifr ? ifr.contentWindow : null; } }); handleWindowResize(); var MessageBox = Window.extend({ init: function (settings) { settings = { border: 1, padding: 20, layout: 'flex', pack: 'center', align: 'center', containerCls: 'panel', autoScroll: true, buttons: { type: 'button', text: 'Ok', action: 'ok' }, items: { type: 'label', multiline: true, maxWidth: 500, maxHeight: 200 } }; this._super(settings); }, Statics: { OK: 1, OK_CANCEL: 2, YES_NO: 3, YES_NO_CANCEL: 4, msgBox: function (settings) { var buttons; var callback = settings.callback || function () { }; function createButton(text, status, primary) { return { type: 'button', text: text, subtype: primary ? 'primary' : '', onClick: function (e) { e.control.parents()[1].close(); callback(status); } }; } switch (settings.buttons) { case MessageBox.OK_CANCEL: buttons = [ createButton('Ok', true, true), createButton('Cancel', false) ]; break; case MessageBox.YES_NO: case MessageBox.YES_NO_CANCEL: buttons = [ createButton('Yes', 1, true), createButton('No', 0) ]; if (settings.buttons === MessageBox.YES_NO_CANCEL) { buttons.push(createButton('Cancel', -1)); } break; default: buttons = [createButton('Ok', true, true)]; break; } return new Window({ padding: 20, x: settings.x, y: settings.y, minWidth: 300, minHeight: 100, layout: 'flex', pack: 'center', align: 'center', buttons: buttons, title: settings.title, role: 'alertdialog', items: { type: 'label', multiline: true, maxWidth: 500, maxHeight: 200, text: settings.text }, onPostRender: function () { this.aria('describedby', this.items()[0]._id); }, onClose: settings.onClose, onCancel: function () { callback(false); } }).renderTo(domGlobals.document.body).reflow(); }, alert: function (settings, callback) { if (typeof settings === 'string') { settings = { text: settings }; } settings.callback = callback; return MessageBox.msgBox(settings); }, confirm: function (settings, callback) { if (typeof settings === 'string') { settings = { text: settings }; } settings.callback = callback; settings.buttons = MessageBox.OK_CANCEL; return MessageBox.msgBox(settings); } } }); function WindowManagerImpl (editor) { var open = function (args, params, closeCallback) { var win; args.title = args.title || ' '; args.url = args.url || args.file; if (args.url) { args.width = parseInt(args.width || 320, 10); args.height = parseInt(args.height || 240, 10); } if (args.body) { args.items = { defaults: args.defaults, type: args.bodyType || 'form', items: args.body, data: args.data, callbacks: args.commands }; } if (!args.url && !args.buttons) { args.buttons = [ { text: 'Ok', subtype: 'primary', onclick: function () { win.find('form')[0].submit(); } }, { text: 'Cancel', onclick: function () { win.close(); } } ]; } win = new Window(args); win.on('close', function () { closeCallback(win); }); if (args.data) { win.on('postRender', function () { this.find('*').each(function (ctrl) { var name = ctrl.name(); if (name in args.data) { ctrl.value(args.data[name]); } }); }); } win.features = args || {}; win.params = params || {}; win = win.renderTo(domGlobals.document.body).reflow(); return win; }; var alert = function (message, choiceCallback, closeCallback) { var win; win = MessageBox.alert(message, function () { choiceCallback(); }); win.on('close', function () { closeCallback(win); }); return win; }; var confirm = function (message, choiceCallback, closeCallback) { var win; win = MessageBox.confirm(message, function (state) { choiceCallback(state); }); win.on('close', function () { closeCallback(win); }); return win; }; var close = function (window) { window.close(); }; var getParams = function (window) { return window.params; }; var setParams = function (window, params) { window.params = params; }; return { open: open, alert: alert, confirm: confirm, close: close, getParams: getParams, setParams: setParams }; } var get = function (editor) { var renderUI = function (args) { return Render.renderUI(editor, this, args); }; var resizeTo = function (w, h) { return Resize.resizeTo(editor, w, h); }; var resizeBy = function (dw, dh) { return Resize.resizeBy(editor, dw, dh); }; var getNotificationManagerImpl = function () { return NotificationManagerImpl(editor); }; var getWindowManagerImpl = function () { return WindowManagerImpl(editor); }; return { renderUI: renderUI, resizeTo: resizeTo, resizeBy: resizeBy, getNotificationManagerImpl: getNotificationManagerImpl, getWindowManagerImpl: getWindowManagerImpl }; }; var ThemeApi = { get: get }; var Layout = global$a.extend({ Defaults: { firstControlClass: 'first', lastControlClass: 'last' }, init: function (settings) { this.settings = global$2.extend({}, this.Defaults, settings); }, preRender: function (container) { container.bodyClasses.add(this.settings.containerClass); }, applyClasses: function (items) { var self = this; var settings = self.settings; var firstClass, lastClass, firstItem, lastItem; firstClass = settings.firstControlClass; lastClass = settings.lastControlClass; items.each(function (item) { item.classes.remove(firstClass).remove(lastClass).add(settings.controlClass); if (item.visible()) { if (!firstItem) { firstItem = item; } lastItem = item; } }); if (firstItem) { firstItem.classes.add(firstClass); } if (lastItem) { lastItem.classes.add(lastClass); } }, renderHtml: function (container) { var self = this; var html = ''; self.applyClasses(container.items()); container.items().each(function (item) { html += item.renderHtml(); }); return html; }, recalc: function () { }, postRender: function () { }, isNative: function () { return false; } }); var AbsoluteLayout = Layout.extend({ Defaults: { containerClass: 'abs-layout', controlClass: 'abs-layout-item' }, recalc: function (container) { container.items().filter(':visible').each(function (ctrl) { var settings = ctrl.settings; ctrl.layoutRect({ x: settings.x, y: settings.y, w: settings.w, h: settings.h }); if (ctrl.recalc) { ctrl.recalc(); } }); }, renderHtml: function (container) { return '<div id="' + container._id + '-absend" class="' + container.classPrefix + 'abs-end"></div>' + this._super(container); } }); var Button = Widget.extend({ Defaults: { classes: 'widget btn', role: 'button' }, init: function (settings) { var self = this; var size; self._super(settings); settings = self.settings; size = self.settings.size; self.on('click mousedown', function (e) { e.preventDefault(); }); self.on('touchstart', function (e) { self.fire('click', e); e.preventDefault(); }); if (settings.subtype) { self.classes.add(settings.subtype); } if (size) { self.classes.add('btn-' + size); } if (settings.icon) { self.icon(settings.icon); } }, icon: function (icon) { if (!arguments.length) { return this.state.get('icon'); } this.state.set('icon', icon); return this; }, repaint: function () { var btnElm = this.getEl().firstChild; var btnStyle; if (btnElm) { btnStyle = btnElm.style; btnStyle.width = btnStyle.height = '100%'; } this._super(); }, renderHtml: function () { var self = this, id = self._id, prefix = self.classPrefix; var icon = self.state.get('icon'), image; var text = self.state.get('text'); var textHtml = ''; var ariaPressed; var settings = self.settings; image = settings.image; if (image) { icon = 'none'; if (typeof image !== 'string') { image = domGlobals.window.getSelection ? image[0] : image[1]; } image = ' style="background-image: url(\'' + image + '\')"'; } else { image = ''; } if (text) { self.classes.add('btn-has-text'); textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>'; } icon = icon ? prefix + 'ico ' + prefix + 'i-' + icon : ''; ariaPressed = typeof settings.active === 'boolean' ? ' aria-pressed="' + settings.active + '"' : ''; 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>'; }, bindStates: function () { var self = this, $ = self.$, textCls = self.classPrefix + 'txt'; function setButtonText(text) { var $span = $('span.' + textCls, self.getEl()); if (text) { if (!$span[0]) { $('button:first', self.getEl()).append('<span class="' + textCls + '"></span>'); $span = $('span.' + textCls, self.getEl()); } $span.html(self.encode(text)); } else { $span.remove(); } self.classes.toggle('btn-has-text', !!text); } self.state.on('change:text', function (e) { setButtonText(e.value); }); self.state.on('change:icon', function (e) { var icon = e.value; var prefix = self.classPrefix; self.settings.icon = icon; icon = icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : ''; var btnElm = self.getEl().firstChild; var iconElm = btnElm.getElementsByTagName('i')[0]; if (icon) { if (!iconElm || iconElm !== btnElm.firstChild) { iconElm = domGlobals.document.createElement('i'); btnElm.insertBefore(iconElm, btnElm.firstChild); } iconElm.className = icon; } else if (iconElm) { btnElm.removeChild(iconElm); } setButtonText(self.state.get('text')); }); return self._super(); } }); var BrowseButton = Button.extend({ init: function (settings) { var self = this; settings = global$2.extend({ text: 'Browse...', multiple: false, accept: null }, settings); self._super(settings); self.classes.add('browsebutton'); if (settings.multiple) { self.classes.add('multiple'); } }, postRender: function () { var self = this; var input = funcs.create('input', { type: 'file', id: self._id + '-browse', accept: self.settings.accept }); self._super(); global$9(input).on('change', function (e) { var files = e.target.files; self.value = function () { if (!files.length) { return null; } else if (self.settings.multiple) { return files; } else { return files[0]; } }; e.preventDefault(); if (files.length) { self.fire('change', e); } }); global$9(input).on('click', function (e) { e.stopPropagation(); }); global$9(self.getEl('button')).on('click', function (e) { e.stopPropagation(); input.click(); }); self.getEl().appendChild(input); }, remove: function () { global$9(this.getEl('button')).off(); global$9(this.getEl('input')).off(); this._super(); } }); var ButtonGroup = Container.extend({ Defaults: { defaultType: 'button', role: 'group' }, renderHtml: function () { var self = this, layout = self._layout; self.classes.add('btn-group'); self.preRender(); layout.preRender(self); return '<div id="' + self._id + '" class="' + self.classes + '">' + '<div id="' + self._id + '-body">' + (self.settings.html || '') + layout.renderHtml(self) + '</div>' + '</div>'; } }); var Checkbox = Widget.extend({ Defaults: { classes: 'checkbox', role: 'checkbox', checked: false }, init: function (settings) { var self = this; self._super(settings); self.on('click mousedown', function (e) { e.preventDefault(); }); self.on('click', function (e) { e.preventDefault(); if (!self.disabled()) { self.checked(!self.checked()); } }); self.checked(self.settings.checked); }, checked: function (state) { if (!arguments.length) { return this.state.get('checked'); } this.state.set('checked', state); return this; }, value: function (state) { if (!arguments.length) { return this.checked(); } return this.checked(state); }, renderHtml: function () { var self = this, id = self._id, prefix = self.classPrefix; 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>'; }, bindStates: function () { var self = this; function checked(state) { self.classes.toggle('checked', state); self.aria('checked', state); } self.state.on('change:text', function (e) { self.getEl('al').firstChild.data = self.translate(e.value); }); self.state.on('change:checked change:value', function (e) { self.fire('change'); checked(e.value); }); self.state.on('change:icon', function (e) { var icon = e.value; var prefix = self.classPrefix; if (typeof icon === 'undefined') { return self.settings.icon; } self.settings.icon = icon; icon = icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : ''; var btnElm = self.getEl().firstChild; var iconElm = btnElm.getElementsByTagName('i')[0]; if (icon) { if (!iconElm || iconElm !== btnElm.firstChild) { iconElm = domGlobals.document.createElement('i'); btnElm.insertBefore(iconElm, btnElm.firstChild); } iconElm.className = icon; } else if (iconElm) { btnElm.removeChild(iconElm); } }); if (self.state.get('checked')) { checked(true); } return self._super(); } }); var global$d = tinymce.util.Tools.resolve('tinymce.util.VK'); var ComboBox = Widget.extend({ init: function (settings) { var self = this; self._super(settings); settings = self.settings; self.classes.add('combobox'); self.subinput = true; self.ariaTarget = 'inp'; settings.menu = settings.menu || settings.values; if (settings.menu) { settings.icon = 'caret'; } self.on('click', function (e) { var elm = e.target; var root = self.getEl(); if (!global$9.contains(root, elm) && elm !== root) { return; } while (elm && elm !== root) { if (elm.id && elm.id.indexOf('-open') !== -1) { self.fire('action'); if (settings.menu) { self.showMenu(); if (e.aria) { self.menu.items()[0].focus(); } } } elm = elm.parentNode; } }); self.on('keydown', function (e) { var rootControl; if (e.keyCode === 13 && e.target.nodeName === 'INPUT') { e.preventDefault(); self.parents().reverse().each(function (ctrl) { if (ctrl.toJSON) { rootControl = ctrl; return false; } }); self.fire('submit', { data: rootControl.toJSON() }); } }); self.on('keyup', function (e) { if (e.target.nodeName === 'INPUT') { var oldValue = self.state.get('value'); var newValue = e.target.value; if (newValue !== oldValue) { self.state.set('value', newValue); self.fire('autocomplete', e); } } }); self.on('mouseover', function (e) { var tooltip = self.tooltip().moveTo(-65535); if (self.statusLevel() && e.target.className.indexOf(self.classPrefix + 'status') !== -1) { var statusMessage = self.statusMessage() || 'Ok'; var rel = tooltip.text(statusMessage).show().testMoveRel(e.target, [ 'bc-tc', 'bc-tl', 'bc-tr' ]); tooltip.classes.toggle('tooltip-n', rel === 'bc-tc'); tooltip.classes.toggle('tooltip-nw', rel === 'bc-tl'); tooltip.classes.toggle('tooltip-ne', rel === 'bc-tr'); tooltip.moveRel(e.target, rel); } }); }, statusLevel: function (value) { if (arguments.length > 0) { this.state.set('statusLevel', value); } return this.state.get('statusLevel'); }, statusMessage: function (value) { if (arguments.length > 0) { this.state.set('statusMessage', value); } return this.state.get('statusMessage'); }, showMenu: function () { var self = this; var settings = self.settings; var menu; if (!self.menu) { menu = settings.menu || []; if (menu.length) { menu = { type: 'menu', items: menu }; } else { menu.type = menu.type || 'menu'; } self.menu = global$4.create(menu).parent(self).renderTo(self.getContainerElm()); self.fire('createmenu'); self.menu.reflow(); self.menu.on('cancel', function (e) { if (e.control === self.menu) { self.focus(); } }); self.menu.on('show hide', function (e) { e.control.items().each(function (ctrl) { ctrl.active(ctrl.value() === self.value()); }); }).fire('show'); self.menu.on('select', function (e) { self.value(e.control.value()); }); self.on('focusin', function (e) { if (e.target.tagName.toUpperCase() === 'INPUT') { self.menu.hide(); } }); self.aria('expanded', true); } self.menu.show(); self.menu.layoutRect({ w: self.layoutRect().w }); self.menu.moveRel(self.getEl(), self.isRtl() ? [ 'br-tr', 'tr-br' ] : [ 'bl-tl', 'tl-bl' ]); }, focus: function () { this.getEl('inp').focus(); }, repaint: function () { var self = this, elm = self.getEl(), openElm = self.getEl('open'), rect = self.layoutRect(); var width, lineHeight, innerPadding = 0; var inputElm = elm.firstChild; if (self.statusLevel() && self.statusLevel() !== 'none') { innerPadding = parseInt(funcs.getRuntimeStyle(inputElm, 'padding-right'), 10) - parseInt(funcs.getRuntimeStyle(inputElm, 'padding-left'), 10); } if (openElm) { width = rect.w - funcs.getSize(openElm).width - 10; } else { width = rect.w - 10; } var doc = domGlobals.document; if (doc.all && (!doc.documentMode || doc.documentMode <= 8)) { lineHeight = self.layoutRect().h - 2 + 'px'; } global$9(inputElm).css({ width: width - innerPadding, lineHeight: lineHeight }); self._super(); return self; }, postRender: function () { var self = this; global$9(this.getEl('inp')).on('change', function (e) { self.state.set('value', e.target.value); self.fire('change', e); }); return self._super(); }, renderHtml: function () { var self = this, id = self._id, settings = self.settings, prefix = self.classPrefix; var value = self.state.get('value') || ''; var icon, text, openBtnHtml = '', extraAttrs = '', statusHtml = ''; if ('spellcheck' in settings) { extraAttrs += ' spellcheck="' + settings.spellcheck + '"'; } if (settings.maxLength) { extraAttrs += ' maxlength="' + settings.maxLength + '"'; } if (settings.size) { extraAttrs += ' size="' + settings.size + '"'; } if (settings.subtype) { extraAttrs += ' type="' + settings.subtype + '"'; } statusHtml = '<i id="' + id + '-status" class="mce-status mce-ico" style="display: none"></i>'; if (self.disabled()) { extraAttrs += ' disabled="disabled"'; } icon = settings.icon; if (icon && icon !== 'caret') { icon = prefix + 'ico ' + prefix + 'i-' + settings.icon; } text = self.state.get('text'); if (icon || text) { 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>'; self.classes.add('has-open'); } 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>'; }, value: function (value) { if (arguments.length) { this.state.set('value', value); return this; } if (this.state.get('rendered')) { this.state.set('value', this.getEl('inp').value); } return this.state.get('value'); }, showAutoComplete: function (items, term) { var self = this; if (items.length === 0) { self.hideMenu(); return; } var insert = function (value, title) { return function () { self.fire('selectitem', { title: title, value: value }); }; }; if (self.menu) { self.menu.items().remove(); } else { self.menu = global$4.create({ type: 'menu', classes: 'combobox-menu', layout: 'flow' }).parent(self).renderTo(); } global$2.each(items, function (item) { self.menu.add({ text: item.title, url: item.previewUrl, match: term, classes: 'menu-item-ellipsis', onclick: insert(item.value, item.title) }); }); self.menu.renderNew(); self.hideMenu(); self.menu.on('cancel', function (e) { if (e.control.parent() === self.menu) { e.stopPropagation(); self.focus(); self.hideMenu(); } }); self.menu.on('select', function () { self.focus(); }); var maxW = self.layoutRect().w; self.menu.layoutRect({ w: maxW, minW: 0, maxW: maxW }); self.menu.repaint(); self.menu.reflow(); self.menu.show(); self.menu.moveRel(self.getEl(), self.isRtl() ? [ 'br-tr', 'tr-br' ] : [ 'bl-tl', 'tl-bl' ]); }, hideMenu: function () { if (this.menu) { this.menu.hide(); } }, bindStates: function () { var self = this; self.state.on('change:value', function (e) { if (self.getEl('inp').value !== e.value) { self.getEl('inp').value = e.value; } }); self.state.on('change:disabled', function (e) { self.getEl('inp').disabled = e.value; }); self.state.on('change:statusLevel', function (e) { var statusIconElm = self.getEl('status'); var prefix = self.classPrefix, value = e.value; funcs.css(statusIconElm, 'display', value === 'none' ? 'none' : ''); funcs.toggleClass(statusIconElm, prefix + 'i-checkmark', value === 'ok'); funcs.toggleClass(statusIconElm, prefix + 'i-warning', value === 'warn'); funcs.toggleClass(statusIconElm, prefix + 'i-error', value === 'error'); self.classes.toggle('has-status', value !== 'none'); self.repaint(); }); funcs.on(self.getEl('status'), 'mouseleave', function () { self.tooltip().hide(); }); self.on('cancel', function (e) { if (self.menu && self.menu.visible()) { e.stopPropagation(); self.hideMenu(); } }); var focusIdx = function (idx, menu) { if (menu && menu.items().length > 0) { menu.items().eq(idx)[0].focus(); } }; self.on('keydown', function (e) { var keyCode = e.keyCode; if (e.target.nodeName === 'INPUT') { if (keyCode === global$d.DOWN) { e.preventDefault(); self.fire('autocomplete'); focusIdx(0, self.menu); } else if (keyCode === global$d.UP) { e.preventDefault(); focusIdx(-1, self.menu); } } }); return self._super(); }, remove: function () { global$9(this.getEl('inp')).off(); if (this.menu) { this.menu.remove(); } this._super(); } }); var ColorBox = ComboBox.extend({ init: function (settings) { var self = this; settings.spellcheck = false; if (settings.onaction) { settings.icon = 'none'; } self._super(settings); self.classes.add('colorbox'); self.on('change keyup postrender', function () { self.repaintColor(self.value()); }); }, repaintColor: function (value) { var openElm = this.getEl('open'); var elm = openElm ? openElm.getElementsByTagName('i')[0] : null; if (elm) { try { elm.style.background = value; } catch (ex) { } } }, bindStates: function () { var self = this; self.state.on('change:value', function (e) { if (self.state.get('rendered')) { self.repaintColor(e.value); } }); return self._super(); } }); var PanelButton = Button.extend({ showPanel: function () { var self = this, settings = self.settings; self.classes.add('opened'); if (!self.panel) { var panelSettings = settings.panel; if (panelSettings.type) { panelSettings = { layout: 'grid', items: panelSettings }; } panelSettings.role = panelSettings.role || 'dialog'; panelSettings.popover = true; panelSettings.autohide = true; panelSettings.ariaRoot = true; self.panel = new FloatPanel(panelSettings).on('hide', function () { self.classes.remove('opened'); }).on('cancel', function (e) { e.stopPropagation(); self.focus(); self.hidePanel(); }).parent(self).renderTo(self.getContainerElm()); self.panel.fire('show'); self.panel.reflow(); } else { self.panel.show(); } var rtlRels = [ 'bc-tc', 'bc-tl', 'bc-tr' ]; var ltrRels = [ 'bc-tc', 'bc-tr', 'bc-tl', 'tc-bc', 'tc-br', 'tc-bl' ]; var rel = self.panel.testMoveRel(self.getEl(), settings.popoverAlign || (self.isRtl() ? rtlRels : ltrRels)); self.panel.classes.toggle('start', rel.substr(-1) === 'l'); self.panel.classes.toggle('end', rel.substr(-1) === 'r'); var isTop = rel.substr(0, 1) === 't'; self.panel.classes.toggle('bottom', !isTop); self.panel.classes.toggle('top', isTop); self.panel.moveRel(self.getEl(), rel); }, hidePanel: function () { var self = this; if (self.panel) { self.panel.hide(); } }, postRender: function () { var self = this; self.aria('haspopup', true); self.on('click', function (e) { if (e.control === self) { if (self.panel && self.panel.visible()) { self.hidePanel(); } else { self.showPanel(); self.panel.focus(!!e.aria); } } }); return self._super(); }, remove: function () { if (this.panel) { this.panel.remove(); this.panel = null; } return this._super(); } }); var DOM$3 = global$3.DOM; var ColorButton = PanelButton.extend({ init: function (settings) { this._super(settings); this.classes.add('splitbtn'); this.classes.add('colorbutton'); }, color: function (color) { if (color) { this._color = color; this.getEl('preview').style.backgroundColor = color; return this; } return this._color; }, resetColor: function () { this._color = null; this.getEl('preview').style.backgroundColor = null; return this; }, renderHtml: function () { var self = this, id = self._id, prefix = self.classPrefix, text = self.state.get('text'); var icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : ''; var image = self.settings.image ? ' style="background-image: url(\'' + self.settings.image + '\')"' : ''; var textHtml = ''; if (text) { self.classes.add('btn-has-text'); textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>'; } 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>'; }, postRender: function () { var self = this, onClickHandler = self.settings.onclick; self.on('click', function (e) { if (e.aria && e.aria.key === 'down') { return; } if (e.control === self && !DOM$3.getParent(e.target, '.' + self.classPrefix + 'open')) { e.stopImmediatePropagation(); onClickHandler.call(self, e); } }); delete self.settings.onclick; return self._super(); } }); var global$e = tinymce.util.Tools.resolve('tinymce.util.Color'); var ColorPicker = Widget.extend({ Defaults: { classes: 'widget colorpicker' }, init: function (settings) { this._super(settings); }, postRender: function () { var self = this; var color = self.color(); var hsv, hueRootElm, huePointElm, svRootElm, svPointElm; hueRootElm = self.getEl('h'); huePointElm = self.getEl('hp'); svRootElm = self.getEl('sv'); svPointElm = self.getEl('svp'); function getPos(elm, event) { var pos = funcs.getPos(elm); var x, y; x = event.pageX - pos.x; y = event.pageY - pos.y; x = Math.max(0, Math.min(x / elm.clientWidth, 1)); y = Math.max(0, Math.min(y / elm.clientHeight, 1)); return { x: x, y: y }; } function updateColor(hsv, hueUpdate) { var hue = (360 - hsv.h) / 360; funcs.css(huePointElm, { top: hue * 100 + '%' }); if (!hueUpdate) { funcs.css(svPointElm, { left: hsv.s + '%', top: 100 - hsv.v + '%' }); } svRootElm.style.background = global$e({ s: 100, v: 100, h: hsv.h }).toHex(); self.color().parse({ s: hsv.s, v: hsv.v, h: hsv.h }); } function updateSaturationAndValue(e) { var pos; pos = getPos(svRootElm, e); hsv.s = pos.x * 100; hsv.v = (1 - pos.y) * 100; updateColor(hsv); self.fire('change'); } function updateHue(e) { var pos; pos = getPos(hueRootElm, e); hsv = color.toHsv(); hsv.h = (1 - pos.y) * 360; updateColor(hsv, true); self.fire('change'); } self._repaint = function () { hsv = color.toHsv(); updateColor(hsv); }; self._super(); self._svdraghelper = new DragHelper(self._id + '-sv', { start: updateSaturationAndValue, drag: updateSaturationAndValue }); self._hdraghelper = new DragHelper(self._id + '-h', { start: updateHue, drag: updateHue }); self._repaint(); }, rgb: function () { return this.color().toRgb(); }, value: function (value) { var self = this; if (arguments.length) { self.color().parse(value); if (self._rendered) { self._repaint(); } } else { return self.color().toHex(); } }, color: function () { if (!this._color) { this._color = global$e(); } return this._color; }, renderHtml: function () { var self = this; var id = self._id; var prefix = self.classPrefix; var hueHtml; var stops = '#ff0000,#ff0080,#ff00ff,#8000ff,#0000ff,#0080ff,#00ffff,#00ff80,#00ff00,#80ff00,#ffff00,#ff8000,#ff0000'; function getOldIeFallbackHtml() { var i, l, html = '', gradientPrefix, stopsList; gradientPrefix = 'filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='; stopsList = stops.split(','); for (i = 0, l = stopsList.length - 1; i < l; i++) { 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>'; } return html; } var gradientCssText = 'background: -ms-linear-gradient(top,' + stops + ');' + 'background: linear-gradient(to bottom,' + stops + ');'; hueHtml = '<div id="' + id + '-h" class="' + prefix + 'colorpicker-h" style="' + gradientCssText + '">' + getOldIeFallbackHtml() + '<div id="' + id + '-hp" class="' + prefix + 'colorpicker-h-marker"></div>' + '</div>'; 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>'; } }); var DropZone = Widget.extend({ init: function (settings) { var self = this; settings = global$2.extend({ height: 100, text: 'Drop an image here', multiple: false, accept: null }, settings); self._super(settings); self.classes.add('dropzone'); if (settings.multiple) { self.classes.add('multiple'); } }, renderHtml: function () { var self = this; var attrs, elm; var cfg = self.settings; attrs = { id: self._id, hidefocus: '1' }; elm = funcs.create('div', attrs, '<span>' + this.translate(cfg.text) + '</span>'); if (cfg.height) { funcs.css(elm, 'height', cfg.height + 'px'); } if (cfg.width) { funcs.css(elm, 'width', cfg.width + 'px'); } elm.className = self.classes; return elm.outerHTML; }, postRender: function () { var self = this; var toggleDragClass = function (e) { e.preventDefault(); self.classes.toggle('dragenter'); self.getEl().className = self.classes; }; var filter = function (files) { var accept = self.settings.accept; if (typeof accept !== 'string') { return files; } var re = new RegExp('(' + accept.split(/\s*,\s*/).join('|') + ')$', 'i'); return global$2.grep(files, function (file) { return re.test(file.name); }); }; self._super(); self.$el.on('dragover', function (e) { e.preventDefault(); }); self.$el.on('dragenter', toggleDragClass); self.$el.on('dragleave', toggleDragClass); self.$el.on('drop', function (e) { e.preventDefault(); if (self.state.get('disabled')) { return; } var files = filter(e.dataTransfer.files); self.value = function () { if (!files.length) { return null; } else if (self.settings.multiple) { return files; } else { return files[0]; } }; if (files.length) { self.fire('change', e); } }); }, remove: function () { this.$el.off(); this._super(); } }); var Path = Widget.extend({ init: function (settings) { var self = this; if (!settings.delimiter) { settings.delimiter = '\xBB'; } self._super(settings); self.classes.add('path'); self.canFocus = true; self.on('click', function (e) { var index; var target = e.target; if (index = target.getAttribute('data-index')) { self.fire('select', { value: self.row()[index], index: index }); } }); self.row(self.settings.row); }, focus: function () { var self = this; self.getEl().firstChild.focus(); return self; }, row: function (row) { if (!arguments.length) { return this.state.get('row'); } this.state.set('row', row); return this; }, renderHtml: function () { var self = this; return '<div id="' + self._id + '" class="' + self.classes + '">' + self._getDataPathHtml(self.state.get('row')) + '</div>'; }, bindStates: function () { var self = this; self.state.on('change:row', function (e) { self.innerHtml(self._getDataPathHtml(e.value)); }); return self._super(); }, _getDataPathHtml: function (data) { var self = this; var parts = data || []; var i, l, html = ''; var prefix = self.classPrefix; for (i = 0, l = parts.length; i < l; i++) { 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>'; } if (!html) { html = '<div class="' + prefix + 'path-item">\xA0</div>'; } return html; } }); var ElementPath = Path.extend({ postRender: function () { var self = this, editor = self.settings.editor; function isHidden(elm) { if (elm.nodeType === 1) { if (elm.nodeName === 'BR' || !!elm.getAttribute('data-mce-bogus')) { return true; } if (elm.getAttribute('data-mce-type') === 'bookmark') { return true; } } return false; } if (editor.settings.elementpath !== false) { self.on('select', function (e) { editor.focus(); editor.selection.select(this.row()[e.index].element); editor.nodeChanged(); }); editor.on('nodeChange', function (e) { var outParents = []; var parents = e.parents; var i = parents.length; while (i--) { if (parents[i].nodeType === 1 && !isHidden(parents[i])) { var args = editor.fire('ResolveName', { name: parents[i].nodeName.toLowerCase(), target: parents[i] }); if (!args.isDefaultPrevented()) { outParents.push({ name: args.name, element: parents[i] }); } if (args.isPropagationStopped()) { break; } } } self.row(outParents); }); } return self._super(); } }); var FormItem = Container.extend({ Defaults: { layout: 'flex', align: 'center', defaults: { flex: 1 } }, renderHtml: function () { var self = this, layout = self._layout, prefix = self.classPrefix; self.classes.add('formitem'); layout.preRender(self); 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>'; } }); var Form = Container.extend({ Defaults: { containerCls: 'form', layout: 'flex', direction: 'column', align: 'stretch', flex: 1, padding: 15, labelGap: 30, spacing: 10, callbacks: { submit: function () { this.submit(); } } }, preRender: function () { var self = this, items = self.items(); if (!self.settings.formItemDefaults) { self.settings.formItemDefaults = { layout: 'flex', autoResize: 'overflow', defaults: { flex: 1 } }; } items.each(function (ctrl) { var formItem; var label = ctrl.settings.label; if (label) { formItem = new FormItem(global$2.extend({ items: { type: 'label', id: ctrl._id + '-l', text: label, flex: 0, forId: ctrl._id, disabled: ctrl.disabled() } }, self.settings.formItemDefaults)); formItem.type = 'formitem'; ctrl.aria('labelledby', ctrl._id + '-l'); if (typeof ctrl.settings.flex === 'undefined') { ctrl.settings.flex = 1; } self.replace(ctrl, formItem); formItem.add(ctrl); } }); }, submit: function () { return this.fire('submit', { data: this.toJSON() }); }, postRender: function () { var self = this; self._super(); self.fromJSON(self.settings.data); }, bindStates: function () { var self = this; self._super(); function recalcLabels() { var maxLabelWidth = 0; var labels = []; var i, labelGap, items; if (self.settings.labelGapCalc === false) { return; } if (self.settings.labelGapCalc === 'children') { items = self.find('formitem'); } else { items = self.items(); } items.filter('formitem').each(function (item) { var labelCtrl = item.items()[0], labelWidth = labelCtrl.getEl().clientWidth; maxLabelWidth = labelWidth > maxLabelWidth ? labelWidth : maxLabelWidth; labels.push(labelCtrl); }); labelGap = self.settings.labelGap || 0; i = labels.length; while (i--) { labels[i].settings.minWidth = maxLabelWidth + labelGap; } } self.on('show', recalcLabels); recalcLabels(); } }); var FieldSet = Form.extend({ Defaults: { containerCls: 'fieldset', layout: 'flex', direction: 'column', align: 'stretch', flex: 1, padding: '25 15 5 15', labelGap: 30, spacing: 10, border: 1 }, renderHtml: function () { var self = this, layout = self._layout, prefix = self.classPrefix; self.preRender(); layout.preRender(self); 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>'; } }); var unique$1 = 0; var generate = function (prefix) { var date = new Date(); var time = date.getTime(); var random = Math.floor(Math.random() * 1000000000); unique$1++; return prefix + '_' + random + unique$1 + String(time); }; var fromHtml = function (html, scope) { var doc = scope || domGlobals.document; var div = doc.createElement('div'); div.innerHTML = html; if (!div.hasChildNodes() || div.childNodes.length > 1) { domGlobals.console.error('HTML does not have a single root node', html); throw new Error('HTML must have a single root node'); } return fromDom(div.childNodes[0]); }; var fromTag = function (tag, scope) { var doc = scope || domGlobals.document; var node = doc.createElement(tag); return fromDom(node); }; var fromText = function (text, scope) { var doc = scope || domGlobals.document; var node = doc.createTextNode(text); return fromDom(node); }; var fromDom = function (node) { if (node === null || node === undefined) { throw new Error('Node cannot be null or undefined'); } return { dom: constant(node) }; }; var fromPoint = function (docElm, x, y) { var doc = docElm.dom(); return Option.from(doc.elementFromPoint(x, y)).map(fromDom); }; var Element = { fromHtml: fromHtml, fromTag: fromTag, fromText: fromText, fromDom: fromDom, fromPoint: fromPoint }; var cached = function (f) { var called = false; var r; return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (!called) { called = true; r = f.apply(null, args); } return r; }; }; var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE; var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE; var COMMENT = domGlobals.Node.COMMENT_NODE; var DOCUMENT = domGlobals.Node.DOCUMENT_NODE; var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE; var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE; var ELEMENT = domGlobals.Node.ELEMENT_NODE; var TEXT = domGlobals.Node.TEXT_NODE; var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE; var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE; var ENTITY = domGlobals.Node.ENTITY_NODE; var NOTATION = domGlobals.Node.NOTATION_NODE; var Immutable = function () { var fields = []; for (var _i = 0; _i < arguments.length; _i++) { fields[_i] = arguments[_i]; } return function () { var values = []; for (var _i = 0; _i < arguments.length; _i++) { values[_i] = arguments[_i]; } if (fields.length !== values.length) { throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments'); } var struct = {}; each(fields, function (name, i) { struct[name] = constant(values[i]); }); return struct; }; }; var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')(); var path = function (parts, scope) { var o = scope !== undefined && scope !== null ? scope : Global; for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i) o = o[parts[i]]; return o; }; var resolve = function (p, scope) { var parts = p.split('.'); return path(parts, scope); }; var unsafe = function (name, scope) { return resolve(name, scope); }; var getOrDie = function (name, scope) { var actual = unsafe(name, scope); if (actual === undefined || actual === null) throw name + ' not available on this browser'; return actual; }; var Global$1 = { getOrDie: getOrDie }; var node = function () { var f = Global$1.getOrDie('Node'); return f; }; var compareDocumentPosition = function (a, b, match) { return (a.compareDocumentPosition(b) & match) !== 0; }; var documentPositionPreceding = function (a, b) { return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_PRECEDING); }; var documentPositionContainedBy = function (a, b) { return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_CONTAINED_BY); }; var Node = { documentPositionPreceding: documentPositionPreceding, documentPositionContainedBy: documentPositionContainedBy }; var firstMatch = function (regexes, s) { for (var i = 0; i < regexes.length; i++) { var x = regexes[i]; if (x.test(s)) return x; } return undefined; }; var find$1 = function (regexes, agent) { var r = firstMatch(regexes, agent); if (!r) return { major: 0, minor: 0 }; var group = function (i) { return Number(agent.replace(r, '$' + i)); }; return nu(group(1), group(2)); }; var detect = function (versionRegexes, agent) { var cleanedAgent = String(agent).toLowerCase(); if (versionRegexes.length === 0) return unknown(); return find$1(versionRegexes, cleanedAgent); }; var unknown = function () { return nu(0, 0); }; var nu = function (major, minor) { return { major: major, minor: minor }; }; var Version = { nu: nu, detect: detect, unknown: unknown }; var edge = 'Edge'; var chrome = 'Chrome'; var ie = 'IE'; var opera = 'Opera'; var firefox = 'Firefox'; var safari = 'Safari'; var isBrowser = function (name, current) { return function () { return current === name; }; }; var unknown$1 = function () { return nu$1({ current: undefined, version: Version.unknown() }); }; var nu$1 = function (info) { var current = info.current; var version = info.version; return { current: current, version: version, isEdge: isBrowser(edge, current), isChrome: isBrowser(chrome, current), isIE: isBrowser(ie, current), isOpera: isBrowser(opera, current), isFirefox: isBrowser(firefox, current), isSafari: isBrowser(safari, current) }; }; var Browser = { unknown: unknown$1, nu: nu$1, edge: constant(edge), chrome: constant(chrome), ie: constant(ie), opera: constant(opera), firefox: constant(firefox), safari: constant(safari) }; var windows$1 = 'Windows'; var ios = 'iOS'; var android = 'Android'; var linux = 'Linux'; var osx = 'OSX'; var solaris = 'Solaris'; var freebsd = 'FreeBSD'; var isOS = function (name, current) { return function () { return current === name; }; }; var unknown$2 = function () { return nu$2({ current: undefined, version: Version.unknown() }); }; var nu$2 = function (info) { var current = info.current; var version = info.version; return { current: current, version: version, isWindows: isOS(windows$1, current), isiOS: isOS(ios, current), isAndroid: isOS(android, current), isOSX: isOS(osx, current), isLinux: isOS(linux, current), isSolaris: isOS(solaris, current), isFreeBSD: isOS(freebsd, current) }; }; var OperatingSystem = { unknown: unknown$2, nu: nu$2, windows: constant(windows$1), ios: constant(ios), android: constant(android), linux: constant(linux), osx: constant(osx), solaris: constant(solaris), freebsd: constant(freebsd) }; var DeviceType = function (os, browser, userAgent) { var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true; var isiPhone = os.isiOS() && !isiPad; var isAndroid3 = os.isAndroid() && os.version.major === 3; var isAndroid4 = os.isAndroid() && os.version.major === 4; var isTablet = isiPad || isAndroid3 || isAndroid4 && /mobile/i.test(userAgent) === true; var isTouch = os.isiOS() || os.isAndroid(); var isPhone = isTouch && !isTablet; var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false; return { isiPad: constant(isiPad), isiPhone: constant(isiPhone), isTablet: constant(isTablet), isPhone: constant(isPhone), isTouch: constant(isTouch), isAndroid: os.isAndroid, isiOS: os.isiOS, isWebView: constant(iOSwebview) }; }; var detect$1 = function (candidates, userAgent) { var agent = String(userAgent).toLowerCase(); return find(candidates, function (candidate) { return candidate.search(agent); }); }; var detectBrowser = function (browsers, userAgent) { return detect$1(browsers, userAgent).map(function (browser) { var version = Version.detect(browser.versionRegexes, userAgent); return { current: browser.name, version: version }; }); }; var detectOs = function (oses, userAgent) { return detect$1(oses, userAgent).map(function (os) { var version = Version.detect(os.versionRegexes, userAgent); return { current: os.name, version: version }; }); }; var UaString = { detectBrowser: detectBrowser, detectOs: detectOs }; var contains = function (str, substr) { return str.indexOf(substr) !== -1; }; var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/; var checkContains = function (target) { return function (uastring) { return contains(uastring, target); }; }; var browsers = [ { name: 'Edge', versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/], search: function (uastring) { var monstrosity = contains(uastring, 'edge/') && contains(uastring, 'chrome') && contains(uastring, 'safari') && contains(uastring, 'applewebkit'); return monstrosity; } }, { name: 'Chrome', versionRegexes: [ /.*?chrome\/([0-9]+)\.([0-9]+).*/, normalVersionRegex ], search: function (uastring) { return contains(uastring, 'chrome') && !contains(uastring, 'chromeframe'); } }, { name: 'IE', versionRegexes: [ /.*?msie\ ?([0-9]+)\.([0-9]+).*/, /.*?rv:([0-9]+)\.([0-9]+).*/ ], search: function (uastring) { return contains(uastring, 'msie') || contains(uastring, 'trident'); } }, { name: 'Opera', versionRegexes: [ normalVersionRegex, /.*?opera\/([0-9]+)\.([0-9]+).*/ ], search: checkContains('opera') }, { name: 'Firefox', versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/], search: checkContains('firefox') }, { name: 'Safari', versionRegexes: [ normalVersionRegex, /.*?cpu os ([0-9]+)_([0-9]+).*/ ], search: function (uastring) { return (contains(uastring, 'safari') || contains(uastring, 'mobile/')) && contains(uastring, 'applewebkit'); } } ]; var oses = [ { name: 'Windows', search: checkContains('win'), versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/] }, { name: 'iOS', search: function (uastring) { return contains(uastring, 'iphone') || contains(uastring, 'ipad'); }, versionRegexes: [ /.*?version\/\ ?([0-9]+)\.([0-9]+).*/, /.*cpu os ([0-9]+)_([0-9]+).*/, /.*cpu iphone os ([0-9]+)_([0-9]+).*/ ] }, { name: 'Android', search: checkContains('android'), versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/] }, { name: 'OSX', search: checkContains('os x'), versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/] }, { name: 'Linux', search: checkContains('linux'), versionRegexes: [] }, { name: 'Solaris', search: checkContains('sunos'), versionRegexes: [] }, { name: 'FreeBSD', search: checkContains('freebsd'), versionRegexes: [] } ]; var PlatformInfo = { browsers: constant(browsers), oses: constant(oses) }; var detect$2 = function (userAgent) { var browsers = PlatformInfo.browsers(); var oses = PlatformInfo.oses(); var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu); var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu); var deviceType = DeviceType(os, browser, userAgent); return { browser: browser, os: os, deviceType: deviceType }; }; var PlatformDetection = { detect: detect$2 }; var detect$3 = cached(function () { var userAgent = domGlobals.navigator.userAgent; return PlatformDetection.detect(userAgent); }); var PlatformDetection$1 = { detect: detect$3 }; var ELEMENT$1 = ELEMENT; var DOCUMENT$1 = DOCUMENT; var bypassSelector = function (dom) { return dom.nodeType !== ELEMENT$1 && dom.nodeType !== DOCUMENT$1 || dom.childElementCount === 0; }; var all = function (selector, scope) { var base = scope === undefined ? domGlobals.document : scope.dom(); return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), Element.fromDom); }; var one = function (selector, scope) { var base = scope === undefined ? domGlobals.document : scope.dom(); return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom); }; var regularContains = function (e1, e2) { var d1 = e1.dom(); var d2 = e2.dom(); return d1 === d2 ? false : d1.contains(d2); }; var ieContains = function (e1, e2) { return Node.documentPositionContainedBy(e1.dom(), e2.dom()); }; var browser = PlatformDetection$1.detect().browser; var contains$1 = browser.isIE() ? ieContains : regularContains; var spot = Immutable('element', 'offset'); var descendants = function (scope, selector) { return all(selector, scope); }; var trim = global$2.trim; var hasContentEditableState = function (value) { return function (node) { if (node && node.nodeType === 1) { if (node.contentEditable === value) { return true; } if (node.getAttribute('data-mce-contenteditable') === value) { return true; } } return false; }; }; var isContentEditableTrue = hasContentEditableState('true'); var isContentEditableFalse = hasContentEditableState('false'); var create = function (type, title, url, level, attach) { return { type: type, title: title, url: url, level: level, attach: attach }; }; var isChildOfContentEditableTrue = function (node) { while (node = node.parentNode) { var value = node.contentEditable; if (value && value !== 'inherit') { return isContentEditableTrue(node); } } return false; }; var select = function (selector, root) { return map(descendants(Element.fromDom(root), selector), function (element) { return element.dom(); }); }; var getElementText = function (elm) { return elm.innerText || elm.textContent; }; var getOrGenerateId = function (elm) { return elm.id ? elm.id : generate('h'); }; var isAnchor = function (elm) { return elm && elm.nodeName === 'A' && (elm.id || elm.name); }; var isValidAnchor = function (elm) { return isAnchor(elm) && isEditable(elm); }; var isHeader = function (elm) { return elm && /^(H[1-6])$/.test(elm.nodeName); }; var isEditable = function (elm) { return isChildOfContentEditableTrue(elm) && !isContentEditableFalse(elm); }; var isValidHeader = function (elm) { return isHeader(elm) && isEditable(elm); }; var getLevel = function (elm) { return isHeader(elm) ? parseInt(elm.nodeName.substr(1), 10) : 0; }; var headerTarget = function (elm) { var headerId = getOrGenerateId(elm); var attach = function () { elm.id = headerId; }; return create('header', getElementText(elm), '#' + headerId, getLevel(elm), attach); }; var anchorTarget = function (elm) { var anchorId = elm.id || elm.name; var anchorText = getElementText(elm); return create('anchor', anchorText ? anchorText : '#' + anchorId, '#' + anchorId, 0, noop); }; var getHeaderTargets = function (elms) { return map(filter(elms, isValidHeader), headerTarget); }; var getAnchorTargets = function (elms) { return map(filter(elms, isValidAnchor), anchorTarget); }; var getTargetElements = function (elm) { var elms = select('h1,h2,h3,h4,h5,h6,a:not([href])', elm); return elms; }; var hasTitle = function (target) { return trim(target.title).length > 0; }; var find$2 = function (elm) { var elms = getTargetElements(elm); return filter(getHeaderTargets(elms).concat(getAnchorTargets(elms)), hasTitle); }; var LinkTargets = { find: find$2 }; var getActiveEditor = function () { return window.tinymce ? window.tinymce.activeEditor : global$1.activeEditor; }; var history = {}; var HISTORY_LENGTH = 5; var clearHistory = function () { history = {}; }; var toMenuItem = function (target) { return { title: target.title, value: { title: { raw: target.title }, url: target.url, attach: target.attach } }; }; var toMenuItems = function (targets) { return global$2.map(targets, toMenuItem); }; var staticMenuItem = function (title, url) { return { title: title, value: { title: title, url: url, attach: noop } }; }; var isUniqueUrl = function (url, targets) { var foundTarget = exists(targets, function (target) { return target.url === url; }); return !foundTarget; }; var getSetting = function (editorSettings, name, defaultValue) { var value = name in editorSettings ? editorSettings[name] : defaultValue; return value === false ? null : value; }; var createMenuItems = function (term, targets, fileType, editorSettings) { var separator = { title: '-' }; var fromHistoryMenuItems = function (history) { var historyItems = history.hasOwnProperty(fileType) ? history[fileType] : []; var uniqueHistory = filter(historyItems, function (url) { return isUniqueUrl(url, targets); }); return global$2.map(uniqueHistory, function (url) { return { title: url, value: { title: url, url: url, attach: noop } }; }); }; var fromMenuItems = function (type) { var filteredTargets = filter(targets, function (target) { return target.type === type; }); return toMenuItems(filteredTargets); }; var anchorMenuItems = function () { var anchorMenuItems = fromMenuItems('anchor'); var topAnchor = getSetting(editorSettings, 'anchor_top', '#top'); var bottomAchor = getSetting(editorSettings, 'anchor_bottom', '#bottom'); if (topAnchor !== null) { anchorMenuItems.unshift(staticMenuItem('<top>', topAnchor)); } if (bottomAchor !== null) { anchorMenuItems.push(staticMenuItem('<bottom>', bottomAchor)); } return anchorMenuItems; }; var join = function (items) { return foldl(items, function (a, b) { var bothEmpty = a.length === 0 || b.length === 0; return bothEmpty ? a.concat(b) : a.concat(separator, b); }, []); }; if (editorSettings.typeahead_urls === false) { return []; } return fileType === 'file' ? join([ filterByQuery(term, fromHistoryMenuItems(history)), filterByQuery(term, fromMenuItems('header')), filterByQuery(term, anchorMenuItems()) ]) : filterByQuery(term, fromHistoryMenuItems(history)); }; var addToHistory = function (url, fileType) { var items = history[fileType]; if (!/^https?/.test(url)) { return; } if (items) { if (indexOf(items, url).isNone()) { history[fileType] = items.slice(0, HISTORY_LENGTH).concat(url); } } else { history[fileType] = [url]; } }; var filterByQuery = function (term, menuItems) { var lowerCaseTerm = term.toLowerCase(); var result = global$2.grep(menuItems, function (item) { return item.title.toLowerCase().indexOf(lowerCaseTerm) !== -1; }); return result.length === 1 && result[0].title === term ? [] : result; }; var getTitle = function (linkDetails) { var title = linkDetails.title; return title.raw ? title.raw : title; }; var setupAutoCompleteHandler = function (ctrl, editorSettings, bodyElm, fileType) { var autocomplete = function (term) { var linkTargets = LinkTargets.find(bodyElm); var menuItems = createMenuItems(term, linkTargets, fileType, editorSettings); ctrl.showAutoComplete(menuItems, term); }; ctrl.on('autocomplete', function () { autocomplete(ctrl.value()); }); ctrl.on('selectitem', function (e) { var linkDetails = e.value; ctrl.value(linkDetails.url); var title = getTitle(linkDetails); if (fileType === 'image') { ctrl.fire('change', { meta: { alt: title, attach: linkDetails.attach } }); } else { ctrl.fire('change', { meta: { text: title, attach: linkDetails.attach } }); } ctrl.focus(); }); ctrl.on('click', function (e) { if (ctrl.value().length === 0 && e.target.nodeName === 'INPUT') { autocomplete(''); } }); ctrl.on('PostRender', function () { ctrl.getRoot().on('submit', function (e) { if (!e.isDefaultPrevented()) { addToHistory(ctrl.value(), fileType); } }); }); }; var statusToUiState = function (result) { var status = result.status, message = result.message; if (status === 'valid') { return { status: 'ok', message: message }; } else if (status === 'unknown') { return { status: 'warn', message: message }; } else if (status === 'invalid') { return { status: 'warn', message: message }; } else { return { status: 'none', message: '' }; } }; var setupLinkValidatorHandler = function (ctrl, editorSettings, fileType) { var validatorHandler = editorSettings.filepicker_validator_handler; if (validatorHandler) { var validateUrl_1 = function (url) { if (url.length === 0) { ctrl.statusLevel('none'); return; } validatorHandler({ url: url, type: fileType }, function (result) { var uiState = statusToUiState(result); ctrl.statusMessage(uiState.message); ctrl.statusLevel(uiState.status); }); }; ctrl.state.on('change:value', function (e) { validateUrl_1(e.value); }); } }; var FilePicker = ComboBox.extend({ Statics: { clearHistory: clearHistory }, init: function (settings) { var self = this, editor = getActiveEditor(), editorSettings = editor.settings; var actionCallback, fileBrowserCallback, fileBrowserCallbackTypes; var fileType = settings.filetype; settings.spellcheck = false; fileBrowserCallbackTypes = editorSettings.file_picker_types || editorSettings.file_browser_callback_types; if (fileBrowserCallbackTypes) { fileBrowserCallbackTypes = global$2.makeMap(fileBrowserCallbackTypes, /[, ]/); } if (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[fileType]) { fileBrowserCallback = editorSettings.file_picker_callback; if (fileBrowserCallback && (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[fileType])) { actionCallback = function () { var meta = self.fire('beforecall').meta; meta = global$2.extend({ filetype: fileType }, meta); fileBrowserCallback.call(editor, function (value, meta) { self.value(value).fire('change', { meta: meta }); }, self.value(), meta); }; } else { fileBrowserCallback = editorSettings.file_browser_callback; if (fileBrowserCallback && (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[fileType])) { actionCallback = function () { fileBrowserCallback(self.getEl('inp').id, self.value(), fileType, window); }; } } } if (actionCallback) { settings.icon = 'browse'; settings.onaction = actionCallback; } self._super(settings); self.classes.add('filepicker'); setupAutoCompleteHandler(self, editorSettings, editor.getBody(), fileType); setupLinkValidatorHandler(self, editorSettings, fileType); } }); var FitLayout = AbsoluteLayout.extend({ recalc: function (container) { var contLayoutRect = container.layoutRect(), paddingBox = container.paddingBox; container.items().filter(':visible').each(function (ctrl) { ctrl.layoutRect({ x: paddingBox.left, y: paddingBox.top, w: contLayoutRect.innerW - paddingBox.right - paddingBox.left, h: contLayoutRect.innerH - paddingBox.top - paddingBox.bottom }); if (ctrl.recalc) { ctrl.recalc(); } }); } }); var FlexLayout = AbsoluteLayout.extend({ recalc: function (container) { var i, l, items, contLayoutRect, contPaddingBox, contSettings, align, pack, spacing, totalFlex, availableSpace, direction; var ctrl, ctrlLayoutRect, ctrlSettings, flex; var maxSizeItems = []; var size, maxSize, ratio, rect, pos, maxAlignEndPos; var sizeName, minSizeName, posName, maxSizeName, beforeName, innerSizeName, deltaSizeName, contentSizeName; var alignAxisName, alignInnerSizeName, alignSizeName, alignMinSizeName, alignBeforeName, alignAfterName; var alignDeltaSizeName, alignContentSizeName; var max = Math.max, min = Math.min; items = container.items().filter(':visible'); contLayoutRect = container.layoutRect(); contPaddingBox = container.paddingBox; contSettings = container.settings; direction = container.isRtl() ? contSettings.direction || 'row-reversed' : contSettings.direction; align = contSettings.align; pack = container.isRtl() ? contSettings.pack || 'end' : contSettings.pack; spacing = contSettings.spacing || 0; if (direction === 'row-reversed' || direction === 'column-reverse') { items = items.set(items.toArray().reverse()); direction = direction.split('-')[0]; } if (direction === 'column') { posName = 'y'; sizeName = 'h'; minSizeName = 'minH'; maxSizeName = 'maxH'; innerSizeName = 'innerH'; beforeName = 'top'; deltaSizeName = 'deltaH'; contentSizeName = 'contentH'; alignBeforeName = 'left'; alignSizeName = 'w'; alignAxisName = 'x'; alignInnerSizeName = 'innerW'; alignMinSizeName = 'minW'; alignAfterName = 'right'; alignDeltaSizeName = 'deltaW'; alignContentSizeName = 'contentW'; } else { posName = 'x'; sizeName = 'w'; minSizeName = 'minW'; maxSizeName = 'maxW'; innerSizeName = 'innerW'; beforeName = 'left'; deltaSizeName = 'deltaW'; contentSizeName = 'contentW'; alignBeforeName = 'top'; alignSizeName = 'h'; alignAxisName = 'y'; alignInnerSizeName = 'innerH'; alignMinSizeName = 'minH'; alignAfterName = 'bottom'; alignDeltaSizeName = 'deltaH'; alignContentSizeName = 'contentH'; } availableSpace = contLayoutRect[innerSizeName] - contPaddingBox[beforeName] - contPaddingBox[beforeName]; maxAlignEndPos = totalFlex = 0; for (i = 0, l = items.length; i < l; i++) { ctrl = items[i]; ctrlLayoutRect = ctrl.layoutRect(); ctrlSettings = ctrl.settings; flex = ctrlSettings.flex; availableSpace -= i < l - 1 ? spacing : 0; if (flex > 0) { totalFlex += flex; if (ctrlLayoutRect[maxSizeName]) { maxSizeItems.push(ctrl); } ctrlLayoutRect.flex = flex; } availableSpace -= ctrlLayoutRect[minSizeName]; size = contPaddingBox[alignBeforeName] + ctrlLayoutRect[alignMinSizeName] + contPaddingBox[alignAfterName]; if (size > maxAlignEndPos) { maxAlignEndPos = size; } } rect = {}; if (availableSpace < 0) { rect[minSizeName] = contLayoutRect[minSizeName] - availableSpace + contLayoutRect[deltaSizeName]; } else { rect[minSizeName] = contLayoutRect[innerSizeName] - availableSpace + contLayoutRect[deltaSizeName]; } rect[alignMinSizeName] = maxAlignEndPos + contLayoutRect[alignDeltaSizeName]; rect[contentSizeName] = contLayoutRect[innerSizeName] - availableSpace; rect[alignContentSizeName] = maxAlignEndPos; rect.minW = min(rect.minW, contLayoutRect.maxW); rect.minH = min(rect.minH, contLayoutRect.maxH); rect.minW = max(rect.minW, contLayoutRect.startMinWidth); rect.minH = max(rect.minH, contLayoutRect.startMinHeight); if (contLayoutRect.autoResize && (rect.minW !== contLayoutRect.minW || rect.minH !== contLayoutRect.minH)) { rect.w = rect.minW; rect.h = rect.minH; container.layoutRect(rect); this.recalc(container); if (container._lastRect === null) { var parentCtrl = container.parent(); if (parentCtrl) { parentCtrl._lastRect = null; parentCtrl.recalc(); } } return; } ratio = availableSpace / totalFlex; for (i = 0, l = maxSizeItems.length; i < l; i++) { ctrl = maxSizeItems[i]; ctrlLayoutRect = ctrl.layoutRect(); maxSize = ctrlLayoutRect[maxSizeName]; size = ctrlLayoutRect[minSizeName] + ctrlLayoutRect.flex * ratio; if (size > maxSize) { availableSpace -= ctrlLayoutRect[maxSizeName] - ctrlLayoutRect[minSizeName]; totalFlex -= ctrlLayoutRect.flex; ctrlLayoutRect.flex = 0; ctrlLayoutRect.maxFlexSize = maxSize; } else { ctrlLayoutRect.maxFlexSize = 0; } } ratio = availableSpace / totalFlex; pos = contPaddingBox[beforeName]; rect = {}; if (totalFlex === 0) { if (pack === 'end') { pos = availableSpace + contPaddingBox[beforeName]; } else if (pack === 'center') { pos = Math.round(contLayoutRect[innerSizeName] / 2 - (contLayoutRect[innerSizeName] - availableSpace) / 2) + contPaddingBox[beforeName]; if (pos < 0) { pos = contPaddingBox[beforeName]; } } else if (pack === 'justify') { pos = contPaddingBox[beforeName]; spacing = Math.floor(availableSpace / (items.length - 1)); } } rect[alignAxisName] = contPaddingBox[alignBeforeName]; for (i = 0, l = items.length; i < l; i++) { ctrl = items[i]; ctrlLayoutRect = ctrl.layoutRect(); size = ctrlLayoutRect.maxFlexSize || ctrlLayoutRect[minSizeName]; if (align === 'center') { rect[alignAxisName] = Math.round(contLayoutRect[alignInnerSizeName] / 2 - ctrlLayoutRect[alignSizeName] / 2); } else if (align === 'stretch') { rect[alignSizeName] = max(ctrlLayoutRect[alignMinSizeName] || 0, contLayoutRect[alignInnerSizeName] - contPaddingBox[alignBeforeName] - contPaddingBox[alignAfterName]); rect[alignAxisName] = contPaddingBox[alignBeforeName]; } else if (align === 'end') { rect[alignAxisName] = contLayoutRect[alignInnerSizeName] - ctrlLayoutRect[alignSizeName] - contPaddingBox.top; } if (ctrlLayoutRect.flex > 0) { size += ctrlLayoutRect.flex * ratio; } rect[sizeName] = size; rect[posName] = pos; ctrl.layoutRect(rect); if (ctrl.recalc) { ctrl.recalc(); } pos += size + spacing; } } }); var FlowLayout = Layout.extend({ Defaults: { containerClass: 'flow-layout', controlClass: 'flow-layout-item', endClass: 'break' }, recalc: function (container) { container.items().filter(':visible').each(function (ctrl) { if (ctrl.recalc) { ctrl.recalc(); } }); }, isNative: function () { return true; } }); var descendant = function (scope, selector) { return one(selector, scope); }; var toggleFormat = function (editor, fmt) { return function () { editor.execCommand('mceToggleFormat', false, fmt); }; }; var addFormatChangedListener = function (editor, name, changed) { var handler = function (state) { changed(state, name); }; if (editor.formatter) { editor.formatter.formatChanged(name, handler); } else { editor.on('init', function () { editor.formatter.formatChanged(name, handler); }); } }; var postRenderFormatToggle = function (editor, name) { return function (e) { addFormatChangedListener(editor, name, function (state) { e.control.active(state); }); }; }; var register = function (editor) { var alignFormats = [ 'alignleft', 'aligncenter', 'alignright', 'alignjustify' ]; var defaultAlign = 'alignleft'; var alignMenuItems = [ { text: 'Left', icon: 'alignleft', onclick: toggleFormat(editor, 'alignleft') }, { text: 'Center', icon: 'aligncenter', onclick: toggleFormat(editor, 'aligncenter') }, { text: 'Right', icon: 'alignright', onclick: toggleFormat(editor, 'alignright') }, { text: 'Justify', icon: 'alignjustify', onclick: toggleFormat(editor, 'alignjustify') } ]; editor.addMenuItem('align', { text: 'Align', menu: alignMenuItems }); editor.addButton('align', { type: 'menubutton', icon: defaultAlign, menu: alignMenuItems, onShowMenu: function (e) { var menu = e.control.menu; global$2.each(alignFormats, function (formatName, idx) { menu.items().eq(idx).each(function (item) { return item.active(editor.formatter.match(formatName)); }); }); }, onPostRender: function (e) { var ctrl = e.control; global$2.each(alignFormats, function (formatName, idx) { addFormatChangedListener(editor, formatName, function (state) { ctrl.icon(defaultAlign); if (state) { ctrl.icon(formatName); } }); }); } }); global$2.each({ alignleft: [ 'Align left', 'JustifyLeft' ], aligncenter: [ 'Align center', 'JustifyCenter' ], alignright: [ 'Align right', 'JustifyRight' ], alignjustify: [ 'Justify', 'JustifyFull' ], alignnone: [ 'No alignment', 'JustifyNone' ] }, function (item, name) { editor.addButton(name, { active: false, tooltip: item[0], cmd: item[1], onPostRender: postRenderFormatToggle(editor, name) }); }); }; var Align = { register: register }; var getFirstFont = function (fontFamily) { return fontFamily ? fontFamily.split(',')[0] : ''; }; var findMatchingValue = function (items, fontFamily) { var font = fontFamily ? fontFamily.toLowerCase() : ''; var value; global$2.each(items, function (item) { if (item.value.toLowerCase() === font) { value = item.value; } }); global$2.each(items, function (item) { if (!value && getFirstFont(item.value).toLowerCase() === getFirstFont(font).toLowerCase()) { value = item.value; } }); return value; }; var createFontNameListBoxChangeHandler = function (editor, items) { return function () { var self = this; self.state.set('value', null); editor.on('init nodeChange', function (e) { var fontFamily = editor.queryCommandValue('FontName'); var match = findMatchingValue(items, fontFamily); self.value(match ? match : null); if (!match && fontFamily) { self.text(getFirstFont(fontFamily)); } }); }; }; var createFormats = function (formats) { formats = formats.replace(/;$/, '').split(';'); var i = formats.length; while (i--) { formats[i] = formats[i].split('='); } return formats; }; var getFontItems = function (editor) { 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'; var fonts = createFormats(editor.settings.font_formats || defaultFontsFormats); return global$2.map(fonts, function (font) { return { text: { raw: font[0] }, value: font[1], textStyle: font[1].indexOf('dings') === -1 ? 'font-family:' + font[1] : '' }; }); }; var registerButtons = function (editor) { editor.addButton('fontselect', function () { var items = getFontItems(editor); return { type: 'listbox', text: 'Font Family', tooltip: 'Font Family', values: items, fixedWidth: true, onPostRender: createFontNameListBoxChangeHandler(editor, items), onselect: function (e) { if (e.control.settings.value) { editor.execCommand('FontName', false, e.control.settings.value); } } }; }); }; var register$1 = function (editor) { registerButtons(editor); }; var FontSelect = { register: register$1 }; var round = function (number, precision) { var factor = Math.pow(10, precision); return Math.round(number * factor) / factor; }; var toPt = function (fontSize, precision) { if (/[0-9.]+px$/.test(fontSize)) { return round(parseInt(fontSize, 10) * 72 / 96, precision || 0) + 'pt'; } return fontSize; }; var findMatchingValue$1 = function (items, pt, px) { var value; global$2.each(items, function (item) { if (item.value === px) { value = px; } else if (item.value === pt) { value = pt; } }); return value; }; var createFontSizeListBoxChangeHandler = function (editor, items) { return function () { var self = this; editor.on('init nodeChange', function (e) { var px, pt, precision, match; px = editor.queryCommandValue('FontSize'); if (px) { for (precision = 3; !match && precision >= 0; precision--) { pt = toPt(px, precision); match = findMatchingValue$1(items, pt, px); } } self.value(match ? match : null); if (!match) { self.text(pt); } }); }; }; var getFontSizeItems = function (editor) { var defaultFontsizeFormats = '8pt 10pt 12pt 14pt 18pt 24pt 36pt'; var fontsizeFormats = editor.settings.fontsize_formats || defaultFontsizeFormats; return global$2.map(fontsizeFormats.split(' '), function (item) { var text = item, value = item; var values = item.split('='); if (values.length > 1) { text = values[0]; value = values[1]; } return { text: text, value: value }; }); }; var registerButtons$1 = function (editor) { editor.addButton('fontsizeselect', function () { var items = getFontSizeItems(editor); return { type: 'listbox', text: 'Font Sizes', tooltip: 'Font Sizes', values: items, fixedWidth: true, onPostRender: createFontSizeListBoxChangeHandler(editor, items), onclick: function (e) { if (e.control.settings.value) { editor.execCommand('FontSize', false, e.control.settings.value); } } }; }); }; var register$2 = function (editor) { registerButtons$1(editor); }; var FontSizeSelect = { register: register$2 }; var hideMenuObjects = function (editor, menu) { var count = menu.length; global$2.each(menu, function (item) { if (item.menu) { item.hidden = hideMenuObjects(editor, item.menu) === 0; } var formatName = item.format; if (formatName) { item.hidden = !editor.formatter.canApply(formatName); } if (item.hidden) { count--; } }); return count; }; var hideFormatMenuItems = function (editor, menu) { var count = menu.items().length; menu.items().each(function (item) { if (item.menu) { item.visible(hideFormatMenuItems(editor, item.menu) > 0); } if (!item.menu && item.settings.menu) { item.visible(hideMenuObjects(editor, item.settings.menu) > 0); } var formatName = item.settings.format; if (formatName) { item.visible(editor.formatter.canApply(formatName)); } if (!item.visible()) { count--; } }); return count; }; var createFormatMenu = function (editor) { var count = 0; var newFormats = []; var defaultStyleFormats = [ { title: 'Headings', items: [ { title: 'Heading 1', format: 'h1' }, { title: 'Heading 2', format: 'h2' }, { title: 'Heading 3', format: 'h3' }, { title: 'Heading 4', format: 'h4' }, { title: 'Heading 5', format: 'h5' }, { title: 'Heading 6', format: 'h6' } ] }, { title: 'Inline', items: [ { title: 'Bold', icon: 'bold', format: 'bold' }, { title: 'Italic', icon: 'italic', format: 'italic' }, { title: 'Underline', icon: 'underline', format: 'underline' }, { title: 'Strikethrough', icon: 'strikethrough', format: 'strikethrough' }, { title: 'Superscript', icon: 'superscript', format: 'superscript' }, { title: 'Subscript', icon: 'subscript', format: 'subscript' }, { title: 'Code', icon: 'code', format: 'code' } ] }, { title: 'Blocks', items: [ { title: 'Paragraph', format: 'p' }, { title: 'Blockquote', format: 'blockquote' }, { title: 'Div', format: 'div' }, { title: 'Pre', format: 'pre' } ] }, { title: 'Alignment', items: [ { title: 'Left', icon: 'alignleft', format: 'alignleft' }, { title: 'Center', icon: 'aligncenter', format: 'aligncenter' }, { title: 'Right', icon: 'alignright', format: 'alignright' }, { title: 'Justify', icon: 'alignjustify', format: 'alignjustify' } ] } ]; var createMenu = function (formats) { var menu = []; if (!formats) { return; } global$2.each(formats, function (format) { var menuItem = { text: format.title, icon: format.icon }; if (format.items) { menuItem.menu = createMenu(format.items); } else { var formatName = format.format || 'custom' + count++; if (!format.format) { format.name = formatName; newFormats.push(format); } menuItem.format = formatName; menuItem.cmd = format.cmd; } menu.push(menuItem); }); return menu; }; var createStylesMenu = function () { var menu; if (editor.settings.style_formats_merge) { if (editor.settings.style_formats) { menu = createMenu(defaultStyleFormats.concat(editor.settings.style_formats)); } else { menu = createMenu(defaultStyleFormats); } } else { menu = createMenu(editor.settings.style_formats || defaultStyleFormats); } return menu; }; editor.on('init', function () { global$2.each(newFormats, function (format) { editor.formatter.register(format.name, format); }); }); return { type: 'menu', items: createStylesMenu(), onPostRender: function (e) { editor.fire('renderFormatsMenu', { control: e.control }); }, itemDefaults: { preview: true, textStyle: function () { if (this.settings.format) { return editor.formatter.getCssText(this.settings.format); } }, onPostRender: function () { var self = this; self.parent().on('show', function () { var formatName, command; formatName = self.settings.format; if (formatName) { self.disabled(!editor.formatter.canApply(formatName)); self.active(editor.formatter.match(formatName)); } command = self.settings.cmd; if (command) { self.active(editor.queryCommandState(command)); } }); }, onclick: function () { if (this.settings.format) { toggleFormat(editor, this.settings.format)(); } if (this.settings.cmd) { editor.execCommand(this.settings.cmd); } } } }; }; var registerMenuItems = function (editor, formatMenu) { editor.addMenuItem('formats', { text: 'Formats', menu: formatMenu }); }; var registerButtons$2 = function (editor, formatMenu) { editor.addButton('styleselect', { type: 'menubutton', text: 'Formats', menu: formatMenu, onShowMenu: function () { if (editor.settings.style_formats_autohide) { hideFormatMenuItems(editor, this.menu); } } }); }; var register$3 = function (editor) { var formatMenu = createFormatMenu(editor); registerMenuItems(editor, formatMenu); registerButtons$2(editor, formatMenu); }; var Formats = { register: register$3 }; var defaultBlocks = 'Paragraph=p;' + 'Heading 1=h1;' + 'Heading 2=h2;' + 'Heading 3=h3;' + 'Heading 4=h4;' + 'Heading 5=h5;' + 'Heading 6=h6;' + 'Preformatted=pre'; var createFormats$1 = function (formats) { formats = formats.replace(/;$/, '').split(';'); var i = formats.length; while (i--) { formats[i] = formats[i].split('='); } return formats; }; var createListBoxChangeHandler = function (editor, items, formatName) { return function () { var self = this; editor.on('nodeChange', function (e) { var formatter = editor.formatter; var value = null; global$2.each(e.parents, function (node) { global$2.each(items, function (item) { if (formatName) { if (formatter.matchNode(node, formatName, { value: item.value })) { value = item.value; } } else { if (formatter.matchNode(node, item.value)) { value = item.value; } } if (value) { return false; } }); if (value) { return false; } }); self.value(value); }); }; }; var lazyFormatSelectBoxItems = function (editor, blocks) { return function () { var items = []; global$2.each(blocks, function (block) { items.push({ text: block[0], value: block[1], textStyle: function () { return editor.formatter.getCssText(block[1]); } }); }); return { type: 'listbox', text: blocks[0][0], values: items, fixedWidth: true, onselect: function (e) { if (e.control) { var fmt = e.control.value(); toggleFormat(editor, fmt)(); } }, onPostRender: createListBoxChangeHandler(editor, items) }; }; }; var buildMenuItems = function (editor, blocks) { return global$2.map(blocks, function (block) { return { text: block[0], onclick: toggleFormat(editor, block[1]), textStyle: function () { return editor.formatter.getCssText(block[1]); } }; }); }; var register$4 = function (editor) { var blocks = createFormats$1(editor.settings.block_formats || defaultBlocks); editor.addMenuItem('blockformats', { text: 'Blocks', menu: buildMenuItems(editor, blocks) }); editor.addButton('formatselect', lazyFormatSelectBoxItems(editor, blocks)); }; var FormatSelect = { register: register$4 }; var createCustomMenuItems = function (editor, names) { var items, nameList; if (typeof names === 'string') { nameList = names.split(' '); } else if (global$2.isArray(names)) { return flatten(global$2.map(names, function (names) { return createCustomMenuItems(editor, names); })); } items = global$2.grep(nameList, function (name) { return name === '|' || name in editor.menuItems; }); return global$2.map(items, function (name) { return name === '|' ? { text: '-' } : editor.menuItems[name]; }); }; var isSeparator$1 = function (menuItem) { return menuItem && menuItem.text === '-'; }; var trimMenuItems = function (menuItems) { var menuItems2 = filter(menuItems, function (menuItem, i, menuItems) { return !isSeparator$1(menuItem) || !isSeparator$1(menuItems[i - 1]); }); return filter(menuItems2, function (menuItem, i, menuItems) { return !isSeparator$1(menuItem) || i > 0 && i < menuItems.length - 1; }); }; var createContextMenuItems = function (editor, context) { var outputMenuItems = [{ text: '-' }]; var menuItems = global$2.grep(editor.menuItems, function (menuItem) { return menuItem.context === context; }); global$2.each(menuItems, function (menuItem) { if (menuItem.separator === 'before') { outputMenuItems.push({ text: '|' }); } if (menuItem.prependToContext) { outputMenuItems.unshift(menuItem); } else { outputMenuItems.push(menuItem); } if (menuItem.separator === 'after') { outputMenuItems.push({ text: '|' }); } }); return outputMenuItems; }; var createInsertMenu = function (editor) { var insertButtonItems = editor.settings.insert_button_items; if (insertButtonItems) { return trimMenuItems(createCustomMenuItems(editor, insertButtonItems)); } else { return trimMenuItems(createContextMenuItems(editor, 'insert')); } }; var registerButtons$3 = function (editor) { editor.addButton('insert', { type: 'menubutton', icon: 'insert', menu: [], oncreatemenu: function () { this.menu.add(createInsertMenu(editor)); this.menu.renderNew(); } }); }; var register$5 = function (editor) { registerButtons$3(editor); }; var InsertButton = { register: register$5 }; var registerFormatButtons = function (editor) { global$2.each({ bold: 'Bold', italic: 'Italic', underline: 'Underline', strikethrough: 'Strikethrough', subscript: 'Subscript', superscript: 'Superscript' }, function (text, name) { editor.addButton(name, { active: false, tooltip: text, onPostRender: postRenderFormatToggle(editor, name), onclick: toggleFormat(editor, name) }); }); }; var registerCommandButtons = function (editor) { global$2.each({ outdent: [ 'Decrease indent', 'Outdent' ], indent: [ 'Increase indent', 'Indent' ], cut: [ 'Cut', 'Cut' ], copy: [ 'Copy', 'Copy' ], paste: [ 'Paste', 'Paste' ], help: [ 'Help', 'mceHelp' ], selectall: [ 'Select all', 'SelectAll' ], visualaid: [ 'Visual aids', 'mceToggleVisualAid' ], newdocument: [ 'New document', 'mceNewDocument' ], removeformat: [ 'Clear formatting', 'RemoveFormat' ], remove: [ 'Remove', 'Delete' ] }, function (item, name) { editor.addButton(name, { tooltip: item[0], cmd: item[1] }); }); }; var registerCommandToggleButtons = function (editor) { global$2.each({ blockquote: [ 'Blockquote', 'mceBlockQuote' ], subscript: [ 'Subscript', 'Subscript' ], superscript: [ 'Superscript', 'Superscript' ] }, function (item, name) { editor.addButton(name, { active: false, tooltip: item[0], cmd: item[1], onPostRender: postRenderFormatToggle(editor, name) }); }); }; var registerButtons$4 = function (editor) { registerFormatButtons(editor); registerCommandButtons(editor); registerCommandToggleButtons(editor); }; var registerMenuItems$1 = function (editor) { global$2.each({ bold: [ 'Bold', 'Bold', 'Meta+B' ], italic: [ 'Italic', 'Italic', 'Meta+I' ], underline: [ 'Underline', 'Underline', 'Meta+U' ], strikethrough: [ 'Strikethrough', 'Strikethrough' ], subscript: [ 'Subscript', 'Subscript' ], superscript: [ 'Superscript', 'Superscript' ], removeformat: [ 'Clear formatting', 'RemoveFormat' ], newdocument: [ 'New document', 'mceNewDocument' ], cut: [ 'Cut', 'Cut', 'Meta+X' ], copy: [ 'Copy', 'Copy', 'Meta+C' ], paste: [ 'Paste', 'Paste', 'Meta+V' ], selectall: [ 'Select all', 'SelectAll', 'Meta+A' ] }, function (item, name) { editor.addMenuItem(name, { text: item[0], icon: name, shortcut: item[2], cmd: item[1] }); }); editor.addMenuItem('codeformat', { text: 'Code', icon: 'code', onclick: toggleFormat(editor, 'code') }); }; var register$6 = function (editor) { registerButtons$4(editor); registerMenuItems$1(editor); }; var SimpleControls = { register: register$6 }; var toggleUndoRedoState = function (editor, type) { return function () { var self = this; var checkState = function () { var typeFn = type === 'redo' ? 'hasRedo' : 'hasUndo'; return editor.undoManager ? editor.undoManager[typeFn]() : false; }; self.disabled(!checkState()); editor.on('Undo Redo AddUndo TypingUndo ClearUndos SwitchMode', function () { self.disabled(editor.readonly || !checkState()); }); }; }; var registerMenuItems$2 = function (editor) { editor.addMenuItem('undo', { text: 'Undo', icon: 'undo', shortcut: 'Meta+Z', onPostRender: toggleUndoRedoState(editor, 'undo'), cmd: 'undo' }); editor.addMenuItem('redo', { text: 'Redo', icon: 'redo', shortcut: 'Meta+Y', onPostRender: toggleUndoRedoState(editor, 'redo'), cmd: 'redo' }); }; var registerButtons$5 = function (editor) { editor.addButton('undo', { tooltip: 'Undo', onPostRender: toggleUndoRedoState(editor, 'undo'), cmd: 'undo' }); editor.addButton('redo', { tooltip: 'Redo', onPostRender: toggleUndoRedoState(editor, 'redo'), cmd: 'redo' }); }; var register$7 = function (editor) { registerMenuItems$2(editor); registerButtons$5(editor); }; var UndoRedo = { register: register$7 }; var toggleVisualAidState = function (editor) { return function () { var self = this; editor.on('VisualAid', function (e) { self.active(e.hasVisual); }); self.active(editor.hasVisual); }; }; var registerMenuItems$3 = function (editor) { editor.addMenuItem('visualaid', { text: 'Visual aids', selectable: true, onPostRender: toggleVisualAidState(editor), cmd: 'mceToggleVisualAid' }); }; var register$8 = function (editor) { registerMenuItems$3(editor); }; var VisualAid = { register: register$8 }; var setupEnvironment = function () { Widget.tooltips = !global$8.iOS; Control$1.translate = function (text) { return global$1.translate(text); }; }; var setupUiContainer = function (editor) { if (editor.settings.ui_container) { global$8.container = descendant(Element.fromDom(domGlobals.document.body), editor.settings.ui_container).fold(constant(null), function (elm) { return elm.dom(); }); } }; var setupRtlMode = function (editor) { if (editor.rtl) { Control$1.rtl = true; } }; var setupHideFloatPanels = function (editor) { editor.on('mousedown progressstate', function () { FloatPanel.hideAll(); }); }; var setup$1 = function (editor) { setupRtlMode(editor); setupHideFloatPanels(editor); setupUiContainer(editor); setupEnvironment(); FormatSelect.register(editor); Align.register(editor); SimpleControls.register(editor); UndoRedo.register(editor); FontSizeSelect.register(editor); FontSelect.register(editor); Formats.register(editor); VisualAid.register(editor); InsertButton.register(editor); }; var FormatControls = { setup: setup$1 }; var GridLayout = AbsoluteLayout.extend({ recalc: function (container) { var settings, rows, cols, items, contLayoutRect, width, height, rect, ctrlLayoutRect, ctrl, x, y, posX, posY, ctrlSettings, contPaddingBox, align, spacingH, spacingV, alignH, alignV, maxX, maxY; var colWidths = []; var rowHeights = []; var ctrlMinWidth, ctrlMinHeight, availableWidth, availableHeight, reverseRows, idx; settings = container.settings; items = container.items().filter(':visible'); contLayoutRect = container.layoutRect(); cols = settings.columns || Math.ceil(Math.sqrt(items.length)); rows = Math.ceil(items.length / cols); spacingH = settings.spacingH || settings.spacing || 0; spacingV = settings.spacingV || settings.spacing || 0; alignH = settings.alignH || settings.align; alignV = settings.alignV || settings.align; contPaddingBox = container.paddingBox; reverseRows = 'reverseRows' in settings ? settings.reverseRows : container.isRtl(); if (alignH && typeof alignH === 'string') { alignH = [alignH]; } if (alignV && typeof alignV === 'string') { alignV = [alignV]; } for (x = 0; x < cols; x++) { colWidths.push(0); } for (y = 0; y < rows; y++) { rowHeights.push(0); } for (y = 0; y < rows; y++) { for (x = 0; x < cols; x++) { ctrl = items[y * cols + x]; if (!ctrl) { break; } ctrlLayoutRect = ctrl.layoutRect(); ctrlMinWidth = ctrlLayoutRect.minW; ctrlMinHeight = ctrlLayoutRect.minH; colWidths[x] = ctrlMinWidth > colWidths[x] ? ctrlMinWidth : colWidths[x]; rowHeights[y] = ctrlMinHeight > rowHeights[y] ? ctrlMinHeight : rowHeights[y]; } } availableWidth = contLayoutRect.innerW - contPaddingBox.left - contPaddingBox.right; for (maxX = 0, x = 0; x < cols; x++) { maxX += colWidths[x] + (x > 0 ? spacingH : 0); availableWidth -= (x > 0 ? spacingH : 0) + colWidths[x]; } availableHeight = contLayoutRect.innerH - contPaddingBox.top - contPaddingBox.bottom; for (maxY = 0, y = 0; y < rows; y++) { maxY += rowHeights[y] + (y > 0 ? spacingV : 0); availableHeight -= (y > 0 ? spacingV : 0) + rowHeights[y]; } maxX += contPaddingBox.left + contPaddingBox.right; maxY += contPaddingBox.top + contPaddingBox.bottom; rect = {}; rect.minW = maxX + (contLayoutRect.w - contLayoutRect.innerW); rect.minH = maxY + (contLayoutRect.h - contLayoutRect.innerH); rect.contentW = rect.minW - contLayoutRect.deltaW; rect.contentH = rect.minH - contLayoutRect.deltaH; rect.minW = Math.min(rect.minW, contLayoutRect.maxW); rect.minH = Math.min(rect.minH, contLayoutRect.maxH); rect.minW = Math.max(rect.minW, contLayoutRect.startMinWidth); rect.minH = Math.max(rect.minH, contLayoutRect.startMinHeight); if (contLayoutRect.autoResize && (rect.minW !== contLayoutRect.minW || rect.minH !== contLayoutRect.minH)) { rect.w = rect.minW; rect.h = rect.minH; container.layoutRect(rect); this.recalc(container); if (container._lastRect === null) { var parentCtrl = container.parent(); if (parentCtrl) { parentCtrl._lastRect = null; parentCtrl.recalc(); } } return; } if (contLayoutRect.autoResize) { rect = container.layoutRect(rect); rect.contentW = rect.minW - contLayoutRect.deltaW; rect.contentH = rect.minH - contLayoutRect.deltaH; } var flexV; if (settings.packV === 'start') { flexV = 0; } else { flexV = availableHeight > 0 ? Math.floor(availableHeight / rows) : 0; } var totalFlex = 0; var flexWidths = settings.flexWidths; if (flexWidths) { for (x = 0; x < flexWidths.length; x++) { totalFlex += flexWidths[x]; } } else { totalFlex = cols; } var ratio = availableWidth / totalFlex; for (x = 0; x < cols; x++) { colWidths[x] += flexWidths ? flexWidths[x] * ratio : ratio; } posY = contPaddingBox.top; for (y = 0; y < rows; y++) { posX = contPaddingBox.left; height = rowHeights[y] + flexV; for (x = 0; x < cols; x++) { if (reverseRows) { idx = y * cols + cols - 1 - x; } else { idx = y * cols + x; } ctrl = items[idx]; if (!ctrl) { break; } ctrlSettings = ctrl.settings; ctrlLayoutRect = ctrl.layoutRect(); width = Math.max(colWidths[x], ctrlLayoutRect.startMinWidth); ctrlLayoutRect.x = posX; ctrlLayoutRect.y = posY; align = ctrlSettings.alignH || (alignH ? alignH[x] || alignH[0] : null); if (align === 'center') { ctrlLayoutRect.x = posX + width / 2 - ctrlLayoutRect.w / 2; } else if (align === 'right') { ctrlLayoutRect.x = posX + width - ctrlLayoutRect.w; } else if (align === 'stretch') { ctrlLayoutRect.w = width; } align = ctrlSettings.alignV || (alignV ? alignV[x] || alignV[0] : null); if (align === 'center') { ctrlLayoutRect.y = posY + height / 2 - ctrlLayoutRect.h / 2; } else if (align === 'bottom') { ctrlLayoutRect.y = posY + height - ctrlLayoutRect.h; } else if (align === 'stretch') { ctrlLayoutRect.h = height; } ctrl.layoutRect(ctrlLayoutRect); posX += width + spacingH; if (ctrl.recalc) { ctrl.recalc(); } } posY += height + spacingV; } } }); var Iframe$1 = Widget.extend({ renderHtml: function () { var self = this; self.classes.add('iframe'); self.canFocus = false; return '<iframe id="' + self._id + '" class="' + self.classes + '" tabindex="-1" src="' + (self.settings.url || 'javascript:\'\'') + '" frameborder="0"></iframe>'; }, src: function (src) { this.getEl().src = src; }, html: function (html, callback) { var self = this, body = this.getEl().contentWindow.document.body; if (!body) { global$7.setTimeout(function () { self.html(html); }); } else { body.innerHTML = html; if (callback) { callback(); } } return this; } }); var InfoBox = Widget.extend({ init: function (settings) { var self = this; self._super(settings); self.classes.add('widget').add('infobox'); self.canFocus = false; }, severity: function (level) { this.classes.remove('error'); this.classes.remove('warning'); this.classes.remove('success'); this.classes.add(level); }, help: function (state) { this.state.set('help', state); }, renderHtml: function () { var self = this, prefix = self.classPrefix; 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>'; }, bindStates: function () { var self = this; self.state.on('change:text', function (e) { self.getEl('body').firstChild.data = self.encode(e.value); if (self.state.get('rendered')) { self.updateLayoutRect(); } }); self.state.on('change:help', function (e) { self.classes.toggle('has-help', e.value); if (self.state.get('rendered')) { self.updateLayoutRect(); } }); return self._super(); } }); var Label = Widget.extend({ init: function (settings) { var self = this; self._super(settings); self.classes.add('widget').add('label'); self.canFocus = false; if (settings.multiline) { self.classes.add('autoscroll'); } if (settings.strong) { self.classes.add('strong'); } }, initLayoutRect: function () { var self = this, layoutRect = self._super(); if (self.settings.multiline) { var size = funcs.getSize(self.getEl()); if (size.width > layoutRect.maxW) { layoutRect.minW = layoutRect.maxW; self.classes.add('multiline'); } self.getEl().style.width = layoutRect.minW + 'px'; layoutRect.startMinH = layoutRect.h = layoutRect.minH = Math.min(layoutRect.maxH, funcs.getSize(self.getEl()).height); } return layoutRect; }, repaint: function () { var self = this; if (!self.settings.multiline) { self.getEl().style.lineHeight = self.layoutRect().h + 'px'; } return self._super(); }, severity: function (level) { this.classes.remove('error'); this.classes.remove('warning'); this.classes.remove('success'); this.classes.add(level); }, renderHtml: function () { var self = this; var targetCtrl, forName, forId = self.settings.forId; var text = self.settings.html ? self.settings.html : self.encode(self.state.get('text')); if (!forId && (forName = self.settings.forName)) { targetCtrl = self.getRoot().find('#' + forName)[0]; if (targetCtrl) { forId = targetCtrl._id; } } if (forId) { return '<label id="' + self._id + '" class="' + self.classes + '"' + (forId ? ' for="' + forId + '"' : '') + '>' + text + '</label>'; } return '<span id="' + self._id + '" class="' + self.classes + '">' + text + '</span>'; }, bindStates: function () { var self = this; self.state.on('change:text', function (e) { self.innerHtml(self.encode(e.value)); if (self.state.get('rendered')) { self.updateLayoutRect(); } }); return self._super(); } }); var Toolbar$1 = Container.extend({ Defaults: { role: 'toolbar', layout: 'flow' }, init: function (settings) { var self = this; self._super(settings); self.classes.add('toolbar'); }, postRender: function () { var self = this; self.items().each(function (ctrl) { ctrl.classes.add('toolbar-item'); }); return self._super(); } }); var MenuBar = Toolbar$1.extend({ Defaults: { role: 'menubar', containerCls: 'menubar', ariaRoot: true, defaults: { type: 'menubutton' } } }); function isChildOf$1(node, parent) { while (node) { if (parent === node) { return true; } node = node.parentNode; } return false; } var MenuButton = Button.extend({ init: function (settings) { var self = this; self._renderOpen = true; self._super(settings); settings = self.settings; self.classes.add('menubtn'); if (settings.fixedWidth) { self.classes.add('fixed-width'); } self.aria('haspopup', true); self.state.set('menu', settings.menu || self.render()); }, showMenu: function (toggle) { var self = this; var menu; if (self.menu && self.menu.visible() && toggle !== false) { return self.hideMenu(); } if (!self.menu) { menu = self.state.get('menu') || []; self.classes.add('opened'); if (menu.length) { menu = { type: 'menu', animate: true, items: menu }; } else { menu.type = menu.type || 'menu'; menu.animate = true; } if (!menu.renderTo) { self.menu = global$4.create(menu).parent(self).renderTo(); } else { self.menu = menu.parent(self).show().renderTo(); } self.fire('createmenu'); self.menu.reflow(); self.menu.on('cancel', function (e) { if (e.control.parent() === self.menu) { e.stopPropagation(); self.focus(); self.hideMenu(); } }); self.menu.on('select', function () { self.focus(); }); self.menu.on('show hide', function (e) { if (e.type === 'hide' && e.control.parent() === self) { self.classes.remove('opened-under'); } if (e.control === self.menu) { self.activeMenu(e.type === 'show'); self.classes.toggle('opened', e.type === 'show'); } self.aria('expanded', e.type === 'show'); }).fire('show'); } self.menu.show(); self.menu.layoutRect({ w: self.layoutRect().w }); self.menu.repaint(); self.menu.moveRel(self.getEl(), self.isRtl() ? [ 'br-tr', 'tr-br' ] : [ 'bl-tl', 'tl-bl' ]); var menuLayoutRect = self.menu.layoutRect(); var selfBottom = self.$el.offset().top + self.layoutRect().h; if (selfBottom > menuLayoutRect.y && selfBottom < menuLayoutRect.y + menuLayoutRect.h) { self.classes.add('opened-under'); } self.fire('showmenu'); }, hideMenu: function () { var self = this; if (self.menu) { self.menu.items().each(function (item) { if (item.hideMenu) { item.hideMenu(); } }); self.menu.hide(); } }, activeMenu: function (state) { this.classes.toggle('active', state); }, renderHtml: function () { var self = this, id = self._id, prefix = self.classPrefix; var icon = self.settings.icon, image; var text = self.state.get('text'); var textHtml = ''; image = self.settings.image; if (image) { icon = 'none'; if (typeof image !== 'string') { image = domGlobals.window.getSelection ? image[0] : image[1]; } image = ' style="background-image: url(\'' + image + '\')"'; } else { image = ''; } if (text) { self.classes.add('btn-has-text'); textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>'; } icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + icon : ''; self.aria('role', self.parent() instanceof MenuBar ? 'menuitem' : 'button'); 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>'; }, postRender: function () { var self = this; self.on('click', function (e) { if (e.control === self && isChildOf$1(e.target, self.getEl())) { self.focus(); self.showMenu(!e.aria); if (e.aria) { self.menu.items().filter(':visible')[0].focus(); } } }); self.on('mouseenter', function (e) { var overCtrl = e.control; var parent = self.parent(); var hasVisibleSiblingMenu; if (overCtrl && parent && overCtrl instanceof MenuButton && overCtrl.parent() === parent) { parent.items().filter('MenuButton').each(function (ctrl) { if (ctrl.hideMenu && ctrl !== overCtrl) { if (ctrl.menu && ctrl.menu.visible()) { hasVisibleSiblingMenu = true; } ctrl.hideMenu(); } }); if (hasVisibleSiblingMenu) { overCtrl.focus(); overCtrl.showMenu(); } } }); return self._super(); }, bindStates: function () { var self = this; self.state.on('change:menu', function () { if (self.menu) { self.menu.remove(); } self.menu = null; }); return self._super(); }, remove: function () { this._super(); if (this.menu) { this.menu.remove(); } } }); var Menu = FloatPanel.extend({ Defaults: { defaultType: 'menuitem', border: 1, layout: 'stack', role: 'application', bodyRole: 'menu', ariaRoot: true }, init: function (settings) { var self = this; settings.autohide = true; settings.constrainToViewport = true; if (typeof settings.items === 'function') { settings.itemsFactory = settings.items; settings.items = []; } if (settings.itemDefaults) { var items = settings.items; var i = items.length; while (i--) { items[i] = global$2.extend({}, settings.itemDefaults, items[i]); } } self._super(settings); self.classes.add('menu'); if (settings.animate && global$8.ie !== 11) { self.classes.add('animate'); } }, repaint: function () { this.classes.toggle('menu-align', true); this._super(); this.getEl().style.height = ''; this.getEl('body').style.height = ''; return this; }, cancel: function () { var self = this; self.hideAll(); self.fire('select'); }, load: function () { var self = this; var time, factory; function hideThrobber() { if (self.throbber) { self.throbber.hide(); self.throbber = null; } } factory = self.settings.itemsFactory; if (!factory) { return; } if (!self.throbber) { self.throbber = new Throbber(self.getEl('body'), true); if (self.items().length === 0) { self.throbber.show(); self.fire('loading'); } else { self.throbber.show(100, function () { self.items().remove(); self.fire('loading'); }); } self.on('hide close', hideThrobber); } self.requestTime = time = new Date().getTime(); self.settings.itemsFactory(function (items) { if (items.length === 0) { self.hide(); return; } if (self.requestTime !== time) { return; } self.getEl().style.width = ''; self.getEl('body').style.width = ''; hideThrobber(); self.items().remove(); self.getEl('body').innerHTML = ''; self.add(items); self.renderNew(); self.fire('loaded'); }); }, hideAll: function () { var self = this; this.find('menuitem').exec('hideMenu'); return self._super(); }, preRender: function () { var self = this; self.items().each(function (ctrl) { var settings = ctrl.settings; if (settings.icon || settings.image || settings.selectable) { self._hasIcons = true; return false; } }); if (self.settings.itemsFactory) { self.on('postrender', function () { if (self.settings.itemsFactory) { self.load(); } }); } self.on('show hide', function (e) { if (e.control === self) { if (e.type === 'show') { global$7.setTimeout(function () { self.classes.add('in'); }, 0); } else { self.classes.remove('in'); } } }); return self._super(); } }); var ListBox = MenuButton.extend({ init: function (settings) { var self = this; var values, selected, selectedText, lastItemCtrl; function setSelected(menuValues) { for (var i = 0; i < menuValues.length; i++) { selected = menuValues[i].selected || settings.value === menuValues[i].value; if (selected) { selectedText = selectedText || menuValues[i].text; self.state.set('value', menuValues[i].value); return true; } if (menuValues[i].menu) { if (setSelected(menuValues[i].menu)) { return true; } } } } self._super(settings); settings = self.settings; self._values = values = settings.values; if (values) { if (typeof settings.value !== 'undefined') { setSelected(values); } if (!selected && values.length > 0) { selectedText = values[0].text; self.state.set('value', values[0].value); } self.state.set('menu', values); } self.state.set('text', settings.text || selectedText); self.classes.add('listbox'); self.on('select', function (e) { var ctrl = e.control; if (lastItemCtrl) { e.lastControl = lastItemCtrl; } if (settings.multiple) { ctrl.active(!ctrl.active()); } else { self.value(e.control.value()); } lastItemCtrl = ctrl; }); }, value: function (value) { if (arguments.length === 0) { return this.state.get('value'); } if (typeof value === 'undefined') { return this; } function valueExists(values) { return exists(values, function (a) { return a.menu ? valueExists(a.menu) : a.value === value; }); } if (this.settings.values) { if (valueExists(this.settings.values)) { this.state.set('value', value); } else if (value === null) { this.state.set('value', null); } } else { this.state.set('value', value); } return this; }, bindStates: function () { var self = this; function activateMenuItemsByValue(menu, value) { if (menu instanceof Menu) { menu.items().each(function (ctrl) { if (!ctrl.hasMenus()) { ctrl.active(ctrl.value() === value); } }); } } function getSelectedItem(menuValues, value) { var selectedItem; if (!menuValues) { return; } for (var i = 0; i < menuValues.length; i++) { if (menuValues[i].value === value) { return menuValues[i]; } if (menuValues[i].menu) { selectedItem = getSelectedItem(menuValues[i].menu, value); if (selectedItem) { return selectedItem; } } } } self.on('show', function (e) { activateMenuItemsByValue(e.control, self.value()); }); self.state.on('change:value', function (e) { var selectedItem = getSelectedItem(self.state.get('menu'), e.value); if (selectedItem) { self.text(selectedItem.text); } else { self.text(self.settings.text); } }); return self._super(); } }); var toggleTextStyle = function (ctrl, state) { var textStyle = ctrl._textStyle; if (textStyle) { var textElm = ctrl.getEl('text'); textElm.setAttribute('style', textStyle); if (state) { textElm.style.color = ''; textElm.style.backgroundColor = ''; } } }; var MenuItem = Widget.extend({ Defaults: { border: 0, role: 'menuitem' }, init: function (settings) { var self = this; var text; self._super(settings); settings = self.settings; self.classes.add('menu-item'); if (settings.menu) { self.classes.add('menu-item-expand'); } if (settings.preview) { self.classes.add('menu-item-preview'); } text = self.state.get('text'); if (text === '-' || text === '|') { self.classes.add('menu-item-sep'); self.aria('role', 'separator'); self.state.set('text', '-'); } if (settings.selectable) { self.aria('role', 'menuitemcheckbox'); self.classes.add('menu-item-checkbox'); settings.icon = 'selected'; } if (!settings.preview && !settings.selectable) { self.classes.add('menu-item-normal'); } self.on('mousedown', function (e) { e.preventDefault(); }); if (settings.menu && !settings.ariaHideMenu) { self.aria('haspopup', true); } }, hasMenus: function () { return !!this.settings.menu; }, showMenu: function () { var self = this; var settings = self.settings; var menu; var parent = self.parent(); parent.items().each(function (ctrl) { if (ctrl !== self) { ctrl.hideMenu(); } }); if (settings.menu) { menu = self.menu; if (!menu) { menu = settings.menu; if (menu.length) { menu = { type: 'menu', items: menu }; } else { menu.type = menu.type || 'menu'; } if (parent.settings.itemDefaults) { menu.itemDefaults = parent.settings.itemDefaults; } menu = self.menu = global$4.create(menu).parent(self).renderTo(); menu.reflow(); menu.on('cancel', function (e) { e.stopPropagation(); self.focus(); menu.hide(); }); menu.on('show hide', function (e) { if (e.control.items) { e.control.items().each(function (ctrl) { ctrl.active(ctrl.settings.selected); }); } }).fire('show'); menu.on('hide', function (e) { if (e.control === menu) { self.classes.remove('selected'); } }); menu.submenu = true; } else { menu.show(); } menu._parentMenu = parent; menu.classes.add('menu-sub'); var rel = menu.testMoveRel(self.getEl(), self.isRtl() ? [ 'tl-tr', 'bl-br', 'tr-tl', 'br-bl' ] : [ 'tr-tl', 'br-bl', 'tl-tr', 'bl-br' ]); menu.moveRel(self.getEl(), rel); menu.rel = rel; rel = 'menu-sub-' + rel; menu.classes.remove(menu._lastRel).add(rel); menu._lastRel = rel; self.classes.add('selected'); self.aria('expanded', true); } }, hideMenu: function () { var self = this; if (self.menu) { self.menu.items().each(function (item) { if (item.hideMenu) { item.hideMenu(); } }); self.menu.hide(); self.aria('expanded', false); } return self; }, renderHtml: function () { var self = this; var id = self._id; var settings = self.settings; var prefix = self.classPrefix; var text = self.state.get('text'); var icon = self.settings.icon, image = '', shortcut = settings.shortcut; var url = self.encode(settings.url), iconHtml = ''; function convertShortcut(shortcut) { var i, value, replace = {}; if (global$8.mac) { replace = { alt: '⌥', ctrl: '⌘', shift: '⇧', meta: '⌘' }; } else { replace = { meta: 'Ctrl' }; } shortcut = shortcut.split('+'); for (i = 0; i < shortcut.length; i++) { value = replace[shortcut[i].toLowerCase()]; if (value) { shortcut[i] = value; } } return shortcut.join('+'); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } function markMatches(text) { var match = settings.match || ''; return match ? text.replace(new RegExp(escapeRegExp(match), 'gi'), function (match) { return '!mce~match[' + match + ']mce~match!'; }) : text; } function boldMatches(text) { return text.replace(new RegExp(escapeRegExp('!mce~match['), 'g'), '<b>').replace(new RegExp(escapeRegExp(']mce~match!'), 'g'), '</b>'); } if (icon) { self.parent().classes.add('menu-has-icons'); } if (settings.image) { image = ' style="background-image: url(\'' + settings.image + '\')"'; } if (shortcut) { shortcut = convertShortcut(shortcut); } icon = prefix + 'ico ' + prefix + 'i-' + (self.settings.icon || 'none'); iconHtml = text !== '-' ? '<i class="' + icon + '"' + image + '></i>\xA0' : ''; text = boldMatches(self.encode(markMatches(text))); url = boldMatches(self.encode(markMatches(url))); 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>'; }, postRender: function () { var self = this, settings = self.settings; var textStyle = settings.textStyle; if (typeof textStyle === 'function') { textStyle = textStyle.call(this); } if (textStyle) { var textElm = self.getEl('text'); if (textElm) { textElm.setAttribute('style', textStyle); self._textStyle = textStyle; } } self.on('mouseenter click', function (e) { if (e.control === self) { if (!settings.menu && e.type === 'click') { self.fire('select'); global$7.requestAnimationFrame(function () { self.parent().hideAll(); }); } else { self.showMenu(); if (e.aria) { self.menu.focus(true); } } } }); self._super(); return self; }, hover: function () { var self = this; self.parent().items().each(function (ctrl) { ctrl.classes.remove('selected'); }); self.classes.toggle('selected', true); return self; }, active: function (state) { toggleTextStyle(this, state); if (typeof state !== 'undefined') { this.aria('checked', state); } return this._super(state); }, remove: function () { this._super(); if (this.menu) { this.menu.remove(); } } }); var Radio = Checkbox.extend({ Defaults: { classes: 'radio', role: 'radio' } }); var ResizeHandle = Widget.extend({ renderHtml: function () { var self = this, prefix = self.classPrefix; self.classes.add('resizehandle'); if (self.settings.direction === 'both') { self.classes.add('resizehandle-both'); } self.canFocus = false; return '<div id="' + self._id + '" class="' + self.classes + '">' + '<i class="' + prefix + 'ico ' + prefix + 'i-resize"></i>' + '</div>'; }, postRender: function () { var self = this; self._super(); self.resizeDragHelper = new DragHelper(this._id, { start: function () { self.fire('ResizeStart'); }, drag: function (e) { if (self.settings.direction !== 'both') { e.deltaX = 0; } self.fire('Resize', e); }, stop: function () { self.fire('ResizeEnd'); } }); }, remove: function () { if (this.resizeDragHelper) { this.resizeDragHelper.destroy(); } return this._super(); } }); function createOptions(options) { var strOptions = ''; if (options) { for (var i = 0; i < options.length; i++) { strOptions += '<option value="' + options[i] + '">' + options[i] + '</option>'; } } return strOptions; } var SelectBox = Widget.extend({ Defaults: { classes: 'selectbox', role: 'selectbox', options: [] }, init: function (settings) { var self = this; self._super(settings); if (self.settings.size) { self.size = self.settings.size; } if (self.settings.options) { self._options = self.settings.options; } self.on('keydown', function (e) { var rootControl; if (e.keyCode === 13) { e.preventDefault(); self.parents().reverse().each(function (ctrl) { if (ctrl.toJSON) { rootControl = ctrl; return false; } }); self.fire('submit', { data: rootControl.toJSON() }); } }); }, options: function (state) { if (!arguments.length) { return this.state.get('options'); } this.state.set('options', state); return this; }, renderHtml: function () { var self = this; var options, size = ''; options = createOptions(self._options); if (self.size) { size = ' size = "' + self.size + '"'; } return '<select id="' + self._id + '" class="' + self.classes + '"' + size + '>' + options + '</select>'; }, bindStates: function () { var self = this; self.state.on('change:options', function (e) { self.getEl().innerHTML = createOptions(e.value); }); return self._super(); } }); function constrain(value, minVal, maxVal) { if (value < minVal) { value = minVal; } if (value > maxVal) { value = maxVal; } return value; } function setAriaProp(el, name, value) { el.setAttribute('aria-' + name, value); } function updateSliderHandle(ctrl, value) { var maxHandlePos, shortSizeName, sizeName, stylePosName, styleValue, handleEl; if (ctrl.settings.orientation === 'v') { stylePosName = 'top'; sizeName = 'height'; shortSizeName = 'h'; } else { stylePosName = 'left'; sizeName = 'width'; shortSizeName = 'w'; } handleEl = ctrl.getEl('handle'); maxHandlePos = (ctrl.layoutRect()[shortSizeName] || 100) - funcs.getSize(handleEl)[sizeName]; styleValue = maxHandlePos * ((value - ctrl._minValue) / (ctrl._maxValue - ctrl._minValue)) + 'px'; handleEl.style[stylePosName] = styleValue; handleEl.style.height = ctrl.layoutRect().h + 'px'; setAriaProp(handleEl, 'valuenow', value); setAriaProp(handleEl, 'valuetext', '' + ctrl.settings.previewFilter(value)); setAriaProp(handleEl, 'valuemin', ctrl._minValue); setAriaProp(handleEl, 'valuemax', ctrl._maxValue); } var Slider = Widget.extend({ init: function (settings) { var self = this; if (!settings.previewFilter) { settings.previewFilter = function (value) { return Math.round(value * 100) / 100; }; } self._super(settings); self.classes.add('slider'); if (settings.orientation === 'v') { self.classes.add('vertical'); } self._minValue = isNumber(settings.minValue) ? settings.minValue : 0; self._maxValue = isNumber(settings.maxValue) ? settings.maxValue : 100; self._initValue = self.state.get('value'); }, renderHtml: function () { var self = this, id = self._id, prefix = self.classPrefix; return '<div id="' + id + '" class="' + self.classes + '">' + '<div id="' + id + '-handle" class="' + prefix + 'slider-handle" role="slider" tabindex="-1"></div>' + '</div>'; }, reset: function () { this.value(this._initValue).repaint(); }, postRender: function () { var self = this; var minValue, maxValue, screenCordName, stylePosName, sizeName, shortSizeName; function toFraction(min, max, val) { return (val + min) / (max - min); } function fromFraction(min, max, val) { return val * (max - min) - min; } function handleKeyboard(minValue, maxValue) { function alter(delta) { var value; value = self.value(); value = fromFraction(minValue, maxValue, toFraction(minValue, maxValue, value) + delta * 0.05); value = constrain(value, minValue, maxValue); self.value(value); self.fire('dragstart', { value: value }); self.fire('drag', { value: value }); self.fire('dragend', { value: value }); } self.on('keydown', function (e) { switch (e.keyCode) { case 37: case 38: alter(-1); break; case 39: case 40: alter(1); break; } }); } function handleDrag(minValue, maxValue, handleEl) { var startPos, startHandlePos, maxHandlePos, handlePos, value; self._dragHelper = new DragHelper(self._id, { handle: self._id + '-handle', start: function (e) { startPos = e[screenCordName]; startHandlePos = parseInt(self.getEl('handle').style[stylePosName], 10); maxHandlePos = (self.layoutRect()[shortSizeName] || 100) - funcs.getSize(handleEl)[sizeName]; self.fire('dragstart', { value: value }); }, drag: function (e) { var delta = e[screenCordName] - startPos; handlePos = constrain(startHandlePos + delta, 0, maxHandlePos); handleEl.style[stylePosName] = handlePos + 'px'; value = minValue + handlePos / maxHandlePos * (maxValue - minValue); self.value(value); self.tooltip().text('' + self.settings.previewFilter(value)).show().moveRel(handleEl, 'bc tc'); self.fire('drag', { value: value }); }, stop: function () { self.tooltip().hide(); self.fire('dragend', { value: value }); } }); } minValue = self._minValue; maxValue = self._maxValue; if (self.settings.orientation === 'v') { screenCordName = 'screenY'; stylePosName = 'top'; sizeName = 'height'; shortSizeName = 'h'; } else { screenCordName = 'screenX'; stylePosName = 'left'; sizeName = 'width'; shortSizeName = 'w'; } self._super(); handleKeyboard(minValue, maxValue); handleDrag(minValue, maxValue, self.getEl('handle')); }, repaint: function () { this._super(); updateSliderHandle(this, this.value()); }, bindStates: function () { var self = this; self.state.on('change:value', function (e) { updateSliderHandle(self, e.value); }); return self._super(); } }); var Spacer = Widget.extend({ renderHtml: function () { var self = this; self.classes.add('spacer'); self.canFocus = false; return '<div id="' + self._id + '" class="' + self.classes + '"></div>'; } }); var SplitButton = MenuButton.extend({ Defaults: { classes: 'widget btn splitbtn', role: 'button' }, repaint: function () { var self = this; var elm = self.getEl(); var rect = self.layoutRect(); var mainButtonElm, menuButtonElm; self._super(); mainButtonElm = elm.firstChild; menuButtonElm = elm.lastChild; global$9(mainButtonElm).css({ width: rect.w - funcs.getSize(menuButtonElm).width, height: rect.h - 2 }); global$9(menuButtonElm).css({ height: rect.h - 2 }); return self; }, activeMenu: function (state) { var self = this; global$9(self.getEl().lastChild).toggleClass(self.classPrefix + 'active', state); }, renderHtml: function () { var self = this; var id = self._id; var prefix = self.classPrefix; var image; var icon = self.state.get('icon'); var text = self.state.get('text'); var settings = self.settings; var textHtml = '', ariaPressed; image = settings.image; if (image) { icon = 'none'; if (typeof image !== 'string') { image = domGlobals.window.getSelection ? image[0] : image[1]; } image = ' style="background-image: url(\'' + image + '\')"'; } else { image = ''; } icon = settings.icon ? prefix + 'ico ' + prefix + 'i-' + icon : ''; if (text) { self.classes.add('btn-has-text'); textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>'; } ariaPressed = typeof settings.active === 'boolean' ? ' aria-pressed="' + settings.active + '"' : ''; 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>'; }, postRender: function () { var self = this, onClickHandler = self.settings.onclick; self.on('click', function (e) { var node = e.target; if (e.control === this) { while (node) { if (e.aria && e.aria.key !== 'down' || node.nodeName === 'BUTTON' && node.className.indexOf('open') === -1) { e.stopImmediatePropagation(); if (onClickHandler) { onClickHandler.call(this, e); } return; } node = node.parentNode; } } }); delete self.settings.onclick; return self._super(); } }); var StackLayout = FlowLayout.extend({ Defaults: { containerClass: 'stack-layout', controlClass: 'stack-layout-item', endClass: 'break' }, isNative: function () { return true; } }); var TabPanel = Panel.extend({ Defaults: { layout: 'absolute', defaults: { type: 'panel' } }, activateTab: function (idx) { var activeTabElm; if (this.activeTabId) { activeTabElm = this.getEl(this.activeTabId); global$9(activeTabElm).removeClass(this.classPrefix + 'active'); activeTabElm.setAttribute('aria-selected', 'false'); } this.activeTabId = 't' + idx; activeTabElm = this.getEl('t' + idx); activeTabElm.setAttribute('aria-selected', 'true'); global$9(activeTabElm).addClass(this.classPrefix + 'active'); this.items()[idx].show().fire('showtab'); this.reflow(); this.items().each(function (item, i) { if (idx !== i) { item.hide(); } }); }, renderHtml: function () { var self = this; var layout = self._layout; var tabsHtml = ''; var prefix = self.classPrefix; self.preRender(); layout.preRender(self); self.items().each(function (ctrl, i) { var id = self._id + '-t' + i; ctrl.aria('role', 'tabpanel'); ctrl.aria('labelledby', id); 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>'; }); 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>'; }, postRender: function () { var self = this; self._super(); self.settings.activeTab = self.settings.activeTab || 0; self.activateTab(self.settings.activeTab); this.on('click', function (e) { var targetParent = e.target.parentNode; if (targetParent && targetParent.id === self._id + '-head') { var i = targetParent.childNodes.length; while (i--) { if (targetParent.childNodes[i] === e.target) { self.activateTab(i); } } } }); }, initLayoutRect: function () { var self = this; var rect, minW, minH; minW = funcs.getSize(self.getEl('head')).width; minW = minW < 0 ? 0 : minW; minH = 0; self.items().each(function (item) { minW = Math.max(minW, item.layoutRect().minW); minH = Math.max(minH, item.layoutRect().minH); }); self.items().each(function (ctrl) { ctrl.settings.x = 0; ctrl.settings.y = 0; ctrl.settings.w = minW; ctrl.settings.h = minH; ctrl.layoutRect({ x: 0, y: 0, w: minW, h: minH }); }); var headH = funcs.getSize(self.getEl('head')).height; self.settings.minWidth = minW; self.settings.minHeight = minH + headH; rect = self._super(); rect.deltaH += headH; rect.innerH = rect.h - rect.deltaH; return rect; } }); var TextBox = Widget.extend({ init: function (settings) { var self = this; self._super(settings); self.classes.add('textbox'); if (settings.multiline) { self.classes.add('multiline'); } else { self.on('keydown', function (e) { var rootControl; if (e.keyCode === 13) { e.preventDefault(); self.parents().reverse().each(function (ctrl) { if (ctrl.toJSON) { rootControl = ctrl; return false; } }); self.fire('submit', { data: rootControl.toJSON() }); } }); self.on('keyup', function (e) { self.state.set('value', e.target.value); }); } }, repaint: function () { var self = this; var style, rect, borderBox, borderW, borderH = 0, lastRepaintRect; style = self.getEl().style; rect = self._layoutRect; lastRepaintRect = self._lastRepaintRect || {}; var doc = domGlobals.document; if (!self.settings.multiline && doc.all && (!doc.documentMode || doc.documentMode <= 8)) { style.lineHeight = rect.h - borderH + 'px'; } borderBox = self.borderBox; borderW = borderBox.left + borderBox.right + 8; borderH = borderBox.top + borderBox.bottom + (self.settings.multiline ? 8 : 0); if (rect.x !== lastRepaintRect.x) { style.left = rect.x + 'px'; lastRepaintRect.x = rect.x; } if (rect.y !== lastRepaintRect.y) { style.top = rect.y + 'px'; lastRepaintRect.y = rect.y; } if (rect.w !== lastRepaintRect.w) { style.width = rect.w - borderW + 'px'; lastRepaintRect.w = rect.w; } if (rect.h !== lastRepaintRect.h) { style.height = rect.h - borderH + 'px'; lastRepaintRect.h = rect.h; } self._lastRepaintRect = lastRepaintRect; self.fire('repaint', {}, false); return self; }, renderHtml: function () { var self = this; var settings = self.settings; var attrs, elm; attrs = { id: self._id, hidefocus: '1' }; global$2.each([ 'rows', 'spellcheck', 'maxLength', 'size', 'readonly', 'min', 'max', 'step', 'list', 'pattern', 'placeholder', 'required', 'multiple' ], function (name) { attrs[name] = settings[name]; }); if (self.disabled()) { attrs.disabled = 'disabled'; } if (settings.subtype) { attrs.type = settings.subtype; } elm = funcs.create(settings.multiline ? 'textarea' : 'input', attrs); elm.value = self.state.get('value'); elm.className = self.classes.toString(); return elm.outerHTML; }, value: function (value) { if (arguments.length) { this.state.set('value', value); return this; } if (this.state.get('rendered')) { this.state.set('value', this.getEl().value); } return this.state.get('value'); }, postRender: function () { var self = this; self.getEl().value = self.state.get('value'); self._super(); self.$el.on('change', function (e) { self.state.set('value', e.target.value); self.fire('change', e); }); }, bindStates: function () { var self = this; self.state.on('change:value', function (e) { if (self.getEl().value !== e.value) { self.getEl().value = e.value; } }); self.state.on('change:disabled', function (e) { self.getEl().disabled = e.value; }); return self._super(); }, remove: function () { this.$el.off(); this._super(); } }); var getApi = function () { return { Selector: Selector, Collection: Collection$2, ReflowQueue: ReflowQueue, Control: Control$1, Factory: global$4, KeyboardNavigation: KeyboardNavigation, Container: Container, DragHelper: DragHelper, Scrollable: Scrollable, Panel: Panel, Movable: Movable, Resizable: Resizable, FloatPanel: FloatPanel, Window: Window, MessageBox: MessageBox, Tooltip: Tooltip, Widget: Widget, Progress: Progress, Notification: Notification, Layout: Layout, AbsoluteLayout: AbsoluteLayout, Button: Button, ButtonGroup: ButtonGroup, Checkbox: Checkbox, ComboBox: ComboBox, ColorBox: ColorBox, PanelButton: PanelButton, ColorButton: ColorButton, ColorPicker: ColorPicker, Path: Path, ElementPath: ElementPath, FormItem: FormItem, Form: Form, FieldSet: FieldSet, FilePicker: FilePicker, FitLayout: FitLayout, FlexLayout: FlexLayout, FlowLayout: FlowLayout, FormatControls: FormatControls, GridLayout: GridLayout, Iframe: Iframe$1, InfoBox: InfoBox, Label: Label, Toolbar: Toolbar$1, MenuBar: MenuBar, MenuButton: MenuButton, MenuItem: MenuItem, Throbber: Throbber, Menu: Menu, ListBox: ListBox, Radio: Radio, ResizeHandle: ResizeHandle, SelectBox: SelectBox, Slider: Slider, Spacer: Spacer, SplitButton: SplitButton, StackLayout: StackLayout, TabPanel: TabPanel, TextBox: TextBox, DropZone: DropZone, BrowseButton: BrowseButton }; }; var appendTo = function (target) { if (target.ui) { global$2.each(getApi(), function (ref, key) { target.ui[key] = ref; }); } else { target.ui = getApi(); } }; var registerToFactory = function () { global$2.each(getApi(), function (ref, key) { global$4.add(key, ref); }); }; var Api = { appendTo: appendTo, registerToFactory: registerToFactory }; Api.registerToFactory(); Api.appendTo(window.tinymce ? window.tinymce : {}); global.add('modern', function (editor) { FormatControls.setup(editor); return ThemeApi.get(editor); }); function Theme () { } return Theme; }(window)); })(); }); Save