: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* @class elFinder command "preference"
elFinder.prototype.commands.preference = function() {
tab = '<li class="' + fm.res('class', 'tabstab') + ' elfinder-preference-tab-{id}"><a href="#'+fm.namespace+'-preference-{id}" id="'+fm.namespace+'-preference-tab-{id}" class="ui-tabs-anchor {class}">{title}</a></li>',
base = jQuery('<div class="ui-tabs ui-widget ui-widget-content ui-corner-all elfinder-preference">'),
ul = jQuery('<ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-top">'),
tabs = jQuery('<div class="elfinder-preference-tabs ui-tabs-panel ui-widget-content ui-corner-bottom"></div>'),
sep = '<div class="elfinder-preference-separator"></div>',
selfUrl = jQuery('base').length? document.location.href.replace(/#.*$/, '') : '',
selectTab = function(tab) {
jQuery('#'+fm.namespace+'-preference-tab-'+tab).trigger('mouseover').trigger('click');
clTabActive = fm.res('class', 'tabsactive'),
var cats = self.options.categories || {
'language' : ['language'],
'toolbar' : ['toolbarPref'],
'workspace' : ['iconSize','columnPref', 'selectAction', 'makefileTypes', 'useStoredEditor', 'editorMaximized', 'useFullscreen', 'showHidden'],
'dialog' : ['autoFocusDialog'],
'selectionInfo' : ['infoItems', 'hashChecker'],
'reset' : ['clearBrowserData'],
forms = self.options.prefs || ['language', 'theme', 'toolbarPref', 'iconSize', 'columnPref', 'selectAction', 'makefileTypes', 'useStoredEditor', 'editorMaximized', 'useFullscreen', 'showHidden', 'infoItems', 'hashChecker', 'autoFocusDialog', 'clearBrowserData'];
forms = fm.arrayFlip(forms, true);
if (fm.options.getFileCallback) {
delete forms.selectAction;
delete forms.useFullscreen;
forms.language && (forms.language = (function() {
var langSel = jQuery('<select></select>').on('change', function() {
var lang = jQuery(this).val();
fm.storage('lang', lang);
jQuery('#'+fm.id).elfinder('reload');
langs = self.options.langs || {
fr_CA: 'Français (Canada)',
jQuery.each(langs, function(lang, name) {
optTags.push('<option value="'+lang+'">'+name+'</option>');
return langSel.append(optTags.join('')).val(fm.lang);
forms.theme && (forms.theme = (function() {
var cnt = fm.options.themes? Object.keys(fm.options.themes).length : 0;
if (cnt === 0 || (cnt === 1 && fm.options.themes.default)) {
var themeSel = jQuery('<select></select>').on('change', function() {
var theme = jQuery(this).val();
fm.changeTheme(theme).storage('theme', theme);
image: '<img class="elfinder-preference-theme elfinder-preference-theme-image" src="$2" />',
link: '<a href="$1" target="_blank" title="$3">$2</a>',
data: '<dt>$1</dt><dd><span class="elfinder-preference-theme elfinder-preference-theme-$0">$2</span></dd>'
items = ['image', 'description', 'author', 'email', 'license'],
render = function(key, data) {
defBtn = jQuery('<button class="ui-button ui-corner-all ui-widget elfinder-preference-theme-default"></button>').text(fm.i18n('default')).on('click', function(e) {
themeSel.val('default').trigger('change');
list = jQuery('<div class="elfinder-reference-hide-taball"></div>').on('click', 'button', function() {
var val = jQuery(this).data('themeid');
themeSel.val(val).trigger('change');
if (!fm.options.themes.default) {
themeSel.append('<option value="default">'+fm.i18n('default')+'</option>');
jQuery.each(fm.options.themes, function(id, val) {
var opt = jQuery('<option class="elfinder-theme-option-'+id+'" value="'+id+'">'+fm.i18n(id)+'</option>'),
dsc = jQuery('<fieldset class="ui-widget ui-widget-content ui-corner-all elfinder-theme-list-'+id+'"><legend>'+fm.i18n(id)+'</legend><div><span class="elfinder-spinner"></span></div></fieldset>'),
tm = setTimeout(function() {
dsc.find('span.elfinder-spinner').replaceWith(fm.i18n(['errRead', id]));
fm.getTheme(id).always(function() {
var link, val = jQuery(), dl = jQuery('<dl></dl>');
link = data.link? tpl.link.replace(/\$1/g, data.link).replace(/\$3/g, fm.i18n('website')) : '$2';
opt.html(fm.i18n(data.name));
dsc.children('legend').html(link.replace(/\$2/g, fm.i18n(data.name) || id));
jQuery.each(items, function(i, key) {
var t = tpl[key] || tpl.data,
elm = t.replace(/\$0/g, fm.escape(key)).replace(/\$1/g, fm.i18n(key)).replace(/\$2/g, fm.i18n(data[key]));
if (key === 'image' && data.link) {
elm = jQuery(elm).on('click', function() {
themeSel.val(id).trigger('change');
}).attr('title', fm.i18n('select'));
val = val.add(jQuery('<div class="elfinder-preference-theme-btn"></div>').append(jQuery('<button class="ui-button ui-corner-all ui-widget"></button>').data('themeid', id).html(fm.i18n('select'))));
dsc.find('span.elfinder-spinner').replaceWith(val);
dsc.find('span.elfinder-spinner').replaceWith(fm.i18n(['errRead', id]));
return jQuery('<div></div>').append(themeSel.val(fm.theme && fm.theme.id? fm.theme.id : 'default'), defBtn, list);
forms.toolbarPref && (forms.toolbarPref = (function() {
var pnls = jQuery.map(fm.options.uiOptions.toolbar, function(v) {
return jQuery.isArray(v)? v : null;
hides = fm.storage('toolbarhides') || {};
jQuery.each(pnls, function() {
name = fm.i18n('cmd'+cmd);
if (name === 'cmd'+cmd) {
tags.push('<span class="elfinder-preference-toolbar-item"><label><input type="checkbox" value="'+cmd+'" '+(hides[cmd]? '' : 'checked')+'/>'+name+'</label></span>');
return jQuery(tags.join(' ')).on('change', 'input', function() {
var v = jQuery(this).val(),
o = jQuery(this).is(':checked');
} else if (o && hides[v]) {
fm.storage('toolbarhides', hides);
fm.trigger('toolbarpref');
forms.iconSize && (forms.iconSize = (function() {
var max = fm.options.uiOptions.cwd.iconsView.sizeMax || 3,
size = fm.storage('iconsize') || fm.options.uiOptions.cwd.iconsView.size || 0,
sld = jQuery('<div class="touch-punch"></div>').slider({
'ui-slider-handle': 'elfinder-tabstop',
fm.getUI('cwd').trigger('iconpref', {size: ui.value});
change: function(e, ui) {
fm.storage('iconsize', ui.value);
fm.getUI('cwd').on('iconpref', function(e, data) {
sld.slider('option', 'value', data.size);
forms.columnPref && (forms.columnPref = (function() {
var cols = fm.options.uiOptions.cwd.listView.columns,
hides = fm.storage('columnhides') || {};
jQuery.each(cols, function() {
name = fm.getColumnName(key);
tags.push('<span class="elfinder-preference-column-item"><label><input type="checkbox" value="'+key+'" '+(hides[key]? '' : 'checked')+'/>'+name+'</label></span>');
return jQuery(tags.join(' ')).on('change', 'input', function() {
var v = jQuery(this).val(),
o = jQuery(this).is(':checked');
} else if (o && hides[v]) {
fm.storage('columnhides', hides);
fm.trigger('columnpref', { repaint: true });
forms.selectAction && (forms.selectAction = (function() {
var actSel = jQuery('<select></select>').on('change', function() {
var act = jQuery(this).val();
fm.storage('selectAction', act === 'default'? null : act);
acts = self.options.selectActions,
defAct = fm.getCommand('open').options.selectAction || 'open';
if (jQuery.inArray(defAct, acts) === -1) {
jQuery.each(acts, function(i, act) {
var names = jQuery.map(act.split('/'), function(cmd) {
var name = fm.i18n('cmd'+cmd);
if (name === 'cmd'+cmd) {
optTags.push('<option value="'+act+'">'+names.join('/')+'</option>');
return actSel.append(optTags.join('')).val(fm.storage('selectAction') || defAct);
forms.makefileTypes && (forms.makefileTypes = (function() {
var hides = fm.getCommand('edit').getMkfileHides(),
hides = fm.getCommand('edit').getMkfileHides();
jQuery.each(fm.mimesCanMakeEmpty, function(mime, type) {
var name = fm.getCommand('mkfile').getTypeName(mime, type);
tags.push('<span class="elfinder-preference-column-item" title="'+fm.escape(name)+'"><label><input type="checkbox" value="'+mime+'" '+(hides[mime]? '' : 'checked')+'/>'+type+'</label></span>');
elm = jQuery('<div></div>').on('change', 'input', function() {
var v = jQuery(this).val(),
o = jQuery(this).is(':checked');
} else if (o && hides[v]) {
fm.storage('mkfileHides', hides);
fm.trigger('canMakeEmptyFile');
add = jQuery('<div></div>').append(
jQuery('<input type="text" placeholder="'+fm.i18n('typeOfTextfile')+'"/>').on('keydown', function(e) {
(e.keyCode === jQuery.ui.keyCode.ENTER) && jQuery(this).next().trigger('click');
jQuery('<button class="ui-button"></button>').html(fm.i18n('add')).on('click', function() {
var input = jQuery(this).prev(),
uiToast = fm.getUI('toast'),
uiToast.appendTo(input.closest('.ui-dialog'));
msg: fm.i18n('errUsupportType'),
uiToast.children().length === 1 && uiToast.appendTo(fm.getUI());
val = fm.arrayFlip(fm.mimeTypes)[val];
if (!fm.mimeIsText(val) || !fm.mimeTypes[val]) {
fm.trigger('canMakeEmptyFile', {mimes: [val], unshift: true});
tmpMimes[val] = fm.mimeTypes[val];
fm.storage('mkfileTextMimes', Object.assign(tmpMimes, fm.storage('mkfileTextMimes') || {}));
uiToast.appendTo(input.closest('.ui-dialog'));
msg: fm.i18n(['complete', val + ' (' + tmpMimes[val] + ')']),
uiToast.children().length === 1 && uiToast.appendTo(fm.getUI());
jQuery('<button class="ui-button"></button>').html(fm.i18n('reset')).on('click', function() {
fm.one('canMakeEmptyFile', {done: function() {
elm.empty().append(getTag());
fm.trigger('canMakeEmptyFile', {resetTexts: true});
fm.bind('canMakeEmptyFile', {done: function(e) {
if (e.data && e.data.mimes && e.data.mimes.length) {
elm.empty().append(getTag());
return jQuery('<div></div>').append(elm, add);
forms.useStoredEditor && (forms.useStoredEditor = jQuery('<input type="checkbox"/>').prop('checked', (function() {
var s = fm.storage('useStoredEditor');
return s? (s > 0) : fm.options.commandsOptions.edit.useStoredEditor;
})()).on('change', function(e) {
fm.storage('useStoredEditor', jQuery(this).is(':checked')? 1 : -1);
forms.editorMaximized && (forms.editorMaximized = jQuery('<input type="checkbox"/>').prop('checked', (function() {
var s = fm.storage('editorMaximized');
return s? (s > 0) : fm.options.commandsOptions.edit.editorMaximized;
})()).on('change', function(e) {
fm.storage('editorMaximized', jQuery(this).is(':checked')? 1 : -1);
forms.useFullscreen && (forms.useFullscreen = jQuery('<input type="checkbox"/>').prop('checked', (function() {
var s = fm.storage('useFullscreen');
return s? (s > 0) : fm.options.commandsOptions.fullscreen.mode === 'screen';
})()).on('change', function(e) {
fm.storage('useFullscreen', jQuery(this).is(':checked')? 1 : -1);
var setTitle = function() {
var s = fm.storage('hide'),
jQuery.each(s.items, function(h, n) {
elms.prop('disabled', !t.length)[t.length? 'removeClass' : 'addClass']('ui-state-disabled');
v = t.length? t.join('\n') : '';
forms.showHidden.attr('title',v);
useTooltip && forms.showHidden.tooltip('option', 'content', v.replace(/\n/g, '<br>')).tooltip('close');
chk = jQuery('<input type="checkbox"/>').prop('checked', (function() {
var s = fm.storage('hide');
})()).on('change', function(e) {
o[jQuery(this).is(':checked')? 'show' : 'hide'] = true;
fm.exec('hide', void(0), o);
btn = jQuery('<button class="ui-button ui-corner-all ui-widget"></button>').append(fm.i18n('reset')).on('click', function() {
fm.exec('hide', void(0), {reset: true});
jQuery(this).parent().find('input:first').prop('checked', false);
elms = jQuery().add(chk).add(btn),
forms.showHidden = jQuery('<div></div>').append(chk, btn);
fm.bind('hide', function(e) {
if (!d.opts || (!d.opts.show && !d.opts.hide)) {
if (fm.UA.Mobile && jQuery.fn.tooltip) {
forms.showHidden.tooltip({
'ui-tooltip': 'elfinder-ui-tooltip ui-widget-shadow'
tooltipClass: 'elfinder-ui-tooltip ui-widget-shadow',
}).css('user-select', 'none');
btn.css('user-select', 'none');
forms.infoItems && (forms.infoItems = (function() {
var items = fm.getCommand('info').items,
hides = fm.storage('infohides') || fm.arrayFlip(fm.options.commandsOptions.info.hideItems, true);
jQuery.each(items, function() {
tags.push('<span class="elfinder-preference-info-item"><label><input type="checkbox" value="'+key+'" '+(hides[key]? '' : 'checked')+'/>'+name+'</label></span>');
return jQuery(tags.join(' ')).on('change', 'input', function() {
var v = jQuery(this).val(),
o = jQuery(this).is(':checked');
} else if (o && hides[v]) {
fm.storage('infohides', hides);
fm.trigger('infopref', { repaint: true });
forms.hashChecker && fm.hashCheckers.length && (forms.hashChecker = (function() {
enabled = fm.arrayFlip(fm.storage('hashchekcer') || fm.options.commandsOptions.info.showHashAlgorisms, true);
jQuery.each(fm.hashCheckers, function() {
tags.push('<span class="elfinder-preference-hashchecker-item"><label><input type="checkbox" value="'+cmd+'" '+(enabled[cmd]? 'checked' : '')+'/>'+name+'</label></span>');
return jQuery(tags.join(' ')).on('change', 'input', function() {
var v = jQuery(this).val(),
o = jQuery(this).is(':checked');
fm.storage('hashchekcer', jQuery.grep(fm.hashCheckers, function(v) {
forms.autoFocusDialog && (forms.autoFocusDialog = jQuery('<input type="checkbox"/>').prop('checked', (function() {
var s = fm.storage('autoFocusDialog');
return s? (s > 0) : fm.options.uiOptions.dialog.focusOnMouseOver;
})()).on('change', function(e) {
fm.storage('autoFocusDialog', jQuery(this).is(':checked')? 1 : -1);
forms.clearBrowserData && (forms.clearBrowserData = jQuery('<button></button>').text(fm.i18n('reset')).button().on('click', function(e) {
jQuery('#'+fm.id).elfinder('reload');
jQuery.each(cats, function(id, prefs) {
jQuery.each(prefs, function(i, n) {
var f, title, chks = '', cbox;
cbox = jQuery(f).filter('input[type="checkbox"]');
cbox = jQuery(f).find('input[type="checkbox"]');