1var shinyTree = function(){ 2 callbackCounter = 0; 3 4 var treeOutput = new Shiny.OutputBinding(); 5 $.extend(treeOutput, { 6 find: function(scope) { 7 return $(scope).find('.shiny-tree'); 8 }, 9 renderValue: function(el, data) { 10 // Wipe the existing tree and create a new one. 11 $elem = $('#' + el.id); 12 13 $elem.jstree('destroy'); 14 15 $elem.html(data); 16 var plugins = []; 17 if ($elem.data('st-checkbox') === 'TRUE'){ 18 plugins.push('checkbox'); 19 } 20 if ($elem.data('st-search') === 'TRUE'){ 21 plugins.push('search'); 22 } 23 if ($elem.data('st-dnd') === 'TRUE'){ 24 plugins.push('dnd'); 25 } 26 if ($elem.data('st-types') === 'TRUE'){ 27 plugins.push('types'); 28 } 29 if ($elem.data('st-unique') === 'TRUE'){ 30 plugins.push('unique'); 31 } 32 if ($elem.data('st-sort') === 'TRUE'){ 33 plugins.push('sort'); 34 } 35 if ($elem.data('st-wholerow') === 'TRUE'){ 36 plugins.push('wholerow'); 37 } 38 if ($elem.data('st-contextmenu') === 'TRUE'){ 39 plugins.push('contextmenu'); 40 } 41 var sttypes = null; 42 var elidtypes = el.id.replace("-", '_'); 43 if (typeof window[elidtypes + "_sttypes"] !== 'undefined'){ 44 sttypes = window[elidtypes + "_sttypes"]; 45 } 46 var tree = $(el).jstree({ 47 'core': { 48 "check_callback" : ($elem.data('st-dnd') === 'TRUE') || ($elem.data('st-contextmenu') === 'TRUE'), 49 'multiple': ($elem.data('st-multiple') === 'TRUE'), 50 'animation': $elem.data('st-animation'), 51 'themes': { 52 'name': $elem.data('st-theme'), 53 'responsive': true, 54 'stripes': ($elem.data('st-theme-stripes') === 'TRUE'), 55 'icons': ($elem.data('st-theme-icons') === 'TRUE'), 56 'dots': ($elem.data('st-theme-dots') === 'TRUE') 57 } 58 }, 59 'checkbox': { 60 'three_state': ($elem.data('st-three-state') === 'TRUE'), 61 'tie_selection': ($elem.data('st-tie-selection') === 'TRUE'), 62 'whole_node': ($elem.data('st-whole-node') === 'TRUE') 63 }, 64 "types" : sttypes, 65 plugins: plugins}); 66 } 67 }); 68 Shiny.outputBindings.register(treeOutput, 'shinyTree.treeOutput'); 69 70 var treeInput = new Shiny.InputBinding(); 71 $.extend(treeInput, { 72 find: function(scope) { 73 return $(scope).find(".shiny-tree"); 74 }, 75 getType: function(){ 76 return "shinyTree"; 77 }, 78 getValue: function(el, keys) { 79 /** 80 * Prune an object recursively to only include the specified keys. 81 * Then add any data. 82 **/ 83 var treeid = $('#' + el.id); 84 var fixOutput = function(arr, keys){ 85 var arrToObj = function(ar){ 86 var obj = {}; 87 $.each(ar, function(i, el){ 88 //add the data for this node 89 var data = {}; 90 $.each($(treeid).jstree(true).get_node(el.id).data, function(key, val){ 91 if (typeof val === 'string'){ 92 data[key] = val.trim(); 93 } else { 94 data[key] = val; 95 } 96 }); 97 el.data = data; 98 obj['' + i] = el; 99 }); 100 return obj; 101 }; 102 103 var toReturn = []; 104 $.each(arr, function(i, obj){ 105 if (obj.children && obj.children.length > 0){ 106 obj.children = arrToObj(fixOutput(obj.children, keys)); 107 } 108 109 var clean = {}; 110 $.each(obj, function(key, val){ 111 if (keys.indexOf(key) >= 0) { 112 if (typeof val === 'string'){ 113 clean[key] = val.trim(); 114 } else { 115 clean[key] = val; 116 } 117 } 118 }); 119 120 toReturn.push(clean); 121 }); 122 result = arrToObj(toReturn); 123 return arrToObj(result); 124 }; 125 126 var tree = $.jstree.reference(el); 127 if (tree) { // May not be loaded yet. 128 if(tree.get_container().find("li").length>0) { // The tree may be initialized but empty 129 var js = tree.get_json(); 130 var fixed = fixOutput(js, ['id', 'state', 'text','children']); 131 callbackCounter++; 132 fixed.callbackCounter = callbackCounter; 133 return fixed; 134 } 135 } 136 }, 137 setValue: function(el, value) {}, 138 subscribe: function(el, callback) { 139 $(el).on("open_node.jstree", function(e) { 140 callback(); 141 }); 142 143 $(el).on("close_node.jstree", function(e) { 144 callback(); 145 }); 146 147 var opts = JSON.parse(el.attributes.options.nodeValue); 148 if (opts.setState && opts.setState === true) { 149 $(el).on("set_state.jstree", function(e) { 150 callback(); 151 }); 152 } 153 if (opts.refresh && opts.refresh === true) { 154 $(el).on("refresh.jstree", function(e) { 155 callback(); 156 }); 157 } 158 159 $(el).on("changed.jstree", function(e) { 160 callback(); 161 }); 162 163 $(el).on("ready.jstree", function(e){ 164 // Initialize the data. 165 callback(); 166 }); 167 168 $(el).on("move_node.jstree", function(e){ 169 callback(); 170 }); 171
172 // callbacks for contextmenue 173 if (el.dataset.stContextmenu == "TRUE") { 174 $(el).on("create_node.jstree", function(e){ 175 callback(); 176 }); 177 $(el).on("rename_node.jstree", function(e){ 178 callback(); 179 }); 180 $(el).on("delete_node.jstree", function(e){ 181 callback(); 182 }); 183 $(el).on("copy_node.jstree", function(e){ 184 callback(); 185 }); 186 $(el).on("cut.jstree", function(e){ 187 callback(); 188 }); 189 $(el).on("copy.jstree", function(e){ 190 callback(); 191 }); 192 $(el).on("paste.jstree", function(e){ 193 callback(); 194 }); 195 } 196 197 }, 198 unsubscribe: function(el) { 199 $(el).off(".jstree"); 200 }, 201 receiveMessage: function(el, message) { 202 // This receives messages of type "updateTree" from the server. 203 if(message.type == 'updateTree' && typeof message.data !== 'undefined') { 204 $(el).jstree(true).settings.core.data = JSON.parse(message.data); 205 $(el).jstree(true).refresh(true, true); 206 } 207 } 208 }); 209 210 Shiny.inputBindings.register(treeInput); 211 212 var exports = {}; 213 214 exports.initSearch = function(treeId, searchId, searchtime){ 215 $(function(){ 216 var to = false; 217 $('#' + searchId).keyup(function () { 218 if(to) { clearTimeout(to); } 219 to = setTimeout(function () { 220 var v = $('#' + searchId).val(); 221 $.jstree.reference('#' + treeId).search(v); 222 }, searchtime); 223 }); 224 }); 225 } 226 227 return exports; 228}()
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.