diff -r 000000000000 -r 4f2f89ce4247 WebCore/dom/Document.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebCore/dom/Document.h Fri Sep 17 09:02:29 2010 +0300 @@ -0,0 +1,1335 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * (C) 1999 Antti Koivisto (koivisto@kde.org) + * (C) 2001 Dirk Mueller (mueller@kde.org) + * (C) 2006 Alexey Proskuryakov (ap@webkit.org) + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) + * + * 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 Document_h +#define Document_h + +#include "CachedResourceHandle.h" +#include "CheckedRadioButtons.h" +#include "ContainerNode.h" +#include "CollectionCache.h" +#include "CollectionType.h" +#include "Color.h" +#include "Document.h" +#include "DocumentMarker.h" +#include "QualifiedName.h" +#include "ScriptExecutionContext.h" +#include "Timer.h" +#include +#include +#include +#include + +#if USE(JSC) +#include +#endif + +namespace WebCore { + + class Attr; + class AXObjectCache; + class CDATASection; + class CachedCSSStyleSheet; + class CachedScript; + class CanvasRenderingContext; + class CharacterData; + class CSSStyleDeclaration; + class CSSStyleSelector; + class CSSStyleSheet; + class Comment; + class Database; + class DOMImplementation; + class DOMSelection; + class DOMWindow; + class DatabaseThread; + class DocLoader; + class DocumentFragment; + class DocumentType; + class DocumentWeakReference; + class EditingText; + class Element; + class EntityReference; + class Event; + class EventListener; + class Frame; + class FrameView; + class HTMLCanvasElement; + class HTMLCollection; + class HTMLAllCollection; + class HTMLDocument; + class HTMLElement; + class HTMLFormElement; + class HTMLFrameOwnerElement; + class HTMLHeadElement; + class HTMLInputElement; + class HTMLMapElement; + class HistoryItem; + class HitTestRequest; + class HitTestResult; + class InspectorTimelineAgent; + class IntPoint; + class DOMWrapperWorld; + class JSNode; + class MediaCanStartListener; + class MouseEventWithHitTestResults; + class NodeFilter; + class NodeIterator; + class Page; + class PlatformMouseEvent; + class ProcessingInstruction; + class Range; + class RegisteredEventListener; + class RenderArena; + class RenderView; + class ScriptableDocumentParser; + class ScriptElementData; + class SecurityOrigin; + class SerializedScriptValue; + class SegmentedString; + class Settings; + class StyleSheet; + class StyleSheetList; + class Text; + class TextResourceDecoder; + class DocumentParser; + class TreeWalker; + class XMLHttpRequest; + +#if ENABLE(SVG) + class SVGDocumentExtensions; +#endif + +#if ENABLE(XSLT) + class TransformSource; +#endif + +#if ENABLE(XBL) + class XBLBindingManager; +#endif + +#if ENABLE(XPATH) + class XPathEvaluator; + class XPathExpression; + class XPathNSResolver; + class XPathResult; +#endif + +#if ENABLE(DASHBOARD_SUPPORT) + struct DashboardRegionValue; +#endif + + typedef int ExceptionCode; + +class FormElementKey { +public: + FormElementKey(AtomicStringImpl* = 0, AtomicStringImpl* = 0); + ~FormElementKey(); + FormElementKey(const FormElementKey&); + FormElementKey& operator=(const FormElementKey&); + + AtomicStringImpl* name() const { return m_name; } + AtomicStringImpl* type() const { return m_type; } + + // Hash table deleted values, which are only constructed and never copied or destroyed. + FormElementKey(WTF::HashTableDeletedValueType) : m_name(hashTableDeletedValue()) { } + bool isHashTableDeletedValue() const { return m_name == hashTableDeletedValue(); } + +private: + void ref() const; + void deref() const; + + static AtomicStringImpl* hashTableDeletedValue() { return reinterpret_cast(-1); } + + AtomicStringImpl* m_name; + AtomicStringImpl* m_type; +}; + +inline bool operator==(const FormElementKey& a, const FormElementKey& b) +{ + return a.name() == b.name() && a.type() == b.type(); +} + +struct FormElementKeyHash { + static unsigned hash(const FormElementKey&); + static bool equal(const FormElementKey& a, const FormElementKey& b) { return a == b; } + static const bool safeToCompareToEmptyOrDeleted = true; +}; + +struct FormElementKeyHashTraits : WTF::GenericHashTraits { + static void constructDeletedValue(FormElementKey& slot) { new (&slot) FormElementKey(WTF::HashTableDeletedValue); } + static bool isDeletedValue(const FormElementKey& value) { return value.isHashTableDeletedValue(); } +}; + +enum PageshowEventPersistence { + PageshowEventNotPersisted = 0, + PageshowEventPersisted = 1 +}; + +class Document : public ContainerNode, public ScriptExecutionContext { +public: + static PassRefPtr create(Frame* frame, const KURL& url) + { + return adoptRef(new Document(frame, url, false, false)); + } + static PassRefPtr createXHTML(Frame* frame, const KURL& url) + { + return adoptRef(new Document(frame, url, true, false)); + } + virtual ~Document(); + + using ContainerNode::ref; + using ContainerNode::deref; + + // Nodes belonging to this document hold "self-only" references - + // these are enough to keep the document from being destroyed, but + // not enough to keep it from removing its children. This allows a + // node that outlives its document to still have a valid document + // pointer without introducing reference cycles + + void selfOnlyRef() + { + ASSERT(!m_deletionHasBegun); + ++m_selfOnlyRefCount; + } + void selfOnlyDeref() + { + ASSERT(!m_deletionHasBegun); + --m_selfOnlyRefCount; + if (!m_selfOnlyRefCount && !refCount()) { +#ifndef NDEBUG + m_deletionHasBegun = true; +#endif + delete this; + } + } + + // DOM methods & attributes for Document + + DEFINE_ATTRIBUTE_EVENT_LISTENER(abort); + DEFINE_ATTRIBUTE_EVENT_LISTENER(change); + DEFINE_ATTRIBUTE_EVENT_LISTENER(click); + DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave); + DEFINE_ATTRIBUTE_EVENT_LISTENER(drop); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart); + DEFINE_ATTRIBUTE_EVENT_LISTENER(drag); + DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend); + DEFINE_ATTRIBUTE_EVENT_LISTENER(input); + DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress); + DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup); + DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel); + DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll); + DEFINE_ATTRIBUTE_EVENT_LISTENER(select); + DEFINE_ATTRIBUTE_EVENT_LISTENER(submit); + + DEFINE_ATTRIBUTE_EVENT_LISTENER(blur); + DEFINE_ATTRIBUTE_EVENT_LISTENER(error); + DEFINE_ATTRIBUTE_EVENT_LISTENER(focus); + DEFINE_ATTRIBUTE_EVENT_LISTENER(load); + + // WebKit extensions + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut); + DEFINE_ATTRIBUTE_EVENT_LISTENER(cut); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy); + DEFINE_ATTRIBUTE_EVENT_LISTENER(copy); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste); + DEFINE_ATTRIBUTE_EVENT_LISTENER(paste); + DEFINE_ATTRIBUTE_EVENT_LISTENER(reset); + DEFINE_ATTRIBUTE_EVENT_LISTENER(search); + DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart); +#if ENABLE(TOUCH_EVENTS) + DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart); + DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove); + DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend); + DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel); +#endif +#if ENABLE(TRANSFORMACTION_EVENTS) + DEFINE_ATTRIBUTE_EVENT_LISTENER(transformactionstart); + DEFINE_ATTRIBUTE_EVENT_LISTENER(transformactionupdate); + DEFINE_ATTRIBUTE_EVENT_LISTENER(transformactionend); +#endif + + DocumentType* doctype() const { return m_docType.get(); } + + DOMImplementation* implementation() const; + + Element* documentElement() const + { + if (!m_documentElement) + cacheDocumentElement(); + return m_documentElement.get(); + } + + virtual PassRefPtr createElement(const AtomicString& tagName, ExceptionCode&); + PassRefPtr createDocumentFragment(); + PassRefPtr createTextNode(const String& data); + PassRefPtr createComment(const String& data); + PassRefPtr createCDATASection(const String& data, ExceptionCode&); + PassRefPtr createProcessingInstruction(const String& target, const String& data, ExceptionCode&); + PassRefPtr createAttribute(const String& name, ExceptionCode&); + PassRefPtr createAttributeNS(const String& namespaceURI, const String& qualifiedName, ExceptionCode&, bool shouldIgnoreNamespaceChecks = false); + PassRefPtr createEntityReference(const String& name, ExceptionCode&); + PassRefPtr importNode(Node* importedNode, bool deep, ExceptionCode&); + virtual PassRefPtr createElementNS(const String& namespaceURI, const String& qualifiedName, ExceptionCode&); + PassRefPtr createElement(const QualifiedName&, bool createdByParser); + Element* getElementById(const AtomicString&) const; + bool hasElementWithId(AtomicStringImpl* id) const; + bool containsMultipleElementsWithId(const AtomicString& elementId) { return m_duplicateIds.contains(elementId.impl()); } + + /** + * Retrieve all nodes that intersect a rect in the window's document, until it is fully enclosed by + * the boundaries of node. + * + * @param centerX x reference for the rectangle in CSS pixels + * @param centerY y reference for the rectangle in CSS pixels + * @param hPadding How much to expand the rectangle horizontally + * @param vPadding How much to expand the rectangle vertically + * @param ignoreClipping whether or not to ignore the root scroll frame when retrieving the element. + * If false, this method returns null for coordinates outside of the viewport. + */ + PassRefPtr nodesFromRect(int centerX, int centerY, unsigned hPadding, unsigned vPadding, bool ignoreClipping) const; + Element* elementFromPoint(int x, int y) const; + PassRefPtr caretRangeFromPoint(int x, int y); + + String readyState() const; + + String defaultCharset() const; + + // Synonyms backing similar DOM attributes. Use Document::encoding() to avoid virtual dispatch. + String inputEncoding() const { return Document::encoding(); } + String charset() const { return Document::encoding(); } + String characterSet() const { return Document::encoding(); } + + void setCharset(const String&); + + String contentLanguage() const { return m_contentLanguage; } + void setContentLanguage(const String& lang) { m_contentLanguage = lang; } + + String xmlEncoding() const { return m_xmlEncoding; } + String xmlVersion() const { return m_xmlVersion; } + bool xmlStandalone() const { return m_xmlStandalone; } + + void setXMLEncoding(const String& encoding) { m_xmlEncoding = encoding; } // read-only property, only to be set from XMLDocumentParser + void setXMLVersion(const String&, ExceptionCode&); + void setXMLStandalone(bool, ExceptionCode&); + + String documentURI() const { return m_documentURI; } + void setDocumentURI(const String&); + + virtual KURL baseURI() const; + + PassRefPtr adoptNode(PassRefPtr source, ExceptionCode&); + + PassRefPtr images(); + PassRefPtr embeds(); + PassRefPtr plugins(); // an alias for embeds() required for the JS DOM bindings. + PassRefPtr applets(); + PassRefPtr links(); + PassRefPtr forms(); + PassRefPtr anchors(); + PassRefPtr objects(); + PassRefPtr scripts(); + PassRefPtr windowNamedItems(const String& name); + PassRefPtr documentNamedItems(const String& name); + + PassRefPtr all(); + + // Find first anchor with the given name. + // First searches for an element with the given ID, but if that fails, then looks + // for an anchor with the given name. ID matching is always case sensitive, but + // Anchor name matching is case sensitive in strict mode and not case sensitive in + // quirks mode for historical compatibility reasons. + Element* findAnchor(const String& name); + + CollectionCache* collectionInfo(CollectionType type) + { + ASSERT(type >= FirstUnnamedDocumentCachedType); + unsigned index = type - FirstUnnamedDocumentCachedType; + ASSERT(index < NumUnnamedDocumentCachedTypes); + m_collectionInfo[index].checkConsistency(); + return &m_collectionInfo[index]; + } + + CollectionCache* nameCollectionInfo(CollectionType, const AtomicString& name); + + // Other methods (not part of DOM) + bool isHTMLDocument() const { return m_isHTML; } + bool isXHTMLDocument() const { return m_isXHTML; } + virtual bool isImageDocument() const { return false; } +#if ENABLE(SVG) + virtual bool isSVGDocument() const { return false; } +#else + static bool isSVGDocument() { return false; } +#endif + virtual bool isPluginDocument() const { return false; } + virtual bool isMediaDocument() const { return false; } +#if ENABLE(WML) + virtual bool isWMLDocument() const { return false; } +#endif +#if ENABLE(XHTMLMP) + bool isXHTMLMPDocument() const; + bool shouldProcessNoscriptElement() const { return m_shouldProcessNoScriptElement; } + void setShouldProcessNoscriptElement(bool shouldDo) { m_shouldProcessNoScriptElement = shouldDo; } +#endif + virtual bool isFrameSet() const { return false; } + + CSSStyleSelector* styleSelector() + { + if (!m_styleSelector) + createStyleSelector(); + return m_styleSelector.get(); + } + + Element* getElementByAccessKey(const String& key) const; + + /** + * Updates the pending sheet count and then calls updateStyleSelector. + */ + void removePendingSheet(); + + /** + * This method returns true if all top-level stylesheets have loaded (including + * any @imports that they may be loading). + */ + bool haveStylesheetsLoaded() const + { + return m_pendingStylesheets <= 0 || m_ignorePendingStylesheets; + } + + /** + * Increments the number of pending sheets. The elements + * invoke this to add themselves to the loading list. + */ + void addPendingSheet() { m_pendingStylesheets++; } + + void addStyleSheetCandidateNode(Node*, bool createdByParser); + void removeStyleSheetCandidateNode(Node*); + + bool gotoAnchorNeededAfterStylesheetsLoad() { return m_gotoAnchorNeededAfterStylesheetsLoad; } + void setGotoAnchorNeededAfterStylesheetsLoad(bool b) { m_gotoAnchorNeededAfterStylesheetsLoad = b; } + + /** + * Called when one or more stylesheets in the document may have been added, removed or changed. + * + * Creates a new style selector and assign it to this document. This is done by iterating through all nodes in + * document (or those before in a HTML document), searching for stylesheets. Stylesheets can be contained in + * ,