Florianschmidtwelzow has uploaded a new change for review.
https://gerrit.wikimedia.org/r/194945
Change subject: WIP: Add basic features to mobile wikitext editor
......................................................................
WIP: Add basic features to mobile wikitext editor
tbd
Bug: T91752
Change-Id: Ib5215d859118bad83e9cd12ea7691283707b13b5
---
M i18n/en.json
M i18n/qqq.json
M includes/Resources.php
A javascripts/modules/editor/AddReferenceOverlay.js
M javascripts/modules/editor/EditorOverlay.js
M less/Overlay.less
M less/iconsNew.less
A less/images/bold-b.svg
A less/images/italic-i.svg
A less/images/reference-ltr.svg
A less/images/reference-rtl.svg
M less/modules/editor/VisualEditorOverlay.less
M templates/modules/editor/EditorOverlayBase.hogan
A templates/modules/editor/contentAddReference.hogan
A templates/modules/editor/editorFooter.hogan
15 files changed, 293 insertions(+), 40 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/MobileFrontend
refs/changes/45/194945/1
diff --git a/i18n/en.json b/i18n/en.json
index 4a523b7..faf07d7 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -104,6 +104,10 @@
"mobile-frontend-editor-viewing-source-page": "<strong>Viewing source
of</strong><span> $1</span>",
"mobile-frontend-editor-visual-editor": "Edit",
"mobile-frontend-editor-wait": "Saving edit, please wait.",
+ "mobile-frontend-editor-bold": "Bold",
+ "mobile-frontend-editor-italic": "Italic",
+ "mobile-frontend-editor-link": "Link",
+ "mobile-frontend-editor-reference": "Reference",
"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 67c06a1..2236d85 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -132,6 +132,10 @@
"mobile-frontend-editor-viewing-source-page": "A heading saying which
page's source code is being viewed. All text should be wrapped in a STRONG tag
except the page title itself.\n\nParameters:\n* $1 - page
title\n{{Related|Mobile-frontend-editor-page}}",
"mobile-frontend-editor-visual-editor": "Label for button that switches
to the \"visual editor\" (a WYSIWYG editing interface). Appears near
{{msg-mw|mobile-frontend-editor-source-edit}}. See
http://www.mediawiki.org/wiki/VisualEditor.\n{{Identical|Edit}}",
"mobile-frontend-editor-wait": "Text that displays while a page edit is
being saved.",
+ "mobile-frontend-editor-bold": "Title of \"Bold\" button in editor.",
+ "mobile-frontend-editor-italic": "Title of \"Italic\" button in
editor.",
+ "mobile-frontend-editor-link": "Title of \"Link\" button in editor.",
+ "mobile-frontend-editor-reference": "Title of \"Reference\" button in
editor.",
"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/includes/Resources.php b/includes/Resources.php
index 1eb7cd4..fa213a3 100644
--- a/includes/Resources.php
+++ b/includes/Resources.php
@@ -497,6 +497,10 @@
'mobile-frontend-editor-source-editor',
'mobile-frontend-editor-switch-editor',
'mobile-frontend-editor-anonwarning',
+ 'mobile-frontend-editor-bold',
+ 'mobile-frontend-editor-italic',
+ 'mobile-frontend-editor-link',
+ 'mobile-frontend-editor-reference',
),
),
@@ -504,12 +508,16 @@
'dependencies' => array(
'mobile.editor.common',
'mobile.loggingSchemas',
+ 'jquery.textSelection',
),
'scripts' => array(
+ 'javascripts/modules/editor/AddReferenceOverlay.js',
'javascripts/modules/editor/EditorOverlay.js',
),
'templates' => array(
'content.hogan' =>
'templates/modules/editor/content.hogan',
+ 'editorFooter.hogan' =>
'templates/modules/editor/editorFooter.hogan',
+ 'contentAddReference.hogan' =>
'templates/modules/editor/contentAddReference.hogan',
),
'messages' => array(
'mobile-frontend-editor-viewing-source-page',
diff --git a/javascripts/modules/editor/AddReferenceOverlay.js
b/javascripts/modules/editor/AddReferenceOverlay.js
new file mode 100644
index 0000000..5bef4a6
--- /dev/null
+++ b/javascripts/modules/editor/AddReferenceOverlay.js
@@ -0,0 +1,64 @@
+( function ( M, $ ) {
+ var AddReferenceOverlay,
+ Overlay = M.require( 'Overlay' );
+
+ /**
+ * Overlay that shows an editor
+ * @class AddReferenceOverlay
+ * @extends Overlay
+ */
+ AddReferenceOverlay = Overlay.extend( {
+ /**
+ * @inheritdoc
+ * @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, {
+ // FIXME: i18n and wording!
+ referenceMsg: 'What source you referring to?',
+ heading: 'Reference a source',
+ headerButtonsListClassName: 'overlay-action',
+ headerButtons: [ {
+ className: 'submit',
+ msg: 'Add'
+ } ]
+ } ),
+ /**
+ * @inheritdoc
+ */
+ templatePartials: $.extend( {},
Overlay.prototype.templatePartials, {
+ content: mw.template.get( 'mobile.editor.overlay',
'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 ( ev ) {
+ ev.preventDefault();
+ ev.stopPropagation();
+ this.hide();
+ }
+ } );
+
+ M.define( 'modules/editor/AddReferenceOverlay', AddReferenceOverlay );
+}( mw.mobileFrontend, jQuery ) );
diff --git a/javascripts/modules/editor/EditorOverlay.js
b/javascripts/modules/editor/EditorOverlay.js
index 810f856..2415ad6 100644
--- a/javascripts/modules/editor/EditorOverlay.js
+++ b/javascripts/modules/editor/EditorOverlay.js
@@ -1,5 +1,6 @@
( function ( M, $ ) {
var EditorOverlayBase = M.require( 'modules/editor/EditorOverlayBase' ),
+ AddReferenceOverlay = M.require(
'modules/editor/AddReferenceOverlay' ),
Section = M.require( 'Section' ),
EditorApi = M.require( 'modules/editor/EditorApi' ),
AbuseFilterPanel = M.require( 'modules/editor/AbuseFilterPanel'
),
@@ -20,6 +21,7 @@
EditorOverlay = EditorOverlayBase.extend( {
templatePartials: $.extend( {},
EditorOverlayBase.prototype.templatePartials, {
content: mw.template.get( 'mobile.editor.overlay',
'content.hogan' ),
+ footer: mw.template.get( 'mobile.editor.overlay',
'editorFooter.hogan' ),
anonWarning: mw.template.get( 'mobile.editor.common',
'EditorOverlayAnonWarning.hogan' )
} ),
/**
@@ -135,6 +137,7 @@
};
}
+ this._initializeEditorButtons();
EditorOverlayBase.prototype.postRender.apply( this,
arguments );
this.$preview = this.$( '.preview' );
@@ -162,6 +165,124 @@
},
/**
+ * 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} Function to call, when this Tool
is selected
+ * @return {OO.ui.Tool}
+ */
+ function getToolButton( group, name, icon, title,
callback ) {
+ var toolButton = function ( group, config ) {
+ // Parent constructor
+ OO.ui.Tool.call( this, group, config );
+ };
+
+ // inherit OO.ui.Tool
+ OO.inheritClass( toolButton, OO.ui.Tool );
+
+ // set callback
+ 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 );
+ //toolbar.initialize();
+ },
+
+ /**
+ * 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: '\'\'\'',
+ // FIXME: i18n
+ peri: 'Bold text ',
+ post: '\'\'\''
+ };
+ break;
+ case 'italic':
+ parts = {
+ pre: '\'\'',
+ // FIXME: i18n
+ peri: 'Italic text ',
+ post: '\'\''
+ };
+ break;
+ }
+ // replace/add the text to the content
+ 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: self
+ } );
+
+ // 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
+ self.on( 'hide', function () {
+ referenceOverlay.remove();
+ } );
+ },
+
+ /**
* Sets additional values used for anonymous editing warning.
* @method
* @private
diff --git a/less/Overlay.less b/less/Overlay.less
index c9bb8f9..64e2358 100644
--- a/less/Overlay.less
+++ b/less/Overlay.less
@@ -308,13 +308,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;
}
}
@@ -377,3 +377,43 @@
}
}
}
+
+// Adjustments for OOJs UI Toolbars in mobile Overlay-Headers and Footers
+@baseIconSize: 24px;
+@targetIconSize: 32px;
+.overlay-header-container,
+.overlay-footer-container {
+ .toolbar {
+ border-left: 1px solid @grayLight;
+ // 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 );
+ }
+ }
+}
\ No newline at end of file
diff --git a/less/iconsNew.less b/less/iconsNew.less
index 52f9cf6..a196e3d 100644
--- a/less/iconsNew.less
+++ b/less/iconsNew.less
@@ -104,3 +104,25 @@
margin-left: 0 !important;
margin-right: 0 !important;
}
+
+.oo-ui-icon-italic {
+ /* @embed */
+ background-image: url('images/italic-i.svg');
+}
+
+.oo-ui-icon-bold {
+ /* @embed */
+ background-image: url('images/bold-b.svg');
+}
+
+/* @noflip */
+.rtl .oo-ui-icon-reference {
+ /* @embed */
+ background-image: url(images/reference-rtl.svg);
+}
+
+/* @noflip */
+.ltr .oo-ui-icon-reference {
+ /* @embed */
+ background-image: url(images/reference-ltr.svg);
+}
diff --git a/less/images/bold-b.svg b/less/images/bold-b.svg
new file mode 100644
index 0000000..4f64820
--- /dev/null
+++ b/less/images/bold-b.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="bold-b">
+ <path id="b" d="M7 18h6c2 0 4-1 4-3 0-1.064.011-1.975-1.989-3 2-.975
1.989-1.935 1.989-3 0-2-2-3-4-3h-6v12zm7-8c0 1.001 0 1-2 1h-2v-3h2c2 0 2 0 2
1v1zm-2 6h-2v-3h2c2 0 2 0 2 1v1s0 1-2 1z"/>
+ </g>
+</svg>
diff --git a/less/images/italic-i.svg b/less/images/italic-i.svg
new file mode 100644
index 0000000..93bec5a
--- /dev/null
+++ b/less/images/italic-i.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="italic-i">
+ <path id="i" d="M12.5
17.999l.249-.994h-1.5l2.509-10.037h1.5l.242-.967h-5l-.242.967h1.5l-2.509
10.037h-1.5l-.249.994z"/>
+ </g>
+</svg>
diff --git a/less/images/reference-ltr.svg b/less/images/reference-ltr.svg
new file mode 100644
index 0000000..11e1c75
--- /dev/null
+++ b/less/images/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/less/images/reference-rtl.svg b/less/images/reference-rtl.svg
new file mode 100644
index 0000000..b31bbac
--- /dev/null
+++ b/less/images/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/less/modules/editor/VisualEditorOverlay.less
b/less/modules/editor/VisualEditorOverlay.less
index c4e9e53..89dd45d 100644
--- a/less/modules/editor/VisualEditorOverlay.less
+++ b/less/modules/editor/VisualEditorOverlay.less
@@ -76,43 +76,4 @@
.overlay-content * {
-webkit-transform: translate3d(0,0,0);
}
-
- // Toolbar
- @baseIconSize: 24px;
- @targetIconSize: 32px;
- .overlay-header-container {
- .toolbar {
- border-left: 1px solid @grayLight;
- // 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/templates/modules/editor/EditorOverlayBase.hogan
b/templates/modules/editor/EditorOverlayBase.hogan
index 7aff9b5..9e02095 100644
--- a/templates/modules/editor/EditorOverlayBase.hogan
+++ b/templates/modules/editor/EditorOverlayBase.hogan
@@ -21,3 +21,4 @@
{{{spinner}}}
{{>content}}
</div>
+{{>footer}}
\ No newline at end of file
diff --git a/templates/modules/editor/contentAddReference.hogan
b/templates/modules/editor/contentAddReference.hogan
new file mode 100644
index 0000000..35ac8dc
--- /dev/null
+++ b/templates/modules/editor/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/templates/modules/editor/editorFooter.hogan
b/templates/modules/editor/editorFooter.hogan
new file mode 100644
index 0000000..855bfb7
--- /dev/null
+++ b/templates/modules/editor/editorFooter.hogan
@@ -0,0 +1,3 @@
+<div class="overlay-footer-container position-fixed edit-buttons">
+ <div class="toolbar"></div>
+</div>
\ No newline at end of file
--
To view, visit https://gerrit.wikimedia.org/r/194945
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib5215d859118bad83e9cd12ea7691283707b13b5
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: Florianschmidtwelzow <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits