jenkins-bot has submitted this change and it was merged.
Change subject: Introduce Ace editor widget
......................................................................
Introduce Ace editor widget
The widget attempts to load the ext.codeEditor.ace.modes module
and if it fails, will fall back to regular TextWidget behaviour.
Bug: T49742
Change-Id: Ie483f6eba25e3732a396c18decc0e1844b806b23
---
M extension.json
A modules/ve-mw/ui/styles/widgets/ve.ui.MWAceEditorWidget.css
M modules/ve-mw/ui/ve.ui.MWExtensionWindow.js
A modules/ve-mw/ui/widgets/ve.ui.MWAceEditorWidget.js
4 files changed, 196 insertions(+), 2 deletions(-)
Approvals:
Jforrester: Looks good to me, approved
jenkins-bot: Verified
diff --git a/extension.json b/extension.json
index 90d3dfc..3ff78dc 100644
--- a/extension.json
+++ b/extension.json
@@ -965,6 +965,7 @@
"modules/ve-mw/ui/ve.ui.MWExtensionWindow.js",
"modules/ve-mw/ui/commands/ve.ui.MWWikitextWarningCommand.js",
"modules/ve-mw/ui/datatransferhandlers/ve.ui.MWWikitextStringTransferHandler.js",
+
"modules/ve-mw/ui/widgets/ve.ui.MWAceEditorWidget.js",
"modules/ve-mw/ui/widgets/ve.ui.MWTargetWidget.js",
"modules/ve-mw/ui/widgets/ve.ui.MWTocItemWidget.js",
"modules/ve-mw/ui/widgets/ve.ui.MWTocWidget.js",
@@ -987,6 +988,7 @@
"modules/ve-mw/ui/styles/dialogs/ve.ui.MWWelcomeDialog.css",
"modules/ve-mw/ui/styles/dialogs/ve.ui.MWSaveDialog.css",
"modules/ve-mw/ui/styles/tools/ve.ui.MWPopupTool.css",
+
"modules/ve-mw/ui/styles/widgets/ve.ui.MWAceEditorWidget.css",
"modules/ve-mw/ui/styles/widgets/ve.ui.MWTocWidget.css",
"modules/ve-mw/ui/styles/tools/ve.ui.MWEducationPopupTool.css"
],
diff --git a/modules/ve-mw/ui/styles/widgets/ve.ui.MWAceEditorWidget.css
b/modules/ve-mw/ui/styles/widgets/ve.ui.MWAceEditorWidget.css
new file mode 100644
index 0000000..b11d584
--- /dev/null
+++ b/modules/ve-mw/ui/styles/widgets/ve.ui.MWAceEditorWidget.css
@@ -0,0 +1,22 @@
+/*!
+ * VisualEditor MediaWiki UserInterface MWAceEditorWidget styles.
+ *
+ * @copyright 2011-2015 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+.ve-ui-mwAceEditorWidget .ace_editor {
+ border: 1px solid #ccc;
+ margin: 1px;
+ font-family: monospace, Courier;
+ font-size: inherit;
+ line-height: 1.5;
+}
+
+.ve-ui-mwAceEditorWidget .ace_focus {
+ /* TODO: Move to mediawiki theme only */
+ border-color: #347bff;
+ /* HACK: Make border grow out as inset doesn't overlap absolute
positioned children */
+ border-width: 2px;
+ margin: 0;
+}
diff --git a/modules/ve-mw/ui/ve.ui.MWExtensionWindow.js
b/modules/ve-mw/ui/ve.ui.MWExtensionWindow.js
index 9b47372..e9973a5 100644
--- a/modules/ve-mw/ui/ve.ui.MWExtensionWindow.js
+++ b/modules/ve-mw/ui/ve.ui.MWExtensionWindow.js
@@ -53,9 +53,9 @@
ve.ui.MWExtensionWindow.prototype.initialize = function () {
this.input = new ve.ui.WhitespacePreservingTextInputWidget( {
limit: 1,
- multiline: true
+ multiline: true,
+ classes: [ 've-ui-mwExtensionWindow-input' ]
} );
- this.input.$element.addClass( 've-ui-mwExtensionWindow-input' );
};
/**
diff --git a/modules/ve-mw/ui/widgets/ve.ui.MWAceEditorWidget.js
b/modules/ve-mw/ui/widgets/ve.ui.MWAceEditorWidget.js
new file mode 100644
index 0000000..4b13dca
--- /dev/null
+++ b/modules/ve-mw/ui/widgets/ve.ui.MWAceEditorWidget.js
@@ -0,0 +1,170 @@
+/*!
+ * VisualEditor UserInterface MWAceEditorWidget class.
+ *
+ * @copyright 2011-2015 VisualEditor Team and others; see
http://ve.mit-license.org
+ */
+
+/* global ace, require */
+
+/**
+ * Text input widget which hides but preserves leading and trailing whitespace
+ *
+ * @class
+ * @extends ve.ui.WhitespacePreservingTextInputWidget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+ve.ui.MWAceEditorWidget = function VeUiMWAceEditorWidget( config ) {
+ // Configuration
+ config = config || {};
+
+ this.$ace = $( '<div dir="ltr">' );
+ this.editor = null;
+ // Initialise to a rejected promise for the setValue call in the parent
constructor
+ this.loadingPromise = $.Deferred().reject().promise();
+ this.styleHeight = null;
+
+ // Parent constructor
+ ve.ui.MWAceEditorWidget.super.call( this, config );
+
+ // Clear the fake loading promise and setup properly
+ this.loadingPromise = null;
+ this.setup();
+
+ this.$element
+ .append( this.$ace )
+ .addClass( 've-ui-mwAceEditorWidget' );
+};
+
+/* Inheritance */
+
+OO.inheritClass( ve.ui.MWAceEditorWidget,
ve.ui.WhitespacePreservingTextInputWidget );
+
+/* Events */
+
+/**
+ * The editor has resized
+ * @event resize
+ */
+
+/* Methods */
+
+/**
+ * Setup the Ace editor instance
+ */
+ve.ui.MWAceEditorWidget.prototype.setup = function () {
+ if ( !this.loadingPromise ) {
+ this.loadingPromise = mw.loader.moduleRegistry.hasOwnProperty(
'ext.codeEditor.ace.modes' ) ?
+ mw.loader.using( 'ext.codeEditor.ace.modes' ).then(
this.setupEditor.bind( this ) ) :
+ $.Deferred().reject().promise();
+ }
+};
+
+/**
+ * Destroy the Ace editor instance
+ */
+ve.ui.MWAceEditorWidget.prototype.teardown = function () {
+ var widget = this;
+ this.loadingPromise.done( function () {
+ widget.$input.removeClass( 'oo-ui-element-hidden' );
+ widget.editor.destroy();
+ widget.editor = null;
+ } ).always( function () {
+ widget.loadingPromise = null;
+ } );
+};
+
+/**
+ * Setup the Ace editor
+ */
+ve.ui.MWAceEditorWidget.prototype.setupEditor = function () {
+ this.$input.addClass( 'oo-ui-element-hidden' );
+ this.editor = ace.edit( this.$ace[ 0 ] );
+ this.editor.setOptions( {
+ minLines: this.minRows || 3,
+ maxLines: this.autosize ? this.maxRows : this.minRows || 3
+ } );
+ this.editor.getSession().on( 'change', this.onEditorChange.bind( this )
);
+ this.editor.renderer.on( 'resize', this.emit.bind( this, 'resize' ) );
+ this.editor.resize();
+};
+
+/**
+ * @inheritdoc
+ */
+ve.ui.MWAceEditorWidget.prototype.setValue = function ( value ) {
+ var widget = this;
+ this.loadingPromise.done( function () {
+ widget.editor.setValue( value );
+ widget.editor.selection.moveTo( 0, 0 );
+ } ).fail( function () {
+ ve.ui.MWAceEditorWidget.super.prototype.setValue.call( widget,
value );
+ } );
+};
+
+/**
+ * Handle change events from the Ace editor
+ */
+ve.ui.MWAceEditorWidget.prototype.onEditorChange = function () {
+ // Call setValue on the parent to keep the value property in sync with
the editor
+ ve.ui.MWAceEditorWidget.super.prototype.setValue.call( this,
this.editor.getValue() );
+};
+
+/**
+ * Toggle the visibility of line numbers
+ *
+ * @param {boolean} visible Visible
+ */
+ve.ui.MWAceEditorWidget.prototype.toggleLineNumbers = function ( visible ) {
+ var widget = this;
+ this.loadingPromise.done( function () {
+ widget.editor.renderer.setShowGutter( visible );
+ } );
+};
+
+/**
+ * Set the language mode of the editor (programming language)
+ *
+ * @param {string} lang Language
+ */
+ve.ui.MWAceEditorWidget.prototype.setLanguage = function ( lang ) {
+ var widget = this;
+ this.loadingPromise.done( function () {
+ widget.editor.getSession().setMode( 'ace/mode/' + ( require(
'ace/mode/' + lang ) ? lang : 'text' ) );
+ } );
+};
+
+/**
+ * Focus the editor
+ */
+ve.ui.MWAceEditorWidget.prototype.focus = function () {
+ var widget = this;
+ this.loadingPromise.done( function () {
+ widget.editor.focus();
+ } ).fail( function () {
+ ve.ui.MWAceEditorWidget.super.prototype.focus.call( widget );
+ } );
+};
+
+/**
+ * @inheritdoc
+ * TODO Move this upstream to OOUI
+ */
+ve.ui.MWAceEditorWidget.prototype.adjustSize = function () {
+ var styleHeight,
+ widget = this;
+
+ // Parent method
+ ve.ui.MWAceEditorWidget.super.prototype.adjustSize.call( this );
+
+ // Implement resize events for plain TextWidget
+ this.loadingPromise.fail( function () {
+ styleHeight = widget.$input[ 0 ].style.height;
+
+ if ( styleHeight !== widget.styleHeight ) {
+ widget.styleHeight = styleHeight;
+ widget.emit( 'resize' );
+ }
+ } );
+};
--
To view, visit https://gerrit.wikimedia.org/r/247851
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ie483f6eba25e3732a396c18decc0e1844b806b23
Gerrit-PatchSet: 5
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Esanders <[email protected]>
Gerrit-Reviewer: Alex Monk <[email protected]>
Gerrit-Reviewer: Bartosz DziewoĆski <[email protected]>
Gerrit-Reviewer: Esanders <[email protected]>
Gerrit-Reviewer: Jforrester <[email protected]>
Gerrit-Reviewer: Krinkle <[email protected]>
Gerrit-Reviewer: Tchanders <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits