diff --git a/AppKit/CPEvent.j b/AppKit/CPEvent.j index 478a08897..190065d4d 100644 --- a/AppKit/CPEvent.j +++ b/AppKit/CPEvent.j @@ -68,6 +68,11 @@ var _CPEventPeriodicEventPeriod = 0, float _deltaX; float _deltaY; float _deltaZ; + +#if PLATFORM(DOM) + BOOL _suppressCappuccinoCut; + BOOL _suppressCappuccinoPaste; +#endif } /*! @@ -473,6 +478,24 @@ var _CPEventPeriodicEventPeriod = 0, return !firstResponderIsText; } +/*! + Return YES if this event is a part of processing a browser controlled cut or paste event + where the browser will go ahead and do the work of cutting or pasting within the input + element after processing of this event. The implication is that it should not be done by + the CPTextField (or whatever else is controlling the input) since this would result in + nothing being cut (because the field already cut the text out), or a double paste + (because the field pasted as well as the browser). +*/ +- (BOOL)_platformIsEffectingCutOrPaste +{ +#if PLATFORM(DOM) + return _suppressCappuccinoCut || _suppressCappuccinoPaste; +#else + return NO; +#endif +} + + /*! Generates periodic events every \c aPeriod seconds. diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index 31b9af003..90638db9b 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -1356,7 +1356,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); if (![self isEditable]) return; - if (![CPPlatform isBrowser]) + if (![[CPApp currentEvent] _platformIsEffectingCutOrPaste]) { [self deleteBackward:sender]; } @@ -1376,7 +1376,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); if (!([self isEnabled] && [self isEditable])) return; - if (![CPPlatform isBrowser]) + if (![[CPApp currentEvent] _platformIsEffectingCutOrPaste]) { var pasteboard = [CPPasteboard generalPasteboard]; diff --git a/AppKit/Platform/DOM/CPPlatformPasteboard.j b/AppKit/Platform/DOM/CPPlatformPasteboard.j index 69a1e667f..e6232d66f 100644 --- a/AppKit/Platform/DOM/CPPlatformPasteboard.j +++ b/AppKit/Platform/DOM/CPPlatformPasteboard.j @@ -37,6 +37,9 @@ #if PLATFORM(DOM) +#define SUPPRESS_CAPPUCCINO_CUT_FOR_EVENT(anEvent) anEvent._suppressCappuccinoCut = YES +#define SUPPRESS_CAPPUCCINO_PASTE_FOR_EVENT(anEvent) anEvent._suppressCappuccinoPaste = YES + var hasEditableTarget = function(aDOMEvent) { var target = aDOMEvent.target || aDOMEvent.srcElement; @@ -261,6 +264,11 @@ var hasEditableTarget = function(aDOMEvent) currentEventShouldDefinitelyBubble = YES; } + + if (!currentEventShouldBeSuppressed && characters === "v") + SUPPRESS_CAPPUCCINO_PASTE_FOR_EVENT(anEvent); + else if (!currentEventShouldBeSuppressed && characters == "x") + SUPPRESS_CAPPUCCINO_CUT_FOR_EVENT(anEvent); } - (BOOL)windowShouldSuppressKeyEvent @@ -456,6 +464,8 @@ Return true if the event may be a copy and paste event, but the target is not an var anEvent = [self _fakeClipboardEvent:aDOMEvent type:"v"], platformWindow = [[anEvent window] platformWindow]; + SUPPRESS_CAPPUCCINO_PASTE_FOR_EVENT(anEvent); + // By default we'll stop the native handling of the event since we're handling it ourselves. However, we need to // stop it before we send the event so that the event can overrule our choice. CPTextField for instance wants the // default handling when focused (which is to insert into the field). @@ -480,6 +490,8 @@ Return true if the event may be a copy and paste event, but the target is not an var anEvent = [self _fakeClipboardEvent:aDOMEvent type:(aDOMEvent.type.indexOf("cut") != CPNotFound ? "x" : "c")], platformWindow = [[anEvent window] platformWindow]; + SUPPRESS_CAPPUCCINO_CUT_FOR_EVENT(anEvent); + [platformWindow _propagateCurrentDOMEvent:NO] // Let the app react through copy: and cut: actions.