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);
}
}