jenkins-bot has submitted this change and it was merged. (
https://gerrit.wikimedia.org/r/371473 )
Change subject: Improve the New Translation dialog
......................................................................
Improve the New Translation dialog
Make New translation dialog show in-place, closable by click outside.
Make selection status clearly differentiable from the search one.
Bug: T111094
Change-Id: I222a29f56786a59f97e03d631b05c37cc9678b15
---
M modules/dashboard/ext.cx.dashboard.js
M modules/dashboard/styles/ext.cx.suggestionlist.less
M modules/source/ext.cx.source.selector.js
M modules/source/styles/ext.cx.source.selector.less
M modules/ui/widgets/mw.cx.ui.PageSelectorWidget.js
M modules/widgets/overlay/ext.cx.overlay.js
M modules/widgets/overlay/ext.cx.overlay.less
7 files changed, 526 insertions(+), 103 deletions(-)
Approvals:
jenkins-bot: Verified
Nikerabbit: Checked; Looks good to me, approved
diff --git a/modules/dashboard/ext.cx.dashboard.js
b/modules/dashboard/ext.cx.dashboard.js
index d3ee47d..817319b 100644
--- a/modules/dashboard/ext.cx.dashboard.js
+++ b/modules/dashboard/ext.cx.dashboard.js
@@ -26,6 +26,7 @@
this.$filter = null;
this.$listHeader = null;
this.$cta = null;
+ this.$sourceSelector = null;
}
CXDashboard.prototype.init = function () {
@@ -254,9 +255,12 @@
this.$filter
);
+ this.$sourceSelector = $( '<div>' )
+ .addClass( 'cx-sourceselector-embedded' );
+
return $( '<div>' )
.addClass( 'cx-translationlist-container' )
- .append( this.$listHeader );
+ .append( this.$listHeader, this.$sourceSelector );
};
CXDashboard.prototype.setActiveList = function ( type ) {
@@ -282,7 +286,8 @@
};
CXDashboard.prototype.listen = function () {
- var self = this;
+ var self = this,
+ onVisibleCallback;
this.$filter.click( '.cx-filter', function ( e ) {
var $filter = $( e.target );
@@ -307,6 +312,16 @@
}
} );
+ onVisibleCallback = function () {
+ if ( $( 'html' ).prop( 'dir' ) === 'rtl' ) {
+ this.left = this.$element.offset().left +
this.$element.parent().width() - this.$menu.width();
+ } else {
+ this.left = this.$element.offset().left;
+ }
+
+ this.$menu.css( this.position() );
+ };
+
$.each( this.lists, function ( name, list ) {
var setFilter = self.setFilter.bind( self );
@@ -314,10 +329,7 @@
onSelect: function ( language ) {
setFilter( 'sourceLanguage', language );
},
- onVisible: function () {
- this.left =
list.languageFilter.$sourceLanguageFilter.offset().left;
- this.$menu.css( 'left', this.left );
- },
+ onVisible: onVisibleCallback,
menuWidth: 'medium',
left:
list.languageFilter.$sourceLanguageFilter.offset().left,
quickList: function () {
@@ -330,10 +342,7 @@
onSelect: function ( language ) {
setFilter( 'targetLanguage', language );
},
- onVisible: function () {
- this.left =
list.languageFilter.$targetLanguageFilter.offset().left;
- this.$menu.css( 'left', this.left );
- },
+ onVisible: onVisibleCallback,
menuWidth: 'medium',
left:
list.languageFilter.$targetLanguageFilter.offset().left,
quickList: function () {
@@ -344,8 +353,14 @@
} );
this.initSourceSelector();
+ this.$newTranslationButton.on( 'click', function ( e ) {
+ self.$listHeader.hide();
+ e.stopPropagation();
+
+ $( window ).scrollTop( 0 );
+ } );
// Scroll handler
- $( window ).scroll( $.throttle( 250, $.proxy( this.scroll, this
) ) );
+ $( window ).scroll( $.throttle( 250, this.scroll.bind( this ) )
);
};
CXDashboard.prototype.setFilter = function ( type, value ) {
@@ -364,7 +379,7 @@
sourceSelectorOptions.sourceLanguage = query.from;
sourceSelectorOptions.targetLanguage = query.to;
sourceSelectorOptions.sourceTitle = query.page;
- sourceSelectorOptions.targetTitle = query.targettitle;
+ sourceSelectorOptions.container = this.$sourceSelector;
this.$newTranslationButton.cxSourceSelector(
sourceSelectorOptions );
if ( query.campaign ) {
diff --git a/modules/dashboard/styles/ext.cx.suggestionlist.less
b/modules/dashboard/styles/ext.cx.suggestionlist.less
index 08b295e..df6c68d 100644
--- a/modules/dashboard/styles/ext.cx.suggestionlist.less
+++ b/modules/dashboard/styles/ext.cx.suggestionlist.less
@@ -63,10 +63,9 @@
.cx-suggestionlist__refresh {
color: @colorProgressive;
- margin-bottom: 48px;
+ margin: -10px 0 48px 0;
border-width: 1px 0;
border-radius: 0 0 @borderRadius @borderRadius;
- margin-top: -10px;
padding: 20px;
font-weight: bold;
diff --git a/modules/source/ext.cx.source.selector.js
b/modules/source/ext.cx.source.selector.js
index 2dad54e..752800f 100644
--- a/modules/source/ext.cx.source.selector.js
+++ b/modules/source/ext.cx.source.selector.js
@@ -23,16 +23,30 @@
this.options = $.extend( {}, options );
this.siteMapper = siteMapper;
+ // Boolean property indicating if CXSourceSelector is used as
+ // modal dialog or embedded
+ this.embedded = !!options.container && options.container
instanceof jQuery;
+
this.sourceLanguages = [];
this.targetLanguages = [];
this.sourceLanguage = null;
this.targetLanguage = null;
- this.$dialog = null;
+ // this.$container is used for both types of CXSourceSelector -
embedded and modal dialog
+ // Embedded version - $container field gets DOM container
passed through options parameter
+ // Dialog version - $container fields gets created in
renderAsDialog method of this class
+ this.$container = this.embedded ? options.container : null;
+ this.$selectedItem = null;
+ this.$selectedItemImage = null;
+ this.$selectedItemInfo = null;
+ this.$languageFilter = null;
this.$sourceLanguage = null;
this.$targetLanguage = null;
+ this.$discardItem = null;
+ this.$sourceInputs = null;
this.$messageBar = null;
this.$targetTitleInput = null;
this.overlay = null;
+ this.$translateFromButton = null;
this.validator = new mw.cx.ContentTranslationValidator(
this.siteMapper );
this.init();
}
@@ -73,6 +87,19 @@
}
/**
+ * Calculate position for ULS, depending on directionality
+ */
+ function calculateUlsPosition() {
+ if ( $( 'html' ).prop( 'dir' ) === 'rtl' ) {
+ this.left = this.$element.offset().left +
this.$element.parent().width() - this.$menu.width();
+ } else {
+ this.left = this.$element.offset().left;
+ }
+
+ this.$menu.css( this.position() );
+ }
+
+ /**
* Initialize the plugin.
*/
CXSourceSelector.prototype.init = function () {
@@ -103,7 +130,8 @@
this.sourcePageSelector.setValue(
this.options.sourceTitle );
}
- if ( this.options.targetTitle ) {
+ // !this.embedded is extra check, second one may be sufficient
+ if ( !this.embedded && this.options.targetTitle ) {
this.$targetTitleInput.val( this.options.targetTitle );
}
@@ -212,7 +240,7 @@
.text( $.uls.data.getAutonym( this.sourceLanguage ) );
mw.storage.set( 'cxSourceLanguage', this.sourceLanguage );
this.sourcePageSelector.setLanguage( this.sourceLanguage );
- this.fillTargetLanguages();
+ this.fillTargetLanguages( this.targetLanguages );
};
/**
@@ -240,17 +268,21 @@
lang: this.targetLanguage,
dir: $.uls.data.getDir( this.targetLanguage )
};
- this.$targetTitleInput.prop( langProps );
+ if ( !this.embedded ) {
+ this.$targetTitleInput.prop( langProps );
+ }
this.$targetLanguage.prop( langProps )
.text( $.uls.data.getAutonym( this.targetLanguage ) );
+ this.sourcePageSelector.setTargetLanguage( language );
mw.storage.set( 'cxTargetLanguage', this.targetLanguage );
};
/**
* Fill the target language dropdown with target languages that have
* language tools compatible with the source language.
+ * @param {array} targetLanguages
*/
- CXSourceSelector.prototype.fillTargetLanguages = function () {
+ CXSourceSelector.prototype.fillTargetLanguages = function (
targetLanguages ) {
var targetLanguageCodes, sourceLanguage,
cxSourceSelector = this,
targetUlsClass = 'cx-sourceselector-uls-target';
@@ -262,7 +294,7 @@
// Don't let the target be the same as source
sourceLanguage = this.getSourceLanguage();
- targetLanguageCodes = $.grep( this.targetLanguages, function (
language ) {
+ targetLanguageCodes = $.grep( targetLanguages, function (
language ) {
return language !== sourceLanguage;
} );
@@ -277,15 +309,7 @@
onReady: function () {
this.$menu.addClass( targetUlsClass );
},
- onVisible: function () {
- if ( $( 'html' ).prop( 'dir' ) === 'rtl' ) {
- this.left = this.$element.offset().left
+ this.$element.parent().width() - this.$menu.width();
- } else {
- this.left = this.$element.offset().left;
- }
-
- this.$menu.css( this.position() );
- },
+ onVisible: calculateUlsPosition,
quickList: function () {
return mw.uls.getFrequentLanguageList().filter(
function ( n ) {
return targetLanguageCodes.indexOf( n )
!== -1;
@@ -299,8 +323,8 @@
*/
CXSourceSelector.prototype.listen = function () {
var self = this;
- // Open or close the dialog when clicking the link.
- // The dialog will be unitialized until the first click.
+ // Open or close the (embedded) dialog when clicking the link.
+ // The (embedded) dialog will be unitialized until the first
click.
this.$trigger.click( $.proxy( this.show, this ) );
this.sourcePageSelector.on( 'change', function () {
@@ -309,15 +333,19 @@
self.$messageBar.hide();
} );
- // Target title input (check)
- this.$targetTitleInput.on( 'input blur',
- $.debounce( 600, false, $.proxy( this.check, this ) )
- );
+ if ( !this.embedded ) {
+ // Target title input (check)
+ this.$targetTitleInput.on( 'input blur',
+ $.debounce( 600, false, $.proxy( this.check,
this ) )
+ );
+ } else {
+ this.$discardItem.click( this.discardSelectedItem.bind(
this ) );
+ }
// Keypress (start translation on enter key)
- this.$dialog.on(
+ this.$container.on(
'keypress',
- '.cx-sourceselector-dialog-title',
+ '.cx-sourceselector-page-title',
$.proxy( this.enterKeyHandler, this )
);
};
@@ -366,7 +394,7 @@
var sourceLanguage = this.getSourceLanguage(),
targetLanguage = this.getTargetLanguage(),
sourceTitle = this.sourcePageSelector.getQueryValue(),
- targetTitle = this.$targetTitleInput.val().trim(),
+ targetTitle = this.embedded ? '' :
this.$targetTitleInput.val().trim(),
selector = this;
this.$messageBar.hide();
@@ -518,7 +546,7 @@
* @param {mw.Message|text} message the message to show
*/
CXSourceSelector.prototype.showMessage = function ( message ) {
- var $messageText = $(
'.cx-sourceselector-dialog__messagebar-text' );
+ var $messageText = $( '.cx-sourceselector-messagebar-text' );
if ( message instanceof mw.Message ) {
$messageText.html( message.parse() );
@@ -536,17 +564,15 @@
* Show the CXSourceSelector.
*/
CXSourceSelector.prototype.show = function () {
- var $container = this.options.container;
-
- if ( $container && $container instanceof jQuery ) {
- this.showAsEmbedded( $container );
+ if ( this.embedded ) {
+ this.showAsEmbedded();
} else {
this.showAsDialog();
}
// If there is something in the source field, it is probably
auto-filled,
// so go immediately to the target to save time
- if ( this.options.sourceTitle ) {
+ if ( !this.embedded && this.options.sourceTitle ) {
this.$targetTitleInput.focus();
} else {
this.sourcePageSelector.focus();
@@ -565,17 +591,17 @@
if ( this.options.top ) {
top = this.options.top;
} else {
- top = ( $( window ).height() - this.$dialog.height() )
/ 2;
+ top = ( $( window ).height() - this.$container.height()
) / 2;
top = top + $( document ).scrollTop();
}
if ( this.options.left ) {
left = this.options.left;
} else {
- left = ( $( window ).width() - this.$dialog.width() ) /
2;
+ left = ( $( window ).width() - this.$container.width()
) / 2;
}
- this.$dialog.css( {
+ this.$container.css( {
top: top,
left: left
} );
@@ -585,18 +611,24 @@
}
this.overlay.show();
- this.$dialog.show();
+ this.$container.show();
};
/**
- * Embeds source selector dialog inside the element
- * specified by $container.
+ * Shows the embedded version of source selector dialog
*
* @param {jQuery} $container the container in which to embed the
selector
*/
- CXSourceSelector.prototype.showAsEmbedded = function ( $container ) {
- $container.append( this.$dialog );
- this.$dialog.show();
+ CXSourceSelector.prototype.showAsEmbedded = function () {
+ var overlayOptions = {};
+
+ if ( !this.overlay ) {
+ overlayOptions.closeOnClick =
this.closeOnClickOutside.bind( this );
+ this.overlay = new mw.cx.widgets.Overlay( 'body',
overlayOptions );
+ }
+
+ this.overlay.show();
+ this.$container.slideDown();
};
/**
@@ -609,17 +641,25 @@
this.$translateFromButton.prop( 'disabled', true );
this.$messageBar.hide();
- if ( !this.options.container ) {
- this.overlay.hide();
- this.$dialog.hide();
- }
+ // Only dialog version of CXSourceSelector has cancel button
+ this.overlay.hide();
+ this.hide();
+ };
+
+ /*
+ * Embedded version of CXSourceSelector supports closing by clicking
anywhere outside of element
+ */
+ CXSourceSelector.prototype.closeOnClickOutside = function () {
+ this.overlay.hide();
+ this.$container.toggle();
+ $( '.translation-filter' ).slideDown();
};
/**
* Hide the entry point dialog.
*/
CXSourceSelector.prototype.hide = function () {
- this.$dialog.hide();
+ this.$container.hide();
};
/**
@@ -634,7 +674,7 @@
sourceLanguage = this.getSourceLanguage();
targetLanguage = this.getTargetLanguage();
originalSourceTitle = this.sourcePageSelector.getQueryValue();
- targetTitle = this.$targetTitleInput.val().trim();
+ targetTitle = this.embedded ? '' :
this.$targetTitleInput.val().trim();
this.validator.isTitleExistInLanguage(
sourceLanguage,
@@ -699,21 +739,76 @@
this.setTargetLanguage( targetLanguage );
};
- /**
- * Render the CXSourceSelector dialog.
- */
+ CXSourceSelector.prototype.setSelectedItem = function ( item ) {
+ var itemImage;
+
+ this.sourcePageSelector.setValue( item.getData() );
+
+ this.$sourceInputs.hide(); // Hide input field
+ this.$selectedItem.show(); // Show selected item view
+
+ itemImage = item.$icon.css( 'background-image' );
+ if ( itemImage !== 'none' ) {
+ this.$selectedItemImage.css( {
+ 'background-color': 'transparent',
+ 'background-image': itemImage
+ } );
+ }
+
+ this.$selectedItemInfo.append(
+ $( '<a>' ).prop( {
+ href: item.$label.prop( 'href' ),
+ title: item.$label.prop( 'title' ),
+ target: '_blank',
+ text: item.$label.text()
+ } )
+ );
+ this.$container
+ .toggleClass( 'cx-sourceselector-embedded--selected' );
+
+ this.$languageFilter.insertBefore( this.$discardItem );
+ };
+
+ CXSourceSelector.prototype.discardSelectedItem = function () {
+ this.$sourceInputs.show(); // Show input field
+ this.$selectedItem.hide(); // Hide selected item view
+
+ this.sourcePageSelector.setValue( '' );
+ this.$messageBar.hide();
+
+ // Discard selected item image and info
+ this.$selectedItemInfo.empty();
+ this.$selectedItemImage.removeAttr( 'style' );
+
+ this.$container
+ .toggleClass( 'cx-sourceselector-embedded--selected' );
+
+ this.$sourceInputs.append( this.$languageFilter );
+ };
+
CXSourceSelector.prototype.render = function () {
+ if ( this.embedded ) {
+ this.renderAsEmbedded();
+ } else {
+ this.renderAsDialog();
+ }
+ };
+
+ /**
+ * Render the CXSourceSelector as dialog.
+ */
+ CXSourceSelector.prototype.renderAsDialog = function () {
var $heading,
$sourceLanguageLabel, $sourceLanguageLabelContainer,
$sourceLanguageContainer,
$targetLanguageLabel, $targetLanguageLabelContainer,
$targetLanguageContainer,
$targetTitleInputContainer,
- $sourceInputs, $targetInputs,
+ $targetInputs,
$messageText,
translateButtonLabel,
$actions, $license,
cxSourceSelector = this;
- this.$dialog = $( '<div>' )
+ this.$container = $( '<div>' )
.addClass( 'cx-sourceselector-dialog' )
.hide();
@@ -740,15 +835,7 @@
onReady: function () {
this.$menu.addClass(
'cx-sourceselector-uls-source' );
},
- onVisible: function () {
- if ( $( 'html' ).prop( 'dir' ) === 'rtl' ) {
- this.left = this.$element.offset().left
+ this.$element.parent().width() - this.$menu.width();
- } else {
- this.left = this.$element.offset().left;
- }
-
- this.$menu.css( this.position() );
- },
+ onVisible: calculateUlsPosition,
quickList: function () {
return mw.uls.getFrequentLanguageList().filter(
function ( n ) {
return
cxSourceSelector.sourceLanguages.indexOf( n ) !== -1;
@@ -775,12 +862,11 @@
.append( this.$targetLanguage );
this.sourcePageSelector = new mw.cx.ui.PageSelectorWidget( {
- classes: [ 'cx-sourceselector-dialog-title' ],
+ classes: [ 'cx-sourceselector-page-title' ],
language: this.getSourceLanguage(),
siteMapper: this.siteMapper,
value: this.options.sourceTitle,
validateTitle: true,
- icon: 'search',
placeholder: mw.msg(
'cx-sourceselector-dialog-source-title-placeholder' )
} );
@@ -791,10 +877,10 @@
} );
$targetTitleInputContainer = $( '<div>' )
- .addClass( 'cx-sourceselector-dialog-title' )
+ .addClass( 'cx-sourceselector-page-title' )
.append( this.$targetTitleInput );
- $sourceInputs = $( '<div>' )
+ this.$sourceInputs = $( '<div>' )
.addClass( 'cx-sourceselector-dialog__source-inputs' )
.append(
$sourceLanguageLabelContainer,
@@ -811,9 +897,9 @@
);
this.$messageBar = $( '<div>' )
- .addClass( 'cx-sourceselector-dialog__messagebar' );
+ .addClass( 'cx-sourceselector-messagebar' );
$messageText = $( '<span>' )
- .addClass( 'cx-sourceselector-dialog__messagebar-text'
);
+ .addClass( 'cx-sourceselector-messagebar-text' );
this.$messageBar
.append( $messageText )
.hide();
@@ -821,7 +907,7 @@
this.$cancelButton = $( '<button>' )
.addClass( 'mw-ui-button mw-ui-quiet
cx-sourceselector-dialog__button-cancel' )
.text( mw.msg( 'cx-sourceselector-dialog-button-cancel'
) )
- .click( $.proxy( this.cancel, this ) );
+ .click( this.cancel.bind( this ) );
translateButtonLabel = mw.msg(
'cx-sourceselector-dialog-button-start-translation' );
this.$translateFromButton = $( '<button>' )
@@ -831,7 +917,7 @@
.click( $.proxy( this.startPageInCX, this ) );
$license = $( '<div>' )
- .addClass( 'cx-sourceselector-dialog__license' )
+ .addClass( 'cx-sourceselector__license' )
.html( mw.message( 'cx-license-agreement',
translateButtonLabel ).parse() );
$actions = $( '<div>' )
@@ -839,15 +925,130 @@
$actions.append( this.$cancelButton, this.$translateFromButton
);
- this.$dialog.append( $heading,
- $sourceInputs,
+ this.$container.append( $heading,
+ this.$sourceInputs,
$targetInputs,
this.$messageBar,
$license,
$actions
);
- $( 'body' ).append( this.$dialog );
+ $( 'body' ).append( this.$container );
+ };
+
+ CXSourceSelector.prototype.renderAsEmbedded = function () {
+ var $sourceLanguageContainer,
+ $targetLanguageContainer,
+ $messageText,
+ translateButtonLabel,
+ $actions, $license,
+ cxSourceSelector = this;
+
+ this.$container.hide(); // Starts as hidden, shown on button
click
+
+ this.$selectedItem = $( '<div>' )
+ .addClass( 'cx-sourceselector-embedded-selected-item' )
+ .hide();
+
+ this.$sourceLanguage = $( '<div>' )
+ .addClass(
'cx-sourceselector-embedded__language-button' );
+
+ this.$sourceLanguage.uls( {
+ languages: getAutonyms( this.sourceLanguages ),
+ menuWidth: getUlsMenuWidth( this.sourceLanguages.length
),
+ onSelect: function ( language ) {
+ cxSourceSelector.sourceLanguageChangeHandler(
language );
+ mw.uls.addPreviousLanguage( language );
+ },
+ onReady: function () {
+ this.$menu.addClass(
'cx-sourceselector-uls-source' );
+ },
+ onVisible: calculateUlsPosition,
+ quickList: function () {
+ return mw.uls.getFrequentLanguageList().filter(
function ( n ) {
+ return
cxSourceSelector.sourceLanguages.indexOf( n ) !== -1;
+ } );
+ }
+ } );
+
+ $sourceLanguageContainer = $( '<div>' )
+ .addClass(
'cx-sourceselector-embedded__source-language' )
+ .append( this.$sourceLanguage );
+
+ this.$targetLanguage = $( '<div>' )
+ .addClass(
'cx-sourceselector-embedded__language-button' );
+
+ $targetLanguageContainer = $( '<div>' )
+ .addClass(
'cx-sourceselector-embedded__target-language' )
+ .append( this.$targetLanguage );
+
+ this.$languageFilter = $( '<div>' )
+ .addClass(
'cx-sourceselector-embedded__language-filter' )
+ .append(
+ $sourceLanguageContainer,
+ $( '<div>' ).addClass(
'translation-language-arrow' ),
+ $targetLanguageContainer
+ );
+ this.sourcePageSelector = new mw.cx.ui.PageSelectorWidget( {
+ classes: [ 'cx-sourceselector-page-title' ],
+ language: this.getSourceLanguage(),
+ siteMapper: this.siteMapper,
+ value: this.options.sourceTitle,
+ validateTitle: true,
+ placeholder: mw.msg(
'cx-sourceselector-dialog-source-title-placeholder' )
+ } );
+ this.sourcePageSelector.onLookupMenuItemChoose =
this.setSelectedItem.bind( this );
+
+ this.$sourceInputs = $( '<div>' )
+ .addClass( 'cx-sourceselector-embedded__source-inputs' )
+ .append(
+ this.sourcePageSelector.$element,
+ this.$languageFilter
+ );
+ this.$selectedItemImage = $( '<div>' )
+ .addClass(
'cx-sourceselector-embedded-selected-item__image' );
+
+ this.$selectedItemInfo = $( '<div>' )
+ .addClass(
'cx-sourceselector-embedded-selected-item__info' );
+
+ this.$discardItem = $( '<div>' )
+ .addClass( 'cx-sourceselector-embedded-discard' );
+
+ this.$selectedItem.append(
+ this.$selectedItemImage,
+ this.$selectedItemInfo,
+ this.$discardItem
+ );
+
+ this.$messageBar = $( '<div>' )
+ .addClass( 'cx-sourceselector-messagebar' );
+ $messageText = $( '<span>' )
+ .addClass( 'cx-sourceselector-messagebar-text' );
+ this.$messageBar
+ .append( $messageText )
+ .hide();
+
+ translateButtonLabel = mw.msg(
'cx-sourceselector-dialog-button-start-translation' );
+ this.$translateFromButton = $( '<button>' )
+ .addClass( 'mw-ui-button mw-ui-progressive
cx-sourceselector-dialog__button-translate' )
+ .text( translateButtonLabel )
+ .prop( 'disabled', true )
+ .click( this.startPageInCX.bind( this ) );
+
+ $license = $( '<div>' )
+ .addClass( 'cx-sourceselector__license' )
+ .html( mw.message( 'cx-license-agreement',
translateButtonLabel ).parse() );
+
+ $actions = $( '<div>' )
+ .addClass( 'cx-sourceselector-embedded__actions' )
+ .append( this.$translateFromButton );
+
+ this.$container.append( this.$sourceInputs,
+ this.$selectedItem,
+ this.$messageBar,
+ $license,
+ $actions
+ );
};
mw.cx.CXSourceSelector = CXSourceSelector;
diff --git a/modules/source/styles/ext.cx.source.selector.less
b/modules/source/styles/ext.cx.source.selector.less
index 468035f..cbef4c5 100644
--- a/modules/source/styles/ext.cx.source.selector.less
+++ b/modules/source/styles/ext.cx.source.selector.less
@@ -4,31 +4,226 @@
.cx-sourceselector-dialog {
.mw-ui-item;
+ background-color: #fff;
color: @gray-darker;
position: absolute;
+ z-index: 400; // 300 is the z-index of overlay
min-width: 650px;
max-width: 700px;
- background: #fff;
border: 1px solid #ddd;
border-bottom-width: 3px;
border-radius: @borderRadius;
padding: 0;
box-shadow: 0 5px 10px rgba( 0, 0, 0, 0.2 );
- z-index: 1001;
+
+ .cx-sourceselector-dialog__heading {
+ @vertical-margin: 10px;
+ @horizontal-margin: 15px;
+
+ .mw-ui-item;
+ .mw-ui-one-whole;
+
+ padding: @vertical-margin @horizontal-margin;
+ font-size: 1.6em;
+ line-height: 1.5em;
+ border-bottom: 1px solid #eee;
+ font-weight: normal;
+ }
}
-.cx-sourceselector-dialog__heading {
- @vertical-margin: 10px;
- @horizontal-margin: 15px;
-
+.cx-sourceselector-embedded {
.mw-ui-item;
- .mw-ui-one-whole;
- padding: @vertical-margin @horizontal-margin;
- font-size: 1.6em;
- line-height: 1.5em;
- border-bottom: 1px solid #eee;
- font-weight: normal;
+ background-color: @white;
+ color: @gray-darker;
+ position: relative;
+ z-index: 400; // 300 is the z-index of overlay
+ margin-bottom: 2em;
+ border-radius: @borderRadius;
+ padding: 0;
+
+ &.cx-sourceselector-embedded--selected {
+ .cx-sourceselector-embedded__target-language,
+ .translation-language-arrow,
+ .cx-sourceselector-embedded-discard,
+ .cx-sourceselector-embedded__actions {
+ display: block;
+ }
+ }
+
+ .cx-sourceselector-embedded-selected-item {
+ @item-height: 6.25em;
+ @image-size: 5.25em;
+
+ .mw-ui-one-whole;
+ .flex-display( box );
+ .flex-display;
+ -ms-flex-align: center; // Support IE10
+ -webkit-box-align: center; // Support 2011 syntax
+ -webkit-align-items: center; // Vendor specific
+ align-items: center; // Modern syntax
+ min-height: @item-height;
+
+ &__image {
+ background-color: @colorGray15;
+
.background-image-svg('../../dashboard/images/page_lightgray.svg',
'../../dashboard/images/page_lightgray.png');
+ background-repeat: no-repeat;
+ background-size: @image-size;
+ background-position: center center;
+ display: block;
+ height: @image-size;
+ width: @image-size;
+ border: 0;
+ margin: 0.5em;
+ }
+
+ &__info {
+ color: @colorGray1;
+
+ .flex-display( box );
+ .flex-display;
+ flex-direction: column;
+ // Support 2009/2012 syntax that does not support
space-around
+ -webkit-box-pack: justify; // iOS 6-, Safari 3.1-6
+ -moz-box-pack: justify; // Firefox 21-
+ -ms-flex-pack: distribute; // Support IE10
+ justify-content: space-around;
+
+ max-width: 60%;
+ min-height: @item-height;
+ padding-left: 0.7em;
+
+ font-size: 1.2em;
+ font-weight: bold;
+
+ // Needs to be overridden for specificity
+ > a {
+ color: @colorGray1;
+ }
+ }
+
+ .cx-sourceselector-embedded-discard {
+ .background-image-svg('../../tools/images/clear.svg',
'../../tools/images/clear.png');
+ background-position: center center;
+ background-repeat: no-repeat;
+ background-size: 16px;
+ opacity: 0.8;
+
+ float: right;
+ width: 30px;
+ height: 30px;
+ padding: 0 8px;
+ cursor: pointer;
+
+ &:hover {
+ opacity: 1;
+ }
+ }
+ }
+
+ .cx-sourceselector-embedded__source-inputs {
+ .flex-display( box );
+ .flex-display;
+
+ height: 40px;
+ border-bottom: 1px solid #eee;
+ padding: 10px;
+ }
+
+ .cx-sourceselector-embedded__actions {
+ display: none;
+ }
+
+ .cx-sourceselector-embedded__language-filter {
+ background: @colorGray15;
+ width: auto;
+ max-width: 25%;
+ border: 1px solid #9d9d9d;
+ border-radius: @borderRadius;
+ padding: 0;
+ font-weight: bold;
+
+ .flex-display( box ); // Support 2009 syntax
+ .flex-display();
+ margin-left: auto;
+
+ .cx-sourceselector-embedded__source-language,
+ .cx-sourceselector-embedded__target-language {
+ float: left;
+ position: relative;
+ box-sizing: border-box;
+ font-size: 18px;
+ cursor: pointer;
+
+ -webkit-box-flex: 1; // iOS 6-, Safari 3.1-6
+ -moz-box-flex: 1; // Firefox 21-
+ width: auto; // Fallback for flex-basis
+ -ms-flex: 0 1 auto; // IE 10
+ -webkit-flex: 0 1 auto; // Safari 6.2 - 8
+ flex: 0 1 auto;
+ overflow: hidden;
+ }
+
+ .cx-sourceselector-embedded__language-button {
+ max-height: 34px;
+ padding: 8px;
+ line-height: 1;
+
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+ }
+
+ .cx-sourceselector-embedded__source-language {
+ padding-right: 8px;
+ margin-right: -8px;
+ }
+
+ .cx-sourceselector-embedded__target-language {
+ display: none;
+
+ padding-left: 8px;
+ margin-left: -8px;
+ }
+
+ .translation-language-arrow {
+ display: none;
+
+ float: left;
+ position: relative;
+ width: 0;
+ height: 34px;
+ margin-right: 16px;
+ }
+
+ .translation-language-arrow:after,
+ .translation-language-arrow:before {
+ content: ' ';
+ position: absolute;
+ top: 50%;
+ left: 100%;
+ width: 0;
+ height: 0;
+ border: solid transparent;
+ pointer-events: none;
+ }
+
+ .translation-language-arrow:after {
+ margin-top: -17px;
+ border-color: rgba( 255, 255, 255, 0 );
+ border-left-color: @colorGray15;
+ border-width: 17px;
+ border-left-width: 12px;
+ }
+
+ .translation-language-arrow:before {
+ margin-top: -18px;
+ border-color: rgba( 157, 157, 157, 0 );
+ border-left-color: #9d9d9d;
+ border-width: 18px;
+ border-left-width: 13px;
+ }
}
.cx-sourceselector-uls-target,
@@ -54,14 +249,14 @@
font-size: large;
}
-.cx-sourceselector-dialog__messagebar {
- .mw-ui-item;
+.cx-sourceselector-messagebar {
.mw-ui-one-whole;
padding: 10px;
background-color: #f7d358;
}
-.cx-sourceselector-dialog__actions {
+.cx-sourceselector-dialog__actions,
+.cx-sourceselector-embedded__actions {
.mw-ui-one-whole;
padding: 10px 15px 15px 15px;
text-align: right;
@@ -72,8 +267,7 @@
}
}
-.cx-sourceselector-dialog__license {
- .mw-ui-item;
+.cx-sourceselector__license {
.mw-ui-one-whole;
padding: 10px;
@@ -114,7 +308,7 @@
}
}
-.cx-sourceselector-dialog-title {
+.cx-sourceselector-page-title {
.mw-ui-item;
.mw-ui-seven-twelfths;
diff --git a/modules/ui/widgets/mw.cx.ui.PageSelectorWidget.js
b/modules/ui/widgets/mw.cx.ui.PageSelectorWidget.js
index 73d6033..6a7390c 100644
--- a/modules/ui/widgets/mw.cx.ui.PageSelectorWidget.js
+++ b/modules/ui/widgets/mw.cx.ui.PageSelectorWidget.js
@@ -55,6 +55,10 @@
this.requestCache = {};
};
+mw.cx.ui.PageSelectorWidget.prototype.setTargetLanguage = function ( language
) {
+ this.targetLanguage = language;
+};
+
/**
* @inheritdoc
*/
diff --git a/modules/widgets/overlay/ext.cx.overlay.js
b/modules/widgets/overlay/ext.cx.overlay.js
index 6376146..ee852d4 100644
--- a/modules/widgets/overlay/ext.cx.overlay.js
+++ b/modules/widgets/overlay/ext.cx.overlay.js
@@ -32,10 +32,16 @@
if ( this.options.showLoading ) {
this.$overlay.append( mw.cx.widgets.spinner() );
}
+
+ if ( this.options.closeOnClick ) {
+ this.$overlay
+ .addClass( 'cx-overlay--clickable' )
+ .click( this.options.closeOnClick );
+ }
+
this.$container
.css( 'position', 'relative' )
.append( this.$overlay );
- this.show();
};
CXOverlay.prototype.show = function () {
diff --git a/modules/widgets/overlay/ext.cx.overlay.less
b/modules/widgets/overlay/ext.cx.overlay.less
index a90628b..ed3be14 100644
--- a/modules/widgets/overlay/ext.cx.overlay.less
+++ b/modules/widgets/overlay/ext.cx.overlay.less
@@ -7,6 +7,10 @@
width: 100%;
height: 100%;
opacity: 0.5;
+
+ &--clickable {
+ background-color: transparent;
+ }
}
body.cx-noscroll {
--
To view, visit https://gerrit.wikimedia.org/r/371473
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I222a29f56786a59f97e03d631b05c37cc9678b15
Gerrit-PatchSet: 9
Gerrit-Project: mediawiki/extensions/ContentTranslation
Gerrit-Branch: master
Gerrit-Owner: Petar.petkovic <[email protected]>
Gerrit-Reviewer: Nikerabbit <[email protected]>
Gerrit-Reviewer: Petar.petkovic <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits