9a24eab7aa53e82ca200d92f532411f37d8487f3 braney Sat Feb 24 18:09:09 2018 -0800 add lazy loading to hgCollection, modify CSP policy to allow blob: diff --git src/hg/js/hgCollection.js src/hg/js/hgCollection.js index 8d73ea6..97612e7 100644 --- src/hg/js/hgCollection.js +++ src/hg/js/hgCollection.js @@ -1,21 +1,21 @@ // hgCollection.js - custom collection builder // Copyright (C) 2018 The Regents of the University of California var hgCollection = (function() { - var names = []; // a list of names that have been used + //$("#workScreen").css("display","block"); var selectedNode; var selectedTree; var $tracks; // the #tracks object var trees = []; var isDirty = false; var goTracks = false; var doAjaxAsync = true; var emptyCollectionText; var addWithoutCollectionText; function currentTrackItems(node) { // populate the menu for the currentCollection tree var items = { addItem: { // The "add" menu item label: "Add", @@ -170,30 +170,31 @@ return true; } return false; } return true; } function dialogCollection() { $("#doNewCollection").off ( "click" ); $("#doNewCollection").click ( newCollection ); $("#viewFuncDiv").show(); $("#customName").val("New Collection"); $("#customDescription").val("New Collection description"); $("#customVis").val("full"); $("#customColorInput").val("#0"); + $("#customColorPicker").spectrum("set", "#0"); $("#viewFunc").val("show all"); $( "#customName" ).select(); $('#collectionDialogHelp').show(); $('#trackDialogHelp').hide(); $( "#newCollectionDialog" ).dialog( 'option', 'title', 'Create New Collection'); $( "#newCollectionDialog" ).dialog("open"); } function newCollection() { var newName = $("#customName").val().trim(); if (!validateLabel(newName)) return; var newDescription = $("#customDescription").val().trim(); if (!validateLabel(newDescription)) @@ -218,92 +219,91 @@ $(selectedTree).jstree("set_icon", newNode, '../images/folderC.png'); $(selectedTree).jstree("deselect_node", selectedNode); $(selectedTree).jstree("select_node", newNode.id); $(selectedTree).on("move.jstree", moveNode); rebuildLabel(); } function addCollection(trees, list) { // called when outputting JSON of all the collectionList var collectTree = trees[list.id]; var v = collectTree.jstree(true).get_json('#', {flat:true, no_data:true, no_state:true, no_a_attr:true}); var mytext = JSON.stringify(v); return mytext; } - function saveCollections(trees) { - // called when the "Save" button is pressed + function finishSaving() { + // save the collection tree to the server var json = "["; var v = $(selectedTree).jstree(true).get_json('#', {flat:true, no_data:true, no_state:true, no_a_attr:true}); var children; var parents = {}; for(ii=0; ii < v.length; ii++) { if (v[ii].parent === '#') { parents[v[ii].id] = v[ii].text; } } for(ii=0; ii < v.length; ii++) { - if (v[ii].li_attr.class === undefined) { + if (v[ii].li_attr.name === undefined) { alert(parents[v[ii].parent] + " does not have any wiggles. Not saved."); } } json += JSON.stringify(v); json += ']'; var requestData = 'jsonp=' + json; $.ajax({ data: requestData , async: doAjaxAsync, dataType: "JSON", type: "PUT", url: "hgCollection?cmd=saveCollection", trueSuccess: updatePage, success: catchErrorOrDispatch, error: errorHandler, }); } + function saveCollections(trees) { + // called when the "Save" button is pressed + $("#workScreen").css("display","block"); + $(selectedTree).on("open_all.jstree", finishSaving); + $(selectedTree).jstree('open_all'); + } + function rebuildLabel() { // rebuild the label for tree item var newText = selectedNode.li_attr.shortlabel + " (" + selectedNode.li_attr.longlabel + ")"; $(selectedTree).jstree('rename_node', selectedNode, newText); isDirty = true; } function colorChange() { // change the color for a track isDirty = true; - var color = $("#customColorPicker").spectrum("get"); $('#customColorInput').val(color); + var color = $("#customColorPicker").spectrum("get"); + $('#customColorInput').val(color); } function isDraggable(nodes) { // only children can be dragged var ii; for (ii=0; ii < nodes.length; ii++) if (nodes[ii].children.length !== 0) return false; return true; } - function recordNames(tree) { - // keep an accounting of track names that have been used - var v = $(tree).jstree(true).get_json('#', {'flat': true}); - for (i = 0; i < v.length; i++) { - var z = v[i]; - names[z.li_attr.name] = 1; - } - } - function checkEmpty(parentId) { if ($('#'+parentId).hasClass('empty')) { var parentNode = $(selectedTree).jstree('get_node', parentId); var stub; for (i = 0; i < parentNode.children.length; i++) { stub = $(selectedTree).jstree('get_node', parentNode.children[i]); if (stub.icon === true) break; } if (i === parentNode.children.length) return; $(selectedTree).jstree('delete_node', stub); $('#'+parentId).removeClass('empty'); @@ -331,44 +331,66 @@ var node = treeObject.jstree("get_node", id); if (node.children.length === 0) { var parentId = $(selectedNode).attr('id'); parentId = findCollection(selectedNode); checkEmpty(parentId); isDirty = true; $(selectedTree).jstree("copy_node", node, parentId,'last'); } } function minusHit (event, data) { // called with the minus icon is hit var treeObject = $(event.currentTarget).parent().parent(); var id = treeObject.attr('id'); var node = treeObject.jstree("get_node", id); - if (node.children.length === 0) { + if (node.parent !== '#') { isDirty = true; var parentNode = treeObject.jstree("get_node", node.parent); if (parentNode.children.length === 1) { treeObject.jstree("create_node", node.parent, emptyCollectionText); parentNode.li_attr.class = "folder empty"; } $(selectedTree).jstree( "delete_node", node); } } + function buildCollections(node, cb) { + // called when jstree wants data to open a node for the collection tree + cb.call(this, collectionData[node.id]); + } + + function buildTracks(node, cb) { + // called when jstree wants data to open a node for the tracks tree + cb.call(this, trackData[node.id]); + } + + function treeReady() { + // called when either the track or collection tree has been loaded + var firstChild = $(this).find("li").first(); + $(this).jstree("select_node", $(firstChild).attr("id")); + } + + function colorInputChange () { + // called when the color text edit box changes + $("#customColorPicker").spectrum("set",$("#customColorInput").val()); + } + function init() { // called at initialization time $body = $("body"); + $("#customColorInput").change(colorInputChange); emptyCollectionText = $('#emptyCollectionText').text(); addWithoutCollectionText = $('#addWithoutCollectionText').text(); // block user input when ajax is running $(document).on({ ajaxStart: function() { $body.addClass("loading"); }, ajaxStop: function() { $body.removeClass("loading"); } }); $('.gbButtonGoContainer').click(submitForm); window.addEventListener("beforeunload", function (e) { if (isDirty) { doAjaxAsync = false; @@ -394,114 +416,109 @@ color : $('#customColorInput').val(), showPalette: true, showInput: true, preferredFormat: "hex", change: colorChange, }; $("#customColorPicker").spectrum(trackOpt); $.jstree.defaults.core.check_callback = checkCallback; $.jstree.defaults.core.themes.dots = true; $.jstree.defaults.contextmenu.show_at_node = false; var addedOne = false; if ( $("#currentCollection ul").length !== 0) { addedOne = true; } - $("#currentCollection div").each(function(index) { - var newTree = this; - $(newTree).jstree({ + var newTree=$('#currentCollection'); + newTree.on("ready.jstree", treeReady); + newTree.jstree({ 'plugins' : ['dnd', 'conditionalselect', 'contextmenu'], //'plugins' : [ 'conditionalselect', 'contextmenu'], 'contextmenu': { "items" : currentCollectionItems}, 'core': { + "data" : buildCollections, "dblclick_toggle" : false, }, 'dnd': { "check_callback" : checkCallback, } }); - recordNames(newTree); - trees[this.id] = $(newTree); $(newTree).on("select_node.jstree", selectTreeNode); $(newTree).on("dblclick.jstree", doubleClickTreeNode); $(newTree).on("move_node.jstree", moveNode); $(newTree).on("copy_node.jstree", function (evt, data) { $(evt.target).jstree("open_node", data.parent); $(evt.target).jstree("set_icon", data.node, 'fa fa-minus-square'); }); $(newTree).on('click', '.jstree-themeicon ', minusHit); - // select the first cild - var firstChild = $(newTree).find("li").first(); - $(newTree).jstree("select_node", $(firstChild).attr("id")); selectedTree = newTree; - }); - treeDiv=$('#tracks'); treeDiv.jstree({ 'plugins' : ['conditionalselect', 'contextmenu'], 'contextmenu': { "items" : currentTrackItems}, 'dnd': { "check_callback" : checkCallback, 'always_copy' : true, is_draggable: isDraggable, }, 'core' : { + "data" : buildTracks, "check_callback" : checkCallback, "dblclick_toggle" : false, }, }); + treeDiv.on("ready.jstree", treeReady); treeDiv.on("select_node.jstree", function (evt, data) { $(evt.target).jstree("open_node", data.node); }); treeDiv.on('click', '.jstree-themeicon ', plusHit); - var firstChild = $(treeDiv).find("li").first(); - $(treeDiv).jstree("select_node", $(firstChild).attr("id")); + $("#workScreen").css("display","none"); } function submitForm() { // Submit the form (from GO button -- as in hgGateway.js) // Show a spinner -- sometimes it takes a while for hgTracks to start displaying. $('.gbIconGo').removeClass('fa-play').addClass('fa-spinner fa-spin'); goTracks = true; saveCollections(trees); } function updatePage(responseJson) { // called after AJAX call isDirty = false; if (!responseJson) { return; } if (goTracks) { // we go straight to hgTracks after save $form = $('#redirectForm'); $form.submit(); } } function getUniqueName(root) { // make sure name is unique in track hub - if (!names[root]) { - names[root] = true; + if (!collectionNames.has(root)) { + collectionNames.add(root); return root; } else { var counter = 1; for(; ; counter++) { var name = root + counter; - if (!names[name]) { - names[name] = true; + if (!collectionNames.has(name)) { + collectionNames.add(name); return name; } } } } return { init: init }; }());