DLynch has uploaded a new change for review.
https://gerrit.wikimedia.org/r/250904
Change subject: Add ve.Scheduler, use it to avoid conflict in ve.ui.Tool
......................................................................
Add ve.Scheduler, use it to avoid conflict in ve.ui.Tool
We have an occasional muddle of setTimeout calls which make it hard to
wait for a clean state sometimes. So, create a Scheduler utility that
handles waiting a reasonably efficient length of time before running
whatever action is required.
As a proof of concept, use it to avoid an issue that ve.Tool has with
attempting to perform certain actions while inspectors are open.
This is the bare-minimum implementation. In the future, we may want to
make it smarter so that it can track a setTimeout stack within the
action it performs, rather than just blindly polling a test function.
Bug: T117620
Bug: T76717
Change-Id: Ib1d6a702f73cd6c99fd524761115dfff27a3199d
---
M build/modules.json
M demos/ve/desktop.html
M demos/ve/mobile.html
M src/ui/ve.ui.Tool.js
A src/ve.Scheduler.js
M tests/index.html
6 files changed, 78 insertions(+), 2 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor
refs/changes/04/250904/1
diff --git a/build/modules.json b/build/modules.json
index 7779105..971b7a2 100644
--- a/build/modules.json
+++ b/build/modules.json
@@ -209,6 +209,7 @@
"src/ve.LeafNode.js",
"src/ve.Document.js",
"src/ve.EventSequencer.js",
+ "src/ve.Scheduler.js",
{ "file": "src/ve.Filibuster.js", "debug": true },
"src/dm/ve.dm.js",
"src/dm/ve.dm.Model.js",
diff --git a/demos/ve/desktop.html b/demos/ve/desktop.html
index 39f43a7..7cf4a79 100644
--- a/demos/ve/desktop.html
+++ b/demos/ve/desktop.html
@@ -170,6 +170,7 @@
<script src="../../src/ve.LeafNode.js"></script>
<script src="../../src/ve.Document.js"></script>
<script src="../../src/ve.EventSequencer.js"></script>
+ <script src="../../src/ve.Scheduler.js"></script>
<script src="../../src/ve.Filibuster.js"></script>
<script src="../../src/dm/ve.dm.js"></script>
<script src="../../src/dm/ve.dm.Model.js"></script>
diff --git a/demos/ve/mobile.html b/demos/ve/mobile.html
index 8f40031..ccdab84 100644
--- a/demos/ve/mobile.html
+++ b/demos/ve/mobile.html
@@ -172,6 +172,7 @@
<script src="../../src/ve.LeafNode.js"></script>
<script src="../../src/ve.Document.js"></script>
<script src="../../src/ve.EventSequencer.js"></script>
+ <script src="../../src/ve.Scheduler.js"></script>
<script src="../../src/ve.Filibuster.js"></script>
<script src="../../src/dm/ve.dm.js"></script>
<script src="../../src/dm/ve.dm.Model.js"></script>
diff --git a/src/ui/ve.ui.Tool.js b/src/ui/ve.ui.Tool.js
index a3fe850..154113d 100644
--- a/src/ui/ve.ui.Tool.js
+++ b/src/ui/ve.ui.Tool.js
@@ -79,9 +79,22 @@
* @inheritdoc
*/
ve.ui.Tool.prototype.onSelect = function () {
- var command = this.getCommand();
+ var command = this.getCommand(),
+ surface = this.toolbar.getSurface();
if ( command instanceof ve.ui.Command ) {
- command.execute( this.toolbar.getSurface() );
+ ve.scheduler.call(
+ function () {
+ if ( surface.context.inspector ) {
+ surface.context.inspector.close();
+ }
+ }, function () {
+ // Make sure the inspector has left the
context, at which point
+ // all its cleanup should be done
+ return !surface.context.inspector;
+ }
+ ).then( function () {
+ command.execute( surface );
+ } );
}
if ( this.constructor.static.deactivateOnSelect ) {
this.setActive( false );
diff --git a/src/ve.Scheduler.js b/src/ve.Scheduler.js
new file mode 100644
index 0000000..7bd7875
--- /dev/null
+++ b/src/ve.Scheduler.js
@@ -0,0 +1,59 @@
+/*!
+ * VisualEditor Scheduler class.
+ *
+ * @copyright 2011-2015 VisualEditor Team and others; see
http://ve.mit-license.org
+ */
+
+/**
+ * @class
+ *
+ * @constructor
+ */
+ve.Scheduler = function VeScheduler() {
+ // TODO: If we decide to start tracking setTimeout calls within
actions, we'll
+ // need to keep state here.
+ };
+
+/* Inheritance */
+
+OO.initClass( ve.Scheduler );
+
+/* Methods */
+
+/**
+ * Perform an action and await a callback
+ *
+ * The signature of this function is designed to let you leave signals about
your intent.
+ * You pass the action with side-effects in, and explain the conditions that
must be met
+ * for further actions to be taken.
+ *
+ * @param {Function} immediateAction Action to take whose status we want to
track
+ * @param {Function} completionTest Tests whether action is complete; ideally
very cheap
+ * @param {number} [delayHint] Optional hint about how long to wait between
tests
+ * @return {jQuery.Promise} Promise that resolves when the completionTest
returns true.
+ * Note that this _could_ already be resolved when it's returned, so
there's no
+ * guarantee that your `then` call on it will be delayed.
+ */
+ve.Scheduler.prototype.call = function ( immediateAction, completionTest,
delayHint ) {
+ var deferred = $.Deferred(),
+ testThenAct = function () {
+ if ( completionTest() ) {
+ deferred.resolve();
+ return;
+ }
+ setTimeout( testThenAct, delayHint || 0 );
+ };
+
+ // In the future, we may want to expand this to track whether other
async calls
+ // were made within the action.
+ immediateAction();
+
+ // Spin up the test cycle
+ testThenAct();
+
+ return deferred.promise();
+};
+
+/* Initialization */
+
+ve.scheduler = new ve.Scheduler();
diff --git a/tests/index.html b/tests/index.html
index 3310e91..c419f2b 100644
--- a/tests/index.html
+++ b/tests/index.html
@@ -98,6 +98,7 @@
<script src="../src/ve.LeafNode.js"></script>
<script src="../src/ve.Document.js"></script>
<script src="../src/ve.EventSequencer.js"></script>
+ <script src="../src/ve.Scheduler.js"></script>
<script src="../src/dm/ve.dm.js"></script>
<script src="../src/dm/ve.dm.Model.js"></script>
<script src="../src/dm/ve.dm.ModelFactory.js"></script>
--
To view, visit https://gerrit.wikimedia.org/r/250904
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib1d6a702f73cd6c99fd524761115dfff27a3199d
Gerrit-PatchSet: 1
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: DLynch <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits