LayoutTests:
[WebKit-https.git] / WebCore / dom / Document.cpp
index a7ac13d..ae3ff06 100644 (file)
@@ -56,6 +56,7 @@
 #include "HTMLDocument.h"
 #include "HTMLElementFactory.h"
 #include "HTMLFrameOwnerElement.h"
+#include "HTMLHeadElement.h"
 #include "HTMLImageLoader.h"
 #include "HTMLInputElement.h"
 #include "HTMLLinkElement.h"
@@ -63,6 +64,7 @@
 #include "HTMLNameCollection.h"
 #include "HTMLNames.h"
 #include "HTMLStyleElement.h"
+#include "HTMLTitleElement.h"
 #include "HTTPParsers.h"
 #include "JSEditor.h"
 #include "KeyboardEvent.h"
@@ -85,6 +87,7 @@
 #include "StringHash.h"
 #include "StyleSheetList.h"
 #include "SystemTime.h"
+#include "TextEvent.h"
 #include "TextIterator.h"
 #include "TextResourceDecoder.h"
 #include "TreeWalker.h"
 #include "kjs_proxy.h"
 #include "xmlhttprequest.h"
 
-#ifdef XPATH_SUPPORT
+#if ENABLE(XPATH)
 #include "XPathEvaluator.h"
 #include "XPathExpression.h"
 #include "XPathNSResolver.h"
 #include "XPathResult.h"
 #endif
 
-#ifdef XSLT_SUPPORT
+#if ENABLE(XSLT)
 #include "XSLTProcessor.h"
 #endif
 
-#ifdef XBL_SUPPORT
+#if ENABLE(XBL)
 #include "XBLBindingManager.h"
 #endif
 
-#ifdef SVG_SUPPORT
+#if ENABLE(SVG)
 #include "SVGDocumentExtensions.h"
 #include "SVGElementFactory.h"
 #include "SVGZoomEvent.h"
 #endif
 
 using namespace std;
+using namespace WTF;
+using namespace Unicode;
 
 namespace WebCore {
 
@@ -131,10 +136,10 @@ using namespace HTMLNames;
 // This amount of time must have elapsed before we will even consider scheduling a layout without a delay.
 // FIXME: For faster machines this value can really be lowered to 200.  250 is adequate, but a little high
 // for dual G5s. :)
-const int cLayoutScheduleThreshold = 250;
+static const int cLayoutScheduleThreshold = 250;
 
 // Use 1 to represent the document's default form.
-HTMLFormElement* const defaultForm = (HTMLFormElement*) 1;
+static HTMLFormElement* const defaultForm = reinterpret_cast<HTMLFormElement*>(1);
 
 // Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
 static const unsigned PHI = 0x9e3779b9U;
@@ -165,12 +170,8 @@ static inline bool isValidNameStart(UChar32 c)
         return true;
 
     // rules (a) and (f) above
-    const uint32_t nameStartMask = WTF::Unicode::Letter_Lowercase |
-                                   WTF::Unicode::Letter_Uppercase |
-                                   WTF::Unicode::Letter_Other |
-                                   WTF::Unicode::Letter_Titlecase |
-                                   WTF::Unicode::Number_Letter;
-    if (!(WTF::Unicode::category(c) & nameStartMask))
+    const uint32_t nameStartMask = Letter_Lowercase | Letter_Uppercase | Letter_Other | Letter_Titlecase | Number_Letter;
+    if (!(Unicode::category(c) & nameStartMask))
         return false;
 
     // rule (c) above
@@ -178,8 +179,8 @@ static inline bool isValidNameStart(UChar32 c)
         return false;
 
     // rule (d) above
-    WTF::Unicode::DecompositionType decompType = WTF::Unicode::decompositionType(c);
-    if (decompType == WTF::Unicode::DecompositionFont || decompType == WTF::Unicode::DecompositionCompat)
+    DecompositionType decompType = decompositionType(c);
+    if (decompType == DecompositionFont || decompType == DecompositionCompat)
         return false;
 
     return true;
@@ -200,12 +201,8 @@ static inline bool isValidNamePart(UChar32 c)
         return true;
 
     // rules (b) and (f) above
-    const uint32_t otherNamePartMask = WTF::Unicode::Mark_NonSpacing |
-                                       WTF::Unicode::Mark_Enclosing |
-                                       WTF::Unicode::Mark_SpacingCombining |
-                                       WTF::Unicode::Letter_Modifier |
-                                       WTF::Unicode::Number_DecimalDigit;
-    if (!(WTF::Unicode::category(c) & otherNamePartMask))
+    const uint32_t otherNamePartMask = Mark_NonSpacing | Mark_Enclosing | Mark_SpacingCombining | Letter_Modifier | Number_DecimalDigit;
+    if (!(Unicode::category(c) & otherNamePartMask))
         return false;
 
     // rule (c) above
@@ -213,8 +210,8 @@ static inline bool isValidNamePart(UChar32 c)
         return false;
 
     // rule (d) above
-    WTF::Unicode::DecompositionType decompType = WTF::Unicode::decompositionType(c);
-    if (decompType == WTF::Unicode::DecompositionFont || decompType == WTF::Unicode::DecompositionCompat)
+    DecompositionType decompType = decompositionType(c);
+    if (decompType == DecompositionFont || decompType == DecompositionCompat)
         return false;
 
     return true;
@@ -279,12 +276,12 @@ Document::Document(DOMImplementation* impl, FrameView *v)
     , m_title("")
     , m_titleSetExplicitly(false)
     , m_imageLoadEventTimer(this, &Document::imageLoadEventTimerFired)
-#ifdef XSLT_SUPPORT
+#if ENABLE(XSLT)
     , m_transformSource(0)
 #endif
     , m_xmlVersion("1.0")
     , m_xmlStandalone(false)
-#ifdef XBL_SUPPORT
+#if ENABLE(XBL)
     , m_bindingManager(new XBLBindingManager(this))
 #endif
     , m_savedRenderer(0)
@@ -292,7 +289,7 @@ Document::Document(DOMImplementation* impl, FrameView *v)
     , m_secureForms(0)
     , m_designMode(inherit)
     , m_selfOnlyRefCount(0)
-#ifdef SVG_SUPPORT
+#if ENABLE(SVG)
     , m_svgExtensions(0)
 #endif
 #if PLATFORM(MAC)
@@ -302,6 +299,7 @@ Document::Document(DOMImplementation* impl, FrameView *v)
     , m_accessKeyMapValid(false)
     , m_createRenderers(true)
     , m_inPageCache(false)
+    , m_isAllowedToLoadLocalResources(false)
 {
     m_document.resetSkippingRef(this);
 
@@ -389,12 +387,15 @@ Document::~Document()
 
     removeAllEventListeners();
 
-#ifdef SVG_SUPPORT
+#if ENABLE(SVG)
     delete m_svgExtensions;
 #endif
 
     XMLHttpRequest::detachRequests(this);
-    KJS::ScriptInterpreter::forgetAllDOMNodesForDocument(this);
+    {
+        KJS::JSLock lock;
+        KJS::ScriptInterpreter::forgetAllDOMNodesForDocument(this);
+    }
 
     if (m_docChanged && changedDocuments)
         changedDocuments->remove(this);
@@ -408,11 +409,11 @@ Document::~Document()
         m_renderArena = 0;
     }
 
-#ifdef XSLT_SUPPORT
+#if ENABLE(XSLT)
     xmlFreeDoc((xmlDocPtr)m_transformSource);
 #endif
 
-#ifdef XBL_SUPPORT
+#if ENABLE(XBL)
     delete m_bindingManager;
 #endif
 
@@ -646,9 +647,33 @@ PassRefPtr<Node> Document::adoptNode(PassRefPtr<Node> source, ExceptionCode& ec)
     return source;
 }
 
+// FIXME: This should really be in a possible ElementFactory class
+PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool createdByParser, ExceptionCode& ec)
+{
+    RefPtr<Element> e;
+
+    // FIXME: Use registered namespaces and look up in a hash to find the right factory.
+    if (qName.namespaceURI() == xhtmlNamespaceURI)
+        e = HTMLElementFactory::createHTMLElement(qName.localName(), this, 0, createdByParser);
+#if ENABLE(SVG)
+    else if (qName.namespaceURI() == SVGNames::svgNamespaceURI)
+        e = SVGElementFactory::createSVGElement(qName, this, createdByParser);
+#endif
+    
+    if (!e)
+        e = new Element(qName, document());
+    
+    if (e && !qName.prefix().isNull()) {
+        e->setPrefix(qName.prefix(), ec);
+        if (ec)
+            return 0;
+    }    
+    
+    return e.release();
+}
+
 PassRefPtr<Element> Document::createElementNS(const String &_namespaceURI, const String &qualifiedName, ExceptionCode& ec)
 {
-    // FIXME: We'd like a faster code path that skips this check for calls from inside the engine where the name is known to be valid.
     String prefix, localName;
     if (!parseQualifiedName(qualifiedName, prefix, localName)) {
         ec = INVALID_CHARACTER_ERR;
@@ -658,24 +683,7 @@ PassRefPtr<Element> Document::createElementNS(const String &_namespaceURI, const
     RefPtr<Element> e;
     QualifiedName qName = QualifiedName(AtomicString(prefix), AtomicString(localName), AtomicString(_namespaceURI));
     
-    // FIXME: Use registered namespaces and look up in a hash to find the right factory.
-    if (_namespaceURI == xhtmlNamespaceURI) {
-        e = HTMLElementFactory::createHTMLElement(qName.localName(), this, 0, false);
-        if (e && !prefix.isNull()) {
-            e->setPrefix(qName.prefix(), ec);
-            if (ec)
-                return 0;
-        }
-    }
-#ifdef SVG_SUPPORT
-    else if (_namespaceURI == SVGNames::svgNamespaceURI)
-        e = SVGElementFactory::createSVGElement(qName, this, false);
-#endif
-    
-    if (!e)
-        e = new Element(qName, document());
-    
-    return e.release();
+    return createElement(qName, false, ec);
 }
 
 Element *Document::getElementById(const AtomicString& elementId) const
@@ -758,6 +766,21 @@ void Document::setXMLStandalone(bool standalone, ExceptionCode& ec)
     m_xmlStandalone = standalone;
 }
 
+String Document::documentURI() const
+{
+    return m_baseURL;
+}
+
+void Document::setDocumentURI(const String &uri)
+{
+    m_baseURL = uri.deprecatedString();
+}
+
+String Document::baseURI() const
+{
+    return documentURI();
+}
+
 Element* Document::elementFromPoint(int x, int y) const
 {
     if (!renderer())
@@ -815,14 +838,24 @@ void Document::updateTitle()
         f->loader()->setTitle(m_title);
 }
 
-void Document::setTitle(const String& title, Node* titleElement)
+void Document::setTitle(const String& title, Element* titleElement)
 {
     if (!titleElement) {
         // Title set by JavaScript -- overrides any title elements.
         m_titleSetExplicitly = true;
-        m_titleElement = 0;
+        if (!isHTMLDocument())
+            m_titleElement = 0;
+        else if (!m_titleElement) {
+            if (HTMLElement* headElement = head()) {
+                ExceptionCode ec = 0;
+                m_titleElement = createElement("title", ec);
+                ASSERT(!ec);
+                headElement->appendChild(m_titleElement, ec);
+                ASSERT(!ec);
+            }
+        }
     } else if (titleElement != m_titleElement) {
-        if (m_titleElement)
+        if (m_titleElement || m_titleSetExplicitly)
             // Only allow the first title element to change the title -- others have no effect.
             return;
         m_titleElement = titleElement;
@@ -833,17 +866,30 @@ void Document::setTitle(const String& title, Node* titleElement)
 
     m_title = title;
     updateTitle();
+
+    if (m_titleSetExplicitly && m_titleElement && m_titleElement->hasTagName(titleTag))
+        static_cast<HTMLTitleElement*>(m_titleElement.get())->setText(m_title);
 }
 
-void Document::removeTitle(Node* titleElement)
+void Document::removeTitle(Element* titleElement)
 {
     if (m_titleElement != titleElement)
         return;
 
-    // FIXME: Ideally we might want this to search for the first remaining title element, and use it.
     m_titleElement = 0;
+    m_titleSetExplicitly = false;
+
+    // Update title based on first title element in the head, if one exists.
+    if (HTMLElement* headElement = head()) {
+        for (Node* e = headElement->firstChild(); e; e = e->nextSibling())
+            if (e->hasTagName(titleTag)) {
+                HTMLTitleElement* titleElement = static_cast<HTMLTitleElement*>(e);
+                setTitle(titleElement->text(), titleElement);
+                break;
+            }
+    }
 
-    if (!m_title.isEmpty()) {
+    if (!m_titleElement && !m_title.isEmpty()) {
         m_title = "";
         updateTitle();
     }
@@ -1211,9 +1257,9 @@ void Document::updateSelection()
 #endif
 }
 
-Tokenizer *Document::createTokenizer()
+TokenizerDocument::createTokenizer()
 {
-    return newXMLTokenizer(this, m_view);
+    return new XMLTokenizer(this, m_view);
 }
 
 void Document::open()
@@ -1224,9 +1270,6 @@ void Document::open()
         setURL(parent->baseURL());
         setBaseURL(parent->baseURL());
     }
-    else
-        setURL(DeprecatedString());
-        
 
     if ((frame() && frame()->loader()->isLoadingMainResource()) || (tokenizer() && tokenizer()->executingScript()))
         return;
@@ -1261,7 +1304,7 @@ void Document::implicitOpen()
 
 HTMLElement* Document::body()
 {
-    Node *de = documentElement();
+    Nodede = documentElement();
     if (!de)
         return 0;
     
@@ -1274,7 +1317,20 @@ HTMLElement* Document::body()
         if (i->hasTagName(bodyTag))
             body = i;
     }
-    return static_cast<HTMLElement *>(body);
+    return static_cast<HTMLElement*>(body);
+}
+
+HTMLHeadElement* Document::head()
+{
+    Node* de = documentElement();
+    if (!de)
+        return 0;
+
+    for (Node* e = de->firstChild(); e; e = e->nextSibling())
+        if (e->hasTagName(headTag))
+            return static_cast<HTMLHeadElement*>(e);
+
+    return 0;
 }
 
 void Document::close()
@@ -1333,19 +1389,22 @@ void Document::implicitClose()
 
     m_processingLoadEvent = false;
 
+    // An event handler may have removed the frame
+    if (!frame())
+        return;
+
     // Make sure both the initial layout and reflow happen after the onload
     // fires. This will improve onload scores, and other browsers do it.
     // If they wanna cheat, we can too. -dwh
 
-    if (frame() && frame()->loader()->isScheduledLocationChangePending() && elapsedTime() < cLayoutScheduleThreshold) {
+    if (frame()->loader()->isScheduledLocationChangePending() && elapsedTime() < cLayoutScheduleThreshold) {
         // Just bail out. Before or during the onload we were shifted to another page.
         // The old i-Bench suite does this. When this happens don't bother painting or laying out.        
         view()->unscheduleRelayout();
         return;
     }
 
-    if (frame())
-        frame()->loader()->checkEmitLoadEvent();
+    frame()->loader()->checkEmitLoadEvent();
 
     // Now do our painting/layout, but only if we aren't in a subframe or if we're in a subframe
     // that has been sized already.  Otherwise, our view size would be incorrect, so doing any 
@@ -1363,7 +1422,7 @@ void Document::implicitClose()
         axObjectCache()->postNotificationToElement(renderer(), "AXLoadComplete");
 #endif
 
-#ifdef SVG_SUPPORT
+#if ENABLE(SVG)
     // FIXME: Officially, time 0 is when the outermost <svg> receives its
     // SVGLoad event, but we don't implement those yet.  This is close enough
     // for now.  In some cases we should have fired earlier.
@@ -1473,9 +1532,37 @@ void Document::clear()
 
 void Document::setURL(const DeprecatedString& url)
 {
+    if (url == m_url)
+        return;
+
     m_url = url;
     if (m_styleSelector)
         m_styleSelector->setEncodedURL(m_url);
+
+    m_isAllowedToLoadLocalResources = shouldBeAllowedToLoadLocalResources();
+ }
+bool Document::shouldBeAllowedToLoadLocalResources() const
+{
+    if (FrameLoader::shouldTreatURLAsLocal(m_url))
+        return true;
+
+    Frame* frame = this->frame();
+    if (!frame)
+        return false;
+    
+    DocumentLoader* documentLoader = frame->loader()->documentLoader();
+    if (!documentLoader)
+        return false;
+    
+    return documentLoader->substituteData().isValid();
+}
+
+void Document::setBaseURL(const DeprecatedString& baseURL) 
+{ 
+    m_baseURL = baseURL; 
+    if (m_elemSheet)
+        m_elemSheet->setHref(m_baseURL);
 }
 
 void Document::setCSSStyleSheet(const String &url, const String& charset, const String &sheet)
@@ -1646,7 +1733,7 @@ void Document::processHttpEquiv(const String &equiv, const String &content)
     } else if (equalIgnoringCase(equiv, "refresh")) {
         double delay;
         String url;
-        if (frame && parseHTTPRefresh(content, delay, url)) {
+        if (frame && parseHTTPRefresh(content, true, delay, url)) {
             if (url.isEmpty())
                 frame->loader()->scheduleRedirection(delay, frame->loader()->url().url(), delay <= 1);
             else
@@ -1669,7 +1756,7 @@ MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& r
     ASSERT(!renderer() || renderer()->isRenderView());
 
     if (!renderer())
-        return MouseEventWithHitTestResults(event, 0, 0, false);
+        return MouseEventWithHitTestResults(event, 0, IntPoint(), 0, false);
 
     HitTestResult result(documentPoint);
     renderer()->layer()->hitTest(request, result);
@@ -1677,8 +1764,8 @@ MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& r
     if (!request.readonly)
         updateRendering();
 
-    bool isOverLink = result.URLElement() && !result.URLElement()->getAttribute(hrefAttr).isNull();
-    return MouseEventWithHitTestResults(event, result.innerNode(), result.scrollbar(), isOverLink);
+    bool isOverLink = result.URLElement() && result.URLElement()->isLink();
+    return MouseEventWithHitTestResults(event, result.innerNode(), result.localPoint(), result.scrollbar(), isOverLink);
 }
 
 // DOM Section 1.1.1
@@ -1710,6 +1797,87 @@ bool Document::childTypeAllowed(NodeType type)
     return false;
 }
 
+bool Document::canReplaceChild(Node* newChild, Node* oldChild)
+{
+    if (oldChild->nodeType() == newChild->nodeType())
+        return true;
+
+    int numDoctypes = 0;
+    int numElements = 0;
+
+    // First, check how many doctypes and elements we have, not counting
+    // the child we're about to remove.
+    for (Node* c = firstChild(); c; c = c->nextSibling()) {
+        if (c == oldChild)
+            continue;
+        
+        switch (c->nodeType()) {
+            case DOCUMENT_TYPE_NODE:
+                numDoctypes++;
+                break;
+            case ELEMENT_NODE:
+                numElements++;
+                break;
+            default:
+                break;
+        }
+    }
+    
+    // Then, see how many doctypes and elements might be added by the new child.
+    if (newChild->nodeType() == DOCUMENT_FRAGMENT_NODE) {
+        for (Node* c = firstChild(); c; c = c->nextSibling()) {
+            switch (c->nodeType()) {
+                case ATTRIBUTE_NODE:
+                case CDATA_SECTION_NODE:
+                case DOCUMENT_FRAGMENT_NODE:
+                case DOCUMENT_NODE:
+                case ENTITY_NODE:
+                case ENTITY_REFERENCE_NODE:
+                case NOTATION_NODE:
+                case TEXT_NODE:
+                case XPATH_NAMESPACE_NODE:
+                    return false;
+                case COMMENT_NODE:
+                case PROCESSING_INSTRUCTION_NODE:
+                    break;
+                case DOCUMENT_TYPE_NODE:
+                    numDoctypes++;
+                    break;
+                case ELEMENT_NODE:
+                    numElements++;
+                    break;
+            }
+        }
+    } else {
+        switch (newChild->nodeType()) {
+            case ATTRIBUTE_NODE:
+            case CDATA_SECTION_NODE:
+            case DOCUMENT_FRAGMENT_NODE:
+            case DOCUMENT_NODE:
+            case ENTITY_NODE:
+            case ENTITY_REFERENCE_NODE:
+            case NOTATION_NODE:
+            case TEXT_NODE:
+            case XPATH_NAMESPACE_NODE:
+                return false;
+            case COMMENT_NODE:
+            case PROCESSING_INSTRUCTION_NODE:
+                return true;
+            case DOCUMENT_TYPE_NODE:
+                numDoctypes++;
+                break;
+            case ELEMENT_NODE:
+                numElements++;
+                break;
+        }                
+    }
+        
+    if (numElements > 1 || numDoctypes > 1)
+        return false;
+    
+    return true;
+}
+
 PassRefPtr<Node> Document::cloneNode(bool /*deep*/)
 {
     // Spec says cloning Document nodes is "implementation dependent"
@@ -1753,7 +1921,7 @@ void Document::stylesheetLoaded()
         printf("Stylesheet loaded at time %d. %d stylesheets still remain.\n", elapsedTime(), m_pendingStylesheets);
 #endif
 
-    updateStyleSelector();    
+    updateStyleSelector();
 }
 
 void Document::updateStyleSelector()
@@ -1804,7 +1972,7 @@ void Document::recalcStyleSelector()
             // Processing instruction (XML documents only)
             ProcessingInstruction* pi = static_cast<ProcessingInstruction*>(n);
             sheet = pi->sheet();
-#ifdef XSLT_SUPPORT
+#if ENABLE(XSLT)
             // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
             if (pi->isXSL() && !transformSourceDocument()) {
                 // Don't apply XSL transforms until loading is finished.
@@ -1836,7 +2004,7 @@ void Document::recalcStyleSelector()
             }
 
         } else if (n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag))
-#ifdef SVG_SUPPORT
+#if ENABLE(SVG)
             ||  (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
 #endif
         ) {
@@ -1855,7 +2023,7 @@ void Document::recalcStyleSelector()
 
             // Get the current preferred styleset.  This is the
             // set of sheets that will be enabled.
-#ifdef SVG_SUPPORT
+#if ENABLE(SVG)
             if (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
                 sheet = static_cast<SVGStyleElement*>(n)->sheet();
             else
@@ -1884,7 +2052,7 @@ void Document::recalcStyleSelector()
                 if (title != m_preferredStylesheetSet)
                     sheet = 0;
 
-#ifdef SVG_SUPPORT
+#if ENABLE(SVG)
                 if (!n->isHTMLElement())
                     title = title.replace('&', "&&");
 #endif
@@ -1926,7 +2094,7 @@ void Document::setActiveNode(PassRefPtr<Node> newActiveNode)
     m_activeNode = newActiveNode;
 }
 
-void Document::focusedNodeDetached(Node* node)
+void Document::focusedNodeRemoved(Node* node)
 {
     setFocusedNode(0);
 }
@@ -1954,6 +2122,7 @@ void Document::activeChainNodeDetached(Node* node)
 }
 
 #if PLATFORM(MAC)
+
 const Vector<DashboardRegionValue>& Document::dashboardRegions() const
 {
     return m_dashboardRegions;
@@ -1964,6 +2133,7 @@ void Document::setDashboardRegions(const Vector<DashboardRegionValue>& regions)
     m_dashboardRegions = regions;
     setDashboardRegionsDirty(false);
 }
+
 #endif
 
 bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
@@ -2045,10 +2215,7 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
             goto SetFocusedNodeDone;
         }
         m_focusedNode->setFocus();
-        
-        if (m_focusedNode.get() == m_focusedNode->rootEditableElement())
-            frame()->editor()->didBeginEditing();
-        
+
         // eww, I suck. set the qt focus correctly
         // ### find a better place in the code for this
         if (view()) {
@@ -2125,20 +2292,22 @@ DOMWindow* Document::defaultView() const
 PassRefPtr<Event> Document::createEvent(const String &eventType, ExceptionCode& ec)
 {
     if (eventType == "UIEvents" || eventType == "UIEvent")
-        return new UIEvent();
+        return new UIEvent;
     if (eventType == "MouseEvents" || eventType == "MouseEvent")
-        return new MouseEvent();
+        return new MouseEvent;
     if (eventType == "MutationEvents" || eventType == "MutationEvent")
-        return new MutationEvent();
+        return new MutationEvent;
     if (eventType == "KeyboardEvents" || eventType == "KeyboardEvent")
-        return new KeyboardEvent();
+        return new KeyboardEvent;
     if (eventType == "HTMLEvents" || eventType == "Event" || eventType == "Events")
-        return new Event();
-#ifdef SVG_SUPPORT
+        return new Event;
+    if (eventType == "TextEvent")
+        return new TextEvent;
+#if ENABLE(SVG)
     if (eventType == "SVGEvents")
-        return new Event();
+        return new Event;
     if (eventType == "SVGZoomEvents")
-        return new SVGZoomEvent();
+        return new SVGZoomEvent;
 #endif
     ec = NOT_SUPPORTED_ERR;
     return 0;
@@ -2437,8 +2606,9 @@ HTMLMapElement *Document::getImageMap(const String& URL) const
     if (URL.isNull())
         return 0;
     int hashPos = URL.find('#');
-    AtomicString name = (hashPos < 0 ? URL : URL.substring(hashPos + 1)).impl();
-    return m_imageMapsByName.get(name.impl());
+    String name = (hashPos < 0 ? URL : URL.substring(hashPos + 1)).impl();
+    AtomicString mapName = hMode == XHtml ? name : name.lower();
+    return m_imageMapsByName.get(mapName.impl());
 }
 
 void Document::setDecoder(TextResourceDecoder *decoder)
@@ -2639,9 +2809,9 @@ void Document::addMarker(Node *node, DocumentMarker newMarker)
         Vector<DocumentMarker>& markers = vectorPair->first;
         Vector<IntRect>& rects = vectorPair->second;
         ASSERT(markers.size() == rects.size());
-        Vector<DocumentMarker>::iterator it;
-        for (it = markers.begin(); it != markers.end();) {
-            DocumentMarker marker = *it;
+        size_t i;
+        for (i = 0; i != markers.size();) {
+            DocumentMarker marker = markers[i];
             
             if (newMarker.endOffset < marker.startOffset+1) {
                 // This is the first marker that is completely after newMarker, and disjoint from it.
@@ -2649,7 +2819,7 @@ void Document::addMarker(Node *node, DocumentMarker newMarker)
                 break;
             } else if (newMarker.startOffset > marker.endOffset) {
                 // maker is before newMarker, and disjoint from it.  Keep scanning.
-                it++;
+                i++;
             } else if (newMarker == marker) {
                 // already have this one, NOP
                 return;
@@ -2658,16 +2828,14 @@ void Document::addMarker(Node *node, DocumentMarker newMarker)
                 newMarker.startOffset = min(newMarker.startOffset, marker.startOffset);
                 newMarker.endOffset = max(newMarker.endOffset, marker.endOffset);
                 // remove old one, we'll add newMarker later
-                unsigned removalIndex = it - markers.begin();
-                markers.remove(removalIndex);
-                rects.remove(removalIndex);
+                markers.remove(i);
+                rects.remove(i);
                 // it points to the next marker to consider
             }
         }
-        // at this point it points to the node before which we want to insert
-        unsigned insertionIndex = it - markers.begin();
-        markers.insert(insertionIndex, newMarker);
-        rects.insert(insertionIndex, placeholderRectForMarker());
+        // at this point i points to the node before which we want to insert
+        markers.insert(i, newMarker);
+        rects.insert(i, placeholderRectForMarker());
     }
     
     // repaint the affected node
@@ -2690,10 +2858,9 @@ void Document::copyMarkers(Node *srcNode, unsigned startOffset, int length, Node
 
     bool docDirty = false;
     unsigned endOffset = startOffset + length - 1;
-    Vector<DocumentMarker>::iterator it;
     Vector<DocumentMarker>& markers = vectorPair->first;
-    for (it = markers.begin(); it != markers.end(); ++it) {
-        DocumentMarker marker = *it;
+    for (size_t i = 0; i != markers.size(); ++i) {
+        DocumentMarker marker = markers[i];
 
         // stop if we are now past the specified range
         if (marker.startOffset > endOffset)
@@ -2734,9 +2901,8 @@ void Document::removeMarkers(Node *node, unsigned startOffset, int length, Docum
     ASSERT(markers.size() == rects.size());
     bool docDirty = false;
     unsigned endOffset = startOffset + length - 1;
-    Vector<DocumentMarker>::iterator it;
-    for (it = markers.begin(); it < markers.end();) {
-        DocumentMarker marker = *it;
+    for (size_t i = 0; i < markers.size();) {
+        DocumentMarker marker = markers[i];
 
         // markers are returned in order, so stop if we are now past the specified range
         if (marker.startOffset > endOffset)
@@ -2744,7 +2910,7 @@ void Document::removeMarkers(Node *node, unsigned startOffset, int length, Docum
         
         // skip marker that is wrong type or before target
         if (marker.endOffset < startOffset || (marker.type != markerType && markerType != DocumentMarker::AllMarkers)) {
-            it++;
+            i++;
             continue;
         }
 
@@ -2752,29 +2918,25 @@ void Document::removeMarkers(Node *node, unsigned startOffset, int length, Docum
         docDirty = true;
 
         // pitch the old marker and any associated rect
-        unsigned removalIndex = it - markers.begin();
-        markers.remove(removalIndex);
-        rects.remove(removalIndex);
-        // it now points to the next node
+        markers.remove(i);
+        rects.remove(i);
         
         // add either of the resulting slices that are left after removing target
         if (startOffset > marker.startOffset) {
             DocumentMarker newLeft = marker;
             newLeft.endOffset = startOffset;
-            unsigned insertionIndex = it - markers.begin();
-            markers.insert(insertionIndex, newLeft);
-            rects.insert(insertionIndex, placeholderRectForMarker());
-            // it now points to the newly-inserted node, but we want to skip that one
-            it++;
+            markers.insert(i, newLeft);
+            rects.insert(i, placeholderRectForMarker());
+            // i now points to the newly-inserted node, but we want to skip that one
+            i++;
         }
         if (marker.endOffset > endOffset) {
             DocumentMarker newRight = marker;
             newRight.startOffset = endOffset;
-            unsigned insertionIndex = it - markers.begin();
-            markers.insert(insertionIndex, newRight);
-            rects.insert(insertionIndex, placeholderRectForMarker());
-            // it now points to the newly-inserted node, but we want to skip that one
-            it++;
+            markers.insert(i, newRight);
+            rects.insert(i, placeholderRectForMarker());
+            // i now points to the newly-inserted node, but we want to skip that one
+            i++;
         }
     }
 
@@ -2887,19 +3049,18 @@ void Document::removeMarkers(DocumentMarker::MarkerType markerType)
         Vector<DocumentMarker>& markers = vectorPair->first;
         Vector<IntRect>& rects = vectorPair->second;
         ASSERT(markers.size() == rects.size());
-        Vector<DocumentMarker>::iterator markerIterator;
-        for (markerIterator = markers.begin(); markerIterator != markers.end();) {
-            DocumentMarker marker = *markerIterator;
+        for (size_t i = 0; i != markers.size();) {
+            DocumentMarker marker = markers[i];
 
             // skip nodes that are not of the specified type
             if (marker.type != markerType && markerType != DocumentMarker::AllMarkers) {
-                ++markerIterator;
+                ++i;
                 continue;
             }
 
             // pitch the old marker
-            markers.remove(markerIterator - markers.begin());
-            rects.remove(markerIterator - markers.begin());
+            markers.remove(i);
+            rects.remove(i);
             nodeNeedsRepaint = true;
             // markerIterator now points to the next node
         }
@@ -2931,10 +3092,9 @@ void Document::repaintMarkers(DocumentMarker::MarkerType markerType)
         // inner loop: process each marker in the current node
         MarkerMapVectorPair* vectorPair = i->second;
         Vector<DocumentMarker>& markers = vectorPair->first;
-        Vector<DocumentMarker>::iterator markerIterator;
         bool nodeNeedsRepaint = false;
-        for (markerIterator = markers.begin(); markerIterator != markers.end(); ++markerIterator) {
-            DocumentMarker marker = *markerIterator;
+        for (size_t i = 0; i != markers.size(); ++i) {
+            DocumentMarker marker = markers[i];
             
             // skip nodes that are not of the specified type
             if (marker.type == markerType || markerType == DocumentMarker::AllMarkers) {
@@ -3002,9 +3162,8 @@ void Document::shiftMarkers(Node *node, unsigned startOffset, int delta, Documen
     ASSERT(markers.size() == rects.size());
     
     bool docDirty = false;
-    Vector<DocumentMarker>::iterator it;
-    for (it = markers.begin(); it != markers.end(); ++it) {
-        DocumentMarker &marker = *it;
+    for (size_t i = 0; i != markers.size(); ++i) {
+        DocumentMarker &marker = markers[i];
         if (marker.startOffset >= startOffset && (markerType == DocumentMarker::AllMarkers || marker.type == markerType)) {
             assert((int)marker.startOffset + delta >= 0);
             marker.startOffset += delta;
@@ -3012,7 +3171,7 @@ void Document::shiftMarkers(Node *node, unsigned startOffset, int delta, Documen
             docDirty = true;
             
             // Marker moved, so previously-computed rendered rectangle is now invalid
-            rects[it - markers.begin()] = placeholderRectForMarker();
+            rects[i] = placeholderRectForMarker();
         }
     }
     
@@ -3021,7 +3180,7 @@ void Document::shiftMarkers(Node *node, unsigned startOffset, int delta, Documen
         node->renderer()->repaint();
 }
 
-#ifdef XSLT_SUPPORT
+#if ENABLE(XSLT)
 
 void Document::applyXSLTransform(ProcessingInstruction* pi)
 {
@@ -3106,7 +3265,7 @@ PassRefPtr<Attr> Document::createAttributeNS(const String &namespaceURI, const S
     return new Attr(0, this, new MappedAttribute(QualifiedName(prefix, localName, namespaceURI), StringImpl::empty()));
 }
 
-#ifdef SVG_SUPPORT
+#if ENABLE(SVG)
 const SVGDocumentExtensions* Document::svgExtensions()
 {
     return m_svgExtensions;
@@ -3250,7 +3409,7 @@ Vector<String> Document::formElementsState() const
 {
     Vector<String> stateVector;
     stateVector.reserveCapacity(m_formElementsWithState.size() * 3);
-    typedef HashSet<HTMLGenericFormElement*>::const_iterator Iterator;
+    typedef ListHashSet<HTMLGenericFormElement*>::const_iterator Iterator;
     Iterator end = m_formElementsWithState.end();
     for (Iterator it = m_formElementsWithState.begin(); it != end; ++it) {
         HTMLGenericFormElement* e = *it;
@@ -3261,7 +3420,7 @@ Vector<String> Document::formElementsState() const
     return stateVector;
 }
 
-#ifdef XPATH_SUPPORT
+#if ENABLE(XPATH)
 
 PassRefPtr<XPathExpression> Document::createExpression(const String& expression,
                                                        XPathNSResolver* resolver,
@@ -3291,7 +3450,7 @@ PassRefPtr<XPathResult> Document::evaluate(const String& expression,
     return m_xpathEvaluator->evaluate(expression, contextNode, resolver, type, result, ec);
 }
 
-#endif // XPATH_SUPPORT
+#endif // ENABLE(XPATH)
 
 void Document::setStateForNewFormElements(const Vector<String>& stateVector)
 {