[Zope3-checkins] SVN: Zope3/branches/tal_mixed_mode/src/zope/pagetemplate/ Enhance the page template input type sniffer. You don't need to add the xml header no more. It checks now the xmlns declarations as well. This is especially here to avoid IE quirks mode with the xml header presence.

Julien Anguenot ja at nuxeo.com
Fri Oct 14 12:22:40 EDT 2005


Log message for revision 39451:
  Enhance the page template input type sniffer. You don't need to add the xml header no more. It checks now the xmlns declarations as well. This is especially here to avoid IE quirks mode with the xml header presence.

Changed:
  U   Zope3/branches/tal_mixed_mode/src/zope/pagetemplate/pagetemplatefile.py
  U   Zope3/branches/tal_mixed_mode/src/zope/pagetemplate/tests/test_ptfile.py
  A   Zope3/branches/tal_mixed_mode/src/zope/pagetemplate/typesniffer.py

-=-
Modified: Zope3/branches/tal_mixed_mode/src/zope/pagetemplate/pagetemplatefile.py
===================================================================
--- Zope3/branches/tal_mixed_mode/src/zope/pagetemplate/pagetemplatefile.py	2005-10-14 16:15:26 UTC (rev 39450)
+++ Zope3/branches/tal_mixed_mode/src/zope/pagetemplate/pagetemplatefile.py	2005-10-14 16:22:40 UTC (rev 39451)
@@ -27,6 +27,8 @@
 
 from zope.pagetemplate.pagetemplate import PageTemplate
 
+from typesniffer import sniff_type
+from typesniffer import XML_PREFIX_MAX_LENGTH
 
 DEFAULT_ENCODING = "utf-8"
 
@@ -79,17 +81,17 @@
         except:
             f.close()
             raise
-        type = sniff_type(text)
-        if type == "text/xml":
+        type_ = sniff_type(text)
+        if type_ == "text/xml":
             text += f.read()
         else:
             # For HTML, we really want the file read in text mode:
             f.close()
             f = open(self.filename)
             text = f.read()
-            text, type = self._prepare_html(text)
+            text, type_ = self._prepare_html(text)
         f.close()
-        return text, type
+        return text, type_
 
     def _cook_check(self):
         if self._v_last_read and not __debug__:
@@ -115,22 +117,3 @@
 
     def __getstate__(self):
         raise TypeError("non-picklable object")
-
-
-XML_PREFIXES = [
-    "<?xml",                      # ascii, utf-8
-    "\xef\xbb\xbf<?xml",          # utf-8 w/ byte order mark
-    "\0<\0?\0x\0m\0l",            # utf-16 big endian
-    "<\0?\0x\0m\0l\0",            # utf-16 little endian
-    "\xfe\xff\0<\0?\0x\0m\0l",    # utf-16 big endian w/ byte order mark
-    "\xff\xfe<\0?\0x\0m\0l\0",    # utf-16 little endian w/ byte order mark
-    ]
-
-XML_PREFIX_MAX_LENGTH = max(map(len, XML_PREFIXES))
-
-def sniff_type(text):
-    """Return 'text/xml' if text appears to be XML, otherwise return None."""
-    for prefix in XML_PREFIXES:
-        if text.startswith(prefix):
-            return "text/xml"
-    return None

Modified: Zope3/branches/tal_mixed_mode/src/zope/pagetemplate/tests/test_ptfile.py
===================================================================
--- Zope3/branches/tal_mixed_mode/src/zope/pagetemplate/tests/test_ptfile.py	2005-10-14 16:15:26 UTC (rev 39450)
+++ Zope3/branches/tal_mixed_mode/src/zope/pagetemplate/tests/test_ptfile.py	2005-10-14 16:22:40 UTC (rev 39451)
@@ -20,8 +20,8 @@
 import unittest
 
 from zope.pagetemplate.pagetemplatefile import PageTemplateFile
+from zope.pagetemplate.typesniffer import sniff_type
 
-
 class TypeSniffingTestCase(unittest.TestCase):
 
     TEMPFILENAME = tempfile.mktemp()
@@ -165,7 +165,32 @@
             u"\u0422\u0435\u0441\u0442"
             u"</title></head></html>\n")
 
+    ##def test_xml_sniffing_from_extension(self):
+    ##    # This checks the extension of the page template
+    ##    this_directory = os.path.split(__file__)[0]
+    ##    filepath = os.path.join(
+    ##        this_directory,
+    ##        'test.xpt')
+    ##    xpt = PageTemplateFile(filepath)
+    ##    self.assert_(os.path.normcase(xpt.filename).endswith('.xpt'))
+    ##    text, type_ = xpt._read_file()
+    ##    self.assertEqual(type_, 'text/xml')
 
+    def test_type_sniffing_based_on_xmlns(self):
+        from zope.pagetemplate.typesniffer import sniff_type
+        self.assertEqual(
+            sniff_type("<doc><element/></doc>"), None)
+        self.assertEqual(
+            sniff_type("<doc xmlns=''><element/></doc>"), 'text/xml')
+        self.assertEqual(
+            sniff_type("<doc><element xmlns=''/></doc>"), 'text/xml')
+        self.assertEqual(
+            sniff_type("<doc xmlns='http://foo/bar'><element/></doc>"),
+            'text/xml')
+        self.assertEqual(
+            sniff_type("<doc ><element xmlns='http://foo/bar'/></doc>"),
+            'text/xml')
+
 def test_suite():
     return unittest.makeSuite(TypeSniffingTestCase)
 

Added: Zope3/branches/tal_mixed_mode/src/zope/pagetemplate/typesniffer.py
===================================================================
--- Zope3/branches/tal_mixed_mode/src/zope/pagetemplate/typesniffer.py	2005-10-14 16:15:26 UTC (rev 39450)
+++ Zope3/branches/tal_mixed_mode/src/zope/pagetemplate/typesniffer.py	2005-10-14 16:22:40 UTC (rev 39451)
@@ -0,0 +1,64 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Type sniffer for page template input
+
+$Id$
+"""
+
+import xml.parsers.expat
+
+XML_PREFIXES = [
+    "<?xml",                      # ascii, utf-8
+    "\xef\xbb\xbf<?xml",          # utf-8 w/ byte order mark
+    "\0<\0?\0x\0m\0l",            # utf-16 big endian
+    "<\0?\0x\0m\0l\0",            # utf-16 little endian
+    "\xfe\xff\0<\0?\0x\0m\0l",    # utf-16 big endian w/ byte order mark
+    "\xff\xfe<\0?\0x\0m\0l\0",    # utf-16 little endian w/ byte order mark
+    ]
+
+XML_PREFIX_MAX_LENGTH = max(map(len, XML_PREFIXES))
+
+class NamespaceFound(Exception):
+    # This exception is throwned by the parser when a namespace is
+    # found to stop the parsing.
+    pass
+
+def StartNamespaceDeclHandler(prefix, url):
+    # Called when an element contains a namespace declaration.
+    raise NamespaceFound
+
+def sniff_type(text):
+    """Return 'text/xml' if text appears to be XML, otherwise return None.
+
+     o if the document contains the xml process header <?xml ... ?>
+     o if the document contains any namespace declarations
+    """
+
+    # Check the xml processing header
+    for prefix in XML_PREFIXES:
+        if text.startswith(prefix):
+            return "text/xml"
+
+    # Check if the document contains any namespace declarations
+    parser = xml.parsers.expat.ParserCreate(namespace_separator=' ')
+    parser.StartNamespaceDeclHandler = StartNamespaceDeclHandler
+    try:
+        parser.Parse(text)
+    except xml.parsers.expat.ExpatError:
+        return None
+    except NamespaceFound:
+        return "text/xml"
+    else:
+        return None
+


Property changes on: Zope3/branches/tal_mixed_mode/src/zope/pagetemplate/typesniffer.py
___________________________________________________________________
Name: svn:keywords
   + Id



More information about the Zope3-Checkins mailing list