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