From 91b42b43d3675fea0ce7a952b0a766a2e96bb052 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 10 Mar 2013 17:25:07 +0400 Subject: [PATCH] update require.js and fix toUrl call --- demo/kitchen-sink/require.js | 170 +++++++++++++++++++------------- lib/ace/worker/worker_client.js | 4 +- 2 files changed, 106 insertions(+), 68 deletions(-) diff --git a/demo/kitchen-sink/require.js b/demo/kitchen-sink/require.js index 39dbad8e..062516ac 100644 --- a/demo/kitchen-sink/require.js +++ b/demo/kitchen-sink/require.js @@ -1,18 +1,18 @@ /** vim: et:ts=4:sw=4:sts=4 - * @license RequireJS 2.1.1 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. + * @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, jQuery, setTimeout, opera */ +/*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.1', + version = '2.1.5', commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, jsSuffixRegExp = /\.js$/, @@ -21,7 +21,6 @@ var requirejs, require, define; ostring = op.toString, hasOwn = op.hasOwnProperty, ap = Array.prototype, - aps = ap.slice, apsp = ap.splice, isBrowser = !!(typeof window !== 'undefined' && navigator && document), isWebWorker = !isBrowser && typeof importScripts !== 'undefined', @@ -81,6 +80,10 @@ var requirejs, require, define; 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 @@ -89,7 +92,7 @@ var requirejs, require, define; function eachProp(obj, func) { var prop; for (prop in obj) { - if (obj.hasOwnProperty(prop)) { + if (hasProp(obj, prop)) { if (func(obj[prop], prop)) { break; } @@ -188,15 +191,21 @@ var requirejs, require, define; 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: {}, - map: {}, 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 = {}, @@ -261,7 +270,7 @@ var requirejs, require, define; //otherwise, assume it is a top-level require that will //be relative to baseUrl in the end. if (baseName) { - if (config.pkgs[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]; @@ -279,7 +288,7 @@ var requirejs, require, define; //Some use of packages may use a . path to reference the //'main' module name, so normalize for that. - pkgConfig = config.pkgs[(pkgName = name[0])]; + pkgConfig = getOwn(config.pkgs, (pkgName = name[0])); name = name.join('/'); if (pkgConfig && name === pkgName + '/' + pkgConfig.main) { name = pkgName; @@ -292,7 +301,7 @@ var requirejs, require, define; } //Apply map config if available. - if (applyMap && (baseParts || starMap) && map) { + if (applyMap && map && (baseParts || starMap)) { nameParts = name.split('/'); for (i = nameParts.length; i > 0; i -= 1) { @@ -302,12 +311,12 @@ var requirejs, require, define; //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('/')]; + mapValue = getOwn(map, baseParts.slice(0, j).join('/')); //baseName segment has config, find if it has one for //this name. if (mapValue) { - mapValue = mapValue[nameSegment]; + mapValue = getOwn(mapValue, nameSegment); if (mapValue) { //Match, update name to the new value. foundMap = mapValue; @@ -325,8 +334,8 @@ var requirejs, require, define; //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]; + if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { + foundStarMap = getOwn(starMap, nameSegment); starI = i; } } @@ -358,7 +367,7 @@ var requirejs, require, define; } function hasPathFallback(id) { - var pathConfig = config.paths[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 @@ -419,7 +428,7 @@ var requirejs, require, define; if (prefix) { prefix = normalize(prefix, parentName, applyMap); - pluginModule = defined[prefix]; + pluginModule = getOwn(defined, prefix); } //Account for relative paths if there is a base name. @@ -472,7 +481,7 @@ var requirejs, require, define; function getModule(depMap) { var id = depMap.id, - mod = registry[id]; + mod = getOwn(registry, id); if (!mod) { mod = registry[id] = new context.Module(depMap); @@ -483,7 +492,7 @@ var requirejs, require, define; function on(depMap, name, fn) { var id = depMap.id, - mod = registry[id]; + mod = getOwn(registry, id); if (hasProp(defined, id) && (!mod || mod.defineEmitComplete)) { @@ -503,7 +512,7 @@ var requirejs, require, define; errback(err); } else { each(ids, function (id) { - var mod = registry[id]; + var mod = getOwn(registry, id); if (mod) { //Set error on module, so it skips timeout checks. mod.error = err; @@ -562,7 +571,7 @@ var requirejs, require, define; id: mod.map.id, uri: mod.map.url, config: function () { - return (config.config && config.config[mod.map.id]) || {}; + return (config.config && getOwn(config.config, mod.map.id)) || {}; }, exports: defined[mod.map.id] }); @@ -573,6 +582,7 @@ var requirejs, require, define; function cleanRegistry(id) { //Clean up machinery used for waiting modules. delete registry[id]; + delete enabledRegistry[id]; } function breakCycle(mod, traced, processed) { @@ -584,14 +594,14 @@ var requirejs, require, define; traced[id] = true; each(mod.depMaps, function (depMap, i) { var depId = depMap.id, - dep = registry[depId]; + 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 (traced[depId]) { + if (getOwn(traced, depId)) { mod.defineDep(i, defined[depId]); mod.check(); //pass false? } else { @@ -621,7 +631,7 @@ var requirejs, require, define; inCheckLoaded = true; //Figure out the state of all the modules. - eachProp(registry, function (mod) { + eachProp(enabledRegistry, function (mod) { map = mod.map; modId = map.id; @@ -691,9 +701,9 @@ var requirejs, require, define; } Module = function (map) { - this.events = undefEvents[map.id] || {}; + this.events = getOwn(undefEvents, map.id) || {}; this.map = map; - this.shim = config.shim[map.id]; + this.shim = getOwn(config.shim, map.id); this.depExports = []; this.depMaps = []; this.depMatched = []; @@ -802,7 +812,7 @@ var requirejs, require, define; }, /** - * Checks is the module is ready to define itself, and if so, + * Checks if the module is ready to define itself, and if so, * define it. */ check: function () { @@ -880,7 +890,7 @@ var requirejs, require, define; } //Clean up - delete registry[id]; + cleanRegistry(id); this.defined = true; } @@ -914,8 +924,7 @@ var requirejs, require, define; name = this.map.name, parentName = this.map.parentMap ? this.map.parentMap.name : null, localRequire = context.makeRequire(map.parentMap, { - enableBuildCallback: true, - skipMap: true + enableBuildCallback: true }); //If current map is not normalized, wait for that @@ -940,7 +949,7 @@ var requirejs, require, define; }); })); - normalizedMod = registry[normalizedMap.id]; + normalizedMod = getOwn(registry, normalizedMap.id); if (normalizedMod) { //Mark this as a dependency for this plugin, so it //can be traced for cycles. @@ -1005,11 +1014,19 @@ var requirejs, require, define; //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) { - throw new Error('fromText eval for ' + moduleName + - ' failed: ' + e); + return onError(makeError('fromtexteval', + 'fromText eval for ' + id + + ' failed: ' + e, + e, + [id])); } if (hasInteractive) { @@ -1039,6 +1056,7 @@ var requirejs, require, define; }, enable: function () { + enabledRegistry[this.map.id] = this; this.enabled = true; //Set flag mentioning that the module is enabling, @@ -1060,7 +1078,7 @@ var requirejs, require, define; !this.skipMap); this.depMaps[i] = depMap; - handler = handlers[depMap.id]; + handler = getOwn(handlers, depMap.id); if (handler) { this.depExports[i] = handler(this); @@ -1085,7 +1103,7 @@ var requirejs, require, define; //Skip special modules like 'require', 'exports', 'module' //Also, don't call enable if it is already enabled, //important in circular dependency cases. - if (!handlers[id] && mod && !mod.enabled) { + if (!hasProp(handlers, id) && mod && !mod.enabled) { context.enable(depMap, this); } })); @@ -1093,7 +1111,7 @@ var requirejs, require, define; //Enable each plugin that is used in //a dependency eachProp(this.pluginMaps, bind(this, function (pluginMap) { - var mod = registry[pluginMap.id]; + var mod = getOwn(registry, pluginMap.id); if (mod && !mod.enabled) { context.enable(pluginMap, this); } @@ -1126,7 +1144,10 @@ var requirejs, require, define; }; function callGetModule(args) { - getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]); + //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) { @@ -1195,6 +1216,7 @@ var requirejs, require, define; Module: Module, makeModuleMap: makeModuleMap, nextTick: req.nextTick, + onError: onError, /** * Set a configuration for the context. @@ -1221,6 +1243,9 @@ var requirejs, require, define; 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); @@ -1239,7 +1264,7 @@ var requirejs, require, define; deps: value }; } - if (value.exports && !value.exportsFn) { + if ((value.exports || value.init) && !value.exportsFn) { value.exportsFn = context.makeShimExports(value); } shim[id] = value; @@ -1301,7 +1326,7 @@ var requirejs, require, define; if (value.init) { ret = value.init.apply(global, arguments); } - return ret || getGlobal(value.exports); + return ret || (value.exports && getGlobal(value.exports)); } return fn; }, @@ -1325,14 +1350,14 @@ var requirejs, require, define; //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 && handlers[deps]) { + 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); + return req.get(context, deps, relMap, localRequire); } //Normalize module name, if it contains . or .. @@ -1383,16 +1408,20 @@ var requirejs, require, define; * plain URLs like nameToUrl. */ toUrl: function (moduleNamePlusExt) { - var index = moduleNamePlusExt.lastIndexOf('.'), - ext = null; + var ext, + index = moduleNamePlusExt.lastIndexOf('.'), + segment = moduleNamePlusExt.split('/')[0], + isRelative = segment === '.' || segment === '..'; - if (index !== -1) { + //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); + relMap && relMap.id, true), ext, true); }, defined: function (id) { @@ -1413,7 +1442,7 @@ var requirejs, require, define; takeGlobalQueue(); var map = makeModuleMap(id, relMap, true), - mod = registry[id]; + mod = getOwn(registry, id); delete defined[id]; delete urlFetched[map.url]; @@ -1437,11 +1466,12 @@ var requirejs, require, define; /** * Called to enable a module if it is still in the registry - * awaiting enablement. parent module is passed in for context, - * used by the optimizer. + * 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, parent) { - var mod = registry[depMap.id]; + enable: function (depMap) { + var mod = getOwn(registry, depMap.id); if (mod) { getModule(depMap).enable(); } @@ -1455,7 +1485,7 @@ var requirejs, require, define; */ completeLoad: function (moduleName) { var found, args, mod, - shim = config.shim[moduleName] || {}, + shim = getOwn(config.shim, moduleName) || {}, shExports = shim.exports; takeGlobalQueue(); @@ -1481,9 +1511,9 @@ var requirejs, require, define; //Do this after the cycle of callGetModule in case the result //of those calls/init calls changes the registry. - mod = registry[moduleName]; + mod = getOwn(registry, moduleName); - if (!found && !defined[moduleName] && mod && !mod.inited) { + if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { if (hasPathFallback(moduleName)) { return; @@ -1510,7 +1540,7 @@ var requirejs, require, define; * 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) { + nameToUrl: function (moduleName, ext, skipExt) { var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url, parentPath; @@ -1534,8 +1564,8 @@ var requirejs, require, define; //and work up from it. for (i = syms.length; i > 0; i -= 1) { parentModule = syms.slice(0, i).join('/'); - pkg = pkgs[parentModule]; - parentPath = paths[parentModule]; + 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 @@ -1559,7 +1589,7 @@ var requirejs, require, define; //Join the path parts together, then figure out if baseUrl is needed. url = syms.join('/'); - url += (ext || (/\?/.test(url) ? '' : '.js')); + url += (ext || (/\?/.test(url) || skipExt ? '' : '.js')); url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; } @@ -1660,7 +1690,7 @@ var requirejs, require, define; contextName = config.context; } - context = contexts[contextName]; + context = getOwn(contexts, contextName); if (!context) { context = contexts[contextName] = req.s.newContext(contextName); } @@ -1798,7 +1828,7 @@ var requirejs, require, define; 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 addEvenListener + //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, @@ -1827,16 +1857,24 @@ var requirejs, require, define; return node; } else if (isWebWorker) { - //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); + 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); + //Account for anonymous modules + context.completeLoad(moduleName); + } catch (e) { + context.onError(makeError('importscripts', + 'importScripts failed for ' + + moduleName + ' at ' + url, + e, + [moduleName])); + } } }; diff --git a/lib/ace/worker/worker_client.js b/lib/ace/worker/worker_client.js index ddd27050..81d83bf3 100644 --- a/lib/ace/worker/worker_client.js +++ b/lib/ace/worker/worker_client.js @@ -53,12 +53,12 @@ var WorkerClient = function(topLevelNamespaces, mod, classname) { // nameToUrl is renamed to toUrl in requirejs 2 if (require.nameToUrl && !require.toUrl) require.toUrl = require.nameToUrl; - workerUrl = normalizePath(require.toUrl("ace/worker/worker", null, "_")); + workerUrl = normalizePath(require.toUrl("ace/worker/worker.js", null, "_")); } var tlns = {}; topLevelNamespaces.forEach(function(ns) { - tlns[ns] = normalizePath(require.toUrl(ns, null, "_").replace(/.js(\?.*)?$/, "")); + tlns[ns] = normalizePath(require.toUrl(ns, null, "_").replace(/(\.js)?(\?.*)?$/, "")); }); }