diff options
author | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-07 22:03:04 +0000 |
---|---|---|
committer | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-07 22:03:04 +0000 |
commit | 2980234571ab83756a11ed71497d1132687aaf88 (patch) | |
tree | 88115f2cbb94ceed1299a3b1a73b18085e4432b8 /webkit/pending | |
parent | c30cf1ab3662fbe9c5ed23f5e575061cf68591ae (diff) | |
download | chromium_src-2980234571ab83756a11ed71497d1132687aaf88.zip chromium_src-2980234571ab83756a11ed71497d1132687aaf88.tar.gz chromium_src-2980234571ab83756a11ed71497d1132687aaf88.tar.bz2 |
Revert r2927 and r2930, which were themselves reversions of prior changelists.
(Misc. build fixes for KJS build and remnants of unforking a couple of files.)
Review URL: http://codereview.chromium.org/6321
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2969 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/pending')
-rw-r--r-- | webkit/pending/HTMLPlugInElement.cpp | 211 | ||||
-rw-r--r-- | webkit/pending/HTMLPlugInElement.h | 84 | ||||
-rw-r--r-- | webkit/pending/Node.cpp | 2010 | ||||
-rw-r--r-- | webkit/pending/Node.h | 549 | ||||
-rw-r--r-- | webkit/pending/ScriptController.h | 328 |
5 files changed, 0 insertions, 3182 deletions
diff --git a/webkit/pending/HTMLPlugInElement.cpp b/webkit/pending/HTMLPlugInElement.cpp deleted file mode 100644 index 19d494e..0000000 --- a/webkit/pending/HTMLPlugInElement.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/** - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * (C) 2000 Stefan Schimanski (1Stein@gmx.de) - * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ -#include "config.h" -#include "HTMLPlugInElement.h" - -#include "CSSPropertyNames.h" -#include "Document.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "FrameTree.h" -#include "HTMLNames.h" -#include "Page.h" -#include "RenderWidget.h" -#include "Settings.h" -#include "Widget.h" -#include "ScriptController.h" - -#if USE(JSC) -#include "runtime.h" -#endif - -#if ENABLE(NETSCAPE_PLUGIN_API) && USE(JSC) -#include "JSNode.h" -#include "NP_jsobject.h" -#include "npruntime_impl.h" -#include "runtime_root.h" -#endif - -namespace WebCore { - -using namespace HTMLNames; - -HTMLPlugInElement::HTMLPlugInElement(const QualifiedName& tagName, Document* doc) - : HTMLFrameOwnerElement(tagName, doc) -#if ENABLE(NETSCAPE_PLUGIN_API) - , m_NPObject(0) -#endif -{ -} - -HTMLPlugInElement::~HTMLPlugInElement() -{ -#if USE(JSC) - ASSERT(!m_instance); // cleared in detach() -#endif - -#if ENABLE(NETSCAPE_PLUGIN_API) - if (m_NPObject) { - // NOTE: mbelshe - can the frame be inaccessible here? If so, - // do we leak objects? - if (document() && document()->frame()) - document()->frame()->script()->functions()->releaseObject(m_NPObject); - m_NPObject = 0; - } -#endif -} - -JSInstance HTMLPlugInElement::getInstance() const -{ - Frame* frame = document()->frame(); - if (!frame) - return JSInstanceHolder::EmptyInstance(); - - // If the host dynamically turns off JavaScript (or Java) we will still return - // the cached allocated Bindings::Instance. Not supporting this edge-case is OK. - if (!m_instance.IsEmpty()) - return m_instance.Get(); - - RenderWidget* renderWidget = renderWidgetForJSBindings(); - if (renderWidget && renderWidget->widget()) - m_instance = frame->script()->createScriptInstanceForWidget(renderWidget->widget()); - - return m_instance.Get(); -} - -void HTMLPlugInElement::detach() -{ - m_instance.Clear(); - HTMLFrameOwnerElement::detach(); -} - -String HTMLPlugInElement::align() const -{ - return getAttribute(alignAttr); -} - -void HTMLPlugInElement::setAlign(const String& value) -{ - setAttribute(alignAttr, value); -} - -String HTMLPlugInElement::height() const -{ - return getAttribute(heightAttr); -} - -void HTMLPlugInElement::setHeight(const String& value) -{ - setAttribute(heightAttr, value); -} - -String HTMLPlugInElement::name() const -{ - return getAttribute(nameAttr); -} - -void HTMLPlugInElement::setName(const String& value) -{ - setAttribute(nameAttr, value); -} - -String HTMLPlugInElement::width() const -{ - return getAttribute(widthAttr); -} - -void HTMLPlugInElement::setWidth(const String& value) -{ - setAttribute(widthAttr, value); -} - -bool HTMLPlugInElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const -{ - if (attrName == widthAttr || - attrName == heightAttr || - attrName == vspaceAttr || - attrName == hspaceAttr) { - result = eUniversal; - return false; - } - - if (attrName == alignAttr) { - result = eReplaced; // Share with <img> since the alignment behavior is the same. - return false; - } - - return HTMLFrameOwnerElement::mapToEntry(attrName, result); -} - -void HTMLPlugInElement::parseMappedAttribute(MappedAttribute* attr) -{ - if (attr->name() == widthAttr) - addCSSLength(attr, CSSPropertyWidth, attr->value()); - else if (attr->name() == heightAttr) - addCSSLength(attr, CSSPropertyHeight, attr->value()); - else if (attr->name() == vspaceAttr) { - addCSSLength(attr, CSSPropertyMarginTop, attr->value()); - addCSSLength(attr, CSSPropertyMarginBottom, attr->value()); - } else if (attr->name() == hspaceAttr) { - addCSSLength(attr, CSSPropertyMarginLeft, attr->value()); - addCSSLength(attr, CSSPropertyMarginRight, attr->value()); - } else if (attr->name() == alignAttr) - addHTMLAlignment(attr); - else - HTMLFrameOwnerElement::parseMappedAttribute(attr); -} - -bool HTMLPlugInElement::checkDTD(const Node* newChild) -{ - return newChild->hasTagName(paramTag) || HTMLFrameOwnerElement::checkDTD(newChild); -} - -void HTMLPlugInElement::defaultEventHandler(Event* event) -{ - RenderObject* r = renderer(); - if (!r || !r->isWidget()) - return; - - if (Widget* widget = static_cast<RenderWidget*>(r)->widget()) - widget->handleEvent(event); -} - -#if ENABLE(NETSCAPE_PLUGIN_API) - -NPObject* HTMLPlugInElement::getNPObject() -{ - ASSERT(document()->frame()); - if (!m_NPObject) - m_NPObject = document()->frame()->script()->createScriptObjectForPluginElement(this); - return m_NPObject; -} - -#endif /* ENABLE(NETSCAPE_PLUGIN_API) */ - -void HTMLPlugInElement::updateWidgetCallback(Node* n) -{ - static_cast<HTMLPlugInElement*>(n)->updateWidget(); -} - -} diff --git a/webkit/pending/HTMLPlugInElement.h b/webkit/pending/HTMLPlugInElement.h deleted file mode 100644 index 599c192..0000000 --- a/webkit/pending/HTMLPlugInElement.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * Copyright (C) 2004, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef HTMLPlugInElement_h -#define HTMLPlugInElement_h - -#include "HTMLFrameOwnerElement.h" -#include "ScriptController.h" - -#if ENABLE(NETSCAPE_PLUGIN_API) -struct NPObject; -#endif - -namespace WebCore { - -class RenderWidget; - -class HTMLPlugInElement : public HTMLFrameOwnerElement { -public: - HTMLPlugInElement(const QualifiedName& tagName, Document*); - virtual ~HTMLPlugInElement(); - - virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const; - virtual void parseMappedAttribute(MappedAttribute*); - - virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; } - virtual bool checkDTD(const Node* newChild); - - virtual void updateWidget() { } - - String align() const; - void setAlign(const String&); - - String height() const; - void setHeight(const String&); - - String name() const; - void setName(const String&); - - String width() const; - void setWidth(const String&); - - virtual void defaultEventHandler(Event*); - - virtual RenderWidget* renderWidgetForJSBindings() const = 0; - virtual void detach(); - JSInstance getInstance() const; - -#if ENABLE(NETSCAPE_PLUGIN_API) - virtual NPObject* getNPObject(); -#endif - -protected: - static void updateWidgetCallback(Node*); - - AtomicString m_name; - mutable JSInstanceHolder m_instance; -#if ENABLE(NETSCAPE_PLUGIN_API) - NPObject* m_NPObject; -#endif -}; - -} // namespace WebCore - -#endif // HTMLPlugInElement_h diff --git a/webkit/pending/Node.cpp b/webkit/pending/Node.cpp deleted file mode 100644 index d16a007..0000000 --- a/webkit/pending/Node.cpp +++ /dev/null @@ -1,2010 +0,0 @@ -/* - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * (C) 2001 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2007 Trolltech ASA - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "Node.h" - -#include "CSSParser.h" -#include "CSSRule.h" -#include "CSSRuleList.h" -#include "CSSSelector.h" -#include "CSSStyleRule.h" -#include "CSSStyleSelector.h" -#include "CSSStyleSheet.h" -#include "CString.h" -#include "ChildNodeList.h" -#include "ClassNodeList.h" -#include "DOMImplementation.h" -#include "Document.h" -#include "DynamicNodeList.h" -#include "Element.h" -#include "ExceptionCode.h" -#include "ExceptionContext.h" -#include "Frame.h" -#include "HTMLNames.h" -#include "Logging.h" -#include "NSResolver.h" -#include "NameNodeList.h" -#include "NamedAttrMap.h" -#include "ProcessingInstruction.h" -#include "RenderObject.h" -#include "ScriptController.h" -#include "SelectorNodeList.h" -#include "StringBuilder.h" -#include "TagNodeList.h" -#include "Text.h" -#include "XMLNames.h" -#include "htmlediting.h" -#include <wtf/RefCountedLeakCounter.h> - -#if USE(JSC) -#include <kjs/JSLock.h> -#endif - -namespace WebCore { - -using namespace HTMLNames; - -struct NodeListsNodeData { - typedef HashSet<DynamicNodeList*> NodeListSet; - NodeListSet m_listsWithCaches; - - DynamicNodeList::Caches m_childNodeListCaches; - - typedef HashMap<String, DynamicNodeList::Caches*> CacheMap; - CacheMap m_classNodeListCaches; - CacheMap m_nameNodeListCaches; - - ~NodeListsNodeData() - { - deleteAllValues(m_classNodeListCaches); - deleteAllValues(m_nameNodeListCaches); - } - - void invalidateCaches(); - void invalidateCachesThatDependOnAttributes(); - bool isEmpty() const; -}; - -// -------- - -bool Node::isSupported(const String& feature, const String& version) -{ - return DOMImplementation::hasFeature(feature, version); -} - -#ifndef NDEBUG -static WTF::RefCountedLeakCounter nodeCounter("WebCoreNode"); - -static bool shouldIgnoreLeaks = false; -static HashSet<Node*> ignoreSet; -#endif - -void Node::startIgnoringLeaks() -{ -#ifndef NDEBUG - shouldIgnoreLeaks = true; -#endif -} - -void Node::stopIgnoringLeaks() -{ -#ifndef NDEBUG - shouldIgnoreLeaks = false; -#endif -} - -Node::StyleChange Node::diff( RenderStyle *s1, RenderStyle *s2 ) -{ - // FIXME: The behavior of this function is just totally wrong. It doesn't handle - // explicit inheritance of non-inherited properties and so you end up not re-resolving - // style in cases where you need to. - StyleChange ch = NoInherit; - EDisplay display1 = s1 ? s1->display() : NONE; - bool fl1 = s1 && s1->hasPseudoStyle(RenderStyle::FIRST_LETTER); - EDisplay display2 = s2 ? s2->display() : NONE; - bool fl2 = s2 && s2->hasPseudoStyle(RenderStyle::FIRST_LETTER); - - if (display1 != display2 || fl1 != fl2 || (s1 && s2 && !s1->contentDataEquivalent(s2))) - ch = Detach; - else if (!s1 || !s2) - ch = Inherit; - else if (*s1 == *s2) - ch = NoChange; - else if (s1->inheritedNotEqual(s2)) - ch = Inherit; - - // If the pseudoStyles have changed, we want any StyleChange that is not NoChange - // because setStyle will do the right thing with anything else. - if (ch == NoChange && s1->hasPseudoStyle(RenderStyle::BEFORE)) { - RenderStyle* ps2 = s2->getPseudoStyle(RenderStyle::BEFORE); - if (!ps2) - ch = NoInherit; - else { - RenderStyle* ps1 = s1->getPseudoStyle(RenderStyle::BEFORE); - ch = ps1 && *ps1 == *ps2 ? NoChange : NoInherit; - } - } - if (ch == NoChange && s1->hasPseudoStyle(RenderStyle::AFTER)) { - RenderStyle* ps2 = s2->getPseudoStyle(RenderStyle::AFTER); - if (!ps2) - ch = NoInherit; - else { - RenderStyle* ps1 = s1->getPseudoStyle(RenderStyle::AFTER); - ch = ps2 && *ps1 == *ps2 ? NoChange : NoInherit; - } - } - - return ch; -} - -Node::Node(Document* doc, bool isElement) - : m_document(doc) - , m_previous(0) - , m_next(0) - , m_renderer(0) - , m_tabIndex(0) - , m_styleChange(NoStyleChange) - , m_hasId(false) - , m_hasClass(false) - , m_attached(false) - , m_hasChangedChild(false) - , m_inDocument(false) - , m_isLink(false) - , m_focused(false) - , m_active(false) - , m_hovered(false) - , m_inActiveChain(false) - , m_inDetach(false) - , m_inSubtreeMark(false) - , m_tabIndexSetExplicitly(false) - , m_isElement(isElement) -{ -#ifndef NDEBUG - if (shouldIgnoreLeaks) - ignoreSet.add(this); - else - nodeCounter.increment(); -#endif -} - -void Node::setDocument(Document* doc) -{ - if (inDocument() || m_document == doc) - return; - - willMoveToNewOwnerDocument(); - - { -#if USE(JSC) - KJS::JSLock lock(false); - ScriptInterpreter::updateDOMNodeDocument(this, m_document.get(), doc); -#endif - } - m_document = doc; - - didMoveToNewOwnerDocument(); -} - -Node::~Node() -{ -#ifndef NDEBUG - HashSet<Node*>::iterator it = ignoreSet.find(this); - if (it != ignoreSet.end()) - ignoreSet.remove(it); - else - nodeCounter.decrement(); -#endif - - if (m_nodeLists && m_document) - document()->removeNodeListCache(); - - if (renderer()) - detach(); - - if (m_previous) - m_previous->setNextSibling(0); - if (m_next) - m_next->setPreviousSibling(0); -} - -String Node::nodeValue() const -{ - return String(); -} - -void Node::setNodeValue(const String& /*nodeValue*/, ExceptionCode& ec) -{ - // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly - if (isReadOnlyNode()) { - ec = NO_MODIFICATION_ALLOWED_ERR; - return; - } - - // By default, setting nodeValue has no effect. -} - -PassRefPtr<NodeList> Node::childNodes() -{ - if (!m_nodeLists) { - m_nodeLists.set(new NodeListsNodeData); - document()->addNodeListCache(); - } - - return ChildNodeList::create(this, &m_nodeLists->m_childNodeListCaches); -} - -Node* Node::virtualFirstChild() const -{ - return 0; -} - -Node* Node::virtualLastChild() const -{ - return 0; -} - -bool Node::virtualHasTagName(const QualifiedName&) const -{ - return false; -} - -Node *Node::lastDescendant() const -{ - Node *n = const_cast<Node *>(this); - while (n && n->lastChild()) - n = n->lastChild(); - return n; -} - -Node* Node::firstDescendant() const -{ - Node *n = const_cast<Node *>(this); - while (n && n->firstChild()) - n = n->firstChild(); - return n; -} - -bool Node::insertBefore(PassRefPtr<Node>, Node*, ExceptionCode& ec, bool) -{ - ec = HIERARCHY_REQUEST_ERR; - return false; -} - -bool Node::replaceChild(PassRefPtr<Node>, Node*, ExceptionCode& ec, bool) -{ - ec = HIERARCHY_REQUEST_ERR; - return false; -} - -bool Node::removeChild(Node*, ExceptionCode& ec) -{ - ec = NOT_FOUND_ERR; - return false; -} - -bool Node::appendChild(PassRefPtr<Node>, ExceptionCode& ec, bool) -{ - ec = HIERARCHY_REQUEST_ERR; - return false; -} - -void Node::remove(ExceptionCode& ec) -{ - ref(); - if (Node *p = parentNode()) - p->removeChild(this, ec); - else - ec = HIERARCHY_REQUEST_ERR; - deref(); -} - -void Node::normalize() -{ - // Go through the subtree beneath us, normalizing all nodes. This means that - // any two adjacent text nodes are merged together. - - RefPtr<Node> node = this; - while (Node* firstChild = node->firstChild()) - node = firstChild; - for (; node; node = node->traverseNextNodePostOrder()) { - NodeType type = node->nodeType(); - if (type == ELEMENT_NODE) - static_cast<Element*>(node.get())->normalizeAttributes(); - - Node* firstChild = node->firstChild(); - if (firstChild && !firstChild->nextSibling() && firstChild->isTextNode()) { - Text* text = static_cast<Text*>(firstChild); - if (!text->length()) { - ExceptionCode ec; - text->remove(ec); - } - } - - if (node == this) - break; - - if (type == TEXT_NODE) { - while (1) { - Node* nextSibling = node->nextSibling(); - if (!nextSibling || !nextSibling->isTextNode()) - break; - // Current child and the next one are both text nodes. Merge them. - Text* text = static_cast<Text*>(node.get()); - RefPtr<Text> nextText = static_cast<Text*>(nextSibling); - unsigned offset = text->length(); - ExceptionCode ec; - text->appendData(nextText->data(), ec); - document()->textNodesMerged(nextText.get(), offset); - nextText->remove(ec); - } - } - } -} - -const AtomicString& Node::prefix() const -{ - // For nodes other than elements and attributes, the prefix is always null - return nullAtom; -} - -void Node::setPrefix(const AtomicString& /*prefix*/, ExceptionCode& ec) -{ - // The spec says that for nodes other than elements and attributes, prefix is always null. - // It does not say what to do when the user tries to set the prefix on another type of - // node, however Mozilla throws a NAMESPACE_ERR exception. - ec = NAMESPACE_ERR; -} - -const AtomicString& Node::localName() const -{ - return nullAtom; -} - -const AtomicString& Node::namespaceURI() const -{ - return nullAtom; -} - -ContainerNode* Node::addChild(PassRefPtr<Node>) -{ - return 0; -} - -bool Node::isContentEditable() const -{ - return parent() && parent()->isContentEditable(); -} - -bool Node::isContentRichlyEditable() const -{ - return parent() && parent()->isContentRichlyEditable(); -} - -bool Node::shouldUseInputMethod() const -{ - return isContentEditable(); -} - -IntRect Node::getRect() const -{ - int _x, _y; - if (renderer() && renderer()->absolutePosition(_x, _y)) - return IntRect( _x, _y, renderer()->width(), renderer()->height() + renderer()->borderTopExtra() + renderer()->borderBottomExtra()); - - return IntRect(); -} - -void Node::setChanged(StyleChangeType changeType) -{ - if ((changeType != NoStyleChange) && !attached()) // changed compared to what? - return; - - if (!(changeType == InlineStyleChange && (m_styleChange == FullStyleChange || m_styleChange == AnimationStyleChange))) - m_styleChange = changeType; - - if (m_styleChange != NoStyleChange) { - for (Node* p = parentNode(); p && !p->hasChangedChild(); p = p->parentNode()) - p->setHasChangedChild(true); - document()->setDocumentChanged(true); - } -} - -static Node* outermostLazyAttachedAncestor(Node* start) -{ - Node* p = start; - for (Node* next = p->parentNode(); !next->renderer(); p = next, next = next->parentNode()) {} - return p; -} - -void Node::lazyAttach() -{ - bool mustDoFullAttach = false; - - for (Node* n = this; n; n = n->traverseNextNode(this)) { - if (!n->canLazyAttach()) { - mustDoFullAttach = true; - break; - } - - if (n->firstChild()) - n->setHasChangedChild(true); - n->m_styleChange = FullStyleChange; - n->m_attached = true; - } - - if (mustDoFullAttach) { - Node* lazyAttachedAncestor = outermostLazyAttachedAncestor(this); - if (lazyAttachedAncestor->attached()) - lazyAttachedAncestor->detach(); - lazyAttachedAncestor->attach(); - } else { - for (Node* p = parentNode(); p && !p->hasChangedChild(); p = p->parentNode()) - p->setHasChangedChild(true); - document()->setDocumentChanged(true); - } -} - -bool Node::canLazyAttach() -{ - return shadowAncestorNode() == this; -} - -bool Node::isFocusable() const -{ - return m_tabIndexSetExplicitly; -} - -bool Node::isKeyboardFocusable(KeyboardEvent*) const -{ - return isFocusable() && m_tabIndex >= 0; -} - -bool Node::isMouseFocusable() const -{ - return isFocusable(); -} - -unsigned Node::nodeIndex() const -{ - Node *_tempNode = previousSibling(); - unsigned count=0; - for( count=0; _tempNode; count++ ) - _tempNode = _tempNode->previousSibling(); - return count; -} - -void Node::registerDynamicNodeList(DynamicNodeList* list) -{ - if (!m_nodeLists) { - m_nodeLists.set(new NodeListsNodeData); - document()->addNodeListCache(); - } else if (!m_document->hasNodeListCaches()) { - // We haven't been receiving notifications while there were no registered lists, so the cache is invalid now. - m_nodeLists->invalidateCaches(); - } - - if (list->hasOwnCaches()) - m_nodeLists->m_listsWithCaches.add(list); -} - -void Node::unregisterDynamicNodeList(DynamicNodeList* list) -{ - ASSERT(m_nodeLists); - if (list->hasOwnCaches()) { - m_nodeLists->m_listsWithCaches.remove(list); - if (m_nodeLists->isEmpty()) { - m_nodeLists.clear(); - document()->removeNodeListCache(); - } - } -} - -void Node::notifyLocalNodeListsAttributeChanged() -{ - if (!m_nodeLists) - return; - - m_nodeLists->invalidateCachesThatDependOnAttributes(); - - if (m_nodeLists->isEmpty()) { - m_nodeLists.clear(); - document()->removeNodeListCache(); - } -} - -void Node::notifyNodeListsAttributeChanged() -{ - for (Node *n = this; n; n = n->parentNode()) - n->notifyLocalNodeListsAttributeChanged(); -} - -void Node::notifyLocalNodeListsChildrenChanged() -{ - if (!m_nodeLists) - return; - - m_nodeLists->invalidateCaches(); - - NodeListsNodeData::NodeListSet::iterator end = m_nodeLists->m_listsWithCaches.end(); - for (NodeListsNodeData::NodeListSet::iterator i = m_nodeLists->m_listsWithCaches.begin(); i != end; ++i) - (*i)->invalidateCache(); - - if (m_nodeLists->isEmpty()) { - m_nodeLists.clear(); - document()->removeNodeListCache(); - } -} - -void Node::notifyNodeListsChildrenChanged() -{ - for (Node* n = this; n; n = n->parentNode()) - n->notifyLocalNodeListsChildrenChanged(); -} - -unsigned Node::childNodeCount() const -{ - return 0; -} - -Node *Node::childNode(unsigned /*index*/) const -{ - return 0; -} - -Node *Node::traverseNextNode(const Node *stayWithin) const -{ - if (firstChild()) - return firstChild(); - if (this == stayWithin) - return 0; - if (nextSibling()) - return nextSibling(); - const Node *n = this; - while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin)) - n = n->parentNode(); - if (n) - return n->nextSibling(); - return 0; -} - -Node *Node::traverseNextSibling(const Node *stayWithin) const -{ - if (this == stayWithin) - return 0; - if (nextSibling()) - return nextSibling(); - const Node *n = this; - while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin)) - n = n->parentNode(); - if (n) - return n->nextSibling(); - return 0; -} - -Node* Node::traverseNextNodePostOrder() const -{ - Node* next = nextSibling(); - if (!next) - return parentNode(); - while (Node* firstChild = next->firstChild()) - next = firstChild; - return next; -} - -Node *Node::traversePreviousNode(const Node *stayWithin) const -{ - if (this == stayWithin) - return 0; - if (previousSibling()) { - Node *n = previousSibling(); - while (n->lastChild()) - n = n->lastChild(); - return n; - } - return parentNode(); -} - -Node *Node::traversePreviousNodePostOrder(const Node *stayWithin) const -{ - if (lastChild()) - return lastChild(); - if (this == stayWithin) - return 0; - if (previousSibling()) - return previousSibling(); - const Node *n = this; - while (n && !n->previousSibling() && (!stayWithin || n->parentNode() != stayWithin)) - n = n->parentNode(); - if (n) - return n->previousSibling(); - return 0; -} - -Node* Node::traversePreviousSiblingPostOrder(const Node* stayWithin) const -{ - if (this == stayWithin) - return 0; - if (previousSibling()) - return previousSibling(); - const Node *n = this; - while (n && !n->previousSibling() && (!stayWithin || n->parentNode() != stayWithin)) - n = n->parentNode(); - if (n) - return n->previousSibling(); - return 0; -} - -void Node::checkSetPrefix(const AtomicString &_prefix, ExceptionCode& ec) -{ - // Perform error checking as required by spec for setting Node.prefix. Used by - // Element::setPrefix() and Attr::setPrefix() - - // FIXME: Implement support for INVALID_CHARACTER_ERR: Raised if the specified prefix contains an illegal character. - - // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. - if (isReadOnlyNode()) { - ec = NO_MODIFICATION_ALLOWED_ERR; - return; - } - - // FIXME: Implement NAMESPACE_ERR: - Raised if the specified prefix is malformed - // We have to comment this out, since it's used for attributes and tag names, and we've only - // switched one over. - /* - // - if the namespaceURI of this node is null, - // - if the specified prefix is "xml" and the namespaceURI of this node is different from - // "http://www.w3.org/XML/1998/namespace", - // - if this node is an attribute and the specified prefix is "xmlns" and - // the namespaceURI of this node is different from "http://www.w3.org/2000/xmlns/", - // - or if this node is an attribute and the qualifiedName of this node is "xmlns" [Namespaces]. - if ((namespacePart(id()) == noNamespace && id() > ID_LAST_TAG) || - (_prefix == "xml" && String(document()->namespaceURI(id())) != "http://www.w3.org/XML/1998/namespace")) { - ec = NAMESPACE_ERR; - return; - }*/ -} - -bool Node::canReplaceChild(Node* newChild, Node* oldChild) -{ - if (newChild->nodeType() != DOCUMENT_FRAGMENT_NODE) { - if (!childTypeAllowed(newChild->nodeType())) - return false; - } - else { - for (Node *n = newChild->firstChild(); n; n = n->nextSibling()) { - if (!childTypeAllowed(n->nodeType())) - return false; - } - } - - return true; -} - -void Node::checkReplaceChild(Node* newChild, Node* oldChild, ExceptionCode& ec) -{ - // Perform error checking as required by spec for adding a new child. Used by - // appendChild(), replaceChild() and insertBefore() - - // Not mentioned in spec: throw NOT_FOUND_ERR if newChild is null - if (!newChild) { - ec = NOT_FOUND_ERR; - return; - } - - // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly - if (isReadOnlyNode()) { - ec = NO_MODIFICATION_ALLOWED_ERR; - return; - } - - bool shouldAdoptChild = false; - - // WRONG_DOCUMENT_ERR: Raised if newChild was created from a different document than the one that - // created this node. - // We assume that if newChild is a DocumentFragment, all children are created from the same document - // as the fragment itself (otherwise they could not have been added as children) - if (newChild->document() != document()) { - // but if the child is not in a document yet then loosen the - // restriction, so that e.g. creating an element with the Option() - // constructor and then adding it to a different document works, - // as it does in Mozilla and Mac IE. - if (!newChild->inDocument()) { - shouldAdoptChild = true; - } else { - ec = WRONG_DOCUMENT_ERR; - return; - } - } - - // HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not allow children of the type of the - // newChild node, or if the node to append is one of this node's ancestors. - - // check for ancestor/same node - if (newChild == this || isDescendantOf(newChild)) { - ec = HIERARCHY_REQUEST_ERR; - return; - } - - if (!canReplaceChild(newChild, oldChild)) { - ec = HIERARCHY_REQUEST_ERR; - return; - } - - // change the document pointer of newChild and all of its children to be the new document - if (shouldAdoptChild) - for (Node* node = newChild; node; node = node->traverseNextNode(newChild)) - node->setDocument(document()); -} - -void Node::checkAddChild(Node *newChild, ExceptionCode& ec) -{ - // Perform error checking as required by spec for adding a new child. Used by - // appendChild(), replaceChild() and insertBefore() - - // Not mentioned in spec: throw NOT_FOUND_ERR if newChild is null - if (!newChild) { - ec = NOT_FOUND_ERR; - return; - } - - // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly - if (isReadOnlyNode()) { - ec = NO_MODIFICATION_ALLOWED_ERR; - return; - } - - bool shouldAdoptChild = false; - - // WRONG_DOCUMENT_ERR: Raised if newChild was created from a different document than the one that - // created this node. - // We assume that if newChild is a DocumentFragment, all children are created from the same document - // as the fragment itself (otherwise they could not have been added as children) - if (newChild->document() != document()) { - // but if the child is not in a document yet then loosen the - // restriction, so that e.g. creating an element with the Option() - // constructor and then adding it to a different document works, - // as it does in Mozilla and Mac IE. - if (!newChild->inDocument()) { - shouldAdoptChild = true; - } else { - ec = WRONG_DOCUMENT_ERR; - return; - } - } - - // HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not allow children of the type of the - // newChild node, or if the node to append is one of this node's ancestors. - - // check for ancestor/same node - if (newChild == this || isDescendantOf(newChild)) { - ec = HIERARCHY_REQUEST_ERR; - return; - } - - if (newChild->nodeType() != DOCUMENT_FRAGMENT_NODE) { - if (!childTypeAllowed(newChild->nodeType())) { - ec = HIERARCHY_REQUEST_ERR; - return; - } - } - else { - for (Node *n = newChild->firstChild(); n; n = n->nextSibling()) { - if (!childTypeAllowed(n->nodeType())) { - ec = HIERARCHY_REQUEST_ERR; - return; - } - } - } - - // change the document pointer of newChild and all of its children to be the new document - if (shouldAdoptChild) - for (Node* node = newChild; node; node = node->traverseNextNode(newChild)) - node->setDocument(document()); -} - -bool Node::isDescendantOf(const Node *other) const -{ - // Return true if other is an ancestor of this, otherwise false - if (!other) - return false; - for (const Node *n = parentNode(); n; n = n->parentNode()) { - if (n == other) - return true; - } - return false; -} - -bool Node::childAllowed(Node* newChild) -{ - return childTypeAllowed(newChild->nodeType()); -} - -void Node::attach() -{ - ASSERT(!attached()); - ASSERT(!renderer() || (renderer()->style() && renderer()->parent())); - - // If this node got a renderer it may be the previousRenderer() of sibling text nodes and thus affect the - // result of Text::rendererIsNeeded() for those nodes. - if (renderer()) { - for (Node* next = nextSibling(); next; next = next->nextSibling()) { - if (next->renderer()) - break; - if (!next->attached()) - break; // Assume this means none of the following siblings are attached. - if (next->isTextNode()) - next->createRendererIfNeeded(); - } - } - - m_attached = true; -} - -void Node::willRemove() -{ -} - -void Node::detach() -{ - m_inDetach = true; - - if (renderer()) - renderer()->destroy(); - setRenderer(0); - - Document* doc = document(); - if (m_hovered) - doc->hoveredNodeDetached(this); - if (m_inActiveChain) - doc->activeChainNodeDetached(this); - - m_active = false; - m_hovered = false; - m_inActiveChain = false; - m_attached = false; - m_inDetach = false; -} - -void Node::insertedIntoDocument() -{ - setInDocument(true); - insertedIntoTree(false); -} - -void Node::removedFromDocument() -{ - if (m_document && m_document->getCSSTarget() == this) - m_document->setCSSTarget(0); - - setInDocument(false); - removedFromTree(false); -} - -Node *Node::previousEditable() const -{ - Node *node = previousLeafNode(); - while (node) { - if (node->isContentEditable()) - return node; - node = node->previousLeafNode(); - } - return 0; -} - -Node *Node::nextEditable() const -{ - Node *node = nextLeafNode(); - while (node) { - if (node->isContentEditable()) - return node; - node = node->nextLeafNode(); - } - return 0; -} - -RenderObject * Node::previousRenderer() -{ - for (Node *n = previousSibling(); n; n = n->previousSibling()) { - if (n->renderer()) - return n->renderer(); - } - return 0; -} - -RenderObject * Node::nextRenderer() -{ - // Avoid an O(n^2) problem with this function by not checking for nextRenderer() when the parent element hasn't even - // been attached yet. - if (parent() && !parent()->attached()) - return 0; - - for (Node *n = nextSibling(); n; n = n->nextSibling()) { - if (n->renderer()) - return n->renderer(); - } - return 0; -} - -// FIXME: This code is used by editing. Seems like it could move over there and not pollute Node. -Node *Node::previousNodeConsideringAtomicNodes() const -{ - if (previousSibling()) { - Node *n = previousSibling(); - while (!isAtomicNode(n) && n->lastChild()) - n = n->lastChild(); - return n; - } - else if (parentNode()) { - return parentNode(); - } - else { - return 0; - } -} - -Node *Node::nextNodeConsideringAtomicNodes() const -{ - if (!isAtomicNode(this) && firstChild()) - return firstChild(); - if (nextSibling()) - return nextSibling(); - const Node *n = this; - while (n && !n->nextSibling()) - n = n->parentNode(); - if (n) - return n->nextSibling(); - return 0; -} - -Node *Node::previousLeafNode() const -{ - Node *node = previousNodeConsideringAtomicNodes(); - while (node) { - if (isAtomicNode(node)) - return node; - node = node->previousNodeConsideringAtomicNodes(); - } - return 0; -} - -Node *Node::nextLeafNode() const -{ - Node *node = nextNodeConsideringAtomicNodes(); - while (node) { - if (isAtomicNode(node)) - return node; - node = node->nextNodeConsideringAtomicNodes(); - } - return 0; -} - -void Node::createRendererIfNeeded() -{ - if (!document()->shouldCreateRenderers()) - return; - - ASSERT(!renderer()); - - Node *parent = parentNode(); - ASSERT(parent); - - RenderObject *parentRenderer = parent->renderer(); - if (parentRenderer && parentRenderer->canHaveChildren() -#if ENABLE(SVG) - && parent->childShouldCreateRenderer(this) -#endif - ) { - RenderStyle* style = styleForRenderer(parentRenderer); - if (rendererIsNeeded(style)) { - if (RenderObject* r = createRenderer(document()->renderArena(), style)) { - if (!parentRenderer->isChildAllowed(r, style)) - r->destroy(); - else { - setRenderer(r); - renderer()->setAnimatableStyle(style); - parentRenderer->addChild(renderer(), nextRenderer()); - } - } - } - style->deref(document()->renderArena()); - } -} - -RenderStyle *Node::styleForRenderer(RenderObject *parent) -{ - RenderStyle *style = parent->style(); - style->ref(); - return style; -} - -bool Node::rendererIsNeeded(RenderStyle *style) -{ - return (document()->documentElement() == this) || (style->display() != NONE); -} - -RenderObject *Node::createRenderer(RenderArena *arena, RenderStyle *style) -{ - ASSERT(false); - return 0; -} - -RenderStyle* Node::renderStyle() const -{ - return m_renderer ? m_renderer->style() : 0; -} - -void Node::setRenderStyle(RenderStyle* s) -{ - if (m_renderer) - m_renderer->setAnimatableStyle(s); -} - -RenderStyle* Node::computedStyle() -{ - return parent() ? parent()->computedStyle() : 0; -} - -int Node::maxCharacterOffset() const -{ - ASSERT_NOT_REACHED(); - return 0; -} - -// FIXME: Shouldn't these functions be in the editing code? Code that asks questions about HTML in the core DOM class -// is obviously misplaced. -bool Node::canStartSelection() const -{ - if (isContentEditable()) - return true; - return parent() ? parent()->canStartSelection() : true; -} - -Node* Node::shadowAncestorNode() -{ -#if ENABLE(SVG) - // SVG elements living in a shadow tree only occour when <use> created them. - // For these cases we do NOT want to return the shadowParentNode() here - // but the actual shadow tree element - as main difference to the HTML forms - // shadow tree concept. (This function _could_ be made virtual - opinions?) - if (isSVGElement()) - return this; -#endif - - Node* root = shadowTreeRootNode(); - if (root) - return root->shadowParentNode(); - return this; -} - -Node* Node::shadowTreeRootNode() -{ - Node* root = this; - while (root) { - if (root->isShadowNode()) - return root; - root = root->parentNode(); - } - return 0; -} - -bool Node::isInShadowTree() -{ - for (Node* n = this; n; n = n->parentNode()) - if (n->isShadowNode()) - return true; - return false; -} - -bool Node::isBlockFlow() const -{ - return renderer() && renderer()->isBlockFlow(); -} - -bool Node::isBlockFlowOrBlockTable() const -{ - return renderer() && (renderer()->isBlockFlow() || renderer()->isTable() && !renderer()->isInline()); -} - -bool Node::isEditableBlock() const -{ - return isContentEditable() && isBlockFlow(); -} - -Element *Node::enclosingBlockFlowElement() const -{ - Node *n = const_cast<Node *>(this); - if (isBlockFlow()) - return static_cast<Element *>(n); - - while (1) { - n = n->parentNode(); - if (!n) - break; - if (n->isBlockFlow() || n->hasTagName(bodyTag)) - return static_cast<Element *>(n); - } - return 0; -} - -Element *Node::enclosingInlineElement() const -{ - Node *n = const_cast<Node *>(this); - Node *p; - - while (1) { - p = n->parentNode(); - if (!p || p->isBlockFlow() || p->hasTagName(bodyTag)) - return static_cast<Element *>(n); - // Also stop if any previous sibling is a block - for (Node *sibling = n->previousSibling(); sibling; sibling = sibling->previousSibling()) { - if (sibling->isBlockFlow()) - return static_cast<Element *>(n); - } - n = p; - } - ASSERT_NOT_REACHED(); - return 0; -} - -Element* Node::rootEditableElement() const -{ - Element* result = 0; - for (Node* n = const_cast<Node*>(this); n && n->isContentEditable(); n = n->parentNode()) { - if (n->isElementNode()) - result = static_cast<Element*>(n); - if (n->hasTagName(bodyTag)) - break; - } - return result; -} - -bool Node::inSameContainingBlockFlowElement(Node *n) -{ - return n ? enclosingBlockFlowElement() == n->enclosingBlockFlowElement() : false; -} - -// FIXME: End of obviously misplaced HTML editing functions. Try to move these out of Node. - -PassRefPtr<NodeList> Node::getElementsByTagName(const String& name) -{ - return getElementsByTagNameNS("*", name); -} - -PassRefPtr<NodeList> Node::getElementsByTagNameNS(const String& namespaceURI, const String& localName) -{ - if (localName.isNull()) - return 0; - - String name = localName; - if (document()->isHTMLDocument()) - name = localName.lower(); - return TagNodeList::create(this, namespaceURI.isEmpty() ? nullAtom : AtomicString(namespaceURI), name); -} - -PassRefPtr<NodeList> Node::getElementsByName(const String& elementName) -{ - if (!m_nodeLists) { - m_nodeLists.set(new NodeListsNodeData); - document()->addNodeListCache(); - } - - pair<NodeListsNodeData::CacheMap::iterator, bool> result = m_nodeLists->m_nameNodeListCaches.add(elementName, 0); - if (result.second) - result.first->second = new DynamicNodeList::Caches; - - return NameNodeList::create(this, elementName, result.first->second); -} - -PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames) -{ - if (!m_nodeLists) { - m_nodeLists.set(new NodeListsNodeData); - document()->addNodeListCache(); - } - - pair<NodeListsNodeData::CacheMap::iterator, bool> result = m_nodeLists->m_classNodeListCaches.add(classNames, 0); - if (result.second) - result.first->second = new DynamicNodeList::Caches; - - return ClassNodeList::create(this, classNames, result.first->second); -} - -template <typename Functor> -static bool forEachTagSelector(Functor& functor, CSSSelector* selector) -{ - ASSERT(selector); - - do { - if (functor(selector)) - return true; - if (CSSSelector* simpleSelector = selector->m_simpleSelector) { - if (forEachTagSelector(functor, simpleSelector)) - return true; - } - } while ((selector = selector->m_tagHistory)); - - return false; -} - -template <typename Functor> -static bool forEachSelector(Functor& functor, CSSSelector* selector) -{ - for (; selector; selector = selector->next()) { - if (forEachTagSelector(functor, selector)) - return true; - } - - return false; -} - -class SelectorNeedsNamespaceResolutionFunctor { -public: - bool operator()(CSSSelector* selector) - { - if (selector->hasTag() && selector->m_tag.prefix() != nullAtom && selector->m_tag.prefix() != starAtom) - return true; - if (selector->hasAttribute() && selector->m_attr.prefix() != nullAtom && selector->m_attr.prefix() != starAtom) - return true; - return false; - } -}; - -class ResolveNamespaceFunctor { -public: - ResolveNamespaceFunctor(NSResolver* resolver, ExceptionCode& ec, ExceptionContext* exec) - : m_resolver(resolver) - , m_exceptionCode(ec) - , m_exec(exec) - { - } - - bool operator()(CSSSelector* selector) - { - if (selector->hasTag() && selector->m_tag.prefix() != nullAtom && selector->m_tag.prefix() != starAtom) { - String resolvedNamespaceURI = m_resolver->lookupNamespaceURI(m_exec, selector->m_tag.prefix()); - if (m_exec && m_exec->hadException()) - return true; - if (resolvedNamespaceURI.isEmpty()) { - m_exceptionCode = NAMESPACE_ERR; - return true; - } - QualifiedName newQualifiedName(selector->m_tag.prefix(), selector->m_tag.localName(), resolvedNamespaceURI); - selector->m_tag = newQualifiedName; - } - if (selector->hasAttribute() && selector->m_attr.prefix() != nullAtom && selector->m_attr.prefix() != starAtom) { - String resolvedNamespaceURI = m_resolver->lookupNamespaceURI(m_exec, selector->m_attr.prefix()); - if (m_exec && m_exec->hadException()) - return true; - if (resolvedNamespaceURI.isEmpty()) { - m_exceptionCode = NAMESPACE_ERR; - return true; - } - QualifiedName newQualifiedName(selector->m_attr.prefix(), selector->m_attr.localName(), resolvedNamespaceURI); - selector->m_attr = newQualifiedName; - } - - return false; - } - -private: - NSResolver* m_resolver; - ExceptionCode& m_exceptionCode; - ExceptionContext* m_exec; -}; - -static bool selectorNeedsNamespaceResolution(CSSSelector* currentSelector) -{ - SelectorNeedsNamespaceResolutionFunctor functor; - return forEachSelector(functor, currentSelector); -} - -static bool resolveNamespacesForSelector(CSSSelector* currentSelector, NSResolver* resolver, ExceptionCode& ec, ExceptionContext* exec) -{ - ResolveNamespaceFunctor functor(resolver, ec, exec); - return forEachSelector(functor, currentSelector); -} - -PassRefPtr<Element> Node::querySelector(const String& selectors, ExceptionCode& ec) -{ - return querySelector(selectors, 0, ec, ExceptionContext::createFromNode(this)); -} - -PassRefPtr<NodeList> Node::querySelectorAll(const String& selectors, ExceptionCode& ec) -{ - return querySelectorAll(selectors, 0, ec, ExceptionContext::createFromNode(this)); -} - -PassRefPtr<Element> Node::querySelector(const String& selectors, NSResolver* resolver, ExceptionCode& ec, ExceptionContext* exec) -{ - if (selectors.isEmpty()) { - ec = SYNTAX_ERR; - return 0; - } - bool strictParsing = !document()->inCompatMode(); - CSSParser p(strictParsing); - if (resolver) { - String defaultNamespace = resolver->lookupNamespaceURI(exec, String()); - if (exec && exec->hadException()) - return 0; - if (!defaultNamespace.isEmpty()) - p.m_defaultNamespace = defaultNamespace; - } - - std::auto_ptr<CSSSelector> querySelector = p.parseSelector(selectors); - if (!querySelector.get()) { - ec = SYNTAX_ERR; - return 0; - } - - if (resolver) { - if (resolveNamespacesForSelector(querySelector.get(), resolver, ec, exec)) - return 0; - } else { - // No NSResolver was passed, so throw a NAMESPACE_ERR if the selector includes any - // namespace prefixes. - if (selectorNeedsNamespaceResolution(querySelector.get())) { - ec = NAMESPACE_ERR; - return 0; - } - } - - // FIXME: we could also optimize for the the [id="foo"] case - if (strictParsing && inDocument() && !querySelector->next() && querySelector->m_match == CSSSelector::Id - && !querySelector->hasTag() && !querySelector->m_tagHistory && !querySelector->m_simpleSelector) { - ASSERT(querySelector->m_attr == idAttr); - Element* element = document()->getElementById(querySelector->m_value); - if (element && (isDocumentNode() || element->isDescendantOf(this))) - return element; - return 0; - } - - CSSStyleSelector::SelectorChecker selectorChecker(document(), strictParsing); - - // FIXME: We can speed this up by implementing caching similar to the one use by getElementById - for (Node* n = firstChild(); n; n = n->traverseNextNode(this)) { - if (n->isElementNode()) { - Element* element = static_cast<Element*>(n); - for (CSSSelector* selector = querySelector.get(); selector; selector = selector->next()) { - if (selectorChecker.checkSelector(selector, element)) - return element; - } - } - } - - return 0; -} - -PassRefPtr<NodeList> Node::querySelectorAll(const String& selectors, NSResolver* resolver, ExceptionCode& ec, ExceptionContext* exec) -{ - if (selectors.isEmpty()) { - ec = SYNTAX_ERR; - return 0; - } - bool strictParsing = !document()->inCompatMode(); - CSSParser p(strictParsing); - if (resolver) { - String defaultNamespace = resolver->lookupNamespaceURI(exec, String()); - if (exec && exec->hadException()) - return false; - if (!defaultNamespace.isEmpty()) - p.m_defaultNamespace = defaultNamespace; - } - - std::auto_ptr<CSSSelector> querySelector = p.parseSelector(selectors); - - if (!querySelector.get()) { - ec = SYNTAX_ERR; - return 0; - } - - if (resolver) { - if (resolveNamespacesForSelector(querySelector.get(), resolver, ec, exec)) - return 0; - } else { - // No NSResolver was passed, so throw a NAMESPACE_ERR if the selector includes any - // namespace prefixes. - if (selectorNeedsNamespaceResolution(querySelector.get())) { - ec = NAMESPACE_ERR; - return 0; - } - } - - return createSelectorNodeList(this, querySelector.get()); -} - -Document *Node::ownerDocument() const -{ - Document *doc = document(); - return doc == this ? 0 : doc; -} - -bool Node::hasAttributes() const -{ - return false; -} - -NamedAttrMap* Node::attributes() const -{ - return 0; -} - -KURL Node::baseURI() const -{ - return parentNode() ? parentNode()->baseURI() : KURL(); -} - -bool Node::isEqualNode(Node *other) const -{ - if (!other) - return false; - - if (nodeType() != other->nodeType()) - return false; - - if (nodeName() != other->nodeName()) - return false; - - if (localName() != other->localName()) - return false; - - if (namespaceURI() != other->namespaceURI()) - return false; - - if (prefix() != other->prefix()) - return false; - - if (nodeValue() != other->nodeValue()) - return false; - - NamedAttrMap *attrs = attributes(); - NamedAttrMap *otherAttrs = other->attributes(); - - if (!attrs && otherAttrs) - return false; - - if (attrs && !attrs->mapsEquivalent(otherAttrs)) - return false; - - Node *child = firstChild(); - Node *otherChild = other->firstChild(); - - while (child) { - if (!child->isEqualNode(otherChild)) - return false; - - child = child->nextSibling(); - otherChild = otherChild->nextSibling(); - } - - if (otherChild) - return false; - - // FIXME: For DocumentType nodes we should check equality on - // the entities and notations NamedNodeMaps as well. - - return true; -} - -bool Node::isDefaultNamespace(const String &namespaceURI) const -{ - // Implemented according to - // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#isDefaultNamespaceAlgo - - switch (nodeType()) { - case ELEMENT_NODE: { - const Element *elem = static_cast<const Element *>(this); - - if (elem->prefix().isNull()) - return elem->namespaceURI() == namespaceURI; - - if (elem->hasAttributes()) { - NamedAttrMap *attrs = elem->attributes(); - - for (unsigned i = 0; i < attrs->length(); i++) { - Attribute *attr = attrs->attributeItem(i); - - if (attr->localName() == "xmlns") - return attr->value() == namespaceURI; - } - } - - if (Element* ancestor = ancestorElement()) - return ancestor->isDefaultNamespace(namespaceURI); - - return false; - } - case DOCUMENT_NODE: - if (Element* de = static_cast<const Document*>(this)->documentElement()) - return de->isDefaultNamespace(namespaceURI); - return false; - case ENTITY_NODE: - case NOTATION_NODE: - case DOCUMENT_TYPE_NODE: - case DOCUMENT_FRAGMENT_NODE: - return false; - case ATTRIBUTE_NODE: { - const Attr *attr = static_cast<const Attr *>(this); - if (attr->ownerElement()) - return attr->ownerElement()->isDefaultNamespace(namespaceURI); - return false; - } - default: - if (Element* ancestor = ancestorElement()) - return ancestor->isDefaultNamespace(namespaceURI); - return false; - } -} - -String Node::lookupPrefix(const String &namespaceURI) const -{ - // Implemented according to - // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespacePrefixAlgo - - if (namespaceURI.isEmpty()) - return String(); - - switch (nodeType()) { - case ELEMENT_NODE: - return lookupNamespacePrefix(namespaceURI, static_cast<const Element *>(this)); - case DOCUMENT_NODE: - if (Element* de = static_cast<const Document*>(this)->documentElement()) - return de->lookupPrefix(namespaceURI); - return String(); - case ENTITY_NODE: - case NOTATION_NODE: - case DOCUMENT_FRAGMENT_NODE: - case DOCUMENT_TYPE_NODE: - return String(); - case ATTRIBUTE_NODE: { - const Attr *attr = static_cast<const Attr *>(this); - if (attr->ownerElement()) - return attr->ownerElement()->lookupPrefix(namespaceURI); - return String(); - } - default: - if (Element* ancestor = ancestorElement()) - return ancestor->lookupPrefix(namespaceURI); - return String(); - } -} - -String Node::lookupNamespaceURI(const String &prefix) const -{ - // Implemented according to - // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespaceURIAlgo - - if (!prefix.isNull() && prefix.isEmpty()) - return String(); - - switch (nodeType()) { - case ELEMENT_NODE: { - const Element *elem = static_cast<const Element *>(this); - - if (!elem->namespaceURI().isNull() && elem->prefix() == prefix) - return elem->namespaceURI(); - - if (elem->hasAttributes()) { - NamedAttrMap *attrs = elem->attributes(); - - for (unsigned i = 0; i < attrs->length(); i++) { - Attribute *attr = attrs->attributeItem(i); - - if (attr->prefix() == "xmlns" && attr->localName() == prefix) { - if (!attr->value().isEmpty()) - return attr->value(); - - return String(); - } else if (attr->localName() == "xmlns" && prefix.isNull()) { - if (!attr->value().isEmpty()) - return attr->value(); - - return String(); - } - } - } - if (Element* ancestor = ancestorElement()) - return ancestor->lookupNamespaceURI(prefix); - return String(); - } - case DOCUMENT_NODE: - if (Element* de = static_cast<const Document*>(this)->documentElement()) - return de->lookupNamespaceURI(prefix); - return String(); - case ENTITY_NODE: - case NOTATION_NODE: - case DOCUMENT_TYPE_NODE: - case DOCUMENT_FRAGMENT_NODE: - return String(); - case ATTRIBUTE_NODE: { - const Attr *attr = static_cast<const Attr *>(this); - - if (attr->ownerElement()) - return attr->ownerElement()->lookupNamespaceURI(prefix); - else - return String(); - } - default: - if (Element* ancestor = ancestorElement()) - return ancestor->lookupNamespaceURI(prefix); - return String(); - } -} - -String Node::lookupNamespacePrefix(const String &_namespaceURI, const Element *originalElement) const -{ - if (_namespaceURI.isNull()) - return String(); - - if (originalElement->lookupNamespaceURI(prefix()) == _namespaceURI) - return prefix(); - - if (hasAttributes()) { - NamedAttrMap *attrs = attributes(); - - for (unsigned i = 0; i < attrs->length(); i++) { - Attribute *attr = attrs->attributeItem(i); - - if (attr->prefix() == "xmlns" && - attr->value() == _namespaceURI && - originalElement->lookupNamespaceURI(attr->localName()) == _namespaceURI) - return attr->localName(); - } - } - - if (Element* ancestor = ancestorElement()) - return ancestor->lookupNamespacePrefix(_namespaceURI, originalElement); - return String(); -} - -void Node::appendTextContent(bool convertBRsToNewlines, StringBuilder& content) const -{ - switch (nodeType()) { - case TEXT_NODE: - case CDATA_SECTION_NODE: - case COMMENT_NODE: - content.append(static_cast<const CharacterData*>(this)->CharacterData::nodeValue()); - break; - - case PROCESSING_INSTRUCTION_NODE: - content.append(static_cast<const ProcessingInstruction*>(this)->ProcessingInstruction::nodeValue()); - break; - - case ELEMENT_NODE: - if (hasTagName(brTag) && convertBRsToNewlines) { - content.append('\n'); - break; - } - // Fall through. - case ATTRIBUTE_NODE: - case ENTITY_NODE: - case ENTITY_REFERENCE_NODE: - case DOCUMENT_FRAGMENT_NODE: - content.setNonNull(); - - for (Node *child = firstChild(); child; child = child->nextSibling()) { - if (child->nodeType() == COMMENT_NODE || child->nodeType() == PROCESSING_INSTRUCTION_NODE) - continue; - - child->appendTextContent(convertBRsToNewlines, content); - } - break; - - case DOCUMENT_NODE: - case DOCUMENT_TYPE_NODE: - case NOTATION_NODE: - case XPATH_NAMESPACE_NODE: - break; - } -} - -String Node::textContent(bool convertBRsToNewlines) const -{ - StringBuilder content; - appendTextContent(convertBRsToNewlines, content); - return content.toString(); -} - -void Node::setTextContent(const String &text, ExceptionCode& ec) -{ - switch (nodeType()) { - case TEXT_NODE: - case CDATA_SECTION_NODE: - case COMMENT_NODE: - case PROCESSING_INSTRUCTION_NODE: - setNodeValue(text, ec); - break; - case ELEMENT_NODE: - case ATTRIBUTE_NODE: - case ENTITY_NODE: - case ENTITY_REFERENCE_NODE: - case DOCUMENT_FRAGMENT_NODE: { - ContainerNode *container = static_cast<ContainerNode *>(this); - - container->removeChildren(); - - if (!text.isEmpty()) - appendChild(document()->createTextNode(text), ec); - break; - } - case DOCUMENT_NODE: - case DOCUMENT_TYPE_NODE: - case NOTATION_NODE: - default: - // Do nothing - break; - } -} - -Element* Node::ancestorElement() const -{ - // In theory, there can be EntityReference nodes between elements, but this is currently not supported. - for (Node* n = parentNode(); n; n = n->parentNode()) { - if (n->isElementNode()) - return static_cast<Element*>(n); - } - return 0; -} - -bool Node::offsetInCharacters() const -{ - return false; -} - -unsigned short Node::compareDocumentPosition(Node* otherNode) -{ - // It is not clear what should be done if |otherNode| is 0. - if (!otherNode) - return DOCUMENT_POSITION_DISCONNECTED; - - if (otherNode == this) - return DOCUMENT_POSITION_EQUIVALENT; - - Attr* attr1 = nodeType() == ATTRIBUTE_NODE ? static_cast<Attr*>(this) : 0; - Attr* attr2 = otherNode->nodeType() == ATTRIBUTE_NODE ? static_cast<Attr*>(otherNode) : 0; - - Node* start1 = attr1 ? attr1->ownerElement() : this; - Node* start2 = attr2 ? attr2->ownerElement() : otherNode; - - // If either of start1 or start2 is null, then we are disconnected, since one of the nodes is - // an orphaned attribute node. - if (!start1 || !start2) - return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC; - - Vector<Node*, 16> chain1; - Vector<Node*, 16> chain2; - if (attr1) - chain1.append(attr1); - if (attr2) - chain2.append(attr2); - - if (attr1 && attr2 && start1 == start2 && start1) { - // We are comparing two attributes on the same node. Crawl our attribute map - // and see which one we hit first. - NamedAttrMap* map = attr1->ownerElement()->attributes(true); - unsigned length = map->length(); - for (unsigned i = 0; i < length; ++i) { - // If neither of the two determining nodes is a child node and nodeType is the same for both determining nodes, then an - // implementation-dependent order between the determining nodes is returned. This order is stable as long as no nodes of - // the same nodeType are inserted into or removed from the direct container. This would be the case, for example, - // when comparing two attributes of the same element, and inserting or removing additional attributes might change - // the order between existing attributes. - Attribute* attr = map->attributeItem(i); - if (attr1->attr() == attr) - return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_FOLLOWING; - if (attr2->attr() == attr) - return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING; - } - - ASSERT_NOT_REACHED(); - return DOCUMENT_POSITION_DISCONNECTED; - } - - // If one node is in the document and the other is not, we must be disconnected. - // If the nodes have different owning documents, they must be disconnected. Note that we avoid - // comparing Attr nodes here, since they return false from inDocument() all the time (which seems like a bug). - if (start1->inDocument() != start2->inDocument() || - start1->document() != start2->document()) - return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC; - - // We need to find a common ancestor container, and then compare the indices of the two immediate children. - Node* current; - for (current = start1; current; current = current->parentNode()) - chain1.append(current); - for (current = start2; current; current = current->parentNode()) - chain2.append(current); - - // Walk the two chains backwards and look for the first difference. - unsigned index1 = chain1.size(); - unsigned index2 = chain2.size(); - for (unsigned i = std::min(index1, index2); i; --i) { - Node* child1 = chain1[--index1]; - Node* child2 = chain2[--index2]; - if (child1 != child2) { - // If one of the children is an attribute, it wins. - if (child1->nodeType() == ATTRIBUTE_NODE) - return DOCUMENT_POSITION_FOLLOWING; - if (child2->nodeType() == ATTRIBUTE_NODE) - return DOCUMENT_POSITION_PRECEDING; - - if (!child2->nextSibling()) - return DOCUMENT_POSITION_FOLLOWING; - if (!child1->nextSibling()) - return DOCUMENT_POSITION_PRECEDING; - - // Otherwise we need to see which node occurs first. Crawl backwards from child2 looking for child1. - for (Node* child = child2->previousSibling(); child; child = child->previousSibling()) { - if (child == child1) - return DOCUMENT_POSITION_FOLLOWING; - } - return DOCUMENT_POSITION_PRECEDING; - } - } - - // There was no difference between the two parent chains, i.e., one was a subset of the other. The shorter - // chain is the ancestor. - return index1 < index2 ? - DOCUMENT_POSITION_FOLLOWING | DOCUMENT_POSITION_CONTAINED_BY : - DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS; -} - -#ifndef NDEBUG - -static void appendAttributeDesc(const Node* node, String& string, const QualifiedName& name, const char* attrDesc) -{ - if (node->isElementNode()) { - String attr = static_cast<const Element*>(node)->getAttribute(name); - if (!attr.isEmpty()) { - string += attrDesc; - string += attr; - } - } -} - -void Node::showNode(const char* prefix) const -{ - if (!prefix) - prefix = ""; - if (isTextNode()) { - String value = nodeValue(); - value.replace('\\', "\\\\"); - value.replace('\n', "\\n"); - fprintf(stderr, "%s%s\t%p \"%s\"\n", prefix, nodeName().utf8().data(), this, value.utf8().data()); - } else { - String attrs = ""; - appendAttributeDesc(this, attrs, classAttr, " CLASS="); - appendAttributeDesc(this, attrs, styleAttr, " STYLE="); - fprintf(stderr, "%s%s\t%p%s\n", prefix, nodeName().utf8().data(), this, attrs.utf8().data()); - } -} - -void Node::showTreeForThis() const -{ - showTreeAndMark(this, "*"); -} - -void Node::showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2, const char * markedLabel2) const -{ - const Node* rootNode; - const Node* node = this; - while (node->parentNode() && !node->hasTagName(bodyTag)) - node = node->parentNode(); - rootNode = node; - - for (node = rootNode; node; node = node->traverseNextNode()) { - if (node == markedNode1) - fprintf(stderr, "%s", markedLabel1); - if (node == markedNode2) - fprintf(stderr, "%s", markedLabel2); - - for (const Node* tmpNode = node; tmpNode && tmpNode != rootNode; tmpNode = tmpNode->parentNode()) - fprintf(stderr, "\t"); - node->showNode(); - } -} - -void Node::formatForDebugger(char* buffer, unsigned length) const -{ - String result; - String s; - - s = nodeName(); - if (s.length() == 0) - result += "<none>"; - else - result += s; - - strncpy(buffer, result.utf8().data(), length - 1); -} - -#endif - -// -------- - -void NodeListsNodeData::invalidateCaches() -{ - m_childNodeListCaches.reset(); - invalidateCachesThatDependOnAttributes(); -} - -void NodeListsNodeData::invalidateCachesThatDependOnAttributes() -{ - CacheMap::iterator classCachesEnd = m_classNodeListCaches.end(); - for (CacheMap::iterator it = m_classNodeListCaches.begin(); it != classCachesEnd; ++it) - it->second->reset(); - - CacheMap::iterator nameCachesEnd = m_nameNodeListCaches.end(); - for (CacheMap::iterator it = m_nameNodeListCaches.begin(); it != nameCachesEnd; ++it) - it->second->reset(); -} - -bool NodeListsNodeData::isEmpty() const -{ - if (!m_listsWithCaches.isEmpty()) - return false; - - if (m_childNodeListCaches.refCount) - return false; - - CacheMap::const_iterator classCachesEnd = m_classNodeListCaches.end(); - for (CacheMap::const_iterator it = m_classNodeListCaches.begin(); it != classCachesEnd; ++it) { - if (it->second->refCount) - return false; - } - - CacheMap::const_iterator nameCachesEnd = m_nameNodeListCaches.end(); - for (CacheMap::const_iterator it = m_nameNodeListCaches.begin(); it != nameCachesEnd; ++it) { - if (it->second->refCount) - return false; - } - - return true; -} - -void Node::getSubresourceURLs(Vector<KURL>& urls) const -{ - Vector<String> subresourceStrings; - getSubresourceAttributeStrings(subresourceStrings); - - for (unsigned i = 0; i < subresourceStrings.size(); ++i) { - String& subresourceString(subresourceStrings[i]); - - // FIXME: Is parseURL appropriate here? - if (subresourceString.length()) - urls.append(document()->completeURL(parseURL(subresourceString))); - } -} - -// -------- - -} // namespace WebCore - -#ifndef NDEBUG - -void showTree(const WebCore::Node* node) -{ - if (node) - node->showTreeForThis(); -} - -#endif diff --git a/webkit/pending/Node.h b/webkit/pending/Node.h deleted file mode 100644 index 81e4e3c..0000000 --- a/webkit/pending/Node.h +++ /dev/null @@ -1,549 +0,0 @@ -/* - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * (C) 2001 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef Node_h -#define Node_h - -#include "DocPtr.h" -#include "PlatformString.h" -#include "TreeShared.h" -#include <wtf/Assertions.h> -#include <wtf/HashSet.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassRefPtr.h> - -namespace WebCore { - -class AtomicString; -class ContainerNode; -class Document; -class DynamicNodeList; -class Element; -class Event; -class EventListener; -class IntRect; -class KURL; -class KeyboardEvent; -class NSResolver; -class NamedAttrMap; -class NodeList; -class PlatformKeyboardEvent; -class PlatformMouseEvent; -class PlatformWheelEvent; -class QualifiedName; -class RegisteredEventListener; -class RenderArena; -class RenderObject; -class RenderStyle; -class StringBuilder; -class ExceptionContext; - -struct NodeListsNodeData; - -typedef int ExceptionCode; - -enum StyleChangeType { NoStyleChange, InlineStyleChange, FullStyleChange, AnimationStyleChange }; - -const unsigned short DOCUMENT_POSITION_EQUIVALENT = 0x00; -const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01; -const unsigned short DOCUMENT_POSITION_PRECEDING = 0x02; -const unsigned short DOCUMENT_POSITION_FOLLOWING = 0x04; -const unsigned short DOCUMENT_POSITION_CONTAINS = 0x08; -const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10; -const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20; - -// this class implements nodes, which can have a parent but no children: -class Node : public TreeShared<Node> { - friend class Document; -public: - enum NodeType { - ELEMENT_NODE = 1, - ATTRIBUTE_NODE = 2, - TEXT_NODE = 3, - CDATA_SECTION_NODE = 4, - ENTITY_REFERENCE_NODE = 5, - ENTITY_NODE = 6, - PROCESSING_INSTRUCTION_NODE = 7, - COMMENT_NODE = 8, - DOCUMENT_NODE = 9, - DOCUMENT_TYPE_NODE = 10, - DOCUMENT_FRAGMENT_NODE = 11, - NOTATION_NODE = 12, - XPATH_NAMESPACE_NODE = 13 - }; - - static bool isSupported(const String& feature, const String& version); - - static void startIgnoringLeaks(); - static void stopIgnoringLeaks(); - - enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force }; - static StyleChange diff(RenderStyle*, RenderStyle*); - - Node(Document*, bool isElement = false); - virtual ~Node(); - - // DOM methods & attributes for Node - - bool hasTagName(const QualifiedName& name) const { return virtualHasTagName(name); } - virtual String nodeName() const = 0; - virtual String nodeValue() const; - virtual void setNodeValue(const String&, ExceptionCode&); - virtual NodeType nodeType() const = 0; - Node* parentNode() const { return parent(); } - Node* parentElement() const { return parent(); } // IE extension - Node* previousSibling() const { return m_previous; } - Node* nextSibling() const { return m_next; } - virtual PassRefPtr<NodeList> childNodes(); - Node* firstChild() const { return virtualFirstChild(); } - Node* lastChild() const { return virtualLastChild(); } - virtual bool hasAttributes() const; - virtual NamedAttrMap* attributes() const; - - virtual KURL baseURI() const; - - void getSubresourceURLs(Vector<KURL>&) const; - - // These should all actually return a node, but this is only important for language bindings, - // which will already know and hold a ref on the right node to return. Returning bool allows - // these methods to be more efficient since they don't need to return a ref - virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, bool shouldLazyAttach = false); - virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, bool shouldLazyAttach = false); - virtual bool removeChild(Node* child, ExceptionCode&); - virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false); - - virtual void remove(ExceptionCode&); - bool hasChildNodes() const { return firstChild(); } - virtual PassRefPtr<Node> cloneNode(bool deep) = 0; - virtual const AtomicString& localName() const; - virtual const AtomicString& namespaceURI() const; - virtual const AtomicString& prefix() const; - virtual void setPrefix(const AtomicString&, ExceptionCode&); - void normalize(); - - bool isSameNode(Node* other) const { return this == other; } - bool isEqualNode(Node*) const; - bool isDefaultNamespace(const String& namespaceURI) const; - String lookupPrefix(const String& namespaceURI) const; - String lookupNamespaceURI(const String& prefix) const; - String lookupNamespacePrefix(const String& namespaceURI, const Element* originalElement) const; - - String textContent(bool convertBRsToNewlines = false) const; - void setTextContent(const String&, ExceptionCode&); - - Node* lastDescendant() const; - Node* firstDescendant() const; - - // Other methods (not part of DOM) - - bool isElementNode() const { return m_isElement; } - virtual bool isHTMLElement() const { return false; } - -#if ENABLE(SVG) - virtual -#endif - bool isSVGElement() const { return false; } - - virtual bool isStyledElement() const { return false; } - virtual bool isFrameOwnerElement() const { return false; } - virtual bool isAttributeNode() const { return false; } - virtual bool isTextNode() const { return false; } - virtual bool isCommentNode() const { return false; } - virtual bool isCharacterDataNode() const { return false; } - virtual bool isDocumentNode() const { return false; } - virtual bool isEventTargetNode() const { return false; } - virtual bool isShadowNode() const { return false; } - virtual Node* shadowParentNode() { return 0; } - Node* shadowAncestorNode(); - Node* shadowTreeRootNode(); - bool isInShadowTree(); - - // The node's parent for the purpose of event capture and bubbling. - virtual Node* eventParentNode() { return parentNode(); } - - bool isBlockFlow() const; - bool isBlockFlowOrBlockTable() const; - - // Used by <form> elements to indicate a malformed state of some kind, typically - // used to keep from applying the bottom margin of the form. - virtual bool isMalformed() { return false; } - virtual void setMalformed(bool malformed) { } - - // These low-level calls give the caller responsibility for maintaining the integrity of the tree. - void setPreviousSibling(Node* previous) { m_previous = previous; } - void setNextSibling(Node* next) { m_next = next; } - - // FIXME: These two functions belong in editing -- "atomic node" is an editing concept. - Node* previousNodeConsideringAtomicNodes() const; - Node* nextNodeConsideringAtomicNodes() const; - - /** (Not part of the official DOM) - * Returns the next leaf node. - * - * Using this function delivers leaf nodes as if the whole DOM tree were a linear chain of its leaf nodes. - * @return next leaf node or 0 if there are no more. - */ - Node* nextLeafNode() const; - - /** (Not part of the official DOM) - * Returns the previous leaf node. - * - * Using this function delivers leaf nodes as if the whole DOM tree were a linear chain of its leaf nodes. - * @return previous leaf node or 0 if there are no more. - */ - Node* previousLeafNode() const; - - bool isEditableBlock() const; - - // enclosingBlockFlowElement() is deprecated. Use enclosingBlock instead. - Element* enclosingBlockFlowElement() const; - - Element* enclosingInlineElement() const; - Element* rootEditableElement() const; - - bool inSameContainingBlockFlowElement(Node*); - - // Used by the parser. Checks against the DTD, unlike DOM operations like appendChild(). - // Also does not dispatch DOM mutation events. - // Returns the appropriate container node for future insertions as you parse, or 0 for failure. - virtual ContainerNode* addChild(PassRefPtr<Node>); - - // Called by the parser when this element's close tag is reached, - // signalling that all child tags have been parsed and added. - // This is needed for <applet> and <object> elements, which can't lay themselves out - // until they know all of their nested <param>s. [Radar 3603191, 4040848]. - // Also used for script elements and some SVG elements for similar purposes, - // but making parsing a special case in this respect should be avoided if possible. - virtual void finishParsingChildren() { } - virtual void beginParsingChildren() { } - - // Called by the frame right before dispatching an unloadEvent. [Radar 4532113] - // This is needed for HTMLInputElements to tell the frame that it is done editing - // (sends textFieldDidEndEditing notification) - virtual void aboutToUnload() { } - - // For <link> and <style> elements. - virtual bool sheetLoaded() { return true; } - - bool hasID() const { return m_hasId; } - bool hasClass() const { return m_hasClass; } - bool active() const { return m_active; } - bool inActiveChain() const { return m_inActiveChain; } - bool inDetach() const { return m_inDetach; } - bool hovered() const { return m_hovered; } - bool focused() const { return m_focused; } - bool attached() const { return m_attached; } - void setAttached(bool b = true) { m_attached = b; } - bool changed() const { return m_styleChange != NoStyleChange; } - StyleChangeType styleChangeType() const { return static_cast<StyleChangeType>(m_styleChange); } - bool hasChangedChild() const { return m_hasChangedChild; } - bool isLink() const { return m_isLink; } - void setHasID(bool b = true) { m_hasId = b; } - void setHasClass(bool b = true) { m_hasClass = b; } - void setHasChangedChild( bool b = true ) { m_hasChangedChild = b; } - void setInDocument(bool b = true) { m_inDocument = b; } - void setInActiveChain(bool b = true) { m_inActiveChain = b; } - void setChanged(StyleChangeType changeType = FullStyleChange); - void setIsLink(bool b = true) { m_isLink = b; } - - bool inSubtreeMark() const { return m_inSubtreeMark; } - void setInSubtreeMark(bool b = true) { m_inSubtreeMark = b; } - - void lazyAttach(); - virtual bool canLazyAttach(); - - virtual void setFocus(bool b = true) { m_focused = b; } - virtual void setActive(bool b = true, bool pause=false) { m_active = b; } - virtual void setHovered(bool b = true) { m_hovered = b; } - - virtual short tabIndex() const { return m_tabIndex; } - - /** - * Whether this node can receive the keyboard focus. - */ - virtual bool supportsFocus() const { return isFocusable(); } - virtual bool isFocusable() const; - virtual bool isKeyboardFocusable(KeyboardEvent*) const; - virtual bool isMouseFocusable() const; - - virtual bool isControl() const { return false; } // Eventually the notion of what is a control will be extensible. - virtual bool isEnabled() const { return true; } - virtual bool isChecked() const { return false; } - virtual bool isIndeterminate() const { return false; } - virtual bool isReadOnlyControl() const { return false; } - virtual bool isTextControl() const { return false; } - - virtual bool isContentEditable() const; - virtual bool isContentRichlyEditable() const; - virtual bool shouldUseInputMethod() const; - virtual IntRect getRect() const; - - virtual void recalcStyle(StyleChange = NoChange) { } - - unsigned nodeIndex() const; - - // Returns the DOM ownerDocument attribute. This method never returns NULL, except in the case - // of (1) a Document node or (2) a DocumentType node that is not used with any Document yet. - virtual Document* ownerDocument() const; - - // Returns the document associated with this node. This method never returns NULL, except in the case - // of a DocumentType node that is not used with any Document yet. A Document node returns itself. - Document* document() const - { - ASSERT(this); - ASSERT(m_document || nodeType() == DOCUMENT_TYPE_NODE && !inDocument()); - return m_document.get(); - } - void setDocument(Document*); - - // Returns true if this node is associated with a document and is in its associated document's - // node tree, false otherwise. - bool inDocument() const - { - ASSERT(m_document || !m_inDocument); - return m_inDocument; - } - - bool isReadOnlyNode() const { return nodeType() == ENTITY_REFERENCE_NODE; } - virtual bool childTypeAllowed(NodeType) { return false; } - virtual unsigned childNodeCount() const; - virtual Node* childNode(unsigned index) const; - - /** - * Does a pre-order traversal of the tree to find the node next node after this one. This uses the same order that - * the tags appear in the source file. - * - * @param stayWithin If not null, the traversal will stop once the specified node is reached. This can be used to - * restrict traversal to a particular sub-tree. - * - * @return The next node, in document order - * - * see @ref traversePreviousNode() - */ - Node* traverseNextNode(const Node* stayWithin = 0) const; - - // Like traverseNextNode, but skips children and starts with the next sibling. - Node* traverseNextSibling(const Node* stayWithin = 0) const; - - /** - * Does a reverse pre-order traversal to find the node that comes before the current one in document order - * - * see @ref traverseNextNode() - */ - Node* traversePreviousNode(const Node * stayWithin = 0) const; - - // Like traverseNextNode, but visits parents after their children. - Node* traverseNextNodePostOrder() const; - - // Like traversePreviousNode, but visits parents before their children. - Node* traversePreviousNodePostOrder(const Node *stayWithin = 0) const; - Node* traversePreviousSiblingPostOrder(const Node *stayWithin = 0) const; - - /** - * Finds previous or next editable leaf node. - */ - Node* previousEditable() const; - Node* nextEditable() const; - - RenderObject* renderer() const { return m_renderer; } - RenderObject* nextRenderer(); - RenderObject* previousRenderer(); - void setRenderer(RenderObject* renderer) { m_renderer = renderer; } - - void checkSetPrefix(const AtomicString& prefix, ExceptionCode&); - bool isDescendantOf(const Node*) const; - - // These two methods are mutually exclusive. The former is used to do strict error-checking - // when adding children via the public DOM API (e.g., appendChild()). The latter is called only when parsing, - // to sanity-check against the DTD for error recovery. - void checkAddChild(Node* newChild, ExceptionCode&); // Error-checking when adding via the DOM API - virtual bool childAllowed(Node* newChild); // Error-checking during parsing that checks the DTD - - void checkReplaceChild(Node* newChild, Node* oldChild, ExceptionCode&); - virtual bool canReplaceChild(Node* newChild, Node* oldChild); - - // Used to determine whether range offsets use characters or node indices. - virtual bool offsetInCharacters() const; - // Number of DOM 16-bit units contained in node. Note that rendered text length can be different - e.g. because of - // css-transform:capitalize breaking up precomposed characters and ligatures. - virtual int maxCharacterOffset() const; - - // FIXME: We should try to find a better location for these methods. - virtual bool canSelectAll() const { return false; } - virtual void selectAll() { } - - // Whether or not a selection can be started in this object - virtual bool canStartSelection() const; - - // ----------------------------------------------------------------------------- - // Integration with rendering tree - - /** - * Attaches this node to the rendering tree. This calculates the style to be applied to the node and creates an - * appropriate RenderObject which will be inserted into the tree (except when the style has display: none). This - * makes the node visible in the FrameView. - */ - virtual void attach(); - - /** - * Detaches the node from the rendering tree, making it invisible in the rendered view. This method will remove - * the node's rendering object from the rendering tree and delete it. - */ - virtual void detach(); - - virtual void willRemove(); - void createRendererIfNeeded(); - virtual RenderStyle* styleForRenderer(RenderObject* parent); - virtual bool rendererIsNeeded(RenderStyle*); -#if ENABLE(SVG) - virtual bool childShouldCreateRenderer(Node*) const { return true; } -#endif - virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); - - // Wrapper for nodes that don't have a renderer, but still cache the style (like HTMLOptionElement). - virtual RenderStyle* renderStyle() const; - virtual void setRenderStyle(RenderStyle*); - - virtual RenderStyle* computedStyle(); - - // ----------------------------------------------------------------------------- - // Notification of document structure changes - - /** - * Notifies the node that it has been inserted into the document. This is called during document parsing, and also - * when a node is added through the DOM methods insertBefore(), appendChild() or replaceChild(). Note that this only - * happens when the node becomes part of the document tree, i.e. only when the document is actually an ancestor of - * the node. The call happens _after_ the node has been added to the tree. - * - * This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event - * dispatching. - */ - virtual void insertedIntoDocument(); - - /** - * Notifies the node that it is no longer part of the document tree, i.e. when the document is no longer an ancestor - * node. - * - * This is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event - * dispatching, and is called _after_ the node is removed from the tree. - */ - virtual void removedFromDocument(); - - // These functions are called whenever you are connected or disconnected from a tree. That tree may be the main - // document tree, or it could be another disconnected tree. Override these functions to do any work that depends - // on connectedness to some ancestor (e.g., an ancestor <form> for example). - virtual void insertedIntoTree(bool deep) { } - virtual void removedFromTree(bool deep) { } - - /** - * Notifies the node that it's list of children have changed (either by adding or removing child nodes), or a child - * node that is of the type CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed its value. - */ - virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) {}; - -#ifndef NDEBUG - virtual void formatForDebugger(char* buffer, unsigned length) const; - - void showNode(const char* prefix = "") const; - void showTreeForThis() const; - void showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2 = 0, const char* markedLabel2 = 0) const; -#endif - - void registerDynamicNodeList(DynamicNodeList*); - void unregisterDynamicNodeList(DynamicNodeList*); - void notifyNodeListsChildrenChanged(); - void notifyLocalNodeListsChildrenChanged(); - void notifyNodeListsAttributeChanged(); - void notifyLocalNodeListsAttributeChanged(); - - PassRefPtr<NodeList> getElementsByTagName(const String&); - PassRefPtr<NodeList> getElementsByTagNameNS(const String& namespaceURI, const String& localName); - PassRefPtr<NodeList> getElementsByName(const String& elementName); - PassRefPtr<NodeList> getElementsByClassName(const String& classNames); - - PassRefPtr<Element> querySelector(const String& selectors, NSResolver*, ExceptionCode&, ExceptionContext*); - PassRefPtr<NodeList> querySelectorAll(const String& selectors, NSResolver*, ExceptionCode&, ExceptionContext*); - // For non-JS bindings. Silently ignores the JavaScript exception if any. - // FIXME: We should support the NSResolver interface for non-JS bindings. - PassRefPtr<Element> querySelector(const String& selectors, ExceptionCode&); - PassRefPtr<NodeList> querySelectorAll(const String& selectors, ExceptionCode&); - - unsigned short compareDocumentPosition(Node*); - -protected: - virtual void willMoveToNewOwnerDocument() { } - virtual void didMoveToNewOwnerDocument() { } - - virtual void getSubresourceAttributeStrings(Vector<String>&) const { } - void setTabIndexExplicitly(short i) - { - m_tabIndex = i; - m_tabIndexSetExplicitly = true; - } - -private: - DocPtr<Document> m_document; - Node* m_previous; - Node* m_next; - RenderObject* m_renderer; - - OwnPtr<NodeListsNodeData> m_nodeLists; - - short m_tabIndex; - - // make sure we don't use more than 16 bits here -- adding more would increase the size of all Nodes - - unsigned m_styleChange : 2; - bool m_hasId : 1; - bool m_hasClass : 1; - bool m_attached : 1; - bool m_hasChangedChild : 1; - bool m_inDocument : 1; - bool m_isLink : 1; - bool m_focused : 1; - bool m_active : 1; - bool m_hovered : 1; - bool m_inActiveChain : 1; - bool m_inDetach : 1; - bool m_inSubtreeMark : 1; - bool m_tabIndexSetExplicitly : 1; - const bool m_isElement : 1; - // no bits left - - Element* ancestorElement() const; - - void appendTextContent(bool convertBRsToNewlines, StringBuilder&) const; - - virtual Node* virtualFirstChild() const; - virtual Node* virtualLastChild() const; - virtual bool virtualHasTagName(const QualifiedName&) const; -}; - -} //namespace - -#ifndef NDEBUG -// Outside the WebCore namespace for ease of invocation from gdb. -void showTree(const WebCore::Node*); -#endif - -#endif diff --git a/webkit/pending/ScriptController.h b/webkit/pending/ScriptController.h deleted file mode 100644 index 3350289..0000000 --- a/webkit/pending/ScriptController.h +++ /dev/null @@ -1,328 +0,0 @@ -// Copyright 2008, Google 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 Google 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 -// OWNER 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. - -// An interface to abstract implementation differences -// for various Javascript engines. - -#ifndef ScriptController_h -#define ScriptController_h - -#include "HashMap.h" - -#include "bindings/npruntime.h" -#if USE(JSC) -#include <kjs/ustring.h> -#endif - -#include <wtf/HashMap.h> - -#if USE(V8) -#include "v8.h" -#include "v8_proxy.h" -#endif - -// JavaScript implementations which expose NPObject will need to implement -// these methods. -typedef void (*NPN_ReleaseVariantValueProcPtr) (NPVariant *variant); - -typedef NPIdentifier(*NPN_GetStringIdentifierProcPtr) (const NPUTF8 *name); -typedef void (*NPN_GetStringIdentifiersProcPtr) (const NPUTF8 **names, - int32_t nameCount, - NPIdentifier *identifiers); -typedef NPIdentifier(*NPN_GetIntIdentifierProcPtr) (int32_t intid); -typedef int32_t (*NPN_IntFromIdentifierProcPtr) (NPIdentifier identifier); -typedef bool (*NPN_IdentifierIsStringProcPtr) (NPIdentifier identifier); -typedef NPUTF8 * (*NPN_UTF8FromIdentifierProcPtr) (NPIdentifier identifier); - -typedef NPObject* (*NPN_CreateObjectProcPtr) (NPP, - NPClass *aClass); -typedef NPObject* (*NPN_RetainObjectProcPtr) (NPObject *obj); -typedef void (*NPN_ReleaseObjectProcPtr) (NPObject *obj); -typedef bool (*NPN_InvokeProcPtr) (NPP npp, - NPObject *obj, - NPIdentifier methodName, - const NPVariant *args, - unsigned argCount, - NPVariant *result); -typedef bool (*NPN_InvokeDefaultProcPtr) (NPP npp, - NPObject *obj, - const NPVariant *args, - unsigned argCount, - NPVariant *result); -typedef bool (*NPN_EvaluateProcPtr) (NPP npp, - NPObject *obj, - NPString *script, - NPVariant *result); -typedef bool (*NPN_GetPropertyProcPtr) (NPP npp, - NPObject *obj, - NPIdentifier propertyName, - NPVariant *result); -typedef bool (*NPN_SetPropertyProcPtr) (NPP npp, - NPObject *obj, - NPIdentifier propertyName, - const NPVariant *value); -typedef bool (*NPN_HasPropertyProcPtr) (NPP, - NPObject *npobj, - NPIdentifier propertyName); -typedef bool (*NPN_HasMethodProcPtr) (NPP npp, - NPObject *npobj, - NPIdentifier methodName); -typedef bool (*NPN_RemovePropertyProcPtr) (NPP npp, - NPObject *obj, - NPIdentifier propertyName); -typedef void (*NPN_SetExceptionProcPtr) (NPObject *obj, - const NPUTF8 *message); - -typedef struct _NPRuntimeFunctions { - NPN_GetStringIdentifierProcPtr getStringIdentifier; - NPN_GetStringIdentifiersProcPtr getStringIdentifiers; - NPN_GetIntIdentifierProcPtr getIntIdentifier; - NPN_IdentifierIsStringProcPtr identifierIsString; - NPN_UTF8FromIdentifierProcPtr utf8FromIdentifier; - NPN_IntFromIdentifierProcPtr intFromIdentifier; - NPN_CreateObjectProcPtr createObject; - NPN_RetainObjectProcPtr retainObject; - NPN_ReleaseObjectProcPtr releaseObject; - NPN_InvokeProcPtr invoke; - NPN_InvokeDefaultProcPtr invokeDefault; - NPN_EvaluateProcPtr evaluate; - NPN_GetPropertyProcPtr getProperty; - NPN_SetPropertyProcPtr setProperty; - NPN_RemovePropertyProcPtr removeProperty; - NPN_HasPropertyProcPtr hasProperty; - NPN_HasMethodProcPtr hasMethod; - NPN_ReleaseVariantValueProcPtr releaseVariantValue; - NPN_SetExceptionProcPtr setException; -} NPRuntimeFunctions; - -#if USE(JSC) -namespace KJS { - namespace Bindings { - class RootObject; - class Instance; - } -} -#endif - -namespace WebCore { -class Document; -class Frame; -class String; -class Node; -class EventListener; -class Event; -class HTMLPlugInElement; -class PausedTimeouts; -class Widget; - -// JSString is the string class used for XMLHttpRequest's -// m_responseText field. -#if USE(JSC) -typedef KJS::UString JSString; -typedef KJS::Bindings::Instance* JSInstance; -typedef KJS::Bindings::Instance* JSPersistentInstance; -typedef KJS::JSValue* JSException; -typedef KJS::JSValue* JSResult; -#endif - -#if USE(V8) -typedef String JSString; -typedef v8::Local<v8::Object> JSInstance; -typedef v8::Persistent<v8::Object> JSPersistentInstance; -typedef v8::Local<v8::Value> JSException; -typedef v8::Persistent<v8::Value> JSResult; -#endif - -class ScriptController { -public: - ScriptController(Frame*); - ~ScriptController(); - -#if USE(V8) - // TODO(eseidel): V8Proxy should either be folded into ScriptController - // or this accessor should be made JSProxy* - V8Proxy* proxy() { return m_proxy.get(); } -#endif - - // Evaluate a script file in the environment of this proxy. - // If succeeded, 'succ' is set to true and result is returned - // as a string. - String evaluate(const String& filename, int baseLine, const String& code, Node* node = NULL, bool* succ = NULL); - - // Second API function for evaluating a JS code. - // It returns a JSResult which must be disposed by calling - // disposeJSResult. If the result is not disposed, it can cause - // serious memory leak. The caller determines whether the evaluation - // is successful by checking the value of JSResult. - JSResult evaluate(const String& filename, int baseLine, const String& code, Node*); - void disposeJSResult(JSResult result); - void collectGarbage(); - - PassRefPtr<EventListener> createHTMLEventHandler(const String& functionName, const String& code, Node*); -#if ENABLE(SVG) - PassRefPtr<EventListener> createSVGEventHandler(const String& functionName, const String& code, Node*); -#endif - - // Get the Root object - // JSRootObject* getRootObject(); - // Creates a property of the global object of a frame. - void BindToWindowObject(Frame*, const String& key, NPObject*); - - NPRuntimeFunctions* functions(); - - JSInstance createScriptInstanceForWidget(Widget*); - - void clearPluginObjects(); - void clearDocumentWrapper(); - void disconnectFrame(); - - // Check if the javascript engine has been initialized. - bool haveInterpreter() const; - - bool isEnabled() const; - - // TODO(eseide): void* is a compile hack - void attachDebugger(void*); - - // Create a NPObject wrapper for a JSObject - // NPObject *WrapScriptObject(NPP pluginId, JSObject* objectToWrap, - // JSRootObject* originRootObject, - // JSRootObject* rootObject); - - // --- Static methods assume we are running VM in single thread, --- - // --- and there is only one VM instance. --- - - // Returns the frame of the calling code is in. - // Not necessary the frame of this proxy. - // For example, JS code in frame A calls windowB.open(...). - // Window::open method has the frame pointer of B, but - // the execution context is in frame A, so it needs - // frame A's loader to complete URL. - static Frame* retrieveActiveFrame(); - - // Check whether it is safe to access a frame in another domain. - static bool isSafeScript(Frame* target); - - // Tell the proxy that document.domain is set. - static void setDomain(Frame* target, const String& newDomain); - - // Pass command-line flags to the JS engine - static void setFlags(const char* str, int length); - - // Protect and unprotect the JS wrapper from garbage collected. - static void gcProtectJSWrapper(void* object); - static void gcUnprotectJSWrapper(void* object); - - // Get/Set RecordPlaybackMode flag. - // This is a special mode where JS helps the browser implement - // playback/record mode. Generally, in this mode, some functions - // of client-side randomness are removed. For example, in - // this mode Math.random() and Date.getTime() may not return - // values which vary. - static bool RecordPlaybackMode() { return m_recordPlaybackMode; } - static void setRecordPlaybackMode(bool value) { m_recordPlaybackMode = value; } - - void finishedWithEvent(Event*); - void setEventHandlerLineno(int lineno); - - void setProcessingTimerCallback(bool b) { m_processingTimerCallback = b; } - bool processingUserGesture() const; - - void setPaused(bool b) { m_paused = b; } - bool isPaused() const { return m_paused; } - - const String* sourceURL() const { return m_sourceURL; } // 0 if we are not evaluating any script - - void clearWindowShell(); - void updateDocument(); - - void pauseTimeouts(OwnPtr<PausedTimeouts>&); - void resumeTimeouts(OwnPtr<PausedTimeouts>&); - - void clearScriptObjects(); - void cleanupScriptObjectsForPlugin(void*); - -#if ENABLE(NETSCAPE_PLUGIN_API) - NPObject* createScriptObjectForPluginElement(HTMLPlugInElement*); - NPObject* windowScriptNPObject(); -#endif - -private: - static bool m_recordPlaybackMode; - - Frame* m_frame; - const String* m_sourceURL; - - bool m_processingTimerCallback; - bool m_paused; - -#if USE(V8) - OwnPtr<V8Proxy> m_proxy; - typedef HashMap<void*, NPObject*> PluginObjectMap; -#endif - -#if USE(JSC) - // The root object used for objects bound outside the context of a plugin. - RefPtr<KJS::Bindings::RootObject> m_bindingRootObject; - RootObjectMap m_rootObjects; -#elif USE(V8) - // A mapping between Widgets and their corresponding script object. - // This list is used so that when the plugin dies, we can immediately - // invalidate all sub-objects which are associated with that plugin. - // The frame keeps a NPObject reference for each item on the list. - PluginObjectMap m_pluginObjects; -#endif -#if ENABLE(NETSCAPE_PLUGIN_API) - NPObject* m_windowScriptNPObject; -#endif -}; - -// JSInstance is an abstraction for a wrapped C class. JSC and V8 -// have very different implementations. -class JSInstanceHolder { -public: - JSInstanceHolder(); - JSInstanceHolder(JSInstance); - ~JSInstanceHolder(); - // Returns true if the holder is empty. - bool IsEmpty(); - // Get the contained JSInstance. - JSInstance Get(); - // Clear the contained JSInstance. - void Clear(); - JSInstanceHolder& operator=(JSInstance); - static JSInstance EmptyInstance(); - -private: - JSPersistentInstance m_instance; -}; - -} // namespace WebCore - -#endif // ScriptController_h |