2437c8984d9bba10fc20c6a05b426b53830e9ecb
[WebKit-https.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 "Comment.h"
34 #include "CookieJar.h"
35 #include "DatabaseThread.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 "JSEditor.h"
72 #include "KeyboardEvent.h"
73 #include "Logging.h"
74 #include "MouseEvent.h"
75 #include "MouseEventWithHitTestResults.h"
76 #include "MutationEvent.h"
77 #include "NameNodeList.h"
78 #include "NodeFilter.h"
79 #include "NodeIterator.h"
80 #include "OverflowEvent.h"
81 #include "Page.h"
82 #include "PlatformKeyboardEvent.h"
83 #include "ProcessingInstruction.h"
84 #include "ProgressEvent.h"
85 #include "RegisteredEventListener.h"
86 #include "RegularExpression.h"
87 #include "RenderArena.h"
88 #include "RenderView.h"
89 #include "RenderWidget.h"
90 #include "SecurityOrigin.h"
91 #include "SegmentedString.h"
92 #include "SelectionController.h"
93 #include "Settings.h"
94 #include "StringHash.h"
95 #include "StyleSheetList.h"
96 #include "SystemTime.h"
97 #include "TextEvent.h"
98 #include "TextIterator.h"
99 #include "TextResourceDecoder.h"
100 #include "TreeWalker.h"
101 #include "UIEvent.h"
102 #include "WheelEvent.h"
103 #include "XMLHttpRequest.h"
104 #include "XMLTokenizer.h"
105 #include "kjs_binding.h"
106 #include "kjs_proxy.h"
107
108 #if ENABLE(XPATH)
109 #include "XPathEvaluator.h"
110 #include "XPathExpression.h"
111 #include "XPathNSResolver.h"
112 #include "XPathResult.h"
113 #endif
114
115 #if ENABLE(XSLT)
116 #include "XSLTProcessor.h"
117 #endif
118
119 #if ENABLE(XBL)
120 #include "XBLBindingManager.h"
121 #endif
122
123 #if ENABLE(SVG)
124 #include "SVGDocumentExtensions.h"
125 #include "SVGElementFactory.h"
126 #include "SVGZoomEvent.h"
127 #include "SVGStyleElement.h"
128 #include "TimeScheduler.h"
129 #endif
130
131 using namespace std;
132 using namespace WTF;
133 using namespace Unicode;
134
135 namespace WebCore {
136
137 using namespace EventNames;
138 using namespace HTMLNames;
139
140 // #define INSTRUMENT_LAYOUT_SCHEDULING 1
141
142 // This amount of time must have elapsed before we will even consider scheduling a layout without a delay.
143 // FIXME: For faster machines this value can really be lowered to 200.  250 is adequate, but a little high
144 // for dual G5s. :)
145 static const int cLayoutScheduleThreshold = 250;
146
147 // Use 1 to represent the document's default form.
148 static HTMLFormElement* const defaultForm = reinterpret_cast<HTMLFormElement*>(1);
149
150 // Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
151 static const unsigned PHI = 0x9e3779b9U;
152
153 // DOM Level 2 says (letters added):
154 //
155 // a) Name start characters must have one of the categories Ll, Lu, Lo, Lt, Nl.
156 // b) Name characters other than Name-start characters must have one of the categories Mc, Me, Mn, Lm, or Nd.
157 // c) Characters in the compatibility area (i.e. with character code greater than #xF900 and less than #xFFFE) are not allowed in XML names.
158 // 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.
159 // 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.
160 // f) Characters #x20DD-#x20E0 are excluded (in accordance with Unicode, section 5.14).
161 // g) Character #x00B7 is classified as an extender, because the property list so identifies it.
162 // h) Character #x0387 is added as a name character, because #x00B7 is its canonical equivalent.
163 // i) Characters ':' and '_' are allowed as name-start characters.
164 // j) Characters '-' and '.' are allowed as name characters.
165 //
166 // It also contains complete tables. If we decide it's better, we could include those instead of the following code.
167
168 static inline bool isValidNameStart(UChar32 c)
169 {
170     // rule (e) above
171     if ((c >= 0x02BB && c <= 0x02C1) || c == 0x559 || c == 0x6E5 || c == 0x6E6)
172         return true;
173
174     // rule (i) above
175     if (c == ':' || c == '_')
176         return true;
177
178     // rules (a) and (f) above
179     const uint32_t nameStartMask = Letter_Lowercase | Letter_Uppercase | Letter_Other | Letter_Titlecase | Number_Letter;
180     if (!(Unicode::category(c) & nameStartMask))
181         return false;
182
183     // rule (c) above
184     if (c >= 0xF900 && c < 0xFFFE)
185         return false;
186
187     // rule (d) above
188     DecompositionType decompType = decompositionType(c);
189     if (decompType == DecompositionFont || decompType == DecompositionCompat)
190         return false;
191
192     return true;
193 }
194
195 static inline bool isValidNamePart(UChar32 c)
196 {
197     // rules (a), (e), and (i) above
198     if (isValidNameStart(c))
199         return true;
200
201     // rules (g) and (h) above
202     if (c == 0x00B7 || c == 0x0387)
203         return true;
204
205     // rule (j) above
206     if (c == '-' || c == '.')
207         return true;
208
209     // rules (b) and (f) above
210     const uint32_t otherNamePartMask = Mark_NonSpacing | Mark_Enclosing | Mark_SpacingCombining | Letter_Modifier | Number_DecimalDigit;
211     if (!(Unicode::category(c) & otherNamePartMask))
212         return false;
213
214     // rule (c) above
215     if (c >= 0xF900 && c < 0xFFFE)
216         return false;
217
218     // rule (d) above
219     DecompositionType decompType = decompositionType(c);
220     if (decompType == DecompositionFont || decompType == DecompositionCompat)
221         return false;
222
223     return true;
224 }
225
226 static Widget* widgetForNode(Node* focusedNode)
227   {
228     if (!focusedNode)
229         return 0;
230     RenderObject* renderer = focusedNode->renderer();
231     if (!renderer || !renderer->isWidget())
232         return 0;
233     return static_cast<RenderWidget*>(renderer)->widget();
234 }
235
236 static bool acceptsEditingFocus(Node *node)
237 {
238     ASSERT(node);
239     ASSERT(node->isContentEditable());
240
241     Node *root = node->rootEditableElement();
242     Frame* frame = node->document()->frame();
243     if (!frame || !root)
244         return false;
245
246     return frame->editor()->shouldBeginEditing(rangeOfContents(root).get());
247 }
248
249 DeprecatedPtrList<Document>*  Document::changedDocuments = 0;
250
251 // FrameView might be 0
252 Document::Document(DOMImplementation* impl, Frame* frame, bool isXHTML)
253     : ContainerNode(0)
254     , m_implementation(impl)
255     , m_domtree_version(0)
256     , m_styleSheets(new StyleSheetList(this))
257     , m_title("")
258     , m_titleSetExplicitly(false)
259     , m_imageLoadEventTimer(this, &Document::imageLoadEventTimerFired)
260     , m_updateFocusAppearanceTimer(this, &Document::updateFocusAppearanceTimerFired)
261 #if ENABLE(XSLT)
262     , m_transformSource(0)
263 #endif
264     , m_xmlVersion("1.0")
265     , m_xmlStandalone(false)
266 #if ENABLE(XBL)
267     , m_bindingManager(new XBLBindingManager(this))
268 #endif
269     , m_savedRenderer(0)
270     , m_secureForms(0)
271     , m_designMode(inherit)
272     , m_selfOnlyRefCount(0)
273 #if ENABLE(SVG)
274     , m_svgExtensions(0)
275 #endif
276     , m_hasDashboardRegions(false)
277     , m_dashboardRegionsDirty(false)
278     , m_accessKeyMapValid(false)
279     , m_createRenderers(true)
280     , m_inPageCache(false)
281     , m_isAllowedToLoadLocalResources(false)
282     , m_useSecureKeyboardEntryWhenActive(false)
283 #if USE(LOW_BANDWIDTH_DISPLAY)
284     , m_inLowBandwidthDisplay(false)
285 #endif
286     , m_isXHTML(isXHTML)
287     , m_numNodeLists(0)
288 {
289     m_document.resetSkippingRef(this);
290
291     m_printing = false;
292
293     m_frame = frame;
294     m_renderArena = 0;
295
296     m_axObjectCache = 0;
297     
298     // FIXME: DocLoader probably no longer needs the frame argument
299     m_docLoader = new DocLoader(frame, this);
300
301     visuallyOrdered = false;
302     m_bParsing = false;
303     m_docChanged = false;
304     m_tokenizer = 0;
305     m_wellFormed = false;
306
307     pMode = Strict;
308     hMode = XHtml;
309     m_textColor = Color::black;
310     m_listenerTypes = 0;
311     m_inDocument = true;
312     m_inStyleRecalc = false;
313     m_closeAfterStyleRecalc = false;
314     m_usesDescendantRules = false;
315     m_usesSiblingRules = false;
316     m_usesFirstLineRules = false;
317     m_usesFirstLetterRules = false;
318     m_gotoAnchorNeededAfterStylesheetsLoad = false;
319
320     m_styleSelector = new CSSStyleSelector(this, m_usersheet, m_styleSheets.get(), m_mappedElementSheet.get(), !inCompatMode());
321     m_didCalculateStyleSelector = false;
322     m_pendingStylesheets = 0;
323     m_ignorePendingStylesheets = false;
324     m_hasNodesWithPlaceholderStyle = false;
325     m_pendingSheetLayout = NoLayoutWithPendingSheets;
326
327     m_cssTarget = 0;
328
329     resetLinkColor();
330     resetVisitedLinkColor();
331     resetActiveLinkColor();
332
333     m_processingLoadEvent = false;
334     m_startTime = currentTime();
335     m_overMinimumLayoutThreshold = false;
336     
337     m_jsEditor = 0;
338
339     initSecurityOrigin();
340
341     static int docID = 0;
342     m_docID = docID++;
343 }
344
345 void Document::removedLastRef()
346 {
347     ASSERT(!m_deletionHasBegun);
348     if (m_selfOnlyRefCount) {
349         // If removing a child removes the last self-only ref, we don't
350         // want the document to be destructed until after
351         // removeAllChildren returns, so we guard ourselves with an
352         // extra self-only ref.
353
354         DocPtr<Document> guard(this);
355
356         // We must make sure not to be retaining any of our children through
357         // these extra pointers or we will create a reference cycle.
358         m_docType = 0;
359         m_focusedNode = 0;
360         m_hoverNode = 0;
361         m_activeNode = 0;
362         m_titleElement = 0;
363         m_documentElement = 0;
364
365         removeAllChildren();
366
367         deleteAllValues(m_markers);
368         m_markers.clear();
369
370         delete m_tokenizer;
371         m_tokenizer = 0;
372
373 #ifndef NDEBUG
374         m_inRemovedLastRefFunction = false;
375 #endif
376     } else {
377 #ifndef NDEBUG
378         m_deletionHasBegun = true;
379 #endif
380         delete this;
381     }
382 }
383
384 Document::~Document()
385 {
386     ASSERT(!renderer());
387     ASSERT(!m_inPageCache);
388     ASSERT(!m_savedRenderer);
389
390     removeAllEventListeners();
391
392 #if ENABLE(SVG)
393     delete m_svgExtensions;
394 #endif
395
396     XMLHttpRequest::detachRequests(this);
397     {
398         KJS::JSLock lock;
399         KJS::ScriptInterpreter::forgetAllDOMNodesForDocument(this);
400     }
401
402     if (m_docChanged && changedDocuments)
403         changedDocuments->remove(this);
404     delete m_tokenizer;
405     m_document.resetSkippingRef(0);
406     delete m_styleSelector;
407     delete m_docLoader;
408     
409     if (m_renderArena) {
410         delete m_renderArena;
411         m_renderArena = 0;
412     }
413
414 #if ENABLE(XSLT)
415     xmlFreeDoc((xmlDocPtr)m_transformSource);
416 #endif
417
418 #if ENABLE(XBL)
419     delete m_bindingManager;
420 #endif
421
422     deleteAllValues(m_markers);
423
424     if (m_axObjectCache) {
425         delete m_axObjectCache;
426         m_axObjectCache = 0;
427     }
428     m_decoder = 0;
429     
430     if (m_jsEditor) {
431         delete m_jsEditor;
432         m_jsEditor = 0;
433     }
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     
1049     ASSERT(!renderer() || renderArena());
1050     if (!renderer() || !renderArena())
1051         goto bail_out;
1052
1053     if (change == Force) {
1054         // style selector may set this again during recalc
1055         m_hasNodesWithPlaceholderStyle = false;
1056         
1057         RenderStyle* oldStyle = renderer()->style();
1058         if (oldStyle)
1059             oldStyle->ref();
1060         RenderStyle* _style = new (m_renderArena) RenderStyle();
1061         _style->ref();
1062         _style->setDisplay(BLOCK);
1063         _style->setVisuallyOrdered(visuallyOrdered);
1064         // ### make the font stuff _really_ work!!!!
1065
1066         FontDescription fontDescription;
1067         fontDescription.setUsePrinterFont(printing());
1068         if (Settings* settings = this->settings()) {
1069             if (printing() && !settings->shouldPrintBackgrounds())
1070                 _style->setForceBackgroundsToWhite(true);
1071             const AtomicString& stdfont = settings->standardFontFamily();
1072             if (!stdfont.isEmpty()) {
1073                 fontDescription.firstFamily().setFamily(stdfont);
1074                 fontDescription.firstFamily().appendFamily(0);
1075             }
1076             fontDescription.setKeywordSize(CSS_VAL_MEDIUM - CSS_VAL_XX_SMALL + 1);
1077             m_styleSelector->setFontSize(fontDescription, m_styleSelector->fontSizeForKeyword(CSS_VAL_MEDIUM, inCompatMode(), false));
1078         }
1079
1080         _style->setFontDescription(fontDescription);
1081         _style->font().update(0);
1082         if (inCompatMode())
1083             _style->setHtmlHacks(true); // enable html specific rendering tricks
1084
1085         StyleChange ch = diff(_style, oldStyle);
1086         if (renderer() && ch != NoChange)
1087             renderer()->setStyle(_style);
1088         if (change != Force)
1089             change = ch;
1090
1091         _style->deref(m_renderArena);
1092         if (oldStyle)
1093             oldStyle->deref(m_renderArena);
1094     }
1095
1096     for (Node* n = firstChild(); n; n = n->nextSibling())
1097         if (change >= Inherit || n->hasChangedChild() || n->changed())
1098             n->recalcStyle(change);
1099
1100     if (changed() && view())
1101         view()->layout();
1102
1103 bail_out:
1104     setChanged(NoStyleChange);
1105     setHasChangedChild(false);
1106     setDocumentChanged(false);
1107     
1108     m_inStyleRecalc = false;
1109     
1110     // If we wanted to call implicitClose() during recalcStyle, do so now that we're finished.
1111     if (m_closeAfterStyleRecalc) {
1112         m_closeAfterStyleRecalc = false;
1113         implicitClose();
1114     }
1115 }
1116
1117 void Document::updateRendering()
1118 {
1119     if (hasChangedChild())
1120         recalcStyle(NoChange);
1121 }
1122
1123 void Document::updateDocumentsRendering()
1124 {
1125     if (!changedDocuments)
1126         return;
1127
1128     while (Document* doc = changedDocuments->take()) {
1129         doc->m_docChanged = false;
1130         doc->updateRendering();
1131     }
1132 }
1133
1134 void Document::updateLayout()
1135 {
1136     if (Element* oe = ownerElement())
1137         oe->document()->updateLayout();
1138
1139     // FIXME: Dave Hyatt's pretty sure we can remove this because layout calls recalcStyle as needed.
1140     updateRendering();
1141
1142     // Only do a layout if changes have occurred that make it necessary.      
1143     FrameView* v = view();
1144     if (v && renderer() && (v->layoutPending() || renderer()->needsLayout()))
1145         v->layout();
1146 }
1147
1148 // FIXME: This is a bad idea and needs to be removed eventually.
1149 // Other browsers load stylesheets before they continue parsing the web page.
1150 // Since we don't, we can run JavaScript code that needs answers before the
1151 // stylesheets are loaded. Doing a layout ignoring the pending stylesheets
1152 // lets us get reasonable answers. The long term solution to this problem is
1153 // to instead suspend JavaScript execution.
1154 void Document::updateLayoutIgnorePendingStylesheets()
1155 {
1156     bool oldIgnore = m_ignorePendingStylesheets;
1157     
1158     if (!haveStylesheetsLoaded()) {
1159         m_ignorePendingStylesheets = true;
1160         // FIXME: We are willing to attempt to suppress painting with outdated style info only once.  Our assumption is that it would be
1161         // dangerous to try to stop it a second time, after page content has already been loaded and displayed
1162         // with accurate style information.  (Our suppression involves blanking the whole page at the
1163         // moment.  If it were more refined, we might be able to do something better.)
1164         // It's worth noting though that this entire method is a hack, since what we really want to do is
1165         // suspend JS instead of doing a layout with inaccurate information.
1166         if (body() && !body()->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
1167             m_pendingSheetLayout = DidLayoutWithPendingSheets;
1168             updateStyleSelector();
1169         } else if (m_hasNodesWithPlaceholderStyle)
1170             // If new nodes have been added or style recalc has been done with style sheets still pending, some nodes 
1171             // may not have had their real style calculated yet. Normally this gets cleaned when style sheets arrive 
1172             // but here we need up-to-date style immediatly.
1173             recalcStyle(Force);
1174     }
1175
1176     updateLayout();
1177
1178     m_ignorePendingStylesheets = oldIgnore;
1179 }
1180
1181 void Document::attach()
1182 {
1183     ASSERT(!attached());
1184     ASSERT(!m_inPageCache);
1185
1186     if (!m_renderArena)
1187         m_renderArena = new RenderArena();
1188     
1189     // Create the rendering tree
1190     setRenderer(new (m_renderArena) RenderView(this, view()));
1191
1192     recalcStyle(Force);
1193
1194     RenderObject* render = renderer();
1195     setRenderer(0);
1196
1197     ContainerNode::attach();
1198
1199     setRenderer(render);
1200 }
1201
1202 void Document::detach()
1203 {
1204     ASSERT(attached());
1205     ASSERT(!m_inPageCache);
1206
1207     RenderObject* render = renderer();
1208
1209     // indicate destruction mode,  i.e. attached() but renderer == 0
1210     setRenderer(0);
1211     
1212     // Empty out these lists as a performance optimization, since detaching
1213     // all the individual render objects will cause all the RenderImage
1214     // objects to remove themselves from the lists.
1215     m_imageLoadEventDispatchSoonList.clear();
1216     m_imageLoadEventDispatchingList.clear();
1217     
1218     m_hoverNode = 0;
1219     m_focusedNode = 0;
1220     m_activeNode = 0;
1221
1222     ContainerNode::detach();
1223
1224     if (render)
1225         render->destroy();
1226
1227     // FIXME: is this needed or desirable?
1228     m_frame = 0;
1229     
1230     if (m_renderArena) {
1231         delete m_renderArena;
1232         m_renderArena = 0;
1233     }
1234 }
1235
1236 void Document::removeAllEventListenersFromAllNodes()
1237 {
1238     m_windowEventListeners.clear();
1239     removeAllDisconnectedNodeEventListeners();
1240     for (Node *n = this; n; n = n->traverseNextNode()) {
1241         if (!n->isEventTargetNode())
1242             continue;
1243         EventTargetNodeCast(n)->removeAllEventListeners();
1244     }
1245 }
1246
1247 void Document::registerDisconnectedNodeWithEventListeners(Node* node)
1248 {
1249     m_disconnectedNodesWithEventListeners.add(node);
1250 }
1251
1252 void Document::unregisterDisconnectedNodeWithEventListeners(Node* node)
1253 {
1254     m_disconnectedNodesWithEventListeners.remove(node);
1255 }
1256
1257 void Document::removeAllDisconnectedNodeEventListeners()
1258 {
1259     HashSet<Node*>::iterator end = m_disconnectedNodesWithEventListeners.end();
1260     for (HashSet<Node*>::iterator i = m_disconnectedNodesWithEventListeners.begin(); i != end; ++i)
1261         EventTargetNodeCast(*i)->removeAllEventListeners();
1262     m_disconnectedNodesWithEventListeners.clear();
1263 }
1264
1265 AXObjectCache* Document::axObjectCache() const
1266 {
1267     // The only document that actually has a AXObjectCache is the top-level
1268     // document.  This is because we need to be able to get from any WebCoreAXObject
1269     // to any other WebCoreAXObject on the same page.  Using a single cache allows
1270     // lookups across nested webareas (i.e. multiple documents).
1271     
1272     if (m_axObjectCache) {
1273         // return already known top-level cache
1274         if (!ownerElement())
1275             return m_axObjectCache;
1276         
1277         // In some pages with frames, the cache is created before the sub-webarea is
1278         // inserted into the tree.  Here, we catch that case and just toss the old
1279         // cache and start over.
1280         delete m_axObjectCache;
1281         m_axObjectCache = 0;
1282     }
1283
1284     // ask the top-level document for its cache
1285     Document* doc = topDocument();
1286     if (doc != this)
1287         return doc->axObjectCache();
1288     
1289     // this is the top-level document, so install a new cache
1290     m_axObjectCache = new AXObjectCache;
1291     return m_axObjectCache;
1292 }
1293
1294 void Document::setVisuallyOrdered()
1295 {
1296     visuallyOrdered = true;
1297     if (renderer())
1298         renderer()->style()->setVisuallyOrdered(true);
1299 }
1300
1301 Tokenizer* Document::createTokenizer()
1302 {
1303     // FIXME: this should probably pass the frame instead
1304     return new XMLTokenizer(this, view());
1305 }
1306
1307 void Document::open()
1308 {
1309     // This is work that we should probably do in clear(), but we can't have it
1310     // happen when implicitOpen() is called unless we reorganize Frame code.
1311     if (Document *parent = parentDocument()) {
1312         if (m_url.isEmpty() || m_url == "about:blank")
1313             setURL(parent->baseURL());
1314         if (m_baseURL.isEmpty() || m_baseURL == "about:blank")
1315             setBaseURL(parent->baseURL());
1316     }
1317
1318     if (m_frame) {
1319         if (m_frame->loader()->isLoadingMainResource() || (tokenizer() && tokenizer()->executingScript()))
1320             return;
1321     
1322         if (m_frame->loader()->state() == FrameStateProvisional)
1323             m_frame->loader()->stopAllLoaders();
1324     }
1325     
1326     implicitOpen();
1327
1328     if (m_frame)
1329         m_frame->loader()->didExplicitOpen();
1330 }
1331
1332 void Document::cancelParsing()
1333 {
1334     if (m_tokenizer) {
1335         // We have to clear the tokenizer to avoid possibly triggering
1336         // the onload handler when closing as a side effect of a cancel-style
1337         // change, such as opening a new document or closing the window while
1338         // still parsing
1339         delete m_tokenizer;
1340         m_tokenizer = 0;
1341         close();
1342     }
1343 }
1344
1345 void Document::implicitOpen()
1346 {
1347     cancelParsing();
1348
1349     clear();
1350     m_tokenizer = createTokenizer();
1351     setParsing(true);
1352 }
1353
1354 HTMLElement* Document::body()
1355 {
1356     Node* de = documentElement();
1357     if (!de)
1358         return 0;
1359     
1360     // try to prefer a FRAMESET element over BODY
1361     Node* body = 0;
1362     for (Node* i = de->firstChild(); i; i = i->nextSibling()) {
1363         if (i->hasTagName(framesetTag))
1364             return static_cast<HTMLElement*>(i);
1365         
1366         if (i->hasTagName(bodyTag))
1367             body = i;
1368     }
1369     return static_cast<HTMLElement*>(body);
1370 }
1371
1372 void Document::setBody(PassRefPtr<HTMLElement> newBody, ExceptionCode& ec)
1373 {
1374     if (!newBody) { 
1375         ec = HIERARCHY_REQUEST_ERR;
1376         return;
1377     }
1378
1379     HTMLElement* b = body();
1380     if (!b)
1381         documentElement()->appendChild(newBody, ec);
1382     else
1383         documentElement()->replaceChild(newBody, b, ec);
1384 }
1385
1386 HTMLHeadElement* Document::head()
1387 {
1388     Node* de = documentElement();
1389     if (!de)
1390         return 0;
1391
1392     for (Node* e = de->firstChild(); e; e = e->nextSibling())
1393         if (e->hasTagName(headTag))
1394             return static_cast<HTMLHeadElement*>(e);
1395
1396     return 0;
1397 }
1398
1399 void Document::close()
1400 {
1401     Frame* frame = this->frame();
1402     if (frame) {
1403         // This code calls implicitClose() if all loading has completed.
1404         FrameLoader* frameLoader = frame->loader();
1405         frameLoader->endIfNotLoadingMainResource();
1406         frameLoader->checkCompleted();
1407     } else {
1408         // Because we have no frame, we don't know if all loading has completed,
1409         // so we just call implicitClose() immediately. FIXME: This might fire
1410         // the load event prematurely <http://bugs.webkit.org/show_bug.cgi?id=14568>.
1411         implicitClose();
1412     }
1413 }
1414
1415 void Document::implicitClose()
1416 {
1417     // 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.
1418     if (m_inStyleRecalc) {
1419         m_closeAfterStyleRecalc = true;
1420         return;
1421     }
1422
1423     bool wasLocationChangePending = frame() && frame()->loader()->isScheduledLocationChangePending();
1424     bool doload = !parsing() && m_tokenizer && !m_processingLoadEvent && !wasLocationChangePending;
1425     
1426     if (!doload)
1427         return;
1428
1429     m_processingLoadEvent = true;
1430
1431     m_wellFormed = m_tokenizer && m_tokenizer->wellFormed();
1432
1433     // We have to clear the tokenizer, in case someone document.write()s from the
1434     // onLoad event handler, as in Radar 3206524.
1435     delete m_tokenizer;
1436     m_tokenizer = 0;
1437
1438     // Create a body element if we don't already have one. See Radar 3758785.
1439     if (!this->body() && isHTMLDocument()) {
1440         if (Node* documentElement = this->documentElement()) {
1441             ExceptionCode ec = 0;
1442             documentElement->appendChild(new HTMLBodyElement(this), ec);
1443             ASSERT(!ec);
1444         }
1445     }
1446     
1447     dispatchImageLoadEventsNow();
1448     this->dispatchWindowEvent(loadEvent, false, false);
1449     if (Frame* f = frame())
1450         f->loader()->handledOnloadEvents();
1451 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
1452     if (!ownerElement())
1453         printf("onload fired at %d\n", elapsedTime());
1454 #endif
1455
1456     m_processingLoadEvent = false;
1457
1458     // An event handler may have removed the frame
1459     if (!frame())
1460         return;
1461
1462     // Make sure both the initial layout and reflow happen after the onload
1463     // fires. This will improve onload scores, and other browsers do it.
1464     // If they wanna cheat, we can too. -dwh
1465
1466     if (frame()->loader()->isScheduledLocationChangePending() && elapsedTime() < cLayoutScheduleThreshold) {
1467         // Just bail out. Before or during the onload we were shifted to another page.
1468         // The old i-Bench suite does this. When this happens don't bother painting or laying out.        
1469         view()->unscheduleRelayout();
1470         return;
1471     }
1472
1473     frame()->loader()->checkCallImplicitClose();
1474
1475     // Now do our painting/layout, but only if we aren't in a subframe or if we're in a subframe
1476     // that has been sized already.  Otherwise, our view size would be incorrect, so doing any 
1477     // layout/painting now would be pointless.
1478     if (!ownerElement() || (ownerElement()->renderer() && !ownerElement()->renderer()->needsLayout())) {
1479         updateRendering();
1480         
1481         // Always do a layout after loading if needed.
1482         if (view() && renderer() && (!renderer()->firstChild() || renderer()->needsLayout()))
1483             view()->layout();
1484             
1485         // Paint immediately after the document is ready.  We do this to ensure that any timers set by the
1486         // onload don't have a chance to fire before we would have painted.  To avoid over-flushing we only
1487         // worry about this for the top-level document.
1488 #if !PLATFORM(MAC)
1489         // FIXME: This causes a timing issue with the dispatchDidFinishLoad delegate callback.
1490         // See <rdar://problem/5092361>
1491         if (view() && !ownerElement())
1492             view()->update();
1493 #endif
1494     }
1495
1496 #if PLATFORM(MAC)
1497     if (renderer() && AXObjectCache::accessibilityEnabled())
1498         axObjectCache()->postNotificationToElement(renderer(), "AXLoadComplete");
1499 #endif
1500
1501 #if ENABLE(SVG)
1502     // FIXME: Officially, time 0 is when the outermost <svg> receives its
1503     // SVGLoad event, but we don't implement those yet.  This is close enough
1504     // for now.  In some cases we should have fired earlier.
1505     if (svgExtensions())
1506         accessSVGExtensions()->startAnimations();
1507 #endif
1508 }
1509
1510 void Document::setParsing(bool b)
1511 {
1512     m_bParsing = b;
1513     if (!m_bParsing && view())
1514         view()->scheduleRelayout();
1515
1516 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
1517     if (!ownerElement() && !m_bParsing)
1518         printf("Parsing finished at %d\n", elapsedTime());
1519 #endif
1520 }
1521
1522 bool Document::shouldScheduleLayout()
1523 {
1524     // We can update layout if:
1525     // (a) we actually need a layout
1526     // (b) our stylesheets are all loaded
1527     // (c) we have a <body>
1528     return (renderer() && renderer()->needsLayout() && haveStylesheetsLoaded() &&
1529             documentElement() && documentElement()->renderer() &&
1530             (!documentElement()->hasTagName(htmlTag) || body()));
1531 }
1532
1533 int Document::minimumLayoutDelay()
1534 {
1535     if (m_overMinimumLayoutThreshold)
1536         return 0;
1537     
1538     int elapsed = elapsedTime();
1539     m_overMinimumLayoutThreshold = elapsed > cLayoutScheduleThreshold;
1540     
1541     // We'll want to schedule the timer to fire at the minimum layout threshold.
1542     return max(0, cLayoutScheduleThreshold - elapsed);
1543 }
1544
1545 int Document::elapsedTime() const
1546 {
1547     return static_cast<int>((currentTime() - m_startTime) * 1000);
1548 }
1549
1550 void Document::write(const DeprecatedString& text)
1551 {
1552     write(String(text));
1553 }
1554
1555 void Document::write(const String& text)
1556 {
1557 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
1558     if (!ownerElement())
1559         printf("Beginning a document.write at %d\n", elapsedTime());
1560 #endif
1561     
1562     if (!m_tokenizer) {
1563         open();
1564         ASSERT(m_tokenizer);
1565         if (!m_tokenizer)
1566             return;
1567         write(DeprecatedString("<html>"));
1568     }
1569     m_tokenizer->write(text, false);
1570     
1571 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
1572     if (!ownerElement())
1573         printf("Ending a document.write at %d\n", elapsedTime());
1574 #endif    
1575 }
1576
1577 void Document::writeln(const String &text)
1578 {
1579     write(text);
1580     write(String("\n"));
1581 }
1582
1583 void Document::finishParsing()
1584 {
1585 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
1586     if (!ownerElement())
1587         printf("Received all data at %d\n", elapsedTime());
1588 #endif
1589     
1590     // Let the tokenizer go through as much data as it can.  There will be three possible outcomes after
1591     // finish() is called:
1592     // (1) All remaining data is parsed, document isn't loaded yet
1593     // (2) All remaining data is parsed, document is loaded, tokenizer gets deleted
1594     // (3) Data is still remaining to be parsed.
1595     if (m_tokenizer)
1596         m_tokenizer->finish();
1597 }
1598
1599 void Document::clear()
1600 {
1601     delete m_tokenizer;
1602     m_tokenizer = 0;
1603
1604     removeChildren();
1605
1606     m_windowEventListeners.clear();
1607 }
1608
1609 void Document::setURL(const DeprecatedString& url)
1610 {
1611     if (url == m_url)
1612         return;
1613
1614     m_url = url;
1615     if (m_styleSelector)
1616         m_styleSelector->setEncodedURL(m_url);
1617
1618     m_isAllowedToLoadLocalResources = shouldBeAllowedToLoadLocalResources();
1619  }
1620  
1621 bool Document::shouldBeAllowedToLoadLocalResources() const
1622 {
1623     if (FrameLoader::shouldTreatURLAsLocal(m_url))
1624         return true;
1625
1626     Frame* frame = this->frame();
1627     if (!frame)
1628         return false;
1629     
1630     DocumentLoader* documentLoader = frame->loader()->documentLoader();
1631     if (!documentLoader)
1632         return false;
1633
1634     if (m_url == "about:blank" && frame->loader()->opener() && frame->loader()->opener()->document()->isAllowedToLoadLocalResources())
1635         return true;
1636     
1637     return documentLoader->substituteData().isValid();
1638 }
1639
1640 void Document::setBaseURL(const DeprecatedString& baseURL) 
1641
1642     m_baseURL = baseURL; 
1643     if (m_elemSheet)
1644         m_elemSheet->setHref(m_baseURL);
1645 }
1646
1647 void Document::setCSSStyleSheet(const String &url, const String& charset, const String &sheet)
1648 {
1649     m_sheet = new CSSStyleSheet(this, url, charset);
1650     m_sheet->parseString(sheet);
1651
1652     updateStyleSelector();
1653 }
1654
1655 void Document::setUserStyleSheet(const String& sheet)
1656 {
1657     if (m_usersheet != sheet) {
1658         m_usersheet = sheet;
1659         updateStyleSelector();
1660     }
1661 }
1662
1663 CSSStyleSheet* Document::elementSheet()
1664 {
1665     if (!m_elemSheet)
1666         m_elemSheet = new CSSStyleSheet(this, baseURL());
1667     return m_elemSheet.get();
1668 }
1669
1670 CSSStyleSheet* Document::mappedElementSheet()
1671 {
1672     if (!m_mappedElementSheet)
1673         m_mappedElementSheet = new CSSStyleSheet(this, baseURL());
1674     return m_mappedElementSheet.get();
1675 }
1676
1677 void Document::determineParseMode(const String&)
1678 {
1679     // For XML documents use strict parse mode.
1680     // HTML overrides this method to determine the parse mode.
1681     pMode = Strict;
1682     hMode = XHtml;
1683 }
1684
1685 static Node* nextNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
1686 {
1687     // Search is inclusive of start
1688     for (Node* n = start; n; n = n->traverseNextNode())
1689         if (n->isKeyboardFocusable(event) && n->tabIndex() == tabIndex)
1690             return n;
1691     
1692     return 0;
1693 }
1694
1695 static Node* previousNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
1696 {
1697     // Search is inclusive of start
1698     for (Node* n = start; n; n = n->traversePreviousNode())
1699         if (n->isKeyboardFocusable(event) && n->tabIndex() == tabIndex)
1700             return n;
1701     
1702     return 0;
1703 }
1704
1705 static Node* nextNodeWithGreaterTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
1706 {
1707     // Search is inclusive of start
1708     int winningTabIndex = SHRT_MAX + 1;
1709     Node* winner = 0;
1710     for (Node* n = start; n; n = n->traverseNextNode())
1711         if (n->isKeyboardFocusable(event) && n->tabIndex() > tabIndex && n->tabIndex() < winningTabIndex) {
1712             winner = n;
1713             winningTabIndex = n->tabIndex();
1714         }
1715     
1716     return winner;
1717 }
1718
1719 static Node* previousNodeWithLowerTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
1720 {
1721     // Search is inclusive of start
1722     int winningTabIndex = 0;
1723     Node* winner = 0;
1724     for (Node* n = start; n; n = n->traversePreviousNode())
1725         if (n->isKeyboardFocusable(event) && n->tabIndex() < tabIndex && n->tabIndex() > winningTabIndex) {
1726             winner = n;
1727             winningTabIndex = n->tabIndex();
1728         }
1729     
1730     return winner;
1731 }
1732
1733 Node* Document::nextFocusableNode(Node* start, KeyboardEvent* event)
1734 {
1735     if (start) {
1736         // First try to find a node with the same tabindex as start that comes after start in the document.
1737         if (Node* winner = nextNodeWithExactTabIndex(start->traverseNextNode(), start->tabIndex(), event))
1738             return winner;
1739
1740         if (start->tabIndex() == 0)
1741             // We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order.
1742             return 0;
1743     }
1744
1745     // Look for the first node in the document that:
1746     // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and
1747     // 2) comes first in the document, if there's a tie.
1748     if (Node* winner = nextNodeWithGreaterTabIndex(this, start ? start->tabIndex() : 0, event))
1749         return winner;
1750
1751     // There are no nodes with a tabindex greater than start's tabindex,
1752     // so find the first node with a tabindex of 0.
1753     return nextNodeWithExactTabIndex(this, 0, event);
1754 }
1755
1756 Node* Document::previousFocusableNode(Node* start, KeyboardEvent* event)
1757 {
1758     Node* last;
1759     for (last = this; last->lastChild(); last = last->lastChild())
1760         ; // Empty loop.
1761
1762     // First try to find the last node in the document that comes before start and has the same tabindex as start.
1763     // If start is null, find the last node in the document with a tabindex of 0.
1764     Node* startingNode;
1765     int startingTabIndex;
1766     if (start) {
1767         startingNode = start->traversePreviousNode();
1768         startingTabIndex = start->tabIndex();
1769     } else {
1770         startingNode = last;
1771         startingTabIndex = 0;
1772     }
1773
1774     if (Node* winner = previousNodeWithExactTabIndex(startingNode, startingTabIndex, event))
1775         return winner;
1776
1777     // There are no nodes before start with the same tabindex as start, so look for a node that:
1778     // 1) has the highest non-zero tabindex (that is less than start's tabindex), and
1779     // 2) comes last in the document, if there's a tie.
1780     startingTabIndex = (start && start->tabIndex()) ? start->tabIndex() : SHRT_MAX;
1781     return previousNodeWithLowerTabIndex(last, startingTabIndex, event);
1782 }
1783
1784 int Document::nodeAbsIndex(Node *node)
1785 {
1786     ASSERT(node->document() == this);
1787
1788     int absIndex = 0;
1789     for (Node *n = node; n && n != this; n = n->traversePreviousNode())
1790         absIndex++;
1791     return absIndex;
1792 }
1793
1794 Node *Document::nodeWithAbsIndex(int absIndex)
1795 {
1796     Node *n = this;
1797     for (int i = 0; n && (i < absIndex); i++) {
1798         n = n->traverseNextNode();
1799     }
1800     return n;
1801 }
1802
1803 void Document::processHttpEquiv(const String &equiv, const String &content)
1804 {
1805     ASSERT(!equiv.isNull() && !content.isNull());
1806
1807     Frame *frame = this->frame();
1808
1809     if (equalIgnoringCase(equiv, "default-style")) {
1810         // The preferred style set has been overridden as per section 
1811         // 14.3.2 of the HTML4.0 specification.  We need to update the
1812         // sheet used variable and then update our style selector. 
1813         // For more info, see the test at:
1814         // http://www.hixie.ch/tests/evil/css/import/main/preferred.html
1815         // -dwh
1816         m_selectedStylesheetSet = content;
1817         m_preferredStylesheetSet = content;
1818         updateStyleSelector();
1819     } else if (equalIgnoringCase(equiv, "refresh")) {
1820         double delay;
1821         String url;
1822         if (frame && parseHTTPRefresh(content, true, delay, url)) {
1823             if (url.isEmpty())
1824                 url = frame->loader()->url().url();
1825             else
1826                 url = completeURL(url);
1827             frame->loader()->scheduleHTTPRedirection(delay, url);
1828         }
1829     } else if (equalIgnoringCase(equiv, "set-cookie")) {
1830         // FIXME: make setCookie work on XML documents too; e.g. in case of <html:meta .....>
1831         if (isHTMLDocument())
1832             static_cast<HTMLDocument*>(this)->setCookie(content);
1833     }
1834 }
1835
1836 MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& request, const IntPoint& documentPoint, const PlatformMouseEvent& event)
1837 {
1838     ASSERT(!renderer() || renderer()->isRenderView());
1839
1840     if (!renderer())
1841         return MouseEventWithHitTestResults(event, HitTestResult(IntPoint()));
1842
1843     HitTestResult result(documentPoint);
1844     renderer()->layer()->hitTest(request, result);
1845
1846     if (!request.readonly)
1847         updateRendering();
1848
1849     return MouseEventWithHitTestResults(event, result);
1850 }
1851
1852 // DOM Section 1.1.1
1853 bool Document::childTypeAllowed(NodeType type)
1854 {
1855     switch (type) {
1856         case ATTRIBUTE_NODE:
1857         case CDATA_SECTION_NODE:
1858         case DOCUMENT_FRAGMENT_NODE:
1859         case DOCUMENT_NODE:
1860         case ENTITY_NODE:
1861         case ENTITY_REFERENCE_NODE:
1862         case NOTATION_NODE:
1863         case TEXT_NODE:
1864         case XPATH_NAMESPACE_NODE:
1865             return false;
1866         case COMMENT_NODE:
1867         case PROCESSING_INSTRUCTION_NODE:
1868             return true;
1869         case DOCUMENT_TYPE_NODE:
1870         case ELEMENT_NODE:
1871             // Documents may contain no more than one of each of these.
1872             // (One Element and one DocumentType.)
1873             for (Node* c = firstChild(); c; c = c->nextSibling())
1874                 if (c->nodeType() == type)
1875                     return false;
1876             return true;
1877     }
1878     return false;
1879 }
1880
1881 bool Document::canReplaceChild(Node* newChild, Node* oldChild)
1882 {
1883     if (oldChild->nodeType() == newChild->nodeType())
1884         return true;
1885
1886     int numDoctypes = 0;
1887     int numElements = 0;
1888
1889     // First, check how many doctypes and elements we have, not counting
1890     // the child we're about to remove.
1891     for (Node* c = firstChild(); c; c = c->nextSibling()) {
1892         if (c == oldChild)
1893             continue;
1894         
1895         switch (c->nodeType()) {
1896             case DOCUMENT_TYPE_NODE:
1897                 numDoctypes++;
1898                 break;
1899             case ELEMENT_NODE:
1900                 numElements++;
1901                 break;
1902             default:
1903                 break;
1904         }
1905     }
1906     
1907     // Then, see how many doctypes and elements might be added by the new child.
1908     if (newChild->nodeType() == DOCUMENT_FRAGMENT_NODE) {
1909         for (Node* c = firstChild(); c; c = c->nextSibling()) {
1910             switch (c->nodeType()) {
1911                 case ATTRIBUTE_NODE:
1912                 case CDATA_SECTION_NODE:
1913                 case DOCUMENT_FRAGMENT_NODE:
1914                 case DOCUMENT_NODE:
1915                 case ENTITY_NODE:
1916                 case ENTITY_REFERENCE_NODE:
1917                 case NOTATION_NODE:
1918                 case TEXT_NODE:
1919                 case XPATH_NAMESPACE_NODE:
1920                     return false;
1921                 case COMMENT_NODE:
1922                 case PROCESSING_INSTRUCTION_NODE:
1923                     break;
1924                 case DOCUMENT_TYPE_NODE:
1925                     numDoctypes++;
1926                     break;
1927                 case ELEMENT_NODE:
1928                     numElements++;
1929                     break;
1930             }
1931         }
1932     } else {
1933         switch (newChild->nodeType()) {
1934             case ATTRIBUTE_NODE:
1935             case CDATA_SECTION_NODE:
1936             case DOCUMENT_FRAGMENT_NODE:
1937             case DOCUMENT_NODE:
1938             case ENTITY_NODE:
1939             case ENTITY_REFERENCE_NODE:
1940             case NOTATION_NODE:
1941             case TEXT_NODE:
1942             case XPATH_NAMESPACE_NODE:
1943                 return false;
1944             case COMMENT_NODE:
1945             case PROCESSING_INSTRUCTION_NODE:
1946                 return true;
1947             case DOCUMENT_TYPE_NODE:
1948                 numDoctypes++;
1949                 break;
1950             case ELEMENT_NODE:
1951                 numElements++;
1952                 break;
1953         }                
1954     }
1955         
1956     if (numElements > 1 || numDoctypes > 1)
1957         return false;
1958     
1959     return true;
1960 }
1961
1962 PassRefPtr<Node> Document::cloneNode(bool /*deep*/)
1963 {
1964     // Spec says cloning Document nodes is "implementation dependent"
1965     // so we do not support it...
1966     return 0;
1967 }
1968
1969 StyleSheetList* Document::styleSheets()
1970 {
1971     return m_styleSheets.get();
1972 }
1973
1974 String Document::preferredStylesheetSet() const
1975 {
1976     return m_preferredStylesheetSet;
1977 }
1978
1979 String Document::selectedStylesheetSet() const
1980 {
1981     return m_selectedStylesheetSet;
1982 }
1983
1984 void Document::setSelectedStylesheetSet(const String& aString)
1985 {
1986     m_selectedStylesheetSet = aString;
1987     updateStyleSelector();
1988     if (renderer())
1989         renderer()->repaint();
1990 }
1991
1992 // This method is called whenever a top-level stylesheet has finished loading.
1993 void Document::removePendingSheet()
1994 {
1995     // Make sure we knew this sheet was pending, and that our count isn't out of sync.
1996     ASSERT(m_pendingStylesheets > 0);
1997
1998     m_pendingStylesheets--;
1999     
2000 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2001     if (!ownerElement())
2002         printf("Stylesheet loaded at time %d. %d stylesheets still remain.\n", elapsedTime(), m_pendingStylesheets);
2003 #endif
2004
2005     updateStyleSelector();
2006     
2007     if (!m_pendingStylesheets && m_tokenizer)
2008         m_tokenizer->executeScriptsWaitingForStylesheets();
2009
2010     if (!m_pendingStylesheets && m_gotoAnchorNeededAfterStylesheetsLoad && m_frame)
2011         m_frame->loader()->gotoAnchor();
2012 }
2013
2014 void Document::updateStyleSelector()
2015 {
2016     // Don't bother updating, since we haven't loaded all our style info yet
2017     // and haven't calculated the style selector for the first time.
2018     if (!m_didCalculateStyleSelector && !haveStylesheetsLoaded())
2019         return;
2020
2021     if (didLayoutWithPendingStylesheets() && m_pendingStylesheets <= 0) {
2022         m_pendingSheetLayout = IgnoreLayoutWithPendingSheets;
2023         if (renderer())
2024             renderer()->repaint();
2025     }
2026
2027 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2028     if (!ownerElement())
2029         printf("Beginning update of style selector at time %d.\n", elapsedTime());
2030 #endif
2031
2032     recalcStyleSelector();
2033     recalcStyle(Force);
2034
2035 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2036     if (!ownerElement())
2037         printf("Finished update of style selector at time %d\n", elapsedTime());
2038 #endif
2039
2040     if (renderer()) {
2041         renderer()->setNeedsLayoutAndPrefWidthsRecalc();
2042         if (view())
2043             view()->scheduleRelayout();
2044     }
2045 }
2046
2047 void Document::recalcStyleSelector()
2048 {
2049     if (!renderer() || !attached())
2050         return;
2051
2052     DeprecatedPtrList<StyleSheet> oldStyleSheets = m_styleSheets->styleSheets;
2053     m_styleSheets->styleSheets.clear();
2054     Node *n;
2055     for (n = this; n; n = n->traverseNextNode()) {
2056         StyleSheet *sheet = 0;
2057
2058         if (n->nodeType() == PROCESSING_INSTRUCTION_NODE)
2059         {
2060             // Processing instruction (XML documents only)
2061             ProcessingInstruction* pi = static_cast<ProcessingInstruction*>(n);
2062             sheet = pi->sheet();
2063 #if ENABLE(XSLT)
2064             // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
2065             if (pi->isXSL() && !transformSourceDocument()) {
2066                 // Don't apply XSL transforms until loading is finished.
2067                 if (!parsing())
2068                     applyXSLTransform(pi);
2069                 return;
2070             }
2071 #endif
2072             if (!sheet && !pi->localHref().isEmpty())
2073             {
2074                 // Processing instruction with reference to an element in this document - e.g.
2075                 // <?xml-stylesheet href="#mystyle">, with the element
2076                 // <foo id="mystyle">heading { color: red; }</foo> at some location in
2077                 // the document
2078                 Element* elem = getElementById(pi->localHref().impl());
2079                 if (elem) {
2080                     String sheetText("");
2081                     Node *c;
2082                     for (c = elem->firstChild(); c; c = c->nextSibling()) {
2083                         if (c->nodeType() == TEXT_NODE || c->nodeType() == CDATA_SECTION_NODE)
2084                             sheetText += c->nodeValue();
2085                     }
2086
2087                     CSSStyleSheet *cssSheet = new CSSStyleSheet(this);
2088                     cssSheet->parseString(sheetText);
2089                     pi->setCSSStyleSheet(cssSheet);
2090                     sheet = cssSheet;
2091                 }
2092             }
2093
2094         } else if (n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag))
2095 #if ENABLE(SVG)
2096             ||  (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
2097 #endif
2098         ) {
2099             Element* e = static_cast<Element*>(n);
2100             DeprecatedString title = e->getAttribute(titleAttr).deprecatedString();
2101             bool enabledViaScript = false;
2102             if (e->hasLocalName(linkTag)) {
2103                 // <LINK> element
2104                 HTMLLinkElement* l = static_cast<HTMLLinkElement*>(n);
2105                 if (l->isDisabled())
2106                     continue;
2107                 enabledViaScript = l->isEnabledViaScript();
2108                 if (l->isLoading()) {
2109                     // it is loading but we should still decide which style sheet set to use
2110                     if (!enabledViaScript && !title.isEmpty() && m_preferredStylesheetSet.isEmpty()) {
2111                         const AtomicString& rel = e->getAttribute(relAttr);
2112                         if (!rel.domString().contains("alternate")) {
2113                             m_preferredStylesheetSet = title;
2114                             m_selectedStylesheetSet = title;
2115                         }
2116                     }
2117                     continue;
2118                 }
2119                 if (!l->sheet())
2120                     title = DeprecatedString::null;
2121             }
2122
2123             // Get the current preferred styleset.  This is the
2124             // set of sheets that will be enabled.
2125 #if ENABLE(SVG)
2126             if (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
2127                 sheet = static_cast<SVGStyleElement*>(n)->sheet();
2128             else
2129 #endif
2130             if (e->hasLocalName(linkTag))
2131                 sheet = static_cast<HTMLLinkElement*>(n)->sheet();
2132             else
2133                 // <STYLE> element
2134                 sheet = static_cast<HTMLStyleElement*>(n)->sheet();
2135
2136             // Check to see if this sheet belongs to a styleset
2137             // (thus making it PREFERRED or ALTERNATE rather than
2138             // PERSISTENT).
2139             if (!enabledViaScript && !title.isEmpty()) {
2140                 // Yes, we have a title.
2141                 if (m_preferredStylesheetSet.isEmpty()) {
2142                     // No preferred set has been established.  If
2143                     // we are NOT an alternate sheet, then establish
2144                     // us as the preferred set.  Otherwise, just ignore
2145                     // this sheet.
2146                     DeprecatedString rel = e->getAttribute(relAttr).deprecatedString();
2147                     if (e->hasLocalName(styleTag) || !rel.contains("alternate"))
2148                         m_preferredStylesheetSet = m_selectedStylesheetSet = title;
2149                 }
2150                 
2151                 if (title != m_preferredStylesheetSet)
2152                     sheet = 0;
2153
2154 #if ENABLE(SVG)
2155                 if (!n->isHTMLElement())
2156                     title = title.replace('&', "&&");
2157 #endif
2158             }
2159         }
2160
2161         if (sheet) {
2162             sheet->ref();
2163             m_styleSheets->styleSheets.append(sheet);
2164         }
2165     
2166         // For HTML documents, stylesheets are not allowed within/after the <BODY> tag. So we
2167         // can stop searching here.
2168         if (isHTMLDocument() && n->hasTagName(bodyTag))
2169             break;
2170     }
2171
2172     // De-reference all the stylesheets in the old list
2173     DeprecatedPtrListIterator<StyleSheet> it(oldStyleSheets);
2174     for (; it.current(); ++it)
2175         it.current()->deref();
2176
2177     // Create a new style selector
2178     delete m_styleSelector;
2179     String usersheet = m_usersheet;
2180     if (view() && view()->mediaType() == "print")
2181         usersheet += m_printSheet;
2182     m_styleSelector = new CSSStyleSelector(this, usersheet, m_styleSheets.get(), m_mappedElementSheet.get(), !inCompatMode());
2183     m_styleSelector->setEncodedURL(m_url);
2184     m_didCalculateStyleSelector = true;
2185 }
2186
2187 void Document::setHoverNode(PassRefPtr<Node> newHoverNode)
2188 {
2189     m_hoverNode = newHoverNode;
2190 }
2191
2192 void Document::setActiveNode(PassRefPtr<Node> newActiveNode)
2193 {
2194     m_activeNode = newActiveNode;
2195 }
2196
2197 void Document::focusedNodeRemoved(Node* node)
2198 {
2199     setFocusedNode(0);
2200 }
2201
2202 void Document::hoveredNodeDetached(Node* node)
2203 {
2204     if (!m_hoverNode || (node != m_hoverNode && (!m_hoverNode->isTextNode() || node != m_hoverNode->parent())))
2205         return;
2206
2207     m_hoverNode = node->parent();
2208     while (m_hoverNode && !m_hoverNode->renderer())
2209         m_hoverNode = m_hoverNode->parent();
2210     if (frame())
2211         frame()->eventHandler()->scheduleHoverStateUpdate();
2212 }
2213
2214 void Document::activeChainNodeDetached(Node* node)
2215 {
2216     if (!m_activeNode || (node != m_activeNode && (!m_activeNode->isTextNode() || node != m_activeNode->parent())))
2217         return;
2218
2219     m_activeNode = node->parent();
2220     while (m_activeNode && !m_activeNode->renderer())
2221         m_activeNode = m_activeNode->parent();
2222 }
2223
2224 const Vector<DashboardRegionValue>& Document::dashboardRegions() const
2225 {
2226     return m_dashboardRegions;
2227 }
2228
2229 void Document::setDashboardRegions(const Vector<DashboardRegionValue>& regions)
2230 {
2231     m_dashboardRegions = regions;
2232     setDashboardRegionsDirty(false);
2233 }
2234
2235 bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
2236 {    
2237     // Make sure newFocusedNode is actually in this document
2238     if (newFocusedNode && (newFocusedNode->document() != this))
2239         return true;
2240
2241     if (m_focusedNode == newFocusedNode)
2242         return true;
2243         
2244     bool focusChangeBlocked = false;
2245     RefPtr<Node> oldFocusedNode = m_focusedNode;
2246     m_focusedNode = 0;
2247
2248     // Remove focus from the existing focus node (if any)
2249     if (oldFocusedNode && !oldFocusedNode->m_inDetach) { 
2250         if (oldFocusedNode->active())
2251             oldFocusedNode->setActive(false);
2252
2253         oldFocusedNode->setFocus(false);
2254                 
2255         // Dispatch a change event for text fields or textareas that have been edited
2256         RenderObject *r = static_cast<RenderObject*>(oldFocusedNode.get()->renderer());
2257         if (r && (r->isTextArea() || r->isTextField()) && r->isEdited()) {
2258             EventTargetNodeCast(oldFocusedNode.get())->dispatchHTMLEvent(changeEvent, true, false);
2259             if ((r = static_cast<RenderObject*>(oldFocusedNode.get()->renderer())))
2260                 r->setEdited(false);
2261         }
2262
2263         // Dispatch the blur event and let the node do any other blur related activities (important for text fields)
2264         EventTargetNodeCast(oldFocusedNode.get())->dispatchBlurEvent();
2265
2266         if (m_focusedNode) {
2267             // handler shifted focus
2268             focusChangeBlocked = true;
2269             newFocusedNode = 0;
2270         }
2271         EventTargetNodeCast(oldFocusedNode.get())->dispatchUIEvent(DOMFocusOutEvent);
2272         if (m_focusedNode) {
2273             // handler shifted focus
2274             focusChangeBlocked = true;
2275             newFocusedNode = 0;
2276         }
2277         if ((oldFocusedNode.get() == this) && oldFocusedNode->hasOneRef())
2278             return true;
2279             
2280         if (oldFocusedNode.get() == oldFocusedNode->rootEditableElement())
2281             frame()->editor()->didEndEditing();
2282     }
2283
2284     if (newFocusedNode) {
2285         if (newFocusedNode == newFocusedNode->rootEditableElement() && !acceptsEditingFocus(newFocusedNode.get())) {
2286             // delegate blocks focus change
2287             focusChangeBlocked = true;
2288             goto SetFocusedNodeDone;
2289         }
2290         // Set focus on the new node
2291         m_focusedNode = newFocusedNode.get();
2292
2293         // Dispatch the focus event and let the node do any other focus related activities (important for text fields)
2294         EventTargetNodeCast(m_focusedNode.get())->dispatchFocusEvent();
2295
2296         if (m_focusedNode != newFocusedNode) {
2297             // handler shifted focus
2298             focusChangeBlocked = true;
2299             goto SetFocusedNodeDone;
2300         }
2301         EventTargetNodeCast(m_focusedNode.get())->dispatchUIEvent(DOMFocusInEvent);
2302         if (m_focusedNode != newFocusedNode) { 
2303             // handler shifted focus
2304             focusChangeBlocked = true;
2305             goto SetFocusedNodeDone;
2306         }
2307         m_focusedNode->setFocus();
2308
2309         if (m_focusedNode.get() == m_focusedNode->rootEditableElement())
2310             frame()->editor()->didBeginEditing();
2311
2312         // eww, I suck. set the qt focus correctly
2313         // ### find a better place in the code for this
2314         if (view()) {
2315             Widget *focusWidget = widgetForNode(m_focusedNode.get());
2316             if (focusWidget) {
2317                 // Make sure a widget has the right size before giving it focus.
2318                 // Otherwise, we are testing edge cases of the Widget code.
2319                 // Specifically, in WebCore this does not work well for text fields.
2320                 updateLayout();
2321                 // Re-get the widget in case updating the layout changed things.
2322                 focusWidget = widgetForNode(m_focusedNode.get());
2323             }
2324             if (focusWidget)
2325                 focusWidget->setFocus();
2326             else
2327                 view()->setFocus();
2328         }
2329    }
2330
2331 #if PLATFORM(MAC)
2332     if (!focusChangeBlocked && m_focusedNode && AXObjectCache::accessibilityEnabled())
2333         axObjectCache()->handleFocusedUIElementChanged();
2334 #endif
2335
2336 SetFocusedNodeDone:
2337     updateRendering();
2338     return !focusChangeBlocked;
2339   }
2340   
2341 void Document::setCSSTarget(Node* n)
2342 {
2343     if (m_cssTarget)
2344         m_cssTarget->setChanged();
2345     m_cssTarget = n;
2346     if (n)
2347         n->setChanged();
2348 }
2349
2350 Node* Document::getCSSTarget() const
2351 {
2352     return m_cssTarget;
2353 }
2354
2355 void Document::attachNodeIterator(NodeIterator *ni)
2356 {
2357     m_nodeIterators.add(ni);
2358 }
2359
2360 void Document::detachNodeIterator(NodeIterator *ni)
2361 {
2362     m_nodeIterators.remove(ni);
2363 }
2364
2365 void Document::notifyBeforeNodeRemoval(Node *n)
2366 {
2367     if (Frame* f = frame()) {
2368         f->selectionController()->nodeWillBeRemoved(n);
2369         f->dragCaretController()->nodeWillBeRemoved(n);
2370     }
2371
2372     HashSet<NodeIterator*>::const_iterator end = m_nodeIterators.end();
2373     for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != end; ++it)
2374         (*it)->notifyBeforeNodeRemoval(n);
2375 }
2376
2377 DOMWindow* Document::defaultView() const
2378 {
2379     if (!frame())
2380         return 0;
2381     
2382     return frame()->domWindow();
2383 }
2384
2385 PassRefPtr<Event> Document::createEvent(const String &eventType, ExceptionCode& ec)
2386 {
2387     if (eventType == "UIEvents" || eventType == "UIEvent")
2388         return new UIEvent;
2389     if (eventType == "MouseEvents" || eventType == "MouseEvent")
2390         return new MouseEvent;
2391     if (eventType == "MutationEvents" || eventType == "MutationEvent")
2392         return new MutationEvent;
2393     if (eventType == "KeyboardEvents" || eventType == "KeyboardEvent")
2394         return new KeyboardEvent;
2395     if (eventType == "HTMLEvents" || eventType == "Event" || eventType == "Events")
2396         return new Event;
2397     if (eventType == "ProgressEvent")
2398         return new ProgressEvent;
2399     if (eventType == "TextEvent")
2400         return new TextEvent;
2401     if (eventType == "OverflowEvent")
2402         return new OverflowEvent;
2403     if (eventType == "WheelEvent")
2404         return new WheelEvent;
2405 #if ENABLE(SVG)
2406     if (eventType == "SVGEvents")
2407         return new Event;
2408     if (eventType == "SVGZoomEvents")
2409         return new SVGZoomEvent;
2410 #endif
2411     ec = NOT_SUPPORTED_ERR;
2412     return 0;
2413 }
2414
2415 CSSStyleDeclaration *Document::getOverrideStyle(Element */*elt*/, const String &/*pseudoElt*/)
2416 {
2417     return 0; // ###
2418 }
2419
2420 void Document::handleWindowEvent(Event *evt, bool useCapture)
2421 {
2422     if (m_windowEventListeners.isEmpty())
2423         return;
2424         
2425     // if any html event listeners are registered on the window, then dispatch them here
2426     RegisteredEventListenerList listenersCopy = m_windowEventListeners;
2427     RegisteredEventListenerList::iterator it = listenersCopy.begin();
2428     
2429     for (; it != listenersCopy.end(); ++it)
2430         if ((*it)->eventType() == evt->type() && (*it)->useCapture() == useCapture && !(*it)->removed()) 
2431             (*it)->listener()->handleEvent(evt, true);
2432 }
2433
2434
2435 void Document::defaultEventHandler(Event *evt)
2436 {
2437     // handle accesskey
2438     if (evt->type() == keydownEvent) {
2439         KeyboardEvent* kevt = static_cast<KeyboardEvent *>(evt);
2440 #if PLATFORM(MAC)
2441         if (kevt->ctrlKey())
2442 #else
2443         if (kevt->altKey())
2444 #endif
2445         {
2446             const PlatformKeyboardEvent* ev = kevt->keyEvent();
2447             String key = (ev ? ev->unmodifiedText() : kevt->keyIdentifier()).lower();
2448             Element* elem = getElementByAccessKey(key);
2449             if (elem) {
2450                 elem->accessKeyAction(false);
2451                 evt->setDefaultHandled();
2452                 return;
2453             }
2454         }
2455     }
2456
2457     ContainerNode::defaultEventHandler(evt);
2458 }
2459
2460 void Document::setHTMLWindowEventListener(const AtomicString &eventType, PassRefPtr<EventListener> listener)
2461 {
2462     // If we already have it we don't want removeWindowEventListener to delete it
2463     removeHTMLWindowEventListener(eventType);
2464     if (listener)
2465         addWindowEventListener(eventType, listener, false);
2466 }
2467
2468 EventListener *Document::getHTMLWindowEventListener(const AtomicString &eventType)
2469 {
2470     RegisteredEventListenerList::iterator it = m_windowEventListeners.begin();
2471        for (; it != m_windowEventListeners.end(); ++it)
2472         if ( (*it)->eventType() == eventType && (*it)->listener()->isHTMLEventListener())
2473             return (*it)->listener();
2474     return 0;
2475 }
2476
2477 void Document::removeHTMLWindowEventListener(const AtomicString &eventType)
2478 {
2479     RegisteredEventListenerList::iterator it = m_windowEventListeners.begin();
2480     for (; it != m_windowEventListeners.end(); ++it)
2481         if ( (*it)->eventType() == eventType && (*it)->listener()->isHTMLEventListener()) {
2482             m_windowEventListeners.remove(it);
2483             return;
2484         }
2485 }
2486
2487 void Document::addWindowEventListener(const AtomicString &eventType, PassRefPtr<EventListener> listener, bool useCapture)
2488 {
2489     // Remove existing identical listener set with identical arguments.
2490     // The DOM 2 spec says that "duplicate instances are discarded" in this case.
2491     removeWindowEventListener(eventType, listener.get(), useCapture);
2492     m_windowEventListeners.append(new RegisteredEventListener(eventType, listener, useCapture));
2493 }
2494
2495 void Document::removeWindowEventListener(const AtomicString &eventType, EventListener *listener, bool useCapture)
2496 {
2497     RegisteredEventListener rl(eventType, listener, useCapture);
2498     RegisteredEventListenerList::iterator it = m_windowEventListeners.begin();
2499     for (; it != m_windowEventListeners.end(); ++it)
2500         if (*(*it) == rl) {
2501             m_windowEventListeners.remove(it);
2502             return;
2503         }
2504 }
2505
2506 bool Document::hasWindowEventListener(const AtomicString &eventType)
2507 {
2508     RegisteredEventListenerList::iterator it = m_windowEventListeners.begin();
2509     for (; it != m_windowEventListeners.end(); ++it)
2510         if ((*it)->eventType() == eventType) {
2511             return true;
2512         }
2513     return false;
2514 }
2515
2516 PassRefPtr<EventListener> Document::createHTMLEventListener(const String& functionName, const String& code, Node *node)
2517 {
2518     if (Frame* frm = frame())
2519         if (KJSProxy* proxy = frm->scriptProxy())
2520             return proxy->createHTMLEventHandler(functionName, code, node);
2521     return 0;
2522 }
2523
2524 void Document::setHTMLWindowEventListener(const AtomicString& eventType, Attribute* attr)
2525 {
2526     setHTMLWindowEventListener(eventType,
2527         createHTMLEventListener(attr->localName().domString(), attr->value(), 0));
2528 }
2529
2530 void Document::dispatchImageLoadEventSoon(HTMLImageLoader *image)
2531 {
2532     m_imageLoadEventDispatchSoonList.append(image);
2533     if (!m_imageLoadEventTimer.isActive())
2534         m_imageLoadEventTimer.startOneShot(0);
2535 }
2536
2537 void Document::removeImage(HTMLImageLoader* image)
2538 {
2539     // Remove instances of this image from both lists.
2540     // Use loops because we allow multiple instances to get into the lists.
2541     while (m_imageLoadEventDispatchSoonList.removeRef(image)) { }
2542     while (m_imageLoadEventDispatchingList.removeRef(image)) { }
2543     if (m_imageLoadEventDispatchSoonList.isEmpty())
2544         m_imageLoadEventTimer.stop();
2545 }
2546
2547 void Document::dispatchImageLoadEventsNow()
2548 {
2549     // need to avoid re-entering this function; if new dispatches are
2550     // scheduled before the parent finishes processing the list, they
2551     // will set a timer and eventually be processed
2552     if (!m_imageLoadEventDispatchingList.isEmpty()) {
2553         return;
2554     }
2555
2556     m_imageLoadEventTimer.stop();
2557     
2558     m_imageLoadEventDispatchingList = m_imageLoadEventDispatchSoonList;
2559     m_imageLoadEventDispatchSoonList.clear();
2560     for (DeprecatedPtrListIterator<HTMLImageLoader> it(m_imageLoadEventDispatchingList); it.current();) {
2561         HTMLImageLoader* image = it.current();
2562         // Must advance iterator *before* dispatching call.
2563         // Otherwise, it might be advanced automatically if dispatching the call had a side effect
2564         // of destroying the current HTMLImageLoader, and then we would advance past the *next* item,
2565         // missing one altogether.
2566         ++it;
2567         image->dispatchLoadEvent();
2568     }
2569     m_imageLoadEventDispatchingList.clear();
2570 }
2571
2572 void Document::imageLoadEventTimerFired(Timer<Document>*)
2573 {
2574     dispatchImageLoadEventsNow();
2575 }
2576
2577 Element* Document::ownerElement() const
2578 {
2579     if (!frame())
2580         return 0;
2581     return frame()->ownerElement();
2582 }
2583
2584 String Document::cookie() const
2585 {
2586     return cookies(URL());
2587 }
2588
2589 void Document::setCookie(const String& value)
2590 {
2591     setCookies(URL(), policyBaseURL().deprecatedString(), value);
2592 }
2593
2594 String Document::referrer() const
2595 {
2596     if (frame())
2597         return frame()->loader()->referrer();
2598     return String();
2599 }
2600
2601 String Document::domain() const
2602 {
2603     if (m_domain.isEmpty()) // not set yet (we set it on demand to save time and space)
2604         m_domain = KURL(URL()).host(); // Initially set to the host
2605     return m_domain;
2606 }
2607
2608 void Document::setDomain(const String& newDomain)
2609 {
2610     // Not set yet (we set it on demand to save time and space)
2611     // Initially set to the host
2612     if (m_domain.isEmpty())
2613         m_domain = KURL(URL()).host();
2614
2615     // Both NS and IE specify that changing the domain is only allowed when
2616     // the new domain is a suffix of the old domain.
2617
2618     // FIXME: We should add logging indicating why a domain was not allowed. 
2619
2620     int oldLength = m_domain.length();
2621     int newLength = newDomain.length();
2622     // e.g. newDomain=kde.org (7) and m_domain=www.kde.org (11)
2623     if (newLength < oldLength) {
2624         String test = m_domain.copy();
2625         // Check that it's a subdomain, not e.g. "de.org"
2626         if (test[oldLength - newLength - 1] == '.') {
2627             // Now test is "kde.org" from m_domain
2628             // and we check that it's the same thing as newDomain
2629             test.remove(0, oldLength - newLength);
2630             if (test == newDomain)
2631                 m_domain = newDomain;
2632         }
2633     }
2634
2635     m_securityOrigin.setDomainFromDOM(newDomain);
2636 }
2637
2638 void Document::setDomainInternal(const String& newDomain)
2639 {
2640     m_domain = newDomain;
2641 }
2642
2643 String Document::lastModified() const
2644 {
2645     Frame* f = frame();
2646     if (!f)
2647         return String();
2648     DocumentLoader* loader = f->loader()->documentLoader();
2649     if (!loader)
2650         return String();
2651     return loader->response().httpHeaderField("Last-Modified");
2652 }
2653
2654 bool Document::isValidName(const String &name)
2655 {
2656     const UChar* s = reinterpret_cast<const UChar*>(name.characters());
2657     unsigned length = name.length();
2658
2659     if (length == 0)
2660         return false;
2661
2662     unsigned i = 0;
2663
2664     UChar32 c;
2665     U16_NEXT(s, i, length, c)
2666     if (!isValidNameStart(c))
2667         return false;
2668
2669     while (i < length) {
2670         U16_NEXT(s, i, length, c)
2671         if (!isValidNamePart(c))
2672             return false;
2673     }
2674
2675     return true;
2676 }
2677
2678 bool Document::parseQualifiedName(const String &qualifiedName, String &prefix, String &localName)
2679 {
2680     unsigned length = qualifiedName.length();
2681
2682     if (length == 0)
2683         return false;
2684
2685     bool nameStart = true;
2686     bool sawColon = false;
2687     int colonPos = 0;
2688
2689     const UChar* s = reinterpret_cast<const UChar*>(qualifiedName.characters());
2690     for (unsigned i = 0; i < length;) {
2691         UChar32 c;
2692         U16_NEXT(s, i, length, c)
2693         if (c == ':') {
2694             if (sawColon)
2695                 return false; // multiple colons: not allowed
2696             nameStart = true;
2697             sawColon = true;
2698             colonPos = i - 1;
2699         } else if (nameStart) {
2700             if (!isValidNameStart(c))
2701                 return false;
2702             nameStart = false;
2703         } else {
2704             if (!isValidNamePart(c))
2705                 return false;
2706         }
2707     }
2708
2709     if (!sawColon) {
2710         prefix = String();
2711         localName = qualifiedName.copy();
2712     } else {
2713         prefix = qualifiedName.substring(0, colonPos);
2714         localName = qualifiedName.substring(colonPos + 1, length - (colonPos + 1));
2715     }
2716
2717     return true;
2718 }
2719
2720 void Document::addImageMap(HTMLMapElement* imageMap)
2721 {
2722     const AtomicString& name = imageMap->getName();
2723     if (!name.impl())
2724         return;
2725
2726     // Add the image map, unless there's already another with that name.
2727     // "First map wins" is the rule other browsers seem to implement.
2728     m_imageMapsByName.add(name.impl(), imageMap);
2729 }
2730
2731 void Document::removeImageMap(HTMLMapElement* imageMap)
2732 {
2733     // Remove the image map by name.
2734     // But don't remove some other image map that just happens to have the same name.
2735     // FIXME: Use a HashCountedSet as we do for IDs to find the first remaining map
2736     // once a map has been removed.
2737     const AtomicString& name = imageMap->getName();
2738     if (!name.impl())
2739         return;
2740
2741     ImageMapsByName::iterator it = m_imageMapsByName.find(name.impl());
2742     if (it != m_imageMapsByName.end() && it->second == imageMap)
2743         m_imageMapsByName.remove(it);
2744 }
2745
2746 HTMLMapElement *Document::getImageMap(const String& URL) const
2747 {
2748     if (URL.isNull())
2749         return 0;
2750     int hashPos = URL.find('#');
2751     String name = (hashPos < 0 ? URL : URL.substring(hashPos + 1)).impl();
2752     AtomicString mapName = hMode == XHtml ? name : name.lower();
2753     return m_imageMapsByName.get(mapName.impl());
2754 }
2755
2756 void Document::setDecoder(TextResourceDecoder *decoder)
2757 {
2758     m_decoder = decoder;
2759 }
2760
2761 UChar Document::backslashAsCurrencySymbol() const
2762 {
2763     if (!m_decoder)
2764         return '\\';
2765     return m_decoder->encoding().backslashAsCurrencySymbol();
2766 }
2767
2768 DeprecatedString Document::completeURL(const DeprecatedString& URL)
2769 {
2770     // FIXME: This treats null URLs the same as empty URLs, unlike the String function below.
2771
2772     // If both the URL and base URL are empty, like they are for documents
2773     // created using DOMImplementation::createDocument, just return the passed in URL.
2774     // (We do this because URL() returns "about:blank" for empty URLs.
2775     if (m_url.isEmpty() && m_baseURL.isEmpty())
2776         return URL;
2777     if (!m_decoder)
2778         return KURL(baseURL(), URL).url();
2779     return KURL(baseURL(), URL, m_decoder->encoding()).url();
2780 }
2781
2782 String Document::completeURL(const String &URL)
2783 {
2784     // FIXME: This always returns null when passed a null URL, unlike the String function above.
2785     if (URL.isNull())
2786         return URL;
2787     return completeURL(URL.deprecatedString());
2788 }
2789
2790 bool Document::inPageCache()
2791 {
2792     return m_inPageCache;
2793 }
2794
2795 void Document::setInPageCache(bool flag)
2796 {
2797     if (m_inPageCache == flag)
2798         return;
2799
2800     m_inPageCache = flag;
2801     if (flag) {
2802         ASSERT(m_savedRenderer == 0);
2803         m_savedRenderer = renderer();
2804         if (FrameView* v = view())
2805             v->resetScrollbars();
2806     } else {
2807         ASSERT(renderer() == 0 || renderer() == m_savedRenderer);
2808         ASSERT(m_renderArena);
2809         setRenderer(m_savedRenderer);
2810         m_savedRenderer = 0;
2811     }
2812 }
2813
2814 void Document::willSaveToCache() 
2815 {
2816     HashSet<Element*>::iterator end = m_pageCacheCallbackElements.end();
2817     for (HashSet<Element*>::iterator i = m_pageCacheCallbackElements.begin(); i != end; ++i)
2818         (*i)->willSaveToCache();
2819 }
2820
2821 void Document::didRestoreFromCache() 
2822 {
2823     HashSet<Element*>::iterator end = m_pageCacheCallbackElements.end();
2824     for (HashSet<Element*>::iterator i = m_pageCacheCallbackElements.begin(); i != end; ++i)
2825         (*i)->didRestoreFromCache();
2826 }
2827
2828 void Document::registerForCacheCallbacks(Element* e)
2829 {
2830     m_pageCacheCallbackElements.add(e);
2831 }
2832
2833 void Document::unregisterForCacheCallbacks(Element* e)
2834 {
2835     m_pageCacheCallbackElements.remove(e);
2836 }
2837
2838 void Document::setShouldCreateRenderers(bool f)
2839 {
2840     m_createRenderers = f;
2841 }
2842
2843 bool Document::shouldCreateRenderers()
2844 {
2845     return m_createRenderers;
2846 }
2847
2848 String Document::toString() const
2849 {
2850     String result;
2851
2852     for (Node *child = firstChild(); child != NULL; child = child->nextSibling()) {
2853         result += child->toString();
2854     }
2855
2856     return result;
2857 }
2858
2859 // Support for Javascript execCommand, and related methods
2860
2861 JSEditor *Document::jsEditor()
2862 {
2863     if (!m_jsEditor)
2864         m_jsEditor = new JSEditor(this);
2865     return m_jsEditor;
2866 }
2867
2868 bool Document::execCommand(const String &command, bool userInterface, const String &value)
2869 {
2870     return jsEditor()->execCommand(command, userInterface, value);
2871 }
2872
2873 bool Document::queryCommandEnabled(const String &command)
2874 {
2875     return jsEditor()->queryCommandEnabled(command);
2876 }
2877
2878 bool Document::queryCommandIndeterm(const String &command)
2879 {
2880     return jsEditor()->queryCommandIndeterm(command);
2881 }
2882
2883 bool Document::queryCommandState(const String &command)
2884 {
2885     return jsEditor()->queryCommandState(command);
2886 }
2887
2888 bool Document::queryCommandSupported(const String &command)
2889 {
2890     return jsEditor()->queryCommandSupported(command);
2891 }
2892
2893 String Document::queryCommandValue(const String &command)
2894 {
2895     return jsEditor()->queryCommandValue(command);
2896 }
2897
2898 static IntRect placeholderRectForMarker(void)
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 String& name)
3492 {
3493     HashMap<AtomicStringImpl*, HTMLCollection::CollectionInfo*>& map = m_nameCollectionInfo[type - HTMLCollection::UnnamedCollectionTypes];
3494     
3495     AtomicString atomicName(name);
3496     
3497     HashMap<AtomicStringImpl*, HTMLCollection::CollectionInfo*>::iterator iter = map.find(atomicName.impl());
3498     if (iter == map.end())
3499         iter = map.add(atomicName.impl(), new HTMLCollection::CollectionInfo).first;
3500     
3501     return iter->second;
3502 }
3503
3504 PassRefPtr<NameNodeList> Document::getElementsByName(const String &elementName)
3505 {
3506     return new NameNodeList(this, elementName);
3507 }
3508
3509 void Document::finishedParsing()
3510 {
3511     setParsing(false);
3512
3513     ExceptionCode ec = 0;
3514     dispatchEvent(new Event(DOMContentLoadedEvent, true, false), ec);
3515
3516     if (Frame* f = frame())
3517         f->loader()->finishedParsing();
3518 }
3519
3520 Vector<String> Document::formElementsState() const
3521 {
3522     Vector<String> stateVector;
3523     stateVector.reserveCapacity(m_formElementsWithState.size() * 3);
3524     typedef ListHashSet<HTMLFormControlElementWithState*>::const_iterator Iterator;
3525     Iterator end = m_formElementsWithState.end();
3526     for (Iterator it = m_formElementsWithState.begin(); it != end; ++it) {
3527         HTMLFormControlElementWithState* e = *it;
3528         String value;
3529         if (e->saveState(value)) {
3530             stateVector.append(e->name().domString());
3531             stateVector.append(e->type().domString());
3532             stateVector.append(value);
3533         }
3534     }
3535     return stateVector;
3536 }
3537
3538 #if ENABLE(XPATH)
3539
3540 PassRefPtr<XPathExpression> Document::createExpression(const String& expression,
3541                                                        XPathNSResolver* resolver,
3542                                                        ExceptionCode& ec)
3543 {
3544     if (!m_xpathEvaluator)
3545         m_xpathEvaluator = new XPathEvaluator;
3546     return m_xpathEvaluator->createExpression(expression, resolver, ec);
3547 }
3548
3549 PassRefPtr<XPathNSResolver> Document::createNSResolver(Node* nodeResolver)
3550 {
3551     if (!m_xpathEvaluator)
3552         m_xpathEvaluator = new XPathEvaluator;
3553     return m_xpathEvaluator->createNSResolver(nodeResolver);
3554 }
3555
3556 PassRefPtr<XPathResult> Document::evaluate(const String& expression,
3557                                            Node* contextNode,
3558                                            XPathNSResolver* resolver,
3559                                            unsigned short type,
3560                                            XPathResult* result,
3561                                            ExceptionCode& ec)
3562 {
3563     if (!m_xpathEvaluator)
3564         m_xpathEvaluator = new XPathEvaluator;
3565     return m_xpathEvaluator->evaluate(expression, contextNode, resolver, type, result, ec);
3566 }
3567
3568 #endif // ENABLE(XPATH)
3569
3570 void Document::setStateForNewFormElements(const Vector<String>& stateVector)
3571 {
3572     // Walk the state vector backwards so that the value to use for each
3573     // name/type pair first is the one at the end of each individual vector
3574     // in the FormElementStateMap. We're using them like stacks.
3575     typedef FormElementStateMap::iterator Iterator;
3576     m_formElementsWithState.clear();
3577     for (size_t i = stateVector.size() / 3 * 3; i; i -= 3) {
3578         AtomicString a = stateVector[i - 3];
3579         AtomicString b = stateVector[i - 2];
3580         const String& c = stateVector[i - 1];
3581         FormElementKey key(a.impl(), b.impl());
3582         Iterator it = m_stateForNewFormElements.find(key);
3583         if (it != m_stateForNewFormElements.end())
3584             it->second.append(c);
3585         else {
3586             Vector<String> v(1);
3587             v[0] = c;
3588             m_stateForNewFormElements.set(key, v);
3589         }
3590     }
3591 }
3592
3593 bool Document::hasStateForNewFormElements() const
3594 {
3595     return !m_stateForNewFormElements.isEmpty();
3596 }
3597
3598 bool Document::takeStateForFormElement(AtomicStringImpl* name, AtomicStringImpl* type, String& state)
3599 {
3600     typedef FormElementStateMap::iterator Iterator;
3601     Iterator it = m_stateForNewFormElements.find(FormElementKey(name, type));
3602     if (it == m_stateForNewFormElements.end())
3603         return false;
3604     ASSERT(it->second.size());
3605     state = it->second.last();
3606     if (it->second.size() > 1)
3607         it->second.removeLast();
3608     else
3609         m_stateForNewFormElements.remove(it);
3610     return true;
3611 }
3612
3613 FormElementKey::FormElementKey(AtomicStringImpl* name, AtomicStringImpl* type)
3614     : m_name(name), m_type(type)
3615 {
3616     ref();
3617 }
3618
3619 FormElementKey::~FormElementKey()
3620 {
3621     deref();
3622 }
3623
3624 FormElementKey::FormElementKey(const FormElementKey& other)
3625     : m_name(other.name()), m_type(other.type())
3626 {
3627     ref();
3628 }
3629
3630 FormElementKey& FormElementKey::operator=(const FormElementKey& other)
3631 {
3632     other.ref();
3633     deref();
3634     m_name = other.name();
3635     m_type = other.type();
3636     return *this;
3637 }
3638
3639 void FormElementKey::ref() const
3640 {
3641     if (name() && name() != HashTraits<AtomicStringImpl*>::deletedValue())
3642         name()->ref();
3643     if (type())
3644         type()->ref();
3645 }
3646
3647 void FormElementKey::deref() const
3648 {
3649     if (name() && name() != HashTraits<AtomicStringImpl*>::deletedValue())
3650         name()->deref();
3651     if (type())
3652         type()->deref();
3653 }
3654
3655 unsigned FormElementKeyHash::hash(const FormElementKey& k)
3656 {
3657     ASSERT(sizeof(k) % (sizeof(uint16_t) * 2) == 0);
3658
3659     unsigned l = sizeof(k) / (sizeof(uint16_t) * 2);
3660     const uint16_t* s = reinterpret_cast<const uint16_t*>(&k);
3661     uint32_t hash = PHI;
3662
3663     // Main loop
3664     for (; l > 0; l--) {
3665         hash += s[0];
3666         uint32_t tmp = (s[1] << 11) ^ hash;
3667         hash = (hash << 16) ^ tmp;
3668         s += 2;
3669         hash += hash >> 11;
3670     }
3671         
3672     // Force "avalanching" of final 127 bits
3673     hash ^= hash << 3;
3674     hash += hash >> 5;
3675     hash ^= hash << 2;
3676     hash += hash >> 15;
3677     hash ^= hash << 10;
3678
3679     // this avoids ever returning a hash code of 0, since that is used to
3680     // signal "hash not computed yet", using a value that is likely to be
3681     // effectively the same as 0 when the low bits are masked
3682     if (hash == 0)
3683         hash = 0x80000000;
3684
3685     return hash;
3686 }
3687
3688 FormElementKey FormElementKeyHashTraits::deletedValue()
3689 {
3690     return HashTraits<AtomicStringImpl*>::deletedValue();
3691 }
3692
3693
3694 String Document::iconURL()
3695 {
3696     return m_iconURL;
3697 }
3698
3699 void Document::setIconURL(const String& iconURL, const String& type)
3700 {
3701     // FIXME - <rdar://problem/4727645> - At some point in the future, we might actually honor the "type" 
3702     if (m_iconURL.isEmpty())
3703         m_iconURL = iconURL;
3704     else if (!type.isEmpty())
3705         m_iconURL = iconURL;
3706 }
3707
3708 void Document::setUseSecureKeyboardEntryWhenActive(bool usesSecureKeyboard)
3709 {
3710     if (m_useSecureKeyboardEntryWhenActive == usesSecureKeyboard)
3711         return;
3712         
3713     m_useSecureKeyboardEntryWhenActive = usesSecureKeyboard;
3714     m_frame->updateSecureKeyboardEntryIfActive();
3715 }
3716
3717 bool Document::useSecureKeyboardEntryWhenActive() const
3718 {
3719     return m_useSecureKeyboardEntryWhenActive;
3720 }
3721
3722 void Document::initSecurityOrigin()
3723 {
3724     if (!m_frame)
3725         return;
3726     m_securityOrigin.setForFrame(m_frame);
3727 }
3728
3729 void Document::updateFocusAppearanceSoon()
3730 {
3731     if (!m_updateFocusAppearanceTimer.isActive())
3732         m_updateFocusAppearanceTimer.startOneShot(0);
3733 }
3734
3735 void Document::cancelFocusAppearanceUpdate()
3736 {
3737     m_updateFocusAppearanceTimer.stop();
3738 }
3739
3740 void Document::updateFocusAppearanceTimerFired(Timer<Document>*)
3741 {
3742     Node* node = focusedNode();
3743     if (!node)
3744         return;
3745     if (!node->isElementNode())
3746         return;
3747
3748     updateLayout();
3749
3750     Element* element = static_cast<Element*>(node);
3751     if (element->isFocusable())
3752         element->updateFocusAppearance(false);
3753 }
3754
3755 #if ENABLE(DATABASE)
3756 DatabaseThread* Document::databaseThread()
3757 {
3758     if (!m_databaseThread) {
3759         m_databaseThread = new DatabaseThread(this);
3760         if (!m_databaseThread->start())
3761             m_databaseThread = 0;
3762     }
3763
3764     return m_databaseThread.get();
3765 }
3766 #endif
3767
3768 } // namespace WebCore