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