mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/WikiEditor
synced 2024-09-23 10:26:26 +00:00
Realtime Preview: display manual-reload bar when previews are slow
After three slow preview requests, switch to showing a bar at the top of the preview area that contains a manual 'reload' button. The manual bar will be hidden when an error message is show, but re-shown again after the error is dismissed. Closing and re-opening the preview pane doesn't reset the manual mode. Bug: T304568 Change-Id: Ia72bd1ceab68fdaed5de53137bd8ac5961db4714
This commit is contained in:
parent
94d4912103
commit
4c760f8634
|
@ -323,20 +323,23 @@
|
|||
"wikieditor-realtimepreview-error",
|
||||
"wikieditor-realtimepreview-reload",
|
||||
"wikieditor-realtimepreview-reload-title",
|
||||
"accesskey-wikieditor-realtimepreview"
|
||||
"accesskey-wikieditor-realtimepreview",
|
||||
"wikieditor-realtimepreview-manual"
|
||||
],
|
||||
"packageFiles": [
|
||||
"realtimepreview/init.js",
|
||||
"realtimepreview/RealtimePreview.js",
|
||||
"realtimepreview/ResizingDragBar.js",
|
||||
"realtimepreview/TwoPaneLayout.js",
|
||||
"realtimepreview/ErrorLayout.js"
|
||||
"realtimepreview/ErrorLayout.js",
|
||||
"realtimepreview/ManualWidget.js"
|
||||
],
|
||||
"styles": [
|
||||
"realtimepreview/RealtimePreview.less",
|
||||
"realtimepreview/ResizingDragBar.less",
|
||||
"realtimepreview/TwoPaneLayout.less",
|
||||
"realtimepreview/ErrorLayout.less"
|
||||
"realtimepreview/ErrorLayout.less",
|
||||
"realtimepreview/ManualWidget.less"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
|
@ -204,5 +204,6 @@
|
|||
"wikieditor-realtimepreview-beta-label": "Realtime Preview",
|
||||
"wikieditor-realtimepreview-beta-desc": "See how wikitext changes will appear to readers inside the [[mw:Special:MyLanguage/Extension:WikiEditor|2010 editor]].",
|
||||
"wikieditor-realtimepreview-reload-title": "Reload the realtime preview pane",
|
||||
"accesskey-wikieditor-realtimepreview": ")"
|
||||
"accesskey-wikieditor-realtimepreview": ")",
|
||||
"wikieditor-realtimepreview-manual": "Please reload now to manually preview your edits."
|
||||
}
|
||||
|
|
|
@ -231,9 +231,10 @@
|
|||
"tag-wikieditor-description": "Long description of the wikieditor tag ({{msg-mw|Tag-wikieditor}}).\n\nShown on [[Special:Tags]].\n\nSee also:\n* {{msg-mw|Tag-wikieditor}}",
|
||||
"wikieditor-realtimepreview-preview": "Label for the toolbar button to enable/disable realtime preview.",
|
||||
"wikieditor-realtimepreview-error": "Header text for realtime preview errors.",
|
||||
"wikieditor-realtimepreview-reload": "Button text for the 'reload' button on realtime preview errors.",
|
||||
"wikieditor-realtimepreview-reload": "Button text for the realtime preview 'reload' buttons (the hover button, the manual-reload button, and the button shown in error messages).",
|
||||
"wikieditor-realtimepreview-beta-label": "Used in [[Special:Preferences]].\n\nUsed as label for checkbox to enable Realtime Preview as a Beta Feature.\n\nThe description for this checkbox is: {{msg-mw|wikieditor-realtimepreview-beta-desc}}.",
|
||||
"wikieditor-realtimepreview-beta-desc": "Used in [[Special:Preferences]].\n\nUsed as description for the checkbox to enable Realtime Preview as a Beta Feature.\n\nThe label for this checkbox is {{msg-mw|wikieditor-realtimepreview-beta-label}}.",
|
||||
"wikieditor-realtimepreview-reload-title": "Tooltip text for the manual reload button.",
|
||||
"accesskey-wikieditor-realtimepreview": "{{doc-accesskey}}\nAccesskey for the manual reload button."
|
||||
"accesskey-wikieditor-realtimepreview": "{{doc-accesskey}}\nAccesskey for the manual reload button.",
|
||||
"wikieditor-realtimepreview-manual": "Message displayed when realtime preview is in 'manual' mode."
|
||||
}
|
||||
|
|
43
modules/realtimepreview/ManualWidget.js
Normal file
43
modules/realtimepreview/ManualWidget.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* global RealtimePreview */
|
||||
/**
|
||||
* @class
|
||||
* @constructor
|
||||
* @param {RealtimePreview} realtimePreview
|
||||
* @param {OO.ui.ButtonWidget} reloadHoverButton
|
||||
*/
|
||||
function ManualWidget( realtimePreview, reloadHoverButton ) {
|
||||
var config = {
|
||||
classes: [ 'ext-WikiEditor-ManualWidget' ],
|
||||
framed: true
|
||||
};
|
||||
ManualWidget.super.call( this, config );
|
||||
|
||||
this.reloadHoverButton = reloadHoverButton;
|
||||
|
||||
// UI elements.
|
||||
var reloadIcon = new OO.ui.IconWidget( { icon: 'reload' } );
|
||||
var $reloadLabel = $( '<span>' )
|
||||
.text( mw.msg( 'wikieditor-realtimepreview-manual' ) );
|
||||
this.reloadButton = new OO.ui.ButtonWidget( {
|
||||
label: mw.msg( 'wikieditor-realtimepreview-reload' ),
|
||||
framed: false,
|
||||
flags: [ 'progressive' ]
|
||||
} );
|
||||
this.reloadButton.connect( realtimePreview, {
|
||||
click: realtimePreview.doRealtimePreview.bind( realtimePreview )
|
||||
} );
|
||||
this.$element.append( reloadIcon.$element, $reloadLabel, this.reloadButton.$element );
|
||||
}
|
||||
|
||||
OO.inheritClass( ManualWidget, OO.ui.Widget );
|
||||
|
||||
ManualWidget.prototype.toggle = function ( show ) {
|
||||
ManualWidget.parent.prototype.toggle.call( this, show );
|
||||
if ( show ) {
|
||||
this.reloadHoverButton.$element.remove();
|
||||
// Use the same access key as the hover reload button, because this won't ever be displayed at the same time as that.
|
||||
this.reloadButton.setAccessKey( mw.msg( 'accesskey-wikieditor-realtimepreview' ) );
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = ManualWidget;
|
21
modules/realtimepreview/ManualWidget.less
Normal file
21
modules/realtimepreview/ManualWidget.less
Normal file
|
@ -0,0 +1,21 @@
|
|||
@import 'mediawiki.ui/variables';
|
||||
|
||||
.ext-WikiEditor-ManualWidget {
|
||||
background-color: @colorGray14;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-color: @colorGray12;
|
||||
border-width: 1px 0;
|
||||
border-style: solid;
|
||||
padding: 6px 24px;
|
||||
|
||||
& > .oo-ui-iconWidget {
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.oo-ui-buttonWidget {
|
||||
margin-left: auto;
|
||||
font-weight: bolder;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
var ResizingDragBar = require( './ResizingDragBar.js' );
|
||||
var TwoPaneLayout = require( './TwoPaneLayout.js' );
|
||||
var ErrorLayout = require( './ErrorLayout.js' );
|
||||
var ManualWidget = require( './ManualWidget.js' );
|
||||
|
||||
/**
|
||||
* @class
|
||||
|
@ -21,13 +22,19 @@ function RealtimePreview() {
|
|||
.append( $previewContent );
|
||||
|
||||
// Loading bar.
|
||||
this.$loadingBar = $( '<div>' ).addClass( 'ext-WikiEditor-realtimepreview-loadingbar' );
|
||||
this.$loadingBar = $( '<div>' ).addClass( 'ext-WikiEditor-realtimepreview-loadingbar' ).append( '<div>' );
|
||||
this.$loadingBar.hide();
|
||||
|
||||
// Error layout.
|
||||
this.errorLayout = new ErrorLayout();
|
||||
this.errorLayout.getReloadButton().connect( this, {
|
||||
click: this.doRealtimePreview.bind( this )
|
||||
click: function () {
|
||||
// Re-show the manual message after the error message is closed.
|
||||
if ( this.inManualMode ) {
|
||||
this.manualWidget.toggle( true );
|
||||
}
|
||||
this.doRealtimePreview();
|
||||
}.bind( this )
|
||||
} );
|
||||
|
||||
// Manual reload button (visible on hover).
|
||||
|
@ -47,7 +54,11 @@ function RealtimePreview() {
|
|||
}.bind( this )
|
||||
} );
|
||||
|
||||
this.twoPaneLayout.getPane2().append( reloadButton.$element, this.$loadingBar, this.$previewNode, this.errorLayout.$element );
|
||||
// Manual mode widget.
|
||||
this.manualWidget = new ManualWidget( this, reloadButton );
|
||||
this.inManualMode = false;
|
||||
|
||||
this.twoPaneLayout.getPane2().append( this.manualWidget.$element, reloadButton.$element, this.$loadingBar, this.$previewNode, this.errorLayout.$element );
|
||||
this.eventNames = 'change.realtimepreview input.realtimepreview cut.realtimepreview paste.realtimepreview';
|
||||
// Used to ensure we wait for a response before making new requests.
|
||||
this.isPreviewing = false;
|
||||
|
@ -146,6 +157,9 @@ RealtimePreview.prototype.toggle = function () {
|
|||
.off( this.eventNames )
|
||||
.on( this.eventNames, this.getEventHandler() );
|
||||
|
||||
// Hide or show the manual-reload message bar.
|
||||
this.manualWidget.toggle( this.inManualMode );
|
||||
|
||||
// Let other things happen after enabling.
|
||||
mw.hook( 'ext.WikiEditor.realtimepreview.enable' ).fire( this );
|
||||
}
|
||||
|
@ -162,7 +176,12 @@ RealtimePreview.prototype.toggle = function () {
|
|||
*/
|
||||
RealtimePreview.prototype.getEventHandler = function () {
|
||||
return mw.util.debounce(
|
||||
this.doRealtimePreview.bind( this ),
|
||||
function () {
|
||||
// Only do preview if we're not in manual mode (as set in this.checkResponseTimes()).
|
||||
if ( !this.inManualMode ) {
|
||||
this.doRealtimePreview();
|
||||
}
|
||||
}.bind( this ),
|
||||
this.configData.realtimeDebounce
|
||||
);
|
||||
};
|
||||
|
@ -173,6 +192,7 @@ RealtimePreview.prototype.getEventHandler = function () {
|
|||
*/
|
||||
RealtimePreview.prototype.showError = function ( $msg ) {
|
||||
this.$previewNode.hide();
|
||||
this.manualWidget.toggle( false );
|
||||
// There is no need for a default message because mw.Api.getErrorMessage() will
|
||||
// always provide something (even for no network connection, server-side fatal errors, etc.).
|
||||
this.errorLayout.setMessage( $msg );
|
||||
|
@ -184,6 +204,11 @@ RealtimePreview.prototype.showError = function ( $msg ) {
|
|||
* @param {number} time
|
||||
*/
|
||||
RealtimePreview.prototype.checkResponseTimes = function ( time ) {
|
||||
// Don't track response times if we're already in manual mode.
|
||||
if ( this.inManualMode ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.responseTimes.push( Date.now() - time );
|
||||
if ( this.responseTimes.length < 3 ) {
|
||||
return;
|
||||
|
@ -194,10 +219,10 @@ RealtimePreview.prototype.checkResponseTimes = function ( time ) {
|
|||
}, 0 );
|
||||
|
||||
if ( ( totalResponseTime / this.responseTimes.length ) > this.configData.realtimeDisableDuration ) {
|
||||
// TODO: switch to the 'manual preview' workflow once designs/behaviour is finalized.
|
||||
this.showError(
|
||||
$( '<div>' ).text( '[PLACEHOLDER] Realtime preview is too slow' )
|
||||
);
|
||||
this.inManualMode = true;
|
||||
// The error message might already be displayed if e.g. server timeout is greater than the disable-duration here.
|
||||
this.errorLayout.toggle( false );
|
||||
this.manualWidget.toggle( true );
|
||||
}
|
||||
|
||||
this.responseTimes.shift();
|
||||
|
@ -218,6 +243,7 @@ RealtimePreview.prototype.doRealtimePreview = function () {
|
|||
this.$loadingBar.show();
|
||||
var loadingSelectors = this.pagePreview.getLoadingSelectors();
|
||||
loadingSelectors.push( '.ext-WikiEditor-realtimepreview-preview' );
|
||||
loadingSelectors.push( '.ext-WikiEditor-ManualWidget' );
|
||||
this.errorLayout.toggle( false );
|
||||
var time = Date.now();
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
@loadingbar-width: 20%;
|
||||
|
||||
.ext-WikiEditor-realtimepreview-loadingbar {
|
||||
.ext-WikiEditor-realtimepreview-loadingbar div {
|
||||
position: absolute;
|
||||
z-index: 5;
|
||||
display: block;
|
||||
|
@ -53,8 +53,8 @@
|
|||
.ext-WikiEditor-twopanes-pane2 .ext-WikiEditor-reloadButton {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
top: 8px;
|
||||
right: 15px;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
flex: 1 1 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.ext-WikiEditor-realtimepreview-preview {
|
||||
overflow: auto;
|
||||
|
|
Loading…
Reference in a new issue