From 54cdeeebc7adcbcd900e8b6a141a8cae27d9a631 Mon Sep 17 00:00:00 2001 From: Steve Block Date: Fri, 10 Jun 2011 16:52:27 +0100 Subject: Merge WebKit at branches/chromium/742 r88085: Initial merge by git. Change-Id: I0501b484b9528e31b0026e5ad64416dd6541cdde --- Source/WebCore/html/HTMLFormControlElement.cpp | 52 ++++++++++++++++++++------ Source/WebCore/html/HTMLInputElement.cpp | 4 ++ Source/WebCore/html/HTMLMediaElement.cpp | 15 ++++---- Source/WebCore/html/HTMLObjectElement.cpp | 4 +- Source/WebCore/html/HTMLScriptElement.cpp | 26 +++++++++++++ Source/WebCore/html/parser/XSSFilter.cpp | 28 ++++++++------ Source/WebCore/html/shadow/MediaControls.h | 11 ++++++ 7 files changed, 107 insertions(+), 33 deletions(-) (limited to 'Source/WebCore/html') diff --git a/Source/WebCore/html/HTMLFormControlElement.cpp b/Source/WebCore/html/HTMLFormControlElement.cpp index 87f4e4d..3d8812e 100644 --- a/Source/WebCore/html/HTMLFormControlElement.cpp +++ b/Source/WebCore/html/HTMLFormControlElement.cpp @@ -120,10 +120,45 @@ void HTMLFormControlElement::parseMappedAttribute(Attribute* attr) setNeedsWillValidateCheck(); } +static bool shouldAutofocus(HTMLFormControlElement* element) +{ + if (!element->autofocus()) + return false; + if (!element->renderer()) + return false; + if (element->document()->ignoreAutofocus()) + return false; + if (element->isReadOnlyFormControl()) + return false; + + // FIXME: Should this set of hasTagName checks be replaced by a + // virtual member function? + if (element->hasTagName(inputTag)) + return !static_cast(element)->isInputTypeHidden(); + if (element->hasTagName(selectTag)) + return true; + if (element->hasTagName(keygenTag)) + return true; + if (element->hasTagName(buttonTag)) + return true; + if (element->hasTagName(textareaTag)) + return true; + + return false; +} + +static void focusPostAttach(Node* element) +{ + static_cast(element)->focus(); + element->deref(); +} + void HTMLFormControlElement::attach() { ASSERT(!attached()); + suspendPostAttachCallbacks(); + HTMLElement::attach(); // The call to updateFromElement() needs to go after the call through @@ -132,17 +167,12 @@ void HTMLFormControlElement::attach() if (renderer()) renderer()->updateFromElement(); - // Focus the element if it should honour its autofocus attribute. - // We have to determine if the element is a TextArea/Input/Button/Select, - // if input type hidden ignore autofocus. So if disabled or readonly. - bool isInputTypeHidden = false; - if (hasTagName(inputTag)) - isInputTypeHidden = static_cast(this)->isInputTypeHidden(); - - if (autofocus() && renderer() && !document()->ignoreAutofocus() && !isReadOnlyFormControl() && - ((hasTagName(inputTag) && !isInputTypeHidden) || hasTagName(selectTag) || - hasTagName(keygenTag) || hasTagName(buttonTag) || hasTagName(textareaTag))) - focus(); + if (shouldAutofocus(this)) { + ref(); + queuePostAttachCallback(focusPostAttach, this); + } + + resumePostAttachCallbacks(); } void HTMLFormControlElement::willMoveToNewOwnerDocument() diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp index d5d0aee..2b262e4 100644 --- a/Source/WebCore/html/HTMLInputElement.cpp +++ b/Source/WebCore/html/HTMLInputElement.cpp @@ -699,6 +699,8 @@ RenderObject* HTMLInputElement::createRenderer(RenderArena* arena, RenderStyle* void HTMLInputElement::attach() { + suspendPostAttachCallbacks(); + if (!m_hasType) updateType(); @@ -708,6 +710,8 @@ void HTMLInputElement::attach() if (document()->focusedNode() == this) document()->updateFocusAppearanceSoon(true /* restore selection */); + + resumePostAttachCallbacks(); } void HTMLInputElement::detach() diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp index eb409af..a9f025f 100644 --- a/Source/WebCore/html/HTMLMediaElement.cpp +++ b/Source/WebCore/html/HTMLMediaElement.cpp @@ -1626,7 +1626,7 @@ void HTMLMediaElement::playbackProgressTimerFired(Timer*) scheduleTimeupdateEvent(true); if (hasMediaControls()) { - if (!m_mouseOver && controls()) + if (!m_mouseOver && controls() && hasVideo()) mediaControls()->makeTransparent(); mediaControls()->playbackProgressed(); } @@ -2671,17 +2671,16 @@ void HTMLMediaElement::privateBrowsingStateDidChange() MediaControls* HTMLMediaElement::mediaControls() { - if (!shadowRoot()) - return 0; - - Node* node = shadowRoot()->firstChild(); - ASSERT(node->isHTMLElement()); - return static_cast(node); + return toMediaControls(shadowRoot()->firstChild()); } bool HTMLMediaElement::hasMediaControls() { - return shadowRoot(); + if (!shadowRoot()) + return false; + + Node* node = shadowRoot()->firstChild(); + return node && node->isMediaControls(); } void HTMLMediaElement::ensureMediaControls() diff --git a/Source/WebCore/html/HTMLObjectElement.cpp b/Source/WebCore/html/HTMLObjectElement.cpp index f5f0083..42064f8 100644 --- a/Source/WebCore/html/HTMLObjectElement.cpp +++ b/Source/WebCore/html/HTMLObjectElement.cpp @@ -378,8 +378,8 @@ void HTMLObjectElement::renderFallbackContent() if (m_imageLoader && m_imageLoader->image() && m_imageLoader->image()->status() != CachedResource::LoadError) { m_serviceType = m_imageLoader->image()->response().mimeType(); if (!isImageType()) { - // If we don't think we have an image type anymore, then ditch the image loader. - m_imageLoader.clear(); + // If we don't think we have an image type anymore, then clear the image from the loader. + m_imageLoader->setImage(0); detach(); attach(); return; diff --git a/Source/WebCore/html/HTMLScriptElement.cpp b/Source/WebCore/html/HTMLScriptElement.cpp index b56b375..f49038b 100644 --- a/Source/WebCore/html/HTMLScriptElement.cpp +++ b/Source/WebCore/html/HTMLScriptElement.cpp @@ -29,6 +29,7 @@ #include "EventNames.h" #include "HTMLNames.h" #include "ScriptEventListener.h" +#include "Settings.h" #include "Text.h" namespace WebCore { @@ -81,8 +82,33 @@ void HTMLScriptElement::parseMappedAttribute(Attribute* attr) HTMLElement::parseMappedAttribute(attr); } +static bool needsOldRequirejsQuirk(HTMLScriptElement* element) +{ + if (element->fastGetAttribute(typeAttr) != "script/cache") + return false; + + Document* document = element->document(); + + const KURL& url = document->url(); + if (!equalIgnoringCase(url.host(), "www.zipcar.com")) + return false; + + Settings* settings = document->settings(); + if (!settings) + return false; + if (!settings->needsSiteSpecificQuirks()) + return false; + + return true; +} + void HTMLScriptElement::insertedIntoDocument() { + if (needsOldRequirejsQuirk(this)) { + if (!asyncAttributeValue()) + handleAsyncAttribute(); // Clear forceAsync, so this script loads in parallel, but executes in order. + setAttribute(typeAttr, "text/javascript"); + } HTMLElement::insertedIntoDocument(); ScriptElement::insertedIntoDocument(); } diff --git a/Source/WebCore/html/parser/XSSFilter.cpp b/Source/WebCore/html/parser/XSSFilter.cpp index ddc3318..27bff31 100644 --- a/Source/WebCore/html/parser/XSSFilter.cpp +++ b/Source/WebCore/html/parser/XSSFilter.cpp @@ -43,9 +43,7 @@ namespace WebCore { using namespace HTMLNames; -namespace { - -bool isNonCanonicalCharacter(UChar c) +static bool isNonCanonicalCharacter(UChar c) { // We remove all non-ASCII characters, including non-printable ASCII characters. // @@ -57,22 +55,22 @@ bool isNonCanonicalCharacter(UChar c) return (c == '\\' || c == '0' || c == '\0' || c >= 127); } -String canonicalize(const String& string) +static String canonicalize(const String& string) { return string.removeCharacters(&isNonCanonicalCharacter); } -bool isRequiredForInjection(UChar c) +static bool isRequiredForInjection(UChar c) { return (c == '\'' || c == '"' || c == '<' || c == '>'); } -bool hasName(const HTMLToken& token, const QualifiedName& name) +static bool hasName(const HTMLToken& token, const QualifiedName& name) { return equalIgnoringNullity(token.name(), static_cast(name.localName())); } -bool findAttributeWithName(const HTMLToken& token, const QualifiedName& name, size_t& indexOfMatchingAttribute) +static bool findAttributeWithName(const HTMLToken& token, const QualifiedName& name, size_t& indexOfMatchingAttribute) { for (size_t i = 0; i < token.attributes().size(); ++i) { if (equalIgnoringNullity(token.attributes().at(i).m_name, name.localName())) { @@ -83,7 +81,7 @@ bool findAttributeWithName(const HTMLToken& token, const QualifiedName& name, si return false; } -bool isNameOfInlineEventHandler(const Vector& name) +static bool isNameOfInlineEventHandler(const Vector& name) { const size_t lengthOfShortestInlineEventHandlerName = 5; // To wit: oncut. if (name.size() < lengthOfShortestInlineEventHandlerName) @@ -91,7 +89,13 @@ bool isNameOfInlineEventHandler(const Vector& name) return name[0] == 'o' && name[1] == 'n'; } -bool containsJavaScriptURL(const Vector& value) +static bool isDangerousHTTPEquiv(const String& value) +{ + String equiv = value.stripWhiteSpace(); + return equalIgnoringCase(equiv, "refresh") || equalIgnoringCase(equiv, "set-cookie"); +} + +static bool containsJavaScriptURL(const Vector& value) { static const char javaScriptScheme[] = "javascript:"; static const size_t lengthOfJavaScriptScheme = sizeof(javaScriptScheme) - 1; @@ -108,7 +112,7 @@ bool containsJavaScriptURL(const Vector& value) return equalIgnoringCase(value.data() + i, javaScriptScheme, lengthOfJavaScriptScheme); } -String decodeURL(const String& string, const TextEncoding& encoding) +static String decodeURL(const String& string, const TextEncoding& encoding) { String workingString = string; workingString.replace('+', ' '); @@ -121,8 +125,6 @@ String decodeURL(const String& string, const TextEncoding& encoding) return canonicalize(decodedString); } -} - XSSFilter::XSSFilter(HTMLDocumentParser* parser) : m_parser(parser) , m_isEnabled(false) @@ -420,6 +422,8 @@ bool XSSFilter::eraseAttributeIfInjected(HTMLToken& token, const QualifiedName& if (isContainedInRequest(snippetForAttribute(token, attribute))) { if (attributeName == srcAttr && isSameOriginResource(String(attribute.m_value.data(), attribute.m_value.size()))) return false; + if (attributeName == http_equivAttr && !isDangerousHTTPEquiv(String(attribute.m_value.data(), attribute.m_value.size()))) + return false; token.eraseValueOfAttribute(indexOfAttribute); if (!replacementValue.isEmpty()) token.appendToAttributeValue(indexOfAttribute, replacementValue); diff --git a/Source/WebCore/html/shadow/MediaControls.h b/Source/WebCore/html/shadow/MediaControls.h index dc88ebb..edbbe21 100644 --- a/Source/WebCore/html/shadow/MediaControls.h +++ b/Source/WebCore/html/shadow/MediaControls.h @@ -73,8 +73,19 @@ protected: private: MediaControls(); + + virtual bool isMediaControls() const { return true; } }; +inline MediaControls* toMediaControls(Node* node) +{ + ASSERT(!node || node->isMediaControls()); + return static_cast(node); +} + +// This will catch anyone doing an unneccessary cast. +void toMediaControls(const Node*); + } #endif -- cgit v1.1