forked from mirrors/gecko-dev
Bug 1812543 - [Cocoa] Check cached transferable properly in nsClipboard::HasDataMatchingFlavors; r=spohl
Differential Revision: https://phabricator.services.mozilla.com/D167932
This commit is contained in:
parent
d05bc6c6f5
commit
38bdecc2a6
5 changed files with 125 additions and 26 deletions
|
|
@ -350,36 +350,42 @@ nsClipboard::HasDataMatchingFlavors(const nsTArray<nsCString>& aFlavorList, int3
|
|||
|
||||
*outResult = false;
|
||||
|
||||
if (aWhichClipboard != kGlobalClipboard) return NS_OK;
|
||||
if (aWhichClipboard != kGlobalClipboard) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// first see if we have data for this in our cached transferable
|
||||
if (mTransferable) {
|
||||
nsTArray<nsCString> flavors;
|
||||
nsresult rv = mTransferable->FlavorsTransferableCanImport(flavors);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (CLIPBOARD_LOG_ENABLED()) {
|
||||
CLIPBOARD_LOG(" Cached transferable types (nums %zu)\n", flavors.Length());
|
||||
for (uint32_t j = 0; j < flavors.Length(); j++) {
|
||||
CLIPBOARD_LOG(" MIME %s\n", flavors[j].get());
|
||||
NSPasteboard* generalPBoard = [NSPasteboard generalPasteboard];
|
||||
if (mCachedClipboard == aWhichClipboard) {
|
||||
if (mChangeCount != [generalPBoard changeCount]) {
|
||||
// Clear the cached transferable as it is no longer valid.
|
||||
ClearClipboardCache();
|
||||
} else if (mTransferable) {
|
||||
// See if we have data for this in our cached transferable.
|
||||
nsTArray<nsCString> flavors;
|
||||
nsresult rv = mTransferable->FlavorsTransferableCanImport(flavors);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (CLIPBOARD_LOG_ENABLED()) {
|
||||
CLIPBOARD_LOG(" Cached transferable types (nums %zu)\n", flavors.Length());
|
||||
for (uint32_t j = 0; j < flavors.Length(); j++) {
|
||||
CLIPBOARD_LOG(" MIME %s\n", flavors[j].get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t j = 0; j < flavors.Length(); j++) {
|
||||
const nsCString& transferableFlavorStr = flavors[j];
|
||||
for (uint32_t j = 0; j < flavors.Length(); j++) {
|
||||
const nsCString& transferableFlavorStr = flavors[j];
|
||||
|
||||
for (uint32_t k = 0; k < aFlavorList.Length(); k++) {
|
||||
if (transferableFlavorStr.Equals(aFlavorList[k])) {
|
||||
CLIPBOARD_LOG(" has %s\n", aFlavorList[k].get());
|
||||
*outResult = true;
|
||||
return NS_OK;
|
||||
for (uint32_t k = 0; k < aFlavorList.Length(); k++) {
|
||||
if (transferableFlavorStr.Equals(aFlavorList[k])) {
|
||||
CLIPBOARD_LOG(" has %s\n", aFlavorList[k].get());
|
||||
*outResult = true;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSPasteboard* generalPBoard = [NSPasteboard generalPasteboard];
|
||||
|
||||
if (CLIPBOARD_LOG_ENABLED()) {
|
||||
NSArray* types = [generalPBoard types];
|
||||
uint32_t count = [types count];
|
||||
|
|
|
|||
|
|
@ -115,12 +115,7 @@ NS_IMETHODIMP nsBaseClipboard::EmptyClipboard(int32_t aWhichClipboard) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mClipboardOwner) {
|
||||
mClipboardOwner->LosingOwnership(mTransferable);
|
||||
mClipboardOwner = nullptr;
|
||||
}
|
||||
|
||||
mTransferable = nullptr;
|
||||
ClearClipboardCache();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -155,3 +150,11 @@ nsBaseClipboard::IsClipboardTypeSupported(int32_t aWhichClipboard,
|
|||
*_retval = kGlobalClipboard == aWhichClipboard;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsBaseClipboard::ClearClipboardCache() {
|
||||
if (mClipboardOwner) {
|
||||
mClipboardOwner->LosingOwnership(mTransferable);
|
||||
mClipboardOwner = nullptr;
|
||||
}
|
||||
mTransferable = nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ class nsBaseClipboard : public nsIClipboard {
|
|||
NS_IMETHOD GetNativeClipboardData(nsITransferable* aTransferable,
|
||||
int32_t aWhichClipboard) = 0;
|
||||
|
||||
void ClearClipboardCache();
|
||||
|
||||
bool mEmptyingForSetData;
|
||||
nsCOMPtr<nsIClipboardOwner> mClipboardOwner;
|
||||
nsCOMPtr<nsITransferable> mTransferable;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ skip-if =
|
|||
skip-if = toolkit != "cocoa" && toolkit != "windows" || (os == "win" && os_version == "10.0" && !ccov) # Bug 1456811
|
||||
[test_bug760802.xhtml]
|
||||
[test_clipboard.xhtml]
|
||||
[test_clipboard_cache.xhtml]
|
||||
[test_panel_mouse_coords.xhtml]
|
||||
skip-if = toolkit == "windows" # bug 1009955
|
||||
|
||||
|
|
|
|||
87
widget/tests/test_clipboard_cache.xhtml
Normal file
87
widget/tests/test_clipboard_cache.xhtml
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1812543
|
||||
-->
|
||||
<window title="Mozilla Bug 1812543"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const clipboard = SpecialPowers.Services.clipboard;
|
||||
const clipboardTypes = [
|
||||
clipboard.kSelectionClipboard,
|
||||
clipboard.kFindClipboard,
|
||||
];
|
||||
|
||||
function GenerateRandomString() {
|
||||
return "random number: " + Math.random();
|
||||
}
|
||||
|
||||
function writeStringToClipboard(aStr, aFlavor, aClipboardType) {
|
||||
let trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
|
||||
trans.init(null);
|
||||
trans.addDataFlavor(aFlavor);
|
||||
|
||||
let supportsStr = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
|
||||
supportsStr.data = aStr;
|
||||
trans.setTransferData(aFlavor, supportsStr);
|
||||
|
||||
clipboard.setData(trans, null, aClipboardType);
|
||||
}
|
||||
|
||||
function CleanupAllClipboard() {
|
||||
clipboard.emptyClipboard(clipboard.kGlobalClipboard);
|
||||
clipboardTypes.forEach(function(type) {
|
||||
if (clipboard.isClipboardTypeSupported(type)) {
|
||||
info(`cleanup clipboard ${type}`);
|
||||
clipboard.emptyClipboard(type);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let supportOtherClipboardTypes = false;
|
||||
clipboardTypes.forEach(function(type) {
|
||||
if (clipboard.isClipboardTypeSupported(type)) {
|
||||
supportOtherClipboardTypes = true;
|
||||
add_task(function test_clipboard_hasDataMatchingFlavors() {
|
||||
info(`Test write data to clipboard type ${type}`);
|
||||
|
||||
// Write text/unicode data to main clipboard.
|
||||
writeStringToClipboard(GenerateRandomString(), "text/unicode", clipboard.kGlobalClipboard);
|
||||
ok(clipboard.hasDataMatchingFlavors(["text/unicode"], clipboard.kGlobalClipboard),
|
||||
"Should have text/unicode flavor");
|
||||
ok(!clipboard.hasDataMatchingFlavors(["text/html"], clipboard.kGlobalClipboard),
|
||||
"Should not have text/html flavor");
|
||||
|
||||
// Write text/html data to other clipboard.
|
||||
writeStringToClipboard(GenerateRandomString(), "text/html", type);
|
||||
ok(clipboard.hasDataMatchingFlavors(["text/unicode"], clipboard.kGlobalClipboard),
|
||||
"Should have text/unicode flavor");
|
||||
ok(!clipboard.hasDataMatchingFlavors(["text/html"], clipboard.kGlobalClipboard),
|
||||
"Should not have text/html flavor");
|
||||
|
||||
// Clean clipboard data.
|
||||
CleanupAllClipboard();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (!supportOtherClipboardTypes) {
|
||||
ok(true, "Don't support other clipboard types, skip tests");
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
||||
Loading…
Reference in a new issue