Example #1
0
JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Document* document)
{
    if (!document)
        return jsNull();

    DOMObject* wrapper = getCachedDOMNodeWrapper(exec, document, document);
    if (wrapper)
        return wrapper;

    if (document->isHTMLDocument())
        wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, HTMLDocument, document);
#if ENABLE(SVG)
    else if (document->isSVGDocument())
        wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, SVGDocument, document);
#endif
    else
        wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Document, document);

    // Make sure the document is kept around by the window object, and works right with the
    // back/forward cache.
    if (!document->frame()) {
        size_t nodeCount = 0;
        for (Node* n = document; n; n = n->traverseNextNode())
            nodeCount++;
        
        exec->heap()->reportExtraMemoryCost(nodeCount * sizeof(Node));
    }

    return wrapper;
}
void JSSVGElementInstance::markChildren(MarkStack& markStack)
{
    Base::markChildren(markStack);

    // Mark the wrapper for our corresponding element, so it can mark its event handlers.
    JSNode* correspondingWrapper = getCachedDOMNodeWrapper(impl()->correspondingElement()->document(), impl()->correspondingElement());
    if (correspondingWrapper)
        markStack.append(correspondingWrapper);
}
Example #3
0
static ALWAYS_INLINE JSValue createWrapperInline(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
{
    ASSERT(node);
    ASSERT(!getCachedDOMNodeWrapper(exec, node->document(), node));
    
    JSNode* wrapper;    
    switch (node->nodeType()) {
        case Node::ELEMENT_NODE:
            if (node->isHTMLElement())
                wrapper = createJSHTMLWrapper(exec, globalObject, static_cast<HTMLElement*>(node));
#if ENABLE(SVG)
            else if (node->isSVGElement())
                wrapper = createJSSVGWrapper(exec, globalObject, static_cast<SVGElement*>(node));
#endif
            else
                wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Element, node);
            break;
        case Node::ATTRIBUTE_NODE:
            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Attr, node);
            break;
        case Node::TEXT_NODE:
            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Text, node);
            break;
        case Node::CDATA_SECTION_NODE:
            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, CDATASection, node);
            break;
        case Node::ENTITY_NODE:
            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Entity, node);
            break;
        case Node::PROCESSING_INSTRUCTION_NODE:
            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, ProcessingInstruction, node);
            break;
        case Node::COMMENT_NODE:
            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Comment, node);
            break;
        case Node::DOCUMENT_NODE:
            // we don't want to cache the document itself in the per-document dictionary
            return toJS(exec, globalObject, static_cast<Document*>(node));
        case Node::DOCUMENT_TYPE_NODE:
            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, DocumentType, node);
            break;
        case Node::NOTATION_NODE:
            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Notation, node);
            break;
        case Node::DOCUMENT_FRAGMENT_NODE:
            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, DocumentFragment, node);
            break;
        case Node::ENTITY_REFERENCE_NODE:
            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, EntityReference, node);
            break;
        default:
            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Node, node);
    }

    return wrapper;    
}
Example #4
0
JSValuePtr toJS(ExecState* exec, Node* node)
{
    if (!node)
        return jsNull();

    JSNode* wrapper = getCachedDOMNodeWrapper(node->document(), node);
    if (wrapper)
        return wrapper;

    return createWrapper(exec, node);
}
Example #5
0
void JSNode::mark()
{
    ASSERT(!marked());

    Node* node = m_impl.get();

    // Nodes in the document are kept alive by JSDocument::mark,
    // so we have no special responsibilities and can just call the base class here.
    if (node->inDocument()) {
        // But if the document isn't marked we have to mark it to ensure that
        // nodes reachable from this one are also marked
        if (Document* doc = node->ownerDocument())
            if (DOMObject* docWrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), doc))
                if (!docWrapper->marked())
                    docWrapper->mark();
        DOMObject::mark();
        return;
    }

    // This is a node outside the document, so find the root of the tree it is in,
    // and start marking from there.
    Node* root = node;
    for (Node* current = m_impl.get(); current; current = current->parentNode())
        root = current;

    // If we're already marking this tree, then we can simply mark this wrapper
    // by calling the base class; our caller is iterating the tree.
    if (root->inSubtreeMark()) {
        DOMObject::mark();
        return;
    }

    // Mark the whole tree; use the global set of roots to avoid reentering.
    root->setInSubtreeMark(true);
    for (Node* nodeToMark = root; nodeToMark; nodeToMark = nodeToMark->traverseNextNode()) {
        JSNode* wrapper = getCachedDOMNodeWrapper(m_impl->document(), nodeToMark);
        if (wrapper) {
            if (!wrapper->marked())
                wrapper->mark();
        } else if (nodeToMark == node) {
            // This is the case where the map from the document to wrappers has
            // been cleared out, but a wrapper is being marked. For now, we'll
            // let the rest of the tree of wrappers get collected, because we have
            // no good way of finding them. Later we should test behavior of other
            // browsers and see if we need to preserve other wrappers in this case.
            if (!marked())
                mark();
        }
    }
    root->setInSubtreeMark(false);

    // Double check that we actually ended up marked. This assert caught problems in the past.
    ASSERT(marked());
}
Example #6
0
void JSStyleSheet::mark()
{
    Base::mark();

    // This prevents us from having a style sheet with a dangling ownerNode pointer.
    // A better solution would be to handle this on the DOM side -- if the style sheet
    // is kept around, then we want the node to stay around too. One possibility would
    // be to make ref/deref on the style sheet ref/deref the node instead, but there's
    // a lot of disentangling of the CSS DOM objects that would need to happen first.
    if (Node* ownerNode = impl()->ownerNode()) {
        if (JSNode* ownerNodeWrapper = getCachedDOMNodeWrapper(ownerNode->document(), ownerNode)) {
            if (!ownerNodeWrapper->marked())
                ownerNodeWrapper->mark();
        }
    }
}