提交 f7e97468 编写于 作者: A Adam Barth

Morph the APIs for Node, ParentNode, and Element closer to the specs

These still don't match the specs exactly, but they're much closer.

R=ojan@chromium.org, eseidel@chromium.org

Review URL: https://codereview.chromium.org/924203002
上级 0b9a9f98
......@@ -413,21 +413,10 @@ def dart_value_to_cpp_value_array_or_sequence(native_array_element_type, variabl
# and is used to provide a human-readable exception message
if index is None:
index = 0 # special case, meaning "setter"
# else:
# index += 1 # human-readable index
if (native_array_element_type.is_interface_type):
this_cpp_type = None
ref_ptr_type = 'RefPtr'
# FIXME(vsm): We're not using ref_ptr_type....
expression_format = '{variable_name} = DartConverter<Vector<{native_array_element_type}>>::FromArguments(args, {index}, exception)'
add_includes_for_type(native_array_element_type)
else:
ref_ptr_type = None
this_cpp_type = native_array_element_type.cpp_type
expression_format = '{variable_name} = DartConverter<Vector<{cpp_type}>>::FromArguments(args, {index}, exception)'
this_cpp_type = native_array_element_type.cpp_type
expression_format = '{variable_name} = DartConverter<Vector<{cpp_type}>>::FromArguments(args, {index}, exception)'
expression = expression_format.format(native_array_element_type=native_array_element_type.name,
cpp_type=this_cpp_type, index=index, ref_ptr_type=ref_ptr_type,
cpp_type=this_cpp_type, index=index,
variable_name=variable_name)
return expression
......
......@@ -338,7 +338,6 @@ sky_core_files = [
"dom/CharacterData.h",
"dom/ChildListMutationScope.cpp",
"dom/ChildListMutationScope.h",
"dom/ChildNode.h",
"dom/ClientRect.cpp",
"dom/ClientRect.h",
"dom/ClientRectList.cpp",
......@@ -458,7 +457,6 @@ sky_core_files = [
"dom/NodeTraversal.cpp",
"dom/NodeTraversal.h",
"dom/NodeWithIndex.h",
"dom/ParentNode.h",
"dom/Position.cpp",
"dom/Position.h",
"dom/PositionIterator.cpp",
......@@ -1195,6 +1193,7 @@ core_idl_files = get_path_info([
"dom/MutationRecord.idl",
"dom/Node.idl",
"dom/NodeList.idl",
"dom/ParentNode.idl",
"dom/Range.idl",
"dom/RequestAnimationFrameCallback.idl",
"dom/shadow/ShadowRoot.idl",
......@@ -1288,8 +1287,6 @@ core_dependency_idl_files =
"animation/DocumentAnimation.idl",
"animation/ElementAnimation.idl",
"css/DocumentFontFaceSet.idl",
"dom/ChildNode.idl",
"dom/ParentNode.idl",
"dom/URLUtils.idl",
"dom/URLUtilsReadOnly.idl",
"events/EventListener.idl",
......
......@@ -30,6 +30,3 @@ interface CharacterData : Node {
[RaisesException] void deleteData(unsigned long offset, unsigned long length);
[RaisesException] void replaceData(unsigned long offset, unsigned long length, DOMString data);
};
CharacterData implements ChildNode;
/*
* Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
* Copyright (C) 2013 Samsung Electronics. All rights reserved.
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
// http://dom.spec.whatwg.org/#interface-childnode
[
LegacyTreatAsPartialInterface,
NoInterfaceObject, // Always used on target of 'implements'
] interface ChildNode {
readonly attribute Element previousElementSibling;
readonly attribute Element nextElementSibling;
[RaisesException, CustomElementCallbacks] void remove();
};
......@@ -51,7 +51,7 @@ static void collectChildrenAndRemoveFromOldParent(Node& node, NodeVector& nodes,
{
if (node.isDocumentFragment()) {
DocumentFragment& fragment = toDocumentFragment(node);
getChildNodes(fragment, nodes);
appendChildNodes(fragment, nodes);
fragment.removeChildren();
return;
}
......@@ -325,7 +325,7 @@ void ContainerNode::willRemoveChild(Node& child)
void ContainerNode::willRemoveChildren()
{
NodeVector children;
getChildNodes(*this, children);
appendChildNodes(*this, children);
ChildListMutationScope mutation(*this);
for (NodeVector::const_iterator it = children.begin(); it != children.end(); ++it) {
......@@ -869,6 +869,72 @@ void ContainerNode::setHovered(bool over)
}
}
Element* ContainerNode::firstElementChild() const
{
return ElementTraversal::firstChild(*this);
}
Element* ContainerNode::lastElementChild() const
{
return ElementTraversal::lastChild(*this);
}
Vector<RefPtr<Node>> ContainerNode::getChildNodes() const
{
Vector<RefPtr<Node>> result;
for (Node* node = firstChild(); node; node = node->nextSibling())
result.append(node);
return result;
}
Vector<RefPtr<Element>> ContainerNode::getChildElements() const
{
Vector<RefPtr<Element>> result;
for (Element* element = ElementTraversal::firstWithin(*this); element; element = ElementTraversal::next(*element, this))
result.append(element);
return result;
}
void ContainerNode::append(Vector<RefPtr<Node>>& nodes, ExceptionState& es)
{
RefPtr<ContainerNode> protect(this);
for (auto& node : nodes) {
appendChild(node.release(), es);
if (es.had_exception())
return;
}
}
void ContainerNode::prepend(Vector<RefPtr<Node>>& nodes, ExceptionState& es)
{
RefPtr<ContainerNode> protect(this);
RefPtr<Node> refChild = m_firstChild;
for (auto& node : nodes) {
insertBefore(node.release(), refChild.get(), es);
if (es.had_exception())
return;
}
}
PassRefPtr<Node> ContainerNode::prependChild(PassRefPtr<Node> node, ExceptionState& es)
{
return insertBefore(node, m_firstChild, es);
}
PassRefPtr<Node> ContainerNode::setChild(PassRefPtr<Node> node, ExceptionState& es)
{
RefPtr<ContainerNode> protect(this);
removeChildren();
return appendChild(node, es);
}
void ContainerNode::setChildren(Vector<RefPtr<Node>>& nodes, ExceptionState& es)
{
RefPtr<ContainerNode> protect(this);
removeChildren();
append(nodes, es);
}
unsigned ContainerNode::countChildren() const
{
unsigned count = 0;
......
......@@ -43,6 +43,7 @@ const int initialNodeVectorSize = 11;
typedef Vector<RefPtr<Node>, initialNodeVectorSize> NodeVector;
class ContainerNode : public Node {
DEFINE_WRAPPERTYPEINFO();
public:
virtual ~ContainerNode();
......@@ -50,6 +51,21 @@ public:
Node* lastChild() const { return m_lastChild; }
bool hasChildren() const { return m_firstChild; }
Element* firstElementChild() const;
Element* lastElementChild() const;
Vector<RefPtr<Node>> getChildNodes() const;
Vector<RefPtr<Element>> getChildElements() const;
// These functions release the nodes from |nodes|.
void append(Vector<RefPtr<Node>>& nodes, ExceptionState&);
void prepend(Vector<RefPtr<Node>>& nodes, ExceptionState&);
PassRefPtr<Node> prependChild(PassRefPtr<Node> node, ExceptionState&);
void removeChildren();
PassRefPtr<Node> setChild(PassRefPtr<Node> node, ExceptionState&);
void setChildren(Vector<RefPtr<Node>>& nodes, ExceptionState&);
bool hasOneChild() const { return m_firstChild && !m_firstChild->nextSibling(); }
bool hasOneTextChild() const { return hasOneChild() && m_firstChild->isTextNode(); }
......@@ -69,7 +85,6 @@ public:
// They don't send DOM mutation events or handle reparenting.
void parserAppendChild(PassRefPtr<Node>);
void removeChildren();
void cloneChildNodes(ContainerNode* clone);
......@@ -216,7 +231,7 @@ inline bool Node::isTreeScope() const
return &treeScope().rootNode() == this;
}
inline void getChildNodes(ContainerNode& node, NodeVector& nodes)
inline void appendChildNodes(ContainerNode& node, NodeVector& nodes)
{
ASSERT(!nodes.size());
for (Node* child = node.firstChild(); child; child = child->nextSibling())
......
......@@ -25,7 +25,7 @@ typedef (CanvasRenderingContext2D or WebGLRenderingContext) RenderingContext;
[
Constructor(),
ConstructorCallWith=Document,
] interface Document : Node {
] interface Document : ParentNode {
readonly attribute Element documentElement;
[CustomElementCallbacks, RaisesException] Element createElement(DOMString tagName);
......@@ -75,5 +75,3 @@ typedef (CanvasRenderingContext2D or WebGLRenderingContext) RenderingContext;
readonly attribute HTMLScriptElement currentScript;
};
Document implements ParentNode;
......@@ -20,9 +20,7 @@
[
Constructor,
ConstructorCallWith=Document,
] interface DocumentFragment : Node {
] interface DocumentFragment : ParentNode {
// NonElementParentNode API.
Element getElementById(DOMString elementId);
};
DocumentFragment implements ParentNode;
......@@ -76,6 +76,9 @@ public:
bool hasAttribute(const AtomicString& name) const;
const AtomicString& getAttribute(const AtomicString& name) const;
void setAttribute(const AtomicString& name, const AtomicString& value, ExceptionState&);
void setAttribute(const AtomicString& name, ExceptionState& es) {
setAttribute(name, String(), es);
}
void removeAttribute(const AtomicString& name);
void removeAttribute(const QualifiedName&);
......
/*
* Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
[
SpecialWrapFor=HTMLElement,
] interface Element : Node {
readonly attribute DOMString? tagName;
DOMString? getAttribute(DOMString name);
[RaisesException, CustomElementCallbacks] void setAttribute(DOMString name, DOMString value);
[CustomElementCallbacks] void removeAttribute(DOMString name);
boolean hasAttribute(DOMString name);
boolean hasAttributes();
sequence<Attr> getAttributes();
readonly attribute CSSStyleDeclaration style;
[Reflect] attribute DOMString id;
readonly attribute DOMString? localName;
[RaisesException] boolean matches(DOMString selectors);
readonly attribute long offsetLeft;
readonly attribute long offsetTop;
readonly attribute long offsetWidth;
readonly attribute long offsetHeight;
readonly attribute Element offsetParent;
readonly attribute long clientLeft;
readonly attribute long clientTop;
readonly attribute long clientWidth;
readonly attribute long clientHeight;
void focus();
void blur();
readonly attribute DOMTokenList classList;
[RaisesException] ShadowRoot ensureShadowRoot();
readonly attribute ShadowRoot shadowRoot;
NodeList getDestinationInsertionPoints();
// CSSOM View Module API
ClientRectList getClientRects();
ClientRect getBoundingClientRect();
[Reflect] attribute DOMString lang;
attribute DOMString dir;
[CustomElementCallbacks] attribute long tabIndex;
[CustomElementCallbacks, RaisesException=Setter] attribute DOMString contentEditable;
readonly attribute boolean isContentEditable;
attribute boolean spellcheck;
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
interface Element : ParentNode {
readonly attribute DOMString tagName;
boolean hasAttribute(DOMString name);
[TreatReturnedNullStringAs=Null] DOMString getAttribute(DOMString name);
[RaisesException] void setAttribute(DOMString name, optional DOMString value);
void removeAttribute(DOMString name);
sequence<Attr> getAttributes();
readonly attribute ShadowRoot shadowRoot;
// TODO(abarth): Move to Node.
readonly attribute CSSStyleDeclaration style;
// TODO(abarth): Remove these when we implement more of the system.
[RaisesException] boolean matches(DOMString selectors);
void focus();
void blur();
attribute long tabIndex;
readonly attribute DOMTokenList classList;
[RaisesException] ShadowRoot ensureShadowRoot();
readonly attribute long offsetLeft;
readonly attribute long offsetTop;
readonly attribute long offsetWidth;
readonly attribute long offsetHeight;
readonly attribute Element offsetParent;
readonly attribute long clientLeft;
readonly attribute long clientTop;
readonly attribute long clientWidth;
readonly attribute long clientHeight;
};
Element implements ParentNode;
Element implements ChildNode;
......@@ -379,6 +379,58 @@ PassRefPtr<Node> Node::appendChild(PassRefPtr<Node> newChild, ExceptionState& ex
return nullptr;
}
Element* Node::previousElementSibling()
{
return ElementTraversal::previousSibling(*this);
}
Element* Node::nextElementSibling()
{
return ElementTraversal::nextSibling(*this);
}
void Node::newInsertBefore(Vector<RefPtr<Node>>& nodes, ExceptionState& es)
{
RefPtr<ContainerNode> parent = parentNode();
if (!parent)
return;
RefPtr<Node> protect(this);
for (auto& node : nodes) {
parent->insertBefore(node.release(), this, es);
if (es.had_exception())
return;
}
}
void Node::newInsertAfter(Vector<RefPtr<Node>>& nodes, ExceptionState& es)
{
RefPtr<ContainerNode> parent = this->parentNode();
if (!parent)
return;
RefPtr<Node> reference = m_next;
for (auto& node : nodes) {
parent->insertBefore(node.release(), reference.get(), es);
if (es.had_exception())
return;
}
}
void Node::replaceWith(Vector<RefPtr<Node>>& nodes, ExceptionState& es)
{
RefPtr<ContainerNode> parent = this->parentNode();
if (!parent)
return;
RefPtr<Node> reference = m_next;
remove(es);
if (es.had_exception())
return;
for (auto& node : nodes) {
parent->insertBefore(node, reference.get(), es);
if (es.had_exception())
return;
}
}
void Node::remove(ExceptionState& exceptionState)
{
if (ContainerNode* parent = parentNode())
......@@ -862,7 +914,7 @@ Document* Node::ownerDocument() const
return doc == this ? 0 : doc;
}
ContainerNode* Node::ownerScope() const
ContainerNode* Node::owner() const
{
if (inDocument())
return &treeScope().rootNode();
......
......@@ -144,6 +144,14 @@ public:
Node* firstChild() const;
Node* lastChild() const;
Element* previousElementSibling();
Element* nextElementSibling();
// These functions release the nodes from |nodes|.
void newInsertBefore(Vector<RefPtr<Node>>& nodes, ExceptionState&);
void newInsertAfter(Vector<RefPtr<Node>>& nodes, ExceptionState&);
void replaceWith(Vector<RefPtr<Node>>& nodes, ExceptionState&);
void remove(ExceptionState&);
// These should all actually return a node, but this is only important for language bindings,
......@@ -340,7 +348,7 @@ public:
return *m_treeScope;
}
ContainerNode* ownerScope() const;
ContainerNode* owner() const;
bool inActiveDocument() const;
......
/*
* Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
[
DependentLifetime,
] interface Node : EventTarget {
readonly attribute Node parentNode;
readonly attribute Node firstChild;
readonly attribute Node lastChild;
readonly attribute Node previousSibling;
readonly attribute Node nextSibling;
readonly attribute Document ownerDocument;
interface Node : EventTarget {
// TODO(abarth): This should actually be a named argument.
Node cloneNode(optional boolean deep);
// TODO(esprehn): This should return TreeScope in Sky, but we don't have
// a TreeScope type yet.
readonly attribute Node ownerScope;
readonly attribute ParentNode owner;
readonly attribute ParentNode parentNode;
readonly attribute Element parentElement;
[CustomElementCallbacks, RaisesException, TypeChecking=Interface] Node insertBefore(Node newChild, Node? refChild);
[CustomElementCallbacks, RaisesException, TypeChecking=Interface] Node replaceChild(Node newChild, Node oldChild);
[CustomElementCallbacks, RaisesException, TypeChecking=Interface] Node removeChild(Node oldChild);
[CustomElementCallbacks, RaisesException, TypeChecking=Interface] Node appendChild(Node newChild);
readonly attribute Node nextSibling;
readonly attribute Node previousSibling;
readonly attribute Element nextElementSibling;
readonly attribute Element previousElementSibling;
[ImplementedAs=hasChildren] boolean hasChildNodes();
[CustomElementCallbacks] Node cloneNode(optional boolean deep);
[RaisesException, ImplementedAs=newInsertBefore] void insertBefore(sequence<Node> nodes);
[RaisesException, ImplementedAs=newInsertAfter] void insertAfter(sequence<Node> nodes);
[RaisesException] void replaceWith(sequence<Node> nodes);
[TreatReturnedNullStringAs=Null, TreatNullAs=NullString, TreatUndefinedAs=NullString, CustomElementCallbacks] attribute DOMString textContent;
[RaisesException] void remove();
boolean contains(Node other);
// DocumentPosition
const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01;
const unsigned short DOCUMENT_POSITION_PRECEDING = 0x02;
const unsigned short DOCUMENT_POSITION_FOLLOWING = 0x04;
const unsigned short DOCUMENT_POSITION_CONTAINS = 0x08;
const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10;
const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
unsigned short compareDocumentPosition(Node other);
readonly attribute Element parentElement;
[TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString textContent;
};
/*
* Copyright (C) 2013 Samsung Electronics. All rights reserved.
*
* 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.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* 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 THE COPYRIGHT
* OWNER OR CONTRIBUTORS 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.
*/
#ifndef SKY_ENGINE_CORE_DOM_PARENTNODE_H_
#define SKY_ENGINE_CORE_DOM_PARENTNODE_H_
#include "sky/engine/core/dom/ContainerNode.h"
#include "sky/engine/core/dom/ElementTraversal.h"
#include "sky/engine/platform/heap/Handle.h"
namespace blink {
class ParentNode {
public:
static Element* firstElementChild(ContainerNode& node)
{
return ElementTraversal::firstChild(node);
}
static Element* lastElementChild(ContainerNode& node)
{
return ElementTraversal::lastChild(node);
}
static unsigned childElementCount(ContainerNode& node)
{
unsigned count = 0;
for (Element* child = ElementTraversal::firstChild(node); child; child = ElementTraversal::nextSibling(*child))
++count;
return count;
}
static PassRefPtr<Element> querySelector(ContainerNode& node, const AtomicString& selectors, ExceptionState& exceptionState)
{
return node.querySelector(selectors, exceptionState);
}
static PassRefPtr<StaticElementList> querySelectorAll(ContainerNode& node, const AtomicString& selectors, ExceptionState& exceptionState)
{
return node.querySelectorAll(selectors, exceptionState);
}
};
} // namespace blink
#endif // SKY_ENGINE_CORE_DOM_PARENTNODE_H_
/*
* Copyright (C) 2013 Samsung Electronics. All rights reserved.
*
* 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.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* 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 THE COPYRIGHT
* OWNER OR CONTRIBUTORS 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.
*/
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
[
LegacyTreatAsPartialInterface,
NoInterfaceObject, // Always used on target of 'implements'
] interface ParentNode {
readonly attribute Element firstElementChild;
readonly attribute Element lastElementChild;
readonly attribute unsigned long childElementCount;
ImplementedAs=ContainerNode,
] interface ParentNode : Node {
readonly attribute Node firstChild;
readonly attribute Node lastChild;
readonly attribute Element firstElementChild;
readonly attribute Element lastElementChild;
// NodeSelector - Selector API
[RaisesException] Element querySelector(DOMString selectors);
[RaisesException] NodeList querySelectorAll(DOMString selectors);
sequence<Node> getChildNodes();
sequence<Element> getChildElements();
[RaisesException] void append(sequence<Node> nodes);
[RaisesException] Node appendChild(Node nodes);
[RaisesException] void prepend(sequence<Node> nodes);
[RaisesException] Node prependChild(Node nodes);
void removeChildren();
[RaisesException] Node setChild(Node node);
[RaisesException] void setChildren(sequence<Node> nodes);
// TODO(abarth): Remove when we have the selector object.
[RaisesException] Element querySelector(DOMString selectors);
[RaisesException] NodeList querySelectorAll(DOMString selectors);
};
......@@ -43,7 +43,7 @@ void RemoveNodePreservingChildrenCommand::doApply()
{
if (m_node->isContainerNode()) {
NodeVector children;
getChildNodes(toContainerNode(*m_node), children);
appendChildNodes(toContainerNode(*m_node), children);
size_t size = children.size();
for (size_t i = 0; i < size; ++i) {
......
......@@ -83,7 +83,7 @@ void SplitElementCommand::doUnapply()
return;
NodeVector children;
getChildNodes(*m_element1, children);
appendChildNodes(*m_element1, children);
RefPtr<Node> refChild = m_element2->firstChild();
......
......@@ -248,9 +248,10 @@ struct DartConverter<Vector<T>> {
Dart_ListLength(handle, &length);
result.reserveCapacity(length);
for (intptr_t i = 0; i < length; ++i) {
Dart_Handle element = Dart_ListGetAt(handle, i);
DCHECK(!Dart_IsError(element));
result.append(DartConverter<T>::FromDart(element));
Dart_Handle item = Dart_ListGetAt(handle, i);
DCHECK(!Dart_IsError(item));
DCHECK(item);
result.append(DartConverter<T>::FromDart(item));
}
return result;
}
......
......@@ -50,9 +50,9 @@ void DartWrappable::FinalizeDartWrapper(void* isolate_callback_data,
}
DartWrappable* DartConverterWrappable::FromDart(Dart_Handle handle) {
intptr_t* peer = 0;
intptr_t peer = 0;
Dart_Handle result =
Dart_GetNativeInstanceField(handle, DartWrappable::kPeerIndex, peer);
Dart_GetNativeInstanceField(handle, DartWrappable::kPeerIndex, &peer);
if (Dart_IsError(result))
return nullptr;
return reinterpret_cast<DartWrappable*>(peer);
......
......@@ -126,6 +126,10 @@ struct DartConverter<RefPtr<T>> {
static Dart_Handle ToDart(RefPtr<T> val) {
return DartConverter<T*>::ToDart(val.get());
}
static RefPtr<T> FromDart(Dart_Handle handle) {
return DartConverter<T*>::FromDart(handle);
}
};
template<typename T>
......
......@@ -22,7 +22,7 @@ void main() {
var oldChild = doc.appendChild(doc.createElement("div"));
expect(childElementCount(doc), equals(1));
var newChild = doc.createElement("div");
doc.replaceChild(newChild, oldChild);
oldChild.replaceWith([newChild]);
expect(childElementCount(doc), equals(1));
expect(newChild.parentNode, equals(doc));
expect(oldChild.parentNode, isNull);
......@@ -33,7 +33,7 @@ void main() {
expect(childElementCount(doc), equals(0));
expect(childNodeCount(doc), equals(1));
var newChild = doc.createElement("div");
doc.replaceChild(newChild, oldChild);
oldChild.replaceWith([newChild]);
expect(childElementCount(doc), equals(1));
expect(childNodeCount(doc), equals(1));
expect(newChild.parentNode, equals(doc));
......@@ -44,7 +44,7 @@ void main() {
var oldChild = doc.appendChild(doc.createElement("div"));
expect(childElementCount(doc), equals(1));
var newChild = new Text(" text ");
doc.replaceChild(newChild, oldChild);
oldChild.replaceWith([newChild]);
expect(childElementCount(doc), equals(0));
expect(childNodeCount(doc), equals(1));
expect(newChild.parentNode, equals(doc));
......@@ -68,7 +68,7 @@ void main() {
fragment.appendChild(new Text(" text "));
var newChild = fragment.appendChild(doc.createElement("div"));
fragment.appendChild(new Text(" "));
doc.replaceChild(fragment, oldChild);
oldChild.replaceWith([fragment]);
expect(childElementCount(doc), equals(1));
expect(childNodeCount(doc), equals(3));
expect(newChild.parentNode, equals(doc));
......
......@@ -11,14 +11,13 @@ void main() {
test("should return null for elements not a child of a scope", () {
var doc = new Document();
var element = doc.createElement("div");
expect(element.ownerScope, isNull);
expect(element.owner, isNull);
});
test("should return the document for elements in the document scope", () {
var doc = new Document();
var element = doc.createElement("div");
doc.appendChild(element);
expect(element.ownerScope, equals(element.ownerDocument));
expect(element.ownerScope, equals(doc));
expect(element.owner, equals(doc));
});
test("should return the shadow root for elements in the shadow root scope", () {
var doc = new Document();
......@@ -26,26 +25,26 @@ void main() {
var child = doc.createElement("div");
var shadowRoot = host.ensureShadowRoot();
shadowRoot.appendChild(child);
expect(child.ownerScope, equals(shadowRoot));
expect(child.owner, equals(shadowRoot));
});
test("should return self for a shadow root or document", () {
var doc = new Document();
var host = doc.createElement("div");
doc.appendChild(host);
var shadowRoot = host.ensureShadowRoot();
expect(shadowRoot.ownerScope, equals(shadowRoot));
expect(doc.ownerScope, equals(doc));
expect(shadowRoot.owner, equals(shadowRoot));
expect(doc.owner, equals(doc));
});
test("should dynamically update", () {
var doc = new Document();
var host = doc.createElement("div");
var child = doc.createElement("div");
var shadowRoot = host.ensureShadowRoot();
expect(child.ownerScope, isNull);
expect(child.owner, isNull);
shadowRoot.appendChild(child);
expect(child.ownerScope, equals(shadowRoot));
expect(child.owner, equals(shadowRoot));
child.remove();
expect(child.ownerScope, isNull);
expect(child.owner, isNull);
});
}
</script>
......
CONSOLE: unittest-suite-wait-for-done
CONSOLE: PASS: should throw with invalid arguments
CONSOLE: PASS: should replace elements
CONSOLE: PASS: should replace text
CONSOLE: PASS: should replace children with a fragment
CONSOLE:
CONSOLE: All 4 tests passed.
CONSOLE: All 3 tests passed.
CONSOLE: unittest-suite-success
DONE
......@@ -12,30 +12,11 @@ void main() {
var childElementCount = DomUtils.childElementCount;
var childNodeCount = DomUtils.childNodeCount;
test("should throw with invalid arguments", () {
var parent = document.createElement("div");
expect(() {
parent.replaceChild();
}, throws);
// expect(() {
// parent.replaceChild(null, null);
// }, throws);
expect(() {
parent.replaceChild({tagName: "div"});
}, throws);
// expect(() {
// parent.replaceChild(null, document.createElement("div"));
// }, throws);
expect(() {
parent.replaceChild(document.createElement("div"), {tagName: "div"});
}, throws);
});
test("should replace elements", () {
var parent = document.createElement("div");
var oldChild = parent.appendChild(document.createElement("div"));
var newChild = document.createElement("div");
parent.replaceChild(newChild, oldChild);
oldChild.replaceWith([newChild]);
expect(oldChild.parentNode, isNull);
expect(newChild.parentNode, equals(parent));
});
......@@ -44,7 +25,7 @@ void main() {
var parent = document.createElement("div");
var oldChild = parent.appendChild(new Text(" it's a text "));
var newChild = document.createElement("div");
parent.replaceChild(newChild, oldChild);
oldChild.replaceWith([newChild]);
expect(oldChild.parentNode, isNull);
expect(newChild.parentNode, equals(parent));
});
......@@ -58,7 +39,7 @@ void main() {
var parent = document.createElement("div");
var oldChild = parent.appendChild(document.createElement("div"));
var lastChild = parent.appendChild(document.createElement("div"));
parent.replaceChild(fragment, oldChild);
oldChild.replaceWith([fragment]);
expect(child1.parentNode, equals(parent));
expect(child2.parentNode, equals(parent));
expect(child3.parentNode, equals(parent));
......
......@@ -20,9 +20,7 @@ void main() {
d.appendChild(new Text('bbb'));
var newHeight = elem.offsetHeight;
while (elem.firstChild != null) {
elem.removeChild(elem.firstChild);
}
elem.removeChildren();
new Timer(Duration.ZERO, expectAsync(() {
expect(elem.offsetHeight, equals(originalHeight));
......
......@@ -26,7 +26,7 @@ void main() {
test("should grow height to 200px", () {
var target = document.querySelectorAll('div').item(1);
target.id = 'high';
target.setAttribute("id", "high");
expect(window.getComputedStyle(target).getPropertyValue("height"),
equals("200px"));
});
......
......@@ -36,13 +36,13 @@ main() {
test("should find elements by id", () {
expect(query("#id5"), isNotNull);
expect(query("#id5").id, equals("id5"));
expect(query("#id5").getAttribute("id"), equals("id5"));
expect(query("#id5").classList.toString(), equals("class5"));
// FIXME(sky): Do we still want to allow multiple id stuff like this?
expect(queryAll("#id5").length, equals(2));
expect(queryAll("#id5").item(0), equals(query("#id5")));
expect(queryAll("#id5").item(1), isNot(equals(query("#id5"))));
expect(queryAll("#id5").item(1).id, equals("id5"));
expect(queryAll("#id5").item(1).getAttribute("id"), equals("id5"));
});
test("should find elements by tag name", () {
......@@ -55,7 +55,7 @@ main() {
test("should find an element by compound selector", () {
expect(query("tag-name-6.class6#id6"), isNotNull);
expect(query("tag-name-6.class6#id6").id, equals("id6"));
expect(query("tag-name-6.class6#id6").getAttribute("id"), equals("id6"));
expect(query("tag-name-6.class6#id6").classList.toString(), equals("class6"));
expect(query("tag-name-6.class6#id6").tagName, equals("tag-name-6"));
});
......@@ -63,21 +63,21 @@ main() {
test("should find all elements by compound selector", () {
expect(queryAll("tag-name-3.class7"), isNotNull);
expect(queryAll("tag-name-3.class7").length, equals(3));
expect(queryAll("tag-name-3.class7").item(0).id, equals("tag1"));
expect(queryAll("tag-name-3.class7").item(1).id, equals("tag2"));
expect(queryAll("tag-name-3.class7").item(0).getAttribute("id"), equals("tag1"));
expect(queryAll("tag-name-3.class7").item(1).getAttribute("id"), equals("tag2"));
});
test("should find all elements by attribute presence selector", () {
expect(queryAll("[testAttr]"), isNotNull);
expect(queryAll("[testAttr]").length, equals(2));
expect(queryAll("[testAttr]").item(0).id, equals("id5"));
expect(queryAll("[testAttr]").item(1).id, equals("id6"));
expect(queryAll("[testAttr]").item(0).getAttribute("id"), equals("id5"));
expect(queryAll("[testAttr]").item(1).getAttribute("id"), equals("id6"));
});
test("should find all elements by attribute value selector", () {
expect(queryAll("[testAttr='the value']"), isNotNull);
expect(queryAll("[testAttr='the value']").length, equals(1));
expect(queryAll("[testAttr='the value']").item(0).id, equals("id6"));
expect(queryAll("[testAttr='the value']").item(0).getAttribute("id"), equals("id6"));
});
}
</script>
......
PASS: <div class= id=id1> order was 1
PASS: <div class=class2 id=> order was 2
PASS: <tag-name-3 class= id=> order was 3
PASS: <div class=class4 class4 id=> order was 4
PASS: <div class=class2 id=null> order was 2
PASS: <tag-name-3 class= id=null> order was 3
PASS: <div class=class4 class4 id=null> order was 4
PASS: <div class=class5 id=id5> order was 5
PASS: <tag-name-6 class=class6 id=id6> order was 6
......@@ -26,7 +26,7 @@
var tests = document.getElementById("tests");
var log = document.getElementById("log");
var i = 1;
for (var element = tests.firstElementChild; element != null; element = element.nextElementSibling) {
for (Element element = tests.firstElementChild; element != null; element = element.nextElementSibling) {
var order = int.parse(window.getComputedStyle(element).getPropertyValue("order"));
var div = document.createElement("div");
var text = (order == i) ? "PASS" : "FAIL";
......@@ -34,7 +34,7 @@
+ element.tagName
+ " class="
+ element.classList.toString()
+ " id=" + element.id
+ " id=" + element.getAttribute("id").toString()
+ "> order was "
+ order.toString();
if (order != i)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册