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