2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
7 * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
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.
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.
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.
31 #include "DocumentMarker.h"
32 #include "HTMLCollection.h"
33 #include "HTMLFormElement.h"
34 #include "ScriptExecutionContext.h"
35 #include "StringHash.h"
37 #include <wtf/HashCountedSet.h>
38 #include <wtf/ListHashSet.h>
40 // FIXME: We should move Mac off of the old Frame-based user stylesheet loading
41 // code and onto the new code in Page. We can't do that until the code in Page
42 // supports non-file: URLs, however.
43 #if PLATFORM(MAC) || PLATFORM(QT)
44 #define FRAME_LOADS_USER_STYLESHEET 1
46 #define FRAME_LOADS_USER_STYLESHEET 0
55 class CachedCSSStyleSheet;
56 class CanvasRenderingContext2D;
58 class CSSStyleDeclaration;
59 class CSSStyleSelector;
63 class DOMImplementation;
68 class DocumentFragment;
72 class EntityReference;
75 class FormControlElementWithState;
79 class HTMLCanvasElement;
82 class HTMLFormElement;
83 class HTMLHeadElement;
84 class HTMLInputElement;
88 class MouseEventWithHitTestResults;
92 class PlatformMouseEvent;
93 class ProcessingInstruction;
95 class RegisteredEventListener;
99 class SegmentedString;
102 class StyleSheetList;
104 class TextResourceDecoder;
107 class XMLHttpRequest;
110 class SVGDocumentExtensions;
114 class XBLBindingManager;
118 class XPathEvaluator;
119 class XPathExpression;
120 class XPathNSResolver;
124 #if ENABLE(DASHBOARD_SUPPORT)
125 struct DashboardRegionValue;
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);
218 Element* documentElement() const
220 if (!m_documentElement)
221 cacheDocumentElement();
222 return m_documentElement.get();
225 virtual PassRefPtr<Element> createElement(const AtomicString& tagName, ExceptionCode&);
226 PassRefPtr<DocumentFragment> createDocumentFragment ();
227 PassRefPtr<Text> createTextNode(const String& data);
228 PassRefPtr<Comment> createComment(const String& data);
229 PassRefPtr<CDATASection> createCDATASection(const String& data, ExceptionCode&);
230 PassRefPtr<ProcessingInstruction> createProcessingInstruction(const String& target, const String& data, ExceptionCode&);
231 PassRefPtr<Attr> createAttribute(const String& name, ExceptionCode& ec) { return createAttributeNS(String(), name, ec, true); }
232 PassRefPtr<Attr> createAttributeNS(const String& namespaceURI, const String& qualifiedName, ExceptionCode&, bool shouldIgnoreNamespaceChecks = false);
233 PassRefPtr<EntityReference> createEntityReference(const String& name, ExceptionCode&);
234 PassRefPtr<Node> importNode(Node* importedNode, bool deep, ExceptionCode&);
235 virtual PassRefPtr<Element> createElementNS(const String& namespaceURI, const String& qualifiedName, ExceptionCode&);
236 PassRefPtr<Element> createElement(const QualifiedName&, bool createdByParser);
237 Element* getElementById(const AtomicString&) const;
238 bool hasElementWithId(AtomicStringImpl* id) const;
239 bool containsMultipleElementsWithId(const AtomicString& elementId) { return m_duplicateIds.contains(elementId.impl()); }
241 Element* elementFromPoint(int x, int y) const;
242 String readyState() const;
244 String defaultCharset() const;
246 // Synonyms backing similar DOM attributes. Use Document::encoding() to avoid virtual dispatch.
247 String inputEncoding() const { return Document::encoding(); }
248 String charset() const { return Document::encoding(); }
249 String characterSet() const { return Document::encoding(); }
251 void setCharset(const String&);
253 String contentLanguage() const { return m_contentLanguage; }
254 void setContentLanguage(const String& lang) { m_contentLanguage = lang; }
256 String xmlEncoding() const { return m_xmlEncoding; }
257 String xmlVersion() const { return m_xmlVersion; }
258 bool xmlStandalone() const { return m_xmlStandalone; }
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&);
264 String documentURI() const { return m_documentURI; }
265 void setDocumentURI(const String&);
267 virtual KURL baseURI() const;
269 PassRefPtr<Node> adoptNode(PassRefPtr<Node> source, ExceptionCode&);
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);
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);
291 HTMLCollection::CollectionInfo* collectionInfo(HTMLCollection::Type type)
293 ASSERT(type >= HTMLCollection::FirstUnnamedDocumentCachedType);
294 unsigned index = type - HTMLCollection::FirstUnnamedDocumentCachedType;
295 ASSERT(index < HTMLCollection::NumUnnamedDocumentCachedTypes);
296 return &m_collectionInfo[index];
299 HTMLCollection::CollectionInfo* nameCollectionInfo(HTMLCollection::Type, const AtomicString& name);
301 // DOM methods overridden from parent classes
303 virtual String nodeName() const;
304 virtual NodeType nodeType() const;
306 // Other methods (not part of DOM)
307 virtual bool isHTMLDocument() const { return false; }
308 virtual bool isImageDocument() const { return false; }
310 virtual bool isSVGDocument() const { return false; }
312 virtual bool isPluginDocument() const { return false; }
313 virtual bool isMediaDocument() const { return false; }
315 virtual bool isWMLDocument() const { return false; }
317 virtual bool isFrameSet() const { return false; }
319 CSSStyleSelector* styleSelector() const { return m_styleSelector; }
321 Element* getElementByAccessKey(const String& key) const;
324 * Updates the pending sheet count and then calls updateStyleSelector.
326 void removePendingSheet();
329 * This method returns true if all top-level stylesheets have loaded (including
330 * any @imports that they may be loading).
332 bool haveStylesheetsLoaded() const
334 return m_pendingStylesheets <= 0 || m_ignorePendingStylesheets;
338 * Increments the number of pending sheets. The <link> elements
339 * invoke this to add themselves to the loading list.
341 void addPendingSheet() { m_pendingStylesheets++; }
343 void addStyleSheetCandidateNode(Node*, bool createdByParser);
344 void removeStyleSheetCandidateNode(Node*);
346 bool gotoAnchorNeededAfterStylesheetsLoad() { return m_gotoAnchorNeededAfterStylesheetsLoad; }
347 void setGotoAnchorNeededAfterStylesheetsLoad(bool b) { m_gotoAnchorNeededAfterStylesheetsLoad = b; }
350 * Called when one or more stylesheets in the document may have been added, removed or changed.
352 * Creates a new style selector and assign it to this document. This is done by iterating through all nodes in
353 * document (or those before <BODY> in a HTML document), searching for stylesheets. Stylesheets can be contained in
354 * <LINK>, <STYLE> or <BODY> elements, as well as processing instructions (XML documents only). A list is
355 * constructed from these which is used to create the a new style selector which collates all of the stylesheets
356 * found and is used to calculate the derived styles for all rendering objects.
358 void updateStyleSelector();
360 void recalcStyleSelector();
362 bool usesDescendantRules() const { return m_usesDescendantRules; }
363 void setUsesDescendantRules(bool b) { m_usesDescendantRules = b; }
364 bool usesSiblingRules() const { return m_usesSiblingRules; }
365 void setUsesSiblingRules(bool b) { m_usesSiblingRules = b; }
366 bool usesFirstLineRules() const { return m_usesFirstLineRules; }
367 void setUsesFirstLineRules(bool b) { m_usesFirstLineRules = b; }
368 bool usesFirstLetterRules() const { return m_usesFirstLetterRules; }
369 void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; }
370 bool usesBeforeAfterRules() const { return m_usesBeforeAfterRules; }
371 void setUsesBeforeAfterRules(bool b) { m_usesBeforeAfterRules = b; }
373 // Machinery for saving and restoring state when you leave and then go back to a page.
374 void registerFormElementWithState(FormControlElementWithState* e) { m_formElementsWithState.add(e); }
375 void unregisterFormElementWithState(FormControlElementWithState* e) { m_formElementsWithState.remove(e); }
376 Vector<String> formElementsState() const;
377 void setStateForNewFormElements(const Vector<String>&);
378 bool hasStateForNewFormElements() const;
379 bool takeStateForFormElement(AtomicStringImpl* name, AtomicStringImpl* type, String& state);
381 FrameView* view() const; // can be NULL
382 Frame* frame() const { return m_frame; } // can be NULL
383 Page* page() const; // can be NULL
384 Settings* settings() const; // can be NULL
386 PassRefPtr<Range> createRange();
388 PassRefPtr<NodeIterator> createNodeIterator(Node* root, unsigned whatToShow,
389 PassRefPtr<NodeFilter>, bool expandEntityReferences, ExceptionCode&);
391 PassRefPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow,
392 PassRefPtr<NodeFilter>, bool expandEntityReferences, ExceptionCode&);
394 // Special support for editing
395 PassRefPtr<CSSStyleDeclaration> createCSSStyleDeclaration();
396 PassRefPtr<EditingText> createEditingTextNode(const String&);
398 virtual void recalcStyle( StyleChange = NoChange );
399 virtual void updateRendering();
401 void updateLayoutIgnorePendingStylesheets();
402 static void updateDocumentsRendering();
403 DocLoader* docLoader() { return m_docLoader; }
405 virtual void attach();
406 virtual void detach();
408 RenderArena* renderArena() { return m_renderArena; }
410 RenderView* renderView() const;
412 void clearAXObjectCache();
413 AXObjectCache* axObjectCache() const;
415 // to get visually ordered hebrew and arabic pages right
416 void setVisuallyOrdered();
418 void open(Document* ownerDocument = 0);
421 void implicitClose();
422 void cancelParsing();
424 void write(const SegmentedString& text, Document* ownerDocument = 0);
425 void write(const String& text, Document* ownerDocument = 0);
426 void writeln(const String& text, Document* ownerDocument = 0);
427 void finishParsing();
430 bool wellFormed() const { return m_wellFormed; }
432 const KURL& url() const { return m_url; }
433 void setURL(const KURL&);
435 const KURL& baseURL() const { return m_baseURL; }
436 // Setting the BaseElementURL will change the baseURL.
437 void setBaseElementURL(const KURL&);
439 const String& baseTarget() const { return m_baseTarget; }
440 // Setting the BaseElementTarget will change the baseTarget.
441 void setBaseElementTarget(const String& baseTarget) { m_baseTarget = baseTarget; }
443 KURL completeURL(const String&) const;
445 virtual String userAgent(const KURL&) const;
447 // from cachedObjectClient
448 virtual void setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet*);
450 #if FRAME_LOADS_USER_STYLESHEET
451 void setUserStyleSheet(const String& sheet);
454 String userStyleSheet() const;
456 CSSStyleSheet* elementSheet();
457 CSSStyleSheet* mappedElementSheet();
458 virtual Tokenizer* createTokenizer();
459 Tokenizer* tokenizer() { return m_tokenizer; }
461 bool printing() const { return m_printing; }
462 void setPrinting(bool p) { m_printing = p; }
464 enum ParseMode { Compat, AlmostStrict, Strict };
467 virtual void determineParseMode() {}
470 void setParseMode(ParseMode m) { m_parseMode = m; }
471 ParseMode parseMode() const { return m_parseMode; }
473 bool inCompatMode() const { return m_parseMode == Compat; }
474 bool inAlmostStrictMode() const { return m_parseMode == AlmostStrict; }
475 bool inStrictMode() const { return m_parseMode == Strict; }
477 void setParsing(bool);
478 bool parsing() const { return m_bParsing; }
479 int minimumLayoutDelay();
480 bool shouldScheduleLayout();
481 int elapsedTime() const;
483 void setTextColor(const Color& color) { m_textColor = color; }
484 Color textColor() const { return m_textColor; }
486 const Color& linkColor() const { return m_linkColor; }
487 const Color& visitedLinkColor() const { return m_visitedLinkColor; }
488 const Color& activeLinkColor() const { return m_activeLinkColor; }
489 void setLinkColor(const Color& c) { m_linkColor = c; }
490 void setVisitedLinkColor(const Color& c) { m_visitedLinkColor = c; }
491 void setActiveLinkColor(const Color& c) { m_activeLinkColor = c; }
492 void resetLinkColor();
493 void resetVisitedLinkColor();
494 void resetActiveLinkColor();
496 MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const IntPoint&, const PlatformMouseEvent&);
498 virtual bool childTypeAllowed(NodeType);
499 virtual PassRefPtr<Node> cloneNode(bool deep);
501 virtual bool canReplaceChild(Node* newChild, Node* oldChild);
503 StyleSheetList* styleSheets();
505 /* Newly proposed CSS3 mechanism for selecting alternate
506 stylesheets using the DOM. May be subject to change as
509 String preferredStylesheetSet() const;
510 String selectedStylesheetSet() const;
511 void setSelectedStylesheetSet(const String&);
513 bool setFocusedNode(PassRefPtr<Node>);
514 Node* focusedNode() const { return m_focusedNode.get(); }
516 // The m_ignoreAutofocus flag specifies whether or not the document has been changed by the user enough
517 // for WebCore to ignore the autofocus attribute on any form controls
518 bool ignoreAutofocus() const { return m_ignoreAutofocus; };
519 void setIgnoreAutofocus(bool shouldIgnore = true) { m_ignoreAutofocus = shouldIgnore; };
521 void setHoverNode(PassRefPtr<Node>);
522 Node* hoverNode() const { return m_hoverNode.get(); }
524 void setActiveNode(PassRefPtr<Node>);
525 Node* activeNode() const { return m_activeNode.get(); }
527 void focusedNodeRemoved();
528 void removeFocusedNodeOfSubtree(Node*, bool amongChildrenOnly = false);
529 void hoveredNodeDetached(Node*);
530 void activeChainNodeDetached(Node*);
532 // Updates for :target (CSS3 selector).
533 void setCSSTarget(Element*);
534 Element* cssTarget() const { return m_cssTarget; }
536 void setDocumentChanged(bool);
538 void attachNodeIterator(NodeIterator*);
539 void detachNodeIterator(NodeIterator*);
541 void attachRange(Range*);
542 void detachRange(Range*);
544 void nodeChildrenChanged(ContainerNode*);
545 void nodeWillBeRemoved(Node*);
547 void textInserted(Node*, unsigned offset, unsigned length);
548 void textRemoved(Node*, unsigned offset, unsigned length);
549 void textNodesMerged(Text* oldNode, unsigned offset);
550 void textNodeSplit(Text* oldNode);
552 DOMWindow* defaultView() const { return domWindow(); }
553 DOMWindow* domWindow() const;
555 PassRefPtr<Event> createEvent(const String& eventType, ExceptionCode&);
557 // keep track of what types of event listeners are registered, so we don't
558 // dispatch events unnecessarily
560 DOMSUBTREEMODIFIED_LISTENER = 0x01,
561 DOMNODEINSERTED_LISTENER = 0x02,
562 DOMNODEREMOVED_LISTENER = 0x04,
563 DOMNODEREMOVEDFROMDOCUMENT_LISTENER = 0x08,
564 DOMNODEINSERTEDINTODOCUMENT_LISTENER = 0x10,
565 DOMATTRMODIFIED_LISTENER = 0x20,
566 DOMCHARACTERDATAMODIFIED_LISTENER = 0x40,
567 OVERFLOWCHANGED_LISTENER = 0x80,
568 ANIMATIONEND_LISTENER = 0x100,
569 ANIMATIONSTART_LISTENER = 0x200,
570 ANIMATIONITERATION_LISTENER = 0x400,
571 TRANSITIONEND_LISTENER = 0x800
574 bool hasListenerType(ListenerType listenerType) const { return (m_listenerTypes & listenerType); }
575 void addListenerType(ListenerType listenerType) { m_listenerTypes = m_listenerTypes | listenerType; }
576 void addListenerTypeIfNeeded(const AtomicString& eventType);
578 CSSStyleDeclaration* getOverrideStyle(Element*, const String& pseudoElt);
580 void handleWindowEvent(Event*, bool useCapture);
581 void setWindowInlineEventListenerForType(const AtomicString& eventType, PassRefPtr<EventListener>);
582 EventListener* windowInlineEventListenerForType(const AtomicString& eventType);
583 void removeWindowInlineEventListenerForType(const AtomicString& eventType);
585 void setWindowInlineEventListenerForTypeAndAttribute(const AtomicString& eventType, Attribute*);
587 void addWindowEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
588 void removeWindowEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
589 bool hasWindowEventListener(const AtomicString& eventType);
591 void addPendingFrameUnloadEventCount();
592 void removePendingFrameUnloadEventCount();
593 void addPendingFrameBeforeUnloadEventCount();
594 void removePendingFrameBeforeUnloadEventCount();
596 PassRefPtr<EventListener> createEventListener(const String& functionName, const String& code, Node*);
599 * Searches through the document, starting from fromNode, for the next selectable element that comes after fromNode.
600 * The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab indexes
601 * first (from lowest to highest), and then elements without tab indexes (in document order).
603 * @param fromNode The node from which to start searching. The node after this will be focused. May be null.
605 * @return The focus node that comes after fromNode
607 * See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
609 Node* nextFocusableNode(Node* start, KeyboardEvent*);
612 * Searches through the document, starting from fromNode, for the previous selectable element (that comes _before_)
613 * fromNode. The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab
614 * indexes first (from lowest to highest), and then elements without tab indexes (in document order).
616 * @param fromNode The node from which to start searching. The node before this will be focused. May be null.
618 * @return The focus node that comes before fromNode
620 * See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
622 Node* previousFocusableNode(Node* start, KeyboardEvent*);
624 int nodeAbsIndex(Node*);
625 Node* nodeWithAbsIndex(int absIndex);
628 * Handles a HTTP header equivalent set by a meta tag using <meta http-equiv="..." content="...">. This is called
629 * when a meta tag is encountered during document parsing, and also when a script dynamically changes or adds a meta
630 * tag. This enables scripts to use meta tags to perform refreshes and set expiry dates in addition to them being
631 * specified in a HTML file.
633 * @param equiv The http header name (value of the meta tag's "equiv" attribute)
634 * @param content The header value (value of the meta tag's "content" attribute)
636 void processHttpEquiv(const String& equiv, const String& content);
638 // Returns the owning element in the parent document.
639 // Returns 0 if this is the top level document.
640 Element* ownerElement() const;
642 String title() const { return m_title; }
643 void setTitle(const String&, Element* titleElement = 0);
644 void removeTitle(Element* titleElement);
646 String cookie() const;
647 void setCookie(const String&);
649 String referrer() const;
651 String domain() const;
652 void setDomain(const String& newDomain);
654 String lastModified() const;
656 const KURL& cookieURL() const { return m_cookieURL; }
658 const KURL& policyBaseURL() const { return m_policyBaseURL; }
659 void setPolicyBaseURL(const KURL& url) { m_policyBaseURL = url; }
661 // The following implements the rule from HTML 4 for what valid names are.
662 // To get this right for all the XML cases, we probably have to improve this or move it
663 // and make it sensitive to the type of document.
664 static bool isValidName(const String&);
666 // The following breaks a qualified name into a prefix and a local name.
667 // It also does a validity check, and returns false if the qualified name
668 // is invalid. It also sets ExceptionCode when name is invalid.
669 static bool parseQualifiedName(const String& qualifiedName, String& prefix, String& localName, ExceptionCode&);
671 // Checks to make sure prefix and namespace do not conflict (per DOM Core 3)
672 static bool hasPrefixNamespaceMismatch(const QualifiedName&);
674 void addElementById(const AtomicString& elementId, Element *element);
675 void removeElementById(const AtomicString& elementId, Element *element);
677 void addImageMap(HTMLMapElement*);
678 void removeImageMap(HTMLMapElement*);
679 HTMLMapElement* getImageMap(const String& url) const;
681 HTMLElement* body() const;
682 void setBody(PassRefPtr<HTMLElement>, ExceptionCode&);
684 HTMLHeadElement* head();
686 bool execCommand(const String& command, bool userInterface = false, const String& value = String());
687 bool queryCommandEnabled(const String& command);
688 bool queryCommandIndeterm(const String& command);
689 bool queryCommandState(const String& command);
690 bool queryCommandSupported(const String& command);
691 String queryCommandValue(const String& command);
693 void addMarker(Range*, DocumentMarker::MarkerType, String description = String());
694 void addMarker(Node*, DocumentMarker);
695 void copyMarkers(Node *srcNode, unsigned startOffset, int length, Node *dstNode, int delta, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
696 void removeMarkers(Range*, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
697 void removeMarkers(Node*, unsigned startOffset, int length, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
698 void removeMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
699 void removeMarkers(Node*);
700 void repaintMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
701 void setRenderedRectForMarker(Node*, DocumentMarker, const IntRect&);
702 void invalidateRenderedRectsForMarkersInRect(const IntRect&);
703 void shiftMarkers(Node*, unsigned startOffset, int delta, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
705 DocumentMarker* markerContainingPoint(const IntPoint&, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
706 Vector<DocumentMarker> markersForNode(Node*);
707 Vector<IntRect> renderedRectsForMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
709 // designMode support
710 enum InheritedBool { off = false, on = true, inherit };
711 void setDesignMode(InheritedBool value);
712 InheritedBool getDesignMode() const;
713 bool inDesignMode() const;
715 Document* parentDocument() const;
716 Document* topDocument() const;
718 int docID() const { return m_docID; }
721 void applyXSLTransform(ProcessingInstruction* pi);
722 void setTransformSource(void* doc);
723 const void* transformSource() { return m_transformSource; }
724 PassRefPtr<Document> transformSourceDocument() { return m_transformSourceDocument; }
725 void setTransformSourceDocument(Document* doc) { m_transformSourceDocument = doc; }
730 XBLBindingManager* bindingManager() const { return m_bindingManager; }
733 void incDOMTreeVersion() { ++m_domtree_version; }
734 unsigned domTreeVersion() const { return m_domtree_version; }
736 void setDocType(PassRefPtr<DocumentType>);
738 virtual void finishedParsing();
741 // XPathEvaluator methods
742 PassRefPtr<XPathExpression> createExpression(const String& expression,
743 XPathNSResolver* resolver,
745 PassRefPtr<XPathNSResolver> createNSResolver(Node *nodeResolver);
746 PassRefPtr<XPathResult> evaluate(const String& expression,
748 XPathNSResolver* resolver,
752 #endif // ENABLE(XPATH)
754 enum PendingSheetLayout { NoLayoutWithPendingSheets, DidLayoutWithPendingSheets, IgnoreLayoutWithPendingSheets };
756 bool didLayoutWithPendingStylesheets() const { return m_pendingSheetLayout == DidLayoutWithPendingSheets; }
758 void setHasNodesWithPlaceholderStyle() { m_hasNodesWithPlaceholderStyle = true; }
760 const String& iconURL() const { return m_iconURL; }
761 void setIconURL(const String& iconURL, const String& type);
763 void setUseSecureKeyboardEntryWhenActive(bool);
764 bool useSecureKeyboardEntryWhenActive() const;
766 void addNodeListCache() { ++m_numNodeListCaches; }
767 void removeNodeListCache() { ASSERT(m_numNodeListCaches > 0); --m_numNodeListCaches; }
768 bool hasNodeListCaches() const { return m_numNodeListCaches; }
770 void updateFocusAppearanceSoon();
771 void cancelFocusAppearanceUpdate();
773 // FF method for accessing the selection added for compatability.
774 DOMSelection* getSelection() const;
776 // Extension for manipulating canvas drawing contexts for use in CSS
777 CanvasRenderingContext2D* getCSSCanvasContext(const String& type, const String& name, int width, int height);
778 HTMLCanvasElement* getCSSCanvasElement(const String& name);
780 bool isDNSPrefetchEnabled() const { return m_isDNSPrefetchEnabled; }
781 void initDNSPrefetch();
782 void parseDNSPrefetchControlHeader(const String&);
784 virtual void reportException(const String& errorMessage, int lineNumber, const String& sourceURL);
785 virtual void addMessage(MessageDestination, MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL);
786 virtual void resourceRetrievedByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString);
787 virtual void scriptImported(unsigned long, const String&);
788 virtual void postTask(PassRefPtr<Task>); // Executes the task on context's thread asynchronously.
791 Document(Frame*, bool isXHTML);
794 virtual void refScriptExecutionContext() { ref(); }
795 virtual void derefScriptExecutionContext() { deref(); }
797 virtual const KURL& virtualURL() const; // Same as url(), but needed for ScriptExecutionContext to implement it without a performance loss for direct calls.
798 virtual KURL virtualCompleteURL(const String&) const; // Same as completeURL() for the same reason as above.
800 String encoding() const;
802 CSSStyleSelector* m_styleSelector;
803 bool m_didCalculateStyleSelector;
806 DocLoader* m_docLoader;
807 Tokenizer* m_tokenizer;
811 KURL m_url; // Document.URL: The URL from which this document was retrieved.
812 KURL m_baseURL; // Node.baseURI: The URL to use when resolving relative URLs.
813 KURL m_baseElementURL; // The URL set by the <base> element.
814 KURL m_cookieURL; // The URL to use for cookie access.
815 KURL m_policyBaseURL; // The policy URL for third-party cookie blocking.
817 // Document.documentURI:
818 // Although URL-like, Document.documentURI can actually be set to any
819 // string by content. Document.documentURI affects m_baseURL unless the
820 // document contains a <base> element, in which case the <base> element
822 String m_documentURI;
826 RefPtr<DocumentType> m_docType;
827 mutable RefPtr<DOMImplementation> m_implementation;
829 RefPtr<StyleSheet> m_sheet;
830 #if FRAME_LOADS_USER_STYLESHEET
834 // Track the number of currently loading top-level stylesheets. Sheets
835 // loaded using the @import directive are not included in this count.
836 // We use this count of pending sheets to detect when we can begin attaching
838 int m_pendingStylesheets;
840 // But sometimes you need to ignore pending stylesheet count to
841 // force an immediate layout when requested by JS.
842 bool m_ignorePendingStylesheets;
844 // If we do ignore the pending stylesheet count, then we need to add a boolean
845 // to track that this happened so that we can do a full repaint when the stylesheets
846 // do eventually load.
847 PendingSheetLayout m_pendingSheetLayout;
849 bool m_hasNodesWithPlaceholderStyle;
851 RefPtr<CSSStyleSheet> m_elemSheet;
852 RefPtr<CSSStyleSheet> m_mappedElementSheet;
856 bool m_ignoreAutofocus;
858 ParseMode m_parseMode;
862 RefPtr<Node> m_focusedNode;
863 RefPtr<Node> m_hoverNode;
864 RefPtr<Node> m_activeNode;
865 mutable RefPtr<Element> m_documentElement;
867 unsigned m_domtree_version;
869 HashSet<NodeIterator*> m_nodeIterators;
870 HashSet<Range*> m_ranges;
872 unsigned short m_listenerTypes;
874 RefPtr<StyleSheetList> m_styleSheets; // All of the stylesheets that are currently in effect for our media type and stylesheet set.
875 ListHashSet<Node*> m_styleSheetCandidateNodes; // All of the nodes that could potentially provide stylesheets to the document (<link>, <style>, <?xml-stylesheet>)
877 RegisteredEventListenerVector m_windowEventListeners;
879 typedef HashMap<FormElementKey, Vector<String>, FormElementKeyHash, FormElementKeyHashTraits> FormElementStateMap;
880 ListHashSet<FormControlElementWithState*> m_formElementsWithState;
881 FormElementStateMap m_stateForNewFormElements;
884 Color m_visitedLinkColor;
885 Color m_activeLinkColor;
887 String m_preferredStylesheetSet;
888 String m_selectedStylesheetSet;
891 bool visuallyOrdered;
894 bool m_inStyleRecalc;
895 bool m_closeAfterStyleRecalc;
896 bool m_usesDescendantRules;
897 bool m_usesSiblingRules;
898 bool m_usesFirstLineRules;
899 bool m_usesFirstLetterRules;
900 bool m_usesBeforeAfterRules;
901 bool m_gotoAnchorNeededAfterStylesheetsLoad;
902 bool m_isDNSPrefetchEnabled;
903 bool m_haveExplicitlyDisabledDNSPrefetch;
904 bool m_frameElementsShouldIgnoreScrolling;
907 bool m_titleSetExplicitly;
908 RefPtr<Element> m_titleElement;
910 RenderArena* m_renderArena;
912 typedef std::pair<Vector<DocumentMarker>, Vector<IntRect> > MarkerMapVectorPair;
913 typedef HashMap<RefPtr<Node>, MarkerMapVectorPair*> MarkerMap;
916 mutable AXObjectCache* m_axObjectCache;
918 Timer<Document> m_updateFocusAppearanceTimer;
920 Element* m_cssTarget;
922 bool m_processingLoadEvent;
924 bool m_overMinimumLayoutThreshold;
927 void* m_transformSource;
928 RefPtr<Document> m_transformSourceDocument;
932 XBLBindingManager* m_bindingManager; // The access point through which documents and elements communicate with XBL.
935 typedef HashMap<AtomicStringImpl*, HTMLMapElement*> ImageMapsByName;
936 ImageMapsByName m_imageMapsByName;
938 HashSet<Node*> m_disconnectedNodesWithEventListeners;
940 int m_docID; // A unique document identifier used for things like document-specific mapped attributes.
942 String m_xmlEncoding;
944 bool m_xmlStandalone;
946 String m_contentLanguage;
949 bool inPageCache() const { return m_inPageCache; }
950 void setInPageCache(bool flag);
952 // Elements can register themselves for the "documentWillBecomeInactive()" and
953 // "documentDidBecomeActive()" callbacks
954 void registerForDocumentActivationCallbacks(Element*);
955 void unregisterForDocumentActivationCallbacks(Element*);
956 void documentWillBecomeInactive();
957 void documentDidBecomeActive();
959 void registerForMediaVolumeCallbacks(Element*);
960 void unregisterForMediaVolumeCallbacks(Element*);
961 void mediaVolumeDidChange();
963 void setShouldCreateRenderers(bool);
964 bool shouldCreateRenderers();
966 void setDecoder(PassRefPtr<TextResourceDecoder>);
967 TextResourceDecoder* decoder() const { return m_decoder.get(); }
969 String displayStringModifiedByEncoding(const String&) const;
970 PassRefPtr<StringImpl> displayStringModifiedByEncoding(PassRefPtr<StringImpl>) const;
971 void displayBufferModifiedByEncoding(UChar* buffer, unsigned len) const;
973 // Quirk for the benefit of Apple's Dictionary application.
974 void setFrameElementsShouldIgnoreScrolling(bool ignore) { m_frameElementsShouldIgnoreScrolling = ignore; }
975 bool frameElementsShouldIgnoreScrolling() const { return m_frameElementsShouldIgnoreScrolling; }
977 #if ENABLE(DASHBOARD_SUPPORT)
978 void setDashboardRegionsDirty(bool f) { m_dashboardRegionsDirty = f; }
979 bool dashboardRegionsDirty() const { return m_dashboardRegionsDirty; }
980 bool hasDashboardRegions () const { return m_hasDashboardRegions; }
981 void setHasDashboardRegions (bool f) { m_hasDashboardRegions = f; }
982 const Vector<DashboardRegionValue>& dashboardRegions() const;
983 void setDashboardRegions(const Vector<DashboardRegionValue>&);
986 void removeAllEventListenersFromAllNodes();
988 void registerDisconnectedNodeWithEventListeners(Node*);
989 void unregisterDisconnectedNodeWithEventListeners(Node*);
991 HTMLFormElement::CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; }
994 const SVGDocumentExtensions* svgExtensions();
995 SVGDocumentExtensions* accessSVGExtensions();
998 void initSecurityContext();
1000 // Explicitly override the security origin for this document.
1001 // Note: It is dangerous to change the security origin of a document
1002 // that already contains content.
1003 void setSecurityOrigin(SecurityOrigin*);
1005 bool processingLoadEvent() const { return m_processingLoadEvent; }
1007 #if ENABLE(DATABASE)
1008 void addOpenDatabase(Database*);
1009 void removeOpenDatabase(Database*);
1010 DatabaseThread* databaseThread(); // Creates the thread as needed, but not if it has been already terminated.
1011 void setHasOpenDatabases() { m_hasOpenDatabases = true; }
1012 bool hasOpenDatabases() { return m_hasOpenDatabases; }
1013 void stopDatabases();
1016 void setUsingGeolocation(bool f) { m_usingGeolocation = f; }
1017 bool usingGeolocation() const { return m_usingGeolocation; };
1020 void resetWMLPageState();
1024 void clearXMLVersion() { m_xmlVersion = String(); }
1028 void removeAllDisconnectedNodeEventListeners();
1029 void updateFocusAppearanceTimerFired(Timer<Document>*);
1030 void updateBaseURL();
1032 void cacheDocumentElement() const;
1034 RenderObject* m_savedRenderer;
1037 RefPtr<TextResourceDecoder> m_decoder;
1039 // We maintain the invariant that m_duplicateIds is the count of all elements with a given ID
1040 // excluding the one referenced in m_elementsById, if any. This means it one less than the total count
1041 // when the first node with a given ID is cached, otherwise the same as the total count.
1042 mutable HashMap<AtomicStringImpl*, Element*> m_elementsById;
1043 mutable HashCountedSet<AtomicStringImpl*> m_duplicateIds;
1045 mutable HashMap<StringImpl*, Element*, CaseFoldingHash> m_elementsByAccessKey;
1047 InheritedBool m_designMode;
1049 int m_selfOnlyRefCount;
1051 HTMLFormElement::CheckedRadioButtons m_checkedRadioButtons;
1053 typedef HashMap<AtomicStringImpl*, HTMLCollection::CollectionInfo*> NamedCollectionMap;
1054 HTMLCollection::CollectionInfo m_collectionInfo[HTMLCollection::NumUnnamedDocumentCachedTypes];
1055 NamedCollectionMap m_nameCollectionInfo[HTMLCollection::NumNamedDocumentCachedTypes];
1058 RefPtr<XPathEvaluator> m_xpathEvaluator;
1062 OwnPtr<SVGDocumentExtensions> m_svgExtensions;
1065 #if ENABLE(DASHBOARD_SUPPORT)
1066 Vector<DashboardRegionValue> m_dashboardRegions;
1067 bool m_hasDashboardRegions;
1068 bool m_dashboardRegionsDirty;
1071 HashMap<String, RefPtr<HTMLCanvasElement> > m_cssCanvasElements;
1073 mutable bool m_accessKeyMapValid;
1074 bool m_createRenderers;
1078 HashSet<Element*> m_documentActivationCallbackElements;
1079 HashSet<Element*> m_mediaVolumeCallbackElements;
1081 bool m_useSecureKeyboardEntryWhenActive;
1085 unsigned m_numNodeListCaches;
1088 typedef HashMap<WebCore::Node*, JSNode*> JSWrapperCache;
1089 JSWrapperCache& wrapperCache() { return m_wrapperCache; }
1091 JSWrapperCache m_wrapperCache;
1093 #if ENABLE(DATABASE)
1094 RefPtr<DatabaseThread> m_databaseThread;
1095 bool m_hasOpenDatabases; // This never changes back to false, even as the database thread is closed.
1096 typedef HashSet<Database*> DatabaseSet;
1097 OwnPtr<DatabaseSet> m_openDatabaseSet;
1100 bool m_usingGeolocation;
1103 inline bool Document::hasElementWithId(AtomicStringImpl* id) const
1106 return m_elementsById.contains(id) || m_duplicateIds.contains(id);
1109 inline bool Node::isDocumentNode() const
1111 return this == m_document.get();
1114 } // namespace WebCore
1116 #endif // Document_h