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