Path: blob/main/public/games/files/algaes-escapade/js/gamejs/yabble.js
1036 views
/*1* Copyright (c) 2010 James Brantly2*3* Permission is hereby granted, free of charge, to any person4* obtaining a copy of this software and associated documentation5* files (the "Software"), to deal in the Software without6* restriction, including without limitation the rights to use,7* copy, modify, merge, publish, distribute, sublicense, and/or sell8* copies of the Software, and to permit persons to whom the9* Software is furnished to do so, subject to the following10* conditions:11*12* The above copyright notice and this permission notice shall be13* included in all copies or substantial portions of the Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,16* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES17* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND18* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT19* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,20* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING21* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR22* OTHER DEALINGS IN THE SOFTWARE.23*/2425(function(globalEval) {2627var Yabble = function() {28throw "Synchronous require() is not supported.";29};3031Yabble.unit = {};3233var _moduleRoot = '',34_modules,35_callbacks,36_fetchFunc,37_timeoutLength = 20000,38_mainProgram;394041var head = document.getElementsByTagName('head')[0];4243// Shortcut to native hasOwnProperty44var hasOwnProperty = Object.prototype.hasOwnProperty;4546// A for..in implementation which uses hasOwnProperty and fixes IE non-enumerable issues47if ((function() {for (var prop in {hasOwnProperty: true}) { return prop; }})() == 'hasOwnProperty') {48var forIn = function(obj, func, ctx) {49for (var prop in obj) {50if (hasOwnProperty.call(obj, prop)) {51func.call(ctx, prop);52}53}54};55}56else {57var ieBadProps = [58'isPrototypeOf',59'hasOwnProperty',60'toLocaleString',61'toString',62'valueOf'63];6465var forIn = function(obj, func, ctx) {66for (var prop in obj) {67if (hasOwnProperty.call(obj, prop)) {68func.call(ctx, prop);69}70}7172for (var i = ieBadProps.length; i--;) {73var prop = ieBadProps[i];74if (hasOwnProperty.call(obj, prop)) {75func.call(ctx, prop);76}77}78};79}8081// Array convenience functions82var indexOf = function(arr, val) {83for (var i = arr.length; i--;) {84if (arr[i] == val) { return i; }85}86return -1;87};8889var removeWhere = function(arr, func) {90var i = 0;91while (i < arr.length) {92if (func.call(null, arr[i], i) === true) {93arr.splice(i, 1);94}95else {96i++;97}98}99};100101var combinePaths = function(relPath, refPath) {102var relPathParts = relPath.split('/');103refPath = refPath || '';104if (refPath.length && refPath.charAt(refPath.length-1) != '/') {105refPath += '/';106}107var refPathParts = refPath.split('/');108refPathParts.pop();109var part;110while (part = relPathParts.shift()) {111if (part == '.') { continue; }112else if (part == '..'113&& refPathParts.length114&& refPathParts[refPathParts.length-1] != '..') { refPathParts.pop(); }115else { refPathParts.push(part); }116}117return refPathParts.join('/');118};119120// Takes a relative path to a module and resolves it according to the reference path121var resolveModuleId = Yabble.unit.resolveModuleId = function(relModuleId, refPath) {122if (relModuleId.charAt(0) != '.') {123return relModuleId;124}125else {126return combinePaths(relModuleId, refPath);127}128};129130// Takes a module's ID and resolves a URI according to the module root path131var resolveModuleUri = function(moduleId) {132if (moduleId.charAt(0) != '.') {133return _moduleRoot+moduleId+'.js';134}135else {136return this._resolveModuleId(moduleId, _moduleRoot)+'.js';137}138};139140// Returns a module object from the module ID141var getModule = function(moduleId) {142if (!hasOwnProperty.call(_modules, moduleId)) {143return null;144}145return _modules[moduleId];146};147148// Adds a callback which is executed when all deep dependencies are loaded149var addCallback = function(deps, cb) {150_callbacks.push([deps.slice(0), cb]);151};152153// Generic implementation of require.ensure() which takes a reference path to154// use when resolving relative module IDs155var ensureImpl = function(deps, cb, refPath) {156var unreadyModules = [];157158for (var i = deps.length; i--;) {159var moduleId = resolveModuleId(deps[i], refPath),160module = getModule(moduleId);161162if (!areDeepDepsDefined(moduleId)) {163unreadyModules.push(moduleId);164}165}166167if (unreadyModules.length) {168addCallback(unreadyModules, function() {169cb(createRequireFunc(refPath));170});171queueModules(unreadyModules);172}173else {174setTimeout(function() {175cb(createRequireFunc(refPath));176}, 0);177}178};179180// Creates a require function that is passed into module factory functions181// and require.ensure() callbacks. It is bound to a reference path for182// relative require()s183var createRequireFunc = function(refPath) {184var require = function(relModuleId) {185var moduleId = resolveModuleId(relModuleId, refPath),186module = getModule(moduleId);187188if (!module) {189throw "Module not loaded";190}191else if (module.error) {192throw "Error loading module";193}194195if (!module.exports) {196module.exports = {};197var moduleDir = moduleId.substring(0, moduleId.lastIndexOf('/')+1),198injects = module.injects,199args = [];200201for (var i = 0, n = injects.length; i<n; i++) {202if (injects[i] == 'require') {203args.push(createRequireFunc(moduleDir));204}205else if (injects[i] == 'exports') {206args.push(module.exports);207}208else if (injects[i] == 'module') {209args.push(module.module);210}211}212213module.factory.apply(null, args);214}215return module.exports;216};217218require.ensure = function(deps, cb) {219ensureImpl(deps, cb, refPath);220};221222if (_mainProgram != null) {223require.main = getModule(_mainProgram).module;224}225226return require;227};228229// Begins loading modules asynchronously230var queueModules = function(moduleIds) {231for (var i = moduleIds.length; i--;) {232var moduleId = moduleIds[i],233module = getModule(moduleId);234235if (module == null) {236module = _modules[moduleId] = {};237_fetchFunc(moduleId);238}239}240};241242// Returns true if all deep dependencies are satisfied (in other words,243// can more or less safely run the module factory function)244var areDeepDepsDefined = function(moduleId) {245var visitedModules = {};246var recurse = function(moduleId) {247if (visitedModules[moduleId] == true) { return true; }248visitedModules[moduleId] = true;249var module = getModule(moduleId);250if (!module || !module.defined) { return false; }251else {252var deps = module.deps || [];253for (var i = deps.length; i--;) {254if (!recurse(deps[i])) {255return false;256}257}258return true;259}260};261return recurse(moduleId);262};263264// Checks dependency callbacks and fires as necessary265var fireCallbacks = function() {266var i = 0;267while (i<_callbacks.length) {268var deps = _callbacks[i][0],269func = _callbacks[i][1],270n = 0;271while (n<deps.length) {272if (areDeepDepsDefined(deps[n])) {273deps.splice(n, 1);274}275else {276n++;277}278}279if (!deps.length) {280_callbacks.splice(i, 1);281if (func != null) {282setTimeout(func, 0);283}284}285else {286i++;287}288}289};290291// Load an unwrapped module using XHR and eval()292var loadModuleByEval = _fetchFunc = function(moduleId) {293var timeoutHandle;294295var errorFunc = function() {296var module = getModule(moduleId);297if (!module.defined) {298module.defined = module.error = true;299fireCallbacks();300}301};302303var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');304var moduleUri = resolveModuleUri(moduleId);305xhr.open('GET', moduleUri, true);306xhr.onreadystatechange = function() {307if (xhr.readyState === 4) {308clearTimeout(timeoutHandle);309if (xhr.status == 200 || xhr.status === 0) {310var moduleCode = xhr.responseText,311deps = determineShallowDependencies(moduleCode),312moduleDir = moduleId.substring(0, moduleId.lastIndexOf('/')+1),313moduleDefs = {};314for (var i = deps.length; i--;) {315deps[i] = resolveModuleId(deps[i], moduleDir);316}317try {318moduleDefs[moduleId] = globalEval('({fn: function(require, exports, module) {\r\n' + moduleCode + '\r\n}})').fn;319} catch (e) {320if (e instanceof SyntaxError) {321var msg = 'Syntax Error: ';322if (e.lineNumber) {323msg += 'line ' + (e.lineNumber - 581);324} else {325console.log('GameJs tip: use Firefox to see line numbers in Syntax Errors.');326}327msg += ' in file ' + moduleUri;328console.log(msg);329}330throw e;331}332333Yabble.define(moduleDefs, deps);334}335else {336errorFunc();337}338}339};340341timeoutHandle = setTimeout(errorFunc, _timeoutLength);342343xhr.send(null);344};345346// Used by loadModuleByEval and by the packager. Determines shallow dependencies of347// a module via static analysis. This can currently break with require.ensure().348var determineShallowDependencies = Yabble.unit.determineShallowDependencies = function(moduleCode) {349// TODO: account for comments350var deps = {}, match, unique = {};351352var requireRegex = /(?:^|[^\w\$_.])require\s*\(\s*("[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*')\s*\)/g;353while (match = requireRegex.exec(moduleCode)) {354var module = eval(match[1]);355if (!hasOwnProperty.call(deps, module)) {356deps[module] = true;357}358}359360var ensureRegex = /(?:^|[^\w\$_.])require.ensure\s*\(\s*(\[("[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*'|\s*|,)*\])/g;361while (match = ensureRegex.exec(moduleCode)) {362var moduleArray = eval(match[1]);363for (var i = moduleArray.length; i--;) {364var module = moduleArray[i];365delete deps[module];366}367}368369var depsArray = [];370forIn(deps, function(module) {371depsArray.push(module);372});373374return depsArray;375};376377// Load a wrapped module via script tags378var loadModuleByScript = function(moduleId) {379var scriptEl = document.createElement('script');380scriptEl.type = 'text/javascript';381scriptEl.src = resolveModuleUri(moduleId);382383var useStandard = !!scriptEl.addEventListener,384timeoutHandle;385386var errorFunc = function() {387postLoadFunc(false);388};389390var loadFunc = function() {391if (useStandard || (scriptEl.readyState == 'complete' || scriptEl.readyState == 'loaded')) {392postLoadFunc(getModule(moduleId).defined);393}394};395396var postLoadFunc = function(loaded) {397clearTimeout(timeoutHandle);398399if (useStandard) {400scriptEl.removeEventListener('load', loadFunc, false);401scriptEl.removeEventListener('error', errorFunc, false);402}403else {404scriptEl.detachEvent('onreadystatechange', loadFunc);405}406407if (!loaded) {408var module = getModule(moduleId);409if (!module.defined) {410module.defined = module.error = true;411fireCallbacks();412}413}414};415416if (useStandard) {417scriptEl.addEventListener('load', loadFunc, false);418scriptEl.addEventListener('error', errorFunc, false);419}420else {421scriptEl.attachEvent('onreadystatechange', loadFunc);422}423424timeoutHandle = setTimeout(errorFunc, _timeoutLength);425426head.appendChild(scriptEl);427};428429var normalizeTransport = function() {430var transport = {modules: []};431var standardInjects = ['require', 'exports', 'module'];432if (typeof arguments[0] == 'object') { // Transport/D433transport.deps = arguments[1] || [];434var moduleDefs = arguments[0];435forIn(moduleDefs, function(moduleId) {436var module = {437id: moduleId438};439440if (typeof moduleDefs[moduleId] == 'function') {441module.factory = moduleDefs[moduleId];442module.injects = standardInjects;443}444else {445module.factory = moduleDefs[moduleId].factory;446module.injects = moduleDefs[moduleId].injects || standardInjects;447}448transport.modules.push(module);449});450}451else { // Transport/C452transport.deps = arguments[1].slice(0);453removeWhere(transport.deps, function(dep) {454return indexOf(standardInjects, dep) >= 0;455});456457transport.modules.push({458id: arguments[0],459factory: arguments[2],460injects: arguments[1]461});462}463return transport;464};465466// Set the uri which forms the conceptual module namespace root467Yabble.setModuleRoot = function(path) {468if (!(/^http(s?):\/\//.test(path))) {469var href = window.location.href;470href = href.substr(0, href.lastIndexOf('/')+1);471path = combinePaths(path, href);472}473474if (path.length && path.charAt(path.length-1) != '/') {475path += '/';476}477478_moduleRoot = path;479};480481// Set a timeout period for async module loading482Yabble.setTimeoutLength = function(milliseconds) {483_timeoutLength = milliseconds;484};485486// Use script tags with wrapped code instead of XHR+eval()487Yabble.useScriptTags = function() {488_fetchFunc = loadModuleByScript;489};490491// Define a module per various transport specifications492Yabble.def = Yabble.define = function() {493var transport = normalizeTransport.apply(null, arguments);494495var unreadyModules = [],496definedModules = [];497498var deps = transport.deps;499500for (var i = transport.modules.length; i--;) {501var moduleDef = transport.modules[i],502moduleId = moduleDef.id,503module = getModule(moduleId);504505if (!module) {506module = _modules[moduleId] = {};507}508module.module = {509id: moduleId,510uri: resolveModuleUri(moduleId)511};512513module.defined = true;514module.deps = deps.slice(0);515module.injects = moduleDef.injects;516module.factory = moduleDef.factory;517definedModules.push(module);518}519520for (var i = deps.length; i--;) {521var moduleId = deps[i],522module = getModule(moduleId);523524if (!module || !areDeepDepsDefined(moduleId)) {525unreadyModules.push(moduleId);526}527}528529if (unreadyModules.length) {530setTimeout(function() {531queueModules(unreadyModules);532}, 0);533}534535fireCallbacks();536};537538Yabble.isKnown = function(moduleId) {539return getModule(moduleId) != null;540};541542Yabble.isDefined = function(moduleId) {543var module = getModule(moduleId);544return !!(module && module.defined);545};546547// Do an async lazy-load of modules548Yabble.ensure = function(deps, cb) {549ensureImpl(deps, cb, '');550};551552// Start an application via a main program module553Yabble.run = function(program, cb) {554program = _mainProgram = resolveModuleId(program, '');555Yabble.ensure([program], function(require) {556require(program);557if (cb != null) { cb(); }558});559};560561// Reset internal state. Used mostly for unit tests.562Yabble.reset = function() {563_mainProgram = null;564_modules = {};565_callbacks = [];566567// Built-in system module568Yabble.define({569'system': function(require, exports, module) {}570});571};572573Yabble.reset();574575// Export to the require global576window.require = Yabble;577})(function(code) {578with (window) {579return eval(code);580};581});582583