cf328dacdfd48d0505b3fa086fcaf19f8d6f94bc
[WebKit-https.git] / WebCore / dom / Document.h
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2001 Dirk Mueller (mueller@kde.org)
5  *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
7  * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  *
24  */
25
26 #ifndef Document_h
27 #define Document_h
28
29 #include "Attr.h"
30 #include "Color.h"
31 #include "DocumentMarker.h"
32 #include "HTMLCollection.h"
33 #include "HTMLFormElement.h"
34 #include "ScriptExecutionContext.h"
35 #include "StringHash.h"
36 #include "Timer.h"
37 #include <wtf/HashCountedSet.h>
38 #include <wtf/ListHashSet.h>
39
40 // FIXME: We should move Mac off of the old Frame-based user stylesheet loading
41 // code and onto the new code in Page. We can't do that until the code in Page
42 // supports non-file: URLs, however.
43 #if PLATFORM(MAC) || PLATFORM(QT)
44 #define FRAME_LOADS_USER_STYLESHEET 1
45 #else
46 #define FRAME_LOADS_USER_STYLESHEET 0
47 #endif
48
49 namespace WebCore {
50
51     class AXObjectCache;
52     class Attr;
53     class Attribute;
54     class CDATASection;
55     class CachedCSSStyleSheet;
56     class CanvasRenderingContext2D;
57     class CharacterData;
58     class CSSStyleDeclaration;
59     class CSSStyleSelector;
60     class CSSStyleSheet;
61     class Comment;
62     class Database;
63     class DOMImplementation;
64     class DOMSelection;
65     class DOMWindow;
66     class DatabaseThread;
67     class DocLoader;
68     class DocumentFragment;
69     class DocumentType;
70     class EditingText;
71     class Element;
72     class EntityReference;
73     class Event;
74     class EventListener;
75     class FormControlElementWithState;
76     class Frame;
77     class FrameView;
78     class HitTestRequest;
79     class HTMLCanvasElement;
80     class HTMLDocument;
81     class HTMLElement;
82     class HTMLFormElement;
83     class HTMLHeadElement;
84     class HTMLInputElement;
85     class HTMLMapElement;
86     class ImageLoader;
87     class IntPoint;
88     class JSNode;
89     class MouseEventWithHitTestResults;
90     class NodeFilter;
91     class NodeIterator;
92     class Page;
93     class PlatformMouseEvent;
94     class ProcessingInstruction;
95     class Range;
96     class RegisteredEventListener;
97     class RenderArena;
98     class RenderView;
99     class SecurityOrigin;
100     class SegmentedString;
101     class Settings;
102     class StyleSheet;
103     class StyleSheetList;
104     class Text;
105     class TextResourceDecoder;
106     class Tokenizer;
107     class TreeWalker;
108     class XMLHttpRequest;
109
110 #if ENABLE(SVG)
111     class SVGDocumentExtensions;
112 #endif
113     
114 #if ENABLE(XBL)
115     class XBLBindingManager;
116 #endif
117
118 #if ENABLE(XPATH)
119     class XPathEvaluator;
120     class XPathExpression;
121     class XPathNSResolver;
122     class XPathResult;
123 #endif
124
125 #if ENABLE(DASHBOARD_SUPPORT)
126     struct DashboardRegionValue;
127 #endif
128
129     typedef int ExceptionCode;
130
131 class FormElementKey {
132 public:
133     FormElementKey(AtomicStringImpl* = 0, AtomicStringImpl* = 0);
134     ~FormElementKey();
135     FormElementKey(const FormElementKey&);
136     FormElementKey& operator=(const FormElementKey&);
137
138     AtomicStringImpl* name() const { return m_name; }
139     AtomicStringImpl* type() const { return m_type; }
140
141     // Hash table deleted values, which are only constructed and never copied or destroyed.
142     FormElementKey(WTF::HashTableDeletedValueType) : m_name(hashTableDeletedValue()) { }
143     bool isHashTableDeletedValue() const { return m_name == hashTableDeletedValue(); }
144
145 private:
146     void ref() const;
147     void deref() const;
148
149     static AtomicStringImpl* hashTableDeletedValue() { return reinterpret_cast<AtomicStringImpl*>(-1); }
150
151     AtomicStringImpl* m_name;
152     AtomicStringImpl* m_type;
153 };
154
155 inline bool operator==(const FormElementKey& a, const FormElementKey& b)
156 {
157     return a.name() == b.name() && a.type() == b.type();
158 }
159
160 struct FormElementKeyHash {
161     static unsigned hash(const FormElementKey&);
162     static bool equal(const FormElementKey& a, const FormElementKey& b) { return a == b; }
163     static const bool safeToCompareToEmptyOrDeleted = true;
164 };
165
166 struct FormElementKeyHashTraits : WTF::GenericHashTraits<FormElementKey> {
167     static void constructDeletedValue(FormElementKey& slot) { new (&slot) FormElementKey(WTF::HashTableDeletedValue); }
168     static bool isDeletedValue(const FormElementKey& value) { return value.isHashTableDeletedValue(); }
169 };
170
171 class Document : public ContainerNode, public ScriptExecutionContext {
172 public:
173     static PassRefPtr<Document> create(Frame* frame)
174     {
175         return new Document(frame, false);
176     }
177     static PassRefPtr<Document> createXHTML(Frame* frame)
178     {
179         return new Document(frame, true);
180     }
181     virtual ~Document();
182
183     virtual bool isDocument() const { return true; }
184
185     using ContainerNode::ref;
186     using ContainerNode::deref;
187     virtual void removedLastRef();
188
189     // Nodes belonging to this document hold "self-only" references -
190     // these are enough to keep the document from being destroyed, but
191     // not enough to keep it from removing its children. This allows a
192     // node that outlives its document to still have a valid document
193     // pointer without introducing reference cycles
194
195     void selfOnlyRef()
196     {
197         ASSERT(!m_deletionHasBegun);
198         ++m_selfOnlyRefCount;
199     }
200     void selfOnlyDeref()
201     {
202         ASSERT(!m_deletionHasBegun);
203         --m_selfOnlyRefCount;
204         if (!m_selfOnlyRefCount && !refCount()) {
205 #ifndef NDEBUG
206             m_deletionHasBegun = true;
207 #endif
208             delete this;
209         }
210     }
211
212     // DOM methods & attributes for Document
213
214     DocumentType* doctype() const { return m_docType.get(); }
215
216     DOMImplementation* implementation() const;
217     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
218     
219     Element* documentElement() const
220     {
221         if (!m_documentElement)
222             cacheDocumentElement();
223         return m_documentElement.get();
224     }
225     
226     virtual PassRefPtr<Element> createElement(const AtomicString& tagName, ExceptionCode&);
227     PassRefPtr<DocumentFragment> createDocumentFragment ();
228     PassRefPtr<Text> createTextNode(const String& data);
229     PassRefPtr<Comment> createComment(const String& data);
230     PassRefPtr<CDATASection> createCDATASection(const String& data, ExceptionCode&);
231     PassRefPtr<ProcessingInstruction> createProcessingInstruction(const String& target, const String& data, ExceptionCode&);
232     PassRefPtr<Attr> createAttribute(const String& name, ExceptionCode& ec) { return createAttributeNS(String(), name, ec, true); }
233     PassRefPtr<Attr> createAttributeNS(const String& namespaceURI, const String& qualifiedName, ExceptionCode&, bool shouldIgnoreNamespaceChecks = false);
234     PassRefPtr<EntityReference> createEntityReference(const String& name, ExceptionCode&);
235     PassRefPtr<Node> importNode(Node* importedNode, bool deep, ExceptionCode&);
236     virtual PassRefPtr<Element> createElementNS(const String& namespaceURI, const String& qualifiedName, ExceptionCode&);
237     PassRefPtr<Element> createElement(const QualifiedName&, bool createdByParser);
238     Element* getElementById(const AtomicString&) const;
239     bool hasElementWithId(AtomicStringImpl* id) const;
240     bool containsMultipleElementsWithId(const AtomicString& elementId) { return m_duplicateIds.contains(elementId.impl()); }
241
242     Element* elementFromPoint(int x, int y) const;
243     String readyState() const;
244     String inputEncoding() const;
245     String defaultCharset() const;
246
247     String charset() const { return inputEncoding(); }
248     String characterSet() const { return inputEncoding(); }
249
250     void setCharset(const String&);
251
252     String contentLanguage() const { return m_contentLanguage; }
253     void setContentLanguage(const String& lang) { m_contentLanguage = lang; }
254
255     String xmlEncoding() const { return m_xmlEncoding; }
256     String xmlVersion() const { return m_xmlVersion; }
257     bool xmlStandalone() const { return m_xmlStandalone; }
258
259     void setXMLEncoding(const String& encoding) { m_xmlEncoding = encoding; } // read-only property, only to be set from XMLTokenizer
260     void setXMLVersion(const String&, ExceptionCode&);
261     void setXMLStandalone(bool, ExceptionCode&);
262
263     String documentURI() const { return m_documentURI; }
264     void setDocumentURI(const String&);
265
266     virtual KURL baseURI() const;
267
268     PassRefPtr<Node> adoptNode(PassRefPtr<Node> source, ExceptionCode&);
269
270     PassRefPtr<HTMLCollection> images();
271     PassRefPtr<HTMLCollection> embeds();
272     PassRefPtr<HTMLCollection> plugins(); // an alias for embeds() required for the JS DOM bindings.
273     PassRefPtr<HTMLCollection> applets();
274     PassRefPtr<HTMLCollection> links();
275     PassRefPtr<HTMLCollection> forms();
276     PassRefPtr<HTMLCollection> anchors();
277     PassRefPtr<HTMLCollection> all();
278     PassRefPtr<HTMLCollection> objects();
279     PassRefPtr<HTMLCollection> scripts();
280     PassRefPtr<HTMLCollection> windowNamedItems(const String& name);
281     PassRefPtr<HTMLCollection> documentNamedItems(const String& name);
282
283     // Find first anchor with the given name.
284     // First searches for an element with the given ID, but if that fails, then looks
285     // for an anchor with the given name. ID matching is always case sensitive, but
286     // Anchor name matching is case sensitive in strict mode and not case sensitive in
287     // quirks mode for historical compatibility reasons.
288     Element* findAnchor(const String& name);
289
290     HTMLCollection::CollectionInfo* collectionInfo(HTMLCollection::Type type)
291     {
292         ASSERT(type >= HTMLCollection::FirstUnnamedDocumentCachedType);
293         unsigned index = type - HTMLCollection::FirstUnnamedDocumentCachedType;
294         ASSERT(index < HTMLCollection::NumUnnamedDocumentCachedTypes);
295         return &m_collectionInfo[index]; 
296     }
297
298     HTMLCollection::CollectionInfo* nameCollectionInfo(HTMLCollection::Type, const AtomicString& name);
299
300     // DOM methods overridden from  parent classes
301
302     virtual String nodeName() const;
303     virtual NodeType nodeType() const;
304
305     // Other methods (not part of DOM)
306     virtual bool isHTMLDocument() const { return false; }
307     virtual bool isImageDocument() const { return false; }
308 #if ENABLE(SVG)
309     virtual bool isSVGDocument() const { return false; }
310 #endif
311     virtual bool isPluginDocument() const { return false; }
312     virtual bool isMediaDocument() const { return false; }
313 #if ENABLE(WML)
314     virtual bool isWMLDocument() const { return false; }
315 #endif
316     virtual bool isFrameSet() const { return false; }
317     
318     CSSStyleSelector* styleSelector() const { return m_styleSelector; }
319
320     Element* getElementByAccessKey(const String& key) const;
321     
322     /**
323      * Updates the pending sheet count and then calls updateStyleSelector.
324      */
325     void removePendingSheet();
326
327     /**
328      * This method returns true if all top-level stylesheets have loaded (including
329      * any @imports that they may be loading).
330      */
331     bool haveStylesheetsLoaded() const
332     {
333         return m_pendingStylesheets <= 0 || m_ignorePendingStylesheets;
334     }
335
336     /**
337      * Increments the number of pending sheets.  The <link> elements
338      * invoke this to add themselves to the loading list.
339      */
340     void addPendingSheet() { m_pendingStylesheets++; }
341
342     void addStyleSheetCandidateNode(Node*, bool createdByParser);
343     void removeStyleSheetCandidateNode(Node*);
344
345     bool gotoAnchorNeededAfterStylesheetsLoad() { return m_gotoAnchorNeededAfterStylesheetsLoad; }
346     void setGotoAnchorNeededAfterStylesheetsLoad(bool b) { m_gotoAnchorNeededAfterStylesheetsLoad = b; }
347
348     /**
349      * Called when one or more stylesheets in the document may have been added, removed or changed.
350      *
351      * Creates a new style selector and assign it to this document. This is done by iterating through all nodes in
352      * document (or those before <BODY> in a HTML document), searching for stylesheets. Stylesheets can be contained in
353      * <LINK>, <STYLE> or <BODY> elements, as well as processing instructions (XML documents only). A list is
354      * constructed from these which is used to create the a new style selector which collates all of the stylesheets
355      * found and is used to calculate the derived styles for all rendering objects.
356      */
357     void updateStyleSelector();
358
359     void recalcStyleSelector();
360
361     bool usesDescendantRules() const { return m_usesDescendantRules; }
362     void setUsesDescendantRules(bool b) { m_usesDescendantRules = b; }
363     bool usesSiblingRules() const { return m_usesSiblingRules; }
364     void setUsesSiblingRules(bool b) { m_usesSiblingRules = b; }
365     bool usesFirstLineRules() const { return m_usesFirstLineRules; }
366     void setUsesFirstLineRules(bool b) { m_usesFirstLineRules = b; }
367     bool usesFirstLetterRules() const { return m_usesFirstLetterRules; }
368     void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; }
369     bool usesBeforeAfterRules() const { return m_usesBeforeAfterRules; }
370     void setUsesBeforeAfterRules(bool b) { m_usesBeforeAfterRules = b; }
371
372     // Machinery for saving and restoring state when you leave and then go back to a page.
373     void registerFormElementWithState(FormControlElementWithState* e) { m_formElementsWithState.add(e); }
374     void unregisterFormElementWithState(FormControlElementWithState* e) { m_formElementsWithState.remove(e); }
375     Vector<String> formElementsState() const;
376     void setStateForNewFormElements(const Vector<String>&);
377     bool hasStateForNewFormElements() const;
378     bool takeStateForFormElement(AtomicStringImpl* name, AtomicStringImpl* type, String& state);
379
380     FrameView* view() const; // can be NULL
381     Frame* frame() const { return m_frame; } // can be NULL
382     Page* page() const; // can be NULL
383     Settings* settings() const; // can be NULL
384
385     PassRefPtr<Range> createRange();
386
387     PassRefPtr<NodeIterator> createNodeIterator(Node* root, unsigned whatToShow,
388         PassRefPtr<NodeFilter>, bool expandEntityReferences, ExceptionCode&);
389
390     PassRefPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow, 
391         PassRefPtr<NodeFilter>, bool expandEntityReferences, ExceptionCode&);
392
393     // Special support for editing
394     PassRefPtr<CSSStyleDeclaration> createCSSStyleDeclaration();
395     PassRefPtr<EditingText> createEditingTextNode(const String&);
396
397     virtual void recalcStyle( StyleChange = NoChange );
398     virtual void updateRendering();
399     void updateLayout();
400     void updateLayoutIgnorePendingStylesheets();
401     static void updateDocumentsRendering();
402     DocLoader* docLoader() { return m_docLoader; }
403
404     virtual void attach();
405     virtual void detach();
406
407     void clearFramePointer();
408
409     RenderArena* renderArena() { return m_renderArena; }
410
411     RenderView* renderView() const;
412
413     void clearAXObjectCache();
414     AXObjectCache* axObjectCache() const;
415     
416     // to get visually ordered hebrew and arabic pages right
417     void setVisuallyOrdered();
418
419     void open(Document* ownerDocument = 0);
420     void implicitOpen();
421     void close();
422     void implicitClose();
423     void cancelParsing();
424
425     void write(const SegmentedString& text, Document* ownerDocument = 0);
426     void write(const String& text, Document* ownerDocument = 0);
427     void writeln(const String& text, Document* ownerDocument = 0);
428     void finishParsing();
429     void clear();
430
431     bool wellFormed() const { return m_wellFormed; }
432
433     const KURL& url() const { return m_url; }
434     void setURL(const KURL&);
435
436     const KURL& baseURL() const { return m_baseURL; }
437     // Setting the BaseElementURL will change the baseURL.
438     void setBaseElementURL(const KURL&);
439
440     const String& baseTarget() const { return m_baseTarget; }
441     // Setting the BaseElementTarget will change the baseTarget.
442     void setBaseElementTarget(const String& baseTarget) { m_baseTarget = baseTarget; }
443
444     KURL completeURL(const String&) const;
445
446     virtual String userAgent(const KURL&) const;
447
448     // from cachedObjectClient
449     virtual void setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet*);
450
451 #if FRAME_LOADS_USER_STYLESHEET
452     void setUserStyleSheet(const String& sheet);
453 #endif
454
455     String userStyleSheet() const;
456
457     CSSStyleSheet* elementSheet();
458     CSSStyleSheet* mappedElementSheet();
459     virtual Tokenizer* createTokenizer();
460     Tokenizer* tokenizer() { return m_tokenizer; }
461     
462     bool printing() const { return m_printing; }
463     void setPrinting(bool p) { m_printing = p; }
464
465     enum ParseMode { Compat, AlmostStrict, Strict };
466
467 private:
468     virtual void determineParseMode() {}
469     
470 public:
471     void setParseMode(ParseMode m) { m_parseMode = m; }
472     ParseMode parseMode() const { return m_parseMode; }
473
474     bool inCompatMode() const { return m_parseMode == Compat; }
475     bool inAlmostStrictMode() const { return m_parseMode == AlmostStrict; }
476     bool inStrictMode() const { return m_parseMode == Strict; }
477     
478     void setParsing(bool);
479     bool parsing() const { return m_bParsing; }
480     int minimumLayoutDelay();
481     bool shouldScheduleLayout();
482     int elapsedTime() const;
483     
484     void setTextColor(const Color& color) { m_textColor = color; }
485     Color textColor() const { return m_textColor; }
486
487     const Color& linkColor() const { return m_linkColor; }
488     const Color& visitedLinkColor() const { return m_visitedLinkColor; }
489     const Color& activeLinkColor() const { return m_activeLinkColor; }
490     void setLinkColor(const Color& c) { m_linkColor = c; }
491     void setVisitedLinkColor(const Color& c) { m_visitedLinkColor = c; }
492     void setActiveLinkColor(const Color& c) { m_activeLinkColor = c; }
493     void resetLinkColor();
494     void resetVisitedLinkColor();
495     void resetActiveLinkColor();
496     
497     MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const IntPoint&, const PlatformMouseEvent&);
498
499     virtual bool childTypeAllowed(NodeType);
500     virtual PassRefPtr<Node> cloneNode(bool deep);
501
502     virtual bool canReplaceChild(Node* newChild, Node* oldChild);
503     
504     StyleSheetList* styleSheets();
505
506     /* Newly proposed CSS3 mechanism for selecting alternate
507        stylesheets using the DOM. May be subject to change as
508        spec matures. - dwh
509     */
510     String preferredStylesheetSet() const;
511     String selectedStylesheetSet() const;
512     void setSelectedStylesheetSet(const String&);
513
514     bool setFocusedNode(PassRefPtr<Node>);
515     Node* focusedNode() const { return m_focusedNode.get(); }
516
517     // The m_ignoreAutofocus flag specifies whether or not the document has been changed by the user enough 
518     // for WebCore to ignore the autofocus attribute on any form controls
519     bool ignoreAutofocus() const { return m_ignoreAutofocus; };
520     void setIgnoreAutofocus(bool shouldIgnore = true) { m_ignoreAutofocus = shouldIgnore; };
521
522     void setHoverNode(PassRefPtr<Node>);
523     Node* hoverNode() const { return m_hoverNode.get(); }
524
525     void setActiveNode(PassRefPtr<Node>);
526     Node* activeNode() const { return m_activeNode.get(); }
527
528     void focusedNodeRemoved();
529     void removeFocusedNodeOfSubtree(Node*, bool amongChildrenOnly = false);
530     void hoveredNodeDetached(Node*);
531     void activeChainNodeDetached(Node*);
532
533     // Updates for :target (CSS3 selector).
534     void setCSSTarget(Element*);
535     Element* cssTarget() const { return m_cssTarget; }
536     
537     void setDocumentChanged(bool);
538
539     void attachNodeIterator(NodeIterator*);
540     void detachNodeIterator(NodeIterator*);
541
542     void attachRange(Range*);
543     void detachRange(Range*);
544
545     void nodeChildrenChanged(ContainerNode*);
546     void nodeWillBeRemoved(Node*);
547
548     void textInserted(Node*, unsigned offset, unsigned length);
549     void textRemoved(Node*, unsigned offset, unsigned length);
550     void textNodesMerged(Text* oldNode, unsigned offset);
551     void textNodeSplit(Text* oldNode);
552
553     DOMWindow* defaultView() const { return domWindow(); } 
554     DOMWindow* domWindow() const;
555
556     PassRefPtr<Event> createEvent(const String& eventType, ExceptionCode&);
557
558     // keep track of what types of event listeners are registered, so we don't
559     // dispatch events unnecessarily
560     enum ListenerType {
561         DOMSUBTREEMODIFIED_LISTENER          = 0x01,
562         DOMNODEINSERTED_LISTENER             = 0x02,
563         DOMNODEREMOVED_LISTENER              = 0x04,
564         DOMNODEREMOVEDFROMDOCUMENT_LISTENER  = 0x08,
565         DOMNODEINSERTEDINTODOCUMENT_LISTENER = 0x10,
566         DOMATTRMODIFIED_LISTENER             = 0x20,
567         DOMCHARACTERDATAMODIFIED_LISTENER    = 0x40,
568         OVERFLOWCHANGED_LISTENER             = 0x80,
569         ANIMATIONEND_LISTENER                = 0x100,
570         ANIMATIONSTART_LISTENER              = 0x200,
571         ANIMATIONITERATION_LISTENER          = 0x400,
572         TRANSITIONEND_LISTENER               = 0x800
573     };
574
575     bool hasListenerType(ListenerType listenerType) const { return (m_listenerTypes & listenerType); }
576     void addListenerType(ListenerType listenerType) { m_listenerTypes = m_listenerTypes | listenerType; }
577     void addListenerTypeIfNeeded(const AtomicString& eventType);
578
579     CSSStyleDeclaration* getOverrideStyle(Element*, const String& pseudoElt);
580
581     void handleWindowEvent(Event*, bool useCapture);
582     void setWindowInlineEventListenerForType(const AtomicString& eventType, PassRefPtr<EventListener>);
583     EventListener* windowInlineEventListenerForType(const AtomicString& eventType);
584     void removeWindowInlineEventListenerForType(const AtomicString& eventType);
585
586     void setWindowInlineEventListenerForTypeAndAttribute(const AtomicString& eventType, Attribute*);
587
588     void addWindowEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
589     void removeWindowEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
590     bool hasWindowEventListener(const AtomicString& eventType);
591     
592     void addPendingFrameUnloadEventCount();
593     void removePendingFrameUnloadEventCount();
594     void addPendingFrameBeforeUnloadEventCount();
595     void removePendingFrameBeforeUnloadEventCount();
596
597     PassRefPtr<EventListener> createEventListener(const String& functionName, const String& code, Node*);
598
599     /**
600      * Searches through the document, starting from fromNode, for the next selectable element that comes after fromNode.
601      * The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab indexes
602      * first (from lowest to highest), and then elements without tab indexes (in document order).
603      *
604      * @param fromNode The node from which to start searching. The node after this will be focused. May be null.
605      *
606      * @return The focus node that comes after fromNode
607      *
608      * See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
609      */
610     Node* nextFocusableNode(Node* start, KeyboardEvent*);
611
612     /**
613      * Searches through the document, starting from fromNode, for the previous selectable element (that comes _before_)
614      * fromNode. The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab
615      * indexes first (from lowest to highest), and then elements without tab indexes (in document order).
616      *
617      * @param fromNode The node from which to start searching. The node before this will be focused. May be null.
618      *
619      * @return The focus node that comes before fromNode
620      *
621      * See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
622      */
623     Node* previousFocusableNode(Node* start, KeyboardEvent*);
624
625     int nodeAbsIndex(Node*);
626     Node* nodeWithAbsIndex(int absIndex);
627
628     /**
629      * Handles a HTTP header equivalent set by a meta tag using <meta http-equiv="..." content="...">. This is called
630      * when a meta tag is encountered during document parsing, and also when a script dynamically changes or adds a meta
631      * tag. This enables scripts to use meta tags to perform refreshes and set expiry dates in addition to them being
632      * specified in a HTML file.
633      *
634      * @param equiv The http header name (value of the meta tag's "equiv" attribute)
635      * @param content The header value (value of the meta tag's "content" attribute)
636      */
637     void processHttpEquiv(const String& equiv, const String& content);
638     
639     void dispatchImageLoadEventSoon(ImageLoader*);
640     void dispatchImageLoadEventsNow();
641     void removeImage(ImageLoader*);
642     
643     // Returns the owning element in the parent document.
644     // Returns 0 if this is the top level document.
645     Element* ownerElement() const;
646
647     String title() const { return m_title; }
648     void setTitle(const String&, Element* titleElement = 0);
649     void removeTitle(Element* titleElement);
650
651     String cookie() const;
652     void setCookie(const String&);
653
654     String referrer() const;
655
656     String domain() const;
657     void setDomain(const String& newDomain);
658
659     String lastModified() const;
660
661     const KURL& cookieURL() const { return m_cookieURL; }
662
663     const KURL& policyBaseURL() const { return m_policyBaseURL; }
664     void setPolicyBaseURL(const KURL& url) { m_policyBaseURL = url; }
665     
666     // The following implements the rule from HTML 4 for what valid names are.
667     // To get this right for all the XML cases, we probably have to improve this or move it
668     // and make it sensitive to the type of document.
669     static bool isValidName(const String&);
670
671     // The following breaks a qualified name into a prefix and a local name.
672     // It also does a validity check, and returns false if the qualified name
673     // is invalid.  It also sets ExceptionCode when name is invalid.
674     static bool parseQualifiedName(const String& qualifiedName, String& prefix, String& localName, ExceptionCode&);
675     
676     // Checks to make sure prefix and namespace do not conflict (per DOM Core 3)
677     static bool hasPrefixNamespaceMismatch(const QualifiedName&);
678     
679     void addElementById(const AtomicString& elementId, Element *element);
680     void removeElementById(const AtomicString& elementId, Element *element);
681
682     void addImageMap(HTMLMapElement*);
683     void removeImageMap(HTMLMapElement*);
684     HTMLMapElement* getImageMap(const String& url) const;
685
686     HTMLElement* body() const;
687     void setBody(PassRefPtr<HTMLElement>, ExceptionCode&);
688
689     HTMLHeadElement* head();
690
691     bool execCommand(const String& command, bool userInterface = false, const String& value = String());
692     bool queryCommandEnabled(const String& command);
693     bool queryCommandIndeterm(const String& command);
694     bool queryCommandState(const String& command);
695     bool queryCommandSupported(const String& command);
696     String queryCommandValue(const String& command);
697     
698     void addMarker(Range*, DocumentMarker::MarkerType, String description = String());
699     void addMarker(Node*, DocumentMarker);
700     void copyMarkers(Node *srcNode, unsigned startOffset, int length, Node *dstNode, int delta, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
701     void removeMarkers(Range*, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
702     void removeMarkers(Node*, unsigned startOffset, int length, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
703     void removeMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
704     void removeMarkers(Node*);
705     void repaintMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
706     void setRenderedRectForMarker(Node*, DocumentMarker, const IntRect&);
707     void invalidateRenderedRectsForMarkersInRect(const IntRect&);
708     void shiftMarkers(Node*, unsigned startOffset, int delta, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
709
710     DocumentMarker* markerContainingPoint(const IntPoint&, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
711     Vector<DocumentMarker> markersForNode(Node*);
712     Vector<IntRect> renderedRectsForMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
713     
714     // designMode support
715     enum InheritedBool { off = false, on = true, inherit };    
716     void setDesignMode(InheritedBool value);
717     InheritedBool getDesignMode() const;
718     bool inDesignMode() const;
719
720     Document* parentDocument() const;
721     Document* topDocument() const;
722
723     int docID() const { return m_docID; }
724
725 #if ENABLE(XSLT)
726     void applyXSLTransform(ProcessingInstruction* pi);
727     void setTransformSource(void* doc);
728     const void* transformSource() { return m_transformSource; }
729     PassRefPtr<Document> transformSourceDocument() { return m_transformSourceDocument; }
730     void setTransformSourceDocument(Document* doc) { m_transformSourceDocument = doc; }
731 #endif
732
733 #if ENABLE(XBL)
734     // XBL methods
735     XBLBindingManager* bindingManager() const { return m_bindingManager; }
736 #endif
737
738     void incDOMTreeVersion() { ++m_domtree_version; }
739     unsigned domTreeVersion() const { return m_domtree_version; }
740
741     void setDocType(PassRefPtr<DocumentType>);
742
743     virtual void finishedParsing();
744
745 #if ENABLE(XPATH)
746     // XPathEvaluator methods
747     PassRefPtr<XPathExpression> createExpression(const String& expression,
748                                                  XPathNSResolver* resolver,
749                                                  ExceptionCode& ec);
750     PassRefPtr<XPathNSResolver> createNSResolver(Node *nodeResolver);
751     PassRefPtr<XPathResult> evaluate(const String& expression,
752                                      Node* contextNode,
753                                      XPathNSResolver* resolver,
754                                      unsigned short type,
755                                      XPathResult* result,
756                                      ExceptionCode& ec);
757 #endif // ENABLE(XPATH)
758     
759     enum PendingSheetLayout { NoLayoutWithPendingSheets, DidLayoutWithPendingSheets, IgnoreLayoutWithPendingSheets };
760
761     bool didLayoutWithPendingStylesheets() const { return m_pendingSheetLayout == DidLayoutWithPendingSheets; }
762     
763     void setHasNodesWithPlaceholderStyle() { m_hasNodesWithPlaceholderStyle = true; }
764
765     const String& iconURL() const { return m_iconURL; }
766     void setIconURL(const String& iconURL, const String& type);
767
768     void setUseSecureKeyboardEntryWhenActive(bool);
769     bool useSecureKeyboardEntryWhenActive() const;
770
771     void addNodeListCache() { ++m_numNodeListCaches; }
772     void removeNodeListCache() { ASSERT(m_numNodeListCaches > 0); --m_numNodeListCaches; }
773     bool hasNodeListCaches() const { return m_numNodeListCaches; }
774
775     void updateFocusAppearanceSoon();
776     void cancelFocusAppearanceUpdate();
777         
778     // FF method for accessing the selection added for compatability.
779     DOMSelection* getSelection() const;
780     
781     // Extension for manipulating canvas drawing contexts for use in CSS
782     CanvasRenderingContext2D* getCSSCanvasContext(const String& type, const String& name, int width, int height);
783     HTMLCanvasElement* getCSSCanvasElement(const String& name);
784
785     bool isDNSPrefetchEnabled() const { return m_isDNSPrefetchEnabled; }
786     void initDNSPrefetch();
787     void parseDNSPrefetchControlHeader(const String&);
788
789     virtual void reportException(const String& errorMessage, int lineNumber, const String& sourceURL);
790     virtual void addMessage(MessageDestination, MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL);
791     virtual void resourceRetrievedByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString);
792     virtual void postTask(PassRefPtr<Task>); // Executes the task on context's thread asynchronously.
793
794 protected:
795     Document(Frame*, bool isXHTML);
796
797 private:
798     virtual void refScriptExecutionContext() { ref(); }
799     virtual void derefScriptExecutionContext() { deref(); }
800
801     virtual const KURL& virtualURL() const; // Same as url(), but needed for ScriptExecutionContext to implement it without a performance loss for direct calls.
802     virtual KURL virtualCompleteURL(const String&) const; // Same as completeURL() for the same reason as above.
803
804     CSSStyleSelector* m_styleSelector;
805     bool m_didCalculateStyleSelector;
806
807     Frame* m_frame;
808     DocLoader* m_docLoader;
809     Tokenizer* m_tokenizer;
810     bool m_wellFormed;
811
812     // Document URLs.
813     KURL m_url;  // Document.URL: The URL from which this document was retrieved.
814     KURL m_baseURL;  // Node.baseURI: The URL to use when resolving relative URLs.
815     KURL m_baseElementURL;  // The URL set by the <base> element.
816     KURL m_cookieURL;  // The URL to use for cookie access.
817     KURL m_policyBaseURL;  // The policy URL for third-party cookie blocking.
818
819     // Document.documentURI:
820     // Although URL-like, Document.documentURI can actually be set to any
821     // string by content.  Document.documentURI affects m_baseURL unless the
822     // document contains a <base> element, in which case the <base> element
823     // takes precedence.
824     String m_documentURI;
825
826     String m_baseTarget;
827
828     RefPtr<DocumentType> m_docType;
829     mutable RefPtr<DOMImplementation> m_implementation;
830
831     RefPtr<StyleSheet> m_sheet;
832 #if FRAME_LOADS_USER_STYLESHEET
833     String m_usersheet;
834 #endif
835
836     // Track the number of currently loading top-level stylesheets.  Sheets
837     // loaded using the @import directive are not included in this count.
838     // We use this count of pending sheets to detect when we can begin attaching
839     // elements.
840     int m_pendingStylesheets;
841
842     // But sometimes you need to ignore pending stylesheet count to
843     // force an immediate layout when requested by JS.
844     bool m_ignorePendingStylesheets;
845
846     // If we do ignore the pending stylesheet count, then we need to add a boolean
847     // to track that this happened so that we can do a full repaint when the stylesheets
848     // do eventually load.
849     PendingSheetLayout m_pendingSheetLayout;
850     
851     bool m_hasNodesWithPlaceholderStyle;
852
853     RefPtr<CSSStyleSheet> m_elemSheet;
854     RefPtr<CSSStyleSheet> m_mappedElementSheet;
855
856     bool m_printing;
857     
858     bool m_ignoreAutofocus;
859
860     ParseMode m_parseMode;
861
862     Color m_textColor;
863
864     RefPtr<Node> m_focusedNode;
865     RefPtr<Node> m_hoverNode;
866     RefPtr<Node> m_activeNode;
867     mutable RefPtr<Element> m_documentElement;
868
869     unsigned m_domtree_version;
870     
871     HashSet<NodeIterator*> m_nodeIterators;
872     HashSet<Range*> m_ranges;
873
874     unsigned short m_listenerTypes;
875
876     RefPtr<StyleSheetList> m_styleSheets; // All of the stylesheets that are currently in effect for our media type and stylesheet set.
877     ListHashSet<Node*> m_styleSheetCandidateNodes; // All of the nodes that could potentially provide stylesheets to the document (<link>, <style>, <?xml-stylesheet>)
878
879     RegisteredEventListenerVector m_windowEventListeners;
880
881     typedef HashMap<FormElementKey, Vector<String>, FormElementKeyHash, FormElementKeyHashTraits> FormElementStateMap;
882     ListHashSet<FormControlElementWithState*> m_formElementsWithState;
883     FormElementStateMap m_stateForNewFormElements;
884     
885     Color m_linkColor;
886     Color m_visitedLinkColor;
887     Color m_activeLinkColor;
888
889     String m_preferredStylesheetSet;
890     String m_selectedStylesheetSet;
891
892     bool m_loadingSheet;
893     bool visuallyOrdered;
894     bool m_bParsing;
895     bool m_docChanged;
896     bool m_inStyleRecalc;
897     bool m_closeAfterStyleRecalc;
898     bool m_usesDescendantRules;
899     bool m_usesSiblingRules;
900     bool m_usesFirstLineRules;
901     bool m_usesFirstLetterRules;
902     bool m_usesBeforeAfterRules;
903     bool m_gotoAnchorNeededAfterStylesheetsLoad;
904     bool m_isDNSPrefetchEnabled;
905     bool m_haveExplicitlyDisabledDNSPrefetch;
906     bool m_frameElementsShouldIgnoreScrolling;
907
908     String m_title;
909     bool m_titleSetExplicitly;
910     RefPtr<Element> m_titleElement;
911     
912     RenderArena* m_renderArena;
913
914     typedef std::pair<Vector<DocumentMarker>, Vector<IntRect> > MarkerMapVectorPair;
915     typedef HashMap<RefPtr<Node>, MarkerMapVectorPair*> MarkerMap;
916     MarkerMap m_markers;
917
918     mutable AXObjectCache* m_axObjectCache;
919     
920     Vector<ImageLoader*> m_imageLoadEventDispatchSoonList;
921     Vector<ImageLoader*> m_imageLoadEventDispatchingList;
922     Timer<Document> m_imageLoadEventTimer;
923
924     Timer<Document> m_updateFocusAppearanceTimer;
925
926     Element* m_cssTarget;
927     
928     bool m_processingLoadEvent;
929     double m_startTime;
930     bool m_overMinimumLayoutThreshold;
931     
932 #if ENABLE(XSLT)
933     void* m_transformSource;
934     RefPtr<Document> m_transformSourceDocument;
935 #endif
936
937 #if ENABLE(XBL)
938     XBLBindingManager* m_bindingManager; // The access point through which documents and elements communicate with XBL.
939 #endif
940     
941     typedef HashMap<AtomicStringImpl*, HTMLMapElement*> ImageMapsByName;
942     ImageMapsByName m_imageMapsByName;
943
944     HashSet<Node*> m_disconnectedNodesWithEventListeners;
945
946     int m_docID; // A unique document identifier used for things like document-specific mapped attributes.
947
948     String m_xmlEncoding;
949     String m_xmlVersion;
950     bool m_xmlStandalone;
951
952     String m_contentLanguage;
953
954 public:
955     bool inPageCache() const { return m_inPageCache; }
956     void setInPageCache(bool flag);
957     
958     // Elements can register themselves for the "documentWillBecomeInactive()" and  
959     // "documentDidBecomeActive()" callbacks
960     void registerForDocumentActivationCallbacks(Element*);
961     void unregisterForDocumentActivationCallbacks(Element*);
962     void documentWillBecomeInactive();
963     void documentDidBecomeActive();
964
965     void registerForMediaVolumeCallbacks(Element*);
966     void unregisterForMediaVolumeCallbacks(Element*);
967     void mediaVolumeDidChange();
968
969     void setShouldCreateRenderers(bool);
970     bool shouldCreateRenderers();
971     
972     void setDecoder(PassRefPtr<TextResourceDecoder>);
973     TextResourceDecoder* decoder() const { return m_decoder.get(); }
974
975     String displayStringModifiedByEncoding(const String&) const;
976     PassRefPtr<StringImpl> displayStringModifiedByEncoding(PassRefPtr<StringImpl>) const;
977     void displayBufferModifiedByEncoding(UChar* buffer, unsigned len) const;
978
979     // Quirk for the benefit of Apple's Dictionary application.
980     void setFrameElementsShouldIgnoreScrolling(bool ignore) { m_frameElementsShouldIgnoreScrolling = ignore; }
981     bool frameElementsShouldIgnoreScrolling() const { return m_frameElementsShouldIgnoreScrolling; }
982
983 #if ENABLE(DASHBOARD_SUPPORT)
984     void setDashboardRegionsDirty(bool f) { m_dashboardRegionsDirty = f; }
985     bool dashboardRegionsDirty() const { return m_dashboardRegionsDirty; }
986     bool hasDashboardRegions () const { return m_hasDashboardRegions; }
987     void setHasDashboardRegions (bool f) { m_hasDashboardRegions = f; }
988     const Vector<DashboardRegionValue>& dashboardRegions() const;
989     void setDashboardRegions(const Vector<DashboardRegionValue>&);
990 #endif
991
992     void removeAllEventListenersFromAllNodes();
993
994     void registerDisconnectedNodeWithEventListeners(Node*);
995     void unregisterDisconnectedNodeWithEventListeners(Node*);
996     
997     HTMLFormElement::CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; }
998     
999 #if ENABLE(SVG)
1000     const SVGDocumentExtensions* svgExtensions();
1001     SVGDocumentExtensions* accessSVGExtensions();
1002 #endif
1003
1004     void initSecurityContext();
1005
1006     // Explicitly override the security origin for this document.
1007     // Note: It is dangerous to change the security origin of a document
1008     //       that already contains content.
1009     void setSecurityOrigin(SecurityOrigin*);
1010
1011     bool processingLoadEvent() const { return m_processingLoadEvent; }
1012
1013 #if ENABLE(DATABASE)
1014     void addOpenDatabase(Database*);
1015     void removeOpenDatabase(Database*);
1016     DatabaseThread* databaseThread();   // Creates the thread as needed, but not if it has been already terminated.
1017     void setHasOpenDatabases() { m_hasOpenDatabases = true; }
1018     bool hasOpenDatabases() { return m_hasOpenDatabases; }
1019     void stopDatabases();
1020 #endif
1021     
1022     void setUsingGeolocation(bool f) { m_usingGeolocation = f; }
1023     bool usingGeolocation() const { return m_usingGeolocation; };
1024
1025 #if ENABLE(WML)
1026     void resetWMLPageState();
1027 #endif
1028
1029 protected:
1030     void clearXMLVersion() { m_xmlVersion = String(); }
1031
1032 private:
1033     void updateTitle();
1034     void removeAllDisconnectedNodeEventListeners();
1035     void imageLoadEventTimerFired(Timer<Document>*);
1036     void updateFocusAppearanceTimerFired(Timer<Document>*);
1037     void updateBaseURL();
1038
1039     void cacheDocumentElement() const;
1040
1041     RenderObject* m_savedRenderer;
1042     int m_secureForms;
1043     
1044     RefPtr<TextResourceDecoder> m_decoder;
1045
1046     // We maintain the invariant that m_duplicateIds is the count of all elements with a given ID
1047     // excluding the one referenced in m_elementsById, if any. This means it one less than the total count
1048     // when the first node with a given ID is cached, otherwise the same as the total count.
1049     mutable HashMap<AtomicStringImpl*, Element*> m_elementsById;
1050     mutable HashCountedSet<AtomicStringImpl*> m_duplicateIds;
1051     
1052     mutable HashMap<StringImpl*, Element*, CaseFoldingHash> m_elementsByAccessKey;
1053     
1054     InheritedBool m_designMode;
1055     
1056     int m_selfOnlyRefCount;
1057
1058     HTMLFormElement::CheckedRadioButtons m_checkedRadioButtons;
1059
1060     typedef HashMap<AtomicStringImpl*, HTMLCollection::CollectionInfo*> NamedCollectionMap;
1061     HTMLCollection::CollectionInfo m_collectionInfo[HTMLCollection::NumUnnamedDocumentCachedTypes];
1062     NamedCollectionMap m_nameCollectionInfo[HTMLCollection::NumNamedDocumentCachedTypes];
1063
1064 #if ENABLE(XPATH)
1065     RefPtr<XPathEvaluator> m_xpathEvaluator;
1066 #endif
1067     
1068 #if ENABLE(SVG)
1069     OwnPtr<SVGDocumentExtensions> m_svgExtensions;
1070 #endif
1071     
1072 #if ENABLE(DASHBOARD_SUPPORT)
1073     Vector<DashboardRegionValue> m_dashboardRegions;
1074     bool m_hasDashboardRegions;
1075     bool m_dashboardRegionsDirty;
1076 #endif
1077
1078     HashMap<String, RefPtr<HTMLCanvasElement> > m_cssCanvasElements;
1079
1080     mutable bool m_accessKeyMapValid;
1081     bool m_createRenderers;
1082     bool m_inPageCache;
1083     String m_iconURL;
1084     
1085     HashSet<Element*> m_documentActivationCallbackElements;
1086     HashSet<Element*> m_mediaVolumeCallbackElements;
1087
1088     bool m_useSecureKeyboardEntryWhenActive;
1089
1090     bool m_isXHTML;
1091
1092     unsigned m_numNodeListCaches;
1093
1094 public:
1095     typedef HashMap<WebCore::Node*, JSNode*> JSWrapperCache;
1096     JSWrapperCache& wrapperCache() { return m_wrapperCache; }
1097 private:
1098     JSWrapperCache m_wrapperCache;
1099
1100 #if ENABLE(DATABASE)
1101     RefPtr<DatabaseThread> m_databaseThread;
1102     bool m_hasOpenDatabases;    // This never changes back to false, even as the database thread is closed.
1103     typedef HashSet<Database*> DatabaseSet;
1104     OwnPtr<DatabaseSet> m_openDatabaseSet;
1105 #endif
1106     
1107     bool m_usingGeolocation;
1108 };
1109
1110 inline bool Document::hasElementWithId(AtomicStringImpl* id) const
1111 {
1112     ASSERT(id);
1113     return m_elementsById.contains(id) || m_duplicateIds.contains(id);
1114 }
1115     
1116 inline bool Node::isDocumentNode() const
1117 {
1118     return this == m_document.get();
1119 }
1120
1121 } // namespace WebCore
1122
1123 #endif // Document_h