UNPKG

jquery.filebrowser

Version:

jQuery File Browser is a plugin for creating OS like file browsers.

10 lines 14.2 kB
/**@license * * jQuery File Browser - directory browser jQuery plugin version 0.8.4 * * Copyright (c) 2016-2021 Jakub T. Jankiewicz <https://jcubic.pl/me> * Released under the MIT license * * Date: Sun, 09 May 2021 10:14:30 +0000 */ (function(X,G){"use strict";function Q(e,t,n){this.browser=e;this.upload=t;this.error=n}Q.prototype.process=function e(t,r){var a=X.Deferred();var i=this;if(t.originalEvent){t=t.originalEvent}var n;if(t.dataTransfer.items){n=[].slice.call(t.dataTransfer.items)}var s=t.dataTransfer.files||t.target.files;if(s){s=[].slice.call(s)}if(n&&n.length){if(n[0].webkitGetAsEntry){var o=[];n.forEach(function(e){var t=e.webkitGetAsEntry();if(t){o.push(t)}});(function e(){var t=o.shift();if(t){i.upload_tree(t,r).then(e)}else{a.resolve()}})()}}else if(s&&s.length){(function e(){var t=s.shift();if(t){i.upload(t,r).then(e)}else{a.resolve()}})()}else if(t.dataTransfer.getFilesAndDirectories){t.dataTransfer.getFilesAndDirectories().then(function(n){(function e(){var t=n.shift();if(t){i.upload_tree(t,r).then(e)}else{a.resolve()}})()})}return a.promise()};Q.prototype.upload_tree=function e(t,n){var a=X.Deferred();var r=this;function i(n,r){n=n.slice();(function e(){var t=n.shift();if(t){r(t).then(e).fail(function(){a.reject()})}else{a.resolve()}})()}function s(e){i(e,function(e){return r.upload_tree(e,r.browser.join(n,t.name))})}function o(e){r.upload(e,n).then(function(){a.resolve()}).fail(function(){a.reject()})}if(typeof Directory!="undefined"&&t instanceof Directory){t.getFilesAndDirectories().then(function(e){s(e)})}else if(typeof File!="undefined"&&t instanceof File){o(t)}else if(t.isFile){t.file(o)}else if(t.isDirectory){var l=t.createReader();l.readEntries(function(e){s(e)})}return a.promise()};X.browse={defaults:{dir:function(){return X.when({files:[],dirs:[]})},root:"/",separator:"/",labels:true,change:X.noop,init:X.noop,item_class:X.noop,rename_delay:300,dbclick_delay:2e3,open:X.noop,rename:X.noop,create:X.noop,remove:X.noop,copy:X.noop,exists:X.noop,upload:X.noop,name:"default",error:X.noop,menu:function(e){return{}},refresh_timer:100},strings:{toolbar:{back:"back",up:"up",refresh:"refresh"}},escape_regex:function(e){if(typeof e=="string"){var t=/([-\\\^$\[\]()+{}?*.|])/g;return e.replace(t,"\\$1")}}};var I;var L;var N={};var P;function z(t){return function(e){return t==e}}function J(e,t){var n=X(t);return n.parents().add("html,body").map(function(){return X(this)[e]()}).get().reduce(function(e,t){return e+t})}function S(e,t,n){if(t===n){return true}n=e.join.apply(e,e.split(n).slice(0,-1));return!!n.match(new RegExp("^"+X.browse.escape_regex(t)))}X.fn.browse=function(e){var o=X.extend({},X.browse.defaults,e);function t(e){if(O){var t=F.offset();B=e.clientX-t.left;Y=e.clientY-t.top;$.show();i();q=true;var n=R.find("li");if(!e.ctrlKey){n.removeClass("selected");N[o.name]=[]}var r=$[0].getBoundingClientRect();var a=n.filter(function(){var e=this.getBoundingClientRect();return e.top+e.height>r.top&&e.left+e.width>r.left&&e.bottom-e.height<r.bottom&&e.right-e.width<r.right});a.addClass("selected").each(function(){N[o.name].push(g.join(b,X(this).text()))})}}function n(e){if(!X(e.target).closest(".browser-menu").length){c()}}function r(e){O=false;$.hide();g.removeClass("no-select")}function i(e){var t=J("scrollTop",R);var n=Math.max(Math.min(M,B),0);var r=Math.max(Math.min(A,Y),-t);var a=Math.max(M,B);var i=Math.max(A,Y);var s=R.prop("clientWidth");var o=R.height()+R.scrollTop()-2;if(a>s){a=s}if(i>o){i=o}$.css({left:n,top:r+t,width:a-n,height:i-r})}function a(e){if(g.hasClass("selected")&&!X(e.target).is("textarea")){var t;var n=R.find(".active");if(e.ctrlKey){if(e.which==67){g.copy()}else if(e.which==88){g.cut()}else if(e.which==86){g.paste(L)}}if(e.which==32){var e=jQuery.Event("click");e.ctrlKey=true;e.target=n[0];n.trigger(e);return false}else if(e.which==8){g.back()}else{if(e.which==13&&n.length){C=(new Date).getTime();n.dblclick()}else{if(e.which>=37&&e.which<=40){if(!e.ctrlKey){R.find("li").removeClass("selected")}if(!n.length){n=R.find("li:eq(0)").addClass("active")}else{var r=R.find("li");var a=R.prop("clientWidth");var i=r.length;var s=R.find("li:eq(0)").outerWidth(true);var o=Math.floor(a/s);t=n.index();if(e.which==37){t--}else if(e.which==38){t=t-o}else if(e.which==39){t++}else if(e.which==40){t=t+o}if(t<0){t=0}else if(t>i-1){t=i-1}r.eq(t).addClass("active").siblings().removeClass("active")}}}}}}function s(e){if(!X(e.target).closest("."+m).length){X(".browser-widget").removeClass("selected")}var t=X(e.target);var n=t.closest(".browser-menu li");if(n.length){if(H){var r=H.target.closest("ul:not(.menu) li");var a=H.menu;n.parents(".ui-menu-item").addBack().each(function(){a=a[X(this).find("> div").text()]});if(!n.find("> ul").length){c()}if(X.isFunction(a)){setTimeout(function(){a.call(g,r)},0)}return false}}else if(!t.closest(".browser-menu").length||t.closest(".browser-menu li").length){c()}}function l(){X("."+m).each(function(){var e=X(this).browse();if(e.path()==b&&e.name()==o.name){e.refresh()}})}function f(e){var t=X(this);var n=t.parent();var r=t.val();if(n.hasClass("rename")){t.remove();n.removeClass("rename");var a=n.find("span").text();if(r!=a){g._rename(g.join(b,a),g.join(b,r)).then(l)}}else if(n.hasClass("new")){if(e){n.remove()}else{var i;if(n.hasClass("directory")){i="directory"}else{i="file"}g.create(i,g.join(b,r))}}}function c(){if(X.fn.menu){X("body > .browser-menu").menu("destroy").remove()}H=null}function u(){var e;if(R.prop){e=R.prop("scrollHeight")}else{e=R.attr("scrollHeight")}R.scrollTop(e)}function d(n,e){var r=X("<ul/>");if(!e){r.addClass("browser-menu")}Object.keys(n).forEach(function(e){var t=X('<li class="'+h(e)+'"><div>'+e+"</div></li>").appendTo(r);if(X.isPlainObject(n[e])){t.append(d(n[e],true))}});return r}function h(e){return e.toLowerCase().replace(/\s+([^\s])/g,function(e,t){return"-"+t})}function p(e){if(!e.is(".new, .rename")){var t=e.find("span").text();X("<textarea>"+t+"</textarea>").appendTo(e).focus().select();e.addClass("rename")}else{e.find("textarea").focus().select()}}function v(e){if(e.originalEvent){e=e.originalEvent}if(e.dataTransfer.items&&e.dataTransfer.items.length){return!![].filter.call(e.dataTransfer.items,function(e){return e.kind=="file"}).length}else{return e.dataTransfer.files&&e.dataTransfer.files.length}}if(this.data("browse")){return this.data("browse")}else if(this.length>1){return this.each(function(){X.fn.browse.call(X(this),o)})}else{var m="browser-widget";N[o.name]=N[o.name]||[];var g=this;g.addClass(m+" hidden");var w=new Q(g,o.upload,o.error);var b;var y=[];var x;var C;var T=false;var _=0;var k=X('<div class="toolbar"/>').appendTo(g);var j=X('<div class="adress-bar"></div>').appendTo(k);X("<button>Home</button>").addClass("home").appendTo(j);var E=X("<ul></ul>").appendTo(k);if(o.labels){E.addClass("labels")}var D=X("<input />").appendTo(j);var K=X.browse.strings.toolbar;Object.keys(K).forEach(function(e){X("<li/>").text(K[e]).addClass(e).appendTo(E)});var R=X("<ul/>").wrap("<div/>").parent().addClass("content").appendTo(g);var F=R.find("ul");var M=0,A=0,B=0,Y=0;var $=X("<div/>").addClass("selection").hide().appendTo(R);var O=false;var q=false;var H;var W={li:{rename:p,delete:function(e){X.when.apply(X,R.find("li.selected").map(function(){var e=X(this).find("span").text();return o.remove(g.join(b,e))})).then(l)}},content:{new:{directory:function(e){g.create("Directory")},file:function(e){g.create("File")}}}};k.on("click.browse","li",function(){var e=X(this);if(!e.hasClass("disabled")){var t=e.text();g[t]()}}).on("click",".home",function(){if(b!=o.root){g.show(o.root)}}).on("keydown.browse","input",function(e){if(e.which==13){var t=X(this);var n=t.val();g.show(n);return false}});R.on("dblclick.browse","li",function(e){var t=X(this);var n=(new Date).getTime()-C;if(n<o.rename_delay&&n<o.dbclick_delay){var r=t.find("span").text();var a=g.join(b,r);if(t.hasClass("directory")){t.removeClass("selected");g.show(a)}else if(t.hasClass("file")){o.open(a)}}}).on("click.browse","ul:not(.menu) > li",function(e){if(!O){var t=X(e.target);var n=X(this);var r=n.find("span").text();var a=g.join(b,r);if(t.is("span")){if(_++%2===0){C=(new Date).getTime()}else{var i=(new Date).getTime()-C;if(i>o.rename_delay&&i<o.dbclick_delay){p(n);return false}}}else{C=(new Date).getTime()}if(!e.ctrlKey){n.siblings().removeClass("selected")}if(!t.is("textarea")){R.find(".active").removeClass("active");n.toggleClass("selected").addClass("active");if(n.hasClass("selected")){if(!e.ctrlKey){N[o.name]=[]}N[o.name].push(a)}else if(e.ctrlKey){N[o.name]=N[o.name].filter(z(a))}else{N[o.name]=[]}}}}).on("keydown","textarea",function(e){if(e.which==13||e.which==27){f.call(this,e.which==27)}if([13,27].indexOf(e.which)!=-1){return false}}).on("contextmenu",function(e){if(o.contextmenu&&!e.ctrlKey){c();H={target:X(e.target)};if(!H.target.is("textarea")){var t=H.target.closest("li");H.type=t.length?"li":"content";H.menu=X.extend(W[H.type],o.menu(H.type)||{});var n=d(H.menu).appendTo("body");n.menu();var r=R.offset();n.css({left:e.pageX,top:e.pageY});return false}}});g.on("click.browse",function(e){X("."+m).removeClass("selected");g.addClass("selected");var t=X(e.target);if(!q){if(!e.ctrlKey&&!t.is(".content li")&&!t.closest(".toolbar").length){R.find("li").removeClass("selected");N[o.name]=[]}}if(!t.is("textarea")){R.find("li.rename,li.new").find("textarea").each(f)}});g.on("dragover.browse",".content",function(e){if(e.originalEvent){e=e.originalEvent}e.dataTransfer.dropEffect="move";return false}).on("dragstart",".content li",function(e){e.originalEvent.dataTransfer.setData("text","anything");var t=X(this);var n=t.text();P={name:n,node:t,path:b,context:g};P.selection=t.hasClass("selected")});R.on("drop.browse",function(e){var t=X(e.target);var n;if(t.is(".directory")){n=g.join(b,t.text())}else{n=b}if(v(e)){w.process(e,n).then(function(){if(!t.is(".directory")){l()}})}else{if(g.name()!==P.context.name()){var r="You can't drag across different filesystems";o.error(r)}var a;if(P.selection){a=X.when.apply(X,N[o.name].map(function(e){var t=g.join(n,g.split(e).pop());if(!S(g,e,t)){return g._rename(e,t)}}))}else{var i=g.join(P.path,P.name);var s=g.join(n,P.name);a=g._rename(i,s)}a.then(function(){P.context.refresh();l()})}return false}).on("mousedown.browse",function(e){var t=X(e.target);if(!t.is("li")&&!t.is("span")&&!t.is("textarea")){O=true;q=false;g.addClass("no-select");var n=F.offset();M=e.clientX-n.left;A=e.clientY-n.top}});X(document).on("click",s).on("keydown",a).on("mousedown",n).on("mousemove",t).on("mouseup",r);X.extend(g,{path:function(){return b},name:function(){return o.name},current:function(){return current},back:function(){if(y.length>1){y.pop();g.show(y[y.length-1],{push:false})}return g},destroy:function(){g.off(".browse");X(document).off("click",s).off("keydown",a).off("mousedown",n).off("mousemove",t).off("mouseup",r);j.remove();R.remove()},_rename:function(e,t){var n=S(g,e,t);if(!n){return X.when(o.rename(e,t))}else{return X.when()}},_create:function(e,t){return X.when(o.create(e,t))},_exists:function(e){return X.when(o.exists(e))},create:function(t,n){var e=h(t);if(n==G){var r=X(['<li class="new '+e+'" draggable="true">'," <span></span>"," <textarea/>","</li>"].join("")).appendTo(F);u();r.find("textarea").val("New "+t).focus().select();return X.when()}return g._exists(n).then(function(e){if(e==true){R.find("li.new").remove();setTimeout(function(){o.error(t+" already exists")},10)}else{return g._create(t,n).then(l)}})},_copy:function(e,t){if(!S(g,e,t)){return o.copy(e,t)}else{return X.when()}},copy:function(){I={path:b,contents:N[o.name],source:g};L=false},cut:function(){g.copy();L=true},paste:function(e){function t(r,a){return X.when.apply(X,I.contents.map(function(e){var t=r.split(e).pop();var n=r.join(b,t);if(!S(g,e,n)){return r[a](e,n)}else{return X.when()}}))}if(I&&I.contents&&I.contents.length){if(g.name()!==I.source.name()){o.error("You can't paste across different filesystems")}else{var n;if(e){n=t(g,"_rename")}else{n=t(g,"_copy")}n.then(function(){I.source.refresh();l()})}}},up:function(){var e=g.split(b);e.pop();g.show(g.join.apply(g,e));return g},refresh:function(){R.addClass("hidden");var e=X.Deferred();var t=X.Deferred();if(o.refresh_timer){setTimeout(e.resolve.bind(e),o.refresh_timer)}else{e.resolve()}g.show(b,{force:true,push:false,callback:function(){t.resolve()}});X.when(e,t).then(function(){R.removeClass("hidden")})},show:function(r,n){function e(e){if(i){return}i=true;if(!e){o.error("Invalid directory");g.removeClass("hidden")}else{x=e;F.empty();x.dirs.forEach(function(e){var t=o.item_class(r,e);var n=X('<li class="directory"><span>'+e+"</span></li>").appendTo(F).attr("draggable",true);if(t){n.addClass(t)}});x.files.forEach(function(e){var t=X('<li class="file"><span>'+e+"</span></li>").appendTo(F).attr("draggable",true);if(e.match(".")){t.addClass(e.split(".").pop())}var n=o.item_class(r,e);if(n){t.addClass(n)}});g.removeClass("hidden");var t=new RegExp(X.browse.escape_regex(o.separator)+"$");if(!r.match(t)&&r!=o.root){r+=o.separator}D.val(r);o.change.call(g);n.callback()}}var t={callback:X.noop,push:true,force:false};n=X.extend({},t,n);if(b!=r||n.force){g.addClass("hidden");if(n.push){y.push(r)}k.find(".up").toggleClass("disabled",r==o.root);k.find(".back").toggleClass("disabled",y.length==1);b=r;var a=o.dir(b,e);if(a&&a.then){a.then(e).catch(function(){e()})}var i=false}return g},join:function(){var e=[].slice.call(arguments);var t=e.map(function(e){var t=new RegExp(X.browse.escape_regex(o.separator)+"$","");return e.replace(t,"")}).filter(Boolean).join(o.separator);var n=new RegExp("^"+X.browse.escape_regex(o.root));return n.test(t)?t:o.root+t},split:function(e){var t=new RegExp("^"+X.browse.escape_regex(o.root));var n=new RegExp(X.browse.escape_regex(o.separator)+"$");e=e.replace(t,"").replace(n,"");if(e){return e.split(o.separator).filter(Boolean)}else{return[]}},walk:function(e,t){var n=this.split(e);var r;while(n.length){r=t(n.shift(),!n.length,r)}return r}});setTimeout(function(){var e=o.start_directory||o.root;g.show(e,{callback:o.init.bind(g)})},0);g.data("browse",g);return g}}})(jQuery);