summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/dispatcher.js.es6
diff options
context:
space:
mode:
authorLuke Bennett <lukeeeebennettplus@gmail.com>2016-07-26 04:52:39 +0100
committerLuke Bennett <lukeeeebennettplus@gmail.com>2016-09-18 15:57:29 +0100
commitf79185dff7482410b73c16c8ba3bcd984bb9ccf7 (patch)
tree94d9d8e65d789c82ca5b7bd1b541d28766e679a7 /app/assets/javascripts/dispatcher.js.es6
parentd54f05dac63d580d4451a954dd5593a065a05a3c (diff)
downloadgitlab-ce-new-dispatcher-es6-idea.tar.gz
Added a new idea for a dispatchernew-dispatcher-es6-idea
Initial version of dispatcher is functioning, now need to add glob patterns and swap out everything in the old dispatcher Added support for wildcard page queries Tidied up names and method order. Started adding code docs Started converting old dispatcher implementations to new dispatcher
Diffstat (limited to 'app/assets/javascripts/dispatcher.js.es6')
-rw-r--r--app/assets/javascripts/dispatcher.js.es691
1 files changed, 91 insertions, 0 deletions
diff --git a/app/assets/javascripts/dispatcher.js.es6 b/app/assets/javascripts/dispatcher.js.es6
new file mode 100644
index 00000000000..bce23e5b257
--- /dev/null
+++ b/app/assets/javascripts/dispatcher.js.es6
@@ -0,0 +1,91 @@
+((global) => {
+ class Dispatcher {
+ constructor() {
+ this.registeredModules = [];
+ this.executedModules = [];
+ document.addEventListener('page:change', this.processModules.bind(this));
+ document.addEventListener('page:before-unload', this.processModules.bind(this));
+ }
+
+ /**
+ * Registers a module to a page query, or an array of page queries.
+ * Module page queries are matched against the `body` `date-page` attribute
+ * in order to
+ * @param {String} pageQuery - A page query, often taken from the body
+ * `data-page` attribute.
+ * e.g. `primary:secondary:tertiary`.
+ * It can also accept wildcards.
+ * e.g. `primary:*:tertiary`.
+ * @param {Function} module - A function to be invoked when a module's
+ * page query matches the current page identifier.
+ * @return {Undefined}
+ */
+ register(pageQuery, module) {
+ if (_.isArray(pageQuery)) {
+ for (pageQuery of pageQuery) {
+ this.registerModule(pageQuery, module);
+ }
+ } else {
+ this.registerModule(pageQuery, module);
+ }
+ }
+
+ processModules(e) {
+ const shouldDestroy = (e.type === 'page:before-unload');
+ for (let i = 0; i < this.registeredModules.length; i++) {
+ const module = this.registeredModules[i];
+ if (shouldDestroy) {
+ this.destroyModule(module);
+ } else {
+ this.executeModule(module);
+ };
+ }
+ if (shouldDestroy) this.executedModules = [];
+ }
+
+ registerModule(pageQuery, module) {
+ this.registeredModules.push({
+ pageQuery,
+ module,
+ });
+ }
+
+ destroyModule(module) {
+ if (!module.destroyableInstance) return;
+ if (module.destroyableInstance.destroy) module.destroyableInstance.destroy();
+ delete module.destroyableInstance;
+ delete global[module.module.name];
+ }
+
+ executeModule(module) {
+ if (!this.isExecutable(module)) return;
+ try {
+ module.destroyableInstance = new module.module();
+ } catch (e) {
+ module.destroyableInstance = module.module();
+ }
+ global[module.module.name] = module.module;
+ this.executedModules.push(module.module.name);
+ }
+
+ isExecutable(module) {
+ for (let i = 0; i < this.executedModules.length; i++) {
+ const executedModuleName = this.executedModules[i];
+ if (module.module.name === executedModuleName) {
+ return false;
+ }
+ }
+ return this.matchesPageIdentifier(module)
+ }
+
+ matchesPageIdentifier(module) {
+ const currentPageIdentifier = document.body.attributes['data-page'].value;
+ const pageQueryRegexString = module.pageQuery.replace(/\*/g, '.*');
+ const pageQueryRegex = new RegExp(pageQueryRegexString, 'gi');
+ return pageQueryRegex.test(currentPageIdentifier);
+ }
+ }
+
+ global.Dispatcher = new Dispatcher();
+
+})(window.gl || (window.gl = {}));