summaryrefslogtreecommitdiff
path: root/Source/WebCore/html/HTMLPropertiesCollection.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-01-06 14:44:00 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-01-06 14:44:00 +0100
commit40736c5763bf61337c8c14e16d8587db021a87d4 (patch)
treeb17a9c00042ad89cb1308e2484491799aa14e9f8 /Source/WebCore/html/HTMLPropertiesCollection.cpp
downloadqtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Source/WebCore/html/HTMLPropertiesCollection.cpp')
-rw-r--r--Source/WebCore/html/HTMLPropertiesCollection.cpp186
1 files changed, 186 insertions, 0 deletions
diff --git a/Source/WebCore/html/HTMLPropertiesCollection.cpp b/Source/WebCore/html/HTMLPropertiesCollection.cpp
new file mode 100644
index 000000000..439bae68c
--- /dev/null
+++ b/Source/WebCore/html/HTMLPropertiesCollection.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2011 Motorola Mobility, 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:
+ *
+ * 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 Motorola Mobility, 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 HOLDER 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(MICRODATA)
+
+#include "HTMLPropertiesCollection.h"
+
+#include "DOMSettableTokenList.h"
+#include "DOMStringList.h"
+#include "HTMLElement.h"
+#include "HTMLNames.h"
+#include "Node.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static inline bool compareTreeOrder(Node* node1, Node* node2)
+{
+ return (node2->compareDocumentPosition(node1) & (Node::DOCUMENT_POSITION_PRECEDING | Node::DOCUMENT_POSITION_DISCONNECTED)) == Node::DOCUMENT_POSITION_PRECEDING;
+}
+
+PassRefPtr<HTMLPropertiesCollection> HTMLPropertiesCollection::create(PassRefPtr<Node> itemNode)
+{
+ return adoptRef(new HTMLPropertiesCollection(itemNode));
+}
+
+HTMLPropertiesCollection::HTMLPropertiesCollection(PassRefPtr<Node> itemNode)
+ : HTMLCollection(itemNode, ItemProperties)
+ , m_propertyNames(DOMStringList::create())
+{
+}
+
+HTMLPropertiesCollection::~HTMLPropertiesCollection()
+{
+}
+
+void HTMLPropertiesCollection::findPropetiesOfAnItem(Node* root) const
+{
+ // 5.2.5 Associating names with items.
+ Vector<Node*> memory;
+
+ memory.append(root);
+
+ Vector<Node*> pending;
+ // Add the child elements of root, if any, to pending.
+ for (Node* child = root->firstChild(); child; child = child->nextSibling())
+ if (child->isHTMLElement())
+ pending.append(child);
+
+ // If root has an itemref attribute, split the value of that itemref attribute on spaces.
+ // For each resulting token ID, if there is an element in the home subtree of root with the ID ID,
+ // then add the first such element to pending.
+ if (toHTMLElement(root)->fastHasAttribute(itemrefAttr)) {
+ DOMSettableTokenList* itemRef = root->itemRef();
+
+ for (size_t i = 0; i < itemRef->length(); ++i) {
+ AtomicString id = itemRef->item(i);
+
+ Element* element = root->document()->getElementById(id);
+ if (element && element->isHTMLElement())
+ pending.append(element);
+ }
+ }
+
+ // Loop till we have processed all pending elements
+ while (!pending.isEmpty()) {
+
+ // Remove first element from pending and let current be that element.
+ Node* current = pending[0];
+ pending.remove(0);
+
+ // If current is already in memory, there is a microdata error;
+ if (memory.contains(current)) {
+ // microdata error;
+ continue;
+ }
+
+ memory.append(current);
+
+ // If current does not have an itemscope attribute, then: add all the child elements of current to pending.
+ HTMLElement* element = toHTMLElement(current);
+ if (!element->fastHasAttribute(itemscopeAttr)) {
+ for (Node* child = current->firstChild(); child; child = child->nextSibling())
+ if (child->isHTMLElement())
+ pending.append(child);
+ }
+
+ // If current has an itemprop attribute specified, add it to results.
+ if (element->fastHasAttribute(itempropAttr))
+ m_properties.append(current);
+ }
+}
+
+unsigned HTMLPropertiesCollection::length() const
+{
+ if (!base())
+ return 0;
+
+ if (!base()->isHTMLElement() || !toHTMLElement(base())->fastHasAttribute(itemscopeAttr))
+ return 0;
+
+ m_properties.clear();
+ findPropetiesOfAnItem(base());
+ return m_properties.size();
+}
+
+Node* HTMLPropertiesCollection::item(unsigned index) const
+{
+ if (!base())
+ return 0;
+
+ if (!base()->isHTMLElement() || !toHTMLElement(base())->fastHasAttribute(itemscopeAttr))
+ return 0;
+
+ m_properties.clear();
+ findPropetiesOfAnItem(base());
+
+ if (m_properties.size() <= index)
+ return 0;
+
+ std::sort(m_properties.begin(), m_properties.end(), compareTreeOrder);
+ return m_properties[index];
+}
+
+PassRefPtr<DOMStringList> HTMLPropertiesCollection::names() const
+{
+ m_properties.clear();
+ m_propertyNames->clear();
+
+ if (!base())
+ return 0;
+
+ if (!base()->isHTMLElement() || !toHTMLElement(base())->fastHasAttribute(itemscopeAttr))
+ return m_propertyNames;
+
+ findPropetiesOfAnItem(base());
+
+ std::sort(m_properties.begin(), m_properties.end(), compareTreeOrder);
+
+ for (size_t i = 0; i < m_properties.size(); ++i) {
+ // For each item properties, split the value of that itemprop attribute on spaces.
+ // Add all tokens to property names, with the order preserved but with duplicates removed.
+ DOMSettableTokenList* itemProperty = m_properties[i]->itemProp();
+ for (size_t i = 0; i < itemProperty->length(); ++i) {
+ AtomicString propertyName = itemProperty->item(i);
+ if (m_propertyNames->isEmpty() || !m_propertyNames->contains(propertyName))
+ m_propertyNames->append(propertyName);
+ }
+ }
+
+ return m_propertyNames;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MICRODATA)