aboutsummaryrefslogtreecommitdiffstats
path: root/static
diff options
context:
space:
mode:
authorThomas Lange <code@nerdmind.de>2015-04-15 21:29:19 +0200
committerThomas Lange <code@nerdmind.de>2015-04-15 21:29:19 +0200
commitbf996f7247133c536511c23b6ad30aa222bfd6d9 (patch)
tree1d9388e6331454fbc9b68b5006a64c4563c202cd /static
downloadbigpipe-bf996f7247133c536511c23b6ad30aa222bfd6d9.tar.gz
bigpipe-bf996f7247133c536511c23b6ad30aa222bfd6d9.tar.xz
bigpipe-bf996f7247133c536511c23b6ad30aa222bfd6d9.zip
Initial commit
Diffstat (limited to 'static')
-rwxr-xr-xstatic/bigpipe-callbacks.js27
-rwxr-xr-xstatic/bigpipe.js274
-rwxr-xr-xstatic/blue.php17
-rwxr-xr-xstatic/delayJS.php16
-rwxr-xr-xstatic/green.php17
-rwxr-xr-xstatic/red.php17
6 files changed, 368 insertions, 0 deletions
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 @@
+<?php
+#====================================================================================================
+# Cache deaktivieren
+#====================================================================================================
+header('Cache-Control: no-cache, no-store, must-revalidate');
+
+#====================================================================================================
+# Content-Type setzen
+#====================================================================================================
+header('Content-Type: text/css');
+
+#====================================================================================================
+# Lange Ladezeit simulieren
+#====================================================================================================
+usleep(intval(rand(60, 100).'0000'));
+?>
+#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 @@
+<?php
+#====================================================================================================
+# Cache deaktivieren
+#====================================================================================================
+header('Cache-Control: no-cache, no-store, must-revalidate');
+
+#====================================================================================================
+# Content-Type setzen
+#====================================================================================================
+header('Content-Type: text/javascript');
+
+#====================================================================================================
+# Lange Ladezeit simulieren
+#====================================================================================================
+usleep(intval(rand(10, 40).'0000'));
+?> \ 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 @@
+<?php
+#====================================================================================================
+# Cache deaktivieren
+#====================================================================================================
+header('Cache-Control: no-cache, no-store, must-revalidate');
+
+#====================================================================================================
+# Content-Type setzen
+#====================================================================================================
+header('Content-Type: text/css');
+
+#====================================================================================================
+# Lange Ladezeit simulieren
+#====================================================================================================
+usleep(intval(rand(60, 100).'0000'));
+?>
+#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 @@
+<?php
+#====================================================================================================
+# Cache deaktivieren
+#====================================================================================================
+header('Cache-Control: no-cache, no-store, must-revalidate');
+
+#====================================================================================================
+# Content-Type setzen
+#====================================================================================================
+header('Content-Type: text/css');
+
+#====================================================================================================
+# Lange Ladezeit simulieren
+#====================================================================================================
+usleep(intval(rand(60, 100).'0000'));
+?>
+#red{background:red;} \ No newline at end of file