зеркало из https://github.com/mozilla/pjs.git
Bug 472302 - get rid of fragile timeouts in textbox binding. r=enn
This commit is contained in:
Родитель
a987cd6742
Коммит
e4583c1bc1
|
@ -68,8 +68,6 @@
|
|||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function doTest() {
|
||||
var t1 = $("t1");
|
||||
var t2 = $("t2");
|
||||
|
@ -79,19 +77,15 @@
|
|||
var t1CanUndo = {};
|
||||
t1.editor.canUndo(t1Enabled, t1CanUndo);
|
||||
ok(t1CanUndo.value, "undo correctly enabled when emptyText was not changed through property");
|
||||
t2.emptyText = "reallyempty";
|
||||
|
||||
// Remaining tests after timeout - emptyText is displayed asynchronously.
|
||||
setTimeout(function () {
|
||||
is(t2.inputField.value, "reallyempty", "updated emptyText displayed");
|
||||
t2.click();
|
||||
synthesizeKey("2", {});
|
||||
var t2Enabled = {};
|
||||
var t2CanUndo = {};
|
||||
t2.editor.canUndo(t2Enabled, t2CanUndo);
|
||||
ok(t2CanUndo.value, "undo correctly enabled when emptyText explicitly changed through property");
|
||||
SimpleTest.finish();
|
||||
}, 100);
|
||||
t2.emptyText = "reallyempty";
|
||||
is(t2.inputField.value, "reallyempty", "updated emptyText displayed");
|
||||
t2.click();
|
||||
synthesizeKey("2", {});
|
||||
var t2Enabled = {};
|
||||
var t2CanUndo = {};
|
||||
t2.editor.canUndo(t2Enabled, t2CanUndo);
|
||||
ok(t2CanUndo.value, "undo correctly enabled when emptyText explicitly changed through property");
|
||||
}
|
||||
|
||||
]]></script>
|
||||
|
|
|
@ -43,16 +43,13 @@ function doTests() {
|
|||
ok("1" === t1.emptyText, "emptyText persists after setting value");
|
||||
|
||||
t1.value = "";
|
||||
// More tests after a timeout, because the emptyText is displayed asynchronously.
|
||||
setTimeout(function () {
|
||||
is(t1.inputField.value, 1, "emptyText is displayed");
|
||||
is(t1.textLength, 0, "textLength while emptyText is displayed");
|
||||
is(t1.inputField.value, 1, "emptyText is displayed");
|
||||
is(t1.textLength, 0, "textLength while emptyText is displayed");
|
||||
|
||||
t1.focus();
|
||||
is(t1.inputField.value, "", "emptyText is not displayed as the textbox has focus");
|
||||
t1.focus();
|
||||
is(t1.inputField.value, "", "emptyText is not displayed as the textbox has focus");
|
||||
|
||||
SimpleTest.finish();
|
||||
}, 100);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
]]></script>
|
||||
|
|
|
@ -164,23 +164,24 @@
|
|||
<method name="_updateVisibleText">
|
||||
<body><![CDATA[
|
||||
if (!this.hasAttribute("focused") &&
|
||||
!this.hasAttribute("empty") &&
|
||||
!this.value &&
|
||||
this.emptyText) {
|
||||
// This section is a wee bit hacky; without the timeout, the CSS
|
||||
// style corresponding to the "empty" attribute doesn't kick in
|
||||
// until the text has changed, leading to an unpleasant moment
|
||||
// where the emptyText flashes black before turning gray.
|
||||
this.setAttribute("empty", true);
|
||||
|
||||
setTimeout(function (textbox) {
|
||||
if (textbox.hasAttribute("empty")) {
|
||||
try {
|
||||
textbox.editor.transactionManager.beginBatch();
|
||||
} catch (e) {}
|
||||
textbox.inputField.value = textbox.emptyText;
|
||||
}
|
||||
}, 0, this);
|
||||
if (!this.hasAttribute("empty")) {
|
||||
this.setAttribute("empty", "true");
|
||||
|
||||
// Hide the emptytext for a bit, in case the textbox will be focused subsequently
|
||||
this.inputField.setAttribute("emptytextdelay", "true");
|
||||
setTimeout(function (textbox) {
|
||||
textbox.inputField.removeAttribute("emptytextdelay");
|
||||
}, 100, this);
|
||||
|
||||
try {
|
||||
this.editor.transactionManager.beginBatch();
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
this.inputField.value = this.emptyText;
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
@ -204,13 +205,8 @@
|
|||
this.boxObject.removeProperty("value");
|
||||
}
|
||||
|
||||
// this.editor may not be initialized yet in
|
||||
// bindings that inherit from xul:textbox, so
|
||||
// do this after construction
|
||||
setTimeout(function (a) {
|
||||
a._updateVisibleText();
|
||||
a._setNewlineHandling();
|
||||
}, 0, this);
|
||||
this._updateVisibleText();
|
||||
this._setNewlineHandling();
|
||||
]]></constructor>
|
||||
|
||||
<destructor>
|
||||
|
@ -226,27 +222,34 @@
|
|||
<handlers>
|
||||
<handler event="focus" phase="capturing">
|
||||
<![CDATA[
|
||||
this._clearEmptyText();
|
||||
if (this.hasAttribute("focused"))
|
||||
return;
|
||||
|
||||
if (!this.hasAttribute("focused")) {
|
||||
if (event.originalTarget == this)
|
||||
this.inputField.focus(); // Forward focus to actual HTML input
|
||||
else if (event.originalTarget != this.inputField)
|
||||
return; // Allow other children (e.g. URL bar buttons) to get focus
|
||||
else if (this.mIgnoreFocus)
|
||||
this.mIgnoreFocus = false;
|
||||
else if (this.clickSelectsAll) {
|
||||
try {
|
||||
const nsIEditorIMESupport =
|
||||
Components.interfaces.nsIEditorIMESupport;
|
||||
var imeEditor = this.editor.QueryInterface(nsIEditorIMESupport);
|
||||
if (!imeEditor || !imeEditor.composing)
|
||||
this.editor.selectAll();
|
||||
} catch (e) {}
|
||||
}
|
||||
switch (event.originalTarget) {
|
||||
case this:
|
||||
// Forward focus to actual HTML input
|
||||
this.inputField.focus();
|
||||
break;
|
||||
case this.inputField:
|
||||
this._clearEmptyText();
|
||||
|
||||
this.setAttribute("focused", "true");
|
||||
if (this.mIgnoreFocus) {
|
||||
this.mIgnoreFocus = false;
|
||||
} else if (this.clickSelectsAll) {
|
||||
try {
|
||||
const nsIEditorIMESupport =
|
||||
Components.interfaces.nsIEditorIMESupport;
|
||||
let imeEditor = this.editor.QueryInterface(nsIEditorIMESupport);
|
||||
if (!imeEditor || !imeEditor.composing)
|
||||
this.editor.selectAll();
|
||||
} catch (e) {}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Allow other children (e.g. URL bar buttons) to get focus
|
||||
return;
|
||||
}
|
||||
this.setAttribute("focused", "true");
|
||||
]]>
|
||||
</handler>
|
||||
|
||||
|
|
|
@ -658,6 +658,11 @@ html|*.textbox-textarea {
|
|||
text-shadow: inherit;
|
||||
}
|
||||
|
||||
textbox[empty="true"] html|*.textbox-input[emptytextdelay="true"] ,
|
||||
textbox[empty="true"] html|*.textbox-textarea[emptytextdelay="true"] {
|
||||
color: transparent !important;
|
||||
}
|
||||
|
||||
.textbox-input-box {
|
||||
-moz-binding: url("chrome://global/content/bindings/textbox.xml#input-box");
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче