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