Helpdesk da PluGzOne, baseado no osTicket
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

230 lines
7.0 KiB

!function( $ ){
"use strict";
var Translatable = function( element, options ) {
this.$element = $(element);
this.options = $.extend({}, $.fn.translatable.defaults, options);
if (!this.$element.data('translateTag'))
return;
this.shown = false;
this.populated = false;
this.fetch('ajax.php/i18n/langs').then($.proxy(function(json) {
this.langs = json;
if (Object.keys(this.langs).length) this.decorate();
}, this));
},
// Class-static variables
urlcache = {};
Translatable.prototype = {
constructor: Translatable,
fetch: function( url, data, callback ) {
if ( !urlcache[ url ] ) {
urlcache[ url ] = $.Deferred(function( defer ) {
$.ajax( url, { data: data, dataType: 'json', global: false } )
.then( defer.resolve, defer.reject );
}).promise();
}
return urlcache[ url ].done( callback );
},
decorate: function() {
this.$translations = $('<ul class="translations"></ul>');
this.$status = $('<li class="status"><i class="icon-spinner icon-spin"></i> '+__('Loading')+' ...</li>')
.appendTo(this.$translations);
this.$footer = $('<div class="add-translation"></div>');
this.$select = $('<select name="locale"></select>');
this.$menu = $(this.options.menu).appendTo('body');
this.$element.wrap('<div class="translatable"></div>');
this.$container = this.$element.parent();
if (this.$element.width() > 100)
this.$element.width(this.$element.width()-35);
this.$container.wrap('<div style="display:inline-block;position:relative;width:auto;white-space:nowrap;"></div>');
this.$button = $(this.options.button).appendTo(this.$container);
this.$menu.append($('<span class="close"><i class="icon-remove"></i></span>')
.on('click', $.proxy(this.hide, this)));
if (this.$element.is('textarea')) {
this.$container.addClass('textarea');
}
this.$menu.append(this.$translations).append(this.$footer);
this.$button.on('click', $.proxy(this.toggle, this));
this.$element
.addClass('translatable')
.focus($.proxy(function() { this.addClass('focus'); }, this.$container))
.blur($.proxy(function() { this.removeClass('focus'); }, this.$container));
getConfig().then($.proxy(function(c) {
this.attr({'spellcheck': 'true', 'lang': c.primary_language})
$('<span class="flag"></span>')
.addClass('flag-' + c.primary_lang_flag)
.insertAfter(this);
}, this.$element));
},
buildAdd: function() {
var self=this;
this.$footer
.append($('<form method="post"></form>')
.append(this.$select)
.append($('<button type="button"><i class="icon-plus-sign"></i> '+__('Add')+'</button>')
.on('click', $.proxy(this.define, this))
)
);
this.fetch('ajax.php/i18n/langs').then(function(langs) {
$.each(langs, function(k, v) {
self.$select.append($('<option>').val(k).text(v.name));
});
});
},
populate: function() {
var self=this;
if (this.populated)
return;
this.buildAdd();
this.fetch('ajax.php/i18n/translate/' + this.$element.data('translateTag'))
.then(function(json) {
$.each(json, function(k,v) {
self.add(k, v);
});
if (!Object.keys(json).length) {
self.$status.text(__('Not currently translated'));
}
else
self.$status.remove();
});
self.populated = true;
},
define: function(e) {
this.add($('option:selected', this.$select).val());
},
add: function(lang, text) {
var info = this.langs[lang];
this.$translations.append(
$('<li>')
.append($('<label class="language">')
.text(info.name)
.prepend($('<span>').addClass('flag flag-'+info.flag))
.append($('<input type="text" data-lang="'+lang+'">')
.attr('lang', lang)
.attr('spellcheck', 'true')
.attr('dir', info.direction || 'ltr')
.on('change keydown', $.proxy(this.showCommit, this))
.val(text)
)
)
.effect('highlight')
);
$('option[value='+lang+']', this.$select).remove();
if (!$('option', this.$select).length)
this.$footer.hide();
this.$status.remove();
},
showCommit: function(e) {
if (this.$commit) {
this.$commit.find('button').empty().text(' '+__('Save'))
.prepend($('<i>').addClass('fa icon-save'));
return !this.$commit.is(':visible')
? this.$commit.slideDown() : true;
}
return this.$commit = $('<div class="language-commit"></div>')
.hide()
.insertAfter(this.$translations)
.append($('<button type="button" class="white button commit"><i class="fa fa-save icon-save"></i> '+__('Save')+'</button>')
.on('click', $.proxy(this.commit, this))
)
.slideDown();
},
commit: function(e) {
var changes = {}, self = this;
$('input[type=text]', this.$translations).each(function() {
var trans = $(this).val();
if (!trans)
$(this).closest('li').slideUp();
changes[$(this).data('lang')] = trans;
});
this.$commit.prop('disabled', true);
this.$commit.find('button').empty().text(' '+__('Saving'))
.prepend($('<i>').addClass('fa icon-spin icon-spinner'));
$.ajax('ajax.php/i18n/translate/' + this.$element.data('translateTag'), {
type: 'post',
data: changes,
success: function() {
self.$commit.slideUp();
}
});
},
toggle: function(e) {
e.stopPropagation();
e.preventDefault();
if (this.shown)
this.hide();
else
this.show();
},
show: function() {
if (this.shown)
return this;
var pos = $.extend({}, this.$container.offset(), {
height: this.$container[0].offsetHeight
})
this.$menu.css({
top: pos.top + pos.height
, left: pos.left
});
this.populate();
this.$menu.show();
this.shown = true;
return this;
},
hide: function() {
if (this.shown) {
this.$menu.hide();
this.shown = false;
}
return this;
}
};
/* PLUGIN DEFINITION
* =========================== */
$.fn.translatable = function ( option ) {
return this.each(function () {
var $this = $(this),
data = $this.data('translatable'),
options = typeof option == 'object' && option;
if (!data) $this.data('translatable', (data = new Translatable(this, options)));
if (typeof option == 'string') data[option]();
});
};
$.fn.translatable.defaults = {
menu: '<div class="translations"></div>',
button: '<button type="button" class="translatable"><i class="fa fa-globe icon-globe"></i></button>'
};
$.fn.translatable.Constructor = Translatable;
}( window.jQuery );