Robmoen has uploaded a new change for review.
https://gerrit.wikimedia.org/r/50045
Change subject: Introduce configurable target views.
......................................................................
Introduce configurable target views.
Major changes:
ve.init.Target.js
* Create abstract class methods for Target.
ve.init.sa.Target.js
* Create Standalone target view methods.
ve.init.mw.Target.js
* Added MW specific target view methods.
* Integration action buttons are now added to the edit
view in the toolbar.
ve.Surface.js
* Change toolbar config object to include views
* Tweak setupToolbars to incorporate view elements and contain
their configured tools.
* Each toolbar view has an actions container.
* Other changes include some documentation and code cleanup.
Change-Id: Iff39266bdd3052f34bda254ca407030dbbc81f26
---
M VisualEditor.php
M demos/ve/index.php
M modules/ve/init/mw/targets/ve.init.mw.ViewPageTarget.js
M modules/ve/init/mw/ve.init.mw.Platform.js
M modules/ve/init/mw/ve.init.mw.Target.js
M modules/ve/init/sa/styles/ve.init.sa.css
M modules/ve/init/sa/ve.init.sa.Platform.js
A modules/ve/init/sa/ve.init.sa.Target.js
M modules/ve/init/ve.init.Platform.js
A modules/ve/init/ve.init.Target.js
M modules/ve/ve.Surface.js
11 files changed, 262 insertions(+), 49 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor
refs/changes/45/50045/1
diff --git a/VisualEditor.php b/VisualEditor.php
index 45a4e33..414bd63 100644
--- a/VisualEditor.php
+++ b/VisualEditor.php
@@ -175,6 +175,7 @@
've/ve.EventEmitter.js',
've/init/ve.init.js',
've/init/ve.init.Platform.js',
+ 've/init/ve.init.Target.js',
),
'debugScripts' => array(
've/ve.debug.js',
diff --git a/demos/ve/index.php b/demos/ve/index.php
index 85295dd..23dbf40 100644
--- a/demos/ve/index.php
+++ b/demos/ve/index.php
@@ -59,7 +59,7 @@
</li>
<?php endforeach; ?>
</ul>
- <div class="ve-demo-content"></div>
+ <div class="ve-container"></div>
<!-- Generated by maintenance/makeStaticLoader.php -->
<!-- Dependencies -->
@@ -71,10 +71,12 @@
<script src="../../modules/ve/ve.EventEmitter.js"></script>
<script src="../../modules/ve/init/ve.init.js"></script>
<script
src="../../modules/ve/init/ve.init.Platform.js"></script>
+ <script src="../../modules/ve/init/ve.init.Target.js"></script>
<script src="../../modules/ve/ve.debug.js"></script>
<!-- Standalone Init -->
<script src="../../modules/ve/init/sa/ve.init.sa.js"></script>
<script
src="../../modules/ve/init/sa/ve.init.sa.Platform.js"></script>
+ <script
src="../../modules/ve/init/sa/ve.init.sa.Target.js"></script>
<script>
<?php
require(
'../../modules/../VisualEditor.i18n.php' );
@@ -212,12 +214,16 @@
<script
src="../../modules/ve/ui/inspectors/ve.ui.MWLinkInspector.js"></script>
<!-- demo -->
<script>
- $(document).ready( function () {
+ $( document ).ready( function () {
+ var target = new ve.init.sa.Target();
new ve.Surface(
- $( '.ve-demo-content' ),
+ target.$,
ve.createDocumentFromHTML( <?php echo
json_encode( $html ) ?> )
+ target
);
$( '.ve-ce-documentNode' ).focus();
+ //expose target for a sec.
+ window.target = target;
} );
</script>
diff --git a/modules/ve/init/mw/targets/ve.init.mw.ViewPageTarget.js
b/modules/ve/init/mw/targets/ve.init.mw.ViewPageTarget.js
index 7fe0be8..8f6d102 100644
--- a/modules/ve/init/mw/targets/ve.init.mw.ViewPageTarget.js
+++ b/modules/ve/init/mw/targets/ve.init.mw.ViewPageTarget.js
@@ -57,13 +57,16 @@
'top': {
'float': !this.isMobileDevice,
// HACK: The toolbar configuration isn't very
extendable, so this is mostly
- // copy-pasted from ve.Surface except using
mwLink for the link tool
- 'tools': [
- { 'name': 'history', 'items' : ['undo',
'redo'] },
- { 'name': 'textStyle', 'items' :
['format'] },
- { 'name': 'textStyle', 'items' :
['bold', 'italic', 'mwLink', 'clear'] },
- { 'name': 'list', 'items' : ['number',
'bullet', 'outdent', 'indent'] }
- ]
+ 'views': {
+ 'edit': {
+ 'groups': [
+ { 'name': 'history',
'items' : ['undo', 'redo'] },
+ { 'name': 'textStyle',
'items' : ['format'] },
+ { 'name': 'textStyle',
'items' : ['bold', 'italic', 'link', 'clear'] },
+ { 'name': 'list',
'items' : ['number', 'bullet', 'outdent', 'indent'] }
+ ]
+ }
+ }
}
},
'commands': ['bold', 'italic', 'mwLink', 'undo', 'redo',
'indent', 'outdent']
@@ -686,7 +689,7 @@
// Store the HTML for reporting purposes
this.originalHtml = doc.body.innerHTML; // TODO store entire document
in the future
// Initialize surface
- this.surface = new ve.Surface( $( '#content' ), doc,
this.surfaceOptions );
+ this.surface = new ve.Surface( this.$, doc, this, this.surfaceOptions );
this.surface.getContext().hide();
this.$document = this.surface.$.find( '.ve-ce-documentNode' );
this.surface.getModel().on( 'transact',
this.proxiedOnSurfaceModelTransact );
@@ -905,7 +908,7 @@
* @method
*/
ve.init.mw.ViewPageTarget.prototype.attachToolbarButtons = function () {
- var $target = $( '.ve-ui-toolbar .ve-ui-actions' );
+ var $target = $( '.ve-ui-toolbar .ve-ui-toolbar-view-edit
.ve-ui-actions' );
$target.append( this.$toolbarFeedbackTool );
if ( !ve.isEmptyObject( this.editNotices ) ) {
$target.append( this.$toolbarEditNoticesTool );
@@ -1711,6 +1714,63 @@
}
};
+/**
+ * Adds an editor view to the target container.
+ *
+ * @method
+ * @param {string} view name of view.
+ * @param {object} config object of jQuery objects for the view.
+ */
+ve.init.mw.ViewPageTarget.prototype.addView = function ( view, config ) {
+ if( view in this.views ) {
+ throw new Error( 'View: ' + view + ' already registered!' );
+ }
+ this.views[view] = config;
+ // Add the view to the target container
+ if( config.$.length === 0 ) {
+ this.$.append( config.$ );
+ }
+ // Add the toolbar view to the toolbar.
+
+};
+
+/**
+ * Hides all registered views and shows given editor view & matching toolbar
view.
+ *
+ * @method
+ * @param {string} view name of view.
+ */
+ve.init.mw.ViewPageTarget.prototype.showView = function ( view ) {
+ var name;
+ if ( !( view in this.views ) ) {
+ throw new Error( 'View: ' + view + ' not found!' );
+ }
+ // Hide all the views.
+ for( name in this.views ) {
+ this.hideView( name );
+ }
+ // Show view container.
+ this.views[view].$.show();
+ this.views[view].$toolbar.show();
+ // Show toolbar view container
+};
+
+
+/**
+ * Hide a view
+ *
+ * @method
+ * @param {string} view name of view.
+ */
+ve.init.mw.Target.prototype.hideView = function ( view ) {
+ if ( ! ( view in this.views ) ) {
+ throw new Error( 'View: ' + view + ' not found!' );
+ }
+ // Hide the view objects.
+ this.views[view].$.hide();
+ this.views[view].$toolbar.hide();
+};
+
/* Initialization */
ve.init.mw.targets.push( new ve.init.mw.ViewPageTarget() );
diff --git a/modules/ve/init/mw/ve.init.mw.Platform.js
b/modules/ve/init/mw/ve.init.mw.Platform.js
index 5cb8c3f..1454d8b 100644
--- a/modules/ve/init/mw/ve.init.mw.Platform.js
+++ b/modules/ve/init/mw/ve.init.mw.Platform.js
@@ -1,5 +1,5 @@
/*!
- * VisualEditor MediaWiki Initialization Target class.
+ * VisualEditor MediaWiki Initialization Platform class.
*
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
diff --git a/modules/ve/init/mw/ve.init.mw.Target.js
b/modules/ve/init/mw/ve.init.mw.Target.js
index 0f941b4..9ef116d 100644
--- a/modules/ve/init/mw/ve.init.mw.Target.js
+++ b/modules/ve/init/mw/ve.init.mw.Target.js
@@ -11,16 +11,17 @@
* Initialization MediaWiki target.
*
* @class
- * @extends ve.EventEmitter
+ * @extends ve.init.Target
* @constructor
* @param {string} pageName Name of target page
* @param {number} [revision] Revision ID
*/
ve.init.mw.Target = function VeInitMwTarget( pageName, revision ) {
// Parent constructor
- ve.EventEmitter.call( this );
+ ve.init.Target.call( this );
// Properties
+ this.$ = $( '#content' );
this.pageName = pageName;
this.pageExists = mw.config.get( 'wgArticleId', 0 ) !== 0;
this.oldid = revision || '';
@@ -70,7 +71,7 @@
/* Inheritance */
-ve.inheritClass( ve.init.mw.Target, ve.EventEmitter );
+ve.inheritClass( ve.init.mw.Target, ve.init.Target );
/* Static Methods */
diff --git a/modules/ve/init/sa/styles/ve.init.sa.css
b/modules/ve/init/sa/styles/ve.init.sa.css
index 0dc2c1e..fac7841 100644
--- a/modules/ve/init/sa/styles/ve.init.sa.css
+++ b/modules/ve/init/sa/styles/ve.init.sa.css
@@ -1,5 +1,5 @@
/*!
- * VisualEditor Stand-alone Initialization styles.
+ * VisualEditor Standalone Initialization styles.
*
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
diff --git a/modules/ve/init/sa/ve.init.sa.Platform.js
b/modules/ve/init/sa/ve.init.sa.Platform.js
index 4daa93d..3b950ec 100644
--- a/modules/ve/init/sa/ve.init.sa.Platform.js
+++ b/modules/ve/init/sa/ve.init.sa.Platform.js
@@ -1,12 +1,12 @@
/*!
- * VisualEditor stand-alone Initialization Target class.
+ * VisualEditor Standalone Initialization Platform class.
*
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
/**
- * Initialization stand-alone platform.
+ * Initialization Standalone platform.
*
* @class
* @extends ve.init.Platform
diff --git a/modules/ve/init/sa/ve.init.sa.Target.js
b/modules/ve/init/sa/ve.init.sa.Target.js
new file mode 100644
index 0000000..c32c1de
--- /dev/null
+++ b/modules/ve/init/sa/ve.init.sa.Target.js
@@ -0,0 +1,72 @@
+/*!
+ * VisualEditor Standalone Initialization Target class.
+ *
+ * @copyright 2011-2012 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/*global mw */
+
+/**
+ * Initialization Standalone target.
+ *
+ * @class
+ * @extends ve.init.Target
+ * @constructor
+ */
+ve.init.sa.Target = function VeInitSaTarget() {
+ // Parent constructor
+ ve.init.Target.call( this );
+ this.$ = $( '.ve-container' );
+};
+
+/* Inheritance */
+
+ve.inheritClass( ve.init.sa.Target, ve.init.Target );
+
+/* Methods */
+
+/**
+ * Adds a view to the target.
+ *
+ * @method
+ * @param {string} message
+ */
+ve.init.sa.Target.prototype.addView = function ( view, config ) {
+ if( view in this.views ) {
+ throw new Error( 'View: ' + view + ' already registered!' );
+ }
+ this.views[view] = config;
+ // If not already present, add the dialog to the container.
+ if( config.$.length === 0 ) {
+ this.$.append( config.$ );
+ }
+};
+
+/**
+ * Show a view
+ *
+ * @method
+ * @param {string} view
+ */
+ve.init.sa.Target.prototype.showView = function ( view ) {
+ if ( ! ( view in this.views ) ) {
+ throw new Error( 'View: ' + view + ' not found!' );
+ }
+ // Show the dialog.
+ this.views[view].$.show();
+};
+
+/**
+ * Hide a view
+ *
+ * @method
+ * @param {string} view name of view.
+ */
+ve.init.sa.Target.prototype.hideView = function ( view ) {
+ if ( ! ( view in this.views ) ) {
+ throw new Error( 'View: ' + view + ' not found!' );
+ }
+ // Hide the dialog.
+ this.views[view].$.hide();
+};
diff --git a/modules/ve/init/ve.init.Platform.js
b/modules/ve/init/ve.init.Platform.js
index b421370..afac259 100644
--- a/modules/ve/init/ve.init.Platform.js
+++ b/modules/ve/init/ve.init.Platform.js
@@ -1,5 +1,5 @@
/*!
- * VisualEditor Initialization Target class.
+ * VisualEditor Initialization Platform class.
*
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
diff --git a/modules/ve/init/ve.init.Target.js
b/modules/ve/init/ve.init.Target.js
new file mode 100644
index 0000000..d178314
--- /dev/null
+++ b/modules/ve/init/ve.init.Target.js
@@ -0,0 +1,56 @@
+/*!
+ * VisualEditor Initialization Target class.
+ *
+ * @copyright 2011-2012 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/**
+ * Generic Initialization target.
+ *
+ * @abstract
+ * @extends ve.EventEmitter
+ * @constructor
+ */
+ve.init.Target = function VeInitTarget() {
+ // Parent constructor
+ ve.EventEmitter.call( this );
+ // Map of target views
+ this.views = {};
+};
+
+/* Inheritance */
+
+ve.inheritClass( ve.init.Target, ve.EventEmitter );
+
+/* Abstract Methods */
+
+/**
+ * Adds a view to the target.
+ *
+ * @method
+ * @abstract
+ */
+ve.init.Target.prototype.addView = function () {
+ throw new Error( 've.init.Target.addView must be overridden in
subclass' );
+};
+
+/**
+ * Show a view.
+ *
+ * @method
+ * @abstract
+ */
+ve.init.Target.prototype.showView = function () {
+ throw new Error( 've.init.Target.showView must be overridden in
subclass' );
+};
+
+/**
+ * Hide a view.
+ *
+ * @method
+ * @abstract
+ */
+ve.init.Target.prototype.hideView = function () {
+ throw new Error( 've.init.Target.hideView must be overridden in
subclass' );
+};
diff --git a/modules/ve/ve.Surface.js b/modules/ve/ve.Surface.js
index b777be1..0a41ee7 100644
--- a/modules/ve/ve.Surface.js
+++ b/modules/ve/ve.Surface.js
@@ -20,24 +20,24 @@
* @constructor
* @param {string} parent Selector of element to attach to
* @param {HTMLDocument} doc HTML document to edit
+ * @param {Object} target Subclass of ve.init.Target
* @param {Object} options Configuration options
*/
-ve.Surface = function VeSurface( parent, doc, options ) {
+ve.Surface = function VeSurface( parent, doc, target, options ) {
// Properties
this.$ = $( '<div>' );
this.documentModel = new ve.dm.Document(
ve.dm.converter.getDataFromDom( doc ) );
this.options = ve.extendObject( true, ve.Surface.defaultOptions,
options );
this.model = new ve.dm.Surface( this.documentModel );
- this.view = new ve.ce.Surface( this.$, this.model, this );
+ this.view = new ve.ce.Surface( this.$, this.model, this );
this.context = new ve.ui.Context( this );
+ this.target = target;
this.toolbars = {};
this.commands = {};
this.enabled = true;
// DOM Changes
- this.$.addClass( 've-surface' );
- $( parent ).append( this.$ );
-
+ $( parent ).append( this.$.addClass( 've-surface' ) );
// Initialization
// Propagate to each node information that it is live (attached to the
live DOM)
this.view.getDocument().getDocumentNode().setLive( true );
@@ -60,12 +60,16 @@
'toolbars': {
'top': {
'float': true,
- 'tools': [
- { 'name': 'history', 'items' : ['undo', 'redo']
},
- { 'name': 'textStyle', 'items' : ['format'] },
- { 'name': 'textStyle', 'items' : ['bold',
'italic', 'link', 'clear'] },
- { 'name': 'list', 'items' : ['number',
'bullet', 'outdent', 'indent'] }
- ]
+ 'views': {
+ 'edit': {
+ 'groups': [
+ { 'name': 'history', 'items' :
['undo', 'redo'] },
+ { 'name': 'textStyle', 'items'
: ['format'] },
+ { 'name': 'textStyle', 'items'
: ['bold', 'italic', 'link', 'clear'] },
+ { 'name': 'list', 'items' :
['number', 'bullet', 'outdent', 'indent'] }
+ ]
+ }
+ }
}
},
// Items can either be symbolic names or objects with trigger and
action properties
@@ -250,37 +254,50 @@
};
/**
- * Initialize the toolbar.
+ * Initialize all configured toolbars.
*
* This method uses {this.options} for its configuration.
*
* @method
*/
ve.Surface.prototype.setupToolbars = function () {
- var name, config, toolbar,
+ var name, config, toolbar, view, $toolbarView,
toolbars = this.options.toolbars;
for ( name in toolbars ) {
config = toolbars[name];
if ( ve.isPlainObject( config ) ) {
this.toolbars[name] = toolbar = { '$': $( '<div
class="ve-ui-toolbar"></div>' ) };
- if ( name === 'top' ) {
+ for( view in config.views ) {
+ // Create a view element to place the tool
groups in.
+ $toolbarView = $( '<div
class="ve-ui-toolbar-view-' + view + '">' )
+ .appendTo( toolbar.$ );
// Add extra sections to the toolbar
- toolbar.$.append(
- '<div class="ve-ui-actions"></div>' +
- '<div style="clear:both"></div>' +
- '<div
class="ve-ui-toolbar-shadow"></div>'
- );
- // Wrap toolbar for floating
- toolbar.$wrapper = $( '<div
class="ve-ui-toolbar-wrapper"></div>' )
- .append( this.toolbars[name].$ );
- // Add toolbar to surface
- this.$.before( toolbar.$wrapper );
- if ( 'float' in config && config.float === true
) {
- // Float top toolbar
- this.floatTopToolbar();
- }
+ $toolbarView.append( '<div
class="ve-ui-actions"></div>' );
+ // Create a new toolbar per configured view
+ toolbar[view] = new ve.ui.Toolbar(
$toolbarView, this, config.views[view].groups );
+ // Register view. If the view is the edit view,
+ // use the Surface jQuery object. Otherwise,
attach an empty container.
+ this.target.addView( view, {
+ '$': view === 'edit' ? this.$ : $(
'<div>' ),
+ '$toolbar': $toolbarView
+ } );
}
- toolbar.instance = new ve.ui.Toolbar( toolbar.$, this,
config.tools );
+ toolbar.$.append(
+ '<div style="clear:both"></div>' +
+ '<div class="ve-ui-toolbar-shadow"></div>'
+ );
+ }
+ // Do special stuff to the top toolbar
+ if ( name === 'top' ) {
+ // Wrap toolbar for floating
+ toolbar.$wrapper = $( '<div
class="ve-ui-toolbar-wrapper"></div>' )
+ .append( toolbar.$ );
+ // Add toolbar to surface
+ this.$.before( toolbar.$wrapper );
+ if ( 'float' in config && config.float === true ) {
+ // Float top toolbar
+ this.floatTopToolbar();
+ }
}
}
};
--
To view, visit https://gerrit.wikimedia.org/r/50045
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iff39266bdd3052f34bda254ca407030dbbc81f26
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Robmoen <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits