测试gitnore
This commit is contained in:
@@ -7,62 +7,11 @@ from django.utils.regex_helper import _lazy_re_compile
|
||||
# ASCII whitespace is U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, or U+0020
|
||||
# SPACE.
|
||||
# https://infra.spec.whatwg.org/#ascii-whitespace
|
||||
ASCII_WHITESPACE = _lazy_re_compile(r"[\t\n\f\r ]+")
|
||||
|
||||
# https://html.spec.whatwg.org/#attributes-3
|
||||
BOOLEAN_ATTRIBUTES = {
|
||||
"allowfullscreen",
|
||||
"async",
|
||||
"autofocus",
|
||||
"autoplay",
|
||||
"checked",
|
||||
"controls",
|
||||
"default",
|
||||
"defer ",
|
||||
"disabled",
|
||||
"formnovalidate",
|
||||
"hidden",
|
||||
"ismap",
|
||||
"itemscope",
|
||||
"loop",
|
||||
"multiple",
|
||||
"muted",
|
||||
"nomodule",
|
||||
"novalidate",
|
||||
"open",
|
||||
"playsinline",
|
||||
"readonly",
|
||||
"required",
|
||||
"reversed",
|
||||
"selected",
|
||||
# Attributes for deprecated tags.
|
||||
"truespeed",
|
||||
}
|
||||
ASCII_WHITESPACE = _lazy_re_compile(r'[\t\n\f\r ]+')
|
||||
|
||||
|
||||
def normalize_whitespace(string):
|
||||
return ASCII_WHITESPACE.sub(" ", string)
|
||||
|
||||
|
||||
def normalize_attributes(attributes):
|
||||
normalized = []
|
||||
for name, value in attributes:
|
||||
if name == "class" and value:
|
||||
# Special case handling of 'class' attribute, so that comparisons
|
||||
# of DOM instances are not sensitive to ordering of classes.
|
||||
value = " ".join(
|
||||
sorted(value for value in ASCII_WHITESPACE.split(value) if value)
|
||||
)
|
||||
# Boolean attributes without a value is same as attribute with value
|
||||
# that equals the attributes name. For example:
|
||||
# <input checked> == <input checked="checked">
|
||||
if name in BOOLEAN_ATTRIBUTES:
|
||||
if not value or value == name:
|
||||
value = None
|
||||
elif value is None:
|
||||
value = ""
|
||||
normalized.append((name, value))
|
||||
return normalized
|
||||
return ASCII_WHITESPACE.sub(' ', string)
|
||||
|
||||
|
||||
class Element:
|
||||
@@ -100,14 +49,27 @@ class Element:
|
||||
for i, child in enumerate(self.children):
|
||||
if isinstance(child, str):
|
||||
self.children[i] = child.strip()
|
||||
elif hasattr(child, "finalize"):
|
||||
elif hasattr(child, 'finalize'):
|
||||
child.finalize()
|
||||
|
||||
def __eq__(self, element):
|
||||
if not hasattr(element, "name") or self.name != element.name:
|
||||
if not hasattr(element, 'name') or self.name != element.name:
|
||||
return False
|
||||
if len(self.attributes) != len(element.attributes):
|
||||
return False
|
||||
if self.attributes != element.attributes:
|
||||
return False
|
||||
# attributes without a value is same as attribute with value that
|
||||
# equals the attributes name:
|
||||
# <input checked> == <input checked="checked">
|
||||
for i in range(len(self.attributes)):
|
||||
attr, value = self.attributes[i]
|
||||
other_attr, other_value = element.attributes[i]
|
||||
if value is None:
|
||||
value = attr
|
||||
if other_value is None:
|
||||
other_value = other_attr
|
||||
if attr != other_attr or value != other_value:
|
||||
return False
|
||||
return self.children == element.children
|
||||
|
||||
def __hash__(self):
|
||||
@@ -162,18 +124,18 @@ class Element:
|
||||
return self.children[key]
|
||||
|
||||
def __str__(self):
|
||||
output = "<%s" % self.name
|
||||
output = '<%s' % self.name
|
||||
for key, value in self.attributes:
|
||||
if value is not None:
|
||||
if value:
|
||||
output += ' %s="%s"' % (key, value)
|
||||
else:
|
||||
output += " %s" % key
|
||||
output += ' %s' % key
|
||||
if self.children:
|
||||
output += ">\n"
|
||||
output += "".join(str(c) for c in self.children)
|
||||
output += "\n</%s>" % self.name
|
||||
output += '>\n'
|
||||
output += ''.join(str(c) for c in self.children)
|
||||
output += '\n</%s>' % self.name
|
||||
else:
|
||||
output += ">"
|
||||
output += '>'
|
||||
return output
|
||||
|
||||
def __repr__(self):
|
||||
@@ -185,7 +147,7 @@ class RootElement(Element):
|
||||
super().__init__(None, ())
|
||||
|
||||
def __str__(self):
|
||||
return "".join(str(c) for c in self.children)
|
||||
return ''.join(str(c) for c in self.children)
|
||||
|
||||
|
||||
class HTMLParseError(Exception):
|
||||
@@ -195,23 +157,10 @@ class HTMLParseError(Exception):
|
||||
class Parser(HTMLParser):
|
||||
# https://html.spec.whatwg.org/#void-elements
|
||||
SELF_CLOSING_TAGS = {
|
||||
"area",
|
||||
"base",
|
||||
"br",
|
||||
"col",
|
||||
"embed",
|
||||
"hr",
|
||||
"img",
|
||||
"input",
|
||||
"link",
|
||||
"meta",
|
||||
"param",
|
||||
"source",
|
||||
"track",
|
||||
"wbr",
|
||||
'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta',
|
||||
'param', 'source', 'track', 'wbr',
|
||||
# Deprecated tags
|
||||
"frame",
|
||||
"spacer",
|
||||
'frame', 'spacer',
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
@@ -228,9 +177,9 @@ class Parser(HTMLParser):
|
||||
position = self.element_positions[element]
|
||||
if position is None:
|
||||
position = self.getpos()
|
||||
if hasattr(position, "lineno"):
|
||||
if hasattr(position, 'lineno'):
|
||||
position = position.lineno, position.offset
|
||||
return "Line %d, Column %d" % position
|
||||
return 'Line %d, Column %d' % position
|
||||
|
||||
@property
|
||||
def current(self):
|
||||
@@ -245,7 +194,14 @@ class Parser(HTMLParser):
|
||||
self.handle_endtag(tag)
|
||||
|
||||
def handle_starttag(self, tag, attrs):
|
||||
attrs = normalize_attributes(attrs)
|
||||
# Special case handling of 'class' attribute, so that comparisons of DOM
|
||||
# instances are not sensitive to ordering of classes.
|
||||
attrs = [
|
||||
(name, ' '.join(sorted(value for value in ASCII_WHITESPACE.split(value) if value)))
|
||||
if name == "class"
|
||||
else (name, value)
|
||||
for name, value in attrs
|
||||
]
|
||||
element = Element(tag, attrs)
|
||||
self.current.append(element)
|
||||
if tag not in self.SELF_CLOSING_TAGS:
|
||||
@@ -254,13 +210,13 @@ class Parser(HTMLParser):
|
||||
|
||||
def handle_endtag(self, tag):
|
||||
if not self.open_tags:
|
||||
self.error("Unexpected end tag `%s` (%s)" % (tag, self.format_position()))
|
||||
self.error("Unexpected end tag `%s` (%s)" % (
|
||||
tag, self.format_position()))
|
||||
element = self.open_tags.pop()
|
||||
while element.name != tag:
|
||||
if not self.open_tags:
|
||||
self.error(
|
||||
"Unexpected end tag `%s` (%s)" % (tag, self.format_position())
|
||||
)
|
||||
self.error("Unexpected end tag `%s` (%s)" % (
|
||||
tag, self.format_position()))
|
||||
element = self.open_tags.pop()
|
||||
|
||||
def handle_data(self, data):
|
||||
|
||||
Reference in New Issue
Block a user