comparison inkscape/firefox/content/tree_component.js @ 352:4350aa369149

Use jQuery UI components.
author wycc
date Mon, 09 Mar 2009 01:27:33 +0800
parents
children
comparison
equal deleted inserted replaced
351:4ae9888bbde6 352:4350aa369149
1 /*
2 * jsTree 0.9.6
3 * http://jstree.com/
4 *
5 * Copyright (c) 2008 Ivan Bozhanov (vakata.com)
6 *
7 * Dual licensed under the MIT and GPL licenses:
8 * http://www.opensource.org/licenses/mit-license.php
9 * http://www.gnu.org/licenses/gpl.html
10 *
11 * Date: 2009-02-24
12 *
13 */
14
15 (function($) {
16 // jQuery plugin
17 $.fn.tree = function (opts) {
18 return this.each(function() {
19 var conf = $.extend({},opts);
20 if(tree_component.inst && tree_component.inst[$(this).attr('id')]) tree_component.inst[$(this).attr('id')].destroy();
21 if(conf !== false) new tree_component().init(this, conf);
22 });
23 };
24 $.tree_create = function() {
25 return new tree_component();
26 };
27 $.tree_focused = function() {
28 return tree_component.inst[tree_component.focused];
29 };
30 // core
31 function tree_component () {
32 // instance manager
33 if(typeof tree_component.inst == "undefined") {
34 tree_component.cntr = 0;
35 tree_component.inst = {};
36
37 // DRAG'N'DROP STUFF
38 tree_component.drag_drop = {
39 isdown : false, // Is there a drag
40 drag_node : false, // The actual node
41 drag_help : false, // The helper
42 origin_tree : false,
43 marker : false,
44
45 move_type : false, // before, after or inside
46 ref_node : false, // reference node
47 appended : false, // is helper appended
48
49 foreign : false, // Is the dragged node a foreign one
50 droppable : [], // Array of classes that can be dropped onto the tree
51
52 open_time : false, // Timeout for opening nodes
53 scroll_time : false // Timeout for scrolling
54 };
55 // listening for clicks on foreign nodes
56 tree_component.mousedown = function(event) {
57 var tmp = $(event.target);
58 if(tree_component.drag_drop.droppable.length && tmp.is("." + tree_component.drag_drop.droppable.join(", .")) ) {
59 tree_component.drag_drop.drag_help = $("<li id='dragged' class='dragged foreign " + event.target.className + "'><a href='#'>" + tmp.text() + "</a></li>");
60 tree_component.drag_drop.drag_node = tree_component.drag_drop.drag_help;
61 tree_component.drag_drop.isdown = true;
62 tree_component.drag_drop.foreign = tmp;
63 tmp.blur();
64 event.preventDefault();
65 event.stopPropagation();
66 return false;
67 }
68 event.stopPropagation();
69 return true;
70 };
71 tree_component.mouseup = function(event) {
72 var tmp = tree_component.drag_drop;
73 if(tmp.open_time) clearTimeout(tmp.open_time);
74 if(tmp.scroll_time) clearTimeout(tmp.scroll_time);
75 if(tmp.foreign === false && tmp.drag_node && tmp.drag_node.size()) {
76 tmp.drag_help.remove();
77 if(tmp.move_type) {
78 var tree1 = tree_component.inst[tmp.ref_node.parents(".tree:eq(0)").attr("id")];
79 if(tree1) tree1.moved(tmp.origin_tree.container.find("li.dragged"), tmp.ref_node, tmp.move_type, false, (tmp.origin_tree.settings.rules.drag_copy == "on" || (tmp.origin_tree.settings.rules.drag_copy == "ctrl" && event.ctrlKey) ) );
80 }
81 tmp.move_type = false;
82 tmp.ref_node = false;
83 }
84 if(tmp.drag_node && tmp.foreign !== false) {
85 tmp.drag_help.remove();
86 if(tmp.move_type) {
87 var tree1 = tree_component.inst[tmp.ref_node.parents(".tree:eq(0)").attr("id")];
88 if(tree1) tree1.settings.callback.ondrop.call(null, tmp.foreign.get(0), tree1.get_node(tmp.ref_node).get(0), tmp.move_type, tree1);
89 }
90 tmp.foreign = false;
91 tmp.move_type = false;
92 tmp.ref_node = false;
93 }
94 // RESET EVERYTHING
95 tree_component.drag_drop.marker.hide();
96 tmp.drag_help = false;
97 tmp.drag_node = false;
98 tmp.isdown = false;
99 tmp.appended = false;
100 if(tmp.origin_tree) tmp.origin_tree.container.find("li.dragged").removeClass("dragged");
101 tmp.origin_tree = false;
102 event.preventDefault();
103 event.stopPropagation();
104 return false;
105 };
106 tree_component.mousemove = function(event) {
107 var tmp = tree_component.drag_drop;
108
109 if(tmp.isdown) {
110 if(tmp.open_time) clearTimeout(tmp.open_time);
111 if(!tmp.appended) {
112 if(tmp.foreign !== false) tmp.origin_tree = $.tree_focused();
113 tmp.origin_tree.container.children("ul:eq(0)").append(tmp.drag_help);
114 var temp = $(tmp.drag_help).offsetParent();
115 if(temp.is("html")) temp = $("body");
116 tmp.po = temp.offset();
117 tmp.w = tmp.drag_help.width();
118
119 tmp.appended = true;
120 }
121 tmp.drag_help.css({ "left" : (event.pageX - tmp.po.left - (tmp.origin_tree.settings.ui.rtl ? tmp.w : -5 ) ), "top" : (event.pageY - tmp.po.top + ($.browser.opera ? tmp.origin_tree.container.scrollTop() : 0) + 15) });
122
123 if(event.target.tagName == "IMG" && event.target.id == "marker") return false;
124
125 var cnt = $(event.target).parents(".tree:eq(0)");
126
127 // if not moving over a tree
128 if(cnt.size() == 0) {
129 if(tmp.scroll_time) clearTimeout(tmp.scroll_time);
130 if(tmp.drag_help.children("IMG").size() == 0) {
131 tmp.drag_help.append("<img style='position:absolute; " + (tmp.origin_tree.settings.ui.rtl ? "right" : "left" ) + ":4px; top:0px; background:white; padding:2px;' src='" + tmp.origin_tree.settings.ui.theme_path + "remove.png' />");
132 }
133 tmp.move_type = false;
134 tmp.ref_node = false;
135 tree_component.drag_drop.marker.hide();
136 return false;
137 }
138
139 var tree2 = tree_component.inst[cnt.attr("id")];
140 tree2.off_height();
141
142 // if moving over another tree and multitree is false
143 if( tmp.foreign === false && tmp.origin_tree.container.get(0) != tree2.container.get(0) && (!tmp.origin_tree.settings.rules.multitree || !tree2.settings.rules.multitree) ) {
144 if(tmp.drag_help.children("IMG").size() == 0) {
145 tmp.drag_help.append("<img style='position:absolute; " + (tmp.origin_tree.settings.ui.rtl ? "right" : "left" ) + ":4px; top:0px; background:white; padding:2px;' src='" + tmp.origin_tree.settings.ui.theme_path + "remove.png' />");
146 }
147 tmp.move_type = false;
148 tmp.ref_node = false;
149 tree_component.drag_drop.marker.hide();
150 return false;
151 }
152
153 if(tmp.scroll_time) clearTimeout(tmp.scroll_time);
154 tmp.scroll_time = setTimeout( function() { tree2.scrollCheck(event.pageX,event.pageY); }, 50);
155
156 var mov = false;
157 var st = cnt.scrollTop();
158
159 var et = $(event.target);
160 if(event.target.tagName == "A" ) {
161 // just in case if hover is over the draggable
162 if(et.is("#dragged")) return false;
163 if(tree2.get_node(event.target).hasClass("closed")) {
164 tmp.open_time = setTimeout( function () { tree2.open_branch(et); }, 500);
165 }
166
167 var goTo = {
168 x : (et.offset().left - 1),
169 y : (event.pageY - tree2.offset.top)
170 };
171 if(cnt.hasClass("rtl")) goTo.x += et.width() - 8;
172 var arr = [];
173 if( (goTo.y + st)%tree2.li_height < tree2.li_height/3 + 1 ) arr = ["before","inside","after"];
174 else if((goTo.y + st)%tree2.li_height > tree2.li_height*2/3 - 1 ) arr = ["after","inside","before"];
175 else {
176 if((goTo.y + st)%tree2.li_height < tree2.li_height/2) arr = ["inside","before","after"];
177 else arr = ["inside","after","before"];
178 }
179 var ok = false;
180 $.each(arr, function(i, val) {
181 if(tree2.checkMove(tmp.origin_tree.container.find("li.dragged"), et, val)) {
182 mov = val;
183 ok = true;
184 return false;
185 }
186 });
187 if(ok) {
188 switch(mov) {
189 case "before":
190 goTo.y = event.pageY - (goTo.y + st)%tree2.li_height - 2 ;
191 if(cnt.hasClass("rtl")) { tree_component.drag_drop.marker.attr("src", tree2.settings.ui.theme_path + "marker_rtl.gif").width(40); }
192 else { tree_component.drag_drop.marker.attr("src", tree2.settings.ui.theme_path + "marker.gif").width(40); }
193 break;
194 case "after":
195 goTo.y = event.pageY - (goTo.y + st)%tree2.li_height + tree2.li_height - 2 ;
196 if(cnt.hasClass("rtl")) { tree_component.drag_drop.marker.attr("src", tree2.settings.ui.theme_path + "marker_rtl.gif").width(40); }
197 else { tree_component.drag_drop.marker.attr("src", tree2.settings.ui.theme_path + "marker.gif").width(40); }
198 break;
199 case "inside":
200 goTo.x -= 2;
201 if(cnt.hasClass("rtl")) {
202 goTo.x += 36;
203 }
204 goTo.y = event.pageY - (goTo.y + st)%tree2.li_height + Math.floor(tree2.li_height/2) - 2 ;
205 tree_component.drag_drop.marker.attr("src", tree2.settings.ui.theme_path + "default/plus.gif").width(11);
206 break;
207 }
208 tmp.move_type = mov;
209 tmp.ref_node = $(event.target);
210 tmp.drag_help.children("IMG").remove();
211 tree_component.drag_drop.marker.css({ "left" : goTo.x , "top" : goTo.y }).show();
212 }
213 }
214 if(event.target.tagName != "A" || !ok) {
215 if(tmp.drag_help.children("IMG").size() == 0) {
216 tmp.drag_help.append("<img style='position:absolute; " + (tmp.origin_tree.settings.ui.rtl ? "right" : "left" ) + ":4px; top:0px; background:white; padding:2px;' src='" + tmp.origin_tree.settings.ui.theme_path + "remove.png' />");
217 }
218 tmp.move_type = false;
219 tmp.ref_node = false;
220 tree_component.drag_drop.marker.hide();
221 }
222 event.preventDefault();
223 event.stopPropagation();
224 return false;
225 }
226 return true;
227 };
228 };
229 return {
230 cntr : ++tree_component.cntr,
231 settings : {
232 data : {
233 type : "predefined", // ENUM [json, xml_flat, xml_nested, predefined]
234 method : "GET", // HOW TO REQUEST FILES
235 async : false, // BOOL - async loading onopen
236 async_data : function (NODE) { return { id : $(NODE).attr("id") || 0 } }, // PARAMETERS PASSED TO SERVER
237 url : false, // FALSE or STRING - url to document to be used (async or not)
238 json : false // FALSE or OBJECT if type is JSON and async is false - the tree dump as json
239 },
240 selected : false, // FALSE or STRING or ARRAY
241 opened : [], // ARRAY OF INITIALLY OPENED NODES
242 languages : [], // ARRAY of string values (which will be used as CSS classes - so they must be valid)
243 path : false, // FALSE or STRING (if false - will be autodetected)
244 cookies : false, // FALSE or OBJECT (prefix, open, selected, opts - from jqCookie - expires, path, domain, secure)
245 ui : {
246 dots : true, // BOOL - dots or no dots
247 rtl : false, // BOOL - is the tree right-to-left
248 animation : 0, // INT - duration of open/close animations in miliseconds
249 hover_mode : true, // SHOULD get_* functions chage focus or change hovered item
250 scroll_spd : 4,
251 theme_path : false, // Path to themes
252 theme_name : "default",// Name of theme
253 context : [
254 {
255 id : "create",
256 label : "Create",
257 icon : "create.png",
258 visible : function (NODE, TREE_OBJ) { if(NODE.length != 1) return false; return TREE_OBJ.check("creatable", NODE); },
259 action : function (NODE, TREE_OBJ) { TREE_OBJ.create(false, TREE_OBJ.selected); }
260 },
261 "separator",
262 {
263 id : "rename",
264 label : "Rename",
265 icon : "rename.png",
266 visible : function (NODE, TREE_OBJ) { if(NODE.length != 1) return false; return TREE_OBJ.check("renameable", NODE); },
267 action : function (NODE, TREE_OBJ) { TREE_OBJ.rename(); }
268 },
269 {
270 id : "delete",
271 label : "Delete",
272 icon : "remove.png",
273 visible : function (NODE, TREE_OBJ) { var ok = true; $.each(NODE, function () { if(TREE_OBJ.check("deletable", this) == false) ok = false; return false; }); return ok; },
274 action : function (NODE, TREE_OBJ) { $.each(NODE, function () { TREE_OBJ.remove(this); }); }
275 }
276 ]
277 },
278 rules : {
279 multiple : false, // FALSE | CTRL | ON - multiple selection off/ with or without holding Ctrl
280 metadata : false, // FALSE or STRING - attribute name (use metadata plugin)
281 type_attr : "rel", // STRING attribute name (where is the type stored if no metadata)
282 multitree : false, // BOOL - is drag n drop between trees allowed
283 createat : "bottom", // STRING (top or bottom) new nodes get inserted at top or bottom
284 use_inline : false, // CHECK FOR INLINE RULES - REQUIRES METADATA
285 clickable : "all", // which node types can the user select | default - all
286 renameable : "all", // which node types can the user select | default - all
287 deletable : "all", // which node types can the user delete | default - all
288 creatable : "all", // which node types can the user create in | default - all
289 draggable : "none", // which node types can the user move | default - none | "all"
290 dragrules : "all", // what move operations between nodes are allowed | default - none | "all"
291 drag_copy : false, // FALSE | CTRL | ON - drag to copy off/ with or without holding Ctrl
292 droppable : []
293 },
294 lang : {
295 new_node : "New folder",
296 loading : "Loading ..."
297 },
298 callback : { // various callbacks to attach custom logic to
299 // before focus - should return true | false
300 beforechange: function(NODE,TREE_OBJ) { return true },
301 beforeopen : function(NODE,TREE_OBJ) { return true },
302 beforeclose : function(NODE,TREE_OBJ) { return true },
303 // before move - should return true | false
304 beforemove : function(NODE,REF_NODE,TYPE,TREE_OBJ) { return true },
305 // before create - should return true | false
306 beforecreate: function(NODE,REF_NODE,TYPE,TREE_OBJ) { return true },
307 // before rename - should return true | false
308 beforerename: function(NODE,LANG,TREE_OBJ) { return true },
309 // before delete - should return true | false
310 beforedelete: function(NODE,TREE_OBJ) { return true },
311
312 onselect : function(NODE,TREE_OBJ) { }, // node selected
313 ondeselect : function(NODE,TREE_OBJ) { }, // node deselected
314 onchange : function(NODE,TREE_OBJ) { }, // focus changed
315 onrename : function(NODE,LANG,TREE_OBJ) { }, // node renamed ISNEW - TRUE|FALSE, current language
316 onmove : function(NODE,REF_NODE,TYPE,TREE_OBJ) { }, // move completed (TYPE is BELOW|ABOVE|INSIDE)
317 oncopy : function(NODE,REF_NODE,TYPE,TREE_OBJ) { }, // copy completed (TYPE is BELOW|ABOVE|INSIDE)
318 oncreate : function(NODE,REF_NODE,TYPE,TREE_OBJ) { }, // node created, parent node (TYPE is createat)
319 ondelete : function(NODE, TREE_OBJ) { }, // node deleted
320 onopen : function(NODE, TREE_OBJ) { }, // node opened
321 onopen_all : function(NODE, TREE_OBJ) { }, // all nodes opened
322 onclose : function(NODE, TREE_OBJ) { }, // node closed
323 error : function(TEXT, TREE_OBJ) { }, // error occured
324 // double click on node - defaults to open/close & select
325 ondblclk : function(NODE, TREE_OBJ) { TREE_OBJ.toggle_branch.call(TREE_OBJ, NODE); TREE_OBJ.select_branch.call(TREE_OBJ, NODE); },
326 // right click - to prevent use: EV.preventDefault(); EV.stopPropagation(); return false
327 onrgtclk : function(NODE, TREE_OBJ, EV) { },
328 onload : function(TREE_OBJ) { },
329 onfocus : function(TREE_OBJ) { },
330 ondrop : function(NODE,REF_NODE,TYPE,TREE_OBJ) {}
331 }
332 },
333 // INITIALIZATION
334 init : function(elem, opts) {
335 var _this = this;
336 this.container = $(elem);
337 if(this.container.size == 0) { alert("Invalid container node!"); return }
338
339 tree_component.inst[this.cntr] = this;
340 if(!this.container.attr("id")) this.container.attr("id","jstree_" + this.cntr);
341 tree_component.inst[this.container.attr("id")] = tree_component.inst[this.cntr];
342 tree_component.focused = this.cntr;
343
344 // MERGE OPTIONS WITH DEFAULTS
345 if(opts && opts.cookies) {
346 this.settings.cookies = $.extend({},this.settings.cookies,opts.cookies);
347 delete opts.cookies;
348 if(!this.settings.cookies.opts) this.settings.cookies.opts = {};
349 }
350 if(opts && opts.callback) {
351 this.settings.callback = $.extend({},this.settings.callback,opts.callback);
352 delete opts.callback;
353 }
354 if(opts && opts.data) {
355 this.settings.data = $.extend({},this.settings.data,opts.data);
356 delete opts.data;
357 }
358 if(opts && opts.ui) {
359 this.settings.ui = $.extend({},this.settings.ui,opts.ui);
360 delete opts.ui;
361 }
362 if(opts && opts.rules) {
363 this.settings.rules = $.extend({},this.settings.rules,opts.rules);
364 delete opts.rules;
365 }
366 if(opts && opts.lang) {
367 this.settings.lang = $.extend({},this.settings.lang,opts.lang);
368 delete opts.lang;
369 }
370 this.settings = $.extend({},this.settings,opts);
371
372 // PATH TO IMAGES AND XSL
373 if(this.settings.path == false) {
374 this.path = "";
375 $("script").each( function () {
376 if(this.src.toString().match(/tree_component.*?js$/)) {
377 _this.path = this.src.toString().replace(/tree_component.*?js$/, "");
378 }
379 });
380 }
381 else this.path = this.settings.path;
382
383 // DEAL WITH LANGUAGE VERSIONS
384 this.current_lang = this.settings.languages && this.settings.languages.length ? this.settings.languages[0] : false;
385 if(this.settings.languages && this.settings.languages.length) {
386 this.sn = get_sheet_num("tree_component.css");
387 var st = false;
388 var id = this.container.attr("id") ? "#" + this.container.attr("id") : ".tree";
389 for(var ln = 0; ln < this.settings.languages.length; ln++) {
390 st = add_css(id + " ." + this.settings.languages[ln], this.sn);
391 if(st !== false) {
392 if(this.settings.languages[ln] == this.current_lang) st.style.display = "inline";
393 else st.style.display = "none";
394 }
395 }
396 }
397
398 // DROPPABLES
399 if(this.settings.rules.droppable.length) {
400 for(var i in this.settings.rules.droppable) {
401 tree_component.drag_drop.droppable.push(this.settings.rules.droppable[i]);
402 }
403 tree_component.drag_drop.droppable = $.unique(tree_component.drag_drop.droppable);
404 }
405
406 // THEMES
407 if(this.settings.ui.theme_path === false) this.settings.ui.theme_path = this.path + "themes/";
408 this.theme = this.settings.ui.theme_path;
409 if(_this.settings.ui.theme_name) this.theme += _this.settings.ui.theme_name + "/";
410 add_sheet(_this.settings.ui.theme_path + "default/style.css");
411 if(this.settings.ui.theme_name && this.settings.ui.theme_name != "default") add_sheet(_this.theme + "style.css");
412
413 this.container.addClass("tree");
414 if(this.settings.ui.rtl) this.container.addClass("rtl");
415 if(this.settings.rules.multiple) this.selected_arr = [];
416 this.offset = false;
417
418 if(this.settings.ui.dots == false) this.container.addClass("no_dots");
419
420 // CONTEXT MENU
421 this.context_menu();
422
423 this.hovered = false;
424 this.locked = false;
425
426 // CREATE DUMMY FOR MOVING
427 if(this.settings.rules.draggable != "none" && tree_component.drag_drop.marker === false) {
428 var _this = this;
429 tree_component.drag_drop.marker = $("<img>")
430 .attr({
431 id : "marker",
432 src : _this.settings.ui.theme_path + "marker.gif"
433 })
434 .css({
435 height : "5px",
436 width : "40px",
437 display : "block",
438 position : "absolute",
439 left : "30px",
440 top : "30px",
441 zIndex : "1000"
442 }).hide().appendTo("body");
443 }
444 this.refresh();
445 this.attachEvents();
446 this.focus();
447 },
448 off_height : function () {
449 if(this.offset === false) {
450 this.container.css({ position : "relative" });
451 this.offset = this.container.offset();
452 var tmp = 0;
453 tmp = parseInt($.curCSS(this.container.get(0), "paddingTop", true),10);
454 if(tmp) this.offset.top += tmp;
455 tmp = parseInt($.curCSS(this.container.get(0), "borderTopWidth", true),10);
456 if(tmp) this.offset.top += tmp;
457 this.container.css({ position : "" });
458 }
459 if(!this.li_height) {
460 var tmp = this.container.find("ul li.closed, ul li.leaf").eq(0);
461 this.li_height = tmp.height();
462 if(tmp.children("ul:eq(0)").size()) this.li_height -= tmp.children("ul:eq(0)").height();
463 if(!this.li_height) this.li_height = 18;
464 }
465 },
466 context_menu : function () {
467 this.context = false;
468 if(this.settings.ui.context != false) {
469 var str = '<div class="context">';
470 for(var i in this.settings.ui.context) {
471 if(this.settings.ui.context[i] == "separator") {
472 str += "<span class='separator'>&nbsp;</span>";
473 continue;
474 }
475 var icn = "";
476 if(this.settings.ui.context[i].icon) icn = 'background-image:url(\'' + ( this.settings.ui.context[i].icon.indexOf("/") == -1 ? this.theme + this.settings.ui.context[i].icon : this.settings.ui.context[i].icon ) + '\');';
477 str += '<a rel="' + this.settings.ui.context[i].id + '" href="#" style="' + icn + '">' + this.settings.ui.context[i].label + '</a>';
478 }
479 str += '</div>';
480 this.context = $(str);
481 this.context.hide();
482 this.context.append = false;
483 }
484 },
485 // REPAINT TREE
486 refresh : function (obj) {
487 if(this.locked) return this.error("LOCKED");
488 var _this = this;
489
490 // SAVE OPENED
491 this.opened = Array();
492 if(this.settings.cookies && $.cookie(this.settings.cookies.prefix + '_open')) {
493 var str = $.cookie(this.settings.cookies.prefix + '_open');
494 var tmp = str.split(",");
495 $.each(tmp, function () {
496 _this.opened.push("#" + this.replace(/^#/,""));
497 });
498 this.settings.opened = false;
499 }
500 else if(this.settings.opened != false) {
501 $.each(this.settings.opened, function (i, item) {
502 _this.opened.push("#" + this.replace(/^#/,""));
503 });
504 this.settings.opened = false;
505 }
506 else {
507 this.container.find("li.open").each(function (i) { _this.opened.push("#" + this.id); });
508 }
509
510 // SAVE SELECTED
511 if(this.selected) {
512 this.settings.selected = Array();
513 if(this.selected_arr) {
514 $.each(this.selected_arr, function () {
515 if(this.attr("id")) _this.settings.selected.push("#" + this.attr("id"));
516 });
517 }
518 else {
519 if(this.selected.attr("id")) this.settings.selected.push("#" + this.selected.attr("id"));
520 }
521 }
522 else if(this.settings.cookies && $.cookie(this.settings.cookies.prefix + '_selected')) {
523 this.settings.selected = Array();
524 var str = $.cookie(this.settings.cookies.prefix + '_selected');
525 var tmp = str.split(",");
526 $.each(tmp, function () {
527 _this.settings.selected.push("#" + this.replace(/^#/,""));
528 });
529 }
530 else if(this.settings.selected !== false) {
531 var tmp = Array();
532 if((typeof this.settings.selected).toLowerCase() == "object") {
533 $.each(this.settings.selected, function () {
534 if(this.replace(/^#/,"").length > 0) tmp.push("#" + this.replace(/^#/,""));
535 });
536 }
537 else {
538 if(this.settings.selected.replace(/^#/,"").length > 0) tmp.push("#" + this.settings.selected.replace(/^#/,""));
539 }
540 this.settings.selected = tmp;
541 }
542
543 if(obj && this.settings.data.async) {
544 this.opened = Array();
545 obj = this.get_node(obj);
546 obj.find("li.open").each(function (i) { _this.opened.push("#" + this.id); });
547 this.close_branch(obj, true);
548 obj.children("ul:eq(0)").html("");
549 return this.open_branch(obj, true, function () { _this.reselect.apply(_this); });
550 }
551
552 var cls = "tree-default";
553 if(this.settings.ui.theme_name != "default") cls += " tree-" + _this.settings.ui.theme_name;
554
555 if(this.settings.data.type == "xml_flat" || this.settings.data.type == "xml_nested") {
556 this.scrtop = this.container.get(0).scrollTop;
557 var xsl = (this.settings.data.type == "xml_flat") ? "flat.xsl" : "nested.xsl";
558 this.container.getTransform(this.path + xsl, this.settings.data.url, { params : { theme_name : cls, theme_path : _this.theme }, meth : _this.settings.data.method, dat : _this.settings.data.async_data.apply(_this,[obj]) ,callback: function () { _this.context_menu.apply(_this); _this.reselect.apply(_this); } });
559 return;
560 }
561 else if(this.settings.data.type == "json") {
562 if(this.settings.data.json) {
563 var str = "";
564 if(this.settings.data.json.length) {
565 for(var i = 0; i < this.settings.data.json.length; i++) {
566 str += this.parseJSON(this.settings.data.json[i]);
567 }
568 } else str = this.parseJSON(this.settings.data.json);
569 this.container.html("<ul class='" + cls + "'>" + str + "</ul>");
570 this.container.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed");
571 this.container.find("li").not(".open").not(".closed").addClass("leaf");
572 this.context_menu();
573 this.reselect();
574 }
575 else {
576 var _this = this;
577 $.ajax({
578 type : this.settings.data.method,
579 url : this.settings.data.url,
580 data : this.settings.data.async_data(false),
581 dataType : "json",
582 success : function (data) {
583 var str = "";
584 if(data.length) {
585 for(var i = 0; i < data.length; i++) {
586 str += _this.parseJSON(data[i]);
587 }
588 } else str = _this.parseJSON(data);
589 _this.container.html("<ul class='" + cls + "'>" + str + "</ul>");
590 _this.container.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed");
591 _this.container.find("li").not(".open").not(".closed").addClass("leaf");
592 _this.context_menu.apply(_this);
593 _this.reselect.apply(_this);
594 }
595 });
596 }
597 }
598 else {
599 this.container.children("ul:eq(0)").attr("class", cls);
600 this.container.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed");
601 this.container.find("li").not(".open").not(".closed").addClass("leaf");
602 this.reselect();
603 }
604 },
605 // CONVERT JSON TO HTML
606 parseJSON : function (data) {
607 if(!data || !data.data) return "";
608 var str = "";
609 str += "<li ";
610 var cls = false;
611 if(data.attributes) {
612 for(var i in data.attributes) {
613 if(i == "class") {
614 str += " class='" + data.attributes[i] + " ";
615 if(data.state == "closed" || data.state == "open") str += " " + data.state + " ";
616 str += "' ";
617 cls = true;
618 }
619 else str += " " + i + "='" + data.attributes[i] + "' ";
620 }
621 }
622 if(!cls && (data.state == "closed" || data.state == "open")) str += " class='" + data.state + "' ";
623 str += ">";
624 if(this.settings.languages.length) {
625 for(var i = 0; i < this.settings.languages.length; i++) {
626 var attr = [];
627 attr["href"] = "#";
628 attr["style"] = "";
629 attr["class"] = this.settings.languages[i];
630 if(data.data[this.settings.languages[i]] && (typeof data.data[this.settings.languages[i]].attributes).toLowerCase() != "undefined") {
631 for(var j in data.data[this.settings.languages[i]].attributes) {
632 if(j == "style" || j == "class") attr[j] += " " + data.data[this.settings.languages[i]].attributes[j];
633 else attr[j] = data.data[this.settings.languages[i]].attributes[j];
634 }
635 }
636 if(data.data[this.settings.languages[i]] && data.data[this.settings.languages[i]].icon) {
637 var icn = data.data[this.settings.languages[i]].icon.indexOf("/") == -1 ? this.theme + data.data[this.settings.languages[i]].icon : data.data[this.settings.languages[i]].icon;
638 attr["style"] += " ; background-image:url('" + icn + "'); ";
639 }
640 str += "<a";
641 for(var j in attr) str += ' ' + j + '="' + attr[j] + '" ';
642 str += ">" + ( (typeof data.data[this.settings.languages[i]].title).toLowerCase() != "undefined" ? data.data[this.settings.languages[i]].title : data.data[this.settings.languages[i]] ) + "</a>";
643 }
644 }
645 else {
646 var attr = [];
647 attr["href"] = "#";
648 attr["style"] = "";
649 attr["class"] = "";
650 if((typeof data.data.attributes).toLowerCase() != "undefined") {
651 for(var i in data.data.attributes) {
652 if(i == "style" || i == "class") attr[i] += " " + data.data.attributes[i];
653 else attr[i] = data.data.attributes[i];
654 }
655 }
656 if(data.data.icon) {
657 var icn = data.data.icon.indexOf("/") == -1 ? this.theme + data.data.icon : data.data.icon;
658 attr["style"] += " ; background-image:url('" + icn + "');";
659 }
660 str += "<a";
661 for(var i in attr) str += ' ' + i + '="' + attr[i] + '" ';
662 str += ">" + ( (typeof data.data.title).toLowerCase() != "undefined" ? data.data.title : data.data ) + "</a>";
663 }
664 if(data.children && data.children.length) {
665 str += '<ul>';
666 for(var i = 0; i < data.children.length; i++) {
667 str += this.parseJSON(data.children[i]);
668 }
669 str += '</ul>';
670 }
671 str += "</li>";
672 return str;
673 },
674 // getJSON from HTML
675 getJSON : function (nod, outer_attrib, inner_attrib, force) {
676 var _this = this;
677 if(!nod || $(nod).size() == 0) {
678 nod = this.container.children("ul").children("li");
679 }
680 else nod = $(nod);
681
682 if(nod.size() > 1) {
683 var arr = [];
684 nod.each(function () {
685 arr.push(_this.getJSON(this, outer_attrib, inner_attrib));
686 });
687 return arr;
688 }
689
690 if(!outer_attrib) outer_attrib = [ "id", "rel", "class" ];
691 if(!inner_attrib) inner_attrib = [ ];
692 var obj = { attributes : {}, data : false };
693 for(var i in outer_attrib) {
694 obj.attributes[outer_attrib[i]] = nod.attr(outer_attrib[i]);
695 }
696 if(this.settings.languages.length) {
697 obj.data = {};
698 for(var i in this.settings.languages) {
699 var a = nod.children("a." + this.settings.languages[i]);
700 if(force || inner_attrib.length || a.get(0).style.backgroundImage.toString().length) {
701 obj.data[this.settings.languages[i]] = {};
702 obj.data[this.settings.languages[i]].title = a.text();
703 if(a.get(0).style.backgroundImage.length) {
704 obj.data[this.settings.languages[i]].icon = a.get(0).style.backgroundImage.replace("url(","").replace(")","");
705 }
706 if(inner_attrib.length) {
707 obj.data[this.settings.languages[i]].attributes = {};
708 for(var j in inner_attrib) {
709 obj.data[this.settings.languages[i]].attributes[inner_attrib[j]] = a.attr(inner_attrib[j]);
710 }
711 }
712 }
713 else {
714 obj.data[this.settings.languages[i]] = a.text();
715 }
716 }
717 }
718 else {
719 var a = nod.children("a");
720 if(force || inner_attrib.length || a.get(0).style.backgroundImage.toString().length) {
721 obj.data = {};
722 obj.data.title = a.text();
723 if(a.get(0).style.backgroundImage.length) {
724 obj.data.icon = a.get(0).style.backgroundImage.replace("url(","").replace(")","");
725 }
726 if(inner_attrib.length) {
727 obj.data.attributes = {};
728 for(var j in inner_attrib) {
729 obj.data.attributes[inner_attrib[j]] = a.attr(inner_attrib[j]);
730 }
731 }
732 }
733 else {
734 obj.data = a.text();
735 }
736 }
737
738 if(nod.children("ul").size() > 0) {
739 obj.children = [];
740 nod.children("ul").children("li").each(function () {
741 obj.children.push(_this.getJSON(this, outer_attrib, inner_attrib));
742 });
743 }
744 return obj;
745 },
746 focus : function () {
747 if(this.locked) return false;
748 if(tree_component.focused != this.cntr) {
749 tree_component.focused = this.cntr;
750 this.settings.callback.onfocus.call(null, this);
751 }
752 },
753 show_context : function (obj, x, y) {
754 var tmp = this.context.show().offsetParent();
755 if(tmp.is("html")) tmp = $("body");
756 tmp = tmp.offset();
757 this.context.css({ "left" : (x - tmp.left - (this.settings.ui.rtl ? $(this.context).width() : -5 ) ), "top" : (y - tmp.top + ($.browser.opera ? this.container.scrollTop() : 0) + 15) });
758 },
759 hide_context : function () {
760 this.context.hide();
761 },
762 // ALL EVENTS
763 attachEvents : function () {
764 var _this = this;
765
766 this.container
767 .bind("mousedown", function (event) {
768 if(tree_component.drag_drop.isdown) {
769 tree_component.drag_drop.move_type = false;
770 event.preventDefault();
771 event.stopPropagation();
772 event.stopImmediatePropagation();
773 return false;
774 }
775 })
776 .bind("mouseup", function (event) {
777 setTimeout( function() { _this.focus.apply(_this); }, 5);
778 })
779 .bind("click", function (event) {
780 //event.stopPropagation();
781 return true;
782 });
783 $("#" + this.container.attr("id") + " li")
784 .live("click", function(event) { // WHEN CLICK IS ON THE ARROW
785 if(event.target.tagName != "LI") return true;
786 _this.toggle_branch.apply(_this, [event.target]);
787 event.stopPropagation();
788 return false;
789 });
790 $("#" + this.container.attr("id") + " li a")
791 .live("click", function (event) { // WHEN CLICK IS ON THE TEXT OR ICON
792 if(event.which && event.which == 3) return true;
793 if(_this.locked) {
794 event.preventDefault();
795 event.target.blur();
796 return _this.error("LOCKED");
797 }
798 _this.select_branch.apply(_this, [event.target, event.ctrlKey || _this.settings.rules.multiple == "on"]);
799 if(_this.inp) { _this.inp.blur(); }
800 event.preventDefault();
801 event.target.blur();
802 return false;
803 })
804 .live("dblclick", function (event) { // WHEN DOUBLECLICK ON TEXT OR ICON
805 if(_this.locked) {
806 event.preventDefault();
807 event.stopPropagation();
808 event.target.blur();
809 return _this.error("LOCKED");
810 }
811 _this.settings.callback.ondblclk.call(null, _this.get_node(event.target).get(0), _this);
812 event.preventDefault();
813 event.stopPropagation();
814 event.target.blur();
815 })
816 .live("contextmenu", function (event) {
817 if(_this.locked) {
818 event.target.blur();
819 return _this.error("LOCKED");
820 }
821 var val = _this.settings.callback.onrgtclk.call(null, _this.get_node(event.target).get(0), _this, event);
822 if(_this.context) {
823 if(_this.context.append == false) {
824 _this.container.find("ul:eq(0)").append(_this.context);
825 _this.context.append = true;
826 for(var i in _this.settings.ui.context) {
827 if(_this.settings.ui.context[i] == "separator") continue;
828 (function () {
829 var func = _this.settings.ui.context[i].action;
830 _this.context.children("[rel=" + _this.settings.ui.context[i].id +"]")
831 .bind("click", function (event) {
832 if(!$(this).hasClass("disabled")) {
833 func.call(null, _this.selected_arr || _this.selected, _this);
834 _this.hide_context();
835 }
836 event.stopPropagation();
837 event.preventDefault();
838 return false;
839 })
840 .bind("mouseup", function (event) {
841 this.blur();
842 if($(this).hasClass("disabled")) {
843 event.stopPropagation();
844 event.preventDefault();
845 return false;
846 }
847 })
848 .bind("mousedown", function (event) {
849 event.stopPropagation();
850 event.preventDefault();
851 });
852 })();
853 }
854 }
855 var obj = _this.get_node(event.target);
856 if(_this.inp) { _this.inp.blur(); }
857 if(obj) {
858 if(!obj.children("a:eq(0)").hasClass("clicked")) {
859 _this.select_branch.apply(_this, [event.target, event.ctrlKey || _this.settings.rules.multiple == "on"]);
860 event.target.blur();
861 }
862 _this.context.children("a").removeClass("disabled").show();
863 var go = false;
864 for(var i in _this.settings.ui.context) {
865 if(_this.settings.ui.context[i] == "separator") continue;
866 var state = _this.settings.ui.context[i].visible.call(null, _this.selected_arr || _this.selected, _this);
867 if(state === false) _this.context.children("[rel=" + _this.settings.ui.context[i].id +"]").addClass("disabled");
868 if(state === -1) _this.context.children("[rel=" + _this.settings.ui.context[i].id +"]").hide();
869 else go = true;
870 }
871 if(go == true) _this.show_context(obj, event.pageX, event.pageY);
872 event.preventDefault();
873 event.stopPropagation();
874 return false;
875 }
876 }
877 return val;
878 })
879 .live("mouseover", function (event) {
880 if(_this.locked) {
881 event.preventDefault();
882 event.stopPropagation();
883 return _this.error("LOCKED");
884 }
885 if(_this.settings.ui.hover_mode && _this.hovered !== false && event.target.tagName == "A") {
886 _this.hovered.children("a").removeClass("hover");
887 _this.hovered = false;
888 }
889 });
890
891 // ATTACH DRAG & DROP ONLY IF NEEDED
892 if(this.settings.rules.draggable != "none") {
893 $("#" + this.container.attr("id") + " li a")
894 .live("mousedown", function (event) {
895 _this.focus.apply(_this);
896 if(_this.locked) return _this.error("LOCKED");
897 // SELECT LIST ITEM NODE
898 var obj = _this.get_node(event.target);
899 // IF ITEM IS DRAGGABLE
900 if(_this.settings.rules.multiple != false && _this.selected_arr.length > 1 && obj.children("a:eq(0)").hasClass("clicked")) {
901 var counter = 0;
902 for(var i in _this.selected_arr) {
903 if(_this.check("draggable", _this.selected_arr[i])) {
904 _this.selected_arr[i].addClass("dragged");
905 tree_component.drag_drop.origin_tree = _this;
906 counter ++;
907 }
908 }
909 if(counter > 0) {
910 if(_this.check("draggable", obj)) tree_component.drag_drop.drag_node = obj;
911 else tree_component.drag_drop.drag_node = _this.container.find("li.dragged:eq(0)");
912 tree_component.drag_drop.isdown = true;
913 tree_component.drag_drop.drag_help = $(tree_component.drag_drop.drag_node.get(0).cloneNode(true));
914 tree_component.drag_drop.drag_help.attr("id","dragged");
915 tree_component.drag_drop.drag_help.children("a").html("Multiple selection").end().children("ul").remove();
916 }
917 }
918 else {
919 if(_this.check("draggable", obj)) {
920 tree_component.drag_drop.drag_node = obj;
921 tree_component.drag_drop.drag_help = $(obj.get(0).cloneNode(true));
922 tree_component.drag_drop.drag_help.attr("id","dragged");
923 tree_component.drag_drop.isdown = true;
924 tree_component.drag_drop.foreign = false;
925 tree_component.drag_drop.origin_tree = _this;
926 obj.addClass("dragged");
927 }
928 }
929 obj.blur();
930 event.preventDefault();
931 event.stopPropagation();
932 return false;
933 });
934 $(document)
935 .bind("mousedown", tree_component.mousedown)
936 .bind("mouseup", tree_component.mouseup)
937 .bind("mousemove", tree_component.mousemove);
938 }
939 // ENDIF OF DRAG & DROP FUNCTIONS
940 if(_this.context) $(document).bind("mousedown", function() { _this.hide_context(); });
941 },
942 checkMove : function (NODES, REF_NODE, TYPE) {
943 if(this.locked) return this.error("LOCKED");
944 var _this = this;
945
946 // OVER SELF OR CHILDREN
947 if(REF_NODE.parents("li.dragged").size() > 0 || REF_NODE.is(".dragged")) return this.error("MOVE: NODE OVER SELF");
948 // CHECK AGAINST DRAG_RULES
949 if(NODES.size() == 1) {
950 var NODE = NODES.eq(0);
951 if(tree_component.drag_drop.foreign) {
952 if(this.settings.rules.droppable.length == 0) return false;
953 if(!NODE.is("." + this.settings.rules.droppable.join(", ."))) return false;
954 var ok = false;
955 for(var i in this.settings.rules.droppable) {
956 if(NODE.is("." + this.settings.rules.droppable[i])) {
957 if(this.settings.rules.metadata) {
958 $.metadata.setType("attr", this.settings.rules.metadata);
959 NODE.attr(this.settings.rules.metadata, "type: '" + this.settings.rules.droppable[i] + "'");
960 }
961 else {
962 NODE.attr(this.settings.rules.type_attr, this.settings.rules.droppable[i]);
963 }
964 ok = true;
965 break;
966 }
967 }
968 if(!ok) return false;
969 }
970 if(!this.check("dragrules", [NODE, TYPE, REF_NODE.parents("li:eq(0)")])) return this.error("MOVE: AGAINST DRAG RULES");
971 }
972 else {
973 var ok = true;
974 NODES.each(function (i) {
975 if(ok == false) return false;
976 if(i > 0) {
977 var ref = NODES.eq( (i - 1) );
978 var mv = "after";
979 }
980 else {
981 var ref = REF_NODE;
982 var mv = TYPE;
983 }
984 if(!_this.check.apply(_this,["dragrules", [$(this), mv, ref]])) ok = false;
985 });
986 if(ok == false) return this.error("MOVE: AGAINST DRAG RULES");
987 }
988 // CHECK AGAINST METADATA
989 if(this.settings.rules.use_inline && this.settings.rules.metadata) {
990 var nd = false;
991 if(TYPE == "inside") nd = REF_NODE.parents("li:eq(0)");
992 else nd = REF_NODE.parents("li:eq(1)");
993 if(nd.size()) {
994 // VALID CHILDREN CHECK
995 if(typeof nd.metadata()["valid_children"] != "undefined") {
996 var tmp = nd.metadata()["valid_children"];
997 var ok = true;
998 NODES.each(function (i) {
999 if(ok == false) return false;
1000 if($.inArray(_this.get_type(this), tmp) == -1) ok = false;
1001 });
1002 if(ok == false) return this.error("MOVE: NOT A VALID CHILD");
1003 }
1004 // CHECK IF PARENT HAS FREE SLOTS FOR CHILDREN
1005 if(typeof nd.metadata()["max_children"] != "undefined") {
1006 if((nd.children("ul:eq(0)").children("li").not(".dragged").size() + NODES.size()) > nd.metadata().max_children) return this.error("MOVE: MAX CHILDREN REACHED");
1007 }
1008 // CHECK FOR MAXDEPTH UP THE CHAIN
1009 var incr = 0;
1010 NODES.each(function (i) {
1011 var i = 1;
1012 var t = $(this);
1013 while(i < 100) {
1014 t = t.children("ul:eq(0)");
1015 if(t.size() == 0) break;
1016 i ++
1017 }
1018 incr = Math.max(i,incr);
1019 });
1020 var ok = true;
1021 nd.parents("li").each(function(i) {
1022 if(ok == false) return false;
1023 if($(this).metadata().max_depth) {
1024 if( (i + incr) >= $(this).metadata().max_depth) ok = false;
1025 }
1026 });
1027 if(ok == false) return this.error("MOVE: MAX_DEPTH REACHED");
1028 }
1029 }
1030 return true;
1031 },
1032 // USED AFTER REFRESH
1033 reselect : function () {
1034 var _this = this;
1035 // REOPEN BRANCHES
1036 if(this.opened && this.opened.length) {
1037 var opn = false;
1038 for(var j = 0; j < this.opened.length; j++) {
1039 if(this.settings.data.async) {
1040 if(this.get_node(this.opened[j]).size() > 0) {
1041 opn = true;
1042 var tmp = this.opened[j];
1043 delete this.opened[j];
1044 this.open_branch(tmp, true, function () { _this.reselect.apply(_this); } )
1045 }
1046 }
1047 else this.open_branch(this.opened[j], true);
1048 }
1049 if(this.settings.data.async && opn) return;
1050 delete this.opened;
1051 }
1052 // REPOSITION SCROLL
1053 if(this.scrtop) {
1054 this.container.scrollTop(_this.scrtop);
1055 delete this.scrtop;
1056 }
1057 // RESELECT PREVIOUSLY SELECTED
1058 if(this.settings.selected !== false) {
1059 $.each(this.settings.selected, function (i) {
1060 _this.select_branch($(_this.settings.selected[i]), (_this.settings.rules.multiple !== false && i > 0) );
1061 });
1062 this.settings.selected = false;
1063 }
1064 this.settings.callback.onload.call(null, _this);
1065 },
1066 // GET THE EXTENDED LI ELEMENT
1067 get_node : function (obj) {
1068 var obj = $(obj);
1069 return obj.is("li") ? obj : obj.parents("li:eq(0)");
1070 },
1071 // GET THE TYPE OF THE NODE
1072 get_type : function (obj) {
1073 obj = !obj ? this.selected : this.get_node(obj);
1074 if(!obj) return;
1075 if(this.settings.rules.metadata) {
1076 $.metadata.setType("attr", this.settings.rules.metadata);
1077 var tmp = obj.metadata().type;
1078 if(tmp) return tmp;
1079 }
1080 return obj.attr(this.settings.rules.type_attr);
1081 },
1082 // SCROLL CONTAINER WHILE DRAGGING
1083 scrollCheck : function (x,y) {
1084 var _this = this;
1085 var cnt = _this.container;
1086 var off = _this.offset;
1087
1088 var st = cnt.scrollTop();
1089 var sl = cnt.scrollLeft();
1090 // DETECT HORIZONTAL SCROLL
1091 var h_cor = (cnt.get(0).scrollWidth > cnt.width()) ? 40 : 20;
1092
1093 if(y - off.top < 20) cnt.scrollTop(Math.max( (st - _this.settings.ui.scroll_spd) ,0)); // NEAR TOP
1094 if(cnt.height() - (y - off.top) < h_cor) cnt.scrollTop(st + _this.settings.ui.scroll_spd); // NEAR BOTTOM
1095 if(x - off.left < 20) cnt.scrollLeft(Math.max( (sl - _this.settings.ui.scroll_spd),0)); // NEAR LEFT
1096 if(cnt.width() - (x - off.left) < 40) cnt.scrollLeft(sl + _this.settings.ui.scroll_spd); // NEAR RIGHT
1097
1098 if(cnt.scrollLeft() != sl || cnt.scrollTop() != st) {
1099 _this.moveType = false;
1100 _this.moveRef = false;
1101 tree_component.drag_drop.marker.hide();
1102 }
1103 tree_component.drag_drop.scroll_time = setTimeout( function() { _this.scrollCheck(x,y); }, 50);
1104 },
1105 check : function (rule, nodes) {
1106 if(this.locked) return this.error("LOCKED");
1107 // CHECK LOCAL RULES IF METADATA
1108 if(rule != "dragrules" && this.settings.rules.use_inline && this.settings.rules.metadata) {
1109 $.metadata.setType("attr", this.settings.rules.metadata);
1110 if(typeof this.get_node(nodes).metadata()[rule] != "undefined") return this.get_node(nodes).metadata()[rule];
1111 }
1112 if(!this.settings.rules[rule]) return false;
1113 if(this.settings.rules[rule] == "none") return false;
1114 if(this.settings.rules[rule] == "all") return true;
1115 if(rule == "dragrules") {
1116 var nds = new Array();
1117 nds[0] = this.get_type(nodes[0]);
1118 nds[1] = nodes[1];
1119 nds[2] = this.get_type(nodes[2]);
1120 for(var i = 0; i < this.settings.rules.dragrules.length; i++) {
1121 var r = this.settings.rules.dragrules[i];
1122 var n = (r.indexOf("!") === 0) ? false : true;
1123 if(!n) r = r.replace("!","");
1124 var tmp = r.split(" ");
1125 for(var j = 0; j < 3; j++) {
1126 if(tmp[j] == nds[j] || tmp[j] == "*") tmp[j] = true;
1127 }
1128 if(tmp[0] === true && tmp[1] === true && tmp[2] === true) return n;
1129 }
1130 return false;
1131 }
1132 else
1133 return ($.inArray(this.get_type(nodes),this.settings.rules[rule]) != -1) ? true : false;
1134 },
1135 hover_branch : function (obj) {
1136 if(this.locked) return this.error("LOCKED");
1137 if(this.settings.ui.hover_mode == false) return this.select_branch(obj);
1138 var _this = this;
1139 var obj = _this.get_node(obj);
1140 if(!obj.size()) return this.error("HOVER: NOT A VALID NODE");
1141 // CHECK AGAINST RULES FOR SELECTABLE NODES
1142 if(!_this.check("clickable", obj)) return this.error("SELECT: NODE NOT SELECTABLE");
1143 if(this.hovered) this.hovered.children("A").removeClass("hover");
1144
1145 // SAVE NEWLY SELECTED
1146 this.hovered = obj;
1147
1148 // FOCUS NEW NODE AND OPEN ALL PARENT NODES IF CLOSED
1149 this.hovered.children("a").removeClass("hover").addClass("hover");
1150
1151 // SCROLL SELECTED NODE INTO VIEW
1152 var off_t = this.hovered.offset().top;
1153 var beg_t = this.container.offset().top;
1154 var end_t = beg_t + this.container.height();
1155 var h_cor = (this.container.get(0).scrollWidth > this.container.width()) ? 40 : 20;
1156 if(off_t + 5 < beg_t) this.container.scrollTop(this.container.scrollTop() - (beg_t - off_t + 5) );
1157 if(off_t + h_cor > end_t) this.container.scrollTop(this.container.scrollTop() + (off_t + h_cor - end_t) );
1158 },
1159 select_branch : function (obj, multiple) {
1160 if(this.locked) return this.error("LOCKED");
1161 if(!obj && this.hovered !== false) obj = this.hovered;
1162 var _this = this;
1163 obj = _this.get_node(obj);
1164 if(!obj.size()) return this.error("SELECT: NOT A VALID NODE");
1165 obj.children("a").removeClass("hover");
1166 // CHECK AGAINST RULES FOR SELECTABLE NODES
1167 if(!_this.check("clickable", obj)) return this.error("SELECT: NODE NOT SELECTABLE");
1168 if(_this.settings.callback.beforechange.call(null,obj.get(0),_this) === false) return this.error("SELECT: STOPPED BY USER");
1169 // IF multiple AND obj IS ALREADY SELECTED - DESELECT IT
1170 if(this.settings.rules.multiple != false && multiple && obj.children("a.clicked").size() > 0) {
1171 return this.deselect_branch(obj);
1172 }
1173 if(this.settings.rules.multiple != false && multiple) {
1174 this.selected_arr.push(obj);
1175 }
1176 if(this.settings.rules.multiple != false && !multiple) {
1177 for(var i in this.selected_arr) {
1178 this.selected_arr[i].children("A").removeClass("clicked");
1179 this.settings.callback.ondeselect.call(null, this.selected_arr[i].get(0), _this);
1180 }
1181 this.selected_arr = [];
1182 this.selected_arr.push(obj);
1183 if(this.selected && this.selected.children("A").hasClass("clicked")) {
1184 this.selected.children("A").removeClass("clicked");
1185 this.settings.callback.ondeselect.call(null, this.selected.get(0), _this);
1186 }
1187 }
1188 if(!this.settings.rules.multiple) {
1189 if(this.selected) {
1190 this.selected.children("A").removeClass("clicked");
1191 this.settings.callback.ondeselect.call(null, this.selected.get(0), _this);
1192 }
1193 }
1194 // SAVE NEWLY SELECTED
1195 this.selected = obj;
1196 if(this.settings.ui.hover_mode && this.hovered !== false) {
1197 this.hovered.children("A").removeClass("hover");
1198 this.hovered = obj;
1199 }
1200
1201 // FOCUS NEW NODE AND OPEN ALL PARENT NODES IF CLOSED
1202 this.selected.children("a").removeClass("clicked").addClass("clicked").end().parents("li.closed").each( function () { _this.open_branch(this, true); });
1203
1204 // SCROLL SELECTED NODE INTO VIEW
1205 var off_t = this.selected.offset().top;
1206 var beg_t = this.container.offset().top;
1207 var end_t = beg_t + this.container.height();
1208 var h_cor = (this.container.get(0).scrollWidth > this.container.width()) ? 40 : 20;
1209 if(off_t + 5 < beg_t) this.container.scrollTop(this.container.scrollTop() - (beg_t - off_t + 5) );
1210 if(off_t + h_cor > end_t) this.container.scrollTop(this.container.scrollTop() + (off_t + h_cor - end_t) );
1211
1212 this.set_cookie("selected");
1213 this.settings.callback.onselect.call(null, this.selected.get(0), _this);
1214 this.settings.callback.onchange.call(null, this.selected.get(0), _this);
1215 },
1216 deselect_branch : function (obj) {
1217 if(this.locked) return this.error("LOCKED");
1218 var _this = this;
1219 var obj = this.get_node(obj);
1220 obj.children("a").removeClass("clicked");
1221 this.settings.callback.ondeselect.call(null, obj.get(0), _this);
1222 if(this.settings.rules.multiple != false && this.selected_arr.length > 1) {
1223 this.selected_arr = [];
1224 this.container.find("a.clicked").filter(":first-child").parent().each(function () {
1225 _this.selected_arr.push($(this));
1226 });
1227 if(obj.get(0) == this.selected.get(0)) {
1228 this.selected = this.selected_arr[0];
1229 this.set_cookie("selected");
1230 }
1231 }
1232 else {
1233 if(this.settings.rules.multiple != false) this.selected_arr = [];
1234 this.selected = false;
1235 this.set_cookie("selected");
1236 }
1237 if(this.selected) this.settings.callback.onchange.call(null, this.selected.get(0), _this);
1238 else this.settings.callback.onchange.call(null, false, _this);
1239 },
1240 toggle_branch : function (obj) {
1241 if(this.locked) return this.error("LOCKED");
1242 var obj = this.get_node(obj);
1243 if(obj.hasClass("closed")) return this.open_branch(obj);
1244 if(obj.hasClass("open")) return this.close_branch(obj);
1245 },
1246 open_branch : function (obj, disable_animation, callback) {
1247 if(this.locked) return this.error("LOCKED");
1248 var obj = this.get_node(obj);
1249 if(!obj.size()) return this.error("OPEN: NO SUCH NODE");
1250 if(obj.hasClass("leaf")) return this.error("OPEN: OPENING LEAF NODE");
1251
1252 if(this.settings.data.async && obj.find("li").size() == 0) {
1253 if(this.settings.callback.beforeopen.call(null,obj.get(0),this) === false) return this.error("OPEN: STOPPED BY USER");
1254 var _this = this;
1255 obj.children("ul:eq(0)").remove().end().append("<ul><li class='last'><a class='loading' href='#'>" + (_this.settings.lang.loading || "Loading ...") + "</a></li></ul>");
1256 obj.removeClass("closed").addClass("open");
1257 if(this.settings.data.type == "xml_flat" || this.settings.data.type == "xml_nested") {
1258 var xsl = (this.settings.data.type == "xml_flat") ? "flat.xsl" : "nested.xsl";
1259 obj.children("ul:eq(0)").getTransform(this.path + xsl, this.settings.data.url, { params : { theme_path : _this.theme }, meth : this.settings.data.method, dat : this.settings.data.async_data(obj), repl : true, callback: function (str, json) {
1260 if(str.length < 15) {
1261 obj.removeClass("closed").removeClass("open").addClass("leaf").children("ul").remove();
1262 if(callback) callback.call();
1263 return;
1264 }
1265 _this.open_branch.apply(_this, [obj]);
1266 if(callback) callback.call();
1267 }
1268 });
1269 }
1270 else {
1271 $.ajax({
1272 type : this.settings.data.method,
1273 url : this.settings.data.url,
1274 data : this.settings.data.async_data(obj),
1275 dataType : "json",
1276 success : function (data, textStatus) {
1277 if(!data || data.length == 0) {
1278 obj.removeClass("closed").removeClass("open").addClass("leaf").children("ul").remove();
1279 if(callback) callback.call();
1280 return;
1281 }
1282 var str = "";
1283 if(data.length) {
1284 for(var i = 0; i < data.length; i++) {
1285 str += _this.parseJSON(data[i]);
1286 }
1287 }
1288 else str = _this.parseJSON(data);
1289 if(str.length > 0) {
1290 obj.children("ul:eq(0)").replaceWith("<ul>" + str + "</ul>");
1291 obj.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed");
1292 obj.find("li").not(".open").not(".closed").addClass("leaf");
1293 _this.open_branch.apply(_this, [obj]);
1294 }
1295 else obj.removeClass("closed").removeClass("open").addClass("leaf").children("ul").remove();
1296 if(callback) callback.call();
1297 }
1298 });
1299 }
1300 return true;
1301 }
1302 else {
1303 if(!this.settings.data.async) {
1304 if(this.settings.callback.beforeopen.call(null,obj.get(0),this) === false) return this.error("OPEN: STOPPED BY USER");
1305 }
1306 if(parseInt(this.settings.ui.animation) > 0 && !disable_animation ) {
1307 obj.children("ul:eq(0)").css("display","none");
1308 obj.removeClass("closed").addClass("open");
1309 obj.children("ul:eq(0)").slideDown(parseInt(this.settings.ui.animation), function() {
1310 $(this).css("display","");
1311 if(callback) callback.call();
1312 });
1313 } else {
1314 obj.removeClass("closed").addClass("open");
1315 if(callback) callback.call();
1316 }
1317 this.set_cookie("open");
1318 this.settings.callback.onopen.call(null, obj.get(0), this);
1319 return true;
1320 }
1321 },
1322 close_branch : function (obj, disable_animation) {
1323 if(this.locked) return this.error("LOCKED");
1324 var _this = this;
1325 var obj = this.get_node(obj);
1326 if(!obj.size()) return this.error("CLOSE: NO SUCH NODE");
1327 if(_this.settings.callback.beforeclose.call(null,obj.get(0),_this) === false) return this.error("CLOSE: STOPPED BY USER");
1328 if(parseInt(this.settings.ui.animation) > 0 && !disable_animation && obj.children("ul:eq(0)").size() == 1) {
1329 obj.children("ul:eq(0)").slideUp(parseInt(this.settings.ui.animation), function() {
1330 obj.removeClass("open").addClass("closed");
1331 _this.set_cookie("open");
1332 $(this).css("display","");
1333 });
1334 }
1335 else {
1336 obj.removeClass("open").addClass("closed");
1337 this.set_cookie("open");
1338 }
1339 if(this.selected && obj.children("ul:eq(0)").find("a.clicked").size() > 0) {
1340 obj.find("li:has(a.clicked)").each(function() {
1341 _this.deselect_branch(this);
1342 });
1343 if(obj.children("a.clicked").size() == 0) this.select_branch(obj, (this.settings.rules.multiple != false && this.selected_arr.length > 0) );
1344 }
1345 this.settings.callback.onclose.call(null, obj.get(0), this);
1346 },
1347 open_all : function (obj, callback) {
1348 if(this.locked) return this.error("LOCKED");
1349 var _this = this;
1350 obj = obj ? $(obj) : this.container;
1351
1352 var s = obj.find("li.closed").size();
1353 if(!callback) this.cl_count = 0;
1354 else this.cl_count --;
1355 if(s > 0) {
1356 this.cl_count += s;
1357 obj.find("li.closed").each( function () { var __this = this; _this.open_branch.apply(_this, [this, true, function() { _this.open_all.apply(_this, [__this, true]); } ]); });
1358 }
1359 else if(this.cl_count == 0) this.settings.callback.onopen_all.call(null,this);
1360 },
1361 close_all : function () {
1362 if(this.locked) return this.error("LOCKED");
1363 var _this = this;
1364 this.container.find("li.open").each( function () { _this.close_branch(this, true); });
1365 },
1366 show_lang : function (i) {
1367 if(this.locked) return this.error("LOCKED");
1368 if(this.settings.languages[i] == this.current_lang) return true;
1369 var st = false;
1370 var id = this.container.attr("id") ? "#" + this.container.attr("id") : ".tree";
1371 st = get_css(id + " ." + this.current_lang, this.sn);
1372 if(st !== false) st.style.display = "none";
1373 st = get_css(id + " ." + this.settings.languages[i], this.sn);
1374 if(st !== false) st.style.display = "block";
1375 this.current_lang = this.settings.languages[i];
1376 return true;
1377 },
1378 cycle_lang : function() {
1379 if(this.locked) return this.error("LOCKED");
1380 var i = $.inArray(this.current_lang, this.settings.languages);
1381 i ++;
1382 if(i > this.settings.languages.length - 1) i = 0;
1383 this.show_lang(i);
1384 },
1385 create : function (type, obj, data, icon, id, position) {
1386 if(this.locked) return this.error("LOCKED");
1387 // NOTHING SELECTED
1388 obj = obj ? this.get_node(obj) : this.selected;
1389 if(!obj || !obj.size()) return this.error("CREATE: NO NODE SELECTED");
1390 if(!this.check("creatable", obj)) return this.error("CREATE: CANNOT CREATE IN NODE");
1391
1392 var t = type || this.get_type(obj) || "";
1393 if(this.settings.rules.use_inline && this.settings.rules.metadata) {
1394 $.metadata.setType("attr", this.settings.rules.metadata);
1395 if(typeof obj.metadata()["valid_children"] != "undefined") {
1396 if($.inArray(t, obj.metadata()["valid_children"]) == -1) return this.error("CREATE: NODE NOT A VALID CHILD");
1397 }
1398 if(typeof obj.metadata()["max_children"] != "undefined") {
1399 if( (obj.children("ul:eq(0)").children("li").size() + 1) > obj.metadata().max_children) return this.error("CREATE: MAX_CHILDREN REACHED");
1400 }
1401 var ok = true;
1402 obj.parents("li").each(function(i) {
1403 if($(this).metadata().max_depth) {
1404 if( (i + 1) >= $(this).metadata().max_depth) {
1405 ok = false;
1406 }
1407 }
1408 });
1409 if(!ok) return this.error("CREATE: MAX_DEPTH REACHED");
1410 }
1411 if(obj.hasClass("closed")) {
1412 var _this = this;
1413 return this.open_branch(obj, true, function () { _this.create.apply(_this, [type, obj, data, icon, id]); } );
1414 }
1415
1416 if(id) $li = $("<li id='" + id + "' />");
1417 else $li = $("<li />");
1418 // NEW NODE IS OF PASSED TYPE OR PARENT'S TYPE
1419 if(this.settings.rules.metadata) {
1420 $.metadata.setType("attr", this.settings.rules.metadata);
1421 $li.attr(this.settings.rules.metadata, "type: '" + t + "'");
1422 }
1423 else {
1424 $li.attr(this.settings.rules.type_attr, t)
1425 }
1426
1427 var icn = "";
1428 if((typeof icon).toLowerCase() == "string") {
1429 icn = icon;
1430 icn = icn.indexOf("/") == -1 ? this.theme + icn : icn;
1431 }
1432 if(this.settings.languages.length) {
1433 for(var i = 0; i < this.settings.languages.length; i++) {
1434 if((typeof data).toLowerCase() == "string") val = data;
1435 else if(data && data[i]) {
1436 val = data[i];
1437 }
1438 else if(this.settings.lang.new_node) {
1439 if((typeof this.settings.lang.new_node).toLowerCase() != "string" && this.settings.lang.new_node[i])
1440 val = this.settings.lang.new_node[i];
1441 else
1442 val = this.settings.lang.new_node;
1443 }
1444 else {
1445 val = "New folder";
1446 }
1447 if((typeof icon).toLowerCase() != "string" && icon && icon[i]) {
1448 icn = icon[i];
1449 icn = icn.indexOf("/") == -1 ? this.theme + icn : icn;
1450 }
1451 $li.append("<a href='#'" + ( icn.length ? " style='background-image:url(\"" + icn + "\");' " : " ") + "class='" + this.settings.languages[i] + "'>" + val + "</a>");
1452 }
1453 }
1454 else { $li.append("<a href='#'" + ( icn.length ? " style='background-image:url(\"" + icn + "\");' " : " ") + ">" + (data || this.settings.lang.new_node || "New folder") + "</a>"); }
1455 $li.addClass("leaf");
1456 if(this.settings.rules.createat == "top" || obj.children("ul").size() == 0) {
1457 this.moved($li,obj.children("a:eq(0)"),"inside", true);
1458 }
1459 else {
1460 this.moved($li,obj.children("ul:eq(0)").children("li:last").children("a:eq(0)"),"after",true);
1461 }
1462 this.select_branch($li.children("a:eq(0)"));
1463 if(!data) this.rename();
1464 return $li;
1465 },
1466 rename : function () {
1467 if(this.locked) return this.error("LOCKED");
1468 if(this.selected) {
1469 var _this = this;
1470 if(!this.check("renameable", this.selected)) return this.error("RENAME: NODE NOT RENAMABLE");
1471 if(!this.settings.callback.beforerename.call(null,this.selected.get(0), _this.current_lang, _this)) return this.error("RENAME: STOPPED BY USER");
1472 var obj = this.selected;
1473 if(this.current_lang) obj = obj.find("a." + this.current_lang).get(0);
1474 else obj = obj.find("a:first").get(0);
1475 last_value = obj.innerHTML;
1476 _this.inp = $("<input type='text' />");
1477 _this.inp
1478 .val(last_value)
1479 .bind("mousedown", function (event) { event.stopPropagation(); })
1480 .bind("mouseup", function (event) { event.stopPropagation(); })
1481 .bind("click", function (event) { event.stopPropagation(); })
1482 .bind("keyup", function (event) {
1483 var key = event.keyCode || event.which;
1484 if(key == 27) { this.value = last_value; this.blur(); return }
1485 if(key == 13) { this.blur(); return }
1486 });
1487 _this.inp.blur(function(event) {
1488 if(this.value == "") this.value == last_value;
1489 $(obj).html( $(obj).parent().find("input").eq(0).attr("value") ).get(0).style.display = "";
1490 $(obj).prevAll("span").remove();
1491 if(this.value != last_value) _this.settings.callback.onrename.call(null, _this.get_node(obj).get(0), _this.current_lang, _this);
1492 _this.inp = false;
1493 });
1494 var spn = $("<span />").addClass(obj.className).append(_this.inp);
1495 spn.attr("style", $(obj).attr("style"));
1496 obj.style.display = "none";
1497 $(obj).parent().prepend(spn);
1498 _this.inp.get(0).focus();
1499 _this.inp.get(0).select();
1500 }
1501 else return this.error("RENAME: NO NODE SELECTED");
1502 },
1503 // REMOVE NODES
1504 remove : function(obj) {
1505 if(this.locked) return this.error("LOCKED");
1506 if(obj) {
1507 obj = this.get_node(obj);
1508 if(obj.size()) {
1509 if(!this.check("deletable", obj)) return this.error("DELETE: NODE NOT DELETABLE");
1510 if(!this.settings.callback.beforedelete.call(null,obj.get(0), _this)) return this.error("DELETE: STOPPED BY USER");
1511 $parent = obj.parent();
1512 obj = obj.remove();
1513 $parent.children("li:last").addClass("last");
1514 if($parent.children("li").size() == 0) {
1515 $li = $parent.parents("li:eq(0)");
1516 $li.removeClass("open").removeClass("closed").addClass("leaf").children("ul").remove();
1517 this.set_cookie("open");
1518 }
1519 this.settings.callback.ondelete.call(null, obj, this);
1520 }
1521 }
1522 else if(this.selected) {
1523 if(!this.check("deletable", this.selected)) return this.error("DELETE: NODE NOT DELETABLE");
1524 if(!this.settings.callback.beforedelete.call(null,this.selected.get(0), _this)) return this.error("DELETE: STOPPED BY USER");
1525 $parent = this.selected.parent();
1526 var obj = this.selected;
1527 if(this.settings.rules.multiple == false || this.selected_arr.length == 1) {
1528 var stop = true;
1529 var tmp = (this.selected.prev("li:eq(0)").size()) ? this.selected.prev("li:eq(0)") : this.selected.parents("li:eq(0)");
1530 // this.get_prev(true);
1531 }
1532 obj = obj.remove();
1533 $parent.children("li:last").addClass("last");
1534 if($parent.children("li").size() == 0) {
1535 $li = $parent.parents("li:eq(0)");
1536 $li.removeClass("open").removeClass("closed").addClass("leaf").children("ul").remove();
1537 this.set_cookie("open");
1538 }
1539 //this.selected = false;
1540 this.settings.callback.ondelete.call(null, obj, this);
1541 if(stop && tmp) this.select_branch(tmp);
1542 if(this.settings.rules.multiple != false && !stop) {
1543 var _this = this;
1544 this.selected_arr = [];
1545 this.container.find("a.clicked").filter(":first-child").parent().each(function () {
1546 _this.selected_arr.push($(this));
1547 });
1548 if(this.selected_arr.length > 0) {
1549 this.selected = this.selected_arr[0];
1550 this.remove();
1551 }
1552 }
1553 }
1554 else return this.error("DELETE: NO NODE SELECTED");
1555 },
1556 // FOR EXPLORER-LIKE KEYBOARD SHORTCUTS
1557 get_next : function(force) {
1558 var obj = this.hovered || this.selected;
1559 if(obj) {
1560 if(obj.hasClass("open")) return force ? this.select_branch(obj.find("li:eq(0)")) : this.hover_branch(obj.find("li:eq(0)"));
1561 else if($(obj).nextAll("li").size() > 0) return force ? this.select_branch(obj.nextAll("li:eq(0)")) : this.hover_branch(obj.nextAll("li:eq(0)"));
1562 else return force ? this.select_branch(obj.parents("li").next("li").eq(0)) : this.hover_branch(obj.parents("li").next("li").eq(0));
1563 }
1564 },
1565 get_prev : function(force) {
1566 var obj = this.hovered || this.selected;
1567 if(obj) {
1568 if(obj.prev("li").size()) {
1569 var obj = obj.prev("li").eq(0);
1570 while(obj.hasClass("open")) obj = obj.children("ul:eq(0)").children("li:last");
1571 return force ? this.select_branch(obj) : this.hover_branch(obj);
1572 }
1573 else { return force ? this.select_branch(obj.parents("li:eq(0)")) : this.hover_branch(obj.parents("li:eq(0)")); }
1574 }
1575 },
1576 get_left : function(force, rtl) {
1577 if(this.settings.ui.rtl && !rtl) return this.get_right(force, true);
1578 var obj = this.hovered || this.selected;
1579 if(obj) {
1580 if(obj.hasClass("open")) this.close_branch(obj);
1581 else {
1582 return force ? this.select_branch(obj.parents("li:eq(0)")) : this.hover_branch(obj.parents("li:eq(0)"));
1583 }
1584 }
1585 },
1586 get_right : function(force, rtl) {
1587 if(this.settings.ui.rtl && !rtl) return this.get_left(force, true);
1588 var obj = this.hovered || this.selected;
1589 if(obj) {
1590 if(obj.hasClass("closed")) this.open_branch(obj);
1591 else {
1592 return force ? this.select_branch(obj.find("li:eq(0)")) : this.hover_branch(obj.find("li:eq(0)"));
1593 }
1594 }
1595 },
1596 toggleDots : function () {
1597 this.container.toggleClass("no_dots");
1598 },
1599 set_cookie : function (type) {
1600 if(this.settings.cookies === false) return false;
1601 if(this.settings.cookies[type] === false) return false;
1602 switch(type) {
1603 case "selected":
1604 if(this.settings.rules.multiple != false && this.selected_arr.length > 1) {
1605 var val = Array();
1606 $.each(this.selected_arr, function () {
1607 val.push(this.attr("id"));
1608 });
1609 val = val.join(",");
1610 }
1611 else var val = this.selected ? this.selected.attr("id") : false;
1612 $.cookie(this.settings.cookies.prefix + '_selected',val,this.settings.cookies.opts);
1613 break;
1614 case "open":
1615 var str = "";
1616 this.container.find("li.open").each(function (i) { str += this.id + ","; });
1617 $.cookie(this.settings.cookies.prefix + '_open',str.replace(/,$/ig,""),this.settings.cookies.opts);
1618 break;
1619 }
1620 },
1621 moved : function (what, where, how, is_new, is_copy) {
1622 var what = $(what);
1623 var $parent = $(what).parents("ul:eq(0)");
1624 var $where = $(where);
1625 // IF MULTIPLE
1626 if(what.size() > 1) {
1627 var _this = this;
1628 var tmp = this.moved(what.eq(0),where,how, false, is_copy);
1629 what.each(function (i) {
1630 if(i == 0) return;
1631 tmp = _this.moved(this, tmp.children("a:eq(0)"), "after", false, is_copy);
1632 });
1633 return;
1634 }
1635 if(is_copy) {
1636 _what = what.clone();
1637 _what.each(function (i) {
1638 this.id = this.id + "_copy";
1639 $(this).find("li").each(function () {
1640 this.id = this.id + "_copy";
1641 });
1642 $(this).removeClass("dragged").find("a.clicked").removeClass("clicked").end().find("li.dragged").removeClass("dragged");
1643 });
1644 }
1645 else _what = what;
1646 if(is_new) {
1647 if(!this.settings.callback.beforecreate.call(null,this.get_node(what).get(0), this.get_node(where).get(0),how,this)) return;
1648 }
1649 else {
1650 if(!this.settings.callback.beforemove.call(null,this.get_node(what).get(0), this.get_node(where).get(0),how,this)) return;
1651 }
1652
1653 if(!is_new) {
1654 var tmp = what.parents(".tree:eq(0)");
1655 // if different trees
1656 if(tmp.get(0) != this.container.get(0)) {
1657 tmp = tree_component.inst[tmp.attr("id")];
1658 // if there are languages - otherwise - no cleanup needed
1659 if(tmp.settings.languages.length) {
1660 var res = [];
1661 // if new tree has no languages - use current visible
1662 if(this.settings.languages.length == 0) res.push("." + tmp.current_lang);
1663 else {
1664 for(var i in this.settings.languages) {
1665 for(var j in tmp.settings.languages) {
1666 if(this.settings.languages[i] == tmp.settings.languages[j]) res.push("." + this.settings.languages[i]);
1667 }
1668 }
1669 }
1670 if(res.length == 0) return this.error("MOVE: NO COMMON LANGUAGES");
1671 what.find("a").not(res.join(",")).remove();
1672 }
1673 what.find("a.clicked").removeClass("clicked");
1674 }
1675 }
1676 what = _what;
1677
1678 // ADD NODE TO NEW PLACE
1679 switch(how) {
1680 case "before":
1681 $where.parents("ul:eq(0)").children("li.last").removeClass("last");
1682 $where.parent().before(what.removeClass("last"));
1683 $where.parents("ul:eq(0)").children("li:last").addClass("last");
1684 break;
1685 case "after":
1686 $where.parents("ul:eq(0)").children("li.last").removeClass("last");
1687 $where.parent().after(what.removeClass("last"));
1688 $where.parents("ul:eq(0)").children("li:last").addClass("last");
1689 break;
1690 case "inside":
1691 if(this.settings.data.async) {
1692 var obj = this.get_node($where);
1693 if(obj.hasClass("closed")) {
1694 var _this = this;
1695 return this.open_branch(obj, true, function () { _this.moved.apply(_this, [what, where, how, is_new, is_copy]); })
1696 }
1697 }
1698 if($where.parent().children("ul:first").size()) {
1699 if(this.settings.rules.createat == "top") $where.parent().children("ul:first").prepend(what.removeClass("last")).children("li:last").addClass("last");
1700 else $where.parent().children("ul:first").children(".last").removeClass("last").end().append(what.removeClass("last")).children("li:last").addClass("last");
1701 }
1702 else {
1703 what.addClass("last");
1704 $where.parent().append("<ul/>").removeClass("leaf").addClass("closed");
1705 $where.parent().children("ul:first").prepend(what);
1706 }
1707 if(!this.settings.data.async) {
1708 this.open_branch($where);
1709 }
1710 break;
1711 default:
1712 break;
1713 }
1714 // CLEANUP OLD PARENT
1715 if($parent.find("li").size() == 0) {
1716 var $li = $parent.parent();
1717 $li.removeClass("open").removeClass("closed").addClass("leaf").children("ul").remove();
1718 $li.parents("ul:eq(0)").children("li.last").removeClass("last").end().children("li:last").addClass("last");
1719 this.set_cookie("open");
1720 }
1721 else {
1722 $parent.children("li.last").removeClass("last");
1723 $parent.children("li:last").addClass("last");
1724 }
1725 if(is_new && how != "inside") where = this.get_node(where).parents("li:eq(0)");
1726 if(is_copy) this.settings.callback.oncopy.call(null, this.get_node(what).get(0), this.get_node(where).get(0), how, this);
1727 else if(is_new) this.settings.callback.oncreate.call(null, this.get_node(what).get(0), this.get_node(where).get(0), this.settings.rules.createat, this);
1728 else this.settings.callback.onmove.call(null, this.get_node(what).get(0), this.get_node(where).get(0), how, this);
1729 return what;
1730 },
1731 error : function (code) {
1732 this.settings.callback.error.call(null,code,this);
1733 return false;
1734 },
1735 lock : function (state) {
1736 this.locked = state;
1737 if(this.locked) this.container.addClass("locked");
1738 else this.container.removeClass("locked");
1739 },
1740 cut : function () {
1741 if(this.locked) return this.error("LOCKED");
1742 if(!this.selected) return this.error("CUT: NO NODE SELECTED");
1743 this.copy_nodes = false;
1744 this.cut_nodes = this.container.find("a.clicked").filter(":first-child").parent();
1745 },
1746 copy : function () {
1747 if(this.locked) return this.error("LOCKED");
1748 if(!this.selected) return this.error("COPY: NO NODE SELECTED");
1749 this.copy_nodes = this.container.find("a.clicked").filter(":first-child").parent();
1750 this.cut_nodes = false;
1751 },
1752 paste : function () {
1753 if(this.locked) return this.error("LOCKED");
1754 if(!this.selected) return this.error("PASTE: NO NODE SELECTED");
1755 if(!this.copy_nodes && !this.cut_nodes) return this.error("PASTE: NOTHING TO DO");
1756 if(this.copy_nodes && this.copy_nodes.size()) {
1757 if(!this.checkMove(this.copy_nodes, this.selected.children("a:eq(0)"), "inside")) return false;
1758 this.moved(this.copy_nodes, this.selected.children("a:eq(0)"), "inside", false, true);
1759 this.copy_nodes = false;
1760 }
1761 if(this.cut_nodes && this.cut_nodes.size()) {
1762 if(!this.checkMove(this.cut_nodes, this.selected.children("a:eq(0)"), "inside")) return false;
1763 this.moved(this.cut_nodes, this.selected.children("a:eq(0)"), "inside");
1764 this.cut_nodes = false;
1765 }
1766 },
1767 search : function(str) {
1768 var _this = this;
1769 if(!str || (this.srch && str != this.srch) ) {
1770 this.srch = "";
1771 this.srch_opn = false;
1772 this.container.find("a.search").removeClass("search");
1773 }
1774 this.srch = str;
1775 if(!str) return;
1776 if(this.settings.data.async) {
1777 if(!this.srch_opn) {
1778 var dd = $.extend( { "search" : str } , this.settings.data.async_data(false) );
1779 $.ajax({
1780 type : this.settings.data.method,
1781 url : this.settings.data.url,
1782 data : dd,
1783 dataType : "text",
1784 success : function (data) {
1785 _this.srch_opn = $.unique(data.split(","));
1786 _this.search.apply(_this,[str]);
1787 }
1788 });
1789 }
1790 else if(this.srch_opn.length) {
1791 if(this.srch_opn && this.srch_opn.length) {
1792 var opn = false;
1793 for(var j = 0; j < this.srch_opn.length; j++) {
1794 if(this.get_node("#" + this.srch_opn[j]).size() > 0) {
1795 opn = true;
1796 var tmp = "#" + this.srch_opn[j];
1797 delete this.srch_opn[j];
1798 this.open_branch(tmp, true, function () { _this.search.apply(_this,[str]); } );
1799 }
1800 }
1801 if(!opn) {
1802 this.srch_opn = [];
1803 _this.search.apply(_this,[str]);
1804 }
1805 }
1806 }
1807 else {
1808 var selector = "a";
1809 // IF LANGUAGE VERSIONS
1810 if(this.settings.languages.length) selector += "." + this.current_lang;
1811 this.container.find(selector + ":contains('" + str + "')").addClass("search");
1812 this.srch_opn = false;
1813 }
1814 }
1815 else {
1816 var selector = "a";
1817 // IF LANGUAGE VERSIONS
1818 if(this.settings.languages.length) selector += "." + this.current_lang;
1819 this.container.find(selector + ":contains('" + str + "')").addClass("search").parents("li.closed").each( function () { _this.open_branch(this, true); });
1820 }
1821 },
1822
1823 destroy : function() {
1824 this.container.unbind().find("li").die().find("a").die();
1825 this.container.removeClass("tree").children("ul").removeClass("tree-" + this.settings.ui.theme_name).find("li").removeClass("leaf").removeClass("open").removeClass("closed").removeClass("last").children("a").removeClass("clicked");
1826
1827 if(this.cntr == tree_component.focused) {
1828 for(var i in tree_component.inst) {
1829 if(i != this.cntr && i != this.container.attr("id")) {
1830 tree_component.inst[i].focus();
1831 break;
1832 }
1833 }
1834 }
1835 delete tree_component.inst[this.cntr];
1836 delete tree_component.inst[this.container.attr("id")];
1837 tree_component.cntr --;
1838 }
1839 }
1840 };
1841 })(jQuery);