(function ($) { window.OpenDrive = { helpers: {}, widgets: {}, templates: {}, factory: {}, forms: {}, popups: {}, _readyHandlers: [], ready: function (f) { if (f instanceof Function) this._readyHandlers.push(f); } }; OpenDrive.forms.initAjaxSubmit = function ($form, opts) { if (!$form.length) return; if (!opts) opts = {}; $form.on('submit', function () { if (!$form.data('disabled')) { function removeDisabled() { $form.removeData('disabled'); $btn.removeClass('disabled') .attr('disabled', false) .find('.js-spinner-rotate') .remove(); } var $btn = $form.find('[type="submit"]'); $btn .addClass('disabled') .attr('disabled', true) .append(''); $form.data('disabled', true); OpenDrive.ajax.do(null, $form.serialize(), function (response) { removeDisabled(); if (opts.onAfterSubmit) opts.onAfterSubmit.call($form, response); }, function () { removeDisabled(); }) } return false; }) }; OpenDrive.popups = { showNotification: function (msg, timeout) { this.show(msg, 'notification', timeout); }, showError: function (msg, timeout) { this.show(msg, 'error', timeout); }, showWarning: function (msg, timeout) { this.show(msg, 'warning', timeout); }, show: function (msgText, type, timeout) { $('.js-popup-message').remove(); var $msg = $(OpenDrive.helpers.applyTemplate({type: type, message: msgText}, 'PopupTemplate')); $(document.body).append($msg); if (!timeout) timeout = 7000; setTimeout(function () { $msg.fadeOutRemove(); }, timeout); } }; $(document).ready(function(){ $(".btn-close-popup").on("click",function(){ $(".popup-message").css("display","none"); }); }); $(document).click(function() { if($(".popup-message").is(':visible')) { $(".popup-message").css("display","none"); } }); OpenDrive.helpers.ellipsisMiddle = function (el) { var $el = el instanceof jQuery ? el : [el]; if (!document.documentElement.contains($el[0])) return; for (var j = 0; el = $el[j++];) { el.style.overflowX = 'hidden'; el.style.whiteSpace = 'nowrap'; var text, i, maxI, newText, odd, dataText = el.getAttribute('data-original-text'); if (dataText) { text = dataText; el.innerHTML = text; el.title = dataText; } else el.setAttribute('data-original-text', (text = $(el).text())); if (text.length <= 2 || (el.clientWidth + 1) >= el.scrollWidth) break; //Add 1px due bug in IE maxI = Math.ceil(text.length / 2); i = maxI; odd = text.length % 2; do { newText = text.substr(0, i + odd) + '...' + text.substr(-i); el.innerHTML = newText; --i; } while (i > 0 && el.clientWidth < el.scrollWidth); } }; OpenDrive.helpers.humanFileSize = function (bytes, si) { var thresh = si ? 1000 : 1024; if (bytes < thresh) return bytes + ' B'; var units = si ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; var u = -1; do { bytes /= thresh; ++u; } while (bytes >= thresh); return bytes.toFixed(1) + ' ' + units[u]; }; OpenDrive.helpers.humanFileSizeShort = function (bytes) { var quant_arr = {'TB' : 1099511627776, 'GB' : 1073741824, 'MB' : 1048576, 'kB': 1024, 'B' : 1} for(var unit in quant_arr){ var mag = quant_arr[unit]; if ( bytes >= mag ) { return (bytes / mag).toFixed(0)+' '+unit; } } }; /** * Place ellipsis in the middle of string * * @param opts */ $.fn.ellipsisMiddle = function (opts) { opts = opts || {}; this.each(function (i, item) { if (opts.reinitialize) item.removeAttribute('data-original-text'); OpenDrive.helpers.ellipsisMiddle(item); }) }; $.fn.escape = function (callback) { return this.each(function () { $(document).on('keydown', this, function (e) { var keycode = (e.keyCode ? e.keyCode : e.which); if (keycode === 27) { callback.call(this, e); } }); }); }; $.fn.fadeOutRemove = function (speed) { this.each(function (i, item) { var $item = $(item); $item.fadeOut(speed, function () { $item.remove(); }) }); }; $.ajaxSetup({ beforeSend: function (xhr) { var token = document.body.getAttribute('data-csrftoken'); if (token != null) xhr.setRequestHeader('X-Ajax-CSRF-Token', token); return true; }, statusCode: { 403: function(jqXHR, textStatus, errorThrown) { if(jqXHR.responseText === "") window.location.href = '/login'; } } }); /** * Apply handlebars template * * @param data Object * @param template jQuery instance * @param target jQuery instance|null to return html * @param replace bool Replace target or target content * @returns {*} */ OpenDrive.helpers.applyTemplate = function (data, template, target, replace) { var compiled; if (typeof template === 'string') { compiled = OpenDrive.templates[template]; if (!compiled) throw 'Invalid template'; } else if(template){ compiled = template.data('compiled-template'); if (!compiled) { compiled = Handlebars.compile(template.html()); template.data('compiled-template', compiled); } } else throw 'Invalid template'; if (target) { if (replace) target.replaceWith(compiled(data)); else target.html(compiled(data)); } else return compiled(data); }; OpenDrive.factory.ajax = function (url) { var onSuceessHooks = []; this.registerHook = function (fn) { if (fn) onSuceessHooks.push(fn); }; this.do = function (action, data, callbackSuccess, callbackFailure) { var ajaxData; if (typeof data === 'string') ajaxData = data; else { ajaxData = action ? {action: action} : {}; if (data instanceof Object) $.extend(ajaxData, data); } return $.post(url, ajaxData, function (response) { if (response && response.new_csrf_token) { document.body.setAttribute('data-csrftoken', response.new_csrf_token); delete response.new_csrf_token; } for (var i = 0; i < onSuceessHooks.length; i++) { var result = onSuceessHooks[i](response); if (result === false) break; else if (result === true || result === 'error') { if (result === 'error' && callbackFailure instanceof Function) callbackFailure(); return; } } if (callbackSuccess instanceof Function) callbackSuccess(response); }, 'json').fail(function () { if (callbackFailure instanceof Function) callbackFailure(); }); }; this.registerHook(function (data) { if (data && data.new_csrf_token) { document.body.setAttribute('data-csrftoken', data.new_csrf_token); delete data.new_csrf_token; } }); this.registerHook(function (data) { if (data && data.error && data.error.code == 401 && data.redirect_url) { location.replace(data.redirect_url); return true; } }); this.registerHook(function (data) { if (data && data.error && data.error.message) { OpenDrive.popups.showError(data.error.message); return 'error'; } }); return this; }; OpenDrive.ajax = new OpenDrive.factory.ajax('/ajax'); OpenDrive.helpers.escapeHTML = function(text){ text = text .replace(/ /g, ' ') .replace(/\s{2,}/g, ' ') .replace(//g, '>') .replace(/"/g, '"') /*.replace(/&/g, '&')*/ .replace(/'/g, '''); return text; }; OpenDrive.widgets.RootMenu = function (el) { var rootMenuItems = $('.js-root-menu-items'); var bottomPanel = $('.js-bottom-panel-actions'); var rootMenu = $('.js-root-menu'); var firstMenuItem = $('.js-first-menu-item'); var _this = this; if(!rootMenu.length) return; this.resize = function () { var rootMenuHeight = $(window).height() - rootMenu.offset().top; if (rootMenuItems.length > 0) { if (bottomPanel.length) rootMenuHeight -= bottomPanel.outerHeight(true); rootMenuHeight -= firstMenuItem.outerHeight(true); rootMenuItems.height(rootMenuHeight); } }; this.scrollToElement = function (el) { if (el) { this.resize(); if (!(el instanceof jQuery)) el = $(el); if(!el.length) return; rootMenuItems[0].scrollTop = el.offset().top - rootMenuItems.offset().top; rootMenuItems.perfectScrollbar('update'); } }; this.showPrimaryMenu = function (show) { var buttons = firstMenuItem.find('.js-create-subfolder, .js-item-menu-btn'); if (show) buttons.show(); else buttons.hide(); }; $(window).resize(function () { _this.resize(); }); _this.resize(); rootMenuItems.perfectScrollbar({theme: 'od'}); this.scrollToElement(el); return this; }; OpenDrive.widgets.ItemTabs = function (itemType, sessionToken) { var breadcrumbsContainer = $('.js-breadcrumbs-container'), content = $('.js-scroll-content'), tabsHeaderContainer = $('.js-item-tabs'), ITEM_TAB = '.js-tab-content', ITEM_TITLE = '.js-tab-title', ITEM_TABHEADER = '.js-item-tab', ITEM_BREADCRUMB = '.js-breadcrumb', _this = this, lruTabs = {}, tabScrollTop = {}, tabMargin, activeTabId; this.openTab = function (id, params, opts) { var $tab = _this.getTab(id); if ($tab.length) return { tab: $tab, exists: true, breadcrumb: _this.getBreadCrumb(id), id: $tab.data('itemid') }; if (params.breadCrumb) { breadcrumbsContainer.append(params.breadCrumb); } $tab = $('
'); $tab.attr('data-itemid', id); if (params.tabContent) $tab.empty().append(params.tabContent); content.append($tab); $tab.data('TabOptions', opts); var titleOpts = params.titleOpts || {}; titleOpts.ItemId = id; titleOpts.Name = params.Name; titleOpts.noActivate = params.noActivate; if(!titleOpts.Hidden) { var tabTitle = OpenDrive.helpers.applyTemplate(titleOpts, 'TabTitle'); if (params.isFirst) tabsHeaderContainer.prepend(tabTitle); else tabsHeaderContainer.append(tabTitle); } if (!params.noActivate) { _this.activateTab(id); } else { $tab.hide(); hideBreadcrumb(id); } onResize(); _this.sessionTabs.save(); return { tab: $tab, breadcrumb: _this.getBreadCrumb(id) }; }; this.getContainer = function () { return tabsHeaderContainer; }; function deactivateAllTabs() { tabsHeaderContainer.find(ITEM_TABHEADER + '.active').removeClass('active'); content.find(ITEM_TAB).hide(); } function hideAllBreadcrumbs() { breadcrumbsContainer.find(ITEM_BREADCRUMB).hide(); } function showBreadcrumb(id) { _this.getBreadCrumb(id).show(); } function hideBreadcrumb(id) { breadcrumbsContainer.find(ITEM_BREADCRUMB + '[data-itemid="' + id + '"]').hide(); } this.updateTab = function (id, content) { var $tab = _this.getTab(id); if ($tab.length) $tab[0].innerHTML = content; }; this.updateTabTitle = function (id, text) { var tabHeader = _this.getTabHeader(id); tabHeader.find(ITEM_TITLE).text(text).attr('title', text); if (tabHeader.hasClass('active')) document.title = text; }; this.getTab = function (id) { return content.find(ITEM_TAB + '[data-itemid="' + id + '"]'); }; this.getFirstTab = function () { return content.find(ITEM_TAB).eq(0); }; this.getTabHeader = function (id) { return tabsHeaderContainer.find(ITEM_TABHEADER + '[data-itemid="' + id + '"]'); }; this.getBreadCrumb = function (id) { return breadcrumbsContainer.find(ITEM_BREADCRUMB + '[data-itemid="' + id + '"]'); }; function getTabOptions($tab) { return $tab.data('TabOptions') || {}; } this.closeTab = function (id, noActivate, noSave) { var $tab = _this.getTab(id); if ($tab.length) { var opts = getTabOptions($tab), activatedTabId; if (opts.close) opts.close.call($tab); _this.getBreadCrumb(id).remove(); tabsHeaderContainer.find(ITEM_TABHEADER + '[data-itemid="' + id + '"]').remove(); $tab.remove(); delete lruTabs[id]; delete tabScrollTop[id]; if (!noActivate) { if (Object.keys(lruTabs).length) { var minTime = 0; for (var i in lruTabs) { if (lruTabs.hasOwnProperty(i)) { if (lruTabs[i] > minTime) { activatedTabId = i; minTime = lruTabs[i]; } } } if (activatedTabId && !_this.activateTab(activatedTabId)) { activatedTabId = false; } } if (!activatedTabId) { var firstTab = this.getFirstTab(); if (firstTab.length) _this.activateTab(firstTab.data('itemid')); } } onResize(); if (!noSave) _this.sessionTabs.save(); } }; this.getActiveTab = function () { var tabHeader = tabsHeaderContainer.find(ITEM_TABHEADER + '.active'); if (tabHeader.length) return _this.getTab(tabHeader.data('itemid')); }; this.activateTab = function (id, args) { var $tab = _this.getTab(id), opts = getTabOptions($tab); if (!$tab.length) return; if (activeTabId) tabScrollTop[activeTabId] = content[0].scrollTop; hideAllBreadcrumbs(); deactivateAllTabs(); var tabHeader = _this.getTabHeader(id); tabHeader.addClass('active'); document.title = tabHeader.text(); showBreadcrumb(id); $tab.show(); activeTabId = id; if (id in tabScrollTop) { content[0].scrollTop = tabScrollTop[id]; } lruTabs[id] = (new Date()).getTime(); if (opts.activate) opts.activate.call($tab, id, args); _this.sessionTabs.save(); return true; }; this.getActiveTab = function () { var tabHeader = tabsHeaderContainer.find(ITEM_TABHEADER + '.active'); if (tabHeader.length) return _this.getTab(tabHeader.data('itemid')); }; this.setTabLoadedStatus = function (itemId, active) { var header = _this.getTabHeader(itemId); if (header.length) header[active ? 'addClass' : 'removeClass']('tab-loaded'); }; tabsHeaderContainer.on('click', ITEM_TITLE, function () { var itemId = $(this).closest(ITEM_TABHEADER).data('itemid'); _this.activateTab(itemId); return false; }); tabsHeaderContainer.on('click', '.js-close-tab', function () { var itemId = $(this).closest(ITEM_TABHEADER).data('itemid'); _this.closeTab(itemId); return false; }); function onResize() { var tabsWidth = tabsHeaderContainer.width() - 1, tabs = tabsHeaderContainer.find(ITEM_TABHEADER); if (tabs.length > 1) { if (!tabMargin) tabMargin = tabs.outerWidth(true) - tabs.outerWidth(); tabs.css('max-width', (Math.floor(tabsWidth / tabs.length) - tabMargin ) + 'px'); } else tabs.css('max-width', 'auto'); } $(window).resize(onResize); onResize(); this.sessionTabs = new function () { this.save = function () { var tabs = content.find(ITEM_TAB); var tabsData = []; tabs.each(function () { var _this = $(this); var id = _this.data('itemid'); var opts = getTabOptions(_this); if (opts.save) { tabsData.push({id: id, data: opts.save.call(_this)}); } }); try { if (sessionToken) localStorage.setItem(itemType + 'Tabs-' + sessionToken, JSON.stringify(tabsData)); } catch (e) { } }; var sessionTabs; try { if (sessionToken) sessionTabs = JSON.parse(localStorage.getItem(itemType + 'Tabs-' + sessionToken)); } catch (e) { } if (!(sessionTabs instanceof Array)) sessionTabs = []; this.restore = function (restoreCallback) { if (sessionTabs.length) { restoreCallback(sessionTabs.shift()); return true; } }; this.clear = function () { try { for (var id in localStorage) { if (localStorage.hasOwnProperty(id) && id.toString().indexOf(itemType + 'Tabs') === 0) { localStorage.removeItem(id); } } } catch (e) { } }; this.getSessionData = function () { return sessionTabs; }; this.find = function (itemId) { for (var i = 0, item; item = (sessionTabs[i++]);) { if (item.id === itemId) return item; } }; }; } /** * * @param $item jQuery instance * @param saveCallback function * @param options * @param cancelCallback function * @constructor */ OpenDrive.widgets.EditableItem = function ($item, saveCallback, options, cancelCallback) { var _defaultOpts = { stripNL: true, trim: true, maxChars: null, initialValue: null }; if (!$item.length) throw 'No item'; $item = $item.first(); var hasEllipsisOverflow = $item.hasClass('ellipsis_overflow'); var caretAtStart = false; var oldHtml; options = $.extend(_defaultOpts, options || {}); options.maxLength = parseInt($item.data('maxlength')); if (isNaN(options.maxLength)) options.maxLength = 0; $item.prop('contenteditable', true) .addClass('editing-item') .removeClass('ellipsis_overflow') .focus(); $item.data('old-html', $item.html()); if (options.initialValue !== null) $item.html(options.initialValue); if (options.maxChars !== null) { $item.data('old-max-width', $item.css('max-width')); $item.css('max-width', options.maxChars + 'ch'); } function stopEdit() { oldHtml = $item.data('old-html'); $item[0].scrollLeft = 0; $item.off('focusout keydown blur click paste') .removeClass('editing-item') .removeData(['old-html', 'old-max-width']) .prop('contenteditable', false); if (hasEllipsisOverflow) $item.addClass('ellipsis_overflow') } $item.one('focusout blur', function () { stopEdit(); saveCallback.call($item, getItemText()); return false; }); $item.on('keydown', function (e) { if (e.keyCode == 13) { stopEdit(); saveCallback.call($item, getItemText()); return false; } if (e.keyCode == 27) { $item.html($item.data('old-html')); stopEdit(); e.preventDefault(); if (cancelCallback) cancelCallback.call($item); } e.stopPropagation(); }).on('click', function () { return false; }).on('paste', function (e) { e.preventDefault(); var text; if (e.originalEvent && e.originalEvent.clipboardData && e.originalEvent.clipboardData.getData) { text = e.originalEvent.clipboardData.getData('text/plain'); text = filterText(text); window.document.execCommand('insertText', false, text); } else if (e.clipboardData && e.clipboardData.getData) { text = e.clipboardData.getData('text/plain'); text = filterText(text); window.document.execCommand('insertText', false, text); } else if (window.clipboardData && window.clipboardData.getData) { text = window.clipboardData.getData('Text'); text = filterText(text); pasteHtmlAtCaret(text); } }); function getItemText() { var text = filterText($item.text()); if (options.maxLength) text = text.substr(0, options.maxLength); if (text == '') { $item.html(oldHtml); text = filterText($item.text()); } return text; } function filterText(text) { if (options.stripNL) text = stripNLCR(text); text.replace(/\s{2,}/g, ' '); if (options.trim) text = text.trim(); return text; } function stripNLCR(text) { return text.replace(/[\r\n]+/g, ' '); } function pasteHtmlAtCaret(html, selectPastedContent) { var sel, range; if (window.getSelection) { // IE9 and non-IE sel = window.getSelection(); if (sel.getRangeAt && sel.rangeCount) { range = sel.getRangeAt(0); range.deleteContents(); // Range.createContextualFragment() would be useful here but is // only relatively recently standardized and is not supported in // some browsers (IE9, for one) var el = document.createElement('div'); el.innerHTML = html; var frag = document.createDocumentFragment(), node, lastNode; while ((node = el.firstChild)) { lastNode = frag.appendChild(node); } var firstNode = frag.firstChild; range.insertNode(frag); // Preserve the selection if (lastNode) { range = range.cloneRange(); range.setStartAfter(lastNode); if (selectPastedContent) { range.setStartBefore(firstNode); } else { range.collapse(true); } sel.removeAllRanges(); sel.addRange(range); } } } else if ((sel = document.selection) && sel.type != 'Control') { // IE < 9 var originalRange = sel.createRange(); originalRange.collapse(true); sel.createRange().pasteHTML(html); if (selectPastedContent) { range = sel.createRange(); range.setEndPoint('StartToStart', originalRange); range.select(); } } } function createCaretPlacer(el, atStart) { if (!document.body.contains(el)) return; el.focus(); if (window.getSelection && typeof document.createRange) { var range = document.createRange(); range.selectNodeContents(el); range.collapse(atStart); var sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); } else if (typeof document.body.createTextRange) { var textRange = document.body.createTextRange(); textRange.moveToElementText(el); textRange.collapse(atStart); textRange.select(); } } setTimeout(function () { createCaretPlacer($item[0], caretAtStart); }, 100); } $(function () { function refreshToken() { OpenDrive.ajax.do('internal.refresh-token', null, function () { setTimeout(refreshToken, 3600000); }, function () { setTimeout(refreshToken, 300000); }) } setTimeout(refreshToken, 3600000); setTimeout(function () { $('.js-popup-message').fadeOutRemove(); }, 5000); if ( $(".has-notice").length > 0 ) { var notice_html = ''; $("body").append(notice_html); var tooltip_text = ''; $(document).on({ mouseenter: function () { var this_el = $(this); var offset = this_el.offset(); var tooltip = $("#notice-tooltip"); if ( this_el.attr('title') && this_el.attr('title') != '' ) { tooltip_text = this_el.attr('title'); this_el.removeAttr('title'); } tooltip.html(tooltip_text); var new_left = offset.left - Math.ceil(tooltip.outerWidth() / 2) + 6; if (new_left < 0) new_left = 0; var new_top = offset.top - tooltip.outerHeight() - 10; if (new_top < 0) new_top = 0; tooltip.css({'left': new_left +'px', 'top': new_top+'px'}).fadeIn('fast'); this_el.css({'text-decoration' : 'underline', 'cursor' : 'pointer'}); return false; }, mouseleave: function () { var this_el = $(this); $("#notice-tooltip").hide(); this_el.css({'text-decoration' : 'none', 'cursor' : 'default'}); this_el.attr('title', tooltip_text); } }, ".has-notice") } $('.js-sidebar-menu-hide').click(function () { var dirsContainer = $('.dirs'); dirsContainer.toggle('slide', 'left', 300, function () { var new_state = dirsContainer.is(':visible') ? 1 : 0; OpenDrive.ajax.do('sidebar-visible', {state: new_state}); $(window).trigger('resize'); }); return false; }); $("#sendsms").click(function () { var authy_id = $("#authy-id").val(); var data = { authy_id: authy_id, }; OpenDrive.ajax.do('authorize.send-sms', data); }); //Templates if(window.Handlebars) $('script[type="text/x-handlebars-template"]').each(function(){ var _this = $(this); var name = _this.data('name'); if(OpenDrive.templates[name]) throw 'Template ' + name + ' is already defined'; OpenDrive.templates[name] = Handlebars.compile(this.innerHTML); if(_this.data('partial')) Handlebars.registerPartial(name, OpenDrive.templates[name]); }); $('.nice-checkbox').on('change', function () { var label = $('label[for="' + this.id + '"]', this.parentNode); if (label.length) { $('> [role="checkbox"]', label).attr('aria-checked', this.checked); } }) }); if (document.webL10n) { //document.webL10n.setLanguage(document.documentElement.lang); OpenDrive._ = document.webL10n.get; document.webL10n.ready(function () { OpenDrive._readyHandlers.forEach(function (f) { f.call(); }) }) } })(jQuery);