| Index: lib/dom/scripts/systemhtml.py
|
| diff --git a/lib/dom/scripts/systemhtml.py b/lib/dom/scripts/systemhtml.py
|
| index 254e9a442e2086a16df21060dff5ebbcf08fdac7..0f9f4a6e2316f92b1a68cc088ccfd5253cc7b3ba 100644
|
| --- a/lib/dom/scripts/systemhtml.py
|
| +++ b/lib/dom/scripts/systemhtml.py
|
| @@ -13,48 +13,63 @@ from systeminterface import *
|
| # but need to be exposed internally to implement dart:html on top of a standard
|
| # browser.
|
| _private_html_members = set([
|
| + 'Document.createElement',
|
| + 'Document.createElementNS',
|
| + 'Document.createEvent',
|
| + 'Document.createTextNode',
|
| + 'Document.createTouchList',
|
| + 'Document.getElementById',
|
| + 'Document.getElementsByClassName',
|
| + 'Document.getElementsByName',
|
| + 'Document.getElementsByTagName',
|
| + 'Document.querySelectorAll',
|
| + 'DocumentFragment.querySelectorAll',
|
| + 'Element.childElementCount',
|
| + 'Element.children',
|
| + 'Element.className',
|
| + 'Element.clientHeight',
|
| 'Element.clientLeft',
|
| 'Element.clientTop',
|
| 'Element.clientWidth',
|
| - 'Element.clientHeight',
|
| + 'Element.firstElementChild',
|
| + 'Element.getAttribute',
|
| + 'Element.getBoundingClientRect',
|
| + 'Element.getClientRects',
|
| + 'Element.getElementsByClassName',
|
| + 'Element.getElementsByTagName',
|
| + 'Element.hasAttribute',
|
| + 'Element.lastElementChild',
|
| + 'Element.offsetHeight',
|
| 'Element.offsetLeft',
|
| 'Element.offsetTop',
|
| 'Element.offsetWidth',
|
| - 'Element.offsetHeight',
|
| + 'Element.querySelectorAll',
|
| + 'Element.removeAttribute',
|
| + 'Element.scrollHeight',
|
| 'Element.scrollLeft',
|
| 'Element.scrollTop',
|
| 'Element.scrollWidth',
|
| - 'Element.scrollHeight',
|
| - 'Element.childElementCount',
|
| - 'Element.firstElementChild',
|
| - 'Element.hasAttribute',
|
| - 'Element.getAttribute',
|
| - 'Element.removeAttribute',
|
| 'Element.setAttribute',
|
| - 'Element.className',
|
| - 'Element.children',
|
| - 'Element.querySelectorAll',
|
| - 'NodeSelector.querySelectorAll',
|
| - 'Document.querySelectorAll',
|
| - 'DocumentFragment.querySelectorAll',
|
| - 'Element.getBoundingClientRect',
|
| - 'Element.getClientRects',
|
| + 'Event.initEvent',
|
| + 'EventTarget.addEventListener',
|
| + 'EventTarget.dispatchEvent',
|
| + 'EventTarget.removeEventListener',
|
| + 'MouseEvent.initMouseEvent',
|
| 'Node.appendChild',
|
| - 'Node.removeChild',
|
| - 'Node.replaceChild',
|
| 'Node.attributes',
|
| 'Node.childNodes',
|
| - 'Document.createElement',
|
| - 'Document.createElementNS',
|
| - 'Document.createEvent',
|
| - 'Document.createTextNode',
|
| - 'Document.createTouchList',
|
| + 'Node.firstChild',
|
| + 'Node.lastChild',
|
| + "Node.nodeType",
|
| + 'Node.removeChild',
|
| + 'Node.replaceChild',
|
| + 'NodeSelector.querySelectorAll',
|
| 'Window.getComputedStyle',
|
| - 'EventTarget.removeEventListener',
|
| - 'EventTarget.addEventListener',
|
| - 'EventTarget.dispatchEvent',
|
| - 'Event.initEvent',
|
| - 'MouseEvent.initMouseEvent',
|
| +])
|
| +
|
| +_manually_generated_html_members = set([
|
| + 'Document.querySelectorAll',
|
| + 'Document.querySelector',
|
| ])
|
|
|
| # Members from the standard dom that exist in the dart:html library with
|
| @@ -66,16 +81,15 @@ _html_library_renames = {
|
| 'Element.querySelector': 'query',
|
| 'Element.webkitMatchesSelector' : 'matchesSelector',
|
| 'Element.scrollIntoViewIfNeeded': 'scrollIntoView',
|
| - 'Document.querySelector': 'query',
|
| 'Node.cloneNode': 'clone',
|
| 'Node.nextSibling': 'nextNode',
|
| 'Node.ownerDocument': 'document',
|
| 'Node.parentNode': 'parent',
|
| 'Node.previousSibling': 'previousNode',
|
| 'Node.textContent': 'text',
|
| - 'SVGElement.className': '_svgClassName',
|
| - 'SVGAnimatedString.className': '_svgClassName',
|
| - 'SVGStylable.className': '_svgClassName',
|
| + 'SVGElement.className': '$dom_svgClassName',
|
| + 'SVGAnimatedString.className': '$dom_svgClassName',
|
| + 'SVGStylable.className': '$dom_svgClassName',
|
| }
|
|
|
| #TODO(jacobr): inject annotations into the interfaces based on this table and
|
| @@ -100,29 +114,22 @@ _html_library_remove = set([
|
| # "CDATASection.*",
|
| # "Comment.*",
|
| # "DOMImplementation.*",
|
| - "Document.get:documentElement",
|
| "Document.get:forms",
|
| # "Document.get:selectedStylesheetSet",
|
| # "Document.set:selectedStylesheetSet",
|
| # "Document.get:preferredStylesheetSet",
|
| "Document.get:links",
|
| - "Document.getElementsByTagName",
|
| "Document.set:domain",
|
| "Document.get:implementation",
|
| "Document.createAttributeNS",
|
| "Document.get:inputEncoding",
|
| - "Document.getElementById",
|
| - "Document.getElementsByClassName",
|
| "Document.get:height",
|
| "Document.get:width",
|
| - "Element.getElementsByClassName",
|
| "Element.getElementsByTagNameNS",
|
| - "Element.getElementsByTagName",
|
| "Document.get:compatMode",
|
| "Document.importNode",
|
| "Document.evaluate",
|
| "Document.get:images",
|
| - "Document.querySelector",
|
| "Document.createExpression",
|
| "Document.getOverrideStyle",
|
| "Document.xmlStandalone",
|
| @@ -130,7 +137,6 @@ _html_library_remove = set([
|
| "Document.adoptNode",
|
| "Document.get:characterSet",
|
| "Document.createAttribute",
|
| - "Document.querySelectorAll",
|
| "Document.get:URL",
|
| "Document.createEntityReference",
|
| "Document.get:documentURI",
|
| @@ -138,7 +144,6 @@ _html_library_remove = set([
|
| "Document.createNodeIterator",
|
| "Document.createProcessingInstruction",
|
| "Document.get:doctype",
|
| - "Document.getElementsByName",
|
| "Document.createTreeWalker",
|
| "Document.location",
|
| "Document.createNSResolver",
|
| @@ -237,9 +242,7 @@ _html_library_remove = set([
|
| "Node.get:COMMENT_NODE",
|
| "Node.get:ENTITY_REFERENCE_NODE",
|
| "Node.isSupported",
|
| - "Node.get:firstChild",
|
| "Node.get:DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC",
|
| - "Node.get:lastChild",
|
| "Node.get:NOTATION_NODE",
|
| "Node.normalize",
|
| "Node.get:parentElement",
|
| @@ -249,7 +252,6 @@ _html_library_remove = set([
|
| "Node.get:prefix",
|
| "Node.set:prefix",
|
| "Node.get:DOCUMENT_POSITION_PRECEDING",
|
| - "Node.get:nodeType",
|
| "Node.removeEventListener",
|
| "Node.get:nodeValue",
|
| "Node.set:nodeValue",
|
| @@ -426,26 +428,13 @@ class HtmlSystemShared(object):
|
| return True
|
| return False
|
|
|
| - def MaybeReturnDocument(self, return_type):
|
| - """
|
| - To make it appear that there are not a distinct Document and
|
| - HTMLHtmlElement (document.documentElement) objects we always use
|
| - documentElement instead of the regular document object so must not
|
| - allow a regular document to leak out.
|
| - """
|
| - # TODO(jacobr): any method that returns a Node could also theoretically
|
| - # really return a Document but there are alot of methods that return nodes
|
| - # and they all appear to be safe. Consider the alternate strategy of
|
| - # whitelisting just the known safe methods that return Nodes.
|
| - return (DartType(return_type) == 'EventTarget' or
|
| - DartType(return_type) == 'Document')
|
| -
|
| def _AllAncestorInterfaces(self, interface):
|
| interfaces = ([interface.id] +
|
| self._generator._AllImplementedInterfaces(interface))
|
| return interfaces
|
|
|
| - def RenameInHtmlLibrary(self, interface, member, member_prefix=''):
|
| + def RenameInHtmlLibrary(self, interface, member, member_prefix='',
|
| + implementation_class=False):
|
| """
|
| Returns the name of the member in the HTML library or None if the member is
|
| suppressed in the HTML library
|
| @@ -453,24 +442,33 @@ class HtmlSystemShared(object):
|
| if not self._AllowInHtmlLibrary(interface, member, member_prefix):
|
| return None
|
|
|
| + target_name = member
|
| for interface_name in self._AllAncestorInterfaces(interface):
|
| name = interface_name + '.' + member
|
| if name in _html_library_renames:
|
| - return _html_library_renames[name]
|
| + target_name = _html_library_renames[name]
|
| name = interface.id + '.' + member_prefix + member
|
| if name in _html_library_renames:
|
| - return _html_library_renames[name]
|
| + target_name = _html_library_renames[name]
|
|
|
| - if self._PrivateInHtmlLibrary(interface, member, member_prefix):
|
| - return '_' + member
|
| + if not target_name.startswith('_'):
|
| + if self._PrivateInHtmlLibrary(interface, member, member_prefix):
|
| + target_name = '$dom_' + target_name
|
| + elif implementation_class and self._ManuallyGeneratedInHtmlLibrary(
|
| + interface, member, member_prefix):
|
| + target_name = '_' + target_name
|
|
|
| # No rename required
|
| - return member
|
| + return target_name
|
|
|
| def _PrivateInHtmlLibrary(self, interface, member, member_prefix):
|
| return self._Matches(interface, member, member_prefix,
|
| _private_html_members)
|
|
|
| + def _ManuallyGeneratedInHtmlLibrary(self, interface, member, member_prefix):
|
| + return self._Matches(interface, member, member_prefix,
|
| + _manually_generated_html_members)
|
| +
|
| # TODO(jacobr): this already exists
|
| def _TraverseParents(self, interface, callback):
|
| for parent in interface.parents:
|
| @@ -701,7 +699,8 @@ class HtmlDartInterfaceGenerator(DartInterfaceGenerator):
|
| operations - contains the overloads, one or more operations with the same
|
| name.
|
| """
|
| - html_name = self._shared.RenameInHtmlLibrary(self._interface, info.name)
|
| + html_name = self._shared.RenameInHtmlLibrary(
|
| + self._interface, info.name)
|
| if html_name and not self._shared.IsPrivate(html_name):
|
| self._members_emitter.Emit('\n'
|
| ' $TYPE $NAME($PARAMS);\n',
|
| @@ -875,9 +874,11 @@ class HtmlFrogClassGenerator(FrogInterfaceGenerator):
|
| def AddAttribute(self, getter, setter):
|
|
|
| html_getter_name = self._shared.RenameInHtmlLibrary(
|
| - self._interface, DartDomNameOfAttribute(getter), 'get:')
|
| + self._interface, DartDomNameOfAttribute(getter), 'get:',
|
| + implementation_class=True)
|
| html_setter_name = self._shared.RenameInHtmlLibrary(
|
| - self._interface, DartDomNameOfAttribute(getter), 'set:')
|
| + self._interface, DartDomNameOfAttribute(getter), 'set:',
|
| + implementation_class=True)
|
|
|
| if not html_getter_name:
|
| getter = None
|
| @@ -887,11 +888,8 @@ class HtmlFrogClassGenerator(FrogInterfaceGenerator):
|
| if not getter and not setter:
|
| return
|
|
|
| - if ((getter and (html_getter_name != getter.id or
|
| - self._shared.MaybeReturnDocument(getter.type.id))) or
|
| - (setter and (html_setter_name != setter.id or
|
| - self._shared.MaybeReturnDocument(setter.type.id))) or
|
| - self._interface.id == 'Document'):
|
| + if ((getter and html_getter_name != getter.id) or
|
| + (setter and html_setter_name != setter.id)):
|
| if getter:
|
| self._AddRenamingGetter(getter, html_getter_name)
|
| if setter:
|
| @@ -951,55 +949,35 @@ class HtmlFrogClassGenerator(FrogInterfaceGenerator):
|
|
|
| def _AddRenamingGetter(self, attr, html_name):
|
| return_type = self._NarrowOutputType(attr.type.id)
|
| - if self._shared.MaybeReturnDocument(attr.type.id):
|
| - self._members_emitter.Emit(
|
| - '\n $TYPE get $(HTML_NAME)() => '
|
| - '_FixHtmlDocumentReference(_$(HTML_NAME));\n',
|
| - HTML_NAME=html_name,
|
| - TYPE=return_type)
|
| - html_name = '_' + html_name
|
| - # For correctness this needs to be the return type of the native helper
|
| - # method due to the fact that the real HTMLDocument object is not typed
|
| - # as a document. TODO(jacobr): we could simplify this.
|
| - return_type = '_EventTargetImpl'
|
| -
|
| self._members_emitter.Emit(
|
| - '\n $TYPE get $(HTML_NAME)() native "return $(THIS).$NAME;";\n',
|
| + '\n $TYPE get $(HTML_NAME)() native "return this.$NAME;";\n',
|
| HTML_NAME=html_name,
|
| NAME=attr.id,
|
| - TYPE=return_type,
|
| - THIS='this.parentNode' if self._interface.id == 'Document' else 'this')
|
| + TYPE=return_type)
|
|
|
| def _AddRenamingSetter(self, attr, html_name):
|
| self._members_emitter.Emit(
|
| '\n void set $HTML_NAME($TYPE value)'
|
| - ' native "$(THIS).$NAME = value;";\n',
|
| + ' native "this.$NAME = value;";\n',
|
| HTML_NAME=html_name,
|
| NAME=attr.id,
|
| - TYPE=self._NarrowInputType(attr.type.id),
|
| - THIS='this.parentNode' if self._interface.id == 'Document' else 'this')
|
| + TYPE=self._NarrowInputType(attr.type.id))
|
|
|
| def AddOperation(self, info):
|
| """
|
| Arguments:
|
| info: An OperationInfo object.
|
| """
|
| - html_name = self._shared.RenameInHtmlLibrary(self._interface, info.name)
|
| + html_name = self._shared.RenameInHtmlLibrary(
|
| + self._interface, info.name, implementation_class=True)
|
| if not html_name:
|
| return
|
|
|
| - maybe_return_document = self._shared.MaybeReturnDocument(info.type_name)
|
| -
|
| # Do we need a native body?
|
| - if (self._interface.id == 'Document' or # Need alternate 'this'
|
| - html_name != info.name or # renamed operation
|
| - maybe_return_document): # need to wrap value
|
| - # For example: use window.document instead of his.parentNode.
|
| + if (html_name != info.name):
|
| return_type = self._NarrowOutputType(info.type_name)
|
|
|
| operation_emitter = self._members_emitter.Emit('$!SCOPE',
|
| - THIS=('this.parentNode' if self._interface.id == 'Document'
|
| - else 'this'),
|
| TYPE=return_type,
|
| HTML_NAME=html_name,
|
| NAME=info.name,
|
| @@ -1008,20 +986,10 @@ class HtmlFrogClassGenerator(FrogInterfaceGenerator):
|
| PARAMS=info.ParametersImplementationDeclaration(
|
| lambda type_name: self._NarrowInputType(type_name)))
|
|
|
| - if maybe_return_document:
|
| - assert len(info.overloads) == 1
|
| - operation_emitter.Emit(
|
| - '\n'
|
| - ' $TYPE $(HTML_NAME)($PARAMS) => '
|
| - '_FixHtmlDocumentReference(_$(HTML_NAME)($PARAMNAMES));\n'
|
| - '\n'
|
| - ' _EventTargetImpl _$(HTML_NAME)($PARAMS)'
|
| - ' native "return $(THIS).$NAME($PARAMNAMES);";\n')
|
| - else:
|
| - operation_emitter.Emit(
|
| - '\n'
|
| - ' $TYPE $(HTML_NAME)($PARAMS)'
|
| - ' native "$(RETURN)$(THIS).$NAME($PARAMNAMES);";\n')
|
| + operation_emitter.Emit(
|
| + '\n'
|
| + ' $TYPE $(HTML_NAME)($PARAMS)'
|
| + ' native "$(RETURN)this.$NAME($PARAMNAMES);";\n')
|
| else:
|
| self._members_emitter.Emit(
|
| '\n'
|
| @@ -1063,10 +1031,8 @@ class HtmlFrogClassGenerator(FrogInterfaceGenerator):
|
|
|
| def _EmitEventGetter(self, events_class):
|
| self._members_emitter.Emit(
|
| - '\n $TYPE get on() =>\n new $TYPE($EVENTTARGET);\n',
|
| - TYPE=events_class,
|
| - EVENTTARGET='_jsDocument' if self._interface.id == 'Document'
|
| - else 'this')
|
| + '\n $TYPE get on() =>\n new $TYPE(this);\n',
|
| + TYPE=events_class)
|
|
|
| # ------------------------------------------------------------------------------
|
|
|
| @@ -1205,7 +1171,7 @@ class HtmlDartiumInterfaceGenerator(object):
|
| self._template = template
|
|
|
| def DomObjectName(self):
|
| - return '_documentPtr' if self._interface.id == 'Document' else '_ptr'
|
| + return '_ptr'
|
|
|
| # TODO(jacobr): these 3 methods are duplicated.
|
| def _NarrowToImplementationType(self, type_name):
|
| @@ -1248,11 +1214,9 @@ class HtmlDartiumInterfaceGenerator(object):
|
| # TODO(jacobr): this is fragile. There isn't a guarantee that dart:dom
|
| # will continue to exactly match the IDL names.
|
| dom_name = interface.javascript_binding_name
|
| - # We hard code the cases for these classes
|
| - if dom_name != 'HTMLHtmlElement' and dom_name != 'Document':
|
| - self._system._wrap_cases.append(
|
| - ' case "%s": return new %s._wrap(domObject);' %
|
| - (dom_name, self._class_name))
|
| + self._system._wrap_cases.append(
|
| + " case '%s': return new %s._wrap(domObject);" %
|
| + (dom_name, self._class_name))
|
|
|
| extends = ' extends ' + base if base else ' extends _DOMTypeBase'
|
|
|
| @@ -1274,11 +1238,9 @@ class HtmlDartiumInterfaceGenerator(object):
|
| EXTENDS=extends,
|
| IMPLEMENTS=' implements ' + implements_str)
|
|
|
| - # Document requires a custom wrapper.
|
| - if dom_name != 'Document':
|
| - self._members_emitter.Emit(
|
| - ' $(CLASSNAME)._wrap(ptr) : super._wrap(ptr);\n',
|
| - CLASSNAME=self._class_name)
|
| + self._members_emitter.Emit(
|
| + ' $(CLASSNAME)._wrap(ptr) : super._wrap(ptr);\n',
|
| + CLASSNAME=self._class_name)
|
|
|
| # Emit a factory provider class for the constructor.
|
| constructor_info = AnalyzeConstructor(interface)
|
| @@ -1362,9 +1324,9 @@ class HtmlDartiumInterfaceGenerator(object):
|
| def AddAttribute(self, getter, setter):
|
| dom_name = DartDomNameOfAttribute(getter or setter)
|
| html_getter_name = self._shared.RenameInHtmlLibrary(
|
| - self._interface, dom_name, 'get:')
|
| + self._interface, dom_name, 'get:', implementation_class=True)
|
| html_setter_name = self._shared.RenameInHtmlLibrary(
|
| - self._interface, dom_name, 'set:')
|
| + self._interface, dom_name, 'set:', implementation_class=True)
|
|
|
| if getter and html_getter_name:
|
| self._AddGetter(getter, html_getter_name)
|
| @@ -1372,23 +1334,13 @@ class HtmlDartiumInterfaceGenerator(object):
|
| self._AddSetter(setter, html_setter_name)
|
|
|
| def _AddGetter(self, attr, html_name):
|
| - if self._shared.MaybeReturnDocument(attr.type.id):
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' $TYPE get $(HTML_NAME)() => '
|
| - '_FixHtmlDocumentReference(_wrap($(THIS).$DOM_NAME));\n',
|
| - HTML_NAME=html_name,
|
| - DOM_NAME=DartDomNameOfAttribute(attr),
|
| - TYPE=DartType(attr.type.id),
|
| - THIS=self.DomObjectName())
|
| - else:
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' $TYPE get $(HTML_NAME)() => _wrap($(THIS).$DOM_NAME);\n',
|
| - HTML_NAME=html_name,
|
| - DOM_NAME=DartDomNameOfAttribute(attr),
|
| - TYPE=DartType(attr.type.id),
|
| - THIS=self.DomObjectName())
|
| + self._members_emitter.Emit(
|
| + '\n'
|
| + ' $TYPE get $(HTML_NAME)() => _wrap($(THIS).$DOM_NAME);\n',
|
| + HTML_NAME=html_name,
|
| + DOM_NAME=DartDomNameOfAttribute(attr),
|
| + TYPE=DartType(attr.type.id),
|
| + THIS=self.DomObjectName())
|
|
|
| def _AddSetter(self, attr, html_name):
|
| self._members_emitter.Emit(
|
| @@ -1622,7 +1574,8 @@ class HtmlDartiumInterfaceGenerator(object):
|
| Arguments:
|
| info: An OperationInfo object.
|
| """
|
| - html_name = self._shared.RenameInHtmlLibrary(self._interface, info.name)
|
| + html_name = self._shared.RenameInHtmlLibrary(
|
| + self._interface, info.name, implementation_class=True)
|
|
|
| if not html_name:
|
| return
|
| @@ -1662,19 +1615,11 @@ class HtmlDartiumInterfaceGenerator(object):
|
| # We could place the logic for handling Document directly in _wrap
|
| # but we chose to place it here so that bugs in the wrapper and
|
| # wrapperless implementations are more consistent.
|
| - if self._shared.MaybeReturnDocument(info.type_name):
|
| - emitter.Emit('$(INDENT)return _FixHtmlDocumentReference('
|
| - '_wrap($(THIS).$NAME($ARGS)));\n',
|
| - INDENT=indent,
|
| - THIS=self.DomObjectName(),
|
| - NAME=info.name,
|
| - ARGS=argument_expressions)
|
| - else:
|
| - emitter.Emit('$(INDENT)return _wrap($(THIS).$NAME($ARGS));\n',
|
| - INDENT=indent,
|
| - THIS=self.DomObjectName(),
|
| - NAME=info.name,
|
| - ARGS=argument_expressions)
|
| + emitter.Emit('$(INDENT)return _wrap($(THIS).$NAME($ARGS));\n',
|
| + INDENT=indent,
|
| + THIS=self.DomObjectName(),
|
| + NAME=info.name,
|
| + ARGS=argument_expressions)
|
| else:
|
| emitter.Emit('$(INDENT)$(THIS).$NAME($ARGS);\n'
|
| '$(INDENT)return;\n',
|
|
|