diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-09-10 19:10:20 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-09-10 19:10:20 +0200 |
commit | 284837daa07b29d6a63a748544a90b1f5842ac5c (patch) | |
tree | ecd258180bde91fe741e0cfd2638beb3c6da7e8e /Source/WebCore/page | |
parent | 2e2ba8ff45915f40ed3e014101269c175f2a89a0 (diff) | |
download | qtwebkit-284837daa07b29d6a63a748544a90b1f5842ac5c.tar.gz |
Imported WebKit commit 68645295d2e3e09af2c942f092556f06aa5f8b0d (http://svn.webkit.org/repository/webkit/trunk@128073)
New snapshot
Diffstat (limited to 'Source/WebCore/page')
61 files changed, 883 insertions, 348 deletions
diff --git a/Source/WebCore/page/Chrome.cpp b/Source/WebCore/page/Chrome.cpp index 436222d88..cca4a0925 100644 --- a/Source/WebCore/page/Chrome.cpp +++ b/Source/WebCore/page/Chrome.cpp @@ -95,6 +95,7 @@ void Chrome::invalidateContentsForSlowScroll(const IntRect& updateRect, bool imm void Chrome::scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) { m_client->scroll(scrollDelta, rectToScroll, clipRect); + InspectorInstrumentation::didScroll(m_page); } #if USE(TILED_BACKING_STORE) diff --git a/Source/WebCore/page/ChromeClient.h b/Source/WebCore/page/ChromeClient.h index dd6afcfe1..fa5b485e0 100644 --- a/Source/WebCore/page/ChromeClient.h +++ b/Source/WebCore/page/ChromeClient.h @@ -48,6 +48,8 @@ class NSResponder; namespace WebCore { class AccessibilityObject; + class DateTimeChooser; + class DateTimeChooserClient; class Element; class FileChooser; class FileIconLoader; @@ -69,6 +71,7 @@ namespace WebCore { class GraphicsContext3D; class Widget; + struct DateTimeChooserParameters; struct FrameLoadRequest; struct ViewportArguments; struct WindowFeatures; @@ -222,6 +225,10 @@ namespace WebCore { virtual PassOwnPtr<ColorChooser> createColorChooser(ColorChooserClient*, const Color&) = 0; #endif +#if ENABLE(CALENDAR_PICKER) + virtual PassOwnPtr<DateTimeChooser> openDateTimeChooser(DateTimeChooserClient*, const DateTimeChooserParameters&) = 0; +#endif + virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>) = 0; // Asynchronous request to load an icon for specified filenames. virtual void loadIconForFiles(const Vector<String>&, FileIconLoader*) = 0; diff --git a/Source/WebCore/page/Console.cpp b/Source/WebCore/page/Console.cpp index d0e5e4fe7..971337728 100644 --- a/Source/WebCore/page/Console.cpp +++ b/Source/WebCore/page/Console.cpp @@ -39,7 +39,6 @@ #include "MemoryInfo.h" #include "Page.h" #include "PageGroup.h" -#include "PlatformString.h" #include "ScriptArguments.h" #include "ScriptCallStack.h" #include "ScriptProfile.h" @@ -48,6 +47,7 @@ #include <stdio.h> #include <wtf/UnusedParam.h> #include <wtf/text/CString.h> +#include <wtf/text/WTFString.h> #if PLATFORM(CHROMIUM) #include "TraceEvent.h" diff --git a/Source/WebCore/page/ContentSecurityPolicy.cpp b/Source/WebCore/page/ContentSecurityPolicy.cpp index a3834faa7..02a151bd3 100644 --- a/Source/WebCore/page/ContentSecurityPolicy.cpp +++ b/Source/WebCore/page/ContentSecurityPolicy.cpp @@ -244,8 +244,10 @@ bool CSPSourceList::matches(const KURL& url) if (m_allowStar) return true; + KURL effectiveURL = SecurityOrigin::shouldUseInnerURL(url) ? SecurityOrigin::extractInnerURL(url) : url; + for (size_t i = 0; i < m_list.size(); ++i) { - if (m_list[i].matches(url)) + if (m_list[i].matches(effectiveURL)) return true; } @@ -897,7 +899,7 @@ bool CSPDirectiveList::checkSourceAndReportViolation(SourceListDirective* direct bool CSPDirectiveList::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const { - DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute JavaScript URL because it violates the following Content Security Policy directive: ")); + DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Refused to execute JavaScript URL because it violates the following Content Security Policy directive: "))); if (reportingStatus == ContentSecurityPolicy::SendReport) { return (checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine) && checkNonceAndReportViolation(m_scriptNonce.get(), String(), consoleMessage, contextURL, contextLine)); @@ -909,7 +911,7 @@ bool CSPDirectiveList::allowJavaScriptURLs(const String& contextURL, const WTF:: bool CSPDirectiveList::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const { - DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute inline event handler because it violates the following Content Security Policy directive: ")); + DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Refused to execute inline event handler because it violates the following Content Security Policy directive: "))); if (reportingStatus == ContentSecurityPolicy::SendReport) { return (checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine) && checkNonceAndReportViolation(m_scriptNonce.get(), String(), consoleMessage, contextURL, contextLine)); @@ -921,7 +923,7 @@ bool CSPDirectiveList::allowInlineEventHandlers(const String& contextURL, const bool CSPDirectiveList::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const { - DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute inline script because it violates the following Content Security Policy directive: ")); + DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Refused to execute inline script because it violates the following Content Security Policy directive: "))); return reportingStatus == ContentSecurityPolicy::SendReport ? checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine) : checkInline(operativeDirective(m_scriptSrc.get())); @@ -929,7 +931,7 @@ bool CSPDirectiveList::allowInlineScript(const String& contextURL, const WTF::Or bool CSPDirectiveList::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const { - DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to apply inline style because it violates the following Content Security Policy directive: ")); + DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Refused to apply inline style because it violates the following Content Security Policy directive: "))); return reportingStatus == ContentSecurityPolicy::SendReport ? checkInlineAndReportViolation(operativeDirective(m_styleSrc.get()), consoleMessage, contextURL, contextLine) : checkInline(operativeDirective(m_styleSrc.get())); @@ -937,7 +939,7 @@ bool CSPDirectiveList::allowInlineStyle(const String& contextURL, const WTF::Ord bool CSPDirectiveList::allowEval(PassRefPtr<ScriptCallStack> callStack, ContentSecurityPolicy::ReportingStatus reportingStatus) const { - DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to evaluate script because it violates the following Content Security Policy directive: ")); + DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Refused to evaluate script because it violates the following Content Security Policy directive: "))); return reportingStatus == ContentSecurityPolicy::SendReport ? checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, String(), WTF::OrdinalNumber::beforeFirst(), callStack) : checkEval(operativeDirective(m_scriptSrc.get())); @@ -945,7 +947,7 @@ bool CSPDirectiveList::allowEval(PassRefPtr<ScriptCallStack> callStack, ContentS bool CSPDirectiveList::allowScriptNonce(const String& nonce, const String& contextURL, const WTF::OrdinalNumber& contextLine, const KURL& url) const { - DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute script because it violates the following Content Security Policy directive: ")); + DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Refused to execute script because it violates the following Content Security Policy directive: "))); if (url.isEmpty()) return checkNonceAndReportViolation(m_scriptNonce.get(), nonce, consoleMessage, contextURL, contextLine); return checkNonceAndReportViolation(m_scriptNonce.get(), nonce, "Refused to load '" + url.string() + "' because it violates the following Content Security Policy directive: ", contextURL, contextLine); @@ -960,7 +962,7 @@ bool CSPDirectiveList::allowPluginType(const String& type, const String& typeAtt bool CSPDirectiveList::allowScriptFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const { - DEFINE_STATIC_LOCAL(String, type, ("script")); + DEFINE_STATIC_LOCAL(String, type, (ASCIILiteral("script"))); return reportingStatus == ContentSecurityPolicy::SendReport ? checkSourceAndReportViolation(operativeDirective(m_scriptSrc.get()), url, type) : checkSource(operativeDirective(m_scriptSrc.get()), url); @@ -968,7 +970,7 @@ bool CSPDirectiveList::allowScriptFromSource(const KURL& url, ContentSecurityPol bool CSPDirectiveList::allowObjectFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const { - DEFINE_STATIC_LOCAL(String, type, ("object")); + DEFINE_STATIC_LOCAL(String, type, (ASCIILiteral("object"))); if (url.isBlankURL()) return true; return reportingStatus == ContentSecurityPolicy::SendReport ? @@ -978,7 +980,7 @@ bool CSPDirectiveList::allowObjectFromSource(const KURL& url, ContentSecurityPol bool CSPDirectiveList::allowChildFrameFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const { - DEFINE_STATIC_LOCAL(String, type, ("frame")); + DEFINE_STATIC_LOCAL(String, type, (ASCIILiteral("frame"))); if (url.isBlankURL()) return true; return reportingStatus == ContentSecurityPolicy::SendReport ? @@ -988,7 +990,7 @@ bool CSPDirectiveList::allowChildFrameFromSource(const KURL& url, ContentSecurit bool CSPDirectiveList::allowImageFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const { - DEFINE_STATIC_LOCAL(String, type, ("image")); + DEFINE_STATIC_LOCAL(String, type, (ASCIILiteral("image"))); return reportingStatus == ContentSecurityPolicy::SendReport ? checkSourceAndReportViolation(operativeDirective(m_imgSrc.get()), url, type) : checkSource(operativeDirective(m_imgSrc.get()), url); @@ -996,7 +998,7 @@ bool CSPDirectiveList::allowImageFromSource(const KURL& url, ContentSecurityPoli bool CSPDirectiveList::allowStyleFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const { - DEFINE_STATIC_LOCAL(String, type, ("style")); + DEFINE_STATIC_LOCAL(String, type, (ASCIILiteral("style"))); return reportingStatus == ContentSecurityPolicy::SendReport ? checkSourceAndReportViolation(operativeDirective(m_styleSrc.get()), url, type) : checkSource(operativeDirective(m_styleSrc.get()), url); @@ -1004,7 +1006,7 @@ bool CSPDirectiveList::allowStyleFromSource(const KURL& url, ContentSecurityPoli bool CSPDirectiveList::allowFontFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const { - DEFINE_STATIC_LOCAL(String, type, ("font")); + DEFINE_STATIC_LOCAL(String, type, (ASCIILiteral("font"))); return reportingStatus == ContentSecurityPolicy::SendReport ? checkSourceAndReportViolation(operativeDirective(m_fontSrc.get()), url, type) : checkSource(operativeDirective(m_fontSrc.get()), url); @@ -1012,7 +1014,7 @@ bool CSPDirectiveList::allowFontFromSource(const KURL& url, ContentSecurityPolic bool CSPDirectiveList::allowMediaFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const { - DEFINE_STATIC_LOCAL(String, type, ("media")); + DEFINE_STATIC_LOCAL(String, type, (ASCIILiteral("media"))); return reportingStatus == ContentSecurityPolicy::SendReport ? checkSourceAndReportViolation(operativeDirective(m_mediaSrc.get()), url, type) : checkSource(operativeDirective(m_mediaSrc.get()), url); @@ -1020,7 +1022,7 @@ bool CSPDirectiveList::allowMediaFromSource(const KURL& url, ContentSecurityPoli bool CSPDirectiveList::allowConnectToSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const { - DEFINE_STATIC_LOCAL(String, type, ("connect")); + DEFINE_STATIC_LOCAL(String, type, (ASCIILiteral("connect"))); return reportingStatus == ContentSecurityPolicy::SendReport ? checkSourceAndReportViolation(operativeDirective(m_connectSrc.get()), url, type) : checkSource(operativeDirective(m_connectSrc.get()), url); @@ -1034,7 +1036,7 @@ void CSPDirectiveList::gatherReportURIs(DOMStringList& list) const bool CSPDirectiveList::allowFormAction(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const { - DEFINE_STATIC_LOCAL(String, type, ("form")); + DEFINE_STATIC_LOCAL(String, type, (ASCIILiteral("form"))); return reportingStatus == ContentSecurityPolicy::SendReport ? checkSourceAndReportViolation(m_formAction.get(), url, type) : checkSource(m_formAction.get(), url); @@ -1108,8 +1110,10 @@ bool CSPDirectiveList::parseDirective(const UChar* begin, const UChar* end, Stri const UChar* valueBegin = position; skipWhile<isDirectiveValueCharacter>(position, end); - if (position != end) + if (position != end) { + m_policy->reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin)); return false; + } // The directive-value may be empty. if (valueBegin == position) @@ -1164,21 +1168,21 @@ void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sand void CSPDirectiveList::addDirective(const String& name, const String& value) { - DEFINE_STATIC_LOCAL(String, defaultSrc, ("default-src")); - DEFINE_STATIC_LOCAL(String, scriptSrc, ("script-src")); - DEFINE_STATIC_LOCAL(String, objectSrc, ("object-src")); - DEFINE_STATIC_LOCAL(String, frameSrc, ("frame-src")); - DEFINE_STATIC_LOCAL(String, imgSrc, ("img-src")); - DEFINE_STATIC_LOCAL(String, styleSrc, ("style-src")); - DEFINE_STATIC_LOCAL(String, fontSrc, ("font-src")); - DEFINE_STATIC_LOCAL(String, mediaSrc, ("media-src")); - DEFINE_STATIC_LOCAL(String, connectSrc, ("connect-src")); - DEFINE_STATIC_LOCAL(String, sandbox, ("sandbox")); - DEFINE_STATIC_LOCAL(String, reportURI, ("report-uri")); + DEFINE_STATIC_LOCAL(String, defaultSrc, (ASCIILiteral("default-src"))); + DEFINE_STATIC_LOCAL(String, scriptSrc, (ASCIILiteral("script-src"))); + DEFINE_STATIC_LOCAL(String, objectSrc, (ASCIILiteral("object-src"))); + DEFINE_STATIC_LOCAL(String, frameSrc, (ASCIILiteral("frame-src"))); + DEFINE_STATIC_LOCAL(String, imgSrc, (ASCIILiteral("img-src"))); + DEFINE_STATIC_LOCAL(String, styleSrc, (ASCIILiteral("style-src"))); + DEFINE_STATIC_LOCAL(String, fontSrc, (ASCIILiteral("font-src"))); + DEFINE_STATIC_LOCAL(String, mediaSrc, (ASCIILiteral("media-src"))); + DEFINE_STATIC_LOCAL(String, connectSrc, (ASCIILiteral("connect-src"))); + DEFINE_STATIC_LOCAL(String, sandbox, (ASCIILiteral("sandbox"))); + DEFINE_STATIC_LOCAL(String, reportURI, (ASCIILiteral("report-uri"))); #if ENABLE(CSP_NEXT) - DEFINE_STATIC_LOCAL(String, formAction, ("form-action")); - DEFINE_STATIC_LOCAL(String, pluginTypes, ("plugin-types")); - DEFINE_STATIC_LOCAL(String, scriptNonce, ("script-nonce")); + DEFINE_STATIC_LOCAL(String, formAction, (ASCIILiteral("form-action"))); + DEFINE_STATIC_LOCAL(String, pluginTypes, (ASCIILiteral("plugin-types"))); + DEFINE_STATIC_LOCAL(String, scriptNonce, (ASCIILiteral("script-nonce"))); #endif ASSERT(!name.isEmpty()); @@ -1502,6 +1506,12 @@ void ContentSecurityPolicy::reportInvalidPluginTypes(const String& pluginType) c logToConsole(message); } +void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const +{ + String message = makeString("The value for Content Security Policy directive '", directiveName, "' contains an invalid character: '", value, "'. Non-whitespace characters outside ASCII 0x21-0x7E must be percent-encoded, as described in RFC 3986, section 2.1: http://tools.ietf.org/html/rfc3986#section-2.1."); + logToConsole(message); +} + void ContentSecurityPolicy::reportInvalidNonce(const String& nonce) const { String message = makeString("Ignoring invalid Content Security Policy script nonce: '", nonce, "'.\n"); diff --git a/Source/WebCore/page/ContentSecurityPolicy.h b/Source/WebCore/page/ContentSecurityPolicy.h index 3c390516a..3d40ec4cd 100644 --- a/Source/WebCore/page/ContentSecurityPolicy.h +++ b/Source/WebCore/page/ContentSecurityPolicy.h @@ -100,6 +100,7 @@ public: void reportDuplicateDirective(const String&) const; void reportIgnoredPathComponent(const String& directiveName, const String& completeSource, const String& path) const; + void reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const; void reportInvalidNonce(const String&) const; void reportInvalidPluginTypes(const String&) const; void reportInvalidSourceExpression(const String& directiveName, const String& source) const; diff --git a/Source/WebCore/page/ContextMenuController.cpp b/Source/WebCore/page/ContextMenuController.cpp index d9019fc30..87f3cc4d6 100644 --- a/Source/WebCore/page/ContextMenuController.cpp +++ b/Source/WebCore/page/ContextMenuController.cpp @@ -149,7 +149,7 @@ PassOwnPtr<ContextMenu> ContextMenuController::createContextMenu(Event* event) HitTestResult result(mouseEvent->absoluteLocation()); if (Frame* frame = event->target()->toNode()->document()->frame()) - result = frame->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), false); + result = frame->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation()); if (!result.innerNonSharedNode()) return nullptr; diff --git a/Source/WebCore/page/Coordinates.h b/Source/WebCore/page/Coordinates.h index ceee538fc..3de1366f1 100644 --- a/Source/WebCore/page/Coordinates.h +++ b/Source/WebCore/page/Coordinates.h @@ -27,7 +27,6 @@ #define Coordinates_h #include "Event.h" -#include "PlatformString.h" #include <wtf/RefCounted.h> namespace WebCore { diff --git a/Source/WebCore/page/Crypto.cpp b/Source/WebCore/page/Crypto.cpp index e38350ab1..16709e9e0 100644 --- a/Source/WebCore/page/Crypto.cpp +++ b/Source/WebCore/page/Crypto.cpp @@ -63,6 +63,10 @@ void Crypto::getRandomValues(ArrayBufferView* array, ExceptionCode& ec) ec = TYPE_MISMATCH_ERR; return; } + if (array->byteLength() > 65536) { + ec = QUOTA_EXCEEDED_ERR; + return; + } cryptographicallyRandomValues(array->baseAddress(), array->byteLength()); #else ASSERT_UNUSED(array, array); diff --git a/Source/WebCore/page/DOMSelection.cpp b/Source/WebCore/page/DOMSelection.cpp index 59f266f41..c3ad42807 100644 --- a/Source/WebCore/page/DOMSelection.cpp +++ b/Source/WebCore/page/DOMSelection.cpp @@ -36,11 +36,11 @@ #include "Frame.h" #include "FrameSelection.h" #include "Node.h" -#include "PlatformString.h" #include "Range.h" #include "TextIterator.h" #include "TreeScope.h" #include "htmlediting.h" +#include <wtf/text/WTFString.h> namespace WebCore { diff --git a/Source/WebCore/page/DOMWindow.cpp b/Source/WebCore/page/DOMWindow.cpp index d787a65bd..6df5a9a99 100644 --- a/Source/WebCore/page/DOMWindow.cpp +++ b/Source/WebCore/page/DOMWindow.cpp @@ -1755,10 +1755,16 @@ String DOMWindow::crossDomainAccessErrorMessage(DOMWindow* activeWindow) if (activeWindowURL.isNull()) return String(); - // FIXME: This error message should contain more specifics of why the same origin check has failed. - // Perhaps we should involve the security origin object in composing it. // FIXME: This message, and other console messages, have extra newlines. Should remove them. - return "Unsafe JavaScript attempt to access frame with URL " + document()->url().string() + " from frame with URL " + activeWindowURL.string() + ". Domains, protocols and ports must match.\n"; + String message = makeString("Unsafe JavaScript attempt to access frame with URL ", document()->url().string(), " from frame with URL ", activeWindowURL.string(), "."); + if (document()->isSandboxed(SandboxOrigin) || activeWindow->document()->isSandboxed(SandboxOrigin)) { + if (document()->isSandboxed(SandboxOrigin) && activeWindow->document()->isSandboxed(SandboxOrigin)) + return makeString("Sandbox access violation: ", message, " Both frames are sandboxed into unique origins.\n"); + if (document()->isSandboxed(SandboxOrigin)) + return makeString("Sandbox access violation: ", message, " The frame being accessed is sandboxed into a unique origin.\n"); + return makeString("Sandbox access violation: ", message, " The frame requesting access is sandboxed into a unique origin.\n"); + } + return makeString(message, " Domains, protocols and ports must match.\n"); } bool DOMWindow::isInsecureScriptAccess(DOMWindow* activeWindow, const String& urlString) diff --git a/Source/WebCore/page/DOMWindow.idl b/Source/WebCore/page/DOMWindow.idl index 53495918d..2e0711cec 100644 --- a/Source/WebCore/page/DOMWindow.idl +++ b/Source/WebCore/page/DOMWindow.idl @@ -786,9 +786,9 @@ module window { attribute [Conditional=MUTATION_OBSERVERS] MutationObserverConstructor WebKitMutationObserver; - attribute [Conditional=MEDIA_SOURCE, V8EnabledAtRuntime=mediaSource] MediaSourceConstructor MediaSource; - attribute [Conditional=MEDIA_SOURCE, V8EnabledAtRuntime=mediaSource] SourceBufferConstructor SourceBuffer; - attribute [Conditional=MEDIA_SOURCE, V8EnabledAtRuntime=mediaSource] SourceBufferListConstructor SourceBufferList; + attribute [Conditional=MEDIA_SOURCE, V8EnabledAtRuntime=mediaSource] MediaSourceConstructor WebKitMediaSource; + attribute [Conditional=MEDIA_SOURCE, V8EnabledAtRuntime=mediaSource] SourceBufferConstructor WebKitSourceBuffer; + attribute [Conditional=MEDIA_SOURCE, V8EnabledAtRuntime=mediaSource] SourceBufferListConstructor WebKitSourceBufferList; #endif // defined(LANGUAGE_JAVASCRIPT) diff --git a/Source/WebCore/page/DiagnosticLoggingKeys.cpp b/Source/WebCore/page/DiagnosticLoggingKeys.cpp index d71a605a8..ca54547b0 100644 --- a/Source/WebCore/page/DiagnosticLoggingKeys.cpp +++ b/Source/WebCore/page/DiagnosticLoggingKeys.cpp @@ -30,55 +30,55 @@ namespace WebCore { const String& DiagnosticLoggingKeys::mediaLoadedKey() { - DEFINE_STATIC_LOCAL(const String, key, ("mediaLoaded")); + DEFINE_STATIC_LOCAL(const String, key, (ASCIILiteral("mediaLoaded"))); return key; } const String& DiagnosticLoggingKeys::mediaLoadingFailedKey() { - DEFINE_STATIC_LOCAL(const String, key, ("mediaFailedLoading")); + DEFINE_STATIC_LOCAL(const String, key, (ASCIILiteral("mediaFailedLoading"))); return key; } const String& DiagnosticLoggingKeys::pluginLoadedKey() { - DEFINE_STATIC_LOCAL(const String, key, ("pluginLoaded")); + DEFINE_STATIC_LOCAL(const String, key, (ASCIILiteral("pluginLoaded"))); return key; } const String& DiagnosticLoggingKeys::pluginLoadingFailedKey() { - DEFINE_STATIC_LOCAL(const String, key, ("pluginFailedLoading")); + DEFINE_STATIC_LOCAL(const String, key, (ASCIILiteral("pluginFailedLoading"))); return key; } const String& DiagnosticLoggingKeys::pageContainsPluginKey() { - DEFINE_STATIC_LOCAL(const String, key, ("pageContainsPlugin")); + DEFINE_STATIC_LOCAL(const String, key, (ASCIILiteral("pageContainsPlugin"))); return key; } const String& DiagnosticLoggingKeys::pageContainsAtLeastOnePluginKey() { - DEFINE_STATIC_LOCAL(const String, key, ("pageContainsAtLeastOnePlugin")); + DEFINE_STATIC_LOCAL(const String, key, (ASCIILiteral("pageContainsAtLeastOnePlugin"))); return key; } const String& DiagnosticLoggingKeys::passKey() { - DEFINE_STATIC_LOCAL(const String, key, ("pass")); + DEFINE_STATIC_LOCAL(const String, key, (ASCIILiteral("pass"))); return key; } const String& DiagnosticLoggingKeys::failKey() { - DEFINE_STATIC_LOCAL(const String, key, ("fail")); + DEFINE_STATIC_LOCAL(const String, key, (ASCIILiteral("fail"))); return key; } const String& DiagnosticLoggingKeys::noopKey() { - DEFINE_STATIC_LOCAL(const String, key, ("noop")); + DEFINE_STATIC_LOCAL(const String, key, (ASCIILiteral("noop"))); return key; } diff --git a/Source/WebCore/page/DragController.cpp b/Source/WebCore/page/DragController.cpp index c744c189e..a1e78b80a 100644 --- a/Source/WebCore/page/DragController.cpp +++ b/Source/WebCore/page/DragController.cpp @@ -544,7 +544,7 @@ bool DragController::canProcessDrag(DragData* dragData) if (!m_page->mainFrame()->contentRenderer()) return false; - result = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, true); + result = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowShadowContent); if (!result.innerNonSharedNode()) return false; @@ -726,7 +726,7 @@ bool DragController::startDrag(Frame* src, const DragState& state, DragOperation if (!src->view() || !src->contentRenderer()) return false; - HitTestResult hitTestResult = src->eventHandler()->hitTestResultAtPoint(dragOrigin, true); + HitTestResult hitTestResult = src->eventHandler()->hitTestResultAtPoint(dragOrigin, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowShadowContent); if (!state.m_dragSrc->contains(hitTestResult.innerNode())) // The original node being dragged isn't under the drag origin anymore... maybe it was // hidden or moved out from under the cursor. Regardless, we don't want to start a drag on diff --git a/Source/WebCore/page/EditorClient.h b/Source/WebCore/page/EditorClient.h index d74636839..e38fda50d 100644 --- a/Source/WebCore/page/EditorClient.h +++ b/Source/WebCore/page/EditorClient.h @@ -155,6 +155,10 @@ public: virtual bool spellingUIIsShowing() = 0; virtual void willSetInputMethodState() = 0; virtual void setInputMethodState(bool enabled) = 0; + + // Support for global selections, used on platforms like the X Window System that treat + // selection as a type of clipboard. + virtual bool supportsGlobalSelection() { return false; } }; } diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp index 04f636eae..3807c5597 100644 --- a/Source/WebCore/page/EventHandler.cpp +++ b/Source/WebCore/page/EventHandler.cpp @@ -308,7 +308,6 @@ EventHandler::EventHandler(Frame* frame) , m_eventHandlerWillResetCapturingMouseEventsNode(0) , m_clickCount(0) , m_mouseDownTimestamp(0) - , m_useLatchedWheelEventNode(false) , m_widgetIsLatched(false) #if PLATFORM(MAC) , m_mouseDownView(nil) @@ -1008,7 +1007,7 @@ void EventHandler::updateAutoscrollRenderer() if (!m_autoscrollRenderer) return; - HitTestResult hitTest = hitTestResultAtPoint(m_panScrollStartPos, true); + HitTestResult hitTest = hitTestResultAtPoint(m_panScrollStartPos, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowShadowContent); if (Node* nodeAtPoint = hitTest.innerNode()) m_autoscrollRenderer = nodeAtPoint->renderer(); @@ -1040,42 +1039,18 @@ DragSourceAction EventHandler::updateDragSourceActionsAllowed() const } #endif // ENABLE(DRAG_SUPPORT) -HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, bool allowShadowContent, bool ignoreClipping, HitTestScrollbars testScrollbars, HitTestRequest::HitTestRequestType hitType, const LayoutSize& padding) +HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType, const LayoutSize& padding) { - enum ShadowContentFilterPolicy shadowContentFilterPolicy = allowShadowContent ? AllowShadowContent : DoNotAllowShadowContent; - HitTestResult result(point, padding.height(), padding.width(), padding.height(), padding.width(), shadowContentFilterPolicy); + HitTestResult result(point, padding.height(), padding.width(), padding.height(), padding.width()); if (!m_frame->contentRenderer()) return result; - if (ignoreClipping) - hitType |= HitTestRequest::IgnoreClipping; - m_frame->contentRenderer()->hitTest(HitTestRequest(hitType), result); + // We always need to handle child frame content. + hitType |= HitTestRequest::AllowChildFrameContent; + + HitTestRequest request(hitType); + m_frame->contentRenderer()->hitTest(request, result); - while (true) { - Node* n = result.innerNode(); - if (!result.isOverWidget() || !n || !n->renderer() || !n->renderer()->isWidget()) - break; - RenderWidget* renderWidget = toRenderWidget(n->renderer()); - Widget* widget = renderWidget->widget(); - if (!widget || !widget->isFrameView()) - break; - Frame* frame = static_cast<HTMLFrameElementBase*>(n)->contentFrame(); - if (!frame || !frame->contentRenderer()) - break; - FrameView* view = static_cast<FrameView*>(widget); - LayoutPoint widgetPoint(result.localPoint().x() + view->scrollX() - renderWidget->borderLeft() - renderWidget->paddingLeft(), - result.localPoint().y() + view->scrollY() - renderWidget->borderTop() - renderWidget->paddingTop()); - HitTestResult widgetHitTestResult(widgetPoint, padding.height(), padding.width(), padding.height(), padding.width(), shadowContentFilterPolicy); - frame->contentRenderer()->hitTest(HitTestRequest(hitType), widgetHitTestResult); - result = widgetHitTestResult; - - if (testScrollbars == ShouldHitTestScrollbars) { - Scrollbar* eventScrollbar = view->scrollbarAtPoint(roundedIntPoint(point)); - if (eventScrollbar) - result.setScrollbar(eventScrollbar); - } - } - // If our HitTestResult is not visible, then we started hit testing too far down the frame chain. // Another hit test at the main frame level should get us the correct visible result. Frame* resultFrame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document()->frame() : 0; @@ -1086,12 +1061,12 @@ HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, bool FrameView* mainView = mainFrame->view(); if (resultView && mainView) { IntPoint mainFramePoint = mainView->rootViewToContents(resultView->contentsToRootView(roundedIntPoint(result.point()))); - result = mainFrame->eventHandler()->hitTestResultAtPoint(mainFramePoint, allowShadowContent, ignoreClipping, testScrollbars, hitType, padding); + result = mainFrame->eventHandler()->hitTestResultAtPoint(mainFramePoint, hitType, padding); } } } - if (!allowShadowContent) + if (!request.allowsShadowContent()) result.setToNonShadowAncestor(); return result; @@ -1501,7 +1476,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent) m_mouseDownWasInSubframe = false; HitTestRequest request(HitTestRequest::Active); - // Save the document point we generate in case the window coordinate is invalidated by what happens + // Save the document point we generate in case the window coordinate is invalidated by what happens // when we dispatch the event. LayoutPoint documentPoint = documentPointForWindowPoint(m_frame, mouseEvent.position()); MouseEventWithHitTestResults mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent); @@ -2299,11 +2274,9 @@ bool EventHandler::handleWheelEvent(const PlatformWheelEvent& e) HitTestResult result(vPoint); doc->renderView()->hitTest(request, result); -#if PLATFORM(MAC) - m_useLatchedWheelEventNode = e.momentumPhase() == PlatformWheelEventPhaseBegan || e.momentumPhase() == PlatformWheelEventPhaseChanged; -#endif + bool useLatchedWheelEventNode = e.useLatchedEventNode(); - if (m_useLatchedWheelEventNode) { + if (useLatchedWheelEventNode) { if (!m_latchedWheelEventNode) { m_latchedWheelEventNode = result.innerNode(); m_widgetIsLatched = result.isOverWidget(); @@ -2367,7 +2340,7 @@ void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEv if (scrollNode(wheelEvent->rawDeltaY(), granularity, ScrollUp, ScrollDown, startNode, &stopNode)) wheelEvent->setDefaultHandled(); - if (!m_useLatchedWheelEventNode) + if (!m_latchedWheelEventNode) m_previousWheelScrolledNode = stopNode; } @@ -2403,7 +2376,7 @@ bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent) eventTarget = m_scrollGestureHandlingNode.get(); if (!eventTarget) { - HitTestResult result = hitTestResultAtPoint(gestureEvent.position(), false, false, DontHitTestScrollbars, HitTestRequest::ReadOnly | HitTestRequest::Active); + HitTestResult result = hitTestResultAtPoint(gestureEvent.position()); eventTarget = result.targetNode(); } @@ -2454,8 +2427,8 @@ bool EventHandler::handleGestureTap(const PlatformGestureEvent& gestureEvent) // FIXME: Refactor this code to not hit test multiple times. We use the adjusted position to ensure that the correct node is targeted by the later redundant hit tests. IntPoint adjustedPoint = gestureEvent.position(); #if ENABLE(TOUCH_ADJUSTMENT) - if (!gestureEvent.area().isEmpty() && !adjustGesturePosition(gestureEvent, adjustedPoint)) - return false; + if (!gestureEvent.area().isEmpty()) + adjustGesturePosition(gestureEvent, adjustedPoint); #endif PlatformMouseEvent fakeMouseMove(adjustedPoint, gestureEvent.globalPosition(), @@ -2490,7 +2463,6 @@ bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture bool EventHandler::handleGestureScrollCore(const PlatformGestureEvent& gestureEvent, PlatformWheelEventGranularity granularity, bool latchedWheel) { - TemporaryChange<bool> latched(m_useLatchedWheelEventNode, latchedWheel); const float tickDivisor = (float)WheelEvent::tickMultiplier; IntPoint point(gestureEvent.position().x(), gestureEvent.position().y()); IntPoint globalPoint(gestureEvent.globalPosition().x(), gestureEvent.globalPosition().y()); @@ -2498,6 +2470,7 @@ bool EventHandler::handleGestureScrollCore(const PlatformGestureEvent& gestureEv gestureEvent.deltaX(), gestureEvent.deltaY(), gestureEvent.deltaX() / tickDivisor, gestureEvent.deltaY() / tickDivisor, granularity, gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey()); + syntheticWheelEvent.setUseLatchedEventNode(latchedWheel); return handleWheelEvent(syntheticWheelEvent); } #endif @@ -2505,9 +2478,8 @@ bool EventHandler::handleGestureScrollCore(const PlatformGestureEvent& gestureEv #if ENABLE(TOUCH_ADJUSTMENT) bool EventHandler::bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode) { - HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active; IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); - HitTestResult result = hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ true, /*ignoreClipping*/ false, DontHitTestScrollbars, hitType, touchRadius); + HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowShadowContent, touchRadius); IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius); RefPtr<StaticHashSetNodeList> nodeList = StaticHashSetNodeList::adopt(result.rectBasedTestResult()); @@ -2524,9 +2496,8 @@ bool EventHandler::bestClickableNodeForTouchPoint(const IntPoint& touchCenter, c bool EventHandler::bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode) { - HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active; IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); - HitTestResult result = hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ true, /*ignoreClipping*/ false, DontHitTestScrollbars, hitType, touchRadius); + HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowShadowContent, touchRadius); IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius); RefPtr<StaticHashSetNodeList> nodeList = StaticHashSetNodeList::adopt(result.rectBasedTestResult()); @@ -2535,9 +2506,8 @@ bool EventHandler::bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode) { - HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active; IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); - HitTestResult result = hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ false, /*ignoreClipping*/ false, DontHitTestScrollbars, hitType, touchRadius); + HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::ReadOnly | HitTestRequest::Active, touchRadius); IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius); RefPtr<StaticHashSetNodeList> nodeList = StaticHashSetNodeList::adopt(result.rectBasedTestResult()); @@ -3579,7 +3549,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) unsigned touchPointTargetKey = point.id() + 1; RefPtr<EventTarget> touchTarget; if (pointState == PlatformTouchPoint::TouchPressed) { - HitTestResult result = hitTestResultAtPoint(pagePoint, /*allowShadowContent*/ false, false, DontHitTestScrollbars, hitType); + HitTestResult result = hitTestResultAtPoint(pagePoint, hitType); Node* node = result.innerNode(); ASSERT(node); @@ -3597,7 +3567,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) touchTarget = node; } else if (pointState == PlatformTouchPoint::TouchReleased || pointState == PlatformTouchPoint::TouchCancelled) { // We only perform a hittest on release or cancel to unset :active or :hover state. - hitTestResultAtPoint(pagePoint, /*allowShadowContent*/ false, false, DontHitTestScrollbars, hitType); + hitTestResultAtPoint(pagePoint, hitType); // The target should be the original target for this touch, so get it from the hashmap. As it's a release or cancel // we also remove it from the map. touchTarget = m_originatingTouchPointTargets.take(touchPointTargetKey); diff --git a/Source/WebCore/page/EventHandler.h b/Source/WebCore/page/EventHandler.h index ac0ff0b1f..97d0bd03f 100644 --- a/Source/WebCore/page/EventHandler.h +++ b/Source/WebCore/page/EventHandler.h @@ -88,8 +88,6 @@ extern const int TextDragHysteresis; extern const int GeneralDragHysteresis; #endif // ENABLE(DRAG_SUPPORT) -enum HitTestScrollbars { ShouldHitTestScrollbars, DontHitTestScrollbars }; - class EventHandler { WTF_MAKE_NONCOPYABLE(EventHandler); public: @@ -115,9 +113,7 @@ public: void dispatchFakeMouseMoveEventSoon(); void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&); - HitTestResult hitTestResultAtPoint(const LayoutPoint&, bool allowShadowContent, bool ignoreClipping = false, - HitTestScrollbars scrollbars = DontHitTestScrollbars, - HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active, + HitTestResult hitTestResultAtPoint(const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active, const LayoutSize& padding = LayoutSize()); bool mousePressed() const { return m_mousePressed; } @@ -430,7 +426,6 @@ private: double m_mouseDownTimestamp; PlatformMouseEvent m_mouseDown; - bool m_useLatchedWheelEventNode; RefPtr<Node> m_latchedWheelEventNode; bool m_widgetIsLatched; diff --git a/Source/WebCore/page/EventSource.cpp b/Source/WebCore/page/EventSource.cpp index 03f78e988..610170208 100644 --- a/Source/WebCore/page/EventSource.cpp +++ b/Source/WebCore/page/EventSource.cpp @@ -41,7 +41,6 @@ #include "ExceptionCode.h" #include "MemoryCache.h" #include "MessageEvent.h" -#include "PlatformString.h" #include "ResourceError.h" #include "ResourceRequest.h" #include "ResourceResponse.h" @@ -51,6 +50,7 @@ #include "SerializedScriptValue.h" #include "TextResourceDecoder.h" #include "ThreadableLoader.h" +#include <wtf/text/StringBuilder.h> namespace WebCore { @@ -210,20 +210,22 @@ void EventSource::didReceiveResponse(unsigned long, const ResourceResponse& resp // If we have a charset, the only allowed value is UTF-8 (case-insensitive). responseIsValid = charset.isEmpty() || equalIgnoringCase(charset, "UTF-8"); if (!responseIsValid) { - String message = "EventSource's response has a charset (\""; - message += charset; - message += "\") that is not UTF-8. Aborting the connection."; + StringBuilder message; + message.appendLiteral("EventSource's response has a charset (\""); + message.append(charset); + message.appendLiteral("\") that is not UTF-8. Aborting the connection."); // FIXME: We are missing the source line. - scriptExecutionContext()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message); + scriptExecutionContext()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message.toString()); } } else { // To keep the signal-to-noise ratio low, we only log 200-response with an invalid MIME type. if (statusCode == 200 && !mimeTypeIsValid) { - String message = "EventSource's response has a MIME type (\""; - message += response.mimeType(); - message += "\") that is not \"text/event-stream\". Aborting the connection."; + StringBuilder message; + message.appendLiteral("EventSource's response has a MIME type (\""); + message.append(response.mimeType()); + message.appendLiteral("\") that is not \"text/event-stream\". Aborting the connection."); // FIXME: We are missing the source line. - scriptExecutionContext()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message); + scriptExecutionContext()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message.toString()); } } diff --git a/Source/WebCore/page/FocusController.cpp b/Source/WebCore/page/FocusController.cpp index 41e9ffdd5..0705c0bfa 100644 --- a/Source/WebCore/page/FocusController.cpp +++ b/Source/WebCore/page/FocusController.cpp @@ -163,7 +163,7 @@ static inline void dispatchEventsOnWindowAndFocusedNode(Document* document, bool static inline bool hasCustomFocusLogic(Node* node) { - return node->hasTagName(inputTag) || node->hasTagName(textareaTag) || node->hasTagName(videoTag) || node->hasTagName(audioTag); + return node->isHTMLElement() && toHTMLElement(node)->hasCustomFocusLogic(); } static inline bool isNonFocusableShadowHost(Node* node, KeyboardEvent* event) @@ -745,7 +745,7 @@ static void updateFocusCandidateIfNeeded(FocusDirection direction, const FocusCa // If 2 nodes are intersecting, do hit test to find which node in on top. LayoutUnit x = intersectionRect.x() + intersectionRect.width() / 2; LayoutUnit y = intersectionRect.y() + intersectionRect.height() / 2; - HitTestResult result = candidate.visibleNode->document()->page()->mainFrame()->eventHandler()->hitTestResultAtPoint(IntPoint(x, y), false, true); + HitTestResult result = candidate.visibleNode->document()->page()->mainFrame()->eventHandler()->hitTestResultAtPoint(IntPoint(x, y), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping); if (candidate.visibleNode->contains(result.innerNode())) { closest = candidate; return; diff --git a/Source/WebCore/page/Frame.cpp b/Source/WebCore/page/Frame.cpp index 1874ddef2..471726729 100644 --- a/Source/WebCore/page/Frame.cpp +++ b/Source/WebCore/page/Frame.cpp @@ -303,11 +303,10 @@ void Frame::setDocument(PassRefPtr<Document> newDoc) if (m_doc && !m_doc->attached()) m_doc->attach(); - // Update the cached 'document' property, which is now stale. - m_script.updateDocument(); - - if (m_doc) + if (m_doc) { + m_script.updateDocument(); m_doc->updateViewportArguments(); + } if (m_page && m_page->mainFrame() == this) { notifyChromeClientWheelEventHandlerCountChanged(); @@ -675,7 +674,7 @@ void Frame::dispatchVisibilityStateChangeEvent() void Frame::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - MemoryClassInfo info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM); info.addInstrumentedMember(m_doc.get()); info.addInstrumentedMember(m_loader); } @@ -725,7 +724,7 @@ String Frame::displayStringModifiedByEncoding(const String& str) const VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint) { - HitTestResult result = eventHandler()->hitTestResultAtPoint(framePoint, true); + HitTestResult result = eventHandler()->hitTestResultAtPoint(framePoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowShadowContent); Node* node = result.innerNonSharedNode(); if (!node) return VisiblePosition(); @@ -747,7 +746,7 @@ Document* Frame::documentAtPoint(const IntPoint& point) HitTestResult result = HitTestResult(pt); if (contentRenderer()) - result = eventHandler()->hitTestResultAtPoint(pt, false); + result = eventHandler()->hitTestResultAtPoint(pt); return result.innerNode() ? result.innerNode()->document() : 0; } @@ -851,7 +850,7 @@ void Frame::tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea) return; unsigned size = paintedArea.size(); // Request repaint from the system - for (int n = 0; n < size; ++n) + for (unsigned n = 0; n < size; ++n) m_page->chrome()->invalidateContentsAndRootView(m_view->contentsToRootView(paintedArea[n]), false); } diff --git a/Source/WebCore/page/FrameTree.cpp b/Source/WebCore/page/FrameTree.cpp index 6378f3fc8..6f8171450 100644 --- a/Source/WebCore/page/FrameTree.cpp +++ b/Source/WebCore/page/FrameTree.cpp @@ -30,6 +30,7 @@ #include <wtf/StringExtras.h> #include <wtf/Vector.h> #include <wtf/text/CString.h> +#include <wtf/text/StringBuilder.h> using std::swap; @@ -150,29 +151,23 @@ AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const break; chain.append(frame); } - String name; - name += framePathPrefix; - if (frame) - name += frame->tree()->uniqueName().string().substring(framePathPrefixLength, - frame->tree()->uniqueName().length() - framePathPrefixLength - framePathSuffixLength); + StringBuilder name; + name.append(framePathPrefix); + if (frame) { + name.append(frame->tree()->uniqueName().string().substring(framePathPrefixLength, + frame->tree()->uniqueName().length() - framePathPrefixLength - framePathSuffixLength)); + } for (int i = chain.size() - 1; i >= 0; --i) { frame = chain[i]; - name += "/"; - name += frame->tree()->uniqueName(); + name.append('/'); + name.append(frame->tree()->uniqueName()); } - // Suffix buffer has more than enough space for: - // 10 characters before the number - // a number (20 digits for the largest 64-bit integer) - // 6 characters after the number - // trailing null byte - // But we still use snprintf just to be extra-safe. - char suffix[40]; - snprintf(suffix, sizeof(suffix), "/<!--frame%u-->-->", childCount()); - - name += suffix; + name.appendLiteral("/<!--frame"); + name.appendNumber(childCount()); + name.appendLiteral("-->-->"); - return AtomicString(name); + return name.toAtomicString(); } inline Frame* FrameTree::scopedChild(unsigned index, TreeScope* scope) const diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp index 4c495fd5a..f4924f121 100644 --- a/Source/WebCore/page/FrameView.cpp +++ b/Source/WebCore/page/FrameView.cpp @@ -101,7 +101,7 @@ double FrameView::sCurrentPaintTimeStamp = 0.0; // Should be removed when applications start using runtime configuration. #if ENABLE(REPAINT_THROTTLING) // Normal delay -double FrameView::s_deferredRepaintDelay = 0.025; +double FrameView::s_normalDeferredRepaintDelay = 0.016; // Negative value would mean that first few repaints happen without a delay double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0; // The delay grows on each repaint to this maximum value @@ -112,7 +112,7 @@ double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0.5; // FIXME: Repaint throttling could be good to have on all platform. // The balance between CPU use and repaint frequency will need some tuning for desktop. // More hooks may be needed to reset the delay on things like GIF and CSS animations. -double FrameView::s_deferredRepaintDelay = 0; +double FrameView::s_normalDeferredRepaintDelay = 0; double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0; double FrameView::s_maxDeferredRepaintDelayDuringLoading = 0; double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0; @@ -609,8 +609,6 @@ void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, S // Don't set it at all. ; } - - Pagination pagination; switch (overflowY) { case OHIDDEN: @@ -625,22 +623,42 @@ void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, S case OAUTO: vMode = ScrollbarAuto; break; - case OPAGEDX: - pagination.mode = WebCore::paginationModeForRenderStyle(o->style()); - break; - case OPAGEDY: - pagination.mode = WebCore::paginationModeForRenderStyle(o->style()); - break; default: - // Don't set it at all. + // Don't set it at all. Values of OPAGEDX and OPAGEDY are handled by applyPaginationToViewPort(). ; } - setPagination(pagination); - m_viewportRenderer = o; } +void FrameView::applyPaginationToViewport() +{ + Document* document = m_frame->document(); + Node* documentElement = document->documentElement(); + RenderObject* documentRenderer = documentElement ? documentElement->renderer() : 0; + RenderObject* documentOrBodyRenderer = documentRenderer; + Node* body = document->body(); + if (body && body->renderer()) { + if (body->hasTagName(bodyTag)) + documentOrBodyRenderer = documentRenderer->style()->overflowX() == OVISIBLE && documentElement->hasTagName(htmlTag) ? body->renderer() : documentRenderer; + } + + Pagination pagination; + + if (!documentOrBodyRenderer) { + setPagination(pagination); + return; + } + + EOverflow overflowY = documentOrBodyRenderer->style()->overflowY(); + if (overflowY == OPAGEDX || overflowY == OPAGEDY) { + pagination.mode = WebCore::paginationModeForRenderStyle(documentOrBodyRenderer->style()); + pagination.gap = static_cast<unsigned>(documentOrBodyRenderer->style()->columnGap()); + } + + setPagination(pagination); +} + void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode, ScrollbarModesCalculationStrategy strategy) { m_viewportRenderer = 0; @@ -788,7 +806,7 @@ bool FrameView::syncCompositingStateForThisFrame(Frame* rootFrameForSync) // If we sync compositing layers and allow the repaint to be deferred, there is time for a // visible flash to occur. Instead, stop the deferred repaint timer and repaint immediately. - stopDelayingDeferredRepaints(); + flushDeferredRepaints(); root->compositor()->flushPendingLayerChanges(rootFrameForSync == m_frame); @@ -1035,6 +1053,10 @@ void FrameView::layout(bool allowSubtree) } else document->evaluateMediaQueryList(); + // If there is any pagination to apply, it will affect the RenderView's style, so we should + // take care of that now. + applyPaginationToViewport(); + // Always ensure our style info is up-to-date. This can happen in situations where // the layout beats any sort of style recalc update that needs to occur. document->updateStyleIfNeeded(); @@ -1314,7 +1336,7 @@ void FrameView::adjustMediaTypeForPrinting(bool printing) bool FrameView::useSlowRepaints(bool considerOverlap) const { - bool mustBeSlow = m_slowRepaintObjectCount > 0 || (platformWidget() && hasFixedObjects()); + bool mustBeSlow = m_slowRepaintObjectCount > 0 || (platformWidget() && hasViewportConstrainedObjects()); // FIXME: WidgetMac.mm makes the assumption that useSlowRepaints == // m_contentIsOpaque, so don't take the fast path for composited layers @@ -1399,13 +1421,13 @@ void FrameView::removeSlowRepaintObject() } } -void FrameView::addFixedObject(RenderObject* object) +void FrameView::addViewportConstrainedObject(RenderObject* object) { - if (!m_fixedObjects) - m_fixedObjects = adoptPtr(new FixedObjectSet); + if (!m_viewportConstrainedObjects) + m_viewportConstrainedObjects = adoptPtr(new ViewportConstrainedObjectSet); - if (!m_fixedObjects->contains(object)) { - m_fixedObjects->add(object); + if (!m_viewportConstrainedObjects->contains(object)) { + m_viewportConstrainedObjects->add(object); if (platformWidget()) updateCanBlitOnScrollRecursively(); @@ -1416,12 +1438,10 @@ void FrameView::addFixedObject(RenderObject* object) } } -void FrameView::removeFixedObject(RenderObject* object) +void FrameView::removeViewportConstrainedObject(RenderObject* object) { - ASSERT(hasFixedObjects()); - - if (m_fixedObjects->contains(object)) { - m_fixedObjects->remove(object); + if (m_viewportConstrainedObjects && m_viewportConstrainedObjects->contains(object)) { + m_viewportConstrainedObjects->remove(object); if (Page* page = m_frame->page()) { if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) scrollingCoordinator->frameViewFixedObjectsDidChange(this); @@ -1490,7 +1510,7 @@ IntPoint FrameView::currentMousePosition() const bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) { - if (!m_fixedObjects || m_fixedObjects->isEmpty()) { + if (!m_viewportConstrainedObjects || m_viewportConstrainedObjects->isEmpty()) { hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); return true; } @@ -1499,10 +1519,10 @@ bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect // Get the rects of the fixed objects visible in the rectToScroll Region regionToUpdate; - FixedObjectSet::const_iterator end = m_fixedObjects->end(); - for (FixedObjectSet::const_iterator it = m_fixedObjects->begin(); it != end; ++it) { + ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObjects->end(); + for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrainedObjects->begin(); it != end; ++it) { RenderObject* renderer = *it; - if (renderer->style()->position() != FixedPosition) + if (!renderer->style()->hasViewportConstrainedPosition()) continue; #if USE(ACCELERATED_COMPOSITING) if (renderer->isComposited()) @@ -1533,8 +1553,8 @@ bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect // 2) update the area of fixed objects that has been invalidated Vector<IntRect> subRectsToUpdate = regionToUpdate.rects(); - size_t fixObjectsCount = subRectsToUpdate.size(); - for (size_t i = 0; i < fixObjectsCount; ++i) { + size_t viewportConstrainedObjectsCount = subRectsToUpdate.size(); + for (size_t i = 0; i < viewportConstrainedObjectsCount; ++i) { IntRect updateRect = subRectsToUpdate[i]; IntRect scrolledRect = updateRect; scrolledRect.move(scrollDelta); @@ -1723,7 +1743,7 @@ void FrameView::scrollElementToRect(Element* element, const IntRect& rect) { m_frame->document()->updateLayoutIgnorePendingStylesheets(); - LayoutRect bounds = element->getRect(); + LayoutRect bounds = element->boundingBox(); int centeringOffsetX = (rect.width() - bounds.width()) / 2; int centeringOffsetY = (rect.height() - bounds.height()) / 2; setScrollPosition(IntPoint(bounds.x() - centeringOffsetX - rect.x(), bounds.y() - centeringOffsetY - rect.y())); @@ -1754,9 +1774,8 @@ void FrameView::setFixedVisibleContentRect(const IntRect& visibleContentRect) bool visibleContentSizeDidChange = false; if (visibleContentRect.size() != this->fixedVisibleContentRect().size()) { // When the viewport size changes or the content is scaled, we need to - // reposition the fixed positioned elements. - if (RenderView* root = rootRenderer(this)) - root->setFixedPositionedObjectsNeedLayout(); + // reposition the fixed and sticky positioned elements. + setViewportConstrainedObjectsNeedLayout(); visibleContentSizeDidChange = true; } @@ -1775,6 +1794,19 @@ void FrameView::setFixedVisibleContentRect(const IntRect& visibleContentRect) frame()->loader()->client()->didChangeScrollOffset(); } +void FrameView::setViewportConstrainedObjectsNeedLayout() +{ + if (!hasViewportConstrainedObjects()) + return; + + ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObjects->end(); + for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrainedObjects->begin(); it != end; ++it) { + RenderObject* renderer = *it; + renderer->setNeedsLayout(true); + } +} + + void FrameView::scrollPositionChangedViaPlatformWidget() { repaintFixedElementsAfterScrolling(); @@ -1799,7 +1831,7 @@ void FrameView::repaintFixedElementsAfterScrolling() { // For fixed position elements, update widget positions and compositing layers after scrolling, // but only if we're not inside of layout. - if (!m_nestedLayoutCount && hasFixedObjects()) { + if (!m_nestedLayoutCount && hasViewportConstrainedObjects()) { if (RenderView* root = rootRenderer(this)) { root->updateWidgetPositions(); root->layer()->updateLayerPositionsAfterScroll(); @@ -1810,7 +1842,7 @@ void FrameView::repaintFixedElementsAfterScrolling() void FrameView::updateFixedElementsAfterScrolling() { #if USE(ACCELERATED_COMPOSITING) - if (m_nestedLayoutCount <= 1 && hasFixedObjects()) { + if (m_nestedLayoutCount <= 1 && hasViewportConstrainedObjects()) { if (RenderView* root = rootRenderer(this)) { root->compositor()->updateCompositingLayers(CompositingUpdateOnScroll); } @@ -1970,25 +2002,22 @@ void FrameView::startDeferredRepaintTimer(double delay) m_deferredRepaintTimer.startOneShot(delay); } -void FrameView::checkStopDelayingDeferredRepaints() +void FrameView::checkFlushDeferredRepaintsAfterLoadComplete() { - Document* document = m_frame->document(); - if (document && (document->parsing() || document->cachedResourceLoader()->requestCount())) + if (shouldUseLoadTimeDeferredRepaintDelay()) return; - - stopDelayingDeferredRepaints(); + m_deferredRepaintDelay = s_normalDeferredRepaintDelay; + flushDeferredRepaints(); } - -void FrameView::stopDelayingDeferredRepaints() + +void FrameView::flushDeferredRepaints() { if (!m_deferredRepaintTimer.isActive()) return; - m_deferredRepaintTimer.stop(); - doDeferredRepaints(); } - + void FrameView::doDeferredRepaints() { if (m_disableRepaints) @@ -2013,21 +2042,32 @@ void FrameView::doDeferredRepaints() m_repaintRects.clear(); m_repaintCount = 0; - updateDeferredRepaintDelay(); + updateDeferredRepaintDelayAfterRepaint(); } -void FrameView::updateDeferredRepaintDelay() +bool FrameView::shouldUseLoadTimeDeferredRepaintDelay() const { + // Don't defer after the initial load of the page has been completed. + if (m_frame->tree()->top()->loader()->isComplete()) + return false; Document* document = m_frame->document(); - if (!document || (!document->parsing() && !document->cachedResourceLoader()->requestCount())) { - m_deferredRepaintDelay = s_deferredRepaintDelay; + if (!document) + return false; + if (document->parsing()) + return true; + if (document->cachedResourceLoader()->requestCount()) + return true; + return false; +} + +void FrameView::updateDeferredRepaintDelayAfterRepaint() +{ + if (!shouldUseLoadTimeDeferredRepaintDelay()) { + m_deferredRepaintDelay = s_normalDeferredRepaintDelay; return; } - if (m_deferredRepaintDelay < s_maxDeferredRepaintDelayDuringLoading) { - m_deferredRepaintDelay += s_deferredRepaintDelayIncrementDuringLoading; - if (m_deferredRepaintDelay > s_maxDeferredRepaintDelayDuringLoading) - m_deferredRepaintDelay = s_maxDeferredRepaintDelayDuringLoading; - } + double incrementedRepaintDelay = m_deferredRepaintDelay + s_deferredRepaintDelayIncrementDuringLoading; + m_deferredRepaintDelay = std::min(incrementedRepaintDelay, s_maxDeferredRepaintDelayDuringLoading); } void FrameView::resetDeferredRepaintDelay() @@ -2090,7 +2130,7 @@ void FrameView::scheduleRelayout() return; if (!m_frame->document()->shouldScheduleLayout()) return; - + InspectorInstrumentation::didInvalidateLayout(m_frame.get()); // When frame flattening is enabled, the contents of the frame could affect the layout of the parent frames. // Also invalidate parent frame starting from the owner element of this frame. if (m_frame->ownerRenderer() && isInChildFrameWithFrameFlattening()) @@ -2152,6 +2192,7 @@ void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot) } } } else if (m_layoutSchedulingEnabled) { + InspectorInstrumentation::didInvalidateLayout(m_frame.get()); int delay = m_frame->document()->minimumLayoutDelay(); m_layoutRoot = relayoutRoot; ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout()); @@ -2300,7 +2341,7 @@ void FrameView::scrollToAnchor() LayoutRect rect; if (anchorNode != m_frame->document()) - rect = anchorNode->getRect(); + rect = anchorNode->boundingBox(); // Scroll nested layers and frames to reveal the anchor. // Align to the top and to the closest side (this matches other browsers). @@ -3112,9 +3153,6 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect) p->fillRect(rect, Color(0xFF, 0, 0), ColorSpaceDeviceRGB); #endif - if (pagination().mode != Pagination::Unpaginated) - p->fillRect(rect, baseBackgroundColor(), ColorSpaceDeviceRGB); - bool isTopLevelPainter = !sCurrentPaintTimeStamp; if (isTopLevelPainter) sCurrentPaintTimeStamp = currentTime(); @@ -3294,14 +3332,6 @@ void FrameView::updateLayoutAndStyleIfNeededRecursive() // This assert ensures that parent frames are clean, when child frames finished updating layout and style. ASSERT(!needsLayout()); } - -void FrameView::flushDeferredRepaints() -{ - if (!m_deferredRepaintTimer.isActive()) - return; - m_deferredRepaintTimer.stop(); - doDeferredRepaints(); -} void FrameView::enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize) { @@ -3551,7 +3581,7 @@ IntPoint FrameView::convertFromContainingView(const IntPoint& parentPoint) const // Normal delay void FrameView::setRepaintThrottlingDeferredRepaintDelay(double p) { - s_deferredRepaintDelay = p; + s_normalDeferredRepaintDelay = p; } // Negative value would mean that first few repaints happen without a delay diff --git a/Source/WebCore/page/FrameView.h b/Source/WebCore/page/FrameView.h index 7e73150b8..0756c4978 100644 --- a/Source/WebCore/page/FrameView.h +++ b/Source/WebCore/page/FrameView.h @@ -197,11 +197,12 @@ public: void removeSlowRepaintObject(); bool hasSlowRepaintObjects() const { return m_slowRepaintObjectCount; } - typedef HashSet<RenderObject*> FixedObjectSet; - void addFixedObject(RenderObject*); - void removeFixedObject(RenderObject*); - const FixedObjectSet* fixedObjects() const { return m_fixedObjects.get(); } - bool hasFixedObjects() const { return m_fixedObjects && m_fixedObjects->size() > 0; } + // Includes fixed- and sticky-position objects. + typedef HashSet<RenderObject*> ViewportConstrainedObjectSet; + void addViewportConstrainedObject(RenderObject*); + void removeViewportConstrainedObject(RenderObject*); + const ViewportConstrainedObjectSet* viewportConstrainedObjects() const { return m_viewportConstrainedObjects.get(); } + bool hasViewportConstrainedObjects() const { return m_viewportConstrainedObjects && m_viewportConstrainedObjects->size() > 0; } // Functions for querying the current scrolled position, negating the effects of overhang // and adjusting for page scale. @@ -211,8 +212,8 @@ public: void beginDeferredRepaints(); void endDeferredRepaints(); - void checkStopDelayingDeferredRepaints(); - void stopDelayingDeferredRepaints(); + void checkFlushDeferredRepaintsAfterLoadComplete(); + void flushDeferredRepaints(); void startDeferredRepaintTimer(double delay); void resetDeferredRepaintDelay(); @@ -264,7 +265,6 @@ public: static double currentPaintTimeStamp() { return sCurrentPaintTimeStamp; } // returns 0 if not painting void updateLayoutAndStyleIfNeededRecursive(); - void flushDeferredRepaints(); void incrementVisuallyNonEmptyCharacterCount(unsigned); void incrementVisuallyNonEmptyPixelCount(const IntSize&); @@ -381,6 +381,7 @@ private: bool contentsInCompositedLayer() const; void applyOverflowToViewport(RenderObject*, ScrollbarMode& hMode, ScrollbarMode& vMode); + void applyPaginationToViewport(); void updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow); @@ -426,9 +427,10 @@ private: virtual void notifyPageThatContentAreaWillPaint() const; + bool shouldUseLoadTimeDeferredRepaintDelay() const; void deferredRepaintTimerFired(Timer<FrameView>*); void doDeferredRepaints(); - void updateDeferredRepaintDelay(); + void updateDeferredRepaintDelayAfterRepaint(); double adjustedDeferredRepaintDelay() const; bool updateWidgets(); @@ -444,6 +446,8 @@ private: bool doLayoutWithFrameFlattening(bool allowSubtree); + void setViewportConstrainedObjectsNeedLayout(); + virtual AXObjectCache* axObjectCache() const; void notifyWidgetsInAllFrames(WidgetNotification); @@ -542,9 +546,9 @@ private: IntSize m_maxAutoSize; OwnPtr<ScrollableAreaSet> m_scrollableAreas; - OwnPtr<FixedObjectSet> m_fixedObjects; + OwnPtr<ViewportConstrainedObjectSet> m_viewportConstrainedObjects; - static double s_deferredRepaintDelay; + static double s_normalDeferredRepaintDelay; static double s_initialDeferredRepaintDelayDuringLoading; static double s_maxDeferredRepaintDelayDuringLoading; static double s_deferredRepaintDelayIncrementDuringLoading; diff --git a/Source/WebCore/page/GroupSettings.h b/Source/WebCore/page/GroupSettings.h index 1bbad2b55..603d06a01 100644 --- a/Source/WebCore/page/GroupSettings.h +++ b/Source/WebCore/page/GroupSettings.h @@ -26,8 +26,8 @@ #ifndef GroupSettings_h #define GroupSettings_h -#include "PlatformString.h" #include <wtf/PassOwnPtr.h> +#include <wtf/text/WTFString.h> namespace WebCore { diff --git a/Source/WebCore/page/History.idl b/Source/WebCore/page/History.idl index 6e8f6ab06..2c7d7998c 100644 --- a/Source/WebCore/page/History.idl +++ b/Source/WebCore/page/History.idl @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ module window { @@ -42,10 +42,10 @@ module window { [DoNotCheckSecurity, CallWith=ScriptExecutionContext] void back(); [DoNotCheckSecurity, CallWith=ScriptExecutionContext] void forward(); [DoNotCheckSecurity, CallWith=ScriptExecutionContext] void go(in [Optional=DefaultIsUndefined] long distance); - - [Custom, V8EnabledAtRuntime] void pushState(in any data, in DOMString title, in [Optional] DOMString url) + + [Custom] void pushState(in any data, in DOMString title, in [Optional] DOMString url) raises(DOMException); - [Custom, V8EnabledAtRuntime] void replaceState(in any data, in DOMString title, in [Optional] DOMString url) + [Custom] void replaceState(in any data, in DOMString title, in [Optional] DOMString url) raises(DOMException); }; diff --git a/Source/WebCore/page/NavigatorBase.cpp b/Source/WebCore/page/NavigatorBase.cpp index 83b859af6..7febae4e5 100644 --- a/Source/WebCore/page/NavigatorBase.cpp +++ b/Source/WebCore/page/NavigatorBase.cpp @@ -28,7 +28,8 @@ #include "NavigatorBase.h" #include "NetworkStateNotifier.h" -#include "PlatformString.h" +#include <wtf/text/WTFString.h> + #if OS(LINUX) #include "sys/utsname.h" #include <wtf/StdLibExtras.h> diff --git a/Source/WebCore/page/OriginAccessEntry.h b/Source/WebCore/page/OriginAccessEntry.h index 67e39fe14..183600bde 100644 --- a/Source/WebCore/page/OriginAccessEntry.h +++ b/Source/WebCore/page/OriginAccessEntry.h @@ -31,7 +31,7 @@ #ifndef OriginAccessEntry_h #define OriginAccessEntry_h -#include "PlatformString.h" +#include <wtf/text/WTFString.h> namespace WebCore { diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp index 8c70f7854..2983808ea 100644 --- a/Source/WebCore/page/Page.cpp +++ b/Source/WebCore/page/Page.cpp @@ -392,6 +392,7 @@ void Page::setGroupName(const String& name) const String& Page::groupName() const { DEFINE_STATIC_LOCAL(String, nullString, ()); + // FIXME: Why not just return String()? return m_group ? m_group->name() : nullString; } @@ -836,7 +837,7 @@ const String& Page::userStyleSheet() const RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("text/css"); m_userStyleSheet = decoder->decode(data->data(), data->size()); - m_userStyleSheet += decoder->flush(); + m_userStyleSheet.append(decoder->flush()); return m_userStyleSheet; } diff --git a/Source/WebCore/page/Page.h b/Source/WebCore/page/Page.h index 2ba722acc..a218d5d4c 100644 --- a/Source/WebCore/page/Page.h +++ b/Source/WebCore/page/Page.h @@ -27,7 +27,6 @@ #include "PageVisibilityState.h" #include "Pagination.h" #include "PlatformScreen.h" -#include "PlatformString.h" #include "Region.h" #include "Supplementable.h" #include "ViewportArguments.h" @@ -35,6 +34,7 @@ #include <wtf/HashMap.h> #include <wtf/HashSet.h> #include <wtf/Noncopyable.h> +#include <wtf/text/WTFString.h> #if OS(SOLARIS) #include <sys/time.h> // For time_t structure. diff --git a/Source/WebCore/page/PageVisibilityState.cpp b/Source/WebCore/page/PageVisibilityState.cpp index de1196e83..d9f774e79 100644 --- a/Source/WebCore/page/PageVisibilityState.cpp +++ b/Source/WebCore/page/PageVisibilityState.cpp @@ -37,10 +37,10 @@ namespace WebCore { String pageVisibilityStateString(PageVisibilityState state) { - DEFINE_STATIC_LOCAL(const String, visible, ("visible")); - DEFINE_STATIC_LOCAL(const String, hidden, ("hidden")); - DEFINE_STATIC_LOCAL(const String, prerender, ("prerender")); - DEFINE_STATIC_LOCAL(const String, preview, ("preview")); + DEFINE_STATIC_LOCAL(const String, visible, (ASCIILiteral("visible"))); + DEFINE_STATIC_LOCAL(const String, hidden, (ASCIILiteral("hidden"))); + DEFINE_STATIC_LOCAL(const String, prerender, (ASCIILiteral("prerender"))); + DEFINE_STATIC_LOCAL(const String, preview, (ASCIILiteral("preview"))); switch (state) { case PageVisibilityStateVisible: diff --git a/Source/WebCore/page/PointerLockController.cpp b/Source/WebCore/page/PointerLockController.cpp index ad7960962..ddbb84fd0 100644 --- a/Source/WebCore/page/PointerLockController.cpp +++ b/Source/WebCore/page/PointerLockController.cpp @@ -62,6 +62,7 @@ void PointerLockController::requestPointerLock(Element* target) enqueueEvent(eventNames().webkitpointerlockchangeEvent, target); m_element = target; } else if (m_page->chrome()->client()->requestPointerLock()) { + m_lockPending = true; m_element = target; } else { enqueueEvent(eventNames().webkitpointerlockerrorEvent, target); @@ -79,7 +80,7 @@ void PointerLockController::elementRemoved(Element* element) m_documentOfRemovedElementWhileWaitingForUnlock = m_element->document(); // Set element null immediately to block any future interaction with it // including mouse events received before the unlock completes. - m_element = 0; + clearElement(); requestPointerUnlock(); } } @@ -87,11 +88,16 @@ void PointerLockController::elementRemoved(Element* element) void PointerLockController::documentDetached(Document* document) { if (m_element && m_element->document() == document) { - m_element = 0; + clearElement(); requestPointerUnlock(); } } +bool PointerLockController::lockPending() const +{ + return m_lockPending; +} + Element* PointerLockController::element() const { return m_element.get(); @@ -100,18 +106,19 @@ Element* PointerLockController::element() const void PointerLockController::didAcquirePointerLock() { enqueueEvent(eventNames().webkitpointerlockchangeEvent, m_element.get()); + m_lockPending = false; } void PointerLockController::didNotAcquirePointerLock() { enqueueEvent(eventNames().webkitpointerlockerrorEvent, m_element.get()); - m_element = 0; + clearElement(); } void PointerLockController::didLosePointerLock() { enqueueEvent(eventNames().webkitpointerlockchangeEvent, m_element ? m_element->document() : m_documentOfRemovedElementWhileWaitingForUnlock.get()); - m_element = 0; + clearElement(); m_documentOfRemovedElementWhileWaitingForUnlock = 0; } @@ -127,6 +134,12 @@ void PointerLockController::dispatchLockedMouseEvent(const PlatformMouseEvent& e m_element->dispatchMouseEvent(event, eventNames().clickEvent, event.clickCount()); } +void PointerLockController::clearElement() +{ + m_lockPending = false; + m_element = 0; +} + void PointerLockController::enqueueEvent(const AtomicString& type, Element* element) { if (element) diff --git a/Source/WebCore/page/PointerLockController.h b/Source/WebCore/page/PointerLockController.h index a942f9368..c820754ae 100644 --- a/Source/WebCore/page/PointerLockController.h +++ b/Source/WebCore/page/PointerLockController.h @@ -48,6 +48,7 @@ public: void requestPointerUnlock(); void elementRemoved(Element*); void documentDetached(Document*); + bool lockPending() const; Element* element() const; void didAcquirePointerLock(); @@ -57,9 +58,11 @@ public: private: explicit PointerLockController(Page*); + void clearElement(); void enqueueEvent(const AtomicString& type, Element*); void enqueueEvent(const AtomicString& type, Document*); Page* m_page; + bool m_lockPending; RefPtr<Element> m_element; RefPtr<Document> m_documentOfRemovedElementWhileWaitingForUnlock; }; diff --git a/Source/WebCore/page/SecurityOrigin.cpp b/Source/WebCore/page/SecurityOrigin.cpp index f5cd1c52e..da15021bd 100644 --- a/Source/WebCore/page/SecurityOrigin.cpp +++ b/Source/WebCore/page/SecurityOrigin.cpp @@ -53,18 +53,7 @@ static bool schemeRequiresAuthority(const KURL& url) return url.protocolIsInHTTPFamily() || url.protocolIs("ftp"); } -// Some URL schemes use nested URLs for their security context. For example, -// filesystem URLs look like the following: -// -// filesystem:http://example.com/temporary/path/to/file.png -// -// We're supposed to use "http://example.com" as the origin. -// -// Generally, we add URL schemes to this list when WebKit support them. For -// example, we don't include the "jar" scheme, even though Firefox understands -// that jar uses an inner URL for it's security origin. -// -static bool shouldUseInnerURL(const KURL& url) +bool SecurityOrigin::shouldUseInnerURL(const KURL& url) { #if ENABLE(BLOB) if (url.protocolIs("blob")) @@ -81,7 +70,7 @@ static bool shouldUseInnerURL(const KURL& url) // In general, extracting the inner URL varies by scheme. It just so happens // that all the URL schemes we currently support that use inner URLs for their // security origin can be parsed using this algorithm. -static KURL extractInnerURL(const KURL& url) +KURL SecurityOrigin::extractInnerURL(const KURL& url) { if (url.innerURL()) return *url.innerURL(); @@ -105,7 +94,7 @@ static bool shouldTreatAsUniqueOrigin(const KURL& url) return true; // FIXME: Do we need to unwrap the URL further? - KURL innerURL = shouldUseInnerURL(url) ? extractInnerURL(url) : url; + KURL innerURL = SecurityOrigin::shouldUseInnerURL(url) ? SecurityOrigin::extractInnerURL(url) : url; // FIXME: Check whether innerURL is valid. @@ -133,7 +122,7 @@ SecurityOrigin::SecurityOrigin(const KURL& url) , m_isUnique(false) , m_universalAccess(false) , m_domainWasSetInDOM(false) - , m_blockThirdPartyStorage(false) + , m_storageBlockingPolicy(AllowAllStorage) , m_enforceFilePathSeparation(false) , m_needsDatabaseIdentifierQuirkForFiles(false) { @@ -159,7 +148,7 @@ SecurityOrigin::SecurityOrigin() , m_universalAccess(false) , m_domainWasSetInDOM(false) , m_canLoadLocalResources(false) - , m_blockThirdPartyStorage(false) + , m_storageBlockingPolicy(AllowAllStorage) , m_enforceFilePathSeparation(false) , m_needsDatabaseIdentifierQuirkForFiles(false) { @@ -176,7 +165,7 @@ SecurityOrigin::SecurityOrigin(const SecurityOrigin* other) , m_universalAccess(other->m_universalAccess) , m_domainWasSetInDOM(other->m_domainWasSetInDOM) , m_canLoadLocalResources(other->m_canLoadLocalResources) - , m_blockThirdPartyStorage(other->m_blockThirdPartyStorage) + , m_storageBlockingPolicy(other->m_storageBlockingPolicy) , m_enforceFilePathSeparation(other->m_enforceFilePathSeparation) , m_needsDatabaseIdentifierQuirkForFiles(other->m_needsDatabaseIdentifierQuirkForFiles) { @@ -400,7 +389,10 @@ bool SecurityOrigin::canAccessStorage(const SecurityOrigin* topOrigin) const if (!topOrigin) return true; - if ((m_blockThirdPartyStorage || topOrigin->m_blockThirdPartyStorage) && topOrigin->isThirdParty(this)) + if (m_storageBlockingPolicy == BlockAllStorage || topOrigin->m_storageBlockingPolicy == BlockAllStorage) + return false; + + if ((m_storageBlockingPolicy == BlockThirdPartyStorage || topOrigin->m_storageBlockingPolicy == BlockThirdPartyStorage) && topOrigin->isThirdParty(this)) return false; return true; @@ -480,8 +472,8 @@ String SecurityOrigin::toRawString() const result.append(m_host); if (m_port) { - result.append(":"); - result.append(String::number(m_port)); + result.append(':'); + result.appendNumber(m_port); } return result.toString(); diff --git a/Source/WebCore/page/SecurityOrigin.h b/Source/WebCore/page/SecurityOrigin.h index 2e32cfb69..e8120eda0 100644 --- a/Source/WebCore/page/SecurityOrigin.h +++ b/Source/WebCore/page/SecurityOrigin.h @@ -29,8 +29,8 @@ #ifndef SecurityOrigin_h #define SecurityOrigin_h -#include "PlatformString.h" #include <wtf/ThreadSafeRefCounted.h> +#include <wtf/text/WTFString.h> namespace WebCore { @@ -45,6 +45,12 @@ public: Ask }; + enum StorageBlockingPolicy { + AllowAllStorage = 0, + BlockThirdPartyStorage, + BlockAllStorage + }; + static PassRefPtr<SecurityOrigin> create(const KURL&); static PassRefPtr<SecurityOrigin> createUnique(); @@ -52,6 +58,19 @@ public: static PassRefPtr<SecurityOrigin> createFromString(const String&); static PassRefPtr<SecurityOrigin> create(const String& protocol, const String& host, int port); + // Some URL schemes use nested URLs for their security context. For example, + // filesystem URLs look like the following: + // + // filesystem:http://example.com/temporary/path/to/file.png + // + // We're supposed to use "http://example.com" as the origin. + // + // Generally, we add URL schemes to this list when WebKit support them. For + // example, we don't include the "jar" scheme, even though Firefox + // understands that "jar" uses an inner URL for it's security origin. + static bool shouldUseInnerURL(const KURL&); + static KURL extractInnerURL(const KURL&); + // Create a deep copy of this SecurityOrigin. This method is useful // when marshalling a SecurityOrigin to another thread. PassRefPtr<SecurityOrigin> isolatedCopy() const; @@ -121,10 +140,12 @@ public: // WARNING: This is an extremely powerful ability. Use with caution! void grantUniversalAccess(); - void blockThirdPartyStorage() { m_blockThirdPartyStorage = true; } + void setStorageBlockingPolicy(StorageBlockingPolicy policy) { m_storageBlockingPolicy = policy; } bool canAccessDatabase(const SecurityOrigin* topOrigin = 0) const { return canAccessStorage(topOrigin); }; bool canAccessLocalStorage(const SecurityOrigin* topOrigin) const { return canAccessStorage(topOrigin); }; + bool canAccessSharedWorkers(const SecurityOrigin* topOrigin) const { return canAccessStorage(topOrigin); } + bool canAccessPluginStorage(const SecurityOrigin* topOrigin) const { return canAccessStorage(topOrigin); } bool canAccessCookies() const { return !isUnique(); } bool canAccessPasswordManager() const { return !isUnique(); } bool canAccessFileSystem() const { return !isUnique(); } @@ -204,7 +225,7 @@ private: bool m_universalAccess; bool m_domainWasSetInDOM; bool m_canLoadLocalResources; - bool m_blockThirdPartyStorage; + StorageBlockingPolicy m_storageBlockingPolicy; bool m_enforceFilePathSeparation; bool m_needsDatabaseIdentifierQuirkForFiles; }; diff --git a/Source/WebCore/page/Settings.cpp b/Source/WebCore/page/Settings.cpp index e97c64f73..f25150b51 100644 --- a/Source/WebCore/page/Settings.cpp +++ b/Source/WebCore/page/Settings.cpp @@ -138,6 +138,7 @@ Settings::Settings(Page* page) , m_sessionStorageQuota(StorageMap::noQuota) , m_editingBehaviorType(editingBehaviorTypeForPlatform()) , m_maximumHTMLParserDOMTreeDepth(defaultMaximumHTMLParserDOMTreeDepth) + , m_storageBlockingPolicy(SecurityOrigin::AllowAllStorage) #if ENABLE(TEXT_AUTOSIZING) , m_textAutosizingFontScaleFactor(1) #if HACK_FORCE_TEXT_AUTOSIZING_ON_DESKTOP @@ -284,7 +285,6 @@ Settings::Settings(Page* page) , m_cookieEnabled(true) , m_windowFocusRestricted(true) , m_diagnosticLoggingEnabled(false) - , m_thirdPartyStorageBlockingEnabled(false) , m_scrollingPerformanceLoggingEnabled(false) , m_loadsImagesAutomaticallyTimer(this, &Settings::loadsImagesAutomaticallyTimerFired) , m_incrementalRenderingSuppressionTimeoutInSeconds(defaultIncrementalRenderingSuppressionTimeoutInSeconds) diff --git a/Source/WebCore/page/Settings.h b/Source/WebCore/page/Settings.h index fd4d9a992..6fa3bc024 100644 --- a/Source/WebCore/page/Settings.h +++ b/Source/WebCore/page/Settings.h @@ -30,6 +30,7 @@ #include "EditingBehaviorTypes.h" #include "FontRenderingMode.h" #include "KURL.h" +#include "SecurityOrigin.h" #include "Timer.h" #include <wtf/HashMap.h> #include <wtf/text/AtomicString.h> @@ -601,8 +602,8 @@ namespace WebCore { void setWindowFocusRestricted(bool restricted) { m_windowFocusRestricted = restricted; } bool windowFocusRestricted() const { return m_windowFocusRestricted; } - void setThirdPartyStorageBlockingEnabled(bool enabled) { m_thirdPartyStorageBlockingEnabled = enabled; } - bool thirdPartyStorageBlockingEnabled() const { return m_thirdPartyStorageBlockingEnabled; } + void setStorageBlockingPolicy(SecurityOrigin::StorageBlockingPolicy policy) { m_storageBlockingPolicy = policy; } + SecurityOrigin::StorageBlockingPolicy storageBlockingPolicy() const { return m_storageBlockingPolicy; } void setScrollingPerformanceLoggingEnabled(bool); bool scrollingPerformanceLoggingEnabled() { return m_scrollingPerformanceLoggingEnabled; } @@ -652,6 +653,7 @@ namespace WebCore { unsigned m_sessionStorageQuota; unsigned m_editingBehaviorType; unsigned m_maximumHTMLParserDOMTreeDepth; + SecurityOrigin::StorageBlockingPolicy m_storageBlockingPolicy; #if ENABLE(TEXT_AUTOSIZING) float m_textAutosizingFontScaleFactor; IntSize m_textAutosizingWindowSizeOverride; @@ -795,8 +797,6 @@ namespace WebCore { bool m_diagnosticLoggingEnabled : 1; - bool m_thirdPartyStorageBlockingEnabled : 1; - bool m_scrollingPerformanceLoggingEnabled : 1; Timer<Settings> m_loadsImagesAutomaticallyTimer; diff --git a/Source/WebCore/page/SpatialNavigation.cpp b/Source/WebCore/page/SpatialNavigation.cpp index 4150b64f3..a9a11e368 100644 --- a/Source/WebCore/page/SpatialNavigation.cpp +++ b/Source/WebCore/page/SpatialNavigation.cpp @@ -522,7 +522,7 @@ LayoutRect nodeRectInAbsoluteCoordinates(Node* node, bool ignoreBorder) if (node->isDocumentNode()) return frameRectInAbsoluteCoordinates(static_cast<Document*>(node)->frame()); - LayoutRect rect = rectToAbsoluteCoordinates(node->document()->frame(), node->getRect()); + LayoutRect rect = rectToAbsoluteCoordinates(node->document()->frame(), node->boundingBox()); // For authors that use border instead of outline in their CSS, we compensate by ignoring the border when calculating // the rect of the focused element. diff --git a/Source/WebCore/page/SpeechInputResult.h b/Source/WebCore/page/SpeechInputResult.h index 457f07835..895f122cb 100644 --- a/Source/WebCore/page/SpeechInputResult.h +++ b/Source/WebCore/page/SpeechInputResult.h @@ -28,9 +28,9 @@ #if ENABLE(INPUT_SPEECH) -#include "PlatformString.h" #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> +#include <wtf/text/WTFString.h> namespace WebCore { diff --git a/Source/WebCore/page/TouchDisambiguation.cpp b/Source/WebCore/page/TouchDisambiguation.cpp new file mode 100644 index 000000000..215bc1cb0 --- /dev/null +++ b/Source/WebCore/page/TouchDisambiguation.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include "TouchDisambiguation.h" + +#include "Document.h" +#include "Element.h" +#include "Frame.h" +#include "FrameView.h" +#include "HTMLNames.h" +#include "HitTestResult.h" +#include <algorithm> +#include <cmath> + +using namespace std; + +namespace WebCore { + +static IntRect boundingBoxForEventNodes(Node* eventNode) +{ + if (!eventNode->document()->view()) + return IntRect(); + + IntRect result; + Node* node = eventNode; + while (node) { + // Skip the whole sub-tree if the node doesn't propagate events. + if (node != eventNode && node->willRespondToMouseClickEvents()) { + node = node->traverseNextSibling(eventNode); + continue; + } + result.unite(node->pixelSnappedBoundingBox()); + node = node->traverseNextNode(eventNode); + } + return eventNode->document()->view()->contentsToWindow(result); +} + +static float scoreTouchTarget(IntPoint touchPoint, int padding, IntRect boundingBox) +{ + if (boundingBox.isEmpty()) + return 0; + + float reciprocalPadding = 1.f / padding; + float score = 1; + + IntSize distance = boundingBox.differenceToPoint(touchPoint); + score *= max((padding - abs(distance.width())) * reciprocalPadding, 0.f); + score *= max((padding - abs(distance.height())) * reciprocalPadding, 0.f); + + return score; +} + +struct TouchTargetData { + IntRect windowBoundingBox; + float score; +}; + +void findGoodTouchTargets(const IntRect& touchBox, Frame* mainFrame, float pageScaleFactor, Vector<IntRect>& goodTargets) +{ + goodTargets.clear(); + + int touchPointPadding = ceil(max(touchBox.width(), touchBox.height()) * 0.5); + // FIXME: Rect-based hit test doesn't transform the touch point size. + // We have to pre-apply page scale factor here. + int padding = ceil(touchPointPadding / pageScaleFactor); + + IntPoint touchPoint = touchBox.center(); + IntPoint contentsPoint = mainFrame->view()->windowToContents(touchPoint); + + HitTestResult result = mainFrame->eventHandler()->hitTestResultAtPoint(contentsPoint, HitTestRequest::ReadOnly | HitTestRequest::Active, IntSize(padding, padding)); + const ListHashSet<RefPtr<Node> >& hitResults = result.rectBasedTestResult(); + + HashMap<Node*, TouchTargetData> touchTargets; + float bestScore = 0; + for (ListHashSet<RefPtr<Node> >::const_iterator it = hitResults.begin(); it != hitResults.end(); ++it) { + for (Node* node = it->get(); node; node = node->parentNode()) { + if (node->isDocumentNode() || node->hasTagName(HTMLNames::htmlTag) || node->hasTagName(HTMLNames::bodyTag)) + break; + if (node->willRespondToMouseClickEvents()) { + TouchTargetData& targetData = touchTargets.add(node, TouchTargetData()).iterator->second; + targetData.windowBoundingBox = boundingBoxForEventNodes(node); + targetData.score = scoreTouchTarget(touchPoint, touchPointPadding, targetData.windowBoundingBox); + bestScore = max(bestScore, targetData.score); + break; + } + } + } + + for (HashMap<Node*, TouchTargetData>::iterator it = touchTargets.begin(); it != touchTargets.end(); ++it) { + // Currently the scoring function uses the overlap area with the fat point as the score. + // We ignore the candidates that has less than 1/2 overlap (we consider not really ambiguous enough) than the best candidate to avoid excessive popups. + if (it->second.score < bestScore * 0.5) + continue; + goodTargets.append(it->second.windowBoundingBox); + } +} + +} // namespace WebCore diff --git a/Source/WebCore/page/TouchDisambiguation.h b/Source/WebCore/page/TouchDisambiguation.h new file mode 100644 index 000000000..5afeb6b5b --- /dev/null +++ b/Source/WebCore/page/TouchDisambiguation.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TouchDisambiguation_h +#define TouchDisambiguation_h + +#include <wtf/Vector.h> + +namespace WebCore { + +class Frame; +class IntRect; + +void findGoodTouchTargets(const IntRect& touchBox, Frame* mainFrame, float pageScaleFactor, Vector<IntRect>& goodTargets); + +} // namespace WebCore + +#endif diff --git a/Source/WebCore/page/UserContentURLPattern.cpp b/Source/WebCore/page/UserContentURLPattern.cpp index 272284a5a..676b65573 100644 --- a/Source/WebCore/page/UserContentURLPattern.cpp +++ b/Source/WebCore/page/UserContentURLPattern.cpp @@ -61,7 +61,7 @@ bool UserContentURLPattern::matchesPatterns(const KURL& url, const Vector<String bool UserContentURLPattern::parse(const String& pattern) { - DEFINE_STATIC_LOCAL(const String, schemeSeparator, ("://")); + DEFINE_STATIC_LOCAL(const String, schemeSeparator, (ASCIILiteral("://"))); size_t schemeEndPos = pattern.find(schemeSeparator); if (schemeEndPos == notFound) diff --git a/Source/WebCore/page/UserContentURLPattern.h b/Source/WebCore/page/UserContentURLPattern.h index 3450ed178..51d9fee33 100644 --- a/Source/WebCore/page/UserContentURLPattern.h +++ b/Source/WebCore/page/UserContentURLPattern.h @@ -26,8 +26,8 @@ #ifndef UserContentURLPattern_h #define UserContentURLPattern_h -#include "PlatformString.h" #include <wtf/Vector.h> +#include <wtf/text/WTFString.h> namespace WebCore { diff --git a/Source/WebCore/page/WindowFeatures.cpp b/Source/WebCore/page/WindowFeatures.cpp index 75641528d..6cde9b5ef 100644 --- a/Source/WebCore/page/WindowFeatures.cpp +++ b/Source/WebCore/page/WindowFeatures.cpp @@ -24,7 +24,6 @@ #include "WindowFeatures.h" #include "FloatRect.h" -#include "PlatformString.h" #include <wtf/Assertions.h> #include <wtf/MathExtras.h> #include <wtf/text/StringHash.h> diff --git a/Source/WebCore/page/WindowFeatures.h b/Source/WebCore/page/WindowFeatures.h index 7449d850e..204b7f8f4 100644 --- a/Source/WebCore/page/WindowFeatures.h +++ b/Source/WebCore/page/WindowFeatures.h @@ -29,8 +29,8 @@ #ifndef WindowFeatures_h #define WindowFeatures_h -#include "PlatformString.h" #include <wtf/HashMap.h> +#include <wtf/text/WTFString.h> namespace WebCore { diff --git a/Source/WebCore/page/WorkerNavigator.h b/Source/WebCore/page/WorkerNavigator.h index 4622b741b..a01c44ccb 100644 --- a/Source/WebCore/page/WorkerNavigator.h +++ b/Source/WebCore/page/WorkerNavigator.h @@ -29,10 +29,10 @@ #if ENABLE(WORKERS) #include "NavigatorBase.h" -#include "PlatformString.h" #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> +#include <wtf/text/WTFString.h> namespace WebCore { diff --git a/Source/WebCore/page/animation/AnimationControllerPrivate.h b/Source/WebCore/page/animation/AnimationControllerPrivate.h index 9a336cd32..ec76f1c98 100644 --- a/Source/WebCore/page/animation/AnimationControllerPrivate.h +++ b/Source/WebCore/page/animation/AnimationControllerPrivate.h @@ -30,7 +30,6 @@ #define AnimationControllerPrivate_h #include "CSSPropertyNames.h" -#include "PlatformString.h" #include "Timer.h" #include <wtf/HashMap.h> #include <wtf/HashSet.h> @@ -38,6 +37,7 @@ #include <wtf/RefPtr.h> #include <wtf/Vector.h> #include <wtf/text/AtomicString.h> +#include <wtf/text/WTFString.h> namespace WebCore { diff --git a/Source/WebCore/page/animation/CSSPropertyAnimation.cpp b/Source/WebCore/page/animation/CSSPropertyAnimation.cpp index f2a81cb0c..f442755a0 100644 --- a/Source/WebCore/page/animation/CSSPropertyAnimation.cpp +++ b/Source/WebCore/page/animation/CSSPropertyAnimation.cpp @@ -901,7 +901,6 @@ private: Vector<AnimationPropertyWrapperBase*> m_propertyWrappers; }; -#if ENABLE(CSS3_FLEXBOX) class PropertyWrapperFlex : public AnimationPropertyWrapperBase { public: PropertyWrapperFlex() : AnimationPropertyWrapperBase(CSSPropertyWebkitFlex) @@ -927,7 +926,6 @@ public: dst->setFlexShrink(blendFunc(anim, a->flexShrink(), b->flexShrink(), progress)); } }; -#endif #if ENABLE(SVG) class PropertyWrapperSVGPaint : public AnimationPropertyWrapperBase { @@ -1046,9 +1044,7 @@ void CSSPropertyAnimation::ensurePropertyMap() gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMinHeight, &RenderStyle::minHeight, &RenderStyle::setMinHeight)); gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMaxHeight, &RenderStyle::maxHeight, &RenderStyle::setMaxHeight)); -#if ENABLE(CSS3_FLEXBOX) gPropertyWrappers->append(new PropertyWrapperFlex()); -#endif gPropertyWrappers->append(new PropertyWrapper<unsigned>(CSSPropertyBorderLeftWidth, &RenderStyle::borderLeftWidth, &RenderStyle::setBorderLeftWidth)); gPropertyWrappers->append(new PropertyWrapper<unsigned>(CSSPropertyBorderRightWidth, &RenderStyle::borderRightWidth, &RenderStyle::setBorderRightWidth)); diff --git a/Source/WebCore/page/mac/EventHandlerMac.mm b/Source/WebCore/page/mac/EventHandlerMac.mm index 76245dab6..bd8ee4704 100644 --- a/Source/WebCore/page/mac/EventHandlerMac.mm +++ b/Source/WebCore/page/mac/EventHandlerMac.mm @@ -50,6 +50,7 @@ #include "WebCoreSystemInterface.h" #include <objc/objc-runtime.h> #include <wtf/MainThread.h> +#include <wtf/ObjcRuntimeExtras.h> #include <wtf/StdLibExtras.h> namespace WebCore { @@ -412,7 +413,7 @@ static void selfRetainingNSScrollViewScrollWheel(NSScrollView *self, SEL selecto if (shouldRetainSelf) [self retain]; - originalNSScrollViewScrollWheel(self, selector, event); + wtfCallIMP<void>(originalNSScrollViewScrollWheel, self, selector, event); if (shouldRetainSelf) [self release]; } diff --git a/Source/WebCore/page/scrolling/ScrollingConstraints.cpp b/Source/WebCore/page/scrolling/ScrollingConstraints.cpp new file mode 100644 index 000000000..b94ee6279 --- /dev/null +++ b/Source/WebCore/page/scrolling/ScrollingConstraints.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ScrollingConstraints.h" + +namespace WebCore { + +FloatSize StickyPositionViewportConstraints::computeStickyOffset(const FloatRect& viewportRect) const +{ + FloatRect boxRect = m_absoluteStickyBoxRect; + + if (hasAnchorEdge(AnchorEdgeRight)) { + float rightLimit = viewportRect.maxX() - m_rightOffset; + float rightDelta = std::min<float>(0, rightLimit - m_absoluteStickyBoxRect.maxX()); + float availableSpace = std::min<float>(0, m_absoluteContainingBlockRect.x() - m_absoluteStickyBoxRect.x()); + if (rightDelta < availableSpace) + rightDelta = availableSpace; + + boxRect.move(rightDelta, 0); + } + + if (hasAnchorEdge(AnchorEdgeLeft)) { + float leftLimit = viewportRect.x() + m_leftOffset; + float leftDelta = std::max<float>(0, leftLimit - m_absoluteStickyBoxRect.x()); + float availableSpace = std::max<float>(0, m_absoluteContainingBlockRect.maxX() - m_absoluteStickyBoxRect.maxX()); + if (leftDelta > availableSpace) + leftDelta = availableSpace; + + boxRect.move(leftDelta, 0); + } + + if (hasAnchorEdge(AnchorEdgeBottom)) { + float bottomLimit = viewportRect.maxY() - m_bottomOffset; + float bottomDelta = std::min<float>(0, bottomLimit - m_absoluteStickyBoxRect.maxY()); + float availableSpace = std::min<float>(0, m_absoluteContainingBlockRect.y() - m_absoluteStickyBoxRect.y()); + if (bottomDelta < availableSpace) + bottomDelta = availableSpace; + + boxRect.move(0, bottomDelta); + } + + if (hasAnchorEdge(AnchorEdgeTop)) { + float topLimit = viewportRect.y() + m_topOffset; + float topDelta = std::max<float>(0, topLimit - m_absoluteStickyBoxRect.y()); + float availableSpace = std::max<float>(0, m_absoluteContainingBlockRect.maxY() - m_absoluteStickyBoxRect.maxY()); + if (topDelta > availableSpace) + topDelta = availableSpace; + + boxRect.move(0, topDelta); + } + + return boxRect.location() - m_absoluteStickyBoxRect.location(); +} + +FloatPoint StickyPositionViewportConstraints::layerPositionForViewportRect(const FloatRect& viewportRect) const +{ + FloatSize offset = computeStickyOffset(viewportRect); + return m_layerPositionAtLastLayout + offset - m_stickyOffsetAtLastLayout; +} + +} // namespace WebCore diff --git a/Source/WebCore/page/scrolling/ScrollingConstraints.h b/Source/WebCore/page/scrolling/ScrollingConstraints.h new file mode 100644 index 000000000..e8be408c8 --- /dev/null +++ b/Source/WebCore/page/scrolling/ScrollingConstraints.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ScrollingConstraints_h +#define ScrollingConstraints_h + +#include "FloatRect.h" + +namespace WebCore { + +// ViewportConstraints classes encapsulate data and logic required to reposition elements whose layout +// depends on the viewport rect (positions fixed and sticky), when scrolling and zooming. +class ViewportConstraints { +public: + enum ConstraintType { + FixedPositionConstaint, + StickyPositionConstraint + }; + + enum AnchorEdgeFlags { + AnchorEdgeLeft = 1 << 0, + AnchorEdgeRight = 1 << 1, + AnchorEdgeTop = 1 << 2, + AnchorEdgeBottom = 1 << 3 + }; + typedef unsigned AnchorEdges; + + ViewportConstraints() + : m_anchorEdges(0) + { } + + virtual ~ViewportConstraints() { } + + virtual ConstraintType constraintType() const = 0; + + AnchorEdges anchorEdges() const { return m_anchorEdges; } + bool hasAnchorEdge(AnchorEdgeFlags flag) const { return m_anchorEdges & flag; } + void addAnchorEdge(AnchorEdgeFlags edgeFlag) { m_anchorEdges |= edgeFlag; } + + FloatSize alignmentOffset() const { return m_alignmentOffset; } + void setAlignmentOffset(const FloatSize& offset) { m_alignmentOffset = offset; } + +protected: + FloatSize m_alignmentOffset; + AnchorEdges m_anchorEdges; +}; + +class StickyPositionViewportConstraints : public ViewportConstraints { +public: + StickyPositionViewportConstraints() + : m_leftOffset(0) + , m_rightOffset(0) + , m_topOffset(0) + , m_bottomOffset(0) + { } + + virtual ConstraintType constraintType() const OVERRIDE { return StickyPositionConstraint; }; + FloatSize computeStickyOffset(const FloatRect& viewportRect) const; + + const FloatSize stickyOffsetAtLastLayout() const { return m_stickyOffsetAtLastLayout; } + void setStickyOffsetAtLastLayout(const FloatSize& offset) { m_stickyOffsetAtLastLayout = offset; } + + FloatPoint layerPositionForViewportRect(const FloatRect& viewportRect) const; + + const FloatPoint& layerPositionAtLastLayout() const { return m_layerPositionAtLastLayout; } + void setLayerPositionAtLastLayout(const FloatPoint& point) { m_layerPositionAtLastLayout = point; } + + float leftOffset() const { return m_leftOffset; } + float rightOffset() const { return m_rightOffset; } + float topOffset() const { return m_topOffset; } + float bottomOffset() const { return m_bottomOffset; } + + void setLeftOffset(float offset) { m_leftOffset = offset; } + void setRightOffset(float offset) { m_rightOffset = offset; } + void setTopOffset(float offset) { m_topOffset = offset; } + void setBottomOffset(float offset) { m_bottomOffset = offset; } + + void setAbsoluteContainingBlockRect(const FloatRect& rect) { m_absoluteContainingBlockRect = rect; } + void setAbsoluteStickyBoxRect(const FloatRect& rect) { m_absoluteStickyBoxRect = rect; } + +private: + float m_leftOffset; + float m_rightOffset; + float m_topOffset; + float m_bottomOffset; + FloatRect m_absoluteContainingBlockRect; + FloatRect m_absoluteStickyBoxRect; + FloatSize m_stickyOffsetAtLastLayout; + FloatPoint m_layerPositionAtLastLayout; +}; + +} // namespace WebCore + +#endif // ScrollingConstraints_h diff --git a/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp b/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp index 40feed77c..1f60151fd 100644 --- a/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp +++ b/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp @@ -36,7 +36,6 @@ #include "Region.h" #include "RenderView.h" #include "ScrollAnimator.h" -#include "ScrollingTreeState.h" #include <wtf/MainThread.h> #if USE(ACCELERATED_COMPOSITING) @@ -46,6 +45,7 @@ #if ENABLE(THREADED_SCROLLING) #include "ScrollingThread.h" #include "ScrollingTree.h" +#include "ScrollingTreeState.h" #include <wtf/Functional.h> #include <wtf/PassRefPtr.h> #endif @@ -118,6 +118,11 @@ static Region computeNonFastScrollableRegion(Frame* frame, const IntPoint& frame if (const FrameView::ScrollableAreaSet* scrollableAreas = frameView->scrollableAreas()) { for (FrameView::ScrollableAreaSet::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) { ScrollableArea* scrollableArea = *it; +#if USE(ACCELERATED_COMPOSITING) + // Composited scrollable areas can be scrolled off the main thread. + if (scrollableArea->usesCompositedScrolling()) + continue; +#endif IntRect box = scrollableArea->scrollableAreaBoundingBox(); box.moveBy(offset); nonFastScrollableRegion.unite(box); @@ -187,7 +192,7 @@ void ScrollingCoordinator::frameViewHasSlowRepaintObjectsDidChange(FrameView* fr if (!coordinatesScrollingForFrameView(frameView)) return; - updateShouldUpdateScrollLayerPositionOnMainThread(); + updateShouldUpdateScrollLayerPositionOnMainThreadReason(); } void ScrollingCoordinator::frameViewFixedObjectsDidChange(FrameView* frameView) @@ -198,7 +203,7 @@ void ScrollingCoordinator::frameViewFixedObjectsDidChange(FrameView* frameView) if (!coordinatesScrollingForFrameView(frameView)) return; - updateShouldUpdateScrollLayerPositionOnMainThread(); + updateShouldUpdateScrollLayerPositionOnMainThreadReason(); } static GraphicsLayer* scrollLayerForFrameView(FrameView* frameView) @@ -227,7 +232,7 @@ void ScrollingCoordinator::frameViewRootLayerDidChange(FrameView* frameView) frameViewLayoutUpdated(frameView); recomputeWheelEventHandlerCount(); - updateShouldUpdateScrollLayerPositionOnMainThread(); + updateShouldUpdateScrollLayerPositionOnMainThreadReason(); setScrollLayer(scrollLayerForFrameView(frameView)); } @@ -354,36 +359,47 @@ void ScrollingCoordinator::recomputeWheelEventHandlerCount() setWheelEventHandlerCount(wheelEventHandlerCount); } -bool ScrollingCoordinator::hasNonLayerFixedObjects(FrameView* frameView) +bool ScrollingCoordinator::hasNonLayerViewportConstrainedObjects(FrameView* frameView) { - const FrameView::FixedObjectSet* fixedObjects = frameView->fixedObjects(); - if (!fixedObjects) + const FrameView::ViewportConstrainedObjectSet* viewportConstrainedObjects = frameView->viewportConstrainedObjects(); + if (!viewportConstrainedObjects) return false; #if USE(ACCELERATED_COMPOSITING) - for (FrameView::FixedObjectSet::const_iterator it = fixedObjects->begin(), end = fixedObjects->end(); it != end; ++it) { - RenderObject* fixedObject = *it; - if (!fixedObject->isBoxModelObject() || !fixedObject->hasLayer()) + for (FrameView::ViewportConstrainedObjectSet::const_iterator it = viewportConstrainedObjects->begin(), end = viewportConstrainedObjects->end(); it != end; ++it) { + RenderObject* viewportConstrainedObject = *it; + if (!viewportConstrainedObject->isBoxModelObject() || !viewportConstrainedObject->hasLayer()) return true; - RenderBoxModelObject* fixedBoxModelObject = toRenderBoxModelObject(fixedObject); - if (!fixedBoxModelObject->layer()->backing()) + RenderBoxModelObject* viewportConstrainedBoxModelObject = toRenderBoxModelObject(viewportConstrainedObject); + if (!viewportConstrainedBoxModelObject->layer()->backing()) return true; } return false; #else - return fixedObjects->size(); + return viewportConstrainedObjects->size(); #endif } -void ScrollingCoordinator::updateShouldUpdateScrollLayerPositionOnMainThread() +void ScrollingCoordinator::updateShouldUpdateScrollLayerPositionOnMainThreadReason() { +#if ENABLE(THREADED_SCROLLING) FrameView* frameView = m_page->mainFrame()->view(); - setShouldUpdateScrollLayerPositionOnMainThread(m_forceMainThreadScrollLayerPositionUpdates - || frameView->hasSlowRepaintObjects() - || (!supportsFixedPositionLayers() && frameView->hasFixedObjects()) - || (supportsFixedPositionLayers() && hasNonLayerFixedObjects(frameView)) - || m_page->mainFrame()->document()->isImageDocument()); + ReasonForUpdatingScrollLayerPositionOnMainThreadFlags reasonsForUpdatingScrollLayerPositionOnMainThread = (ReasonForUpdatingScrollLayerPositionOnMainThreadFlags)0; + + if (m_forceMainThreadScrollLayerPositionUpdates) + reasonsForUpdatingScrollLayerPositionOnMainThread |= ScrollingTreeState::ForcedOnMainThread; + if (frameView->hasSlowRepaintObjects()) + reasonsForUpdatingScrollLayerPositionOnMainThread |= ScrollingTreeState::HasSlowRepaintObjects; + if (!supportsFixedPositionLayers() && frameView->hasViewportConstrainedObjects()) + reasonsForUpdatingScrollLayerPositionOnMainThread |= ScrollingTreeState::HasNonCompositedViewportConstrainedObjects; + if (supportsFixedPositionLayers() && hasNonLayerViewportConstrainedObjects(frameView)) + reasonsForUpdatingScrollLayerPositionOnMainThread |= ScrollingTreeState::HasNonLayerViewportConstrainedObjects; + if (m_page->mainFrame()->document()->isImageDocument()) + reasonsForUpdatingScrollLayerPositionOnMainThread |= ScrollingTreeState::IsImageDocument; + + setShouldUpdateScrollLayerPositionOnMainThreadReason(reasonsForUpdatingScrollLayerPositionOnMainThread); +#endif } void ScrollingCoordinator::setForceMainThreadScrollLayerPositionUpdates(bool forceMainThreadScrollLayerPositionUpdates) @@ -392,7 +408,7 @@ void ScrollingCoordinator::setForceMainThreadScrollLayerPositionUpdates(bool for return; m_forceMainThreadScrollLayerPositionUpdates = forceMainThreadScrollLayerPositionUpdates; - updateShouldUpdateScrollLayerPositionOnMainThread(); + updateShouldUpdateScrollLayerPositionOnMainThreadReason(); } #if ENABLE(THREADED_SCROLLING) @@ -430,16 +446,18 @@ void ScrollingCoordinator::setWheelEventHandlerCount(unsigned wheelEventHandlerC scheduleTreeStateCommit(); } -void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread(bool shouldUpdateScrollLayerPositionOnMainThread) +#if ENABLE(THREADED_SCROLLING) +void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThreadReason(ReasonForUpdatingScrollLayerPositionOnMainThreadFlags reasons) { // The FrameView's GraphicsLayer is likely to be out-of-synch with the PlatformLayer // at this point. So we'll update it before we switch back to main thread scrolling // in order to avoid layer positioning bugs. - if (shouldUpdateScrollLayerPositionOnMainThread) + if (reasons) updateMainFrameScrollLayerPosition(); - m_scrollingTreeState->setShouldUpdateScrollLayerPositionOnMainThread(shouldUpdateScrollLayerPositionOnMainThread); + m_scrollingTreeState->setShouldUpdateScrollLayerPositionOnMainThreadReason(reasons); scheduleTreeStateCommit(); } +#endif void ScrollingCoordinator::scheduleTreeStateCommit() { @@ -488,6 +506,11 @@ void ScrollingCoordinator::setLayerIsFixedToContainerLayer(GraphicsLayer*, bool) { // FIXME: Implement! } + +void ScrollingCoordinator::scrollableAreaScrollLayerDidChange(ScrollableArea*, GraphicsLayer*) +{ + // FIXME: Implement. +} #endif // !ENABLE(THREADED_SCROLLING) } // namespace WebCore diff --git a/Source/WebCore/page/scrolling/ScrollingCoordinator.h b/Source/WebCore/page/scrolling/ScrollingCoordinator.h index 5d45eb620..8bc4b6a75 100644 --- a/Source/WebCore/page/scrolling/ScrollingCoordinator.h +++ b/Source/WebCore/page/scrolling/ScrollingCoordinator.h @@ -34,6 +34,7 @@ #include <wtf/Forward.h> #if ENABLE(THREADED_SCROLLING) +#include "ScrollingTreeState.h" #include <wtf/ThreadSafeRefCounted.h> #include <wtf/Threading.h> #endif @@ -48,6 +49,7 @@ class FrameView; class GraphicsLayer; class Page; class Region; +class ScrollableArea; class ScrollingCoordinatorPrivate; class ScrollingTreeState; @@ -92,6 +94,9 @@ public: // Should be called whenever the vertical scrollbar layer for the given frame view changes. void frameViewVerticalScrollbarLayerDidChange(FrameView*, GraphicsLayer* verticalScrollbarLayer); + // Should be called whenever the scrollable layer for the given scroll area changes. + void scrollableAreaScrollLayerDidChange(ScrollableArea*, GraphicsLayer*); + // Requests that the scrolling coordinator updates the scroll position of the given frame view. If this function returns true, it means that the // position will be updated asynchronously. If it returns false, the caller should update the scrolling position itself. bool requestScrollPositionUpdate(FrameView*, const IntPoint&); @@ -127,8 +132,8 @@ private: explicit ScrollingCoordinator(Page*); void recomputeWheelEventHandlerCount(); - bool hasNonLayerFixedObjects(FrameView*); - void updateShouldUpdateScrollLayerPositionOnMainThread(); + bool hasNonLayerViewportConstrainedObjects(FrameView*); + void updateShouldUpdateScrollLayerPositionOnMainThreadReason(); void setScrollLayer(GraphicsLayer*); void setNonFastScrollableRegion(const Region&); @@ -151,7 +156,9 @@ private: void setScrollParameters(const ScrollParameters&); void setWheelEventHandlerCount(unsigned); - void setShouldUpdateScrollLayerPositionOnMainThread(bool); +#if ENABLE(THREADED_SCROLLING) + void setShouldUpdateScrollLayerPositionOnMainThreadReason(ReasonForUpdatingScrollLayerPositionOnMainThreadFlags); +#endif void updateMainFrameScrollLayerPosition(); diff --git a/Source/WebCore/page/scrolling/ScrollingCoordinatorNone.cpp b/Source/WebCore/page/scrolling/ScrollingCoordinatorNone.cpp index f0acfe0cc..26c6e530e 100644 --- a/Source/WebCore/page/scrolling/ScrollingCoordinatorNone.cpp +++ b/Source/WebCore/page/scrolling/ScrollingCoordinatorNone.cpp @@ -67,9 +67,11 @@ void ScrollingCoordinator::setWheelEventHandlerCount(unsigned) { } -void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread(bool) +#if ENABLE(THREADED_SCROLLING) +void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThreadReason(ReasonForUpdatingScrollLayerPositionOnMainThreadFlags) { } +#endif bool ScrollingCoordinator::supportsFixedPositionLayers() const { @@ -83,6 +85,10 @@ void ScrollingCoordinator::setLayerIsContainerForFixedPositionLayers(GraphicsLay void ScrollingCoordinator::setLayerIsFixedToContainerLayer(GraphicsLayer*, bool) { } + +void ScrollingCoordinator::scrollableAreaScrollLayerDidChange(ScrollableArea*, GraphicsLayer*) +{ +} #endif // !ENABLE(THREADED_SCROLLING) } diff --git a/Source/WebCore/page/scrolling/ScrollingTree.cpp b/Source/WebCore/page/scrolling/ScrollingTree.cpp index ba6a52ac7..690ec9225 100644 --- a/Source/WebCore/page/scrolling/ScrollingTree.cpp +++ b/Source/WebCore/page/scrolling/ScrollingTree.cpp @@ -224,7 +224,7 @@ void ScrollingTree::setScrollingPerformanceLoggingEnabled(bool flag) m_scrollingPerformanceLoggingEnabled = flag; } -bool ScrollingTree::scrollingPeformanceLoggingEnabled() +bool ScrollingTree::scrollingPerformanceLoggingEnabled() { return m_scrollingPerformanceLoggingEnabled; } diff --git a/Source/WebCore/page/scrolling/ScrollingTree.h b/Source/WebCore/page/scrolling/ScrollingTree.h index 4120e9eac..40705a0fc 100644 --- a/Source/WebCore/page/scrolling/ScrollingTree.h +++ b/Source/WebCore/page/scrolling/ScrollingTree.h @@ -98,7 +98,7 @@ public: #endif void setScrollingPerformanceLoggingEnabled(bool flag); - bool scrollingPeformanceLoggingEnabled(); + bool scrollingPerformanceLoggingEnabled(); private: explicit ScrollingTree(ScrollingCoordinator*); diff --git a/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp b/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp index 28402ce16..150ba7213 100644 --- a/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp +++ b/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp @@ -34,7 +34,7 @@ namespace WebCore { ScrollingTreeNode::ScrollingTreeNode(ScrollingTree* scrollingTree) : m_scrollingTree(scrollingTree) - , m_shouldUpdateScrollLayerPositionOnMainThread(false) + , m_shouldUpdateScrollLayerPositionOnMainThreadReason(0) , m_horizontalScrollElasticity(ScrollElasticityNone) , m_verticalScrollElasticity(ScrollElasticityNone) , m_hasEnabledHorizontalScrollbar(false) @@ -56,8 +56,8 @@ void ScrollingTreeNode::update(ScrollingTreeState* state) if (state->changedProperties() & ScrollingTreeState::ContentsSize) m_contentsSize = state->contentsSize(); - if (state->changedProperties() & ScrollingTreeState::ShouldUpdateScrollLayerPositionOnMainThread) - m_shouldUpdateScrollLayerPositionOnMainThread = state->shouldUpdateScrollLayerPositionOnMainThread(); + if (state->changedProperties() & ScrollingTreeState::ShouldUpdateScrollLayerPositionOnMainThreadReason) + m_shouldUpdateScrollLayerPositionOnMainThreadReason = state->shouldUpdateScrollLayerPositionOnMainThreadReason(); if (state->changedProperties() & ScrollingTreeState::HorizontalScrollElasticity) m_horizontalScrollElasticity = state->horizontalScrollElasticity(); diff --git a/Source/WebCore/page/scrolling/ScrollingTreeNode.h b/Source/WebCore/page/scrolling/ScrollingTreeNode.h index f69ae9f41..3cad506cd 100644 --- a/Source/WebCore/page/scrolling/ScrollingTreeNode.h +++ b/Source/WebCore/page/scrolling/ScrollingTreeNode.h @@ -30,6 +30,7 @@ #include "IntRect.h" #include "ScrollTypes.h" +#include "ScrollingTreeState.h" #include <wtf/PassOwnPtr.h> namespace WebCore { @@ -47,7 +48,7 @@ public: virtual void handleWheelEvent(const PlatformWheelEvent&) = 0; virtual void setScrollPosition(const IntPoint&) = 0; - bool shouldUpdateScrollLayerPositionOnMainThread() const { return m_shouldUpdateScrollLayerPositionOnMainThread; } + ReasonForUpdatingScrollLayerPositionOnMainThreadFlags shouldUpdateScrollLayerPositionOnMainThreadReason() const { return m_shouldUpdateScrollLayerPositionOnMainThreadReason; } protected: explicit ScrollingTreeNode(ScrollingTree*); @@ -74,7 +75,7 @@ private: IntSize m_contentsSize; IntPoint m_scrollOrigin; - bool m_shouldUpdateScrollLayerPositionOnMainThread; + ReasonForUpdatingScrollLayerPositionOnMainThreadFlags m_shouldUpdateScrollLayerPositionOnMainThreadReason; ScrollElasticity m_horizontalScrollElasticity; ScrollElasticity m_verticalScrollElasticity; diff --git a/Source/WebCore/page/scrolling/ScrollingTreeState.cpp b/Source/WebCore/page/scrolling/ScrollingTreeState.cpp index 5eb53abe6..2334b5958 100644 --- a/Source/WebCore/page/scrolling/ScrollingTreeState.cpp +++ b/Source/WebCore/page/scrolling/ScrollingTreeState.cpp @@ -38,7 +38,7 @@ PassOwnPtr<ScrollingTreeState> ScrollingTreeState::create() ScrollingTreeState::ScrollingTreeState() : m_changedProperties(0) , m_wheelEventHandlerCount(0) - , m_shouldUpdateScrollLayerPositionOnMainThread(false) + , m_shouldUpdateScrollLayerPositionOnMainThreadReason(0) , m_horizontalScrollElasticity(ScrollElasticityNone) , m_verticalScrollElasticity(ScrollElasticityNone) , m_hasEnabledHorizontalScrollbar(false) @@ -88,13 +88,13 @@ void ScrollingTreeState::setWheelEventHandlerCount(unsigned wheelEventHandlerCou m_changedProperties |= WheelEventHandlerCount; } -void ScrollingTreeState::setShouldUpdateScrollLayerPositionOnMainThread(bool shouldUpdateScrollLayerPositionOnMainThread) +void ScrollingTreeState::setShouldUpdateScrollLayerPositionOnMainThreadReason(ReasonForUpdatingScrollLayerPositionOnMainThreadFlags reasons) { - if (m_shouldUpdateScrollLayerPositionOnMainThread == shouldUpdateScrollLayerPositionOnMainThread) + if ((bool)m_shouldUpdateScrollLayerPositionOnMainThreadReason == (bool)reasons) return; - m_shouldUpdateScrollLayerPositionOnMainThread = shouldUpdateScrollLayerPositionOnMainThread; - m_changedProperties |= ShouldUpdateScrollLayerPositionOnMainThread; + m_shouldUpdateScrollLayerPositionOnMainThreadReason = reasons; + m_changedProperties |= ShouldUpdateScrollLayerPositionOnMainThreadReason; } void ScrollingTreeState::setHorizontalScrollElasticity(ScrollElasticity horizontalScrollElasticity) diff --git a/Source/WebCore/page/scrolling/ScrollingTreeState.h b/Source/WebCore/page/scrolling/ScrollingTreeState.h index 3b4a8d68b..0f662fd23 100644 --- a/Source/WebCore/page/scrolling/ScrollingTreeState.h +++ b/Source/WebCore/page/scrolling/ScrollingTreeState.h @@ -40,6 +40,8 @@ namespace WebCore { +typedef unsigned ReasonForUpdatingScrollLayerPositionOnMainThreadFlags; + // The ScrollingTreeState object keeps track of the current state of scrolling related properties. // Whenever any properties change, the scrolling coordinator will be informed and will update the state // and schedule a timer that will clone the new state and send it over to the scrolling thread, avoiding locking. @@ -54,7 +56,7 @@ public: ContentsSize = 1 << 1, NonFastScrollableRegion = 1 << 2, WheelEventHandlerCount = 1 << 3, - ShouldUpdateScrollLayerPositionOnMainThread = 1 << 4, + ShouldUpdateScrollLayerPositionOnMainThreadReason = 1 << 4, HorizontalScrollElasticity = 1 << 5, VerticalScrollElasticity = 1 << 6, HasEnabledHorizontalScrollbar = 1 << 7, @@ -66,6 +68,14 @@ public: RequestedScrollPosition = 1 << 13, }; + enum ReasonForUpdatingScrollLayerPositionOnMainThread { + ForcedOnMainThread = 1 << 0, + HasSlowRepaintObjects = 1 << 1, + HasNonCompositedViewportConstrainedObjects = 1 << 2, + HasNonLayerViewportConstrainedObjects = 1 << 3, + IsImageDocument = 1 << 4 + }; + bool hasChangedProperties() const { return m_changedProperties; } unsigned changedProperties() const { return m_changedProperties; } @@ -81,8 +91,8 @@ public: unsigned wheelEventHandlerCount() const { return m_wheelEventHandlerCount; } void setWheelEventHandlerCount(unsigned); - bool shouldUpdateScrollLayerPositionOnMainThread() const { return m_shouldUpdateScrollLayerPositionOnMainThread; } - void setShouldUpdateScrollLayerPositionOnMainThread(bool); + ReasonForUpdatingScrollLayerPositionOnMainThreadFlags shouldUpdateScrollLayerPositionOnMainThreadReason() const { return m_shouldUpdateScrollLayerPositionOnMainThreadReason; } + void setShouldUpdateScrollLayerPositionOnMainThreadReason(ReasonForUpdatingScrollLayerPositionOnMainThreadFlags); ScrollElasticity horizontalScrollElasticity() const { return m_horizontalScrollElasticity; } void setHorizontalScrollElasticity(ScrollElasticity); @@ -126,7 +136,7 @@ private: unsigned m_wheelEventHandlerCount; - bool m_shouldUpdateScrollLayerPositionOnMainThread; + ReasonForUpdatingScrollLayerPositionOnMainThreadFlags m_shouldUpdateScrollLayerPositionOnMainThreadReason; ScrollElasticity m_horizontalScrollElasticity; ScrollElasticity m_verticalScrollElasticity; diff --git a/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp b/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp index e256bde1a..807decb5f 100644 --- a/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp +++ b/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp @@ -29,12 +29,16 @@ #include "Frame.h" #include "FrameView.h" +#include "GraphicsLayerChromium.h" #include "Page.h" #include "Region.h" #include "RenderLayerCompositor.h" #include "RenderView.h" #include "ScrollbarThemeComposite.h" +#include "WebScrollbarImpl.h" #include "WebScrollbarThemeGeometryNative.h" +#include <public/Platform.h> +#include <public/WebCompositorSupport.h> #include <public/WebScrollbar.h> #include <public/WebScrollbarLayer.h> #include <public/WebScrollbarThemeGeometry.h> @@ -55,7 +59,13 @@ public: { } - ~ScrollingCoordinatorPrivate() { } + ~ScrollingCoordinatorPrivate() + { + if (m_horizontalScrollbarLayer) + GraphicsLayerChromium::unregisterContentsLayer(m_horizontalScrollbarLayer->layer()); + if (m_verticalScrollbarLayer) + GraphicsLayerChromium::unregisterContentsLayer(m_verticalScrollbarLayer->layer()); + } void setScrollLayer(WebLayer* layer) { @@ -153,9 +163,10 @@ static PassOwnPtr<WebScrollbarLayer> createScrollbarLayer(Scrollbar* scrollbar, WebKit::WebScrollbarThemePainter painter(themeComposite, scrollbar); OwnPtr<WebKit::WebScrollbarThemeGeometry> geometry(WebKit::WebScrollbarThemeGeometryNative::create(themeComposite)); - OwnPtr<WebScrollbarLayer> scrollbarLayer = adoptPtr(WebScrollbarLayer::create(scrollbar, painter, geometry.release())); + OwnPtr<WebScrollbarLayer> scrollbarLayer = adoptPtr(WebKit::Platform::current()->compositorSupport()->createScrollbarLayer(new WebKit::WebScrollbarImpl(scrollbar), painter, geometry.leakPtr())); scrollbarLayer->setScrollLayer(scrollLayer); + GraphicsLayerChromium::registerContentsLayer(scrollbarLayer->layer()); scrollbarGraphicsLayer->setContentsToMedia(scrollbarLayer->layer()); scrollbarGraphicsLayer->setDrawsContent(false); scrollbarLayer->layer()->setOpaque(scrollbarGraphicsLayer->contentsOpaque()); @@ -212,13 +223,15 @@ void ScrollingCoordinator::setWheelEventHandlerCount(unsigned wheelEventHandlerC m_private->scrollLayer()->setHaveWheelEventHandlers(wheelEventHandlerCount > 0); } -void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread(bool should) +#if ENABLE(THREADED_SCROLLING) +void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThreadReason(ReasonForUpdatingScrollLayerPositionOnMainThreadFlags reasons) { // We won't necessarily get a setScrollLayer() call before this one, so grab the root ourselves. setScrollLayer(scrollLayerForFrameView(m_page->mainFrame()->view())); if (m_private->scrollLayer()) - m_private->scrollLayer()->setShouldScrollOnMainThread(should); + m_private->scrollLayer()->setShouldScrollOnMainThread(reasons); } +#endif bool ScrollingCoordinator::supportsFixedPositionLayers() const { @@ -237,4 +250,18 @@ void ScrollingCoordinator::setLayerIsFixedToContainerLayer(GraphicsLayer* layer, scrollableLayer->setFixedToContainerLayer(enable); } +void ScrollingCoordinator::scrollableAreaScrollLayerDidChange(ScrollableArea* scrollableArea, GraphicsLayer* scrollLayer) +{ + if (!scrollLayer) + return; + GraphicsLayerChromium* layer = static_cast<GraphicsLayerChromium*>(scrollLayer); + layer->setScrollableArea(scrollableArea); + + if (WebLayer* webLayer = scrollLayer->platformLayer()) { + webLayer->setScrollable(true); + webLayer->setScrollPosition(scrollableArea->scrollPosition()); + webLayer->setMaxScrollPosition(IntSize(scrollableArea->scrollSize(HorizontalScrollbar), scrollableArea->scrollSize(VerticalScrollbar))); + } +} + } diff --git a/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.mm b/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.mm index 4a6401ca5..101bbd002 100644 --- a/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.mm +++ b/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.mm @@ -62,7 +62,7 @@ void ScrollingTree::updateDebugRootLayer() RetainPtr<CGColorRef> backgroundColor; - if (m_rootNode->shouldUpdateScrollLayerPositionOnMainThread()) + if (m_rootNode->shouldUpdateScrollLayerPositionOnMainThreadReason()) backgroundColor = adoptCF(CGColorCreateGenericRGB(1, 0, 0, .7)); { diff --git a/Source/WebCore/page/scrolling/mac/ScrollingTreeNodeMac.mm b/Source/WebCore/page/scrolling/mac/ScrollingTreeNodeMac.mm index 38dd9e53e..1194f8981 100644 --- a/Source/WebCore/page/scrolling/mac/ScrollingTreeNodeMac.mm +++ b/Source/WebCore/page/scrolling/mac/ScrollingTreeNodeMac.mm @@ -37,9 +37,13 @@ #include <wtf/CurrentTime.h> #include <wtf/Deque.h> +#include <wtf/text/StringBuilder.h> +#include <wtf/text/CString.h> namespace WebCore { +static void logThreadedScrollingMode(unsigned reasonsForUpdatingScrollLayerPositionOnMainThread); + PassOwnPtr<ScrollingTreeNode> ScrollingTreeNode::create(ScrollingTree* scrollingTree) { return adoptPtr(new ScrollingTreeNodeMac(scrollingTree)); @@ -70,15 +74,22 @@ void ScrollingTreeNodeMac::update(ScrollingTreeState* state) if (state->changedProperties() & (ScrollingTreeState::ScrollLayer | ScrollingTreeState::ContentsSize | ScrollingTreeState::ViewportRect)) updateMainFramePinState(scrollPosition()); - if ((state->changedProperties() & ScrollingTreeState::ShouldUpdateScrollLayerPositionOnMainThread) && shouldUpdateScrollLayerPositionOnMainThread()) { - // We're transitioning to the slow "update scroll layer position on the main thread" mode. - // Initialize the probable main thread scroll position with the current scroll layer position. - if (state->changedProperties() & ScrollingTreeState::RequestedScrollPosition) - m_probableMainThreadScrollPosition = state->requestedScrollPosition(); - else { - CGPoint scrollLayerPosition = m_scrollLayer.get().position; - m_probableMainThreadScrollPosition = IntPoint(-scrollLayerPosition.x, -scrollLayerPosition.y); + if ((state->changedProperties() & ScrollingTreeState::ShouldUpdateScrollLayerPositionOnMainThreadReason)) { + unsigned reasonsForUpdatingScrollLayerPositionOnMainThread = this->shouldUpdateScrollLayerPositionOnMainThreadReason(); + + if (reasonsForUpdatingScrollLayerPositionOnMainThread) { + // We're transitioning to the slow "update scroll layer position on the main thread" mode. + // Initialize the probable main thread scroll position with the current scroll layer position. + if (state->changedProperties() & ScrollingTreeState::RequestedScrollPosition) + m_probableMainThreadScrollPosition = state->requestedScrollPosition(); + else { + CGPoint scrollLayerPosition = m_scrollLayer.get().position; + m_probableMainThreadScrollPosition = IntPoint(-scrollLayerPosition.x, -scrollLayerPosition.y); + } } + + if (scrollingTree()->scrollingPerformanceLoggingEnabled()) + logThreadedScrollingMode(reasonsForUpdatingScrollLayerPositionOnMainThread); } } @@ -225,7 +236,7 @@ void ScrollingTreeNodeMac::stopSnapRubberbandTimer() IntPoint ScrollingTreeNodeMac::scrollPosition() const { - if (shouldUpdateScrollLayerPositionOnMainThread()) + if (shouldUpdateScrollLayerPositionOnMainThreadReason()) return m_probableMainThreadScrollPosition; CGPoint scrollLayerPosition = m_scrollLayer.get().position; @@ -240,7 +251,7 @@ void ScrollingTreeNodeMac::setScrollPosition(const IntPoint& scrollPosition) setScrollPositionWithoutContentEdgeConstraints(newScrollPosition); - if (scrollingTree()->scrollingPeformanceLoggingEnabled()) + if (scrollingTree()->scrollingPerformanceLoggingEnabled()) logExposedUnfilledArea(); } @@ -248,7 +259,7 @@ void ScrollingTreeNodeMac::setScrollPositionWithoutContentEdgeConstraints(const { updateMainFramePinState(scrollPosition); - if (shouldUpdateScrollLayerPositionOnMainThread()) { + if (shouldUpdateScrollLayerPositionOnMainThreadReason()) { m_probableMainThreadScrollPosition = scrollPosition; scrollingTree()->updateMainFrameScrollPositionAndScrollLayerPosition(scrollPosition); return; @@ -260,7 +271,7 @@ void ScrollingTreeNodeMac::setScrollPositionWithoutContentEdgeConstraints(const void ScrollingTreeNodeMac::setScrollLayerPosition(const IntPoint& position) { - ASSERT(!shouldUpdateScrollLayerPositionOnMainThread()); + ASSERT(!shouldUpdateScrollLayerPositionOnMainThreadReason()); m_scrollLayer.get().position = CGPointMake(-position.x() + scrollOrigin().x(), -position.y() + scrollOrigin().y()); } @@ -327,7 +338,31 @@ void ScrollingTreeNodeMac::logExposedUnfilledArea() unsigned unfilledArea = TileCache::blankPixelCountForTiles(tiles, viewportRect(), IntPoint(-scrollPosition.x(), -scrollPosition.y())); if (unfilledArea) - printf("SCROLLING: Exposed tileless area. Time: %f Unfilled Pixels: %u\n", WTF::monotonicallyIncreasingTime(), unfilledArea); + WTFLogAlways("SCROLLING: Exposed tileless area. Time: %f Unfilled Pixels: %u\n", WTF::monotonicallyIncreasingTime(), unfilledArea); +} + +static void logThreadedScrollingMode(unsigned reasonsForUpdatingScrollLayerPositionOnMainThread) +{ + if (reasonsForUpdatingScrollLayerPositionOnMainThread) { + StringBuilder reasonsDescription; + + if (reasonsForUpdatingScrollLayerPositionOnMainThread & ScrollingTreeState::ForcedOnMainThread) + reasonsDescription.append("forced,"); + if (reasonsForUpdatingScrollLayerPositionOnMainThread & ScrollingTreeState::HasSlowRepaintObjects) + reasonsDescription.append("slow-repaint objects,"); + if (reasonsForUpdatingScrollLayerPositionOnMainThread & ScrollingTreeState::HasNonCompositedViewportConstrainedObjects) + reasonsDescription.append("viewport-constrained objects,"); + if (reasonsForUpdatingScrollLayerPositionOnMainThread & ScrollingTreeState::HasNonLayerViewportConstrainedObjects) + reasonsDescription.append("non-layer viewport-constrained objects,"); + if (reasonsForUpdatingScrollLayerPositionOnMainThread & ScrollingTreeState::IsImageDocument) + reasonsDescription.append("image document,"); + + // Strip the trailing comma. + String reasonsDescriptionTrimmed = reasonsDescription.toString().left(reasonsDescription.length() - 1); + + WTFLogAlways("SCROLLING: Switching to main-thread scrolling mode. Time: %f Reason(s): %s\n", WTF::monotonicallyIncreasingTime(), reasonsDescriptionTrimmed.ascii().data()); + } else + WTFLogAlways("SCROLLING: Switching to threaded scrolling mode. Time: %f\n", WTF::monotonicallyIncreasingTime()); } } // namespace WebCore |