2007-12-29 Jan Michael Alonzo <jmalonzo@unpluggable.com>
[WebKit.git] / WebCore / dom / Document.cpp
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 Apple Inc. All rights reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 #include "config.h"
25 #include "Document.h"
26
27 #include "AXObjectCache.h"
28 #include "CDATASection.h"
29 #include "CSSHelper.h"
30 #include "CSSStyleSelector.h"
31 #include "CSSStyleSheet.h"
32 #include "CSSValueKeywords.h"
33 #include "ClassNodeList.h"
34 #include "Comment.h"
35 #include "CookieJar.h"
36 #include "DOMImplementation.h"
37 #include "DocLoader.h"
38 #include "DocumentFragment.h"
39 #include "DocumentLoader.h"
40 #include "DocumentType.h"
41 #include "EditingText.h"
42 #include "Editor.h"
43 #include "EditorClient.h"
44 #include "EntityReference.h"
45 #include "Event.h"
46 #include "EventHandler.h"
47 #include "EventListener.h"
48 #include "EventNames.h"
49 #include "ExceptionCode.h"
50 #include "FocusController.h"
51 #include "Frame.h"
52 #include "FrameLoader.h"
53 #include "FrameTree.h"
54 #include "FrameView.h"
55 #include "HTMLBodyElement.h"
56 #include "HTMLDocument.h"
57 #include "HTMLElementFactory.h"
58 #include "HTMLFrameOwnerElement.h"
59 #include "HTMLHeadElement.h"
60 #include "HTMLImageLoader.h"
61 #include "HTMLInputElement.h"
62 #include "HTMLLinkElement.h"
63 #include "HTMLMapElement.h"
64 #include "HTMLNameCollection.h"
65 #include "HTMLNames.h"
66 #include "HTMLStyleElement.h"
67 #include "HTMLTitleElement.h"
68 #include "HTTPParsers.h"
69 #include "HitTestRequest.h"
70 #include "HitTestResult.h"
71 #include "KeyboardEvent.h"
72 #include "Logging.h"
73 #include "MouseEvent.h"
74 #include "MouseEventWithHitTestResults.h"
75 #include "MutationEvent.h"
76 #include "NameNodeList.h"
77 #include "NodeFilter.h"
78 #include "NodeIterator.h"
79 #include "OverflowEvent.h"
80 #include "Page.h"
81 #include "PlatformKeyboardEvent.h"
82 #include "ProcessingInstruction.h"
83 #include "ProgressEvent.h"
84 #include "RegisteredEventListener.h"
85 #include "RegularExpression.h"
86 #include "RenderArena.h"
87 #include "RenderView.h"
88 #include "RenderWidget.h"
89 #include "SecurityOrigin.h"
90 #include "SegmentedString.h"
91 #include "SelectionController.h"
92 #include "Settings.h"
93 #include "StringHash.h"
94 #include "StyleSheetList.h"
95 #include "SystemTime.h"
96 #include "TextEvent.h"
97 #include "TextIterator.h"
98 #include "TextResourceDecoder.h"
99 #include "TreeWalker.h"
100 #include "UIEvent.h"
101 #include "WheelEvent.h"
102 #include "XMLHttpRequest.h"
103 #include "XMLTokenizer.h"
104 #include "kjs_binding.h"
105 #include "kjs_proxy.h"
106
107 #if ENABLE(DATABASE)
108 #include "DatabaseThread.h"
109 #endif
110
111 #if ENABLE(XPATH)
112 #include "XPathEvaluator.h"
113 #include "XPathExpression.h"
114 #include "XPathNSResolver.h"
115 #include "XPathResult.h"
116 #endif
117
118 #if ENABLE(XSLT)
119 #include "XSLTProcessor.h"
120 #endif
121
122 #if ENABLE(XBL)
123 #include "XBLBindingManager.h"
124 #endif
125
126 #if ENABLE(SVG)
127 #include "SVGDocumentExtensions.h"
128 #include "SVGElementFactory.h"
129 #include "SVGZoomEvent.h"
130 #include "SVGStyleElement.h"
131 #include "TimeScheduler.h"
132 #endif
133
134 using namespace std;
135 using namespace WTF;
136 using namespace Unicode;
137
138 namespace WebCore {
139
140 using namespace EventNames;
141 using namespace HTMLNames;
142
143 // #define INSTRUMENT_LAYOUT_SCHEDULING 1
144
145 // This amount of time must have elapsed before we will even consider scheduling a layout without a delay.
146 // FIXME: For faster machines this value can really be lowered to 200.  250 is adequate, but a little high
147 // for dual G5s. :)
148 static const int cLayoutScheduleThreshold = 250;
149
150 // Use 1 to represent the document's default form.
151 static HTMLFormElement* const defaultForm = reinterpret_cast<HTMLFormElement*>(1);
152
153 // Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
154 static const unsigned PHI = 0x9e3779b9U;
155
156 // DOM Level 2 says (letters added):
157 //
158 // a) Name start characters must have one of the categories Ll, Lu, Lo, Lt, Nl.
159 // b) Name characters other than Name-start characters must have one of the categories Mc, Me, Mn, Lm, or Nd.
160 // c) Characters in the compatibility area (i.e. with character code greater than #xF900 and less than #xFFFE) are not allowed in XML names.
161 // d) Characters which have a font or compatibility decomposition (i.e. those with a "compatibility formatting tag" in field 5 of the database -- marked by field 5 beginning with a "<") are not allowed.
162 // e) The following characters are treated as name-start characters rather than name characters, because the property file classifies them as Alphabetic: [#x02BB-#x02C1], #x0559, #x06E5, #x06E6.
163 // f) Characters #x20DD-#x20E0 are excluded (in accordance with Unicode, section 5.14).
164 // g) Character #x00B7 is classified as an extender, because the property list so identifies it.
165 // h) Character #x0387 is added as a name character, because #x00B7 is its canonical equivalent.
166 // i) Characters ':' and '_' are allowed as name-start characters.
167 // j) Characters '-' and '.' are allowed as name characters.
168 //
169 // It also contains complete tables. If we decide it's better, we could include those instead of the following code.
170
171 static inline bool isValidNameStart(UChar32 c)
172 {
173     // rule (e) above
174     if ((c >= 0x02BB && c <= 0x02C1) || c == 0x559 || c == 0x6E5 || c == 0x6E6)
175         return true;
176
177     // rule (i) above
178     if (c == ':' || c == '_')
179         return true;
180
181     // rules (a) and (f) above
182     const uint32_t nameStartMask = Letter_Lowercase | Letter_Uppercase | Letter_Other | Letter_Titlecase | Number_Letter;
183     if (!(Unicode::category(c) & nameStartMask))
184         return false;
185
186     // rule (c) above
187     if (c >= 0xF900 && c < 0xFFFE)
188         return false;
189
190     // rule (d) above
191     DecompositionType decompType = decompositionType(c);
192     if (decompType == DecompositionFont || decompType == DecompositionCompat)
193         return false;
194
195     return true;
196 }
197
198 static inline bool isValidNamePart(UChar32 c)
199 {
200     // rules (a), (e), and (i) above
201     if (isValidNameStart(c))
202         return true;
203
204     // rules (g) and (h) above
205     if (c == 0x00B7 || c == 0x0387)
206         return true;
207
208     // rule (j) above
209     if (c == '-' || c == '.')
210         return true;
211
212     // rules (b) and (f) above
213     const uint32_t otherNamePartMask = Mark_NonSpacing | Mark_Enclosing | Mark_SpacingCombining | Letter_Modifier | Number_DecimalDigit;
214     if (!(Unicode::category(c) & otherNamePartMask))
215         return false;
216
217     // rule (c) above
218     if (c >= 0xF900 && c < 0xFFFE)
219         return false;
220
221     // rule (d) above
222     DecompositionType decompType = decompositionType(c);
223     if (decompType == DecompositionFont || decompType == DecompositionCompat)
224         return false;
225
226     return true;
227 }
228
229 static Widget* widgetForNode(Node* focusedNode)
230   {
231     if (!focusedNode)
232         return 0;
233     RenderObject* renderer = focusedNode->renderer();
234     if (!renderer || !renderer->isWidget())
235         return 0;
236     return static_cast<RenderWidget*>(renderer)->widget();
237 }
238
239 static bool acceptsEditingFocus(Node *node)
240 {
241     ASSERT(node);
242     ASSERT(node->isContentEditable());
243
244     Node *root = node->rootEditableElement();
245     Frame* frame = node->document()->frame();
246     if (!frame || !root)
247         return false;
248
249     return frame->editor()->shouldBeginEditing(rangeOfContents(root).get());
250 }
251
252 DeprecatedPtrList<Document>*  Document::changedDocuments = 0;
253
254 // FrameView might be 0
255 Document::Document(DOMImplementation* impl, Frame* frame, bool isXHTML)
256     : ContainerNode(0)
257     , m_implementation(impl)
258     , m_domtree_version(0)
259     , m_styleSheets(new StyleSheetList(this))
260     , m_title("")
261     , m_titleSetExplicitly(false)
262     , m_imageLoadEventTimer(this, &Document::imageLoadEventTimerFired)
263     , m_updateFocusAppearanceTimer(this, &Document::updateFocusAppearanceTimerFired)
264 #if ENABLE(XSLT)
265     , m_transformSource(0)
266 #endif
267     , m_xmlVersion("1.0")
268     , m_xmlStandalone(false)
269 #if ENABLE(XBL)
270     , m_bindingManager(new XBLBindingManager(this))
271 #endif
272     , m_savedRenderer(0)
273     , m_secureForms(0)
274     , m_designMode(inherit)
275     , m_selfOnlyRefCount(0)
276 #if ENABLE(SVG)
277     , m_svgExtensions(0)
278 #endif
279     , m_hasDashboardRegions(false)
280     , m_dashboardRegionsDirty(false)
281     , m_accessKeyMapValid(false)
282     , m_createRenderers(true)
283     , m_inPageCache(false)
284     , m_isAllowedToLoadLocalResources(false)
285     , m_useSecureKeyboardEntryWhenActive(false)
286     , m_isXHTML(isXHTML)
287     , m_numNodeLists(0)
288 #if USE(LOW_BANDWIDTH_DISPLAY)
289     , m_inLowBandwidthDisplay(false)
290 #endif
291 {
292     m_document.resetSkippingRef(this);
293
294     m_printing = false;
295
296     m_frame = frame;
297     m_renderArena = 0;
298
299     m_axObjectCache = 0;
300     
301     // FIXME: DocLoader probably no longer needs the frame argument
302     m_docLoader = new DocLoader(frame, this);
303
304     visuallyOrdered = false;
305     m_bParsing = false;
306     m_docChanged = false;
307     m_tokenizer = 0;
308     m_wellFormed = false;
309
310     pMode = Strict;
311     hMode = XHtml;
312     m_textColor = Color::black;
313     m_listenerTypes = 0;
314     m_inDocument = true;
315     m_inStyleRecalc = false;
316     m_closeAfterStyleRecalc = false;
317     m_usesDescendantRules = false;
318     m_usesSiblingRules = false;
319     m_usesFirstLineRules = false;
320     m_usesFirstLetterRules = false;
321     m_gotoAnchorNeededAfterStylesheetsLoad = false;
322
323     bool matchAuthorAndUserStyles = true;
324     if (Settings* settings = this->settings())
325         matchAuthorAndUserStyles = settings->authorAndUserStylesEnabled();
326     m_styleSelector = new CSSStyleSelector(this, m_usersheet, m_styleSheets.get(), m_mappedElementSheet.get(), !inCompatMode(), matchAuthorAndUserStyles);
327
328     m_didCalculateStyleSelector = false;
329     m_pendingStylesheets = 0;
330     m_ignorePendingStylesheets = false;
331     m_hasNodesWithPlaceholderStyle = false;
332     m_pendingSheetLayout = NoLayoutWithPendingSheets;
333
334     m_cssTarget = 0;
335
336     resetLinkColor();
337     resetVisitedLinkColor();
338     resetActiveLinkColor();
339
340     m_processingLoadEvent = false;
341     m_startTime = currentTime();
342     m_overMinimumLayoutThreshold = false;
343     
344     initSecurityOrigin();
345
346     static int docID = 0;
347     m_docID = docID++;
348 }
349
350 void Document::removedLastRef()
351 {
352     ASSERT(!m_deletionHasBegun);
353     if (m_selfOnlyRefCount) {
354         // If removing a child removes the last self-only ref, we don't
355         // want the document to be destructed until after
356         // removeAllChildren returns, so we guard ourselves with an
357         // extra self-only ref.
358
359         DocPtr<Document> guard(this);
360
361         // We must make sure not to be retaining any of our children through
362         // these extra pointers or we will create a reference cycle.
363         m_docType = 0;
364         m_focusedNode = 0;
365         m_hoverNode = 0;
366         m_activeNode = 0;
367         m_titleElement = 0;
368         m_documentElement = 0;
369
370         removeAllChildren();
371
372         deleteAllValues(m_markers);
373         m_markers.clear();
374
375         delete m_tokenizer;
376         m_tokenizer = 0;
377
378 #ifndef NDEBUG
379         m_inRemovedLastRefFunction = false;
380 #endif
381     } else {
382 #ifndef NDEBUG
383         m_deletionHasBegun = true;
384 #endif
385         delete this;
386     }
387 }
388
389 Document::~Document()
390 {
391     ASSERT(!renderer());
392     ASSERT(!m_inPageCache);
393     ASSERT(!m_savedRenderer);
394
395     removeAllEventListeners();
396
397 #if ENABLE(SVG)
398     delete m_svgExtensions;
399 #endif
400
401     XMLHttpRequest::detachRequests(this);
402     {
403         KJS::JSLock lock;
404         KJS::ScriptInterpreter::forgetAllDOMNodesForDocument(this);
405     }
406
407     if (m_docChanged && changedDocuments)
408         changedDocuments->remove(this);
409     delete m_tokenizer;
410     m_document.resetSkippingRef(0);
411     delete m_styleSelector;
412     delete m_docLoader;
413     
414     if (m_renderArena) {
415         delete m_renderArena;
416         m_renderArena = 0;
417     }
418
419 #if ENABLE(XSLT)
420     xmlFreeDoc((xmlDocPtr)m_transformSource);
421 #endif
422
423 #if ENABLE(XBL)
424     delete m_bindingManager;
425 #endif
426
427     deleteAllValues(m_markers);
428
429     if (m_axObjectCache) {
430         delete m_axObjectCache;
431         m_axObjectCache = 0;
432     }
433     m_decoder = 0;
434     
435     unsigned count = sizeof(m_nameCollectionInfo) / sizeof(m_nameCollectionInfo[0]);
436     for (unsigned i = 0; i < count; i++)
437         deleteAllValues(m_nameCollectionInfo[i]);
438
439 #if ENABLE(DATABASE)
440     if (m_databaseThread) {
441         m_databaseThread->documentGoingAway();
442         m_databaseThread = 0;
443     }
444 #endif
445
446     if (m_styleSheets)
447         m_styleSheets->documentDestroyed();
448 }
449
450 void Document::resetLinkColor()
451 {
452     m_linkColor = Color(0, 0, 238);
453 }
454
455 void Document::resetVisitedLinkColor()
456 {
457     m_visitedLinkColor = Color(85, 26, 139);    
458 }
459
460 void Document::resetActiveLinkColor()
461 {
462     m_activeLinkColor.setNamedColor("red");
463 }
464
465 void Document::setDocType(PassRefPtr<DocumentType> docType)
466 {
467     m_docType = docType;
468 }
469
470 DocumentType *Document::doctype() const
471 {
472     return m_docType.get();
473 }
474
475 DOMImplementation* Document::implementation() const
476 {
477     return m_implementation.get();
478 }
479
480 void Document::childrenChanged()
481 {
482     // invalidate the document element we have cached in case it was replaced
483     m_documentElement = 0;
484 }
485
486 Element* Document::documentElement() const
487 {
488     if (!m_documentElement) {
489         Node* n = firstChild();
490         while (n && !n->isElementNode())
491             n = n->nextSibling();
492         m_documentElement = static_cast<Element*>(n);
493     }
494
495     return m_documentElement.get();
496 }
497
498 PassRefPtr<Element> Document::createElement(const String &name, ExceptionCode& ec)
499 {
500     if (m_isXHTML) {
501         if (!isValidName(name)) {
502             ec = INVALID_CHARACTER_ERR;
503             return 0;
504         }
505
506         return HTMLElementFactory::createHTMLElement(AtomicString(name), this, 0, false);
507     } else
508         return createElementNS(nullAtom, name, ec);
509 }
510
511 PassRefPtr<DocumentFragment> Document::createDocumentFragment()
512 {
513     return new DocumentFragment(document());
514 }
515
516 PassRefPtr<Text> Document::createTextNode(const String &data)
517 {
518     return new Text(this, data);
519 }
520
521 PassRefPtr<Comment> Document::createComment (const String &data)
522 {
523     return new Comment(this, data);
524 }
525
526 PassRefPtr<CDATASection> Document::createCDATASection(const String &data, ExceptionCode& ec)
527 {
528     if (isHTMLDocument()) {
529         ec = NOT_SUPPORTED_ERR;
530         return 0;
531     }
532     return new CDATASection(this, data);
533 }
534
535 PassRefPtr<ProcessingInstruction> Document::createProcessingInstruction(const String &target, const String &data, ExceptionCode& ec)
536 {
537     if (!isValidName(target)) {
538         ec = INVALID_CHARACTER_ERR;
539         return 0;
540     }
541     if (isHTMLDocument()) {
542         ec = NOT_SUPPORTED_ERR;
543         return 0;
544     }
545     return new ProcessingInstruction(this, target, data);
546 }
547
548 PassRefPtr<EntityReference> Document::createEntityReference(const String &name, ExceptionCode& ec)
549 {
550     if (!isValidName(name)) {
551         ec = INVALID_CHARACTER_ERR;
552         return 0;
553     }
554     if (isHTMLDocument()) {
555         ec = NOT_SUPPORTED_ERR;
556         return 0;
557     }
558     return new EntityReference(this, name);
559 }
560
561 PassRefPtr<EditingText> Document::createEditingTextNode(const String &text)
562 {
563     return new EditingText(this, text);
564 }
565
566 PassRefPtr<CSSStyleDeclaration> Document::createCSSStyleDeclaration()
567 {
568     return new CSSMutableStyleDeclaration;
569 }
570
571 PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionCode& ec)
572 {
573     ec = 0;
574     
575     if (!importedNode
576 #if ENABLE(SVG)
577         || (importedNode->isSVGElement() && page() && page()->settings()->usesDashboardBackwardCompatibilityMode())
578 #endif
579         ) {
580         ec = NOT_SUPPORTED_ERR;
581         return 0;
582     }
583
584     switch (importedNode->nodeType()) {
585         case TEXT_NODE:
586             return createTextNode(importedNode->nodeValue());
587         case CDATA_SECTION_NODE:
588             return createCDATASection(importedNode->nodeValue(), ec);
589         case ENTITY_REFERENCE_NODE:
590             return createEntityReference(importedNode->nodeName(), ec);
591         case PROCESSING_INSTRUCTION_NODE:
592             return createProcessingInstruction(importedNode->nodeName(), importedNode->nodeValue(), ec);
593         case COMMENT_NODE:
594             return createComment(importedNode->nodeValue());
595         case ELEMENT_NODE: {
596             Element* oldElement = static_cast<Element*>(importedNode);
597             RefPtr<Element> newElement = createElementNS(oldElement->namespaceURI(), oldElement->tagQName().toString(), ec);
598                         
599             if (ec)
600                 return 0;
601
602             NamedAttrMap* attrs = oldElement->attributes(true);
603             if (attrs) {
604                 unsigned length = attrs->length();
605                 for (unsigned i = 0; i < length; i++) {
606                     Attribute* attr = attrs->attributeItem(i);
607                     newElement->setAttribute(attr->name(), attr->value().impl(), ec);
608                     if (ec)
609                         return 0;
610                 }
611             }
612
613             newElement->copyNonAttributeProperties(oldElement);
614
615             if (deep) {
616                 for (Node* oldChild = oldElement->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
617                     RefPtr<Node> newChild = importNode(oldChild, true, ec);
618                     if (ec)
619                         return 0;
620                     newElement->appendChild(newChild.release(), ec);
621                     if (ec)
622                         return 0;
623                 }
624             }
625
626             return newElement.release();
627         }
628         case ATTRIBUTE_NODE: {
629             RefPtr<Attr> newAttr = new Attr(0, this, static_cast<Attr*>(importedNode)->attr()->clone());
630             newAttr->createTextChild();
631             return newAttr.release();
632         }
633         case DOCUMENT_FRAGMENT_NODE: {
634             DocumentFragment* oldFragment = static_cast<DocumentFragment*>(importedNode);
635             RefPtr<DocumentFragment> newFragment = createDocumentFragment();
636             if (deep) {
637                 for (Node* oldChild = oldFragment->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
638                     RefPtr<Node> newChild = importNode(oldChild, true, ec);
639                     if (ec)
640                         return 0;
641                     newFragment->appendChild(newChild.release(), ec);
642                     if (ec)
643                         return 0;
644                 }
645             }
646             
647             return newFragment.release();
648         }
649         case ENTITY_NODE:
650         case NOTATION_NODE:
651             // FIXME: It should be possible to import these node types, however in DOM3 the DocumentType is readonly, so there isn't much sense in doing that.
652             // Ability to add these imported nodes to a DocumentType will be considered for addition to a future release of the DOM.
653         case DOCUMENT_NODE:
654         case DOCUMENT_TYPE_NODE:
655         case XPATH_NAMESPACE_NODE:
656             break;
657     }
658
659     ec = NOT_SUPPORTED_ERR;
660     return 0;
661 }
662
663
664 PassRefPtr<Node> Document::adoptNode(PassRefPtr<Node> source, ExceptionCode& ec)
665 {
666     if (!source) {
667         ec = NOT_SUPPORTED_ERR;
668         return 0;
669     }
670     
671     switch (source->nodeType()) {
672         case ENTITY_NODE:
673         case NOTATION_NODE:
674         case DOCUMENT_NODE:
675         case DOCUMENT_TYPE_NODE:
676         case XPATH_NAMESPACE_NODE:
677             ec = NOT_SUPPORTED_ERR;
678             return 0;            
679         case ATTRIBUTE_NODE: {                   
680             Attr* attr = static_cast<Attr*>(source.get());
681             if (attr->ownerElement())
682                 attr->ownerElement()->removeAttributeNode(attr, ec);
683             attr->m_attrWasSpecifiedOrElementHasRareData = true;
684             break;
685         }       
686         default:
687             if (source->parentNode())
688                 source->parentNode()->removeChild(source.get(), ec);
689     }
690                 
691     for (Node* node = source.get(); node; node = node->traverseNextNode(source.get()))
692         node->setDocument(this);
693
694     return source;
695 }
696
697 // FIXME: This should really be in a possible ElementFactory class
698 PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool createdByParser, ExceptionCode& ec)
699 {
700     RefPtr<Element> e;
701
702     // FIXME: Use registered namespaces and look up in a hash to find the right factory.
703     if (qName.namespaceURI() == xhtmlNamespaceURI)
704         e = HTMLElementFactory::createHTMLElement(qName.localName(), this, 0, createdByParser);
705 #if ENABLE(SVG)
706     else if (qName.namespaceURI() == SVGNames::svgNamespaceURI)
707         e = SVGElementFactory::createSVGElement(qName, this, createdByParser);
708 #endif
709     
710     if (!e)
711         e = new Element(qName, document());
712     
713     if (e && !qName.prefix().isNull()) {
714         ec = 0;
715         e->setPrefix(qName.prefix(), ec);
716         if (ec)
717             return 0;
718     }    
719     
720     return e.release();
721 }
722
723 PassRefPtr<Element> Document::createElementNS(const String &_namespaceURI, const String &qualifiedName, ExceptionCode& ec)
724 {
725     String prefix, localName;
726     if (!parseQualifiedName(qualifiedName, prefix, localName)) {
727         ec = INVALID_CHARACTER_ERR;
728         return 0;
729     }
730
731     RefPtr<Element> e;
732     QualifiedName qName = QualifiedName(AtomicString(prefix), AtomicString(localName), AtomicString(_namespaceURI));
733     
734     return createElement(qName, false, ec);
735 }
736
737 Element *Document::getElementById(const AtomicString& elementId) const
738 {
739     if (elementId.length() == 0)
740         return 0;
741
742     Element *element = m_elementsById.get(elementId.impl());
743     if (element)
744         return element;
745
746     if (m_duplicateIds.contains(elementId.impl())) {
747         // We know there's at least one node with this id, but we don't know what the first one is.
748         for (Node *n = traverseNextNode(); n != 0; n = n->traverseNextNode()) {
749             if (n->isElementNode()) {
750                 element = static_cast<Element*>(n);
751                 if (element->hasID() && element->getAttribute(idAttr) == elementId) {
752                     m_duplicateIds.remove(elementId.impl());
753                     m_elementsById.set(elementId.impl(), element);
754                     return element;
755                 }
756             }
757         }
758         ASSERT_NOT_REACHED();
759     }
760     return 0;
761 }
762
763 String Document::readyState() const
764 {
765     if (Frame* f = frame()) {
766         if (f->loader()->isComplete()) 
767             return "complete";
768         if (parsing()) 
769             return "loading";
770       return "loaded";
771       // FIXME: What does "interactive" mean?
772       // FIXME: Missing support for "uninitialized".
773     }
774     return String();
775 }
776
777 String Document::inputEncoding() const
778 {
779     if (TextResourceDecoder* d = decoder())
780         return d->encoding().name();
781     return String();
782 }
783
784 String Document::defaultCharset() const
785 {
786     if (Settings* settings = this->settings())
787         return settings->defaultTextEncodingName();
788     return String();
789 }
790
791 void Document::setCharset(const String& charset)
792 {
793     if (!decoder())
794         return;
795     decoder()->setEncoding(charset, TextResourceDecoder::UserChosenEncoding);
796 }
797
798 void Document::setXMLVersion(const String& version, ExceptionCode& ec)
799 {
800     // FIXME: also raise NOT_SUPPORTED_ERR if the version is set to a value that is not supported by this Document.
801     if (!implementation()->hasFeature("XML", String())) {
802         ec = NOT_SUPPORTED_ERR;
803         return;
804     }
805    
806     m_xmlVersion = version;
807 }
808
809 void Document::setXMLStandalone(bool standalone, ExceptionCode& ec)
810 {
811     if (!implementation()->hasFeature("XML", String())) {
812         ec = NOT_SUPPORTED_ERR;
813         return;
814     }
815
816     m_xmlStandalone = standalone;
817 }
818
819 String Document::documentURI() const
820 {
821     return m_baseURL;
822 }
823
824 void Document::setDocumentURI(const String &uri)
825 {
826     m_baseURL = uri.deprecatedString();
827 }
828
829 String Document::baseURI() const
830 {
831     return documentURI();
832 }
833
834 Element* Document::elementFromPoint(int x, int y) const
835 {
836     if (!renderer())
837         return 0;
838
839     HitTestRequest request(true, true);
840     HitTestResult result(IntPoint(x, y));
841     renderer()->layer()->hitTest(request, result); 
842
843     Node* n = result.innerNode();
844     while (n && !n->isElementNode())
845         n = n->parentNode();
846     if (n)
847         n = n->shadowAncestorNode();
848     return static_cast<Element*>(n);
849 }
850
851 void Document::addElementById(const AtomicString& elementId, Element* element)
852 {
853     typedef HashMap<AtomicStringImpl*, Element*>::iterator iterator;
854     if (!m_duplicateIds.contains(elementId.impl())) {
855         // Fast path. The ID is not already in m_duplicateIds, so we assume that it's
856         // also not already in m_elementsById and do an add. If that add succeeds, we're done.
857         pair<iterator, bool> addResult = m_elementsById.add(elementId.impl(), element);
858         if (addResult.second)
859             return;
860         // The add failed, so this ID was already cached in m_elementsById.
861         // There are multiple elements with this ID. Remove the m_elementsById
862         // cache for this ID so getElementById searches for it next time it is called.
863         m_elementsById.remove(addResult.first);
864         m_duplicateIds.add(elementId.impl());
865     } else {
866         // There are multiple elements with this ID. If it exists, remove the m_elementsById
867         // cache for this ID so getElementById searches for it next time it is called.
868         iterator cachedItem = m_elementsById.find(elementId.impl());
869         if (cachedItem != m_elementsById.end()) {
870             m_elementsById.remove(cachedItem);
871             m_duplicateIds.add(elementId.impl());
872         }
873     }
874     m_duplicateIds.add(elementId.impl());
875 }
876
877 void Document::removeElementById(const AtomicString& elementId, Element* element)
878 {
879     if (m_elementsById.get(elementId.impl()) == element)
880         m_elementsById.remove(elementId.impl());
881     else
882         m_duplicateIds.remove(elementId.impl());
883 }
884
885 Element* Document::getElementByAccessKey(const String& key) const
886 {
887     if (key.isEmpty())
888         return 0;
889     if (!m_accessKeyMapValid) {
890         for (Node* n = firstChild(); n; n = n->traverseNextNode()) {
891             if (!n->isElementNode())
892                 continue;
893             Element* element = static_cast<Element*>(n);
894             const AtomicString& accessKey = element->getAttribute(accesskeyAttr);
895             if (!accessKey.isEmpty())
896                 m_elementsByAccessKey.set(accessKey.impl(), element);
897         }
898         m_accessKeyMapValid = true;
899     }
900     return m_elementsByAccessKey.get(key.impl());
901 }
902
903 void Document::updateTitle()
904 {
905     if (Frame* f = frame())
906         f->loader()->setTitle(m_title);
907 }
908
909 void Document::setTitle(const String& title, Element* titleElement)
910 {
911     if (!titleElement) {
912         // Title set by JavaScript -- overrides any title elements.
913         m_titleSetExplicitly = true;
914         if (!isHTMLDocument())
915             m_titleElement = 0;
916         else if (!m_titleElement) {
917             if (HTMLElement* headElement = head()) {
918                 ExceptionCode ec = 0;
919                 m_titleElement = createElement("title", ec);
920                 ASSERT(!ec);
921                 headElement->appendChild(m_titleElement, ec);
922                 ASSERT(!ec);
923             }
924         }
925     } else if (titleElement != m_titleElement) {
926         if (m_titleElement || m_titleSetExplicitly)
927             // Only allow the first title element to change the title -- others have no effect.
928             return;
929         m_titleElement = titleElement;
930     }
931
932     if (m_title == title)
933         return;
934
935     m_title = title;
936     updateTitle();
937
938     if (m_titleSetExplicitly && m_titleElement && m_titleElement->hasTagName(titleTag))
939         static_cast<HTMLTitleElement*>(m_titleElement.get())->setText(m_title);
940 }
941
942 void Document::removeTitle(Element* titleElement)
943 {
944     if (m_titleElement != titleElement)
945         return;
946
947     m_titleElement = 0;
948     m_titleSetExplicitly = false;
949
950     // Update title based on first title element in the head, if one exists.
951     if (HTMLElement* headElement = head()) {
952         for (Node* e = headElement->firstChild(); e; e = e->nextSibling())
953             if (e->hasTagName(titleTag)) {
954                 HTMLTitleElement* titleElement = static_cast<HTMLTitleElement*>(e);
955                 setTitle(titleElement->text(), titleElement);
956                 break;
957             }
958     }
959
960     if (!m_titleElement && !m_title.isEmpty()) {
961         m_title = "";
962         updateTitle();
963     }
964 }
965
966 String Document::nodeName() const
967 {
968     return "#document";
969 }
970
971 Node::NodeType Document::nodeType() const
972 {
973     return DOCUMENT_NODE;
974 }
975
976 FrameView* Document::view() const
977 {
978     return m_frame ? m_frame->view() : 0;
979 }
980
981 Page* Document::page() const
982 {
983     return m_frame ? m_frame->page() : 0;    
984 }
985
986 Settings* Document::settings() const
987 {
988     return m_frame ? m_frame->settings() : 0;
989 }
990
991 PassRefPtr<Range> Document::createRange()
992 {
993     return new Range(this);
994 }
995
996 PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, 
997     NodeFilter* filter, bool expandEntityReferences, ExceptionCode& ec)
998 {
999     if (!root) {
1000         ec = NOT_SUPPORTED_ERR;
1001         return 0;
1002     }
1003     return new NodeIterator(root, whatToShow, filter, expandEntityReferences);
1004 }
1005
1006 PassRefPtr<TreeWalker> Document::createTreeWalker(Node *root, unsigned whatToShow, 
1007     NodeFilter* filter, bool expandEntityReferences, ExceptionCode& ec)
1008 {
1009     if (!root) {
1010         ec = NOT_SUPPORTED_ERR;
1011         return 0;
1012     }
1013     return new TreeWalker(root, whatToShow, filter, expandEntityReferences);
1014 }
1015
1016 void Document::setDocumentChanged(bool b)
1017 {
1018     if (b) {
1019         if (!m_docChanged) {
1020             if (!changedDocuments)
1021                 changedDocuments = new DeprecatedPtrList<Document>;
1022             changedDocuments->append(this);
1023         }
1024         if (m_accessKeyMapValid) {
1025             m_accessKeyMapValid = false;
1026             m_elementsByAccessKey.clear();
1027         }
1028     } else {
1029         if (m_docChanged && changedDocuments)
1030             changedDocuments->remove(this);
1031     }
1032
1033     m_docChanged = b;
1034 }
1035
1036 void Document::recalcStyle(StyleChange change)
1037 {
1038     // we should not enter style recalc while painting
1039     if (frame() && frame()->isPainting()) {
1040         ASSERT(!frame()->isPainting());
1041         return;
1042     }
1043     
1044     if (m_inStyleRecalc)
1045         return; // Guard against re-entrancy. -dwh
1046         
1047     m_inStyleRecalc = true;
1048     suspendPostAttachCallbacks();
1049     
1050     ASSERT(!renderer() || renderArena());
1051     if (!renderer() || !renderArena())
1052         goto bail_out;
1053
1054     if (change == Force) {
1055         // style selector may set this again during recalc
1056         m_hasNodesWithPlaceholderStyle = false;
1057         
1058         RenderStyle* oldStyle = renderer()->style();
1059         if (oldStyle)
1060             oldStyle->ref();
1061         RenderStyle* _style = new (m_renderArena) RenderStyle();
1062         _style->ref();
1063         _style->setDisplay(BLOCK);
1064         _style->setVisuallyOrdered(visuallyOrdered);
1065         // ### make the font stuff _really_ work!!!!
1066
1067         FontDescription fontDescription;
1068         fontDescription.setUsePrinterFont(printing());
1069         if (Settings* settings = this->settings()) {
1070             fontDescription.setRenderingMode(settings->fontRenderingMode());
1071             if (printing() && !settings->shouldPrintBackgrounds())
1072                 _style->setForceBackgroundsToWhite(true);
1073             const AtomicString& stdfont = settings->standardFontFamily();
1074             if (!stdfont.isEmpty()) {
1075                 fontDescription.firstFamily().setFamily(stdfont);
1076                 fontDescription.firstFamily().appendFamily(0);
1077             }
1078             fontDescription.setKeywordSize(CSS_VAL_MEDIUM - CSS_VAL_XX_SMALL + 1);
1079             m_styleSelector->setFontSize(fontDescription, m_styleSelector->fontSizeForKeyword(CSS_VAL_MEDIUM, inCompatMode(), false));
1080         }
1081
1082         _style->setFontDescription(fontDescription);
1083         _style->font().update(m_styleSelector->fontSelector());
1084         if (inCompatMode())
1085             _style->setHtmlHacks(true); // enable html specific rendering tricks
1086
1087         StyleChange ch = diff(_style, oldStyle);
1088         if (renderer() && ch != NoChange)
1089             renderer()->setStyle(_style);
1090         if (change != Force)
1091             change = ch;
1092
1093         _style->deref(m_renderArena);
1094         if (oldStyle)
1095             oldStyle->deref(m_renderArena);
1096     }
1097
1098     for (Node* n = firstChild(); n; n = n->nextSibling())
1099         if (change >= Inherit || n->hasChangedChild() || n->changed())
1100             n->recalcStyle(change);
1101
1102     if (changed() && view())
1103         view()->layout();
1104
1105 bail_out:
1106     setChanged(NoStyleChange);
1107     setHasChangedChild(false);
1108     setDocumentChanged(false);
1109     
1110     resumePostAttachCallbacks();
1111     m_inStyleRecalc = false;
1112     
1113     // If we wanted to call implicitClose() during recalcStyle, do so now that we're finished.
1114     if (m_closeAfterStyleRecalc) {
1115         m_closeAfterStyleRecalc = false;
1116         implicitClose();
1117     }
1118 }
1119
1120 void Document::updateRendering()
1121 {
1122     if (hasChangedChild())
1123         recalcStyle(NoChange);
1124 }
1125
1126 void Document::updateDocumentsRendering()
1127 {
1128     if (!changedDocuments)
1129         return;
1130
1131     while (Document* doc = changedDocuments->take()) {
1132         doc->m_docChanged = false;
1133         doc->updateRendering();
1134     }
1135 }
1136
1137 void Document::updateLayout()
1138 {
1139     if (Element* oe = ownerElement())
1140         oe->document()->updateLayout();
1141
1142     // FIXME: Dave Hyatt's pretty sure we can remove this because layout calls recalcStyle as needed.
1143     updateRendering();
1144
1145     // Only do a layout if changes have occurred that make it necessary.      
1146     FrameView* v = view();
1147     if (v && renderer() && (v->layoutPending() || renderer()->needsLayout()))
1148         v->layout();
1149 }
1150
1151 // FIXME: This is a bad idea and needs to be removed eventually.
1152 // Other browsers load stylesheets before they continue parsing the web page.
1153 // Since we don't, we can run JavaScript code that needs answers before the
1154 // stylesheets are loaded. Doing a layout ignoring the pending stylesheets
1155 // lets us get reasonable answers. The long term solution to this problem is
1156 // to instead suspend JavaScript execution.
1157 void Document::updateLayoutIgnorePendingStylesheets()
1158 {
1159     bool oldIgnore = m_ignorePendingStylesheets;
1160     
1161     if (!haveStylesheetsLoaded()) {
1162         m_ignorePendingStylesheets = true;
1163         // FIXME: We are willing to attempt to suppress painting with outdated style info only once.  Our assumption is that it would be
1164         // dangerous to try to stop it a second time, after page content has already been loaded and displayed
1165         // with accurate style information.  (Our suppression involves blanking the whole page at the
1166         // moment.  If it were more refined, we might be able to do something better.)
1167         // It's worth noting though that this entire method is a hack, since what we really want to do is
1168         // suspend JS instead of doing a layout with inaccurate information.
1169         if (body() && !body()->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
1170             m_pendingSheetLayout = DidLayoutWithPendingSheets;
1171             updateStyleSelector();
1172         } else if (m_hasNodesWithPlaceholderStyle)
1173             // If new nodes have been added or style recalc has been done with style sheets still pending, some nodes 
1174             // may not have had their real style calculated yet. Normally this gets cleaned when style sheets arrive 
1175             // but here we need up-to-date style immediatly.
1176             recalcStyle(Force);
1177     }
1178
1179     updateLayout();
1180
1181     m_ignorePendingStylesheets = oldIgnore;
1182 }
1183
1184 void Document::attach()
1185 {
1186     ASSERT(!attached());
1187     ASSERT(!m_inPageCache);
1188
1189     if (!m_renderArena)
1190         m_renderArena = new RenderArena();
1191     
1192     // Create the rendering tree
1193     setRenderer(new (m_renderArena) RenderView(this, view()));
1194
1195     recalcStyle(Force);
1196
1197     RenderObject* render = renderer();
1198     setRenderer(0);
1199
1200     ContainerNode::attach();
1201
1202     setRenderer(render);
1203 }
1204
1205 void Document::detach()
1206 {
1207     ASSERT(attached());
1208     ASSERT(!m_inPageCache);
1209
1210     RenderObject* render = renderer();
1211
1212     // indicate destruction mode,  i.e. attached() but renderer == 0
1213     setRenderer(0);
1214     
1215     // Empty out these lists as a performance optimization, since detaching
1216     // all the individual render objects will cause all the RenderImage
1217     // objects to remove themselves from the lists.
1218     m_imageLoadEventDispatchSoonList.clear();
1219     m_imageLoadEventDispatchingList.clear();
1220     
1221     m_hoverNode = 0;
1222     m_focusedNode = 0;
1223     m_activeNode = 0;
1224
1225     ContainerNode::detach();
1226
1227     if (render)
1228         render->destroy();
1229
1230     // FIXME: is this needed or desirable?
1231     m_frame = 0;
1232     
1233     if (m_renderArena) {
1234         delete m_renderArena;
1235         m_renderArena = 0;
1236     }
1237 }
1238
1239 void Document::removeAllEventListenersFromAllNodes()
1240 {
1241     m_windowEventListeners.clear();
1242     removeAllDisconnectedNodeEventListeners();
1243     for (Node *n = this; n; n = n->traverseNextNode()) {
1244         if (!n->isEventTargetNode())
1245             continue;
1246         EventTargetNodeCast(n)->removeAllEventListeners();
1247     }
1248 }
1249
1250 void Document::registerDisconnectedNodeWithEventListeners(Node* node)
1251 {
1252     m_disconnectedNodesWithEventListeners.add(node);
1253 }
1254
1255 void Document::unregisterDisconnectedNodeWithEventListeners(Node* node)
1256 {
1257     m_disconnectedNodesWithEventListeners.remove(node);
1258 }
1259
1260 void Document::removeAllDisconnectedNodeEventListeners()
1261 {
1262     HashSet<Node*>::iterator end = m_disconnectedNodesWithEventListeners.end();
1263     for (HashSet<Node*>::iterator i = m_disconnectedNodesWithEventListeners.begin(); i != end; ++i)
1264         EventTargetNodeCast(*i)->removeAllEventListeners();
1265     m_disconnectedNodesWithEventListeners.clear();
1266 }
1267
1268 AXObjectCache* Document::axObjectCache() const
1269 {
1270     // The only document that actually has a AXObjectCache is the top-level
1271     // document.  This is because we need to be able to get from any WebCoreAXObject
1272     // to any other WebCoreAXObject on the same page.  Using a single cache allows
1273     // lookups across nested webareas (i.e. multiple documents).
1274     
1275     if (m_axObjectCache) {
1276         // return already known top-level cache
1277         if (!ownerElement())
1278             return m_axObjectCache;
1279         
1280         // In some pages with frames, the cache is created before the sub-webarea is
1281         // inserted into the tree.  Here, we catch that case and just toss the old
1282         // cache and start over.
1283         delete m_axObjectCache;
1284         m_axObjectCache = 0;
1285     }
1286
1287     // ask the top-level document for its cache
1288     Document* doc = topDocument();
1289     if (doc != this)
1290         return doc->axObjectCache();
1291     
1292     // this is the top-level document, so install a new cache
1293     m_axObjectCache = new AXObjectCache;
1294     return m_axObjectCache;
1295 }
1296
1297 void Document::setVisuallyOrdered()
1298 {
1299     visuallyOrdered = true;
1300     if (renderer())
1301         renderer()->style()->setVisuallyOrdered(true);
1302 }
1303
1304 Tokenizer* Document::createTokenizer()
1305 {
1306     // FIXME: this should probably pass the frame instead
1307     return new XMLTokenizer(this, view());
1308 }
1309
1310 void Document::open()
1311 {
1312     // This is work that we should probably do in clear(), but we can't have it
1313     // happen when implicitOpen() is called unless we reorganize Frame code.
1314     if (Document *parent = parentDocument()) {
1315         if (m_url.isEmpty() || m_url == "about:blank")
1316             setURL(parent->baseURL());
1317         if (m_baseURL.isEmpty() || m_baseURL == "about:blank")
1318             setBaseURL(parent->baseURL());
1319     }
1320
1321     if (m_frame) {
1322         if (m_frame->loader()->isLoadingMainResource() || (tokenizer() && tokenizer()->executingScript()))
1323             return;
1324     
1325         if (m_frame->loader()->state() == FrameStateProvisional)
1326             m_frame->loader()->stopAllLoaders();
1327     }
1328     
1329     implicitOpen();
1330
1331     if (m_frame)
1332         m_frame->loader()->didExplicitOpen();
1333 }
1334
1335 void Document::cancelParsing()
1336 {
1337     if (m_tokenizer) {
1338         // We have to clear the tokenizer to avoid possibly triggering
1339         // the onload handler when closing as a side effect of a cancel-style
1340         // change, such as opening a new document or closing the window while
1341         // still parsing
1342         delete m_tokenizer;
1343         m_tokenizer = 0;
1344         close();
1345     }
1346 }
1347
1348 void Document::implicitOpen()
1349 {
1350     cancelParsing();
1351
1352     clear();
1353     m_tokenizer = createTokenizer();
1354     setParsing(true);
1355 }
1356
1357 HTMLElement* Document::body()
1358 {
1359     Node* de = documentElement();
1360     if (!de)
1361         return 0;
1362     
1363     // try to prefer a FRAMESET element over BODY
1364     Node* body = 0;
1365     for (Node* i = de->firstChild(); i; i = i->nextSibling()) {
1366         if (i->hasTagName(framesetTag))
1367             return static_cast<HTMLElement*>(i);
1368         
1369         if (i->hasTagName(bodyTag))
1370             body = i;
1371     }
1372     return static_cast<HTMLElement*>(body);
1373 }
1374
1375 void Document::setBody(PassRefPtr<HTMLElement> newBody, ExceptionCode& ec)
1376 {
1377     if (!newBody) { 
1378         ec = HIERARCHY_REQUEST_ERR;
1379         return;
1380     }
1381
1382     HTMLElement* b = body();
1383     if (!b)
1384         documentElement()->appendChild(newBody, ec);
1385     else
1386         documentElement()->replaceChild(newBody, b, ec);
1387 }
1388
1389 HTMLHeadElement* Document::head()
1390 {
1391     Node* de = documentElement();
1392     if (!de)
1393         return 0;
1394
1395     for (Node* e = de->firstChild(); e; e = e->nextSibling())
1396         if (e->hasTagName(headTag))
1397             return static_cast<HTMLHeadElement*>(e);
1398
1399     return 0;
1400 }
1401
1402 void Document::close()
1403 {
1404     Frame* frame = this->frame();
1405     if (frame) {
1406         // This code calls implicitClose() if all loading has completed.
1407         FrameLoader* frameLoader = frame->loader();
1408         frameLoader->endIfNotLoadingMainResource();
1409         frameLoader->checkCompleted();
1410     } else {
1411         // Because we have no frame, we don't know if all loading has completed,
1412         // so we just call implicitClose() immediately. FIXME: This might fire
1413         // the load event prematurely <http://bugs.webkit.org/show_bug.cgi?id=14568>.
1414         implicitClose();
1415     }
1416 }
1417
1418 void Document::implicitClose()
1419 {
1420     // If we're in the middle of recalcStyle, we need to defer the close until the style information is accurate and all elements are re-attached.
1421     if (m_inStyleRecalc) {
1422         m_closeAfterStyleRecalc = true;
1423         return;
1424     }
1425
1426     bool wasLocationChangePending = frame() && frame()->loader()->isScheduledLocationChangePending();
1427     bool doload = !parsing() && m_tokenizer && !m_processingLoadEvent && !wasLocationChangePending;
1428     
1429     if (!doload)
1430         return;
1431
1432     m_processingLoadEvent = true;
1433
1434     m_wellFormed = m_tokenizer && m_tokenizer->wellFormed();
1435
1436     // We have to clear the tokenizer, in case someone document.write()s from the
1437     // onLoad event handler, as in Radar 3206524.
1438     delete m_tokenizer;
1439     m_tokenizer = 0;
1440
1441     // Create a body element if we don't already have one. See Radar 3758785.
1442     if (!this->body() && isHTMLDocument()) {
1443         if (Node* documentElement = this->documentElement()) {
1444             ExceptionCode ec = 0;
1445             documentElement->appendChild(new HTMLBodyElement(this), ec);
1446             ASSERT(!ec);
1447         }
1448     }
1449     
1450     dispatchImageLoadEventsNow();
1451     this->dispatchWindowEvent(loadEvent, false, false);
1452     if (Frame* f = frame())
1453         f->loader()->handledOnloadEvents();
1454 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
1455     if (!ownerElement())
1456         printf("onload fired at %d\n", elapsedTime());
1457 #endif
1458
1459     m_processingLoadEvent = false;
1460
1461     // An event handler may have removed the frame
1462     if (!frame())
1463         return;
1464
1465     // Make sure both the initial layout and reflow happen after the onload
1466     // fires. This will improve onload scores, and other browsers do it.
1467     // If they wanna cheat, we can too. -dwh
1468
1469     if (frame()->loader()->isScheduledLocationChangePending() && elapsedTime() < cLayoutScheduleThreshold) {
1470         // Just bail out. Before or during the onload we were shifted to another page.
1471         // The old i-Bench suite does this. When this happens don't bother painting or laying out.        
1472         view()->unscheduleRelayout();
1473         return;
1474     }
1475
1476     frame()->loader()->checkCallImplicitClose();
1477
1478     // Now do our painting/layout, but only if we aren't in a subframe or if we're in a subframe
1479     // that has been sized already.  Otherwise, our view size would be incorrect, so doing any 
1480     // layout/painting now would be pointless.
1481     if (!ownerElement() || (ownerElement()->renderer() && !ownerElement()->renderer()->needsLayout())) {
1482         updateRendering();
1483         
1484         // Always do a layout after loading if needed.
1485         if (view() && renderer() && (!renderer()->firstChild() || renderer()->needsLayout()))
1486             view()->layout();
1487             
1488         // Paint immediately after the document is ready.  We do this to ensure that any timers set by the
1489         // onload don't have a chance to fire before we would have painted.  To avoid over-flushing we only
1490         // worry about this for the top-level document.
1491 #if !PLATFORM(MAC)
1492         // FIXME: This causes a timing issue with the dispatchDidFinishLoad delegate callback.
1493         // See <rdar://problem/5092361>
1494         if (view() && !ownerElement())
1495             view()->update();
1496 #endif
1497     }
1498
1499 #if PLATFORM(MAC)
1500     if (renderer() && AXObjectCache::accessibilityEnabled())
1501         axObjectCache()->postNotificationToElement(renderer(), "AXLoadComplete");
1502 #endif
1503
1504 #if ENABLE(SVG)
1505     // FIXME: Officially, time 0 is when the outermost <svg> receives its
1506     // SVGLoad event, but we don't implement those yet.  This is close enough
1507     // for now.  In some cases we should have fired earlier.
1508     if (svgExtensions())
1509         accessSVGExtensions()->startAnimations();
1510 #endif
1511 }
1512
1513 void Document::setParsing(bool b)
1514 {
1515     m_bParsing = b;
1516     if (!m_bParsing && view())
1517         view()->scheduleRelayout();
1518
1519 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
1520     if (!ownerElement() && !m_bParsing)
1521         printf("Parsing finished at %d\n", elapsedTime());
1522 #endif
1523 }
1524
1525 bool Document::shouldScheduleLayout()
1526 {
1527     // We can update layout if:
1528     // (a) we actually need a layout
1529     // (b) our stylesheets are all loaded
1530     // (c) we have a <body>
1531     return (renderer() && renderer()->needsLayout() && haveStylesheetsLoaded() &&
1532             documentElement() && documentElement()->renderer() &&
1533             (!documentElement()->hasTagName(htmlTag) || body()));
1534 }
1535
1536 int Document::minimumLayoutDelay()
1537 {
1538     if (m_overMinimumLayoutThreshold)
1539         return 0;
1540     
1541     int elapsed = elapsedTime();
1542     m_overMinimumLayoutThreshold = elapsed > cLayoutScheduleThreshold;
1543     
1544     // We'll want to schedule the timer to fire at the minimum layout threshold.
1545     return max(0, cLayoutScheduleThreshold - elapsed);
1546 }
1547
1548 int Document::elapsedTime() const
1549 {
1550     return static_cast<int>((currentTime() - m_startTime) * 1000);
1551 }
1552
1553 void Document::write(const DeprecatedString& text)
1554 {
1555     write(String(text));
1556 }
1557
1558 void Document::write(const String& text)
1559 {
1560 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
1561     if (!ownerElement())
1562         printf("Beginning a document.write at %d\n", elapsedTime());
1563 #endif
1564     
1565     if (!m_tokenizer) {
1566         open();
1567         ASSERT(m_tokenizer);
1568         if (!m_tokenizer)
1569             return;
1570         write(DeprecatedString("<html>"));
1571     }
1572     m_tokenizer->write(text, false);
1573     
1574 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
1575     if (!ownerElement())
1576         printf("Ending a document.write at %d\n", elapsedTime());
1577 #endif    
1578 }
1579
1580 void Document::writeln(const String &text)
1581 {
1582     write(text);
1583     write(String("\n"));
1584 }
1585
1586 void Document::finishParsing()
1587 {
1588 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
1589     if (!ownerElement())
1590         printf("Received all data at %d\n", elapsedTime());
1591 #endif
1592     
1593     // Let the tokenizer go through as much data as it can.  There will be three possible outcomes after
1594     // finish() is called:
1595     // (1) All remaining data is parsed, document isn't loaded yet
1596     // (2) All remaining data is parsed, document is loaded, tokenizer gets deleted
1597     // (3) Data is still remaining to be parsed.
1598     if (m_tokenizer)
1599         m_tokenizer->finish();
1600 }
1601
1602 void Document::clear()
1603 {
1604     delete m_tokenizer;
1605     m_tokenizer = 0;
1606
1607     removeChildren();
1608
1609     m_windowEventListeners.clear();
1610 }
1611
1612 void Document::setURL(const DeprecatedString& url)
1613 {
1614     if (url == m_url)
1615         return;
1616
1617     m_url = url;
1618     if (m_styleSelector)
1619         m_styleSelector->setEncodedURL(m_url);
1620
1621     m_isAllowedToLoadLocalResources = shouldBeAllowedToLoadLocalResources();
1622  }
1623  
1624 bool Document::shouldBeAllowedToLoadLocalResources() const
1625 {
1626     if (FrameLoader::shouldTreatURLAsLocal(m_url))
1627         return true;
1628
1629     Frame* frame = this->frame();
1630     if (!frame)
1631         return false;
1632     
1633     DocumentLoader* documentLoader = frame->loader()->documentLoader();
1634     if (!documentLoader)
1635         return false;
1636
1637     if (m_url == "about:blank" && frame->loader()->opener() && frame->loader()->opener()->document()->isAllowedToLoadLocalResources())
1638         return true;
1639     
1640     return documentLoader->substituteData().isValid();
1641 }
1642
1643 void Document::setBaseURL(const DeprecatedString& baseURL) 
1644
1645     m_baseURL = baseURL; 
1646     if (m_elemSheet)
1647         m_elemSheet->setHref(m_baseURL);
1648 }
1649
1650 void Document::setCSSStyleSheet(const String &url, const String& charset, const String &sheet)
1651 {
1652     m_sheet = new CSSStyleSheet(this, url, charset);
1653     m_sheet->parseString(sheet);
1654
1655     updateStyleSelector();
1656 }
1657
1658 void Document::setUserStyleSheet(const String& sheet)
1659 {
1660     if (m_usersheet != sheet) {
1661         m_usersheet = sheet;
1662         updateStyleSelector();
1663     }
1664 }
1665
1666 CSSStyleSheet* Document::elementSheet()
1667 {
1668     if (!m_elemSheet)
1669         m_elemSheet = new CSSStyleSheet(this, baseURL());
1670     return m_elemSheet.get();
1671 }
1672
1673 CSSStyleSheet* Document::mappedElementSheet()
1674 {
1675     if (!m_mappedElementSheet)
1676         m_mappedElementSheet = new CSSStyleSheet(this, baseURL());
1677     return m_mappedElementSheet.get();
1678 }
1679
1680 void Document::determineParseMode(const String&)
1681 {
1682     // For XML documents use strict parse mode.
1683     // HTML overrides this method to determine the parse mode.
1684     pMode = Strict;
1685     hMode = XHtml;
1686 }
1687
1688 static Node* nextNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
1689 {
1690     // Search is inclusive of start
1691     for (Node* n = start; n; n = n->traverseNextNode())
1692         if (n->isKeyboardFocusable(event) && n->tabIndex() == tabIndex)
1693             return n;
1694     
1695     return 0;
1696 }
1697
1698 static Node* previousNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
1699 {
1700     // Search is inclusive of start
1701     for (Node* n = start; n; n = n->traversePreviousNode())
1702         if (n->isKeyboardFocusable(event) && n->tabIndex() == tabIndex)
1703             return n;
1704     
1705     return 0;
1706 }
1707
1708 static Node* nextNodeWithGreaterTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
1709 {
1710     // Search is inclusive of start
1711     int winningTabIndex = SHRT_MAX + 1;
1712     Node* winner = 0;
1713     for (Node* n = start; n; n = n->traverseNextNode())
1714         if (n->isKeyboardFocusable(event) && n->tabIndex() > tabIndex && n->tabIndex() < winningTabIndex) {
1715             winner = n;
1716             winningTabIndex = n->tabIndex();
1717         }
1718     
1719     return winner;
1720 }
1721
1722 static Node* previousNodeWithLowerTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
1723 {
1724     // Search is inclusive of start
1725     int winningTabIndex = 0;
1726     Node* winner = 0;
1727     for (Node* n = start; n; n = n->traversePreviousNode())
1728         if (n->isKeyboardFocusable(event) && n->tabIndex() < tabIndex && n->tabIndex() > winningTabIndex) {
1729             winner = n;
1730             winningTabIndex = n->tabIndex();
1731         }
1732     
1733     return winner;
1734 }
1735
1736 Node* Document::nextFocusableNode(Node* start, KeyboardEvent* event)
1737 {
1738     if (start) {
1739         // First try to find a node with the same tabindex as start that comes after start in the document.
1740         if (Node* winner = nextNodeWithExactTabIndex(start->traverseNextNode(), start->tabIndex(), event))
1741             return winner;
1742
1743         if (start->tabIndex() == 0)
1744             // We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order.
1745             return 0;
1746     }
1747
1748     // Look for the first node in the document that:
1749     // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and
1750     // 2) comes first in the document, if there's a tie.
1751     if (Node* winner = nextNodeWithGreaterTabIndex(this, start ? start->tabIndex() : 0, event))
1752         return winner;
1753
1754     // There are no nodes with a tabindex greater than start's tabindex,
1755     // so find the first node with a tabindex of 0.
1756     return nextNodeWithExactTabIndex(this, 0, event);
1757 }
1758
1759 Node* Document::previousFocusableNode(Node* start, KeyboardEvent* event)
1760 {
1761     Node* last;
1762     for (last = this; last->lastChild(); last = last->lastChild())
1763         ; // Empty loop.
1764
1765     // First try to find the last node in the document that comes before start and has the same tabindex as start.
1766     // If start is null, find the last node in the document with a tabindex of 0.
1767     Node* startingNode;
1768     int startingTabIndex;
1769     if (start) {
1770         startingNode = start->traversePreviousNode();
1771         startingTabIndex = start->tabIndex();
1772     } else {
1773         startingNode = last;
1774         startingTabIndex = 0;
1775     }
1776
1777     if (Node* winner = previousNodeWithExactTabIndex(startingNode, startingTabIndex, event))
1778         return winner;
1779
1780     // There are no nodes before start with the same tabindex as start, so look for a node that:
1781     // 1) has the highest non-zero tabindex (that is less than start's tabindex), and
1782     // 2) comes last in the document, if there's a tie.
1783     startingTabIndex = (start && start->tabIndex()) ? start->tabIndex() : SHRT_MAX;
1784     return previousNodeWithLowerTabIndex(last, startingTabIndex, event);
1785 }
1786
1787 int Document::nodeAbsIndex(Node *node)
1788 {
1789     ASSERT(node->document() == this);
1790
1791     int absIndex = 0;
1792     for (Node *n = node; n && n != this; n = n->traversePreviousNode())
1793         absIndex++;
1794     return absIndex;
1795 }
1796
1797 Node *Document::nodeWithAbsIndex(int absIndex)
1798 {
1799     Node *n = this;
1800     for (int i = 0; n && (i < absIndex); i++) {
1801         n = n->traverseNextNode();
1802     }
1803     return n;
1804 }
1805
1806 void Document::processHttpEquiv(const String &equiv, const String &content)
1807 {
1808     ASSERT(!equiv.isNull() && !content.isNull());
1809
1810     Frame *frame = this->frame();
1811
1812     if (equalIgnoringCase(equiv, "default-style")) {
1813         // The preferred style set has been overridden as per section 
1814         // 14.3.2 of the HTML4.0 specification.  We need to update the
1815         // sheet used variable and then update our style selector. 
1816         // For more info, see the test at:
1817         // http://www.hixie.ch/tests/evil/css/import/main/preferred.html
1818         // -dwh
1819         m_selectedStylesheetSet = content;
1820         m_preferredStylesheetSet = content;
1821         updateStyleSelector();
1822     } else if (equalIgnoringCase(equiv, "refresh")) {
1823         double delay;
1824         String url;
1825         if (frame && parseHTTPRefresh(content, true, delay, url)) {
1826             if (url.isEmpty())
1827                 url = frame->loader()->url().string();
1828             else
1829                 url = completeURL(url);
1830             frame->loader()->scheduleHTTPRedirection(delay, url);
1831         }
1832     } else if (equalIgnoringCase(equiv, "set-cookie")) {
1833         // FIXME: make setCookie work on XML documents too; e.g. in case of <html:meta .....>
1834         if (isHTMLDocument())
1835             static_cast<HTMLDocument*>(this)->setCookie(content);
1836     }
1837 }
1838
1839 MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& request, const IntPoint& documentPoint, const PlatformMouseEvent& event)
1840 {
1841     ASSERT(!renderer() || renderer()->isRenderView());
1842
1843     if (!renderer())
1844         return MouseEventWithHitTestResults(event, HitTestResult(IntPoint()));
1845
1846     HitTestResult result(documentPoint);
1847     renderer()->layer()->hitTest(request, result);
1848
1849     if (!request.readonly)
1850         updateRendering();
1851
1852     return MouseEventWithHitTestResults(event, result);
1853 }
1854
1855 // DOM Section 1.1.1
1856 bool Document::childTypeAllowed(NodeType type)
1857 {
1858     switch (type) {
1859         case ATTRIBUTE_NODE:
1860         case CDATA_SECTION_NODE:
1861         case DOCUMENT_FRAGMENT_NODE:
1862         case DOCUMENT_NODE:
1863         case ENTITY_NODE:
1864         case ENTITY_REFERENCE_NODE:
1865         case NOTATION_NODE:
1866         case TEXT_NODE:
1867         case XPATH_NAMESPACE_NODE:
1868             return false;
1869         case COMMENT_NODE:
1870         case PROCESSING_INSTRUCTION_NODE:
1871             return true;
1872         case DOCUMENT_TYPE_NODE:
1873         case ELEMENT_NODE:
1874             // Documents may contain no more than one of each of these.
1875             // (One Element and one DocumentType.)
1876             for (Node* c = firstChild(); c; c = c->nextSibling())
1877                 if (c->nodeType() == type)
1878                     return false;
1879             return true;
1880     }
1881     return false;
1882 }
1883
1884 bool Document::canReplaceChild(Node* newChild, Node* oldChild)
1885 {
1886     if (!oldChild)
1887         // ContainerNode::replaceChild will raise a NOT_FOUND_ERR.
1888         return true;
1889
1890     if (oldChild->nodeType() == newChild->nodeType())
1891         return true;
1892
1893     int numDoctypes = 0;
1894     int numElements = 0;
1895
1896     // First, check how many doctypes and elements we have, not counting
1897     // the child we're about to remove.
1898     for (Node* c = firstChild(); c; c = c->nextSibling()) {
1899         if (c == oldChild)
1900             continue;
1901         
1902         switch (c->nodeType()) {
1903             case DOCUMENT_TYPE_NODE:
1904                 numDoctypes++;
1905                 break;
1906             case ELEMENT_NODE:
1907                 numElements++;
1908                 break;
1909             default:
1910                 break;
1911         }
1912     }
1913     
1914     // Then, see how many doctypes and elements might be added by the new child.
1915     if (newChild->nodeType() == DOCUMENT_FRAGMENT_NODE) {
1916         for (Node* c = firstChild(); c; c = c->nextSibling()) {
1917             switch (c->nodeType()) {
1918                 case ATTRIBUTE_NODE:
1919                 case CDATA_SECTION_NODE:
1920                 case DOCUMENT_FRAGMENT_NODE:
1921                 case DOCUMENT_NODE:
1922                 case ENTITY_NODE:
1923                 case ENTITY_REFERENCE_NODE:
1924                 case NOTATION_NODE:
1925                 case TEXT_NODE:
1926                 case XPATH_NAMESPACE_NODE:
1927                     return false;
1928                 case COMMENT_NODE:
1929                 case PROCESSING_INSTRUCTION_NODE:
1930                     break;
1931                 case DOCUMENT_TYPE_NODE:
1932                     numDoctypes++;
1933                     break;
1934                 case ELEMENT_NODE:
1935                     numElements++;
1936                     break;
1937             }
1938         }
1939     } else {
1940         switch (newChild->nodeType()) {
1941             case ATTRIBUTE_NODE:
1942             case CDATA_SECTION_NODE:
1943             case DOCUMENT_FRAGMENT_NODE:
1944             case DOCUMENT_NODE:
1945             case ENTITY_NODE:
1946             case ENTITY_REFERENCE_NODE:
1947             case NOTATION_NODE:
1948             case TEXT_NODE:
1949             case XPATH_NAMESPACE_NODE:
1950                 return false;
1951             case COMMENT_NODE:
1952             case PROCESSING_INSTRUCTION_NODE:
1953                 return true;
1954             case DOCUMENT_TYPE_NODE:
1955                 numDoctypes++;
1956                 break;
1957             case ELEMENT_NODE:
1958                 numElements++;
1959                 break;
1960         }                
1961     }
1962         
1963     if (numElements > 1 || numDoctypes > 1)
1964         return false;
1965     
1966     return true;
1967 }
1968
1969 PassRefPtr<Node> Document::cloneNode(bool /*deep*/)
1970 {
1971     // Spec says cloning Document nodes is "implementation dependent"
1972     // so we do not support it...
1973     return 0;
1974 }
1975
1976 StyleSheetList* Document::styleSheets()
1977 {
1978     return m_styleSheets.get();
1979 }
1980
1981 String Document::preferredStylesheetSet() const
1982 {
1983     return m_preferredStylesheetSet;
1984 }
1985
1986 String Document::selectedStylesheetSet() const
1987 {
1988     return m_selectedStylesheetSet;
1989 }
1990
1991 void Document::setSelectedStylesheetSet(const String& aString)
1992 {
1993     m_selectedStylesheetSet = aString;
1994     updateStyleSelector();
1995     if (renderer())
1996         renderer()->repaint();
1997 }
1998
1999 // This method is called whenever a top-level stylesheet has finished loading.
2000 void Document::removePendingSheet()
2001 {
2002     // Make sure we knew this sheet was pending, and that our count isn't out of sync.
2003     ASSERT(m_pendingStylesheets > 0);
2004
2005     m_pendingStylesheets--;
2006     
2007 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2008     if (!ownerElement())
2009         printf("Stylesheet loaded at time %d. %d stylesheets still remain.\n", elapsedTime(), m_pendingStylesheets);
2010 #endif
2011
2012     updateStyleSelector();
2013     
2014     if (!m_pendingStylesheets && m_tokenizer)
2015         m_tokenizer->executeScriptsWaitingForStylesheets();
2016
2017     if (!m_pendingStylesheets && m_gotoAnchorNeededAfterStylesheetsLoad && m_frame)
2018         m_frame->loader()->gotoAnchor();
2019 }
2020
2021 void Document::updateStyleSelector()
2022 {
2023     // Don't bother updating, since we haven't loaded all our style info yet
2024     // and haven't calculated the style selector for the first time.
2025     if (!m_didCalculateStyleSelector && !haveStylesheetsLoaded())
2026         return;
2027
2028     if (didLayoutWithPendingStylesheets() && m_pendingStylesheets <= 0) {
2029         m_pendingSheetLayout = IgnoreLayoutWithPendingSheets;
2030         if (renderer())
2031             renderer()->repaint();
2032     }
2033
2034 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2035     if (!ownerElement())
2036         printf("Beginning update of style selector at time %d.\n", elapsedTime());
2037 #endif
2038
2039     recalcStyleSelector();
2040     recalcStyle(Force);
2041
2042 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2043     if (!ownerElement())
2044         printf("Finished update of style selector at time %d\n", elapsedTime());
2045 #endif
2046
2047     if (renderer()) {
2048         renderer()->setNeedsLayoutAndPrefWidthsRecalc();
2049         if (view())
2050             view()->scheduleRelayout();
2051     }
2052 }
2053
2054 void Document::recalcStyleSelector()
2055 {
2056     if (!renderer() || !attached())
2057         return;
2058
2059     DeprecatedPtrList<StyleSheet> oldStyleSheets = m_styleSheets->styleSheets;
2060     m_styleSheets->styleSheets.clear();
2061
2062     bool matchAuthorAndUserStyles = true;
2063     if (Settings* settings = this->settings())
2064         matchAuthorAndUserStyles = settings->authorAndUserStylesEnabled();
2065
2066     Node* n = matchAuthorAndUserStyles ? this : 0;
2067     for ( ; n; n = n->traverseNextNode()) {
2068         StyleSheet* sheet = 0;
2069
2070         if (n->nodeType() == PROCESSING_INSTRUCTION_NODE) {
2071             // Processing instruction (XML documents only)
2072             ProcessingInstruction* pi = static_cast<ProcessingInstruction*>(n);
2073             sheet = pi->sheet();
2074 #if ENABLE(XSLT)
2075             // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
2076             if (pi->isXSL() && !transformSourceDocument()) {
2077                 // Don't apply XSL transforms until loading is finished.
2078                 if (!parsing())
2079                     applyXSLTransform(pi);
2080                 return;
2081             }
2082 #endif
2083             if (!sheet && !pi->localHref().isEmpty()) {
2084                 // Processing instruction with reference to an element in this document - e.g.
2085                 // <?xml-stylesheet href="#mystyle">, with the element
2086                 // <foo id="mystyle">heading { color: red; }</foo> at some location in
2087                 // the document
2088                 Element* elem = getElementById(pi->localHref().impl());
2089                 if (elem) {
2090                     String sheetText("");
2091                     for (Node* c = elem->firstChild(); c; c = c->nextSibling()) {
2092                         if (c->nodeType() == TEXT_NODE || c->nodeType() == CDATA_SECTION_NODE)
2093                             sheetText += c->nodeValue();
2094                     }
2095
2096                     CSSStyleSheet* cssSheet = new CSSStyleSheet(this);
2097                     cssSheet->parseString(sheetText);
2098                     pi->setCSSStyleSheet(cssSheet);
2099                     sheet = cssSheet;
2100                 }
2101             }
2102         } else if (n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag))
2103 #if ENABLE(SVG)
2104             ||  (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
2105 #endif
2106         ) {
2107             Element* e = static_cast<Element*>(n);
2108             DeprecatedString title = e->getAttribute(titleAttr).deprecatedString();
2109             bool enabledViaScript = false;
2110             if (e->hasLocalName(linkTag)) {
2111                 // <LINK> element
2112                 HTMLLinkElement* l = static_cast<HTMLLinkElement*>(n);
2113                 if (l->isDisabled())
2114                     continue;
2115                 enabledViaScript = l->isEnabledViaScript();
2116                 if (l->isLoading()) {
2117                     // it is loading but we should still decide which style sheet set to use
2118                     if (!enabledViaScript && !title.isEmpty() && m_preferredStylesheetSet.isEmpty()) {
2119                         const AtomicString& rel = e->getAttribute(relAttr);
2120                         if (!rel.domString().contains("alternate")) {
2121                             m_preferredStylesheetSet = title;
2122                             m_selectedStylesheetSet = title;
2123                         }
2124                     }
2125                     continue;
2126                 }
2127                 if (!l->sheet())
2128                     title = DeprecatedString::null;
2129             }
2130
2131             // Get the current preferred styleset.  This is the
2132             // set of sheets that will be enabled.
2133 #if ENABLE(SVG)
2134             if (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
2135                 sheet = static_cast<SVGStyleElement*>(n)->sheet();
2136             else
2137 #endif
2138             if (e->hasLocalName(linkTag))
2139                 sheet = static_cast<HTMLLinkElement*>(n)->sheet();
2140             else
2141                 // <STYLE> element
2142                 sheet = static_cast<HTMLStyleElement*>(n)->sheet();
2143
2144             // Check to see if this sheet belongs to a styleset
2145             // (thus making it PREFERRED or ALTERNATE rather than
2146             // PERSISTENT).
2147             if (!enabledViaScript && !title.isEmpty()) {
2148                 // Yes, we have a title.
2149                 if (m_preferredStylesheetSet.isEmpty()) {
2150                     // No preferred set has been established.  If
2151                     // we are NOT an alternate sheet, then establish
2152                     // us as the preferred set.  Otherwise, just ignore
2153                     // this sheet.
2154                     DeprecatedString rel = e->getAttribute(relAttr).deprecatedString();
2155                     if (e->hasLocalName(styleTag) || !rel.contains("alternate"))
2156                         m_preferredStylesheetSet = m_selectedStylesheetSet = title;
2157                 }
2158
2159                 if (title != m_preferredStylesheetSet)
2160                     sheet = 0;
2161
2162 #if ENABLE(SVG)
2163                 if (!n->isHTMLElement())
2164                     title = title.replace('&', "&&");
2165 #endif
2166             }
2167         }
2168
2169         if (sheet) {
2170             sheet->ref();
2171             m_styleSheets->styleSheets.append(sheet);
2172         }
2173
2174         // For HTML documents, stylesheets are not allowed within/after the <BODY> tag. So we
2175         // can stop searching here.
2176         if (isHTMLDocument() && n->hasTagName(bodyTag))
2177             break;
2178     }
2179
2180     // De-reference all the stylesheets in the old list
2181     DeprecatedPtrListIterator<StyleSheet> it(oldStyleSheets);
2182     for (; it.current(); ++it)
2183         it.current()->deref();
2184
2185     // Create a new style selector
2186     delete m_styleSelector;
2187     String usersheet = m_usersheet;
2188     if (view() && view()->mediaType() == "print")
2189         usersheet += m_printSheet;
2190     m_styleSelector = new CSSStyleSelector(this, usersheet, m_styleSheets.get(), m_mappedElementSheet.get(), !inCompatMode(), matchAuthorAndUserStyles);
2191     m_styleSelector->setEncodedURL(m_url);
2192     m_didCalculateStyleSelector = true;
2193 }
2194
2195 void Document::setHoverNode(PassRefPtr<Node> newHoverNode)
2196 {
2197     m_hoverNode = newHoverNode;
2198 }
2199
2200 void Document::setActiveNode(PassRefPtr<Node> newActiveNode)
2201 {
2202     m_activeNode = newActiveNode;
2203 }
2204
2205 void Document::focusedNodeRemoved()
2206 {
2207     setFocusedNode(0);
2208 }
2209
2210 void Document::removeFocusedNodeOfSubtree(Node* node, bool amongChildrenOnly)
2211 {
2212     if (!m_focusedNode || this->inPageCache()) // If the document is in the page cache, then we don't need to clear out the focused node.
2213         return;
2214         
2215     bool nodeInSubtree = false;
2216     if (amongChildrenOnly)
2217         nodeInSubtree = m_focusedNode->isDescendantOf(node);
2218     else
2219         nodeInSubtree = (m_focusedNode == node) || m_focusedNode->isDescendantOf(node);
2220     
2221     if (nodeInSubtree)
2222         document()->focusedNodeRemoved();
2223 }
2224
2225 void Document::hoveredNodeDetached(Node* node)
2226 {
2227     if (!m_hoverNode || (node != m_hoverNode && (!m_hoverNode->isTextNode() || node != m_hoverNode->parent())))
2228         return;
2229
2230     m_hoverNode = node->parent();
2231     while (m_hoverNode && !m_hoverNode->renderer())
2232         m_hoverNode = m_hoverNode->parent();
2233     if (frame())
2234         frame()->eventHandler()->scheduleHoverStateUpdate();
2235 }
2236
2237 void Document::activeChainNodeDetached(Node* node)
2238 {
2239     if (!m_activeNode || (node != m_activeNode && (!m_activeNode->isTextNode() || node != m_activeNode->parent())))
2240         return;
2241
2242     m_activeNode = node->parent();
2243     while (m_activeNode && !m_activeNode->renderer())
2244         m_activeNode = m_activeNode->parent();
2245 }
2246
2247 const Vector<DashboardRegionValue>& Document::dashboardRegions() const
2248 {
2249     return m_dashboardRegions;
2250 }
2251
2252 void Document::setDashboardRegions(const Vector<DashboardRegionValue>& regions)
2253 {
2254     m_dashboardRegions = regions;
2255     setDashboardRegionsDirty(false);
2256 }
2257
2258 bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
2259 {    
2260     // Make sure newFocusedNode is actually in this document
2261     if (newFocusedNode && (newFocusedNode->document() != this))
2262         return true;
2263
2264     if (m_focusedNode == newFocusedNode)
2265         return true;
2266         
2267     bool focusChangeBlocked = false;
2268     RefPtr<Node> oldFocusedNode = m_focusedNode;
2269     m_focusedNode = 0;
2270
2271     // Remove focus from the existing focus node (if any)
2272     if (oldFocusedNode && !oldFocusedNode->m_inDetach) { 
2273         if (oldFocusedNode->active())
2274             oldFocusedNode->setActive(false);
2275
2276         oldFocusedNode->setFocus(false);
2277                 
2278         // Dispatch a change event for text fields or textareas that have been edited
2279         RenderObject *r = static_cast<RenderObject*>(oldFocusedNode.get()->renderer());
2280         if (r && (r->isTextArea() || r->isTextField()) && r->isEdited()) {
2281             EventTargetNodeCast(oldFocusedNode.get())->dispatchHTMLEvent(changeEvent, true, false);
2282             if ((r = static_cast<RenderObject*>(oldFocusedNode.get()->renderer())))
2283                 r->setEdited(false);
2284         }
2285
2286         // Dispatch the blur event and let the node do any other blur related activities (important for text fields)
2287         EventTargetNodeCast(oldFocusedNode.get())->dispatchBlurEvent();
2288
2289         if (m_focusedNode) {
2290             // handler shifted focus
2291             focusChangeBlocked = true;
2292             newFocusedNode = 0;
2293         }
2294         EventTargetNodeCast(oldFocusedNode.get())->dispatchUIEvent(DOMFocusOutEvent);
2295         if (m_focusedNode) {
2296             // handler shifted focus
2297             focusChangeBlocked = true;
2298             newFocusedNode = 0;
2299         }
2300         if ((oldFocusedNode.get() == this) && oldFocusedNode->hasOneRef())
2301             return true;
2302             
2303         if (oldFocusedNode.get() == oldFocusedNode->rootEditableElement())
2304             frame()->editor()->didEndEditing();
2305     }
2306
2307     if (newFocusedNode) {
2308         if (newFocusedNode == newFocusedNode->rootEditableElement() && !acceptsEditingFocus(newFocusedNode.get())) {
2309             // delegate blocks focus change
2310             focusChangeBlocked = true;
2311             goto SetFocusedNodeDone;
2312         }
2313         // Set focus on the new node
2314         m_focusedNode = newFocusedNode.get();
2315
2316         // Dispatch the focus event and let the node do any other focus related activities (important for text fields)
2317         EventTargetNodeCast(m_focusedNode.get())->dispatchFocusEvent();
2318
2319         if (m_focusedNode != newFocusedNode) {
2320             // handler shifted focus
2321             focusChangeBlocked = true;
2322             goto SetFocusedNodeDone;
2323         }
2324         EventTargetNodeCast(m_focusedNode.get())->dispatchUIEvent(DOMFocusInEvent);
2325         if (m_focusedNode != newFocusedNode) { 
2326             // handler shifted focus
2327             focusChangeBlocked = true;
2328             goto SetFocusedNodeDone;
2329         }
2330         m_focusedNode->setFocus();
2331
2332         if (m_focusedNode.get() == m_focusedNode->rootEditableElement())
2333             frame()->editor()->didBeginEditing();
2334
2335         // eww, I suck. set the qt focus correctly
2336         // ### find a better place in the code for this
2337         if (view()) {
2338             Widget *focusWidget = widgetForNode(m_focusedNode.get());
2339             if (focusWidget) {
2340                 // Make sure a widget has the right size before giving it focus.
2341                 // Otherwise, we are testing edge cases of the Widget code.
2342                 // Specifically, in WebCore this does not work well for text fields.
2343                 updateLayout();
2344                 // Re-get the widget in case updating the layout changed things.
2345                 focusWidget = widgetForNode(m_focusedNode.get());
2346             }
2347             if (focusWidget)
2348                 focusWidget->setFocus();
2349             else
2350                 view()->setFocus();
2351         }
2352    }
2353
2354 #if PLATFORM(MAC)
2355     if (!focusChangeBlocked && m_focusedNode && AXObjectCache::accessibilityEnabled())
2356         axObjectCache()->handleFocusedUIElementChanged();
2357 #endif
2358
2359 SetFocusedNodeDone:
2360     updateRendering();
2361     return !focusChangeBlocked;
2362   }
2363   
2364 void Document::setCSSTarget(Node* n)
2365 {
2366     if (m_cssTarget)
2367         m_cssTarget->setChanged();
2368     m_cssTarget = n;
2369     if (n)
2370         n->setChanged();
2371 }
2372
2373 Node* Document::getCSSTarget() const
2374 {
2375     return m_cssTarget;
2376 }
2377
2378 void Document::attachNodeIterator(NodeIterator *ni)
2379 {
2380     m_nodeIterators.add(ni);
2381 }
2382
2383 void Document::detachNodeIterator(NodeIterator *ni)
2384 {
2385     m_nodeIterators.remove(ni);
2386 }
2387
2388 void Document::notifyBeforeNodeRemoval(Node *n)
2389 {
2390     if (Frame* f = frame()) {
2391         f->selectionController()->nodeWillBeRemoved(n);
2392         f->dragCaretController()->nodeWillBeRemoved(n);
2393     }
2394
2395     HashSet<NodeIterator*>::const_iterator end = m_nodeIterators.end();
2396     for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != end; ++it)
2397         (*it)->notifyBeforeNodeRemoval(n);
2398 }
2399
2400 DOMWindow* Document::defaultView() const
2401 {
2402     if (!frame())
2403         return 0;
2404     
2405     return frame()->domWindow();
2406 }
2407
2408 PassRefPtr<Event> Document::createEvent(const String &eventType, ExceptionCode& ec)
2409 {
2410     if (eventType == "UIEvents" || eventType == "UIEvent")
2411         return new UIEvent;
2412     if (eventType == "MouseEvents" || eventType == "MouseEvent")
2413         return new MouseEvent;
2414     if (eventType == "MutationEvents" || eventType == "MutationEvent")
2415         return new MutationEvent;
2416     if (eventType == "KeyboardEvents" || eventType == "KeyboardEvent")
2417         return new KeyboardEvent;
2418     if (eventType == "HTMLEvents" || eventType == "Event" || eventType == "Events")
2419         return new Event;
2420     if (eventType == "ProgressEvent")
2421         return new ProgressEvent;
2422     if (eventType == "TextEvent")
2423         return new TextEvent;
2424     if (eventType == "OverflowEvent")
2425         return new OverflowEvent;
2426     if (eventType == "WheelEvent")
2427         return new WheelEvent;
2428 #if ENABLE(SVG)
2429     if (eventType == "SVGEvents")
2430         return new Event;
2431     if (eventType == "SVGZoomEvents")
2432         return new SVGZoomEvent;
2433 #endif
2434     ec = NOT_SUPPORTED_ERR;
2435     return 0;
2436 }
2437
2438 CSSStyleDeclaration *Document::getOverrideStyle(Element */*elt*/, const String &/*pseudoElt*/)
2439 {
2440     return 0; // ###
2441 }
2442
2443 void Document::handleWindowEvent(Event *evt, bool useCapture)
2444 {
2445     if (m_windowEventListeners.isEmpty())
2446         return;
2447         
2448     // if any html event listeners are registered on the window, then dispatch them here
2449     RegisteredEventListenerList listenersCopy = m_windowEventListeners;
2450     RegisteredEventListenerList::iterator it = listenersCopy.begin();
2451     
2452     for (; it != listenersCopy.end(); ++it)
2453         if ((*it)->eventType() == evt->type() && (*it)->useCapture() == useCapture && !(*it)->removed()) 
2454             (*it)->listener()->handleEvent(evt, true);
2455 }
2456
2457 void Document::setHTMLWindowEventListener(const AtomicString &eventType, PassRefPtr<EventListener> listener)
2458 {
2459     // If we already have it we don't want removeWindowEventListener to delete it
2460     removeHTMLWindowEventListener(eventType);
2461     if (listener)
2462         addWindowEventListener(eventType, listener, false);
2463 }
2464
2465 EventListener *Document::getHTMLWindowEventListener(const AtomicString &eventType)
2466 {
2467     RegisteredEventListenerList::iterator it = m_windowEventListeners.begin();
2468        for (; it != m_windowEventListeners.end(); ++it)
2469         if ( (*it)->eventType() == eventType && (*it)->listener()->isHTMLEventListener())
2470             return (*it)->listener();
2471     return 0;
2472 }
2473
2474 void Document::removeHTMLWindowEventListener(const AtomicString &eventType)
2475 {
2476     RegisteredEventListenerList::iterator it = m_windowEventListeners.begin();
2477     for (; it != m_windowEventListeners.end(); ++it)
2478         if ( (*it)->eventType() == eventType && (*it)->listener()->isHTMLEventListener()) {
2479             m_windowEventListeners.remove(it);
2480             return;
2481         }
2482 }
2483
2484 void Document::addWindowEventListener(const AtomicString &eventType, PassRefPtr<EventListener> listener, bool useCapture)
2485 {
2486     // Remove existing identical listener set with identical arguments.
2487     // The DOM 2 spec says that "duplicate instances are discarded" in this case.
2488     removeWindowEventListener(eventType, listener.get(), useCapture);
2489     m_windowEventListeners.append(new RegisteredEventListener(eventType, listener, useCapture));
2490 }
2491
2492 void Document::removeWindowEventListener(const AtomicString &eventType, EventListener *listener, bool useCapture)
2493 {
2494     RegisteredEventListener rl(eventType, listener, useCapture);
2495     RegisteredEventListenerList::iterator it = m_windowEventListeners.begin();
2496     for (; it != m_windowEventListeners.end(); ++it)
2497         if (*(*it) == rl) {
2498             m_windowEventListeners.remove(it);
2499             return;
2500         }
2501 }
2502
2503 bool Document::hasWindowEventListener(const AtomicString &eventType)
2504 {
2505     RegisteredEventListenerList::iterator it = m_windowEventListeners.begin();
2506     for (; it != m_windowEventListeners.end(); ++it)
2507         if ((*it)->eventType() == eventType) {
2508             return true;
2509         }
2510     return false;
2511 }
2512
2513 PassRefPtr<EventListener> Document::createHTMLEventListener(const String& functionName, const String& code, Node *node)
2514 {
2515     if (Frame* frm = frame())
2516         if (KJSProxy* proxy = frm->scriptProxy())
2517             return proxy->createHTMLEventHandler(functionName, code, node);
2518     return 0;
2519 }
2520
2521 void Document::setHTMLWindowEventListener(const AtomicString& eventType, Attribute* attr)
2522 {
2523     setHTMLWindowEventListener(eventType,
2524         createHTMLEventListener(attr->localName().domString(), attr->value(), 0));
2525 }
2526
2527 void Document::dispatchImageLoadEventSoon(HTMLImageLoader *image)
2528 {
2529     m_imageLoadEventDispatchSoonList.append(image);
2530     if (!m_imageLoadEventTimer.isActive())
2531         m_imageLoadEventTimer.startOneShot(0);
2532 }
2533
2534 void Document::removeImage(HTMLImageLoader* image)
2535 {
2536     // Remove instances of this image from both lists.
2537     // Use loops because we allow multiple instances to get into the lists.
2538     while (m_imageLoadEventDispatchSoonList.removeRef(image)) { }
2539     while (m_imageLoadEventDispatchingList.removeRef(image)) { }
2540     if (m_imageLoadEventDispatchSoonList.isEmpty())
2541         m_imageLoadEventTimer.stop();
2542 }
2543
2544 void Document::dispatchImageLoadEventsNow()
2545 {
2546     // need to avoid re-entering this function; if new dispatches are
2547     // scheduled before the parent finishes processing the list, they
2548     // will set a timer and eventually be processed
2549     if (!m_imageLoadEventDispatchingList.isEmpty()) {
2550         return;
2551     }
2552
2553     m_imageLoadEventTimer.stop();
2554     
2555     m_imageLoadEventDispatchingList = m_imageLoadEventDispatchSoonList;
2556     m_imageLoadEventDispatchSoonList.clear();
2557     for (DeprecatedPtrListIterator<HTMLImageLoader> it(m_imageLoadEventDispatchingList); it.current();) {
2558         HTMLImageLoader* image = it.current();
2559         // Must advance iterator *before* dispatching call.
2560         // Otherwise, it might be advanced automatically if dispatching the call had a side effect
2561         // of destroying the current HTMLImageLoader, and then we would advance past the *next* item,
2562         // missing one altogether.
2563         ++it;
2564         image->dispatchLoadEvent();
2565     }
2566     m_imageLoadEventDispatchingList.clear();
2567 }
2568
2569 void Document::imageLoadEventTimerFired(Timer<Document>*)
2570 {
2571     dispatchImageLoadEventsNow();
2572 }
2573
2574 Element* Document::ownerElement() const
2575 {
2576     if (!frame())
2577         return 0;
2578     return frame()->ownerElement();
2579 }
2580
2581 String Document::cookie() const
2582 {
2583     return cookies(url());
2584 }
2585
2586 void Document::setCookie(const String& value)
2587 {
2588     setCookies(url(), policyBaseURL().deprecatedString(), value);
2589 }
2590
2591 String Document::referrer() const
2592 {
2593     if (frame())
2594         return frame()->loader()->referrer();
2595     return String();
2596 }
2597
2598 String Document::domain() const
2599 {
2600     return m_securityOrigin->domain();
2601 }
2602
2603 void Document::setDomain(const String& newDomain)
2604 {
2605     // Both NS and IE specify that changing the domain is only allowed when
2606     // the new domain is a suffix of the old domain.
2607
2608     // FIXME: We should add logging indicating why a domain was not allowed.
2609
2610     // If the new domain is the same as the old domain, still call
2611     // m_securityOrigin.setDomainForDOM. This will change the
2612     // security check behavior. For example, if a page loaded on port 8000
2613     // assigns its current domain using document.domain, the page will
2614     // allow other pages loaded on different ports in the same domain that
2615     // have also assigned to access this page.
2616     if (equalIgnoringCase(domain(), newDomain)) {
2617         m_securityOrigin->setDomainFromDOM(newDomain);
2618         return;
2619     }
2620
2621     int oldLength = domain().length();
2622     int newLength = newDomain.length();
2623     // e.g. newDomain = webkit.org (10) and domain() = www.webkit.org (14)
2624     if (newLength >= oldLength)
2625         return;
2626
2627     String test = domain().copy();
2628     // Check that it's a subdomain, not e.g. "ebkit.org"
2629     if (test[oldLength - newLength - 1] != '.')
2630         return;
2631
2632     // Now test is "webkit.org" from domain()
2633     // and we check that it's the same thing as newDomain
2634     test.remove(0, oldLength - newLength);
2635     if (test != newDomain)
2636         return;
2637
2638     m_securityOrigin->setDomainFromDOM(newDomain);
2639 }
2640
2641 String Document::lastModified() const
2642 {
2643     Frame* f = frame();
2644     if (!f)
2645         return String();
2646     DocumentLoader* loader = f->loader()->documentLoader();
2647     if (!loader)
2648         return String();
2649     return loader->response().httpHeaderField("Last-Modified");
2650 }
2651
2652 bool Document::isValidName(const String &name)
2653 {
2654     const UChar* s = reinterpret_cast<const UChar*>(name.characters());
2655     unsigned length = name.length();
2656
2657     if (length == 0)
2658         return false;
2659
2660     unsigned i = 0;
2661
2662     UChar32 c;
2663     U16_NEXT(s, i, length, c)
2664     if (!isValidNameStart(c))
2665         return false;
2666
2667     while (i < length) {
2668         U16_NEXT(s, i, length, c)
2669         if (!isValidNamePart(c))
2670             return false;
2671     }
2672
2673     return true;
2674 }
2675
2676 bool Document::parseQualifiedName(const String &qualifiedName, String &prefix, String &localName)
2677 {
2678     unsigned length = qualifiedName.length();
2679
2680     if (length == 0)
2681         return false;
2682
2683     bool nameStart = true;
2684     bool sawColon = false;
2685     int colonPos = 0;
2686
2687     const UChar* s = reinterpret_cast<const UChar*>(qualifiedName.characters());
2688     for (unsigned i = 0; i < length;) {
2689         UChar32 c;
2690         U16_NEXT(s, i, length, c)
2691         if (c == ':') {
2692             if (sawColon)
2693                 return false; // multiple colons: not allowed
2694             nameStart = true;
2695             sawColon = true;
2696             colonPos = i - 1;
2697         } else if (nameStart) {
2698             if (!isValidNameStart(c))
2699                 return false;
2700             nameStart = false;
2701         } else {
2702             if (!isValidNamePart(c))
2703                 return false;
2704         }
2705     }
2706
2707     if (!sawColon) {
2708         prefix = String();
2709         localName = qualifiedName.copy();
2710     } else {
2711         prefix = qualifiedName.substring(0, colonPos);
2712         localName = qualifiedName.substring(colonPos + 1, length - (colonPos + 1));
2713     }
2714
2715     return true;
2716 }
2717
2718 void Document::addImageMap(HTMLMapElement* imageMap)
2719 {
2720     const AtomicString& name = imageMap->getName();
2721     if (!name.impl())
2722         return;
2723
2724     // Add the image map, unless there's already another with that name.
2725     // "First map wins" is the rule other browsers seem to implement.
2726     m_imageMapsByName.add(name.impl(), imageMap);
2727 }
2728
2729 void Document::removeImageMap(HTMLMapElement* imageMap)
2730 {
2731     // Remove the image map by name.
2732     // But don't remove some other image map that just happens to have the same name.
2733     // FIXME: Use a HashCountedSet as we do for IDs to find the first remaining map
2734     // once a map has been removed.
2735     const AtomicString& name = imageMap->getName();
2736     if (!name.impl())
2737         return;
2738
2739     ImageMapsByName::iterator it = m_imageMapsByName.find(name.impl());
2740     if (it != m_imageMapsByName.end() && it->second == imageMap)
2741         m_imageMapsByName.remove(it);
2742 }
2743
2744 HTMLMapElement *Document::getImageMap(const String& url) const
2745 {
2746     if (url.isNull())
2747         return 0;
2748     int hashPos = url.find('#');
2749     String name = (hashPos < 0 ? url : url.substring(hashPos + 1)).impl();
2750     AtomicString mapName = hMode == XHtml ? name : name.lower();
2751     return m_imageMapsByName.get(mapName.impl());
2752 }
2753
2754 void Document::setDecoder(TextResourceDecoder *decoder)
2755 {
2756     m_decoder = decoder;
2757 }
2758
2759 UChar Document::backslashAsCurrencySymbol() const
2760 {
2761     if (!m_decoder)
2762         return '\\';
2763     return m_decoder->encoding().backslashAsCurrencySymbol();
2764 }
2765
2766 DeprecatedString Document::completeURL(const DeprecatedString& url)
2767 {
2768     // FIXME: This treats null URLs the same as empty URLs, unlike the String function below.
2769
2770     // If both the URL and base URL are empty, like they are for documents
2771     // created using DOMImplementation::createDocument, just return the passed in URL.
2772     // (We do this because url() returns "about:blank" for empty URLs.
2773     if (m_url.isEmpty() && m_baseURL.isEmpty())
2774         return url;
2775     if (!m_decoder)
2776         return KURL(baseURL(), url).deprecatedString();
2777     return KURL(baseURL(), url, m_decoder->encoding()).deprecatedString();
2778 }
2779
2780 String Document::completeURL(const String& url)
2781 {
2782     // FIXME: This always returns null when passed a null URL, unlike the String function above.
2783     if (url.isNull())
2784         return url;
2785     return completeURL(url.deprecatedString());
2786 }
2787
2788 bool Document::inPageCache()
2789 {
2790     return m_inPageCache;
2791 }
2792
2793 void Document::setInPageCache(bool flag)
2794 {
2795     if (m_inPageCache == flag)
2796         return;
2797
2798     m_inPageCache = flag;
2799     if (flag) {
2800         ASSERT(m_savedRenderer == 0);
2801         m_savedRenderer = renderer();
2802         if (FrameView* v = view())
2803             v->resetScrollbars();
2804     } else {
2805         ASSERT(renderer() == 0 || renderer() == m_savedRenderer);
2806         ASSERT(m_renderArena);
2807         setRenderer(m_savedRenderer);
2808         m_savedRenderer = 0;
2809     }
2810 }
2811
2812 void Document::willSaveToCache() 
2813 {
2814     HashSet<Element*>::iterator end = m_pageCacheCallbackElements.end();
2815     for (HashSet<Element*>::iterator i = m_pageCacheCallbackElements.begin(); i != end; ++i)
2816         (*i)->willSaveToCache();
2817 }
2818
2819 void Document::didRestoreFromCache() 
2820 {
2821     HashSet<Element*>::iterator end = m_pageCacheCallbackElements.end();
2822     for (HashSet<Element*>::iterator i = m_pageCacheCallbackElements.begin(); i != end; ++i)
2823         (*i)->didRestoreFromCache();
2824 }
2825
2826 void Document::registerForCacheCallbacks(Element* e)
2827 {
2828     m_pageCacheCallbackElements.add(e);
2829 }
2830
2831 void Document::unregisterForCacheCallbacks(Element* e)
2832 {
2833     m_pageCacheCallbackElements.remove(e);
2834 }
2835
2836 void Document::setShouldCreateRenderers(bool f)
2837 {
2838     m_createRenderers = f;
2839 }
2840
2841 bool Document::shouldCreateRenderers()
2842 {
2843     return m_createRenderers;
2844 }
2845
2846 String Document::toString() const
2847 {
2848     String result;
2849
2850     for (Node *child = firstChild(); child != NULL; child = child->nextSibling()) {
2851         result += child->toString();
2852     }
2853
2854     return result;
2855 }
2856
2857 // Support for Javascript execCommand, and related methods
2858
2859 static Editor::Command command(Document* document, const String& commandName, bool userInterface = false)
2860 {
2861     Frame* frame = document->frame();
2862     if (!frame || frame->document() != document)
2863         return Editor::Command();
2864     return frame->editor()->command(commandName,
2865         userInterface ? CommandFromDOMWithUserInterface : CommandFromDOM);
2866 }
2867
2868 bool Document::execCommand(const String& commandName, bool userInterface, const String& value)
2869 {
2870     return command(this, commandName, userInterface).execute(value);
2871 }
2872
2873 bool Document::queryCommandEnabled(const String& commandName)
2874 {
2875     return command(this, commandName).isEnabled();
2876 }
2877
2878 bool Document::queryCommandIndeterm(const String& commandName)
2879 {
2880     return command(this, commandName).state() == MixedTriState;
2881 }
2882
2883 bool Document::queryCommandState(const String& commandName)
2884 {
2885     return command(this, commandName).state() != FalseTriState;
2886 }
2887
2888 bool Document::queryCommandSupported(const String& commandName)
2889 {
2890     return command(this, commandName).isSupported();
2891 }
2892
2893 String Document::queryCommandValue(const String& commandName)
2894 {
2895     return command(this, commandName).value();
2896 }
2897
2898 static IntRect placeholderRectForMarker()
2899 {
2900     return IntRect(-1, -1, -1, -1);
2901 }
2902
2903 void Document::addMarker(Range *range, DocumentMarker::MarkerType type, String description)
2904 {
2905     // Use a TextIterator to visit the potentially multiple nodes the range covers.
2906     for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) {
2907         RefPtr<Range> textPiece = markedText.range();
2908         int exception = 0;
2909         DocumentMarker marker = {type, textPiece->startOffset(exception), textPiece->endOffset(exception), description};
2910         addMarker(textPiece->startContainer(exception), marker);
2911     }
2912 }
2913
2914 void Document::removeMarkers(Range* range, DocumentMarker::MarkerType markerType)
2915 {
2916     if (m_markers.isEmpty())
2917         return;
2918
2919     ExceptionCode ec = 0;
2920     Node* startContainer = range->startContainer(ec);
2921     Node* endContainer = range->endContainer(ec);
2922
2923     Node* pastEndNode = range->pastEndNode();
2924     for (Node* node = range->startNode(); node != pastEndNode; node = node->traverseNextNode()) {
2925         int startOffset = node == startContainer ? range->startOffset(ec) : 0;
2926         int endOffset = node == endContainer ? range->endOffset(ec) : INT_MAX;
2927         int length = endOffset - startOffset;
2928         removeMarkers(node, startOffset, length, markerType);
2929     }
2930 }
2931
2932 // Markers are stored in order sorted by their location.
2933 // They do not overlap each other, as currently required by the drawing code in RenderText.cpp.
2934
2935 void Document::addMarker(Node *node, DocumentMarker newMarker) 
2936 {
2937     ASSERT(newMarker.endOffset >= newMarker.startOffset);
2938     if (newMarker.endOffset == newMarker.startOffset)
2939         return;
2940     
2941     MarkerMapVectorPair* vectorPair = m_markers.get(node);
2942     
2943     if (!vectorPair) {
2944         vectorPair = new MarkerMapVectorPair;
2945         vectorPair->first.append(newMarker);
2946         vectorPair->second.append(placeholderRectForMarker());
2947         m_markers.set(node, vectorPair);
2948     } else {
2949         Vector<DocumentMarker>& markers = vectorPair->first;
2950         Vector<IntRect>& rects = vectorPair->second;
2951         ASSERT(markers.size() == rects.size());
2952         size_t i;
2953         for (i = 0; i != markers.size();) {
2954             DocumentMarker marker = markers[i];
2955             
2956             if (newMarker.endOffset < marker.startOffset+1) {
2957                 // This is the first marker that is completely after newMarker, and disjoint from it.
2958                 // We found our insertion point.
2959                 break;
2960             } else if (newMarker.startOffset > marker.endOffset) {
2961                 // maker is before newMarker, and disjoint from it.  Keep scanning.
2962                 i++;
2963             } else if (newMarker == marker) {
2964                 // already have this one, NOP
2965                 return;
2966             } else {
2967                 // marker and newMarker intersect or touch - merge them into newMarker
2968                 newMarker.startOffset = min(newMarker.startOffset, marker.startOffset);
2969                 newMarker.endOffset = max(newMarker.endOffset, marker.endOffset);
2970                 // remove old one, we'll add newMarker later
2971                 markers.remove(i);
2972                 rects.remove(i);
2973                 // it points to the next marker to consider
2974             }
2975         }
2976         // at this point i points to the node before which we want to insert
2977         markers.insert(i, newMarker);
2978         rects.insert(i, placeholderRectForMarker());
2979     }
2980     
2981     // repaint the affected node
2982     if (node->renderer())
2983         node->renderer()->repaint();
2984 }
2985
2986 // copies markers from srcNode to dstNode, applying the specified shift delta to the copies.  The shift is
2987 // useful if, e.g., the caller has created the dstNode from a non-prefix substring of the srcNode.
2988 void Document::copyMarkers(Node *srcNode, unsigned startOffset, int length, Node *dstNode, int delta, DocumentMarker::MarkerType markerType)
2989 {
2990     if (length <= 0)
2991         return;
2992     
2993     MarkerMapVectorPair* vectorPair = m_markers.get(srcNode);
2994     if (!vectorPair)
2995         return;
2996
2997     ASSERT(vectorPair->first.size() == vectorPair->second.size());
2998
2999     bool docDirty = false;
3000     unsigned endOffset = startOffset + length - 1;
3001     Vector<DocumentMarker>& markers = vectorPair->first;
3002     for (size_t i = 0; i != markers.size(); ++i) {
3003         DocumentMarker marker = markers[i];
3004
3005         // stop if we are now past the specified range
3006         if (marker.startOffset > endOffset)
3007             break;
3008         
3009         // skip marker that is before the specified range or is the wrong type
3010         if (marker.endOffset < startOffset || (marker.type != markerType && markerType != DocumentMarker::AllMarkers))
3011             continue;
3012
3013         // pin the marker to the specified range and apply the shift delta
3014         docDirty = true;
3015         if (marker.startOffset < startOffset)
3016             marker.startOffset = startOffset;
3017         if (marker.endOffset > endOffset)
3018             marker.endOffset = endOffset;
3019         marker.startOffset += delta;
3020         marker.endOffset += delta;
3021         
3022         addMarker(dstNode, marker);
3023     }
3024     
3025     // repaint the affected node
3026     if (docDirty && dstNode->renderer())
3027         dstNode->renderer()->repaint();
3028 }
3029
3030 void Document::removeMarkers(Node* node, unsigned startOffset, int length, DocumentMarker::MarkerType markerType)
3031 {
3032     if (length <= 0)
3033         return;
3034
3035     MarkerMapVectorPair* vectorPair = m_markers.get(node);
3036     if (!vectorPair)
3037         return;
3038
3039     Vector<DocumentMarker>& markers = vectorPair->first;
3040     Vector<IntRect>& rects = vectorPair->second;
3041     ASSERT(markers.size() == rects.size());
3042     bool docDirty = false;
3043     unsigned endOffset = startOffset + length;
3044     for (size_t i = 0; i < markers.size();) {
3045         DocumentMarker marker = markers[i];
3046
3047         // markers are returned in order, so stop if we are now past the specified range
3048         if (marker.startOffset >= endOffset)
3049             break;
3050         
3051         // skip marker that is wrong type or before target
3052         if (marker.endOffset < startOffset || (marker.type != markerType && markerType != DocumentMarker::AllMarkers)) {
3053             i++;
3054             continue;
3055         }
3056
3057         // at this point we know that marker and target intersect in some way
3058         docDirty = true;
3059
3060         // pitch the old marker and any associated rect
3061         markers.remove(i);
3062         rects.remove(i);
3063         
3064         // add either of the resulting slices that are left after removing target
3065         if (startOffset > marker.startOffset) {
3066             DocumentMarker newLeft = marker;
3067             newLeft.endOffset = startOffset;
3068             markers.insert(i, newLeft);
3069             rects.insert(i, placeholderRectForMarker());
3070             // i now points to the newly-inserted node, but we want to skip that one
3071             i++;
3072         }
3073         if (marker.endOffset > endOffset) {
3074             DocumentMarker newRight = marker;
3075             newRight.startOffset = endOffset;
3076             markers.insert(i, newRight);
3077             rects.insert(i, placeholderRectForMarker());
3078             // i now points to the newly-inserted node, but we want to skip that one
3079             i++;
3080         }
3081     }
3082
3083     if (markers.isEmpty()) {
3084         ASSERT(rects.isEmpty());
3085         m_markers.remove(node);
3086         delete vectorPair;
3087     }
3088
3089     // repaint the affected node
3090     if (docDirty && node->renderer())
3091         node->renderer()->repaint();
3092 }
3093
3094 DocumentMarker* Document::markerContainingPoint(const IntPoint& point, DocumentMarker::MarkerType markerType)
3095 {
3096     // outer loop: process each node that contains any markers
3097     MarkerMap::iterator end = m_markers.end();
3098     for (MarkerMap::iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
3099         // inner loop; process each marker in this node
3100         MarkerMapVectorPair* vectorPair = nodeIterator->second;
3101         Vector<DocumentMarker>& markers = vectorPair->first;
3102         Vector<IntRect>& rects = vectorPair->second;
3103         ASSERT(markers.size() == rects.size());
3104         unsigned markerCount = markers.size();
3105         for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) {
3106             DocumentMarker& marker = markers[markerIndex];
3107             
3108             // skip marker that is wrong type
3109             if (marker.type != markerType && markerType != DocumentMarker::AllMarkers)
3110                 continue;
3111             
3112             IntRect& r = rects[markerIndex];
3113             
3114             // skip placeholder rects
3115             if (r == placeholderRectForMarker())
3116                 continue;
3117             
3118             if (r.contains(point))
3119                 return &marker;
3120         }
3121     }
3122     
3123     return 0;
3124 }
3125
3126 Vector<DocumentMarker> Document::markersForNode(Node* node)
3127 {
3128     MarkerMapVectorPair* vectorPair = m_markers.get(node);
3129     if (vectorPair)
3130         return vectorPair->first;
3131     return Vector<DocumentMarker>();
3132 }
3133
3134 Vector<IntRect> Document::renderedRectsForMarkers(DocumentMarker::MarkerType markerType)
3135 {
3136     Vector<IntRect> result;
3137     
3138     // outer loop: process each node
3139     MarkerMap::iterator end = m_markers.end();
3140     for (MarkerMap::iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
3141         // inner loop; process each marker in this node
3142         MarkerMapVectorPair* vectorPair = nodeIterator->second;
3143         Vector<DocumentMarker>& markers = vectorPair->first;
3144         Vector<IntRect>& rects = vectorPair->second;
3145         ASSERT(markers.size() == rects.size());
3146         unsigned markerCount = markers.size();
3147         for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) {
3148             DocumentMarker marker = markers[markerIndex];
3149             
3150             // skip marker that is wrong type
3151             if (marker.type != markerType && markerType != DocumentMarker::AllMarkers)
3152                 continue;
3153             
3154             IntRect r = rects[markerIndex];
3155             // skip placeholder rects
3156             if (r == placeholderRectForMarker())
3157                 continue;
3158
3159             result.append(r);
3160         }
3161     }
3162     
3163     return result;
3164 }
3165
3166 void Document::removeMarkers(Node* node)
3167 {
3168     MarkerMap::iterator i = m_markers.find(node);
3169     if (i != m_markers.end()) {
3170         delete i->second;
3171         m_markers.remove(i);
3172         if (RenderObject* renderer = node->renderer())
3173             renderer->repaint();
3174     }
3175 }
3176
3177 void Document::removeMarkers(DocumentMarker::MarkerType markerType)
3178 {
3179     // outer loop: process each markered node in the document
3180     MarkerMap markerMapCopy = m_markers;
3181     MarkerMap::iterator end = markerMapCopy.end();
3182     for (MarkerMap::iterator i = markerMapCopy.begin(); i != end; ++i) {
3183         Node* node = i->first.get();
3184         bool nodeNeedsRepaint = false;
3185
3186         // inner loop: process each marker in the current node
3187         MarkerMapVectorPair* vectorPair = i->second;
3188         Vector<DocumentMarker>& markers = vectorPair->first;
3189         Vector<IntRect>& rects = vectorPair->second;
3190         ASSERT(markers.size() == rects.size());
3191         for (size_t i = 0; i != markers.size();) {
3192             DocumentMarker marker = markers[i];
3193
3194             // skip nodes that are not of the specified type
3195             if (marker.type != markerType && markerType != DocumentMarker::AllMarkers) {
3196                 ++i;
3197                 continue;
3198             }
3199
3200             // pitch the old marker
3201             markers.remove(i);
3202             rects.remove(i);
3203             nodeNeedsRepaint = true;
3204             // markerIterator now points to the next node
3205         }
3206
3207         // Redraw the node if it changed. Do this before the node is removed from m_markers, since 
3208         // m_markers might contain the last reference to the node.
3209         if (nodeNeedsRepaint) {
3210             RenderObject* renderer = node->renderer();
3211             if (renderer)
3212                 renderer->repaint();
3213         }
3214
3215         // delete the node's list if it is now empty
3216         if (markers.isEmpty()) {
3217             ASSERT(rects.isEmpty());
3218             m_markers.remove(node);
3219             delete vectorPair;
3220         }
3221     }
3222 }
3223
3224 void Document::repaintMarkers(DocumentMarker::MarkerType markerType)
3225 {
3226     // outer loop: process each markered node in the document
3227     MarkerMap::iterator end = m_markers.end();
3228     for (MarkerMap::iterator i = m_markers.begin(); i != end; ++i) {
3229         Node* node = i->first.get();
3230         
3231         // inner loop: process each marker in the current node
3232         MarkerMapVectorPair* vectorPair = i->second;
3233         Vector<DocumentMarker>& markers = vectorPair->first;
3234         bool nodeNeedsRepaint = false;
3235         for (size_t i = 0; i != markers.size(); ++i) {
3236             DocumentMarker marker = markers[i];
3237             
3238             // skip nodes that are not of the specified type
3239             if (marker.type == markerType || markerType == DocumentMarker::AllMarkers) {
3240                 nodeNeedsRepaint = true;
3241                 break;
3242             }
3243         }
3244         
3245         if (!nodeNeedsRepaint)
3246             continue;
3247         
3248         // cause the node to be redrawn
3249         if (RenderObject* renderer = node->renderer())
3250             renderer->repaint();
3251     }
3252 }
3253
3254 void Document::setRenderedRectForMarker(Node* node, DocumentMarker marker, const IntRect& r)
3255 {
3256     MarkerMapVectorPair* vectorPair = m_markers.get(node);
3257     if (!vectorPair) {
3258         ASSERT_NOT_REACHED(); // shouldn't be trying to set the rect for a marker we don't already know about
3259         return;
3260     }
3261     
3262     Vector<DocumentMarker>& markers = vectorPair->first;
3263     ASSERT(markers.size() == vectorPair->second.size());
3264     unsigned markerCount = markers.size();
3265     for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) {
3266         DocumentMarker m = markers[markerIndex];
3267         if (m == marker) {
3268             vectorPair->second[markerIndex] = r;
3269             return;
3270         }
3271     }
3272     
3273     ASSERT_NOT_REACHED(); // shouldn't be trying to set the rect for a marker we don't already know about
3274 }
3275
3276 void Document::invalidateRenderedRectsForMarkersInRect(const IntRect& r)
3277 {
3278     // outer loop: process each markered node in the document
3279     MarkerMap::iterator end = m_markers.end();
3280     for (MarkerMap::iterator i = m_markers.begin(); i != end; ++i) {
3281         
3282         // inner loop: process each rect in the current node
3283         MarkerMapVectorPair* vectorPair = i->second;
3284         Vector<IntRect>& rects = vectorPair->second;
3285         
3286         unsigned rectCount = rects.size();
3287         for (unsigned rectIndex = 0; rectIndex < rectCount; ++rectIndex)
3288             if (rects[rectIndex].intersects(r))
3289                 rects[rectIndex] = placeholderRectForMarker();
3290     }
3291 }
3292
3293 void Document::shiftMarkers(Node *node, unsigned startOffset, int delta, DocumentMarker::MarkerType markerType)
3294 {
3295     MarkerMapVectorPair* vectorPair = m_markers.get(node);
3296     if (!vectorPair)
3297         return;
3298     
3299     Vector<DocumentMarker>& markers = vectorPair->first;
3300     Vector<IntRect>& rects = vectorPair->second;
3301     ASSERT(markers.size() == rects.size());
3302     
3303     bool docDirty = false;
3304     for (size_t i = 0; i != markers.size(); ++i) {
3305         DocumentMarker &marker = markers[i];
3306         if (marker.startOffset >= startOffset && (markerType == DocumentMarker::AllMarkers || marker.type == markerType)) {
3307             ASSERT((int)marker.startOffset + delta >= 0);
3308             marker.startOffset += delta;
3309             marker.endOffset += delta;
3310             docDirty = true;
3311             
3312             // Marker moved, so previously-computed rendered rectangle is now invalid
3313             rects[i] = placeholderRectForMarker();
3314         }
3315     }
3316     
3317     // repaint the affected node
3318     if (docDirty && node->renderer())
3319         node->renderer()->repaint();
3320 }
3321
3322 #if ENABLE(XSLT)
3323
3324 void Document::applyXSLTransform(ProcessingInstruction* pi)
3325 {
3326     RefPtr<XSLTProcessor> processor = new XSLTProcessor;
3327     processor->setXSLStylesheet(static_cast<XSLStyleSheet*>(pi->sheet()));
3328     
3329     String resultMIMEType;
3330     String newSource;
3331     String resultEncoding;
3332     if (!processor->transformToString(this, resultMIMEType, newSource, resultEncoding))
3333         return;
3334     // FIXME: If the transform failed we should probably report an error (like Mozilla does).
3335     processor->createDocumentFromSource(newSource, resultEncoding, resultMIMEType, this, frame());
3336 }
3337
3338 void Document::setTransformSource(void* doc)
3339 {
3340     if (doc == m_transformSource)
3341         return;
3342
3343     xmlFreeDoc((xmlDocPtr)m_transformSource);
3344     m_transformSource = doc;
3345 }
3346
3347 #endif
3348
3349 void Document::setDesignMode(InheritedBool value)
3350 {
3351     m_designMode = value;
3352 }
3353
3354 Document::InheritedBool Document::getDesignMode() const
3355 {
3356     return m_designMode;
3357 }
3358
3359 bool Document::inDesignMode() const
3360 {
3361     for (const Document* d = this; d; d = d->parentDocument()) {
3362         if (d->m_designMode != inherit)
3363             return d->m_designMode;
3364     }
3365     return false;
3366 }
3367
3368 Document *Document::parentDocument() const
3369 {
3370     Frame *childPart = frame();
3371     if (!childPart)
3372         return 0;
3373     Frame *parent = childPart->tree()->parent();
3374     if (!parent)
3375         return 0;
3376     return parent->document();
3377 }
3378
3379 Document *Document::topDocument() const
3380 {
3381     Document *doc = const_cast<Document *>(this);
3382     Element *element;
3383     while ((element = doc->ownerElement()))
3384         doc = element->document();
3385     
3386     return doc;
3387 }
3388
3389 PassRefPtr<Attr> Document::createAttributeNS(const String &namespaceURI, const String &qualifiedName, ExceptionCode& ec)
3390 {
3391     if (qualifiedName.isNull()) {
3392         ec = NAMESPACE_ERR;
3393         return 0;
3394     }
3395
3396     String localName = qualifiedName;
3397     String prefix;
3398     int colonpos;
3399     if ((colonpos = qualifiedName.find(':')) >= 0) {
3400         prefix = qualifiedName.copy();
3401         localName = qualifiedName.copy();
3402         prefix.truncate(colonpos);
3403         localName.remove(0, colonpos+1);
3404     }
3405
3406     if (!isValidName(localName)) {
3407         ec = INVALID_CHARACTER_ERR;
3408         return 0;
3409     }
3410     
3411     // FIXME: Assume this is a mapped attribute, since createAttribute isn't namespace-aware.  There's no harm to XML
3412     // documents if we're wrong.
3413     return new Attr(0, this, new MappedAttribute(QualifiedName(prefix, localName, namespaceURI), StringImpl::empty()));
3414 }
3415
3416 #if ENABLE(SVG)
3417 const SVGDocumentExtensions* Document::svgExtensions()
3418 {
3419     return m_svgExtensions;
3420 }
3421
3422 SVGDocumentExtensions* Document::accessSVGExtensions()
3423 {
3424     if (!m_svgExtensions)
3425         m_svgExtensions = new SVGDocumentExtensions(this);
3426     return m_svgExtensions;
3427 }
3428 #endif
3429
3430 PassRefPtr<HTMLCollection> Document::images()
3431 {
3432     return new HTMLCollection(this, HTMLCollection::DocImages);
3433 }
3434
3435 PassRefPtr<HTMLCollection> Document::applets()
3436 {
3437     return new HTMLCollection(this, HTMLCollection::DocApplets);
3438 }
3439
3440 PassRefPtr<HTMLCollection> Document::embeds()
3441 {
3442     return new HTMLCollection(this, HTMLCollection::DocEmbeds);
3443 }
3444
3445 PassRefPtr<HTMLCollection> Document::plugins()
3446 {
3447     // This is an alias for embeds() required for the JS DOM bindings.
3448     return new HTMLCollection(this, HTMLCollection::DocEmbeds);
3449 }
3450
3451 PassRefPtr<HTMLCollection> Document::objects()
3452 {
3453     return new HTMLCollection(this, HTMLCollection::DocObjects);
3454 }
3455
3456 PassRefPtr<HTMLCollection> Document::scripts()
3457 {
3458     return new HTMLCollection(this, HTMLCollection::DocScripts);
3459 }
3460
3461 PassRefPtr<HTMLCollection> Document::links()
3462 {
3463     return new HTMLCollection(this, HTMLCollection::DocLinks);
3464 }
3465
3466 PassRefPtr<HTMLCollection> Document::forms()
3467 {
3468     return new HTMLCollection(this, HTMLCollection::DocForms);
3469 }
3470
3471 PassRefPtr<HTMLCollection> Document::anchors()
3472 {
3473     return new HTMLCollection(this, HTMLCollection::DocAnchors);
3474 }
3475
3476 PassRefPtr<HTMLCollection> Document::all()
3477 {
3478     return new HTMLCollection(this, HTMLCollection::DocAll);
3479 }
3480
3481 PassRefPtr<HTMLCollection> Document::windowNamedItems(const String &name)
3482 {
3483     return new HTMLNameCollection(this, HTMLCollection::WindowNamedItems, name);
3484 }
3485
3486 PassRefPtr<HTMLCollection> Document::documentNamedItems(const String &name)
3487 {
3488     return new HTMLNameCollection(this, HTMLCollection::DocumentNamedItems, name);
3489 }
3490
3491 HTMLCollection::CollectionInfo* Document::nameCollectionInfo(HTMLCollection::Type type, const AtomicString& name)
3492 {
3493     ASSERT(type >= HTMLCollection::FirstNamedDocumentCachedType);
3494     unsigned index = type - HTMLCollection::FirstNamedDocumentCachedType;
3495     ASSERT(index < HTMLCollection::NumNamedDocumentCachedTypes);
3496
3497     NamedCollectionMap& map = m_nameCollectionInfo[index];
3498     NamedCollectionMap::iterator iter = map.find(name.impl());
3499     if (iter == map.end())
3500         iter = map.add(name.impl(), new HTMLCollection::CollectionInfo).first;
3501     return iter->second;
3502 }
3503
3504 void Document::finishedParsing()
3505 {
3506     setParsing(false);
3507
3508     ExceptionCode ec = 0;
3509     dispatchEvent(new Event(DOMContentLoadedEvent, true, false), ec);
3510
3511     if (Frame* f = frame())
3512         f->loader()->finishedParsing();
3513 }
3514
3515 Vector<String> Document::formElementsState() const
3516 {
3517     Vector<String> stateVector;
3518     stateVector.reserveCapacity(m_formElementsWithState.size() * 3);
3519     typedef ListHashSet<HTMLFormControlElementWithState*>::const_iterator Iterator;
3520     Iterator end = m_formElementsWithState.end();
3521     for (Iterator it = m_formElementsWithState.begin(); it != end; ++it) {
3522         HTMLFormControlElementWithState* e = *it;
3523         String value;
3524         if (e->saveState(value)) {
3525             stateVector.append(e->name().domString());
3526             stateVector.append(e->type().domString());
3527             stateVector.append(value);
3528         }
3529     }
3530     return stateVector;
3531 }
3532
3533 #if ENABLE(XPATH)
3534
3535 PassRefPtr<XPathExpression> Document::createExpression(const String& expression,
3536                                                        XPathNSResolver* resolver,
3537                                                        ExceptionCode& ec)
3538 {
3539     if (!m_xpathEvaluator)
3540         m_xpathEvaluator = new XPathEvaluator;
3541     return m_xpathEvaluator->createExpression(expression, resolver, ec);
3542 }
3543
3544 PassRefPtr<XPathNSResolver> Document::createNSResolver(Node* nodeResolver)
3545 {
3546     if (!m_xpathEvaluator)
3547         m_xpathEvaluator = new XPathEvaluator;
3548     return m_xpathEvaluator->createNSResolver(nodeResolver);
3549 }
3550
3551 PassRefPtr<XPathResult> Document::evaluate(const String& expression,
3552                                            Node* contextNode,
3553                                            XPathNSResolver* resolver,
3554                                            unsigned short type,
3555                                            XPathResult* result,
3556                                            ExceptionCode& ec)
3557 {
3558     if (!m_xpathEvaluator)
3559         m_xpathEvaluator = new XPathEvaluator;
3560     return m_xpathEvaluator->evaluate(expression, contextNode, resolver, type, result, ec);
3561 }
3562
3563 #endif // ENABLE(XPATH)
3564
3565 void Document::setStateForNewFormElements(const Vector<String>& stateVector)
3566 {
3567     // Walk the state vector backwards so that the value to use for each
3568     // name/type pair first is the one at the end of each individual vector
3569     // in the FormElementStateMap. We're using them like stacks.
3570     typedef FormElementStateMap::iterator Iterator;
3571     m_formElementsWithState.clear();
3572     for (size_t i = stateVector.size() / 3 * 3; i; i -= 3) {
3573         AtomicString a = stateVector[i - 3];
3574         AtomicString b = stateVector[i - 2];
3575         const String& c = stateVector[i - 1];
3576         FormElementKey key(a.impl(), b.impl());
3577         Iterator it = m_stateForNewFormElements.find(key);
3578         if (it != m_stateForNewFormElements.end())
3579             it->second.append(c);
3580         else {
3581             Vector<String> v(1);
3582             v[0] = c;
3583             m_stateForNewFormElements.set(key, v);
3584         }
3585     }
3586 }
3587
3588 bool Document::hasStateForNewFormElements() const
3589 {
3590     return !m_stateForNewFormElements.isEmpty();
3591 }
3592
3593 bool Document::takeStateForFormElement(AtomicStringImpl* name, AtomicStringImpl* type, String& state)
3594 {
3595     typedef FormElementStateMap::iterator Iterator;
3596     Iterator it = m_stateForNewFormElements.find(FormElementKey(name, type));
3597     if (it == m_stateForNewFormElements.end())
3598         return false;
3599     ASSERT(it->second.size());
3600     state = it->second.last();
3601     if (it->second.size() > 1)
3602         it->second.removeLast();
3603     else
3604         m_stateForNewFormElements.remove(it);
3605     return true;
3606 }
3607
3608 FormElementKey::FormElementKey(AtomicStringImpl* name, AtomicStringImpl* type)
3609     : m_name(name), m_type(type)
3610 {
3611     ref();
3612 }
3613
3614 FormElementKey::~FormElementKey()
3615 {
3616     deref();
3617 }
3618
3619 FormElementKey::FormElementKey(const FormElementKey& other)
3620     : m_name(other.name()), m_type(other.type())
3621 {
3622     ref();
3623 }
3624
3625 FormElementKey& FormElementKey::operator=(const FormElementKey& other)
3626 {
3627     other.ref();
3628     deref();
3629     m_name = other.name();
3630     m_type = other.type();
3631     return *this;
3632 }
3633
3634 void FormElementKey::ref() const
3635 {
3636     if (name() && name() != HashTraits<AtomicStringImpl*>::deletedValue())
3637         name()->ref();
3638     if (type())
3639         type()->ref();
3640 }
3641
3642 void FormElementKey::deref() const
3643 {
3644     if (name() && name() != HashTraits<AtomicStringImpl*>::deletedValue())
3645         name()->deref();
3646     if (type())
3647         type()->deref();
3648 }
3649
3650 unsigned FormElementKeyHash::hash(const FormElementKey& k)
3651 {
3652     ASSERT(sizeof(k) % (sizeof(uint16_t) * 2) == 0);
3653
3654     unsigned l = sizeof(k) / (sizeof(uint16_t) * 2);
3655     const uint16_t* s = reinterpret_cast<const uint16_t*>(&k);
3656     uint32_t hash = PHI;
3657
3658     // Main loop
3659     for (; l > 0; l--) {
3660         hash += s[0];
3661         uint32_t tmp = (s[1] << 11) ^ hash;
3662         hash = (hash << 16) ^ tmp;
3663         s += 2;
3664         hash += hash >> 11;
3665     }
3666         
3667     // Force "avalanching" of final 127 bits
3668     hash ^= hash << 3;
3669     hash += hash >> 5;
3670     hash ^= hash << 2;
3671     hash += hash >> 15;
3672     hash ^= hash << 10;
3673
3674     // this avoids ever returning a hash code of 0, since that is used to
3675     // signal "hash not computed yet", using a value that is likely to be
3676     // effectively the same as 0 when the low bits are masked
3677     if (hash == 0)
3678         hash = 0x80000000;
3679
3680     return hash;
3681 }
3682
3683 FormElementKey FormElementKeyHashTraits::deletedValue()
3684 {
3685     return HashTraits<AtomicStringImpl*>::deletedValue();
3686 }
3687
3688
3689 String Document::iconURL()
3690 {
3691     return m_iconURL;
3692 }
3693
3694 void Document::setIconURL(const String& iconURL, const String& type)
3695 {
3696     // FIXME - <rdar://problem/4727645> - At some point in the future, we might actually honor the "type" 
3697     if (m_iconURL.isEmpty())
3698         m_iconURL = iconURL;
3699     else if (!type.isEmpty())
3700         m_iconURL = iconURL;
3701 }
3702
3703 void Document::setUseSecureKeyboardEntryWhenActive(bool usesSecureKeyboard)
3704 {
3705     if (m_useSecureKeyboardEntryWhenActive == usesSecureKeyboard)
3706         return;
3707         
3708     m_useSecureKeyboardEntryWhenActive = usesSecureKeyboard;
3709     m_frame->updateSecureKeyboardEntryIfActive();
3710 }
3711
3712 bool Document::useSecureKeyboardEntryWhenActive() const
3713 {
3714     return m_useSecureKeyboardEntryWhenActive;
3715 }
3716
3717 void Document::initSecurityOrigin()
3718 {
3719     m_securityOrigin = SecurityOrigin::createForFrame(m_frame);
3720 }
3721
3722 void Document::updateFocusAppearanceSoon()
3723 {
3724     if (!m_updateFocusAppearanceTimer.isActive())
3725         m_updateFocusAppearanceTimer.startOneShot(0);
3726 }
3727
3728 void Document::cancelFocusAppearanceUpdate()
3729 {
3730     m_updateFocusAppearanceTimer.stop();
3731 }
3732
3733 void Document::updateFocusAppearanceTimerFired(Timer<Document>*)
3734 {
3735     Node* node = focusedNode();
3736     if (!node)
3737         return;
3738     if (!node->isElementNode())
3739         return;
3740
3741     updateLayout();
3742
3743     Element* element = static_cast<Element*>(node);
3744     if (element->isFocusable())
3745         element->updateFocusAppearance(false);
3746 }
3747
3748 #if ENABLE(DATABASE)
3749 DatabaseThread* Document::databaseThread()
3750 {
3751     if (!m_databaseThread) {
3752         m_databaseThread = new DatabaseThread(this);
3753         if (!m_databaseThread->start())
3754             m_databaseThread = 0;
3755     }
3756
3757     return m_databaseThread.get();
3758 }
3759 #endif
3760
3761 } // namespace WebCore