diff options
Diffstat (limited to 'Source/WebCore/page')
51 files changed, 899 insertions, 161 deletions
diff --git a/Source/WebCore/page/Chrome.cpp b/Source/WebCore/page/Chrome.cpp index 5881d5e..dce7d33 100644 --- a/Source/WebCore/page/Chrome.cpp +++ b/Source/WebCore/page/Chrome.cpp @@ -280,8 +280,16 @@ void Chrome::closeWindowSoon() m_client->closeWindowSoon(); } +static inline void willRunModalDialog(const Frame* frame, const ChromeClient::DialogType& dialogType, const ChromeClient* client) +{ + if (frame->loader()->pageDismissalEventBeingDispatched()) + client->willRunModalDialogDuringPageDismissal(dialogType); +} + void Chrome::runJavaScriptAlert(Frame* frame, const String& message) { + willRunModalDialog(frame, ChromeClient::AlertDialog, m_client); + // Defer loads in case the client method runs a new event loop that would // otherwise cause the load to continue while we're in the middle of executing JavaScript. PageGroupLoadDeferrer deferrer(m_page, true); @@ -292,6 +300,8 @@ void Chrome::runJavaScriptAlert(Frame* frame, const String& message) bool Chrome::runJavaScriptConfirm(Frame* frame, const String& message) { + willRunModalDialog(frame, ChromeClient::ConfirmDialog, m_client); + // Defer loads in case the client method runs a new event loop that would // otherwise cause the load to continue while we're in the middle of executing JavaScript. PageGroupLoadDeferrer deferrer(m_page, true); @@ -302,6 +312,8 @@ bool Chrome::runJavaScriptConfirm(Frame* frame, const String& message) bool Chrome::runJavaScriptPrompt(Frame* frame, const String& prompt, const String& defaultValue, String& result) { + willRunModalDialog(frame, ChromeClient::PromptDialog, m_client); + // Defer loads in case the client method runs a new event loop that would // otherwise cause the load to continue while we're in the middle of executing JavaScript. PageGroupLoadDeferrer deferrer(m_page, true); @@ -432,6 +444,13 @@ void Chrome::cancelGeolocationPermissionRequestForFrame(Frame* frame, Geolocatio m_client->cancelGeolocationPermissionRequestForFrame(frame, geolocation); } +#if ENABLE(DIRECTORY_UPLOAD) +void Chrome::enumerateChosenDirectory(const String& path, FileChooser* fileChooser) +{ + m_client->enumerateChosenDirectory(path, fileChooser); +} +#endif + void Chrome::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser) { m_client->runOpenPanel(frame, fileChooser); @@ -547,4 +566,9 @@ bool Chrome::requiresFullscreenForVideoPlayback() return m_client->requiresFullscreenForVideoPlayback(); } +void Chrome::willRunModalHTMLDialog(const Frame* frame) const +{ + willRunModalDialog(frame, ChromeClient::HTMLDialog, m_client); +} + } // namespace WebCore diff --git a/Source/WebCore/page/Chrome.h b/Source/WebCore/page/Chrome.h index 9984a7c..9adfec8 100644 --- a/Source/WebCore/page/Chrome.h +++ b/Source/WebCore/page/Chrome.h @@ -153,6 +153,9 @@ namespace WebCore { void runOpenPanel(Frame*, PassRefPtr<FileChooser>); void chooseIconForFiles(const Vector<String>&, FileChooser*); +#if ENABLE(DIRECTORY_UPLOAD) + void enumerateChosenDirectory(const String&, FileChooser*); +#endif void dispatchViewportDataDidChange(const ViewportArguments&) const; @@ -175,6 +178,8 @@ namespace WebCore { void showContextMenu(); #endif + void willRunModalHTMLDialog(const Frame*) const; + private: Page* m_page; ChromeClient* m_client; diff --git a/Source/WebCore/page/ChromeClient.h b/Source/WebCore/page/ChromeClient.h index 73fe904..4e6b45e 100644 --- a/Source/WebCore/page/ChromeClient.h +++ b/Source/WebCore/page/ChromeClient.h @@ -224,6 +224,11 @@ namespace WebCore { // Asynchronous request to load an icon for specified filenames. virtual void chooseIconForFiles(const Vector<String>&, FileChooser*) = 0; +#if ENABLE(DIRECTORY_UPLOAD) + // Asychronous request to enumerate all files in a directory chosen by the user. + virtual void enumerateChosenDirectory(const String&, FileChooser*) = 0; +#endif + // Notification that the given form element has changed. This function // will be called frequently, so handling should be very fast. virtual void formStateDidChange(const Node*) = 0; @@ -303,9 +308,20 @@ namespace WebCore { virtual void didCompleteRubberBandForMainFrame(const IntSize&) const { } +<<<<<<< HEAD #if ENABLE(ANDROID_INSTALLABLE_WEB_APPS) virtual void webAppCanBeInstalled() = 0; #endif +======= + enum DialogType { + AlertDialog = 0, + ConfirmDialog = 1, + PromptDialog = 2, + HTMLDialog = 3, + NumDialogTypes = 4 + }; + virtual void willRunModalDialogDuringPageDismissal(const DialogType&) const { } +>>>>>>> WebKit.org at r84325 protected: virtual ~ChromeClient() { } diff --git a/Source/WebCore/page/Console.h b/Source/WebCore/page/Console.h index ceefb38..bfdcaa7 100644 --- a/Source/WebCore/page/Console.h +++ b/Source/WebCore/page/Console.h @@ -50,7 +50,6 @@ class Frame; class Page; class ScriptCallStack; -// Keep in sync with inspector/front-end/Console.js enum MessageSource { HTMLMessageSource, WMLMessageSource, diff --git a/Source/WebCore/page/ContentSecurityPolicy.cpp b/Source/WebCore/page/ContentSecurityPolicy.cpp index 6bcf99c..98e311c 100644 --- a/Source/WebCore/page/ContentSecurityPolicy.cpp +++ b/Source/WebCore/page/ContentSecurityPolicy.cpp @@ -57,6 +57,11 @@ bool isHostCharacter(UChar c) return isASCIIAlphanumeric(c) || c == '-'; } +bool isOptionValueCharacter(UChar c) +{ + return isASCIIAlphanumeric(c) || c == '-'; +} + bool isSchemeContinuationCharacter(UChar c) { return isASCIIAlphanumeric(c) || c == '+' || c == '-' || c == '.'; @@ -385,8 +390,7 @@ bool CSPSourceList::parsePort(const UChar* begin, const UChar* end, int& port, b void CSPSourceList::addSourceSelf() { - // FIXME: Inherit the scheme, host, and port from the current URL. - notImplemented(); + m_list.append(CSPSource(m_origin->protocol(), m_origin->host(), m_origin->port(), false, false)); } class CSPDirective { @@ -406,6 +410,55 @@ private: CSPSourceList m_sourceList; }; +class CSPOptions { +public: + explicit CSPOptions(const String& value) + : m_disableXSSProtection(false) + , m_evalScript(false) + { + parse(value); + } + + bool disableXSSProtection() const { return m_disableXSSProtection; } + bool evalScript() const { return m_evalScript; } + +private: + void parse(const String&); + + bool m_disableXSSProtection; + bool m_evalScript; +}; + +// options = "options" *( 1*WSP option-value ) *WSP +// option-value = 1*( ALPHA / DIGIT / "-" ) +// +void CSPOptions::parse(const String& value) +{ + DEFINE_STATIC_LOCAL(String, disableXSSProtection, ("disable-xss-protection")); + DEFINE_STATIC_LOCAL(String, evalScript, ("eval-script")); + + const UChar* position = value.characters(); + const UChar* end = position + value.length(); + + while (position < end) { + skipWhile<isASCIISpace>(position, end); + + const UChar* optionsValueBegin = position; + + if (!skipExactly<isOptionValueCharacter>(position, end)) + return; + + skipWhile<isOptionValueCharacter>(position, end); + + String optionsValue(optionsValueBegin, position - optionsValueBegin); + + if (equalIgnoringCase(optionsValue, disableXSSProtection)) + m_disableXSSProtection = true; + else if (equalIgnoringCase(optionsValue, evalScript)) + m_evalScript = true; + } +} + ContentSecurityPolicy::ContentSecurityPolicy(SecurityOrigin* origin) : m_havePolicy(false) , m_origin(origin) @@ -425,14 +478,29 @@ void ContentSecurityPolicy::didReceiveHeader(const String& header) m_havePolicy = true; } +bool ContentSecurityPolicy::protectAgainstXSS() const +{ + return m_scriptSrc && (!m_options || !m_options->disableXSSProtection()); +} + bool ContentSecurityPolicy::allowJavaScriptURLs() const { - return !m_scriptSrc; + return !protectAgainstXSS(); } bool ContentSecurityPolicy::allowInlineEventHandlers() const { - return !m_scriptSrc; + return !protectAgainstXSS(); +} + +bool ContentSecurityPolicy::allowInlineScript() const +{ + return !protectAgainstXSS(); +} + +bool ContentSecurityPolicy::allowEval() const +{ + return !m_scriptSrc || (m_options && m_options->evalScript()); } bool ContentSecurityPolicy::allowScriptFromSource(const KURL& url) const @@ -440,6 +508,31 @@ bool ContentSecurityPolicy::allowScriptFromSource(const KURL& url) const return !m_scriptSrc || m_scriptSrc->allows(url); } +bool ContentSecurityPolicy::allowObjectFromSource(const KURL& url) const +{ + return !m_objectSrc || m_objectSrc->allows(url); +} + +bool ContentSecurityPolicy::allowImageFromSource(const KURL& url) const +{ + return !m_imgSrc || m_imgSrc->allows(url); +} + +bool ContentSecurityPolicy::allowStyleFromSource(const KURL& url) const +{ + return !m_styleSrc || m_styleSrc->allows(url); +} + +bool ContentSecurityPolicy::allowFontFromSource(const KURL& url) const +{ + return !m_fontSrc || m_fontSrc->allows(url); +} + +bool ContentSecurityPolicy::allowMediaFromSource(const KURL& url) const +{ + return !m_mediaSrc || m_mediaSrc->allows(url); +} + // policy = directive-list // directive-list = [ directive *( ";" [ directive ] ) ] // @@ -514,11 +607,29 @@ bool ContentSecurityPolicy::parseDirective(const UChar* begin, const UChar* end, void ContentSecurityPolicy::addDirective(const String& name, const String& value) { DEFINE_STATIC_LOCAL(String, scriptSrc, ("script-src")); + DEFINE_STATIC_LOCAL(String, objectSrc, ("object-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, options, ("options")); ASSERT(!name.isEmpty()); if (!m_scriptSrc && equalIgnoringCase(name, scriptSrc)) m_scriptSrc = adoptPtr(new CSPDirective(value, m_origin.get())); + else if (!m_objectSrc && equalIgnoringCase(name, objectSrc)) + m_objectSrc = adoptPtr(new CSPDirective(value, m_origin.get())); + else if (!m_imgSrc && equalIgnoringCase(name, imgSrc)) + m_imgSrc = adoptPtr(new CSPDirective(value, m_origin.get())); + else if (!m_styleSrc && equalIgnoringCase(name, styleSrc)) + m_styleSrc = adoptPtr(new CSPDirective(value, m_origin.get())); + else if (!m_fontSrc && equalIgnoringCase(name, fontSrc)) + m_fontSrc = adoptPtr(new CSPDirective(value, m_origin.get())); + else if (!m_mediaSrc && equalIgnoringCase(name, mediaSrc)) + m_mediaSrc = adoptPtr(new CSPDirective(value, m_origin.get())); + else if (!m_options && equalIgnoringCase(name, options)) + m_options = adoptPtr(new CSPOptions(value)); } } diff --git a/Source/WebCore/page/ContentSecurityPolicy.h b/Source/WebCore/page/ContentSecurityPolicy.h index a7cd216..2b430f4 100644 --- a/Source/WebCore/page/ContentSecurityPolicy.h +++ b/Source/WebCore/page/ContentSecurityPolicy.h @@ -32,6 +32,7 @@ namespace WebCore { class CSPDirective; +class CSPOptions; class KURL; class SecurityOrigin; @@ -47,11 +48,21 @@ public: bool allowJavaScriptURLs() const; bool allowInlineEventHandlers() const; + bool allowInlineScript() const; + bool allowEval() const; + bool allowScriptFromSource(const KURL&) const; + bool allowObjectFromSource(const KURL&) const; + bool allowImageFromSource(const KURL&) const; + bool allowStyleFromSource(const KURL&) const; + bool allowFontFromSource(const KURL&) const; + bool allowMediaFromSource(const KURL&) const; private: explicit ContentSecurityPolicy(SecurityOrigin*); + bool protectAgainstXSS() const; + void parse(const String&); bool parseDirective(const UChar* begin, const UChar* end, String& name, String& value); void addDirective(const String& name, const String& value); @@ -59,6 +70,12 @@ private: bool m_havePolicy; RefPtr<SecurityOrigin> m_origin; OwnPtr<CSPDirective> m_scriptSrc; + OwnPtr<CSPDirective> m_objectSrc; + OwnPtr<CSPDirective> m_imgSrc; + OwnPtr<CSPDirective> m_styleSrc; + OwnPtr<CSPDirective> m_fontSrc; + OwnPtr<CSPDirective> m_mediaSrc; + OwnPtr<CSPOptions> m_options; }; } diff --git a/Source/WebCore/page/DOMSelection.cpp b/Source/WebCore/page/DOMSelection.cpp index 31ab956..2e4e09c 100644 --- a/Source/WebCore/page/DOMSelection.cpp +++ b/Source/WebCore/page/DOMSelection.cpp @@ -332,6 +332,8 @@ void DOMSelection::modify(const String& alterString, const String& directionStri granularity = ParagraphBoundary; else if (equalIgnoringCase(granularityString, "documentboundary")) granularity = DocumentBoundary; + else if (equalIgnoringCase(granularityString, "-webkit-visual-word")) + granularity = WebKitVisualWordGranularity; else return; @@ -472,14 +474,14 @@ bool DOMSelection::containsNode(const Node* n, bool allowPartial) const return false; ExceptionCode ec = 0; - bool nodeFullySelected = Range::compareBoundaryPoints(parentNode, nodeIndex, selectedRange->startContainer(ec), selectedRange->startOffset(ec)) >= 0 - && Range::compareBoundaryPoints(parentNode, nodeIndex + 1, selectedRange->endContainer(ec), selectedRange->endOffset(ec)) <= 0; + bool nodeFullySelected = Range::compareBoundaryPoints(parentNode, nodeIndex, selectedRange->startContainer(ec), selectedRange->startOffset(ec), ec) >= 0 && !ec + && Range::compareBoundaryPoints(parentNode, nodeIndex + 1, selectedRange->endContainer(ec), selectedRange->endOffset(ec), ec) <= 0 && !ec; ASSERT(!ec); if (nodeFullySelected) return true; - bool nodeFullyUnselected = Range::compareBoundaryPoints(parentNode, nodeIndex, selectedRange->endContainer(ec), selectedRange->endOffset(ec)) > 0 - || Range::compareBoundaryPoints(parentNode, nodeIndex + 1, selectedRange->startContainer(ec), selectedRange->startOffset(ec)) < 0; + bool nodeFullyUnselected = (Range::compareBoundaryPoints(parentNode, nodeIndex, selectedRange->endContainer(ec), selectedRange->endOffset(ec), ec) > 0 && !ec) + || (Range::compareBoundaryPoints(parentNode, nodeIndex + 1, selectedRange->startContainer(ec), selectedRange->startOffset(ec), ec) < 0 && !ec); ASSERT(!ec); if (nodeFullyUnselected) return false; diff --git a/Source/WebCore/page/DOMWindow.cpp b/Source/WebCore/page/DOMWindow.cpp index 90458ff..fda46df 100644 --- a/Source/WebCore/page/DOMWindow.cpp +++ b/Source/WebCore/page/DOMWindow.cpp @@ -86,6 +86,7 @@ #include "Settings.h" #include "Storage.h" #include "StorageArea.h" +#include "StorageInfo.h" #include "StorageNamespace.h" #include "StyleMedia.h" #include "SuddenTermination.h" @@ -743,7 +744,7 @@ IDBFactory* DOMWindow::webkitIndexedDB() const #endif #if ENABLE(FILE_SYSTEM) -void DOMWindow::requestFileSystem(int type, long long size, PassRefPtr<FileSystemCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) +void DOMWindow::webkitRequestFileSystem(int type, long long size, PassRefPtr<FileSystemCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) { Document* document = this->document(); if (!document) @@ -755,7 +756,7 @@ void DOMWindow::requestFileSystem(int type, long long size, PassRefPtr<FileSyste } AsyncFileSystem::Type fileSystemType = static_cast<AsyncFileSystem::Type>(type); - if (fileSystemType != AsyncFileSystem::Temporary && fileSystemType != AsyncFileSystem::Persistent) { + if (fileSystemType != AsyncFileSystem::Temporary && fileSystemType != AsyncFileSystem::Persistent && fileSystemType != AsyncFileSystem::External) { DOMFileSystem::scheduleCallback(document, errorCallback, FileError::create(FileError::INVALID_MODIFICATION_ERR)); return; } @@ -763,7 +764,7 @@ void DOMWindow::requestFileSystem(int type, long long size, PassRefPtr<FileSyste LocalFileSystem::localFileSystem().requestFileSystem(document, fileSystemType, size, FileSystemCallbacks::create(successCallback, errorCallback, document), false); } -void DOMWindow::resolveLocalFileSystemURL(const String& url, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) +void DOMWindow::webkitResolveLocalFileSystemURL(const String& url, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) { Document* document = this->document(); if (!document) @@ -786,6 +787,8 @@ void DOMWindow::resolveLocalFileSystemURL(const String& url, PassRefPtr<EntryCal LocalFileSystem::localFileSystem().readFileSystem(document, type, ResolveURICallbacks::create(successCallback, errorCallback, document, filePath)); } +COMPILE_ASSERT(static_cast<int>(DOMWindow::EXTERNAL) == static_cast<int>(AsyncFileSystem::External), enum_mismatch); + COMPILE_ASSERT(static_cast<int>(DOMWindow::TEMPORARY) == static_cast<int>(AsyncFileSystem::Temporary), enum_mismatch); COMPILE_ASSERT(static_cast<int>(DOMWindow::PERSISTENT) == static_cast<int>(AsyncFileSystem::Persistent), enum_mismatch); @@ -1867,6 +1870,9 @@ void DOMWindow::showModalDialog(const String& urlString, const String& dialogFea if (!firstFrame) return; + if (m_frame->page()) + m_frame->page()->chrome()->willRunModalHTMLDialog(m_frame); + if (!canShowModalDialogNow(m_frame) || !firstWindow->allowPopUp()) return; @@ -1887,4 +1893,13 @@ DOMURL* DOMWindow::webkitURL() const } #endif +#if ENABLE(QUOTA) +StorageInfo* DOMWindow::webkitStorageInfo() const +{ + if (!m_storageInfo) + m_storageInfo = StorageInfo::create(); + return m_storageInfo.get(); +} +#endif + } // namespace WebCore diff --git a/Source/WebCore/page/DOMWindow.h b/Source/WebCore/page/DOMWindow.h index 404f40f..14ae79c 100644 --- a/Source/WebCore/page/DOMWindow.h +++ b/Source/WebCore/page/DOMWindow.h @@ -64,6 +64,7 @@ namespace WebCore { class Screen; class SerializedScriptValue; class Storage; + class StorageInfo; class StyleMedia; class WebKitPoint; @@ -284,8 +285,6 @@ namespace WebCore { DEFINE_ATTRIBUTE_EVENT_LISTENER(ended); DEFINE_ATTRIBUTE_EVENT_LISTENER(error); DEFINE_ATTRIBUTE_EVENT_LISTENER(focus); - DEFINE_ATTRIBUTE_EVENT_LISTENER(formchange); - DEFINE_ATTRIBUTE_EVENT_LISTENER(forminput); DEFINE_ATTRIBUTE_EVENT_LISTENER(hashchange); DEFINE_ATTRIBUTE_EVENT_LISTENER(input); DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid); @@ -391,9 +390,10 @@ namespace WebCore { enum FileSystemType { TEMPORARY, PERSISTENT, + EXTERNAL, }; - void requestFileSystem(int type, long long size, PassRefPtr<FileSystemCallback>, PassRefPtr<ErrorCallback>); - void resolveLocalFileSystemURL(const String&, PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>); + void webkitRequestFileSystem(int type, long long size, PassRefPtr<FileSystemCallback>, PassRefPtr<ErrorCallback>); + void webkitResolveLocalFileSystemURL(const String&, PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>); #endif #if ENABLE(INDEXED_DATABASE) @@ -404,6 +404,10 @@ namespace WebCore { NotificationCenter* webkitNotifications() const; #endif +#if ENABLE(QUOTA) + StorageInfo* webkitStorageInfo() const; +#endif + #if ENABLE(OFFLINE_WEB_APPLICATIONS) DOMApplicationCache* applicationCache() const; DOMApplicationCache* optionalApplicationCache() const { return m_applicationCache.get(); } @@ -496,6 +500,10 @@ namespace WebCore { #if ENABLE(BLOB) mutable RefPtr<DOMURL> m_domURL; #endif + +#if ENABLE(QUOTA) + mutable RefPtr<StorageInfo> m_storageInfo; +#endif }; inline String DOMWindow::status() const diff --git a/Source/WebCore/page/DOMWindow.idl b/Source/WebCore/page/DOMWindow.idl index 8c6e929..9f7313c 100644 --- a/Source/WebCore/page/DOMWindow.idl +++ b/Source/WebCore/page/DOMWindow.idl @@ -194,10 +194,10 @@ module window { #if defined(ENABLE_FILE_SYSTEM) && ENABLE_FILE_SYSTEM const unsigned short TEMPORARY = 0; const unsigned short PERSISTENT = 1; - [EnabledAtRuntime=FileSystem] void requestFileSystem(in unsigned short type, in long long size, in [Callback, Optional] FileSystemCallback successCallback, in [Callback, Optional] ErrorCallback errorCallback); - [EnabledAtRuntime=FileSystem] void resolveLocalFileSystemURL(in DOMString url, in [Callback, Optional] EntryCallback successCallback, in [Callback, Optional] ErrorCallback errorCallback); + [EnabledAtRuntime=FileSystem] void webkitRequestFileSystem(in unsigned short type, in long long size, in [Callback, Optional] FileSystemCallback successCallback, in [Callback, Optional] ErrorCallback errorCallback); + [EnabledAtRuntime=FileSystem] void webkitResolveLocalFileSystemURL(in DOMString url, in [Callback, Optional] EntryCallback successCallback, in [Callback, Optional] ErrorCallback errorCallback); - attribute [EnabledAtRuntime=FileSystem] FlagsConstructor Flags; + attribute [EnabledAtRuntime=FileSystem] WebKitFlagsConstructor WebKitFlags; #endif #if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS @@ -268,8 +268,6 @@ module window { attribute EventListener onended; attribute EventListener onerror; attribute EventListener onfocus; - attribute EventListener onformchange; - attribute EventListener onforminput; attribute EventListener onhashchange; attribute EventListener oninput; attribute EventListener oninvalid; @@ -785,10 +783,14 @@ module window { attribute [Conditional=BLOB|FILE_SYSTEM] FileErrorConstructor FileError; attribute [Conditional=BLOB] FileReaderConstructor FileReader; - attribute [Conditional=BLOB] BlobBuilderConstructor BlobBuilder; + attribute [Conditional=BLOB] WebKitBlobBuilderConstructor WebKitBlobBuilder; readonly attribute [Conditional=BLOB] DOMURL webkitURL; +#if defined(ENABLE_QUOTA) && ENABLE_QUOTA + readonly attribute [EnabledAtRuntime=Quota] StorageInfo webkitStorageInfo; +#endif + #endif // defined(LANGUAGE_JAVASCRIPT) #if defined(V8_BINDING) && V8_BINDING diff --git a/Source/WebCore/page/EditorClient.h b/Source/WebCore/page/EditorClient.h index aeda844..df24a5b 100644 --- a/Source/WebCore/page/EditorClient.h +++ b/Source/WebCore/page/EditorClient.h @@ -27,7 +27,7 @@ #ifndef EditorClient_h #define EditorClient_h -#include "CorrectionPanelInfo.h" +#include "SpellingCorrectionController.h" #include "EditorInsertAction.h" #include "FloatRect.h" #include "PlatformString.h" diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp index de59083..d5ba4de 100644 --- a/Source/WebCore/page/EventHandler.cpp +++ b/Source/WebCore/page/EventHandler.cpp @@ -79,6 +79,7 @@ #include "UserGestureIndicator.h" #include "UserTypingGestureIndicator.h" #include "WheelEvent.h" +#include "WindowsKeyboardCodes.h" #include <wtf/CurrentTime.h> #include <wtf/StdLibExtras.h> @@ -133,8 +134,6 @@ const double autoscrollInterval = 0.05; const double fakeMouseMoveInterval = 0.1; -static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&); - static inline bool scrollNode(float delta, WheelEvent::Granularity granularity, ScrollDirection positiveDirection, ScrollDirection negativeDirection, Node* node, Node** stopNode) { if (!delta) @@ -283,7 +282,7 @@ static void setNonDirectionalSelectionIfNeeded(SelectionController* selection, c void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& result) { - Node* innerNode = result.targetNode(); + Node* innerNode = targetNode(result); VisibleSelection newSelection; if (innerNode && innerNode->renderer() && m_mouseDownMayStartSelect) { @@ -310,7 +309,7 @@ void EventHandler::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHit if (!result.hitTestResult().isLiveLink()) return selectClosestWordFromMouseEvent(result); - Node* innerNode = result.targetNode(); + Node* innerNode = targetNode(result); if (innerNode && innerNode->renderer() && m_mouseDownMayStartSelect) { VisibleSelection newSelection; @@ -352,7 +351,7 @@ bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestR if (event.event().button() != LeftButton) return false; - Node* innerNode = event.targetNode(); + Node* innerNode = targetNode(event); if (!(innerNode && innerNode->renderer() && m_mouseDownMayStartSelect)) return false; @@ -382,7 +381,7 @@ static int textDistance(const Position& start, const Position& end) bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event) { - Node* innerNode = event.targetNode(); + Node* innerNode = targetNode(event); if (!(innerNode && innerNode->renderer() && m_mouseDownMayStartSelect)) return false; @@ -458,7 +457,7 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve // If we got the event back, that must mean it wasn't prevented, // so it's allowed to start a drag or selection. - m_mouseDownMayStartSelect = canMouseDownStartSelect(event.targetNode()); + m_mouseDownMayStartSelect = canMouseDownStartSelect(targetNode(event)); #if ENABLE(DRAG_SUPPORT) // Careful that the drag starting logic stays in sync with eventMayStartDrag() @@ -488,7 +487,7 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve if (singleClick) focusDocumentView(); - Node* innerNode = event.targetNode(); + Node* innerNode = targetNode(event); m_mousePressNode = innerNode; #if ENABLE(DRAG_SUPPORT) @@ -545,7 +544,7 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e if (!m_mousePressed) return false; - Node* targetNode = event.targetNode(); + Node* targetNode = EventHandler::targetNode(event); if (event.event().button() != LeftButton || !targetNode || !targetNode->renderer()) return false; @@ -577,9 +576,10 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active); HitTestResult result(m_mouseDownPos); m_frame->document()->renderView()->layer()->hitTest(request, result); - updateSelectionForMouseDrag(result.innerNode(), result.localPoint()); + + updateSelectionForMouseDrag(result); } - updateSelectionForMouseDrag(targetNode, event.localPoint()); + updateSelectionForMouseDrag(event.hitTestResult()); return true; } @@ -629,25 +629,42 @@ void EventHandler::updateSelectionForMouseDrag() HitTestRequest::MouseMove); HitTestResult result(view->windowToContents(m_currentMousePosition)); layer->hitTest(request, result); - updateSelectionForMouseDrag(result.innerNode(), result.localPoint()); + updateSelectionForMouseDrag(result); } -void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint& localPoint) +static VisiblePosition selectionExtentRespectingEditingBoundary(const VisibleSelection& selection, const IntPoint& localPoint, Node* targetNode) { - if (!m_mouseDownMayStartSelect) - return; + IntPoint selectionEndPoint = localPoint; + Element* editableElement = selection.rootEditableElement(); - if (!targetNode) + if (!targetNode->renderer()) + return VisiblePosition(); + + if (editableElement && !editableElement->contains(targetNode)) { + if (!editableElement->renderer()) + return VisiblePosition(); + + FloatPoint absolutePoint = targetNode->renderer()->localToAbsolute(FloatPoint(selectionEndPoint)); + selectionEndPoint = roundedIntPoint(editableElement->renderer()->absoluteToLocal(absolutePoint)); + targetNode = editableElement; + } + + return targetNode->renderer()->positionForPoint(selectionEndPoint); +} + +void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResult) +{ + if (!m_mouseDownMayStartSelect) return; - if (!canMouseDragExtendSelect(targetNode)) + Node* target = targetNode(hitTestResult); + if (!target) return; - RenderObject* targetRenderer = targetNode->renderer(); - if (!targetRenderer) + if (!canMouseDragExtendSelect(target)) return; - VisiblePosition targetPosition(targetRenderer->positionForPoint(localPoint)); + VisiblePosition targetPosition = selectionExtentRespectingEditingBoundary(m_frame->selection()->selection(), hitTestResult.localPoint(), target); // Don't modify the selection if we're not on a node. if (targetPosition.isNull()) @@ -663,7 +680,7 @@ void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint& if (Node* selectionBaseNode = newSelection.base().deprecatedNode()) if (RenderObject* selectionBaseRenderer = selectionBaseNode->renderer()) if (selectionBaseRenderer->isSVGText()) - if (targetNode->renderer()->containingBlock() != selectionBaseRenderer->containingBlock()) + if (target->renderer()->containingBlock() != selectionBaseRenderer->containingBlock()) return; #endif @@ -731,7 +748,7 @@ bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e && m_frame->selection()->isRange() && event.event().button() != RightButton) { VisibleSelection newSelection; - Node* node = event.targetNode(); + Node* node = targetNode(event); bool caretBrowsing = m_frame->settings()->caretBrowsingEnabled(); if (node && (caretBrowsing || node->rendererIsEditable()) && node->renderer()) { VisiblePosition pos = node->renderer()->positionForPoint(event.localPoint()); @@ -1106,11 +1123,11 @@ IntPoint EventHandler::currentMousePosition() const return m_currentMousePosition; } -Frame* subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResult) +Frame* EventHandler::subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResult) { if (!hitTestResult.isOverWidget()) return 0; - return EventHandler::subframeForTargetNode(hitTestResult.targetNode()); + return subframeForTargetNode(targetNode(hitTestResult)); } Frame* EventHandler::subframeForTargetNode(Node* node) @@ -1142,7 +1159,7 @@ static bool nodeIsNotBeingEdited(Node* node, Frame* frame) Cursor EventHandler::selectCursor(const MouseEventWithHitTestResults& event, Scrollbar* scrollbar) { - Node* node = event.targetNode(); + Node* node = targetNode(event); RenderObject* renderer = node ? node->renderer() : 0; RenderStyle* style = renderer ? renderer->style() : 0; @@ -1307,6 +1324,27 @@ static IntPoint documentPointForWindowPoint(Frame* frame, const IntPoint& window return view ? view->windowToContents(windowPoint) : windowPoint; } +Node* EventHandler::targetNode(const MouseEventWithHitTestResults& event) +{ + return targetNode(event.hitTestResult()); +} + +Node* EventHandler::targetNode(const HitTestResult& hitTestResult) +{ + Node* node = hitTestResult.innerNode(); + if (!node) + return 0; + if (node->inDocument()) + return node; + + Element* element = node->parentElement(); + if (element && element->inDocument()) + return element; + + return node; + +} + bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent) { RefPtr<FrameView> protector(m_frame->view()); @@ -1344,12 +1382,12 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent) IntPoint documentPoint = documentPointForWindowPoint(m_frame, mouseEvent.pos()); MouseEventWithHitTestResults mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent); - if (!mev.targetNode()) { + if (!targetNode(mev)) { invalidateClick(); return false; } - m_mousePressNode = mev.targetNode(); + m_mousePressNode = targetNode(mev); if (InspectorInstrumentation::handleMousePress(m_frame->page())) { invalidateClick(); @@ -1362,7 +1400,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent) // the m_mousePressed flag, which may happen if an AppKit widget entered a modal event loop. m_capturesDragging = subframe->eventHandler()->capturesDragging(); if (m_mousePressed && m_capturesDragging) { - m_capturingMouseEventsNode = mev.targetNode(); + m_capturingMouseEventsNode = targetNode(mev); m_eventHandlerWillResetCapturingMouseEventsNode = true; } invalidateClick(); @@ -1370,16 +1408,21 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent) } #if ENABLE(PAN_SCROLLING) - Page* page = m_frame->page(); - if ((page && page->mainFrame()->eventHandler()->panScrollInProgress()) || m_autoscrollInProgress) { + // We store whether pan scrolling is in progress before calling stopAutoscrollTimer() + // because it will set m_panScrollInProgress to false on return. + bool isPanScrollInProgress = m_frame->page() && m_frame->page()->mainFrame()->eventHandler()->panScrollInProgress(); + if (isPanScrollInProgress || m_autoscrollInProgress) stopAutoscrollTimer(); + if (isPanScrollInProgress) { + // We invalidate the click when exiting pan scrolling so that we don't inadvertently navigate + // away from the current page (e.g. the click was on a hyperlink). See <rdar://problem/6095023>. invalidateClick(); return true; } #endif m_clickCount = mouseEvent.clickCount(); - m_clickNode = mev.targetNode(); + m_clickNode = targetNode(mev); if (FrameView* view = m_frame->view()) { RenderLayer* layer = m_clickNode->renderer() ? m_clickNode->renderer()->enclosingLayer() : 0; @@ -1395,7 +1438,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent) m_frame->selection()->setCaretBlinkingSuspended(true); - bool swallowEvent = dispatchMouseEvent(eventNames().mousedownEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true); + bool swallowEvent = dispatchMouseEvent(eventNames().mousedownEvent, targetNode(mev), true, m_clickCount, mouseEvent, true); m_capturesDragging = !swallowEvent; // If the hit testing originally determined the event was in a scrollbar, refetch the MouseEventWithHitTestResults @@ -1421,7 +1464,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent) // If a mouse event handler changes the input element type to one that has a widget associated, // we'd like to EventHandler::handleMousePressEvent to pass the event to the widget and thus the // event target node can't still be the shadow node. - if (mev.targetNode()->isShadowRoot() && mev.targetNode()->shadowHost()->hasTagName(inputTag)) { + if (targetNode(mev)->isShadowRoot() && targetNode(mev)->shadowHost()->hasTagName(inputTag)) { HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active); mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent); } @@ -1462,9 +1505,9 @@ bool EventHandler::handleMouseDoubleClickEvent(const PlatformMouseEvent& mouseEv return true; m_clickCount = mouseEvent.clickCount(); - bool swallowMouseUpEvent = dispatchMouseEvent(eventNames().mouseupEvent, mev.targetNode(), true, m_clickCount, mouseEvent, false); + bool swallowMouseUpEvent = dispatchMouseEvent(eventNames().mouseupEvent, targetNode(mev), true, m_clickCount, mouseEvent, false); - bool swallowClickEvent = mouseEvent.button() != RightButton && mev.targetNode() == m_clickNode && dispatchMouseEvent(eventNames().clickEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true); + bool swallowClickEvent = mouseEvent.button() != RightButton && targetNode(mev) == m_clickNode && dispatchMouseEvent(eventNames().clickEvent, targetNode(mev), true, m_clickCount, mouseEvent, true); if (m_lastScrollbarUnderMouse) swallowMouseUpEvent = m_lastScrollbarUnderMouse->mouseUp(); @@ -1590,7 +1633,7 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi if (newSubframe) { // Update over/out state before passing the event to the subframe. - updateMouseEventTargetNode(mev.targetNode(), mouseEvent, true); + updateMouseEventTargetNode(targetNode(mev), mouseEvent, true); // Event dispatch in updateMouseEventTargetNode may have caused the subframe of the target // node to be detached from its FrameView, in which case the event should not be passed. @@ -1605,8 +1648,8 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi // in case the particular plugin doesn't manipulate cursor at all. Thus, even a CSS cursor set on body has no // effect on plugins (which matches Firefox). bool overPluginElement = false; - if (mev.targetNode() && mev.targetNode()->isHTMLElement()) { - HTMLElement* el = toHTMLElement(mev.targetNode()); + if (targetNode(mev) && targetNode(mev)->isHTMLElement()) { + HTMLElement* el = toHTMLElement(targetNode(mev)); overPluginElement = el->hasTagName(appletTag) || el->hasTagName(objectTag) || el->hasTagName(embedTag); } if (!overPluginElement) { @@ -1622,7 +1665,7 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi if (swallowEvent) return true; - swallowEvent = dispatchMouseEvent(eventNames().mousemoveEvent, mev.targetNode(), false, 0, mouseEvent, true); + swallowEvent = dispatchMouseEvent(eventNames().mousemoveEvent, targetNode(mev), false, 0, mouseEvent, true); #if ENABLE(DRAG_SUPPORT) if (!swallowEvent) swallowEvent = handleMouseDraggedEvent(mev); @@ -1684,9 +1727,9 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent) if (subframe && passMouseReleaseEventToSubframe(mev, subframe)) return true; - bool swallowMouseUpEvent = dispatchMouseEvent(eventNames().mouseupEvent, mev.targetNode(), true, m_clickCount, mouseEvent, false); + bool swallowMouseUpEvent = dispatchMouseEvent(eventNames().mouseupEvent, targetNode(mev), true, m_clickCount, mouseEvent, false); - bool swallowClickEvent = m_clickCount > 0 && mouseEvent.button() != RightButton && mev.targetNode() == m_clickNode && dispatchMouseEvent(eventNames().clickEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true); + bool swallowClickEvent = m_clickCount > 0 && mouseEvent.button() != RightButton && targetNode(mev) == m_clickNode && dispatchMouseEvent(eventNames().clickEvent, targetNode(mev), true, m_clickCount, mouseEvent, true); if (m_resizeLayer) { m_resizeLayer->setInResizeMode(false); @@ -1712,11 +1755,9 @@ bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTa return false; view->resetDeferredRepaintDelay(); - IntPoint contentsPos = view->windowToContents(event.pos()); - RefPtr<MouseEvent> me = MouseEvent::create(eventType, true, true, m_frame->document()->defaultView(), - 0, event.globalX(), event.globalY(), contentsPos.x(), contentsPos.y(), + 0, event.globalX(), event.globalY(), event.x(), event.y(), event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(), 0, 0, clipboard); @@ -1765,7 +1806,7 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* MouseEventWithHitTestResults mev = prepareMouseEvent(request, event); // Drag events should never go to text nodes (following IE, and proper mouseover/out dispatch) - Node* newTarget = mev.targetNode(); + Node* newTarget = targetNode(mev); if (newTarget && newTarget->isTextNode()) newTarget = newTarget->parentNode(); if (newTarget) @@ -2074,6 +2115,10 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e) HitTestResult result(vPoint); doc->renderView()->layer()->hitTest(request, result); +#if PLATFORM(MAC) + m_useLatchedWheelEventNode = e.momentumPhase() == PlatformWheelEventPhaseBegan || e.momentumPhase() == PlatformWheelEventPhaseChanged; +#endif + if (m_useLatchedWheelEventNode) { if (!m_latchedWheelEventNode) { m_latchedWheelEventNode = result.innerNode(); @@ -2108,9 +2153,10 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e) } node = node->shadowAncestorNode(); - node->dispatchWheelEvent(e); - if (e.isAccepted()) + if (!node->dispatchWheelEvent(e)) { + e.accept(); return true; + } } if (e.isAccepted()) @@ -2178,12 +2224,12 @@ bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event) // FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse. // If the selection is non-editable, we do word selection to make it easier to use the contextual menu items // available for text selections. But only if we're above text. - && (m_frame->selection()->isContentEditable() || (mev.targetNode() && mev.targetNode()->isTextNode()))) { + && (m_frame->selection()->isContentEditable() || (targetNode(mev) && targetNode(mev)->isTextNode()))) { m_mouseDownMayStartSelect = true; // context menu events are always allowed to perform a selection selectClosestWordOrLinkFromMouseEvent(mev); } - swallowEvent = dispatchMouseEvent(eventNames().contextmenuEvent, mev.targetNode(), true, 0, event, false); + swallowEvent = dispatchMouseEvent(eventNames().contextmenuEvent, targetNode(mev), true, 0, event, false); return swallowEvent; } @@ -2414,6 +2460,9 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent) { RefPtr<FrameView> protector(m_frame->view()); + if (initialKeyEvent.windowsVirtualKeyCode() == VK_CAPITAL) + capsLockStateMayHaveChanged(); + #if ENABLE(PAN_SCROLLING) if (Page* page = m_frame->page()) { if (page->mainFrame()->eventHandler()->panScrollInProgress() || m_autoscrollInProgress) { @@ -2553,6 +2602,8 @@ void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event) return; if (event->keyIdentifier() == "U+0009") defaultTabEventHandler(event); + else if (event->keyIdentifier() == "U+0008") + defaultBackspaceEventHandler(event); else { FocusDirection direction = focusDirectionForKey(event->keyIdentifier()); if (direction != FocusDirectionNone) @@ -2854,20 +2905,30 @@ void EventHandler::defaultTextInputEventHandler(TextEvent* event) event->setDefaultHandled(); } +<<<<<<< HEAD #if PLATFORM(QT) || PLATFORM(MAC) || PLATFORM(ANDROID) // These two platforms handle the space event in the platform-specific WebKit code. // Eventually it would be good to eliminate that and use the code here instead, but // the Qt version is inside an ifdef and the Mac version has some extra behavior // so we can't unify everything yet. +======= +#if PLATFORM(QT) +// Qt handles the space event in platform-specific WebKit code. +// Eventually it would be good to eliminate that and use the code here instead. +>>>>>>> WebKit.org at r84325 void EventHandler::defaultSpaceEventHandler(KeyboardEvent*) { } - #else void EventHandler::defaultSpaceEventHandler(KeyboardEvent* event) { + ASSERT(event->type() == eventNames().keypressEvent); + + if (event->ctrlKey() || event->metaKey() || event->altKey() || event->altGraphKey()) + return; + ScrollLogicalDirection direction = event->shiftKey() ? ScrollBlockDirectionBackward : ScrollBlockDirectionForward; if (logicalScrollOverflow(direction, ScrollByPage)) { event->setDefaultHandled(); @@ -2884,8 +2945,33 @@ void EventHandler::defaultSpaceEventHandler(KeyboardEvent* event) #endif +void EventHandler::defaultBackspaceEventHandler(KeyboardEvent* event) +{ + ASSERT(event->type() == eventNames().keydownEvent); + + if (event->ctrlKey() || event->metaKey() || event->altKey() || event->altGraphKey()) + return; + + Page* page = m_frame->page(); + if (!page) + return; + + bool handledEvent = false; + + if (event->shiftKey()) + handledEvent = page->goForward(); + else + handledEvent = page->goBack(); + + if (handledEvent) + event->setDefaultHandled(); +} + + void EventHandler::defaultArrowEventHandler(FocusDirection focusDirection, KeyboardEvent* event) { + ASSERT(event->type() == eventNames().keydownEvent); + if (event->ctrlKey() || event->metaKey() || event->altGraphKey() || event->shiftKey()) return; @@ -2907,6 +2993,8 @@ void EventHandler::defaultArrowEventHandler(FocusDirection focusDirection, Keybo void EventHandler::defaultTabEventHandler(KeyboardEvent* event) { + ASSERT(event->type() == eventNames().keydownEvent); + // We should only advance focus on tabs if no special modifier keys are held down. if (event->ctrlKey() || event->metaKey() || event->altGraphKey()) return; @@ -2947,7 +3035,7 @@ void EventHandler::sendScrollEvent() { setFrameWasScrolledByUser(); if (m_frame->view() && m_frame->document()) - m_frame->document()->eventQueue()->enqueueScrollEvent(m_frame->document(), EventQueue::ScrollEventDocumentTarget); + m_frame->document()->eventQueue()->enqueueOrDispatchScrollEvent(m_frame->document(), EventQueue::ScrollEventDocumentTarget); } void EventHandler::setFrameWasScrolledByUser() diff --git a/Source/WebCore/page/EventHandler.h b/Source/WebCore/page/EventHandler.h index 70d6194..7b4bcce 100644 --- a/Source/WebCore/page/EventHandler.h +++ b/Source/WebCore/page/EventHandler.h @@ -143,6 +143,7 @@ public: void setIgnoreWheelEvents(bool); static Frame* subframeForTargetNode(Node*); + static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&); bool scrollOverflow(ScrollDirection, ScrollGranularity, Node* startingNode = 0); bool logicalScrollOverflow(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0); @@ -264,13 +265,16 @@ private: PassRefPtr<Clipboard> createDraggingClipboard() const; #endif // ENABLE(DRAG_SUPPORT) - + bool eventActivatedView(const PlatformMouseEvent&) const; void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&); void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&); bool handleMouseDoubleClickEvent(const PlatformMouseEvent&); + static Node* targetNode(const MouseEventWithHitTestResults&); + static Node* targetNode(const HitTestResult&); + bool handleMousePressEvent(const MouseEventWithHitTestResults&); bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&); bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&); @@ -344,6 +348,7 @@ private: bool passWheelEventToWidget(PlatformWheelEvent&, Widget*); void defaultSpaceEventHandler(KeyboardEvent*); + void defaultBackspaceEventHandler(KeyboardEvent*); void defaultTabEventHandler(KeyboardEvent*); void defaultArrowEventHandler(FocusDirection, KeyboardEvent*); @@ -359,7 +364,7 @@ private: #endif #if ENABLE(DRAG_SUPPORT) - void updateSelectionForMouseDrag(Node* targetNode, const IntPoint& localPoint); + void updateSelectionForMouseDrag(const HitTestResult&); #endif void updateLastScrollbarUnderMouse(Scrollbar*, bool); diff --git a/Source/WebCore/page/EventSource.cpp b/Source/WebCore/page/EventSource.cpp index 08d0868..2a52bcb 100644 --- a/Source/WebCore/page/EventSource.cpp +++ b/Source/WebCore/page/EventSource.cpp @@ -2,6 +2,7 @@ * Copyright (C) 2009 Ericsson AB * All rights reserved. * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2011, Code Aurora Forum. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -45,6 +46,7 @@ #include "ResourceError.h" #include "ResourceRequest.h" #include "ResourceResponse.h" +#include "ScriptCallStack.h" #include "ScriptExecutionContext.h" #include "SerializedScriptValue.h" #include "TextResourceDecoder.h" @@ -180,7 +182,32 @@ ScriptExecutionContext* EventSource::scriptExecutionContext() const void EventSource::didReceiveResponse(const ResourceResponse& response) { int statusCode = response.httpStatusCode(); - if (statusCode == 200 && response.mimeType() == "text/event-stream") { + bool mimeTypeIsValid = response.mimeType() == "text/event-stream"; + bool responseIsValid = statusCode == 200 && mimeTypeIsValid; + if (responseIsValid) { + const String& charset = response.textEncodingName(); + // If we have a charset, the only allowed value is UTF-8 (case-insensitive). This should match + // the updated EventSource standard. + 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."; + // FIXME: We are missing the source line. + scriptExecutionContext()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message, 1, String(), 0); + } + } 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."; + // FIXME: We are missing the source line. + scriptExecutionContext()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message, 1, String(), 0); + } + } + + if (responseIsValid) { m_state = OPEN; dispatchEvent(Event::create(eventNames().openEvent, false, false)); } else { diff --git a/Source/WebCore/page/FocusController.cpp b/Source/WebCore/page/FocusController.cpp index 41cfee4..5b91eeb 100644 --- a/Source/WebCore/page/FocusController.cpp +++ b/Source/WebCore/page/FocusController.cpp @@ -170,7 +170,15 @@ static Node* deepFocusableNode(FocusDirection direction, Node* node, KeyboardEve bool FocusController::setInitialFocus(FocusDirection direction, KeyboardEvent* event) { - return advanceFocus(direction, event, true); + bool didAdvanceFocus = advanceFocus(direction, event, true); + + // If focus is being set initially, accessibility needs to be informed that system focus has moved + // into the web area again, even if focus did not change within WebCore. PostNotification is called instead + // of handleFocusedUIElementChanged, because this will send the notification even if the element is the same. + if (AXObjectCache::accessibilityEnabled()) + focusedOrMainFrame()->document()->axObjectCache()->postNotification(focusedOrMainFrame()->document()->renderer(), AXObjectCache::AXFocusedUIElementChanged, true); + + return didAdvanceFocus; } bool FocusController::advanceFocus(FocusDirection direction, KeyboardEvent* event, bool initialFocus) @@ -589,6 +597,9 @@ bool FocusController::advanceFocusDirectionally(FocusDirection direction, Keyboa Node* focusedNode = focusedDocument->focusedNode(); Node* container = focusedDocument; + if (container->isDocumentNode()) + static_cast<Document*>(container)->updateLayoutIgnorePendingStylesheets(); + // Figure out the starting rect. IntRect startingRect; if (focusedNode) { @@ -604,11 +615,11 @@ bool FocusController::advanceFocusDirectionally(FocusDirection direction, Keyboa bool consumed = false; do { - if (container->isDocumentNode()) - static_cast<Document*>(container)->updateLayoutIgnorePendingStylesheets(); consumed = advanceFocusDirectionallyInContainer(container, startingRect, direction, event); startingRect = nodeRectInAbsoluteCoordinates(container, true /* ignore border */); container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(direction, container); + if (container && container->isDocumentNode()) + static_cast<Document*>(container)->updateLayoutIgnorePendingStylesheets(); } while (!consumed && container); return consumed; diff --git a/Source/WebCore/page/Frame.cpp b/Source/WebCore/page/Frame.cpp index 3652c9a..c3b56e7 100644 --- a/Source/WebCore/page/Frame.cpp +++ b/Source/WebCore/page/Frame.cpp @@ -5,7 +5,7 @@ * 2000 Simon Hausmann <hausmann@kde.org> * 2000 Stefan Schimanski <1Stein@gmx.de> * 2001 George Staikos <staikos@kde.org> - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com> * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * Copyright (C) 2008 Eric Seidel <eric@webkit.org> @@ -72,6 +72,7 @@ #include "RenderView.h" #include "ScriptController.h" #include "ScriptSourceCode.h" +#include "ScriptValue.h" #include "Settings.h" #include "TextIterator.h" #include "TextResourceDecoder.h" @@ -522,9 +523,9 @@ void Frame::injectUserScripts(UserScriptInjectionTime injectionTime) if (!m_page) return; - if (loader()->stateMachine()->creatingInitialEmptyDocument()) + if (loader()->stateMachine()->creatingInitialEmptyDocument() && !settings()->shouldInjectUserScriptsInInitialEmptyDocument()) return; - + // Walk the hashtable. Inject by world. const UserScriptMap* userScripts = m_page->group().userScripts(); if (!userScripts) @@ -808,6 +809,31 @@ Document* Frame::documentAtPoint(const IntPoint& point) return result.innerNode() ? result.innerNode()->document() : 0; } +PassRefPtr<Range> Frame::rangeForPoint(const IntPoint& framePoint) +{ + VisiblePosition position = visiblePositionForPoint(framePoint); + if (position.isNull()) + return 0; + + VisiblePosition previous = position.previous(); + if (previous.isNotNull()) { + RefPtr<Range> previousCharacterRange = makeRange(previous, position); + IntRect rect = editor()->firstRectForRange(previousCharacterRange.get()); + if (rect.contains(framePoint)) + return previousCharacterRange.release(); + } + + VisiblePosition next = position.next(); + if (next.isNotNull()) { + RefPtr<Range> nextCharacterRange = makeRange(position, next); + IntRect rect = editor()->firstRectForRange(nextCharacterRange.get()); + if (rect.contains(framePoint)) + return nextCharacterRange.release(); + } + + return 0; +} + void Frame::createView(const IntSize& viewportSize, const Color& backgroundColor, bool transparent, const IntSize& fixedLayoutSize, bool useFixedLayout, @@ -947,6 +973,8 @@ void Frame::setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor if (!document) return; + m_editor.dismissCorrectionPanelAsIgnored(); + #if ENABLE(SVG) // Respect SVGs zoomAndPan="disabled" property in standalone SVG documents. // FIXME: How to handle compound documents + zoomAndPan="disabled"? Needs SVG WG clarification. @@ -999,16 +1027,18 @@ void Frame::scalePage(float scale, const IntPoint& origin) if (!document) return; - m_pageScaleFactor = scale; + if (scale != m_pageScaleFactor) { + m_pageScaleFactor = scale; - if (document->renderer()) - document->renderer()->setNeedsLayout(true); + if (document->renderer()) + document->renderer()->setNeedsLayout(true); - document->recalcStyle(Node::Force); + document->recalcStyle(Node::Force); #if USE(ACCELERATED_COMPOSITING) - updateContentsScale(scale); + updateContentsScale(scale); #endif + } if (FrameView* view = this->view()) { if (document->renderer() && document->renderer()->needsLayout() && view->didFirstLayout()) diff --git a/Source/WebCore/page/Frame.h b/Source/WebCore/page/Frame.h index f22fcb8..05805cf 100644 --- a/Source/WebCore/page/Frame.h +++ b/Source/WebCore/page/Frame.h @@ -184,6 +184,7 @@ namespace WebCore { VisiblePosition visiblePositionForPoint(const IntPoint& framePoint); Document* documentAtPoint(const IntPoint& windowPoint); + PassRefPtr<Range> rangeForPoint(const IntPoint& framePoint); String searchForLabelsAboveCell(RegularExpression*, HTMLTableCellElement*, size_t* resultDistanceFromStartOfCell); String searchForLabelsBeforeElement(const Vector<String>& labels, Element*, size_t* resultDistance, bool* resultIsInCellAbove); diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp index 9cf2c57..ee6bd6b 100644 --- a/Source/WebCore/page/FrameView.cpp +++ b/Source/WebCore/page/FrameView.cpp @@ -152,6 +152,11 @@ FrameView::FrameView(Frame* frame) if (Page* page = m_frame->page()) { m_page = page; m_page->addScrollableArea(this); + + if (m_frame == m_page->mainFrame()) { + ScrollableArea::setVerticalScrollElasticity(ScrollElasticityAllowed); + ScrollableArea::setHorizontalScrollElasticity(ScrollElasticityAllowed); + } } } } @@ -265,6 +270,10 @@ void FrameView::resetScrollbars() void FrameView::resetScrollbarsAndClearContentsSize() { + // Since the contents size is being cleared, the scroll position will lost as a consequence. + // Cache the scroll position so it can be restored by the page cache if necessary. + cacheCurrentScrollPosition(); + resetScrollbars(); setScrollbarsSuppressed(true); @@ -335,7 +344,7 @@ bool FrameView::didFirstLayout() const void FrameView::invalidateRect(const IntRect& rect) { if (!parent()) { - if (hostWindow() && shouldUpdate()) + if (hostWindow()) hostWindow()->invalidateContentsAndWindow(rect, false /*immediate*/); return; } @@ -524,6 +533,8 @@ void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, S void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode) { + m_viewportRenderer = 0; + const HTMLFrameOwnerElement* owner = m_frame->ownerElement(); if (owner && (owner->scrollingMode() == ScrollbarAlwaysOff)) { hMode = ScrollbarAlwaysOff; @@ -590,6 +601,30 @@ void FrameView::updateCompositingLayers() #endif } +GraphicsLayer* FrameView::layerForHorizontalScrollbar() const +{ + RenderView* view = m_frame->contentRenderer(); + if (!view) + return 0; + return view->compositor()->layerForHorizontalScrollbar(); +} + +GraphicsLayer* FrameView::layerForVerticalScrollbar() const +{ + RenderView* view = m_frame->contentRenderer(); + if (!view) + return 0; + return view->compositor()->layerForVerticalScrollbar(); +} + +GraphicsLayer* FrameView::layerForScrollCorner() const +{ + RenderView* view = m_frame->contentRenderer(); + if (!view) + return 0; + return view->compositor()->layerForScrollCorner(); +} + bool FrameView::syncCompositingStateForThisFrame() { ASSERT(m_frame->view() == this); @@ -602,6 +637,13 @@ bool FrameView::syncCompositingStateForThisFrame() if (needsLayout()) return false; + if (GraphicsLayer* graphicsLayer = view->compositor()->layerForHorizontalScrollbar()) + graphicsLayer->syncCompositingStateForThisLayerOnly(); + if (GraphicsLayer* graphicsLayer = view->compositor()->layerForVerticalScrollbar()) + graphicsLayer->syncCompositingStateForThisLayerOnly(); + if (GraphicsLayer* graphicsLayer = view->compositor()->layerForScrollCorner()) + graphicsLayer->syncCompositingStateForThisLayerOnly(); + view->compositor()->flushPendingLayerChanges(); #if ENABLE(FULLSCREEN_API) @@ -646,7 +688,7 @@ bool FrameView::hasCompositedContentIncludingDescendants() const if (compositor->inCompositingMode()) return true; - if (!RenderLayerCompositor::allowsIndependentlyCompositedIFrames(this)) + if (!RenderLayerCompositor::allowsIndependentlyCompositedFrames(this)) break; } } @@ -857,7 +899,7 @@ void FrameView::layout(bool allowSubtree) printf("Elapsed time before first layout: %d\n", document->elapsedTime()); #endif } - + ScrollbarMode hMode; ScrollbarMode vMode; calculateScrollbarModesForLayout(hMode, vMode); @@ -1320,7 +1362,7 @@ void FrameView::setIsOverlapped(bool isOverlapped) } } - if (RenderLayerCompositor::allowsIndependentlyCompositedIFrames(this)) { + if (RenderLayerCompositor::allowsIndependentlyCompositedFrames(this)) { // We also need to trigger reevaluation for this and all descendant frames, // since a frame uses compositing if any ancestor is compositing. for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) { @@ -1503,7 +1545,7 @@ void FrameView::repaintContentRectangle(const IntRect& r, bool immediate) { ASSERT(!m_frame->ownerElement()); - double delay = adjustedDeferredRepaintDelay(); + double delay = m_deferringRepaints ? 0 : adjustedDeferredRepaintDelay(); if ((m_deferringRepaints || m_deferredRepaintTimer.isActive() || delay) && !immediate) { IntRect paintRect = r; if (clipsRepaints() && !paintsEntireContents()) @@ -1561,6 +1603,13 @@ void FrameView::visibleContentsResized() if (needsLayout()) layout(); + +#if USE(ACCELERATED_COMPOSITING) + if (RenderView* root = m_frame->contentRenderer()) { + if (root->usesCompositing()) + root->compositor()->frameViewDidChangeSize(); + } +#endif } void FrameView::beginDeferredRepaints() @@ -1659,6 +1708,7 @@ void FrameView::resetDeferredRepaintDelay() double FrameView::adjustedDeferredRepaintDelay() const { + ASSERT(!m_deferringRepaints); if (!m_deferredRepaintDelay) return 0; double timeSinceLastPaint = currentTime() - m_lastPaintTime; @@ -1748,10 +1798,12 @@ void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot) if (isObjectAncestorContainerOf(m_layoutRoot, relayoutRoot)) { // Keep the current root relayoutRoot->markContainingBlocksForLayout(false, m_layoutRoot); + ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout()); } else if (m_layoutRoot && isObjectAncestorContainerOf(relayoutRoot, m_layoutRoot)) { // Re-root at relayoutRoot m_layoutRoot->markContainingBlocksForLayout(false, relayoutRoot); m_layoutRoot = relayoutRoot; + ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout()); } else { // Just do a full relayout if (m_layoutRoot) @@ -1763,6 +1815,7 @@ void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot) } else if (m_layoutSchedulingEnabled) { int delay = m_frame->document()->minimumLayoutDelay(); m_layoutRoot = relayoutRoot; + ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout()); m_delayedLayout = delay != 0; m_layoutTimer.startOneShot(delay * 0.001); } @@ -1869,8 +1922,6 @@ bool FrameView::shouldUpdate(bool immediateRequested) const { if (!immediateRequested && isOffscreen() && !shouldUpdateWhileOffscreen()) return false; - if (!m_frame || !m_frame->document() || m_frame->document()->mayCauseFlashOfUnstyledContent()) - return false; return true; } @@ -2141,7 +2192,11 @@ void FrameView::didCompleteRubberBand(const IntSize& initialOverhang) const void FrameView::scrollbarStyleChanged() { - m_frame->page()->setNeedsRecalcStyleInAllFrames(); + Page* page = m_frame->page(); + ASSERT(page); + if (!page) + return; + page->setNeedsRecalcStyleInAllFrames(); } bool FrameView::shouldSuspendScrollAnimations() const @@ -2179,11 +2234,6 @@ void FrameView::updateDashboardRegions() } #endif -void FrameView::invalidateScrollCorner() -{ - invalidateRect(scrollCornerRect()); -} - void FrameView::updateScrollCorner() { RenderObject* renderer = 0; @@ -2218,11 +2268,13 @@ void FrameView::updateScrollCorner() if (!m_scrollCorner) m_scrollCorner = new (renderer->renderArena()) RenderScrollbarPart(renderer->document()); m_scrollCorner->setStyle(cornerStyle.release()); - invalidateRect(scrollCornerRect()); + invalidateScrollCorner(); } else if (m_scrollCorner) { m_scrollCorner->destroy(); m_scrollCorner = 0; } + + ScrollView::updateScrollCorner(); } void FrameView::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect) diff --git a/Source/WebCore/page/FrameView.h b/Source/WebCore/page/FrameView.h index 9af0552..d00b423 100644 --- a/Source/WebCore/page/FrameView.h +++ b/Source/WebCore/page/FrameView.h @@ -218,6 +218,7 @@ public: void setNodeToDraw(Node*); virtual void paintOverhangAreas(GraphicsContext*, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect); + virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect); static double currentPaintTimeStamp() { return sCurrentPaintTimeStamp; } // returns 0 if not painting @@ -258,7 +259,6 @@ public: virtual IntPoint convertToRenderer(const RenderObject*, const IntPoint&) const; bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; } - void invalidateScrollCorner(); void calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode); @@ -324,6 +324,11 @@ private: virtual void scrollTo(const IntSize&); virtual void didCompleteRubberBand(const IntSize&) const; virtual void scrollbarStyleChanged(); +#if USE(ACCELERATED_COMPOSITING) + virtual GraphicsLayer* layerForHorizontalScrollbar() const; + virtual GraphicsLayer* layerForVerticalScrollbar() const; + virtual GraphicsLayer* layerForScrollCorner() const; +#endif virtual void notifyPageThatContentAreaWillPaint() const; virtual void disconnectFromPage() { m_page = 0; } @@ -341,7 +346,6 @@ private: bool hasCustomScrollbars() const; virtual void updateScrollCorner(); - virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect); FrameView* parentFrameView() const; diff --git a/Source/WebCore/page/MouseEventWithHitTestResults.cpp b/Source/WebCore/page/MouseEventWithHitTestResults.cpp index 042269c..b372cff 100644 --- a/Source/WebCore/page/MouseEventWithHitTestResults.cpp +++ b/Source/WebCore/page/MouseEventWithHitTestResults.cpp @@ -32,21 +32,6 @@ MouseEventWithHitTestResults::MouseEventWithHitTestResults(const PlatformMouseEv , m_hitTestResult(hitTestResult) { } - -Node* MouseEventWithHitTestResults::targetNode() const -{ - Node* node = m_hitTestResult.innerNode(); - if (!node) - return 0; - if (node->inDocument()) - return node; - - Element* element = node->parentElement(); - if (element && element->inDocument()) - return element; - - return node; -} const IntPoint MouseEventWithHitTestResults::localPoint() const { diff --git a/Source/WebCore/page/MouseEventWithHitTestResults.h b/Source/WebCore/page/MouseEventWithHitTestResults.h index 8c28574..b351f92 100644 --- a/Source/WebCore/page/MouseEventWithHitTestResults.h +++ b/Source/WebCore/page/MouseEventWithHitTestResults.h @@ -34,7 +34,6 @@ public: const PlatformMouseEvent& event() const { return m_event; } const HitTestResult& hitTestResult() const { return m_hitTestResult; } - Node* targetNode() const; const IntPoint localPoint() const; Scrollbar* scrollbar() const; bool isOverLink() const; diff --git a/Source/WebCore/page/Navigator.cpp b/Source/WebCore/page/Navigator.cpp index 9526536..773483e 100644 --- a/Source/WebCore/page/Navigator.cpp +++ b/Source/WebCore/page/Navigator.cpp @@ -34,6 +34,8 @@ #include "Geolocation.h" #include "KURL.h" #include "Language.h" +#include "NavigatorUserMediaErrorCallback.h" +#include "NavigatorUserMediaSuccessCallback.h" #include "Page.h" #include "PageGroup.h" #include "PlatformString.h" @@ -281,4 +283,13 @@ void Navigator::registerProtocolHandler(const String& scheme, const String& url, } #endif +#if ENABLE(MEDIA_STREAM) +void Navigator::webkitGetUserMedia(const String& options, + PassRefPtr<NavigatorUserMediaSuccessCallback> successCallback, + PassRefPtr<NavigatorUserMediaErrorCallback> errorCallback) +{ + // FIXME: implement a call to the media stream context when available. +} +#endif + } // namespace WebCore diff --git a/Source/WebCore/page/Navigator.h b/Source/WebCore/page/Navigator.h index 8514279..f0963ac 100644 --- a/Source/WebCore/page/Navigator.h +++ b/Source/WebCore/page/Navigator.h @@ -36,6 +36,8 @@ class DOMMimeTypeArray; class DOMPluginArray; class Frame; class Geolocation; +class NavigatorUserMediaErrorCallback; +class NavigatorUserMediaSuccessCallback; class PluginData; #if PLATFORM(ANDROID) class ApplicationInstalledCallback; @@ -84,6 +86,11 @@ public: void registerProtocolHandler(const String& scheme, const String& url, const String& title, ExceptionCode&); #endif +#if ENABLE(MEDIA_STREAM) + virtual void webkitGetUserMedia(const String& options, PassRefPtr<NavigatorUserMediaSuccessCallback>, + PassRefPtr<NavigatorUserMediaErrorCallback> = 0); +#endif + private: Navigator(Frame*); Frame* m_frame; diff --git a/Source/WebCore/page/Navigator.idl b/Source/WebCore/page/Navigator.idl index b92ef4a..9b54f2f 100644 --- a/Source/WebCore/page/Navigator.idl +++ b/Source/WebCore/page/Navigator.idl @@ -37,7 +37,7 @@ module window { readonly attribute DOMString vendorSub; readonly attribute boolean cookieEnabled; boolean javaEnabled(); - + readonly attribute boolean onLine; #if defined(ENABLE_CONNECTION) && ENABLE_CONNECTION @@ -62,6 +62,12 @@ module window { void registerProtocolHandler(in DOMString scheme, in DOMString url, in DOMString title) raises(DomException); #endif + +#if defined(ENABLE_MEDIA_STREAM) && ENABLE_MEDIA_STREAM + [Custom, EnabledAtRuntime] void webkitGetUserMedia(in DOMString options, + in [Callback=FunctionOnly] NavigatorUserMediaSuccessCallback successCallback, + in [Callback=FunctionOnly, Optional] NavigatorUserMediaErrorCallback errorCallback); +#endif }; } diff --git a/Source/WebCore/page/NavigatorUserMediaError.h b/Source/WebCore/page/NavigatorUserMediaError.h new file mode 100644 index 0000000..cc88b4f --- /dev/null +++ b/Source/WebCore/page/NavigatorUserMediaError.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2011 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: + * 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 NavigatorUserMediaError_h +#define NavigatorUserMediaError_h + +#include <wtf/RefCounted.h> + +#if ENABLE(MEDIA_STREAM) + +namespace WebCore { + +class NavigatorUserMediaError : public RefCounted<NavigatorUserMediaError> { +public: + // Should be kept in sync with the values in the idl file. + enum ErrorCode { + PERMISSION_DENIED = 1 + }; + + NavigatorUserMediaError(ErrorCode code) : m_code(code) { } + virtual ~NavigatorUserMediaError() { } + + ErrorCode code() const { return m_code; } + +private: + ErrorCode m_code; +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // NavigatorUserMediaError_h diff --git a/Source/WebCore/page/NavigatorUserMediaError.idl b/Source/WebCore/page/NavigatorUserMediaError.idl new file mode 100644 index 0000000..293450b --- /dev/null +++ b/Source/WebCore/page/NavigatorUserMediaError.idl @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2011 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: + * 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. + */ + +module window { + interface [ + Conditional=MEDIA_STREAM + ] NavigatorUserMediaError { + const unsigned short PERMISSION_DENIED = 1; + readonly attribute unsigned short code; + }; + +} + diff --git a/Source/WebCore/page/NavigatorUserMediaErrorCallback.h b/Source/WebCore/page/NavigatorUserMediaErrorCallback.h new file mode 100644 index 0000000..19fb9f6 --- /dev/null +++ b/Source/WebCore/page/NavigatorUserMediaErrorCallback.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2011 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: + * 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 NavigatorUserMediaErrorCallback_h +#define NavigatorUserMediaErrorCallback_h + +#if ENABLE(MEDIA_STREAM) + +#include <wtf/RefCounted.h> + +namespace WebCore { + +class NavigatorUserMediaError; + +class NavigatorUserMediaErrorCallback : public RefCounted<NavigatorUserMediaErrorCallback> { +public: + virtual ~NavigatorUserMediaErrorCallback() { } + virtual bool handleEvent(NavigatorUserMediaError*) = 0; +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // NavigatorUserMediaErrorCallback_h diff --git a/Source/WebCore/page/NavigatorUserMediaErrorCallback.idl b/Source/WebCore/page/NavigatorUserMediaErrorCallback.idl new file mode 100644 index 0000000..66748cd --- /dev/null +++ b/Source/WebCore/page/NavigatorUserMediaErrorCallback.idl @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2011 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: + * 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. + */ + +module window { + interface [ + Conditional=MEDIA_STREAM, + Callback=FunctionOnly + ] NavigatorUserMediaErrorCallback { + boolean handleEvent(in NavigatorUserMediaError error); + }; + +} diff --git a/Source/WebCore/page/NavigatorUserMediaSuccessCallback.h b/Source/WebCore/page/NavigatorUserMediaSuccessCallback.h new file mode 100644 index 0000000..770693d --- /dev/null +++ b/Source/WebCore/page/NavigatorUserMediaSuccessCallback.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2011 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: + * 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 NavigatorUserMediaSuccessCallback_h +#define NavigatorUserMediaSuccessCallback_h + +#if ENABLE(MEDIA_STREAM) + +#include <wtf/RefCounted.h> + +namespace WebCore { + +class NavigatorUserMediaSuccessCallback : public RefCounted<NavigatorUserMediaSuccessCallback> { +public: + virtual ~NavigatorUserMediaSuccessCallback() { } + // FIXME: set correct type when the GeneratedStream class is available. + // virtual bool handleEvent(GeneratedStream*) = 0; + virtual bool handleEvent(int dummy) = 0; +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // NavigatorUserMediaSuccessCallback_h diff --git a/Source/WebCore/page/NavigatorUserMediaSuccessCallback.idl b/Source/WebCore/page/NavigatorUserMediaSuccessCallback.idl new file mode 100644 index 0000000..e12540c --- /dev/null +++ b/Source/WebCore/page/NavigatorUserMediaSuccessCallback.idl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2011 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: + * 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. + */ + +module window { + interface [ + Conditional=MEDIA_STREAM, + Callback=FunctionOnly + ] NavigatorUserMediaSuccessCallback { + // FIXME: implement the correct type when the GeneratedStream class is available. + // boolean handleEvent(in GeneratedStream stream); + boolean handleEvent(in int dummy); + }; + +} diff --git a/Source/WebCore/page/Page.h b/Source/WebCore/page/Page.h index 8307123..ac4c160 100644 --- a/Source/WebCore/page/Page.h +++ b/Source/WebCore/page/Page.h @@ -29,6 +29,10 @@ #include <wtf/HashSet.h> #include <wtf/Noncopyable.h> +#if OS(SOLARIS) +#include <sys/time.h> // For time_t structure. +#endif + #if PLATFORM(MAC) #include "SchedulePair.h" #endif diff --git a/Source/WebCore/page/PageGroup.cpp b/Source/WebCore/page/PageGroup.cpp index 969e2a6..b1efbc5 100644 --- a/Source/WebCore/page/PageGroup.cpp +++ b/Source/WebCore/page/PageGroup.cpp @@ -33,6 +33,7 @@ #include "GroupSettings.h" #include "IDBFactoryBackendInterface.h" #include "Page.h" +#include "PageCache.h" #include "SecurityOrigin.h" #include "Settings.h" #include "StorageNamespace.h" @@ -291,6 +292,7 @@ inline void PageGroup::addVisitedLink(LinkHash hash) return; #endif Page::visitedStateChanged(this, hash); + pageCache()->markPagesForVistedLinkStyleRecalc(); } void PageGroup::addVisitedLink(const KURL& url) @@ -315,11 +317,13 @@ void PageGroup::removeVisitedLinks() return; m_visitedLinkHashes.clear(); Page::allVisitedStateChanged(this); + pageCache()->markPagesForVistedLinkStyleRecalc(); } void PageGroup::removeAllVisitedLinks() { Page::removeAllVisitedLinks(); + pageCache()->markPagesForVistedLinkStyleRecalc(); } void PageGroup::setShouldTrackVisitedLinks(bool shouldTrack) diff --git a/Source/WebCore/page/PerformanceTiming.cpp b/Source/WebCore/page/PerformanceTiming.cpp index 56d6aa9..f17e771 100644 --- a/Source/WebCore/page/PerformanceTiming.cpp +++ b/Source/WebCore/page/PerformanceTiming.cpp @@ -161,7 +161,7 @@ unsigned long long PerformanceTiming::domainLookupStart() const { ResourceLoadTiming* timing = resourceLoadTiming(); if (!timing) - return 0; + return fetchStart(); // This will be -1 when a DNS request is not performed. // Rather than exposing a special value that indicates no DNS, we "backfill" with fetchStart. @@ -176,7 +176,7 @@ unsigned long long PerformanceTiming::domainLookupEnd() const { ResourceLoadTiming* timing = resourceLoadTiming(); if (!timing) - return 0; + return domainLookupStart(); // This will be -1 when a DNS request is not performed. // Rather than exposing a special value that indicates no DNS, we "backfill" with domainLookupStart. @@ -191,11 +191,11 @@ unsigned long long PerformanceTiming::connectStart() const { DocumentLoader* loader = documentLoader(); if (!loader) - return 0; + return domainLookupEnd(); ResourceLoadTiming* timing = loader->response().resourceLoadTiming(); if (!timing) - return 0; + return domainLookupEnd(); // connectStart will be -1 when a network request is not made. // Rather than exposing a special value that indicates no new connection, we "backfill" with domainLookupEnd. @@ -215,11 +215,11 @@ unsigned long long PerformanceTiming::connectEnd() const { DocumentLoader* loader = documentLoader(); if (!loader) - return 0; + return connectStart(); ResourceLoadTiming* timing = loader->response().resourceLoadTiming(); if (!timing) - return 0; + return connectStart(); // connectEnd will be -1 when a network request is not made. // Rather than exposing a special value that indicates no new connection, we "backfill" with connectStart. @@ -251,7 +251,7 @@ unsigned long long PerformanceTiming::requestStart() const { ResourceLoadTiming* timing = resourceLoadTiming(); if (!timing) - return 0; + return connectEnd(); ASSERT(timing->sendStart >= 0); return resourceLoadTimeRelativeToAbsolute(timing->sendStart); @@ -261,7 +261,7 @@ unsigned long long PerformanceTiming::responseStart() const { ResourceLoadTiming* timing = resourceLoadTiming(); if (!timing) - return 0; + return requestStart(); // FIXME: Response start needs to be the time of the first received byte. // However, the ResourceLoadTiming API currently only supports the time @@ -286,7 +286,7 @@ unsigned long long PerformanceTiming::domLoading() const { const DocumentTiming* timing = documentTiming(); if (!timing) - return 0; + return fetchStart(); return toIntegerMilliseconds(timing->domLoading); } diff --git a/Source/WebCore/page/SecurityOrigin.cpp b/Source/WebCore/page/SecurityOrigin.cpp index ddd42ea..243f02a 100644 --- a/Source/WebCore/page/SecurityOrigin.cpp +++ b/Source/WebCore/page/SecurityOrigin.cpp @@ -103,6 +103,8 @@ SecurityOrigin::SecurityOrigin(const KURL& url, SandboxFlags sandboxFlags) // For edge case URLs that were probably misparsed, make sure that the origin is unique. if (schemeRequiresAuthority(m_protocol) && m_host.isEmpty()) m_isUnique = true; + if (m_protocol.isEmpty()) + m_isUnique = true; // document.domain starts as m_host, but can be set by the DOM. m_domain = m_host; diff --git a/Source/WebCore/page/SecurityOrigin.h b/Source/WebCore/page/SecurityOrigin.h index 262dd8d..f6ef570 100644 --- a/Source/WebCore/page/SecurityOrigin.h +++ b/Source/WebCore/page/SecurityOrigin.h @@ -133,9 +133,6 @@ public: // resources, and can set arbitrary headers on XMLHttpRequests. bool isLocal() const; - // The empty SecurityOrigin is the least privileged SecurityOrigin. - bool isEmpty() const; - // The origin is a globally unique identifier assigned when the Document is // created. http://www.whatwg.org/specs/web-apps/current-work/#sandboxOrigin // @@ -144,6 +141,13 @@ public: // addition, the SandboxOrigin flag is inherited by iframes. bool isUnique() const { return m_isUnique; } + // The empty SecurityOrigin is a unique security orign (in the sense of + // isUnique above) that was created for a "blank" document, such about + // about:blank. Empty origins differ from unique origins in that they can + // sometimes be replaced by non-empty origins, for example when an + // about:blank iframe inherits its security origin from its parent frame. + bool isEmpty() const; + // Marks a file:// origin as being in a domain defined by its path. void enforceFilePathSeparation(); diff --git a/Source/WebCore/page/Settings.cpp b/Source/WebCore/page/Settings.cpp index 5cf20d6..f272325 100644 --- a/Source/WebCore/page/Settings.cpp +++ b/Source/WebCore/page/Settings.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -101,6 +101,7 @@ Settings::Settings(Page* page) , m_isSpatialNavigationEnabled(false) , m_isJavaEnabled(false) , m_loadsImagesAutomatically(false) + , m_loadsSiteIconsIgnoringImageLoadingSetting(false) , m_privateBrowsingEnabled(false) , m_caretBrowsingEnabled(false) , m_areImagesEnabled(true) @@ -175,6 +176,7 @@ Settings::Settings(Page* page) , m_crossOriginCheckInGetMatchedCSSRulesDisabled(false) , m_useQuickLookResourceCachingQuirks(false) , m_forceCompositingMode(false) +<<<<<<< HEAD #ifdef ANDROID_LAYOUT , m_useWideViewport(false) #endif @@ -190,6 +192,9 @@ Settings::Settings(Page* page) #ifdef ANDROID_PLUGINS , m_pluginsOnDemand(false) #endif +======= + , m_shouldInjectUserScriptsInInitialEmptyDocument(false) +>>>>>>> WebKit.org at r84325 { // A Frame may not have been created yet, so we initialize the AtomicString // hash before trying to use it. @@ -303,6 +308,11 @@ void Settings::setLoadsImagesAutomatically(bool loadsImagesAutomatically) setLoadsImagesAutomaticallyInAllFrames(m_page); } +void Settings::setLoadsSiteIconsIgnoringImageLoadingSetting(bool loadsSiteIcons) +{ + m_loadsSiteIconsIgnoringImageLoadingSetting = loadsSiteIcons; +} + void Settings::setJavaScriptEnabled(bool isJavaScriptEnabled) { m_isJavaScriptEnabled = isJavaScriptEnabled; diff --git a/Source/WebCore/page/Settings.h b/Source/WebCore/page/Settings.h index 35446c5..8aedd77 100644 --- a/Source/WebCore/page/Settings.h +++ b/Source/WebCore/page/Settings.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved. * (C) 2006 Graham Dennis (graham.dennis@gmail.com) * * Redistribution and use in source and binary forms, with or without @@ -109,10 +109,18 @@ namespace WebCore { void setLoadsImagesAutomatically(bool); bool loadsImagesAutomatically() const { return m_loadsImagesAutomatically; } +<<<<<<< HEAD #ifdef ANDROID_BLOCK_NETWORK_IMAGE void setBlockNetworkImage(bool); bool blockNetworkImage() const { return m_blockNetworkImage; } #endif +======= + // This setting only affects site icon image loading if loadsImagesAutomatically setting is false and this setting is true. + // All other permutations still heed loadsImagesAutomatically setting. + void setLoadsSiteIconsIgnoringImageLoadingSetting(bool); + bool loadsSiteIconsIgnoringImageLoadingSetting() const { return m_loadsSiteIconsIgnoringImageLoadingSetting; } + +>>>>>>> WebKit.org at r84325 void setJavaScriptEnabled(bool); // Instead of calling isJavaScriptEnabled directly, please consider calling // ScriptController::canExecuteScripts, which takes things like the @@ -453,6 +461,9 @@ namespace WebCore { void setForceCompositingMode(bool flag) { m_forceCompositingMode = flag; } bool forceCompositingMode() { return m_forceCompositingMode; } + + void setShouldInjectUserScriptsInInitialEmptyDocument(bool flag) { m_shouldInjectUserScriptsInInitialEmptyDocument = flag; } + bool shouldInjectUserScriptsInInitialEmptyDocument() { return m_shouldInjectUserScriptsInInitialEmptyDocument; } #if ENABLE(WEB_AUTOFILL) void setAutoFillEnabled(bool flag) { m_autoFillEnabled = flag; } @@ -505,6 +516,7 @@ namespace WebCore { bool m_isSpatialNavigationEnabled : 1; bool m_isJavaEnabled : 1; bool m_loadsImagesAutomatically : 1; + bool m_loadsSiteIconsIgnoringImageLoadingSetting : 1; bool m_privateBrowsingEnabled : 1; bool m_caretBrowsingEnabled : 1; bool m_areImagesEnabled : 1; @@ -577,6 +589,7 @@ namespace WebCore { bool m_crossOriginCheckInGetMatchedCSSRulesDisabled : 1; bool m_useQuickLookResourceCachingQuirks : 1; bool m_forceCompositingMode : 1; +<<<<<<< HEAD #ifdef ANDROID_META_SUPPORT // default is yes bool m_viewport_user_scalable : 1; @@ -606,6 +619,9 @@ namespace WebCore { #ifdef ANDROID_PLUGINS bool m_pluginsOnDemand : 1; #endif +======= + bool m_shouldInjectUserScriptsInInitialEmptyDocument : 1; +>>>>>>> WebKit.org at r84325 #if USE(SAFARI_THEME) static bool gShouldPaintNativeControls; diff --git a/Source/WebCore/page/SpatialNavigation.cpp b/Source/WebCore/page/SpatialNavigation.cpp index 15d3639..26b24aa 100644 --- a/Source/WebCore/page/SpatialNavigation.cpp +++ b/Source/WebCore/page/SpatialNavigation.cpp @@ -300,6 +300,8 @@ bool hasOffscreenRect(Node* node, FocusDirection direction) if (!frameView) return true; + ASSERT(!frameView->needsLayout()); + IntRect containerViewportRect = frameView->visibleContentRect(); // We want to select a node if it is currently off screen, but will be // exposed after we scroll. Adjust the viewport to post-scrolling position. @@ -517,7 +519,7 @@ static IntRect rectToAbsoluteCoordinates(Frame* initialFrame, const IntRect& ini IntRect nodeRectInAbsoluteCoordinates(Node* node, bool ignoreBorder) { - ASSERT(node && node->renderer()); + ASSERT(node && node->renderer() && !node->document()->view()->needsLayout()); if (node->isDocumentNode()) return frameRectInAbsoluteCoordinates(static_cast<Document*>(node)->frame()); diff --git a/Source/WebCore/page/android/EventHandlerAndroid.cpp b/Source/WebCore/page/android/EventHandlerAndroid.cpp index 16ca09c..6b36583 100644 --- a/Source/WebCore/page/android/EventHandlerAndroid.cpp +++ b/Source/WebCore/page/android/EventHandlerAndroid.cpp @@ -53,7 +53,7 @@ void EventHandler::focusDocumentView() bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event) { // Figure out which view to send the event to. - RenderObject* target = event.targetNode() ? event.targetNode()->renderer() : 0; + RenderObject* target = targetNode(event) ? targetNode(event)->renderer() : 0; if (!target || !target->isWidget()) return false; return passMouseDownEventToWidget(toRenderWidget(target)->widget()); diff --git a/Source/WebCore/page/animation/AnimationBase.cpp b/Source/WebCore/page/animation/AnimationBase.cpp index 0fe98be..e232b03 100644 --- a/Source/WebCore/page/animation/AnimationBase.cpp +++ b/Source/WebCore/page/animation/AnimationBase.cpp @@ -142,6 +142,9 @@ static inline ShadowStyle blendFunc(const AnimationBase* anim, ShadowStyle from, static inline ShadowData* blendFunc(const AnimationBase* anim, const ShadowData* from, const ShadowData* to, double progress) { ASSERT(from && to); + if (from->style() != to->style()) + return new ShadowData(*to); + return new ShadowData(blendFunc(anim, from->x(), to->x(), progress), blendFunc(anim, from->y(), to->y(), progress), blendFunc(anim, from->blur(), to->blur(), progress), @@ -360,14 +363,15 @@ public: const ShadowData* shadowA = (a->*m_getter)(); const ShadowData* shadowB = (b->*m_getter)(); ShadowData defaultShadowData(0, 0, 0, 0, Normal, property() == CSSPropertyWebkitBoxShadow, Color::transparent); + ShadowData defaultInsetShadowData(0, 0, 0, 0, Inset, property() == CSSPropertyWebkitBoxShadow, Color::transparent); ShadowData* newShadowData = 0; ShadowData* lastShadow = 0; while (shadowA || shadowB) { - const ShadowData* srcShadow = shadowA ? shadowA : &defaultShadowData; - const ShadowData* dstShadow = shadowB ? shadowB : &defaultShadowData; - + const ShadowData* srcShadow = shadowA ? shadowA : (shadowB->style() == Inset ? &defaultInsetShadowData : &defaultShadowData); + const ShadowData* dstShadow = shadowB ? shadowB : (shadowA->style() == Inset ? &defaultInsetShadowData : &defaultShadowData); + ShadowData* blendedShadow = blendFunc(anim, srcShadow, dstShadow, progress); if (!lastShadow) newShadowData = blendedShadow; @@ -926,6 +930,9 @@ bool AnimationBase::animationsMatch(const Animation* anim) const void AnimationBase::updateStateMachine(AnimStateInput input, double param) { + if (!m_compAnim) + return; + // If we get AnimationStateInputRestartAnimation then we force a new animation, regardless of state. if (input == AnimationStateInputMakeNew) { if (m_animState == AnimationStateStartWaitStyleAvailable) @@ -1194,6 +1201,9 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) void AnimationBase::fireAnimationEventsIfNeeded() { + if (!m_compAnim) + return; + // If we are waiting for the delay time to expire and it has, go to the next state if (m_animState != AnimationStateStartWaitTimer && m_animState != AnimationStateLooping && m_animState != AnimationStateEnding) return; @@ -1248,6 +1258,9 @@ void AnimationBase::fireAnimationEventsIfNeeded() void AnimationBase::updatePlayState(EAnimPlayState playState) { + if (!m_compAnim) + return; + // When we get here, we can have one of 4 desired states: running, paused, suspended, paused & suspended. // The state machine can be in one of two states: running, paused. // Set the state machine to the desired state. @@ -1357,6 +1370,9 @@ void AnimationBase::goIntoEndingOrLoopingState() void AnimationBase::freezeAtTime(double t) { + if (!m_compAnim) + return; + if (!m_startTime) { // If we haven't started yet, just generate the start event now m_compAnim->animationController()->receivedStartTimeResponse(currentTime()); @@ -1376,6 +1392,9 @@ void AnimationBase::freezeAtTime(double t) double AnimationBase::beginAnimationUpdateTime() const { + if (!m_compAnim) + return 0; + return m_compAnim->animationController()->beginAnimationUpdateTime(); } diff --git a/Source/WebCore/page/animation/AnimationBase.h b/Source/WebCore/page/animation/AnimationBase.h index 1ab14e3..c07f66e 100644 --- a/Source/WebCore/page/animation/AnimationBase.h +++ b/Source/WebCore/page/animation/AnimationBase.h @@ -54,7 +54,7 @@ public: virtual ~AnimationBase() { } RenderObject* renderer() const { return m_object; } - void clearRenderer() { m_object = 0; } + void clear() { m_object = 0; m_compAnim = 0; } double duration() const; diff --git a/Source/WebCore/page/animation/CompositeAnimation.cpp b/Source/WebCore/page/animation/CompositeAnimation.cpp index 27409d9..29b32eb 100644 --- a/Source/WebCore/page/animation/CompositeAnimation.cpp +++ b/Source/WebCore/page/animation/CompositeAnimation.cpp @@ -43,7 +43,10 @@ namespace WebCore { CompositeAnimation::~CompositeAnimation() { - // Toss the refs to all animations + // Toss the refs to all animations, but make sure we remove them from + // any waiting lists first. + + clearRenderer(); m_transitions.clear(); m_keyframeAnimations.clear(); } @@ -57,7 +60,7 @@ void CompositeAnimation::clearRenderer() for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) { ImplicitAnimation* transition = it->second.get(); animationController()->animationWillBeRemoved(transition); - transition->clearRenderer(); + transition->clear(); } } if (!m_keyframeAnimations.isEmpty()) { @@ -66,7 +69,7 @@ void CompositeAnimation::clearRenderer() for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { KeyframeAnimation* anim = it->second.get(); animationController()->animationWillBeRemoved(anim); - anim->clearRenderer(); + anim->clear(); } } } @@ -261,7 +264,7 @@ void CompositeAnimation::updateKeyframeAnimations(RenderObject* renderer, Render if (keyframeAnim->index() < 0) { animsToBeRemoved.append(keyframeAnim->name().impl()); animationController()->animationWillBeRemoved(keyframeAnim); - keyframeAnim->clearRenderer(); + keyframeAnim->clear(); } } diff --git a/Source/WebCore/page/brew/EventHandlerBrew.cpp b/Source/WebCore/page/brew/EventHandlerBrew.cpp index f3acec6..ae5d83b 100644 --- a/Source/WebCore/page/brew/EventHandlerBrew.cpp +++ b/Source/WebCore/page/brew/EventHandlerBrew.cpp @@ -59,7 +59,7 @@ void EventHandler::focusDocumentView() bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event) { // Figure out which view to send the event to. - RenderObject* target = event.targetNode() ? event.targetNode()->renderer() : 0; + RenderObject* target = targetNode(event) ? targetNode(event)->renderer() : 0; if (!target || !target->isWidget()) return false; return passMouseDownEventToWidget(toRenderWidget(target)->widget()); diff --git a/Source/WebCore/page/chromium/EventHandlerChromium.cpp b/Source/WebCore/page/chromium/EventHandlerChromium.cpp index 09b4dfa..faf4d47 100644 --- a/Source/WebCore/page/chromium/EventHandlerChromium.cpp +++ b/Source/WebCore/page/chromium/EventHandlerChromium.cpp @@ -61,7 +61,7 @@ bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& m IntPoint p = m_frame->view()->windowToContents(mev.event().pos()); if (m_frame->selection()->contains(p)) { VisiblePosition visiblePos( - mev.targetNode()->renderer()->positionForPoint(mev.localPoint())); + targetNode(mev)->renderer()->positionForPoint(mev.localPoint())); VisibleSelection newSelection(visiblePos); if (m_frame->selection()->shouldChangeSelection(newSelection)) m_frame->selection()->setSelection(newSelection); @@ -103,9 +103,9 @@ bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& wheelEvent, Widget bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event) { // Figure out which view to send the event to. - if (!event.targetNode() || !event.targetNode()->renderer() || !event.targetNode()->renderer()->isWidget()) + if (!targetNode(event) || !targetNode(event)->renderer() || !targetNode(event)->renderer()->isWidget()) return false; - return passMouseDownEventToWidget(toRenderWidget(event.targetNode()->renderer())->widget()); + return passMouseDownEventToWidget(toRenderWidget(targetNode(event)->renderer())->widget()); } bool EventHandler::passMouseDownEventToWidget(Widget* widget) diff --git a/Source/WebCore/page/efl/EventHandlerEfl.cpp b/Source/WebCore/page/efl/EventHandlerEfl.cpp index c079617..3a3c4dd 100644 --- a/Source/WebCore/page/efl/EventHandlerEfl.cpp +++ b/Source/WebCore/page/efl/EventHandlerEfl.cpp @@ -61,7 +61,7 @@ void EventHandler::focusDocumentView() bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event) { - RenderObject* target = event.targetNode() ? event.targetNode()->renderer() : 0; + RenderObject* target = targetNode(event) ? targetNode(event)->renderer() : 0; if (!target || !target->isWidget()) return false; diff --git a/Source/WebCore/page/gtk/EventHandlerGtk.cpp b/Source/WebCore/page/gtk/EventHandlerGtk.cpp index ceb7565..ab54d83 100644 --- a/Source/WebCore/page/gtk/EventHandlerGtk.cpp +++ b/Source/WebCore/page/gtk/EventHandlerGtk.cpp @@ -59,7 +59,7 @@ void EventHandler::focusDocumentView() bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event) { // Figure out which view to send the event to. - RenderObject* target = event.targetNode() ? event.targetNode()->renderer() : 0; + RenderObject* target = targetNode(event) ? targetNode(event)->renderer() : 0; if (!target || !target->isWidget()) return false; return passMouseDownEventToWidget(toRenderWidget(target)->widget()); diff --git a/Source/WebCore/page/haiku/EventHandlerHaiku.cpp b/Source/WebCore/page/haiku/EventHandlerHaiku.cpp index ed4ea32..5c53614 100644 --- a/Source/WebCore/page/haiku/EventHandlerHaiku.cpp +++ b/Source/WebCore/page/haiku/EventHandlerHaiku.cpp @@ -73,7 +73,7 @@ void EventHandler::focusDocumentView() bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event) { // Figure out which view to send the event to. - RenderObject* target = event.targetNode() ? event.targetNode()->renderer() : 0; + RenderObject* target = targetNode(event) ? targetNode(event)->renderer() : 0; if (!target || !target->isWidget()) return false; return passMouseDownEventToWidget(toRenderWidget(target)->widget()); diff --git a/Source/WebCore/page/mac/DragControllerMac.mm b/Source/WebCore/page/mac/DragControllerMac.mm index 9b61510..70a10a7 100644 --- a/Source/WebCore/page/mac/DragControllerMac.mm +++ b/Source/WebCore/page/mac/DragControllerMac.mm @@ -72,8 +72,11 @@ void DragController::cleanupAfterSystemDrag() // Drag has ended, dragEnded *should* have been called, however it is possible // for the UIDelegate to take over the drag, and fail to send the appropriate // drag termination event. As dragEnded just resets drag variables, we just - // call it anyway to be on the safe side - dragEnded(); + // call it anyway to be on the safe side. + // We don't want to do this for WebKit2, since the client call to start the drag + // is asynchronous. + if (m_page->mainFrame()->view()->platformWidget()) + dragEnded(); } } // namespace WebCore diff --git a/Source/WebCore/page/mac/EventHandlerMac.mm b/Source/WebCore/page/mac/EventHandlerMac.mm index 5e96917..d93cc82 100644 --- a/Source/WebCore/page/mac/EventHandlerMac.mm +++ b/Source/WebCore/page/mac/EventHandlerMac.mm @@ -113,8 +113,6 @@ bool EventHandler::wheelEvent(NSEvent *event) CurrentEventScope scope(event); - m_useLatchedWheelEventNode = wkIsLatchingWheelEvent(event); - PlatformWheelEvent wheelEvent(event, page->chrome()->platformPageClient()); handleWheelEvent(wheelEvent); @@ -170,7 +168,7 @@ void EventHandler::focusDocumentView() bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event) { // Figure out which view to send the event to. - RenderObject* target = event.targetNode() ? event.targetNode()->renderer() : 0; + RenderObject* target = targetNode(event) ? targetNode(event)->renderer() : 0; if (!target || !target->isWidget()) return false; @@ -383,7 +381,7 @@ bool EventHandler::passSubframeEventToSubframe(MouseEventWithHitTestResults& eve return true; case NSLeftMouseDown: { - Node* node = event.targetNode(); + Node* node = targetNode(event); if (!node) return false; RenderObject* renderer = node->renderer(); diff --git a/Source/WebCore/page/qt/DragControllerQt.cpp b/Source/WebCore/page/qt/DragControllerQt.cpp index cdea55b..dccd6cc 100644 --- a/Source/WebCore/page/qt/DragControllerQt.cpp +++ b/Source/WebCore/page/qt/DragControllerQt.cpp @@ -50,7 +50,7 @@ bool DragController::isCopyKeyDown(DragData*) DragOperation DragController::dragOperation(DragData* dragData) { - //FIXME: This logic is incomplete + // FIXME: This logic is incomplete. if (dragData->containsURL(0)) return DragOperationCopy; diff --git a/Source/WebCore/page/wx/EventHandlerWx.cpp b/Source/WebCore/page/wx/EventHandlerWx.cpp index 66bae01..ba2f9cd 100644 --- a/Source/WebCore/page/wx/EventHandlerWx.cpp +++ b/Source/WebCore/page/wx/EventHandlerWx.cpp @@ -63,10 +63,10 @@ bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event) { // Figure out which view to send the event to. - if (!event.targetNode() || !event.targetNode()->renderer() || !event.targetNode()->renderer()->isWidget()) + if (!targetNode(event) || !targetNode(event)->renderer() || !targetNode(event)->renderer()->isWidget()) return false; - return passMouseDownEventToWidget(toRenderWidget(event.targetNode()->renderer())->widget()); + return passMouseDownEventToWidget(toRenderWidget(targetNode(event)->renderer())->widget()); } bool EventHandler::passWidgetMouseDownEventToWidget(RenderWidget* renderWidget) |