: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
url = fm.convAbsUrl(fm.url(file.hash));
node = jQuery('<iframe class="elfinder-quicklook-preview-iframe" scrolling="no"></iframe>')
.css('background-color', 'transparent')
ql.preview.after(ql.info);
jQuery(this).css('background-color', '#fff').show();
.on('error', function() {
ql.preview.after(ql.info);
.attr('src', '//sharecad.org/cadframe/load?url=' + encodeURIComponent(url));
ql.info.after(ql.preview);
* KML preview with GoogleMaps API
* @param elFinder.commands.quicklook
'application/vnd.google-earth.kml+xml' : true,
'application/vnd.google-earth.kmz' : true
gMaps, loadMap, wGmfail, fail, mapScr;
if (ql.options.googleMapsApiKey) {
link: 'https://www.google.com/intl/' + fm.lang.replace('_', '-') + '/help/terms_maps.html'
gMaps = (window.google && google.maps);
loadMap = function(file, node, prog) {
var mapsOpts = ql.options.googleMapsOpts.maps;
fm.forExternalUrl(file.hash, { progressBar: prog }).done(function(url) {
new gMaps.KmlLayer(url, Object.assign({
map: new gMaps.Map(node.get(0), mapsOpts)
}, ql.options.googleMapsOpts.kml));
// keep stored error handler if exists
wGmfail = window.gm_authFailure;
mapScr = 'https://maps.googleapis.com/maps/api/js?key=' + ql.options.googleMapsApiKey;
window.gm_authFailure = function() {
preview.on(ql.evUpdate, function(e) {
if (mapScr && mimes[file.mime.toLowerCase()]) {
getLink = (file.url == '1' && !fm.option('onetimeUrl', file.hash)),
loading, prog, url, node;
e.stopImmediatePropagation();
loading = jQuery('<div class="elfinder-quicklook-info-data"><span class="elfinder-spinner-text">'+fm.i18n('nowLoading')+'</span><span class="elfinder-spinner"></span></div>').appendTo(ql.info.find('.elfinder-quicklook-info'));
prog = jQuery('<div class="elfinder-quicklook-info-progress"></div>').appendTo(loading);
jQuery('<div class="elfinder-quicklook-info-data"><button class="elfinder-info-button">'+fm.i18n('getLink')+'</button></div>').appendTo(ql.info.find('.elfinder-quicklook-info'))
.on('click', function() {
self.html('<span class="elfinder-spinner">');
data : {cmd : 'url', target : file.hash},
var rfile = fm.file(file.hash);
file.url = rfile.url = data.url || '';
if (file.url !== '' && !getLink) {
node = jQuery('<div style="width:100%;height:100%;"></div>').appendTo(preview);
preview.one('change', function() {
fm.loadScript([mapScr], function() {
gMaps = window.google && google.maps;
gMaps && loadMap(file, node, prog);
loadMap(file, node, prog);
* Any supported files preview plugin using (Google docs | MS Office) online viewer
* @param elFinder.commands.quicklook
mimes = Object.assign(fm.arrayFlip(ql.options.googleDocsMimes || [], 'g'), fm.arrayFlip(ql.options.officeOnlineMimes || [], 'm')),
g: 'docs.google.com/gview?embedded=true&url=',
m: 'view.officeapps.live.com/op/embed.aspx?wdStartOn=0&src='
if (ql.options.googleDocsMimes.length) {
title: 'Google Docs Viewer',
link: 'https://docs.google.com/'
if (ql.options.officeOnlineMimes.length) {
title: 'MS Online Doc Viewer',
link: 'https://products.office.com/office-online/view-office-documents-online'
preview.on(ql.evUpdate, function(e) {
// 25MB is maximum filesize of Google Docs prevew
if (file.size <= 26214400 && (type = mimes[file.mime])) {
navi.css('bottom', win.hasClass('elfinder-quicklook-fullscreen')? navBottom[type] : '');
ext = fm.mimeTypes[file.mime],
getLink = (file.url == '1' && !fm.option('onetimeUrl', file.hash)),
if ((mLimits[ext] && file.size > mLimits[ext]) || file.size > mLimits.other) {
jQuery('<div class="elfinder-quicklook-info-data"><button class="elfinder-info-button">'+fm.i18n('getLink')+'</button></div>').appendTo(ql.info.find('.elfinder-quicklook-info'))
.on('click', function() {
self.html('<span class="elfinder-spinner">');
data : {cmd : 'url', target : file.hash},
var rfile = fm.file(file.hash);
file.url = rfile.url = data.url || '';
if (file.url !== '' && !getLink) {
e.stopImmediatePropagation();
preview.one('change', function() {
dfd && dfd.status && dfd.status() === 'pending' && dfd.reject();
win.off('viewchange.googledocs');
node.off('load').remove();
}).addClass('elfinder-overflow-auto');
loading = jQuery('<div class="elfinder-quicklook-info-data"><span class="elfinder-spinner-text">'+fm.i18n('nowLoading')+'</span><span class="elfinder-spinner"></span></div>').appendTo(ql.info.find('.elfinder-quicklook-info'));
prog = jQuery('<div class="elfinder-quicklook-info-progress"></div>').appendTo(loading);
node = jQuery('<iframe class="elfinder-quicklook-preview-iframe"></iframe>')
.css('background-color', 'transparent')
dfd = fm.forExternalUrl(file.hash, { progressBar: prog }).done(function(url) {
if (node && (!node.attr('src') || node.get(0).contentWindow.document/*maybe HTTP 204*/)) {
node.attr('src', 'https://' + urls[type] + encodeURIComponent(url));
// Retry because Google Docs viewer sometimes returns HTTP 204
tm = setTimeout(load, 2000);
url += (url.match(/\?/)? '&' : '?') + '_t=' + file.ts;
node.on('load', function() {
ql.preview.after(ql.info);
jQuery(this).css('background-color', '#fff').show();
.on('error', function() {
ql.preview.after(ql.info);
win.on('viewchange.googledocs', setNavi);
ql.info.after(ql.preview);
* @param elFinder.commands.quicklook
textLines = parseInt(ql.options.textInitialLines) || 150,
prettifyLines = parseInt(ql.options.prettifyMaxLines) || 500,
prettify = function() { return false; };
_PR && (window.PR = _PR);
prettify = function(node) {
if (fm.options.cdns.prettify) {
prettify = function(node) {
fm.loadScript([fm.options.cdns.prettify + (fm.options.cdns.prettify.match(/\?/)? '&' : '?') + 'autorun=false'], function(wPR) {
if (typeof PR === 'object') {
prettify = function() { return true; };
if (node && !node.hasClass('prettyprinted')) {
node.css('cursor', 'wait');
requestAnimationFrame(function() {
PR.prettyPrint && PR.prettyPrint(null, node.get(0));
PRcheck = function(node) {
var status = prettify(node);
preview.on(ql.evUpdate, function(e) {
jqxhr, loading, prog, encSelect;
if (fm.mimeIsText(file.mime) && (!ql.options.getSizeMax || file.size <= ql.options.getSizeMax) && PR !== false) {
e.stopImmediatePropagation();
loading = jQuery('<div class="elfinder-quicklook-info-data"><span class="elfinder-spinner-text">'+fm.i18n('nowLoading')+'</span><span class="elfinder-spinner"></span></div>').appendTo(ql.info.find('.elfinder-quicklook-info'));
prog = jQuery('<div class="elfinder-quicklook-info-progress"></div>').appendTo(loading);
// stop loading on change file if not loadin yet
preview.one('change', function() {
jqxhr.state() == 'pending' && jqxhr.reject();
encSelect && encSelect.remove();
data : {cmd : 'get', target : file.hash, conv : (file.encoding || 1), _t : file.ts},
options : {type: 'get', cache : true},
var reg = new RegExp('^(data:'+file.mime.replace(/([.+])/g, '\\$1')+';base64,)', 'i'),
part, more, node, lines, m;
if (typeof text !== 'string') {
if (window.atob && (m = text.match(reg))) {
text = atob(text.substr(m[1].length));
lines = text.match(/([^\r\n]{1,100}[\r\n]*)/g);
more = lines.length - textLines;
part = lines.splice(0, textLines).join('');
node = jQuery('<div class="elfinder-quicklook-preview-text-wrapper"><pre class="elfinder-quicklook-preview-text prettyprint"></pre></div>');
node.append(jQuery('<div class="elfinder-quicklook-preview-charsleft"><hr/><span>' + fm.i18n('linesLeft', fm.toLocaleString(more)) + '</span></div>')
.on('click', function() {
var top = node.scrollTop();
node.children('pre').removeClass('prettyprinted').text(text).scrollTop(top);
if (lines.length <= prettifyLines) {
node.children('pre').text(part || text);
node.on('touchstart', function(e) {
if (jQuery(this)['scroll' + (fm.direction === 'ltr'? 'Right' : 'Left')]() > 5) {
e.originalEvent._preventSwipeX = true;
if (data.toasts && Array.isArray(data.toasts)) {
jQuery.each(data.toasts, function() {
this.msg && fm.toast(this);
if (cmdEdit = fm.getCommand('edit')) {
if (data && data.encoding) {
head.push({value: data.encoding});
head.push({value: 'UTF-8'});
sel = cmdEdit.getEncSelect(head);
sel.on('change', function() {
file.encoding = sel.val();
fm.cache(file, 'change');
encSelect = jQuery('<div class="elfinder-quicklook-encoding"></div>').append(sel);
ql.window.append(encSelect);