Simplify copy and paste code path.

This change begins to clean up the control flow of copy and paste. Before, copy and paste was dealt with partly in CPPlatformWindow, partly in CPApp and partly in CPTextField.

Now, CPApplication has been removed from the path, simplifying it down to the two more expected actors.
This commit is contained in:
Alexander Ljungberg
2013-06-15 17:08:11 +01:00
parent 0ead233cba
commit 2b0754c6a0
3 changed files with 32 additions and 45 deletions
-29
View File
@@ -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)
{
+16 -4
View File
@@ -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
+16 -12
View File
@@ -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];