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