зеркало из https://github.com/mozilla/gecko-dev.git
Bug 407983, add clipboard events constructor, r=smaug
This commit is contained in:
Родитель
5624ee6b03
Коммит
9fe80b713b
|
@ -7,6 +7,7 @@
|
|||
#include "nsContentUtils.h"
|
||||
#include "nsClientRect.h"
|
||||
#include "nsDOMDataTransfer.h"
|
||||
#include "DictionaryHelpers.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
|
||||
nsDOMClipboardEvent::nsDOMClipboardEvent(mozilla::dom::EventTarget* aOwner,
|
||||
|
@ -41,6 +42,45 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
|
|||
NS_IMPL_ADDREF_INHERITED(nsDOMClipboardEvent, nsDOMEvent)
|
||||
NS_IMPL_RELEASE_INHERITED(nsDOMClipboardEvent, nsDOMEvent)
|
||||
|
||||
nsresult
|
||||
nsDOMClipboardEvent::InitClipboardEvent(const nsAString & aType, bool aCanBubble, bool aCancelable,
|
||||
nsIDOMDataTransfer* clipboardData)
|
||||
{
|
||||
nsresult rv = nsDOMEvent::InitEvent(aType, aCanBubble, aCancelable);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsClipboardEvent* event = static_cast<nsClipboardEvent*>(mEvent);
|
||||
event->clipboardData = clipboardData;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMClipboardEvent::InitFromCtor(const nsAString& aType,
|
||||
JSContext* aCx, jsval* aVal)
|
||||
{
|
||||
mozilla::idl::ClipboardEventInit d;
|
||||
nsresult rv = d.Init(aCx, aVal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsRefPtr<nsDOMDataTransfer> clipboardData;
|
||||
if (mEventIsInternal) {
|
||||
nsClipboardEvent* event = static_cast<nsClipboardEvent*>(mEvent);
|
||||
if (event) {
|
||||
// Always create a clipboardData for the copy event. If this is changed to
|
||||
// support other types of events, make sure that read/write privileges are
|
||||
// checked properly within nsDOMDataTransfer.
|
||||
clipboardData = new nsDOMDataTransfer(NS_COPY, false);
|
||||
clipboardData->SetData(d.dataType, d.data);
|
||||
}
|
||||
}
|
||||
|
||||
rv = InitClipboardEvent(aType, d.bubbles, d.cancelable, clipboardData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMClipboardEvent::GetClipboardData(nsIDOMDataTransfer** aClipboardData)
|
||||
{
|
||||
|
|
|
@ -24,6 +24,10 @@ public:
|
|||
|
||||
// Forward to base class
|
||||
NS_FORWARD_TO_NSDOMEVENT
|
||||
|
||||
nsresult InitFromCtor(const nsAString& aType,
|
||||
JSContext* aCx, jsval* aVal);
|
||||
|
||||
};
|
||||
|
||||
#endif // nsDOMClipboardEvent_h_
|
||||
|
|
|
@ -742,7 +742,7 @@ nsEventDispatcher::CreateEvent(mozilla::dom::EventTarget* aOwner,
|
|||
return NS_NewDOMTextEvent(aDOMEvent, aOwner, aPresContext,
|
||||
static_cast<nsTextEvent*>(aEvent));
|
||||
case NS_CLIPBOARD_EVENT:
|
||||
return NS_NewDOMClipboardEvent(aDOMEvent, aPresContext,
|
||||
return NS_NewDOMClipboardEvent(aDOMEvent, aOwner, aPresContext,
|
||||
static_cast<nsClipboardEvent*>(aEvent));
|
||||
case NS_SVG_EVENT:
|
||||
return NS_NewDOMSVGEvent(aDOMEvent, aOwner, aPresContext,
|
||||
|
|
|
@ -1196,6 +1196,7 @@ NS_DEFINE_CONTRACT_CTOR(MozActivity, NS_DOMACTIVITY_CONTRACTID)
|
|||
NS_DEFINE_EVENT_CTOR(UIEvent)
|
||||
NS_DEFINE_EVENT_CTOR(MouseEvent)
|
||||
NS_DEFINE_EVENT_CTOR(WheelEvent)
|
||||
NS_DEFINE_EVENT_CTOR(ClipboardEvent)
|
||||
|
||||
#define MOZ_GENERATED_EVENT_LIST
|
||||
#define MOZ_GENERATED_EVENT(_event_interface) \
|
||||
|
@ -1222,6 +1223,7 @@ static const nsConstructorFuncMapData kConstructorFuncMap[] =
|
|||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(UIEvent)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MouseEvent)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(WheelEvent)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(ClipboardEvent)
|
||||
#ifdef MOZ_B2G_RIL
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MozWifiStatusChangeEvent)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MozWifiConnectionInfoEvent)
|
||||
|
|
|
@ -13,4 +13,16 @@ interface nsIDOMClipboardEvent : nsIDOMEvent
|
|||
{
|
||||
readonly attribute nsIDOMDataTransfer clipboardData;
|
||||
|
||||
// The constructor must be used from script to initialize
|
||||
// clipboard events.
|
||||
[noscript] void initClipboardEvent(in DOMString typeArg,
|
||||
in boolean canBubbleArg,
|
||||
in boolean cancelableArg,
|
||||
in nsIDOMDataTransfer clipboardData);
|
||||
};
|
||||
|
||||
dictionary ClipboardEventInit : EventInit
|
||||
{
|
||||
DOMString data;
|
||||
DOMString dataType;
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<title>Test for Clipboard Events</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
@ -12,6 +12,10 @@
|
|||
<div id="content" style="border: 3px solid black; padding: 3em;">CONTENT TEXT<input id="content-input" value="INPUT TEXT"></div>
|
||||
<button id="button">Button</button>
|
||||
|
||||
<div id="syntheticSpot" oncut="compareSynthetic(event, 'cut')"
|
||||
oncopy="compareSynthetic(event, 'copy')"
|
||||
onpaste="compareSynthetic(event, 'paste')">Spot</div>
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
|
||||
|
@ -64,25 +68,27 @@ window.onfocus = function()
|
|||
test_input_copypaste_dataTransfer_multiple,
|
||||
test_input_copy_button_dataTransfer
|
||||
];
|
||||
|
||||
|
||||
// Run the main tests. This will also populate the delayedTests array
|
||||
for (let i = 0; i < testFunctions.length; i++) {
|
||||
// Init clipboard
|
||||
setClipboardText(clipboardInitialValue);
|
||||
|
||||
|
||||
// Reset value of contentInput.
|
||||
contentInput.value = "INPUT TEXT";
|
||||
|
||||
|
||||
var func = testFunctions[i];
|
||||
func();
|
||||
}
|
||||
|
||||
// Finally, check if the cached clipboard data can be accessed or modified
|
||||
|
||||
// Check if the cached clipboard data can be accessed or modified
|
||||
// and whether it modifies the real clipboard
|
||||
checkCachedDataTransfer(cachedCutData, "cut");
|
||||
checkCachedDataTransfer(cachedCopyData, "copy");
|
||||
checkCachedDataTransfer(cachedPasteData, "paste");
|
||||
|
||||
checkSyntheticEvents();
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
@ -102,7 +108,7 @@ function getClipboardText() {
|
|||
trans = trans.QueryInterface(Components.interfaces.nsITransferable);
|
||||
trans.init(getLoadContext());
|
||||
trans.addDataFlavor("text/unicode");
|
||||
|
||||
|
||||
var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
|
||||
.getService();
|
||||
clipboard = clipboard.QueryInterface(Components.interfaces.nsIClipboard);
|
||||
|
@ -110,7 +116,7 @@ function getClipboardText() {
|
|||
|
||||
var str = new Object();
|
||||
var strLen = new Object();
|
||||
|
||||
|
||||
try {
|
||||
trans.getTransferData("text/unicode", str, strLen);
|
||||
} catch(e) {
|
||||
|
@ -124,15 +130,15 @@ function getClipboardText() {
|
|||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!str) return null;
|
||||
|
||||
str = str.value.QueryInterface(Components.interfaces.nsISupportsString);
|
||||
if (!str) return null;
|
||||
|
||||
|
||||
str = str.data.substring(0, strLen.value / 2);
|
||||
if (!str) return null;
|
||||
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -160,6 +166,7 @@ function test_dom_oncopy() {
|
|||
// handler was called, and the clipboard contents have set to CONTENT TEXT.
|
||||
// Test firing oncopy event on ctrl-c:
|
||||
selectContentDiv();
|
||||
|
||||
var oncopy_fired = false;
|
||||
content.oncopy = function() { oncopy_fired = true; };
|
||||
try {
|
||||
|
@ -564,6 +571,85 @@ function test_input_copy_button_dataTransfer() {
|
|||
}
|
||||
}
|
||||
|
||||
let expectedData = [];
|
||||
|
||||
// Check to make that synthetic events do not change the clipboard
|
||||
function checkSyntheticEvents()
|
||||
{
|
||||
let syntheticSpot = document.getElementById("syntheticSpot");
|
||||
setClipboardText(clipboardInitialValue);
|
||||
|
||||
// No dataType specified
|
||||
let event = new ClipboardEvent("cut", { data: "something" });
|
||||
expectedData = { type: "cut", data: null }
|
||||
compareSynthetic(event, "before");
|
||||
syntheticSpot.dispatchEvent(event);
|
||||
ok(expectedData.eventFired, "cut event fired");
|
||||
compareSynthetic(event, "after");
|
||||
|
||||
event = new ClipboardEvent("cut", { dataType: "text/plain", data: "something" });
|
||||
expectedData = { type: "cut", dataType: "text/plain", data: "something" }
|
||||
compareSynthetic(event, "before");
|
||||
syntheticSpot.dispatchEvent(event);
|
||||
ok(expectedData.eventFired, "cut event fired");
|
||||
compareSynthetic(event, "after");
|
||||
|
||||
event = new ClipboardEvent("copy", { dataType: "text/plain", data: "something" });
|
||||
expectedData = { type: "copy", dataType: "text/plain", data: "something" }
|
||||
compareSynthetic(event, "before");
|
||||
syntheticSpot.dispatchEvent(event);
|
||||
ok(expectedData.eventFired, "copy event fired");
|
||||
compareSynthetic(event, "after");
|
||||
|
||||
event = new ClipboardEvent("copy", { dataType: "text/plain" });
|
||||
expectedData = { type: "copy", dataType: "text/plain", data: "" }
|
||||
compareSynthetic(event, "before");
|
||||
syntheticSpot.dispatchEvent(event);
|
||||
ok(expectedData.eventFired, "copy event fired");
|
||||
compareSynthetic(event, "after");
|
||||
|
||||
event = new ClipboardEvent("paste", { dataType: "text/plain", data: "something" });
|
||||
expectedData = { type: "paste", dataType: "text/plain", data: "something" }
|
||||
compareSynthetic(event, "before");
|
||||
syntheticSpot.dispatchEvent(event);
|
||||
ok(expectedData.eventFired, "paste event fired");
|
||||
compareSynthetic(event, "after");
|
||||
|
||||
event = new ClipboardEvent("paste", { dataType: "application/unknown", data: "unknown" });
|
||||
expectedData = { type: "paste", dataType: "application/unknown", data: "unknown" }
|
||||
compareSynthetic(event, "before");
|
||||
syntheticSpot.dispatchEvent(event);
|
||||
ok(expectedData.eventFired, "paste event fired");
|
||||
compareSynthetic(event, "after");
|
||||
}
|
||||
|
||||
function compareSynthetic(event, eventtype)
|
||||
{
|
||||
let step = (eventtype == "cut" || eventtype == "copy" || eventtype == "paste") ? "during" : eventtype;
|
||||
if (step == "during") {
|
||||
is(eventtype, expectedData.type, "synthetic " + eventtype + " event fired");
|
||||
}
|
||||
|
||||
ok(event.clipboardData instanceof DataTransfer, "clipboardData is assigned");
|
||||
|
||||
is(event.type, expectedData.type, "synthetic " + eventtype + " event type");
|
||||
if (expectedData.data === null) {
|
||||
is(event.clipboardData.mozItemCount, 0, "synthetic " + eventtype + " empty data");
|
||||
}
|
||||
else {
|
||||
is(event.clipboardData.mozItemCount, 1, "synthetic " + eventtype + " item count");
|
||||
is(event.clipboardData.types.length, 1, "synthetic " + eventtype + " types length");
|
||||
is(event.clipboardData.getData(expectedData.dataType), expectedData.data,
|
||||
"synthetic " + eventtype + " data");
|
||||
}
|
||||
|
||||
is(getClipboardText(), "empty", "event does not change the clipboard " + step + " dispatch");
|
||||
|
||||
if (step == "during") {
|
||||
expectedData.eventFired = true;
|
||||
}
|
||||
}
|
||||
|
||||
function checkCachedDataTransfer(cd, eventtype)
|
||||
{
|
||||
var testprefix = "cached " + eventtype + " dataTransfer";
|
||||
|
|
|
@ -7,6 +7,7 @@ dictionaries = [
|
|||
[ 'EventInit', 'nsIDOMEvent.idl' ],
|
||||
[ 'UIEventInit', 'nsIDOMUIEvent.idl' ],
|
||||
[ 'MouseEventInit', 'nsIDOMMouseEvent.idl' ],
|
||||
[ 'ClipboardEventInit', 'nsIDOMClipboardEvent.idl' ],
|
||||
[ 'WheelEventInit', 'nsIDOMWheelEvent.idl' ],
|
||||
[ 'IDBObjectStoreParameters', 'nsIIDBDatabase.idl' ],
|
||||
[ 'IDBIndexParameters', 'nsIIDBObjectStore.idl' ],
|
||||
|
|
Загрузка…
Ссылка в новой задаче