Skip to content

Commit a1f8071

Browse files
Fixed patch mechanism
1 parent f8f9ace commit a1f8071

File tree

3 files changed

+73
-99
lines changed

3 files changed

+73
-99
lines changed

build/requirejs-sandbox.js

Lines changed: 69 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* requirejs-sandbox - v0.4.2-72 (build date: 18/06/2014)
2+
* requirejs-sandbox - v0.4.2-89 (build date: 18/06/2014)
33
* https://github.com/a-ignatov-parc/requirejs-sandbox
44
* Sandbox manager for require.js allows user to run multiple apps without scope intersection issues
55
* Copyright (c) 2014 Anton Ignatov
@@ -742,7 +742,32 @@ define('requirejs-sandbox',['requirejs-sandbox/logger/logger','requirejs-sandbox
742742

743743
createLoader: function(target) {
744744
var loadHandler = function(script, sandbox) {
745-
var patchList = this.options.patch;
745+
var patchList = this.options.patch,
746+
patchModule = function(module, patch) {
747+
patch.enable(window, sandbox, module);
748+
console.debug('Patch for module "' + patch.name + '" applied correctly');
749+
},
750+
success = utils.bind(function() {
751+
console.debug('Executing module callback');
752+
753+
// Если в модуль был передана функция-обработчик, то вызываем ее, передавая в
754+
// качестве аргументов ссылку на функцию `require` их песочницы.
755+
this.options.success.call(this.api, this.api.require, this.api.define);
756+
}, this),
757+
resolvePatch = function(patch) {
758+
for (var i = 0, length = patchList.length; i < length; i++) {
759+
if (typeof(patchList[i]) === 'string' && patch.name === patchList[i]) {
760+
patchList[i] = patch;
761+
console.debug('Patch "' + patch.name + '" is resolved.');
762+
break;
763+
}
764+
}
765+
766+
if (!--unresolvedPatchesCount) {
767+
success();
768+
}
769+
},
770+
unresolvedPatchesCount = 0;
746771

747772
// Создаем ссылку на `require.js` в api песочницы для дальнейшей работы с ним
748773
this.api.require = this.sandbox.sandboxApi.require = sandbox.require;
@@ -767,95 +792,6 @@ define('requirejs-sandbox',['requirejs-sandbox/logger/logger','requirejs-sandbox
767792
return;
768793
}
769794

770-
console.debug('require.js has loaded! Patching "load" method...');
771-
772-
// Переопределяем загрузчик чтоб можно было легко применять патчи.
773-
this.api.require.load = (function(load) {
774-
return function(context) {
775-
if (!context.completeLoad.isOverided) {
776-
context.completeLoad = (function(completeLoad) {
777-
return function(moduleName) {
778-
var fnContext = this,
779-
fnArgs = arguments,
780-
patchIsResolved,
781-
patchName,
782-
registry,
783-
module,
784-
patchModule = function(module, patch) {
785-
patch.enable(window, sandbox, module);
786-
console.debug('Patch for module "' + moduleName + '" applied correctly');
787-
},
788-
applyPatch = function(patch) {
789-
console.debug('Found patch for loaded module: "' + moduleName + '"! Applying...');
790-
791-
// Если патч для данного модуля существует, то инициализируем его.
792-
if (patch) {
793-
try {
794-
registry = fnContext.registry[moduleName];
795-
module = registry && registry.shim && registry.shim.exportsFn() || sandbox[patch.shimName];
796-
797-
if (module == null) {
798-
if (registry && registry.events.defined && typeof(registry.events.defined.push) === 'function') {
799-
registry.events.defined.push(function(module) {
800-
patchModule(module, patch);
801-
});
802-
803-
// Резолвим загрузку модуля.
804-
completeLoad.apply(fnContext, fnArgs);
805-
} else {
806-
throw 'Module registry does not have defined event';
807-
}
808-
} else {
809-
patchModule(module, patch);
810-
811-
// Резолвим загрузку модуля.
812-
completeLoad.apply(fnContext, fnArgs);
813-
}
814-
} catch(e) {
815-
console.debug('Patch for module "' + moduleName + '" did not applied correctly! Look into debug info for more details');
816-
console.error(moduleName, e);
817-
}
818-
}
819-
};
820-
821-
// Проверяем имя модуля и делаем его патч если необходимо.
822-
for (var i = 0, length = patchList.length; i < length; i++) {
823-
if (typeof(patchList[i]) === 'string') {
824-
patchName = patchList[i];
825-
patchIsResolved = false;
826-
} else if (typeof(patchList[i]) === 'object' && typeof(patchList[i].enable) === 'function') {
827-
patchName = patchList[i].name;
828-
patchIsResolved = true;
829-
} else {
830-
patchName = false;
831-
patchIsResolved = false;
832-
}
833-
834-
if (patchName == moduleName) {
835-
if (patchIsResolved) {
836-
applyPatch(patchList[i]);
837-
} else {
838-
window.require([['requirejs-sandbox', 'patches', moduleName].join('/')], applyPatch);
839-
}
840-
return;
841-
}
842-
}
843-
return completeLoad.apply(fnContext, fnArgs);
844-
};
845-
})(context.completeLoad);
846-
847-
// Высталяем флаг о том что мы переопределили хендлер и делать это
848-
// повторно не нужно.
849-
context.completeLoad.isOverided = true;
850-
}
851-
852-
// Запускаем загрузку модулей.
853-
load.apply(this, arguments);
854-
};
855-
})(this.api.require.load);
856-
857-
console.debug('require.js "load" method has been patched! Configuring...');
858-
859795
// Конфигурируем загрузчик на основе переданных параметров.
860796
this.api.require.config(this.options.requireConfig);
861797

@@ -891,11 +827,49 @@ define('requirejs-sandbox',['requirejs-sandbox/logger/logger','requirejs-sandbox
891827
return sandbox;
892828
});
893829

894-
console.debug('Executing module callback');
830+
console.debug('Creating handler for amd modules load');
831+
832+
// Для того чтоб пропатчить модули до того как они будут зарезолвлены
833+
// пользователю создаем обработчик который будет отлавливать момент
834+
// загрузки + резолвинга и отслеживать нужные модули.
835+
this.api.require.onResourceLoad = function(context, map) {
836+
var module = context.defined[map.id],
837+
moduleName = map.name,
838+
patch;
839+
840+
// Проверяем имя модуля и делаем его патч если необходимо.
841+
for (var i = 0, length = patchList.length; i < length; i++) {
842+
patch = patchList[i];
895843

896-
// Если в модуль был передана функция-обработчик, то вызываем ее, передавая в
897-
// качестве аргументов ссылку на функцию `require` их песочницы.
898-
this.options.success.call(this.api, this.api.require, this.api.define);
844+
if (patch.name == moduleName) {
845+
patchModule(module || sandbox[patch.shimName], patchList[i]);
846+
}
847+
}
848+
};
849+
850+
console.debug('Checking for unresolved patches');
851+
852+
// Так как при резолвинге нельзя делать отложенный патч модуля нужно
853+
// разрезолвить все модули до окончательной инициализации песочницы.
854+
for (i = 0, length = patchList.length; i < length; i++) {
855+
if (typeof(patchList[i]) === 'string') {
856+
var patchName = ['requirejs-sandbox', 'patches', patchList[i]].join('/');
857+
858+
if (window.require.defined(patchName)) {
859+
console.debug('Patch "' + patchName + '" is resolved in parent page. Linking with patch list...');
860+
patchList[i] = window.require(patchName);
861+
} else {
862+
unresolvedPatchesCount++;
863+
console.debug('Patch "' + patchName + '" is unresolved. Resolving...');
864+
window.require([patchName], resolvePatch);
865+
}
866+
}
867+
}
868+
869+
// Если нет не зарезолвленных патчей то окончательно инициализируем песочницу.
870+
if (!unresolvedPatchesCount) {
871+
success();
872+
}
899873
};
900874

901875
// Вставляем с песочницу скрипт reuqire.js.

0 commit comments

Comments
 (0)