canvas-lms/public/javascripts/full_files.js

2814 lines
123 KiB
JavaScript

/**
* Copyright (C) 2011 Instructure, Inc.
*
* This file is part of Canvas.
*
* Canvas is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, version 3 of the License.
*
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
define([
'underscore',
'INST' /* INST */,
'i18n!files',
'jquery' /* jQuery, $ */,
'str/htmlEscape',
'compiled/tinymce',
'tinymce.editor_box',
'jqueryui/draggable' /* /\.draggable/ */,
'jquery.ajaxJSON' /* ajaxJSON */,
'jquery.doc_previews' /* loadDocPreview */,
'jquery.inst_tree' /* instTree */,
'jquery.instructure_date_and_time' /* parseFromISO */,
'jquery.instructure_forms' /* formSubmit, handlesHTML5Files, ajaxFileUpload, fileData, fillFormData, formErrors */,
'jqueryui/dialog',
'jquery.instructure_misc_helpers' /* replaceTags, /\$\.underscore/ */,
'jquery.instructure_misc_plugins' /* confirmDelete, fragmentChange, showIf */,
'jquery.keycodes' /* keycodes */,
'jquery.loadingImg' /* loadingImage */,
'jquery.scrollToVisible' /* scrollToVisible */,
'jquery.templateData' /* fillTemplateData, getTemplateData */,
'media_comments' /* mediaComment */,
'vendor/jquery.scrollTo' /* /\.scrollTo/ */,
'jqueryui/droppable' /* /\.droppable/ */,
'jqueryui/progressbar' /* /\.progressbar/ */,
'vendor/scribd.view' /* scribd */
], function(_, INST, I18n, $, htmlEscape) {
var files = {};
var fileStructureData = [];
(function() {
var $files_content = $("#files_content"),
$swfupload_holder = $("#swfupload_holder"),
$add_file_link = $("#add_file_link"),
$files_structure = $("#files_structure"),
$files_structure_list = $("#files_structure_list");
$.extend(files, {
canManageAContext: false,
init: function() {
// Re-initialize common finds, just in case
$files_content = $("#files_content");
$swfupload_holder = $("#swfupload_holder");
$add_file_link = $("#add_file_link");
$files_structure = $("#files_structure");
$files_structure_list = $("#files_structure_list");
$files_content.prepend($swfupload_holder);
files.clearDataCache.cacheIndex = 0;
for(var idx in contexts) {
var obj = {
context: contexts[idx],
context_name: contexts[idx].name,
context_string: contexts[idx].asset_string
};
if(contexts[idx].asset_string) {
var context_type = contexts[idx].asset_string.replace(/_\d+$/, '');
obj[context_type] = contexts[idx];
}
fileStructureData.push([
obj, {}
]);
}
for(var idx in fileStructureData) {
if(fileStructureData[idx]) {
var context = fileStructureData[idx][0];
var context_type = null;
var context_name = null;
var context_object = null;
for(var jdx in context) {
if(context[jdx] && jdx != "context_string" && jdx != "context_name" && jdx != 'context') {
context_type = jdx;
context_name = context[jdx].name;
context_object = context[jdx];
}
}
fileStructureData[idx][0].context_string = context_type + "_" + context[context_type].id;
fileStructureData[idx][0].context_name = context_name;
fileStructureData[idx][0].context = context_object;
if(context_object && context_object.permissions && context_object.permissions.manage_files) {
files.canManageAContext = true;
}
}
}
$files_content.append($("#drag_n_drop_panel"));
$files_content.append($("#content_templates .content_panel").hide());
if($.handlesHTML5Files) {
$files_content.bind('dragenter dragover', function(event) {
event.preventDefault();
event.stopPropagation();
var folder = files.currentItemData();
if(!folder || folder.mime_class != 'folder') { return; }
$(this).addClass('file_drag');
$("#drag_n_drop_panel").css('top', $files_content.scrollTop());
}).bind('dragleave dragout', function(event) {
if(!$(this).closest(".drag_panel").length) {
$(this).removeClass('file_drag');
}
}).bind('drop', function(event) {
var dt = event.originalEvent.dataTransfer;
if (dt) {
var folder = files.currentItemData();
event.preventDefault();
event.stopPropagation();
$(this).removeClass('file_drag');
if(!folder || folder.mime_class != 'folder') { return; }
var filesToUpload = [];
var filesList = dt.files;
for(var idx = 0; idx < filesList.length; idx++) {
if(filesList[idx] && filesList[idx].size > 0) {
if(true) {
filesToUpload.push(filesList[idx]);
}
}
}
if(filesToUpload.length === 0) {
alert(I18n.t('messages.no_files_selected', "No valid files were selected"));
return;
}
var unzip = false;
if(filesToUpload.length == 1 && filesToUpload[0].type.match(/application\/(x-)?zip/)) {
unzip = confirm(I18n.t('prompts.extract_zip', "This file is a zip file. Do you want to extract its contents into this folder?"));
}
if(unzip) {
var file = filesToUpload[0];
folder.context_string;
var url = $("." + folder.context_string + "_zip_import_url").attr('href');
var params = {
'folder_id': folder.id,
'zip_file': filesToUpload[0],
'format': 'json'
};
var import_id = null;
var $dialog = $("<div/>");
$dialog.append("Uploading and extracting <b>" + htmlEscape(file.name) + "</b><br/>to " + htmlEscape(folder.name) + "...");
$dialog.append("<div class='progress'/>");
var $progress = $dialog.find(".progress");
$progress.css('margin', '10px');
$progress.progressbar();
$dialog.dialog({
title: I18n.t('titles.extracting', "Extracting Files into Folder"),
close: function() {
$dialog.data('closed', true);
setTimeout(function() {
$dialog.detach();
}, 500);
}
});
var importFailed = function(errors) {
$dialog.text(I18n.t('errors.extracting', "There were errors extracting the zip file. Please try again."));
var $ul = $("<ul/>");
for(var idx in errors) {
var error = errors[idx];
var $li = $("<li/>");
$li.text(error);
$ul.append($li);
}
$dialog.append($ul);
};
var pollImport = function(zip_import_id) {
var pollUrl = $("#file_context_links ." + folder.context_string + "_zip_import_status_url").attr('href');
pollUrl = $.replaceTags(pollUrl, 'id', zip_import_id);
$.ajaxJSON(pollUrl, 'GET', {}, function(data) {
var zfi = data.zip_file_import;
if($dialog.data('closed')) { return; }
if(zfi && zfi.data && zfi.data.errors) {
importFailed(zfi.data.errors);
} else if(zfi && zfi.workflow_state == 'imported') {
$progress.progressbar('value', 100);
$dialog.append(I18n.t('messages.extraction_complete', "Extraction complete! Updating..."));
files.refreshContext(folder.context_string, function() {
$dialog.dialog('close');
});
} else if(!zfi) {
pollImport.blankCount = pollImport.blankCount || 0;
pollImport.blankCount++;
if(pollImport.blankCount > 30) {
importFailed([I18n.t('errors.server_returned_invalid_status', "The server stopped returning a valid status")]);
} else {
setTimeout(function() { pollImport(zip_import_id) }, 2000);
}
} else if (zfi && zfi.workflow_state == 'failed') {
importFailed([]);
} else {
pollImport.errorCount = 0;
setTimeout(function() { pollImport(zip_import_id) }, 2000);
$progress.progressbar('value', ((zfi.progress || 0) * 100));
}
}, function(data) {
pollImport.errorCount = pollImport.errorCount || 0;
pollImport.errorCount++;
if(pollImport.errorCount > 5) {
importFailed([I18n.t('errors.server_unresponsive', "The server stopped responding to status requests")]);
} else {
setTimeout(function() { pollImport(zip_import_id) }, 2000);
}
});
};
$.ajaxFileUpload({
url: url,
data: params,
method: 'POST',
success: function(data) {
zip_import_id = data.zip_file_import.id;
pollImport(zip_import_id);
},
error: function(data) {
$dialog.text(I18n.t('errors.uploading_zip', "There were errors uploading the zip file."));
}
});
} else {
var folder = files.currentItemData();
var filenames = [];
for (idx in filesToUpload) {
filenames.push(filesToUpload[idx].name);
}
files.preflight(folder.id, folder.context_string, filenames,
function(duplicate_handling_method) { // onChooseDuplicateHandler
for (idx in filesToUpload) {
filesToUpload[idx].duplicate_handling = duplicate_handling_method;
}
},
function() { // onSuccess
for(var idx in filesToUpload) {
fileUpload.queueAjaxUpload(filesToUpload[idx]);
}
},
function() { // onCancel
});
}
return false;
}
});
}
},
preflight: function(folder_id, folder_context_string, filenames, on_choose, on_success, on_cancel) {
var params = {
'folder_id': folder_id,
'context_code': folder_context_string,
'filenames': filenames
};
$.ajaxJSON('/files/preflight', 'GET', params, function(data) {
if (data.duplicates && data.duplicates.length > 0) {
var $dialog = $("#duplicate_filename_dialog");
$dialog.find(".duplicate_filename_prompt").text(
I18n.t('prompts.duplicate_filenames', "Files with the following names already exist in this folder. Do you want to replace them, or rename the new files with unique names?"));
var duplicatesHtml = '';
for (idx in data.duplicates) {
duplicatesHtml += "<span class='duplicate_filename'>" + htmlEscape(data.duplicates[idx]) + "</span>";
}
$dialog.find(".duplicate_filenames").html(duplicatesHtml);
$dialog.dialog({
title: '',
width: 500
});
$dialog.find("button").unbind('click');
$dialog.find(".cancel_button").click(function() {
on_cancel();
$dialog.dialog('close');
});
$dialog.find(".rename_button").click(function() {
on_choose('rename');
on_success();
$dialog.dialog('close');
});
$dialog.find(".overwrite_button").click(function() {
on_choose('overwrite');
on_success();
$dialog.dialog('close');
});
} else {
on_success();
}
}, function(data) {
on_cancel();
});
},
context_page_view_ids: {},
updatePageView: function(context_string) {
return;
// I'm thinking we won't track these as page views after all... I mean,
// what value is there in knowing the student looked at the file browser,
// we just care if they access files.
},
viewFile: function(context_string, id) {
var url = $("#file_context_links ." + context_string + "_inline_view_attachment_url").attr('href');
url = $.replaceTags(url, 'id', id);
$.ajaxJSON(url, 'POST', {}, function() { }, function() { });
},
selectFolder: function($original_node) {
if(!files.selectFolder.forceRefresh && ($original_node.hasClass('active-node') || $original_node.hasClass('active-leaf'))) { return; }
files.selectFolder.forceRefresh = false;
var $node = $original_node;
while($node.parent("ul").parent("li").length > 0) {
$node = $node.parent("ul").parent("li");
files.expandFolder($node);
}
$original_node.children('.text:visible:first').click();
if($files_structure.find("li.node.active-node,li.leaf.active-leaf").length === 0) {
$files_structure.find("li.node:visible:first").children(".text:visible:first").click();
}
if(!files.currentItemData()) {
setTimeout(function() {
files.selectFolder($original_node);
}, 250);
return;
}
if(!files.currentItemData().includes_files && files.currentItemData().full_name) {
files.getFilesForFolder(files.currentItemData());
}
},
deleteAttachmentIds: function(ids) {
for(var idx in ids) {
var id = ids[idx];
var $file = $("#files_structure .file_" + id)
$file.prev("li.separator").remove();
$file.remove();
files.refreshView();
files.updateQuota();
}
},
gettingFiles: {},
getFilesForFolder: function(original_folder, refresh) {
var key = original_folder.context_string + "_" + original_folder.id;
if(files.gettingFiles[key]) { return; }
var $folder = $files_structure.find("li.folder_" + original_folder.id);
if($folder.hasClass('folder_locked') && (!original_folder.context || !original_folder.context.permissions || !original_folder.context.permissions.manage_files)) {
return;
}
if(original_folder.false_folder) {
files.refreshContext(original_folder.context_string, function() {
files.getFilesForFolder(original_folder, refresh);
});
return;
}
files.gettingFiles[key] = true;
var url = $.replaceTags($("#file_context_links ." + original_folder.context_string + "_folder_url").attr('href'), 'id', original_folder.id);
$.ajaxJSON(url, 'GET', {}, function(data) {
files.gettingFiles[key] = false;
var folder = data.actual_folder.folder;
folder.includes_files = true;
files.updateFolder(original_folder.context_string, {folder: folder, already_in_place: true}, false);
// returns adds an empty string to ensure .toLowerCase() isn't calling on an undefined object
data.files = _.sortBy(data.files, function(obj){ return (obj.attachment.display_name || "").toLowerCase() });
for(var idx in data.files) {
var file = data.files[idx].attachment;
if(file) {
files.updateFile(original_folder.context_string, {attachment: file, definitely_new: true}, false);
}
}
$files_structure.find(".folder_" + folder.id).triggerHandler('files_load');
var needsRefreshing = $files_content.find(".message.no_content:visible").length > 0;
if(refresh !== false || needsRefreshing) {
if(refresh && $.isFunction(refresh)) {
refresh(data);
} else {
files.refreshView();
}
}
$add_file_link.triggerHandler('show');
}, function(data) {
files.gettingFiles[key] = false;
});
},
expandFolder: function($node) {
$files_structure_list[0] && $files_structure_list[0].ExpandNode && $files_structure_list[0].ExpandNode($("#files_structure_list"), $node);
},
collapseFolder: function($node) {
$files_structure_list[0] && $files_structure_list[0].CollapseNode && $files_structure_list[0].CollapseNode($("#files_structure_list"), $node);
},
fullPath: function($node) {
var names = [];
var data = files.itemData($node);
names.unshift(data.name.replace(/\//g, "//"));
while($node.parent("ul").parent("li").length > 0) {
$node = $node.parent("ul").parent("li");
data = files.itemData($node);
names.unshift(data.name.replace(/\//g, "//"));
}
return names.join('/');
},
selectNodeFromPath: function(path) {
var $node = files.nodeFromPath(path);
files.selectFolder($node);
var files_load = function() {
$node.unbind('files_load', files_load);
if($node.hasClass('active-node')) {
files.selectNodeFromPath(path);
}
};
$node.bind('files_load', files_load);
if($files_structure.find(".node.active-node,.leaf.active-leaf").length === 0) {
files.selectFolder($files_structure.find(".node:visible:first"));
}
},
nodeFromPath: function(path) {
try {
if($files_structure.find("#files_structure_list > li." + path).length > 0) {
return $files_structure.find("#files_structure_list > li." + path);
}
} catch(e) {}
var names = path.replace(/\/\//g, "\\").split('/');
var $node = $files_structure;
var keepGoing = true;
for(var idx in names) {
var name = names[idx].replace(/\\\\/g, "/");
var found = false;
if(keepGoing) {
$node.children("ul").children("li").each(function() {
if($(this).children(".text.name").text() == name) {
$node = $(this);
found = true;
return false;
}
});
}
keepGoing = found;
}
return $node;
},
draggable_helper: function(event, $item) {
if($(this).hasClass('folder_item')) {
$item = $(this);
} else {
var width = $item.width();
return $item.clone().css('backgroundColor', '#eeeeee').css('height', 50).css('borderWidth', 1).css('borderStyle', 'solid').css('borderColor', '#ccc').css('width', width - 50);
}
var $result = $item.clone().attr('id', 'file_drag');
$result.find(".header .sub_header").remove();
$result.find(".header").append("<div class='sub_header'/>");
$result.find(".header .sub_header").html("&nbsp;");
$result.addClass('file_drag');
$result.find(".links").remove();
$result.css('width', 100);
var $ul = $("<ul/>");
$ul.addClass('files_content');
$ul.append($result);
$ul.addClass('true-draggable');
$ul.css('width', 200);
$ul.css('height', 50);
$("#content").append($ul);
return $ul;
},
updateQuota: function() {
if(!$("#quota").length) { return; }
var url = $(".quota_url").attr('href');
$.ajaxJSON(url, 'GET', {}, function(data) {
$("#quota").text(data.quota);
$("#quota_used").text(data.quota_used);
}, function() {
});
}
});
$.extend(files, {
draggable_options: {
handle: '.draggable.item_icon',
distance: 5,
helper: files.draggable_helper,
start: function(event, ui) {
$files_content.addClass('dragging');
},
stop: function() {
setTimeout(function() {
$files_content.removeClass('dragging');
}, 500);
}
},
droppable_options: {
accept: '.file,.folder',
hoverClass: 'drop_target',
tolerance: 'pointer',
drop: function(event, ui) {
if(!$(ui.helper).hasClass('true-draggable')) {
return;
}
var $item = $(ui.draggable);
var draggable = files.itemData($item);
var $droppable = $(this);
var droppable = files.itemData($(this).parent(".folder"));
droppable = droppable || files.itemData($(this));
$files_structure.loadingImage();
if($item.hasClass('file')) {
if($(ui.helper).hasClass('copy_drag')) {
var url = $("#file_context_links ." + droppable.context_string + "_attachments_url").attr('href');
var data = {
'attachment[source_attachment_id]': draggable.id,
'attachment[folder_id]': droppable.id
};
$.ajaxJSON(url, 'POST', data, function(data) {
$files_structure.loadingImage('remove');
files.updateFile(droppable.context_string, data, false);
files.selectFolder($droppable);
files.refreshView();
}, function(data) {
$files_structure.loadingImage('remove');
});
} else {
var url = $("#file_context_links ." + droppable.context_string + "_attachment_url").attr('href');
url = $.replaceTags(url, 'id', draggable.id);
$.ajaxJSON(url, 'PUT', {'attachment[folder_id]': droppable.id}, function(data) {
$files_structure.loadingImage('remove');
files.updateFile(droppable.context_string, data, false);
files.selectFolder($droppable);
files.refreshView();
}, function(data) {
$files_structure.loadingImage('remove');
});
}
} else {
if($(ui.helper).hasClass('copy_drag')) {
var url = $("#file_context_links ." + droppable.context_string + "_folders_url").attr('href');
var data = {
'folder[source_folder_id]': draggable.id,
'folder[parent_folder_id]': droppable.id
};
$.ajaxJSON(url, 'POST', data, function(data) {
$files_structure.loadingImage('remove');
files.refreshContext(droppable.root_context_string);
}, function(data) {
$files_structure.loadingImage('remove');
});
} else {
var url = $("#file_context_links ." + droppable.context_string + "_folder_url").attr('href');
url = $.replaceTags(url, 'id', draggable.id);
$.ajaxJSON(url, 'PUT', {'folder[parent_folder_id]': droppable.id}, function(data) {
$files_structure.loadingImage('remove');
files.refreshContext(draggable.root_context_string);
}, function(data) {
$files_structure.loadingImage('remove');
});
}
}
},
over: function(event, ui) {
if(!$(ui.helper).hasClass('true-draggable')) {
$(this).removeClass('drop_target');
}
var draggable = files.itemData($(ui.draggable));
var droppable = files.itemData($(this).parent(".folder"));
droppable = droppable || files.itemData($(this));
$(ui.helper).find(".header .sub_header").text("move to " + droppable.name);
if(draggable && droppable && draggable.context_string != droppable.context_string) {
$(ui.helper).addClass('copy_drag');
$(ui.helper).find(".header .sub_header").html("<strong>copy</strong> to " + htmlEscape(droppable.name));
}
},
out: function(event, ui) {
$(ui.helper).removeClass('copy_drag');
$(ui.helper).find(".header .sub_header").html("&nbsp;");
}
},
breadcrumb: function() {
var folders = location.hash.substring(1).replace(/\/\//g, "\\").split("/");
var $crumbs = $("<div/>");
var soFar = [];
for(var idx = 0; idx < folders.length - 1; idx++) {
var $a = $("<a/>");
soFar.push(folders[idx].replace(/\\\\/g, "/"));
$a.attr('href', '#' + soFar.join("/"));
$a.text(folders[idx]);
$crumbs.append($a);
}
return $crumbs;
},
refreshContext: function(context_string, callback) {
files.refreshContext.refreshing = files.refreshContext.refreshing || {};
if(files.refreshContext.refreshing[context_string]) { return; }
files.refreshContext.refreshing[context_string] = true;
var url = $("#file_context_links ." + context_string + "_attachments_url").attr('href');
$.ajaxJSON(url, 'GET', {}, function(data) {
files.clearDataCache();
files.refreshContext.refreshing[context_string] = false;
var scrollTop = $files_structure.scrollTop();
var context_name = null;
for(var idx in fileStructureData) {
var context = fileStructureData[idx][0];
if(context.context_string == context_string) {
context_name = context.context_name;
fileStructureData[idx][0].context.includes_files = true;
for(var jdx in data.folders) {
for(var kdx in fileStructureData[idx][1].folders) {
if(fileStructureData[idx][1].folders[kdx].id == data.folders[jdx].id) {
data.folders[jdx].includes_files = fileStructureData[idx][1].folders[kdx].includes_files;
}
}
}
data.files = data.files || [];
for(var jdx in fileStructureData[idx][1].files) {
data.files.push(fileStructureData[idx][1].files[jdx]);
}
fileStructureData[idx][1] = data;
}
}
var $context = $("#files_structure > ul > li.context." + context_string).filter(":first");
if($context.length === 0) { $context = null; }
var opens = [];
var openRoot = false;
if($context) {
openRoot = $context.hasClass('open');
var $opens = $context.find("li.node.open");
$opens.each(function() {
opens.push(files.itemData($(this)).id);
});
}
var context_type = null;
for(var idx in data.contexts) {
for(var jdx in data.contexts[idx]) {
if(!context_type) {
context_type = jdx;
context_name = data.contexts[idx][jdx].name;
}
}
}
var root_folder = null;
if(!data.folders && data[0] && data[0][1] && data[0][1].folders) {
data.folders = data[0][1].folders;
}
for(var idx in data.folders) {
if(!root_folder && data.folders[idx].folder && data.folders[idx].folder.parent_folder_id === null) {
root_folder = data.folders[idx].folder;
}
}
var $context_folder = $context;
if(!$context_folder || $context_folder.length === 0) {
$context_folder = $files_structure.find(".folder_blank")
.clone(true)
.removeClass('folder_blank');
}
$context_folder.children(".name").text(context_name);
$context_folder.children(".id").text(root_folder.id);
$context_folder.addClass('context folder folder_' + root_folder.id + ' ' + context_string);
$context_folder.find("li").addClass('to_be_removed');
var $ul = $context_folder.children("ul");
var addChildren = function($parent_folder, folder) {
for(var jdx in data.folders) {
if(folder.id && data.folders[jdx].folder.parent_folder_id == folder.id) {
var $folder = $parent_folder.children("ul").children(".folder_" + data.folders[jdx].folder.id);
if($folder.length === 0) {
$folder = $files_structure.find(".folder_blank").clone(true).removeClass('folder_blank');
$folder.addClass('folder folder_' + data.folders[jdx].folder.id);
$folder.children(".id").text(data.folders[jdx].folder.id);
$folder.children(".name").text(data.folders[jdx].folder.name);
}
$folder.removeClass('to_be_removed');
addChildren($folder, data.folders[jdx].folder);
if($folder.parents("body").length === 0) {
$parent_folder.children("ul").append($folder.show());
}
}
}
};
// returns adds an empty string to ensure .toLowerCase() isn't calling on an undefined object
data.folders = _.sortBy(data.folders, function(obj){ return (obj.folder.name || "").toLowerCase() });
for(var idx in data.folders) {
if(data.folders[idx].folder.parent_folder_id == root_folder.id) {
var $folder = $ul.find(".folder_" + data.folders[idx].folder.id);
if($folder.length === 0) {
$folder = $files_structure.find(".folder_blank").clone(true).removeClass('folder_blank');
$folder.addClass('folder folder_' + data.folders[idx].folder.id);
$folder.children(".name").text(data.folders[idx].folder.name);
$folder.children(".id").text(data.folders[idx].folder.id);
}
$folder.removeClass('to_be_removed');
addChildren($folder, data.folders[idx].folder);
// Check to see if this folder is attached to the dom.
if($folder.parents("body").length === 0) {
$ul.append($folder.show());
}
}
}
if(data.collaborations && !context_string.match(/^user_/)) {
var $collaborations = $files_structure.find(".folder_blank").clone(true).removeClass('folder_blank');
$collaborations.addClass('collaborations');
$collaborations.fillTemplateData({data: {name: "collaborations"}});
for(var idx in data.collaborations) {
var collaboration = data.collaborations[idx].collaboration || data.collaborations[idx].google_docs_collaboration || data.collaborations[idx].etherpad_collaboration;
var $file = $(".collaboration_" + collaboration.id);
if($file.length === 0) {
$file = $files_structure.find(".file_blank").clone(true).removeClass('file_blank');
$file.addClass('collaboration_' + data.collaborations[idx].collaboration.id);
$file.addClass('collaboration ' + data.collaborations[idx].collaboration.collaboration_type);
$file.fillTemplateData({data: {name: data.collaborations[idx].collaboration.title, id: data.collaborations[idx].collaboration.id}});
}
$file.removeClass('to_be_removed');
if($file.parents("body").length === 0) {
$collaborations.children("ul").append($file.show());
}
}
$ul.append($collaborations.show());
}
var group_names = {};
for(var idx in data.groups) {
group_names[(data.groups[idx].group || data.groups[idx].course_assigned_group).category] = true;
}
for(var idx in group_names) {
var $category = $files_structure.find(".folder_blank").clone(true).removeClass('folder_blank');
$category.fillTemplateData({data: {name: idx}});
$category.addClass('groups');
for(var jdx in data.groups) {
var group = (data.groups[jdx].group || data.groups[jdx].course_assigned_group);
if(group.category == idx) {
var root_group_folder = null;
for(var kdx in data.folders) {
if(!root_group_folder && !data.folders[kdx].folder.parent_folder_id === null) {
root_group_folder = data.folders[kdx].folder;
}
}
if(root_group_folder) {
var $group = $category.children("ul").children(".group_" + group.id);
if($group.length === 0) {
$group = $files_structure.find(".folder_blank").clone(true).removeClass('folder_blank');
$group.addClass('group context folder folder_' + root_group_folder.id);
$group.addClass('group_' + group.id);
$group.fillTemplateData({data: {name: group.name, id: root_group_folder.id}});
}
$group.removeClass('to_be_removed');
addChildren($group, root_group_folder);
if($group.parents("body").length === 0) {
$category.children("ul").append($group.show());
}
}
}
}
$ul.append($category.show());
}
var found = false;
$context_folder.find(".to_be_removed").remove();
$files_structure.find("#files_structure_list > .folder").each(function() {
var data = files.itemData($(this));
if(data && data.root_context_string == context_string) {
if($(this)[0] != $context_folder[0]) {
$(this).after($context_folder.show());
$(this).remove();
}
found = true;
}
});
if(!found) {
$files_structure.find("#files_structure_list").append($context_folder.show());
}
$context_folder.children(".text").droppable(files.droppable_options);
$context_folder.find(".folder > .text").droppable(files.droppable_options);
for(var idx in opens) {
files.expandFolder($context_folder.find(".folder_" + opens[idx]));
}
if(openRoot) {
files.expandFolder($context_folder);
}
$files_structure.scrollTop(scrollTop);
$files_structure_list.instTree.InitInstTree($files_structure_list);
$files_structure.find("li.node.active-node,li.leaf.active-leaf").filter(":first").children(".name").click();
if(callback && $.isFunction(callback)) {
callback();
}
}, function() {
files.refreshContext.refreshing[context_string] = false;
});
},
refreshContentListeners: function() {
var context = files.currentContext();
if(context && context.permissions && context.permissions.manage_files) {
$files_content.find(".folder.draggable_droppable").droppable(files.droppable_options);
}
if(files.canManageAContext) {
$files_content.find(".folder.draggable_droppable").draggable(files.draggable_options);
$files_content.find(".file").draggable(files.draggable_options);
}
},
nodeClumpSize: 25,
addScrollCatcher: function() {
var addMoreItems = function() {
var scrollTop = $files_content.scrollTop();
var more = false;
var itemIdx = 0;
$files_content.find(".catcher").remove();
var $lastItem = $files_content.find(".folder_item:visible:last");
var $node = $lastItem.data('node');
if($node) {
$node = $node.next();
var tooMany = false;
while($node.length > 0) {
if(!$node.hasClass('separator')) {
itemIdx++;
if(itemIdx <= files.nodeClumpSize) {
files.addContentItem($node);
} else {
tooMany = true;
}
}
$node = $node.next();
}
files.refreshContentListeners();
if(tooMany) {
files.addScrollCatcher();
}
}
$files_content.scrollTop(scrollTop);
};
var $li = $("<li class='catcher'>&nbsp;</li>");
if(!files.watchingScroll) {
$files_content.bind('scroll', function(event) {
var $catcher = $files_content.find(".catcher:visible:first");
if($catcher.length > 0) {
var catcherTop = $catcher.offset().top;
var contentBottom = $files_content.offset().top + $files_content.height();
if(catcherTop < contentBottom) {
addMoreItems();
}
}
});
files.watchingScroll = true;
}
$files_content.append($li);
},
addContentItem: function($item, hidden) {
var data = files.itemData($item);
if(!data || !data.id) { return; }
var isNew = false;
if($item.hasClass('node')) {
var $content = $files_content.find(".folder_" + data.id);
if($content.length === 0) {
var folder_url = $.replaceTags($("." + data.context_string + "_folder_url")
.attr('href'), 'id', data.id);
isNew = true;
$content = $("#content_templates .folder:first").clone(true);
if(hidden) $content.hide();
$content.fillTemplateData({ data: data })
.data({'node': $item, 'parent_node': $item.parent().parent()})
.addClass('folder_' + data.id);
$content.find(".rename_item_link,.delete_item_link,.folder_url")
.attr('href', folder_url);
$content.find(".item_icon.draggable")
.attr('title', I18n.t('titles.click_and_drag', 'Click and drag to move folder to another folder'));
}
$content.toggleClass('editable_folder_item', !!(!$item.hasClass('context') &&
(( data.context &&
data.context.permissions &&
data.context.permissions.manage_files) ||
(data.permissions && data.permissions.update)
)))
$content.removeClass('to_be_removed');
$content.find(".item_icon").toggleClass('draggable', $content.hasClass('editable_folder_item'));
$content.find(".item_icon")
.attr('alt', I18n.t('alts.folder', 'Folder'))
.attr('src', $("#content_blank_icon").attr('src'));
if(data && data.currently_locked) {
$content.find(".item_icon")
.attr('alt', I18n.t('alts.folder_locked', 'Locked Folder'))
.attr('src', $("#content_locked_icon").attr('src'));
}
$content.find(".lock_item_link").showIf(!data.currently_locked);
$content.find(".unlock_item_link").showIf(data.currently_locked);
$content.toggleClass('folder_locked', !!(data && data.currently_locked))
.toggleClass('draggable_droppable', $item.hasClass('folder') && !$item.hasClass('context'));
if(isNew) {
var folders = _.filter(fileStructureData[0][1].folders, function(obj){
return obj.folder.parent_folder_id === data.parent_folder_id
});
var folder = _.find(folders, function(obj){
return obj.folder.name == data.name;
});
var index = _.indexOf(folders, folder);
$target = $files_content.find("li.folder_item.folder")
.eq(index);
$files = $files_content.children('li.folder_item.file');
if ($target.length){
$target.before($content);
}else if($files && $files.length){
$files.first()
.before($content);
} else{
$files_content.append($content);
}
}
} else if($item.hasClass('collaboration')) {
// set the edit and delete urls, for sure
var $content = $files_content.find(".collaboration_" + data.id);
if($content.length === 0) {
isNew = true;
$content = $("#content_templates .collaboration:first").clone(true);
if(hidden) $content.hide();
$content.fillTemplateData({ data: data })
.data('parent_node', $item.parent().parent())
.data('node', $item);
var collaboration_url = $.replaceTags($("." + data.context_string + "_collaboration_url").attr('href'), "id", data.id);
$content.find(".collaboration_url")
.attr('href', collaboration_url);
$content.addClass('collaboration_' + data.id)
.addClass(data.collaboration_type);
}
$content.toggleClass('editable_folder_item', !!(data.permissions && data.permissions.update))
.removeClass('to_be_removed');
$content.find(".item_icon")
.attr('alt', I18n.t('alts.collaboration', 'Collaboration'))
.attr('src', $("#content_blank_icon").attr('src'));
if (isNew) $files_content.append($content);
// Else it's a file
} else {
var $content = $files_content.find(".file_" + data.id);
if($content.length === 0) {
isNew = true;
$content = $("#content_templates .file:first").clone(true);
if (hidden) $content.hide();
var file_url = $.replaceTags($("#file_context_links ." + data.context_string + "_attachment_url").attr('href'), "id", data.id);
var download_url = $.replaceTags($("#file_context_links ." + data.context_string + "_download_attachment_url").attr('href'), "id", data.id);
$content.fillTemplateData({
data: data
})
.data({
parent_node: $item.parent().parent(),
node: $item
})
.addClass(data.mime_class + ' file_' + data.id);
$content.find(".attachment_url").attr('href', file_url);
$content.find(".download_url").attr('href', download_url);
$content.find(".item_icon.draggable").attr('title', 'Click and drag to move file to another folder');
}
$content
.toggleClass('editable_folder_item', !!((data.context && data.context.permissions && data.context.permissions.manage_files) || (data.permissions && data.permissions.update)))
.removeClass('to_be_removed')
.find(".item_icon")
.attr({
alt: I18n.t('alts.file', 'File'),
src: $("#content_blank_icon").attr('src')
});
if(data && data.currently_locked) {
$content.find(".item_icon").attr({
alt: I18n.t('alts.locked_file', 'Locked File'),
src: $("#content_locked_icon").attr('src')
});
}
$content.find(".lock_item_link").showIf(!data.currently_locked);
$content.find(".unlock_item_link").showIf(data.currently_locked);
$content.find(".preview_item_link").showIf(data.scribd_doc || data.content_type.match(/image/) || (data.content_type.match(/(video|audio)/) && data.media_entry_id));
// Need to be careful on this one... we can't let students turn in a
// file and then edit it after the fact...
$content.find(".edit_item_content_link_holder").showIf($content.hasClass('editable_folder_item') && data.context_type != 'User' && ($content.hasClass('text') || $content.hasClass('html') || $content.hasClass('code')));
$content.find(".item_icon").toggleClass('draggable', $content.hasClass('editable_folder_item'));
if(isNew) {
var folder_files = _.filter(fileStructureData[0][1].files, function(obj){
return obj.attachment.folder_id === data.folder_id
});
var folder_file = _.find(folder_files, function(obj){
return obj.attachment.display_name === data.display_name;
});
var index = _.indexOf(folder_files, folder_file);
$target = $files_content.find("li.folder_item.file")
.eq(index);
($target.length) ? $target.before($content) : $files_content.append($content);
}
}
return isNew;
},
updateCollaboration: function(context_string, data, refresh) {
var file_context_string = $.underscore(data.collaboration.context_type) + "_" + data.collaboration.context_id;
for(var idx in fileStructureData) {
if(fileStructureData[idx] && (fileStructureData[idx][0].context_string == context_string || fileStructureData[idx][0].context_string == file_context_string)) {
var found = false;
for(var jdx in fileStructureData[idx][1].collaborations) {
var collab = fileStructureData[idx][1].collaborations[jdx].collaboration;
if(collab.id == data.collaboration.id) {
fileStructureData[idx][1].collaborations[jdx] = data;
$files_structure.find(".collaboration_" + collab.id).each(function() {
var folder = files.itemData($(this).parent("ul").parent("li"));
$(this).fillTemplateData({data: {'name': data.collaboration.title}});
// add 'title="this is the filename.txt" so you can read files/folders that have really long names
if (data.collaboration.title) $(this).find('.name').attr('title', data.collaboration.title);
});
found = true;
}
}
if(!found) {
var collab = data.collaboration;
fileStructureData[idx][1].collaborations.push(data);
var $collab = $files_structure.find(".file_blank").clone(true).removeClass('file_blank');
$collab.removeClass('file');
$collab.addClass('collaboration collaboration_' + collab.id + ' ' + collab.collaboration_type);
collab.name = collab.title;
$collab.fillTemplateData({data: collab});
// add 'title="this is the filename.txt" so you can read files/folders that have really long names
if (collab.title) $collab.find('.name').attr('title', collab.title);
$files_structure.find("." + context_string + " .collaborations").children("ul").prepend($collab.show());
}
}
}
if(refresh !== false ) {
files.refreshView(data.attachment);
$files_structure_list.instTree.InitInstTree($files_structure_list);
}
},
updateFile: function(context_string, data, refresh) {
files.clearDataCache();
var file_context_string = $.underscore(data.attachment.context_type) + "_" + data.attachment.context_id;
for(var idx in fileStructureData) {
var context_is_correct = fileStructureData[idx] &&
(
fileStructureData[idx][0].context_string == context_string ||
fileStructureData[idx][0].context_string == file_context_string
)
if(context_is_correct) {
var found = false;
var moved = false;
if(!data.definitely_new) {
for(var jdx in fileStructureData[idx][1].files) {
var file = fileStructureData[idx][1].files[jdx].attachment;
if(file.id == data.attachment.id) {
fileStructureData[idx][1].files[jdx] = data;
$files_structure.find(".file_" + file.id).each(function() {
var folder = files.itemData($(this).parent("ul").parent("li"));
if(folder.id == data.attachment.folder_id) {
$(this).fillTemplateData({data: {'name': data.attachment.display_name}});
if (data.attachment.display_name) $(this).find('.name').attr('title', data.attachment.display_name);
} else {
moved = true;
}
});
found = true;
if(moved) {
$files_structure.find(".file_" + file.id).remove();
}
}
}
}
if(!found || moved) {
if(!found) {
data.definitely_new = false;
fileStructureData[idx][1].files.push(data);
}
// Sort files
var unsorted_files = fileStructureData[idx][1].files
fileStructureData[idx][1].files = _.sortBy(
unsorted_files, function(obj){
// returns adds an empty string to ensure .toLowerCase() isn't calling on an undefined object
return (obj.attachment.display_name || "").toLowerCase();
}
);
var attachment = data.attachment;
attachment.name = attachment.display_name;
var $file = $files_structure.find(".file_blank")
.clone(true)
.removeClass('file_blank')
.addClass('file_' + attachment.id)
.addClass(attachment.mime_class)
.fillTemplateData({data: attachment});
if (attachment.name) $file.find('.name').attr('title', attachment.name);
var append_file_to_parent_folder = function(){
$files_structure.find(".folder_" + attachment.folder_id)
.children("ul")
.append($file.show());
}
// Find location to insert files ----------------
var folder_files = _.filter(fileStructureData[idx][1].files, function(obj){
return obj.attachment.folder_id === data.attachment.folder_id
});
var folder_file = _.find(folder_files, function(obj){
return obj.attachment.display_name === data.attachment.display_name;
});
var index = _.indexOf(folder_files, folder_file);
var $element = $files_structure.find(".folder_" + attachment.folder_id)
.children("ul")
.find('li.file')
.eq(index);
// Insert file in the correct location
($element.length) ? $element.before($file.show()) : append_file_to_parent_folder();
}
}
}
if(refresh !== false ) {
files.refreshView(data.attachment);
$files_structure_list.instTree.InitInstTree($files_structure_list);
}
},
updateFolder: function(context_string, data, refresh) {
files.clearDataCache();
var folder_context_string = $.underscore(data.folder.context_type) + "_" + data.folder.context_id;
var already_in_place = data.already_in_place;
data.already_in_place = null;
for(var idx in fileStructureData) {
// Check for the folder in all contexts
if(fileStructureData[idx] && (fileStructureData[idx][0].context_string == context_string || fileStructureData[idx][0].context_string == folder_context_string)) {
var found = false;
var moved = false;
for(var jdx in fileStructureData[idx][1].folders) {
var folder = fileStructureData[idx][1].folders[jdx].folder;
if(folder.id == data.folder.id) {
// Update the cached data for the folder
if(folder.includes_files) {
data.folder.includes_files = folder.includes_files;
}
fileStructureData[idx][1].folders[jdx] = data;
// For each visual representation, update the name
// and insert into the dom if not there already
$files_structure.find(".folder_" + folder.id).each(function() {
var folder = files.itemData($(this).parent("ul").parent("li"));
folder = folder || {parent_folder_id: null};
if(folder.id == data.folder.parent_folder_id) {
if(!$(this).hasClass('context')) {
$(this).children(".name").text(data.folder.name)
// add 'title="this is the filename.txt" so you can read files/folders that have really long names
.attr('title', data.folder.name);
}
if(!already_in_place) {
$(this).prev("li.separator").remove();
var $parent = $(this).parent("ul").parent("li");
var $before = null;
var $new_folder = $(this);
var new_folder_el = $(this)[0];
var new_folder_name = files.itemData($(this)).name || "";
$parent.children("ul").children("li:not(.separator)").each(function() {
var current_folder_name = files.itemData($(this)).name || "";
var $current_folder = $(this);
var current_folder_el = $current_folder[0];
if(current_folder_el != new_folder_el && (!$current_folder.hasClass('folder') || new_folder_name.toLowerCase() < current_folder_name.toLowerCase())) {
$before = $current_folder;
return false;
}
});
if($before) {
$before.before($new_folder.show())
.before("<li class='separator'/>");
} else {
$parent.children("ul")
.append("<li class='separator'/>")
.append($new_folder.show());
}
}
} else {
moved = true;
}
});
found = true;
if(moved) {
$files_structure.find(".folder_" + folder.id).remove();
}
}
}
if(!found || moved) {
files.foldersStillLoading = files.foldersStillLoading || {};
files.foldersStillLoading[data.folder.id] = data;
files.refreshContext(context_string);
if(context_string != folder_context_string) {
files.refreshContext(folder_context_string);
}
}
}
}
if(refresh !== false ) {
files.refreshView(data.folder);
}
},
refreshView: function(file) {
$files_structure.find("li.node.active-node,li.leaf.active-leaf").filter(":first").children(".text:visible:first").click();
if(file && file.id) {
$files_content.find(".file_" + file.id).mouseover();
$files_content.find(".folder_" + file.id).mouseover();
}
$add_file_link.triggerHandler('show');
},
currentItemData: function() {
return files.itemData($files_structure.find("li.node.active-node,#files_structure li.leaf.active-leaf"));
},
currentContext: function() {
var context_string = files.currentItemData().context_string;
for(var idx in fileStructureData) {
if(fileStructureData[idx][0].context_string == context_string) {
return fileStructureData[idx][0].context;
}
}
return null;
},
clearDataCache: function() {
files.clearDataCache.cacheIndex++;
},
itemData: function($node) {
var res = $node.data('item_data');
if(res && res.cacheIndex == files.clearDataCache.cacheIndex) {
return res;
}
var res = files.uncachedItemData($node);
if(res) {
res.cacheIndex = files.clearDataCache.cacheIndex;
$node.data('item_data', res);
}
return res;
},
uncachedItemData: function($node) {
if($node.closest("#files_content").length > 0) {
return files.itemData($node.data('node'));
}
var id = $node.getTemplateData({textValues: ['id']}).id;
for(var idx in fileStructureData) {
var context = fileStructureData[idx];
var context_object = null;
if($node.hasClass('file')) {
var file_list = context[1].files;
for(var jdx in file_list) {
var file = file_list[jdx].attachment;
if(file.id == id) {
file.context_string = $.underscore(file.context_type) + "_" + file.context_id;
file.root_context_string = context[0].context_string;
file.context = context[0].context;
file.name = file.display_name;
return file;
}
}
} else if($node.hasClass('collaborations')) {
if($node.parents("li.context:last").hasClass(context[0].context_string)) {
res = $node.getTemplateData({textValues: ['name']});
res.context_string = context[0].context_string;
res.context = context[0].context;
return res;
}
} else if($node.hasClass('groups')) {
if($node.parents("li.context:last").hasClass(context[0].context_string)) {
res = $node.getTemplateData({textValues: ['name']});
res.context_string = context[0].context_string;
res.context = context[0].context;
return res;
}
} else if($node.hasClass('collaboration')) {
var collaborations = context[1].collaborations;
for(var jdx in collaborations) {
var collaboration = collaborations[jdx].collaboration;
if(collaboration.id == id) {
collaboration.context_string = $.underscore(collaboration.context_type) + "_" + collaboration.context_id;
collaboration.root_context_string = context[0].context_string;
collaboration.name = collaboration.title;
return collaboration;
}
}
} else if($node.hasClass('folder')) {
var folders = context[1].folders;
for(var jdx in folders) {
var folder = folders[jdx].folder;
if(folder.id == id) {
folder.context_string = $.underscore(folder.context_type) + "_" + folder.context_id;
folder.root_context_string = context[0].context_string;
if($node.hasClass('context')) {
folder.name = $node.getTemplateData({textValues: ['name']}).name;
}
folder.context = context[0].context;
return folder;
}
}
} else if($node.hasClass('group')) {
var groups = context[1].groups;
for(var jdx in groups) {
var group = groups[jdx].group || groups[jdx].course_assigned_group;
group.context_string = $.underscore(group.context_type) + "_" + group.context_id;
group.root_context_string = context[0].context_string;
if(group.id == id) {
return group;
}
}
}
}
if($node.hasClass('folder')) {
var context = null;
for(var idx in fileStructureData) {
if($node.closest('.context').hasClass(fileStructureData[idx][0].context_string)) {
context = fileStructureData[idx];
}
}
for(var idx in files.foldersStillLoading) {
if(files.foldersStillLoading[idx].folder.id == id) {
var folder = files.foldersStillLoading[idx].folder;
folder.name = $node.getTemplateData({textValues: ['name']}).name;
folder.context_string = context[0].context_string;
folder.context = context[0].context;
return folder;
}
}
if(context) {
var folder = {};
folder.name = $node.getTemplateData({textValues: ['name']}).name;
folder.id = id;
folder.context_string = context[0].context_string;
folder.permissions = {read_contents: true};
folder.context = context[0].context;
folder.false_folder = true;
return folder;
}
}
return null;
}
});
$(document).ready(function() {
files.init();
setInterval(function() {
$add_file_link.triggerHandler('show');
}, 1000);
$(".folder_item").live('mousedown', function(event) {
event.preventDefault();
});
$(".folder_item.ui-draggable").live('mouseover', function() {
$(this).find(".item_icon").attr('title', I18n.t('titles.drag_to_move', 'Drag to move to a different folder'));
});
// on hover of the swfupload link, manually set the underline on
// the add files link because otherwise the swf keeps the link from
// registering mouseover events.
$swfupload_holder.hover(function(e) {
$add_file_link.css('text-decoration', 'underline');
}, function(e) {
$add_file_link.css('text-decoration', 'none');
});
$add_file_link.bind('show', function() {
var linkWidth = $add_file_link.width();
var linkHeight = $add_file_link.height();
var linkOffset = $add_file_link.offset();
var holderOffset = $files_content.offset();
linkOffset.left = linkOffset.left - holderOffset.left;
linkOffset.top = linkOffset.top - holderOffset.top;
$swfupload_holder.css({
width: linkWidth + 5,
height: linkHeight + 5,
top: linkOffset.top - 5,
left: linkOffset.left - 5
});
});
$("#file_uploads_dialog_link").click(function(event) {
event.preventDefault();
$("#file_uploads").dialog({
title: I18n.t('titles.file_uplaods_queue', "File Uploads Queue")
});
});
setTimeout(function() {
$files_structure.find(".folder > .text").droppable(files.droppable_options);
$("#files_structure_list > li").hide();
$files_structure_list.instTree({
autoclose: false,
multi: false,
dragdrop: false,
onExpand: function(node) {
if(node.hasClass('folder')) {
var folder = files.itemData(node);
if(folder && !folder.includes_files) {
files.getFilesForFolder(folder, false);
}
}
},
onCollapse: function(node) {
if(node.find(".node.active-node,.leaf.active-leaf").length > 0) {
node.find(".text:visible:first").click();
}
},
onClick: function(event, node) {
$files_content.find(".content_panel").addClass('to_be_hidden');
$files_content.find(".folder_item").addClass('to_be_removed');
$files_content.find(".catcher").addClass('to_be_removed');
$files_content.find(".file_preview").remove();
$files_content.find(".message").remove();
var clearExtras = function() {
$files_content.find(".content_panel.to_be_hidden").hide();
$files_content.find(".catcher.to_be_removed").remove();
$files_content.find(".folder_item.to_be_removed").remove();
};
var data = files.itemData(node);
var path = encodeURIComponent(files.fullPath(node));
if(location.hash != "#" + path) {
location.replace("#" + path);
}
// $swfupload_holder.css('left', -1000);
if(!data.includes_files && data.full_name) {
files.getFilesForFolder(data);
}
if(data.context_string) {
if(INST) {
INST.interaction_context = data.context_string;
}
files.updatePageView(data.context_string);
}
if(node.hasClass('node')) {
var folder_url = $.replaceTags($("." + data.context_string + "_folder_url").attr('href'), 'id', data.id);
var cancelled = false;
var $no_content = $("<li class='message'>" + I18n.t('messages.folder_empty', "Nothing in this Folder") + "</li>");
if(node.hasClass('folder')) {
if(!data || !data.permissions || !data.permissions.read_contents) {
$files_content.find(".content_panel:last")
.after("<li class='message'>" + I18n.t('messages.access_denied', "You cannot read the contents of this folder.") + "</li>");
cancelled = true;
} else {
// add a control panel to the top for adding files, folders to this
var $panel = $("#folder_panel");
$panel.find(".rename_item_link,.delete_item_link,.folder_url").attr('href', folder_url);
$panel.find(".breadcrumb").empty().append(files.breadcrumb());
$panel.toggleClass('editable_content_panel', !!((data.context && data.context.permissions && data.context.permissions.manage_files) || (data.permissions && data.permissions.update)))
.toggleClass('addable_content_panel', !!((data.context && data.context.permissions && data.context.permissions.manage_files) || (data.permissions && data.permissions.update)))
.toggleClass('downloadable_content_panel', !$panel.hasClass('editable_content_panel') && !$panel.hasClass('addable_content_panel') && !!(data.permissions && data.permissions.read_contents));
$panel.removeClass('to_be_hidden');
$panel.find(".download_zip,.upload_zip").hide();
if(node.hasClass('context') || !(data && data.permissions && data.permissions.update)) {
$panel.removeClass('editable_content_panel');
}
var download_folder_url = $.replaceTags($("." + data.context_string + "_folder_url").attr('href') + "/download", 'id', data.id);
$(".download_zip_link").attr('href', download_folder_url);
$(".upload_zip_link").attr('href', $("." + data.context_string + "_import_url").attr('href') + "?return_to=" + encodeURIComponent(location.href) + "&folder_id=" + data.id);
data.unlock_at_string = $.parseFromISO(data.unlock_at).datetime_formatted;
data.lock_at_string = $.parseFromISO(data.lock_at).datetime_formatted;
$panel.find(".lock_after").showIf(data.lock_at);
$panel.find(".lock_until").showIf(data.unlock_at);
$panel.find(".currently_locked_box").showIf(data.currently_locked);
$panel.find(".lock_item_link").showIf(data.parent_folder_id && !data.currently_locked);
$panel.find(".unlock_item_link").showIf(data.parent_folder_id && data.currently_locked);
$panel.find(".download_zip").showIf(data.permissions && data.permissions.read_contents);
$panel.find(".upload_zip").showIf(data.context && data.context.permissions && data.context.permissions.manage_files);
$panel.find(".edit_link").showIf(data.context && data.context.permissions && data.context.permissions.manage_files);
$panel.fillTemplateData({data: data});
$panel.data('node', node);
$panel.show();
$add_file_link.triggerHandler('show');
}
} else if(node.hasClass('collaborations')) {
var $panel = $("#collaborations_panel");
var context = data.context;
$panel.find(".header .name").text(context.name);
$panel.find(".breadcrumb").empty().append(files.breadcrumb());
var collaborations_url = $("." + data.context_string + "_collaborations_url").attr('href');
$panel.find(".collaborations_link").attr('href', collaborations_url);
$panel.find(".add_collaboration_link").attr('href', collaborations_url);
$panel.find(".view_collaborations").showIf(context && context.permissions && context.permissions.manage_grades);
$panel.removeClass('to_be_hidden');
$panel.toggleClass('addable_content_panel', !!(data.context && data.context.permissions && data.context.permissions.create_collaborations));
$panel.data('node', node);
$panel.show();
} else if(node.hasClass('groups')) {
var $panel = $("#groups_panel");
var context = data.context;
var groups_url = $("." + data.context_string + "_groups_url").attr('href');
$panel.find(".category_name").text(data.name);
$panel.find(".context_name").text(context.name);
$panel.find(".breadcrumb").empty().append(files.breadcrumb());
$panel.find(".groups_link").attr('href', groups_url);
$panel.removeClass('to_be_hidden');
if(context && context.permissions && context.permissions.read_roster) {
$panel.toggleClass('addable_content_panel', true);
}
$panel.show();
}
if(!cancelled) {
var nodeIdx = 0;
var nodeCount = node.children("ul").children("li.node,li.leaf").length;
clearExtras.already_cleared = true;
setTimeout(function() {
var added = false;
node.children("ul")
.children("li.node,li.leaf")
.each(function() {
nodeIdx++;
if(nodeIdx < files.nodeClumpSize) {
newItem = files.addContentItem($(this), true);
if(newItem) { added = true; }
}
});
$files_content.find("li.folder_item").show();
if(nodeCount >= files.nodeClumpSize) {
files.addScrollCatcher();
}
if(added) {
files.refreshContentListeners();
}
if(node.children("ul").children("li.node,li.leaf").length === 0 || (node.hasClass('folder') && !data.includes_files)) {
if(node.hasClass('folder') && !data.includes_files) {
$no_content.addClass('no_content');
$no_content.text(I18n.t('messages.loading_files', "Loading Files..."));
files.getFilesForFolder(data, function(data) {
if(data.files.length > 0) {
files.refreshView();
} else {
$files_content.find(".message.no_content").remove();
}
});
}
if($files_content.find(".message.no_content").length === 0) {
if (node.hasClass('collaborations')) {
var find_out_more = "";
if(data.context.permissions.create_collaborations) {
find_out_more = '<p>' + I18n.t('descriptions.collaborations2', 'To find out more about a particular type of collaboration, click &quot;New collaboration&quot; and then choose that type in the dropdown list.') + '</p>';
}
$no_content.html([
'<div class="ui-state-highlight" style="padding:1em;">',
'<p>', I18n.t('descriptions.collaborations',
'Collaborations are a way for you to use web-based tools like ' +
'Google Docs and EtherPad ' +
'to work collaboratively on tasks like group papers or note-taking. This is a special folder that shows you any collaborations you have created ' +
'so you have an easy place to keep track of and create those collaborations'),
'</p>',
find_out_more,
'</div>',
'<p>', I18n.t('messages.no_collaborations', "There are no collaborations to show"), '</p>'
].join('').replace('Google Docs', '<a href="http://docs.google.com">Google Docs</a>').replace('EtherPad', '<a href="http://www.etherpad.org">EtherPad</a>'));
}
$files_content.append($no_content);
}
}
clearExtras();
}, 10);
}
} else {
if(node.hasClass('file')) {
// show a file control panel with file size, download link, etc.
var $panel = $("#file_panel");
var $preview = null;
data.unlock_at_string = $.parseFromISO(data.unlock_at).datetime_formatted;
data.lock_at_string = $.parseFromISO(data.lock_at).datetime_formatted;
$panel.find(".lock_after").showIf(data.lock_at);
$panel.find(".lock_until").showIf(data.unlock_at);
$panel.find(".currently_locked_box").showIf(data.currently_locked);
$panel.find(".lock_item_link").showIf(!data.currently_locked);
$panel.find(".unlock_item_link").showIf(data.currently_locked);
$panel.removeClass('to_be_hidden');
$panel.fillTemplateData({data: data});
var file_url = $.replaceTags($("#file_context_links ." + data.context_string + "_attachment_url").attr('href'), "id", data.id);
var download_url = $.replaceTags($("#file_context_links ." + data.context_string + "_download_attachment_url").attr('href'), "id", data.id);
$panel.find(".breadcrumb").empty().append(files.breadcrumb());
$panel.find(".attachment_url").attr('href', file_url).end()
.find(".download_item_link").attr('href', download_url);
$panel.removeClass('editable_content_panel');
if(data && data.permissions && data.permissions.update) {
// show a few more settings in the top control panel
$panel.addClass('editable_content_panel');
}
$panel.removeClass('panel_locked');
if(!data || !data.permissions || !data.permissions.download) {
// get rid of the download link, add a "this file is currently locked (details)"
$panel.addClass('panel_locked');
} else if (data && data.permissions && data.permissions.download && $.isPreviewable(data.content_type)) {
// show an inline preview
$preview = $("#content_templates .file_scribd_preview").clone(true);
$preview.append("<div id='doc_preview_holder'/>");
} else {
// show a few more details about the file, preview if possible
if(data && data.content_type.match(/image/)) {
$preview = $("#content_templates .file_image_preview").clone(true);
var url = $.replaceTags($("#file_context_links ." + data.context_string + "_preview_attachment_url").attr('href'), "id", data.id);
$preview.find("a").attr('href', download_url);
$preview.find("img")
.attr('src', $(".preview_loading_image").attr('src'))
.attr('src', url || "")
.attr('title', data.display_name);
} else if(data && data.content_type.match(/(video|audio)/) && data.media_entry_id) {
$preview = $("#content_templates .file_media_preview").clone(true);
$preview.fillTemplateData({data: data});
var type = data.content_type.match(/video/) ? 'video' : 'audio';
$preview.find(".media_preview").mediaComment('show_inline', 'maybe', type, download_url);
$preview.find("a").attr('href', download_url);
} else {
$preview = $("#content_templates .file_no_preview").clone(true);
$preview.fillTemplateData({data: data});
$preview.find("a").attr('href', download_url);
}
}
$panel.data('node', node);
$panel.show();
if ($preview) {
$preview.addClass('file_preview');
$files_content.append($preview);
var showPreview = function() {
$('#doc_preview_holder').loadDocPreview({
mimeType: data.content_type,
attachment_id: data.id,
height: '100%',
crocodoc_session_url: data.crocodocSession,
scribd_doc_id: data.scribd_doc && data.scribd_doc.attributes && data.scribd_doc.attributes.doc_id,
scribd_access_key: data.scribd_doc && data.scribd_doc.attributes && data.scribd_doc.attributes.access_key
});
files.viewFile(data.context_string, data.id);
};
if (data.permissions && data.permissions.download && $.isPreviewable(data.content_type)) {
if (data['crocodoc_available?'] && !data.crocodocSession) {
$preview.disableWhileLoading(
$.ajaxJSON(
'/attachments/' + data.id + '/crocodoc_sessions/',
'POST',
{annotations: false},
function(response) {
data.crocodocSession = response.session_url;
showPreview();
},
function() {
data['crocodoc_available?'] = false;
showPreview();
}
)
);
}
else {
showPreview();
}
}
}
$(window).triggerHandler('resize');
} else if(node.hasClass('collaboration')) {
var $panel = $("#collaboration_panel");
$panel.find(".header .name").text(data.name);
$panel.removeClass('to_be_hidden');
var subdata = {
name: data.name,
updated_at: $.parseFromISO(data.updated_at).datetime_formatted,
collaborator_count: (data.collaborator_ids || "").split(",").length,
description: data.description,
collaborator_ids: data.collaborator_ids
};
$panel.find(".breadcrumb").empty().append(files.breadcrumb());
var collaboration_url = $("." + data.context_string + "_collaboration_url").attr('href');
collaboration_url = $.replaceTags(collaboration_url, 'id', data.id);
$panel.find(".collaborations_link").attr('href', collaboration_url);
$panel.find(".edit_collaboration_link").attr('href', collaboration_url);
$panel.find(".delete_collaboration_link").attr('href', collaboration_url);
$panel.find(".view_item_link").attr('href', collaboration_url);
$panel.data('node', node);
var $subpanel = $("#collaboration_sub_panel");
$subpanel.find(".subcontent").fillTemplateData({data: subdata});
$subpanel.removeClass('to_be_hidden');
$subpanel.find(".subcontent .collaboration_icon").hide();
$subpanel.find(".subcontent .google_docs_icon").showIf(data.collaboration_type == 'google_docs');
$subpanel.find(".subcontent .etherpad_icon").showIf(data.collaboration_type == 'etherpad');
$subpanel.find(".view_item_link").attr('href', collaboration_url);
$subpanel.find(".collaborators").empty();
var ids = (subdata.collaborator_ids || '').split(',');
for(var idx in ids) {
var id = ids[idx];
var $user = $("." + data.context_string + "_user_list:first .collaborator_" + id).clone(true);
$user.find(":checkbox").remove();
$subpanel.find(".collaborators").append($user);
}
$files_content.find(".content_panel:last").after($subpanel); //.prepend($subpanel);
$panel.show();
$panel.removeClass('editable_content_panel');
// show the collaboration control panel with description, link, etc.
// show list of participants, delete (two possibles: delete for everyone, just take me off the ACL)
if(data && data.permissions && data.permissions.update) {
// show a few more settings for editing, deleting
// managing list of participants
$panel.addClass('editable_content_panel');
}
}
}
if(!clearExtras.already_cleared) {
clearExtras();
}
}
});
$("#files_structure_list > li.context").show();
if($("#files_structure_list .context").length == 1) {
files.expandFolder($("#files_structure_list .context"));
}
}, 500);
$(window).bind('resize', function() {
var top = $files_structure.offset().top;
var height = $(window).height() - top;
var spaceNeededForFooter = 142;
var sectionTabsHeight = $("#section-tabs").height();
$files_structure.height(Math.max(sectionTabsHeight, height - spaceNeededForFooter));
$files_content.height(Math.max(sectionTabsHeight, height - spaceNeededForFooter));
var contentHeight = $files_content.height();
var panelHeight = $("#file_panel").outerHeight();
$("#doc_preview_holder").height(contentHeight - panelHeight);
});
$(".folder_item .edit_collaboration_link, #collaboration_panel .edit_collaboration_link").click(function(event) {
event.preventDefault();
event.stopPropagation();
$("#edit_collaboration_form").attr('action', $(this).attr('href'));
$("#edit_collaboration_form").attr('method', 'PUT');
$("#edit_collaboration_form .submit_button").text(I18n.t('buttons.update_collaboration', "Update Collaboration"));
$("#edit_collaboration_form .add_collaboration").hide();
if($files_content.find(".add_form:visible").length> 0) { return; };
$files_content.children(".message").remove();
var data = files.itemData($(this).parents(".folder_item,#collaboration_panel"));
var context_string = data.context_string;
$("#edit_collaboration_dialog").data('context_string', context_string);
var $users = $("." + context_string + "_user_list:first").clone(true);
var ids = (data.collaborator_ids || "").split(",");
$("#edit_collaboration_form").fillFormData(data, {object_name: 'collaboration'});
$users.find(".collaborator input").each(function() {
$(this).attr('id', $(this).attr('class'));
var id = $(this).parent("li.collaborator").getTemplateData({textValues: ['user_id']}).user_id;
if($.inArray(id, ids) != -1) {
$(this).attr('checked', true);
}
});
$("#edit_collaboration_dialog .collaborator_list").empty().append($users);
$("#edit_collaboration_dialog").dialog({
title: I18n.t('titles.edit_collaboration', 'Edit Collaboration'),
width: 500
});
});
$("#collaborations_panel .add_collaboration_link").click(function(event) {
event.preventDefault();
$("#edit_collaboration_form").attr('action', $(this).attr('href'));
$("#edit_collaboration_form").attr('method', 'POST');
$("#edit_collaboration_form .submit_button").text(I18n.t('buttons.add_collaboration', "Add Collaboration"));
$("#edit_collaboration_form .add_collaboration").show();
$("#collaboration_collaboration_type").triggerHandler('change');
if($files_content.find(".add_form:visible").length> 0) { return; };
$files_content.children(".message").remove();
var data = files.itemData($("#collaborations_panel").data('node'));
data.title = "";
data.description = "";
$("#edit_collaboration_form").fillFormData(data, {object_name: 'collaboration'});
var context_string = data.context_string;
$("#edit_collaboration_dialog").data('context_string', context_string);
var $users = $("." + context_string + "_user_list:first").clone(true);
$users.find(".collaborator input").each(function() {
$(this).attr('id', $(this).attr('class'));
});
$("#edit_collaboration_dialog .collaborator_list").empty().append($users);
$("#edit_collaboration_dialog").dialog({
title: I18n.t('titles.add_collaboration', 'Add New Collaboration'),
width: 500
});
});
$("#folder_panel .download_zip").click(function(event) {
event.preventDefault();
INST.downloadFolderFiles($(this).find(".download_zip_link").attr('href'));
});
$("#edit_collaboration_dialog").find(".select_all_link,.deselect_all_link").click(function(event) {
event.preventDefault();
var $link = $(this);
$("#edit_collaboration_dialog .collaborator_list :checkbox").each(function() {
$(this).attr('checked', $link.hasClass('select_all_link'));
});
});
$("#edit_collaboration_dialog .cancel_button").click(function() {
$("#edit_collaboration_dialog").dialog('close');
});
$("#edit_collaboration_form").formSubmit({
beforeSubmit: function(data) {
$(this).loadingImage();
},
success: function(data) {
var context_string = $("#edit_collaboration_dialog").data('context_string');
$("#edit_collaboration_dialog").dialog('close');
files.updateCollaboration(context_string, data);
$(this).loadingImage('remove');
},
error: function(data) {
$(this).loadingImage('remove');
$(this).formErrors(data);
}
});
$("#collaboration_collaboration_type").change(function() {
$("#edit_collaboration_dialog .collaboration_description").hide();
$("#edit_collaboration_dialog #" + $(this).val() + "_description").show();
$("#edit_collaboration_dialog .collaborate_data").show();
$("#edit_collaboration_dialog .collaboration_authorization").hide();
if($(this).val() == "google_docs" && $("#edit_collaboration_dialog #collaborate_authorize_google_docs").length > 0) {
$("#edit_collaboration_dialog .collaborate_data").hide();
$("#edit_collaboration_dialog #collaborate_authorize_google_docs").show();
}
}).triggerHandler('change');
$(".folder_item .edit_item_content_link").click(function(event) {
event.preventDefault();
event.stopPropagation();
var $item = $(this).parents(".folder_item,#file_panel,#folder_panel");
var data = files.itemData($item);
var url = $item.find(".download_url").attr('href');
var display_name = $item.find(".name:first").text();
var $dialog = $("#edit_content_dialog");
$dialog.data('update_url', $item.find(".rename_item_link").attr('href')).data('content_type', data.content_type || '').data('filename', data.filename || 'file_to_update');
$dialog.find(".display_name").text(display_name);
$dialog.find(".loading_message").text("Loading File Contents...").show().end()
.find(".content").hide();
$dialog.dialog({
width: 600,
height: 410,
buttons: [
{
text: I18n.t('cancel', 'Cancel'),
click: function() {
$("#edit_content_dialog").dialog('close');
}
},
{
text: I18n.t('update_file', 'Update File'),
click: submitFile,
'class': 'btn-primary'
}
],
close: function() {
var $textarea = $(this).find('textarea');
if ($textarea.data('tinyIsVisible')) {
$textarea.editorBox('toggle');
$textarea.data('tinyIsVisible', false);
}
}
});
$.ajax({
dataType: 'json',
error: function() {
$dialog.find(".loading_message").text(I18n.t('errors.loading_file', "Error Loading File Contents. Please try again."));
},
success: function(data) {
var body = data.body;
var $textarea = $dialog.find("textarea").val(body);
var inittedTiny = $textarea.data('rich_text');
var tinyIsVisible = $textarea.data('tinyIsVisible');
$textarea.css('width', '100%');
$dialog.find(".loading_message").hide().end().find(".content").show();
if ($item.hasClass('html')) {
$dialog.css('height', '380px');
$dialog.find('.switch_views').show().unbind('click').bind('click', function(event) {
event.preventDefault();
if (inittedTiny) {
$textarea.editorBox('toggle');
$textarea.data('tinyIsVisible', !tinyIsVisible);
} else {
inittedTiny = true;
setTimeout(function(){
$dialog.find('.html_edit_warning').fadeIn();
}, 250);
$textarea.editorBox({
tinyOptions: {
valid_elements: '*[*]',
extended_valid_elements: '*[*]',
plugins: "autolink,instructure_external_tools,instructure_contextmenu,instructure_links,instructure_embed,instructure_equation,instructure_equella,media,paste,table,inlinepopups"
}
});
$textarea.data('tinyIsVisible', !tinyIsVisible);
}
});
}
$dialog.find(".textarea").focus();
},
url: url.replace(/\/download/, "/contents")
});
});
function submitFile() {
var $dialog = $("#edit_content_dialog");
$dialog.find("button")
.attr('disabled', false)
.filter(".save_button")
.text(I18n.t('buttons.update_file', "Update File"));
$dialog.find("button")
.attr('disabled', true)
.filter(".save_button")
.text(I18n.t('messages.updating_file', "Updating File..."));
var context_string = files.currentItemData().context_string;
var $textarea = $dialog.find('textarea');
var content = $textarea.data('tinyIsVisible') ? $textarea.editorBox('get_code') : $textarea.val()
$.ajaxFileUpload({
url: $dialog.data('update_url'),
method: 'PUT',
binary: false,
data: {
'attachment[uploaded_data]': {
fake_file: true,
name: $dialog.data('filename'),
content_type: $dialog.data('content_type'),
content: content
}
},
success: function(data) {
$dialog.find("button")
.attr('disabled', false)
.filter(".save_button")
.text(I18n.t('buttons.update_file', "Update File"));
files.updateFile(context_string, data);
$dialog.dialog('close');
},
error: function() {
$dialog.find("button")
.attr('disabled', false)
.filter(".save_button")
.text(I18n.t('errors.update_file_failed', "Updating File Failed, please try again"));
}
});
}
$(".folder_item .preview_item_link").click(function(event) {
event.preventDefault();
event.stopPropagation();
files.selectFolder($(this).parents(".folder_item").data('node'));
});
$(".folder_item .rename_item_link,#file_panel .rename_item_link,#folder_panel .rename_item_link").click(function(event) {
event.preventDefault();
event.stopPropagation();
var $item = $(this).parents(".folder_item,#file_panel,#folder_panel");
var name = $item.getTemplateData({textValues: ['name']}).name;
$item.find(".name").hide()
.after($("#rename_entry_field"));
$("#rename_entry_field").val(name).focus().select();
$(this).blur();
});
$("#rename_entry_field").bind('blur', function(event, update) {
var $item = $(this).parents(".folder_item,#file_panel,#folder_panel");
if($item.length === 0) { return; }
var old_name = $item.getTemplateData({textValues: ['name']}).name;
var new_name = $(this).val();
if(update !== false && new_name != "" && old_name != new_name) {
$item.find(".name").text(new_name);
var data = files.itemData($item.data('node'));
var context_string = data.root_context_string;
if($item.hasClass('folder') || $item.attr('id') == 'folder_panel') {
var url = $.replaceTags($("#file_context_links ." + context_string + "_folder_url").attr('href'), 'id', data.id);
$.ajaxJSON(url, 'PUT', {'folder[name]': new_name}, function(data) {
files.updateFolder(context_string, {folder: data.folder, already_in_place: true});
}, function() {
});
} else {
var url = $.replaceTags($("#file_context_links ." + context_string + "_attachment_url").attr('href'), 'id', data.id);
$.ajaxJSON(url, 'PUT', {'attachment[display_name]': new_name}, function(data) {
files.updateFile(context_string, data);
}, function() {
});
}
}
$item.find(".name").show();
$(this).val("").appendTo($("#file_context_links"));
$(this).triggerHandler('blur', false);
});
$("#rename_entry_field").keycodes('return esc', function(event) {
$(this).triggerHandler('blur', event.keyString == 'return');
});
$(".folder_item .delete_item_link,#folder_panel .delete_item_link,#file_panel .delete_item_link").click(function(event) {
event.preventDefault();
event.stopPropagation();
var data = files.itemData($(this).parents(".folder_item"));
data = data || files.itemData($(this).parents("#folder_panel,#file_panel").data('node'));
var item_type = $(this).parents(".folder_item").hasClass('file') ? 'file' : 'folder';
if($(this).parents(".folder_item").hasClass('collaboration')) { item_type = 'collaboration'; }
$(this).parents(".folder_item").confirmDelete({
message: ($(this).parents(".folder_item").hasClass('folder') || $(this).hasClass('folder_url') ? I18n.t('prompts.delete_folder', "Are you sure you want to delete this folder and all of its contents?") : I18n.t('prompts.delete_file', "Are you sure you want to delete this file?")),
url: $(this).attr('href'),
success: function() {
if($files_structure.find(".file_" + data.id + ",.folder_" + data.id).filter(".active-node,.active-leaf").length > 0) {
files.selectFolder($files_structure.find(".file_" + data.id + ",.folder_" + data.id).filter(".active-node,.active-leaf").parent("ul").parent("li"));
}
$files_structure.find(".file_" + data.id).prev("li.separator").remove();
$files_structure.find(".file_" + data.id).remove();
$files_structure.find(".folder_" + data.id).prev("li.separator").remove();
$files_structure.find(".folder_" + data.id).remove();
$files_structure.find(".collaboration_" + data.id).prev("li.separator").remove();
$files_structure.find(".collaboration_" + data.id).remove();
files.refreshView();
files.updateQuota();
$(this).slideUp(function() {
$(this).remove();
});
}
});
});
$(".folder_item:not(.add_item)").click(function(event) {
var $item = $(this);
event.preventDefault();
if($files_content.filter(".dragging").length > 0) { return; }
if($(this).find("#rename_entry_field").length > 0) { return; }
event.stopPropagation();
if($item.data('parent_node')) {
files.expandFolder($item.data('parent_node'));
}
setTimeout(function() {
if($item.hasClass('folder')) {
files.expandFolder($item.data('node'));
var refresh = function() {
files.refreshView();
$(this).unbind('files_load', refresh);
};
$item.data('node').bind('files_load', refresh);
$item.data('node').children(".text").click();
} else if($item.hasClass('collaboration')) {
$item.data('node').children(".text").click();
} else {
$item.find(".name").focus();
location.href = $item.find(".download_url").attr('href');
}
}, 50);
});
$(".folder_item").hover(function(event, scroll) {
$(".folder_item_hover").removeClass('folder_item_hover');
$(this).addClass('folder_item_hover');
}, function() {
});
$("#folder_panel .add_file_link").click(function(event) {
event.preventDefault();
if($files_content.find(".add_form:visible").length> 0) { return; };
var $form = $("#add_file_form").clone(true)
.removeAttr('id');
$files_content.children(".message")
.remove();
$files_content.append($form);
$files_content.scrollToVisible($form);
var itemData = files.currentItemData();
$form.fillFormData({folder_id: itemData.id}, {object_name: 'attachment'});
$form.find("form")
.attr('action', $("#file_context_links ." +
itemData.context_string +
"_attachments_url").attr('href') +
".text");
$form.mouseover();
$form.find(":text:first")
.focus()
.select();
});
$("#folder_panel .add_folder_link").click(function(event) {
event.preventDefault();
if($files_content.find(".add_form:visible").length> 0) { return; };
var $form = $("#add_folder_form").clone(true).removeAttr('id');
$files_content.children(".message").remove();
$files_content.find("#folder_panel.addable_content_panel").after($form);
$files_content.scrollToVisible($form);
var itemData = files.currentItemData();
$form.fillFormData({parent_folder_id: itemData.id}, {object_name: 'folder'});
$form.find("form").attr('action', $("#file_context_links ." + itemData.context_string + "_folders_url").attr('href'));
$form.mouseover();
$form.find(":text:first").focus().select();
});
$("#add_folder_form :text").keycodes('esc', function(event) {
if(event.keyString == 'esc') {
$(this).trigger('blur', true);
}
});
$("#add_folder_form :text").bind('blur', function(event, isFromEscKey) {
if (isFromEscKey) {
$(this).parents("li").remove();
} else if ($.trim($(this).val())) {
$(this).parents("form").trigger('submit');
}
});
$("#add_folder_form .add_folder_form").formSubmit({
beforeSubmit: function(data) {
if($(this).hasClass('submitting')) { return false; }
$(this).addClass('submitting');
$(this).find(".name").show().text(data['folder[name]']);
$(this).find(":text").hide();
$(this).data('root_context_string', files.currentItemData().root_context_string);
},
success: function(data) {
$(this).removeClass('submitting');
for(var idx in fileStructureData) {
if(fileStructureData[idx][0].context_string == $(this).data('root_context_string')) {
fileStructureData[idx][1].folders.push(data);
}
}
var unsorted_folders = fileStructureData[0][1].folders;
fileStructureData[0][1].folders = _.sortBy(
// returns adds an empty string to ensure .toLowerCase() isn't calling on an undefined object
unsorted_folders, function(obj){ return (obj.folder.name || "").toLowerCase() }
);
var folder = data.folder;
var $folder = $files_structure.find(".folder_blank")
.clone(true)
.removeClass('folder_blank');
$folder.addClass('folder folder_' + folder.id);
$folder.fillTemplateData({data: {name: folder.name, id: folder.id}});
var $parent = $files_structure.find(".folder_" + folder.parent_folder_id);
$parent.children("ul").append("<li class='separator'/>");
$parent.children("ul").append($folder.show());
files.updateFolder($(this).data('root_context_string'), data);
$(this).parents("li").remove();
$folder.find('span').droppable(files.droppable_options);
files.refreshView(folder);
},
error: function(data) {
$(this).removeClass('submitting');
$(this).formErrors(data);
}
});
$("#add_file_form .add_file_form").formSubmit({
fileUpload: true,
beforeSubmit: function(data) {
$(this).data('context_string', files.currentItemData().context_string);
$(this).find(".loading_message").slideDown();
},
success: function(data) {
$(this).parents("li").remove();
files.updateFile($(this).data('context_string'), data);
files.updateQuota();
},
error: function(data) {
$(this).find(".loading_message").slideUp();
$(this).formErrors(data);
}
});
$("#add_file_form .cancel_button").click(function() {
$(this).parents("li").remove();
});
$(".folder_item .lock_item_link,#file_panel .lock_item_link,#folder_panel .lock_item_link").click(function(event) {
event.preventDefault();
event.stopPropagation();
var item_type = 'attachment';
var $form = $("#lock_attachment_form");
var $item = $(this).parents(".folder_item,#file_panel,#folder_panel");
var data = files.itemData($item) || files.itemData($item.data('node'));
var url = $(this).attr('href');
if($item.hasClass('folder') || $(this).parents("#folder_panel").length > 0) {
item_type = 'folder';
$form = $("#lock_folder_form");
}
$form.attr('action', url);
$form.data('context_string', data.context_string);
$("#lock_item_dialog form").hide();
$form.show();
data.lock_at = $.parseFromISO(data.last_lock_at).datetime_formatted;
data.unlock_at = $.parseFromISO(data.last_unlock_at).datetime_formatted;
data.locked = (!data.lock_at && !data.unlock_at) ? '1' : '0';
$("#lock_item_dialog").fillTemplateData({data: {name: data.name}});
$form.fillFormData(data, {
object_name: item_type
});
$form.find("#folder_just_hide,#attachment_just_hide").attr('checked', false).change();
$form.find(".item_type").text(item_type);
$("#lock_item_dialog").dialog({
modal: true,
width: 350,
title: item_type == 'folder' ? I18n.t('titles.lock_folder', "Lock Folder") : I18n.t('titles.lock_file', 'Lock File')
});
});
$("#folder_just_hide,#attachment_just_hide").change(function() {
$(this).parents("form").find(".full_lock").showIf(!$(this).attr('checked'));
$(this).parents("form").find(".lock_checkbox").change();
}).change();
$("#lock_item_dialog .cancel_button").click(function() {
$("#lock_item_dialog").dialog('close');
});
$("#lock_item_dialog .lock_checkbox").change(function() {
$(this).parents("table").find(".lock_range").showIf(!$(this).attr('checked'));
}).change();
$("#lock_attachment_form").formSubmit({
processData: function(data) {
return data;
},
beforeSubmit: function(data) {
$(this).loadingImage();
},
success: function(data) {
$(this).loadingImage('remove');
$("#lock_item_dialog").dialog('close');
files.updateFile($(this).data('context_string'), data);
}
});
$("#lock_folder_form").formSubmit({
processData: function(data) {
return data;
},
beforeSubmit: function(data) {
$(this).loadingImage();
},
success: function(data) {
$(this).loadingImage('remove');
$("#lock_item_dialog").dialog('close');
files.updateFolder($(this).data('context_string'), {folder: data.folder, already_in_place: true});
}
});
$(".folder_item .unlock_item_link,#file_panel .unlock_item_link,#folder_panel .unlock_item_link").click(function(event) {
event.preventDefault();
event.stopPropagation();
var item_type = 'attachment';
var $form = $("#lock_attachment_form");
var $item = $(this).parents(".folder_item,#file_panel,#folder_panel");
var item_data = files.itemData($item) || files.itemData($item.data('node'));
var url = $(this).attr('href');
if($item.hasClass('folder') || $(this).parents("#folder_panel").length > 0) {
item_type = 'folder';
$form = $("#lock_folder_form");
url = $item.find(".folder_url").attr('href');
}
$item.loadingImage();
var data = {};
data['[' + item_type + '][locked]'] = '';
data['[' + item_type + '][hidden]'] = '';
data['[' + item_type + '][lock_at]'] = '';
data['[' + item_type + '][unlock_at]'] = '';
$item.loadingImage();
$.ajaxJSON(url, 'PUT', data, function(data) {
$item.loadingImage('remove');
if(item_type == 'attachment') {
files.updateFile(item_data.context_string, data);
} else {
files.updateFolder(item_data.context_string, {folder: data.folder, already_in_place: true});
}
}, function(data) {
$item.loadingImage('remove');
});
});
if(location.hash === "" || location.hash == "#") {
var text = $("#files_structure_list .context:first .name:first").text();
location.href = "#" + encodeURIComponent(text);
}
$(document).fragmentChange(function(event, hash) {
setTimeout(function() {
files.selectNodeFromPath(hash.substring(1));
$files_structure.scrollToVisible($("li.active-node,li.active-leaf").find("span.name").filter(":first"));
}, 100);
}).fragmentChange();
setTimeout(function() {
$(window).triggerHandler('resize');
$("#file_swf").uploadify({
fileObjName: 'file',
swf: '/flash/uploadify/uploadify.swf',
uploader: 's3_url',
multi: true,
auto: false,
fileSizeLimit: 10737418240,
buttonText: "",
hideButton: true,
width: 60,
height: 22,
cancelImg: '/images/blank.png',
onInit: function() {
$add_file_link.text(I18n.t('links.add_files', "Add Files")).triggerHandler('show');
},
onSelect: fileUpload.swfFileQueue,
onCancel: fileUpload.swfCancel,
onUploadError: fileUpload.swfFileError,
onUploadStart: fileUpload.swfFileOpen,
onUploadProgress: fileUpload.swfFileProgress,
onUploadSuccess: fileUpload.swfFileSuccess
});
}, 1000);
});
})();
var fileUpload = {
ajaxUploadCount: 0,
swfUploadCount: 0,
queuedAjaxUploads: [],
currentlyUploading: false,
status_status: "hidden",
status_request: "hidden",
showStatus: function() {
fileUpload.status_request = "shown";
if(fileUpload.status_status == "hidden") {
fileUpload.status_status = "showing";
$("#file_uploads_progress").slideDown(null,null,function() {
setTimeout(function() {
fileUpload.status_status = "shown";
if(fileUpload.status_request == "hidden") fileUpload.hideStatus();
}, 3000);
});
}
},
hideStatus: function() {
fileUpload.status_request = "hidden";
if(fileUpload.status_status == "shown") {
fileUpload.status_status = "hiding";
$("#file_uploads_progress").slideUp(null,null,function() {
fileUpload.status_status = "hidden";
if(fileUpload.status_request == "shown") fileUpload.showStatus();
});
}
},
queueAjaxUpload: function(file, folder_id) {
fileUpload.ajaxUploadCount = fileUpload.queuedAjaxUploads.length;
var fileWrapper = {
file: file,
folder_id: folder_id,
name: file.name
};
var $file = fileUpload.initFile(fileWrapper);
$file.data('folder', files.currentItemData());
$file.find(".status").text("Queued");
fileUpload.queuedAjaxUploads.push(fileWrapper);
fileUpload.updateUploadCount();
fileUpload.uploadAjaxFiles();
},
uploadAjaxFiles: function(cycle) {
if(fileUpload.currentlyUploading && !cycle) { return; }
var file = fileUpload.queuedAjaxUploads.shift();
if(!file) {
fileUpload.currentlyUploading = false;
fileUpload.ajaxUploadCount = 0;
fileUpload.updateUploadCount();
} else {
fileUpload.currentlyUploading = true;
var $file = fileUpload.initFile(file);
$file.find(".status").text("Uploading");
$file.find(".progress_bar").progressbar('value', 10);
var folder = $file.data('folder');
var fileData = file.file;
$.ajaxFileUpload({
url: $("." + folder.context_string + "_attachments_url").attr('href'),
data: {
'attachment[uploaded_data]': fileData,
'attachment[display_name]': fileData.name,
'attachment[folder_id]': folder.id,
'duplicate_handling': file.file.duplicate_handling
},
method: 'POST',
success: function(data) {
setTimeout(function() {
fileUpload.uploadAjaxFiles(true);
}, 500);
var attachment = data.attachment;
var context_code = $.underscore(attachment.context_type) + "_" + attachment.context_id;
$file.find(".cancel_upload_link").hide().end()
.find(".status").text(I18n.t('messages.done_uploading', "Done uploading"));
$file.addClass('done');
setTimeout(function() {
$file.slideUp(function() {
$file.remove();
});
}, 5000);
if (data.deleted_attachment_ids) {
files.deleteAttachmentIds(data.deleted_attachment_ids);
}
files.updateFile(attachment.context_code, data);
},
error: function(data) {
setTimeout(function() {
fileUpload.uploadAjaxFiles(true);
}, 500);
$file.find(".status").text(I18n.t('#errors.failed', "Failed")).end()
.find(".cancel_upload_link").hide();
}
});
}
},
updateUploadCount: function() {
fileUpload.ajaxUploadCount = fileUpload.queuedAjaxUploads.length;
if(fileUpload.currentlyUploading) { fileUpload.ajaxUploadCount++; }
var count = (fileUpload.swfPreQueued.length + fileUpload.swfFiles.length + fileUpload.ajaxUploadCount);
var errorCount = $("#file_uploads .file_upload.errored:visible").length;
if(count === 0 && errorCount == 0) {
fileUpload.hideStatus();
var $msg = $("#file_upload_blank").clone(true).removeAttr('id').addClass('finished_message').empty();
$msg.text("Finished uploading all files");
if(!$("#file_uploads .file_upload:visible:first").hasClass('finished_message')) {
$("#file_uploads").prepend($msg);
$msg.slideDown('fast');
}
$msg.addClass('finished_message');
$msg.click(function() {
$(this).slideUp(function() {
$(this).remove();
});
});
setTimeout(function() {
$msg.slideUp(function() {
$msg.remove();
});
}, 5000);
} else {
$("#file_uploads_dialog_link").text(I18n.t('messages.uploading_files', {one: "Uploading 1 File...", other: "Uploading %{count} Files..."}, { count: count}));
if(count === 0) {
$("#file_uploads_dialog_link").text(I18n.t('messages.error_count', {one: "1 Error", other: "%{count} Errors"}, { count: errorCount}));
}
fileUpload.showStatus();
}
},
fileDialogComplete: function(numFilesSelected, numFilesQueued) {
try {
if (numFilesQueued > 0) {
this.startUpload();
}
} catch (ex) {
this.debug(ex);
}
},
swfPreQueued: [],
swfQueuedAndPendingFiles: [],
swfFiles: [],
swfFileQueueOnce: function(event, data) {
var queue = fileUpload.swfPreQueued;
var folder = files.currentItemData();
var filenames = [];
for (idx in queue) {
filenames.push(queue[idx].name);
}
files.preflight(folder.id, folder.context_string, filenames,
function(method) {
for (idx in queue) {
queue[idx].duplicate_handling = method;
}
},
fileUpload.swfFileQueueNext,
function() {
for (idx in queue) {
$("#file_swf").uploadify('cancel', queue[idx].id);
}
}
);
},
swfFileQueue: function(file) {
fileUpload.swfPreQueued.push(file);
clearTimeout(fileUpload.swfFileQueueOnceTimeout);
fileUpload.swfFileQueueOnceTimeout = setTimeout(fileUpload.swfFileQueueOnce, 500);
},
swfFileQueueNext: function() {
var file = fileUpload.swfPreQueued.shift();
if (file) {
fileUpload.swfFileQueueReal(file);
} else {
fileUpload.swfQueueComplete();
}
},
swfFileQueueReal: function(file) { //onSelect
var $file = fileUpload.initFile(file);
$file.data('folder', files.currentItemData());
$file.find(".status").text(I18n.t('messages.queued', "Queued"));
fileUpload.swfFiles.push(file);
var folder = $file.data('folder');
var post_params = {
'attachment[folder_id]': folder.id,
'attachment[filename]': file.name,
'attachment[context_code]': folder.context_string,
'no_redirect': true,
'attachment[duplicate_handling]': file.duplicate_handling
};
fileUpload.updateUploadCount();
$.ajaxJSON('/files/pending', 'POST', post_params, function(data) {
file.upload_url = data.proxied_upload_url || data.upload_url;
file.upload_params = data.upload_params;
$file.data('success_url', data.success_url);
if(!$file.hasClass('done')) {
fileUpload.swfQueuedAndPendingFiles.push(file);
fileUpload.swfUploadNext();
}
fileUpload.updateUploadCount();
}, function(data) {
$.flashError(
data && data.base && data.base.match(/quota/) ?
data.base :
I18n.t('upload_error', 'There was an error uploading your file')
);
$("#file_swf").uploadify('cancel', file.id);
$file.find(".cancel_upload_link").hide().end()
.find(".status").text("Upload Failed");
}, {skipDefaultError: true});
},
swfUploadNext: function() {
if(fileUpload.swfQueuedAndPendingFiles.length > 0) {
file = fileUpload.swfQueuedAndPendingFiles.shift();
if(file) {
$("#file_swf").uploadify('settings', 'uploader', file.upload_url);
$("#file_swf").uploadify('settings', 'formData', file.upload_params);
$("#file_swf").uploadify('upload', file.id);
}
}
fileUpload.updateUploadCount();
},
swfCancel: function(file) { // onCancel
var $file = fileUpload.initFile(file);
$("#file_uploads_dialog_link").text(I18n.t('errors.uploading', "Uploading Error"));
$file.addClass('done');
if(!$file.hasClass('errored') && !$file.hasClass('error_cancelled')) {
$file.find(".cancel_upload_link").hide().end()
.find(".status").text("Canceled");
fileUpload.swfFiles = $.grep(fileUpload.swfFiles, function(f) { return f.id != file.id; });
}
//fileUpload.swfUploadNext();
//return false;
},
swfFileError: function(file, errorCode, errorMsg, errorString, cancelable) { // onUploadError
cancelable = typeof(cancelable) != 'undefined' ? cancelable : true;
if (errorCode == SWFUpload.UPLOAD_ERROR.HTTP_ERROR && errorMsg == "201") {
// As of Chrome 21 on Windows, uploadify seems to be calling the error callback when
// the upload succeeds. Luckily we can see the success in the error code here and
// intercept it.
fileUpload.s3Success(file);
return;
}
var $file = fileUpload.initFile(file);
setTimeout(function() {
$file.addClass('error_cancelled');
//if(cancelable) $("#file_swf").uploadify('cancel', file.id, true); //TODO: always suppress?
}, 50);
fileUpload.swfFiles = $.grep(fileUpload.swfFiles, function(f) { return f.id != file.id; });
$("#file_uploads_dialog_link").text(I18n.t('errors.uploading', "Uploading Error"));
fileUpload.showStatus();
$file.find(".cancel_upload_link").hide().end()
.find(".status").text(I18n.t('errors.failed_uploading', "Failed uploading: %{error_info}", {error_info: errorString}));
$file.addClass('done').addClass('errored');
fileUpload.swfFileQueueNext();
},
swfFileOpen: function(file) { // onUploadStart
var $file = fileUpload.initFile(file);
if(file.upload_url) $("#file_swf").uploadify('settings', 'uploader', file.upload_url);
if(file.upload_params) $("#file_swf").uploadify('settings', 'formData', file.upload_params);
fileUpload.swfQueuedAndPendingFiles = $.grep(fileUpload.swfQueuedAndPendingFiles, function(f) { return f.id != file.id; });
$file.find(".progress_bar").progressbar('value', 1);
$file.find(".status").text(I18n.t('messages.uploading', "Uploading"));
},
swfFileProgress: function(file, bytesUploaded, bytesTotal, totalBytesUploaded, totalBytesTotal) { // onUploadProgress
var $file = fileUpload.initFile(file);
$file.find(".status").text(I18n.t('messages.uploading', "Uploading"));
$file.find(".cancel_upload_link").showIf(totalBytesUploaded < totalBytesTotal);
$file.find(".progress_bar").progressbar('value', 100 * totalBytesUploaded / totalBytesTotal);
},
s3Success: function(file) {
var $file = fileUpload.initFile(file);
$file.find(".status").text(I18n.t('messages.finalizing', "Finalizing"));
var errored = function() {
fileUpload.swfFileError(file, '', '', I18n.t('errors.unexpected_response', "didn't get back expected response"));
};
$.ajaxJSON($file.data('success_url'), 'GET', {}, function(data) {
if(data && data.attachment) {
fileUpload.swfFileSuccess(file, JSON.stringify(data), true);
if (data.deleted_attachment_ids) {
files.deleteAttachmentIds(data.deleted_attachment_ids);
}
} else {
errored();
}
}, errored);
},
swfFileSuccess: function(file, data, response) { // onUploadSuccess
if(data.indexOf("<PostResponse>") >= 0) {
// we just got back XML stuff from S3. that means success (?)
fileUpload.s3Success(file);
return;
}
var $file = fileUpload.initFile(file);
fileUpload.swfFiles = $.grep(fileUpload.swfFiles, function(f) { return f.id != file.id; });
$file.find(".status").text(I18n.t('messages.upload_complete', "Done uploading"));
$file.find(".cancel_upload_link").remove();
$file.find(".progress_bar").progressbar('value', 100);
$file.addClass('done');
var context_string = $file.data('folder').context_string;
setTimeout(function() {
$file.slideUp(function() {
$file.remove();
});
}, 5000);
if(data) {
try {
data = $.parseJSON(data);
if("errors" in data && !jQuery.isEmptyObject(data["errors"])) {
fileUpload.swfFileError(file, '', '', JSON.stringify(data["errors"]), false);
return;
} else {
data.swf = true;
setTimeout(function() {
if (data.deleted_attachment_ids) {
files.deleteAttachmentIds(data.deleted_attachment_ids);
}
files.updateFile(context_string, data);
}, 500);
}
} catch(e) {
fileUpload.swfFileError(file, '', '', e.toString(), false);
return;
}
} else {
$file.find(".status").text(I18n.t('warnings.file_uploaded_without_response', "File may have uploaded, but the server failed to respond. Reload the page to confirm."));
}
fileUpload.swfFileQueueNext();
},
swfQueueComplete: function() {
fileUpload.updateUploadCount();
},
initFile: function(file) {
if(!file.id) {
file.id = "tmp_" + Math.round(Math.random() * 9999);
}
var $file = $("#file_upload_" + file.id);
if($file.length === 0) {
$file = $("#file_upload_blank").clone(true).attr('id', "file_upload_" + file.id);
$("#file_uploads").append($file);
$file.find(".progress_bar").progressbar();
$file.click(function(event) {
if($(this).find(".cancel_upload_link:visible").length === 0 && $(this).hasClass('done')) {
event.preventDefault();
$(this).slideUp(function() {
$(this).remove();
fileUpload.updateUploadCount();
});
}
});
$file.find(".cancel_upload_link").click(function(event) {
event.preventDefault();
var id = ($(this).parents(".file_upload").attr('id') || "").substring(12);
$("#file_swf").uploadify('cancel', file.id);
});
}
$file.find(".file_name").text(file.name);
$file.slideDown('fast');
return $file;
},
attempt: 0,
file_details: {}
};
});