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.
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.
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.
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.
30 #include "DeprecatedPtrList.h"
31 #include "DocumentMarker.h"
32 #include "HTMLCollection.h"
33 #include "HTMLFormElement.h"
35 #include "ScriptExecutionContext.h"
36 #include "StringHash.h"
38 #include <wtf/HashCountedSet.h>
39 #include <wtf/ListHashSet.h>
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
47 #define FRAME_LOADS_USER_STYLESHEET 0
56 class CachedCSSStyleSheet
;
57 class CanvasRenderingContext2D
;
59 class CSSStyleDeclaration
;
60 class CSSStyleSelector
;
64 class DOMImplementation
;
69 class DocumentFragment
;
73 class EntityReference
;
78 class HTMLCanvasElement
;
81 class HTMLFormControlElementWithState
;
82 class HTMLFormElement
;
83 class HTMLHeadElement
;
84 class HTMLInputElement
;
89 class MouseEventWithHitTestResults
;
93 class PlatformMouseEvent
;
94 class ProcessingInstruction
;
96 class RegisteredEventListener
;
101 class StyleSheetList
;
103 class TextResourceDecoder
;
106 class XMLHttpRequest
;
109 class SVGDocumentExtensions
;
113 class XBLBindingManager
;
117 class XPathEvaluator
;
118 class XPathExpression
;
119 class XPathNSResolver
;
123 #if ENABLE(DASHBOARD_SUPPORT)
124 struct DashboardRegionValue
;
126 struct HitTestRequest
;
128 typedef int ExceptionCode
;
130 class FormElementKey
{
132 FormElementKey(AtomicStringImpl
* = 0, AtomicStringImpl
* = 0);
134 FormElementKey(const FormElementKey
&);
135 FormElementKey
& operator=(const FormElementKey
&);
137 AtomicStringImpl
* name() const { return m_name
; }
138 AtomicStringImpl
* type() const { return m_type
; }
140 // Hash table deleted values, which are only constructed and never copied or destroyed.
141 FormElementKey(WTF::HashTableDeletedValueType
) : m_name(hashTableDeletedValue()) { }
142 bool isHashTableDeletedValue() const { return m_name
== hashTableDeletedValue(); }
148 static AtomicStringImpl
* hashTableDeletedValue() { return reinterpret_cast<AtomicStringImpl
*>(-1); }
150 AtomicStringImpl
* m_name
;
151 AtomicStringImpl
* m_type
;
154 inline bool operator==(const FormElementKey
& a
, const FormElementKey
& b
)
156 return a
.name() == b
.name() && a
.type() == b
.type();
159 struct FormElementKeyHash
{
160 static unsigned hash(const FormElementKey
&);
161 static bool equal(const FormElementKey
& a
, const FormElementKey
& b
) { return a
== b
; }
162 static const bool safeToCompareToEmptyOrDeleted
= true;
165 struct FormElementKeyHashTraits
: WTF::GenericHashTraits
<FormElementKey
> {
166 static void constructDeletedValue(FormElementKey
& slot
) { new (&slot
) FormElementKey(WTF::HashTableDeletedValue
); }
167 static bool isDeletedValue(const FormElementKey
& value
) { return value
.isHashTableDeletedValue(); }
170 class Document
: public ContainerNode
, public ScriptExecutionContext
{
172 static PassRefPtr
<Document
> create(Frame
* frame
)
174 return new Document(frame
, false);
176 static PassRefPtr
<Document
> createXHTML(Frame
* frame
)
178 return new Document(frame
, true);
182 virtual bool isDocument() const { return true; }
184 using ContainerNode::ref
;
185 using ContainerNode::deref
;
186 virtual void removedLastRef();
188 // Nodes belonging to this document hold "self-only" references -
189 // these are enough to keep the document from being destroyed, but
190 // not enough to keep it from removing its children. This allows a
191 // node that outlives its document to still have a valid document
192 // pointer without introducing reference cycles
196 ASSERT(!m_deletionHasBegun
);
197 ++m_selfOnlyRefCount
;
201 ASSERT(!m_deletionHasBegun
);
202 --m_selfOnlyRefCount
;
203 if (!m_selfOnlyRefCount
&& !refCount()) {
205 m_deletionHasBegun
= true;
211 // DOM methods & attributes for Document
213 DocumentType
* doctype() const { return m_docType
.get(); }
215 DOMImplementation
* implementation() const;
216 virtual void childrenChanged(bool changedByParser
= false, Node
* beforeChange
= 0, Node
* afterChange
= 0, int childCountDelta
= 0);
217 Element
* documentElement() const;
218 virtual PassRefPtr
<Element
> createElement(const AtomicString
& tagName
, ExceptionCode
&);
219 PassRefPtr
<DocumentFragment
> createDocumentFragment ();
220 PassRefPtr
<Text
> createTextNode(const String
& data
);
221 PassRefPtr
<Comment
> createComment(const String
& data
);
222 PassRefPtr
<CDATASection
> createCDATASection(const String
& data
, ExceptionCode
&);
223 PassRefPtr
<ProcessingInstruction
> createProcessingInstruction(const String
& target
, const String
& data
, ExceptionCode
&);
224 PassRefPtr
<Attr
> createAttribute(const String
& name
, ExceptionCode
& ec
) { return createAttributeNS(String(), name
, ec
, true); }
225 PassRefPtr
<Attr
> createAttributeNS(const String
& namespaceURI
, const String
& qualifiedName
, ExceptionCode
&, bool shouldIgnoreNamespaceChecks
= false);
226 PassRefPtr
<EntityReference
> createEntityReference(const String
& name
, ExceptionCode
&);
227 PassRefPtr
<Node
> importNode(Node
* importedNode
, bool deep
, ExceptionCode
&);
228 virtual PassRefPtr
<Element
> createElementNS(const String
& namespaceURI
, const String
& qualifiedName
, ExceptionCode
&);
229 PassRefPtr
<Element
> createElement(const QualifiedName
&, bool createdByParser
, ExceptionCode
& ec
);
230 Element
* getElementById(const AtomicString
&) const;
231 bool hasElementWithId(AtomicStringImpl
* id
) const;
232 bool containsMultipleElementsWithId(const AtomicString
& elementId
) { return m_duplicateIds
.contains(elementId
.impl()); }
234 Element
* elementFromPoint(int x
, int y
) const;
235 String
readyState() const;
236 String
inputEncoding() const;
237 String
defaultCharset() const;
239 String
charset() const { return inputEncoding(); }
240 String
characterSet() const { return inputEncoding(); }
242 void setCharset(const String
&);
244 String
contentLanguage() const { return m_contentLanguage
; }
245 void setContentLanguage(const String
& lang
) { m_contentLanguage
= lang
; }
247 String
xmlEncoding() const { return m_xmlEncoding
; }
248 String
xmlVersion() const { return m_xmlVersion
; }
249 bool xmlStandalone() const { return m_xmlStandalone
; }
251 void setXMLEncoding(const String
& encoding
) { m_xmlEncoding
= encoding
; } // read-only property, only to be set from XMLTokenizer
252 void setXMLVersion(const String
&, ExceptionCode
&);
253 void setXMLStandalone(bool, ExceptionCode
&);
255 String
documentURI() const { return m_documentURI
; }
256 void setDocumentURI(const String
&);
258 virtual KURL
baseURI() const;
260 PassRefPtr
<Node
> adoptNode(PassRefPtr
<Node
> source
, ExceptionCode
&);
262 PassRefPtr
<HTMLCollection
> images();
263 PassRefPtr
<HTMLCollection
> embeds();
264 PassRefPtr
<HTMLCollection
> plugins(); // an alias for embeds() required for the JS DOM bindings.
265 PassRefPtr
<HTMLCollection
> applets();
266 PassRefPtr
<HTMLCollection
> links();
267 PassRefPtr
<HTMLCollection
> forms();
268 PassRefPtr
<HTMLCollection
> anchors();
269 PassRefPtr
<HTMLCollection
> all();
270 PassRefPtr
<HTMLCollection
> objects();
271 PassRefPtr
<HTMLCollection
> scripts();
272 PassRefPtr
<HTMLCollection
> windowNamedItems(const String
& name
);
273 PassRefPtr
<HTMLCollection
> documentNamedItems(const String
& name
);
275 HTMLCollection::CollectionInfo
* collectionInfo(HTMLCollection::Type type
)
277 ASSERT(type
>= HTMLCollection::FirstUnnamedDocumentCachedType
);
278 unsigned index
= type
- HTMLCollection::FirstUnnamedDocumentCachedType
;
279 ASSERT(index
< HTMLCollection::NumUnnamedDocumentCachedTypes
);
280 return &m_collectionInfo
[index
];
283 HTMLCollection::CollectionInfo
* nameCollectionInfo(HTMLCollection::Type
, const AtomicString
& name
);
285 // DOM methods overridden from parent classes
287 virtual String
nodeName() const;
288 virtual NodeType
nodeType() const;
290 // Other methods (not part of DOM)
291 virtual bool isHTMLDocument() const { return false; }
292 virtual bool isImageDocument() const { return false; }
294 virtual bool isSVGDocument() const { return false; }
296 virtual bool isPluginDocument() const { return false; }
297 virtual bool isMediaDocument() const { return false; }
299 CSSStyleSelector
* styleSelector() const { return m_styleSelector
; }
301 Element
* getElementByAccessKey(const String
& key
) const;
304 * Updates the pending sheet count and then calls updateStyleSelector.
306 void removePendingSheet();
309 * This method returns true if all top-level stylesheets have loaded (including
310 * any @imports that they may be loading).
312 bool haveStylesheetsLoaded() const
314 return m_pendingStylesheets
<= 0 || m_ignorePendingStylesheets
315 #if USE(LOW_BANDWIDTH_DISPLAY)
316 || m_inLowBandwidthDisplay
322 * Increments the number of pending sheets. The <link> elements
323 * invoke this to add themselves to the loading list.
325 void addPendingSheet() { m_pendingStylesheets
++; }
327 void addStyleSheetCandidateNode(Node
*, bool createdByParser
);
328 void removeStyleSheetCandidateNode(Node
*);
330 bool gotoAnchorNeededAfterStylesheetsLoad() { return m_gotoAnchorNeededAfterStylesheetsLoad
; }
331 void setGotoAnchorNeededAfterStylesheetsLoad(bool b
) { m_gotoAnchorNeededAfterStylesheetsLoad
= b
; }
334 * Called when one or more stylesheets in the document may have been added, removed or changed.
336 * Creates a new style selector and assign it to this document. This is done by iterating through all nodes in
337 * document (or those before <BODY> in a HTML document), searching for stylesheets. Stylesheets can be contained in
338 * <LINK>, <STYLE> or <BODY> elements, as well as processing instructions (XML documents only). A list is
339 * constructed from these which is used to create the a new style selector which collates all of the stylesheets
340 * found and is used to calculate the derived styles for all rendering objects.
342 void updateStyleSelector();
344 void recalcStyleSelector();
346 bool usesDescendantRules() const { return m_usesDescendantRules
; }
347 void setUsesDescendantRules(bool b
) { m_usesDescendantRules
= b
; }
348 bool usesSiblingRules() const { return m_usesSiblingRules
; }
349 void setUsesSiblingRules(bool b
) { m_usesSiblingRules
= b
; }
350 bool usesFirstLineRules() const { return m_usesFirstLineRules
; }
351 void setUsesFirstLineRules(bool b
) { m_usesFirstLineRules
= b
; }
352 bool usesFirstLetterRules() const { return m_usesFirstLetterRules
; }
353 void setUsesFirstLetterRules(bool b
) { m_usesFirstLetterRules
= b
; }
355 // Machinery for saving and restoring state when you leave and then go back to a page.
356 void registerFormElementWithState(HTMLFormControlElementWithState
* e
) { m_formElementsWithState
.add(e
); }
357 void unregisterFormElementWithState(HTMLFormControlElementWithState
* e
) { m_formElementsWithState
.remove(e
); }
358 Vector
<String
> formElementsState() const;
359 void setStateForNewFormElements(const Vector
<String
>&);
360 bool hasStateForNewFormElements() const;
361 bool takeStateForFormElement(AtomicStringImpl
* name
, AtomicStringImpl
* type
, String
& state
);
363 FrameView
* view() const; // can be NULL
364 Frame
* frame() const { return m_frame
; } // can be NULL
365 Page
* page() const; // can be NULL
366 Settings
* settings() const; // can be NULL
368 PassRefPtr
<Range
> createRange();
370 PassRefPtr
<NodeIterator
> createNodeIterator(Node
* root
, unsigned whatToShow
,
371 PassRefPtr
<NodeFilter
>, bool expandEntityReferences
, ExceptionCode
&);
373 PassRefPtr
<TreeWalker
> createTreeWalker(Node
* root
, unsigned whatToShow
,
374 PassRefPtr
<NodeFilter
>, bool expandEntityReferences
, ExceptionCode
&);
376 // Special support for editing
377 PassRefPtr
<CSSStyleDeclaration
> createCSSStyleDeclaration();
378 PassRefPtr
<EditingText
> createEditingTextNode(const String
&);
380 virtual void recalcStyle( StyleChange
= NoChange
);
381 virtual void updateRendering();
383 void updateLayoutIgnorePendingStylesheets();
384 static void updateDocumentsRendering();
385 DocLoader
* docLoader() { return m_docLoader
; }
387 virtual void attach();
388 virtual void detach();
390 void clearFramePointer();
392 RenderArena
* renderArena() { return m_renderArena
; }
394 void clearAXObjectCache();
395 AXObjectCache
* axObjectCache() const;
397 // to get visually ordered hebrew and arabic pages right
398 void setVisuallyOrdered();
400 void open(Document
* ownerDocument
= 0);
403 void implicitClose();
404 void cancelParsing();
406 void write(const String
& text
, Document
* ownerDocument
= 0);
407 void writeln(const String
& text
, Document
* ownerDocument
= 0);
408 void finishParsing();
411 bool wellFormed() const { return m_wellFormed
; }
413 const KURL
& url() const { return m_url
; }
414 void setURL(const KURL
&);
416 const KURL
& baseURL() const { return m_baseURL
; }
417 // Setting the BaseElementURL will change the baseURL.
418 void setBaseElementURL(const KURL
&);
420 const String
& baseTarget() const { return m_baseTarget
; }
421 // Setting the BaseElementTarget will change the baseTarget.
422 void setBaseElementTarget(const String
& baseTarget
) { m_baseTarget
= baseTarget
; }
424 KURL
completeURL(const String
&) const;
426 unsigned visitedLinkHash(const AtomicString
& attributeURL
) const;
428 // from cachedObjectClient
429 virtual void setCSSStyleSheet(const String
& url
, const String
& charset
, const CachedCSSStyleSheet
*);
431 #if FRAME_LOADS_USER_STYLESHEET
432 void setUserStyleSheet(const String
& sheet
);
435 String
userStyleSheet() const;
437 CSSStyleSheet
* elementSheet();
438 CSSStyleSheet
* mappedElementSheet();
439 virtual Tokenizer
* createTokenizer();
440 Tokenizer
* tokenizer() { return m_tokenizer
; }
442 bool printing() const { return m_printing
; }
443 void setPrinting(bool p
) { m_printing
= p
; }
445 enum ParseMode
{ Compat
, AlmostStrict
, Strict
};
448 virtual void determineParseMode() {}
451 void setParseMode(ParseMode m
) { m_parseMode
= m
; }
452 ParseMode
parseMode() const { return m_parseMode
; }
454 bool inCompatMode() const { return m_parseMode
== Compat
; }
455 bool inAlmostStrictMode() const { return m_parseMode
== AlmostStrict
; }
456 bool inStrictMode() const { return m_parseMode
== Strict
; }
458 void setParsing(bool);
459 bool parsing() const { return m_bParsing
; }
460 int minimumLayoutDelay();
461 bool shouldScheduleLayout();
462 int elapsedTime() const;
464 void setTextColor(const Color
& color
) { m_textColor
= color
; }
465 Color
textColor() const { return m_textColor
; }
467 const Color
& linkColor() const { return m_linkColor
; }
468 const Color
& visitedLinkColor() const { return m_visitedLinkColor
; }
469 const Color
& activeLinkColor() const { return m_activeLinkColor
; }
470 void setLinkColor(const Color
& c
) { m_linkColor
= c
; }
471 void setVisitedLinkColor(const Color
& c
) { m_visitedLinkColor
= c
; }
472 void setActiveLinkColor(const Color
& c
) { m_activeLinkColor
= c
; }
473 void resetLinkColor();
474 void resetVisitedLinkColor();
475 void resetActiveLinkColor();
477 MouseEventWithHitTestResults
prepareMouseEvent(const HitTestRequest
&, const IntPoint
&, const PlatformMouseEvent
&);
479 virtual bool childTypeAllowed(NodeType
);
480 virtual PassRefPtr
<Node
> cloneNode(bool deep
);
482 virtual bool canReplaceChild(Node
* newChild
, Node
* oldChild
);
484 StyleSheetList
* styleSheets();
486 /* Newly proposed CSS3 mechanism for selecting alternate
487 stylesheets using the DOM. May be subject to change as
490 String
preferredStylesheetSet() const;
491 String
selectedStylesheetSet() const;
492 void setSelectedStylesheetSet(const String
&);
494 bool setFocusedNode(PassRefPtr
<Node
>);
495 Node
* focusedNode() const { return m_focusedNode
.get(); }
497 // The m_ignoreAutofocus flag specifies whether or not the document has been changed by the user enough
498 // for WebCore to ignore the autofocus attribute on any form controls
499 bool ignoreAutofocus() const { return m_ignoreAutofocus
; };
500 void setIgnoreAutofocus(bool shouldIgnore
= true) { m_ignoreAutofocus
= shouldIgnore
; };
502 void setHoverNode(PassRefPtr
<Node
>);
503 Node
* hoverNode() const { return m_hoverNode
.get(); }
505 void setActiveNode(PassRefPtr
<Node
>);
506 Node
* activeNode() const { return m_activeNode
.get(); }
508 void focusedNodeRemoved();
509 void removeFocusedNodeOfSubtree(Node
*, bool amongChildrenOnly
= false);
510 void hoveredNodeDetached(Node
*);
511 void activeChainNodeDetached(Node
*);
513 // Updates for :target (CSS3 selector).
514 void setCSSTarget(Node
*);
515 Node
* getCSSTarget() const;
517 void setDocumentChanged(bool);
519 void attachNodeIterator(NodeIterator
*);
520 void detachNodeIterator(NodeIterator
*);
522 void attachRange(Range
*);
523 void detachRange(Range
*);
525 void nodeChildrenChanged(ContainerNode
*);
526 void nodeWillBeRemoved(Node
*);
528 void textInserted(Node
*, unsigned offset
, unsigned length
);
529 void textRemoved(Node
*, unsigned offset
, unsigned length
);
530 void textNodesMerged(Text
* oldNode
, unsigned offset
);
531 void textNodeSplit(Text
* oldNode
);
533 DOMWindow
* defaultView() const { return domWindow(); }
534 DOMWindow
* domWindow() const;
536 PassRefPtr
<Event
> createEvent(const String
& eventType
, ExceptionCode
&);
538 // keep track of what types of event listeners are registered, so we don't
539 // dispatch events unnecessarily
541 DOMSUBTREEMODIFIED_LISTENER
= 0x01,
542 DOMNODEINSERTED_LISTENER
= 0x02,
543 DOMNODEREMOVED_LISTENER
= 0x04,
544 DOMNODEREMOVEDFROMDOCUMENT_LISTENER
= 0x08,
545 DOMNODEINSERTEDINTODOCUMENT_LISTENER
= 0x10,
546 DOMATTRMODIFIED_LISTENER
= 0x20,
547 DOMCHARACTERDATAMODIFIED_LISTENER
= 0x40,
548 OVERFLOWCHANGED_LISTENER
= 0x80,
549 ANIMATIONEND_LISTENER
= 0x100,
550 ANIMATIONSTART_LISTENER
= 0x200,
551 ANIMATIONITERATION_LISTENER
= 0x400,
552 TRANSITIONEND_LISTENER
= 0x800
555 bool hasListenerType(ListenerType listenerType
) const { return (m_listenerTypes
& listenerType
); }
556 void addListenerType(ListenerType listenerType
) { m_listenerTypes
= m_listenerTypes
| listenerType
; }
557 void addListenerTypeIfNeeded(const AtomicString
& eventType
);
559 CSSStyleDeclaration
* getOverrideStyle(Element
*, const String
& pseudoElt
);
561 void handleWindowEvent(Event
*, bool useCapture
);
562 void setWindowInlineEventListenerForType(const AtomicString
& eventType
, PassRefPtr
<EventListener
>);
563 EventListener
* windowInlineEventListenerForType(const AtomicString
& eventType
);
564 void removeWindowInlineEventListenerForType(const AtomicString
& eventType
);
566 void setWindowInlineEventListenerForTypeAndAttribute(const AtomicString
& eventType
, Attribute
*);
568 void addWindowEventListener(const AtomicString
& eventType
, PassRefPtr
<EventListener
>, bool useCapture
);
569 void removeWindowEventListener(const AtomicString
& eventType
, EventListener
*, bool useCapture
);
570 bool hasWindowEventListener(const AtomicString
& eventType
);
572 void addPendingFrameUnloadEventCount();
573 void removePendingFrameUnloadEventCount();
574 void addPendingFrameBeforeUnloadEventCount();
575 void removePendingFrameBeforeUnloadEventCount();
577 PassRefPtr
<EventListener
> createEventListener(const String
& functionName
, const String
& code
, Node
*);
580 * Searches through the document, starting from fromNode, for the next selectable element that comes after fromNode.
581 * The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab indexes
582 * first (from lowest to highest), and then elements without tab indexes (in document order).
584 * @param fromNode The node from which to start searching. The node after this will be focused. May be null.
586 * @return The focus node that comes after fromNode
588 * See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
590 Node
* nextFocusableNode(Node
* start
, KeyboardEvent
*);
593 * Searches through the document, starting from fromNode, for the previous selectable element (that comes _before_)
594 * fromNode. The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab
595 * indexes first (from lowest to highest), and then elements without tab indexes (in document order).
597 * @param fromNode The node from which to start searching. The node before this will be focused. May be null.
599 * @return The focus node that comes before fromNode
601 * See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
603 Node
* previousFocusableNode(Node
* start
, KeyboardEvent
*);
605 int nodeAbsIndex(Node
*);
606 Node
* nodeWithAbsIndex(int absIndex
);
609 * Handles a HTTP header equivalent set by a meta tag using <meta http-equiv="..." content="...">. This is called
610 * when a meta tag is encountered during document parsing, and also when a script dynamically changes or adds a meta
611 * tag. This enables scripts to use meta tags to perform refreshes and set expiry dates in addition to them being
612 * specified in a HTML file.
614 * @param equiv The http header name (value of the meta tag's "equiv" attribute)
615 * @param content The header value (value of the meta tag's "content" attribute)
617 void processHttpEquiv(const String
& equiv
, const String
& content
);
619 void dispatchImageLoadEventSoon(ImageLoader
*);
620 void dispatchImageLoadEventsNow();
621 void removeImage(ImageLoader
*);
623 // Returns the owning element in the parent document.
624 // Returns 0 if this is the top level document.
625 Element
* ownerElement() const;
627 String
title() const { return m_title
; }
628 void setTitle(const String
&, Element
* titleElement
= 0);
629 void removeTitle(Element
* titleElement
);
631 String
cookie() const;
632 void setCookie(const String
&);
634 String
referrer() const;
636 String
domain() const;
637 void setDomain(const String
& newDomain
);
639 String
lastModified() const;
641 const KURL
& cookieURL() const { return m_cookieURL
; }
643 const KURL
& policyBaseURL() const { return m_policyBaseURL
; }
644 void setPolicyBaseURL(const KURL
& url
) { m_policyBaseURL
= url
; }
646 // The following implements the rule from HTML 4 for what valid names are.
647 // To get this right for all the XML cases, we probably have to improve this or move it
648 // and make it sensitive to the type of document.
649 static bool isValidName(const String
&);
651 // The following breaks a qualified name into a prefix and a local name.
652 // It also does a validity check, and returns false if the qualified name
653 // is invalid. It also sets ExceptionCode when name is invalid.
654 static bool parseQualifiedName(const String
& qualifiedName
, String
& prefix
, String
& localName
, ExceptionCode
&);
656 // Checks to make sure prefix and namespace do not conflict (per DOM Core 3)
657 static bool hasPrefixNamespaceMismatch(const QualifiedName
&);
659 void addElementById(const AtomicString
& elementId
, Element
*element
);
660 void removeElementById(const AtomicString
& elementId
, Element
*element
);
662 void addImageMap(HTMLMapElement
*);
663 void removeImageMap(HTMLMapElement
*);
664 HTMLMapElement
* getImageMap(const String
& url
) const;
667 void setBody(PassRefPtr
<HTMLElement
>, ExceptionCode
&);
669 HTMLHeadElement
* head();
671 bool execCommand(const String
& command
, bool userInterface
= false, const String
& value
= String());
672 bool queryCommandEnabled(const String
& command
);
673 bool queryCommandIndeterm(const String
& command
);
674 bool queryCommandState(const String
& command
);
675 bool queryCommandSupported(const String
& command
);
676 String
queryCommandValue(const String
& command
);
678 void addMarker(Range
*, DocumentMarker::MarkerType
, String description
= String());
679 void addMarker(Node
*, DocumentMarker
);
680 void copyMarkers(Node
*srcNode
, unsigned startOffset
, int length
, Node
*dstNode
, int delta
, DocumentMarker::MarkerType
= DocumentMarker::AllMarkers
);
681 void removeMarkers(Range
*, DocumentMarker::MarkerType
= DocumentMarker::AllMarkers
);
682 void removeMarkers(Node
*, unsigned startOffset
, int length
, DocumentMarker::MarkerType
= DocumentMarker::AllMarkers
);
683 void removeMarkers(DocumentMarker::MarkerType
= DocumentMarker::AllMarkers
);
684 void removeMarkers(Node
*);
685 void repaintMarkers(DocumentMarker::MarkerType
= DocumentMarker::AllMarkers
);
686 void setRenderedRectForMarker(Node
*, DocumentMarker
, const IntRect
&);
687 void invalidateRenderedRectsForMarkersInRect(const IntRect
&);
688 void shiftMarkers(Node
*, unsigned startOffset
, int delta
, DocumentMarker::MarkerType
= DocumentMarker::AllMarkers
);
690 DocumentMarker
* markerContainingPoint(const IntPoint
&, DocumentMarker::MarkerType
= DocumentMarker::AllMarkers
);
691 Vector
<DocumentMarker
> markersForNode(Node
*);
692 Vector
<IntRect
> renderedRectsForMarkers(DocumentMarker::MarkerType
= DocumentMarker::AllMarkers
);
694 // designMode support
695 enum InheritedBool
{ off
= false, on
= true, inherit
};
696 void setDesignMode(InheritedBool value
);
697 InheritedBool
getDesignMode() const;
698 bool inDesignMode() const;
700 Document
* parentDocument() const;
701 Document
* topDocument() const;
703 int docID() const { return m_docID
; }
706 void applyXSLTransform(ProcessingInstruction
* pi
);
707 void setTransformSource(void* doc
);
708 const void* transformSource() { return m_transformSource
; }
709 PassRefPtr
<Document
> transformSourceDocument() { return m_transformSourceDocument
; }
710 void setTransformSourceDocument(Document
* doc
) { m_transformSourceDocument
= doc
; }
715 XBLBindingManager
* bindingManager() const { return m_bindingManager
; }
718 void incDOMTreeVersion() { ++m_domtree_version
; }
719 unsigned domTreeVersion() const { return m_domtree_version
; }
721 void setDocType(PassRefPtr
<DocumentType
>);
723 void finishedParsing();
726 // XPathEvaluator methods
727 PassRefPtr
<XPathExpression
> createExpression(const String
& expression
,
728 XPathNSResolver
* resolver
,
730 PassRefPtr
<XPathNSResolver
> createNSResolver(Node
*nodeResolver
);
731 PassRefPtr
<XPathResult
> evaluate(const String
& expression
,
733 XPathNSResolver
* resolver
,
737 #endif // ENABLE(XPATH)
739 enum PendingSheetLayout
{ NoLayoutWithPendingSheets
, DidLayoutWithPendingSheets
, IgnoreLayoutWithPendingSheets
};
741 bool didLayoutWithPendingStylesheets() const { return m_pendingSheetLayout
== DidLayoutWithPendingSheets
; }
743 void setHasNodesWithPlaceholderStyle() { m_hasNodesWithPlaceholderStyle
= true; }
745 const String
& iconURL() const { return m_iconURL
; }
746 void setIconURL(const String
& iconURL
, const String
& type
);
748 void setUseSecureKeyboardEntryWhenActive(bool);
749 bool useSecureKeyboardEntryWhenActive() const;
751 #if USE(LOW_BANDWIDTH_DISPLAY)
752 void setDocLoader(DocLoader
* loader
) { m_docLoader
= loader
; }
753 bool inLowBandwidthDisplay() const { return m_inLowBandwidthDisplay
; }
754 void setLowBandwidthDisplay(bool lowBandWidth
) { m_inLowBandwidthDisplay
= lowBandWidth
; }
757 void addNodeListCache() { ++m_numNodeListCaches
; }
758 void removeNodeListCache() { ASSERT(m_numNodeListCaches
> 0); --m_numNodeListCaches
; }
759 bool hasNodeListCaches() const { return m_numNodeListCaches
; }
761 void updateFocusAppearanceSoon();
762 void cancelFocusAppearanceUpdate();
764 // FF method for accessing the selection added for compatability.
765 DOMSelection
* getSelection() const;
767 // Extension for manipulating canvas drawing contexts for use in CSS
768 CanvasRenderingContext2D
* getCSSCanvasContext(const String
& type
, const String
& name
, int width
, int height
);
769 HTMLCanvasElement
* getCSSCanvasElement(const String
& name
);
771 bool isDNSPrefetchEnabled() const { return m_isDNSPrefetchEnabled
; }
772 void initDNSPrefetch();
773 void parseDNSPrefetchControlHeader(const String
&);
776 Document(Frame
*, bool isXHTML
);
779 virtual void refScriptExecutionContext() { ref(); }
780 virtual void derefScriptExecutionContext() { deref(); }
782 virtual const KURL
& virtualURL() const; // Same as url(), but needed for ScriptExecutionContext to implement it without a performance loss for direct calls.
784 CSSStyleSelector
* m_styleSelector
;
785 bool m_didCalculateStyleSelector
;
788 DocLoader
* m_docLoader
;
789 Tokenizer
* m_tokenizer
;
793 KURL m_url
; // Document.URL: The URL from which this document was retrieved.
794 KURL m_baseURL
; // Node.baseURI: The URL to use when resolving relative URLs.
795 KURL m_baseElementURL
; // The URL set by the <base> element.
796 KURL m_cookieURL
; // The URL to use for cookie access.
797 KURL m_policyBaseURL
; // The policy URL for third-party cookie blocking.
799 // Document.documentURI:
800 // Although URL-like, Document.documentURI can actually be set to any
801 // string by content. Document.documentURI affects m_baseURL unless the
802 // document contains a <base> element, in which case the <base> element
804 String m_documentURI
;
808 RefPtr
<DocumentType
> m_docType
;
809 mutable RefPtr
<DOMImplementation
> m_implementation
;
811 RefPtr
<StyleSheet
> m_sheet
;
812 #if FRAME_LOADS_USER_STYLESHEET
816 // Track the number of currently loading top-level stylesheets. Sheets
817 // loaded using the @import directive are not included in this count.
818 // We use this count of pending sheets to detect when we can begin attaching
820 int m_pendingStylesheets
;
822 // But sometimes you need to ignore pending stylesheet count to
823 // force an immediate layout when requested by JS.
824 bool m_ignorePendingStylesheets
;
826 // If we do ignore the pending stylesheet count, then we need to add a boolean
827 // to track that this happened so that we can do a full repaint when the stylesheets
828 // do eventually load.
829 PendingSheetLayout m_pendingSheetLayout
;
831 bool m_hasNodesWithPlaceholderStyle
;
833 RefPtr
<CSSStyleSheet
> m_elemSheet
;
834 RefPtr
<CSSStyleSheet
> m_mappedElementSheet
;
838 bool m_ignoreAutofocus
;
840 ParseMode m_parseMode
;
844 RefPtr
<Node
> m_focusedNode
;
845 RefPtr
<Node
> m_hoverNode
;
846 RefPtr
<Node
> m_activeNode
;
847 mutable RefPtr
<Element
> m_documentElement
;
849 unsigned m_domtree_version
;
851 HashSet
<NodeIterator
*> m_nodeIterators
;
852 HashSet
<Range
*> m_ranges
;
854 unsigned short m_listenerTypes
;
856 RefPtr
<StyleSheetList
> m_styleSheets
; // All of the stylesheets that are currently in effect for our media type and stylesheet set.
857 ListHashSet
<Node
*> m_styleSheetCandidateNodes
; // All of the nodes that could potentially provide stylesheets to the document (<link>, <style>, <?xml-stylesheet>)
859 RegisteredEventListenerList m_windowEventListeners
;
861 typedef HashMap
<FormElementKey
, Vector
<String
>, FormElementKeyHash
, FormElementKeyHashTraits
> FormElementStateMap
;
862 ListHashSet
<HTMLFormControlElementWithState
*> m_formElementsWithState
;
863 FormElementStateMap m_stateForNewFormElements
;
866 Color m_visitedLinkColor
;
867 Color m_activeLinkColor
;
869 String m_preferredStylesheetSet
;
870 String m_selectedStylesheetSet
;
873 bool visuallyOrdered
;
876 bool m_inStyleRecalc
;
877 bool m_closeAfterStyleRecalc
;
878 bool m_usesDescendantRules
;
879 bool m_usesSiblingRules
;
880 bool m_usesFirstLineRules
;
881 bool m_usesFirstLetterRules
;
882 bool m_gotoAnchorNeededAfterStylesheetsLoad
;
884 bool m_isDNSPrefetchEnabled
;
885 bool m_haveExplicitlyDisabledDNSPrefetch
;
888 bool m_titleSetExplicitly
;
889 RefPtr
<Element
> m_titleElement
;
891 RenderArena
* m_renderArena
;
893 typedef std::pair
<Vector
<DocumentMarker
>, Vector
<IntRect
> > MarkerMapVectorPair
;
894 typedef HashMap
<RefPtr
<Node
>, MarkerMapVectorPair
*> MarkerMap
;
897 mutable AXObjectCache
* m_axObjectCache
;
899 DeprecatedPtrList
<ImageLoader
> m_imageLoadEventDispatchSoonList
;
900 DeprecatedPtrList
<ImageLoader
> m_imageLoadEventDispatchingList
;
901 Timer
<Document
> m_imageLoadEventTimer
;
903 Timer
<Document
> m_updateFocusAppearanceTimer
;
907 bool m_processingLoadEvent
;
909 bool m_overMinimumLayoutThreshold
;
912 void* m_transformSource
;
913 RefPtr
<Document
> m_transformSourceDocument
;
917 XBLBindingManager
* m_bindingManager
; // The access point through which documents and elements communicate with XBL.
920 typedef HashMap
<AtomicStringImpl
*, HTMLMapElement
*> ImageMapsByName
;
921 ImageMapsByName m_imageMapsByName
;
923 HashSet
<Node
*> m_disconnectedNodesWithEventListeners
;
925 int m_docID
; // A unique document identifier used for things like document-specific mapped attributes.
927 String m_xmlEncoding
;
929 bool m_xmlStandalone
;
931 String m_contentLanguage
;
935 void setInPageCache(bool flag
);
937 // Elements can register themselves for the "documentWillBecomeInactive()" and
938 // "documentDidBecomeActive()" callbacks
939 void registerForDocumentActivationCallbacks(Element
*);
940 void unregisterForDocumentActivationCallbacks(Element
*);
941 void documentWillBecomeInactive();
942 void documentDidBecomeActive();
944 void setShouldCreateRenderers(bool);
945 bool shouldCreateRenderers();
947 void setDecoder(PassRefPtr
<TextResourceDecoder
>);
948 TextResourceDecoder
* decoder() const { return m_decoder
.get(); }
950 UChar
backslashAsCurrencySymbol() const;
952 #if ENABLE(DASHBOARD_SUPPORT)
953 void setDashboardRegionsDirty(bool f
) { m_dashboardRegionsDirty
= f
; }
954 bool dashboardRegionsDirty() const { return m_dashboardRegionsDirty
; }
955 bool hasDashboardRegions () const { return m_hasDashboardRegions
; }
956 void setHasDashboardRegions (bool f
) { m_hasDashboardRegions
= f
; }
957 const Vector
<DashboardRegionValue
>& dashboardRegions() const;
958 void setDashboardRegions(const Vector
<DashboardRegionValue
>&);
961 void removeAllEventListenersFromAllNodes();
963 void registerDisconnectedNodeWithEventListeners(Node
*);
964 void unregisterDisconnectedNodeWithEventListeners(Node
*);
966 HTMLFormElement::CheckedRadioButtons
& checkedRadioButtons() { return m_checkedRadioButtons
; }
969 const SVGDocumentExtensions
* svgExtensions();
970 SVGDocumentExtensions
* accessSVGExtensions();
973 void initSecurityContext();
974 SecurityOrigin
* securityOrigin() const { return m_securityOrigin
.get(); }
976 // Explicitly override the security origin for this document.
977 // Note: It is dangerous to change the security origin of a document
978 // that already contains content.
979 void setSecurityOrigin(SecurityOrigin
*);
981 bool processingLoadEvent() const { return m_processingLoadEvent
; }
984 void addOpenDatabase(Database
*);
985 void removeOpenDatabase(Database
*);
986 DatabaseThread
* databaseThread(); // Creates the thread as needed, but not if it has been already terminated.
987 void setHasOpenDatabases() { m_hasOpenDatabases
= true; }
988 bool hasOpenDatabases() { return m_hasOpenDatabases
; }
989 void stopDatabases();
992 void setUsingGeolocation(bool f
) { m_usingGeolocation
= f
; }
993 bool usingGeolocation() const { return m_usingGeolocation
; };
996 void clearXMLVersion() { m_xmlVersion
= String(); }
1000 void removeAllDisconnectedNodeEventListeners();
1001 void imageLoadEventTimerFired(Timer
<Document
>*);
1002 void updateFocusAppearanceTimerFired(Timer
<Document
>*);
1003 void updateBaseURL();
1005 RefPtr
<SecurityOrigin
> m_securityOrigin
;
1007 RenderObject
* m_savedRenderer
;
1010 RefPtr
<TextResourceDecoder
> m_decoder
;
1012 // We maintain the invariant that m_duplicateIds is the count of all elements with a given ID
1013 // excluding the one referenced in m_elementsById, if any. This means it one less than the total count
1014 // when the first node with a given ID is cached, otherwise the same as the total count.
1015 mutable HashMap
<AtomicStringImpl
*, Element
*> m_elementsById
;
1016 mutable HashCountedSet
<AtomicStringImpl
*> m_duplicateIds
;
1018 mutable HashMap
<StringImpl
*, Element
*, CaseFoldingHash
> m_elementsByAccessKey
;
1020 InheritedBool m_designMode
;
1022 int m_selfOnlyRefCount
;
1024 HTMLFormElement::CheckedRadioButtons m_checkedRadioButtons
;
1026 typedef HashMap
<AtomicStringImpl
*, HTMLCollection::CollectionInfo
*> NamedCollectionMap
;
1027 HTMLCollection::CollectionInfo m_collectionInfo
[HTMLCollection::NumUnnamedDocumentCachedTypes
];
1028 NamedCollectionMap m_nameCollectionInfo
[HTMLCollection::NumNamedDocumentCachedTypes
];
1031 RefPtr
<XPathEvaluator
> m_xpathEvaluator
;
1035 OwnPtr
<SVGDocumentExtensions
> m_svgExtensions
;
1038 #if ENABLE(DASHBOARD_SUPPORT)
1039 Vector
<DashboardRegionValue
> m_dashboardRegions
;
1040 bool m_hasDashboardRegions
;
1041 bool m_dashboardRegionsDirty
;
1044 HashMap
<String
, RefPtr
<HTMLCanvasElement
> > m_cssCanvasElements
;
1046 mutable bool m_accessKeyMapValid
;
1047 bool m_createRenderers
;
1051 HashSet
<Element
*> m_documentActivationCallbackElements
;
1053 bool m_useSecureKeyboardEntryWhenActive
;
1057 unsigned m_numNodeListCaches
;
1060 typedef HashMap
<WebCore::Node
*, JSNode
*> JSWrapperCache
;
1061 JSWrapperCache
& wrapperCache() { return m_wrapperCache
; }
1063 JSWrapperCache m_wrapperCache
;
1065 #if ENABLE(DATABASE)
1066 RefPtr
<DatabaseThread
> m_databaseThread
;
1067 bool m_hasOpenDatabases
; // This never changes back to false, even as the database thread is closed.
1068 typedef HashSet
<Database
*> DatabaseSet
;
1069 OwnPtr
<DatabaseSet
> m_openDatabaseSet
;
1072 bool m_usingGeolocation
;
1074 #if USE(LOW_BANDWIDTH_DISPLAY)
1075 bool m_inLowBandwidthDisplay
;
1079 inline bool Document::hasElementWithId(AtomicStringImpl
* id
) const
1082 return m_elementsById
.contains(id
) || m_duplicateIds
.contains(id
);
1085 inline bool Node::isDocumentNode() const
1087 return this == m_document
.get();
1090 } // namespace WebCore
1092 #endif // Document_h