diff options
author | Ben Murdoch <benm@google.com> | 2011-05-24 11:24:40 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-06-02 09:53:15 +0100 |
commit | 81bc750723a18f21cd17d1b173cd2a4dda9cea6e (patch) | |
tree | 7a9e5ed86ff429fd347a25153107221543909b19 /Source/WebCore/page | |
parent | 94088a6d336c1dd80a1e734af51e96abcbb689a7 (diff) | |
download | external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.zip external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.gz external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.bz2 |
Merge WebKit at r80534: Intial merge by Git
Change-Id: Ia7a83357124c9e1cdb1debf55d9661ec0bd09a61
Diffstat (limited to 'Source/WebCore/page')
47 files changed, 763 insertions, 383 deletions
diff --git a/Source/WebCore/page/Chrome.cpp b/Source/WebCore/page/Chrome.cpp index 08bf1c3..26ea33b 100644 --- a/Source/WebCore/page/Chrome.cpp +++ b/Source/WebCore/page/Chrome.cpp @@ -398,7 +398,7 @@ void Chrome::setToolTip(const HitTestResult& result) if (input->isFileUpload()) { FileList* files = input->files(); unsigned listSize = files->length(); - if (files && listSize > 1) { + if (listSize > 1) { Vector<UChar> names; for (size_t i = 0; i < listSize; ++i) { append(names, files->item(i)->fileName()); diff --git a/Source/WebCore/page/ChromeClient.h b/Source/WebCore/page/ChromeClient.h index 42ef727..7fcec2e 100644 --- a/Source/WebCore/page/ChromeClient.h +++ b/Source/WebCore/page/ChromeClient.h @@ -31,14 +31,11 @@ #include "PopupMenuClient.h" #include "ScrollTypes.h" #include "SearchPopupMenu.h" +#include "WebCoreKeyboardUIMode.h" #include <wtf/Forward.h> #include <wtf/PassOwnPtr.h> #include <wtf/Vector.h> -#if PLATFORM(MAC) -#include "WebCoreKeyboardUIMode.h" -#endif - #ifndef __OBJC__ class NSMenu; class NSResponder; @@ -132,7 +129,7 @@ namespace WebCore { virtual bool runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result) = 0; virtual void setStatusbarText(const String&) = 0; virtual bool shouldInterruptJavaScript() = 0; - virtual bool tabsToLinks() const = 0; + virtual KeyboardUIMode keyboardUIMode() = 0; #if ENABLE(REGISTER_PROTOCOL_HANDLER) virtual void registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title) = 0; @@ -277,8 +274,6 @@ namespace WebCore { #endif #if PLATFORM(MAC) - virtual KeyboardUIMode keyboardUIMode() { return KeyboardAccessDefault; } - virtual NSResponder *firstResponder() { return 0; } virtual void makeFirstResponder(NSResponder *) { } diff --git a/Source/WebCore/page/Console.cpp b/Source/WebCore/page/Console.cpp index a1b92e9..0b8ddb0 100644 --- a/Source/WebCore/page/Console.cpp +++ b/Source/WebCore/page/Console.cpp @@ -143,8 +143,7 @@ void Console::addMessage(MessageSource source, MessageType type, MessageLevel le if (!page) return; - if (source == JSMessageSource) - page->chrome()->client()->addMessageToConsole(source, type, level, message, lineNumber, sourceURL); + page->chrome()->client()->addMessageToConsole(source, type, level, message, lineNumber, sourceURL); if (callStack) InspectorInstrumentation::addMessageToConsole(page, source, type, level, message, 0, callStack); diff --git a/Source/WebCore/page/ContentSecurityPolicy.cpp b/Source/WebCore/page/ContentSecurityPolicy.cpp index 045e5aa..97cd447 100644 --- a/Source/WebCore/page/ContentSecurityPolicy.cpp +++ b/Source/WebCore/page/ContentSecurityPolicy.cpp @@ -29,20 +29,126 @@ namespace WebCore { +class CSPDirective { +public: + explicit CSPDirective(const String& value) + : m_value(value) + { + } + + bool allows(const KURL&) + { + return false; + } + +private: + String m_value; +}; + ContentSecurityPolicy::ContentSecurityPolicy() - : m_isEnabled(false) + : m_havePolicy(false) +{ +} + +ContentSecurityPolicy::~ContentSecurityPolicy() { } void ContentSecurityPolicy::didReceiveHeader(const String& header) { - m_isEnabled = true; - m_header = header; + if (m_havePolicy) + return; // The first policy wins. + + parse(header); + m_havePolicy = true; +} + +bool ContentSecurityPolicy::allowJavaScriptURLs() const +{ + return !m_scriptSrc; +} + +bool ContentSecurityPolicy::canLoadExternalScriptFromSrc(const String& url) const +{ + return !m_scriptSrc || m_scriptSrc->allows(KURL(ParsedURLString, url)); +} + +void ContentSecurityPolicy::parse(const String& policy) +{ + ASSERT(!m_havePolicy); + + if (policy.isEmpty()) + return; + + const UChar* pos = policy.characters(); + const UChar* end = pos + policy.length(); + + while (pos < end) { + Vector<UChar, 32> name; + Vector<UChar, 64> value; + + parseDirective(pos, end, name, value); + if (name.isEmpty()) + continue; + + // We use a copy here instead of String::adopt because we expect + // the name and the value to be relatively short, so the copy will + // be cheaper than the extra malloc. + emitDirective(String(name), String(value)); + } +} + +void ContentSecurityPolicy::parseDirective(const UChar*& pos, const UChar* end, Vector<UChar, 32>& name, Vector<UChar, 64>& value) +{ + ASSERT(pos < end); + ASSERT(name.isEmpty()); + ASSERT(value.isEmpty()); + + enum { + BeforeDirectiveName, + DirectiveName, + AfterDirectiveName, + DirectiveValue, + } state = BeforeDirectiveName; + + while (pos < end) { + UChar currentCharacter = *pos++; + switch (state) { + case BeforeDirectiveName: + if (isASCIISpace(currentCharacter)) + continue; + state = DirectiveName; + // Fall through. + case DirectiveName: + if (!isASCIISpace(currentCharacter)) { + name.append(currentCharacter); + continue; + } + state = AfterDirectiveName; + // Fall through. + case AfterDirectiveName: + if (isASCIISpace(currentCharacter)) + continue; + state = DirectiveValue; + // Fall through. + case DirectiveValue: + if (currentCharacter != ';') { + value.append(currentCharacter); + continue; + } + return; + } + } } -bool ContentSecurityPolicy::canLoadExternalScriptFromSrc(const String&) const +void ContentSecurityPolicy::emitDirective(const String& name, const String& value) { - return !m_isEnabled; + DEFINE_STATIC_LOCAL(String, scriptSrc, ("script-src")); + + ASSERT(!name.isEmpty()); + + if (!m_scriptSrc && equalIgnoringCase(name, scriptSrc)) + m_scriptSrc = adoptPtr(new CSPDirective(value)); } } diff --git a/Source/WebCore/page/ContentSecurityPolicy.h b/Source/WebCore/page/ContentSecurityPolicy.h index ef0d551..0eebd05 100644 --- a/Source/WebCore/page/ContentSecurityPolicy.h +++ b/Source/WebCore/page/ContentSecurityPolicy.h @@ -26,21 +26,33 @@ #ifndef ContentSecurityPolicy_h #define ContentSecurityPolicy_h +#include <wtf/Vector.h> #include <wtf/text/WTFString.h> namespace WebCore { -class ContentSecurityPolicy { - WTF_MAKE_NONCOPYABLE(ContentSecurityPolicy); +class CSPDirective; + +class ContentSecurityPolicy : public RefCounted<ContentSecurityPolicy> { public: - ContentSecurityPolicy(); + static PassRefPtr<ContentSecurityPolicy> create() { return adoptRef(new ContentSecurityPolicy); } + ~ContentSecurityPolicy(); void didReceiveHeader(const String&); + + bool allowJavaScriptURLs() const; + // FIXME: Rename canLoadExternalScriptFromSrc to allowScriptFromURL. bool canLoadExternalScriptFromSrc(const String& url) const; private: - bool m_isEnabled; - String m_header; + ContentSecurityPolicy(); + + void parse(const String&); + void parseDirective(const UChar*& pos, const UChar* end, Vector<UChar, 32>& name, Vector<UChar, 64>& value); + void emitDirective(const String& name, const String& value); + + bool m_havePolicy; + OwnPtr<CSPDirective> m_scriptSrc; }; } diff --git a/Source/WebCore/page/ContextMenuController.cpp b/Source/WebCore/page/ContextMenuController.cpp index 36ac89d..c807d7a 100644 --- a/Source/WebCore/page/ContextMenuController.cpp +++ b/Source/WebCore/page/ContextMenuController.cpp @@ -207,7 +207,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item) // For now, call into the client. This is temporary! frame->editor()->copyImage(m_hitTestResult); break; -#if PLATFORM(QT) +#if PLATFORM(QT) || PLATFORM(GTK) case ContextMenuItemTagCopyImageUrlToClipboard: frame->editor()->copyURL(m_hitTestResult.absoluteImageURL(), m_hitTestResult.textContent()); break; @@ -278,7 +278,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item) ASSERT(frame->editor()->selectedText().length()); if (frame->editor()->shouldInsertText(item->title(), frame->selection()->toNormalizedRange().get(), EditorInsertActionPasted)) { Document* document = frame->document(); - RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::create(document, createFragmentFromMarkup(document, item->title(), ""), true, false, true); + RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::create(document, createFragmentFromMarkup(document, item->title(), ""), ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::MatchStyle | ReplaceSelectionCommand::PreventNesting); applyCommand(command); frame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded); } @@ -647,7 +647,7 @@ void ContextMenuController::populate() contextMenuItemTagDownloadImageToDisk()); ContextMenuItem CopyImageItem(ActionType, ContextMenuItemTagCopyImageToClipboard, contextMenuItemTagCopyImageToClipboard()); -#if PLATFORM(QT) +#if PLATFORM(QT) || PLATFORM(GTK) ContextMenuItem CopyImageUrlItem(ActionType, ContextMenuItemTagCopyImageUrlToClipboard, contextMenuItemTagCopyImageUrlToClipboard()); #endif @@ -733,7 +733,7 @@ void ContextMenuController::populate() appendItem(DownloadImageItem, m_contextMenu.get()); if (imageURL.isLocalFile() || m_hitTestResult.image()) appendItem(CopyImageItem, m_contextMenu.get()); -#if PLATFORM(QT) +#if PLATFORM(QT) || PLATFORM(GTK) appendItem(CopyImageUrlItem, m_contextMenu.get()); #endif } @@ -780,6 +780,14 @@ void ContextMenuController::populate() #if ENABLE(INSPECTOR) if (!(frame->page() && frame->page()->inspectorController()->hasInspectorFrontendClient())) { #endif + + // In GTK+ unavailable items are not hidden but insensitive +#if PLATFORM(GTK) + appendItem(BackItem, m_contextMenu.get()); + appendItem(ForwardItem, m_contextMenu.get()); + appendItem(StopItem, m_contextMenu.get()); + appendItem(ReloadItem, m_contextMenu.get()); +#else if (frame->page() && frame->page()->backForward()->canGoBackOrForward(-1)) appendItem(BackItem, m_contextMenu.get()); @@ -792,6 +800,7 @@ void ContextMenuController::populate() appendItem(StopItem, m_contextMenu.get()); else appendItem(ReloadItem, m_contextMenu.get()); +#endif #if ENABLE(INSPECTOR) } #endif @@ -1001,11 +1010,8 @@ void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const break; case ContextMenuItemTagLeftToRight: case ContextMenuItemTagRightToLeft: { - ExceptionCode ec = 0; - RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration(); String direction = item.action() == ContextMenuItemTagLeftToRight ? "ltr" : "rtl"; - style->setProperty(CSSPropertyDirection, direction, false, ec); - shouldCheck = frame->editor()->selectionHasStyle(style.get()) != FalseTriState; + shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyDirection, direction) != FalseTriState; shouldEnable = true; break; } @@ -1051,10 +1057,7 @@ void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const break; #endif case ContextMenuItemTagUnderline: { - ExceptionCode ec = 0; - RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration(); - style->setProperty(CSSPropertyWebkitTextDecorationsInEffect, "underline", false, ec); - shouldCheck = frame->editor()->selectionHasStyle(style.get()) != FalseTriState; + shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline") != FalseTriState; shouldEnable = frame->editor()->canEditRichly(); break; } @@ -1069,18 +1072,12 @@ void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const #endif break; case ContextMenuItemTagItalic: { - ExceptionCode ec = 0; - RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration(); - style->setProperty(CSSPropertyFontStyle, "italic", false, ec); - shouldCheck = frame->editor()->selectionHasStyle(style.get()) != FalseTriState; + shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyFontStyle, "italic") != FalseTriState; shouldEnable = frame->editor()->canEditRichly(); break; } case ContextMenuItemTagBold: { - ExceptionCode ec = 0; - RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration(); - style->setProperty(CSSPropertyFontWeight, "bold", false, ec); - shouldCheck = frame->editor()->selectionHasStyle(style.get()) != FalseTriState; + shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyFontWeight, "bold") != FalseTriState; shouldEnable = frame->editor()->canEditRichly(); break; } @@ -1188,7 +1185,7 @@ void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const case ContextMenuItemTagOpenImageInNewWindow: case ContextMenuItemTagDownloadImageToDisk: case ContextMenuItemTagCopyImageToClipboard: -#if PLATFORM(QT) +#if PLATFORM(QT) || PLATFORM(GTK) case ContextMenuItemTagCopyImageUrlToClipboard: #endif break; diff --git a/Source/WebCore/page/DOMSelection.cpp b/Source/WebCore/page/DOMSelection.cpp index dbb0944..67c87d2 100644 --- a/Source/WebCore/page/DOMSelection.cpp +++ b/Source/WebCore/page/DOMSelection.cpp @@ -101,7 +101,7 @@ Node* DOMSelection::anchorNode() const return 0; if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) return shadowAncestor->parentNodeGuaranteedHostFree(); - return anchorPosition(visibleSelection()).node(); + return anchorPosition(visibleSelection()).deprecatedNode(); } int DOMSelection::anchorOffset() const @@ -119,7 +119,7 @@ Node* DOMSelection::focusNode() const return 0; if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) return shadowAncestor->parentNodeGuaranteedHostFree(); - return focusPosition(visibleSelection()).node(); + return focusPosition(visibleSelection()).deprecatedNode(); } int DOMSelection::focusOffset() const @@ -137,7 +137,7 @@ Node* DOMSelection::baseNode() const return 0; if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) return shadowAncestor->parentNodeGuaranteedHostFree(); - return basePosition(visibleSelection()).node(); + return basePosition(visibleSelection()).deprecatedNode(); } int DOMSelection::baseOffset() const @@ -155,7 +155,7 @@ Node* DOMSelection::extentNode() const return 0; if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) return shadowAncestor->parentNodeGuaranteedHostFree(); - return extentPosition(visibleSelection()).node(); + return extentPosition(visibleSelection()).deprecatedNode(); } int DOMSelection::extentOffset() const @@ -211,7 +211,8 @@ void DOMSelection::collapse(Node* node, int offset, ExceptionCode& ec) if (!isValidForPosition(node)) return; - m_frame->selection()->moveTo(VisiblePosition(node, offset, DOWNSTREAM)); + // FIXME: Eliminate legacy editing positions + m_frame->selection()->moveTo(VisiblePosition(Position(node, offset), DOWNSTREAM)); } void DOMSelection::collapseToEnd(ExceptionCode& ec) @@ -264,8 +265,9 @@ void DOMSelection::setBaseAndExtent(Node* baseNode, int baseOffset, Node* extent if (!isValidForPosition(baseNode) || !isValidForPosition(extentNode)) return; - VisiblePosition visibleBase = VisiblePosition(baseNode, baseOffset, DOWNSTREAM); - VisiblePosition visibleExtent = VisiblePosition(extentNode, extentOffset, DOWNSTREAM); + // FIXME: Eliminate legacy editing positions + VisiblePosition visibleBase = VisiblePosition(Position(baseNode, baseOffset), DOWNSTREAM); + VisiblePosition visibleExtent = VisiblePosition(Position(extentNode, extentOffset), DOWNSTREAM); m_frame->selection()->moveTo(visibleBase, visibleExtent); } @@ -282,7 +284,8 @@ void DOMSelection::setPosition(Node* node, int offset, ExceptionCode& ec) if (!isValidForPosition(node)) return; - m_frame->selection()->moveTo(VisiblePosition(node, offset, DOWNSTREAM)); + // FIXME: Eliminate legacy editing positions + m_frame->selection()->moveTo(VisiblePosition(Position(node, offset), DOWNSTREAM)); } void DOMSelection::modify(const String& alterString, const String& directionString, const String& granularityString) @@ -353,7 +356,8 @@ void DOMSelection::extend(Node* node, int offset, ExceptionCode& ec) if (!isValidForPosition(node)) return; - m_frame->selection()->setExtent(VisiblePosition(node, offset, DOWNSTREAM)); + // FIXME: Eliminate legacy editing positions + m_frame->selection()->setExtent(VisiblePosition(Position(node, offset), DOWNSTREAM)); } PassRefPtr<Range> DOMSelection::getRangeAt(int index, ExceptionCode& ec) diff --git a/Source/WebCore/page/DOMTimer.cpp b/Source/WebCore/page/DOMTimer.cpp index 57e6512..eaca8f2 100644 --- a/Source/WebCore/page/DOMTimer.cpp +++ b/Source/WebCore/page/DOMTimer.cpp @@ -39,13 +39,14 @@ namespace WebCore { static const int maxTimerNestingLevel = 5; static const double oneMillisecond = 0.001; -double DOMTimer::s_minTimerInterval = 0.010; // 10 milliseconds +double DOMTimer::s_minDefaultTimerInterval = 0.010; // 10 milliseconds static int timerNestingLevel = 0; DOMTimer::DOMTimer(ScriptExecutionContext* context, PassOwnPtr<ScheduledAction> action, int timeout, bool singleShot) : SuspendableTimer(context) , m_action(action) + , m_originalTimeout(timeout) { static int lastUsedTimeoutId = 0; ++lastUsedTimeoutId; @@ -58,10 +59,7 @@ DOMTimer::DOMTimer(ScriptExecutionContext* context, PassOwnPtr<ScheduledAction> scriptExecutionContext()->addTimeout(m_timeoutId, this); - double intervalMilliseconds = max(oneMillisecond, timeout * oneMillisecond); - - if (intervalMilliseconds < s_minTimerInterval && m_nestingLevel >= maxTimerNestingLevel) - intervalMilliseconds = s_minTimerInterval; + double intervalMilliseconds = intervalClampedToMinimum(timeout, context->minimumTimerInterval()); if (singleShot) startOneShot(intervalMilliseconds); else @@ -108,10 +106,11 @@ void DOMTimer::fired() // Simple case for non-one-shot timers. if (isActive()) { - if (repeatInterval() && repeatInterval() < s_minTimerInterval) { + double minimumInterval = context->minimumTimerInterval(); + if (repeatInterval() && repeatInterval() < minimumInterval) { m_nestingLevel++; if (m_nestingLevel >= maxTimerNestingLevel) - augmentRepeatInterval(s_minTimerInterval - repeatInterval()); + augmentRepeatInterval(minimumInterval - repeatInterval()); } // No access to member variables after this point, it can delete the timer. @@ -150,4 +149,30 @@ void DOMTimer::stop() m_action.clear(); } +void DOMTimer::adjustMinimumTimerInterval(double oldMinimumTimerInterval) +{ + if (m_nestingLevel < maxTimerNestingLevel) + return; + + double newMinimumInterval = scriptExecutionContext()->minimumTimerInterval(); + double newClampedInterval = intervalClampedToMinimum(m_originalTimeout, newMinimumInterval); + + if (repeatInterval()) { + augmentRepeatInterval(newClampedInterval - repeatInterval()); + return; + } + + double previousClampedInterval = intervalClampedToMinimum(m_originalTimeout, oldMinimumTimerInterval); + augmentFireInterval(newClampedInterval - previousClampedInterval); +} + +double DOMTimer::intervalClampedToMinimum(int timeout, double minimumTimerInterval) const +{ + double intervalMilliseconds = max(oneMillisecond, timeout * oneMillisecond); + + if (intervalMilliseconds < minimumTimerInterval && m_nestingLevel >= maxTimerNestingLevel) + intervalMilliseconds = minimumTimerInterval; + return intervalMilliseconds; +} + } // namespace WebCore diff --git a/Source/WebCore/page/DOMTimer.h b/Source/WebCore/page/DOMTimer.h index 4fc6aae..ba260e0 100644 --- a/Source/WebCore/page/DOMTimer.h +++ b/Source/WebCore/page/DOMTimer.h @@ -34,7 +34,10 @@ namespace WebCore { + class Settings; + class DOMTimer : public SuspendableTimer { + friend class Settings; public: virtual ~DOMTimer(); // Creates a new timer owned by specified ScriptExecutionContext, starts it @@ -46,18 +49,27 @@ namespace WebCore { virtual void contextDestroyed(); virtual void stop(); - // The lowest allowable timer setting (in seconds, 0.001 == 1 ms). - static double minTimerInterval() { return s_minTimerInterval; } - static void setMinTimerInterval(double value) { s_minTimerInterval = value; } + // Adjust to a change in the ScriptExecutionContext's minimum timer interval. + // This allows the minimum allowable interval time to be changed in response + // to events like moving a tab to the background. + void adjustMinimumTimerInterval(double oldMinimumTimerInterval); private: DOMTimer(ScriptExecutionContext*, PassOwnPtr<ScheduledAction>, int timeout, bool singleShot); virtual void fired(); + double intervalClampedToMinimum(int timeout, double minimumTimerInterval) const; + + // The default minimum allowable timer setting (in seconds, 0.001 == 1 ms). + // These are only modified via static methods in Settings. + static double defaultMinTimerInterval() { return s_minDefaultTimerInterval; } + static void setDefaultMinTimerInterval(double value) { s_minDefaultTimerInterval = value; } + int m_timeoutId; int m_nestingLevel; OwnPtr<ScheduledAction> m_action; - static double s_minTimerInterval; + int m_originalTimeout; + static double s_minDefaultTimerInterval; }; } // namespace WebCore diff --git a/Source/WebCore/page/DOMWindow.cpp b/Source/WebCore/page/DOMWindow.cpp index c732a10..269c109 100644 --- a/Source/WebCore/page/DOMWindow.cpp +++ b/Source/WebCore/page/DOMWindow.cpp @@ -99,6 +99,8 @@ #if ENABLE(FILE_SYSTEM) #include "AsyncFileSystem.h" #include "DOMFileSystem.h" +#include "DOMFileSystemBase.h" +#include "EntryCallback.h" #include "ErrorCallback.h" #include "FileError.h" #include "FileSystemCallback.h" @@ -753,6 +755,29 @@ void DOMWindow::requestFileSystem(int type, long long size, PassRefPtr<FileSyste LocalFileSystem::localFileSystem().requestFileSystem(document, fileSystemType, size, FileSystemCallbacks::create(successCallback, errorCallback, document), false); } +void DOMWindow::resolveLocalFileSystemURI(const String& uri, PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) +{ + Document* document = this->document(); + if (!document) + return; + + SecurityOrigin* securityOrigin = document->securityOrigin(); + KURL completedURL = document->completeURL(uri); + if (!AsyncFileSystem::isAvailable() || !securityOrigin->canAccessFileSystem() || !securityOrigin->canRequest(completedURL)) { + DOMFileSystem::scheduleCallback(document, errorCallback, FileError::create(FileError::SECURITY_ERR)); + return; + } + + AsyncFileSystem::Type type; + String filePath; + if (!completedURL.isValid() || !DOMFileSystemBase::crackFileSystemURL(completedURL, type, filePath)) { + DOMFileSystem::scheduleCallback(document, errorCallback, FileError::create(FileError::SYNTAX_ERR)); + return; + } + + LocalFileSystem::localFileSystem().readFileSystem(document, type, ResolveURICallbacks::create(successCallback, errorCallback, document, filePath)); +} + 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); @@ -1533,9 +1558,10 @@ bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener void DOMWindow::dispatchLoadEvent() { RefPtr<Event> loadEvent(Event::create(eventNames().loadEvent, false, false)); - // The DocumentLoader (and thus its DocumentLoadTiming) might get destroyed while dispatching - // the event, so protect it to prevent writing the end time into freed memory. - if (RefPtr<DocumentLoader> documentLoader = m_frame ? m_frame->loader()->documentLoader() : 0) { + if (m_frame && m_frame->loader()->documentLoader() && !m_frame->loader()->documentLoader()->timing()->loadEventStart) { + // The DocumentLoader (and thus its DocumentLoadTiming) might get destroyed while dispatching + // the event, so protect it to prevent writing the end time into freed memory. + RefPtr<DocumentLoader> documentLoader = m_frame->loader()->documentLoader(); DocumentLoadTiming* timing = documentLoader->timing(); dispatchTimedEvent(loadEvent, document(), &timing->loadEventStart, &timing->loadEventEnd); } else @@ -1544,7 +1570,7 @@ void DOMWindow::dispatchLoadEvent() // For load events, send a separate load event to the enclosing frame only. // This is a DOM extension and is independent of bubbling/capturing rules of // the DOM. - Element* ownerElement = document()->ownerElement(); + Element* ownerElement = m_frame ? m_frame->ownerElement() : 0; if (ownerElement) { RefPtr<Event> ownerEvent = Event::create(eventNames().loadEvent, false, false); ownerEvent->setTarget(ownerElement); diff --git a/Source/WebCore/page/DOMWindow.h b/Source/WebCore/page/DOMWindow.h index 8318369..b365f53 100644 --- a/Source/WebCore/page/DOMWindow.h +++ b/Source/WebCore/page/DOMWindow.h @@ -45,6 +45,7 @@ namespace WebCore { class DatabaseCallback; class Document; class Element; + class EntryCallback; class ErrorCallback; class EventListener; class FileSystemCallback; @@ -390,6 +391,7 @@ namespace WebCore { PERSISTENT, }; void requestFileSystem(int type, long long size, PassRefPtr<FileSystemCallback>, PassRefPtr<ErrorCallback>); + void resolveLocalFileSystemURI(const String&, PassRefPtr<EntryCallback>, PassRefPtr<ErrorCallback>); #endif #if ENABLE(INDEXED_DATABASE) diff --git a/Source/WebCore/page/DOMWindow.idl b/Source/WebCore/page/DOMWindow.idl index b04a8a2..530c4ad 100644 --- a/Source/WebCore/page/DOMWindow.idl +++ b/Source/WebCore/page/DOMWindow.idl @@ -184,20 +184,18 @@ module window { attribute [EnabledAtRuntime] IDBDatabaseConstructor webkitIDBDatabase; attribute [EnabledAtRuntime] IDBDatabaseErrorConstructor webkitIDBDatabaseError; attribute [EnabledAtRuntime] IDBDatabaseExceptionConstructor webkitIDBDatabaseException; - attribute [EnabledAtRuntime] IDBErrorEventConstructor webkitIDBErrorEvent; - attribute [EnabledAtRuntime] IDBEventConstructor webkitIDBEvent; attribute [EnabledAtRuntime] IDBFactoryConstructor webkitIDBFactory; attribute [EnabledAtRuntime] IDBIndexConstructor webkitIDBIndex; attribute [EnabledAtRuntime] IDBKeyRangeConstructor webkitIDBKeyRange; attribute [EnabledAtRuntime] IDBObjectStoreConstructor webkitIDBObjectStore; attribute [EnabledAtRuntime] IDBRequestConstructor webkitIDBRequest; - attribute [EnabledAtRuntime] IDBSuccessEventConstructor webkitIDBSuccessEvent; attribute [EnabledAtRuntime] IDBTransactionConstructor webkitIDBTransaction; #endif #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 resolveLocalFileSystemURI(in DOMString uri, in [Callback, Optional] EntryCallback successCallback, in [Callback, Optional] ErrorCallback errorCallback); attribute [EnabledAtRuntime=FileSystem] FlagsConstructor Flags; #endif diff --git a/Source/WebCore/page/DragController.cpp b/Source/WebCore/page/DragController.cpp index b258e9d..6a4bb70 100644 --- a/Source/WebCore/page/DragController.cpp +++ b/Source/WebCore/page/DragController.cpp @@ -353,7 +353,7 @@ DragOperation DragController::operationForLoad(DragData* dragData) { ASSERT(dragData); Document* doc = m_page->mainFrame()->documentAtPoint(dragData->clientPosition()); - if (doc && (m_didInitiateDrag || doc->isPluginDocument() || (doc->frame() && doc->frame()->editor()->clientIsEditable()))) + if (doc && (m_didInitiateDrag || doc->isPluginDocument() || doc->inDesignMode())) return DragOperationNone; return dragOperation(dragData); } @@ -403,7 +403,7 @@ bool DragController::concludeEditDrag(DragData* dragData) RefPtr<Range> innerRange = innerFrame->selection()->toNormalizedRange(); RefPtr<CSSStyleDeclaration> style = m_documentUnderMouse->createCSSStyleDeclaration(); ExceptionCode ec; - style->setProperty("color", color.name(), ec); + style->setProperty("color", color.serialized(), ec); if (!innerFrame->editor()->shouldApplyStyle(style.get(), innerRange.get())) return false; m_client->willPerformDragDestinationAction(DragDestinationActionEdit, dragData); @@ -465,8 +465,14 @@ bool DragController::concludeEditDrag(DragData* dragData) bool smartInsert = smartDelete && innerFrame->selection()->granularity() == WordGranularity && dragData->canSmartReplace(); applyCommand(MoveSelectionCommand::create(fragment, dragCaret.base(), smartInsert, smartDelete)); } else { - if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) - applyCommand(ReplaceSelectionCommand::create(m_documentUnderMouse.get(), fragment, true, dragData->canSmartReplace(), chosePlainText)); + if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) { + ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::PreventNesting; + if (dragData->canSmartReplace()) + options |= ReplaceSelectionCommand::SmartReplace; + if (chosePlainText) + options |= ReplaceSelectionCommand::MatchStyle; + applyCommand(ReplaceSelectionCommand::create(m_documentUnderMouse.get(), fragment, options)); + } } } else { String text = dragData->asPlainText(innerFrame); @@ -477,7 +483,7 @@ bool DragController::concludeEditDrag(DragData* dragData) m_client->willPerformDragDestinationAction(DragDestinationActionEdit, dragData); if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) - applyCommand(ReplaceSelectionCommand::create(m_documentUnderMouse.get(), createFragmentFromText(range.get(), text), true, false, true)); + applyCommand(ReplaceSelectionCommand::create(m_documentUnderMouse.get(), createFragmentFromText(range.get(), text), ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::MatchStyle | ReplaceSelectionCommand::PreventNesting)); } cachedResourceLoader->setAllowStaleResources(false); @@ -747,7 +753,7 @@ bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation s doSystemDrag(dragImage, dragLoc, mouseDraggedPoint, clipboard, src, true); } else if (isSelected && (m_dragSourceAction & DragSourceActionSelection)) { if (!clipboard->hasData()) { - if (isNodeInTextFormControl(src->selection()->start().node())) + if (isNodeInTextFormControl(src->selection()->start().deprecatedNode())) clipboard->writePlainText(src->editor()->selectedText()); else { RefPtr<Range> selectionRange = src->selection()->toNormalizedRange(); diff --git a/Source/WebCore/page/EditorClient.h b/Source/WebCore/page/EditorClient.h index c805920..d5de6a4 100644 --- a/Source/WebCore/page/EditorClient.h +++ b/Source/WebCore/page/EditorClient.h @@ -67,34 +67,12 @@ class KeyboardEvent; class Node; class Range; class SpellChecker; +class TextCheckerClient; class VisibleSelection; class VisiblePosition; -struct GrammarDetail { - int location; - int length; - Vector<String> guesses; - String userDescription; -}; - -enum TextCheckingType { - TextCheckingTypeSpelling = 1 << 1, - TextCheckingTypeGrammar = 1 << 2, - TextCheckingTypeLink = 1 << 5, - TextCheckingTypeQuote = 1 << 6, - TextCheckingTypeDash = 1 << 7, - TextCheckingTypeReplacement = 1 << 8, - TextCheckingTypeCorrection = 1 << 9 -}; +struct GrammarDetail; -struct TextCheckingResult { - TextCheckingType type; - int location; - int length; - Vector<GrammarDetail> details; - String replacement; -}; - class EditorClient { public: virtual ~EditorClient() { } @@ -109,8 +87,6 @@ public: virtual bool isGrammarCheckingEnabled() = 0; virtual void toggleGrammarChecking() = 0; virtual int spellCheckerDocumentTag() = 0; - - virtual bool isEditable() = 0; virtual bool shouldBeginEditing(Range*) = 0; virtual bool shouldEndEditing(Range*) = 0; @@ -132,6 +108,8 @@ public: virtual void registerCommandForRedo(PassRefPtr<EditCommand>) = 0; virtual void clearUndoRedoOperations() = 0; + virtual bool canCopyCut(bool defaultValue) const = 0; + virtual bool canPaste(bool defaultValue) const = 0; virtual bool canUndo() const = 0; virtual bool canRedo() const = 0; @@ -178,30 +156,25 @@ public: virtual void toggleAutomaticSpellingCorrection() = 0; #endif - virtual void ignoreWordInSpellDocument(const String&) = 0; - virtual void learnWord(const String&) = 0; - virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength) = 0; - virtual String getAutoCorrectSuggestionForMisspelledWord(const String& misspelledWord) = 0; - virtual void checkGrammarOfString(const UChar*, int length, Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) = 0; -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) - virtual void checkTextOfParagraph(const UChar* text, int length, uint64_t checkingTypes, Vector<TextCheckingResult>& results) = 0; -#endif + virtual TextCheckerClient* textChecker() = 0; #if SUPPORT_AUTOCORRECTION_PANEL + enum AutocorrectionResponseType { + AutocorrectionEdited, + AutocorrectionReverted + }; virtual void showCorrectionPanel(CorrectionPanelInfo::PanelType, const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacmentString, const Vector<String>& alternativeReplacementStrings, Editor*) = 0; virtual void dismissCorrectionPanel(ReasonForDismissingCorrectionPanel) = 0; virtual bool isShowingCorrectionPanel() = 0; + virtual void recordAutocorrectionResponse(AutocorrectionResponseType, const String& replacedString, const String& replacementString) = 0; #endif virtual void updateSpellingUIWithGrammarString(const String&, const GrammarDetail& detail) = 0; virtual void updateSpellingUIWithMisspelledWord(const String&) = 0; virtual void showSpellingUI(bool show) = 0; virtual bool spellingUIIsShowing() = 0; - // For spellcheckers that support multiple languages, it's often important to be able to identify the language in order to provide more accurate correction suggestions. Caller can pass in more text in "context" to aid such spellcheckers on language identification. Noramlly it's the text surrounding the "word" for which we are getting correction suggestions. - virtual void getGuessesForWord(const String& word, const String& context, Vector<String>& guesses) = 0; virtual void willSetInputMethodState() = 0; virtual void setInputMethodState(bool enabled) = 0; - virtual void requestCheckingOfString(SpellChecker*, int, const String&) = 0; }; } diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp index b173532..ef2ffb3 100644 --- a/Source/WebCore/page/EventHandler.cpp +++ b/Source/WebCore/page/EventHandler.cpp @@ -45,6 +45,7 @@ #include "FrameLoader.h" #include "FrameTree.h" #include "FrameView.h" +#include "htmlediting.h" #include "HTMLFrameElementBase.h" #include "HTMLFrameSetElement.h" #include "HTMLInputElement.h" @@ -78,7 +79,6 @@ #include "UserGestureIndicator.h" #include "UserTypingGestureIndicator.h" #include "WheelEvent.h" -#include "htmlediting.h" // for comparePositions() #include <wtf/CurrentTime.h> #include <wtf/StdLibExtras.h> @@ -204,7 +204,7 @@ EventHandler::EventHandler(Frame* frame) #if PLATFORM(MAC) , m_mouseDownView(nil) , m_sendingEventToSubview(false) - , m_activationEventNumber(0) + , m_activationEventNumber(-1) #endif #if ENABLE(TOUCH_EVENTS) , m_touchPressed(false) @@ -296,7 +296,7 @@ void EventHandler::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHit VisibleSelection newSelection; Element* URLElement = result.hitTestResult().URLElement(); VisiblePosition pos(innerNode->renderer()->positionForPoint(result.localPoint())); - if (pos.isNotNull() && pos.deepEquivalent().node()->isDescendantOf(URLElement)) + if (pos.isNotNull() && pos.deepEquivalent().deprecatedNode()->isDescendantOf(URLElement)) newSelection = VisibleSelection::selectionFromContentsOfNode(URLElement); TextGranularity granularity = CharacterGranularity; @@ -358,7 +358,7 @@ bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestR static int textDistance(const Position& start, const Position& end) { - RefPtr<Range> range = Range::create(start.node()->document(), start, end); + RefPtr<Range> range = Range::create(start.anchorNode()->document(), start, end); return TextIterator::rangeLength(range.get(), true); } @@ -383,7 +383,7 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR VisiblePosition visiblePos(innerNode->renderer()->positionForPoint(event.localPoint())); if (visiblePos.isNull()) - visiblePos = VisiblePosition(innerNode, 0, DOWNSTREAM); + visiblePos = VisiblePosition(firstPositionInOrBeforeNode(innerNode), DOWNSTREAM); Position pos = visiblePos.deepEquivalent(); VisibleSelection newSelection = m_frame->selection()->selection(); @@ -637,7 +637,7 @@ void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint& #if ENABLE(SVG) // Special case to limit selection to the containing block for SVG text. // FIXME: Isn't there a better non-SVG-specific way to do this? - if (Node* selectionBaseNode = newSelection.base().node()) + if (Node* selectionBaseNode = newSelection.base().deprecatedNode()) if (RenderObject* selectionBaseRenderer = selectionBaseNode->renderer()) if (selectionBaseRenderer->isSVGText()) if (targetNode->renderer()->containingBlock() != selectionBaseRenderer->containingBlock()) @@ -1049,7 +1049,7 @@ bool EventHandler::scrollRecursively(ScrollDirection direction, ScrollGranularit frame = frame->tree()->parent(); if (!frame) return false; - return frame->eventHandler()->scrollRecursively(direction, granularity, m_frame->document()->ownerElement()); + return frame->eventHandler()->scrollRecursively(direction, granularity, m_frame->ownerElement()); } bool EventHandler::logicalScrollRecursively(ScrollLogicalDirection direction, ScrollGranularity granularity, Node* startingNode) @@ -1078,7 +1078,7 @@ bool EventHandler::logicalScrollRecursively(ScrollLogicalDirection direction, Sc if (!frame) return false; - return frame->eventHandler()->logicalScrollRecursively(direction, granularity, m_frame->document()->ownerElement()); + return frame->eventHandler()->logicalScrollRecursively(direction, granularity, m_frame->ownerElement()); } IntPoint EventHandler::currentMousePosition() const @@ -2159,7 +2159,7 @@ bool EventHandler::sendContextMenuEventForKey() SelectionController* selectionController = m_frame->selection(); Position start = selectionController->selection().start(); - if (start.node() && (selectionController->rootEditableElement() || selectionController->isRange())) { + if (start.deprecatedNode() && (selectionController->rootEditableElement() || selectionController->isRange())) { RefPtr<Range> selection = selectionController->toNormalizedRange(); IntRect firstRect = m_frame->editor()->firstRectForRange(selection.get()); @@ -2167,6 +2167,8 @@ bool EventHandler::sendContextMenuEventForKey() location = IntPoint(x, firstRect.maxY()); } else if (focusedNode) { RenderBoxModelObject* box = focusedNode->renderBoxModelObject(); + if (!box) + return false; IntRect clippedRect = box->absoluteClippedOverflowRect(); location = IntPoint(clippedRect.x(), clippedRect.maxY() - 1); } else { @@ -2763,23 +2765,33 @@ bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEve return event->defaultHandled(); } -#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(HAIKU) && !PLATFORM(EFL) -bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent*) const +bool EventHandler::isKeyboardOptionTab(KeyboardEvent* event) { - return false; + return event + && (event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent) + && event->altKey() + && event->keyIdentifier() == "U+0009"; } + +static bool eventInvertsTabsToLinksClientCallResult(KeyboardEvent* event) +{ +#if PLATFORM(MAC) || PLATFORM(QT) || PLATFORM(HAIKU) || PLATFORM(EFL) + return EventHandler::isKeyboardOptionTab(event); +#else + return false; #endif +} bool EventHandler::tabsToLinks(KeyboardEvent* event) const { + // FIXME: This function needs a better name. It can be called for keypresses other than Tab when spatial navigation is enabled. + Page* page = m_frame->page(); if (!page) return false; - if (page->chrome()->client()->tabsToLinks()) - return !invertSenseOfTabsToLinks(event); - - return invertSenseOfTabsToLinks(event); + bool tabsToLinksClientCallResult = page->chrome()->client()->keyboardUIMode() & KeyboardAccessTabsToLinks; + return eventInvertsTabsToLinksClientCallResult(event) ? !tabsToLinksClientCallResult : tabsToLinksClientCallResult; } void EventHandler::defaultTextInputEventHandler(TextEvent* event) @@ -2874,7 +2886,7 @@ void EventHandler::capsLockStateMayHaveChanged() void EventHandler::sendResizeEvent() { - m_frame->document()->dispatchWindowEvent(Event::create(eventNames().resizeEvent, false, false)); + m_frame->document()->enqueueWindowEvent(Event::create(eventNames().resizeEvent, false, false)); } void EventHandler::sendScrollEvent() diff --git a/Source/WebCore/page/EventHandler.h b/Source/WebCore/page/EventHandler.h index 1e825c2..e20e43c 100644 --- a/Source/WebCore/page/EventHandler.h +++ b/Source/WebCore/page/EventHandler.h @@ -152,7 +152,7 @@ public: bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&) const; bool tabsToLinks(KeyboardEvent*) const; - bool tabsToAllControls(KeyboardEvent*) const; + bool tabsToAllFormControls(KeyboardEvent*) const; bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; } @@ -229,6 +229,8 @@ public: #endif #endif + static bool isKeyboardOptionTab(KeyboardEvent*); + private: #if ENABLE(DRAG_SUPPORT) enum DragAndDropHandleType { @@ -351,8 +353,6 @@ private: bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&); #endif - bool invertSenseOfTabsToLinks(KeyboardEvent*) const; - #if ENABLE(DRAG_SUPPORT) void updateSelectionForMouseDrag(Node* targetNode, const IntPoint& localPoint); #endif diff --git a/Source/WebCore/page/EventSource.cpp b/Source/WebCore/page/EventSource.cpp index 39f15e9..08d0868 100644 --- a/Source/WebCore/page/EventSource.cpp +++ b/Source/WebCore/page/EventSource.cpp @@ -196,7 +196,7 @@ void EventSource::didReceiveData(const char* data, int length) parseEventStream(); } -void EventSource::didFinishLoading(unsigned long) +void EventSource::didFinishLoading(unsigned long, double) { if (m_receiveBuf.size() > 0 || m_data.size() > 0) { append(m_receiveBuf, "\n\n"); diff --git a/Source/WebCore/page/EventSource.h b/Source/WebCore/page/EventSource.h index 10ad6ba..3385d90 100644 --- a/Source/WebCore/page/EventSource.h +++ b/Source/WebCore/page/EventSource.h @@ -91,8 +91,8 @@ namespace WebCore { virtual EventTargetData* ensureEventTargetData(); virtual void didReceiveResponse(const ResourceResponse&); - virtual void didReceiveData(const char* data, int length); - virtual void didFinishLoading(unsigned long); + virtual void didReceiveData(const char*, int); + virtual void didFinishLoading(unsigned long, double); virtual void didFail(const ResourceError&); virtual void didFailRedirectCheck(); diff --git a/Source/WebCore/page/FocusController.cpp b/Source/WebCore/page/FocusController.cpp index 679288f..10901c5 100644 --- a/Source/WebCore/page/FocusController.cpp +++ b/Source/WebCore/page/FocusController.cpp @@ -55,6 +55,7 @@ #include "Settings.h" #include "SpatialNavigation.h" #include "Widget.h" +#include "htmlediting.h" // For firstPositionInOrBeforeNode namespace WebCore { @@ -201,7 +202,7 @@ bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, Keyb bool caretBrowsing = focusedOrMainFrame()->settings()->caretBrowsingEnabled(); if (caretBrowsing && !currentNode) - currentNode = frame->selection()->start().node(); + currentNode = frame->selection()->start().deprecatedNode(); document->updateLayoutIgnorePendingStylesheets(); @@ -287,7 +288,8 @@ bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, Keyb setFocusedFrame(newDocument->frame()); if (caretBrowsing) { - VisibleSelection newSelection(Position(node, 0), Position(node, 0), DOWNSTREAM); + Position position = firstPositionInOrBeforeNode(node); + VisibleSelection newSelection(position, position, DOWNSTREAM); if (frame->selection()->shouldChangeSelection(newSelection)) frame->selection()->setSelection(newSelection); } @@ -325,7 +327,7 @@ static void clearSelectionIfNeeded(Frame* oldFocusedFrame, Frame* newFocusedFram if (caretBrowsing) return; - Node* selectionStartNode = s->selection().start().node(); + Node* selectionStartNode = s->selection().start().deprecatedNode(); if (selectionStartNode == newFocusedNode || selectionStartNode->isDescendantOf(newFocusedNode) || selectionStartNode->shadowAncestorNode() == newFocusedNode) return; @@ -421,7 +423,7 @@ void FocusController::setActive(bool active) dispatchEventsOnWindowAndFocusedNode(m_focusedFrame->document(), active); } -static void updateFocusCandidateIfNeeded(FocusDirection direction, const IntRect& startingRect, FocusCandidate& candidate, FocusCandidate& closest) +static void updateFocusCandidateIfNeeded(FocusDirection direction, const FocusCandidate& current, FocusCandidate& candidate, FocusCandidate& closest) { ASSERT(candidate.visibleNode->isElementNode()); ASSERT(candidate.visibleNode->renderer()); @@ -434,8 +436,6 @@ static void updateFocusCandidateIfNeeded(FocusDirection direction, const IntRect if (candidate.isOffscreen && !canBeScrolledIntoView(direction, candidate)) return; - FocusCandidate current; - current.rect = startingRect; distanceDataForNode(direction, current, candidate); if (candidate.distance == maxDistance()) return; @@ -449,7 +449,7 @@ static void updateFocusCandidateIfNeeded(FocusDirection direction, const IntRect } IntRect intersectionRect = intersection(candidate.rect, closest.rect); - if (!intersectionRect.isEmpty()) { + if (!intersectionRect.isEmpty() && !areElementsOnSameLine(closest, candidate)) { // If 2 nodes are intersecting, do hit test to find which node in on top. int x = intersectionRect.x() + intersectionRect.width() / 2; int y = intersectionRect.y() + intersectionRect.height() / 2; @@ -478,6 +478,11 @@ void FocusController::findFocusCandidateInContainer(Node* container, const IntRe Node* focusedNode = (focusedFrame() && focusedFrame()->document()) ? focusedFrame()->document()->focusedNode() : 0; Node* node = container->firstChild(); + FocusCandidate current; + current.rect = startingRect; + current.focusableNode = focusedNode; + current.visibleNode = focusedNode; + for (; node; node = (node->isFrameOwnerElement() || canScrollInDirection(node, direction)) ? node->traverseNextSibling(container) : node->traverseNextNode(container)) { if (node == focusedNode) continue; @@ -493,7 +498,7 @@ void FocusController::findFocusCandidateInContainer(Node* container, const IntRe continue; candidate.enclosingScrollableBox = container; - updateFocusCandidateIfNeeded(direction, startingRect, candidate, closest); + updateFocusCandidateIfNeeded(direction, current, candidate, closest); } } diff --git a/Source/WebCore/page/Frame.cpp b/Source/WebCore/page/Frame.cpp index 84df3d1..9a562a1 100644 --- a/Source/WebCore/page/Frame.cpp +++ b/Source/WebCore/page/Frame.cpp @@ -555,13 +555,6 @@ void Frame::injectUserScriptsForWorld(DOMWrapperWorld* world, const UserScriptVe } } -bool Frame::isContentEditable() const -{ - if (m_editor.clientIsEditable()) - return true; - return m_doc->inDesignMode(); -} - #ifndef NDEBUG static HashSet<Frame*>& keepAliveSet() { diff --git a/Source/WebCore/page/Frame.h b/Source/WebCore/page/Frame.h index a1e5c10..25f8aac 100644 --- a/Source/WebCore/page/Frame.h +++ b/Source/WebCore/page/Frame.h @@ -182,8 +182,6 @@ namespace WebCore { DragImageRef nodeImage(Node*); DragImageRef dragImageForSelection(); - bool isContentEditable() const; // if true, everything in frame is editable - VisiblePosition visiblePositionForPoint(const IntPoint& framePoint); Document* documentAtPoint(const IntPoint& windowPoint); diff --git a/Source/WebCore/page/FrameActionScheduler.cpp b/Source/WebCore/page/FrameActionScheduler.cpp new file mode 100644 index 0000000..66d9b3c --- /dev/null +++ b/Source/WebCore/page/FrameActionScheduler.cpp @@ -0,0 +1,111 @@ +/* + * 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: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "FrameActionScheduler.h" + +#include "Event.h" +#include "Node.h" +#include <wtf/Vector.h> + +namespace WebCore { + +class EventFrameAction : public FrameAction { +public: + EventFrameAction(PassRefPtr<Event> event, PassRefPtr<Node> target) + : m_event(event) + , m_eventTarget(target) + { + } + + virtual void fire() + { + // Only dispatch events to nodes that are in the document + ExceptionCode ec = 0; + if (m_eventTarget->inDocument()) + m_eventTarget->dispatchEvent(m_event, ec); + } + +private: + RefPtr<Event> m_event; + RefPtr<Node> m_eventTarget; +}; + +FrameActionScheduler::FrameActionScheduler() + : m_enqueueActions(0) +{ +} + +FrameActionScheduler::~FrameActionScheduler() +{ + clear(); +} + +bool FrameActionScheduler::isEmpty() const +{ + return m_scheduledActions.isEmpty(); +} + +void FrameActionScheduler::clear() +{ + m_scheduledActions.clear(); + m_enqueueActions = 0; +} + +void FrameActionScheduler::pause() +{ + ASSERT(isEmpty() || m_enqueueActions); + m_enqueueActions++; +} + +void FrameActionScheduler::resume() +{ + m_enqueueActions--; + if (!m_enqueueActions) + dispatch(); + ASSERT(isEmpty() || m_enqueueActions); +} + +void FrameActionScheduler::dispatch() +{ + Vector< OwnPtr<FrameAction> > snapshot; + m_scheduledActions.swap(snapshot); + + for (Vector< OwnPtr<FrameAction> >::iterator i = snapshot.begin(); i != snapshot.end(); ++i) + (*i)->fire(); +} + +void FrameActionScheduler::scheduleAction(PassOwnPtr<FrameAction> action) +{ + m_scheduledActions.append(action); +} + +void FrameActionScheduler::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<Node> eventTarget) +{ + scheduleAction(new EventFrameAction(event, eventTarget)); +} + + +} // namespace WebCore diff --git a/Source/WebCore/page/FrameActionScheduler.h b/Source/WebCore/page/FrameActionScheduler.h new file mode 100644 index 0000000..9590de9 --- /dev/null +++ b/Source/WebCore/page/FrameActionScheduler.h @@ -0,0 +1,72 @@ +/* + * 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: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FrameActionScheduler_h +#define FrameActionScheduler_h + +#include <wtf/FastAllocBase.h> +#include <wtf/Noncopyable.h> +#include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + +class Node; +class Event; + +class FrameAction { + WTF_MAKE_FAST_ALLOCATED; + WTF_MAKE_NONCOPYABLE(FrameAction); +public: + FrameAction() {} + virtual ~FrameAction() {} + virtual void fire() = 0; +}; + +class FrameActionScheduler { +public: + FrameActionScheduler(); + ~FrameActionScheduler(); + + bool isEmpty() const; + bool isScheduled() const { return 0 < m_enqueueActions; } + void clear(); + void pause(); + void resume(); + + void scheduleAction(PassOwnPtr<FrameAction>); + void scheduleEvent(PassRefPtr<Event>, PassRefPtr<Node>); + +private: + void dispatch(); + + unsigned m_enqueueActions; + Vector< OwnPtr<FrameAction> > m_scheduledActions; +}; + +} // namespace WebCore + +#endif // FrameActionScheduler_h diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp index 0dc71f6..3be999c 100644 --- a/Source/WebCore/page/FrameView.cpp +++ b/Source/WebCore/page/FrameView.cpp @@ -37,6 +37,7 @@ #include "FloatRect.h" #include "FocusController.h" #include "Frame.h" +#include "FrameActionScheduler.h" #include "FrameLoader.h" #include "FrameLoaderClient.h" #include "FrameTree.h" @@ -118,14 +119,6 @@ double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0; // The maximum number of updateWidgets iterations that should be done before returning. static const unsigned maxUpdateWidgetsIterations = 2; -struct ScheduledEvent { - WTF_MAKE_NONCOPYABLE(ScheduledEvent); WTF_MAKE_FAST_ALLOCATED; -public: - ScheduledEvent() { } - RefPtr<Event> m_event; - RefPtr<Node> m_eventTarget; -}; - FrameView::FrameView(Frame* frame) : m_frame(frame) , m_canHaveScrollbars(true) @@ -139,7 +132,7 @@ FrameView::FrameView(Frame* frame) , m_isTransparent(false) , m_baseBackgroundColor(Color::white) , m_mediaType("screen") - , m_enqueueEvents(0) + , m_actionScheduler(new FrameActionScheduler()) , m_overflowStatusDirty(true) , m_viewportRenderer(0) , m_wasScrolledByUser(false) @@ -148,6 +141,7 @@ FrameView::FrameView(Frame* frame) , m_shouldUpdateWhileOffscreen(true) , m_deferSetNeedsLayouts(0) , m_setNeedsLayoutWasDeferred(false) + , m_isRestoringFromBackForward(false) , m_scrollCorner(0) #if ENABLE(ANDROID_OVERFLOW_SCROLL) , m_hasOverflowScroll(false) @@ -167,6 +161,7 @@ PassRefPtr<FrameView> FrameView::create(Frame* frame, const IntSize& initialSize { RefPtr<FrameView> view = adoptRef(new FrameView(frame)); view->Widget::setFrameRect(IntRect(view->pos(), initialSize)); + view->setInitialBoundsSize(initialSize); view->show(); return view.release(); } @@ -175,8 +170,7 @@ FrameView::~FrameView() { if (m_hasPendingPostLayoutTasks) { m_postLayoutTasksTimer.stop(); - m_scheduledEvents.clear(); - m_enqueueEvents = 0; + m_actionScheduler->clear(); } if (AXObjectCache::accessibilityEnabled() && axObjectCache()) @@ -192,8 +186,7 @@ FrameView::~FrameView() setHasVerticalScrollbar(false); ASSERT(!m_scrollCorner); - ASSERT(m_scheduledEvents.isEmpty()); - ASSERT(!m_enqueueEvents); + ASSERT(m_actionScheduler->isEmpty()); if (m_frame) { ASSERT(m_frame->view() != this || !m_frame->contentRenderer()); @@ -236,6 +229,7 @@ void FrameView::reset() m_isPainting = false; m_isVisuallyNonEmpty = false; m_firstVisuallyNonEmptyLayoutCallbackPending = true; + m_isRestoringFromBackForward = false; m_maintainScrollPositionAnchor = 0; } @@ -269,7 +263,7 @@ void FrameView::init() m_size = IntSize(); // Propagate the marginwidth/height and scrolling modes to the view. - Element* ownerElement = m_frame && m_frame->document() ? m_frame->document()->ownerElement() : 0; + Element* ownerElement = m_frame ? m_frame->ownerElement() : 0; if (ownerElement && (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))) { HTMLFrameElement* frameElt = static_cast<HTMLFrameElement*>(ownerElement); if (frameElt->scrollingMode() == ScrollbarAlwaysOff) @@ -675,10 +669,8 @@ bool FrameView::isEnclosedInCompositingLayer() const if (frameOwnerRenderer && frameOwnerRenderer->containerForRepaint()) return true; - if (Frame* parentFrame = m_frame->tree()->parent()) { - if (FrameView* parentView = parentFrame->view()) - return parentView->isEnclosedInCompositingLayer(); - } + if (FrameView* parentView = parentFrameView()) + return parentView->isEnclosedInCompositingLayer(); #endif return false; } @@ -844,7 +836,7 @@ void FrameView::layout(bool allowSubtree) } #ifdef INSTRUMENT_LAYOUT_SCHEDULING - if (m_firstLayout && !document->ownerElement()) + if (m_firstLayout && !m_frame->ownerElement()) printf("Elapsed time before first layout: %d\n", document->elapsedTime()); #endif } @@ -862,7 +854,12 @@ void FrameView::layout(bool allowSubtree) if (m_firstLayout || (hMode != currentHMode || vMode != currentVMode)) { if (m_firstLayout) { - setScrollbarsSuppressed(true); + if (!m_isRestoringFromBackForward) + setScrollbarsSuppressed(true); + else { + setScrollbarsSuppressed(false); + m_isRestoringFromBackForward = false; + } m_firstLayout = false; m_firstLayoutCallbackPending = true; @@ -901,7 +898,7 @@ void FrameView::layout(bool allowSubtree) RenderLayer* layer = root->enclosingLayer(); - pauseScheduledEvents(); + m_actionScheduler->pause(); bool disableLayoutState = false; if (subtree) { @@ -983,13 +980,12 @@ void FrameView::layout(bool allowSubtree) m_hasPendingPostLayoutTasks = true; m_postLayoutTasksTimer.startOneShot(0); if (needsLayout()) { - pauseScheduledEvents(); + m_actionScheduler->pause(); layout(); } } } else { - resumeScheduledEvents(); - ASSERT(m_enqueueEvents); + m_actionScheduler->resume(); } InspectorInstrumentation::didLayout(cookie); @@ -1069,10 +1065,8 @@ bool FrameView::useSlowRepaints() const if (m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || m_isOverlapped || !m_contentIsOpaque) return true; - if (Frame* parentFrame = m_frame->tree()->parent()) { - if (FrameView* parentView = parentFrame->view()) - return parentView->useSlowRepaints(); - } + if (FrameView* parentView = parentFrameView()) + return parentView->useSlowRepaints(); return false; } @@ -1082,10 +1076,8 @@ bool FrameView::useSlowRepaintsIfNotOverlapped() const if (m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || !m_contentIsOpaque) return true; - if (Frame* parentFrame = m_frame->tree()->parent()) { - if (FrameView* parentView = parentFrame->view()) - return parentView->useSlowRepaintsIfNotOverlapped(); - } + if (FrameView* parentView = parentFrameView()) + return parentView->useSlowRepaintsIfNotOverlapped(); return false; } @@ -1134,6 +1126,7 @@ void FrameView::removeFixedObject() updateCanBlitOnScrollRecursively(); } +<<<<<<< HEAD #if PLATFORM(ANDROID) // When the screen size change, fixed positioned element should be updated. void FrameView::updatePositionedObjects() @@ -1156,6 +1149,64 @@ void FrameView::updatePositionedObjects() } } #endif +======= +int FrameView::scrollXForFixedPosition() const +{ + int visibleContentWidth = visibleContentRect().width(); + int maxX = contentsWidth() - visibleContentWidth; + + if (maxX == 0) + return 0; + + int x = scrollX(); + + if (x < 0) + x = 0; + else if (x > maxX) + x = maxX; + + if (!m_frame) + return x; + + float pageScaleFactor = m_frame->pageScaleFactor(); + + // When the page is scaled, the scaled "viewport" with respect to which fixed object are positioned + // doesn't move as fast as the content view, so that when the content is scrolled all the way to the + // end, the bottom of the scaled "viewport" touches the bottom of the real viewport. + float dragFactor = (contentsWidth() - visibleContentWidth * pageScaleFactor) / maxX; + + return x * dragFactor / pageScaleFactor; +} + +int FrameView::scrollYForFixedPosition() const +{ + int visibleContentHeight = visibleContentRect().height(); + + int maxY = contentsHeight() - visibleContentHeight; + if (maxY == 0) + return 0; + + int y = scrollY(); + + if (y < 0) + y = 0; + else if (y > maxY) + y = maxY; + + if (!m_frame) + return y; + + float pageScaleFactor = m_frame->pageScaleFactor(); + float dragFactor = (contentsHeight() - visibleContentHeight * pageScaleFactor) / maxY; + + return y * dragFactor / pageScaleFactor; +} + +IntSize FrameView::scrollOffsetForFixedPosition() const +{ + return IntSize(scrollXForFixedPosition(), scrollYForFixedPosition()); +} +>>>>>>> WebKit at r80534 IntPoint FrameView::currentMousePosition() const { @@ -1277,11 +1328,9 @@ bool FrameView::isOverlappedIncludingAncestors() const if (isOverlapped()) return true; - if (Frame* parentFrame = m_frame->tree()->parent()) { - if (FrameView* parentView = parentFrame->view()) { - if (parentView->isOverlapped()) - return true; - } + if (FrameView* parentView = parentFrameView()) { + if (parentView->isOverlapped()) + return true; } return false; @@ -1440,7 +1489,7 @@ const unsigned cRepaintRectUnionThreshold = 25; void FrameView::repaintContentRectangle(const IntRect& r, bool immediate) { - ASSERT(!m_frame->document()->ownerElement()); + ASSERT(!m_frame->ownerElement()); double delay = adjustedDeferredRepaintDelay(); if ((m_deferringRepaints || m_deferredRepaintTimer.isActive() || delay) && !immediate) { @@ -1776,11 +1825,12 @@ Color FrameView::baseBackgroundColor() const return m_baseBackgroundColor; } -void FrameView::setBaseBackgroundColor(Color bc) +void FrameView::setBaseBackgroundColor(const Color& backgroundColor) { - if (!bc.isValid()) - bc = Color::white; - m_baseBackgroundColor = bc; + if (!backgroundColor.isValid()) + m_baseBackgroundColor = Color::white; + else + m_baseBackgroundColor = backgroundColor; } void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent) @@ -1814,30 +1864,17 @@ bool FrameView::shouldUpdate(bool immediateRequested) const void FrameView::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<Node> eventTarget) { - if (!m_enqueueEvents) { - ExceptionCode ec = 0; - eventTarget->dispatchEvent(event, ec); - return; - } - - ScheduledEvent* scheduledEvent = new ScheduledEvent; - scheduledEvent->m_event = event; - scheduledEvent->m_eventTarget = eventTarget; - m_scheduledEvents.append(scheduledEvent); + m_actionScheduler->scheduleEvent(event, eventTarget); } void FrameView::pauseScheduledEvents() { - ASSERT(m_scheduledEvents.isEmpty() || m_enqueueEvents); - m_enqueueEvents++; + m_actionScheduler->pause(); } void FrameView::resumeScheduledEvents() { - m_enqueueEvents--; - if (!m_enqueueEvents) - dispatchScheduledEvents(); - ASSERT(m_scheduledEvents.isEmpty() || m_enqueueEvents); + m_actionScheduler->resume(); } void FrameView::scrollToAnchor() @@ -1940,14 +1977,16 @@ void FrameView::performPostLayoutTasks() m_frame->selection()->setCaretRectNeedsUpdate(); m_frame->selection()->updateAppearance(); - if (m_firstLayoutCallbackPending) { - m_firstLayoutCallbackPending = false; - m_frame->loader()->didFirstLayout(); - } - - if (m_isVisuallyNonEmpty && m_firstVisuallyNonEmptyLayoutCallbackPending) { - m_firstVisuallyNonEmptyLayoutCallbackPending = false; - m_frame->loader()->didFirstVisuallyNonEmptyLayout(); + if (m_nestedLayoutCount <= 1) { + if (m_firstLayoutCallbackPending) { + m_firstLayoutCallbackPending = false; + m_frame->loader()->didFirstLayout(); + } + + if (m_isVisuallyNonEmpty && m_firstVisuallyNonEmptyLayoutCallbackPending) { + m_firstVisuallyNonEmptyLayoutCallbackPending = false; + m_frame->loader()->didFirstVisuallyNonEmptyLayout(); + } } RenderView* root = m_frame->contentRenderer(); @@ -1961,7 +2000,7 @@ void FrameView::performPostLayoutTasks() scrollToAnchor(); - resumeScheduledEvents(); + m_actionScheduler->resume(); if (!root->printing()) { IntSize currentSize = IntSize(width(), height()); @@ -1998,35 +2037,13 @@ void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverf m_horizontalOverflow = horizontalOverflow; m_verticalOverflow = verticalOverflow; - scheduleEvent(OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow, + m_actionScheduler->scheduleEvent(OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow, verticalOverflowChanged, verticalOverflow), m_viewportRenderer->node()); } } -void FrameView::dispatchScheduledEvents() -{ - if (m_scheduledEvents.isEmpty()) - return; - - Vector<ScheduledEvent*> scheduledEventsCopy = m_scheduledEvents; - m_scheduledEvents.clear(); - - Vector<ScheduledEvent*>::iterator end = scheduledEventsCopy.end(); - for (Vector<ScheduledEvent*>::iterator it = scheduledEventsCopy.begin(); it != end; ++it) { - ScheduledEvent* scheduledEvent = *it; - - ExceptionCode ec = 0; - - // Only dispatch events to nodes that are in the document - if (scheduledEvent->m_eventTarget->inDocument()) - scheduledEvent->m_eventTarget->dispatchEvent(scheduledEvent->m_event, ec); - - delete scheduledEvent; - } -} - IntRect FrameView::windowClipRect(bool clipToContents) const { ASSERT(m_frame->view() == this); @@ -2036,11 +2053,11 @@ IntRect FrameView::windowClipRect(bool clipToContents) const // Set our clip rect to be our contents. IntRect clipRect = contentsToWindow(visibleContentRect(!clipToContents)); - if (!m_frame || !m_frame->document() || !m_frame->document()->ownerElement()) + if (!m_frame || !m_frame->ownerElement()) return clipRect; // Take our owner element and get the clip rect from the enclosing layer. - Element* elt = m_frame->document()->ownerElement(); + Element* elt = m_frame->ownerElement(); RenderLayer* layer = elt->renderer()->enclosingLayer(); // FIXME: layer should never be null, but sometimes seems to be anyway. if (!layer) @@ -2208,6 +2225,15 @@ bool FrameView::hasCustomScrollbars() const return false; } +FrameView* FrameView::parentFrameView() const +{ + if (Widget* parentView = parent()) { + if (parentView->isFrameView()) + return static_cast<FrameView*>(parentView); + } + return 0; +} + void FrameView::updateControlTints() { // This is called when control tints are changed from aqua/graphite to clear and vice versa. @@ -2252,13 +2278,13 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect) InspectorInstrumentationCookie cookie = InspectorInstrumentation::willPaint(m_frame.get(), rect); - Document* document = frame()->document(); + Document* document = m_frame->document(); #ifndef NDEBUG bool fillWithRed; if (document->printing()) fillWithRed = false; // Printing, don't fill with red (can't remember why). - else if (document->ownerElement()) + else if (m_frame->ownerElement()) fillWithRed = false; // Subframe, don't fill with red. else if (isTransparent()) fillWithRed = false; // Transparent, don't fill with red. @@ -2293,6 +2319,12 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect) #endif PaintBehavior oldPaintBehavior = m_paintBehavior; + + if (FrameView* parentView = parentFrameView()) { + if (parentView->paintBehavior() & PaintBehaviorFlattenCompositingLayers) + m_paintBehavior |= PaintBehaviorFlattenCompositingLayers; + } + if (m_paintBehavior == PaintBehaviorNormal) document->markers()->invalidateRenderedRectsForMarkersInRect(rect); @@ -2300,7 +2332,7 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect) m_paintBehavior |= PaintBehaviorFlattenCompositingLayers; bool flatteningPaint = m_paintBehavior & PaintBehaviorFlattenCompositingLayers; - bool isRootFrame = !document->ownerElement(); + bool isRootFrame = !m_frame->ownerElement(); if (flatteningPaint && isRootFrame) notifyWidgetsInAllFrames(WillPaintFlattened); diff --git a/Source/WebCore/page/FrameView.h b/Source/WebCore/page/FrameView.h index 6c0ead2..8e79a3a 100644 --- a/Source/WebCore/page/FrameView.h +++ b/Source/WebCore/page/FrameView.h @@ -37,6 +37,7 @@ namespace WebCore { class Color; class Event; +class FrameActionScheduler; class FrameViewPrivate; class IntRect; class Node; @@ -46,8 +47,6 @@ class RenderObject; class RenderEmbeddedObject; class RenderScrollbarPart; -struct ScheduledEvent; - template <typename T> class Timer; class FrameView : public ScrollView { @@ -147,7 +146,7 @@ public: void setTransparent(bool isTransparent); Color baseBackgroundColor() const; - void setBaseBackgroundColor(Color); + void setBaseBackgroundColor(const Color&); void updateBackgroundRecursively(const Color&, bool); bool shouldUpdateWhileOffscreen() const; @@ -181,6 +180,12 @@ public: void addFixedObject(); void removeFixedObject(); + // Functions for querying the current scrolled position, negating the effects of overhang + // and adjusting for page scale. + int scrollXForFixedPosition() const; + int scrollYForFixedPosition() const; + IntSize scrollOffsetForFixedPosition() const; + void beginDeferredRepaints(); void endDeferredRepaints(); void checkStopDelayingDeferredRepaints(); @@ -269,6 +274,9 @@ public: // FIXME: Remove this method once plugin loading is decoupled from layout. void flushAnyPendingPostLayoutTasks(); + void setIsRestoringFromBackForward(bool isRestoring) { m_isRestoringFromBackForward = isRestoring; } + bool isRestoringFromBackForward() const { return m_isRestoringFromBackForward; } + protected: virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); virtual void scrollContentsSlowPath(const IntRect& updateRect); @@ -295,7 +303,6 @@ private: void updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow); - void dispatchScheduledEvents(); void performPostLayoutTasks(); virtual void repaintContentRectangle(const IntRect&, bool immediate); @@ -315,7 +322,6 @@ private: virtual void getTickmarks(Vector<IntRect>&) const; virtual void scrollTo(const IntSize&); virtual void didCompleteRubberBand(const IntSize&) const; - virtual bool scrollbarWillRenderIntoCompositingLayer() const { return hasCompositedContent() || isEnclosedInCompositingLayer(); } void deferredRepaintTimerFired(Timer<FrameView>*); void doDeferredRepaints(); @@ -332,6 +338,8 @@ private: virtual void updateScrollCorner(); virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect); + FrameView* parentFrameView() const; + virtual AXObjectCache* axObjectCache() const; void notifyWidgetsInAllFrames(WidgetNotification); @@ -378,9 +386,8 @@ private: String m_mediaType; String m_mediaTypeWhenNotPrinting; - unsigned m_enqueueEvents; - Vector<ScheduledEvent*> m_scheduledEvents; - + OwnPtr<FrameActionScheduler> m_actionScheduler; + bool m_overflowStatusDirty; bool m_horizontalOverflow; bool m_verticalOverflow; @@ -408,6 +415,8 @@ private: bool m_isVisuallyNonEmpty; bool m_firstVisuallyNonEmptyLayoutCallbackPending; + bool m_isRestoringFromBackForward; + RefPtr<Node> m_maintainScrollPositionAnchor; // Renderer to hold our custom scroll corner. diff --git a/Source/WebCore/page/Geolocation.h b/Source/WebCore/page/Geolocation.h index d53c827..7c06ae4 100644 --- a/Source/WebCore/page/Geolocation.h +++ b/Source/WebCore/page/Geolocation.h @@ -215,3 +215,4 @@ private: } // namespace WebCore #endif // Geolocation_h + diff --git a/Source/WebCore/page/GeolocationController.h b/Source/WebCore/page/GeolocationController.h index 1a2ce69..7c55ce2 100644 --- a/Source/WebCore/page/GeolocationController.h +++ b/Source/WebCore/page/GeolocationController.h @@ -57,6 +57,8 @@ public: GeolocationPosition* lastPosition(); + GeolocationClient* client() { return m_client; } + private: Page* m_page; GeolocationClient* m_client; diff --git a/Source/WebCore/page/Location.idl b/Source/WebCore/page/Location.idl index 76340d9..280131a 100644 --- a/Source/WebCore/page/Location.idl +++ b/Source/WebCore/page/Location.idl @@ -65,7 +65,7 @@ module window { DOMString getParameter(in DOMString name); #if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT - [DontEnum, Custom, V8OnInstance, V8ReadOnly] DOMString toString(); + [DontEnum, Custom, V8OnInstance, V8ReadOnly, ImplementationFunction=toStringFunction] DOMString toString(); #endif #if defined(V8_BINDING) && V8_BINDING [DontEnum, Custom, V8OnInstance, V8ReadOnly] DOMObject valueOf(); diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp index 6ffea29..f8d6168 100644 --- a/Source/WebCore/page/Page.cpp +++ b/Source/WebCore/page/Page.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All Rights Reserved. + * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All Rights Reserved. * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) * * This library is free software; you can redistribute it and/or @@ -176,6 +176,7 @@ Page::Page(const PageClients& pageClients) , m_customHTMLTokenizerChunkSize(-1) , m_canStartMedia(true) , m_viewMode(ViewModeWindowed) + , m_minimumTimerInterval(Settings::defaultMinDOMTimerInterval()) { if (!allPages) { allPages = new HashSet<Page*>; @@ -348,25 +349,10 @@ void Page::goToItem(HistoryItem* item, FrameLoadType type) // stopAllLoaders may end up running onload handlers, which could cause further history traversals that may lead to the passed in HistoryItem // being deref()-ed. Make sure we can still use it with HistoryController::goToItem later. RefPtr<HistoryItem> protector(item); - - // Abort any current load unless we're navigating the current document to a new state object - HistoryItem* currentItem = m_mainFrame->loader()->history()->currentItem(); - if (!item->stateObject() || !currentItem || item->documentSequenceNumber() != currentItem->documentSequenceNumber() || item == currentItem) { - // Define what to do with any open database connections. By default we stop them and terminate the database thread. - DatabasePolicy databasePolicy = DatabasePolicyStop; - -#if ENABLE(DATABASE) - // If we're navigating the history via a fragment on the same document, then we do not want to stop databases. - const KURL& currentURL = m_mainFrame->document()->url(); - const KURL& newURL = item->url(); - - if (newURL.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(currentURL, newURL)) - databasePolicy = DatabasePolicyContinue; -#endif - m_mainFrame->loader()->stopAllLoaders(databasePolicy); - } - + if (m_mainFrame->loader()->history()->shouldStopLoadingForHistoryItem(item)) + m_mainFrame->loader()->stopAllLoaders(); + m_mainFrame->loader()->history()->goToItem(item, type); } @@ -375,11 +361,6 @@ int Page::getHistoryLength() return backForward()->backCount() + 1 + backForward()->forwardCount(); } -void Page::setGlobalHistoryItem(HistoryItem* item) -{ - m_globalHistoryItem = item; -} - void Page::setGroupName(const String& name) { if (m_group && !m_group->name().isEmpty()) { @@ -850,6 +831,21 @@ bool Page::javaScriptURLsAreAllowed() const return m_javaScriptURLsAreAllowed; } +void Page::setMinimumTimerInterval(double minimumTimerInterval) +{ + double oldTimerInterval = m_minimumTimerInterval; + m_minimumTimerInterval = minimumTimerInterval; + for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNextWithWrap(false)) { + if (frame->document()) + frame->document()->adjustMinimumTimerInterval(oldTimerInterval); + } +} + +double Page::minimumTimerInterval() const +{ + return m_minimumTimerInterval; +} + #if ENABLE(INPUT_SPEECH) SpeechInput* Page::speechInput() { @@ -870,6 +866,9 @@ void Page::privateBrowsingStateChanged() { bool privateBrowsingEnabled = m_settings->privateBrowsingEnabled(); + for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) + frame->document()->privateBrowsingStateDidChange(); + // Collect the PluginViews in to a vector to ensure that action the plug-in takes // from below privateBrowsingStateChanged does not affect their lifetime. Vector<RefPtr<PluginViewBase>, 32> pluginViewBases; diff --git a/Source/WebCore/page/Page.h b/Source/WebCore/page/Page.h index 071b142..4498d36 100644 --- a/Source/WebCore/page/Page.h +++ b/Source/WebCore/page/Page.h @@ -75,7 +75,6 @@ namespace WebCore { class SharedGraphicsContext3D; class SpeechInput; class SpeechInputClient; - #if ENABLE(DOM_STORAGE) class StorageNamespace; #endif @@ -92,6 +91,7 @@ namespace WebCore { class Page { WTF_MAKE_NONCOPYABLE(Page); + friend class Settings; public: static void scheduleForcedStyleRecalcForAllPages(); @@ -147,9 +147,6 @@ namespace WebCore { void goToItem(HistoryItem*, FrameLoadType); - HistoryItem* globalHistoryItem() const { return m_globalHistoryItem.get(); } - void setGlobalHistoryItem(HistoryItem*); - void setGroupName(const String&); const String& groupName() const; @@ -298,6 +295,9 @@ namespace WebCore { MediaCanStartListener* takeAnyMediaCanStartListener(); + void setMinimumTimerInterval(double); + double minimumTimerInterval() const; + OwnPtr<Chrome> m_chrome; OwnPtr<SelectionController> m_dragCaretController; @@ -332,8 +332,6 @@ namespace WebCore { OwnPtr<BackForwardController> m_backForwardController; RefPtr<Frame> m_mainFrame; - RefPtr<HistoryItem> m_globalHistoryItem; - mutable RefPtr<PluginData> m_pluginData; RefPtr<RenderTheme> m_theme; @@ -386,6 +384,8 @@ namespace WebCore { ViewMode m_viewMode; ViewportArguments m_viewportArguments; + + double m_minimumTimerInterval; }; } // namespace WebCore diff --git a/Source/WebCore/page/PageGroupLoadDeferrer.cpp b/Source/WebCore/page/PageGroupLoadDeferrer.cpp index 781bc34..292b4cd 100644 --- a/Source/WebCore/page/PageGroupLoadDeferrer.cpp +++ b/Source/WebCore/page/PageGroupLoadDeferrer.cpp @@ -39,22 +39,8 @@ PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf) HashSet<Page*>::const_iterator end = pages.end(); for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) { Page* otherPage = *it; - if ((deferSelf || otherPage != page)) { - if (!otherPage->defersLoading()) { - m_deferredFrames.append(otherPage->mainFrame()); - - // This code is not logically part of load deferring, but we do not want JS code executed beneath modal - // windows or sheets, which is exactly when PageGroupLoadDeferrer is used. - // NOTE: if PageGroupLoadDeferrer is ever used for tasks other than showing a modal window or sheet, - // the constructor will need to take a ActiveDOMObject::ReasonForSuspension. - for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree()->traverseNext()) { - frame->document()->suspendActiveDOMObjects(ActiveDOMObject::WillShowDialog); - frame->document()->asyncScriptRunner()->suspend(); - if (DocumentParser* parser = frame->document()->parser()) - parser->suspendScheduledTasks(); - } - } - } + if ((deferSelf || otherPage != page) && !otherPage->defersLoading()) + m_deferredFrames.append(otherPage->mainFrame()); } size_t count = m_deferredFrames.size(); @@ -66,16 +52,8 @@ PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf) PageGroupLoadDeferrer::~PageGroupLoadDeferrer() { for (size_t i = 0; i < m_deferredFrames.size(); ++i) { - if (Page* page = m_deferredFrames[i]->page()) { + if (Page* page = m_deferredFrames[i]->page()) page->setDefersLoading(false); - - for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) { - frame->document()->resumeActiveDOMObjects(); - frame->document()->asyncScriptRunner()->resume(); - if (DocumentParser* parser = frame->document()->parser()) - parser->resumeScheduledTasks(); - } - } } } diff --git a/Source/WebCore/page/PerformanceTiming.cpp b/Source/WebCore/page/PerformanceTiming.cpp index 76b410a..56d6aa9 100644 --- a/Source/WebCore/page/PerformanceTiming.cpp +++ b/Source/WebCore/page/PerformanceTiming.cpp @@ -94,6 +94,9 @@ unsigned long long PerformanceTiming::navigationStart() const if (!timing) return 0; + if (timing->hasCrossOriginRedirect) + return 0; + return toIntegerMilliseconds(timing->navigationStart); } @@ -103,7 +106,7 @@ unsigned long long PerformanceTiming::unloadEventStart() const if (!timing) return 0; - if (!timing->hasSameOriginAsPreviousDocument) + if (timing->hasCrossOriginRedirect || !timing->hasSameOriginAsPreviousDocument) return 0; return toIntegerMilliseconds(timing->unloadEventStart); @@ -115,7 +118,7 @@ unsigned long long PerformanceTiming::unloadEventEnd() const if (!timing) return 0; - if (!timing->hasSameOriginAsPreviousDocument) + if (timing->hasCrossOriginRedirect || !timing->hasSameOriginAsPreviousDocument) return 0; return toIntegerMilliseconds(timing->unloadEventEnd); diff --git a/Source/WebCore/page/Settings.cpp b/Source/WebCore/page/Settings.cpp index 49180f5..1db8a92 100644 --- a/Source/WebCore/page/Settings.cpp +++ b/Source/WebCore/page/Settings.cpp @@ -37,6 +37,7 @@ #include "HistoryItem.h" #include "Page.h" #include "PageCache.h" +#include "ResourceHandle.h" #include "StorageMap.h" #include <limits> @@ -154,6 +155,7 @@ Settings::Settings(Page* page) , m_enforceCSSMIMETypeInNoQuirksMode(true) , m_usesEncodingDetector(false) , m_allowScriptsToCloseWindows(false) + , m_acceleratedDrawingEnabled(false) // FIXME: This should really be disabled by default as it makes platforms that don't support the feature download files // they can't use by. Leaving enabled for now to not change existing behavior. , m_downloadableBinaryFontsEnabled(true) @@ -365,6 +367,10 @@ void Settings::setPrivateBrowsingEnabled(bool privateBrowsingEnabled) if (m_privateBrowsingEnabled == privateBrowsingEnabled) return; +#if USE(CFURLSTORAGESESSIONS) + ResourceHandle::setPrivateBrowsingEnabled(privateBrowsingEnabled); +#endif + // FIXME: We can only enable cookie private browsing mode globally, so it's misleading to have it as a per-page setting. setCookieStoragePrivateBrowsingEnabled(privateBrowsingEnabled); @@ -463,9 +469,24 @@ void Settings::setDOMPasteAllowed(bool DOMPasteAllowed) m_isDOMPasteAllowed = DOMPasteAllowed; } +void Settings::setDefaultMinDOMTimerInterval(double interval) +{ + DOMTimer::setDefaultMinTimerInterval(interval); +} + +double Settings::defaultMinDOMTimerInterval() +{ + return DOMTimer::defaultMinTimerInterval(); +} + void Settings::setMinDOMTimerInterval(double interval) { - DOMTimer::setMinTimerInterval(interval); + m_page->setMinimumTimerInterval(interval); +} + +double Settings::minDOMTimerInterval() +{ + return m_page->minimumTimerInterval(); } void Settings::setUsesPageCache(bool usesPageCache) @@ -800,6 +821,11 @@ void Settings::setAcceleratedCompositingEnabled(bool enabled) setNeedsRecalcStyleInAllFrames(m_page); } +void Settings::setAcceleratedDrawingEnabled(bool enabled) +{ + m_acceleratedDrawingEnabled = enabled; +} + void Settings::setAcceleratedCompositingFor3DTransformsEnabled(bool enabled) { m_acceleratedCompositingFor3DTransformsEnabled = enabled; diff --git a/Source/WebCore/page/Settings.h b/Source/WebCore/page/Settings.h index 3b06834..aee749e 100644 --- a/Source/WebCore/page/Settings.h +++ b/Source/WebCore/page/Settings.h @@ -231,8 +231,12 @@ namespace WebCore { void setDOMPasteAllowed(bool); bool isDOMPasteAllowed() const { return m_isDOMPasteAllowed; } - static void setMinDOMTimerInterval(double); // Interval specified in seconds. + static void setDefaultMinDOMTimerInterval(double); // Interval specified in seconds. + static double defaultMinDOMTimerInterval(); + void setMinDOMTimerInterval(double); // Per-page; initialized to default value. + double minDOMTimerInterval(); + void setUsesPageCache(bool); bool usesPageCache() const { return m_usesPageCache; } @@ -347,6 +351,9 @@ namespace WebCore { void setXSSAuditorEnabled(bool); bool xssAuditorEnabled() const { return m_xssAuditorEnabled; } + void setAcceleratedDrawingEnabled(bool); + bool acceleratedDrawingEnabled() const { return m_acceleratedDrawingEnabled; } + void setAcceleratedCompositingEnabled(bool); bool acceleratedCompositingEnabled() const { return m_acceleratedCompositingEnabled; } @@ -541,6 +548,7 @@ namespace WebCore { bool m_enforceCSSMIMETypeInNoQuirksMode : 1; bool m_usesEncodingDetector : 1; bool m_allowScriptsToCloseWindows : 1; + bool m_acceleratedDrawingEnabled : 1; bool m_downloadableBinaryFontsEnabled : 1; bool m_xssAuditorEnabled : 1; bool m_acceleratedCompositingEnabled : 1; diff --git a/Source/WebCore/page/SpatialNavigation.cpp b/Source/WebCore/page/SpatialNavigation.cpp index 34a2c97..15d3639 100644 --- a/Source/WebCore/page/SpatialNavigation.cpp +++ b/Source/WebCore/page/SpatialNavigation.cpp @@ -39,6 +39,7 @@ #include "IntRect.h" #include "Node.h" #include "Page.h" +#include "RenderInline.h" #include "RenderLayer.h" #include "Settings.h" @@ -594,12 +595,39 @@ void entryAndExitPointsForDirection(FocusDirection direction, const IntRect& sta } } +bool areElementsOnSameLine(const FocusCandidate& firstCandidate, const FocusCandidate& secondCandidate) +{ + if (firstCandidate.isNull() || secondCandidate.isNull()) + return false; + + if (!firstCandidate.visibleNode->renderer() || !secondCandidate.visibleNode->renderer()) + return false; + + if (!firstCandidate.rect.intersects(secondCandidate.rect)) + return false; + + if (firstCandidate.focusableNode->hasTagName(HTMLNames::areaTag) || secondCandidate.focusableNode->hasTagName(HTMLNames::areaTag)) + return false; + + if (!firstCandidate.visibleNode->renderer()->isRenderInline() || !secondCandidate.visibleNode->renderer()->isRenderInline()) + return false; + + if (firstCandidate.visibleNode->renderer()->containingBlock() != secondCandidate.visibleNode->renderer()->containingBlock()) + return false; + + return true; +} + void distanceDataForNode(FocusDirection direction, const FocusCandidate& current, FocusCandidate& candidate) { - if (candidate.isNull()) - return; - if (!candidate.visibleNode->renderer()) - return; + if (areElementsOnSameLine(current, candidate)) { + if ((direction == FocusDirectionUp && current.rect.y() > candidate.rect.y()) || (direction == FocusDirectionDown && candidate.rect.y() > current.rect.y())) { + candidate.distance = 0; + candidate.alignment = Full; + return; + } + } + IntRect nodeRect = candidate.rect; IntRect currentRect = current.rect; deflateIfOverlapped(currentRect, nodeRect); diff --git a/Source/WebCore/page/SpatialNavigation.h b/Source/WebCore/page/SpatialNavigation.h index 9795f28..436aa6e 100644 --- a/Source/WebCore/page/SpatialNavigation.h +++ b/Source/WebCore/page/SpatialNavigation.h @@ -141,6 +141,7 @@ bool scrollInDirection(Node* container, FocusDirection); bool canScrollInDirection(const Node* container, FocusDirection); bool canScrollInDirection(const Frame*, FocusDirection); bool canBeScrolledIntoView(FocusDirection, const FocusCandidate&); +bool areElementsOnSameLine(const FocusCandidate& firstCandidate, const FocusCandidate& secondCandidate); void distanceDataForNode(FocusDirection, const FocusCandidate& current, FocusCandidate& candidate); Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(FocusDirection, Node*); IntRect nodeRectInAbsoluteCoordinates(Node*, bool ignoreBorder = false); diff --git a/Source/WebCore/page/mac/WebCoreKeyboardUIMode.h b/Source/WebCore/page/WebCoreKeyboardUIMode.h index 187cf09..187cf09 100644 --- a/Source/WebCore/page/mac/WebCoreKeyboardUIMode.h +++ b/Source/WebCore/page/WebCoreKeyboardUIMode.h diff --git a/Source/WebCore/page/android/EventHandlerAndroid.cpp b/Source/WebCore/page/android/EventHandlerAndroid.cpp index f8a048c..16ca09c 100644 --- a/Source/WebCore/page/android/EventHandlerAndroid.cpp +++ b/Source/WebCore/page/android/EventHandlerAndroid.cpp @@ -39,7 +39,7 @@ namespace WebCore { -bool EventHandler::tabsToAllControls(KeyboardEvent*) const +bool EventHandler::tabsToAllFormControls(KeyboardEvent*) const { return true; } diff --git a/Source/WebCore/page/brew/EventHandlerBrew.cpp b/Source/WebCore/page/brew/EventHandlerBrew.cpp index e3b6645..f3acec6 100644 --- a/Source/WebCore/page/brew/EventHandlerBrew.cpp +++ b/Source/WebCore/page/brew/EventHandlerBrew.cpp @@ -44,7 +44,7 @@ namespace WebCore { -bool EventHandler::tabsToAllControls(KeyboardEvent* event) const +bool EventHandler::tabsToAllFormControls(KeyboardEvent* event) const { return true; } diff --git a/Source/WebCore/page/chromium/EventHandlerChromium.cpp b/Source/WebCore/page/chromium/EventHandlerChromium.cpp index 9b40fb3..09b4dfa 100644 --- a/Source/WebCore/page/chromium/EventHandlerChromium.cpp +++ b/Source/WebCore/page/chromium/EventHandlerChromium.cpp @@ -114,7 +114,7 @@ bool EventHandler::passMouseDownEventToWidget(Widget* widget) return false; } -bool EventHandler::tabsToAllControls(KeyboardEvent*) const +bool EventHandler::tabsToAllFormControls(KeyboardEvent*) const { return true; } @@ -128,8 +128,8 @@ bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const { - RefPtr<ChromiumDataObjectLegacy> dataObject = ChromiumDataObjectLegacy::create(Clipboard::DragAndDrop); - return ClipboardChromium::create(Clipboard::DragAndDrop, ChromiumDataObject::create(dataObject), ClipboardWritable, m_frame); + RefPtr<ChromiumDataObject> dataObject = ChromiumDataObject::create(Clipboard::DragAndDrop); + return ClipboardChromium::create(Clipboard::DragAndDrop, dataObject.get(), ClipboardWritable, m_frame); } void EventHandler::focusDocumentView() diff --git a/Source/WebCore/page/efl/EventHandlerEfl.cpp b/Source/WebCore/page/efl/EventHandlerEfl.cpp index 33db17e..c079617 100644 --- a/Source/WebCore/page/efl/EventHandlerEfl.cpp +++ b/Source/WebCore/page/efl/EventHandlerEfl.cpp @@ -48,20 +48,7 @@ namespace WebCore { const double EventHandler::TextDragDelay = 0.0; -static bool isKeyboardOptionTab(KeyboardEvent* event) -{ - return event - && (event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent) - && event->altKey() - && event->keyIdentifier() == "U+0009"; -} - -bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent* event) const -{ - return isKeyboardOptionTab(event); -} - -bool EventHandler::tabsToAllControls(KeyboardEvent* event) const +bool EventHandler::tabsToAllFormControls(KeyboardEvent* event) const { return true; } diff --git a/Source/WebCore/page/gtk/EventHandlerGtk.cpp b/Source/WebCore/page/gtk/EventHandlerGtk.cpp index 6e69d9f..ceb7565 100644 --- a/Source/WebCore/page/gtk/EventHandlerGtk.cpp +++ b/Source/WebCore/page/gtk/EventHandlerGtk.cpp @@ -44,7 +44,7 @@ namespace WebCore { const double EventHandler::TextDragDelay = 0.0; -bool EventHandler::tabsToAllControls(KeyboardEvent* event) const +bool EventHandler::tabsToAllFormControls(KeyboardEvent* event) const { // We always allow tabs to all controls return true; diff --git a/Source/WebCore/page/haiku/EventHandlerHaiku.cpp b/Source/WebCore/page/haiku/EventHandlerHaiku.cpp index 933921a..ed4ea32 100644 --- a/Source/WebCore/page/haiku/EventHandlerHaiku.cpp +++ b/Source/WebCore/page/haiku/EventHandlerHaiku.cpp @@ -50,21 +50,7 @@ namespace WebCore { const double EventHandler::TextDragDelay = 0.0; -static bool isKeyboardOptionTab(KeyboardEvent* event) -{ - return event - && (event->type() == eventNames().keydownEvent - || event->type() == eventNames().keypressEvent) - && event->altKey() - && event->keyIdentifier() == "U+0009"; -} - -bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent* event) const -{ - return isKeyboardOptionTab(event); -} - -bool EventHandler::tabsToAllControls(KeyboardEvent* event) const +bool EventHandler::tabsToAllFormControls(KeyboardEvent* event) const { bool handlingOptionTab = isKeyboardOptionTab(event); diff --git a/Source/WebCore/page/mac/EventHandlerMac.mm b/Source/WebCore/page/mac/EventHandlerMac.mm index 6011859..5e96917 100644 --- a/Source/WebCore/page/mac/EventHandlerMac.mm +++ b/Source/WebCore/page/mac/EventHandlerMac.mm @@ -718,20 +718,7 @@ PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const #endif -static inline bool isKeyboardOptionTab(KeyboardEvent* event) -{ - return event - && (event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent) - && event->altKey() - && event->keyIdentifier() == "U+0009"; -} - -bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent* event) const -{ - return isKeyboardOptionTab(event); -} - -bool EventHandler::tabsToAllControls(KeyboardEvent* event) const +bool EventHandler::tabsToAllFormControls(KeyboardEvent* event) const { Page* page = m_frame->page(); if (!page) diff --git a/Source/WebCore/page/qt/EventHandlerQt.cpp b/Source/WebCore/page/qt/EventHandlerQt.cpp index 2c658e7..0343c79 100644 --- a/Source/WebCore/page/qt/EventHandlerQt.cpp +++ b/Source/WebCore/page/qt/EventHandlerQt.cpp @@ -62,20 +62,7 @@ const double EventHandler::TextDragDelay = 0.15; const double EventHandler::TextDragDelay = 0.0; #endif -static bool isKeyboardOptionTab(KeyboardEvent* event) -{ - return event - && (event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent) - && event->altKey() - && event->keyIdentifier() == "U+0009"; -} - -bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent* event) const -{ - return isKeyboardOptionTab(event); -} - -bool EventHandler::tabsToAllControls(KeyboardEvent* event) const +bool EventHandler::tabsToAllFormControls(KeyboardEvent* event) const { return (isKeyboardOptionTab(event) ? !qt_tab_all_widgets : qt_tab_all_widgets); } diff --git a/Source/WebCore/page/win/EventHandlerWin.cpp b/Source/WebCore/page/win/EventHandlerWin.cpp index 039d70b..39a91de 100644 --- a/Source/WebCore/page/win/EventHandlerWin.cpp +++ b/Source/WebCore/page/win/EventHandlerWin.cpp @@ -81,7 +81,7 @@ bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& wheelEvent, Widget return static_cast<FrameView*>(widget)->frame()->eventHandler()->handleWheelEvent(wheelEvent); } -bool EventHandler::tabsToAllControls(KeyboardEvent*) const +bool EventHandler::tabsToAllFormControls(KeyboardEvent*) const { return true; } diff --git a/Source/WebCore/page/wx/EventHandlerWx.cpp b/Source/WebCore/page/wx/EventHandlerWx.cpp index fbb1eaa..66bae01 100644 --- a/Source/WebCore/page/wx/EventHandlerWx.cpp +++ b/Source/WebCore/page/wx/EventHandlerWx.cpp @@ -82,7 +82,7 @@ bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& event, Widget* wid return static_cast<FrameView*>(widget)->frame()->eventHandler()->handleWheelEvent(event); } -bool EventHandler::tabsToAllControls(KeyboardEvent* event) const +bool EventHandler::tabsToAllFormControls(KeyboardEvent* event) const { notImplemented(); return false; |