diff options
Diffstat (limited to 'module/web/themes/default/js/sources')
-rw-r--r-- | module/web/themes/default/js/sources/MooDialog.js | 140 | ||||
-rw-r--r-- | module/web/themes/default/js/sources/MooDropMenu.js | 86 | ||||
-rw-r--r-- | module/web/themes/default/js/sources/admin.coffee | 58 | ||||
-rw-r--r-- | module/web/themes/default/js/sources/base.coffee | 173 | ||||
-rw-r--r-- | module/web/themes/default/js/sources/filemanager.js | 291 | ||||
-rw-r--r-- | module/web/themes/default/js/sources/package.js | 376 | ||||
-rw-r--r-- | module/web/themes/default/js/sources/purr.js | 309 | ||||
-rw-r--r-- | module/web/themes/default/js/sources/settings.coffee | 107 | ||||
-rw-r--r-- | module/web/themes/default/js/sources/tinytab.js | 43 |
9 files changed, 1583 insertions, 0 deletions
diff --git a/module/web/themes/default/js/sources/MooDialog.js b/module/web/themes/default/js/sources/MooDialog.js new file mode 100644 index 000000000..45a52496f --- /dev/null +++ b/module/web/themes/default/js/sources/MooDialog.js @@ -0,0 +1,140 @@ +/* +--- +name: MooDialog +description: The base class of MooDialog +authors: Arian Stolwijk +license: MIT-style license +requires: [Core/Class, Core/Element, Core/Element.Style, Core/Element.Event] +provides: [MooDialog, Element.MooDialog] +... +*/ + + +var MooDialog = new Class({ + + Implements: [Options, Events], + + options: { + 'class': 'MooDialog', + title: null, + scroll: true, // IE + forceScroll: false, + useEscKey: true, + destroyOnHide: true, + autoOpen: true, + closeButton: true, + onInitialize: function(){ + this.wrapper.setStyle('display', 'none'); + }, + onBeforeOpen: function(){ + this.wrapper.setStyle('display', 'block'); + this.fireEvent('show'); + }, + onBeforeClose: function(){ + this.wrapper.setStyle('display', 'none'); + this.fireEvent('hide'); + }/*, + onOpen: function(){}, + onClose: function(){}, + onShow: function(){}, + onHide: function(){}, + onInitialize: function(wrapper){}, + onContentChange: function(content){}*/ + }, + + initialize: function(options){ + this.setOptions(options); + this.options.inject = this.options.inject || document.body; + options = this.options; + + var wrapper = this.wrapper = new Element('div.' + options['class'].replace(' ', '.')).inject(options.inject); + this.content = new Element('div.content').inject(wrapper); + + if (options.title){ + this.title = new Element('div.title').set('text', options.title).inject(wrapper); + wrapper.addClass('MooDialogTitle'); + } + + if (options.closeButton){ + this.closeButton = new Element('a.close', { + events: {click: this.close.bind(this)} + }).inject(wrapper); + } + + + /*<ie6>*/// IE 6 scroll + if ((options.scroll && Browser.ie6) || options.forceScroll){ + wrapper.setStyle('position', 'absolute'); + var position = wrapper.getPosition(options.inject); + window.addEvent('scroll', function(){ + var scroll = document.getScroll(); + wrapper.setPosition({ + x: position.x + scroll.x, + y: position.y + scroll.y + }); + }); + } + /*</ie6>*/ + + if (options.useEscKey){ + // Add event for the esc key + document.addEvent('keydown', function(e){ + if (e.key == 'esc') this.close(); + }.bind(this)); + } + + this.addEvent('hide', function(){ + if (options.destroyOnHide) this.destroy(); + }.bind(this)); + + this.fireEvent('initialize', wrapper); + }, + + setContent: function(){ + var content = Array.from(arguments); + if (content.length == 1) content = content[0]; + + this.content.empty(); + + var type = typeOf(content); + if (['string', 'number'].contains(type)) this.content.set('text', content); + else this.content.adopt(content); + + this.fireEvent('contentChange', this.content); + + return this; + }, + + open: function(){ + this.fireEvent('beforeOpen', this.wrapper).fireEvent('open'); + this.opened = true; + return this; + }, + + close: function(){ + this.fireEvent('beforeClose', this.wrapper).fireEvent('close'); + this.opened = false; + return this; + }, + + destroy: function(){ + this.wrapper.destroy(); + }, + + toElement: function(){ + return this.wrapper; + } + +}); + + +Element.implement({ + + MooDialog: function(options){ + this.store('MooDialog', + new MooDialog(options).setContent(this).open() + ); + return this; + } + +}); diff --git a/module/web/themes/default/js/sources/MooDropMenu.js b/module/web/themes/default/js/sources/MooDropMenu.js new file mode 100644 index 000000000..ac0fa1874 --- /dev/null +++ b/module/web/themes/default/js/sources/MooDropMenu.js @@ -0,0 +1,86 @@ +/* +--- +description: This provides a simple Drop Down menu with infinit levels + +license: MIT-style + +authors: +- Arian Stolwijk + +requires: + - Core/Class.Extras + - Core/Element.Event + - Core/Selectors + +provides: [MooDropMenu, Element.MooDropMenu] + +... +*/ + +var MooDropMenu = new Class({ + + Implements: [Options, Events], + + options: { + onOpen: function(el){ + el.removeClass('close').addClass('open'); + }, + onClose: function(el){ + el.removeClass('open').addClass('close'); + }, + onInitialize: function(el){ + el.removeClass('open').addClass('close'); + }, + mouseoutDelay: 200, + mouseoverDelay: 0, + listSelector: 'ul', + itemSelector: 'li', + openEvent: 'mouseenter', + closeEvent: 'mouseleave' + }, + + initialize: function(menu, options, level){ + this.setOptions(options); + options = this.options; + + var menu = this.menu = document.id(menu); + + menu.getElements(options.itemSelector + ' > ' + options.listSelector).each(function(el){ + + this.fireEvent('initialize', el); + + var parent = el.getParent(options.itemSelector), + timer; + + parent.addEvent(options.openEvent, function(){ + parent.store('DropDownOpen', true); + + clearTimeout(timer); + if (options.mouseoverDelay) timer = this.fireEvent.delay(options.mouseoverDelay, this, ['open', el]); + else this.fireEvent('open', el); + + }.bind(this)).addEvent(options.closeEvent, function(){ + parent.store('DropDownOpen', false); + + clearTimeout(timer); + timer = (function(){ + if (!parent.retrieve('DropDownOpen')) this.fireEvent('close', el); + }).delay(options.mouseoutDelay, this); + + }.bind(this)); + + }, this); + }, + + toElement: function(){ + return this.menu + } + +}); + +/* So you can do like this $('nav').MooDropMenu(); or even $('nav').MooDropMenu().setStyle('border',1); */ +Element.implement({ + MooDropMenu: function(options){ + return this.store('MooDropMenu', new MooDropMenu(this, options)); + } +}); diff --git a/module/web/themes/default/js/sources/admin.coffee b/module/web/themes/default/js/sources/admin.coffee new file mode 100644 index 000000000..c4ab86911 --- /dev/null +++ b/module/web/themes/default/js/sources/admin.coffee @@ -0,0 +1,58 @@ +root = this + +window.addEvent "domready", -> + + root.passwordDialog = new MooDialog {destroyOnHide: false} + root.passwordDialog.setContent $ 'password_box' + + $("login_password_reset").addEvent "click", (e) -> root.passwordDialog.close() + $("login_password_button").addEvent "click", (e) -> + + newpw = $("login_new_password").get("value") + newpw2 = $("login_new_password2").get("value") + + if newpw is newpw2 + form = $("password_form") + form.set "send", { + onSuccess: (data) -> + root.notify.alert "Success", { + 'className': 'success' + } + onFailure: (data) -> + root.notify.alert "Error", { + 'className': 'error' + } + } + + form.send() + + root.passwordDialog.close() + else + alert '{{_("Passwords did not match.")}}' + + e.stop() + + for item in $$(".change_password") + id = item.get("id") + user = id.split("|")[1] + $("user_login").set("value", user) + item.addEvent "click", (e) -> root.passwordDialog.open() + + $('quit-pyload').addEvent "click", (e) -> + new MooDialog.Confirm "{{_('You are really sure you want to quit pyLoad?')}}", -> + new Request.JSON({ + url: '/api/kill' + method: 'get' + }).send() + , -> + e.stop() + + $('restart-pyload').addEvent "click", (e) -> + new MooDialog.Confirm "{{_('Are you sure you want to restart pyLoad?')}}", -> + new Request.JSON({ + url: '/api/restart' + method: 'get' + onSuccess: (data) -> alert "{{_('pyLoad restarted')}}" + }).send() + , -> + e.stop() diff --git a/module/web/themes/default/js/sources/base.coffee b/module/web/themes/default/js/sources/base.coffee new file mode 100644 index 000000000..55151acc9 --- /dev/null +++ b/module/web/themes/default/js/sources/base.coffee @@ -0,0 +1,173 @@ +# External scope +root = this + +# helper functions +humanFileSize = (size) -> + filesizename = new Array("B", "KiB", "MiB", "GiB", "TiB", "PiB") + loga = Math.log(size) / Math.log(1024) + i = Math.floor(loga) + a = Math.pow(1024, i) + if size is 0 then "0 B" else (Math.round(size * 100 / a) / 100 + " " + filesizename[i]) + +parseUri = () -> + oldString = $("add_links").value + regxp = new RegExp('(ht|f)tp(s?):\/\/[a-zA-Z0-9\-\.\/\?=_&%#]+[<| |\"|\'|\r|\n|\t]{1}', 'g') + resu = oldString.match regxp + return if resu == null + res = ""; + + for part in resu + if part.indexOf(" ") != -1 + res = res + part.replace(" ", " \n") + else if part.indexOf("\t") != -1 + res = res + part.replace("\t", " \n") + else if part.indexOf("\r") != -1 + res = res + part.replace("\r", " \n") + else if part.indexOf("\"") != -1 + res = res + part.replace("\"", " \n") + else if part.indexOf("<") != -1 + res = res + part.replace("<", " \n") + else if part.indexOf("'") != -1 + res = res + part.replace("'", " \n") + else + res = res + part.replace("\n", " \n") + + $("add_links").value = res; + + +Array::remove = (from, to) -> + rest = this.slice((to || from) + 1 || this.length) + this.length = from < 0 ? this.length + from : from + return [] if this.length == 0 + return this.push.apply(this, rest) + + +document.addEvent "domready", -> + + # global notification + root.notify = new Purr { + 'mode': 'top' + 'position': 'center' + } + + root.captchaBox = new MooDialog {destroyOnHide: false} + root.captchaBox.setContent $ 'cap_box' + + root.addBox = new MooDialog {destroyOnHide: false} + root.addBox.setContent $ 'add_box' + + $('add_form').onsubmit = -> + $('add_form').target = 'upload_target' + if $('add_name').value is "" and $('add_file').value is "" + alert '{{_("Please Enter a packagename.")}}' + return false + else + root.addBox.close() + return true + + $('add_reset').addEvent 'click', -> root.addBox.close() + + $('action_add').addEvent 'click', -> $("add_form").reset(); root.addBox.open() + $('action_play').addEvent 'click', -> new Request({method: 'get', url: '/api/unpauseServer'}).send() + $('action_cancel').addEvent 'click', -> new Request({method: 'get', url: '/api/stopAllDownloads'}).send() + $('action_stop').addEvent 'click', -> new Request({method: 'get', url: '/api/pauseServer'}).send() + + + # captcha events + + $('cap_info').addEvent 'click', -> + load_captcha "get", "" + root.captchaBox.open() + $('cap_reset').addEvent 'click', -> root.captchaBox.close() + $('cap_form').addEvent 'submit', (e) -> + submit_captcha() + e.stop() + + $('cap_positional').addEvent 'click', on_captcha_click + + new Request.JSON({ + url: "/json/status" + onSuccess: LoadJsonToContent + secure: false + async: true + initialDelay: 0 + delay: 4000 + limit: 3000 + }).startTimer() + +LoadJsonToContent = (data) -> + $("speed").set 'text', humanFileSize(data.speed)+"/s" + $("aktiv").set 'text', data.active + $("aktiv_from").set 'text', data.queue + $("aktiv_total").set 'text', data.total + + if data.captcha + if $("cap_info").getStyle("display") != "inline" + $("cap_info").setStyle 'display', 'inline' + root.notify.alert '{{_("New Captcha Request")}}', { + 'className': 'notify' + } + else + $("cap_info").setStyle 'display', 'none' + + + if data.download + $("time").set 'text', ' {{_("on")}}' + $("time").setStyle 'background-color', "#8ffc25" + else + $("time").set 'text', ' {{_("off")}}' + $("time").setStyle 'background-color', "#fc6e26" + + if data.reconnect + $("reconnect").set 'text', ' {{_("on")}}' + $("reconnect").setStyle 'background-color', "#8ffc25" + else + $("reconnect").set 'text', ' {{_("off")}}' + $("reconnect").setStyle 'background-color', "#fc6e26" + + return null + + +set_captcha = (data) -> + $('cap_id').set 'value', data.id + if (data.result_type is 'textual') + $('cap_textual_img').set 'src', data.src + $('cap_title').set 'text', '{{_("Please read the text on the captcha.")}}' + $('cap_submit').setStyle 'display', 'inline' + $('cap_textual').setStyle 'display', 'block' + $('cap_positional').setStyle 'display', 'none' + + else if (data.result_type == 'positional') + $('cap_positional_img').set('src', data.src) + $('cap_title').set('text', '{{_("Please click on the right captcha position.")}}') + $('cap_submit').setStyle('display', 'none') + $('cap_textual').setStyle('display', 'none') + + +load_captcha = (method, post) -> + new Request.JSON({ + url: "/json/set_captcha" + onSuccess: (data) -> set_captcha(data) if data.captcha else clear_captcha() + secure: false + async: true + method: method + }).send(post) + +clear_captcha = -> + $('cap_textual').setStyle 'display', 'none' + $('cap_textual_img').set 'src', '' + $('cap_positional').setStyle 'display', 'none' + $('cap_positional_img').set 'src', '' + $('cap_title').set 'text', '{{_("No Captchas to read.")}}' + +submit_captcha = -> + load_captcha("post", "cap_id=" + $('cap_id').get('value') + "&cap_result=" + $('cap_result').get('value') ); + $('cap_result').set('value', '') + false + +on_captcha_click = (e) -> + position = e.target.getPosition() + x = e.page.x - position.x + y = e.page.y - position.y + $('cap_result').value = x + "," + y + submit_captcha() diff --git a/module/web/themes/default/js/sources/filemanager.js b/module/web/themes/default/js/sources/filemanager.js new file mode 100644 index 000000000..be2f51e13 --- /dev/null +++ b/module/web/themes/default/js/sources/filemanager.js @@ -0,0 +1,291 @@ +var load, rename_box, confirm_box; + +document.addEvent("domready", function() { + load = new Fx.Tween($("load-indicator"), {link: "cancel"}); + load.set("opacity", 0); + + rename_box = new Fx.Tween($('rename_box')); + confirm_box = new Fx.Tween($('confirm_box')); + $('rename_reset').addEvent('click', function() { + hide_rename_box() + }); + $('delete_reset').addEvent('click', function() { + hide_confirm_box() + }); + + /*$('filemanager_actions_list').getChildren("li").each(function(action) { + var action_name = action.className; + if(functions[action.className] != undefined) + { + action.addEvent('click', functions[action.className]); + } + });*/ +}); + +function indicateLoad() { + //$("load-indicator").reveal(); + load.start("opacity", 1) +} + +function indicateFinish() { + load.start("opacity", 0) +} + +function indicateSuccess() { + indicateFinish(); + notify.alert('{{_("Success")}}.', { + 'className': 'success' + }); +} + +function indicateFail() { + indicateFinish(); + notify.alert('{{_("Failed")}}.', { + 'className': 'error' + }); +} + +function show_rename_box() { + bg_show(); + $("rename_box").setStyle('display', 'block'); + rename_box.start('opacity', 1) +} + +function hide_rename_box() { + bg_hide(); + rename_box.start('opacity', 0).chain(function() { + $('rename_box').setStyle('display', 'none'); + }); +} + +function show_confirm_box() { + bg_show(); + $("confirm_box").setStyle('display', 'block'); + confirm_box.start('opacity', 1) +} + +function hide_confirm_box() { + bg_hide(); + confirm_box.start('opacity', 0).chain(function() { + $('confirm_box').setStyle('display', 'none'); + }); +} + +var FilemanagerUI = new Class({ + initialize: function(url, type) { + this.url = url; + this.type = type; + this.directories = []; + this.files = []; + this.parseChildren(); + }, + + parseChildren: function() { + $("directories-list").getChildren("li.folder").each(function(ele) { + var path = ele.getElements("input.path")[0].get("value"); + var name = ele.getElements("input.name")[0].get("value"); + this.directories.push(new Item(this, path, name, ele)) + }.bind(this)); + + $("directories-list").getChildren("li.file").each(function(ele) { + var path = ele.getElements("input.path")[0].get("value"); + var name = ele.getElements("input.name")[0].get("value"); + this.files.push(new Item(this, path, name, ele)) + }.bind(this)); + } +}); + +var Item = new Class({ + initialize: function(ui, path, name, ele) { + this.ui = ui; + this.path = path; + this.name = name; + this.ele = ele; + this.directories = []; + this.files = []; + this.actions = new Array(); + this.actions["delete"] = this.del; + this.actions["rename"] = this.rename; + this.actions["mkdir"] = this.mkdir; + this.parseElement(); + + var pname = this.ele.getElements("span")[0]; + this.buttons = new Fx.Tween(this.ele.getElements(".buttons")[0], {link: "cancel"}); + this.buttons.set("opacity", 0); + + pname.addEvent("mouseenter", function(e) { + this.buttons.start("opacity", 1) + }.bind(this)); + + pname.addEvent("mouseleave", function(e) { + this.buttons.start("opacity", 0) + }.bind(this)); + + }, + + parseElement: function() { + this.ele.getChildren('span span.buttons img').each(function(img) { + img.addEvent('click', this.actions[img.className].bind(this)); + }, this); + + //click on the directory name must open the directory itself + this.ele.getElements('b')[0].addEvent('click', this.toggle.bind(this)); + + //iterate over child directories + var uls = this.ele.getElements('ul'); + if(uls.length > 0) + { + uls[0].getChildren("li.folder").each(function(fld) { + var path = fld.getElements("input.path")[0].get("value"); + var name = fld.getElements("input.name")[0].get("value"); + this.directories.push(new Item(this, path, name, fld)); + }.bind(this)); + uls[0].getChildren("li.file").each(function(fld) { + var path = fld.getElements("input.path")[0].get("value"); + var name = fld.getElements("input.name")[0].get("value"); + this.files.push(new Item(this, path, name, fld)); + }.bind(this)); + } + }, + + reorderElements: function() { + //TODO sort the main ul again (to keep data ordered after renaming something) + }, + + del: function(event) { + $("confirm_form").removeEvents("submit"); + $("confirm_form").addEvent("submit", this.deleteDirectory.bind(this)); + + $$("#confirm_form p").set('html', '{{_(("Are you sure you want to delete the selected item?"))}}'); + + show_confirm_box(); + event.stop(); + }, + + deleteDirectory: function(event) { + hide_confirm_box(); + new Request.JSON({ + method: 'POST', + url: "/json/filemanager/delete", + data: {"path": this.path, "name": this.name}, + onSuccess: function(data) { + if(data.response == "success") + { + new Fx.Tween(this.ele).start('opacity', 0); + var ul = this.ele.parentNode; + this.ele.dispose(); + //if this was the only child, add a "empty folder" div + if(!ul.getChildren('li')[0]) + { + var div = new Element("div", { 'html': '{{ _("Folder is empty") }}' }); + div.replaces(ul); + } + + indicateSuccess(); + } else + { + //error from json code... + indicateFail(); + } + }.bind(this), + onFailure: indicateFail + }).send(); + + event.stop(); + }, + + rename: function(event) { + $("rename_form").removeEvents("submit"); + $("rename_form").addEvent("submit", this.renameDirectory.bind(this)); + + $("path").set("value", this.path); + $("old_name").set("value", this.name); + $("new_name").set("value", this.name); + + show_rename_box(); + event.stop(); + }, + + renameDirectory: function(event) { + hide_rename_box(); + new Request.JSON({ + method: 'POST', + url: "/json/filemanager/rename", + onSuccess: function(data) { + if(data.response == "success") + { + this.name = $("new_name").get("value"); + this.ele.getElements("b")[0].set('html', $("new_name").get("value")); + this.reorderElements(); + indicateSuccess(); + } else + { + //error from json code... + indicateFail(); + } + }.bind(this), + onFailure: indicateFail + }).send($("rename_form").toQueryString()); + + event.stop(); + }, + + mkdir: function(event) { + new Request.JSON({ + method: 'POST', + url: "/json/filemanager/mkdir", + data: {"path": this.path + "/" + this.name, "name": '{{_("New folder")}}'}, + onSuccess: function(data) { + if(data.response == "success") + { + new Request.HTML({ + method: 'POST', + url: "/filemanager/get_dir", + data: {"path": data.path, "name": data.name}, + onSuccess: function(li) { + //add node as first child of ul + var ul = this.ele.getChildren('ul')[0]; + if(!ul) + { + //remove the "Folder Empty" div + this.ele.getChildren('div').dispose(); + + //create new ul to contain subfolder + ul = new Element("ul"); + ul.inject(this.ele, 'bottom'); + } + li[0].inject(ul, 'top'); + + //add directory as a subdirectory of the current item + this.directories.push(new Item(this.ui, data.path, data.name, ul.firstChild)); + }.bind(this), + onFailure: indicateFail + }).send(); + indicateSuccess(); + } else + { + //error from json code... + indicateFail(); + } + }.bind(this), + onFailure: indicateFail + }).send(); + + event.stop(); + }, + + toggle: function() { + var child = this.ele.getElement('ul'); + if(child == null) + child = this.ele.getElement('div'); + + if(child != null) + { + if (child.getStyle('display') == "block") { + child.dissolve(); + } else { + child.reveal(); + } + } + } +}); diff --git a/module/web/themes/default/js/sources/package.js b/module/web/themes/default/js/sources/package.js new file mode 100644 index 000000000..5d0ecbd3e --- /dev/null +++ b/module/web/themes/default/js/sources/package.js @@ -0,0 +1,376 @@ +var root = this; + +document.addEvent("domready", function() { + root.load = new Fx.Tween($("load-indicator"), {link: "cancel"}); + root.load.set("opacity", 0); + + + root.packageBox = new MooDialog({destroyOnHide: false}); + root.packageBox.setContent($('pack_box')); + + $('pack_reset').addEvent('click', function() { + $('pack_form').reset(); + root.packageBox.close(); + }); +}); + +function indicateLoad() { + //$("load-indicator").reveal(); + root.load.start("opacity", 1) +} + +function indicateFinish() { + root.load.start("opacity", 0) +} + +function indicateSuccess() { + indicateFinish(); + root.notify.alert('{{_("Success")}}.', { + 'className': 'success' + }); +} + +function indicateFail() { + indicateFinish(); + root.notify.alert('{{_("Failed")}}.', { + 'className': 'error' + }); +} + +var PackageUI = new Class({ + initialize: function(url, type) { + this.url = url; + this.type = type; + this.packages = []; + this.parsePackages(); + + this.sorts = new Sortables($("package-list"), { + constrain: false, + clone: true, + revert: true, + opacity: 0.4, + handle: ".package_drag", + onComplete: this.saveSort.bind(this) + }); + + $("del_finished").addEvent("click", this.deleteFinished.bind(this)); + $("restart_failed").addEvent("click", this.restartFailed.bind(this)); + + }, + + parsePackages: function() { + $("package-list").getChildren("li").each(function(ele) { + var id = ele.getFirst().get("id").match(/[0-9]+/); + this.packages.push(new Package(this, id, ele)) + }.bind(this)) + }, + + loadPackages: function() { + }, + + deleteFinished: function() { + indicateLoad(); + new Request.JSON({ + method: 'get', + url: '/api/deleteFinished', + onSuccess: function(data) { + if (data.length > 0) { + window.location.reload() + } else { + this.packages.each(function(pack) { + pack.close(); + }); + indicateSuccess(); + } + }.bind(this), + onFailure: indicateFail + }).send(); + }, + + restartFailed: function() { + indicateLoad(); + new Request.JSON({ + method: 'get', + url: '/api/restartFailed', + onSuccess: function(data) { + this.packages.each(function(pack) { + pack.close(); + }); + indicateSuccess(); + }.bind(this), + onFailure: indicateFail + }).send(); + }, + + startSort: function(ele, copy) { + }, + + saveSort: function(ele, copy) { + var order = []; + this.sorts.serialize(function(li, pos) { + if (li == ele && ele.retrieve("order") != pos) { + order.push(ele.retrieve("pid") + "|" + pos) + } + li.store("order", pos) + }); + if (order.length > 0) { + indicateLoad(); + new Request.JSON({ + method: 'get', + url: '/json/package_order/' + order[0], + onSuccess: indicateFinish, + onFailure: indicateFail + }).send(); + } + } + +}); + +var Package = new Class({ + initialize: function(ui, id, ele, data) { + this.ui = ui; + this.id = id; + this.linksLoaded = false; + + if (!ele) { + this.createElement(data); + } else { + this.ele = ele; + this.order = ele.getElements("div.order")[0].get("html"); + this.ele.store("order", this.order); + this.ele.store("pid", this.id); + this.parseElement(); + } + + var pname = this.ele.getElements(".packagename")[0]; + this.buttons = new Fx.Tween(this.ele.getElements(".buttons")[0], {link: "cancel"}); + this.buttons.set("opacity", 0); + + pname.addEvent("mouseenter", function(e) { + this.buttons.start("opacity", 1) + }.bind(this)); + + pname.addEvent("mouseleave", function(e) { + this.buttons.start("opacity", 0) + }.bind(this)); + + + }, + + createElement: function() { + alert("create") + }, + + parseElement: function() { + var imgs = this.ele.getElements('img'); + + this.name = this.ele.getElements('.name')[0]; + this.folder = this.ele.getElements('.folder')[0]; + this.password = this.ele.getElements('.password')[0]; + + imgs[1].addEvent('click', this.deletePackage.bind(this)); + imgs[2].addEvent('click', this.restartPackage.bind(this)); + imgs[3].addEvent('click', this.editPackage.bind(this)); + imgs[4].addEvent('click', this.movePackage.bind(this)); + + this.ele.getElement('.packagename').addEvent('click', this.toggle.bind(this)); + + }, + + loadLinks: function() { + indicateLoad(); + new Request.JSON({ + method: 'get', + url: '/json/package/' + this.id, + onSuccess: this.createLinks.bind(this), + onFailure: indicateFail + }).send(); + }, + + createLinks: function(data) { + var ul = $("sort_children_{id}".substitute({"id": this.id})); + ul.set("html", ""); + data.links.each(function(link) { + link.id = link.fid; + var li = new Element("li", { + "style": { + "margin-left": 0 + } + }); + + var html = "<span style='cursor: move' class='child_status sorthandle'><img src='../img/{icon}' style='width: 12px; height:12px;'/></span>\n".substitute({"icon": link.icon}); + html += "<span style='font-size: 15px'><a href=\"{url}\" target=\"_blank\">{name}</a></span><br /><div class='child_secrow'>".substitute({"url": link.url, "name": link.name}); + html += "<span class='child_status'>{statusmsg}</span>{error} ".substitute({"statusmsg": link.statusmsg, "error":link.error}); + html += "<span class='child_status'>{format_size}</span>".substitute({"format_size": link.format_size}); + html += "<span class='child_status'>{plugin}</span> ".substitute({"plugin": link.plugin}); + html += "<img title='{{_(\"Delete Link\")}}' style='cursor: pointer;' width='10px' height='10px' src='../img/delete.png' /> "; + html += "<img title='{{_(\"Restart Link\")}}' style='cursor: pointer;margin-left: -4px' width='10px' height='10px' src='../img/arrow_refresh.png' /></div>"; + + var div = new Element("div", { + "id": "file_" + link.id, + "class": "child", + "html": html + }); + + li.store("order", link.order); + li.store("lid", link.id); + + li.adopt(div); + ul.adopt(li); + }); + this.sorts = new Sortables(ul, { + constrain: false, + clone: true, + revert: true, + opacity: 0.4, + handle: ".sorthandle", + onComplete: this.saveSort.bind(this) + }); + this.registerLinkEvents(); + this.linksLoaded = true; + indicateFinish(); + this.toggle(); + }, + + registerLinkEvents: function() { + this.ele.getElements('.child').each(function(child) { + var lid = child.get('id').match(/[0-9]+/); + var imgs = child.getElements('.child_secrow img'); + imgs[0].addEvent('click', function(e) { + new Request({ + method: 'get', + url: '/api/deleteFiles/[' + this + "]", + onSuccess: function() { + $('file_' + this).nix() + }.bind(this), + onFailure: indicateFail + }).send(); + }.bind(lid)); + + imgs[1].addEvent('click', function(e) { + new Request({ + method: 'get', + url: '/api/restartFile/' + this, + onSuccess: function() { + var ele = $('file_' + this); + var imgs = ele.getElements("img"); + imgs[0].set("src", "../img/status_queue.png"); + var spans = ele.getElements(".child_status"); + spans[1].set("html", "queued"); + indicateSuccess(); + }.bind(this), + onFailure: indicateFail + }).send(); + }.bind(lid)); + }); + }, + + toggle: function() { + var child = this.ele.getElement('.children'); + if (child.getStyle('display') == "block") { + child.dissolve(); + } else { + if (!this.linksLoaded) { + this.loadLinks(); + } else { + child.reveal(); + } + } + }, + + + deletePackage: function(event) { + indicateLoad(); + new Request({ + method: 'get', + url: '/api/deletePackages/[' + this.id + "]", + onSuccess: function() { + this.ele.nix(); + indicateFinish(); + }.bind(this), + onFailure: indicateFail + }).send(); + //hide_pack(); + event.stop(); + }, + + restartPackage: function(event) { + indicateLoad(); + new Request({ + method: 'get', + url: '/api/restartPackage/' + this.id, + onSuccess: function() { + this.close(); + indicateSuccess(); + }.bind(this), + onFailure: indicateFail + }).send(); + event.stop(); + }, + + close: function() { + var child = this.ele.getElement('.children'); + if (child.getStyle('display') == "block") { + child.dissolve(); + } + var ul = $("sort_children_{id}".substitute({"id": this.id})); + ul.erase("html"); + this.linksLoaded = false; + }, + + movePackage: function(event) { + indicateLoad(); + new Request({ + method: 'get', + url: '/json/move_package/' + ((this.ui.type + 1) % 2) + "/" + this.id, + onSuccess: function() { + this.ele.nix(); + indicateFinish(); + }.bind(this), + onFailure: indicateFail + }).send(); + event.stop(); + }, + + editPackage: function(event) { + $("pack_form").removeEvents("submit"); + $("pack_form").addEvent("submit", this.savePackage.bind(this)); + + $("pack_id").set("value", this.id); + $("pack_name").set("value", this.name.get("text")); + $("pack_folder").set("value", this.folder.get("text")); + $("pack_pws").set("value", this.password.get("text")); + + root.packageBox.open(); + event.stop(); + }, + + savePackage: function(event) { + $("pack_form").send(); + this.name.set("text", $("pack_name").get("value")); + this.folder.set("text", $("pack_folder").get("value")); + this.password.set("text", $("pack_pws").get("value")); + root.packageBox.close(); + event.stop(); + }, + + saveSort: function(ele, copy) { + var order = []; + this.sorts.serialize(function(li, pos) { + if (li == ele && ele.retrieve("order") != pos) { + order.push(ele.retrieve("lid") + "|" + pos) + } + li.store("order", pos) + }); + if (order.length > 0) { + indicateLoad(); + new Request.JSON({ + method: 'get', + url: '/json/link_order/' + order[0], + onSuccess: indicateFinish, + onFailure: indicateFail + }).send(); + } + } + +}); diff --git a/module/web/themes/default/js/sources/purr.js b/module/web/themes/default/js/sources/purr.js new file mode 100644 index 000000000..9cbc503d9 --- /dev/null +++ b/module/web/themes/default/js/sources/purr.js @@ -0,0 +1,309 @@ +/* +--- +script: purr.js + +description: Class to create growl-style popup notifications. + +license: MIT-style + +authors: [atom smith] + +requires: +- core/1.3: [Core, Browser, Array, Function, Number, String, Hash, Event, Class.Extras, Element.Event, Element.Style, Element.Dimensions, Fx.CSS, FX.Tween, Fx.Morph] + +provides: [Purr, Element.alert] +... +*/ + + +var Purr = new Class({ + + 'options': { + 'mode': 'top', + 'position': 'left', + 'elementAlertClass': 'purr-element-alert', + 'elements': { + 'wrapper': 'div', + 'alert': 'div', + 'buttonWrapper': 'div', + 'button': 'button' + }, + 'elementOptions': { + 'wrapper': { + 'styles': { + 'position': 'fixed', + 'z-index': '9999' + }, + 'class': 'purr-wrapper' + }, + 'alert': { + 'class': 'purr-alert', + 'styles': { + 'opacity': '.85' + } + }, + 'buttonWrapper': { + 'class': 'purr-button-wrapper' + }, + 'button': { + 'class': 'purr-button' + } + }, + 'alert': { + 'buttons': [], + 'clickDismiss': true, + 'hoverWait': true, + 'hideAfter': 5000, + 'fx': { + 'duration': 500 + }, + 'highlight': false, + 'highlightRepeat': false, + 'highlight': { + 'start': '#FF0', + 'end': false + } + } + }, + + 'Implements': [Options, Events, Chain], + + 'initialize': function(options){ + this.setOptions(options); + this.createWrapper(); + return this; + }, + + 'bindAlert': function(){ + return this.alert.bind(this); + }, + + 'createWrapper': function(){ + this.wrapper = new Element(this.options.elements.wrapper, this.options.elementOptions.wrapper); + if(this.options.mode == 'top') + { + this.wrapper.setStyle('top', 0); + } + else + { + this.wrapper.setStyle('bottom', 0); + } + document.id(document.body).grab(this.wrapper); + this.positionWrapper(this.options.position); + }, + + 'positionWrapper': function(position){ + if(typeOf(position) == 'object') + { + + var wrapperCoords = this.getWrapperCoords(); + + this.wrapper.setStyles({ + 'bottom': '', + 'left': position.x, + 'top': position.y - wrapperCoords.height, + 'position': 'absolute' + }); + } + else if(position == 'left') + { + this.wrapper.setStyle('left', 0); + } + else if(position == 'right') + { + this.wrapper.setStyle('right', 0); + } + else + { + this.wrapper.setStyle('left', (window.innerWidth / 2) - (this.getWrapperCoords().width / 2)); + } + return this; + }, + + 'getWrapperCoords': function(){ + this.wrapper.setStyle('visibility', 'hidden'); + var measurer = this.alert('need something in here to measure'); + var coords = this.wrapper.getCoordinates(); + measurer.destroy(); + this.wrapper.setStyle('visibility',''); + return coords; + }, + + 'alert': function(msg, options){ + + options = Object.merge({}, this.options.alert, options || {}); + + var alert = new Element(this.options.elements.alert, this.options.elementOptions.alert); + + if(typeOf(msg) == 'string') + { + alert.set('html', msg); + } + else if(typeOf(msg) == 'element') + { + alert.grab(msg); + } + else if(typeOf(msg) == 'array') + { + var alerts = []; + msg.each(function(m){ + alerts.push(this.alert(m, options)); + }, this); + return alerts; + } + + alert.store('options', options); + + if(options.buttons.length > 0) + { + options.clickDismiss = false; + options.hideAfter = false; + options.hoverWait = false; + var buttonWrapper = new Element(this.options.elements.buttonWrapper, this.options.elementOptions.buttonWrapper); + alert.grab(buttonWrapper); + options.buttons.each(function(button){ + if(button.text != undefined) + { + var callbackButton = new Element(this.options.elements.button, this.options.elementOptions.button); + callbackButton.set('html', button.text); + if(button.callback != undefined) + { + callbackButton.addEvent('click', button.callback.pass(alert)); + } + if(button.dismiss != undefined && button.dismiss) + { + callbackButton.addEvent('click', this.dismiss.pass(alert, this)); + } + buttonWrapper.grab(callbackButton); + } + }, this); + } + if(options.className != undefined) + { + alert.addClass(options.className); + } + + this.wrapper.grab(alert, (this.options.mode == 'top') ? 'bottom' : 'top'); + + var fx = Object.merge(this.options.alert.fx, options.fx); + var alertFx = new Fx.Morph(alert, fx); + alert.store('fx', alertFx); + this.fadeIn(alert); + + if(options.highlight) + { + alertFx.addEvent('complete', function(){ + alert.highlight(options.highlight.start, options.highlight.end); + if(options.highlightRepeat) + { + alert.highlight.periodical(options.highlightRepeat, alert, [options.highlight.start, options.highlight.end]); + } + }); + } + if(options.hideAfter) + { + this.dismiss(alert); + } + + if(options.clickDismiss) + { + alert.addEvent('click', function(){ + this.holdUp = false; + this.dismiss(alert, true); + }.bind(this)); + } + + if(options.hoverWait) + { + alert.addEvents({ + 'mouseenter': function(){ + this.holdUp = true; + }.bind(this), + 'mouseleave': function(){ + this.holdUp = false; + }.bind(this) + }); + } + + return alert; + }, + + 'fadeIn': function(alert){ + var alertFx = alert.retrieve('fx'); + alertFx.set({ + 'opacity': 0 + }); + alertFx.start({ + 'opacity': [this.options.elementOptions.alert.styles.opacity, .9].pick(), + }); + }, + + 'dismiss': function(alert, now){ + now = now || false; + var options = alert.retrieve('options'); + if(now) + { + this.fadeOut(alert); + } + else + { + this.fadeOut.delay(options.hideAfter, this, alert); + } + }, + + 'fadeOut': function(alert){ + if(this.holdUp) + { + this.dismiss.delay(100, this, [alert, true]) + return null; + } + var alertFx = alert.retrieve('fx'); + if(!alertFx) + { + return null; + } + var to = { + 'opacity': 0 + } + if(this.options.mode == 'top') + { + to['margin-top'] = '-'+alert.offsetHeight+'px'; + } + else + { + to['margin-bottom'] = '-'+alert.offsetHeight+'px'; + } + alertFx.start(to); + alertFx.addEvent('complete', function(){ + alert.destroy(); + }); + } +}); + +Element.implement({ + + 'alert': function(msg, options){ + var alert = this.retrieve('alert'); + if(!alert) + { + options = options || { + 'mode':'top' + }; + alert = new Purr(options) + this.store('alert', alert); + } + + var coords = this.getCoordinates(); + + alert.alert(msg, options); + + alert.wrapper.setStyles({ + 'bottom': '', + 'left': (coords.left - (alert.wrapper.getWidth() / 2)) + (this.getWidth() / 2), + 'top': coords.top - (alert.wrapper.getHeight()), + 'position': 'absolute' + }); + + } + +});
\ No newline at end of file diff --git a/module/web/themes/default/js/sources/settings.coffee b/module/web/themes/default/js/sources/settings.coffee new file mode 100644 index 000000000..68ca6c6a0 --- /dev/null +++ b/module/web/themes/default/js/sources/settings.coffee @@ -0,0 +1,107 @@ +root = this + +window.addEvent 'domready', -> + root.accountDialog = new MooDialog {destroyOnHide: false} + root.accountDialog.setContent $ 'account_box' + + new TinyTab $$('#toptabs li a'), $$('#tabs-body > span') + + $$('ul.nav').each (nav) -> + new MooDropMenu nav, { + onOpen: (el) -> el.fade 'in' + onClose: (el) -> el.fade 'out' + onInitialize: (el) -> el.fade('hide').set 'tween', {duration:500} + } + + new SettingsUI() + + +class SettingsUI + constructor: -> + @menu = $$ "#general-menu li" + @menu.append $$ "#plugin-menu li" + + @name = $ "tabsback" + @general = $ "general_form_content" + @plugin = $ "plugin_form_content" + + el.addEvent 'click', @menuClick.bind(this) for el in @menu + + $("general|submit").addEvent "click", @configSubmit.bind(this) + $("plugin|submit").addEvent "click", @configSubmit.bind(this) + + $("account_add").addEvent "click", (e) -> + root.accountDialog.open() + e.stop() + + $("account_reset").addEvent "click", (e) -> + root.accountDialog.close() + + $("account_add_button").addEvent "click", @addAccount.bind(this) + $("account_submit").addEvent "click", @submitAccounts.bind(this) + + + menuClick: (e) -> + [category, section] = e.target.get("id").split("|") + name = e.target.get "text" + + + target = if category is "general" then @general else @plugin + target.dissolve() + + new Request({ + "method" : "get" + "url" : "/json/load_config/#{category}/#{section}" + "onSuccess": (data) => + target.set "html", data + target.reveal() + this.name.set "text", name + }).send() + + + configSubmit: (e) -> + category = e.target.get("id").split("|")[0]; + form = $("#{category}_form"); + + form.set "send", { + "method": "post" + "url": "/json/save_config/#{category}" + "onSuccess" : -> + root.notify.alert '{{ _("Settings saved.")}}', { + 'className': 'success' + } + "onFailure": -> + root.notify.alert '{{ _("Error occured.")}}', { + 'className': 'error' + } + } + form.send() + e.stop() + + addAccount: (e) -> + form = $ "add_account_form" + form.set "send", { + "method": "post" + "onSuccess" : -> window.location.reload() + "onFailure": -> + root.notify.alert '{{_("Error occured.")}}', { + 'className': 'error' + } + } + + form.send() + e.stop() + + submitAccounts: (e) -> + form = $ "account_form" + form.set "send", { + "method": "post", + "onSuccess" : -> window.location.reload() + "onFailure": -> + root.notify.alert('{{ _("Error occured.") }}', { + 'className': 'error' + }); + } + + form.send() + e.stop() diff --git a/module/web/themes/default/js/sources/tinytab.js b/module/web/themes/default/js/sources/tinytab.js new file mode 100644 index 000000000..de50279fc --- /dev/null +++ b/module/web/themes/default/js/sources/tinytab.js @@ -0,0 +1,43 @@ +/* +--- +description: TinyTab - Tiny and simple tab handler for Mootools. + +license: MIT-style + +authors: +- Danillo César de O. Melo + +requires: +- core/1.2.4: '*' + +provides: TinyTab + +... +*/ +(function($) { + this.TinyTab = new Class({ + Implements: Events, + initialize: function(tabs, contents, opt) { + this.tabs = tabs; + this.contents = contents; + if(!opt) opt = {}; + this.css = opt.selectedClass || 'selected'; + this.select(this.tabs[0]); + tabs.each(function(el){ + el.addEvent('click',function(e){ + this.select(el); + e.stop(); + }.bind(this)); + }.bind(this)); + }, + + select: function(el) { + this.tabs.removeClass(this.css); + el.addClass(this.css); + this.contents.setStyle('display','none'); + var content = this.contents[this.tabs.indexOf(el)]; + content.setStyle('display','block'); + this.fireEvent('change',[content,el]); + } + }); +})(document.id);
\ No newline at end of file |