18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
2dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2007, 2009, 2010 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSNode.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Attr.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CDATASection.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Comment.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DocumentFragment.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DocumentType.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Entity.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EntityReference.h"
37dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "ExceptionCode.h"
382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "HTMLAudioElement.h"
392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "HTMLCanvasElement.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLElement.h"
412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "HTMLFrameElementBase.h"
422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "HTMLImageElement.h"
432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "HTMLLinkElement.h"
442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "HTMLNames.h"
452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "HTMLScriptElement.h"
462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "HTMLStyleElement.h"
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSAttr.h"
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSCDATASection.h"
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSComment.h"
50dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "JSDOMBinding.h"
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSDocument.h"
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSDocumentFragment.h"
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSDocumentType.h"
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSEntity.h"
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSEntityReference.h"
568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "JSEventListener.h"
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSHTMLElement.h"
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSHTMLElementWrapperFactory.h"
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSNotation.h"
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSProcessingInstruction.h"
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSText.h"
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Node.h"
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Notation.h"
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ProcessingInstruction.h"
655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "RegisteredEventListener.h"
662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "StyleSheet.h"
672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "StyledElement.h"
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Text.h"
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/PassRefPtr.h>
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/RefPtr.h>
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(SVG)
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSSVGElementWrapperFactory.h"
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SVGElement.h"
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace JSC;
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochusing namespace HTMLNames;
822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic bool isObservable(JSNode* jsNode, Node* node, DOMWrapperWorld* world)
842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Certain conditions implicitly make existence of a JS DOM node wrapper observable
862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // through the DOM, even if no explicit reference to it remains.
872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // The DOM doesn't know how to keep a tree of nodes alive without the root
892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // being explicitly referenced. So, we artificially treat the root of
902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // every tree as observable.
912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // FIXME: Resolve this lifetime issue in the DOM, and remove this inefficiency.
922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!node->parentNode())
932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return true;
942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // If a node is in the document, and its wrapper has custom properties,
962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // the wrapper is observable because future access to the node through the
972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // DOM must reflect those properties.
982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (jsNode->hasCustomProperties())
992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return true;
1002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // If a node is in the document, and has event listeners, its wrapper is
1022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // observable because its wrapper is responsible for marking those event listeners.
1032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (node->hasEventListeners())
1042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return true;
1052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // If a node owns another object with a wrapper with custom properties,
1072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // the wrapper must be treated as observable, because future access to
1082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // those objects through the DOM must reflect those properties.
1092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // FIXME: It would be better if this logic could be in the node next to
1102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // the custom markChildren functions rather than here.
1112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Note that for some compound objects like stylesheets and CSSStyleDeclarations,
1122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // we don't descend to check children for custom properties, and just conservatively
1132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // keep the node wrappers protecting them alive.
1142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (node->isElementNode()) {
1152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (node->isStyledElement()) {
1162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (CSSMutableStyleDeclaration* style = static_cast<StyledElement*>(node)->inlineStyleDecl()) {
1172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                if (world->m_wrappers.get(style))
1182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    return true;
1192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            }
1202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
1212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (static_cast<Element*>(node)->hasTagName(canvasTag)) {
1222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (CanvasRenderingContext* context = static_cast<HTMLCanvasElement*>(node)->renderingContext()) {
1232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                if (JSDOMWrapper* wrapper = world->m_wrappers.get(context).get()) {
1242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    if (wrapper->hasCustomProperties())
1252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                        return true;
1262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                }
1272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            }
1282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        } else if (static_cast<Element*>(node)->hasTagName(linkTag)) {
1292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (StyleSheet* sheet = static_cast<HTMLLinkElement*>(node)->sheet()) {
1302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                if (world->m_wrappers.get(sheet))
1312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    return true;
1322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            }
1332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        } else if (static_cast<Element*>(node)->hasTagName(styleTag)) {
1342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (StyleSheet* sheet = static_cast<HTMLStyleElement*>(node)->sheet()) {
1352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                if (world->m_wrappers.get(sheet))
1362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    return true;
1372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            }
1382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
1392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    } else if (node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE) {
1402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (StyleSheet* sheet = static_cast<ProcessingInstruction*>(node)->sheet()) {
1412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (world->m_wrappers.get(sheet))
1422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                return true;
1432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
1442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
1452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return false;
1472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
1482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic inline bool isReachableFromDOM(JSNode* jsNode, Node* node, DOMWrapperWorld* world, MarkStack& markStack)
1502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
1512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!node->inDocument()) {
1522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // If a wrapper is the last reference to an image or script element
1532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // that is loading but not in the document, the wrapper is observable
1542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // because it is the only thing keeping the image element alive, and if
1552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // the image element is destroyed, its load event will not fire.
1562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // FIXME: The DOM should manage this issue without the help of JavaScript wrappers.
1572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (node->hasTagName(imgTag) && !static_cast<HTMLImageElement*>(node)->haveFiredLoadEvent())
1582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return true;
1592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (node->hasTagName(scriptTag) && !static_cast<HTMLScriptElement*>(node)->haveFiredLoadEvent())
1602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return true;
1612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    #if ENABLE(VIDEO)
1622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (node->hasTagName(audioTag) && !static_cast<HTMLAudioElement*>(node)->paused())
1632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return true;
1642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    #endif
1652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // If a node is firing event listeners, its wrapper is observable because
1672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // its wrapper is responsible for marking those event listeners.
1682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (node->isFiringEventListeners())
1692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return true;
1702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
1712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return isObservable(jsNode, node, world) && markStack.containsOpaqueRoot(root(node));
1732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
1742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool JSNodeOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void* context, MarkStack& markStack)
1762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
1772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    JSNode* jsNode = static_cast<JSNode*>(handle.get().asCell());
1782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    DOMWrapperWorld* world = static_cast<DOMWrapperWorld*>(context);
1792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return isReachableFromDOM(jsNode, jsNode->impl(), world, markStack);
1802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
1812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid JSNodeOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
1832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
1842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    JSNode* jsNode = static_cast<JSNode*>(handle.get().asCell());
1852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    DOMWrapperWorld* world = static_cast<DOMWrapperWorld*>(context);
1862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    uncacheWrapper(world, jsNode->impl(), jsNode);
1872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
1882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1895af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeJSValue JSNode::insertBefore(ExecState* exec)
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
191dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Node* imp = static_cast<Node*>(impl());
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ExceptionCode ec = 0;
1935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool ok = imp->insertBefore(toNode(exec->argument(0)), toNode(exec->argument(1)), ec, true);
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setDOMException(exec, ec);
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ok)
1965af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return exec->argument(0);
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return jsNull();
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2005af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeJSValue JSNode::replaceChild(ExecState* exec)
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
202dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Node* imp = static_cast<Node*>(impl());
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ExceptionCode ec = 0;
2045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool ok = imp->replaceChild(toNode(exec->argument(0)), toNode(exec->argument(1)), ec, true);
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setDOMException(exec, ec);
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ok)
2075af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return exec->argument(1);
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return jsNull();
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2115af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeJSValue JSNode::removeChild(ExecState* exec)
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
213dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Node* imp = static_cast<Node*>(impl());
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ExceptionCode ec = 0;
2155af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool ok = imp->removeChild(toNode(exec->argument(0)), ec);
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setDOMException(exec, ec);
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ok)
2185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return exec->argument(0);
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return jsNull();
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2225af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeJSValue JSNode::appendChild(ExecState* exec)
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
224dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Node* imp = static_cast<Node*>(impl());
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ExceptionCode ec = 0;
2265af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool ok = imp->appendChild(toNode(exec->argument(0)), ec, true);
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setDOMException(exec, ec);
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ok)
2295af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        return exec->argument(0);
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return jsNull();
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochScopeChainNode* JSNode::pushEventHandlerScope(ExecState*, ScopeChainNode* node) const
2348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
23581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return node;
2368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
2378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid JSNode::markChildren(MarkStack& markStack)
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    Base::markChildren(markStack);
241231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
242231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    Node* node = m_impl.get();
2438a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    node->markJSEventListeners(markStack);
2440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    markStack.addOpaqueRoot(root(node));
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
248dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic ALWAYS_INLINE JSValue createWrapperInline(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(node);
2512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ASSERT(!getCachedWrapper(currentWorld(exec), node));
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSNode* wrapper;
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (node->nodeType()) {
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ELEMENT_NODE:
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node->isHTMLElement())
2572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                wrapper = createJSHTMLWrapper(exec, globalObject, toHTMLElement(node));
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(SVG)
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else if (node->isSVGElement())
2600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                wrapper = createJSSVGWrapper(exec, globalObject, static_cast<SVGElement*>(node));
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
2630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Element, node);
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ATTRIBUTE_NODE:
2660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Attr, node);
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::TEXT_NODE:
2690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Text, node);
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::CDATA_SECTION_NODE:
2720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, CDATASection, node);
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ENTITY_NODE:
2750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Entity, node);
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::PROCESSING_INSTRUCTION_NODE:
2780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, ProcessingInstruction, node);
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::COMMENT_NODE:
2810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Comment, node);
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_NODE:
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // we don't want to cache the document itself in the per-document dictionary
2850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return toJS(exec, globalObject, static_cast<Document*>(node));
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_TYPE_NODE:
2870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, DocumentType, node);
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::NOTATION_NODE:
2900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Notation, node);
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::DOCUMENT_FRAGMENT_NODE:
2930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, DocumentFragment, node);
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Node::ENTITY_REFERENCE_NODE:
2960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, EntityReference, node);
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        default:
2990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Node, node);
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return wrapper;
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
304dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
305dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockJSValue createWrapper(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
307dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return createWrapperInline(exec, globalObject, node);
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
310dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockJSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!node)
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return jsNull();
314dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
315dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return createWrapperInline(exec, globalObject, node);
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
319