/*
* An input preset converter.
*
* The API allows to convert text entered into an element to a URL, slug or file name
* value in another input element.
*
* Supported data attributes:
* - data-input-preset: specifies a CSS selector for a source input element
* - data-input-preset-closest-parent: optional, specifies a CSS selector for a closest common parent
* for the source and destination input elements.
* - data-input-preset-type: specifies the conversion type. Supported values are:
* url, file, slug, camel.
* - data-input-preset-prefix-input: optional, prefixes the converted value with the value found
* in the supplied input element using a CSS selector.
* - data-input-preset-remove-words: optional, use removeList to filter stop words of source string.
*
* Example: <input type="text" id="name" value=""/>
* <input type="text"
* data-input-preset="#name"
* data-input-preset-type="file">
*
* JavaScript API:
* $('#filename').inputPreset({inputPreset: '#name', inputPresetType: 'file'})
*/
+function ($) { "use strict";
var VIETNAMESE_MAP = {
'Á': 'A', 'À': 'A', 'Ã': 'A', '?': 'A', '?': 'A', '?': 'A', '?': 'A', '?':
'A', '?': 'A', '?': 'A', '?': 'A', '?': 'A', '?': 'A', '?': 'A', '?': 'A',
'?': 'D', 'É': 'E', 'È': 'E', '?': 'E', '?': 'E', '?': 'E', '?': 'E', '?':
'E', '?': 'E', '?': 'E', '?': 'E', 'Ó': 'O', 'Ò': 'O', '?': 'O', 'Õ': 'O',
'?': 'O', '?': 'O', '?': 'O', '?': 'O', '?': 'O', '?': 'O', '?': 'O', '?':
'O', '?': 'O', '?': 'O', '?': 'O', '?': 'O', 'Í': 'I', 'Ì': 'I', '?': 'I',
'?': 'I', '?': 'I', 'Ú': 'U', 'Ù': 'U', '?': 'U', '?': 'U', '?': 'U', '?':
'U', '?': 'U', '?': 'U', '?': 'U', '?': 'U', '?': 'U', 'Ý': 'Y', '?': 'Y',
'?': 'Y', '?': 'Y', '?': 'Y', 'á': 'a', 'à': 'a', 'ã': 'a', '?': 'a', '?':
'a', '?': 'a', '?': 'a', '?': 'a', '?': 'a', '?': 'a', '?': 'a', '?': 'a',
'?': 'a', '?': 'a', '?': 'a', '?': 'd', 'é': 'e', 'è': 'e', '?': 'e', '?':
'e', '?': 'e', '?': 'e', '?': 'e', '?': 'e', '?': 'e', '?': 'e', 'ó': 'o',
'ò': 'o', '?': 'o', 'õ': 'o', '?': 'o', '?': 'o', '?': 'o', '?': 'o', '?':
'o', '?': 'o', '?': 'o', '?': 'o', '?': 'o', '?': 'o', '?': 'o', '?': 'o',
'í': 'i', 'ì': 'i', '?': 'i', '?': 'i', '?': 'i', 'ú': 'u', 'ù': 'u', '?':
'u', '?': 'u', '?': 'u', '?': 'u', '?': 'u', '?': 'u', '?': 'u', '?': 'u',
'?': 'u', 'ý': 'y', '?': 'y', '?': 'y', '?': 'y', '?': 'y'
},
LATIN_MAP = {
'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç':
'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I',
'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö':
'O', '?': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', '?': 'U',
'Ý': 'Y', 'Þ': 'TH', '?': 'Y', 'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã':
'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e', 'é': 'e', 'ê': 'e',
'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò':
'o', 'ó': 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', '?': 'o', 'ø': 'o', '?': 'o',
'?': 'oe', 'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u', '?': 'u', 'ý': 'y', 'þ':
'th', 'ÿ': 'y'
},
LATIN_SYMBOLS_MAP = {
'©':'(c)'
},
GREEK_MAP = {
'?':'a', '?':'b', '?':'g', '?':'d', '?':'e', '?':'z', '?':'h', '?':'8',
'?':'i', '?':'k', '?':'l', '?':'m', '?':'n', '?':'3', '?':'o', '?':'p',
'?':'r', '?':'s', '?':'t', '?':'y', '?':'f', '?':'x', '?':'ps', '?':'w',
'?':'a', '?':'e', '?':'i', '?':'o', '?':'y', '?':'h', '?':'w', '?':'s',
'?':'i', '?':'y', '?':'y', '?':'i',
'?':'A', '?':'B', '?':'G', '?':'D', '?':'E', '?':'Z', '?':'H', '?':'8',
'?':'I', '?':'K', '?':'L', '?':'M', '?':'N', '?':'3', '?':'O', '?':'P',
'?':'R', '?':'S', '?':'T', '?':'Y', '?':'F', '?':'X', '?':'PS', '?':'W',
'?':'A', '?':'E', '?':'I', '?':'O', '?':'Y', '?':'H', '?':'W', '?':'I',
'?':'Y'
},
TURKISH_MAP = {
'?':'s', '?':'S', '?':'i', '?':'I', 'ç':'c', 'Ç':'C', 'ü':'u', 'Ü':'U',
'ö':'o', 'Ö':'O', '?':'g', '?':'G'
},
RUSSIAN_MAP = {
'?':'a', '?':'b', '?':'v', '?':'g', '?':'d', '?':'e', '?':'yo', '?':'zh',
'?':'z', '?':'i', '?':'j', '?':'k', '?':'l', '?':'m', '?':'n', '?':'o',
'?':'p', '?':'r', '?':'s', '?':'t', '?':'u', '?':'f', '?':'h', '?':'c',
'?':'ch', '?':'sh', '?':'shch', '?':'', '?':'y', '?':'', '?':'e', '?':'yu',
'?':'ya',
'?':'A', '?':'B', '?':'V', '?':'G', '?':'D', '?':'E', '?':'Yo', '?':'Zh',
'?':'Z', '?':'I', '?':'J', '?':'K', '?':'L', '?':'M', '?':'N', '?':'O',
'?':'P', '?':'R', '?':'S', '?':'T', '?':'U', '?':'F', '?':'H', '?':'C',
'?':'Ch', '?':'Sh', '?':'Shch', '?':'', '?':'Y', '?':'', '?':'E', '?':'Yu',
'?':'Ya'
},
UKRAINIAN_MAP = {
'?':'Ye', '?':'I', '?':'Yi', '?':'G', '?':'ye', '?':'i', '?':'yi', '?':'g'
},
CZECH_MAP = {
'?':'c', '?':'d', '?':'e', '?': 'n', '?':'r', '?':'s', '?':'t', '?':'u',
'?':'z', '?':'C', '?':'D', '?':'E', '?': 'N', '?':'R', '?':'S', '?':'T',
'?':'U', '?':'Z'
},
POLISH_MAP = {
'?':'a', '?':'c', '?':'e', '?':'l', '?':'n', 'ó':'o', '?':'s', '?':'z',
'?':'z', '?':'A', '?':'C', '?':'E', '?':'L', '?':'N', 'Ó':'O', '?':'S',
'?':'Z', '?':'Z'
},
LATVIAN_MAP = {
'?':'a', '?':'c', '?':'e', '?':'g', '?':'i', '?':'k', '?':'l', '?':'n',
'?':'s', '?':'u', '?':'z', '?':'A', '?':'C', '?':'E', '?':'G', '?':'I',
'?':'K', '?':'L', '?':'N', '?':'S', '?':'U', '?':'Z'
},
ARABIC_MAP = {
'?':'a', '?':'b', '?':'t', '?': 'th', '?':'g', '?':'h', '?':'kh', '?':'d',
'?':'th', '?':'r', '?':'z', '?':'s', '?':'sh', '?':'s', '?':'d', '?':'t',
'?':'th', '?':'aa', '?':'gh', '?':'f', '?':'k', '?':'k', '?':'l', '?':'m',
'?':'n', '?':'h', '?':'o', '?':'y'
},
PERSIAN_MAP = {
'?':'a', '?':'a', '?':'p', '?':'ch', '?':'zh', '?':'k', '?':'gh', '?':'y'
},
LITHUANIAN_MAP = {
'?':'a', '?':'c', '?':'e', '?':'e', '?':'i', '?':'s', '?':'u', '?':'u',
'?':'z',
'?':'A', '?':'C', '?':'E', '?':'E', '?':'I', '?':'S', '?':'U', '?':'U',
'?':'Z'
},
SERBIAN_MAP = {
'?':'dj', '?':'j', '?':'lj', '?':'nj', '?':'c', '?':'dz', '?':'d',
'?':'Dj', '?':'j', '?':'Lj', '?':'Nj', '?':'C', '?':'Dz', '?':'D'
},
AZERBAIJANI_MAP = {
'ç':'c', '?':'e', '?':'g', '?':'i', 'ö':'o', '?':'s', 'ü':'u',
'Ç':'C', '?':'E', '?':'G', '?':'I', 'Ö':'O', '?':'S', 'Ü':'U'
},
ROMANIAN_MAP = {
'?':'a', 'â':'a', 'î':'i', '?':'s', '?':'t',
'?':'A', 'Â':'A', 'Î':'I', '?':'S', '?':'T'
},
BELARUSIAN_MAP = {
'?':'w', '?':'W'
},
SPECIFIC_MAPS = {
'de': {
'Ä': 'AE', 'Ö': 'OE', 'Ü': 'UE',
'ä': 'ae', 'ö': 'oe', 'ü': 'ue'
}
},
ALL_MAPS = [
VIETNAMESE_MAP,
LATIN_MAP,
LATIN_SYMBOLS_MAP,
GREEK_MAP,
TURKISH_MAP,
RUSSIAN_MAP,
UKRAINIAN_MAP,
CZECH_MAP,
POLISH_MAP,
LATVIAN_MAP,
ARABIC_MAP,
PERSIAN_MAP,
LITHUANIAN_MAP,
SERBIAN_MAP,
AZERBAIJANI_MAP,
ROMANIAN_MAP,
BELARUSIAN_MAP
]
var removeList = [
"a", "an", "as", "at", "before", "but", "by", "for", "from", "is",
"in", "into", "like", "of", "off", "on", "onto", "per", "since",
"than", "the", "this", "that", "to", "up", "via", "with"
]
var locale = $('meta[name="backend-locale"]').attr('content')
var Downcoder = {
Initialize: function() {
if (Downcoder.map) {
return;
}
Downcoder.map = {};
Downcoder.chars = [];
if(typeof SPECIFIC_MAPS[locale] === 'object') {
ALL_MAPS.push(SPECIFIC_MAPS[locale]);
}
for (var i=0; i<ALL_MAPS.length; i++) {
var lookup = ALL_MAPS[i];
for (var c in lookup) {
if (lookup.hasOwnProperty(c)) {
Downcoder.map[c] = lookup[c];
}
}
}
for (var k in Downcoder.map) {
if (Downcoder.map.hasOwnProperty(k)) {
Downcoder.chars.push(k);
}
}
Downcoder.regex = new RegExp(Downcoder.chars.join('|'), 'g');
}
}
var InputPreset = function (element, options) {
var $el = this.$el = $(element)
this.options = options || {}
this.cancelled = false
var parent = options.inputPresetClosestParent !== undefined
? $el.closest(options.inputPresetClosestParent)
: undefined,
self = this,
prefix = ''
if (options.inputPresetPrefixInput !== undefined)
prefix = $(options.inputPresetPrefixInput, parent).val()
if (prefix === undefined)
prefix = ''
// Do not update the element if it already has a value and the value doesn't match the prefix
if ($el.val().length && $el.val() != prefix)
return
$el.val(prefix).trigger('oc.inputPreset.afterUpdate')
this.$src = $(options.inputPreset, parent)
this.$src.on('input paste', function(event) {
if (self.cancelled)
return
var timeout = event.type === 'paste' ? 100 : 0
var updateValue = function(self, el, prefix) {
if (el.data('update') === false) {
return
}
el
.val(prefix + self.formatValue())
.trigger('oc.inputPreset.afterUpdate')
}
var src = $(this)
setTimeout(function() {
$el.trigger('oc.inputPreset.beforeUpdate', [src])
setTimeout(updateValue, 100, self, $el, prefix)
}, timeout)
})
this.$el.on('change', function() {
self.cancelled = true
})
}
InputPreset.prototype.formatNamespace = function() {
var value = this.toCamel(this.$src.val())
return value.substr(0, 1).toUpperCase() + value.substr(1)
}
InputPreset.prototype.formatValue = function() {
if (this.options.inputPresetType == 'exact') {
return this.$src.val();
}
else if (this.options.inputPresetType == 'namespace') {
return this.formatNamespace()
}
if (this.options.inputPresetType == 'camel') {
var value = this.toCamel(this.$src.val(), this.$el.attr('maxlength'))
}
else {
var value = this.slugify(this.$src.val(), this.$el.attr('maxlength'))
}
if (this.options.inputPresetType == 'url') {
value = '/' + value
}
return value.replace(/\s/gi, "-")
}
InputPreset.prototype.toCamel = function(slug, numChars) {
Downcoder.Initialize()
slug = slug.replace(Downcoder.regex, function(m) {
return Downcoder.map[m]
})
slug = this.removeStopWords(slug);
slug = slug.toLowerCase()
slug = slug.replace(/(\b|-)\w/g, function(m) {
return m.toUpperCase();
});
slug = slug.replace(/[^-\w\s]/g, '')
slug = slug.replace(/^\s+|\s+$/g, '')
slug = slug.replace(/[-\s]+/g, '')
slug = slug.substr(0, 1).toLowerCase() + slug.substr(1);
return slug.substring(0, numChars)
}
InputPreset.prototype.slugify = function(slug, numChars) {
Downcoder.Initialize()
slug = slug.replace(Downcoder.regex, function(m) {
return Downcoder.map[m]
})
slug = this.removeStopWords(slug);
slug = slug.replace(/[^-\w\s]/g, '')
slug = slug.replace(/^\s+|\s+$/g, '')
slug = slug.replace(/[-\s]+/g, '-')
slug = slug.toLowerCase()
return slug.substring(0, numChars)
}
InputPreset.prototype.removeStopWords = function(str) {
if (this.options.inputPresetRemoveWords) {
var regex = new RegExp('\\b(' + removeList.join('|') + ')\\b', 'gi')
str = str.replace(regex, '')
}
return str;
}
InputPreset.DEFAULTS = {
inputPreset: '',
inputPresetType: 'slug',
inputPresetClosestParent: undefined,
inputPresetPrefixInput: undefined,
inputPresetRemoveWords: true
}
// INPUT CONVERTER PLUGIN DEFINITION
// ============================
var old = $.fn.inputPreset
$.fn.inputPreset = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('oc.inputPreset')
var options = $.extend({}, InputPreset.DEFAULTS, $this.data(), typeof option == 'object' && option)
if (!data) $this.data('oc.inputPreset', (data = new InputPreset(this, options)))
})
}
$.fn.inputPreset.Constructor = InputPreset
// INPUT CONVERTER NO CONFLICT
// =================
$.fn.inputPreset.noConflict = function () {
$.fn.inputPreset = old
return this
}
// INPUT CONVERTER DATA-API
// ===============
$(document).render(function() {
$('[data-input-preset]').inputPreset()
})
}(window.jQuery);
|