From 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c Mon Sep 17 00:00:00 2001 From: Lorry Tar Creator Date: Tue, 27 Jun 2017 06:07:23 +0000 Subject: webkitgtk-2.16.5 --- Source/WebCore/html/CollectionTraversal.h | 245 ++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 Source/WebCore/html/CollectionTraversal.h (limited to 'Source/WebCore/html/CollectionTraversal.h') diff --git a/Source/WebCore/html/CollectionTraversal.h b/Source/WebCore/html/CollectionTraversal.h new file mode 100644 index 000000000..66829338d --- /dev/null +++ b/Source/WebCore/html/CollectionTraversal.h @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 APPLE INC. AND ITS 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 APPLE INC. OR ITS 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. + */ + +#pragma once + +#include "CollectionType.h" +#include "ElementChildIterator.h" +#include "ElementDescendantIterator.h" + +namespace WebCore { + +template +struct CollectionTraversal { }; + +template <> +struct CollectionTraversal { + using Iterator = ElementDescendantIterator; + + static ElementDescendantIterator end(ContainerNode&) { return ElementDescendantIterator(); } + + template + static ElementDescendantIterator begin(const CollectionClass&, ContainerNode& rootNode); + + template + static ElementDescendantIterator last(const CollectionClass&, ContainerNode& rootNode); + + template + static void traverseForward(const CollectionClass&, ElementDescendantIterator& current, unsigned count, unsigned& traversedCount); + + template + static void traverseBackward(const CollectionClass&, ElementDescendantIterator& current, unsigned count); +}; + +template +inline ElementDescendantIterator CollectionTraversal::begin(const CollectionClass& collection, ContainerNode& rootNode) +{ + auto descendants = elementDescendants(rootNode); + auto end = descendants.end(); + for (auto it = descendants.begin(); it != end; ++it) { + if (collection.elementMatches(*it)) { + // Drop iterator assertions because HTMLCollections / NodeList use a fine-grained invalidation scheme. + it.dropAssertions(); + return it; + } + } + return end; +} + +template +inline ElementDescendantIterator CollectionTraversal::last(const CollectionClass& collection, ContainerNode& rootNode) +{ + auto descendants = elementDescendants(rootNode); + ElementDescendantIterator invalid; + for (auto it = descendants.last(); it != invalid; --it) { + if (collection.elementMatches(*it)) { + // Drop iterator assertions because HTMLCollections / NodeList use a fine-grained invalidation scheme. + it.dropAssertions(); + return it; + } + } + return invalid; +} + +template +inline void CollectionTraversal::traverseForward(const CollectionClass& collection, ElementDescendantIterator& current, unsigned count, unsigned& traversedCount) +{ + ASSERT(collection.elementMatches(*current)); + ElementDescendantIterator invalid; + for (traversedCount = 0; traversedCount < count; ++traversedCount) { + do { + ++current; + if (current == invalid) + return; + } while (!collection.elementMatches(*current)); + } +} + +template +inline void CollectionTraversal::traverseBackward(const CollectionClass& collection, ElementDescendantIterator& current, unsigned count) +{ + ASSERT(collection.elementMatches(*current)); + ElementDescendantIterator invalid; + for (; count; --count) { + do { + --current; + if (current == invalid) + return; + } while (!collection.elementMatches(*current)); + } +} + +template <> +struct CollectionTraversal { + using Iterator = ElementChildIterator; + + static ElementChildIterator end(ContainerNode& rootNode) { return ElementChildIterator(rootNode); } + + template + static ElementChildIterator begin(const CollectionClass&, ContainerNode& rootNode); + + template + static ElementChildIterator last(const CollectionClass&, ContainerNode& rootNode); + + template + static void traverseForward(const CollectionClass&, ElementChildIterator& current, unsigned count, unsigned& traversedCount); + + template + static void traverseBackward(const CollectionClass&, ElementChildIterator& current, unsigned count); +}; + +template +inline ElementChildIterator CollectionTraversal::begin(const CollectionClass& collection, ContainerNode& rootNode) +{ + auto children = childrenOfType(rootNode); + auto end = children.end(); + for (auto it = children.begin(); it != end; ++it) { + if (collection.elementMatches(*it)) { + // Drop iterator assertions because HTMLCollections / NodeList use a fine-grained invalidation scheme. + it.dropAssertions(); + return it; + } + } + return end; +} + +template +inline ElementChildIterator CollectionTraversal::last(const CollectionClass& collection, ContainerNode& rootNode) +{ + auto children = childrenOfType(rootNode); + ElementChildIterator invalid(collection.rootNode()); + ElementChildIterator last(rootNode, children.last()); + for (auto it = last; it != invalid; --it) { + if (collection.elementMatches(*it)) { + // Drop iterator assertions because HTMLCollections / NodeList use a fine-grained invalidation scheme. + it.dropAssertions(); + return it; + } + } + return invalid; +} + +template +inline void CollectionTraversal::traverseForward(const CollectionClass& collection, ElementChildIterator& current, unsigned count, unsigned& traversedCount) +{ + ASSERT(collection.elementMatches(*current)); + ElementChildIterator invalid(collection.rootNode()); + for (traversedCount = 0; traversedCount < count; ++traversedCount) { + do { + ++current; + if (current == invalid) + return; + } while (!collection.elementMatches(*current)); + } +} + +template +inline void CollectionTraversal::traverseBackward(const CollectionClass& collection, ElementChildIterator& current, unsigned count) +{ + ASSERT(collection.elementMatches(*current)); + ElementChildIterator invalid(collection.rootNode()); + for (; count; --count) { + do { + --current; + if (current == invalid) + return; + } while (!collection.elementMatches(*current)); + } +} + +template <> +struct CollectionTraversal { + using Iterator = Element*; + + static Element* end(ContainerNode&) { return nullptr; } + + template + static Element* begin(const CollectionClass&, ContainerNode&); + + template + static Element* last(const CollectionClass&, ContainerNode&); + + template + static void traverseForward(const CollectionClass&, Element*& current, unsigned count, unsigned& traversedCount); + + template + static void traverseBackward(const CollectionClass&, Element*&, unsigned count); +}; + +template +inline Element* CollectionTraversal::begin(const CollectionClass& collection, ContainerNode&) +{ + return collection.customElementAfter(nullptr); +} + +template +inline Element* CollectionTraversal::last(const CollectionClass&, ContainerNode&) +{ + ASSERT_NOT_REACHED(); + return nullptr; +} + +template +inline void CollectionTraversal::traverseForward(const CollectionClass& collection, Element*& current, unsigned count, unsigned& traversedCount) +{ + Element* element = current; + for (traversedCount = 0; traversedCount < count; ++traversedCount) { + element = collection.customElementAfter(element); + if (!element) { + current = nullptr; + return; + } + } + current = element; +} + +template +inline void CollectionTraversal::traverseBackward(const CollectionClass&, Element*&, unsigned count) +{ + UNUSED_PARAM(count); + ASSERT_NOT_REACHED(); +} + +} // namespace WebCore -- cgit v1.2.1