diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index 74b2ecc8f..e25353df8 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -602,39 +602,10 @@ CPRunContinuesResponse = -1002; var theWindow = [anEvent window]; -#if PLATFORM(DOM) - var willPropagate = [[theWindow platformWindow] _willPropagateCurrentDOMEvent]; - - // temporarily pretend we won't propagate the event. we'll restore the saved value later - // we do this outside the if so that changes user code might make in _handleKeyEquiv. are preserved - [[theWindow platformWindow] _propagateCurrentDOMEvent:NO]; -#endif - // Check if this is a candidate for key equivalent... if ([anEvent _couldBeKeyEquivalent] && [self _handleKeyEquivalent:anEvent]) - { -#if PLATFORM(DOM) - var characters = [anEvent characters], - modifierFlags = [anEvent modifierFlags]; - - // Unconditionally propagate on these keys to allow browser cut and paste to kick in, unless it's a simulated event actually generated by - // native copy and paste handling in which case we need to not mess with what it's doing with _propagateCurrentDOMEvent:. - // TODO Find a way to move this logic to CPPlatformWindow itself. It's in a weird spot. - if ((characters == "c" || characters == "x" || characters == "v") && (modifierFlags & CPPlatformActionKeyMask) && ![[anEvent data1] valueForKey:@"simulated"]) - { - [[theWindow platformWindow] _propagateCurrentDOMEvent:YES]; - return; - } -#endif - // The key equivalent was handled. return; - } - -#if PLATFORM(DOM) - // if we make it this far, then restore the original willPropagate value - [[theWindow platformWindow] _propagateCurrentDOMEvent:willPropagate]; -#endif if ([anEvent type] == CPMouseMoved) { diff --git a/AppKit/CPCompatibility.j b/AppKit/CPCompatibility.j index d55cbc55b..a912a0276 100644 --- a/AppKit/CPCompatibility.j +++ b/AppKit/CPCompatibility.j @@ -86,7 +86,9 @@ CPFileAPIFeature = 31; CPCanvasParentDrawErrorsOnMovementBug = 1 << 0; // The paste event is only sent if an input or textarea has focus. -CPJavaScriptPasteRequiresFocusedInput = 1 << 1; +CPJavaScriptPasteRequiresEditableTarget = 1 << 1; +// Redirecting the focus of the browser on keydown to an input for Cmd-V or Ctrl-V makes the paste fail. +CPJavaScriptPasteCantRefocus = 1 << 2; var USER_AGENT = "", @@ -171,7 +173,9 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1) PLATFORM_FEATURES[CPSOPDisabledFromFileURLs] = YES; PLATFORM_FEATURES[CPHTMLDragAndDropFeature] = YES; // https://bugs.webkit.org/show_bug.cgi?id=75891 - PLATFORM_BUGS |= CPJavaScriptPasteRequiresFocusedInput; + PLATFORM_BUGS |= CPJavaScriptPasteRequiresEditableTarget; + // https://bugs.webkit.org/show_bug.cgi?id=39689 + PLATFORM_BUGS |= CPJavaScriptPasteCantRefocus; } // Assume this bug was introduced around Safari 5.1/Chrome 16. This could probably be tighter. @@ -204,8 +208,16 @@ else if (USER_AGENT.indexOf("Gecko") !== -1) // Must follow KHTML check. // Some day this might be fixed and should be version prefixed. No known fixed version yet. PLATFORM_FEATURES[CPInput1PxLeftPadding] = YES; - if (version >= 22.0) - PLATFORM_FEATURES[CPJavaScriptClipboardEventsFeature] = YES; + // This was supposed to be added in Firefox 22, but when testing with the latest beta as of 2013-06-14 + // it does not seem to work. It seems to exhibit the CPJavaScriptPasteRequiresEditableTarget problem, + // and in addition doesn't seem to work with our native copy code either. + /*if (version >= 22.0) + { + PLATFORM_FEATURES[CPJavaScriptClipboardEventsFeature] = YES; + // TODO File a bug at https://bugzilla.mozilla.org/. In other browsers, one can return "false" from the + // beforepaste event to indicate a paste should be enabled even that the DOMEvent.target is not editable. + PLATFORM_BUGS |= CPJavaScriptPasteRequiresEditableTarget; + }*/ } // Feature-specific checks diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j index 1b36c6171..e72983def 100644 --- a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j +++ b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j @@ -199,8 +199,9 @@ var ModifierKeyCodes = [ supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop], - supportsNativeCopyAndPaste = CPFeatureIsCompatible(CPJavaScriptClipboardEventsFeature), - hasBugWhichPreventsNonEditablePaste = CPPlatformHasBug(CPJavaScriptPasteRequiresFocusedInput); + supportsNativeCopyAndPaste = CPFeatureIsCompatible(CPJavaScriptClipboardEventsFeature), + hasBugWhichPreventsNonEditablePaste = CPPlatformHasBug(CPJavaScriptPasteRequiresEditableTarget), + hasBugWhichPreventsNonEditablePasteRedirect = CPPlatformHasBug(CPJavaScriptPasteCantRefocus); var resizeTimer = nil; @@ -413,13 +414,13 @@ var hasEditableTarget = function(aDOMEvent) pasteEventSelector = @selector(pasteEvent:), pasteEventImplementation = class_getMethodImplementation(theClass, pasteEventSelector), - pasteEventCallback = function (anEvent) {pasteEventImplementation(self, nil, anEvent); }, + pasteEventCallback = function (anEvent) { return pasteEventImplementation(self, nil, anEvent); }, nativePasteEventCallback = function (anEvent) { return [self nativePasteEvent:anEvent]; }, keyEventSelector = @selector(keyEvent:), keyEventImplementation = class_getMethodImplementation(theClass, keyEventSelector), - keyEventCallback = function (anEvent) { keyEventImplementation(self, nil, anEvent); }, + keyEventCallback = function (anEvent) { return keyEventImplementation(self, nil, anEvent); }, mouseEventSelector = @selector(mouseEvent:), mouseEventImplementation = class_getMethodImplementation(theClass, mouseEventSelector), @@ -817,18 +818,17 @@ var hasEditableTarget = function(aDOMEvent) // sending a CPEvent. Select our element to see if anything gets pasted in it. if (characters === "v" && mayRequireDOMPasteboardElement) { - if (hasBugWhichPreventsNonEditablePaste && !hasEditableTarget(aDOMEvent)) + StopDOMEventPropagation = NO; + + if (supportsNativeCopyAndPaste && hasBugWhichPreventsNonEditablePaste && hasBugWhichPreventsNonEditablePasteRedirect && !hasEditableTarget(aDOMEvent)) { // You can't paste from the system clipboard into a non-editable area in Safari, neither using native // copy and paste nor our _DOMPasteboardElement hack. We will paste from the Cappuccino pasteboard only // and allow Safari to "beep" to indicate something went wrong. - StopDOMEventPropagation = NO; isNativePasteEvent = NO; } - else if (supportsNativeCopyAndPaste) - isNativePasteEvent = YES; - else if (!supportsNativeCopyAndPaste && !_ignoreNativePastePreparation) + else if (!(supportsNativeCopyAndPaste || hasBugWhichPreventsNonEditablePaste) && !_ignoreNativePastePreparation) { // We don't support native copy and paste so we must focus the _DOMPasteboardElement to receive the // paste content. @@ -836,15 +836,17 @@ var hasEditableTarget = function(aDOMEvent) _DOMPasteboardElement.select(); _DOMPasteboardElement.value = ""; - StopDOMEventPropagation = NO; isNativePasteEvent = YES; } + else if (supportsNativeCopyAndPaste) + isNativePasteEvent = YES; } // However, of this could be a native COPY event, we need to let the normal event-process take place so it // can capture our internal Cappuccino pasteboard. else if ((characters == "c" || characters == "x") && mayRequireDOMPasteboardElement) { + StopDOMEventPropagation = NO; isNativeCopyOrCutEvent = YES; if (!supportsNativeCopyAndPaste && _ignoreNativeCopyOrCutEvent) @@ -946,7 +948,9 @@ var hasEditableTarget = function(aDOMEvent) break; } - if (event && !isNativePasteEvent) + // If we are going to use our native cut and paste handlers, they will fake the keydown later. So we need to + // not send it here too, or a single cut turns into 2 cuts, etc. + if (event && !isNativePasteEvent && (!supportsNativeCopyAndPaste || !isNativeCopyOrCutEvent)) { event._DOMEvent = aDOMEvent; @@ -957,10 +961,10 @@ var hasEditableTarget = function(aDOMEvent) // If this is a native copy event, then check if the pasteboard has anything in it. [self _primeDOMPasteboardElement]; } - } if (StopDOMEventPropagation) CPDOMEventStop(aDOMEvent, self); + } [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];