Exemplo n.º 1
0
 def __getattr__(self, tagName: str) -> Tag:
     if tagName == "transparent":
         return Tag("")
     # allow for E.del as E.del_
     tagName = tagName.rstrip("_")
     if tagName not in VALID_HTML_TAG_NAMES:
         raise AttributeError(f"unknown tag {tagName!r}")
     return Tag(tagName)
Exemplo n.º 2
0
 def __getattr__(self, tagName):
     if tagName == 'transparent':
         return Tag('')
     # allow for E.del as E.del_
     tagName = tagName.rstrip('_')
     if tagName not in VALID_HTML_TAG_NAMES:
         raise AttributeError('unknown tag %r' % (tagName,))
     return Tag(tagName)
Exemplo n.º 3
0
 def test_serializeUnicode(self):
     """
     Test that unicode is encoded correctly in the appropriate places, and
     raises an error when it occurs in inappropriate place.
     """
     snowman = u'\N{SNOWMAN}'
     return gatherResults([
         self.assertFlattensTo(snowman, '\xe2\x98\x83'),
         self.assertFlattensTo(tags.p(snowman), '<p>\xe2\x98\x83</p>'),
         self.assertFlattensTo(Comment(snowman), '<!--\xe2\x98\x83-->'),
         self.assertFlattensTo(CDATA(snowman), '<![CDATA[\xe2\x98\x83]]>'),
         self.assertFlatteningRaises(Tag(snowman), UnicodeEncodeError),
         self.assertFlatteningRaises(Tag('p', attributes={snowman: ''}),
                                     UnicodeEncodeError),
     ])
Exemplo n.º 4
0
 def test_tagWithoutLocation(self):
     """
     If a L{FlattenerError} is created with a L{Tag} instance without source
     location information, only the tagName is included in the string
     representation of the exception.
     """
     self.assertEqual(
         str(FlattenerError(RuntimeError("reason"), [Tag('span')], [])),
         "Exception while flattening:\n"
         "  Tag <span>\n"
         "RuntimeError: reason\n")
Exemplo n.º 5
0
    def test_tag(self):
        """
        If a L{FlattenerError} is created with a L{Tag} instance with source
        location information, the source location is included in the string
        representation of the exception.
        """
        tag = Tag('div',
                  filename='/foo/filename.xhtml',
                  lineNumber=17,
                  columnNumber=12)

        self.assertEqual(
            str(FlattenerError(RuntimeError("reason"), [tag], [])),
            "Exception while flattening:\n"
            "  File \"/foo/filename.xhtml\", line 17, column 12, in \"div\"\n"
            "RuntimeError: reason\n")
Exemplo n.º 6
0
    def startElementNS(self, namespaceAndName, qname, attrs):
        """
        Gets called when we encounter a new xmlns attribute.

        @param namespaceAndName: a (namespace, name) tuple, where name
            determines which type of action to take, if the namespace matches
            L{TEMPLATE_NAMESPACE}.
        @param qname: ignored.
        @param attrs: attributes on the element being started.
        """

        filename = self.sourceFilename
        lineNumber = self.locator.getLineNumber()
        columnNumber = self.locator.getColumnNumber()

        ns, name = namespaceAndName
        if ns == TEMPLATE_NAMESPACE:
            if name == 'transparent':
                name = ''
            elif name == 'slot':
                try:
                    # Try to get the default value for the slot
                    default = attrs[(None, 'default')]
                except KeyError:
                    # If there wasn't one, then use None to indicate no
                    # default.
                    default = None
                el = slot(
                    attrs[(None, 'name')], default=default,
                    filename=filename, lineNumber=lineNumber,
                    columnNumber=columnNumber)
                self.stack.append(el)
                self.current.append(el)
                self.current = el.children
                return

        render = None

        attrs = OrderedDict(attrs)
        for k, v in items(attrs):
            attrNS, justTheName = k
            if attrNS != TEMPLATE_NAMESPACE:
                continue
            if justTheName == 'render':
                render = v
                del attrs[k]

        # nonTemplateAttrs is a dictionary mapping attributes that are *not* in
        # TEMPLATE_NAMESPACE to their values.  Those in TEMPLATE_NAMESPACE were
        # just removed from 'attrs' in the loop immediately above.  The key in
        # nonTemplateAttrs is either simply the attribute name (if it was not
        # specified as having a namespace in the template) or prefix:name,
        # preserving the xml namespace prefix given in the document.

        nonTemplateAttrs = OrderedDict()
        for (attrNs, attrName), v in items(attrs):
            nsPrefix = self.prefixMap.get(attrNs)
            if nsPrefix is None:
                attrKey = attrName
            else:
                attrKey = '%s:%s' % (nsPrefix, attrName)
            nonTemplateAttrs[attrKey] = v

        if ns == TEMPLATE_NAMESPACE and name == 'attr':
            if not self.stack:
                # TODO: define a better exception for this?
                raise AssertionError(
                    '<{%s}attr> as top-level element' % (TEMPLATE_NAMESPACE,))
            if 'name' not in nonTemplateAttrs:
                # TODO: same here
                raise AssertionError(
                    '<{%s}attr> requires a name attribute' % (TEMPLATE_NAMESPACE,))
            el = Tag('', render=render, filename=filename,
                     lineNumber=lineNumber, columnNumber=columnNumber)
            self.stack[-1].attributes[nonTemplateAttrs['name']] = el
            self.stack.append(el)
            self.current = el.children
            return

        # Apply any xmlns attributes
        if self.xmlnsAttrs:
            nonTemplateAttrs.update(OrderedDict(self.xmlnsAttrs))
            self.xmlnsAttrs = []

        # Add the prefix that was used in the parsed template for non-template
        # namespaces (which will not be consumed anyway).
        if ns != TEMPLATE_NAMESPACE and ns is not None:
            prefix = self.prefixMap[ns]
            if prefix is not None:
                name = '%s:%s' % (self.prefixMap[ns],name)
        el = Tag(
            name, attributes=OrderedDict(nonTemplateAttrs), render=render,
            filename=filename, lineNumber=lineNumber,
            columnNumber=columnNumber)
        self.stack.append(el)
        self.current.append(el)
        self.current = el.children
Exemplo n.º 7
0
    def startElementNS(
        self,
        namespaceAndName: Tuple[str, str],
        qname: Optional[str],
        attrs: Mapping[Tuple[Optional[str], str], str],
    ) -> None:
        """
        Gets called when we encounter a new xmlns attribute.

        @param namespaceAndName: a (namespace, name) tuple, where name
            determines which type of action to take, if the namespace matches
            L{TEMPLATE_NAMESPACE}.
        @param qname: ignored.
        @param attrs: attributes on the element being started.
        """

        filename = self.sourceFilename
        lineNumber = self.locator.getLineNumber()
        columnNumber = self.locator.getColumnNumber()

        ns, name = namespaceAndName
        if ns == TEMPLATE_NAMESPACE:
            if name == "transparent":
                name = ""
            elif name == "slot":
                default: Optional[str]
                try:
                    # Try to get the default value for the slot
                    default = attrs[(None, "default")]
                except KeyError:
                    # If there wasn't one, then use None to indicate no
                    # default.
                    default = None
                sl = slot(
                    attrs[(None, "name")],
                    default=default,
                    filename=filename,
                    lineNumber=lineNumber,
                    columnNumber=columnNumber,
                )
                self.stack.append(sl)
                self.current.append(sl)
                self.current = sl.children
                return

        render = None

        attrs = OrderedDict(attrs)
        for k, v in list(attrs.items()):
            attrNS, justTheName = k
            if attrNS != TEMPLATE_NAMESPACE:
                continue
            if justTheName == "render":
                render = v
                del attrs[k]

        # nonTemplateAttrs is a dictionary mapping attributes that are *not* in
        # TEMPLATE_NAMESPACE to their values.  Those in TEMPLATE_NAMESPACE were
        # just removed from 'attrs' in the loop immediately above.  The key in
        # nonTemplateAttrs is either simply the attribute name (if it was not
        # specified as having a namespace in the template) or prefix:name,
        # preserving the xml namespace prefix given in the document.

        nonTemplateAttrs = OrderedDict()
        for (attrNs, attrName), v in attrs.items():
            nsPrefix = self.prefixMap.get(attrNs)
            if nsPrefix is None:
                attrKey = attrName
            else:
                attrKey = f"{nsPrefix}:{attrName}"
            nonTemplateAttrs[attrKey] = v

        if ns == TEMPLATE_NAMESPACE and name == "attr":
            if not self.stack:
                # TODO: define a better exception for this?
                raise AssertionError(
                    f"<{{{TEMPLATE_NAMESPACE}}}attr> as top-level element")
            if "name" not in nonTemplateAttrs:
                # TODO: same here
                raise AssertionError(
                    f"<{{{TEMPLATE_NAMESPACE}}}attr> requires a name attribute"
                )
            el = Tag(
                "",
                render=render,
                filename=filename,
                lineNumber=lineNumber,
                columnNumber=columnNumber,
            )
            self.stack[-1].attributes[nonTemplateAttrs["name"]] = el
            self.stack.append(el)
            self.current = el.children
            return

        # Apply any xmlns attributes
        if self.xmlnsAttrs:
            nonTemplateAttrs.update(OrderedDict(self.xmlnsAttrs))
            self.xmlnsAttrs = []

        # Add the prefix that was used in the parsed template for non-template
        # namespaces (which will not be consumed anyway).
        if ns != TEMPLATE_NAMESPACE and ns is not None:
            prefix = self.prefixMap[ns]
            if prefix is not None:
                name = "{}:{}".format(self.prefixMap[ns], name)
        el = Tag(
            name,
            attributes=OrderedDict(
                cast(Mapping[Union[bytes, str], str], nonTemplateAttrs)),
            render=render,
            filename=filename,
            lineNumber=lineNumber,
            columnNumber=columnNumber,
        )
        self.stack.append(el)
        self.current.append(el)
        self.current = el.children