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