diff options
author | Luke Bennett <lukeeeebennettplus@gmail.com> | 2016-07-26 04:52:39 +0100 |
---|---|---|
committer | Luke Bennett <lukeeeebennettplus@gmail.com> | 2016-09-18 15:57:29 +0100 |
commit | f79185dff7482410b73c16c8ba3bcd984bb9ccf7 (patch) | |
tree | 94d9d8e65d789c82ca5b7bd1b541d28766e679a7 /app/assets/javascripts/dispatcher.js.es6 | |
parent | d54f05dac63d580d4451a954dd5593a065a05a3c (diff) | |
download | gitlab-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.es6 | 91 |
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 = {})); |