зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1518339 - Make user-select: auto behave like user-select: text for editing roots. r=mats
This is the closest to the spec behavior, I think, and less likely to cause interop issues, but if you prefer me to stop the 'inheritance' chain at contenteditable elements or what not I can also do that. Differential Revision: https://phabricator.services.mozilla.com/D15963 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
12ae3deec9
Коммит
2caa18fcc1
|
@ -849,6 +849,7 @@ class nsGenericHTMLElement : public nsGenericHTMLElementBase {
|
|||
// Used by A, AREA, LINK, and STYLE.
|
||||
already_AddRefed<nsIURI> GetHrefURIForAnchors() const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Returns whether this element is an editable root. There are two types of
|
||||
* editable roots:
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<!doctype html>
|
||||
<html class="reftest-wait">
|
||||
<title>Test reference</title>
|
||||
<script src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<div contenteditable="true">
|
||||
Can you edit <b>me</b>?
|
||||
</div>
|
||||
<script>
|
||||
SimpleTest.waitForFocus(function() {
|
||||
const editable = document.querySelector('div[contenteditable="true"]');
|
||||
editable.focus();
|
||||
synthesizeMouseAtCenter(editable.querySelector("b"), {});
|
||||
setTimeout(() => document.documentElement.removeAttribute("class"), 0);
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,23 @@
|
|||
<!doctype html>
|
||||
<html class="reftest-wait">
|
||||
<title>contenteditable is selectable by default, even with a user-select: none ancestor</title>
|
||||
<script src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<style>
|
||||
:root {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
</style>
|
||||
<div contenteditable="true">
|
||||
Can you edit <b>me</b>?
|
||||
</div>
|
||||
<script>
|
||||
SimpleTest.waitForFocus(function() {
|
||||
const editable = document.querySelector('div[contenteditable="true"]');
|
||||
editable.focus();
|
||||
synthesizeMouseAtCenter(editable.querySelector("b"), {});
|
||||
setTimeout(() => document.documentElement.removeAttribute("class"), 0);
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,25 @@
|
|||
<!doctype html>
|
||||
<html class="reftest-wait">
|
||||
<title>Test reference</title>
|
||||
<script src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<style>
|
||||
div {
|
||||
-webkit-user-select: all;
|
||||
-moz-user-select: all;
|
||||
user-select: all;
|
||||
}
|
||||
</style>
|
||||
<div contenteditable="true">
|
||||
<div>
|
||||
You should be able to select <b>all</b> of me.
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
SimpleTest.waitForFocus(function() {
|
||||
const editable = document.querySelector('div[contenteditable="true"]');
|
||||
editable.focus();
|
||||
synthesizeMouseAtCenter(editable.querySelector("b"), {});
|
||||
setTimeout(() => document.documentElement.removeAttribute("class"), 0);
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,23 @@
|
|||
<!doctype html>
|
||||
<html class="reftest-wait">
|
||||
<title>user-select can be overriden on a contenteditable element</title>
|
||||
<script src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<style>
|
||||
div {
|
||||
-webkit-user-select: all;
|
||||
-moz-user-select: all;
|
||||
user-select: all;
|
||||
}
|
||||
</style>
|
||||
<div contenteditable="true">
|
||||
You should be able to select <b>all</b> of me.
|
||||
</div>
|
||||
<script>
|
||||
SimpleTest.waitForFocus(function() {
|
||||
const editable = document.querySelector('div[contenteditable="true"]');
|
||||
editable.focus();
|
||||
synthesizeMouseAtCenter(editable.querySelector("b"), {});
|
||||
setTimeout(() => document.documentElement.removeAttribute("class"), 0);
|
||||
});
|
||||
</script>
|
|
@ -364,6 +364,10 @@ support-files =
|
|||
bug1506547-6.html
|
||||
bug1506547-4-ref.html
|
||||
bug1506547-5-ref.html
|
||||
bug1518339-1.html
|
||||
bug1518339-1-ref.html
|
||||
bug1518339-2.html
|
||||
bug1518339-2-ref.html
|
||||
|
||||
[test_remote_frame.html]
|
||||
[test_resize_flush.html]
|
||||
|
|
|
@ -213,6 +213,8 @@ var tests = [
|
|||
[ 'bug1506547-6.html' , 'bug1506547-5-ref.html' ] ,
|
||||
[ 'bug1510942-1.html' , 'bug1510942-1-ref.html' ] ,
|
||||
[ 'bug1510942-2.html' , 'bug1510942-2-ref.html' ] ,
|
||||
[ 'bug1518339-1.html' , 'bug1518339-1-ref.html' ] ,
|
||||
[ 'bug1518339-2.html' , 'bug1518339-2-ref.html' ] ,
|
||||
function() {SpecialPowers.pushPrefEnv({'clear': [['layout.accessiblecaret.enabled']]}, nextTest);} ,
|
||||
];
|
||||
|
||||
|
|
|
@ -3931,16 +3931,41 @@ nsresult nsFrame::GetDataForTableSelection(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool IsEditingHost(const nsIFrame* aFrame) {
|
||||
auto* element = nsGenericHTMLElement::FromNodeOrNull(aFrame->GetContent());
|
||||
return element && element->IsEditableRoot();
|
||||
}
|
||||
|
||||
static StyleUserSelect UsedUserSelect(const nsIFrame* aFrame) {
|
||||
if (aFrame->HasAnyStateBits(NS_FRAME_GENERATED_CONTENT)) {
|
||||
return StyleUserSelect::None;
|
||||
}
|
||||
|
||||
// Per https://drafts.csswg.org/css-ui-4/#content-selection:
|
||||
//
|
||||
// The computed value is the specified value, except:
|
||||
//
|
||||
// 1 - on editable elements where the computed value is always 'contain'
|
||||
// regardless of the specified value.
|
||||
// 2 - when the specified value is auto, which computes to one of the other
|
||||
// values [...]
|
||||
//
|
||||
// See https://github.com/w3c/csswg-drafts/issues/3344 to see why we do this
|
||||
// at used-value time instead of at computed-value time.
|
||||
//
|
||||
// Also, we check for auto first to allow explicitly overriding the value for
|
||||
// the editing host.
|
||||
auto style = aFrame->StyleUIReset()->mUserSelect;
|
||||
if (style != StyleUserSelect::Auto) {
|
||||
return style;
|
||||
}
|
||||
|
||||
if (IsEditingHost(aFrame)) {
|
||||
// We don't implement 'contain' itself, but we make 'text' behave as
|
||||
// 'contain' for contenteditable elements anyway so this is ok.
|
||||
return StyleUserSelect::Text;
|
||||
}
|
||||
|
||||
auto* parent = nsLayoutUtils::GetParentOrPlaceholderFor(aFrame);
|
||||
return parent ? UsedUserSelect(parent) : StyleUserSelect::Text;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче