You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by ch...@apache.org on 2008/06/29 02:52:53 UTC

svn commit: r672597 - in /incubator/shindig/trunk/php/src/gadgets: GadgetFeatureRegistry.php GadgetServer.php JsLibrary.php http/GadgetRenderingServlet.php http/JsServlet.php

Author: chabotc
Date: Sat Jun 28 17:52:53 2008
New Revision: 672597

URL: http://svn.apache.org/viewvc?rev=672597&view=rev
Log:
Reworked forced JS lib support once more, this time got it right in all border cases,
sometimes dependencies were being included externally and inlined too, or no inlining
at all, after this patch all the tests i was able to throw at it worked perfectly.

Also changed the version param (?v=) to create the md5 based on _all_ javascripts, before
this only included the inlined javascripts of a gadget, so changed based on the features
included in the gadget xml, which was bad for browser cachability since it led to having
a bunch of different ones. Since this is a 'heavy' operation it's fully cached so not to
impact the performance.

Now that the inclusion order is completely fixed, i've moved the runOnLoadHandlers() back
to the document bottom instead of being fired on the window.onload event, gives back that
extra crisp snappy feeling that we'd otherwise have to miss.

Bunch of small changes include removing some old comments, the RESOURCE JS lib type (which
php doesn't have) and fixed an ugly bug in the preloader code where it would fail if there
were multiple URL's preloaded (somehow they were being appended as strings instead of
having a propper json array)


Modified:
    incubator/shindig/trunk/php/src/gadgets/GadgetFeatureRegistry.php
    incubator/shindig/trunk/php/src/gadgets/GadgetServer.php
    incubator/shindig/trunk/php/src/gadgets/JsLibrary.php
    incubator/shindig/trunk/php/src/gadgets/http/GadgetRenderingServlet.php
    incubator/shindig/trunk/php/src/gadgets/http/JsServlet.php

Modified: incubator/shindig/trunk/php/src/gadgets/GadgetFeatureRegistry.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/GadgetFeatureRegistry.php?rev=672597&r1=672596&r2=672597&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/GadgetFeatureRegistry.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/GadgetFeatureRegistry.php Sat Jun 28 17:52:53 2008
@@ -102,9 +102,7 @@
 			return;
 		}
 		foreach ($feature->deps as $dep) {
-			/*
-			 * TODO: Temporal fix, double check where empty dependencies are being added
-			 */
+			 //TODO: Temporal fix, double check where empty dependencies are being added
 			if (! empty($dep)) {
 				$this->addFeatureToResults($results, $this->features[$dep]);
 			}

Modified: incubator/shindig/trunk/php/src/gadgets/GadgetServer.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/GadgetServer.php?rev=672597&r1=672596&r2=672597&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/GadgetServer.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/GadgetServer.php Sat Jun 28 17:52:53 2008
@@ -19,11 +19,6 @@
  *
  */
 
-/*
- * This isn't a multi threaded java envirioment, so we do things a bit more straightforward with context blocks and workflows,
- * which means departing from how the shinding java implementation works but it saves a lot 'dead' code here
- */
-
 class GadgetServer {
 
 	public function processGadget($context)

Modified: incubator/shindig/trunk/php/src/gadgets/JsLibrary.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/JsLibrary.php?rev=672597&r1=672596&r2=672597&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/JsLibrary.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/JsLibrary.php Sat Jun 28 17:52:53 2008
@@ -19,7 +19,7 @@
  */
 
 class JsLibrary {
-	private $types = array('FILE', 'RESOURCE', 'URL', 'INLINE');
+	private $types = array('FILE', 'URL', 'INLINE');
 	private $type;
 	private $content;
 	private $featureName; // used to track what feature this belongs to

Modified: incubator/shindig/trunk/php/src/gadgets/http/GadgetRenderingServlet.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/http/GadgetRenderingServlet.php?rev=672597&r1=672596&r2=672597&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/http/GadgetRenderingServlet.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/http/GadgetRenderingServlet.php Sat Jun 28 17:52:53 2008
@@ -154,31 +154,40 @@
 		if (! $view->getQuirks()) {
 			echo "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n";
 		}
-		echo "<html><head><style type=\"text/css\">" . Config::get('gadget_css') . "</style></head>";
+		echo "<html><head><style type=\"text/css\">" . Config::get('gadget_css') . "</style></head><body>\n";
 		// Forced libs first.
 		if (! empty($forcedLibs)) {
 			$libs = explode(':', $forcedLibs);
-			echo "\n".sprintf($externFmt, Config::get('default_js_prefix') . $this->getJsUrl($libs, $gadget)) . "\n";
+			echo sprintf($externFmt, Config::get('default_js_prefix') . $this->getJsUrl($libs, $gadget)."&container=".$context->getContainer()) . "\n";
+		}
+		echo "<script>\n";
+		
+		if (!empty($forcedLibs)) {
+			// if some of the feature libraries are externalized (through a browser cachable <script src="/gadgets/js/opensocial-0.7:settitle.js">
+			// type url), then we don't want to include dependencies twice, so find the complete features chain, so we can skip over those
+			$forcedLibsArray = explode(':', $forcedLibs);
+			$registry = $this->context->getRegistry();
+			$missing = array();
+			$registry->getIncludedFeatures($forcedLibsArray, $forcedLibsArray, $missing);
 		}
-		echo "<script><!--\n";
 		foreach ($gadget->getJsLibraries() as $library) {
 			$type = $library->getType();
 			if ($type == 'URL') {
 				// TODO: This case needs to be handled more gracefully by the js
 				// servlet. We should probably inline external JS as well.
 				$externJs .= sprintf($externFmt, $library->getContent()) . "\n";
-			} elseif (empty($forcedLibs)) {
+			// else check if there are no forcedLibs, or if it wasn't included in their dep chain
+			} elseif (empty($forcedLibs) || !in_array($library->getFeatureName(), $forcedLibsArray)) {
 				echo $library->getContent();
 			}
 			// otherwise it was already included by config.forceJsLibs.
 		}
-		echo "\n--></script>\n";
+		echo $this->appendJsConfig($context, $gadget, !empty($forcedLibs)) . $this->appendMessages($gadget) . 
+			 $this->appendPreloads($gadget, $context).
+			 "</script>";
 		if (strlen($externJs) > 0) {
 			echo $externJs;
-		}
-		echo "\n<script><!--\n".
-			$this->appendJsConfig($context, $gadget) . $this->appendMessages($gadget) . $this->appendPreloads($gadget, $context).
-			"\n--></script>\n<body onload='gadgets.util.runOnLoadHandlers();'>\n";
+		}	
 		$gadgetExceptions = array();
 		$content = $gadget->getSubstitutions()->substitute($view->getContent());
 		if (empty($content)) {
@@ -188,7 +197,8 @@
 		if (count($gadgetExceptions)) {
 			throw new GadgetException(print_r($gadgetExceptions, true));
 		}
-		echo $content . "\n</body>\n</html>";
+		echo $content . 
+			 "\n<script>gadgets.util.runOnLoadHandlers();</script></body>\n</html>";
 	}
 
 	/**
@@ -287,29 +297,43 @@
 				$buf .= $lib;
 			}
 		}
-		// Build a version string from the sha1() checksum of all included javascript
-		// to ensure the client always has the right version
-		$inlineJs = '';
-		foreach ($gadget->getJsLibraries() as $library) {
-			$type = $library->getType();
-			if ($type != 'URL') {
-				$inlineJs .= $library->getContent() . "\n";
+		$cache = $this->context->getCache();
+		if (($md5 = $cache->get(md5('getJsUrlMD5'))) === false) {
+			$registry = $this->context->getRegistry();
+			$features = $registry->getAllFeatures();
+			// Build a version string from the md5() checksum of all included javascript
+			// to ensure the client always has the right version
+			$inlineJs = '';
+			foreach ($features as $feature) {
+				$library = $feature->getFeature();
+				$libs = $library->getLibraries($this->context->getRenderingContext());
+				foreach ($libs as $lib) {
+					$inlineJs .= $lib->getContent();
+				}
 			}
+			$md5 = md5($inlineJs);
+			$cache->set(md5('getJsUrlMD5'), $md5);
 		}
-		$buf .= ".js?v=" . md5($inlineJs);
+		$buf .= ".js?v=" . $md5;
 		return $buf;
 	}
 
-	private function appendJsConfig($context, $gadget)
+	private function appendJsConfig($context, $gadget, $hasForcedLibs)
 	{
 		$container = $context->getContainer();
 		$containerConfig = $context->getContainerConfig();
-		$gadgetConfig = array();
-		$featureConfig = $containerConfig->getConfig($container, 'gadgets.features');
-		foreach ($gadget->getJsLibraries() as $library) {
-			$feature = $library->getFeatureName();
-			if (! isset($gadgetConfig[$feature]) && ! empty($featureConfig[$feature])) {
-				$gadgetConfig[$feature] = $featureConfig[$feature];
+		//TODO some day we should parse the forcedLibs too, and include their config selectivly as well
+		// for now we just include everything if forced libs is set.
+		if ($hasForcedLibs) {
+			$gadgetConfig = $containerConfig->getConfig($container, 'gadgets.features');
+		} else {
+			$gadgetConfig = array();
+			$featureConfig = $containerConfig->getConfig($container, 'gadgets.features');
+			foreach ($gadget->getJsLibraries() as $library) {
+				$feature = $library->getFeatureName();
+				if (! isset($gadgetConfig[$feature]) && ! empty($featureConfig[$feature])) {
+					$gadgetConfig[$feature] = $featureConfig[$feature];
+				}
 			}
 		}
 		return "gadgets.config.init(" . json_encode($gadgetConfig) . ");\n";
@@ -366,17 +390,16 @@
 							echo "<html><body><h1>" . "500 - Internal Server Error" . "</h1></body></html>";
 							die();
 					}
-					$json = array(
-							$preload->getHref() => array(
-									'body' => $response->getResponseContent(), 
-									'rc' => $response->getHttpCode()));
-					$resp .= json_encode($json);
+					$resp[$preload->getHref()] = array(
+						'body' => $response->getResponseContent(), 
+						'rc' => $response->getHttpCode()
+					);
 				}
 			} catch (Exception $e) {
 				throw new Exception($e);
 			}
 		}
-		$resp = $resp == '' ? "{}" : $resp;
+		$resp = count($resp) ? json_encode($resp) : "{}";
 		return "gadgets.io.preloaded_ = " . $resp . ";\n";
 	}
 

Modified: incubator/shindig/trunk/php/src/gadgets/http/JsServlet.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/http/JsServlet.php?rev=672597&r1=672596&r2=672597&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/http/JsServlet.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/http/JsServlet.php Sat Jun 28 17:52:53 2008
@@ -27,7 +27,8 @@
 
 /**
  * This event handler deals with the /js/core:caja:etc.js request which content type=url gadgets can use
- * to retrieve our features javascript code
+ * to retrieve our features javascript code, or used to make the most frequently used part of the feature
+ * library external, and hence cachable by the browser
  */
 class JsServlet extends HttpServlet {
 
@@ -37,6 +38,7 @@
 		if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
 			header("HTTP/1.1 304 Not Modified");
 			header('Content-Length: 0');
+			ob_end_clean();
 			die();
 		}
 		$uri = strtolower($_SERVER["REQUEST_URI"]);
@@ -71,7 +73,7 @@
 							$jsLib = $feature;
 							foreach ($jsLib->getLibraries($context) as $lib) {
 								if ($lib->getType() != 'URL') {
-									$jsData .= $lib->getContent();
+									$jsData .= $lib->getContent()."\n";
 								}
 							}
 						}
@@ -84,12 +86,10 @@
 				die();
 			}
 			$this->setCachingHeaders();
-			header('Content-Length: ' . strlen($jsData));
 			header("Content-Type: text/javascript");
 			echo $jsData;
 		} else {
 			header("HTTP/1.0 404 Not Found", true);
-		
 		}
 		die();
 	}