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