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