From 4a1bee769ba33c1e60884970a3ebecb1ba55df81 Mon Sep 17 00:00:00 2001 From: Connor Christie Date: Mon, 1 Jan 2018 09:42:34 -0600 Subject: [PATCH 1/6] Add true module dom creation events --- js/main.js | 36 +++++++++++++++++++++++++++++++----- js/module.js | 43 +++++++++++++++++++++---------------------- 2 files changed, 52 insertions(+), 27 deletions(-) diff --git a/js/main.js b/js/main.js index f499da62..242be5a8 100644 --- a/js/main.js +++ b/js/main.js @@ -96,17 +96,44 @@ var MM = (function() { * argument speed Number - The number of microseconds for the animation. (optional) */ var updateDom = function(module, speed) { - var newContent = module.getDom(); + var newContentPromise = module.getDom(); var newHeader = module.getHeader(); - if (!module.hidden) { + if (!(newContentPromise instanceof Promise)) { + // convert to a promise if not already one to avoid if/else's everywhere + newContentPromise = Promise.resolve(newContentPromise); + } + + newContentPromise.then((newContent) => { + var updatePromise = updateDomWithContent(module, speed, newHeader, newContent); + + updatePromise.then(() => { + // dom has been updated + sendNotification("MODULE_DOM_CREATED", { module: module.name }); + }).catch((err) => { + Log.error(err); + }); + }).catch((err) => { + Log.error(err); + }); + }; + + var updateDomWithContent = function(module, speed, newHeader, newContent) { + return new Promise((resolve) => { + if (module.hidden || !speed) { + updateModuleContent(module, newHeader, newContent); + resolve(); + return; + } if (!moduleNeedsUpdate(module, newHeader, newContent)) { + resolve(); return; } if (!speed) { updateModuleContent(module, newHeader, newContent); + resolve(); return; } @@ -115,10 +142,9 @@ var MM = (function() { if (!module.hidden) { showModule(module, speed / 2); } + resolve(); }); - } else { - updateModuleContent(module, newHeader, newContent); - } + }); }; /* moduleNeedsUpdate(module, newContent) diff --git a/js/module.js b/js/module.js index 464509ee..dbcfe91f 100644 --- a/js/module.js +++ b/js/module.js @@ -81,31 +81,30 @@ var Module = Class.extend({ * return domobject - The dom to display. */ getDom: function () { - var div = document.createElement("div"); - var template = this.getTemplate(); - var templateData = this.getTemplateData(); + return new Promise((resolve) => { + var div = document.createElement("div"); + var template = this.getTemplate(); + var templateData = this.getTemplateData(); + + // Check to see if we need to render a template string or a file. + if (/^.*((\.html)|(\.njk))$/.test(template)) { + // the template is a filename + this.nunjucksEnvironment().render(template, templateData, function (err, res) { + if (err) { + Log.error(err) + } - // Check to see if we need to render a template string or a file. - if (/^.*((\.html)|(\.njk))$/.test(template)) { - // the template is a filename - this.nunjucksEnvironment().render(template, templateData, function (err, res) { - if (err) { - Log.error(err) - } + div.innerHTML = res; - // The inner content of the div will be set after the template is received. - // This isn't the most optimal way, but since it's near instant - // it probably won't be an issue. - // If it gives problems, we can always add a way to pre fetch the templates. - // Let's not over optimise this ... KISS! :) - div.innerHTML = res; - }); - } else { - // the template is a template string. - div.innerHTML = this.nunjucksEnvironment().renderString(template, templateData); - } + resolve(div); + }); + } else { + // the template is a template string. + div.innerHTML = this.nunjucksEnvironment().renderString(template, templateData); - return div; + resolve(div); + } + }); }, /* getHeader() From 80b84212cc99c4e0596e3b5592ce87b2bfaa53f6 Mon Sep 17 00:00:00 2001 From: Connor Christie Date: Mon, 1 Jan 2018 10:23:15 -0600 Subject: [PATCH 2/6] Add notification for module dom creation with async support --- js/main.js | 103 +++++++++++++++++++++++++---------------------------- 1 file changed, 49 insertions(+), 54 deletions(-) diff --git a/js/main.js b/js/main.js index 242be5a8..e3412e14 100644 --- a/js/main.js +++ b/js/main.js @@ -19,38 +19,39 @@ var MM = (function() { * are configured for a specific position. */ var createDomObjects = function() { - for (var m in modules) { - var module = modules[m]; - - if (typeof module.data.position === "string") { - - var wrapper = selectWrapper(module.data.position); - - var dom = document.createElement("div"); - dom.id = module.identifier; - dom.className = module.name; - - if (typeof module.data.classes === "string") { - dom.className = "module " + dom.className + " " + module.data.classes; - } - - dom.opacity = 0; - wrapper.appendChild(dom); - - if (typeof module.data.header !== "undefined" && module.data.header !== "") { - var moduleHeader = document.createElement("header"); - moduleHeader.innerHTML = module.data.header; - moduleHeader.className = "module-header"; - dom.appendChild(moduleHeader); - } - - var moduleContent = document.createElement("div"); - moduleContent.className = "module-content"; - dom.appendChild(moduleContent); - - updateDom(module, 0); + modules.forEach(module => { + if (typeof module.data.position !== "string") { + return; } - } + + var wrapper = selectWrapper(module.data.position); + + var dom = document.createElement("div"); + dom.id = module.identifier; + dom.className = module.name; + + if (typeof module.data.classes === "string") { + dom.className = "module " + dom.className + " " + module.data.classes; + } + + dom.opacity = 0; + wrapper.appendChild(dom); + + if (typeof module.data.header !== "undefined" && module.data.header !== "") { + var moduleHeader = document.createElement("header"); + moduleHeader.innerHTML = module.data.header; + moduleHeader.className = "module-header"; + dom.appendChild(moduleHeader); + } + + var moduleContent = document.createElement("div"); + moduleContent.className = "module-content"; + dom.appendChild(moduleContent); + + updateDom(module, 0).then(() => { + sendNotification("MODULE_DOM_CREATED", null, null, module); + }).catch(Log.error); + }); updateWrapperStates(); @@ -80,10 +81,9 @@ var MM = (function() { * argument payload mixed - The payload of the notification. * argument sender Module - The module that sent the notification. */ - var sendNotification = function(notification, payload, sender) { - for (var m in modules) { - var module = modules[m]; - if (module !== sender) { + var sendNotification = function(notification, payload, sender, sendTo) { + for (var module of modules) { + if (module !== sender && (!sendTo || module === sendTo)) { module.notificationReceived(notification, payload, sender); } } @@ -96,25 +96,20 @@ var MM = (function() { * argument speed Number - The number of microseconds for the animation. (optional) */ var updateDom = function(module, speed) { - var newContentPromise = module.getDom(); - var newHeader = module.getHeader(); - - if (!(newContentPromise instanceof Promise)) { - // convert to a promise if not already one to avoid if/else's everywhere - newContentPromise = Promise.resolve(newContentPromise); - } - - newContentPromise.then((newContent) => { - var updatePromise = updateDomWithContent(module, speed, newHeader, newContent); - - updatePromise.then(() => { - // dom has been updated - sendNotification("MODULE_DOM_CREATED", { module: module.name }); - }).catch((err) => { - Log.error(err); - }); - }).catch((err) => { - Log.error(err); + return new Promise((resolve) => { + var newContentPromise = module.getDom(); + var newHeader = module.getHeader(); + + if (!(newContentPromise instanceof Promise)) { + // convert to a promise if not already one to avoid if/else's everywhere + newContentPromise = Promise.resolve(newContentPromise); + } + + newContentPromise.then((newContent) => { + var updatePromise = updateDomWithContent(module, speed, newHeader, newContent); + + updatePromise.then(resolve).catch(Log.error); + }).catch(Log.error); }); }; From 7bb11d6436a70e0e2ab80e4bf27aaf22463285e6 Mon Sep 17 00:00:00 2001 From: Connor Christie Date: Mon, 1 Jan 2018 10:38:00 -0600 Subject: [PATCH 3/6] Add documentation regarding updates --- js/main.js | 15 +++++++++++++++ modules/README.md | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/js/main.js b/js/main.js index e3412e14..782b6863 100644 --- a/js/main.js +++ b/js/main.js @@ -80,6 +80,7 @@ var MM = (function() { * argument notification string - The identifier of the notification. * argument payload mixed - The payload of the notification. * argument sender Module - The module that sent the notification. + * argument sendTo Module - The module to send the notification to. (optional) */ var sendNotification = function(notification, payload, sender, sendTo) { for (var module of modules) { @@ -94,6 +95,8 @@ var MM = (function() { * * argument module Module - The module that needs an update. * argument speed Number - The number of microseconds for the animation. (optional) + * + * return Promise - Resolved when the dom is fully updated. */ var updateDom = function(module, speed) { return new Promise((resolve) => { @@ -113,6 +116,16 @@ var MM = (function() { }); }; + /* updateDomWithContent(module, speed, newHeader, newContent) + * Update the dom with the specified content + * + * argument module Module - The module that needs an update. + * argument speed Number - The number of microseconds for the animation. (optional) + * argument newHeader String - The new header that is generated. + * argument newContent Domobject - The new content that is generated. + * + * return Promise - Resolved when the module dom has been updated. + */ var updateDomWithContent = function(module, speed, newHeader, newContent) { return new Promise((resolve) => { if (module.hidden || !speed) { @@ -146,6 +159,7 @@ var MM = (function() { * Check if the content has changed. * * argument module Module - The module to check. + * argument newHeader String - The new header that is generated. * argument newContent Domobject - The new content that is generated. * * return bool - Does the module need an update? @@ -173,6 +187,7 @@ var MM = (function() { * Update the content of a module on screen. * * argument module Module - The module to check. + * argument newHeader String - The new header that is generated. * argument newContent Domobject - The new content that is generated. */ var updateModuleContent = function(module, newHeader, newContent) { diff --git a/modules/README.md b/modules/README.md index 76973996..0b5c2d7c 100644 --- a/modules/README.md +++ b/modules/README.md @@ -230,11 +230,12 @@ notificationReceived: function(notification, payload, sender) { } ```` -**Note:** the system sends two notifications when starting up. These notifications could come in handy! +**Note:** the system sends three notifications when starting up. These notifications could come in handy! - `ALL_MODULES_STARTED` - All modules are started. You can now send notifications to other modules. - `DOM_OBJECTS_CREATED` - All dom objects are created. The system is now ready to perform visual changes. +- `MODULE_DOM_CREATED` - This module's dom has been fully loaded. You can now access your module's dom objects. #### `socketNotificationReceived: function(notification, payload)` From e2df5739f0d82b25de2372f6fe67f595b54d060e Mon Sep 17 00:00:00 2001 From: Connor Christie Date: Mon, 1 Jan 2018 10:40:52 -0600 Subject: [PATCH 4/6] Update module docs --- js/module.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/module.js b/js/module.js index dbcfe91f..71a14827 100644 --- a/js/module.js +++ b/js/module.js @@ -78,7 +78,7 @@ var Module = Class.extend({ * This method can to be subclassed if the module wants to display info on the mirror. * Alternatively, the getTemplete method could be subclassed. * - * return domobject - The dom to display. + * return DomObject | Promise - The dom or a promise with the dom to display. */ getDom: function () { return new Promise((resolve) => { From be3d7036923b8804904eb1e897e20eae2adcf587 Mon Sep 17 00:00:00 2001 From: Connor Christie Date: Mon, 1 Jan 2018 10:55:39 -0600 Subject: [PATCH 5/6] Fix linter errors --- js/main.js | 12 ++++++------ js/module.js | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/js/main.js b/js/main.js index 782b6863..0e1e5239 100644 --- a/js/main.js +++ b/js/main.js @@ -95,22 +95,22 @@ var MM = (function() { * * argument module Module - The module that needs an update. * argument speed Number - The number of microseconds for the animation. (optional) - * + * * return Promise - Resolved when the dom is fully updated. */ var updateDom = function(module, speed) { return new Promise((resolve) => { var newContentPromise = module.getDom(); var newHeader = module.getHeader(); - + if (!(newContentPromise instanceof Promise)) { // convert to a promise if not already one to avoid if/else's everywhere newContentPromise = Promise.resolve(newContentPromise); } - + newContentPromise.then((newContent) => { var updatePromise = updateDomWithContent(module, speed, newHeader, newContent); - + updatePromise.then(resolve).catch(Log.error); }).catch(Log.error); }); @@ -118,12 +118,12 @@ var MM = (function() { /* updateDomWithContent(module, speed, newHeader, newContent) * Update the dom with the specified content - * + * * argument module Module - The module that needs an update. * argument speed Number - The number of microseconds for the animation. (optional) * argument newHeader String - The new header that is generated. * argument newContent Domobject - The new content that is generated. - * + * * return Promise - Resolved when the module dom has been updated. */ var updateDomWithContent = function(module, speed, newHeader, newContent) { diff --git a/js/module.js b/js/module.js index 71a14827..57bdde4f 100644 --- a/js/module.js +++ b/js/module.js @@ -85,7 +85,7 @@ var Module = Class.extend({ var div = document.createElement("div"); var template = this.getTemplate(); var templateData = this.getTemplateData(); - + // Check to see if we need to render a template string or a file. if (/^.*((\.html)|(\.njk))$/.test(template)) { // the template is a filename From 9e83234df147e7d9e2d25eaeb3352f009c2bb521 Mon Sep 17 00:00:00 2001 From: Connor Christie Date: Tue, 2 Jan 2018 18:06:21 -0600 Subject: [PATCH 6/6] Update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad3cfd9e..8d65fc3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [2.2.3] - 2018-01-03 + +### Added + +- Add system notification `MODULE_DOM_CREATED` for notifying each module when their Dom has been fully loaded. + ## [2.2.2] - 2018-01-02 ### Added