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