File: /var/www/vhost/disk-apps/magento.bikenow.co/lib/web/mage/translate-inline-vde.js
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
/**
* @deprecated since version 2.2.0
*/
define([
'jquery',
'mage/template',
'jquery-ui-modules/widget',
'jquery-ui-modules/core',
'mage/translate-inline',
'mage/translate'
], function ($, mageTemplate) {
'use strict';
/**
* Widget for a dialog to edit translations.
*/
$.widget('mage.translateInlineDialogVde', $.mage.translateInline, {
options: {
translateForm: {
template: '#translate-inline-dialog-form-template',
data: {
selector: '#translate-inline-dialog-form'
}
},
dialogClass: 'translate-dialog',
draggable: false,
modal: false,
resizable: false,
height: 'auto',
minHeight: 0,
buttons: [{
text: $.mage.__('Cancel'),
'class': 'translate-dialog-cancel',
/**
* Click.
*/
click: function () {
$(this).translateInlineDialogVde('close');
}
},
{
text: $.mage.__('Save'),
'class': 'translate-dialog-save',
/**
* Click.
*/
click: function () {
$(this).translateInlineDialogVde('submit');
}
}],
area: 'vde',
ajaxUrl: null,
textTranslations: null,
imageTranslations: null,
scriptTranslations: null,
translateMode: null,
translateModes: ['text', 'script', 'alt']
},
/**
* Identifies if the form is already being submitted.
*
* @type {Boolean}
*/
isSubmitting: false,
/**
* Identifies if inline text is being editied. Only one element can be edited at a time.
*
* @type {Boolean}
*/
isBeingEdited: false,
/**
* Creates the translation dialog widget. Fulfills jQuery WidgetFactory _create hook.
*/
_create: function () {
this._super();
// Unbind previously bound events that may be present from previous loads of vde container.
if (parent && parent.jQuery) {
parent.jQuery('[data-frame="editor"]')
.off('modeChange')
.on('modeChange', $.proxy(this._checkTranslateEditing, this));
}
},
/**
* @param {jQuery.Event} e
* @param {Object} widget
* @param {Function} callback
*/
openWithWidget: function (e, widget, callback) {
if (widget && callback) {
this.callback = callback;
this.element.html(this._prepareContent($(widget.element).data('translate')));
this.triggerElement = widget.element;
$(window).on('resize.translateInlineDialogVde', $.proxy(this._positionNearTarget, this));
this._positionNearTarget();
}
this.open(arguments);
},
/**
* @private
*/
_positionNearTarget: function () {
this.option('position', {
of: this.triggerElement,
my: 'left top',
at: 'left-3 top-9'
});
this.option('width', $(this.triggerElement).width());
},
/**
* Close.
*/
close: function () {
this._super();
this._onCancel();
this.isBeingEdited = false;
$(window).off('resize.translateInlineVdeDialog');
},
/**
* Shows translate mode applicable css styles.
*/
toggleStyle: function (mode) {
// TODO: need to remove eventually
this._toggleOutline(mode);
this.options.textTranslations.translateInlineVde('toggleIcon', mode);
this.options.imageTranslations.translateInlineImageVde('toggleIcon', mode);
this.options.scriptTranslations.translateInlineScriptVde('toggleIcon', mode);
},
/**
* Determine if user has modified inline translation text, but has not saved it.
*/
_checkTranslateEditing: function (event, data) {
var url, dataDisable;
if (this.isBeingEdited) {
alert(data['alert_message']); //eslint-disable-line no-alert
data['is_being_edited'] = true;
} else {
// Disable inline translation.
url = parent.jQuery('[data-frame="editor"]').attr('src');
dataDisable = {
frameUrl: url.substring(0, url.indexOf('translation_mode')),
mode: this.options.translateMode
};
parent.jQuery('[vde-translate]').trigger('disableInlineTranslation', dataDisable);
// Inline translation text is not being edited. Continue on.
parent.jQuery('[data-frame="editor"]').trigger(data['next_action'], data);
}
},
/**
* @return {*}
* @private
*/
_prepareContent: function () {
var content = this._superApply(arguments);
this._on(content.find('textarea[data-translate-input-index]'), {
/**
* @param {jQuery.Event} e
*/
keydown: function (e) {
var keyCode = $.ui.keyCode;
switch (e.keyCode) {
case keyCode.ESCAPE:
e.preventDefault();
this.close();
break;
case keyCode.ENTER:
e.preventDefault();
this._formSubmit();
break;
default:
// keep track of the fact that translate text has been changed
this.isBeingEdited = true;
}
}
});
this._on(content.find(this.options.translateForm.data.selector), {
/**
* @param {jQuery.Event} e
* @return {Boolean}
*/
submit: function (e) {
e.preventDefault();
this._formSubmit();
return true;
}
});
return content;
},
/**
* Submits the form.
*/
_formSubmit: function () {
this._superApply(arguments);
this.isBeingEdited = false;
},
/**
* Callback for when the AJAX call in _formSubmit is completed.
*/
_formSubmitComplete: function () {
// TODO: need to replace with merged version
var self = this;
this.element.find('[data-translate-input-index]').each($.proxy(function (count, elem) {
var index = $(elem).data('translate-input-index'),
value = $(elem).val() || '';
self.callback(index, value);
self = null;
}, this));
$(window).off('resize.translateInlineVdeDialog');
this._onSubmitComplete();
this._superApply(arguments);
this.isSubmitting = false;
},
/**
* @param {*} mode
* @private
*/
_toggleOutline: function (mode) {
var that = this;
// TODO: need to remove eventually
if (mode == null) {
mode = this.options.translateMode;
} else {
this.options.translateMode = mode;
}
this.element.closest('[data-container="body"]').addClass('trnslate-inline-' + mode + '-area');
$.each(this.options.translateModes, function () {
if (this != mode) { //eslint-disable-line eqeqeq
that.element.closest('[data-container="body"]').removeClass('trnslate-inline-' + this + '-area');
}
});
},
/**
* @private
*/
_onCancel: function () {
// TODO: need to remove eventually
this._toggleOutline();
this.options.textTranslations.translateInlineVde('show');
this.options.imageTranslations.translateInlineImageVde('show');
this.options.scriptTranslations.translateInlineScriptVde('show');
},
/**
* @private
*/
_onSubmitComplete: function () {
// TODO: need to remove eventually
this._toggleOutline();
this.options.textTranslations.translateInlineVde('show');
this.options.imageTranslations.translateInlineImageVde('show');
this.options.scriptTranslations.translateInlineScriptVde('show');
}
});
/**
* Widget for an icon to be displayed indicating that text can be translated.
*/
$.widget('mage.translateInlineVde', {
options: {
iconTemplateSelector: '[data-template="translate-inline-icon"]',
img: null,
imgHover: null,
offsetLeft: -16,
dataAttrName: 'translate',
translateMode: null,
/**
* On click.
*/
onClick: function () {}
},
/**
* Elements to wrap instead of just inserting a child element. This is
* to work around some different behavior in Firefox vs. WebKit.
*
* @type {Array}
*/
elementsToWrap: ['button'],
/**
* Determines if the template is already appended to the element.
*
* @type {Boolean}
*/
isTemplateAttached: false,
iconTemplate: null,
iconWrapperTemplate: null,
elementWrapperTemplate: null,
/**
* Determines if the element is suppose to be wrapped or just attached.
*
* @type {Boolean}, null is unset, false/true is set
*/
isElementWrapped: null,
/**
* Creates the icon widget to indicate text that can be translated.
* Fulfills jQuery's WidgetFactory _create hook.
*/
_create: function () {
this.element.addClass('translate-edit-icon-container');
this._initTemplates();
this.show();
},
/**
* Shows the widget.
*/
show: function () {
this._attachIcon();
this.iconTemplate.removeClass('hidden');
if (this.element.data('translateMode') != this.options.translateMode) { //eslint-disable-line eqeqeq
this.iconTemplate.addClass('hidden');
}
this.element.on('dblclick', $.proxy(this._invokeAction, this));
this._disableElementClicks();
},
/**
* Show edit icon for given translate mode.
*/
toggleIcon: function (mode) {
if (mode == this.element.data('translateMode')) { //eslint-disable-line eqeqeq
this.iconTemplate.removeClass('hidden');
} else {
this.iconTemplate.addClass('hidden');
}
this.options.translateMode = mode;
},
/**
* Determines if the element should have an icon element wrapped around it or
* if an icon element should be added as a child element.
*/
_shouldWrap: function () {
var c;
if (this.isElementWrapped !== null) {
return this.isElementWrapped;
}
this.isElementWrapped = false;
for (c = 0; c < this.elementsToWrap.length; c++) {
if (this.element.is(this.elementsToWrap[c])) {
this.isElementWrapped = true;
break;
}
}
return this.isElementWrapped;
},
/**
* Attaches an icon to the widget's element.
*/
_attachIcon: function () {
if (this._shouldWrap()) {
if (!this.isTemplateAttached) {
this.iconWrapperTemplate = this.iconTemplate.wrap('<div/>').parent();
this.iconWrapperTemplate.addClass('translate-edit-icon-wrapper-text');
this.elementWrapperTemplate = this.element.wrap('<div/>').parent();
this.elementWrapperTemplate.addClass('translate-edit-icon-container');
this.iconTemplate.appendTo(this.iconWrapperTemplate);
this.iconWrapperTemplate.appendTo(this.elementWrapperTemplate);
}
} else {
this.iconTemplate.appendTo(this.element);
this.element.removeClass('invisible');
}
this.isTemplateAttached = true;
},
/**
* Disables the element click from actually performing a click.
*/
_disableElementClicks: function () {
this.element.find('a').off('click');
if (this.element.is('A')) {
this.element.on('click', function () {
return false;
});
}
},
/**
* Hides the widget.
*/
hide: function () {
this.element.off('dblclick');
this.iconTemplate.addClass('hidden');
},
/**
* Replaces the translated text inside the widget with the new value.
*/
replaceText: function (index, value) {
var translateData = this.element.data(this.options.dataAttrName),
innerHtmlStr = this.element.html();
if (value === null || value === '') {
value = ' ';
}
innerHtmlStr = innerHtmlStr.replace(translateData[index].shown, value);
this.element.html(innerHtmlStr);
translateData[index].shown = value;
translateData[index].translated = value;
this.element.data(this.options.dataAttrName, translateData);
},
/**
* Initializes all the templates for the widget.
*/
_initTemplates: function () {
this._initIconTemplate();
this.iconTemplate.addClass('translate-edit-icon-text');
},
/**
* Changes depending on hover action.
*/
_hoverIcon: function () {
if (this.options.imgHover) {
this.iconTemplate.prop('src', this.options.imgHover);
}
},
/**
* Changes depending on hover action.
*/
_unhoverIcon: function () {
if (this.options.imgHover) {
this.iconTemplate.prop('src', this.options.img);
}
},
/**
* Initializes the icon template for the widget. Sets the widget up to
* respond to events.
*/
_initIconTemplate: function () {
this.iconTemplate = $(mageTemplate(this.options.iconTemplateSelector, {
data: this.options
}));
this.iconTemplate.on('click', $.proxy(this._invokeAction, this))
.on('mouseover', $.proxy(this._hoverIcon, this))
.on('mouseout', $.proxy(this._unhoverIcon, this));
},
/**
* Invokes the action (e.g. activate the inline dialog)
*/
_invokeAction: function (event) {
this._detachIcon();
this.options.onClick(event, this);
},
/**
* Destroys the widget. Fulfills jQuery's WidgetFactory _destroy hook.
*/
_destroy: function () {
this.iconTemplate.remove();
this._detachIcon();
},
/**
* Detaches an icon from the widget's element.
*/
_detachIcon: function () {
this._unhoverIcon();
$(this.iconTemplate).detach();
if (this._shouldWrap()) {
this.iconWrapperTemplate.remove();
this.element.unwrap();
this.elementWrapperTemplate.remove();
} else {
this.element.addClass('invisible');
}
this.isTemplateAttached = false;
}
});
$.widget('mage.translateInlineImageVde', $.mage.translateInlineVde, {
/**
* @private
*/
_attachIcon: function () {
if (!this.isTemplateAttached) {
this.iconWrapperTemplate = this.iconTemplate.wrap('<div/>').parent();
this.iconWrapperTemplate.addClass('translate-edit-icon-wrapper-image');
this.elementWrapperTemplate = this.element.wrap('<div/>').parent();
this.elementWrapperTemplate.addClass('translate-edit-icon-container');
this.iconTemplate.appendTo(this.iconWrapperTemplate);
this.iconWrapperTemplate.appendTo(this.elementWrapperTemplate);
this.isTemplateAttached = true;
}
},
/**
* @private
*/
_initTemplates: function () {
this._initIconTemplate();
this.iconTemplate.addClass('translate-edit-icon-image');
},
/**
* @private
*/
_detachIcon: function () {
$(this.iconTemplate).detach();
this.iconWrapperTemplate.remove();
this.element.unwrap();
this.elementWrapperTemplate.remove();
this.isTemplateAttached = false;
}
});
$.widget('mage.translateInlineScriptVde', $.mage.translateInlineVde, {});
/*
* @TODO move the "escapeHTML" method into the file with global utility functions
*/
$.extend(true, $, {
mage: {
/**
* @param {String} str
* @return {String}
*/
escapeHTML: function (str) {
return str ? str.replace(/"/g, '"') : '';
}
}
});
});