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

Reply via email to