diff options
-rw-r--r-- | include/classes/BigPipe/BigPipe.php | 4 | ||||
-rw-r--r-- | include/classes/Document.php | 34 | ||||
-rw-r--r-- | static/bigpipe.js | 36 | ||||
-rw-r--r-- | template/document.php | 44 | ||||
-rw-r--r-- | test.php | 66 |
5 files changed, 172 insertions, 12 deletions
diff --git a/include/classes/BigPipe/BigPipe.php b/include/classes/BigPipe/BigPipe.php index d84083e..737e860 100644 --- a/include/classes/BigPipe/BigPipe.php +++ b/include/classes/BigPipe/BigPipe.php @@ -89,10 +89,6 @@ class BigPipe { } } } - - if(self::enabled()) { - echo "<script>BigPipe.onLastPageletArrived();</script>\n"; - } } } ?>
\ No newline at end of file diff --git a/include/classes/Document.php b/include/classes/Document.php new file mode 100644 index 0000000..9b9893a --- /dev/null +++ b/include/classes/Document.php @@ -0,0 +1,34 @@ +<?php +use BigPipe\BigPipe; +use BigPipe\Pagelet; + +class Document { + private $contentCallbacks = []; + private $pagelets = []; + + public function addPagelet(Pagelet $Pagelet, callable $callback) { + $this->pagelets[] = $Pagelet; + + $this->contentCallbacks[$Pagelet->getID()] = $callback; + + if(!BigPipe::enabled()) { + $Pagelet->addHTML($callback($Pagelet)); + } + } + + public function render($content_html, $sidebar_html) { + require 'template/document.php'; + BigPipe::flushOutputBuffer(); + + if(BigPipe::enabled()) { + foreach($this->pagelets as $Pagelet) { + $Pagelet->addHTML($this->contentCallbacks[$Pagelet->getID()]($Pagelet)); + $Pagelet->flush(); + } + } + + BigPipe::completeResponse(); + echo "</body>\n</html>"; + } +} +?>
\ No newline at end of file diff --git a/static/bigpipe.js b/static/bigpipe.js index cc048a5..41bd4fd 100644 --- a/static/bigpipe.js +++ b/static/bigpipe.js @@ -272,7 +272,27 @@ BigPipe = (function() { wait: [], interval: null, + eventNode: document, + eventName: "DOMContentLoaded", + eventFunc: function() { + BigPipe.onLastPageletArrived(); + BigPipe.unregisterEventListener(); + }, + + registerEventListener() { + this.eventNode.addEventListener(this.eventName, this.eventFunc, false); + }, + + unregisterEventListener() { + this.eventNode.removeEventListener(this.eventName, this.eventFunc, false); + }, + onPageletArrive(data, codeContainer) { + if(this.phase === 0) { + this.phase = 1; + this.registerEventListener(); + } + let pageletHTML = codeContainer.innerHTML; pageletHTML = pageletHTML.substring(5, pageletHTML.length - 4); codeContainer.parentNode.removeChild(codeContainer); @@ -281,10 +301,6 @@ BigPipe = (function() { this.pagelets.push(pagelet); - if(this.phase === 0) { - this.phase = 1; - } - if(pagelet.NEED.length === 0 || pagelet.NEED.every(function(needID) { return BigPipe.done.indexOf(needID) !== -1; })) { @@ -339,12 +355,16 @@ BigPipe = (function() { // Public-Access //============================================================================== return { - onPageletArrive(data, codeContainer) { - BigPipe.onPageletArrive(data, codeContainer); + setLastPageletEventNode(eventNode) { + BigPipe.eventNode = eventNode; }, - onLastPageletArrived() { - BigPipe.onLastPageletArrived(); + setLastPageletEventName(eventName) { + BigPipe.eventName = eventName; + }, + + onPageletArrive(data, codeContainer) { + BigPipe.onPageletArrive(data, codeContainer); }, reset() { diff --git a/template/document.php b/template/document.php new file mode 100644 index 0000000..f556bb6 --- /dev/null +++ b/template/document.php @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8" /> + <meta name="referrer" content="origin-when-crossorigin" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <style> + html,body{margin:0;padding:0;} + html{font-size:1.25rem;color:#333;background:#CCC;-webkit-hyphens:auto;hyphens:auto;} + body{font-family:Ruda,sans-serif;font-size:0.7rem;line-height:1.0rem;} + blockquote,pre,code{font-family:"PT Mono",monospace;} + a{color:#0060A0;}a:focus{background:#CCC;text-decoration:underline;} + #container{background:#FFF;max-width:50rem;margin:0 auto;border:0.05rem solid #AAA;} + #main_header{background:#5E819F;} + </style> + <script src="static/bigpipe.js"></script> + <title>Example</title> +</head> +<body> +<section id="container"> + <header id="main_header"> + <h1>BigPipe</h1> + <p>This is an example page to demonstrate how <em>BigPipe</em> works.</p> + <nav id="main_navi"> + <ul> + <li><a href="#">Home</a></li> + <li><a href="#">Profile</a></li> + <li><a href="#">Settings</a></li> + </ul> + </nav> + </header> + <div id="main_container"> + <main id="main_content"> + <?="{$content_html}\n"?> + </main> + <aside id="main_sidebar"> + <?="{$sidebar_html}\n"?> + </aside> + </div> + <footer id="main_footer"> + Imprint | Footer + </footer> +</section> +<!-- We skip closing the <body> and <html> tags because the pagelets are getting flushed at this position. --> diff --git a/test.php b/test.php new file mode 100644 index 0000000..04a674a --- /dev/null +++ b/test.php @@ -0,0 +1,66 @@ +<?php +# >>> pagelets.php +#=============================================================================== +# Autoload register for classes +#=============================================================================== +spl_autoload_register(function($classname) { + $classname = str_replace('\\', '/', $classname); + require "include/classes/{$classname}.php"; +}); + +#=============================================================================== +# Enable debugging mode +#=============================================================================== +Application::$debugging = TRUE; + +#=============================================================================== +# Check if BigPipe should be disabled +#=============================================================================== +if(isset($_GET['bigpipe']) AND $_GET['bigpipe'] === '0') { + # You can use this method to disable the pipeline for Googlebot or something + # else. If BigPipe is "disabled", then all pagelets will be rendered without + # being pipelined through the javascript library. The content of the pagelet + # will be present at the original position within the HTML response (and all + # external stylesheets and javascripts will be displayed as simple <link> or + # <script> elements within the HTML document). + BigPipe\BigPipe::enabled(FALSE); +} + +#=============================================================================== +# Initialize pagelet instances +#=============================================================================== +$DemoPagelet0 = Application::createPagelet('main_pagelet_0'); +$DemoPagelet1 = Application::createPagelet('main_pagelet_1'); +$DemoPagelet2 = Application::createPagelet('main_pagelet_2'); +$DemoPagelet3 = Application::createPagelet('side_pagelet_3'); + +$Document = new Document(); + +$Document->addPagelet($DemoPagelet0, function() { + return 'I am the first demo pagelet.'; +}); + +$Document->addPagelet($DemoPagelet1, function() { + sleep(1); # simulate long execution of code (database queries, network communication, etc) + return 'I am the second demo pagelet and take very long to generate at server.'; +}); + +$Document->addPagelet($DemoPagelet2, function() { + return 'I am the third demo pagelet.'; +}); + +$Document->addPagelet($DemoPagelet3, function() { + sleep(1); # simulate long execution of code (database queries, network communication, etc) + return 'I am the fourth demo pagelet and I also take very long to generate at server.'; +}); + +$content_html = "<ul> + <li>DemoPagelet0: {$DemoPagelet0}</li> + <li>DemoPagelet1: {$DemoPagelet1}</li> + <li>DemoPagelet2: {$DemoPagelet2}</li> + </ul>"; + +$sidebar_html = "{$DemoPagelet3}"; + +$Document->render($content_html, $sidebar_html); +?>
\ No newline at end of file |