jenkins-bot has submitted this change and it was merged.
Change subject: Add a new Wikitext editor with very basic formatting features
......................................................................
Add a new Wikitext editor with very basic formatting features
With this new editor, MobileFrontend get's some very basic editing
features to easier:
* add (or format existing) text to in bold or italic to the wikitext
* add a reference to the cursor position
The editor is sampled to 50% of wikitext editors and logged with the
editor name "SourceEditorWithFormatting" to EventLogging.
Depends on: Idd2275788f11303bd965994c9fb2e6c2d59daa33
Bug: T91752
Change-Id: Ib5215d859118bad83e9cd12ea7691283707b13b5
---
M i18n/en.json
M i18n/qqq.json
A images/icons/reference-ltr.svg
A images/icons/reference-rtl.svg
M includes/Resources.php
M jsduck.json
M minerva.less/minerva.variables.less
M resources/mobile.editor.common/EditorOverlayBase.hogan
A resources/mobile.editor.overlay.withtoolbar/AddReferenceOverlay.js
A resources/mobile.editor.overlay.withtoolbar/EditorOverlayWithToolbar.js
A resources/mobile.editor.overlay.withtoolbar/EditorOverlayWithToolbar.less
A resources/mobile.editor.overlay.withtoolbar/contentAddReference.hogan
A resources/mobile.editor.overlay.withtoolbar/editorFooter.hogan
M resources/mobile.editor/init.js
M resources/mobile.overlays/Overlay.less
15 files changed, 381 insertions(+), 3 deletions(-)
Approvals:
Kaldari: Looks good to me, approved
jenkins-bot: Verified
diff --git a/i18n/en.json b/i18n/en.json
index 3b167ba..c56b6b4 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -142,6 +142,14 @@
"mobile-frontend-editor-redlink-leave": "No, thanks.",
"mobile-frontend-editor-redlink-explain": "This page has not yet been
created on {{SITENAME}}.",
"mobile-frontend-editor-redlink-create": "Create page",
+ "mobile-frontend-editor-bold": "Bold",
+ "mobile-frontend-editor-italic": "Italic",
+ "mobile-frontend-editor-bold-text": "Bold text",
+ "mobile-frontend-editor-italic-text": "Italic text",
+ "mobile-frontend-editor-reference": "Reference",
+ "mobile-frontend-editor-insert-reference": "Insert reference",
+ "mobile-frontend-editor-reference-placeholder": "Which source do you
refer to?",
+ "mobile-frontend-editor-add-reference": "Add",
"mobile-frontend-enable-images": "Enable images on mobile site",
"mobile-frontend-errorreport-button-label": "Report an error",
"mobile-frontend-errorreport-error": "Error, feedback could not be
posted.",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 6c56e41..e0d3fcb 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -137,6 +137,14 @@
"mobile-frontend-editor-redlink-leave": "Used as a message for a link,
that the user doesn't want to edit a page, that does not exist
yet.\n{{Identical|No thanks}}",
"mobile-frontend-editor-redlink-explain": "Question for the user, if he
want to edit a page, which link he clicked and that does not exist yet, or
not.",
"mobile-frontend-editor-redlink-create": "Label for a create page
button.\n{{Identical|Create page}}",
+ "mobile-frontend-editor-bold": "Title of \"Bold\" button in editor.",
+ "mobile-frontend-editor-italic": "Title of \"Italic\" button in
editor.",
+ "mobile-frontend-editor-bold-text": "Placeholder, which will be
inserted into the text area, if the user clicks the bold text button in editor,
and no text is selected.",
+ "mobile-frontend-editor-italic-text": "Placeholder, which will be
inserted into the text area, if the user clicks the italic text button in
editor, and no text is selected.",
+ "mobile-frontend-editor-reference": "Title of \"Reference\" button in
editor.",
+ "mobile-frontend-editor-insert-reference": "Title of the insert
reference overlay in editor.",
+ "mobile-frontend-editor-reference-placeholder": "Placeholder text for
the textarea on the reference overlay.",
+ "mobile-frontend-editor-add-reference": "Message used in the reference
overlay to add a reference to the wikitext textarea.",
"mobile-frontend-enable-images": "Unused at this time.\n\nSee also:\n*
{{msg-mw|Mobile-frontend-disable-images}}",
"mobile-frontend-errorreport-button-label": "Label for button for
submitting an error report. Keep this short.",
"mobile-frontend-errorreport-error": "Error displayed when feedback
could not be posted.",
diff --git a/images/icons/reference-ltr.svg b/images/icons/reference-ltr.svg
new file mode 100644
index 0000000..11e1c75
--- /dev/null
+++ b/images/icons/reference-ltr.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24
24">
+ <g id="reference">
+ <path id="bookmark" d="M5 4v17h12c1 0 2-1 2-2v-15h-14zm12 14c0 1-1 1-1
1h-8v-13h2v6l2-2 2 2v-6h3v12z"/>
+ </g>
+</svg>
diff --git a/images/icons/reference-rtl.svg b/images/icons/reference-rtl.svg
new file mode 100644
index 0000000..b31bbac
--- /dev/null
+++ b/images/icons/reference-rtl.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24
24">
+ <g id="reference">
+ <path id="bookmark" d="M19 4v17h-12c-1 0-2-1-2-2v-15h14zm-12 14c0 1 1
1 1 1h8v-13h-2v6l-2-2-2 2v-6h-3v12z"/>
+ </g>
+</svg>
diff --git a/includes/Resources.php b/includes/Resources.php
index 6276e65..f1c4eb7 100644
--- a/includes/Resources.php
+++ b/includes/Resources.php
@@ -664,6 +664,58 @@
),
),
+ 'mobile.editor.overlay.withtoolbar' =>
$wgMFResourceFileModuleBoilerplate + array(
+ 'dependencies' => array(
+ 'mobile.editor.overlay',
+ 'mobile.loggingSchemas',
+ 'oojs-ui.styles.icons-editing-styling',
+ 'jquery.textSelection',
+ 'mobile.editor.overlay.withtoolbar.images',
+ ),
+ 'scripts' => array(
+
'resources/mobile.editor.overlay.withtoolbar/AddReferenceOverlay.js',
+
'resources/mobile.editor.overlay.withtoolbar/EditorOverlayWithToolbar.js',
+ ),
+ 'styles' => array(
+
'resources/mobile.editor.overlay.withtoolbar/EditorOverlayWithToolbar.less'
+ ),
+ 'templates' => array(
+ 'editorFooter.hogan' =>
'resources/mobile.editor.overlay.withtoolbar/editorFooter.hogan',
+ 'contentAddReference.hogan' =>
+
'resources/mobile.editor.overlay.withtoolbar/contentAddReference.hogan',
+ ),
+ 'messages' => array(
+ 'mobile-frontend-editor-bold',
+ 'mobile-frontend-editor-italic',
+ 'mobile-frontend-editor-reference',
+ 'mobile-frontend-editor-insert-reference',
+ 'mobile-frontend-editor-reference-placeholder',
+ 'mobile-frontend-editor-italic-text',
+ 'mobile-frontend-editor-bold-text',
+ 'mobile-frontend-editor-add-reference',
+ ),
+ ),
+
+ 'mobile.editor.overlay.withtoolbar.images' =>
$wgMFResourceFileModuleBoilerplate + array(
+ 'class' => 'ResourceLoaderImageModule',
+ 'prefix' => 'oo-ui-icon',
+ 'selector' => '.oo-ui-icon-{name}',
+ 'position' => 'bottom',
+ 'images' => array(
+ 'reference' => array(
+ 'file' => array(
+ /**
+ * Reference-icons taken from
VisualEditor team:
+ *
https://github.com/wikimedia/mediawiki-extensions-VisualEditor/blob/
+ *
3e2f7f07285cf361adf8563667ff602ca938a859/modules/ve-mw/ui/styles/ve.ui.Icons.css
+ */
+ 'rtl' =>
'images/icons/reference-rtl.svg',
+ 'ltr' =>
'images/icons/reference-ltr.svg',
+ ),
+ ),
+ )
+ ),
+
'mobile.talk' => $wgMFResourceFileModuleBoilerplate + array(
'dependencies' => array(
'mobile.overlays',
diff --git a/jsduck.json b/jsduck.json
index 1359009..65ef84f 100644
--- a/jsduck.json
+++ b/jsduck.json
@@ -17,6 +17,7 @@
"mw.user",
"mw.Api",
"OO.ui.ToolGroup",
+ "OO.ui.Tool",
"OO.ui.LookupElement",
"OO.EventEmitter",
"ve.init.mw.MobileArticleTarget"
diff --git a/minerva.less/minerva.variables.less
b/minerva.less/minerva.variables.less
index e51e46f..e50d353 100644
--- a/minerva.less/minerva.variables.less
+++ b/minerva.less/minerva.variables.less
@@ -97,6 +97,10 @@
// Wiki specific variables
@infoboxWidth: 320px;
+// OOJs specific icon variables
+@baseIconSize: 24px;
+@targetIconSize: 32px;
+
// z-index definitions (see bug 64707)
@z-indexBase: 0;
@z-indexContent: 1;
diff --git a/resources/mobile.editor.common/EditorOverlayBase.hogan
b/resources/mobile.editor.common/EditorOverlayBase.hogan
index 064a87f..9c7b5d9 100644
--- a/resources/mobile.editor.common/EditorOverlayBase.hogan
+++ b/resources/mobile.editor.common/EditorOverlayBase.hogan
@@ -22,3 +22,6 @@
{{{spinner}}}
{{>content}}
</div>
+<div class="overlay-footer-container position-fixed">
+ {{>footer}}
+</div>
diff --git a/resources/mobile.editor.overlay.withtoolbar/AddReferenceOverlay.js
b/resources/mobile.editor.overlay.withtoolbar/AddReferenceOverlay.js
new file mode 100644
index 0000000..3c33096
--- /dev/null
+++ b/resources/mobile.editor.overlay.withtoolbar/AddReferenceOverlay.js
@@ -0,0 +1,63 @@
+( function ( M, $ ) {
+ var AddReferenceOverlay,
+ Overlay = M.require( 'Overlay' );
+
+ /**
+ * Overlay that shows an editor
+ * @class AddReferenceOverlay
+ * @extends Overlay
+ */
+ AddReferenceOverlay = Overlay.extend( {
+ /**
+ * @inheritdoc
+ * @cfg {Object} defaults Default options hash.
+ * @cfg {String} defaults.referenceMsg Label of the reference
input field
+ * @cfg {String} defaults.heading Title of the error reporting
interface
+ * logging in.
+ */
+ defaults: $.extend( {}, Overlay.prototype.defaults, {
+ referenceMsg: mw.msg(
'mobile-frontend-editor-reference-placeholder' ),
+ heading: mw.msg(
'mobile-frontend-editor-insert-reference' ),
+ headerButtonsListClassName: 'overlay-action',
+ headerButtons: [ {
+ className: 'submit',
+ msg: mw.msg(
'mobile-frontend-editor-add-reference' )
+ } ]
+ } ),
+ /**
+ * @inheritdoc
+ */
+ templatePartials: $.extend( {},
Overlay.prototype.templatePartials, {
+ content: mw.template.get(
'mobile.editor.overlay.withtoolbar', 'contentAddReference.hogan' )
+ } ),
+ /**
+ * @inheritdoc
+ */
+ events: $.extend( {}, Overlay.prototype.events, {
+ 'click button.submit': 'onSubmitClick'
+ } ),
+ /**
+ * Handle a click on the submit button
+ */
+ onSubmitClick: function () {
+ var parts = {
+ pre: '<ref>',
+ peri: $( '.referenceInput' ).val(),
+ post: '</ref>'
+ };
+
+ this.options.editorOverlay.$content.textSelection(
'encapsulateSelection', parts );
+ this.hide();
+ },
+
+ /**
+ * @inheritdoc
+ */
+ onExit: function () {
+ this.hide();
+ return false;
+ }
+ } );
+
+ M.define( 'modules/editor/AddReferenceOverlay', AddReferenceOverlay );
+}( mw.mobileFrontend, jQuery ) );
diff --git
a/resources/mobile.editor.overlay.withtoolbar/EditorOverlayWithToolbar.js
b/resources/mobile.editor.overlay.withtoolbar/EditorOverlayWithToolbar.js
new file mode 100644
index 0000000..409f1a3
--- /dev/null
+++ b/resources/mobile.editor.overlay.withtoolbar/EditorOverlayWithToolbar.js
@@ -0,0 +1,164 @@
+( function ( M, $ ) {
+ var EditorOverlay = M.require( 'modules/editor/EditorOverlay' ),
+ AddReferenceOverlay = M.require(
'modules/editor/AddReferenceOverlay' ),
+ EditorOverlayWithToolbar;
+
+ /**
+ * Overlay that shows an editor
+ * @class EditorOverlayWithToolbar
+ * @extends EditorOverlay
+ */
+ EditorOverlayWithToolbar = EditorOverlay.extend( {
+ templatePartials: $.extend( {},
EditorOverlay.prototype.templatePartials, {
+ footer: mw.template.get(
'mobile.editor.overlay.withtoolbar', 'editorFooter.hogan' )
+ } ),
+ editor: 'SourceEditorWithFormatting',
+ /** @inheritdoc **/
+ postRender: function () {
+ this._initializeEditorButtons();
+ EditorOverlay.prototype.postRender.apply( this,
arguments );
+ },
+
+ /**
+ * Creates several basic buttons to better work with wikitext
+ */
+ _initializeEditorButtons: function () {
+ var formattingTools,
+ toolFactory = new OO.ui.ToolFactory(),
+ toolGroupFactory = new OO.ui.ToolGroupFactory(),
+ toolbar = new OO.ui.Toolbar( toolFactory,
toolGroupFactory );
+
+ /**
+ * Creates and returns a new Tool object with the given
data
+ * @param {String} group The group this Tool should been
+ * @param {String} name The name of this Tool
+ * @param {String} icon Name of the icon to use
+ * @param {String} title Title of the Tool
+ * @param {Function} callback Function to call, when
this Tool is selected
+ * @return {OO.ui.Tool}
+ * @ignore
+ */
+ function getToolButton( group, name, icon, title,
callback ) {
+ /**
+ * Creates a new instance of OO.ui.Tool
+ * @param {String} group The group this Tool
should been
+ * @param {Object} [config] Configuration
options
+ */
+ var toolButton = function ( group, config ) {
+ // Parent constructor
+ OO.ui.Tool.call( this, group, config );
+ };
+
+ // inherit OO.ui.Tool
+ OO.inheritClass( toolButton, OO.ui.Tool );
+
+ /**
+ * Handle the tool being selected.
+ */
+ toolButton.prototype.onSelect = function () {
+ callback.call( this );
+ // we don't want to leave the button
selected
+ this.setActive( false );
+ };
+
+ // set properties
+ toolButton.static.name = name;
+ toolButton.static.group = group;
+ toolButton.static.title = title;
+ toolButton.static.icon = icon;
+
+ return toolButton;
+ }
+ // Array of buttons to add to the toolbar and their data
+ formattingTools = [
+ [ 'formattingTools', 'bold', 'bold', mw.msg(
'mobile-frontend-editor-bold' ), $.proxy( this, 'onWrapOrAddDefault', 'bold' )
],
+ [ 'formattingTools', 'italic', 'italic',
mw.msg( 'mobile-frontend-editor-italic' ), $.proxy( this, 'onWrapOrAddDefault',
'italic' ) ],
+ [ 'formattingTools', 'reference', 'reference',
mw.msg( 'mobile-frontend-editor-reference' ), $.proxy( this, 'onAddReference' )
]
+ ];
+ // add the buttons to the toolbar
+ $.each( formattingTools, function ( i, data ) {
+ toolFactory.register( getToolButton( data[0],
data[1], data[2], data[3], data[4] ) );
+ } );
+
+ toolbar.setup( [ {
+ // include the button group in this toolbar
+ include: [ {
+ group: 'formattingTools'
+ } ]
+ } ] );
+ // add the toolbar to the toolbar container
+ this.$( '.toolbar' ).append( toolbar.$element );
+ },
+
+ /**
+ * Handles a click on a toolbar Tool button and wraps
+ * the selected text (if any) into the action's pre- and post
+ * signs. If no text is selected it adds an example to the
cursor
+ * position.
+ * @param {String} action The performed action
+ */
+ onWrapOrAddDefault: function ( action ) {
+ var parts = {};
+
+ // set pre and post and default strings
+ switch ( action ) {
+ case 'bold':
+ parts = {
+ pre: '\'\'\'',
+ peri: mw.msg(
'mobile-frontend-editor-bold-text' ) + ' ',
+ post: '\'\'\''
+ };
+ break;
+ case 'italic':
+ parts = {
+ pre: '\'\'',
+ peri: mw.msg(
'mobile-frontend-editor-italic-text' ) + ' ',
+ post: '\'\''
+ };
+ break;
+ }
+ // replace/add the text to the content
+ this.onInputWikitextEditor();
+ this.$content.textSelection( 'encapsulateSelection',
parts );
+ },
+
+ /**
+ * Handles a click on the "add reference" button and opens a
simple Overlay to add
+ * a source/cite/reference to the text.
+ */
+ onAddReference: function () {
+ var self = this,
+ referenceOverlay = new AddReferenceOverlay( {
+ editorOverlay: this
+ } );
+
+ // Open the Overlay and handle the hide event
+ referenceOverlay.on( 'hide', function () {
+ self.show();
+ } ).show();
+
+ // When closing this overlay, also close the child
section overlay
+ this.on( 'hide', function () {
+ referenceOverlay.remove();
+ } );
+ },
+
+ /**
+ * @inheritdoc
+ */
+ onStageChanges: function () {
+ this.$( '.overlay-footer-container' ).hide();
+ EditorOverlay.prototype.onStageChanges.apply( this,
arguments );
+ },
+
+ /**
+ * @inheritdoc
+ */
+ _hidePreview: function () {
+ this.$( '.overlay-footer-container' ).show();
+ EditorOverlay.prototype._hidePreview.apply( this,
arguments );
+ }
+ } );
+
+ M.define( 'modules/editor/EditorOverlayWithToolbar',
EditorOverlayWithToolbar );
+}( mw.mobileFrontend, jQuery ) );
diff --git
a/resources/mobile.editor.overlay.withtoolbar/EditorOverlayWithToolbar.less
b/resources/mobile.editor.overlay.withtoolbar/EditorOverlayWithToolbar.less
new file mode 100644
index 0000000..2f1ffd4
--- /dev/null
+++ b/resources/mobile.editor.overlay.withtoolbar/EditorOverlayWithToolbar.less
@@ -0,0 +1,51 @@
+@import "minerva.variables.less";
+@import "minerva.mixins.less";
+
+/* add a border to each tool, instead of using a toolgroup for every tool */
+.oo-ui-widget {
+ border-left: 1px solid @grayLight;
+}
+
+/* remove the doubled border for the toolgroup element */
+.oo-ui-toolGroup {
+ border-left: 0;
+}
+
+// Adjustments for OOJs UI Toolbars in mobile
+.overlay-footer {
+ // center-align buttons
+ text-align: center;
+
+ .toolbar {
+ // Expand the toolbar as wide as possible to limit the size of
the
+ // overlay-action. (Both are displayed as table-cells.)
+ width: 100%;
+ .oo-ui-toolbar {
+ // Everything is measured in ems so the easiest way to
scale
+ // is to change the base font size.
+ font-size: unit( @targetIconSize / @baseIconSize, em );
+ .oo-ui-iconElement-icon {
+ /* We should be able to use 'contain' here, but
some OOUI icon containers are oversized (T85139) */
+ .background-size( @targetIconSize,
@targetIconSize );
+ }
+ }
+ .oo-ui-tool-title,
+ .oo-ui-popupToolGroup-header {
+ // Undo font size increase for labels
+ font-size: unit( 0.9 / ( @targetIconSize /
@baseIconSize ), em );
+ }
+ .oo-ui-toolbar-bar {
+ // Overlay toolbar has its own borders
+ border: 0;
+ }
+ // Convert 0.3em margin to padding to make clickable area larger
+ .oo-ui-toolGroup {
+ margin: 0;
+ }
+ .oo-ui-barToolGroup .oo-ui-tool-link {
+ padding: 0.25em + 0.3em;
+ // Remove once MF box-sizing is fixed
+ .box-sizing( content-box );
+ }
+ }
+}
diff --git
a/resources/mobile.editor.overlay.withtoolbar/contentAddReference.hogan
b/resources/mobile.editor.overlay.withtoolbar/contentAddReference.hogan
new file mode 100644
index 0000000..35ac8dc
--- /dev/null
+++ b/resources/mobile.editor.overlay.withtoolbar/contentAddReference.hogan
@@ -0,0 +1 @@
+<textarea class="mw-ui-input wikitext-editor referenceInput"
placeholder="{{referenceMsg}}"></textarea>
\ No newline at end of file
diff --git a/resources/mobile.editor.overlay.withtoolbar/editorFooter.hogan
b/resources/mobile.editor.overlay.withtoolbar/editorFooter.hogan
new file mode 100644
index 0000000..c2dfcd7
--- /dev/null
+++ b/resources/mobile.editor.overlay.withtoolbar/editorFooter.hogan
@@ -0,0 +1,3 @@
+<div class="overlay-footer edit-buttons">
+ <div class="toolbar"></div>
+</div>
\ No newline at end of file
diff --git a/resources/mobile.editor/init.js b/resources/mobile.editor/init.js
index d4b51bf..57ddb09 100644
--- a/resources/mobile.editor/init.js
+++ b/resources/mobile.editor/init.js
@@ -144,8 +144,16 @@
* @method
*/
function loadSourceEditor() {
- loader.loadModule( 'mobile.editor.overlay'
).done( function () {
- var EditorOverlay = M.require(
'modules/editor/EditorOverlay' );
+ var rlModuleName, moduleName;
+ if ( !user.inUserBucketA() &&
context.isBetaGroupMember() ) {
+ moduleName =
'modules/editor/EditorOverlayWithToolbar';
+ rlModuleName =
'mobile.editor.overlay.withtoolbar';
+ } else {
+ moduleName =
'modules/editor/EditorOverlay';
+ rlModuleName = 'mobile.editor.overlay';
+ }
+ loader.loadModule( rlModuleName ).done(
function () {
+ var EditorOverlay = M.require(
moduleName );
result.resolve( new EditorOverlay(
editorOptions ) );
} );
}
diff --git a/resources/mobile.overlays/Overlay.less
b/resources/mobile.overlays/Overlay.less
index f0c75e2..1ed4781 100644
--- a/resources/mobile.overlays/Overlay.less
+++ b/resources/mobile.overlays/Overlay.less
@@ -305,13 +305,13 @@
.overlay-footer-container {
background-color: #FFF;
bottom: 0;
+ border-top: 1px solid @grayLight;
& a {
display: block;
// The 1em bottom whitespace is applied as padding since Chrome
and Safari ignore
// it otherwise. The 10px padding corresponds with the icon
margin.
padding: 1em 1em 1em 10px;
- border-top: 1px solid @grayLight;
text-align: center;
}
}
--
To view, visit https://gerrit.wikimedia.org/r/194945
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ib5215d859118bad83e9cd12ea7691283707b13b5
Gerrit-PatchSet: 19
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: Florianschmidtwelzow <[email protected]>
Gerrit-Reviewer: BarryTheBrowserTestBot <[email protected]>
Gerrit-Reviewer: Esanders <[email protected]>
Gerrit-Reviewer: Florianschmidtwelzow <[email protected]>
Gerrit-Reviewer: Frankiebot <[email protected]>
Gerrit-Reviewer: Jdlrobson <[email protected]>
Gerrit-Reviewer: Jforrester <[email protected]>
Gerrit-Reviewer: Kaldari <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: Trevor Parscal <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits