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