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