UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

1,208 lines (1,049 loc) 1.97 MB
(function (root, factory) { if (typeof define === 'function' && define.amd) { //Allow using this built library as an AMD module //in another project. That other project will only //see this AMD call, not the internal modules in //the closure below. define([], factory); } else { //Browser globals case. Just assign the //result to a property on the global. root.Thebe = factory()['Thebe']; } }(this, function () { /** * @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved. * Available via the MIT or new BSD license. * see: http://github.com/jrburke/almond for details */ //Going sloppy to avoid 'use strict' string cost, but strict practices should //be followed. /*jslint sloppy: true */ /*global setTimeout: false */ var requirejs, require, define; (function (undef) { var main, req, makeMap, handlers, defined = {}, waiting = {}, config = {}, defining = {}, hasOwn = Object.prototype.hasOwnProperty, aps = [].slice, jsSuffixRegExp = /\.js$/; function hasProp(obj, prop) { return hasOwn.call(obj, prop); } /** * 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. * @returns {String} normalized name */ function normalize(name, baseName) { var nameParts, nameSegment, mapValue, foundMap, lastIndex, foundI, foundStarMap, starI, i, j, part, baseParts = baseName && baseName.split("/"), 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) { name = name.split('/'); lastIndex = name.length - 1; // Node .js allowance: if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); } //Lop off the last part of baseParts, so that . matches the //"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. name = baseParts.slice(0, baseParts.length - 1).concat(name); //start trimDots for (i = 0; i < name.length; i += 1) { part = name[i]; if (part === ".") { name.splice(i, 1); i -= 1; } else if (part === "..") { if (i === 1 && (name[2] === '..' || name[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) { name.splice(i - 1, 2); i -= 2; } } } //end trimDots name = name.join("/"); } 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 ((baseParts || starMap) && map) { 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 = map[baseParts.slice(0, j).join('/')]; //baseName segment has config, find if it has one for //this name. if (mapValue) { mapValue = 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 && starMap[nameSegment]) { foundStarMap = starMap[nameSegment]; starI = i; } } if (!foundMap && foundStarMap) { foundMap = foundStarMap; foundI = starI; } if (foundMap) { nameParts.splice(0, foundI, foundMap); name = nameParts.join('/'); } } return name; } function makeRequire(relName, forceSync) { return function () { //A version of a require function that passes a moduleName //value for items that may need to //look up paths relative to the moduleName var args = aps.call(arguments, 0); //If first arg is not require('string'), and there is only //one arg, it is the array form without a callback. Insert //a null so that the following concat is correct. if (typeof args[0] !== 'string' && args.length === 1) { args.push(null); } return req.apply(undef, args.concat([relName, forceSync])); }; } function makeNormalize(relName) { return function (name) { return normalize(name, relName); }; } function makeLoad(depName) { return function (value) { defined[depName] = value; }; } function callDep(name) { if (hasProp(waiting, name)) { var args = waiting[name]; delete waiting[name]; defining[name] = true; main.apply(undef, args); } if (!hasProp(defined, name) && !hasProp(defining, name)) { throw new Error('No ' + name); } return defined[name]; } //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]; } /** * Makes a name map, normalizing the name, and using a plugin * for normalization if necessary. Grabs a ref to plugin * too, as an optimization. */ makeMap = function (name, relName) { var plugin, parts = splitPrefix(name), prefix = parts[0]; name = parts[1]; if (prefix) { prefix = normalize(prefix, relName); plugin = callDep(prefix); } //Normalize according if (prefix) { if (plugin && plugin.normalize) { name = plugin.normalize(name, makeNormalize(relName)); } else { name = normalize(name, relName); } } else { name = normalize(name, relName); parts = splitPrefix(name); prefix = parts[0]; name = parts[1]; if (prefix) { plugin = callDep(prefix); } } //Using ridiculous property names for space reasons return { f: prefix ? prefix + '!' + name : name, //fullName n: name, pr: prefix, p: plugin }; }; function makeConfig(name) { return function () { return (config && config.config && config.config[name]) || {}; }; } handlers = { require: function (name) { return makeRequire(name); }, exports: function (name) { var e = defined[name]; if (typeof e !== 'undefined') { return e; } else { return (defined[name] = {}); } }, module: function (name) { return { id: name, uri: '', exports: defined[name], config: makeConfig(name) }; } }; main = function (name, deps, callback, relName) { var cjsModule, depName, ret, map, i, args = [], callbackType = typeof callback, usingExports; //Use name if no relName relName = relName || name; //Call the callback to define the module, if necessary. if (callbackType === 'undefined' || callbackType === 'function') { //Pull out the defined dependencies and pass the ordered //values to the callback. //Default to [require, exports, module] if no deps deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps; for (i = 0; i < deps.length; i += 1) { map = makeMap(deps[i], relName); depName = map.f; //Fast path CommonJS standard dependencies. if (depName === "require") { args[i] = handlers.require(name); } else if (depName === "exports") { //CommonJS module spec 1.1 args[i] = handlers.exports(name); usingExports = true; } else if (depName === "module") { //CommonJS module spec 1.1 cjsModule = args[i] = handlers.module(name); } else if (hasProp(defined, depName) || hasProp(waiting, depName) || hasProp(defining, depName)) { args[i] = callDep(depName); } else if (map.p) { map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {}); args[i] = defined[depName]; } else { throw new Error(name + ' missing ' + depName); } } ret = callback ? callback.apply(defined[name], args) : undefined; if (name) { //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. if (cjsModule && cjsModule.exports !== undef && cjsModule.exports !== defined[name]) { defined[name] = cjsModule.exports; } else if (ret !== undef || !usingExports) { //Use the return value from the function. defined[name] = ret; } } } else if (name) { //May just be an object definition for the module. Only //worry about defining if have a module name. defined[name] = callback; } }; requirejs = require = req = function (deps, callback, relName, forceSync, alt) { if (typeof deps === "string") { if (handlers[deps]) { //callback in this case is really relName return handlers[deps](callback); } //Just return the module wanted. In this scenario, the //deps arg is the module name, and second arg (if passed) //is just the relName. //Normalize module name, if it contains . or .. return callDep(makeMap(deps, callback).f); } else if (!deps.splice) { //deps is a config object, not an array. config = deps; if (config.deps) { req(config.deps, config.callback); } if (!callback) { return; } if (callback.splice) { //callback is an array, which means it is a dependency list. //Adjust args if there are dependencies deps = callback; callback = relName; relName = null; } else { deps = undef; } } //Support require(['a']) callback = callback || function () {}; //If relName is a function, it is an errback handler, //so remove it. if (typeof relName === 'function') { relName = forceSync; forceSync = alt; } //Simulate async callback; if (forceSync) { main(undef, deps, callback, relName); } else { //Using a non-zero value because of concern for what old browsers //do, and latest browsers "upgrade" to 4 if lower value is used: //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout: //If want a value immediately, use require('id') instead -- something //that works in almond on the global level, but not guaranteed and //unlikely to work in other AMD implementations. setTimeout(function () { main(undef, deps, callback, relName); }, 4); } return req; }; /** * Just drops the config on the floor, but returns req in case * the config return value is used. */ req.config = function (cfg) { return req(cfg); }; /** * Expose module registry for debugging and tooling */ requirejs._defined = defined; define = function (name, deps, callback) { if (typeof name !== 'string') { throw new Error('See almond README: incorrect module build, no module name'); } //This module may not have dependencies if (!deps.splice) { //deps is not an array, so probably means //an object literal or factory function for //the value. Adjust args. callback = deps; deps = []; } if (!hasProp(defined, name) && !hasProp(waiting, name)) { waiting[name] = [name, deps, callback]; } }; define.amd = { jQuery: true }; }()); define("almond", function(){}); // Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. var Jupyter = Jupyter || {}; var jprop = function(name, module_path){ Object.defineProperty(Jupyter, name, { get: function() { console.warn('accessing `'+name+'` is deprecated. Use `require("'+module_path+'")`'); return require(module_path); }, enumerable: true, configurable: false }); } var jglobal = function(name, module_path){ Object.defineProperty(Jupyter, name, { get: function() { console.warn('accessing `'+name+'` is deprecated. Use `require("'+module_path+'").'+name+'`'); return require(module_path)[name]; }, enumerable: true, configurable: false }); } define('base/js/namespace',[],function(){ "use strict"; // expose modules jprop('utils','base/js/utils') //Jupyter.load_extensions = Jupyter.utils.load_extensions; // jprop('security','base/js/security'); jprop('keyboard','base/js/keyboard'); jprop('dialog','base/js/dialog'); jprop('mathjaxutils','notebook/js/mathjaxutils'); //// exposed constructors jglobal('CommManager','services/kernels/comm') jglobal('Comm','services/kernels/comm') jglobal('NotificationWidget','base/js/notificationwidget'); jglobal('Kernel','services/kernels/kernel'); jglobal('Session','services/sessions/session'); jglobal('LoginWidget','auth/js/loginwidget'); jglobal('Page','base/js/page'); // notebook jglobal('TextCell','notebook/js/textcell'); jglobal('OutputArea','notebook/js/outputarea'); jglobal('KeyboardManager','notebook/js/keyboardmanager'); jglobal('Completer','notebook/js/completer'); jglobal('Notebook','notebook/js/notebook'); jglobal('Tooltip','notebook/js/tooltip'); jglobal('Toolbar','notebook/js/toolbar'); jglobal('SaveWidget','notebook/js/savewidget'); jglobal('Pager','notebook/js/pager'); jglobal('QuickHelp','notebook/js/quickhelp'); jglobal('MarkdownCell','notebook/js/textcell'); jglobal('RawCell','notebook/js/textcell'); jglobal('Cell','notebook/js/cell'); jglobal('MainToolBar','notebook/js/maintoolbar'); jglobal('NotebookNotificationArea','notebook/js/notificationarea'); jglobal('NotebookTour', 'notebook/js/tour'); jglobal('MenuBar', 'notebook/js/menubar'); // tree jglobal('SessionList','tree/js/sessionlist'); jglobal('ClusterList','tree/js/clusterlist'); jglobal('ClusterItem','tree/js/clusterlist'); Jupyter.version = "4.0.5"; Jupyter._target = '_blank'; return Jupyter; }); // deprecated since 4.0, remove in 5+ var IPython = Jupyter ; !function(){var a,b,c,d;!function(){var e={},f={};a=function(a,b,c){e[a]={deps:b,callback:c}},d=c=b=function(a){function c(b){if("."!==b.charAt(0))return b;for(var c=b.split("/"),d=a.split("/").slice(0,-1),e=0,f=c.length;f>e;e++){var g=c[e];if(".."===g)d.pop();else{if("."===g)continue;d.push(g)}}return d.join("/")}if(d._eak_seen=e,f[a])return f[a];if(f[a]={},!e[a])throw new Error("Could not find module "+a);for(var g,h=e[a],i=h.deps,j=h.callback,k=[],l=0,m=i.length;m>l;l++)"exports"===i[l]?k.push(g={}):k.push(b(c(i[l])));var n=j.apply(this,k);return f[a]=g||n}}(),a("promise/all",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to all.");return new b(function(b,c){function d(a){return function(b){f(a,b)}}function f(a,c){h[a]=c,0===--i&&b(h)}var g,h=[],i=a.length;0===i&&b([]);for(var j=0;j<a.length;j++)g=a[j],g&&e(g.then)?g.then(d(j),c):f(j,g)})}var d=a.isArray,e=a.isFunction;b.all=c}),a("promise/asap",["exports"],function(a){"use strict";function b(){return function(){process.nextTick(e)}}function c(){var a=0,b=new i(e),c=document.createTextNode("");return b.observe(c,{characterData:!0}),function(){c.data=a=++a%2}}function d(){return function(){j.setTimeout(e,1)}}function e(){for(var a=0;a<k.length;a++){var b=k[a],c=b[0],d=b[1];c(d)}k=[]}function f(a,b){var c=k.push([a,b]);1===c&&g()}var g,h="undefined"!=typeof window?window:{},i=h.MutationObserver||h.WebKitMutationObserver,j="undefined"!=typeof global?global:void 0===this?window:this,k=[];g="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?b():i?c():d(),a.asap=f}),a("promise/config",["exports"],function(a){"use strict";function b(a,b){return 2!==arguments.length?c[a]:(c[a]=b,void 0)}var c={instrument:!1};a.config=c,a.configure=b}),a("promise/polyfill",["./promise","./utils","exports"],function(a,b,c){"use strict";function d(){var a;a="undefined"!=typeof global?global:"undefined"!=typeof window&&window.document?window:self;var b="Promise"in a&&"resolve"in a.Promise&&"reject"in a.Promise&&"all"in a.Promise&&"race"in a.Promise&&function(){var b;return new a.Promise(function(a){b=a}),f(b)}();b||(a.Promise=e)}var e=a.Promise,f=b.isFunction;c.polyfill=d}),a("promise/promise",["./config","./utils","./all","./race","./resolve","./reject","./asap","exports"],function(a,b,c,d,e,f,g,h){"use strict";function i(a){if(!v(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof i))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._subscribers=[],j(a,this)}function j(a,b){function c(a){o(b,a)}function d(a){q(b,a)}try{a(c,d)}catch(e){d(e)}}function k(a,b,c,d){var e,f,g,h,i=v(c);if(i)try{e=c(d),g=!0}catch(j){h=!0,f=j}else e=d,g=!0;n(b,e)||(i&&g?o(b,e):h?q(b,f):a===D?o(b,e):a===E&&q(b,e))}function l(a,b,c,d){var e=a._subscribers,f=e.length;e[f]=b,e[f+D]=c,e[f+E]=d}function m(a,b){for(var c,d,e=a._subscribers,f=a._detail,g=0;g<e.length;g+=3)c=e[g],d=e[g+b],k(b,c,d,f);a._subscribers=null}function n(a,b){var c,d=null;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(u(b)&&(d=b.then,v(d)))return d.call(b,function(d){return c?!0:(c=!0,b!==d?o(a,d):p(a,d),void 0)},function(b){return c?!0:(c=!0,q(a,b),void 0)}),!0}catch(e){return c?!0:(q(a,e),!0)}return!1}function o(a,b){a===b?p(a,b):n(a,b)||p(a,b)}function p(a,b){a._state===B&&(a._state=C,a._detail=b,t.async(r,a))}function q(a,b){a._state===B&&(a._state=C,a._detail=b,t.async(s,a))}function r(a){m(a,a._state=D)}function s(a){m(a,a._state=E)}var t=a.config,u=(a.configure,b.objectOrFunction),v=b.isFunction,w=(b.now,c.all),x=d.race,y=e.resolve,z=f.reject,A=g.asap;t.async=A;var B=void 0,C=0,D=1,E=2;i.prototype={constructor:i,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(a,b){var c=this,d=new this.constructor(function(){});if(this._state){var e=arguments;t.async(function(){k(c._state,d,e[c._state-1],c._detail)})}else l(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}},i.all=w,i.race=x,i.resolve=y,i.reject=z,h.Promise=i}),a("promise/race",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to race.");return new b(function(b,c){for(var d,e=0;e<a.length;e++)d=a[e],d&&"function"==typeof d.then?d.then(b,c):b(d)})}var d=a.isArray;b.race=c}),a("promise/reject",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b,c){c(a)})}a.reject=b}),a("promise/resolve",["exports"],function(a){"use strict";function b(a){if(a&&"object"==typeof a&&a.constructor===this)return a;var b=this;return new b(function(b){b(a)})}a.resolve=b}),a("promise/utils",["exports"],function(a){"use strict";function b(a){return c(a)||"object"==typeof a&&null!==a}function c(a){return"function"==typeof a}function d(a){return"[object Array]"===Object.prototype.toString.call(a)}var e=Date.now||function(){return(new Date).getTime()};a.objectOrFunction=b,a.isFunction=c,a.isArray=d,a.now=e}),b("promise/polyfill").polyfill()}(); define("components/es6-promise/promise.min", function(){}); /*! * jQuery doTimeout: Like setTimeout, but better! - v1.0 - 3/3/2010 * http://benalman.com/projects/jquery-dotimeout-plugin/ * * Copyright (c) 2010 "Cowboy" Ben Alman * Dual licensed under the MIT and GPL licenses. * http://benalman.com/about/license/ */ // Script: jQuery doTimeout: Like setTimeout, but better! // // *Version: 1.0, Last updated: 3/3/2010* // // Project Home - http://benalman.com/projects/jquery-dotimeout-plugin/ // GitHub - http://github.com/cowboy/jquery-dotimeout/ // Source - http://github.com/cowboy/jquery-dotimeout/raw/master/jquery.ba-dotimeout.js // (Minified) - http://github.com/cowboy/jquery-dotimeout/raw/master/jquery.ba-dotimeout.min.js (1.0kb) // // About: License // // Copyright (c) 2010 "Cowboy" Ben Alman, // Dual licensed under the MIT and GPL licenses. // http://benalman.com/about/license/ // // About: Examples // // These working examples, complete with fully commented code, illustrate a few // ways in which this plugin can be used. // // Debouncing - http://benalman.com/code/projects/jquery-dotimeout/examples/debouncing/ // Delays, Polling - http://benalman.com/code/projects/jquery-dotimeout/examples/delay-poll/ // Hover Intent - http://benalman.com/code/projects/jquery-dotimeout/examples/hoverintent/ // // About: Support and Testing // // Information about what version or versions of jQuery this plugin has been // tested with, what browsers it has been tested in, and where the unit tests // reside (so you can test it yourself). // // jQuery Versions - 1.3.2, 1.4.2 // Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome 4-5, Opera 9.6-10.1. // Unit Tests - http://benalman.com/code/projects/jquery-dotimeout/unit/ // // About: Release History // // 1.0 - (3/3/2010) Callback can now be a string, in which case it will call // the appropriate $.method or $.fn.method, depending on where .doTimeout // was called. Callback must now return `true` (not just a truthy value) // to poll. // 0.4 - (7/15/2009) Made the "id" argument optional, some other minor tweaks // 0.3 - (6/25/2009) Initial release define('thebe/dotimeout',[ 'jquery', ], function($) { (function($){ '$:nomunge'; // Used by YUI compressor. var cache = {}, // Reused internal string. doTimeout = 'doTimeout', // A convenient shortcut. aps = Array.prototype.slice; // Method: jQuery.doTimeout // // Initialize, cancel, or force execution of a callback after a delay. // // If delay and callback are specified, a doTimeout is initialized. The // callback will execute, asynchronously, after the delay. If an id is // specified, this doTimeout will override and cancel any existing doTimeout // with the same id. Any additional arguments will be passed into callback // when it is executed. // // If the callback returns true, the doTimeout loop will execute again, after // the delay, creating a polling loop until the callback returns a non-true // value. // // Note that if an id is not passed as the first argument, this doTimeout will // NOT be able to be manually canceled or forced. (for debouncing, be sure to // specify an id). // // If id is specified, but delay and callback are not, the doTimeout will be // canceled without executing the callback. If force_mode is specified, the // callback will be executed, synchronously, but will only be allowed to // continue a polling loop if force_mode is true (provided the callback // returns true, of course). If force_mode is false, no polling loop will // continue, even if the callback returns true. // // Usage: // // > jQuery.doTimeout( [ id, ] delay, callback [, arg ... ] ); // > jQuery.doTimeout( id [, force_mode ] ); // // Arguments: // // id - (String) An optional unique identifier for this doTimeout. If id is // not specified, the doTimeout will NOT be able to be manually canceled or // forced. // delay - (Number) A zero-or-greater delay in milliseconds after which // callback will be executed. // callback - (Function) A function to be executed after delay milliseconds. // callback - (String) A jQuery method to be executed after delay // milliseconds. This method will only poll if it explicitly returns // true. // force_mode - (Boolean) If true, execute that id's doTimeout callback // immediately and synchronously, continuing any callback return-true // polling loop. If false, execute the callback immediately and // synchronously but do NOT continue a callback return-true polling loop. // If omitted, cancel that id's doTimeout. // // Returns: // // If force_mode is true, false or undefined and there is a // yet-to-be-executed callback to cancel, true is returned, but if no // callback remains to be executed, undefined is returned. $[doTimeout] = function() { return p_doTimeout.apply( window, [ 0 ].concat( aps.call( arguments ) ) ); }; // Method: jQuery.fn.doTimeout // // Initialize, cancel, or force execution of a callback after a delay. // Operates like <jQuery.doTimeout>, but the passed callback executes in the // context of the jQuery collection of elements, and the id is stored as data // on the first element in that collection. // // If delay and callback are specified, a doTimeout is initialized. The // callback will execute, asynchronously, after the delay. If an id is // specified, this doTimeout will override and cancel any existing doTimeout // with the same id. Any additional arguments will be passed into callback // when it is executed. // // If the callback returns true, the doTimeout loop will execute again, after // the delay, creating a polling loop until the callback returns a non-true // value. // // Note that if an id is not passed as the first argument, this doTimeout will // NOT be able to be manually canceled or forced (for debouncing, be sure to // specify an id). // // If id is specified, but delay and callback are not, the doTimeout will be // canceled without executing the callback. If force_mode is specified, the // callback will be executed, synchronously, but will only be allowed to // continue a polling loop if force_mode is true (provided the callback // returns true, of course). If force_mode is false, no polling loop will // continue, even if the callback returns true. // // Usage: // // > jQuery('selector').doTimeout( [ id, ] delay, callback [, arg ... ] ); // > jQuery('selector').doTimeout( id [, force_mode ] ); // // Arguments: // // id - (String) An optional unique identifier for this doTimeout, stored as // jQuery data on the element. If id is not specified, the doTimeout will // NOT be able to be manually canceled or forced. // delay - (Number) A zero-or-greater delay in milliseconds after which // callback will be executed. // callback - (Function) A function to be executed after delay milliseconds. // callback - (String) A jQuery.fn method to be executed after delay // milliseconds. This method will only poll if it explicitly returns // true (most jQuery.fn methods return a jQuery object, and not `true`, // which allows them to be chained and prevents polling). // force_mode - (Boolean) If true, execute that id's doTimeout callback // immediately and synchronously, continuing any callback return-true // polling loop. If false, execute the callback immediately and // synchronously but do NOT continue a callback return-true polling loop. // If omitted, cancel that id's doTimeout. // // Returns: // // When creating a <jQuery.fn.doTimeout>, the initial jQuery collection of // elements is returned. Otherwise, if force_mode is true, false or undefined // and there is a yet-to-be-executed callback to cancel, true is returned, // but if no callback remains to be executed, undefined is returned. $.fn[doTimeout] = function() { var args = aps.call( arguments ), result = p_doTimeout.apply( this, [ doTimeout + args[0] ].concat( args ) ); return typeof args[0] === 'number' || typeof args[1] === 'number' ? this : result; }; function p_doTimeout( jquery_data_key ) { var that = this, elem, data = {}, // Allows the plugin to call a string callback method. method_base = jquery_data_key ? $.fn : $, // Any additional arguments will be passed to the callback. args = arguments, slice_args = 4, id = args[1], delay = args[2], callback = args[3]; if ( typeof id !== 'string' ) { slice_args--; id = jquery_data_key = 0; delay = args[1]; callback = args[2]; } // If id is passed, store a data reference either as .data on the first // element in a jQuery collection, or in the internal cache. if ( jquery_data_key ) { // Note: key is 'doTimeout' + id // Get id-object from the first element's data, otherwise initialize it to {}. elem = that.eq(0); elem.data( jquery_data_key, data = elem.data( jquery_data_key ) || {} ); } else if ( id ) { // Get id-object from the cache, otherwise initialize it to {}. data = cache[ id ] || ( cache[ id ] = {} ); } // Clear any existing timeout for this id. data.id && clearTimeout( data.id ); delete data.id; // Clean up when necessary. function cleanup() { if ( jquery_data_key ) { elem.removeData( jquery_data_key ); } else if ( id ) { delete cache[ id ]; } }; // Yes, there actually is a setTimeout call in here! function actually_setTimeout() { data.id = setTimeout( function(){ data.fn(); }, delay ); }; if ( callback ) { // A callback (and delay) were specified. Store the callback reference for // possible later use, and then setTimeout. data.fn = function( no_polling_loop ) { // If the callback value is a string, it is assumed to be the name of a // method on $ or $.fn depending on where doTimeout was executed. if ( typeof callback === 'string' ) { callback = method_base[ callback ]; } callback.apply( that, aps.call( args, slice_args ) ) === true && !no_polling_loop // Since the callback returned true, and we're not specifically // canceling a polling loop, do it again! ? actually_setTimeout() // Otherwise, clean up and quit. : cleanup(); }; // Set that timeout! actually_setTimeout(); } else if ( data.fn ) { // No callback passed. If force_mode (delay) is true, execute the data.fn // callback immediately, continuing any callback return-true polling loop. // If force_mode is false, execute the data.fn callback immediately but do // NOT continue a callback return-true polling loop. If force_mode is // undefined, simply clean up. Since data.fn was still defined, whatever // was supposed to happen hadn't yet, so return true. delay === undefined ? cleanup() : data.fn( delay === false ); return true; } else { // Since no callback was passed, and data.fn isn't defined, it looks like // whatever was supposed to happen already did. Clean up and quit! cleanup(); } }; })(jQuery); }); // CodeMirror, copyright (c) by Marijn Haverbeke and others // Distributed under an MIT license: http://codemirror.net/LICENSE // This is CodeMirror (http://codemirror.net), a code editor // implemented in JavaScript on top of the browser's DOM. // // You can find some technical background for some of the code below // at http://marijnhaverbeke.nl/blog/#cm-internals . (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS module.exports = mod(); else if (typeof define == "function" && define.amd) // AMD return define('codemirror/lib/codemirror',[], mod); else // Plain browser env this.CodeMirror = mod(); })(function() { "use strict"; // BROWSER SNIFFING // Kludges for bugs and behavior differences that can't be feature // detected are enabled based on userAgent etc sniffing. var gecko = /gecko\/\d/i.test(navigator.userAgent); var ie_upto10 = /MSIE \d/.test(navigator.userAgent); var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent); var ie = ie_upto10 || ie_11up; var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]); var webkit = /WebKit\//.test(navigator.userAgent); var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent); var chrome = /Chrome\//.test(navigator.userAgent); var presto = /Opera\//.test(navigator.userAgent); var safari = /Apple Computer/.test(navigator.vendor); var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent); var phantom = /PhantomJS/.test(navigator.userAgent); var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent); // This is woefully incomplete. Suggestions for alternative methods welcome. var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent); var mac = ios || /Mac/.test(navigator.platform); var windows = /win/i.test(navigator.platform); var presto_version = presto && navigator.userAgent.match(/Version\/(\d*\.\d*)/); if (presto_version) presto_version = Number(presto_version[1]); if (presto_version && presto_version >= 15) { presto = false; webkit = true; } // Some browsers use the wrong event properties to signal cmd/ctrl on OS X var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)); var captureRightClick = gecko || (ie && ie_version >= 9); // Optimize some code when these features are not used. var sawReadOnlySpans = false, sawCollapsedSpans = false; // EDITOR CONSTRUCTOR // A CodeMirror instance represents an editor. This is the object // that user code is usually dealing with. function CodeMirror(place, options) { if (!(this instanceof CodeMirror)) return new CodeMirror(place, options); this.options = options = options ? copyObj(options) : {}; // Determine effective options based on given values and defaults. copyObj(defaults, options, false); setGuttersForLineNumbers(options); var doc = options.value; if (typeof doc == "string") doc = new Doc(doc, options.mode, null, options.lineSeparator); this.doc = doc; var input = new CodeMirror.inputStyles[options.inputStyle](this); var display = this.display = new Display(place, doc, input); display.wrapper.CodeMirror = this; updateGutters(this); themeChanged(this); if (options.lineWrapping) this.display.wrapper.className += " CodeMirror-wrap"; if (options.autofocus && !mobile) display.input.focus(); initScrollbars(this); this.state = { keyMaps: [], // stores maps added by addKeyMap overlays: [], // highlighting overlays, as added by addOverlay modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info overwrite: false, delayingBlurEvent: false, focused: false, suppressEdits: false, // used to disable editing during key handlers when in readOnly mode pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll draggingText: false, highlight: new Delayed(), // stores highlight worker timeout keySeq: null, // Unfinished key sequence specialChars: null }; var cm = this; // Override magic textarea content restore that IE sometimes does // on our hidden textarea on reload if (ie && ie_version < 11) setTimeout(function() { cm.display.input.reset(true); }, 20); registerEventHandlers(this); ensureGlobalHandlers(); startOperation(this); this.curOp.forceUpdate = true; attachDoc(this, doc); if ((options.autofocus && !mobile) || cm.hasFocus()) setTimeout(bind(onFocus, this), 20); else onBlur(this); for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt)) optionHandlers[opt](this, options[opt], Init); maybeUpdateLineNumberWidth(this); if (options.finishInit) options.finishInit(this); for (var i = 0; i < initHooks.length; ++i) initHooks[i](this); endOperation(this); // Suppress optimizelegibility in Webkit, since it breaks text // measuring on line wrapping boundaries. if (webkit && options.lineWrapping && getComputedStyle(display.lineDiv).textRendering == "optimizelegibility") display.lineDiv.style.textRendering = "auto"; } // DISPLAY CONSTRUCTOR // The display handles the DOM integration, both for input reading // and content drawing. It holds references to DOM nodes and // display-related state. function Display(place, doc, input) { var d = this; this.input = input; // Covers bottom-right square when both scrollbars are present. d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler"); d.scrollbarFiller.setAttribute("cm-not-content", "true"); // Covers bottom of gutter when coverGutterNextToScrollbar is on // and h scrollbar is present. d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler"); d.gutterFiller.setAttribute("cm-not-content", "true"); // Will contain the actual code, positioned to cover the viewport. d.lineDiv = elt("div", null, "CodeMirror-code"); // Elements are added to these to represent selection and cursors. d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1"); d.cursorDiv = elt("div", null, "CodeMirror-cursors"); // A visibility: hidden element used to find the size of things. d.measure = elt("div", null, "CodeMirror-measure"); // When lines outside of the viewport are measured, they are drawn in this. d.lineMeasure = elt("div", null, "CodeMirror-measure"); // Wraps everything that needs to exist inside the vertically-padded coordinate system d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], null, "position: relative; outline: none"); // Moved around its parent to cover visible view. d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative"); // Set to the height of the document, allowing scrolling. d.sizer = elt("div", [d.mover], "CodeMirror-sizer"); d.sizerWidth = null; // Behavior of elts with overflow: auto and padding is // inconsistent across browsers. This is used to ensure the // scrollable area is big enough. d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;"); // Will contain the gutters, if any. d.gutters = elt("div", null, "CodeMirror-gutters"); d.lineGutter = null; // Actual scrollable element. d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll"); d.scroller.setAttribute("tabIndex", "-1"); // The element in which the editor lives. d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; } if (!webkit && !(gecko && mobile)) d.scroller.draggable = true; if (place) { if (place.appendChild) place.appendChild(d.wrapper); else place(d.wrapper); } // Current rendered range (may be bigger than the view window). d.viewFrom = d.viewTo = doc.first; d.reportedViewFrom = d.reportedViewTo = doc.first; // Information about the rendered lines. d.view = []; d.renderedView = null; // Holds info about a single rendered line when it was rendered // for measurement, while not in view. d.externalMeasured = null; // Empty space (in pixels) above the view d.viewOffset = 0; d.lastWrapHeight = d.lastWrapWidth = 0; d.updateLineNumbers = null; d.nativeBarWidth = d.barHeight = d.barWidth = 0; d.scrollbarsClipped = false; // Used to only resize the line number gutter when necessary (when // the amount of lines crosses a boundary that makes its width change) d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null; // Set to true when a non-horizontal-scrolling line widget is // added. As an optimization, line widget aligning is skipped when // this is false. d.alignWidgets = false; d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; // Tracks the maximum line length so that the horizontal scrollbar // can be kept static when scrolling. d.maxLine = null; d.maxLineLength = 0; d.maxLineChanged = false; // Used for measuring wheel scrolling granularity d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null; // True when shift is held down. d.shift = false; // Used to track whether anything happened since the context menu // was opened. d.selForContextMenu = null; d.activeTouch = null; input.init(d); } // STATE UPDATES // Used to get the editor into a consistent state again when options change. function loadMode(cm) { cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption); resetModeState(cm); } function resetModeState(cm) { cm.doc.iter(function(line) { if (line.stateAfter) line.stateAfter = null; if (line.styles) line.styles = null; }); cm.doc.frontier = cm.doc.first; startWorker(cm, 100); cm.state.modeGen++; if (cm.curOp) regChange(cm); } function wrappingChanged(cm) { if (cm.options.lineWrapping) { addClass(cm.display.wrapper, "CodeMirror-wrap"); cm.display.sizer.style.minWidth = ""; cm.display.sizerWidth = null; } else { rmClass(cm.display.wrapper, "CodeMirror-wrap"); findMaxLine(cm); } estimateLineHeights(cm); regChange(cm); clearCaches(cm); setTimeout(function(){updateScrollbars(cm);}, 100); } // Returns a function that estimates the height of a line, to use as // first approximation until the line becomes visible (and is thus // properly measurable). function estimateHeight(cm) { var th = textHeight(cm.display), wrapping = cm.options.lineWrapping; var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3); return function(line) { if (lineIsHidden(cm.doc, line)) return 0; var widgetsHeight = 0; if (line.widgets) for (var i = 0; i < line.widgets.length; i++) { if (line.widgets[i].height) widgetsHeight += line.widgets[i].height; } if (wrapping) return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th; else return widgetsHeight + th; }; } function estimateLineHeights(cm) { var doc = cm.doc, est = estimateHeight(cm); doc.iter(function(line) { var estHeight = est(line); if (estHeight != line.height) updateLineHeight(line, estHeight); }); } function themeChanged(cm) { cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-"); clearCaches(cm); } function guttersChanged(cm) { updateGutters(cm); regChange(cm); setTimeout(function(){alignHorizontally(cm);}, 20); } // Rebuild the gutter elements, ensure the margin to the left of the // code matches their width. function updateGutters(cm) { var gutters = cm.display.gutters, specs = cm.options.gutters; removeChildren(gutters); for (var i = 0; i < specs.length; ++i) { var gutterClass = specs[i]; var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass)); if (gutterClass == "CodeMirror-linenumbers") { cm.display.lineGutter = gElt; gElt.style.width = (cm.display.lineNumWidth || 1) + "px"; } } gutters.style.display = i ? "" : "none"; updateGutterSpace(cm); } function updateGutterSpace(cm) { var width = cm.display.gutters.offsetWidth; cm.display.sizer.style.marginLeft = width + "px"; } // Compute the character length of a line, taking into account // collapsed ranges (see markText) that might hide parts, and join // other lines onto it. function lineLength(line) { if (line.height == 0) return 0; var len = line.text.length, merged, cur = line; while (merged = collapsedSpanAtStart(cur)) { var found = merged.find(0, true); cur = found.from.line; len += found.from.ch - found.to.ch; } cur = line; while (merged = collapsedSpanAtEnd(cur)) { var found = merged.find(0, true); len -= cur.text.length - found.from.ch; cur = found.to.line; len += cur.text.length - found.to.ch; } return len; } // Find the longest line in the document. function findMaxLine(cm) { var d = cm.display, doc = cm.doc; d.maxLine = getLine(doc, doc.first); d.maxLineLength = lineLength(d.maxLine); d.maxLineChanged = true; doc.iter(function(line) { var len = lineLength(line); if (len > d.maxLineLength) { d.maxLineLength = len; d.maxLine = line; } }); } // Make sure the gutters options contains the element // "CodeMirror-linenumbers" when the lineNumbers option is true. function setGuttersForLineNumbers(options) { var found = indexOf(options.gutters, "CodeMirror-linenumbers"); if (found == -1 && options.lineNumbers) { options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]); } else if (found > -1 && !options.lineNumbers) { options.gutters = options.gutters.slice(0); options.gutters.splice(found, 1); } } // SCROLLBARS // Prepare DOM reads