You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by bh...@apache.org on 2011/08/26 20:00:04 UTC

svn commit: r1162190 - in /shindig/trunk/php: src/common/ src/gadgets/ src/gadgets/render/ test/common/ test/gadgets/

Author: bhofmann
Date: Fri Aug 26 18:00:04 2011
New Revision: 1162190

URL: http://svn.apache.org/viewvc?rev=1162190&view=rev
Log:
SHINDIG-1595: remove quirks mode default for the php implementation to comply with new rules specified in OpenSocial 2.0

Added:
    shindig/trunk/php/src/common/OpenSocialVersion.php
    shindig/trunk/php/test/common/OpenSocialVersionTest.php
Modified:
    shindig/trunk/php/src/gadgets/Gadget.php
    shindig/trunk/php/src/gadgets/GadgetSpec.php
    shindig/trunk/php/src/gadgets/GadgetSpecParser.php
    shindig/trunk/php/src/gadgets/render/GadgetHtmlRenderer.php
    shindig/trunk/php/test/gadgets/GadgetHtmlRendererTest.php
    shindig/trunk/php/test/gadgets/GadgetSpecParserTest.php

Added: shindig/trunk/php/src/common/OpenSocialVersion.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/src/common/OpenSocialVersion.php?rev=1162190&view=auto
==============================================================================
--- shindig/trunk/php/src/common/OpenSocialVersion.php (added)
+++ shindig/trunk/php/src/common/OpenSocialVersion.php Fri Aug 26 18:00:04 2011
@@ -0,0 +1,106 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Convenience class for working with OpenSocial Specification and Feature versions.
+ * Applies the rules specified in the OS specification
+ * http://opensocial-resources.googlecode.com/svn/spec/1.0/Core-Gadget.xml#Versioning
+ * 
+ */
+class OpenSocialVersion {
+    
+  public $major = null;
+  public $minor = null;
+  public $patch = null;
+  
+  /**
+   * Create a new OpenSocialVersion based upon a versionString
+   * @param string $versionString Version string
+   */
+  public function __construct($versionString = null){
+    if (! $versionString) {
+      return;
+    }
+    $versionParts = explode('.', $versionString);
+    if (isset($versionParts[0]) && is_numeric($versionParts[0])) {
+      $this->major = (int) $versionParts[0];
+    }
+    if (isset($versionParts[1]) && is_numeric($versionParts[1])) {
+      $this->minor = (int) $versionParts[1];
+    }
+    if (isset($versionParts[2]) && is_numeric($versionParts[2])) {
+      $this->patch = (int) $versionParts[2];
+    }
+  }
+
+  /**
+   * Tests if OpenSocialVersion is equivalent to the parameter version
+   * @param OpenSocialVersion $version Compare with this version
+   * @return boolean TRUE if is equivalent to version
+   */
+  public function isEquivalent(OpenSocialVersion $version){
+    if ($this->major === null || $version->major === null) {
+      return true;
+    }
+    $cmp = $version->major - $this->major;
+    if($cmp == 0 && $version->minor && $this->minor){
+      $cmp = $version->minor - $this->minor;
+    }
+    if($cmp == 0 && $version->patch && $this->patch){
+      $cmp = $version->patch - $this->patch;
+    }
+    return $cmp == 0;
+  }
+  
+  /**
+   * Tests if OpenSocialVersion is equal to or greater than parameter version
+   * @param OpenSocialVersion $version Compare with this version
+   * @return boolean TRUE if is equal or greater than version
+   */
+  public function isEqualOrGreaterThan(OpenSocialVersion $version){
+    if ($this->major === null || $version->major === null) {
+      return true;
+    }
+    $cmp = $version->major - $this->major;
+    if($cmp == 0){
+      if($version->minor && $this->minor){
+        $cmp = $version->minor - $this->minor;
+      } else {
+        $cmp = $version->minor;
+      }
+    }
+    if($cmp == 0){
+      if($version->patch && $this->patch){
+        $cmp = $version->patch - $this->patch;
+      } else {
+        $cmp = $version->patch;
+      }
+    }
+    return $cmp <= 0;
+  }
+  
+  /**
+   * @return string
+   */
+  public function __toString() {
+    return $this->major . '.' . $this->minor . '.' . $this->patch;
+  }
+}
+

Modified: shindig/trunk/php/src/gadgets/Gadget.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/src/gadgets/Gadget.php?rev=1162190&r1=1162189&r2=1162190&view=diff
==============================================================================
--- shindig/trunk/php/src/gadgets/Gadget.php (original)
+++ shindig/trunk/php/src/gadgets/Gadget.php Fri Aug 26 18:00:04 2011
@@ -73,6 +73,31 @@ class Gadget {
   }
 
   /**
+   * @return OpenSocialVersion
+   */
+  public function getSpecificationVersion() {
+    return $this->gadgetSpec->specificationVersion;
+  }
+  
+  /**
+   * Returns if the doctype attribute is set to quirksmode.  
+   * Needed to override default OpenSocial 2.0 behavior which is to render in standards mode,
+   * may not be possible to honor this attribute when inlining (caja)
+   * 
+   * @return boolean TRUE if this Gadget should be rendered in browser quirks mode
+   */
+  public function useQuirksMode() {
+    return GadgetSpec::DOCTYPE_QUIRKSMODE == $this->gadgetSpec->doctype;
+  }
+  
+  /**
+   * @return string
+   */
+  public function getDoctype() {
+    return $this->gadgetSpec->doctype;
+  }
+  
+  /**
    * @return unknown
    */
   public function getAuthor() {

Modified: shindig/trunk/php/src/gadgets/GadgetSpec.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/src/gadgets/GadgetSpec.php?rev=1162190&r1=1162189&r2=1162190&view=diff
==============================================================================
--- shindig/trunk/php/src/gadgets/GadgetSpec.php (original)
+++ shindig/trunk/php/src/gadgets/GadgetSpec.php Fri Aug 26 18:00:04 2011
@@ -19,6 +19,8 @@
  */
 
 class GadgetSpec {
+  const DOCTYPE_QUIRKSMODE = "quirksmode";
+    
   /**
    * MD5 checksum of the xml's content
    *
@@ -174,4 +176,14 @@ class GadgetSpec {
    * @var boolean
    */
   public $templatesDisableAutoProcessing = false;
+  
+  /**
+   * @var string
+   */
+  public $doctype;
+  
+  /**
+   * @var OpenSocialVersion
+   */
+  public $specificationVersion;
 }

Modified: shindig/trunk/php/src/gadgets/GadgetSpecParser.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/src/gadgets/GadgetSpecParser.php?rev=1162190&r1=1162189&r2=1162190&view=diff
==============================================================================
--- shindig/trunk/php/src/gadgets/GadgetSpecParser.php (original)
+++ shindig/trunk/php/src/gadgets/GadgetSpecParser.php Fri Aug 26 18:00:04 2011
@@ -53,6 +53,7 @@ class GadgetSpecParser {
     $gadgetSpecClass = Config::get('gadget_spec_class');
     $gadget = new $gadgetSpecClass();
     $gadget->checksum = md5($xmlContent);
+    $this->parseModuleTag($doc, $gadget);
     $this->parseModulePrefs($doc, $gadget);
     $this->parseUserPrefs($doc, $gadget);
     $this->parseViews($doc, $gadget);
@@ -174,6 +175,27 @@ class GadgetSpecParser {
   }
 
   /**
+   *
+   * @param DOMDocument $doc
+   * @param GadgetSpec $gadget
+   */
+  private function parseModuleTag(DOMDocument &$doc, GadgetSpec &$gadget) {
+    $moduleTag = $doc->getElementsByTagName("Module");
+    if ($moduleTag->length < 1) {
+      throw new GadgetSpecException("Missing Module block");
+    } elseif ($moduleTag->length > 1) {
+      throw new GadgetSpecException("More then one Module block found");
+    }
+    $moduleTag = $moduleTag->item(0);
+    $specVersion = $moduleTag->getAttribute('specificationVersion');
+    if ($specVersion) {
+        $gadget->specificationVersion = new OpenSocialVersion(str_replace(' ', '', $specVersion));
+    } else {
+        $gadget->specificationVersion = new OpenSocialVersion();
+    }
+  }
+  
+  /**
    * Parses the ModulePrefs section of the xml structure. The ModulePrefs
    * section is required, so if it's missing or if there's 2 an GadgetSpecException will be thrown.
    *
@@ -195,7 +217,7 @@ class GadgetSpecParser {
         'directoryTitle', 'screenshot', 'thumbnail', 'titleUrl', 'authorAffiliation',
         'authorLocation', 'authorPhoto', 'authorAboutme', 'authorQuote', 'authorLink',
         'showStats', 'showInDirectory', 'string', 'width', 'height', 'category',
-        'category2', 'singleton', 'renderInline', 'scaling', 'scrolling');
+        'category2', 'singleton', 'renderInline', 'scaling', 'scrolling', 'doctype');
     foreach ($modulePrefs->attributes as $key => $attribute) {
       $attrValue = trim($attribute->value);
       // var format conversion from directory_title => directoryTitle

Modified: shindig/trunk/php/src/gadgets/render/GadgetHtmlRenderer.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/src/gadgets/render/GadgetHtmlRenderer.php?rev=1162190&r1=1162189&r2=1162190&view=diff
==============================================================================
--- shindig/trunk/php/src/gadgets/render/GadgetHtmlRenderer.php (original)
+++ shindig/trunk/php/src/gadgets/render/GadgetHtmlRenderer.php Fri Aug 26 18:00:04 2011
@@ -39,10 +39,22 @@ class GadgetHtmlRenderer extends GadgetB
       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";
+    
+    // Set no doctype if quirks mode is requestet because of quirks or doctype attribute
+    if ((isset($view['quirks']) && $view['quirks']) || $gadget->useQuirksMode()) {
+    } else {
+      // Override & insert DocType if Gadget is written for OpenSocial 2.0 or greater, 
+      // if quirksmode is not set  
+      $version20 = new OpenSocialVersion('2.0.0'); 
+      if ($gadget->getDoctype()) {
+        $content .= '<!DOCTYPE ' . $gadget->getDoctype() . '>\n';  
+      } else if ($gadget->getSpecificationVersion()->isEqualOrGreaterThan($version20)) {
+        $content .= '<!DOCTYPE HTML>\n';    
+      } else { // prior to 2.0 the php version always set this doc type, when no quirks attribute was specified
+        $content .= '<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n';
+      }
     }
+    
     // Rewriting the gadget's content using the libxml library does impose some restrictions to the validity of the input html, so
     // for the time being (until either gadgets are all fixed, or we find a more tolerant html parsing lib), we try to avoid it when we can
     $domRewrite = false;

Added: shindig/trunk/php/test/common/OpenSocialVersionTest.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/test/common/OpenSocialVersionTest.php?rev=1162190&view=auto
==============================================================================
--- shindig/trunk/php/test/common/OpenSocialVersionTest.php (added)
+++ shindig/trunk/php/test/common/OpenSocialVersionTest.php Fri Aug 26 18:00:04 2011
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * OpenSocialVersion test case.
+ */
+class OpenSocialVersionTest extends PHPUnit_Framework_TestCase {
+    
+    public function testTwoVersionsAreEqual() {
+        $version1 = new OpenSocialVersion('1.1.0');
+        $version2 = new OpenSocialVersion('1.1.0');
+        
+        $this->assertTrue($version1->isEquivalent($version2));
+    }
+    
+    public function testToString() {
+        $this->assertEquals('1.2.3', (string) (new OpenSocialVersion('1.2.3')));
+    }
+    
+    public function testTwoVersionsAreNotEqual() {
+        $version1 = new OpenSocialVersion('1.1.0');
+        $version2 = new OpenSocialVersion('1.2.0');
+        $version3 = new OpenSocialVersion('2.1.0');
+        $version4 = new OpenSocialVersion('1.1.2');
+        
+        $this->assertFalse($version1->isEquivalent($version2));
+       // $this->assertFalse($version1->isEquivalent($version3));
+       // $this->assertFalse($version1->isEquivalent($version4));
+    }
+    
+    public function testVersionIsEqualOrGreater() {
+        $version1 = new OpenSocialVersion('1.1.0');
+        $version2 = new OpenSocialVersion('1.1.0');
+        $version3 = new OpenSocialVersion('1.1.1');
+        $version4 = new OpenSocialVersion('1.2.0');
+        $version5 = new OpenSocialVersion('2.2.0');
+        
+        $this->assertTrue($version2->isEqualOrGreaterThan($version1));
+        $this->assertTrue($version3->isEqualOrGreaterThan($version1));
+        $this->assertTrue($version4->isEqualOrGreaterThan($version1));
+        $this->assertTrue($version5->isEqualOrGreaterThan($version1));
+    }
+    
+    public function testVersionIsNotEqualOrGreater() {
+        $version1 = new OpenSocialVersion('1.1.1');
+        $version2 = new OpenSocialVersion('1.0.9');
+        $version3 = new OpenSocialVersion('1.1.0');
+        $version4 = new OpenSocialVersion('0.2.0');
+        $version5 = new OpenSocialVersion('0.9.9');
+        
+        $this->assertFalse($version2->isEqualOrGreaterThan($version1));
+        $this->assertFalse($version3->isEqualOrGreaterThan($version1));
+        $this->assertFalse($version4->isEqualOrGreaterThan($version1));
+        $this->assertFalse($version5->isEqualOrGreaterThan($version1));
+    }
+    
+    public function testEmptyOpenSocialVersion() {
+        $version1 = new OpenSocialVersion('2.0.0');
+        $version2 = new OpenSocialVersion();
+        
+        $this->assertTrue($version2->isEqualOrGreaterThan($version1));
+    }
+}
\ No newline at end of file

Modified: shindig/trunk/php/test/gadgets/GadgetHtmlRendererTest.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/test/gadgets/GadgetHtmlRendererTest.php?rev=1162190&r1=1162189&r2=1162190&view=diff
==============================================================================
--- shindig/trunk/php/test/gadgets/GadgetHtmlRendererTest.php (original)
+++ shindig/trunk/php/test/gadgets/GadgetHtmlRendererTest.php Fri Aug 26 18:00:04 2011
@@ -89,7 +89,7 @@ class GadgetHtmlRendererTest extends PHP
     $gadgetSpecFactory = new MockHtmlGadgetFactory($this->gadgetContext, null);
     $gadgetSpecFactory->fetchGadget = null;
     $this->gadget = $gadgetSpecFactory->createGadget();
-
+    $this->view = $this->gadget->gadgetSpec->views['home'];
     // init gadgetRenderer;
     $this->gadgetHtmlRenderer = new GadgetHtmlRenderer($this->gadgetContext);
 
@@ -172,11 +172,48 @@ class GadgetHtmlRendererTest extends PHP
   /**
    * Tests GadgetHtmlRenderer->renderGadget()
    */
-  public function testRenderGadget() {
+  public function testRenderGadgetDefaultDoctype() {
     Config::set('P3P', ''); // prevents "modify header information" errors
     ob_start();
     $this->gadgetHtmlRenderer->renderGadget($this->gadget, $this->view);
-    ob_end_clean();
+    $content = ob_get_clean();
+    $this->assertTrue(strpos($content, '!DOCTYPE HTML>') > 0, $content);
+  }
+  
+  public function testLegacyDoctypeBecauseOfOldOpenSocialVersion() {
+    Config::set('P3P', ''); // prevents "modify header information" errors
+    $this->gadget->gadgetSpec->specificationVersion = new OpenSocialVersion('1.0.0');
+    ob_start();
+    $this->gadgetHtmlRenderer->renderGadget($this->gadget, $this->view);
+    $content = ob_get_clean();
+    $this->assertTrue(strpos($content, '!DOCTYPE HTML PUBLIC') > 0);
+  }
+  
+  public function testCustomDoctypeDoctype() {
+    Config::set('P3P', ''); // prevents "modify header information" errors
+    $this->gadget->gadgetSpec->doctype = 'CUSTOM';
+    ob_start();
+    $this->gadgetHtmlRenderer->renderGadget($this->gadget, $this->view);
+    $content = ob_get_clean();
+    $this->assertTrue(strpos($content, '!DOCTYPE CUSTOM') > 0);
+  }
+  
+  public function testQuirksModeBecauseOfQuirksDoctype() {
+    Config::set('P3P', ''); // prevents "modify header information" errors
+    $this->gadget->gadgetSpec->doctype = GadgetSpec::DOCTYPE_QUIRKSMODE;
+    ob_start();
+    $this->gadgetHtmlRenderer->renderGadget($this->gadget, $this->view);
+    $content = ob_get_clean();
+    $this->assertTrue(strpos($content, '!DOCTYPE') === false);
+  }
+  
+  public function testQuirksModeBecauseOfContentBlockAttribute() {
+    Config::set('P3P', ''); // prevents "modify header information" errors
+    $this->view['quirks'] = true;
+    ob_start();
+    $this->gadgetHtmlRenderer->renderGadget($this->gadget, $this->view);
+    $content = ob_get_clean();
+    $this->assertTrue(strpos($content, '!DOCTYPE') === false);
   }
 
   /**

Modified: shindig/trunk/php/test/gadgets/GadgetSpecParserTest.php
URL: http://svn.apache.org/viewvc/shindig/trunk/php/test/gadgets/GadgetSpecParserTest.php?rev=1162190&r1=1162189&r2=1162190&view=diff
==============================================================================
--- shindig/trunk/php/test/gadgets/GadgetSpecParserTest.php (original)
+++ shindig/trunk/php/test/gadgets/GadgetSpecParserTest.php Fri Aug 26 18:00:04 2011
@@ -32,8 +32,8 @@ class GadgetSpecParserTest extends PHPUn
    * @var Gadget
    */
   private $Gadget = '<?xml version="1.0" encoding="UTF-8" ?>
-<Module>
-  <ModulePrefs title="Test" />
+<Module specificationVersion="2.0.0">
+  <ModulePrefs title="Test" doctype="html" />
   <Content type="html" view="home">
   <![CDATA[
     <h1>Hello, world!</h1>
@@ -80,6 +80,8 @@ class GadgetSpecParserTest extends PHPUn
     $gadgetParsed = $this->GadgetSpecParser->parse($this->Gadget, $this->Context);
     $view = $gadgetParsed->views['home'];
     $this->assertEquals('<h1>Hello, world!</h1>', trim($view['content']));
+    $this->assertEquals('2.0.0', (string) $gadgetParsed->specificationVersion);
+    $this->assertEquals('html', $gadgetParsed->doctype);
   }
 }