jenkins-bot has submitted this change and it was merged.
Change subject: Insert new graphs in a page inside VisualEditor
......................................................................
Insert new graphs in a page inside VisualEditor
- Graphs can now be added via the Insert menu in VisualEditor
- Slightly refactored change applying mechanism to leverage staging layers
Bug: T112994
Change-Id: Id913e0cbda4f8a45b6dd5c4e5b0829199d68b900
---
M Graph.hooks.php
M modules/ve-graph/tests/ext.graph.visualEditor.test.js
M modules/ve-graph/ve.ce.MWGraphNode.js
M modules/ve-graph/ve.dm.MWGraphModel.js
M modules/ve-graph/ve.dm.MWGraphNode.js
M modules/ve-graph/ve.ui.MWGraphDialog.js
M modules/ve-graph/ve.ui.MWGraphDialogTool.js
7 files changed, 160 insertions(+), 31 deletions(-)
Approvals:
Esanders: Looks good to me, approved
jenkins-bot: Verified
diff --git a/Graph.hooks.php b/Graph.hooks.php
index 65dccfc..7de4c7d 100644
--- a/Graph.hooks.php
+++ b/Graph.hooks.php
@@ -25,9 +25,9 @@
$addModules = array(
'ext.graph.visualEditor' => $graphModuleTemplate +
array(
'scripts' => array(
+ 'modules/ve-graph/ve.ce.MWGraphNode.js',
'modules/ve-graph/ve.dm.MWGraphModel.js',
'modules/ve-graph/ve.dm.MWGraphNode.js',
- 'modules/ve-graph/ve.ce.MWGraphNode.js',
'modules/ve-graph/ve.ui.MWGraphDialog.js',
'modules/ve-graph/ve.ui.MWGraphDialogTool.js',
'modules/ve-graph/widgets/ve.ui.RowWidget.js',
diff --git a/modules/ve-graph/tests/ext.graph.visualEditor.test.js
b/modules/ve-graph/tests/ext.graph.visualEditor.test.js
index 1f20692..23de4ea 100644
--- a/modules/ve-graph/tests/ext.graph.visualEditor.test.js
+++ b/modules/ve-graph/tests/ext.graph.visualEditor.test.js
@@ -335,7 +335,7 @@
var node = new ve.dm.MWGraphNode(),
specString = JSON.stringify( sampleSpecs.areaGraph );
- assert.deepEqual( node.getSpec(), null, 'MWGraphNode spec is
initialized to null' );
+ assert.deepEqual( node.getSpec(),
ve.dm.MWGraphNode.static.defaultSpec, 'MWGraphNode spec is initialized to the
default spec' );
node.setSpecFromString( specString );
assert.deepEqual( node.getSpec(), sampleSpecs.areaGraph, 'Basic
valid spec is parsed' );
@@ -355,10 +355,19 @@
'<div typeof="mw:Extension/graph"></div>'
),
documentNode = view.getDocument().getDocumentNode(),
- node = documentNode.children[ 0 ].children[ 0 ];
+ node = documentNode.children[ 0 ],
+ mwData = ve.copy( node.getModel().getAttribute( 'mw' )
);
assert.equal( node.type, 'mwGraph', 'Parsoid HTML graphs are
properly recognized as graph nodes' );
+ ve.setProp( mwData, 'body', 'extsrc', undefined );
+ view.getModel().change(
+ ve.dm.Transaction.newFromAttributeChanges(
+ view.getModel().getDocument(),
+ node.getOffset(),
+ { mw: mwData }
+ )
+ );
assert.equal( $( node.$element[ 0 ] ).text(), ve.msg(
'graph-ve-no-spec' ), 'A null spec displays an error message' );
} );
diff --git a/modules/ve-graph/ve.ce.MWGraphNode.js
b/modules/ve-graph/ve.ce.MWGraphNode.js
index a8e961d..f30f1e9 100644
--- a/modules/ve-graph/ve.ce.MWGraphNode.js
+++ b/modules/ve-graph/ve.ce.MWGraphNode.js
@@ -49,7 +49,7 @@
canvasNode;
// Check if the spec is currently valid
- if ( spec ) {
+ if ( !ve.isEmptyObject( spec ) ) {
vg.parse.spec( spec, function ( chart ) {
try {
chart( { el: element } ).update();
diff --git a/modules/ve-graph/ve.dm.MWGraphModel.js
b/modules/ve-graph/ve.dm.MWGraphModel.js
index d773662..feec44c 100644
--- a/modules/ve-graph/ve.dm.MWGraphModel.js
+++ b/modules/ve-graph/ve.dm.MWGraphModel.js
@@ -221,6 +221,7 @@
{ mw: mwData }
)
);
+ surfaceModel.applyStaging();
};
/**
diff --git a/modules/ve-graph/ve.dm.MWGraphNode.js
b/modules/ve-graph/ve.dm.MWGraphNode.js
index e370902..4a8ea88 100644
--- a/modules/ve-graph/ve.dm.MWGraphNode.js
+++ b/modules/ve-graph/ve.dm.MWGraphNode.js
@@ -32,8 +32,10 @@
mw = this.getAttribute( 'mw' );
extsrc = ve.getProp( mw, 'body', 'extsrc' );
- if ( extsrc !== undefined ) {
+ if ( extsrc ) {
this.setSpecFromString( extsrc );
+ } else {
+ this.setSpec( ve.dm.MWGraphNode.static.defaultSpec );
}
};
@@ -47,6 +49,96 @@
ve.dm.MWGraphNode.static.extensionName = 'graph';
+ve.dm.MWGraphNode.static.defaultSpec = {
+ width: 400,
+ height: 200,
+ data: [
+ {
+ name: 'table',
+ values: [
+ {
+ x: 0,
+ y: 1
+ },
+ {
+ x: 1,
+ y: 3
+ },
+ {
+ x: 2,
+ y: 2
+ },
+ {
+ x: 3,
+ y: 4
+ }
+ ]
+ }
+ ],
+ scales: [
+ {
+ name: 'x',
+ type: 'linear',
+ range: 'width',
+ zero: false,
+ domain: {
+ data: 'table',
+ field: 'data.x'
+ }
+ },
+ {
+ name: 'y',
+ type: 'linear',
+ range: 'height',
+ nice: true,
+ domain: {
+ data: 'table',
+ field: 'data.y'
+ }
+ }
+ ],
+ axes: [
+ {
+ type: 'x',
+ scale: 'x'
+ },
+ {
+ type: 'y',
+ scale: 'y'
+ }
+ ],
+ marks: [
+ {
+ type: 'area',
+ from: {
+ data: 'table'
+ },
+ properties: {
+ enter: {
+ x: {
+ scale: 'x',
+ field: 'data.x'
+ },
+ y: {
+ scale: 'y',
+ field: 'data.y'
+ },
+ y2: {
+ scale: 'y',
+ value: 0
+ },
+ fill: {
+ value: 'steelblue'
+ },
+ interpolate: {
+ value: 'monotone'
+ }
+ }
+ }
+ }
+ ]
+};
+
/* Static Methods */
/**
diff --git a/modules/ve-graph/ve.ui.MWGraphDialog.js
b/modules/ve-graph/ve.ui.MWGraphDialog.js
index 5ee4fb7..bd3cb61 100644
--- a/modules/ve-graph/ve.ui.MWGraphDialog.js
+++ b/modules/ve-graph/ve.ui.MWGraphDialog.js
@@ -19,13 +19,14 @@
// Properties
this.graphModel = null;
+ this.mode = '';
this.cachedRawData = null;
this.changingJsonTextInput = false;
};
/* Inheritance */
-OO.inheritClass( ve.ui.MWGraphDialog, ve.ui.NodeDialog );
+OO.inheritClass( ve.ui.MWGraphDialog, ve.ui.MWExtensionDialog );
/* Static properties */
@@ -39,10 +40,16 @@
ve.ui.MWGraphDialog.static.actions = [
{
- action: 'apply',
+ action: 'done',
label: OO.ui.deferMsg( 'graph-ve-dialog-edit-apply' ),
flags: [ 'progressive', 'primary' ],
modes: 'edit'
+ },
+ {
+ action: 'done',
+ label: OO.ui.deferMsg( 'visualeditor-dialog-action-insert' ),
+ flags: [ 'constructive', 'primary' ],
+ modes: 'insert'
},
{
label: OO.ui.deferMsg( 'graph-ve-dialog-edit-cancel' ),
@@ -221,10 +228,27 @@
* @inheritdoc
*/
ve.ui.MWGraphDialog.prototype.getSetupProcess = function ( data ) {
- var spec;
-
return ve.ui.MWGraphDialog.super.prototype.getSetupProcess.call( this,
data )
.next( function () {
+ var spec, newElement;
+
+ this.getFragment().getSurface().pushStaging();
+
+ // Create new graph node if not present (insert mode)
+ if ( !this.selectedNode ) {
+ this.setMode( 'insert' );
+
+ newElement = this.getNewElement();
+ this.fragment =
this.getFragment().insertContent( [
+ newElement,
+ { type: '/' + newElement.type }
+ ] );
+ this.getFragment().select();
+ this.selectedNode =
this.getFragment().getSelectedNode();
+ } else {
+ this.setMode( 'edit' );
+ }
+
// Set up model
spec = ve.copy( this.selectedNode.getSpec() );
@@ -248,8 +272,8 @@
/**
* @inheritdoc
*/
-ve.ui.MWGraphDialog.prototype.getTeardownProcess = function () {
- return ve.ui.MWGraphDialog.super.prototype.getTeardownProcess.call(
this )
+ve.ui.MWGraphDialog.prototype.getTeardownProcess = function ( data ) {
+ return ve.ui.MWGraphDialog.super.prototype.getTeardownProcess.call(
this, data )
.first( function () {
// Kill model
this.graphModel.disconnect( this );
@@ -262,6 +286,11 @@
this.dataTable.$element.remove();
this.dataTable = null;
+
+ // Kill staging
+ if ( data === undefined ) {
+ this.getFragment().getSurface().popStaging();
+ }
}, this );
};
@@ -270,7 +299,7 @@
*/
ve.ui.MWGraphDialog.prototype.getActionProcess = function ( action ) {
switch ( action ) {
- case 'apply':
+ case 'done':
return new OO.ui.Process( function () {
this.graphModel.applyChanges(
this.selectedNode, this.getFragment().getSurface() );
this.close( { action: action } );
@@ -531,11 +560,23 @@
areChangesValid;
this.jsonTextInput.isValid().done( function ( isJsonTextInputValid ) {
- areChangesValid = ( hasModelBeenChanged && isJsonTextInputValid
);
- self.actions.setAbilities( { apply: areChangesValid } );
+ areChangesValid = self.mode === 'insert' ||
+ ( hasModelBeenChanged &&
isJsonTextInputValid );
+ self.actions.setAbilities( { done: areChangesValid } );
} );
};
+/**
+ * Sets and caches the mode of the dialog.
+ *
+ * @private
+ * @param {string} mode The new mode, either `edit` or `insert`
+ */
+ve.ui.MWGraphDialog.prototype.setMode = function ( mode ) {
+ this.actions.setMode( mode );
+ this.mode = mode;
+};
+
/* Registration */
ve.ui.windowFactory.register( ve.ui.MWGraphDialog );
diff --git a/modules/ve-graph/ve.ui.MWGraphDialogTool.js
b/modules/ve-graph/ve.ui.MWGraphDialogTool.js
index 6bb7f91..03227b1 100644
--- a/modules/ve-graph/ve.ui.MWGraphDialogTool.js
+++ b/modules/ve-graph/ve.ui.MWGraphDialogTool.js
@@ -1,11 +1,5 @@
-/*!
- * VisualEditor MediaWiki graph dialog tool classes.
- *
- * @license The MIT License (MIT); see LICENSE.txt
- */
-
/**
- * MediaWiki UserInterface graph edit tool.
+ * MediaWiki UserInterface graph tool.
*
* @class
* @extends ve.ui.DialogTool
@@ -24,20 +18,12 @@
/* Static properties */
ve.ui.MWGraphDialogTool.static.name = 'graph';
-
ve.ui.MWGraphDialogTool.static.group = 'object';
-
ve.ui.MWGraphDialogTool.static.icon = 'graph';
-
-ve.ui.MWGraphDialogTool.static.title = OO.ui.deferMsg(
'graph-ve-dialog-button-tooltip' );
-
+ve.ui.MWGraphDialogTool.static.title =
+ OO.ui.deferMsg( 'graph-ve-dialog-button-tooltip' );
ve.ui.MWGraphDialogTool.static.modelClasses = [ ve.dm.MWGraphNode ];
-
ve.ui.MWGraphDialogTool.static.commandName = 'graph';
-
-ve.ui.MWGraphDialogTool.static.autoAddToCatchall = false;
-
-ve.ui.MWGraphDialogTool.static.autoAddToGroup = false;
/* Registration */
--
To view, visit https://gerrit.wikimedia.org/r/246726
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Id913e0cbda4f8a45b6dd5c4e5b0829199d68b900
Gerrit-PatchSet: 7
Gerrit-Project: mediawiki/extensions/Graph
Gerrit-Branch: master
Gerrit-Owner: Ferdbold <[email protected]>
Gerrit-Reviewer: Esanders <[email protected]>
Gerrit-Reviewer: Ferdbold <[email protected]>
Gerrit-Reviewer: Jforrester <[email protected]>
Gerrit-Reviewer: Mooeypoo <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits