[js:core] fix #2453 handling back button press to close dialog

1. Close the dialog by pressing the back button if the dialog is open
2. If the dialog is not open, go back one history
3. Display "Press again to exit." toast message when there is no return
history

It need client option `useBrowserHistory` to true (default is true).
This commit is contained in:
nao-pon
2018-04-01 11:28:01 +09:00
parent 00ae96153c
commit 3de71b2f36
5 changed files with 63 additions and 20 deletions
+17 -8
View File
@@ -52,6 +52,16 @@ elFinder.prototype.history = function(fm) {
return fm.exec('open', history[fwd ? ++current : --current]).fail(reset);
}
return $.Deferred().reject();
},
/**
* Sets the native history.
*
* @param String thash target hash
*/
setNativeHistory = function(thash) {
if (nativeHistory && (! nativeHistory.state || nativeHistory.state.thash !== thash)) {
nativeHistory.pushState({thash: thash}, null, location.pathname + location.search + (thash? '#elf_' + thash : ''));
}
};
/**
@@ -89,7 +99,12 @@ elFinder.prototype.history = function(fm) {
};
// bind to elfinder events
fm.open(function() {
fm.bind('init', function() {
if (nativeHistory && !nativeHistory.state) {
setNativeHistory(fm.startDir());
}
})
.open(function() {
var l = history.length,
cwd = fm.cwd().hash;
@@ -100,13 +115,7 @@ elFinder.prototype.history = function(fm) {
}
update = true;
if (nativeHistory) {
if (! nativeHistory.state) {
nativeHistory.replaceState({thash: cwd}, null, location.pathname + location.search + '#elf_' + cwd);
} else {
nativeHistory.state.thash != cwd && nativeHistory.pushState({thash: cwd}, null, location.pathname + location.search + '#elf_' + cwd);
}
}
setNativeHistory(cwd);
})
.reload(fm.options.reloadClearHistory && reset);
+40 -10
View File
@@ -2613,9 +2613,10 @@ var elFinder = function(elm, opts, bootCallback) {
*
* @param String event(s) name(s)
* @param Object event handler
* @param Boolean priority first
* @return elFinder
*/
this.bind = function(event, callback) {
this.bind = function(event, callback, priorityFirst) {
var i, len;
if (typeof(callback) == 'function') {
@@ -2626,7 +2627,7 @@ var elFinder = function(elm, opts, bootCallback) {
if (listeners[event[i]] === void(0)) {
listeners[event[i]] = [];
}
listeners[event[i]].push(callback);
listeners[event[i]][priorityFirst? 'unshift' : 'push'](callback);
}
}
return this;
@@ -4103,12 +4104,40 @@ var elFinder = function(elm, opts, bootCallback) {
// attach events to window
self.options.useBrowserHistory && $(window)
.on('popstate.' + namespace, function(ev) {
var target = ev.originalEvent.state && ev.originalEvent.state.thash;
target && !$.isEmptyObject(self.files()) && self.request({
data : {cmd : 'open', target : target, onhistory : 1},
notify : {type : 'open', cnt : 1, hideCnt : true},
syncOnFail : true
});
var state = ev.originalEvent.state,
dialog = node.find('.elfinder-frontmost:visible'),
onOpen, toast, thash;
if (dialog.length) {
state = { thash: self.cwd().hash };
history.pushState(state, null, location.pathname + location.search + '#elf_' + state.thash);
if (dialog.hasClass('elfinder-dialog')) {
dialog.elfinderdialog('close');
} else {
dialog.trigger('close');
}
} else {
if (state && state.thash) {
!$.isEmptyObject(self.files()) && self.request({
data : {cmd : 'open', target : state.thash, onhistory : 1},
notify : {type : 'open', cnt : 1, hideCnt : true},
syncOnFail : true
});
} else {
thash = self.cwd().hash;
onOpen = function() {
toast.trigger('click');
};
self.one('open', onOpen, true);
toast = self.toast({
msg: self.i18n('pressAgainToExit'),
onHidden: function() {
self.unbind('open', onOpen);
state = { thash: thash };
history.pushState(state, null, location.pathname + location.search + '#elf_' + thash);
}
});
}
}
});
$(window).on('resize.' + namespace, function(e){
@@ -6795,9 +6824,10 @@ elFinder.prototype = {
*
* @param String event name
* @param Function callback
* @param Boolan priority first
* @return elFinder
*/
one : function(ev, callback) {
one : function(ev, callback, priorityFirst) {
var self = this,
event = ev.toLowerCase(),
h = function(e, f) {
@@ -6810,7 +6840,7 @@ elFinder.prototype = {
});
return callback.apply(this, arguments);
};
return this.bind(event, h);
return this.bind(event, h, priorityFirst);
},
/**
+2 -1
View File
@@ -2,7 +2,7 @@
* English translation
* @author Troex Nevelin <troex@fury.scancode.ru>
* @author Naoki Sawada <hypweb+elfinder@gmail.com>
* @version 2018-03-28
* @version 2018-04-01
*/
// elfinder.en.js is integrated into elfinder.(full|min).js by jake build
if (typeof elFinder === 'function' && elFinder.prototype.i18) {
@@ -444,6 +444,7 @@ if (typeof elFinder === 'function' && elFinder.prototype.i18) {
'selectionInfo' : 'Selection Info', // from v2.1.33 added 7.3.2018
'hashChecker' : 'Algorithms to show the file hash', // from v2.1.33 added 10.3.2018
'infoItems' : 'Info Items (Selection Info Panel)', // from v2.1.38 added 28.3.2018
'pressAgainToExit': 'Press again to exit.', // from v2.1.38 added 1.4.2018
/********************************** mimetypes **********************************/
'kindUnknown' : 'Unknown',
+2 -1
View File
@@ -2,7 +2,7 @@
* Japanese translation
* @author Tomoaki Yoshida <info@yoshida-studio.jp>
* @author Naoki Sawada <hypweb+elfinder@gmail.com>
* @version 2018-03-28
* @version 2018-04-01
*/
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
@@ -451,6 +451,7 @@
'selectionInfo' : '選択情報', // from v2.1.33 added 7.3.2018
'hashChecker' : 'ファイルハッシュを表示するアルゴリズム', // from v2.1.33 added 10.3.2018
'infoItems' : '情報項目 (選択情報パネル)', // from v2.1.38 added 28.3.2018
'pressAgainToExit': 'もう一度押すと終了します。', // from v2.1.38 added 1.4.2018
/********************************** mimetypes **********************************/
'kindUnknown' : '不明',
+2
View File
@@ -54,6 +54,8 @@ $.fn.elfindertoast = function(opts, fm) {
self.on('click', function(e) {
e.stopPropagation();
e.preventDefault();
rmTm && clearTimeout(rmTm);
opts.onHidden && opts.onHidden();
self.stop().remove();
}).on('mouseenter mouseleave', function(e) {
if (opts.timeOut) {