示例#1
0
PassRefPtr<DOMStringList> HTMLPropertiesCollection::names() const
{
    m_properties.clear();
    m_propertyNames->clear();

    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;
}
示例#2
0
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);
    }
}
示例#3
0
void HTMLPropertiesCollection::updateNameCache() const
{
    if (hasNameCache())
        return;

    updateRefElements();

    for (unsigned i = 0; i < m_itemRefElements.size(); ++i) {
        HTMLElement* refElement = m_itemRefElements[i];
        for (HTMLElement* element = virtualItemAfter(refElement, 0); element; element = virtualItemAfter(refElement, element)) {
            DOMSettableTokenList* itemProperty = element->itemProp();
            for (unsigned propertyIndex = 0; propertyIndex < itemProperty->length(); ++propertyIndex)
                updatePropertyCache(element, itemProperty->item(propertyIndex));
        }
    }

    setHasNameCache();
}
示例#4
0
void HTMLElement::getItemRefElements(Vector<HTMLElement*>& itemRefElements)
{
    if (!fastHasAttribute(itemscopeAttr))
        return;

    if (!fastHasAttribute(itemrefAttr) || !itemRef()->length()) {
        itemRefElements.append(this);
        return;
    }

    DOMSettableTokenList* itemRefs = itemRef();
    RefPtr<DOMSettableTokenList> processedItemRef = DOMSettableTokenList::create();

    Node* rootNode;
    if (inDocument())
        rootNode = document();
    else {
        rootNode = this;
        while (Node* parent = rootNode->parentNode())
            rootNode = parent;
    }

    for (Node* current = rootNode; current; current = NodeTraversal::next(current, rootNode)) {
        if (!current->isHTMLElement())
            continue;
        HTMLElement* element = toHTMLElement(current);

        if (element == this) {
            itemRefElements.append(element);
            continue;
        }

        const AtomicString& id = element->getIdAttribute();
        if (!processedItemRef->tokens().contains(id) && itemRefs->tokens().contains(id)) {
            processedItemRef->setValue(id);
            if (!element->isDescendantOf(this))
                itemRefElements.append(element);
        }
    }
}
v8::Handle<v8::Value> V8DOMSettableTokenList::indexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info)
{
    INC_STATS("DOM.DOMSettableTokenList.IndexedPropertyGetter");
    DOMSettableTokenList* list = V8DOMSettableTokenList::toNative(info.Holder());
    return v8StringOrNull(list->item(index));
}