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