Bug 1686012 - Make Headless clipboard support the HTML type; r=spohl

Differential Revision: https://phabricator.services.mozilla.com/D191195
This commit is contained in:
Edgar Chen 2023-10-18 08:15:27 +00:00
parent cf37085d32
commit 8e9d770444
6 changed files with 77 additions and 38 deletions

View File

@ -362,7 +362,6 @@ skip-if = [
["test_bug331959.html"]
["test_bug333064.html"]
skip-if = ["headless"] # Headless: Bug 1405868
["test_bug333198.html"]

View File

@ -59,7 +59,6 @@ support-files = ["test_bug332636.html^headers^"]
skip-if = ["os == 'android'"]
["test_bug410986.html"]
skip-if = ["headless"]
["test_bug414526.html"]
@ -84,12 +83,10 @@ skip-if = ["headless"]
["test_bug471722.html"]
["test_bug478725.html"]
skip-if = ["headless"]
["test_bug480647.html"]
["test_bug480972.html"]
skip-if = ["headless"]
["test_bug483651.html"]
@ -104,10 +101,8 @@ skip-if = [
["test_bug514156.html"]
["test_bug520189.html"]
skip-if = ["headless"]
["test_bug525389.html"]
skip-if = ["headless"]
["test_bug537046.html"]
@ -120,7 +115,6 @@ support-files = [
["test_bug550434.html"]
["test_bug551704.html"]
skip-if = ["headless"]
["test_bug552782.html"]
@ -216,7 +210,6 @@ skip-if = ["os == 'android'"]
["test_bug677752.html"]
["test_bug681229.html"]
skip-if = ["headless"]
["test_bug686203.html"]
@ -330,7 +323,6 @@ skip-if = ["os == 'win' && ccov && xorigin"] # high frequency intermittent
["test_bug1230473.html"]
["test_bug1247483.html"]
skip-if = ["headless"]
["test_bug1248128.html"]
@ -588,7 +580,6 @@ skip-if = ["verify && debug && os == 'win'"] # bug 1485293
["test_root_element_replacement.html"]
["test_sanitizer_on_paste.html"]
skip-if = ["headless"] # 1686012
support-files = ["file_sanitizer_on_paste.sjs"]
["test_select_all_without_body.html"]

View File

@ -213,7 +213,6 @@ support-files = [
["test_bug1646140-1.html"]
["test_bug1646140-2.html"]
skip-if = ["headless"] # Bug 1685088
["test_compatmode.html"]

View File

@ -32,23 +32,36 @@ HeadlessClipboard::SetNativeClipboardData(nsITransferable* aTransferable,
// Clear out the clipboard in order to set the new data.
EmptyNativeClipboardData(aWhichClipboard);
// Only support plain text for now.
nsCOMPtr<nsISupports> clip;
nsresult rv = aTransferable->GetTransferData(kTextMime, getter_AddRefs(clip));
nsTArray<nsCString> flavors;
nsresult rv = aTransferable->FlavorsTransferableCanExport(flavors);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsISupportsString> wideString = do_QueryInterface(clip);
if (!wideString) {
return NS_ERROR_NOT_IMPLEMENTED;
}
auto& clipboard = mClipboards[aWhichClipboard];
MOZ_ASSERT(clipboard);
nsAutoString utf16string;
wideString->GetData(utf16string);
clipboard->SetText(utf16string);
for (const auto& flavor : flavors) {
if (!flavor.EqualsLiteral(kTextMime) && !flavor.EqualsLiteral(kHTMLMime)) {
continue;
}
nsCOMPtr<nsISupports> data;
rv = aTransferable->GetTransferData(flavor.get(), getter_AddRefs(data));
if (NS_FAILED(rv)) {
continue;
}
nsCOMPtr<nsISupportsString> wideString = do_QueryInterface(data);
if (!wideString) {
continue;
}
nsAutoString utf16string;
wideString->GetData(utf16string);
flavor.EqualsLiteral(kTextMime) ? clipboard->SetText(utf16string)
: clipboard->SetHTML(utf16string);
}
return NS_OK;
}
@ -60,25 +73,43 @@ HeadlessClipboard::GetNativeClipboardData(nsITransferable* aTransferable,
MOZ_DIAGNOSTIC_ASSERT(
nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
nsTArray<nsCString> flavors;
nsresult rv = aTransferable->FlavorsTransferableCanImport(flavors);
if (NS_FAILED(rv)) {
return NS_ERROR_FAILURE;
}
auto& clipboard = mClipboards[aWhichClipboard];
MOZ_ASSERT(clipboard);
if (!clipboard->HasText()) {
return NS_OK;
for (const auto& flavor : flavors) {
if (!flavor.EqualsLiteral(kTextMime) && !flavor.EqualsLiteral(kHTMLMime)) {
continue;
}
bool isText = flavor.EqualsLiteral(kTextMime);
if (!(isText ? clipboard->HasText() : clipboard->HasHTML())) {
continue;
}
nsCOMPtr<nsISupportsString> dataWrapper =
do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
rv = dataWrapper->SetData(isText ? clipboard->GetText()
: clipboard->GetHTML());
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
nsCOMPtr<nsISupports> genericDataWrapper = do_QueryInterface(dataWrapper);
rv = aTransferable->SetTransferData(flavor.get(), genericDataWrapper);
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
// XXX Other platforms only fill the first available type, too.
break;
}
nsresult rv;
nsCOMPtr<nsISupportsString> dataWrapper =
do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
rv = dataWrapper->SetData(clipboard->GetText());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsISupports> genericDataWrapper = do_QueryInterface(dataWrapper);
rv = aTransferable->SetTransferData(kTextMime, genericDataWrapper);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
@ -112,7 +143,8 @@ HeadlessClipboard::HasNativeClipboardDataMatchingFlavors(
// Retrieve the union of all aHasType in aFlavorList
for (auto& flavor : aFlavorList) {
if (flavor.EqualsLiteral(kTextMime) && clipboard->HasText()) {
if ((flavor.EqualsLiteral(kTextMime) && clipboard->HasText()) ||
(flavor.EqualsLiteral(kHTMLMime) && clipboard->HasHTML())) {
return true;
}
}

View File

@ -15,10 +15,20 @@ bool HeadlessClipboardData::HasText() const { return !mPlain.IsVoid(); }
const nsAString& HeadlessClipboardData::GetText() const { return mPlain; }
void HeadlessClipboardData::SetHTML(const nsAString& aHTML) {
mHTML = aHTML;
mChangeCount++;
}
bool HeadlessClipboardData::HasHTML() const { return !mHTML.IsVoid(); }
const nsAString& HeadlessClipboardData::GetHTML() const { return mHTML; }
int32_t HeadlessClipboardData::GetChangeCount() const { return mChangeCount; }
void HeadlessClipboardData::Clear() {
mPlain.SetIsVoid(true);
mHTML.SetIsVoid(true);
mChangeCount++;
}

View File

@ -13,20 +13,28 @@ namespace widget {
class HeadlessClipboardData final {
public:
HeadlessClipboardData() : mPlain(VoidString()) {}
HeadlessClipboardData() : mPlain(VoidString()), mHTML(VoidString()) {}
~HeadlessClipboardData() = default;
// For text/plain
void SetText(const nsAString& aText);
bool HasText() const;
const nsAString& GetText() const;
// For text/html
void SetHTML(const nsAString& aHTML);
bool HasHTML() const;
const nsAString& GetHTML() const;
int32_t GetChangeCount() const;
// For other APIs
void Clear();
private:
nsAutoString mPlain;
nsString mPlain;
nsString mHTML;
int32_t mChangeCount = 0;
};