You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by ch...@apache.org on 2009/04/11 12:36:09 UTC

svn commit: r764191 - in /incubator/shindig/trunk/php/src/gadgets: render/GadgetHrefRenderer.php render/GadgetHtmlRenderer.php rewrite/GadgetRewriter.php

Author: chabotc
Date: Sat Apr 11 10:36:09 2009
New Revision: 764191

URL: http://svn.apache.org/viewvc?rev=764191&view=rev
Log:
This patch changes the gadget rendering to a completely DOMDocument model (using the GadgetRewriter class),
and now adds the javascript and css blobs via the DOM.

Because of this the same dom actions can be re-used by the HrefRenderer in order to have a valid and consistent
style and gadgets API available there too.

On href views (proxied content) it automatically append a setHeight() call to the init script, so the view is
always fully visible

The only thing still missing from the proxied content/data-pipelining implementation now is the EL expression
parsing, which will be dealt with by the to-be-implemented template parser; Otherwise it's now feature complete.


Modified:
    incubator/shindig/trunk/php/src/gadgets/render/GadgetHrefRenderer.php
    incubator/shindig/trunk/php/src/gadgets/render/GadgetHtmlRenderer.php
    incubator/shindig/trunk/php/src/gadgets/rewrite/GadgetRewriter.php

Modified: incubator/shindig/trunk/php/src/gadgets/render/GadgetHrefRenderer.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/render/GadgetHrefRenderer.php?rev=764191&r1=764190&r2=764191&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/render/GadgetHrefRenderer.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/render/GadgetHrefRenderer.php Sat Apr 11 10:36:09 2009
@@ -39,7 +39,9 @@
  * <os:HttpRequest href="http://developersite.com/api?ids=${PagedFriends.ids}"/>
  */
 
-class GadgetHrefRenderer extends GadgetRenderer {
+require 'GadgetHtmlRenderer.php';
+
+class GadgetHrefRenderer extends GadgetHtmlRenderer {
 
   /**
    * Renders a 'proxied content' view, for reference see:
@@ -49,6 +51,7 @@
    * @param array $view
    */
   public function renderGadget(Gadget $gadget, $view) {
+    $this->gadget = $gadget;
     /* TODO
      * We should really re-add OAuth fetching support some day, uses these view atributes:
      * $view['oauthServiceName'], $view['oauthTokenName'], $view['oauthRequestToken'], $view['oauthRequestTokenSecret'];
@@ -56,7 +59,6 @@
     $authz = $this->getAuthz($view);
     $refreshInterval = $this->getRefreshInterval($view);
     $href = $this->buildHref($view, $authz);
-
     if (count($view['dataPipelining'])) {
       $dataPipeliningResults = $this->fetchDataPipelining($view['dataPipelining']);
       // if data-pipeling tags are present, post the json encoded results to the remote url
@@ -69,7 +71,6 @@
       $request->setRefreshInterval($refreshInterval);
       $request->getOptions()->ignoreCache = $gadget->gadgetContext->getIgnoreCache();
     }
-
     $signingFetcherFactory = $gadgetSigner = false;
     if ($authz != 'none') {
       $gadgetSigner = Config::get('security_token_signer');
@@ -79,11 +80,16 @@
       $request->setAuthType($authz);
       $signingFetcherFactory = new SigningFetcherFactory(Config::get("private_key_file"));
     }
-
     $basicFetcher = new BasicRemoteContentFetcher();
     $basicRemoteContent = new BasicRemoteContent($basicFetcher, $signingFetcherFactory, $gadgetSigner);
     $response = $basicRemoteContent->fetch($request);
-    echo $response->getResponseContent();
+    // Rewrite the content, this will rewrite resource links to proxied versions (if requested), sanitize if configured, and
+    // add the various javascript tags to the document
+    $rewriter = new GadgetRewriter($this->context);
+    $rewriter->addObserver('head', $this, 'addHeadTags');
+    $rewriter->addObserver('body', $this, 'addBodyTags');
+    $content = $rewriter->rewrite($response->getResponseContent(), $gadget);
+    echo $content;
   }
 
   /**

Modified: incubator/shindig/trunk/php/src/gadgets/render/GadgetHtmlRenderer.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/render/GadgetHtmlRenderer.php?rev=764191&r1=764190&r2=764191&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/render/GadgetHtmlRenderer.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/render/GadgetHtmlRenderer.php Sat Apr 11 10:36:09 2009
@@ -27,19 +27,61 @@
  *
  */
 class GadgetHtmlRenderer extends GadgetRenderer {
+  public $gadget;
 
   public function renderGadget(Gadget $gadget, $view) {
+    $this->gadget = $gadget;
     // Was a privacy policy header configured? if so set it
     if (Config::get('P3P') != '') {
       header("P3P: " . Config::get('P3P'));
     }
-
     $content = '';
     // Set doctype if quirks = false or empty in the view
     if (! empty($view['quirks']) || ! $view['quirks']) {
       $content .= "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n";
     }
-    $content .= "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/><style type=\"text/css\">" . Config::get('gadget_css') . "</style></head><body>\n";
+    $content .= "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/></head><body>\n";
+    // Append the content for the selected view
+    $content .= $gadget->substitutions->substitute($view['content']);
+    $content .= "\n</body>\n</html>";
+    // Rewrite the content, this will rewrite resource links to proxied versions (if requested), sanitize if configured, and
+    // add the various javascript tags to the document
+    $rewriter = new GadgetRewriter($this->context);
+    $rewriter->addObserver('head', $this, 'addHeadTags');
+    $rewriter->addObserver('body', $this, 'addBodyTags');
+    $content = $rewriter->rewrite($content, $gadget);
+    echo $content;
+  }
+
+  /**
+   * Append the runOnLoadHandlers script to the gadget's document body
+   *
+   * @param DOMElement $node
+   * @param DOMDocument $doc
+   */
+  public function addBodyTags(DOMElement &$node, DOMDocument $doc) {
+    $script = "gadgets.util.runOnLoadHandlers();";
+    if ($this instanceof GadgetHrefRenderer) {
+      $script .= " gadgets.window.adjustHeight();";
+    }
+    $scriptNode = $doc->createElement('script');
+    $scriptNode->nodeValue = $script;
+    $node->appendChild($scriptNode);
+  }
+
+  /**
+   * Adds the various bits of javascript to the gadget's document head element
+   *
+   * @param DOMElement $node
+   * @param DOMDocument $doc
+   */
+  public function addHeadTags(DOMElement &$node, DOMDocument $doc) {
+
+    // Inject our configured gadget document style
+    $styleNode = $doc->createElement('style');
+    $styleNode->setAttribute('type', 'text/css');
+    $styleNode->nodeValue = Config::get('gadget_css');
+    $node->appendChild($styleNode);
 
     // Inject the OpenSocial feature javascripts
     $forcedJsLibs = $this->getForcedJsLibs();
@@ -47,37 +89,30 @@
       // if some of the feature libraries are externalized (through a browser cachable <script src="/gadgets/js/opensocial-0.9:settitle.js"> type url)
       // we inject the tag and don't inline those libs (and their dependencies)
       $forcedJsLibs = explode(':', $forcedJsLibs);
-      $content .= sprintf("<script src=\"%s\"></script>\n", Config::get('default_js_prefix') . $this->getJsUrl($forcedJsLibs, $gadget) . "&container=" . $this->context->getContainer()) . "\n";
+      $scriptNode = $doc->createElement('script');
+      $scriptNode->setAttribute('src', Config::get('default_js_prefix') . $this->getJsUrl($forcedJsLibs, $this->gadget) . "&container=" . $this->context->getContainer());
+      $node->appendChild($scriptNode);
       $registry = $this->context->getRegistry();
       $missing = array();
       $registry->resolveFeatures($forcedJsLibs, $forcedJsLibs, $missing);
     }
-    $content .= "<script>\n";
-    foreach ($gadget->features as $feature) {
+
+    $script = '';
+    foreach ($this->gadget->features as $feature) {
       if (! is_array($forcedJsLibs) || (is_array($forcedJsLibs) && ! in_array($feature, $forcedJsLibs))) {
-        $content .= $this->context->getRegistry()->getFeatureContent($feature, $this->context, true);
+        $script .= $this->context->getRegistry()->getFeatureContent($feature, $this->context, true);
       }
     }
 
     // Add the JavaScript initialization strings for the configuration, localization and preloads
-    $content .= "\n";
-    $content .= $this->appendJsConfig($gadget, count($forcedJsLibs));
-    $content .= $this->appendMessages($gadget);
-    $content .= $this->appendPreloads($gadget);
-    $content .= "</script>";
-
-    // Append the content for the selected view
-    $viewContent = $gadget->substitutions->substitute($view['content']);
-
-    // Rewrite the content, the GadgetRewriter will check for the Content-Rewrtie and Caja feature, if
-    // sanitazation is required, plus look for any template exapanding that needs to be done
-    $rewriter = new GadgetRewriter($this->context);
-    $content .= $rewriter->rewrite($viewContent, $gadget);
-
-    // And add our runOnLoadHandlers() call
-    $content .= "\n<script>gadgets.util.runOnLoadHandlers();</script></body>\n</html>";
-
-    echo $content;
+    $script .= "\n";
+    $script .= $this->appendJsConfig($this->gadget, count($forcedJsLibs));
+    $script .= $this->appendMessages($this->gadget);
+    $script .= $this->appendPreloads($this->gadget);
+
+    $scriptNode = $doc->createElement('script');
+    $scriptNode->nodeValue = $script;
+    $node->appendChild($scriptNode);
   }
 
   /**

Modified: incubator/shindig/trunk/php/src/gadgets/rewrite/GadgetRewriter.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/rewrite/GadgetRewriter.php?rev=764191&r1=764190&r2=764191&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/rewrite/GadgetRewriter.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/rewrite/GadgetRewriter.php Sat Apr 11 10:36:09 2009
@@ -25,6 +25,7 @@
  */
 class GadgetRewriter {
   private $context;
+  private $doc;
   private $domObservers = array();
 
   public function __construct(GadgetContext $context) {
@@ -44,42 +45,35 @@
       $contentRewriter = new ContentRewriter($this->context, $gadget);
       $contentRewriter->register($this);
     }
-
     // Are we configured to sanitize certain views? (if so the config should be an array of view names to sanitize, iaw: array('profile', 'home'))
     if (is_array(Config::get('sanitize_views'))) {
       require_once "src/gadgets/rewrite/SanitizeRewriter.php";
       $sanitizeRewriter = new SanitizeRewriter($this->context, $gadget);
       $sanitizeRewriter->register($this);
     }
-
     // no observers registered, return the original content, otherwise parse the DOM tree and call the observers
-    if (!count($this->domObservers)) {
+    if (! count($this->domObservers)) {
       return $content;
     } else {
       libxml_use_internal_errors(true);
-      $doc = new DOMDocument(null, 'utf-8');
-      $doc->preserveWhiteSpace = false;
-      $doc->formatOutput = false;
-      $doc->strictErrorChecking = false;
-      $doc->recover = false;
-      if (! $doc->loadHtml($content)) {
+      $this->doc = new DOMDocument(null, 'utf-8');
+      $this->doc->preserveWhiteSpace = true;
+      $this->doc->formatOutput = false;
+      $this->doc->strictErrorChecking = false;
+      $this->doc->recover = false;
+      if (! $this->doc->loadHtml($content)) {
         // parsing failed, return the unmodified content
         return $content;
       }
-
       // find and parse all nodes in the dom document
-      $rootNodes = $doc->getElementsByTagName('*');
+      $rootNodes = $this->doc->getElementsByTagName('*');
       $this->parseNodes($rootNodes);
-
       // DomDocument tries to make the document a valid html document, so added the html/body/head elements to it.. so lets strip them off before returning the content
-      $html = $doc->saveHTML();
-      $html = preg_replace('/^<!DOCTYPE.+?>/', '', str_replace(array('&amp;', '<head>', '</head>', '<html>', '</html>', '<body>', '</body>'), array('&', '', '', '', '', '', ''), $html));
-
+      $html = $this->doc->saveHTML();
       // If the gadget specified the caja feature, cajole it
       if (in_array('caja', $gadget->features)) {
         //TODO : use the caja daemon to cajole the content (experimental patch is available and will be added soon)
       }
-
       return $html;
     }
   }
@@ -92,7 +86,7 @@
    * @param object instance $class
    * @param string $function
    */
-  public function addObserver($tag, DomRewriter $class, $function) {
+  public function addObserver($tag, $class, $function) {
     // add the tag => function to call relationship to our $observers array
     $this->domObservers[] = array('tag' => $tag, 'class' => $class, 'function' => $function);
   }
@@ -109,7 +103,7 @@
         if ($observer['tag'] == $tagName) {
           $class = $observer['class'];
           $function = $observer['function'];
-          $class->$function($node);
+          $class->$function($node, $this->doc);
         }
       }
     }