From bf996f7247133c536511c23b6ad30aa222bfd6d9 Mon Sep 17 00:00:00 2001 From: Thomas Lange Date: Wed, 15 Apr 2015 21:29:19 +0200 Subject: Initial commit --- static/bigpipe-callbacks.js | 27 +++++ static/bigpipe.js | 274 ++++++++++++++++++++++++++++++++++++++++++++ static/blue.php | 17 +++ static/delayJS.php | 16 +++ static/green.php | 17 +++ static/red.php | 17 +++ 6 files changed, 368 insertions(+) create mode 100755 static/bigpipe-callbacks.js create mode 100755 static/bigpipe.js create mode 100755 static/blue.php create mode 100755 static/delayJS.php create mode 100755 static/green.php create mode 100755 static/red.php (limited to 'static') diff --git a/static/bigpipe-callbacks.js b/static/bigpipe-callbacks.js new file mode 100755 index 0000000..a9f48f1 --- /dev/null +++ b/static/bigpipe-callbacks.js @@ -0,0 +1,27 @@ +// Folgende Phasen stehen zur Auswahl: PAGELET_STARTED, RESOURCE_DONE, PAGELET_HTML_RENDERED, PAGELET_JS_EXECUTED und BIGPIPE_PAGELETS_RENDERED + +var debugLine = "------------------------------------------------------------------------------------------------------------------------"; + +BigPipe.registerPhaseDoneCallback('PAGELET_STARTED', function(Pagelet) { + console.log(debugLine); + console.log(Pagelet.pageletID + ":\t" + "Die Ausführung des Pagelets wurde gestartet."); +}); + +BigPipe.registerPhaseDoneCallback('RESOURCE_DONE', function(Resource) { + console.log(Resource.pageletID + ":\t" + 'Die Ressource ' + Resource.file + ' wurde geladen.'); +}); + +BigPipe.registerPhaseDoneCallback('PAGELET_HTML_RENDERED', function(Pagelet) { + console.log(Pagelet.pageletID + ":\t" + 'Die Platzhalter wurden mit HTML-Code befüllt.'); +}); + +BigPipe.registerPhaseDoneCallback('BIGPIPE_PAGELETS_RENDERED', function() { + console.log(debugLine); + console.log('BP' + ":\t" + 'Die Platzhalter von allen Pagelets wurden mit ihrem HTML-Code befüllt.'); + console.log(debugLine); +}); + +BigPipe.registerPhaseDoneCallback('PAGELET_JS_EXECUTED', function(Pagelet) { + console.log(Pagelet.pageletID + ":\t" + 'Der zugehörige Javascript-Code des Pagelets wurde ausgeführt.'); + console.log(debugLine); +}); \ No newline at end of file diff --git a/static/bigpipe.js b/static/bigpipe.js new file mode 100755 index 0000000..fcd35e9 --- /dev/null +++ b/static/bigpipe.js @@ -0,0 +1,274 @@ +//=================================================================================================== +// REVEALING MODLUE PATTERN: BigPipe +//=================================================================================================== +var BigPipe = (function() { + //=================================================================================================== + // PROTOTYPE: PageletResource-Konstruktor + //=================================================================================================== + function PageletResource(file, type, pageletID) { + this.pageletID = pageletID; + this.callbacks = []; + this.done = false; + this.file = file; + this.type = type; + } + + //=================================================================================================== + // PROTOTYPE: Startet den Ladevorgang der Ressource + //=================================================================================================== + PageletResource.prototype.start = function() { + if(this.type === 0) { + var element = document.createElement('link'); + element.setAttribute('rel', 'stylesheet'); + element.setAttribute('href', this.file); + } + + else { + var element = document.createElement('script'); + element.setAttribute('src', this.file); + element.async = true; + } + + document.head.appendChild(element); + + element.onload = function() { + BigPipe.executePhaseDoneCallbacks('RESOURCE_DONE', this); + this.executeCallbacks(); + }.bind(this); + + element.onerror = function() { + BigPipe.executePhaseDoneCallbacks('RESOURCE_DONE', this); + this.executeCallbacks(); + }.bind(this); + }; + + //=================================================================================================== + // PROTOTYPE: Registriert eine Callback-Funktion + //=================================================================================================== + PageletResource.prototype.registerCallback = function(callback) { + return this.callbacks.push(callback); + }; + + //=================================================================================================== + // PROTOTYPE: Führt alle registrierten Callback-Funktionen aus + //=================================================================================================== + PageletResource.prototype.executeCallbacks = function() { + if(!this.done) { + this.done = true; + + this.callbacks.forEach(function(callback) { + callback(); + }); + } + }; + + //=================================================================================================== + // PROTOTYPE: Pagelet-Konstruktor + //=================================================================================================== + function Pagelet(data) { + this.pageletID = data.ID; + this.HTML = data.HTML || ""; + this.CSSFiles = data.RESOURCES.CSS; + this.JSFiles = data.RESOURCES.JS; + this.JSCode = data.RESOURCES.JS_CODE; + + this.phase = 0; // 1 => Laden von CSS-Ressourcen, 2 => CSS-Ressourcen geladen, 3 => HTML wurde injiziert, 4 => JS-Ressourcen geladen und JS-Code ausgeführt + this.CSSResources = []; + this.JSResources = []; + } + + //=================================================================================================== + // PROTOTYPE: Startet die Initialisierung des Pagelets und startet die Pagelet-Ressourcen + //=================================================================================================== + Pagelet.prototype.start = function() { + BigPipe.executePhaseDoneCallbacks('PAGELET_STARTED', this); + this.CSSFiles.forEach(function(file) { + this.attachCSSResource(new PageletResource(file, 0, this.pageletID)); + }.bind(this)); + + this.JSFiles.forEach(function(file) { + this.attachJSResource(new PageletResource(file, 1, this.pageletID)); + }.bind(this)); + + this.CSSResources.forEach(function(resource) { + this.phase = 1; + resource.start(); + }.bind(this)); + + if(this.phase === 0) { + this.injectHTML(); + } + }; + + //=================================================================================================== + // PROTOTYPE: Fügt eine CSS-Ressource hinzu + //=================================================================================================== + Pagelet.prototype.attachCSSResource = function(resource) { + resource.registerCallback(this.onloadCSS.bind(this)); + return this.CSSResources.push(resource); + }; + + //=================================================================================================== + // PROTOTYPE: Fügt eine JS-Ressource hinzu + //=================================================================================================== + Pagelet.prototype.attachJSResource = function(resource) { + resource.registerCallback(this.onloadJS.bind(this)); + return this.JSResources.push(resource); + }; + + //=================================================================================================== + // PROTOTYPE: Führt den statischen JS-Code des Pagelets aus + //=================================================================================================== + Pagelet.prototype.executeJSCode = function() { + try { + globalExecution(this.JSCode); + BigPipe.executePhaseDoneCallbacks('PAGELET_JS_EXECUTED', this); + } catch(e) { + console.error(this.pageletID + ":\t" + e); + } + }; + + //=================================================================================================== + // PROTOTYPE: Pagelet-Methode + //=================================================================================================== + Pagelet.prototype.onloadJS = function() { + if(this.phase === 3 && this.JSResources.every(function(resource){ + return resource.done; + })) { + this.executeJSCode(); + this.phase = 4; + } + }; + + //=================================================================================================== + // PROTOTYPE: Pagelet-Methode + //=================================================================================================== + Pagelet.prototype.onloadCSS = function() { + if(this.CSSResources.every(function(resource){ + return resource.done; + })) { + this.injectHTML(); + } + }; + + //=================================================================================================== + // PROTOTYPE: Injiziert den HTML-Code des Pagelets in den DOM + //=================================================================================================== + Pagelet.prototype.injectHTML = function() { + this.phase = 2; + if(placeholder = document.getElementById(this.pageletID)) { + if(this.HTML) { + placeholder.innerHTML = this.HTML; + } + + else { + var content = document.getElementById('_' + this.pageletID); + placeholder.innerHTML = content.innerHTML.substring(5, content.innerHTML.length - 4); + document.body.removeChild(content); + } + } + + this.phase = 3; + + BigPipe.executePhaseDoneCallbacks('PAGELET_HTML_RENDERED', this); + BigPipe.executeNextPagelet(); + + if(BigPipe.phase === 2 && BigPipe.pagelets[BigPipe.pagelets.length - 1].pageletID === this.pageletID) { + BigPipe.executePhaseDoneCallbacks('BIGPIPE_PAGELETS_RENDERED'); + BigPipe.loadJSResources(); + } + }; + + //=================================================================================================== + // BigPipe-Hauptobjekt + //=================================================================================================== + var BigPipe = { + pagelets: [], + phase: 0, // 1 => Erstes Pagelet gestartet, 2 => Alle Pagelets angekommen, 3 => JS-Ressourcen geladen + JS-Code ausgeführt + offset: 0, + phaseDoneCallbacks: {}, + + executeNextPagelet: function() { + if(this.pagelets[this.offset]) { + this.pagelets[this.offset++].start(); + } + + else if(this.phase < 2) { + setTimeout(this.executeNextPagelet.bind(this), 30); + } + }, + + registerPhaseDoneCallback: function(phase, callback) { + if(!this.phaseDoneCallbacks[phase]) { + this.phaseDoneCallbacks[phase] = []; + } + return this.phaseDoneCallbacks[phase].push(callback); + }, + + executePhaseDoneCallbacks: function(phase, param) { + if(this.phaseDoneCallbacks[phase]) { + this.phaseDoneCallbacks[phase].forEach(function(callback) { + callback(param); + }); + } + }, + + onPageletArrive: function(data) { + if(this.pagelets.push(new Pagelet(data)) && this.phase === 0 && !data.IS_LAST) { + this.phase = 1; + this.executeNextPagelet(); + } + + else if(data.IS_LAST) { + this.phase = 2; + if(this.pagelets.length === 1) { + this.executeNextPagelet(); + } + } + }, + + loadJSResources: function() { + this.phase = 3; + var isLoading = false; + + this.pagelets.forEach(function(Pagelet) { + if(Pagelet.JSResources.length === 0) { + Pagelet.onloadJS(); + } + }); + + this.pagelets.forEach(function(Pagelet) { + Pagelet.JSResources.forEach(function(Resource) { + Resource.start(); + isLoading = true; + }); + }); + + if(!isLoading) { + this.pagelets.forEach(function(Pagelet) { + Pagelet.onloadJS(); + }); + } + } + }; + + //=================================================================================================== + // REVEALING MODULE PATTERN: Öffentliche API + //=================================================================================================== + return { + onPageletArrive: function(data) { + BigPipe.onPageletArrive(data); + }, + + registerPhaseDoneCallback: function(phase, callback) { + BigPipe.registerPhaseDoneCallback(phase, callback); + }, + + reset: function() { + BigPipe.phaseDoneCallbacks = {}; + BigPipe.pagelets = []; + BigPipe.offset = 0; + BigPipe.phase = 0; + } + }; +})(); \ No newline at end of file diff --git a/static/blue.php b/static/blue.php new file mode 100755 index 0000000..ddffcf6 --- /dev/null +++ b/static/blue.php @@ -0,0 +1,17 @@ + +#blue{background:blue;} \ No newline at end of file diff --git a/static/delayJS.php b/static/delayJS.php new file mode 100755 index 0000000..1307ca0 --- /dev/null +++ b/static/delayJS.php @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/static/green.php b/static/green.php new file mode 100755 index 0000000..3e45fc6 --- /dev/null +++ b/static/green.php @@ -0,0 +1,17 @@ + +#green{background:green;} \ No newline at end of file diff --git a/static/red.php b/static/red.php new file mode 100755 index 0000000..9ad993e --- /dev/null +++ b/static/red.php @@ -0,0 +1,17 @@ + +#red{background:red;} \ No newline at end of file -- cgit v1.2.3