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