Bug 1357206 part 4. Don't move the cursor even if eSetValue_MoveCursorToEndIfValueChanged is set, if the value did not change. r=ehsan

This commit is contained in:
Boris Zbarsky 2017-05-01 13:28:54 -04:00
Родитель ff31c3ca29
Коммит 29d5ae0bfd
8 изменённых файлов: 63 добавлений и 18 удалений

Просмотреть файл

@ -13,6 +13,8 @@ function setConditionalBreakpoint(dbg, index, condition) {
selectMenuItem(dbg, 2);
yield waitForElement(dbg, ".conditional-breakpoint-panel input");
findElementWithSelector(dbg, ".conditional-breakpoint-panel input").focus();
// Position cursor reliably at the end of the text.
pressKey(dbg, "End")
type(dbg, condition);
pressKey(dbg, "Enter");
});

Просмотреть файл

@ -32,6 +32,8 @@ async function addExpression(dbg, input) {
async function editExpression(dbg, input) {
info("updating the expression");
dblClickElement(dbg, "expressionNode", 1);
// Position cursor reliably at the end of the text.
pressKey(dbg, "End")
type(dbg, input);
pressKey(dbg, "Enter");
await waitForDispatch(dbg, "EVALUATE_EXPRESSION");

Просмотреть файл

@ -560,6 +560,10 @@ const keyMappings = {
Enter: { code: "VK_RETURN" },
Up: { code: "VK_UP" },
Down: { code: "VK_DOWN" },
Right: { code: "VK_RIGHT" },
Left: { code: "VK_LEFT" },
End: { code: "VK_RIGHT", modifiers: cmdOrCtrl },
Start: { code: "VK_LEFT", modifiers: cmdOrCtrl },
Tab: { code: "VK_TAB" },
Escape: { code: "VK_ESCAPE" },
pauseKey: { code: "VK_F8" },

Просмотреть файл

@ -297,6 +297,7 @@ bool nsContentUtils::sUseActivityCursor = false;
bool nsContentUtils::sAnimationsAPICoreEnabled = false;
bool nsContentUtils::sAnimationsAPIElementAnimateEnabled = false;
bool nsContentUtils::sGetBoxQuadsEnabled = false;
bool nsContentUtils::sSkipCursorMoveForSameValueSet = false;
int32_t nsContentUtils::sPrivacyMaxInnerWidth = 1000;
int32_t nsContentUtils::sPrivacyMaxInnerHeight = 1000;
@ -645,6 +646,10 @@ nsContentUtils::Init()
Preferences::AddBoolVarCache(&sGetBoxQuadsEnabled,
"layout.css.getBoxQuads.enabled", false);
Preferences::AddBoolVarCache(&sSkipCursorMoveForSameValueSet,
"dom.input.skip_cursor_move_for_same_value_set",
true);
Element::InitCCCallbacks();
nsCOMPtr<nsIUUIDGenerator> uuidGenerator =

Просмотреть файл

@ -2888,6 +2888,13 @@ public:
*/
static uint64_t GenerateTabId();
/**
* Check whether we should skip moving the cursor for a same-value .value set
* on a text input or textarea.
*/
static bool
SkipCursorMoveForSameValueSet() { return sSkipCursorMoveForSameValueSet; }
private:
static bool InitializeEventTable();
@ -3012,6 +3019,7 @@ private:
static bool sAnimationsAPICoreEnabled;
static bool sAnimationsAPIElementAnimateEnabled;
static bool sGetBoxQuadsEnabled;
static bool sSkipCursorMoveForSameValueSet;
static uint32_t sCookiesLifetimePolicy;
static uint32_t sCookiesBehavior;

Просмотреть файл

@ -2636,26 +2636,41 @@ nsTextEditorState::SetValue(const nsAString& aValue, uint32_t aFlags)
if (!mValue) {
mValue.emplace();
}
if (!mValue->Assign(newValue, fallible)) {
return false;
}
// Since we have no editor we presumably have cached selection state.
if (IsSelectionCached()) {
SelectionProperties& props = GetSelectionProperties();
if (aFlags & eSetValue_MoveCursorToEndIfValueChanged) {
props.SetStart(newValue.Length());
props.SetEnd(newValue.Length());
} else {
// Make sure our cached selection position is not outside the new value.
props.SetStart(std::min(props.GetStart(), newValue.Length()));
props.SetEnd(std::min(props.GetEnd(), newValue.Length()));
// We can't just early-return here if mValue->Equals(newValue), because
// ValueWasChanged and OnValueChanged below still need to be called.
if (!mValue->Equals(newValue) ||
!nsContentUtils::SkipCursorMoveForSameValueSet()) {
if (!mValue->Assign(newValue, fallible)) {
return false;
}
}
// Update the frame display if needed
if (mBoundFrame) {
mBoundFrame->UpdateValueDisplay(true);
// Since we have no editor we presumably have cached selection state.
if (IsSelectionCached()) {
SelectionProperties& props = GetSelectionProperties();
if (aFlags & eSetValue_MoveCursorToEndIfValueChanged) {
props.SetStart(newValue.Length());
props.SetEnd(newValue.Length());
} else {
// Make sure our cached selection position is not outside the new value.
props.SetStart(std::min(props.GetStart(), newValue.Length()));
props.SetEnd(std::min(props.GetEnd(), newValue.Length()));
}
}
// Update the frame display if needed
if (mBoundFrame) {
mBoundFrame->UpdateValueDisplay(true);
}
} else {
// Even if our value is not actually changing, apparently we need to mark
// our SelectionProperties dirty to make accessibility tests happy.
// Probably because they depend on the SetSelectionRange() call we make on
// our frame in RestoreSelectionState, but I have no idea why they do.
if (IsSelectionCached()) {
SelectionProperties& props = GetSelectionProperties();
props.SetIsDirty();
}
}
}

Просмотреть файл

@ -282,11 +282,16 @@ public:
mIsDirty = true;
mDirection = value;
}
// return true only if mStart, mEnd, or mDirection have been modified
// return true only if mStart, mEnd, or mDirection have been modified,
// or if SetIsDirty() was explicitly called.
bool IsDirty() const
{
return mIsDirty;
}
void SetIsDirty()
{
mIsDirty = true;
}
private:
uint32_t mStart, mEnd;
bool mIsDirty = false;

Просмотреть файл

@ -1251,6 +1251,10 @@ pref("dom.select_popup_in_parent.enabled", false);
// Enable Directory API. By default, disabled.
pref("dom.input.dirpicker", false);
// Enable not moving the cursor to end when a text input or textarea has .value
// set to the value it already has. By default, enabled.
pref("dom.input.skip_cursor_move_for_same_value_set", true);
// Enables system messages and activities
pref("dom.sysmsg.enabled", false);