Add nicer realtime preview error messages

Add a new ErrorLayout to display error messages along with an
image.

Bug: T303383
Change-Id: I1ec27a212b5ab67d3e805c0d7756432850de89ea
This commit is contained in:
Sam Wilson 2022-03-23 11:28:12 +08:00
parent 7f5f5aa658
commit 6175e2c519
9 changed files with 153 additions and 15 deletions

View file

@ -301,24 +301,39 @@
"group": "ext.wikiEditor",
"styles": "ext.wikiEditor.toolbar.styles.less"
},
"ext.wikiEditor.images": {
"class": "ResourceLoaderImageModule",
"selector": ".ext-WikiEditor-image-{name}",
"images": {
"realtimepreview-error": {
"file": "realtimepreview/error.svg"
}
}
},
"ext.wikiEditor.realtimepreview": {
"dependencies": [
"ext.wikiEditor",
"mediawiki.page.preview"
"mediawiki.page.preview",
"ext.wikiEditor.images",
"oojs-ui.styles.icons-interactions"
],
"messages": [
"wikieditor-realtimepreview-preview"
"wikieditor-realtimepreview-preview",
"wikieditor-realtimepreview-error",
"wikieditor-realtimepreview-reload"
],
"packageFiles": [
"realtimepreview/init.js",
"realtimepreview/RealtimePreview.js",
"realtimepreview/ResizingDragBar.js",
"realtimepreview/TwoPaneLayout.js"
"realtimepreview/TwoPaneLayout.js",
"realtimepreview/ErrorLayout.js"
],
"styles": [
"realtimepreview/RealtimePreview.less",
"realtimepreview/ResizingDragBar.less",
"realtimepreview/TwoPaneLayout.less"
"realtimepreview/TwoPaneLayout.less",
"realtimepreview/ErrorLayout.less"
]
}
},

View file

@ -198,5 +198,7 @@
"wikieditor-toolbar-help-content-indent-result": "Normal text<dl><dd>Indented text<dl><dd>Indented text</dd></dl></dd></dl>",
"tag-wikieditor": "-",
"tag-wikieditor-description": "Edit made using [[mw:Special:MyLanguage/Extension:WikiEditor|WikiEditor]] (2010 wikitext editor)",
"wikieditor-realtimepreview-preview": "Preview"
"wikieditor-realtimepreview-preview": "Preview",
"wikieditor-realtimepreview-error": "Preview not loading",
"wikieditor-realtimepreview-reload": "Reload"
}

View file

@ -229,5 +229,7 @@
"wikieditor-toolbar-help-content-indent-result": "{{RawHtml|phab=T294760}}\n\nHTML example used in the help section \"discussion\" of the toolbar",
"tag-wikieditor": "{{ignored}}Short description of the wikieditor tag.\n\nShown on lists of changes (history, recentchanges, etc.) for each edit made using WikiEditor.\n\nSee also:\n* {{msg-mw|Tag-wikieditor-description}}",
"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 real-time preview."
"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."
}

View file

@ -0,0 +1,48 @@
/**
* This is a layout for displaying an error message.
*
* @class
* @constructor
* @extends OO.ui.Layout
* @param {Object} [config] Configuration options
*/
function ErrorLayout( config ) {
config = config || {};
ErrorLayout.super.call( this, config );
var $image = $( '<div>' ).addClass( 'ext-WikiEditor-image-realtimepreview-error' );
var $title = $( '<h3>' ).text( mw.msg( 'wikieditor-realtimepreview-error' ) );
this.$message = $( '<div>' ).addClass( 'ext-WikiEditor-realtimepreview-error-msg' );
this.reloadButton = new OO.ui.ButtonWidget( {
icon: 'reload',
label: mw.msg( 'wikieditor-realtimepreview-reload' ),
framed: false
} );
this.$element.addClass( 'ext-WikiEditor-realtimepreview-ErrorLayout' );
this.$element.append( $image, $title, this.$message, this.reloadButton.$element );
}
OO.inheritClass( ErrorLayout, OO.ui.Layout );
/**
* @public
* @return {OO.ui.ButtonWidget}
*/
ErrorLayout.prototype.getReloadButton = function () {
return this.reloadButton;
};
/**
* Set the displayed error message.
*
* @public
* @param {jQuery} $errorMsg The message to display.
*/
ErrorLayout.prototype.setMessage = function ( $errorMsg ) {
this.$message
.empty()
.append( $errorMsg );
};
module.exports = ErrorLayout;

View file

@ -0,0 +1,26 @@
@import 'mediawiki.ui/variables.less';
.ext-WikiEditor-realtimepreview-ErrorLayout {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
background-color: @colorGray15;
height: 100%;
width: 100%;
text-align: center;
& > * {
max-width: 268px;
margin: 6px;
}
.oo-ui-buttonWidget {
margin-top: 18px;
}
}
.ext-WikiEditor-image-realtimepreview-error {
height: 103px;
width: 92px;
}

View file

@ -1,5 +1,6 @@
var ResizingDragBar = require( './ResizingDragBar.js' );
var TwoPaneLayout = require( './TwoPaneLayout.js' );
var ErrorLayout = require( './ErrorLayout.js' );
/**
* @class
@ -15,9 +16,11 @@ function RealtimePreview() {
this.$previewNode = $( '<div>' )
.addClass( 'ext-WikiEditor-realtimepreview-preview' )
.append( $previewContent );
this.$errorNode = $( '<div>' )
.addClass( 'error' );
this.twoPaneLayout.getPane2().append( this.$previewNode, this.$errorNode );
this.errorLayout = new ErrorLayout();
this.errorLayout.getReloadButton().connect( this, {
click: this.doRealtimePreview.bind( this )
} );
this.twoPaneLayout.getPane2().append( 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;
@ -112,6 +115,18 @@ RealtimePreview.prototype.addPreviewListener = function ( $editor ) {
.on( this.eventNames, mw.util.debounce( 2000, this.doRealtimePreview.bind( this ) ) );
};
/**
* @private
* @param {jQuery} $msg
*/
RealtimePreview.prototype.showError = function ( $msg ) {
this.$previewNode.hide();
// 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 );
this.errorLayout.toggle( true );
};
/**
* @private
*/
@ -127,16 +142,13 @@ RealtimePreview.prototype.doRealtimePreview = function () {
this.twoPaneLayout.getPane2().addClass( 'ext-WikiEditor-twopanes-loading' );
var loadingSelectors = this.pagePreview.getLoadingSelectors();
loadingSelectors.push( '.ext-WikiEditor-realtimepreview-preview' );
this.$errorNode.empty();
this.errorLayout.toggle( false );
this.pagePreview.doPreview( {
$previewNode: this.$previewNode,
$spinnerNode: false,
loadingSelectors: loadingSelectors
} ).fail( function ( code, result ) {
var $errorMsg = ( new mw.Api() ).getErrorMessage( result );
this.$previewNode.hide();
this.$errorNode.append( $errorMsg );
this.showError( ( new mw.Api() ).getErrorMessage( result ) );
}.bind( this ) ).always( function () {
this.twoPaneLayout.getPane2().removeClass( 'ext-WikiEditor-twopanes-loading' );
this.isPreviewing = false;

View file

@ -10,6 +10,10 @@
max-height: none;
}
.ext-WikiEditor-realtimepreview-preview {
padding: 0 6px;
}
.wikiEditor-ui .wikiEditor-ui-view {
border-bottom: 0;
}

View file

@ -18,7 +18,7 @@
border-width: 0 0 0 1px;
flex: 1 1 0;
overflow: auto;
padding: 0 6px;
padding: 0;
}
@loadingbar-width: 20%;

View file

@ -0,0 +1,29 @@
<svg width="92" height="103" viewBox="0 0 92 103" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M54.5 88.8V71.2L68 57.7H77.2V12.5H69.5C68.8 12.5 68.2 11.9 68.2 11.2V3.5H14.2C13.5 3.5 12.9 4.1 12.9 4.8L12.7 47.1V59.1V87.6C12.7 88.5 14.3 88.9 15.2 88.9C16.6 88.9 16.5 90 17.7 90.4C19 90.8 19.5 88.9 20.6 88.9C21.8 88.9 21.6 90.4 23 90.4C24.3 90.4 24.4 88.9 25.8 88.9C27.2 88.9 27.2 90.4 28.5 90.4C29.8 90.4 29.8 88.9 31.2 88.9C32.6 88.9 32.6 90.4 34 90.4C35.4 90.4 35.2 88.9 36.6 88.9C38 88.9 38.1 90.4 39.4 90.4C40.7 90.4 40.9 88.9 42.3 88.9C43.7 88.9 43.5 90.4 44.8 90.4C46.1 90.4 46.2 88.9 47.5 88.9C48.8 88.9 49.1 90.7 50.4 90.4C51.7 90 51.7 88.9 53 88.9C54.3 88.9 54.3 90.4 55.6 90.4C55.8 90.4 55.9 90.4 56.1 90.3L54.5 88.8Z" fill="#F8F9FA"/>
<path d="M68.6 3.49998C68.7 3.39998 68.9 3.49998 69 3.59998L77 11.4C77.1 11.5 77.1 11.6 77.1 11.7C77.1 11.9 77 12 76.8 12H76.7H76.4H75.5H72.7H69.9H69H68.7V12C68.5 12 68.4 11.9 68.4 11.7V3.79998C68.4 3.69998 68.4 3.59998 68.6 3.49998Z" fill="#C8CCD1" stroke="#A2A9B1" stroke-width="1.3298"/>
<path d="M22.1 19C24.5853 19 26.6 17.0301 26.6 14.6C26.6 12.17 24.5853 10.2 22.1 10.2C19.6147 10.2 17.6 12.17 17.6 14.6C17.6 17.0301 19.6147 19 22.1 19Z" fill="#A2A9B1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M55.5 20.5C55.5 20.5 66.3 27.7 68.7 25C71.1 22.4 68.7 28.8 68.7 28.8H47.4" fill="#A2A9B1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.2 24.3C13.2 24.3 21.8 30.2 33.7 30.2C45.6 30.2 36.6 34 36.6 34H13.2" fill="#A2A9B1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.6 34.1C14.6 34.1 61.5 12 55.7 23.1C49.9 34.2 76.7 20.5 76.7 20.5V34.1" fill="#C8CCD1"/>
<path d="M76.6 33.6H13.2V34.6H76.6V33.6Z" fill="#F8F9FA"/>
<path d="M19.1 42.8H54C54.3 42.8 54.5 43 54.5 43.3C54.5 43.6 54.3 43.8 54 43.8H19.1C18.8 43.8 18.6 43.6 18.6 43.3C18.6 43 18.8 42.8 19.1 42.8Z" fill="#C8CCD1"/>
<path d="M19.1 54.4H57.9C58.2 54.4 58.4 54.6 58.4 54.9C58.4 55.2 58.2 55.4 57.9 55.4H19.1C18.8 55.4 18.6 55.2 18.6 54.9C18.6 54.7 18.8 54.4 19.1 54.4Z" fill="#A2A9B1"/>
<path d="M19.1 80.6H33.8C34.1 80.6 34.3 80.8 34.3 81.1C34.3 81.4 34.1 81.6 33.8 81.6H19.1C18.8 81.6 18.6 81.4 18.6 81.1C18.6 80.9 18.8 80.6 19.1 80.6Z" fill="#A2A9B1"/>
<path d="M19.1 61.2H26.5C26.8 61.2 27 61.4 27 61.7C27 62 26.8 62.2 26.5 62.2H19.1C18.8 62.2 18.6 62 18.6 61.7C18.6 61.4 18.8 61.2 19.1 61.2Z" fill="#A2A9B1"/>
<path d="M28.9 61.2H62.5C62.8 61.2 63 61.4 63 61.7C63 62 62.8 62.2 62.5 62.2H28.9C28.6 62.2 28.4 62 28.4 61.7C28.4 61.4 28.6 61.2 28.9 61.2Z" fill="#A2A9B1"/>
<path d="M19.1 77.2H26.5C26.8 77.2 27 77.4 27 77.7C27 78 26.8 78.2 26.5 78.2H19.1C18.8 78.2 18.6 78 18.6 77.7C18.6 77.5 18.8 77.2 19.1 77.2Z" fill="#A2A9B1"/>
<path d="M28.9 77.2H52.9C53.2 77.2 53.4 77.4 53.4 77.7C53.4 78 53.2 78.2 52.9 78.2H28.9C28.6 78.2 28.4 78 28.4 77.7C28.4 77.5 28.6 77.2 28.9 77.2Z" fill="#A2A9B1"/>
<path d="M71.1 54.4H60.3C60 54.4 59.8 54.6 59.8 54.9C59.8 55.2 60 55.4 60.3 55.4H71.1C71.4 55.4 71.6 55.2 71.6 54.9C71.6 54.7 71.4 54.4 71.1 54.4Z" fill="#A2A9B1"/>
<path d="M45.6 51H51.5C51.8 51 52 51.2 52 51.5C52 51.8 51.8 52 51.5 52H45.6C45.3 52 45.1 51.8 45.1 51.5C45.1 51.3 45.3 51 45.6 51Z" fill="#A2A9B1"/>
<path d="M53.9 51H71.1C71.4 51 71.6 51.2 71.6 51.5C71.6 51.8 71.4 52 71.1 52H53.9C53.6 52 53.4 51.8 53.4 51.5C53.5 51.3 53.7 51 53.9 51Z" fill="#A2A9B1"/>
<path d="M19.1 51H43.2C43.5 51 43.7 51.2 43.7 51.5C43.7 51.8 43.5 52 43.2 52H19.1C18.8 52 18.6 51.8 18.6 51.5C18.6 51.3 18.8 51 19.1 51Z" fill="#A2A9B1"/>
<path d="M19.1 39.4H43.2C43.5 39.4 43.7 39.6 43.7 39.9C43.7 40.2 43.5 40.4 43.2 40.4H19.1C18.8 40.4 18.6 40.2 18.6 39.9C18.6 39.6 18.8 39.4 19.1 39.4Z" fill="#A2A9B1"/>
<path d="M55.4 89.6C55.2 89.6 55 89.4 54.8 89.1C54.4 88.7 54 88.1 53 88.1C52 88.1 51.5 88.6 51.1 89C50.8 89.3 50.6 89.5 50.2 89.6C49.9 89.7 49.8 89.6 49.4 89.1C49 88.7 48.5 88.1 47.5 88.1C46.5 88.1 46 88.7 45.6 89.1C45.3 89.5 45.1 89.6 44.8 89.6C44.5 89.6 44.4 89.5 44.2 89.1C43.9 88.7 43.4 88.1 42.4 88.1C41.4 88.1 40.8 88.6 40.4 89C40 89.3 39.8 89.5 39.5 89.5C39.1 89.5 39 89.3 38.6 89C38.2 88.6 37.7 88.1 36.7 88.1C35.7 88.1 35.2 88.7 34.9 89.1C34.6 89.5 34.5 89.6 34.1 89.6C33.7 89.6 33.5 89.4 33.2 89.1C32.8 88.7 32.3 88.2 31.3 88.2C30.3 88.2 29.8 88.8 29.5 89.2C29.2 89.6 29 89.7 28.7 89.7C28.4 89.7 28.2 89.6 27.9 89.2C27.5 88.8 27 88.2 26 88.2C25 88.2 24.5 88.8 24.1 89.2C23.8 89.6 23.6 89.7 23.2 89.7C22.9 89.7 22.7 89.6 22.4 89.2C22.1 88.8 21.7 88.2 20.8 88.2C20 88.2 19.5 88.7 19 89.2C18.5 89.7 18.3 89.8 18 89.7C17.6 89.6 17.4 89.4 17.2 89.1C16.8 88.7 16.4 88.2 15.3 88.2C14.4 88.2 13.5 87.7 13.5 87.5V47.1V4.79999C13.5 4.39999 13.8 4.09999 14.2 4.09999H67.5V11.1C67.5 12.2 68.4 13.1 69.5 13.1H76.5V57.7H77.8V11.8H69.5C69.1 11.8 68.8 11.5 68.8 11.1V2.79999H14.2C13.1 2.79999 12.2 3.69999 12.2 4.79999L12 47.1V87.6C12 89 14 89.6 15.1 89.6C15.6 89.6 15.7 89.8 16 90.1C16.3 90.4 16.7 90.8 17.4 91.1C17.7 91 17.9 91 18.1 91C18.9 91 19.4 90.5 19.8 90C20.2 89.6 20.4 89.4 20.6 89.4C20.8 89.4 20.9 89.5 21.2 89.8C21.5 90.2 22 90.8 23 90.8C23.9 90.8 24.5 90.3 24.8 89.9C25.2 89.5 25.4 89.3 25.8 89.3C26.2 89.3 26.4 89.5 26.7 89.8C27.1 90.2 27.5 90.7 28.5 90.7C29.5 90.7 30 90.1 30.3 89.7C30.6 89.3 30.8 89.2 31.1 89.2C31.5 89.2 31.7 89.4 32 89.7C32.4 90.1 32.9 90.6 33.9 90.6C34.9 90.6 35.4 90 35.7 89.6C36 89.2 36.1 89.1 36.5 89.1C36.9 89.1 37.1 89.3 37.5 89.7C37.9 90.1 38.4 90.6 39.3 90.6C40.2 90.6 40.7 90.1 41.2 89.7C41.6 89.3 41.8 89.1 42.2 89.1C42.6 89.1 42.7 89.2 43 89.6C43.3 90 43.7 90.6 44.7 90.6C45.6 90.6 46.1 90.1 46.5 89.7C46.8 89.3 47 89.2 47.4 89.2C47.7 89.2 47.9 89.4 48.3 89.8C48.7 90.3 49.4 90.9 50.5 90.7C51.3 90.5 51.7 90.1 52 89.7C52.3 89.4 52.5 89.2 52.9 89.2C53.3 89.2 53.4 89.3 53.7 89.7C54 90.1 54.5 90.7 55.5 90.7C55.9 90.7 56.2 90.6 56.5 90.4L55.4 89.6Z" fill="#A2A9B1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M70.6 65.3L61.6 74.3V86.3L70.6 95.3H82.6L91.6 86.3V74.3L82.6 65.3H70.6ZM75.1 83.3H78.1V71.3H75.1V83.3ZM75.1 89.3H78.1V86.3H75.1V89.3Z" fill="#72777D"/>
<path d="M54.5 84H19.1C18.8 84 18.6 84.2 18.6 84.5C18.6 84.8 18.8 85 19.1 85H54.5V84Z" fill="#A2A9B1"/>
<path d="M54.5 80.6H36.3C36 80.6 35.8 80.8 35.8 81.1C35.8 81.4 36 81.6 36.3 81.6H54.5V80.6Z" fill="#A2A9B1"/>
<path d="M54.5 71.4H19.1C18.8 71.4 18.6 71.6 18.6 71.9C18.6 72.2 18.8 72.4 19.1 72.4H54.5V71.4Z" fill="#A2A9B1"/>
<path d="M57.7 68H19.1C18.8 68 18.6 68.2 18.6 68.5C18.6 68.8 18.8 69 19.1 69H56.7L57.7 68Z" fill="#A2A9B1"/>
<path d="M61.1 64.6H19.1C18.8 64.6 18.6 64.8 18.6 65.1C18.6 65.4 18.8 65.6 19.1 65.6H60.1L61.1 64.6Z" fill="#A2A9B1"/>
<path d="M67.8 57.8H19.1C18.8 57.8 18.6 58 18.6 58.3C18.6 58.6 18.8 58.8 19.1 58.8H66.9L67.8 57.8Z" fill="#A2A9B1"/>
</svg>

After

Width:  |  Height:  |  Size: 6.5 KiB