define([ 'jquery', 'jquery.ui.progressbar', 'jquery.magnific-popup', 'simplemodal', 'underscore', 'backbone', 'common', 'file-tree', 'app/collections/dirents', 'app/views/dirent', 'app/views/fileupload', 'app/views/share' ], function($, progressbar, magnificPopup, simplemodal, _, Backbone, Common, FileTree, DirentCollection, DirentView, FileUploadView, ShareView) { 'use strict'; var DirView = Backbone.View.extend({ el: $('#dir-view'), path_bar_template: _.template($('#dir-path-bar-tmpl').html()), dir_op_bar_template: _.template($('#dir-op-bar-tmpl').html()), dirents_hd_template: _.template($('#dirents-hd-tmpl').html()), top_search_form_template: _.template($('#top-search-form-tmpl').html()), newDirTemplate: _.template($("#add-new-dir-form-template").html()), newFileTemplate: _.template($("#add-new-file-form-template").html()), mvcpTemplate: _.template($("#mvcp-form-template").html()), mvProgressTemplate: _.template($("#mv-progress-popup-template").html()), initialize: function(options) { this.$dirent_list = this.$('.repo-file-list tbody'); this.$path_bar = this.$('.path'); // For compatible with css, we use .repo-op instead of .dir-op this.$dir_op_bar = this.$('.repo-op'); this.dir = new DirentCollection(); this.listenTo(this.dir, 'add', this.addOne); this.listenTo(this.dir, 'reset', this.reset); this.fileUploadView = new FileUploadView({dirView: this}); this.$el.magnificPopup({ type: 'image', delegate: '.img-name-link', tClose: gettext("Close (Esc)"), // Alt text on close button tLoading: gettext("Loading..."), // Text that is displayed during loading. Can contain %curr% and %total% keys gallery: { enabled: true, tPrev: gettext("Previous (Left arrow key)"), // Alt text on left arrow tNext: gettext("Next (Right arrow key)"), // Alt text on right arrow tCounter: gettext("%curr% of %total%") // Markup for "1 of 7" counter }, image: { titleSrc: function(item) { var el = item.el; var img_name = el[0].innerHTML; var img_link = '' + gettext("Open in New Tab") + ''; return img_name + '
' + img_link; }, tError: gettext('The image could not be loaded.') // Error message when image could not be loaded } }); // scroll window: get 'more', fix 'op bar' var _this = this; $(window).scroll(function() { if ($(_this.el).is(':visible')) { _this.onWindowScroll(); } }); // hide 'hidden-op' popup $(document).click(function(e) { var target = e.target || event.srcElement; var $popup = $('.hidden-op:visible'); if ($popup.length > 0 && // There is a visible popup !$('.more-op-icon', $popup.closest('tr')).is(target) && !$popup.is(target) && !$popup.find('*').is(target)) { $popup.addClass('hide'); var $tr = $popup.closest('tr'); if (!$tr.find('*').is(target)) { $tr.removeClass('hl').find('.repo-file-op').addClass('vh'); $('.repo-file-list tr:gt(0)').each(function() { if ($(this).find('*').is(target)) { $(this).addClass('hl').find('.repo-file-op').removeClass('vh'); } }); } } }); // hide 'rename form' $(document).click(function(e) { var target = e.target || event.srcElement; var $form = $('#rename-form'); if ($form.length && !$form.find('*').is(target)) { var $tr = $form.closest('tr'); // get $tr before $form removed in `.cancel click()` $('.cancel', $form).click(); if (!$tr.find('*').is(target)) { $tr.removeClass('hl').find('.repo-file-op').addClass('vh'); $('.repo-file-list tr:gt(0)').each(function() { if ($(this).find('*').is(target)) { $(this).addClass('hl').find('.repo-file-op').removeClass('vh'); } }); } } }); }, showDir: function(category, repo_id, path) { $('#top-search-form').html(this.top_search_form_template({ search_repo_id: repo_id })); this.$el.show(); this.$dirent_list.empty(); var loading_tip = this.$('.loading-tip').show(); var dir = this.dir; dir.setPath(category, repo_id, path); var _this = this; dir.fetch({ cache: false, reset: true, data: {'p': path}, success: function (collection, response, opts) { dir.last_start = 0; // for 'more' if (response.dirent_list.length == 0 || // the dir is empty !response.dirent_more ) { // no 'more' loading_tip.hide(); } }, error: function (collection, response, opts) { loading_tip.hide(); var $el_con = _this.$('.repo-file-list-topbar, .repo-file-list').hide(); var $error = _this.$('.error'); var err_msg; var lib_need_decrypt = false; if (response.responseText) { if (response.responseJSON.lib_need_decrypt) { lib_need_decrypt = true; } else { err_msg = response.responseJSON.error; } } else { err_msg = gettext('Please check the network.'); } if (err_msg) { $error.html(err_msg).show(); } if (lib_need_decrypt) { var form = $($('#repo-decrypt-form-template').html()); var decrypt_success = false; form.modal({ containerCss: {'padding': '1px'}, onClose: function () { $.modal.close(); $el_con.show(); if (!decrypt_success) { app.router.navigate( category + '/', // need to append '/' at end {trigger: true} ); } } }); $('#simplemodal-container').css({'height':'auto'}); form.submit(function() { var passwd = $.trim($('[name="password"]', form).val()); if (!passwd) { $('.error', form).html(gettext("Password is required.")).removeClass('hide'); return false; } Common.ajaxPost({ form: form, form_id: form.attr('id'), post_url: Common.getUrl({'name':'repo_set_password'}), post_data: { repo_id: repo_id, password: passwd, username: app.pageOptions.username }, after_op_success: function() { decrypt_success = true; $.modal.close(); _this.showDir(category, repo_id, path); } }); return false; }); } } }); }, hide: function() { $('#top-search-form').html(this.top_search_form_template({ search_repo_id: '' })); this.$el.hide(); }, addOne: function(dirent) { var view = new DirentView({model: dirent, dirView: this}); this.$dirent_list.append(view.render().el); }, reset: function() { this.dir.each(this.addOne, this); this.renderPath(); this.renderDirOpBar(); this.renderDirentsHd(); this.fileUploadView.setFileInput(); this.getImageThumbnail(); }, getImageThumbnail: function() { if (!app.pageOptions.enable_thumbnail || this.dir.encrypted) { return false; } var images_with_no_thumbnail = this.dir.filter(function(dirent) { // 'dirent' is a model return dirent.get('is_img') && !dirent.get('encoded_thumbnail_src'); }); if (images_with_no_thumbnail.length == 0) { return ; } var images_len = images_with_no_thumbnail.length, repo_id = this.dir.repo_id, cur_path = this.dir.path, _this = this; var get_thumbnail = function(i) { var cur_img = images_with_no_thumbnail[i]; var cur_img_path = Common.pathJoin([cur_path, cur_img.get('obj_name')]); $.ajax({ url: Common.getUrl({name: 'thumbnail_create', repo_id: repo_id}), data: {'path': cur_img_path}, cache: false, dataType: 'json', success: function(data) { cur_img.set({ 'encoded_thumbnail_src': data.encoded_thumbnail_src }); }, complete: function() { // cur path may be changed. e.g., the user enter another directory if (i < images_len - 1 && _this.dir.repo_id == repo_id && _this.dir.path == cur_path) { get_thumbnail(++i); } } }); }; get_thumbnail(0); }, renderPath: function() { var dir = this.dir; var path = dir.path; var context = 'my'; var category_start = dir.category.split('/')[0]; if (category_start == 'org') { context = 'org'; } else if (category_start == 'group') { context = 'group'; } else if (category_start == 'common') { context = 'common'; } var obj = { path: path, repo_name: dir.repo_name, category: dir.category, context: context }; var path_list = path.substr(1).split('/'); var path_list_encoded = Common.encodePath(path.substr(1)).split('/'); if (path != '/') { $.extend(obj, { path_list: path_list, path_list_encoded: path_list_encoded, repo_id: dir.repo_id }); } this.$path_bar.html(this.path_bar_template(obj)); }, renderDirOpBar: function() { var dir = this.dir; this.$dir_op_bar.html($.trim(this.dir_op_bar_template({ user_perm: dir.user_perm, encrypted: dir.encrypted, path: dir.path, repo_id: dir.repo_id, site_root: app.pageOptions.site_root, is_repo_owner: dir.is_repo_owner, is_virtual: dir.is_virtual, can_generate_shared_link: app.pageOptions.can_generate_shared_link, enable_upload_folder: app.pageOptions.enable_upload_folder }))); }, renderDirentsHd: function() { this.$('thead').html(this.dirents_hd_template()); }, // Directory Operations events: { 'click .path-link': 'visitDir', 'click #upload-file': 'uploadFile', 'click #add-new-dir': 'newDir', 'click #add-new-file': 'newFile', 'click #share-cur-dir': 'share', 'click th.select': 'select', 'click #mv-dirents': 'mv', 'click #cp-dirents': 'cp', 'click #del-dirents': 'del', 'click .by-name': 'sortByName', 'click .by-time': 'sortByTime' }, newDir: function() { var form = $(this.newDirTemplate()), form_id = form.attr('id'), dir = this.dir, dirView = this; form.modal({appendTo:'#main'}); $('#simplemodal-container').css({'height':'auto'}); form.submit(function() { var dirent_name = $.trim($('input[name="name"]', form).val()); if (!dirent_name) { Common.showFormError(form_id, gettext("It is required.")); return false; }; var post_data = {'dirent_name': dirent_name}, post_url = Common.getUrl({name: "new_dir", repo_id: dir.repo_id}) + '?parent_dir=' + encodeURIComponent(dir.path); var after_op_success = function(data) { $.modal.close(); var new_dirent = dir.add({ 'is_dir': true, 'obj_name': data['name'], 'perm': 'rw', 'last_modified': new Date().getTime() / 1000, 'last_update': gettext("Just now"), 'p_dpath': data['p_dpath'] }, {silent:true}); dirView.addNewDir(new_dirent); }; Common.ajaxPost({ 'form': form, 'post_url': post_url, 'post_data': post_data, 'after_op_success': after_op_success, 'form_id': form_id }); return false; }); }, newFile: function() { var form = $(this.newFileTemplate()), form_id = form.attr('id'), file_name = form.find('input[name="name"]'), dir = this.dir, dirView = this; form.modal({ appendTo: '#main', focus: false, containerCss: {'padding':'20px 25px'} }); $('#simplemodal-container').css({'height':'auto'}); $('.set-file-type', form).click(function() { file_name.val('.' + $(this).data('filetype')); Common.setCaretPos(file_name[0], 0); file_name.focus(); }); form.submit(function() { var dirent_name = $.trim(file_name.val()); if (!dirent_name) { Common.showFormError(form_id, gettext("It is required.")); return false; }; // if it has an extension, make sure it has a name if (dirent_name.lastIndexOf('.') != -1 && dirent_name.substr(0, dirent_name.lastIndexOf('.')).length == 0) { Common.showFormError(form_id, gettext("Only an extension there, please input a name.")); return false; } var post_data = {'dirent_name': dirent_name}, post_url = Common.getUrl({name: "new_file", repo_id: dir.repo_id}) + '?parent_dir=' + encodeURIComponent(dir.path); var after_op_success = function(data) { $.modal.close(); var new_dirent = dir.add({ 'is_file': true, 'is_img': Common.imageCheck(data['name']), 'obj_name': data['name'], 'file_size': Common.fileSizeFormat(0), 'obj_id': '0000000000000000000000000000000000000000', 'file_icon': 'file.png', 'starred': false, 'perm': 'rw', 'last_modified': new Date().getTime() / 1000, 'last_update': gettext("Just now") }, {silent: true}); dirView.addNewFile(new_dirent); }; Common.ajaxPost({ 'form': form, 'post_url': post_url, 'post_data': post_data, 'after_op_success': after_op_success, 'form_id': form_id }); return false; }); }, addNewFile: function(new_dirent) { var dirView = this, dir = this.dir; var view = new DirentView({model: new_dirent, dirView: dirView}); var new_file = view.render().el; // put the new file as the first file if ($('tr', dirView.$dirent_list).length == 0) { dirView.$dirent_list.append(new_file); } else { var dirs = dir.where({'is_dir':true}); if (dirs.length == 0) { dirView.$dirent_list.prepend(new_file); } else { // put the new file after the last dir $($('tr', dirView.$dirent_list)[dirs.length - 1]).after(new_file); } } }, addNewDir: function(new_dirent) { var dirView = this; var view = new DirentView({model: new_dirent, dirView: dirView}); dirView.$dirent_list.prepend(view.render().el); // put the new dir as the first one }, share: function () { var dir = this.dir; var path = dir.path; var options = { 'is_repo_owner': dir.is_repo_owner, 'is_virtual': dir.is_virtual, 'user_perm': dir.user_perm, 'repo_id': dir.repo_id, 'is_dir': true, 'dirent_path': path, 'obj_name': path == '/' ? dir.repo_name : path.substr(path.lastIndexOf('/') + 1) }; new ShareView(options); }, sortByName: function() { this.$('.by-time .sort-icon').hide(); var dirents = this.dir; var el = this.$('.by-name .sort-icon'); dirents.comparator = function(a, b) { if (a.get('is_dir') && b.get('is_file')) { return -1; } if (a.get('is_file') && b.get('is_dir')) { return 1; } var result = Common.compareTwoWord(a.get('obj_name'), b.get('obj_name')); if (el.hasClass('icon-caret-up')) { return -result; } else { return result; } }; dirents.sort(); this.$dirent_list.empty(); dirents.each(this.addOne, this); el.toggleClass('icon-caret-up icon-caret-down').show(); dirents.comparator = null; }, sortByTime: function () { this.$('.by-name .sort-icon').hide(); var dirents = this.dir; var el = this.$('.by-time .sort-icon'); dirents.comparator = function(a, b) { if (a.get('is_dir') && b.get('is_file')) { return -1; } if (a.get('is_file') && b.get('is_dir')) { return 1; } if (el.hasClass('icon-caret-down')) { return a.get('last_modified') < b.get('last_modified') ? 1 : -1; } else { return a.get('last_modified') < b.get('last_modified') ? -1 : 1; } }; dirents.sort(); this.$dirent_list.empty(); dirents.each(this.addOne, this); el.toggleClass('icon-caret-up icon-caret-down').show(); dirents.comparator = null; }, select: function () { var el = this.$('th .checkbox'); el.toggleClass('checkbox-checked'); var dir = this.dir; var all_dirent_checkbox = this.$('.checkbox'); var $dirents_op = this.$('#multi-dirents-op'); if (el.hasClass('checkbox-checked')) { all_dirent_checkbox.addClass('checkbox-checked'); dir.each(function(model) { model.set({'selected': true}, {silent: true}); }); $dirents_op.css({'display':'inline'}); } else { all_dirent_checkbox.removeClass('checkbox-checked'); dir.each(function(model) { model.set({'selected': false}, {silent: true}); }); $dirents_op.hide(); } }, del: function () { var dirents = this.dir; var _this = this; var del_dirents = function() { $('#confirm-popup').append('

' + gettext("Processing...") + '

'); var selected_dirents = dirents.where({'selected':true}), selected_names = []; $(selected_dirents).each(function() { selected_names.push(this.get('obj_name')); }); $.ajax({ url: Common.getUrl({ name: 'del_dirents', repo_id: dirents.repo_id }) + '?parent_dir=' + encodeURIComponent(dirents.path), type: 'POST', dataType: 'json', beforeSend: Common.prepareCSRFToken, traditional: true, data: { 'dirents_names': selected_names }, success: function(data) { var del_len = data['deleted'].length, not_del_len = data['undeleted'].length, msg_s, msg_f; if (del_len > 0) { if (del_len == selected_names.length) { dirents.remove(selected_dirents); _this.$('th .checkbox').removeClass('checkbox-checked'); _this.$('#multi-dirents-op').hide(); } else { $(selected_dirents).each(function() { if (data['deleted'].indexOf(this.get('obj_name')) != -1) { dirents.remove(this); } }); } if (del_len == 1) { msg_s = gettext("Successfully deleted %(name)s."); } else if (del_len == 2) { msg_s = gettext("Successfully deleted %(name)s and 1 other item."); } else { msg_s = gettext("Successfully deleted %(name)s and %(amount)s other items."); } msg_s = msg_s.replace('%(name)s', Common.HTMLescape(data['deleted'][0])).replace('%(amount)s', del_len - 1); Common.feedback(msg_s, 'success'); } if (not_del_len > 0) { if (not_del_len == 1) { msg_f = gettext("Failed to delete %(name)s."); } else if (not_del_len == 2) { msg_f = gettext("Failed to delete %(name)s and 1 other item."); } else { msg_f = gettext("Failed to delete %(name)s and %(amount)s other items."); } msg_f = msg_f.replace('%(name)s', Common.HTMLescape(data['undeleted'][0])).replace('%(amount)s', not_del_len - 1); Common.feedback(msg_f, 'error'); } $.modal.close(); }, error: function(xhr, textStatus, errorThrown) { $.modal.close(); Common.ajaxErrorHandler(xhr, textStatus, errorThrown); } }); }; Common.showConfirm(gettext("Delete Items"), gettext("Are you sure you want to delete these selected items?"), del_dirents); }, mv: function () { this.mvcp({'op':'mv'}); }, cp: function () { this.mvcp({'op':'cp'}); }, mvcp: function (params) { var dir = this.dir; var op = params.op; var title = op == 'mv' ? gettext("Move selected item(s) to:") : gettext("Copy selected item(s) to:"); var form = $(this.mvcpTemplate({ form_title: title, op_type: op, obj_type: '', obj_name: '', show_other_repos: !dir.encrypted })); form.modal({appendTo:'#main', autoResize:true, focus:false}); $('#simplemodal-container').css({'width':'auto', 'height':'auto'}); FileTree.renderTreeForPath({ repo_name: dir.repo_name, repo_id: dir.repo_id, path: dir.path }); if (!dir.encrypted) { FileTree.prepareOtherReposTree({cur_repo_id: dir.repo_id}); } var _this = this; var dirents = this.dir; // get models var dirs = dirents.where({'is_dir':true, 'selected':true}), files = dirents.where({'is_file':true, 'selected':true}); var dir_names = [], file_names = []; $(dirs).each(function() { dir_names.push(this.get('obj_name')); }); $(files).each(function() { file_names.push(this.get('obj_name')); }); form.submit(function() { var dst_repo = $('[name="dst_repo"]', form).val(), dst_path = $('[name="dst_path"]', form).val(), url_main; var cur_path = dirents.path; var url_obj = {repo_id:dirents.repo_id}; if (!$.trim(dst_repo) || !$.trim(dst_path)) { $('.error', form).removeClass('hide'); return false; } if (dst_repo == dirents.repo_id && dst_path == cur_path) { $('.error', form).html(gettext("Invalid destination path")).removeClass('hide'); return false; } Common.disableButton($('[type="submit"]', form)); form.append('

' + gettext("Processing...") + '

'); if (dst_repo == dirents.repo_id) { // when mv/cp in current lib, files/dirs can be handled in batch, and no need to show progress url_obj.name = op == 'mv' ? 'mv_dirents' : 'cp_dirents'; $.ajax({ url: Common.getUrl(url_obj) + '?parent_dir=' + encodeURIComponent(cur_path), type: 'POST', dataType: 'json', beforeSend: Common.prepareCSRFToken, traditional: true, data: { 'file_names': file_names, 'dir_names': dir_names, 'dst_repo': dst_repo, 'dst_path': dst_path }, success: function(data) { var success_len = data['success'].length, msg_s, msg_f, view_url = data['url']; $.modal.close(); if (success_len > 0) { if (op == 'mv') { if (success_len == files.length + dirs.length) { dirents.remove(dirs); dirents.remove(files); _this.$('th .checkbox').removeClass('checkbox-checked'); _this.$('#multi-dirents-op').hide(); } else { $(dirs).each(function() { if (this.get('obj_name') in data['success']) { dirents.remove(this); } }); $(files).each(function() { if (this.get('obj_name') in data['success']) { dirents.remove(this); } }); } if (success_len == 1) { msg_s = gettext("Successfully moved %(name)s."); } else if (success_len == 2) { msg_s = gettext("Successfully moved %(name)s and 1 other item."); } else { msg_s = gettext("Successfully moved %(name)s and %(amount)s other items."); } } else { // cp if (success_len == 1) { msg_s = gettext("Successfully copied %(name)s."); } else if (success_len == 2) { msg_s = gettext("Successfully copied %(name)s and 1 other item."); } else { msg_s = gettext("Successfully copied %(name)s and %(amount)s other items."); } } msg_s = msg_s.replace('%(name)s', Common.HTMLescape(data['success'][0])).replace('%(amount)s', success_len - 1); //msg_s += ' ' + "View" + ''; Common.feedback(msg_s, 'success'); } if (data['failed'].length > 0) { if (op == 'mv') { if (data['failed'].length > 1) { msg_f = gettext("Internal error. Failed to move %(name)s and %(amount)s other item(s)."); } else { msg_f = gettext("Internal error. Failed to move %(name)s."); } } else { if (data['failed'].length > 1) { msg_f = gettext("Internal error. Failed to copy %(name)s and %(amount)s other item(s)."); } else { msg_f = gettext("Internal error. Failed to copy %(name)s."); } } msg_f = msg_f.replace('%(name)s', Common.HTMLescape(data['failed'][0])).replace('%(amount)s', data['failed'].length - 1); Common.feedback(msg_f, 'error'); } }, error: function(xhr, textStatus, errorThrown) { $.modal.close(); Common.ajaxErrorHandler(xhr, textStatus, errorThrown); } }); } else { // when mv/cp to another lib, files/dirs should be handled one by one, and need to show progress var op_objs = dirents.where({'selected':true}), i = 0; // progress popup var mv_progress_popup = $(_this.mvProgressTemplate()); var details = $('#mv-details', mv_progress_popup), cancel_btn = $('#cancel-mv', mv_progress_popup), other_info = $('#mv-other-info', mv_progress_popup); var mvcpDirent = function () { var op_obj = op_objs[i], obj_type = op_obj.get('is_dir') ? 'dir':'file', obj_name = op_obj.get('obj_name'), post_url, post_data; if (op == 'mv') { url_obj.name = obj_type == 'dir' ? 'mv_dir' : 'mv_file'; } else { url_obj.name = obj_type == 'dir' ? 'cp_dir' : 'cp_file'; } post_url = Common.getUrl(url_obj) + '?path=' + encodeURIComponent(cur_path) + '&obj_name=' + encodeURIComponent(obj_name); post_data = { 'dst_repo': dst_repo, 'dst_path': dst_path }; var after_op_success = function (data) { var det_text = op == 'mv' ? gettext("Moving file %(index)s of %(total)s") : gettext("Copying file %(index)s of %(total)s"); details.html(det_text.replace('%(index)s', i + 1).replace('%(total)s', op_objs.length)).removeClass('vh'); cancel_btn.removeClass('hide'); var req_progress = function () { var task_id = data['task_id']; cancel_btn.data('task_id', task_id); $.ajax({ url: Common.getUrl({name:'get_cp_progress'}) + '?task_id=' + encodeURIComponent(task_id), dataType: 'json', success: function(data) { var bar = $('.ui-progressbar-value', $('#mv-progress')); if (!data['failed'] && !data['canceled'] && !data['successful']) { setTimeout(req_progress, 1000); } else { if (data['successful']) { bar.css('width', parseInt((i + 1)/op_objs.length*100, 10) + '%').show(); if (op == 'mv') { dirents.remove(op_obj); } endOrContinue(); } else { // failed or canceled if (data['failed']) { var error_msg = op == 'mv' ? gettext('Failed to move %(name)s') : gettext('Failed to copy %(name)s'); cancel_btn.after('

' + error_msg.replace('%(name)s', Common.HTMLescape(obj_name)) + '

'); end(); } } } }, error: function(xhr, textStatus, errorThrown) { var error; if (xhr.responseText) { error = $.parseJSON(xhr.responseText).error; } else { error = gettext("Failed. Please check the network."); } cancel_btn.after('

' + error + '

'); end(); } }); }; // 'req_progress' ends if (i == 0) { $.modal.close(); setTimeout(function () { mv_progress_popup.modal({containerCss: { width: 300, height: 150, paddingTop: 50 }, focus:false}); $('#mv-progress').progressbar(); req_progress(); }, 100); } else { req_progress(); } }; // 'after_op_success' ends Common.ajaxPost({ 'form': form, 'post_url': post_url, 'post_data': post_data, 'after_op_success': after_op_success, 'form_id': form.attr('id') }); }; // 'mvcpDirent' ends var endOrContinue = function () { if (i == op_objs.length - 1) { setTimeout(function () { $.modal.close(); }, 500); } else { mvcpDirent(++i); } }; var end = function () { setTimeout(function () { $.modal.close(); }, 500); }; mvcpDirent(); cancel_btn.click(function() { Common.disableButton(cancel_btn); var task_id = $(this).data('task_id'); $.ajax({ url: Common.getUrl({name:'cancel_cp'}) + '?task_id=' + encodeURIComponent(task_id), dataType: 'json', success: function(data) { other_info.html(gettext("Canceled.")).removeClass('hide'); cancel_btn.addClass('hide'); end(); }, error: function(xhr, textStatus, errorThrown) { var error; if (xhr.responseText) { error = $.parseJSON(xhr.responseText).error; } else { error = gettext("Failed. Please check the network."); } other_info.html(error).removeClass('hide'); Common.enableButton(cancel_btn); } }); }); } return false; }); }, onWindowScroll: function () { // 'more' var dir = this.dir, start = dir.more_start; if (dir.dirent_more && $(window).scrollTop() + $(window).height() > $(document).height() - $('#footer').outerHeight(true) && start != dir.last_start) { var loading_tip = this.$('.loading-tip'), _this = this; dir.last_start = start; dir.fetch({ cache: false, remove: false, data: { 'p': dir.path, 'start': dir.more_start }, success: function (collection, response, opts) { if (!response.dirent_more ) { // no 'more' loading_tip.hide(); } _this.getImageThumbnail(); }, error: function(xhr, textStatus, errorThrown) { loading_tip.hide(); Common.ajaxErrorHandler(xhr, textStatus, errorThrown); } }); } // fixed 'dir-op-bar' var op_bar = this.$dir_op_bar, path_bar = this.$path_bar, // the element before op_bar repo_file_list = this.$('.repo-file-list'); // the element after op_bar var op_bar_top = path_bar.offset().top + path_bar.outerHeight(true); var fixed_styles = { 'position': 'fixed', 'top': 0, 'left': path_bar.offset().left, 'z-index': 12 // make 'op_bar' shown on top of the checkboxes }; if ($(window).scrollTop() >= op_bar_top) { repo_file_list.css({'margin-top':op_bar.outerHeight(true)}); op_bar.outerWidth(this.$el.width()).css(fixed_styles); } else { repo_file_list.css({'margin-top':0}); op_bar.removeAttr('style'); } } }); return DirView; });