mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-12-20 02:01:20 +00:00
Merge "EditCheck: move checks to a sidebar"
This commit is contained in:
commit
4280c2c082
|
@ -18,6 +18,7 @@
|
||||||
"editcheck-dialog-addref-success-notify": "Thank you for adding a citation!",
|
"editcheck-dialog-addref-success-notify": "Thank you for adding a citation!",
|
||||||
"editcheck-dialog-addref-title": "Add a citation",
|
"editcheck-dialog-addref-title": "Add a citation",
|
||||||
"editcheck-dialog-title": "Before publishing",
|
"editcheck-dialog-title": "Before publishing",
|
||||||
|
"editcheck-review-title": "Review changes",
|
||||||
"tag-editcheck-reference-decline-common-knowledge": "Edit Check (references) declined (common knowledge)",
|
"tag-editcheck-reference-decline-common-knowledge": "Edit Check (references) declined (common knowledge)",
|
||||||
"tag-editcheck-reference-decline-common-knowledge-description": "EditCheck reference was declined as common knowledge",
|
"tag-editcheck-reference-decline-common-knowledge-description": "EditCheck reference was declined as common knowledge",
|
||||||
"tag-editcheck-reference-decline-irrelevant": "Edit Check (references) declined (irrelevant)",
|
"tag-editcheck-reference-decline-irrelevant": "Edit Check (references) declined (irrelevant)",
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
"editcheck-dialog-addref-success-notify": "Notification messages shown after a citation is added successfully.",
|
"editcheck-dialog-addref-success-notify": "Notification messages shown after a citation is added successfully.",
|
||||||
"editcheck-dialog-addref-title": "Title for the edit check context asking user to add a citation.",
|
"editcheck-dialog-addref-title": "Title for the edit check context asking user to add a citation.",
|
||||||
"editcheck-dialog-title": "Title shown in the toolbar while the user is in the add a citation workflow.",
|
"editcheck-dialog-title": "Title shown in the toolbar while the user is in the add a citation workflow.",
|
||||||
|
"editcheck-review-title": "Title shown in the sidebar / drawer while checks are displayed",
|
||||||
"tag-editcheck-reference-decline-common-knowledge": "Short description of the editcheck-reference-decline-common-knowledge tag.\n\nTag added when a user declines to add a suggested reference and selects the \"common knowledge\" reason.\n\nSee also:\n* {{msg-mw|editcheck-dialog-addref-reject-common-knowledge}}",
|
"tag-editcheck-reference-decline-common-knowledge": "Short description of the editcheck-reference-decline-common-knowledge tag.\n\nTag added when a user declines to add a suggested reference and selects the \"common knowledge\" reason.\n\nSee also:\n* {{msg-mw|editcheck-dialog-addref-reject-common-knowledge}}",
|
||||||
"tag-editcheck-reference-decline-common-knowledge-description": "Long description of the editcheck-reference-decline-common-knowledge tag.\n\nTag added when a user declines to add a suggested reference and selects the \"common knowledge\" reason.\n\nSee also:\n* {{msg-mw|editcheck-dialog-addref-reject-common-knowledge}}",
|
"tag-editcheck-reference-decline-common-knowledge-description": "Long description of the editcheck-reference-decline-common-knowledge tag.\n\nTag added when a user declines to add a suggested reference and selects the \"common knowledge\" reason.\n\nSee also:\n* {{msg-mw|editcheck-dialog-addref-reject-common-knowledge}}",
|
||||||
"tag-editcheck-reference-decline-irrelevant": "Short description of the editcheck-reference-decline-irrelevant tag.\n\nTag added when a user declines to add a suggested reference and selects the \"irrelevant\" reason.\n\nSee also:\n* {{msg-mw|editcheck-dialog-addref-reject-irrelevant}}",
|
"tag-editcheck-reference-decline-irrelevant": "Short description of the editcheck-reference-decline-irrelevant tag.\n\nTag added when a user declines to add a suggested reference and selects the \"irrelevant\" reason.\n\nSee also:\n* {{msg-mw|editcheck-dialog-addref-reject-irrelevant}}",
|
||||||
|
|
|
@ -26,8 +26,19 @@ mw.editcheck.BaseEditCheck.static.defaultConfig = {
|
||||||
ignoreLeadSection: false
|
ignoreLeadSection: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mw.editcheck.BaseEditCheck.static.title = ve.msg( 'editcheck-review-title' );
|
||||||
|
|
||||||
mw.editcheck.BaseEditCheck.static.description = ve.msg( 'editcheck-dialog-addref-description' );
|
mw.editcheck.BaseEditCheck.static.description = ve.msg( 'editcheck-dialog-addref-description' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the check type
|
||||||
|
*
|
||||||
|
* @return {string} Check type name
|
||||||
|
*/
|
||||||
|
mw.editcheck.BaseEditCheck.prototype.getName = function () {
|
||||||
|
return this.constructor.static.name;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ve.dm.Surface} surfaceModel
|
* @param {ve.dm.Surface} surfaceModel
|
||||||
* @return {mw.editcheck.EditCheckAction[]}
|
* @return {mw.editcheck.EditCheckAction[]}
|
||||||
|
@ -43,7 +54,8 @@ mw.editcheck.BaseEditCheck.prototype.onDocumentChange = null;
|
||||||
/**
|
/**
|
||||||
* @param {string} choice `action` key from static.choices
|
* @param {string} choice `action` key from static.choices
|
||||||
* @param {mw.editcheck.EditCheckAction} action
|
* @param {mw.editcheck.EditCheckAction} action
|
||||||
* @param {ve.ui.EditCheckContextItem} contextItem
|
* @param {ve.ui.Surface} surface
|
||||||
|
* @return {jQuery.Promise} Promise which resolves when action is complete
|
||||||
*/
|
*/
|
||||||
mw.editcheck.BaseEditCheck.prototype.act = null;
|
mw.editcheck.BaseEditCheck.prototype.act = null;
|
||||||
|
|
||||||
|
@ -55,6 +67,16 @@ mw.editcheck.BaseEditCheck.prototype.getChoices = function () {
|
||||||
return this.constructor.static.choices;
|
return this.constructor.static.choices;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the title of the check
|
||||||
|
*
|
||||||
|
* @param {mw.editcheck.EditCheckAction} action
|
||||||
|
* @return {jQuery|string|Function|OO.ui.HtmlSnippet}
|
||||||
|
*/
|
||||||
|
mw.editcheck.BaseEditCheck.prototype.getTitle = function () {
|
||||||
|
return this.constructor.static.title;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {mw.editcheck.EditCheckAction} action
|
* @param {mw.editcheck.EditCheckAction} action
|
||||||
* @return {string}
|
* @return {string}
|
||||||
|
|
|
@ -1,8 +1,29 @@
|
||||||
|
@import '../../lib/codex-design-tokens/theme-wikimedia-ui.less';
|
||||||
|
|
||||||
|
@media ( max-width: 1492px ) {
|
||||||
|
/* Hides the Vector sidebar while an editcheck-enabled editing session is occurring. See T379443. */
|
||||||
|
/* stylelint-disable selector-class-pattern */
|
||||||
|
.ve-editcheck-available {
|
||||||
|
.mw-body .vector-column-end,
|
||||||
|
.vector-pinnable-header-pin-button {
|
||||||
|
display: none !important; /* stylelint-disable-line declaration-no-important */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* stylelint-enable selector-class-pattern */
|
||||||
|
}
|
||||||
|
|
||||||
/* Toolbar */
|
/* Toolbar */
|
||||||
|
|
||||||
.ve-ui-editCheck-toolbar {
|
.ve-ui-editCheck-toolbar {
|
||||||
|
font-size: 0.875rem; // ignore content scaling
|
||||||
|
|
||||||
|
.mw-mf & {
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
.oo-ui-toolbar-bar {
|
.oo-ui-toolbar-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.oo-ui-toolbar-tools {
|
.oo-ui-toolbar-tools {
|
||||||
|
@ -14,6 +35,12 @@
|
||||||
flex: 0;
|
flex: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.oo-ui-toolbar-actions + div {
|
||||||
|
// There's a clear div that we need to enhance slightly
|
||||||
|
flex-basis: 100%;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
&.ve-init-mw-mobileArticleTarget-toolbar .oo-ui-toolbar-tools.oo-ui-toolbar-after {
|
&.ve-init-mw-mobileArticleTarget-toolbar .oo-ui-toolbar-tools.oo-ui-toolbar-after {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -44,6 +71,162 @@
|
||||||
border-bottom-color: #fce7fe;
|
border-bottom-color: #fce7fe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Actions */
|
||||||
|
|
||||||
|
.ve-ui-editCheckDialog {
|
||||||
|
font-size: 0.875rem; // ignore content scaling
|
||||||
|
|
||||||
|
.oo-ui-window-body {
|
||||||
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-title {
|
||||||
|
display: block;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: @spacing-50 0;
|
||||||
|
margin-bottom: @spacing-50;
|
||||||
|
border-bottom: 1px solid @border-color-base;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
> .oo-ui-labelWidget {
|
||||||
|
align-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ve-ui-editCheckActionWidget {
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: @border-base;
|
||||||
|
margin: @spacing-100 0;
|
||||||
|
white-space: normal; // Minerva needs this
|
||||||
|
|
||||||
|
&-head {
|
||||||
|
position: relative;
|
||||||
|
padding: @spacing-50 @spacing-75;
|
||||||
|
|
||||||
|
> .oo-ui-labelElement-label {
|
||||||
|
display: block;
|
||||||
|
margin-left: 2em;
|
||||||
|
font-weight: @font-weight-semi-bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-body {
|
||||||
|
margin: @spacing-50 @spacing-75 @spacing-100;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-actions {
|
||||||
|
margin-top: @spacing-100;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ve-ui-editCheckActionWidget-collapsed {
|
||||||
|
filter: grayscale( 1 );
|
||||||
|
|
||||||
|
> .ve-ui-editCheckActionWidget-body {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.oo-ui-flaggedElement-warning {
|
||||||
|
border-color: @border-color-warning;
|
||||||
|
|
||||||
|
> .ve-ui-editCheckActionWidget-head {
|
||||||
|
background-color: @background-color-warning-subtle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.oo-ui-flaggedElement-error {
|
||||||
|
border-color: @border-color-error;
|
||||||
|
|
||||||
|
> .ve-ui-editCheckActionWidget-head {
|
||||||
|
background-color: @background-color-error-subtle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.oo-ui-flaggedElement-success {
|
||||||
|
border-color: @border-color-success;
|
||||||
|
|
||||||
|
> .ve-ui-editCheckActionWidget-head {
|
||||||
|
background-color: @background-color-success-subtle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.oo-ui-flaggedElement-notice {
|
||||||
|
border-color: @border-color-notice;
|
||||||
|
|
||||||
|
> .ve-ui-editCheckActionWidget-head {
|
||||||
|
background-color: @background-color-notice-subtle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ve-ui-editCheckDialog-singleAction .ve-ui-editCheckActionWidget-collapsed {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mw-mf & {
|
||||||
|
top: auto;
|
||||||
|
// See: .ve-ui-mobileContext, which this is closely mimicking
|
||||||
|
background-color: @background-color-interactive-subtle;
|
||||||
|
/* Match toolbar border & shadow */
|
||||||
|
border-top: @border-subtle;
|
||||||
|
box-shadow: 0 -1px 1px 0 rgba( 0, 0, 0, 0.1 );
|
||||||
|
/* Transition out faster, as keyboard may be coming up */
|
||||||
|
transition: transform 100ms;
|
||||||
|
transform: translateY( 0% );
|
||||||
|
max-width: 995px;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
&-title {
|
||||||
|
padding: @spacing-75 @spacing-100;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-close {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-footer {
|
||||||
|
margin: 0 @spacing-100 @spacing-50;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ve-ui-editCheckDialog-collapsed {
|
||||||
|
display: block;
|
||||||
|
transition: transform 250ms;
|
||||||
|
transform: translateY( calc( 100% - 2.5em ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
.oo-ui-window-body {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ve-ui-editCheckActionWidget {
|
||||||
|
margin: 0;
|
||||||
|
border-width: 0;
|
||||||
|
|
||||||
|
&-head {
|
||||||
|
background-color: transparent !important; /* stylelint-disable-line declaration-no-important */
|
||||||
|
}
|
||||||
|
|
||||||
|
&-body {
|
||||||
|
padding-left: 2em;
|
||||||
|
margin-bottom: @spacing-75;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mw-mf .ve-ce-surface-reviewMode.ve-ce-surface-deactivated {
|
||||||
|
// Otherwise the content will be covered by the mobile context at the end
|
||||||
|
// of the document. (Upstream this?)
|
||||||
|
margin-bottom: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
/* Selections */
|
/* Selections */
|
||||||
|
|
||||||
.ve-ce-surface-reviewMode + .ve-ui-overlay .ve-ce-surface-selections-editCheck .ve-ce-surface-selection {
|
.ve-ce-surface-reviewMode + .ve-ui-overlay .ve-ce-surface-selections-editCheck .ve-ce-surface-selection {
|
||||||
|
@ -68,9 +251,41 @@
|
||||||
mix-blend-mode: darken;
|
mix-blend-mode: darken;
|
||||||
// Adjust target colours to account for 50% opacity
|
// Adjust target colours to account for 50% opacity
|
||||||
background: ( #fef6e7 - 0.8 * ( #fff ) ) / 0.2;
|
background: ( #fef6e7 - 0.8 * ( #fff ) ) / 0.2;
|
||||||
border: 1px solid ( ( #a66200 - 0.8 * ( #fff ) ) / 0.2 );
|
// border: 1px solid ( ( #a66200 - 0.8 * ( #fff ) ) / 0.2 );
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
margin: -2px 0 0 -2px;
|
margin: -2px 0 0 -2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ve-ui-editCheck-gutter-highlight {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 2px;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: @color-base;
|
||||||
|
|
||||||
|
&-error {
|
||||||
|
background-color: @color-error;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-warning {
|
||||||
|
background-color: @color-warning;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-notice {
|
||||||
|
background-color: @color-notice;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-success {
|
||||||
|
background-color: @color-success;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-inactive {
|
||||||
|
background-color: @border-color-base;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mw-mf & {
|
||||||
|
left: -10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,15 +5,28 @@
|
||||||
* @param {mw.editcheck.BaseEditCheck} check
|
* @param {mw.editcheck.BaseEditCheck} check
|
||||||
* @param {ve.dm.SurfaceFragment[]} fragments Affected fragments
|
* @param {ve.dm.SurfaceFragment[]} fragments Affected fragments
|
||||||
* @param {jQuery|string|Function|OO.ui.HtmlSnippet} message Check message body
|
* @param {jQuery|string|Function|OO.ui.HtmlSnippet} message Check message body
|
||||||
|
* @param {jQuery|string|Function|OO.ui.HtmlSnippet} title Check title
|
||||||
*/
|
*/
|
||||||
mw.editcheck.EditCheckAction = function MWEditCheckAction( config ) {
|
mw.editcheck.EditCheckAction = function MWEditCheckAction( config ) {
|
||||||
this.check = config.check;
|
this.check = config.check;
|
||||||
this.fragments = config.fragments;
|
this.fragments = config.fragments;
|
||||||
this.message = config.message;
|
this.message = config.message;
|
||||||
|
this.title = config.title;
|
||||||
|
this.icon = config.icon;
|
||||||
|
this.type = config.type || 'warning';
|
||||||
};
|
};
|
||||||
|
|
||||||
OO.initClass( mw.editcheck.EditCheckAction );
|
OO.initClass( mw.editcheck.EditCheckAction );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the action's title
|
||||||
|
*
|
||||||
|
* @return {jQuery|string|Function|OO.ui.HtmlSnippet}
|
||||||
|
*/
|
||||||
|
mw.editcheck.EditCheckAction.prototype.getTitle = function () {
|
||||||
|
return this.title || this.check.getTitle( this );
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the available choices
|
* Get the available choices
|
||||||
*
|
*
|
||||||
|
@ -38,5 +51,137 @@ mw.editcheck.EditCheckAction.prototype.getHighlightSelections = function () {
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
mw.editcheck.EditCheckAction.prototype.getDescription = function () {
|
mw.editcheck.EditCheckAction.prototype.getDescription = function () {
|
||||||
return this.check.getDescription( this );
|
return this.message || this.check.getDescription( this );
|
||||||
|
};
|
||||||
|
|
||||||
|
mw.editcheck.EditCheckAction.prototype.getType = function () {
|
||||||
|
return this.type;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the check type
|
||||||
|
*
|
||||||
|
* @return {string} Check type name
|
||||||
|
*/
|
||||||
|
mw.editcheck.EditCheckAction.prototype.getName = function () {
|
||||||
|
return this.check.getName();
|
||||||
|
};
|
||||||
|
|
||||||
|
mw.editcheck.EditCheckAction.prototype.render = function ( collapsed, singleAction, surface ) {
|
||||||
|
const widget = new mw.editcheck.EditCheckActionWidget( {
|
||||||
|
type: this.type,
|
||||||
|
icon: this.icon,
|
||||||
|
label: this.getTitle(),
|
||||||
|
message: this.getDescription(),
|
||||||
|
classes: collapsed ? [ 've-ui-editCheckActionWidget-collapsed' ] : '',
|
||||||
|
singleAction: singleAction
|
||||||
|
} );
|
||||||
|
this.getChoices().forEach( ( choice ) => {
|
||||||
|
const button = new OO.ui.ButtonWidget( choice );
|
||||||
|
button.connect( this, {
|
||||||
|
click: () => {
|
||||||
|
const promise = this.check.act( choice.action, this, surface ) || ve.createDeferred().resolve().promise();
|
||||||
|
widget.emit( 'act', choice, choice.action, promise );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
widget.addAction( button );
|
||||||
|
} );
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
};
|
||||||
|
|
||||||
|
mw.editcheck.EditCheckActionWidget = function MWEditCheckActionWidget( config ) {
|
||||||
|
// Configuration initialization
|
||||||
|
config = config || {};
|
||||||
|
|
||||||
|
this.singleAction = config.singleAction;
|
||||||
|
|
||||||
|
this.actions = [];
|
||||||
|
|
||||||
|
// Parent constructor
|
||||||
|
mw.editcheck.EditCheckActionWidget.super.call( this, config );
|
||||||
|
|
||||||
|
// Mixin constructors
|
||||||
|
OO.ui.mixin.IconElement.call( this, config );
|
||||||
|
OO.ui.mixin.LabelElement.call( this, config );
|
||||||
|
OO.ui.mixin.TitledElement.call( this, config );
|
||||||
|
OO.ui.mixin.FlaggedElement.call( this, config );
|
||||||
|
|
||||||
|
this.setType( config.type );
|
||||||
|
|
||||||
|
if ( config.icon ) {
|
||||||
|
this.setIcon( config.icon );
|
||||||
|
}
|
||||||
|
|
||||||
|
this.message = new OO.ui.LabelWidget( { label: config.message } );
|
||||||
|
this.$actions = $( '<div>' ).addClass( 've-ui-editCheckActionWidget-actions oo-ui-element-hidden' );
|
||||||
|
|
||||||
|
this.$head = $( '<div>' )
|
||||||
|
.append( this.$icon, this.$label )
|
||||||
|
.addClass( 've-ui-editCheckActionWidget-head' )
|
||||||
|
.on( 'click', this.onHeadClick.bind( this ) );
|
||||||
|
this.$body = $( '<div>' )
|
||||||
|
.append( this.message.$element, this.$actions )
|
||||||
|
.addClass( 've-ui-editCheckActionWidget-body' );
|
||||||
|
|
||||||
|
this.$element
|
||||||
|
.append( this.$head, this.$body )
|
||||||
|
// .append( this.$icon, this.$label, this.closeButton && this.closeButton.$element )
|
||||||
|
.addClass( 've-ui-editCheckActionWidget' );
|
||||||
|
};
|
||||||
|
|
||||||
|
OO.inheritClass( mw.editcheck.EditCheckActionWidget, OO.ui.Widget );
|
||||||
|
OO.mixinClass( mw.editcheck.EditCheckActionWidget, OO.ui.mixin.IconElement );
|
||||||
|
OO.mixinClass( mw.editcheck.EditCheckActionWidget, OO.ui.mixin.LabelElement );
|
||||||
|
OO.mixinClass( mw.editcheck.EditCheckActionWidget, OO.ui.mixin.TitledElement );
|
||||||
|
OO.mixinClass( mw.editcheck.EditCheckActionWidget, OO.ui.mixin.FlaggedElement );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
mw.editcheck.EditCheckActionWidget.prototype.setDisabled = function ( disabled ) {
|
||||||
|
OO.ui.Widget.prototype.setDisabled.call( this, disabled );
|
||||||
|
this.actions.forEach( ( action ) => {
|
||||||
|
action.setDisabled( disabled );
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
|
||||||
|
mw.editcheck.EditCheckActionWidget.static.iconMap = {
|
||||||
|
notice: 'infoFilled',
|
||||||
|
error: 'error',
|
||||||
|
warning: 'alert'
|
||||||
|
};
|
||||||
|
|
||||||
|
mw.editcheck.EditCheckActionWidget.prototype.setType = function ( type ) {
|
||||||
|
if ( !this.constructor.static.iconMap[ type ] ) {
|
||||||
|
type = 'notice';
|
||||||
|
}
|
||||||
|
if ( type !== this.type ) {
|
||||||
|
this.clearFlags();
|
||||||
|
this.setFlags( type );
|
||||||
|
|
||||||
|
this.setIcon( this.constructor.static.iconMap[ type ] );
|
||||||
|
}
|
||||||
|
this.type = type;
|
||||||
|
};
|
||||||
|
|
||||||
|
mw.editcheck.EditCheckActionWidget.prototype.getType = function () {
|
||||||
|
return this.type;
|
||||||
|
};
|
||||||
|
|
||||||
|
mw.editcheck.EditCheckActionWidget.prototype.addAction = function ( action ) {
|
||||||
|
this.actions.push( action );
|
||||||
|
this.$actions.append( action.$element ).removeClass( 'oo-ui-element-hidden' );
|
||||||
|
};
|
||||||
|
|
||||||
|
mw.editcheck.EditCheckActionWidget.prototype.onHeadClick = function ( e ) {
|
||||||
|
if ( this.singleAction ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
// eslint-disable-next-line no-jquery/no-class-state
|
||||||
|
this.$element.toggleClass( 've-ui-editCheckActionWidget-collapsed' );
|
||||||
|
// eslint-disable-next-line no-jquery/no-class-state
|
||||||
|
this.emit( 'togglecollapse', this.$element.hasClass( 've-ui-editCheckActionWidget-collapsed' ) );
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,15 +27,14 @@ OO.inheritClass( ve.ui.EditCheckDialog, ve.ui.ToolbarDialog );
|
||||||
|
|
||||||
ve.ui.EditCheckDialog.static.name = 'editCheckDialog';
|
ve.ui.EditCheckDialog.static.name = 'editCheckDialog';
|
||||||
|
|
||||||
ve.ui.EditCheckDialog.static.position = 'side';
|
ve.ui.EditCheckDialog.static.position = OO.ui.isMobile() ? 'below' : 'side';
|
||||||
|
|
||||||
ve.ui.EditCheckDialog.static.size = 'medium';
|
ve.ui.EditCheckDialog.static.size = OO.ui.isMobile() ? 'full' : 'medium';
|
||||||
|
|
||||||
ve.ui.EditCheckDialog.static.framed = false;
|
ve.ui.EditCheckDialog.static.framed = false;
|
||||||
|
|
||||||
// // Invisible title for accessibility
|
// Invisible title for accessibility
|
||||||
// ve.ui.EditCheckDialog.static.title =
|
ve.ui.EditCheckDialog.static.title = OO.ui.deferMsg( 'editcheck-review-title' );
|
||||||
// OO.ui.deferMsg( 'visualeditor-find-and-replace-title' );
|
|
||||||
|
|
||||||
/* Methods */
|
/* Methods */
|
||||||
|
|
||||||
|
@ -46,26 +45,190 @@ ve.ui.EditCheckDialog.prototype.initialize = function () {
|
||||||
// Parent method
|
// Parent method
|
||||||
ve.ui.EditCheckDialog.super.prototype.initialize.call( this );
|
ve.ui.EditCheckDialog.super.prototype.initialize.call( this );
|
||||||
|
|
||||||
|
this.title = new OO.ui.LabelWidget( {
|
||||||
|
label: this.constructor.static.title,
|
||||||
|
classes: [ 've-ui-editCheckDialog-title' ]
|
||||||
|
} );
|
||||||
|
|
||||||
|
// FIXME: click handlers are getting unbound when the window is closed
|
||||||
|
|
||||||
|
this.closeButton = new OO.ui.ButtonWidget( {
|
||||||
|
classes: [ 've-ui-editCheckDialog-close' ],
|
||||||
|
framed: false,
|
||||||
|
label: ve.msg( 'visualeditor-contextitemwidget-label-close' ),
|
||||||
|
invisibleLabel: true,
|
||||||
|
icon: 'expand'
|
||||||
|
} ).connect( this, {
|
||||||
|
click: 'onCloseButtonClick'
|
||||||
|
} );
|
||||||
|
|
||||||
|
this.currentOffset = 0;
|
||||||
|
|
||||||
|
this.footerLabel = new OO.ui.LabelWidget();
|
||||||
|
this.previousButton = new OO.ui.ButtonWidget( {
|
||||||
|
icon: 'previous',
|
||||||
|
title: ve.msg( 'last' ),
|
||||||
|
invisibleLabel: true,
|
||||||
|
framed: false
|
||||||
|
} ).connect( this, {
|
||||||
|
click: 'onPreviousButtonClick'
|
||||||
|
} );
|
||||||
|
this.nextButton = new OO.ui.ButtonWidget( {
|
||||||
|
icon: 'next',
|
||||||
|
title: ve.msg( 'next' ),
|
||||||
|
invisibleLabel: true,
|
||||||
|
framed: false
|
||||||
|
} ).connect( this, {
|
||||||
|
click: 'onNextButtonClick'
|
||||||
|
} );
|
||||||
|
this.footer = new OO.ui.HorizontalLayout( {
|
||||||
|
classes: [ 've-ui-editCheckDialog-footer' ],
|
||||||
|
items: [
|
||||||
|
this.footerLabel,
|
||||||
|
this.previousButton,
|
||||||
|
this.nextButton
|
||||||
|
]
|
||||||
|
} );
|
||||||
|
|
||||||
|
this.$checks = $( '<div>' );
|
||||||
|
this.$body.append( this.title.$element, this.closeButton.$element, this.$checks, this.footer.$element );
|
||||||
|
|
||||||
|
this.$highlights = $( '<div>' );
|
||||||
|
|
||||||
this.updateDebounced = ve.debounce( this.update.bind( this ), 100 );
|
this.updateDebounced = ve.debounce( this.update.bind( this ), 100 );
|
||||||
|
this.positionDebounced = ve.debounce( this.position.bind( this ), 100 );
|
||||||
};
|
};
|
||||||
|
|
||||||
ve.ui.EditCheckDialog.prototype.update = function () {
|
ve.ui.EditCheckDialog.prototype.update = function () {
|
||||||
const surfaceView = this.surface.getView();
|
const surfaceView = this.surface.getView();
|
||||||
const checks = mw.editcheck.editCheckFactory.createAllByListener( 'onDocumentChange', this.surface.getModel() );
|
// We only regenerate the checks on-change during the edit. If we're in
|
||||||
const $checks = $( '<div>' );
|
// the proofreading step, no new checks should appear based on changes:
|
||||||
const selections = [];
|
if ( this.listener === 'onDocumentChange' || !this.currentChecks ) {
|
||||||
|
this.currentChecks = mw.editcheck.editCheckFactory.createAllByListener( this.listener, this.surface.getModel() );
|
||||||
|
}
|
||||||
|
if ( this.listener === 'onBeforeSave' && this.currentChecks.length === 0 ) {
|
||||||
|
return this.close( 'complete' );
|
||||||
|
}
|
||||||
|
const checks = this.currentChecks;
|
||||||
|
const newOffset = Math.min( this.currentOffset, checks.length - 1 );
|
||||||
|
this.$checks.empty();
|
||||||
|
this.$highlights.empty();
|
||||||
|
|
||||||
|
checks.forEach( ( check, index ) => {
|
||||||
|
const widget = check.render( index !== newOffset, this.listener === 'onBeforeSave', this.surface );
|
||||||
|
widget.on( 'togglecollapse', this.onToggleCollapse, [ check, index ], this );
|
||||||
|
widget.on( 'act', this.onAct, [ widget ], this );
|
||||||
|
this.$checks.append( widget.$element );
|
||||||
|
check.widget = widget;
|
||||||
|
} );
|
||||||
|
|
||||||
|
if ( this.reviewMode ) {
|
||||||
|
// Review mode grays out everything that's not highlighted:
|
||||||
|
const highlightNodes = [];
|
||||||
checks.forEach( ( check ) => {
|
checks.forEach( ( check ) => {
|
||||||
$checks.append( new OO.ui.MessageWidget( {
|
|
||||||
type: 'warning',
|
|
||||||
label: check.message,
|
|
||||||
framed: false
|
|
||||||
} ).$element );
|
|
||||||
check.getHighlightSelections().forEach( ( selection ) => {
|
check.getHighlightSelections().forEach( ( selection ) => {
|
||||||
selections.push( ve.ce.Selection.static.newFromModel( selection, surfaceView ) );
|
highlightNodes.push.apply( highlightNodes, surfaceView.getDocument().selectNodes( selection.getCoveringRange(), 'branches' ).map( ( spec ) => spec.node ) );
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
surfaceView.getSelectionManager().drawSelections( 'editCheckWarning', selections );
|
surfaceView.setReviewMode( true, highlightNodes );
|
||||||
this.$body.empty().append( $checks );
|
}
|
||||||
|
|
||||||
|
this.setCurrentOffset( newOffset );
|
||||||
|
};
|
||||||
|
|
||||||
|
ve.ui.EditCheckDialog.prototype.position = function () {
|
||||||
|
this.drawHighlights();
|
||||||
|
this.scrollCurrentCheckIntoView();
|
||||||
|
};
|
||||||
|
|
||||||
|
ve.ui.EditCheckDialog.prototype.drawHighlights = function () {
|
||||||
|
const surfaceView = this.surface.getView();
|
||||||
|
this.$highlights.empty();
|
||||||
|
|
||||||
|
this.currentChecks.forEach( ( check, index ) => {
|
||||||
|
check.getHighlightSelections().forEach( ( selection ) => {
|
||||||
|
const selectionView = ve.ce.Selection.static.newFromModel( selection, surfaceView );
|
||||||
|
const rect = selectionView.getSelectionBoundingRect();
|
||||||
|
// The following classes are used here:
|
||||||
|
// * ve-ui-editCheck-gutter-highlight-error
|
||||||
|
// * ve-ui-editCheck-gutter-highlight-warning
|
||||||
|
// * ve-ui-editCheck-gutter-highlight-notice
|
||||||
|
// * ve-ui-editCheck-gutter-highlight-success
|
||||||
|
// * ve-ui-editCheck-gutter-highlight-active
|
||||||
|
// * ve-ui-editCheck-gutter-highlight-inactive
|
||||||
|
this.$highlights.append( $( '<div>' )
|
||||||
|
.addClass( 've-ui-editCheck-gutter-highlight' )
|
||||||
|
.addClass( 've-ui-editCheck-gutter-highlight-' + check.getType() )
|
||||||
|
.addClass( 've-ui-editCheck-gutter-highlight-' + ( index === this.currentOffset ? 'active' : 'inactive' ) )
|
||||||
|
.css( {
|
||||||
|
top: rect.top - 2,
|
||||||
|
height: rect.height + 4
|
||||||
|
} )
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
surfaceView.appendHighlights( this.$highlights, false );
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the offset of the current check, within the list of all checks
|
||||||
|
*
|
||||||
|
* @param {number} offset
|
||||||
|
*/
|
||||||
|
ve.ui.EditCheckDialog.prototype.setCurrentOffset = function ( offset ) {
|
||||||
|
// TODO: work out how to tell the window to recalculate height here
|
||||||
|
this.currentOffset = Math.max( 0, offset );
|
||||||
|
|
||||||
|
this.$body.find( '.ve-ui-editCheckActionWidget' ).each( ( i, el ) => {
|
||||||
|
$( el ).toggleClass( 've-ui-editCheckActionWidget-collapsed', i !== this.currentOffset );
|
||||||
|
} );
|
||||||
|
|
||||||
|
this.footerLabel.setLabel(
|
||||||
|
ve.msg( 'visualeditor-find-and-replace-results',
|
||||||
|
ve.init.platform.formatNumber( this.currentOffset + 1 ),
|
||||||
|
ve.init.platform.formatNumber( this.currentChecks.length )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
this.nextButton.setDisabled( this.currentOffset >= this.currentChecks.length - 1 );
|
||||||
|
this.previousButton.setDisabled( this.currentOffset <= 0 );
|
||||||
|
|
||||||
|
this.updateSize();
|
||||||
|
|
||||||
|
const surfaceView = this.surface.getView();
|
||||||
|
if ( this.currentChecks.length > 0 ) {
|
||||||
|
// The currently-focused check gets a selection:
|
||||||
|
// TODO: clicking the selection should activate the sidebar-action
|
||||||
|
surfaceView.getSelectionManager().drawSelections(
|
||||||
|
'editCheckWarning',
|
||||||
|
this.currentChecks[ this.currentOffset ].getHighlightSelections().map(
|
||||||
|
( selection ) => ve.ce.Selection.static.newFromModel( selection, surfaceView )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.scrollCurrentCheckIntoView();
|
||||||
|
} else {
|
||||||
|
surfaceView.getSelectionManager().drawSelections( 'editCheckWarning', [] );
|
||||||
|
}
|
||||||
|
|
||||||
|
this.drawHighlights();
|
||||||
|
};
|
||||||
|
|
||||||
|
ve.ui.EditCheckDialog.prototype.scrollCurrentCheckIntoView = function () {
|
||||||
|
const currentCheck = this.currentChecks[ this.currentOffset ];
|
||||||
|
if ( currentCheck ) {
|
||||||
|
// scrollSelectionIntoView scrolls to the focus of a selection, but we
|
||||||
|
// want the very beginning to be in view, so collapse it:
|
||||||
|
const selection = currentCheck.getHighlightSelections()[ 0 ].collapseToStart();
|
||||||
|
this.surface.scrollSelectionIntoView( selection, {
|
||||||
|
animate: true,
|
||||||
|
padding: {
|
||||||
|
top: ( OO.ui.isMobile() ? 80 : currentCheck.widget.$element[ 0 ].getBoundingClientRect().top ),
|
||||||
|
bottom: ( OO.ui.isMobile() ? this.getContentHeight() : 0 ) + 20
|
||||||
|
},
|
||||||
|
alignToTop: true
|
||||||
|
} );
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,8 +237,24 @@ ve.ui.EditCheckDialog.prototype.update = function () {
|
||||||
ve.ui.EditCheckDialog.prototype.getSetupProcess = function ( data ) {
|
ve.ui.EditCheckDialog.prototype.getSetupProcess = function ( data ) {
|
||||||
return ve.ui.EditCheckDialog.super.prototype.getSetupProcess.call( this, data )
|
return ve.ui.EditCheckDialog.super.prototype.getSetupProcess.call( this, data )
|
||||||
.first( () => {
|
.first( () => {
|
||||||
|
this.currentOffset = 0;
|
||||||
|
this.listener = data.listener || 'onDocumentChange';
|
||||||
|
this.reviewMode = data.reviewMode;
|
||||||
this.surface = data.surface;
|
this.surface = data.surface;
|
||||||
|
|
||||||
this.surface.getModel().on( 'undoStackChange', this.updateDebounced );
|
this.surface.getModel().on( 'undoStackChange', this.updateDebounced );
|
||||||
|
this.surface.getView().on( 'position', this.positionDebounced );
|
||||||
|
|
||||||
|
this.closeButton.toggle( OO.ui.isMobile() );
|
||||||
|
this.footer.toggle(
|
||||||
|
this.listener === 'onBeforeSave' &&
|
||||||
|
!mw.config.get( 'wgVisualEditorConfig' ).editCheckSingle
|
||||||
|
);
|
||||||
|
|
||||||
|
this.$element.toggleClass( 've-ui-editCheckDialog-singleAction', this.listener === 'onBeforeSave' );
|
||||||
|
|
||||||
|
this.surface.context.hide();
|
||||||
|
|
||||||
this.update();
|
this.update();
|
||||||
}, this );
|
}, this );
|
||||||
};
|
};
|
||||||
|
@ -86,6 +265,12 @@ ve.ui.EditCheckDialog.prototype.getSetupProcess = function ( data ) {
|
||||||
ve.ui.EditCheckDialog.prototype.getReadyProcess = function ( data ) {
|
ve.ui.EditCheckDialog.prototype.getReadyProcess = function ( data ) {
|
||||||
return ve.ui.EditCheckDialog.super.prototype.getReadyProcess.call( this, data )
|
return ve.ui.EditCheckDialog.super.prototype.getReadyProcess.call( this, data )
|
||||||
.next( () => {
|
.next( () => {
|
||||||
|
// The end of the ready process triggers a reflow after an
|
||||||
|
// animation, so we need to get past that to avoid the content
|
||||||
|
// being immediately scrolled away
|
||||||
|
setTimeout( () => {
|
||||||
|
this.scrollCurrentCheckIntoView();
|
||||||
|
}, 500 );
|
||||||
}, this );
|
}, this );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -95,17 +280,105 @@ ve.ui.EditCheckDialog.prototype.getReadyProcess = function ( data ) {
|
||||||
ve.ui.EditCheckDialog.prototype.getTeardownProcess = function ( data ) {
|
ve.ui.EditCheckDialog.prototype.getTeardownProcess = function ( data ) {
|
||||||
return ve.ui.EditCheckDialog.super.prototype.getTeardownProcess.call( this, data )
|
return ve.ui.EditCheckDialog.super.prototype.getTeardownProcess.call( this, data )
|
||||||
.next( () => {
|
.next( () => {
|
||||||
|
this.surface.getView().setReviewMode( false );
|
||||||
|
this.surface.getView().getSelectionManager().drawSelections( 'editCheckWarning', [] );
|
||||||
|
this.surface.getView().off( 'position', this.positionDebounced );
|
||||||
this.surface.getModel().off( 'undoStackChange', this.updateDebounced );
|
this.surface.getModel().off( 'undoStackChange', this.updateDebounced );
|
||||||
|
this.$highlights.remove().empty();
|
||||||
|
this.$checks.empty();
|
||||||
}, this );
|
}, this );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle 'act' events from the mw.widget.EditCheckActionWidget
|
||||||
|
*
|
||||||
|
* @param {mw.editcheck.EditCheckActionWidget} widget
|
||||||
|
* @param {Object} choice Choice object (with 'reason', 'object', 'label')
|
||||||
|
* @param {string} actionChosen Choice action
|
||||||
|
* @param {jQuery.Promise} promise Promise which resolves when the action is complete
|
||||||
|
*/
|
||||||
|
ve.ui.EditCheckDialog.prototype.onAct = function ( widget, choice, actionChosen, promise ) {
|
||||||
|
widget.setDisabled( true );
|
||||||
|
this.nextButton.setDisabled( true );
|
||||||
|
this.previousButton.setDisabled( true );
|
||||||
|
promise.then( ( data ) => {
|
||||||
|
widget.setDisabled( false );
|
||||||
|
this.nextButton.setDisabled( false );
|
||||||
|
this.previousButton.setDisabled( false );
|
||||||
|
this.surface.getModel().setNullSelection();
|
||||||
|
if ( OO.ui.isMobile() ) {
|
||||||
|
// Delay on mobile means we need to rehide this
|
||||||
|
setTimeout( () => this.surface.getModel().setNullSelection(), 300 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !data ) {
|
||||||
|
// Nothing happened, just fall back and leave the check
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( this.listener === 'onBeforeSave' ) {
|
||||||
|
// We must have been acting on the currentOffset
|
||||||
|
setTimeout( () => {
|
||||||
|
// We want to linger for a brief moment before moving away
|
||||||
|
this.currentChecks.splice( this.currentOffset, 1 );
|
||||||
|
this.currentOffset = Math.max( 0, this.currentOffset - 1 );
|
||||||
|
this.update();
|
||||||
|
}, 500 );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle 'togglecollapse' events from the mw.widget.EditCheckActionWidget
|
||||||
|
*
|
||||||
|
* @param {mw.editcheck.EditCheckAction} check
|
||||||
|
* @param {number} index
|
||||||
|
* @param {boolean} collapsed
|
||||||
|
*/
|
||||||
|
ve.ui.EditCheckDialog.prototype.onToggleCollapse = function ( check, index, collapsed ) {
|
||||||
|
if ( !collapsed ) {
|
||||||
|
// expanded one
|
||||||
|
this.setCurrentOffset( this.currentChecks.indexOf( check ) );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle click events from the close button
|
||||||
|
*/
|
||||||
|
ve.ui.EditCheckDialog.prototype.onCloseButtonClick = function () {
|
||||||
|
// eslint-disable-next-line no-jquery/no-class-state
|
||||||
|
const collapse = !this.$element.hasClass( 've-ui-editCheckDialog-collapsed' );
|
||||||
|
this.$element.toggleClass( 've-ui-editCheckDialog-collapsed', collapse );
|
||||||
|
this.closeButton.setIcon( collapse ? 'collapse' : 'expand' );
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle click events from the next button
|
||||||
|
*/
|
||||||
|
ve.ui.EditCheckDialog.prototype.onNextButtonClick = function () {
|
||||||
|
this.setCurrentOffset( this.currentOffset + 1 );
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle click events from the previous button
|
||||||
|
*/
|
||||||
|
ve.ui.EditCheckDialog.prototype.onPreviousButtonClick = function () {
|
||||||
|
this.setCurrentOffset( this.currentOffset - 1 );
|
||||||
|
};
|
||||||
|
|
||||||
/* Registration */
|
/* Registration */
|
||||||
|
|
||||||
ve.ui.windowFactory.register( ve.ui.EditCheckDialog );
|
ve.ui.windowFactory.register( ve.ui.EditCheckDialog );
|
||||||
|
|
||||||
ve.ui.commandRegistry.register(
|
ve.ui.commandRegistry.register(
|
||||||
new ve.ui.Command(
|
new ve.ui.Command(
|
||||||
'editCheckDialog', 'window', 'toggle', { args: [ 'editCheckDialog' ] }
|
'editCheckDialogInProcess', 'window', 'toggle', { args: [ 'editCheckDialog', { listener: 'onDocumentChange' } ] }
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
ve.ui.commandRegistry.register(
|
||||||
|
new ve.ui.Command(
|
||||||
|
'editCheckDialogBeforeSave', 'window', 'toggle', { args: [ 'editCheckDialog', { listener: 'onBeforeSave', reviewMode: true } ] }
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -125,7 +398,8 @@ ve.ui.EditCheckDialogTool.static.group = 'notices';
|
||||||
ve.ui.EditCheckDialogTool.static.icon = 'robot';
|
ve.ui.EditCheckDialogTool.static.icon = 'robot';
|
||||||
ve.ui.EditCheckDialogTool.static.title = 'Edit check'; // OO.ui.deferMsg( 'visualeditor-dialog-command-help-title' );
|
ve.ui.EditCheckDialogTool.static.title = 'Edit check'; // OO.ui.deferMsg( 'visualeditor-dialog-command-help-title' );
|
||||||
ve.ui.EditCheckDialogTool.static.autoAddToCatchall = false;
|
ve.ui.EditCheckDialogTool.static.autoAddToCatchall = false;
|
||||||
ve.ui.EditCheckDialogTool.static.commandName = 'editCheckDialog';
|
ve.ui.EditCheckDialogTool.static.commandName = 'editCheckDialogInProcess';
|
||||||
|
// ve.ui.EditCheckDialogTool.static.commandName = 'editCheckDialogBeforeSave';
|
||||||
|
|
||||||
// Demo button for opening edit check sidebar
|
// Demo button for opening edit check sidebar
|
||||||
// ve.ui.toolFactory.register( ve.ui.EditCheckDialogTool );
|
// ve.ui.toolFactory.register( ve.ui.EditCheckDialogTool );
|
||||||
|
|
|
@ -66,7 +66,7 @@ mw.editcheck.EditCheckFactory.prototype.getNamesByListener = function ( listener
|
||||||
* @return {mw.editcheck.EditCheckActions[]} Actions, sorted by range
|
* @return {mw.editcheck.EditCheckActions[]} Actions, sorted by range
|
||||||
*/
|
*/
|
||||||
mw.editcheck.EditCheckFactory.prototype.createAllByListener = function ( listener, surfaceModel ) {
|
mw.editcheck.EditCheckFactory.prototype.createAllByListener = function ( listener, surfaceModel ) {
|
||||||
const newChecks = [];
|
let newChecks = [];
|
||||||
this.getNamesByListener( listener ).forEach( ( checkName ) => {
|
this.getNamesByListener( listener ).forEach( ( checkName ) => {
|
||||||
const check = this.create( checkName, mw.editcheck.config[ checkName ] );
|
const check = this.create( checkName, mw.editcheck.config[ checkName ] );
|
||||||
if ( !check.canBeShown() ) {
|
if ( !check.canBeShown() ) {
|
||||||
|
@ -80,6 +80,10 @@ mw.editcheck.EditCheckFactory.prototype.createAllByListener = function ( listene
|
||||||
newChecks.sort(
|
newChecks.sort(
|
||||||
( a, b ) => a.getHighlightSelections()[ 0 ].getCoveringRange().start - b.getHighlightSelections()[ 0 ].getCoveringRange().start
|
( a, b ) => a.getHighlightSelections()[ 0 ].getCoveringRange().start - b.getHighlightSelections()[ 0 ].getCoveringRange().start
|
||||||
);
|
);
|
||||||
|
if ( mw.config.get( 'wgVisualEditorConfig' ).editCheckSingle && listener === 'onBeforeSave' ) {
|
||||||
|
newChecks = newChecks.filter( ( action ) => action.getName() === 'addReference' );
|
||||||
|
newChecks.splice( 1 );
|
||||||
|
}
|
||||||
return newChecks;
|
return newChecks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,6 @@ ve.ui.EditCheckInspector.prototype.getSetupProcess = function ( data ) {
|
||||||
return ve.ui.EditCheckInspector.super.prototype.getSetupProcess.call( this, data )
|
return ve.ui.EditCheckInspector.super.prototype.getSetupProcess.call( this, data )
|
||||||
.first( function () {
|
.first( function () {
|
||||||
this.surface = data.surface;
|
this.surface = data.surface;
|
||||||
this.saveProcessDeferred = data.saveProcessDeferred;
|
|
||||||
this.answerRadioSelect.selectItem( null );
|
this.answerRadioSelect.selectItem( null );
|
||||||
}, this );
|
}, this );
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,8 @@ OO.inheritClass( mw.editcheck.AddReferenceEditCheck, mw.editcheck.BaseEditCheck
|
||||||
|
|
||||||
mw.editcheck.AddReferenceEditCheck.static.name = 'addReference';
|
mw.editcheck.AddReferenceEditCheck.static.name = 'addReference';
|
||||||
|
|
||||||
|
mw.editcheck.AddReferenceEditCheck.static.title = ve.msg( 'editcheck-dialog-addref-title' );
|
||||||
|
|
||||||
mw.editcheck.AddReferenceEditCheck.static.description = ve.msg( 'editcheck-dialog-addref-description' );
|
mw.editcheck.AddReferenceEditCheck.static.description = ve.msg( 'editcheck-dialog-addref-description' );
|
||||||
|
|
||||||
mw.editcheck.AddReferenceEditCheck.static.defaultConfig = ve.extendObject( {}, mw.editcheck.BaseEditCheck.static.defaultConfig, {
|
mw.editcheck.AddReferenceEditCheck.static.defaultConfig = ve.extendObject( {}, mw.editcheck.BaseEditCheck.static.defaultConfig, {
|
||||||
|
@ -20,9 +22,11 @@ mw.editcheck.AddReferenceEditCheck.prototype.onBeforeSave = function ( surfaceMo
|
||||||
return new mw.editcheck.EditCheckAction( {
|
return new mw.editcheck.EditCheckAction( {
|
||||||
fragments: [ fragment ],
|
fragments: [ fragment ],
|
||||||
check: this
|
check: this
|
||||||
|
// icon: 'quotes',
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
};
|
};
|
||||||
|
mw.editcheck.AddReferenceEditCheck.prototype.onDocumentChange = mw.editcheck.AddReferenceEditCheck.prototype.onBeforeSave;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find content ranges which have been inserted
|
* Find content ranges which have been inserted
|
||||||
|
@ -53,9 +57,9 @@ mw.editcheck.AddReferenceEditCheck.prototype.findAddedContent = function ( docum
|
||||||
return ranges;
|
return ranges;
|
||||||
};
|
};
|
||||||
|
|
||||||
mw.editcheck.AddReferenceEditCheck.prototype.act = function ( choice, action, contextItem ) {
|
mw.editcheck.AddReferenceEditCheck.prototype.act = function ( choice, action, surface ) {
|
||||||
// The complex citoid workflow means that we can't just count on a single "windowAction" here...
|
// The complex citoid workflow means that we can't just count on a single "windowAction" here...
|
||||||
const windowAction = ve.ui.actionFactory.create( 'window', contextItem.context.getSurface(), 'check' );
|
const windowAction = ve.ui.actionFactory.create( 'window', surface, 'check' );
|
||||||
switch ( choice ) {
|
switch ( choice ) {
|
||||||
case 'accept':
|
case 'accept':
|
||||||
ve.track( 'activity.editCheckReferences', { action: 'edit-check-confirm' } );
|
ve.track( 'activity.editCheckReferences', { action: 'edit-check-confirm' } );
|
||||||
|
@ -67,7 +71,7 @@ mw.editcheck.AddReferenceEditCheck.prototype.act = function ( choice, action, co
|
||||||
if ( citoidData && citoidData.action === 'manual-choose' ) {
|
if ( citoidData && citoidData.action === 'manual-choose' ) {
|
||||||
// The plain reference dialog has been launched. Wait for the data from
|
// The plain reference dialog has been launched. Wait for the data from
|
||||||
// the basic Cite closing promise instead.
|
// the basic Cite closing promise instead.
|
||||||
contextItem.context.getSurface().getDialogs().once( 'closing', ( win, closed, citeData ) => {
|
surface.getDialogs().once( 'closing', ( win, closed, citeData ) => {
|
||||||
citoidOrCiteDataDeferred.resolve( citeData );
|
citoidOrCiteDataDeferred.resolve( citeData );
|
||||||
} );
|
} );
|
||||||
} else {
|
} else {
|
||||||
|
@ -75,18 +79,11 @@ mw.editcheck.AddReferenceEditCheck.prototype.act = function ( choice, action, co
|
||||||
// use the data form the Citoid closing promise.
|
// use the data form the Citoid closing promise.
|
||||||
citoidOrCiteDataDeferred.resolve( citoidData );
|
citoidOrCiteDataDeferred.resolve( citoidData );
|
||||||
}
|
}
|
||||||
citoidOrCiteDataDeferred.promise().then( ( data ) => {
|
return citoidOrCiteDataDeferred.promise().done( ( data ) => {
|
||||||
if ( !data ) {
|
if ( data ) {
|
||||||
// Reference was not inserted - re-open this context
|
|
||||||
setTimeout( () => {
|
|
||||||
// Deactivate again for mobile after teardown has modified selections
|
|
||||||
contextItem.context.getSurface().getView().deactivate();
|
|
||||||
contextItem.context.afterContextChange();
|
|
||||||
}, 500 );
|
|
||||||
} else {
|
|
||||||
// Edit check inspector is already closed by this point, but
|
// Edit check inspector is already closed by this point, but
|
||||||
// we need to end the workflow.
|
// we need to end the workflow.
|
||||||
contextItem.close( citoidData );
|
mw.notify( ve.msg( 'editcheck-dialog-addref-success-notify' ), { type: 'success' } );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
@ -95,20 +92,14 @@ mw.editcheck.AddReferenceEditCheck.prototype.act = function ( choice, action, co
|
||||||
return windowAction.open(
|
return windowAction.open(
|
||||||
'editCheckReferencesInspector',
|
'editCheckReferencesInspector',
|
||||||
{
|
{
|
||||||
fragment: action.fragments[ 0 ],
|
fragment: action.fragments[ 0 ]
|
||||||
callback: contextItem.data.callback,
|
|
||||||
saveProcessDeferred: contextItem.data.saveProcessDeferred
|
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line arrow-body-style
|
// eslint-disable-next-line arrow-body-style
|
||||||
).then( ( instance ) => {
|
).then( ( instance ) => {
|
||||||
// contextItem.openingCitoid = false;
|
|
||||||
return instance.closing;
|
return instance.closing;
|
||||||
} ).then( ( data ) => {
|
} ).done( ( data ) => {
|
||||||
if ( !data ) {
|
if ( data && data.action === 'reject' && data.reason ) {
|
||||||
// Form was closed, re-open this context
|
mw.editcheck.rejections.push( data.reason );
|
||||||
contextItem.context.afterContextChange();
|
|
||||||
} else {
|
|
||||||
contextItem.close( data );
|
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,13 @@ OO.inheritClass( mw.editcheck.TextMatchEditCheck, mw.editcheck.BaseEditCheck );
|
||||||
|
|
||||||
mw.editcheck.TextMatchEditCheck.static.name = 'textMatch';
|
mw.editcheck.TextMatchEditCheck.static.name = 'textMatch';
|
||||||
|
|
||||||
|
mw.editcheck.TextMatchEditCheck.static.choices = [];
|
||||||
|
|
||||||
mw.editcheck.TextMatchEditCheck.static.replacers = [
|
mw.editcheck.TextMatchEditCheck.static.replacers = [
|
||||||
// TODO: Load text replacement rules from community config
|
// TODO: Load text replacement rules from community config
|
||||||
{
|
{
|
||||||
query: 'unfortunately',
|
query: 'unfortunately',
|
||||||
|
title: 'Adverb usage',
|
||||||
message: new OO.ui.HtmlSnippet( 'Use of adverbs such as "unfortunately" should usually be avoided so as to maintain an impartial tone. <a href="#">Read more</a>.' )
|
message: new OO.ui.HtmlSnippet( 'Use of adverbs such as "unfortunately" should usually be avoided so as to maintain an impartial tone. <a href="#">Read more</a>.' )
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -23,6 +26,7 @@ mw.editcheck.TextMatchEditCheck.prototype.onDocumentChange = function ( surfaceM
|
||||||
actions.push(
|
actions.push(
|
||||||
new mw.editcheck.EditCheckAction( {
|
new mw.editcheck.EditCheckAction( {
|
||||||
fragments: [ fragment ],
|
fragments: [ fragment ],
|
||||||
|
title: replacer.title,
|
||||||
message: replacer.message,
|
message: replacer.message,
|
||||||
check: this
|
check: this
|
||||||
} )
|
} )
|
||||||
|
@ -32,4 +36,6 @@ mw.editcheck.TextMatchEditCheck.prototype.onDocumentChange = function ( surfaceM
|
||||||
return actions;
|
return actions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// mw.editcheck.TextMatchEditCheck.prototype.onBeforeSave = mw.editcheck.TextMatchEditCheck.prototype.onDocumentChange;
|
||||||
|
|
||||||
mw.editcheck.editCheckFactory.register( mw.editcheck.TextMatchEditCheck );
|
mw.editcheck.editCheckFactory.register( mw.editcheck.TextMatchEditCheck );
|
||||||
|
|
|
@ -83,8 +83,12 @@ if ( mw.config.get( 'wgVisualEditorConfig' ).editCheckTagging ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mw.config.get( 'wgVisualEditorConfig' ).editCheck || mw.editcheck.ecenable ) {
|
if ( mw.config.get( 'wgVisualEditorConfig' ).editCheck || mw.editcheck.ecenable ) {
|
||||||
let saveProcessDeferred;
|
mw.hook( 've.activationStart' ).add( () => {
|
||||||
|
document.documentElement.classList.add( 've-editcheck-available' );
|
||||||
|
} );
|
||||||
|
mw.hook( 've.deactivationComplete' ).add( () => {
|
||||||
|
document.documentElement.classList.remove( 've-editcheck-available' );
|
||||||
|
} );
|
||||||
mw.hook( 've.preSaveProcess' ).add( ( saveProcess, target ) => {
|
mw.hook( 've.preSaveProcess' ).add( ( saveProcess, target ) => {
|
||||||
const surface = target.getSurface();
|
const surface = target.getSurface();
|
||||||
|
|
||||||
|
@ -101,12 +105,11 @@ if ( mw.config.get( 'wgVisualEditorConfig' ).editCheck || mw.editcheck.ecenable
|
||||||
// clear rejection-reasons between runs of the save process, so only the last one counts
|
// clear rejection-reasons between runs of the save process, so only the last one counts
|
||||||
mw.editcheck.rejections.length = 0;
|
mw.editcheck.rejections.length = 0;
|
||||||
|
|
||||||
let checks = mw.editcheck.editCheckFactory.createAllByListener( 'onBeforeSave', surface.getModel() );
|
const checks = mw.editcheck.editCheckFactory.createAllByListener( 'onBeforeSave', surface.getModel() );
|
||||||
if ( checks.length ) {
|
if ( checks.length ) {
|
||||||
ve.track( 'counter.editcheck.preSaveChecksShown' );
|
ve.track( 'counter.editcheck.preSaveChecksShown' );
|
||||||
mw.editcheck.refCheckShown = true;
|
mw.editcheck.refCheckShown = true;
|
||||||
|
|
||||||
const surfaceView = surface.getView();
|
|
||||||
const toolbar = target.getToolbar();
|
const toolbar = target.getToolbar();
|
||||||
const reviewToolbar = new ve.ui.PositionedTargetToolbar( target, target.toolbarConfig );
|
const reviewToolbar = new ve.ui.PositionedTargetToolbar( target, target.toolbarConfig );
|
||||||
reviewToolbar.setup( [
|
reviewToolbar.setup( [
|
||||||
|
@ -142,118 +145,47 @@ if ( mw.config.get( 'wgVisualEditorConfig' ).editCheck || mw.editcheck.ecenable
|
||||||
target.toolbar.$element.before( reviewToolbar.$element );
|
target.toolbar.$element.before( reviewToolbar.$element );
|
||||||
target.toolbar = reviewToolbar;
|
target.toolbar = reviewToolbar;
|
||||||
|
|
||||||
saveProcessDeferred = ve.createDeferred();
|
let $contextContainer, contextPadding;
|
||||||
const context = surface.getContext();
|
if ( surface.context.popup ) {
|
||||||
|
contextPadding = surface.context.popup.containerPadding;
|
||||||
// TODO: Allow multiple checks to be shown when multicheck is enabled
|
$contextContainer = surface.context.popup.$container;
|
||||||
checks = checks.slice( 0, 1 );
|
surface.context.popup.$container = surface.$element;
|
||||||
|
surface.context.popup.containerPadding = 20;
|
||||||
// eslint-disable-next-line no-shadow
|
|
||||||
const drawSelections = ( checks ) => {
|
|
||||||
const highlightNodes = [];
|
|
||||||
const selections = [];
|
|
||||||
checks.forEach( ( check ) => {
|
|
||||||
check.getHighlightSelections().forEach( ( selection ) => {
|
|
||||||
highlightNodes.push.apply( highlightNodes, surfaceView.getDocument().selectNodes( selection.getCoveringRange(), 'branches' ).map( ( spec ) => spec.node ) );
|
|
||||||
const selectionView = ve.ce.Selection.static.newFromModel( selection, surfaceView );
|
|
||||||
selections.push( selectionView );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
// TODO: Make selections clickable when multicheck is enabled
|
|
||||||
surfaceView.getSelectionManager().drawSelections(
|
|
||||||
'editCheck',
|
|
||||||
selections
|
|
||||||
);
|
|
||||||
surfaceView.setReviewMode( true, highlightNodes );
|
|
||||||
};
|
|
||||||
|
|
||||||
const contextDone = ( responseData, contextData ) => {
|
|
||||||
if ( !responseData ) {
|
|
||||||
// this is the back button
|
|
||||||
return saveProcessDeferred.resolve();
|
|
||||||
}
|
}
|
||||||
const selectionIndex = checks.indexOf( contextData.action );
|
|
||||||
|
|
||||||
if ( responseData.action !== 'reject' ) {
|
|
||||||
mw.notify( ve.msg( 'editcheck-dialog-addref-success-notify' ), { type: 'success' } );
|
|
||||||
} else if ( responseData.reason ) {
|
|
||||||
mw.editcheck.rejections.push( responseData.reason );
|
|
||||||
}
|
|
||||||
// TODO: Move on to the next issue, when multicheck is enabled
|
|
||||||
// checks = mw.editcheck.editCheckFactory.createAllByListener( 'onBeforeSave', surface.getModel() );
|
|
||||||
checks = [];
|
|
||||||
|
|
||||||
if ( checks.length ) {
|
|
||||||
context.removePersistentSource( 'editCheckReferences' );
|
|
||||||
setTimeout( () => {
|
|
||||||
// timeout needed to wait out the newly added content being focused
|
|
||||||
surface.getModel().setNullSelection();
|
|
||||||
drawSelections( checks );
|
|
||||||
setTimeout( () => {
|
|
||||||
// timeout needed to allow the context to reposition
|
|
||||||
showCheckContext( checks[ Math.min( selectionIndex, checks.length - 1 ) ] );
|
|
||||||
} );
|
|
||||||
}, 500 );
|
|
||||||
} else {
|
|
||||||
saveProcessDeferred.resolve( true );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-inner-declarations
|
|
||||||
function showCheckContext( check ) {
|
|
||||||
const fragment = check.fragments[ 0 ];
|
|
||||||
|
|
||||||
// Select the found content to correctly position the context on desktop
|
|
||||||
fragment.select();
|
|
||||||
|
|
||||||
context.addPersistentSource( {
|
|
||||||
embeddable: false,
|
|
||||||
data: {
|
|
||||||
action: check,
|
|
||||||
fragment: fragment,
|
|
||||||
callback: contextDone,
|
|
||||||
saveProcessDeferred: saveProcessDeferred
|
|
||||||
},
|
|
||||||
name: 'editCheckReferences'
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Deactivate to prevent selection suppressing mobile context
|
|
||||||
surface.getView().deactivate();
|
|
||||||
|
|
||||||
// Once the context is positioned, clear the selection
|
|
||||||
setTimeout( () => {
|
|
||||||
surface.getModel().setNullSelection();
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
drawSelections( checks );
|
|
||||||
toolbar.toggle( false );
|
|
||||||
target.onContainerScroll();
|
|
||||||
|
|
||||||
saveProcess.next( () => {
|
saveProcess.next( () => {
|
||||||
showCheckContext( checks[ 0 ] );
|
toolbar.toggle( false );
|
||||||
|
target.onContainerScroll();
|
||||||
return saveProcessDeferred.promise().then( ( data ) => {
|
// surface.executeCommand( 'editCheckDialogBeforeSave' );
|
||||||
context.removePersistentSource( 'editCheckReferences' );
|
const windowAction = ve.ui.actionFactory.create( 'window', surface, 'check' );
|
||||||
|
return windowAction.open( 'editCheckDialog', { listener: 'onBeforeSave', reviewMode: true } )
|
||||||
surfaceView.getSelectionManager().drawSelections( 'editCheck', [] );
|
.then( ( instance ) => instance.closing )
|
||||||
surfaceView.setReviewMode( false );
|
.then( ( data ) => {
|
||||||
|
|
||||||
reviewToolbar.$element.remove();
|
reviewToolbar.$element.remove();
|
||||||
toolbar.toggle( true );
|
toolbar.toggle( true );
|
||||||
target.toolbar = toolbar;
|
target.toolbar = toolbar;
|
||||||
|
if ( $contextContainer ) {
|
||||||
|
surface.context.popup.$container = $contextContainer;
|
||||||
|
surface.context.popup.containerPadding = contextPadding;
|
||||||
|
}
|
||||||
|
// Creating a new PositionedTargetToolbar stole the
|
||||||
|
// toolbar windowmanagers, so we need to make the
|
||||||
|
// original toolbar reclaim them:
|
||||||
|
toolbar.disconnect( target );
|
||||||
|
target.setupToolbar( surface );
|
||||||
target.onContainerScroll();
|
target.onContainerScroll();
|
||||||
|
|
||||||
// Check the user inserted a citation
|
|
||||||
if ( data ) {
|
if ( data ) {
|
||||||
const delay = ve.createDeferred();
|
const delay = ve.createDeferred();
|
||||||
// If they inserted, wait 2 seconds on desktop before showing save dialog
|
// If they inserted, wait 2 seconds on desktop
|
||||||
|
// before showing save dialog to make sure insertions are finialized
|
||||||
setTimeout( () => {
|
setTimeout( () => {
|
||||||
ve.track( 'counter.editcheck.preSaveChecksCompleted' );
|
ve.track( 'counter.editcheck.preSaveChecksCompleted' );
|
||||||
delay.resolve();
|
delay.resolve();
|
||||||
}, !OO.ui.isMobile() && data.action !== 'reject' ? 2000 : 0 );
|
}, !OO.ui.isMobile() && data.action !== 'reject' ? 2000 : 0 );
|
||||||
return delay.promise();
|
return delay.promise();
|
||||||
} else {
|
} else {
|
||||||
|
// closed via "back" or otherwise
|
||||||
ve.track( 'counter.editcheck.preSaveChecksAbandoned' );
|
ve.track( 'counter.editcheck.preSaveChecksAbandoned' );
|
||||||
return ve.createDeferred().reject().promise();
|
return ve.createDeferred().reject().promise();
|
||||||
}
|
}
|
||||||
|
@ -265,11 +197,6 @@ if ( mw.config.get( 'wgVisualEditorConfig' ).editCheck || mw.editcheck.ecenable
|
||||||
ve.track( 'counter.editcheck.preSaveChecksNotShown' );
|
ve.track( 'counter.editcheck.preSaveChecksNotShown' );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
mw.hook( 've.deactivationComplete' ).add( () => {
|
|
||||||
if ( saveProcessDeferred ) {
|
|
||||||
saveProcessDeferred.reject();
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ve.ui.EditCheckBack = function VeUiEditCheckBack() {
|
ve.ui.EditCheckBack = function VeUiEditCheckBack() {
|
||||||
|
@ -286,12 +213,9 @@ ve.ui.EditCheckBack.static.autoAddToGroup = false;
|
||||||
ve.ui.EditCheckBack.static.title =
|
ve.ui.EditCheckBack.static.title =
|
||||||
OO.ui.deferMsg( 'visualeditor-backbutton-tooltip' );
|
OO.ui.deferMsg( 'visualeditor-backbutton-tooltip' );
|
||||||
ve.ui.EditCheckBack.prototype.onSelect = function () {
|
ve.ui.EditCheckBack.prototype.onSelect = function () {
|
||||||
const context = this.toolbar.getSurface().getContext();
|
const surface = this.toolbar.getSurface();
|
||||||
if ( context.inspector ) {
|
surface.getContext().hide();
|
||||||
context.inspector.close();
|
surface.execute( 'window', 'close', 'editCheckDialog' );
|
||||||
} else {
|
|
||||||
context.items[ 0 ].close();
|
|
||||||
}
|
|
||||||
this.setActive( false );
|
this.setActive( false );
|
||||||
};
|
};
|
||||||
ve.ui.EditCheckBack.prototype.onUpdateState = function () {
|
ve.ui.EditCheckBack.prototype.onUpdateState = function () {
|
||||||
|
|
|
@ -136,6 +136,10 @@
|
||||||
"value": false,
|
"value": false,
|
||||||
"description": "Enable experimental Edit Check feature. Can also be enabled using ?ecenable=1."
|
"description": "Enable experimental Edit Check feature. Can also be enabled using ?ecenable=1."
|
||||||
},
|
},
|
||||||
|
"VisualEditorEditCheckSingleCheckMode": {
|
||||||
|
"value": true,
|
||||||
|
"description": "Only allow a single edit check to be surfaced"
|
||||||
|
},
|
||||||
"VisualEditorEditCheckABTest": {
|
"VisualEditorEditCheckABTest": {
|
||||||
"value": false,
|
"value": false,
|
||||||
"description": "A/B test Edit Check for all users. A/B bucket status will override VisualEditorEditCheck."
|
"description": "A/B test Edit Check for all users. A/B bucket status will override VisualEditorEditCheck."
|
||||||
|
@ -647,7 +651,10 @@
|
||||||
"editcheck-dialog-addref-success-notify",
|
"editcheck-dialog-addref-success-notify",
|
||||||
"editcheck-dialog-addref-title",
|
"editcheck-dialog-addref-title",
|
||||||
"editcheck-dialog-title",
|
"editcheck-dialog-title",
|
||||||
"visualeditor-backbutton-tooltip"
|
"editcheck-review-title",
|
||||||
|
"visualeditor-backbutton-tooltip",
|
||||||
|
"next",
|
||||||
|
"last"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ext.visualEditor.core.utils": {
|
"ext.visualEditor.core.utils": {
|
||||||
|
|
|
@ -1159,6 +1159,7 @@ class Hooks implements
|
||||||
'useChangeTagging' => $veConfig->get( 'VisualEditorUseChangeTagging' ),
|
'useChangeTagging' => $veConfig->get( 'VisualEditorUseChangeTagging' ),
|
||||||
'editCheckTagging' => $veConfig->get( 'VisualEditorEditCheckTagging' ),
|
'editCheckTagging' => $veConfig->get( 'VisualEditorEditCheckTagging' ),
|
||||||
'editCheck' => $veConfig->get( 'VisualEditorEditCheck' ),
|
'editCheck' => $veConfig->get( 'VisualEditorEditCheck' ),
|
||||||
|
'editCheckSingle' => $veConfig->get( 'VisualEditorEditCheckSingleCheckMode' ),
|
||||||
'editCheckABTest' => $veConfig->get( 'VisualEditorEditCheckABTest' ),
|
'editCheckABTest' => $veConfig->get( 'VisualEditorEditCheckABTest' ),
|
||||||
'editCheckReliabilityAvailable' => ApiEditCheckReferenceUrl::isAvailable(),
|
'editCheckReliabilityAvailable' => ApiEditCheckReferenceUrl::isAvailable(),
|
||||||
'namespacesWithSubpages' => $namespacesWithSubpagesEnabled,
|
'namespacesWithSubpages' => $namespacesWithSubpagesEnabled,
|
||||||
|
|
Loading…
Reference in a new issue