# -*- coding: utf-8 -*- # Copyright JS Foundation and other contributors, https://js.foundation/ # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from __future__ import absolute_import, unicode_literals
from .compat import uchr from .character import Character from . import jsx_nodes as JSXNode from .jsx_syntax import JSXSyntax from . import nodes as Node from .parser import Marker, Parser from .token import Token, TokenName from .xhtml_entities import XHTMLEntities
class MetaJSXElement(object): def __init__(self, node=None, opening=None, closing=None, children=None):
self.node = node
self.opening = opening
self.closing = closing
self.children = children
class JSXToken(object):
Identifier = 100
Text = 101
class RawJSXToken(object): def __init__(self, type=None, value=None, lineNumber=None, lineStart=None, start=None, end=None):
self.type = type
self.value = value
self.lineNumber = lineNumber
self.lineStart = lineStart
self.start = start
self.end = end
# Fully qualified element name, e.g. <svg:path> returns "svg:path" def getQualifiedElementName(elementName):
typ = elementName.type if typ is JSXSyntax.JSXIdentifier:
id = elementName
qualifiedName = id.name elif typ is JSXSyntax.JSXNamespacedName:
ns = elementName
qualifiedName = getQualifiedElementName(ns.namespace) + ':' + getQualifiedElementName(ns.name) elif typ is JSXSyntax.JSXMemberExpression:
expr = elementName
qualifiedName = getQualifiedElementName(expr.object) + '.' + getQualifiedElementName(expr.property)
if valid and terminated and len(result) > 2: # e.g. 'A' becomes just '#x41'
st = result[1:-1] if numeric and len(st) > 1:
result = uchr(int(st[1:], 10)) elif hex and len(st) > 2:
result = uchr(int(st[2:], 16)) elifnot numeric andnot hex and st in XHTMLEntities:
result = XHTMLEntities[st]
return result
# Scan the next JSX token. This replaces Scanner#lex when in JSX mode.
# ... or . if ch == '.':
start = self.scanner.index if self.scanner.source[start + 1:start + 3] == '..':
value = '...'
self.scanner.index += 3 else:
value = '.'
self.scanner.index += 1 return RawJSXToken(
type=Token.Punctuator,
value=value,
lineNumber=self.scanner.lineNumber,
lineStart=self.scanner.lineStart,
start=start,
end=self.scanner.index
)
# ` if ch == '`': # Only placeholder, since it will be rescanned as a real assignment expression. return RawJSXToken(
type=Token.Template,
value='',
lineNumber=self.scanner.lineNumber,
lineStart=self.scanner.lineStart,
start=self.scanner.index,
end=self.scanner.index
)
# Identifer can not contain backslash (char code 92). if Character.isIdentifierStart(ch) and ch != '\\':
start = self.scanner.index
self.scanner.index += 1 whilenot self.scanner.eof():
ch = self.scanner.source[self.scanner.index] if Character.isIdentifierPart(ch) and ch != '\\':
self.scanner.index += 1 elif ch == '-': # Hyphen (char code 45) can be part of an identifier.
self.scanner.index += 1 else: break
def parseJSXAttributeValue(self): if self.matchJSX('{'): return self.parseJSXExpressionAttribute() if self.matchJSX('<'): return self.parseJSXElement()
return self.parseJSXStringLiteralAttribute()
def parseJSXNameValueAttribute(self):
node = self.createJSXNode()
name = self.parseJSXAttributeName()
value = None if self.matchJSX('='):
self.expectJSX('=')
value = self.parseJSXAttributeValue()
if self.scanner.source[self.scanner.index] == '{':
container = self.parseJSXExpressionContainer()
children.append(container) else: break
return children
def parseComplexJSXElement(self, el):
stack = []
whilenot self.scanner.eof():
el.children.extend(self.parseJSXChildren())
node = self.createJSXChildNode()
element = self.parseJSXBoundaryElement() if element.type is JSXSyntax.JSXOpeningElement:
opening = element if opening.selfClosing:
child = self.finalize(node, JSXNode.JSXElement(opening, [], None))
el.children.append(child) else:
stack.append(el)
el = MetaJSXElement(
node=node,
opening=opening,
closing=None,
children=[],
)
if element.type is JSXSyntax.JSXClosingElement:
el.closing = element
open = getQualifiedElementName(el.opening.name)
close = getQualifiedElementName(el.closing.name) if open != close:
self.tolerateError('Expected corresponding JSX closing tag for %0', open)
if stack:
child = self.finalize(el.node, JSXNode.JSXElement(el.opening, el.children, el.closing))
el = stack[-1]
el.children.append(child)
stack.pop() else: break
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.