jquery.ui-all-1.5b3.js
上传用户:stephen_wu
上传日期:2008-07-05
资源大小:1757k
文件大小:262k
源码类别:

网络

开发平台:

Unix_Linux

  1. stop: this.stop,
  2. drag: this.drag,
  3. condition: function(e) {
  4. if(this.options.disabled || this.options.type == 'static') return false;
  5. //Find out if the clicked node (or one of its parents) is a actual item in this.items
  6. var currentItem = null, nodes = $(e.target).parents().each(function() {
  7. if($.data(this, 'sortable-item')) {
  8. currentItem = $(this);
  9. return false;
  10. }
  11. });
  12. if($.data(e.target, 'sortable-item')) currentItem = $(e.target);
  13. if(!currentItem) return false;
  14. if(this.options.handle) {
  15. var validHandle = false;
  16. $(this.options.handle, currentItem).each(function() { if(this == e.target) validHandle = true; });
  17. if(!validHandle) return false;
  18. }
  19. this.currentItem = currentItem;
  20. return true;
  21. }
  22. });
  23. },
  24. plugins: {},
  25. ui: function(inst) {
  26. return {
  27. helper: (inst || this)["helper"],
  28. placeholder: (inst || this)["placeholder"] || $([]),
  29. position: (inst || this)["position"].current,
  30. absolutePosition: (inst || this)["position"].absolute,
  31. instance: this,
  32. options: this.options,
  33. element: this.element,
  34. item: (inst || this)["currentItem"],
  35. sender: inst ? inst.element : null
  36. };
  37. },
  38. propagate: function(n,e,inst) {
  39. $.ui.plugin.call(this, n, [e, this.ui(inst)]);
  40. this.element.triggerHandler(n == "sort" ? n : "sort"+n, [e, this.ui(inst)], this.options[n]);
  41. },
  42. serialize: function(o) {
  43. var items = $(this.options.items, this.element).not('.ui-sortable-helper'); //Only the items of the sortable itself
  44. var str = []; o = o || {};
  45. items.each(function() {
  46. var res = ($(this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
  47. if(res) str.push((o.key || res[1])+'[]='+(o.key ? res[1] : res[2]));
  48. });
  49. return str.join('&');
  50. },
  51. toArray: function(attr) {
  52. var items = $(this.options.items, this.element).not('.ui-sortable-helper'); //Only the items of the sortable itself
  53. var ret = [];
  54. items.each(function() { ret.push($(this).attr(attr || 'id')); });
  55. return ret;
  56. },
  57. enable: function() {
  58. this.element.removeClass("ui-sortable-disabled");
  59. this.options.disabled = false;
  60. },
  61. disable: function() {
  62. this.element.addClass("ui-sortable-disabled");
  63. this.options.disabled = true;
  64. },
  65. /* Be careful with the following core functions */
  66. intersectsWith: function(item) {
  67. var x1 = this.position.absolute.left, x2 = x1 + this.helperProportions.width,
  68. y1 = this.position.absolute.top, y2 = y1 + this.helperProportions.height;
  69. var l = item.left, r = l + item.width, 
  70. t = item.top, b = t + item.height;
  71. if(this.options.tolerance == "pointer") {
  72. return (y1 + this.clickOffset.top > t && y1 + this.clickOffset.top < b && x1 + this.clickOffset.left > l && x1 + this.clickOffset.left < r);
  73. } else {
  74. return (l < x1 + (this.helperProportions.width / 2) // Right Half
  75. && x2 - (this.helperProportions.width / 2) < r // Left Half
  76. && t < y1 + (this.helperProportions.height / 2) // Bottom Half
  77. && y2 - (this.helperProportions.height / 2) < b ); // Top Half
  78. }
  79. },
  80. intersectsWithEdge: function(item) {
  81. var x1 = this.position.absolute.left, x2 = x1 + this.helperProportions.width,
  82. y1 = this.position.absolute.top, y2 = y1 + this.helperProportions.height;
  83. var l = item.left, r = l + item.width, 
  84. t = item.top, b = t + item.height;
  85. if(this.options.tolerance == "pointer") {
  86. if(!(y1 + this.clickOffset.top > t && y1 + this.clickOffset.top < b && x1 + this.clickOffset.left > l && x1 + this.clickOffset.left < r)) return false;
  87. if(this.floating) {
  88. if(x1 + this.clickOffset.left > l && x1 + this.clickOffset.left < l + item.width/2) return 2;
  89. if(x1 + this.clickOffset.left > l+item.width/2 && x1 + this.clickOffset.left < r) return 1;
  90. } else {
  91. if(y1 + this.clickOffset.top > t && y1 + this.clickOffset.top < t + item.height/2) return 2;
  92. if(y1 + this.clickOffset.top > t+item.height/2 && y1 + this.clickOffset.top < b) return 1;
  93. }
  94. } else {
  95. if (!(l < x1 + (this.helperProportions.width / 2) // Right Half
  96. && x2 - (this.helperProportions.width / 2) < r // Left Half
  97. && t < y1 + (this.helperProportions.height / 2) // Bottom Half
  98. && y2 - (this.helperProportions.height / 2) < b )) return false; // Top Half
  99. if(this.floating) {
  100. if(x2 > l && x1 < l) return 2; //Crosses left edge
  101. if(x1 < r && x2 > r) return 1; //Crosses right edge
  102. } else {
  103. if(y2 > t && y1 < t) return 1; //Crosses top edge
  104. if(y1 < b && y2 > b) return 2; //Crosses bottom edge
  105. }
  106. }
  107. return false;
  108. },
  109. //This method checks approximately if the item is dragged in a container, but doesn't touch any items
  110. inEmptyZone: function(container) {
  111. if(!$(container.options.items, container.element).length) {
  112. return container.options.dropOnEmpty ? true : false;
  113. };
  114. var last = $(container.options.items, container.element).not('.ui-sortable-helper'); last = $(last[last.length-1]);
  115. var top = last.offset()[this.floating ? 'left' : 'top'] + last[0][this.floating ? 'offsetWidth' : 'offsetHeight'];
  116. return (this.position.absolute[this.floating ? 'left' : 'top'] > top);
  117. },
  118. refresh: function() {
  119. this.refreshItems();
  120. this.refreshPositions();
  121. },
  122. refreshItems: function() {
  123. this.items = [];
  124. this.containers = [this];
  125. var items = this.items;
  126. var queries = [$(this.options.items, this.element)];
  127. if(this.options.connectWith) {
  128. for (var i = this.options.connectWith.length - 1; i >= 0; i--){
  129. var cur = $(this.options.connectWith[i]);
  130. for (var j = cur.length - 1; j >= 0; j--){
  131. var inst = $.data(cur[j], 'sortable');
  132. if(inst && !inst.options.disabled) {
  133. queries.push($(inst.options.items, inst.element));
  134. this.containers.push(inst);
  135. }
  136. };
  137. };
  138. }
  139. for (var i = queries.length - 1; i >= 0; i--){
  140. queries[i].each(function() {
  141. $.data(this, 'sortable-item', true); // Data for target checking (mouse manager)
  142. items.push({
  143. item: $(this),
  144. width: 0, height: 0,
  145. left: 0, top: 0
  146. });
  147. });
  148. };
  149. },
  150. refreshPositions: function(fast) {
  151. for (var i = this.items.length - 1; i >= 0; i--){
  152. var t = this.items[i].item;
  153. if(!fast) this.items[i].width = (this.options.toleranceElement ? $(this.options.toleranceElement, t) : t).outerWidth();
  154. if(!fast) this.items[i].height = (this.options.toleranceElement ? $(this.options.toleranceElement, t) : t).outerHeight();
  155. var p = (this.options.toleranceElement ? $(this.options.toleranceElement, t) : t).offset();
  156. this.items[i].left = p.left;
  157. this.items[i].top = p.top;
  158. };
  159. for (var i = this.containers.length - 1; i >= 0; i--){
  160. var p =this.containers[i].element.offset();
  161. this.containers[i].containerCache.left = p.left;
  162. this.containers[i].containerCache.top = p.top;
  163. this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
  164. this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
  165. };
  166. },
  167. destroy: function() {
  168. this.element
  169. .removeClass("ui-sortable ui-sortable-disabled")
  170. .removeData("sortable")
  171. .unbind(".sortable")
  172. .mouse("destroy");
  173. for ( var i = this.items.length - 1; i >= 0; i-- )
  174. this.items[i].item.removeData("sortable-item");
  175. },
  176. createPlaceholder: function(that) {
  177. (that || this).placeholderElement = this.options.placeholderElement ? $(this.options.placeholderElement, (that || this).currentItem) : (that || this).currentItem;
  178. (that || this).placeholder = $('<div></div>')
  179. .addClass(this.options.placeholder)
  180. .appendTo('body')
  181. .css({ position: 'absolute' })
  182. .css((that || this).placeholderElement.offset())
  183. .css({ width: (that || this).placeholderElement.outerWidth(), height: (that || this).placeholderElement.outerHeight() })
  184. ;
  185. },
  186. contactContainers: function(e) {
  187. for (var i = this.containers.length - 1; i >= 0; i--){
  188. if(this.intersectsWith(this.containers[i].containerCache)) {
  189. if(!this.containers[i].containerCache.over) {
  190. if(this.currentContainer != this.containers[i]) {
  191. //When entering a new container, we will find the item with the least distance and append our item near it
  192. var dist = 10000; var itemWithLeastDistance = null; var base = this.position.absolute[this.containers[i].floating ? 'left' : 'top'];
  193. for (var j = this.items.length - 1; j >= 0; j--) {
  194. if(!contains(this.containers[i].element[0], this.items[j].item[0])) continue;
  195. var cur = this.items[j][this.containers[i].floating ? 'left' : 'top'];
  196. if(Math.abs(cur - base) < dist) {
  197. dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
  198. }
  199. }
  200. //We also need to exchange the placeholder
  201. if(this.placeholder) this.placeholder.remove();
  202. if(this.containers[i].options.placeholder) {
  203. this.containers[i].createPlaceholder(this);
  204. } else {
  205. this.placeholder = null; this.placeholderElement = null;
  206. }
  207. itemWithLeastDistance ? this.rearrange(e, itemWithLeastDistance) : this.rearrange(e, null, this.containers[i].element);
  208. this.propagate("change", e); //Call plugins and callbacks
  209. this.containers[i].propagate("change", e, this); //Call plugins and callbacks
  210. this.currentContainer = this.containers[i];
  211. }
  212. this.containers[i].propagate("over", e, this);
  213. this.containers[i].containerCache.over = 1;
  214. }
  215. } else {
  216. if(this.containers[i].containerCache.over) {
  217. this.containers[i].propagate("out", e, this);
  218. this.containers[i].containerCache.over = 0;
  219. }
  220. }
  221. };
  222. },
  223. start: function(e,el) {
  224. var o = this.options;
  225. this.currentContainer = this;
  226. this.refresh();
  227. //Create and append the visible helper
  228. this.helper = typeof o.helper == 'function' ? $(o.helper.apply(this.element[0], [e, this.currentItem])) : this.currentItem.clone();
  229. if(!this.helper.parents('body').length) this.helper.appendTo(o.appendTo || this.currentItem[0].parentNode); //Add the helper to the DOM if that didn't happen already
  230. this.helper.css({ position: 'absolute', clear: 'both' }).addClass('ui-sortable-helper'); //Position it absolutely and add a helper class
  231. //Prepare variables for position generation
  232. $.extend(this, {
  233. offsetParent: this.helper.offsetParent(),
  234. offsets: {
  235. absolute: this.currentItem.offset()
  236. },
  237. mouse: {
  238. start: { top: e.pageY, left: e.pageX }
  239. },
  240. margins: {
  241. top: parseInt(this.currentItem.css("marginTop")) || 0,
  242. left: parseInt(this.currentItem.css("marginLeft")) || 0
  243. }
  244. });
  245. //The relative click offset
  246. this.offsets.parent = this.offsetParent.offset();
  247. this.clickOffset = { left: e.pageX - this.offsets.absolute.left, top: e.pageY - this.offsets.absolute.top };
  248. this.originalPosition = {
  249. left: this.offsets.absolute.left - this.offsets.parent.left - this.margins.left,
  250. top: this.offsets.absolute.top - this.offsets.parent.top - this.margins.top
  251. }
  252. //Generate a flexible offset that will later be subtracted from e.pageX/Y
  253. //I hate margins - they need to be removed before positioning the element absolutely..
  254. this.offset = {
  255. left: e.pageX - this.originalPosition.left,
  256. top: e.pageY - this.originalPosition.top
  257. };
  258. //Save the first time position
  259. $.extend(this, {
  260. position: {
  261. current: { top: e.pageY - this.offset.top, left: e.pageX - this.offset.left },
  262. absolute: { left: e.pageX - this.clickOffset.left, top: e.pageY - this.clickOffset.top },
  263. dom: this.currentItem.prev()[0]
  264. }
  265. });
  266. //If o.placeholder is used, create a new element at the given position with the class
  267. if(o.placeholder) this.createPlaceholder();
  268. this.propagate("start", e); //Call plugins and callbacks
  269. this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() }; //Save and store the helper proportions
  270. //If we have something in cursorAt, we'll use it
  271. if(o.cursorAt) {
  272. if(o.cursorAt.top != undefined || o.cursorAt.bottom != undefined) {
  273. this.offset.top -= this.clickOffset.top - (o.cursorAt.top != undefined ? o.cursorAt.top : (this.helperProportions.height - o.cursorAt.bottom));
  274. this.clickOffset.top = (o.cursorAt.top != undefined ? o.cursorAt.top : (this.helperProportions.height - o.cursorAt.bottom));
  275. }
  276. if(o.cursorAt.left != undefined || o.cursorAt.right != undefined) {
  277. this.offset.left -= this.clickOffset.left - (o.cursorAt.left != undefined ? o.cursorAt.left : (this.helperProportions.width - o.cursorAt.right));
  278. this.clickOffset.left = (o.cursorAt.left != undefined ? o.cursorAt.left : (this.helperProportions.width - o.cursorAt.right));
  279. }
  280. }
  281. if(this.options.placeholder != 'clone') $(this.currentItem).css('visibility', 'hidden'); //Set the original element visibility to hidden to still fill out the white space
  282. for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i].propagate("activate", e, this); } //Post 'activate' events to possible containers
  283. //Prepare possible droppables
  284. if($.ui.ddmanager) $.ui.ddmanager.current = this;
  285. if ($.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(this, e);
  286. this.dragging = true;
  287. return false;
  288. },
  289. stop: function(e) {
  290. this.propagate("stop", e); //Call plugins and trigger callbacks
  291. if(this.position.dom != this.currentItem.prev()[0]) this.propagate("update", e); //Trigger update callback if the DOM position has changed
  292. if(!contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
  293. this.propagate("remove", e);
  294. for (var i = this.containers.length - 1; i >= 0; i--){
  295. if(contains(this.containers[i].element[0], this.currentItem[0])) {
  296. this.containers[i].propagate("update", e, this);
  297. this.containers[i].propagate("receive", e, this);
  298. }
  299. };
  300. };
  301. //Post events to containers
  302. for (var i = this.containers.length - 1; i >= 0; i--){
  303. this.containers[i].propagate("deactivate", e, this);
  304. if(this.containers[i].containerCache.over) {
  305. this.containers[i].propagate("out", e, this);
  306. this.containers[i].containerCache.over = 0;
  307. }
  308. }
  309. //If we are using droppables, inform the manager about the drop
  310. if ($.ui.ddmanager && !this.options.dropBehaviour) $.ui.ddmanager.drop(this, e);
  311. this.dragging = false;
  312. if(this.cancelHelperRemoval) return false;
  313. $(this.currentItem).css('visibility', '');
  314. if(this.placeholder) this.placeholder.remove();
  315. this.helper.remove();
  316. return false;
  317. },
  318. drag: function(e) {
  319. //Compute the helpers position
  320. this.position.current = { top: e.pageY - this.offset.top, left: e.pageX - this.offset.left };
  321. this.position.absolute = { left: e.pageX - this.clickOffset.left, top: e.pageY - this.clickOffset.top };
  322. //Rearrange
  323. for (var i = this.items.length - 1; i >= 0; i--) {
  324. var intersection = this.intersectsWithEdge(this.items[i]);
  325. if(!intersection) continue;
  326. if(this.items[i].item[0] != this.currentItem[0] //cannot intersect with itself
  327. && this.currentItem[intersection == 1 ? "next" : "prev"]()[0] != this.items[i].item[0] //no useless actions that have been done before
  328. && !contains(this.currentItem[0], this.items[i].item[0]) //no action if the item moved is the parent of the item checked
  329. && (this.options.type == 'semi-dynamic' ? !contains(this.element[0], this.items[i].item[0]) : true)
  330. ) {
  331. this.direction = intersection == 1 ? "down" : "up";
  332. this.rearrange(e, this.items[i]);
  333. this.propagate("change", e); //Call plugins and callbacks
  334. break;
  335. }
  336. }
  337. //Post events to containers
  338. this.contactContainers(e);
  339. //Interconnect with droppables
  340. if($.ui.ddmanager) $.ui.ddmanager.drag(this, e);
  341. this.propagate("sort", e); //Call plugins and callbacks
  342. this.helper.css({ left: this.position.current.left+'px', top: this.position.current.top+'px' }); // Stick the helper to the cursor
  343. return false;
  344. },
  345. rearrange: function(e, i, a) {
  346. a ? a.append(this.currentItem) : i.item[this.direction == 'down' ? 'before' : 'after'](this.currentItem);
  347. this.refreshPositions(true); //Precompute after each DOM insertion, NOT on mousemove
  348. if(this.placeholderElement) this.placeholder.css(this.placeholderElement.offset());
  349. if(this.placeholderElement && this.placeholderElement.is(":visible")) this.placeholder.css({ width: this.placeholderElement.outerWidth(), height: this.placeholderElement.outerHeight() });
  350. }
  351. });
  352. $.extend($.ui.sortable, {
  353. getter: "serialize toArray",
  354. defaults: {
  355. items: '> *',
  356. zIndex: 1000
  357. }
  358. });
  359. /*
  360.  * Sortable Extensions
  361.  */
  362. $.ui.plugin.add("sortable", "cursor", {
  363. start: function(e, ui) {
  364. var t = $('body');
  365. if (t.css("cursor")) ui.options._cursor = t.css("cursor");
  366. t.css("cursor", ui.options.cursor);
  367. },
  368. stop: function(e, ui) {
  369. if (ui.options._cursor) $('body').css("cursor", ui.options._cursor);
  370. }
  371. });
  372. $.ui.plugin.add("sortable", "zIndex", {
  373. start: function(e, ui) {
  374. var t = ui.helper;
  375. if(t.css("zIndex")) ui.options._zIndex = t.css("zIndex");
  376. t.css('zIndex', ui.options.zIndex);
  377. },
  378. stop: function(e, ui) {
  379. if(ui.options._zIndex) $(ui.helper).css('zIndex', ui.options._zIndex);
  380. }
  381. });
  382. $.ui.plugin.add("sortable", "opacity", {
  383. start: function(e, ui) {
  384. var t = ui.helper;
  385. if(t.css("opacity")) ui.options._opacity = t.css("opacity");
  386. t.css('opacity', ui.options.opacity);
  387. },
  388. stop: function(e, ui) {
  389. if(ui.options._opacity) $(ui.helper).css('opacity', ui.options._opacity);
  390. }
  391. });
  392. $.ui.plugin.add("sortable", "revert", {
  393. stop: function(e, ui) {
  394. var self = ui.instance;
  395. self.cancelHelperRemoval = true;
  396. var cur = self.currentItem.offset();
  397. var op = self.helper.offsetParent().offset();
  398. if(ui.instance.options.zIndex) ui.helper.css('zIndex', ui.instance.options.zIndex); //Do the zIndex again because it already was resetted by the plugin above on stop
  399. //Also animate the placeholder if we have one
  400. if(ui.instance.placeholder) ui.instance.placeholder.animate({ opacity: 'hide' }, parseInt(ui.options.revert, 10) || 500);
  401. ui.helper.animate({
  402. left: cur.left - op.left - self.margins.left,
  403. top: cur.top - op.top - self.margins.top
  404. }, parseInt(ui.options.revert, 10) || 500, function() {
  405. self.currentItem.css('visibility', 'visible');
  406. window.setTimeout(function() {
  407. if(self.placeholder) self.placeholder.remove();
  408. self.helper.remove();
  409. if(ui.options._zIndex) ui.helper.css('zIndex', ui.options._zIndex);
  410. }, 50);
  411. });
  412. }
  413. });
  414. $.ui.plugin.add("sortable", "containment", {
  415. start: function(e, ui) {
  416. var o = ui.options;
  417. if((o.containment.left != undefined || o.containment.constructor == Array) && !o._containment) return;
  418. if(!o._containment) o._containment = o.containment;
  419. if(o._containment == 'parent') o._containment = this[0].parentNode;
  420. if(o._containment == 'sortable') o._containment = this[0];
  421. if(o._containment == 'document') {
  422. o.containment = [
  423. 0,
  424. 0,
  425. $(document).width(),
  426. ($(document).height() || document.body.parentNode.scrollHeight)
  427. ];
  428. } else { //I'm a node, so compute top/left/right/bottom
  429. var ce = $(o._containment);
  430. var co = ce.offset();
  431. o.containment = [
  432. co.left,
  433. co.top,
  434. co.left+(ce.outerWidth() || ce[0].scrollWidth),
  435. co.top+(ce.outerHeight() || ce[0].scrollHeight)
  436. ];
  437. }
  438. },
  439. sort: function(e, ui) {
  440. var o = ui.options;
  441. var h = ui.helper;
  442. var c = o.containment;
  443. var self = ui.instance;
  444. var borderLeft = (parseInt(self.offsetParent.css("borderLeftWidth"), 10) || 0);
  445. var borderRight = (parseInt(self.offsetParent.css("borderRightWidth"), 10) || 0);
  446. var borderTop = (parseInt(self.offsetParent.css("borderTopWidth"), 10) || 0);
  447. var borderBottom = (parseInt(self.offsetParent.css("borderBottomWidth"), 10) || 0);
  448. if(c.constructor == Array) {
  449. if((self.position.absolute.left < c[0])) self.position.current.left = c[0] - self.offsets.parent.left - self.margins.left;
  450. if((self.position.absolute.top < c[1])) self.position.current.top = c[1] - self.offsets.parent.top - self.margins.top;
  451. if(self.position.absolute.left - c[2] + self.helperProportions.width >= 0) self.position.current.left = c[2] - self.offsets.parent.left - self.helperProportions.width - self.margins.left - borderLeft - borderRight;
  452. if(self.position.absolute.top - c[3] + self.helperProportions.height >= 0) self.position.current.top = c[3] - self.offsets.parent.top - self.helperProportions.height - self.margins.top - borderTop - borderBottom;
  453. } else {
  454. if((ui.position.left < c.left)) self.position.current.left = c.left;
  455. if((ui.position.top < c.top)) self.position.current.top = c.top;
  456. if(ui.position.left - self.offsetParent.innerWidth() + self.helperProportions.width + c.right + borderLeft + borderRight >= 0) self.position.current.left = self.offsetParent.innerWidth() - self.helperProportions.width - c.right - borderLeft - borderRight;
  457. if(ui.position.top - self.offsetParent.innerHeight() + self.helperProportions.height + c.bottom + borderTop + borderBottom >= 0) self.position.current.top = self.offsetParent.innerHeight() - self.helperProportions.height - c.bottom - borderTop - borderBottom;
  458. }
  459. }
  460. });
  461. $.ui.plugin.add("sortable", "axis", {
  462. sort: function(e, ui) {
  463. var o = ui.options;
  464. if(o.constraint) o.axis = o.constraint; //Legacy check
  465. o.axis == 'x' ? ui.instance.position.current.top = ui.instance.originalPosition.top : ui.instance.position.current.left = ui.instance.originalPosition.left;
  466. }
  467. });
  468. $.ui.plugin.add("sortable", "scroll", {
  469. start: function(e, ui) {
  470. var o = ui.options;
  471. o.scrollSensitivity = o.scrollSensitivity || 20;
  472. o.scrollSpeed = o.scrollSpeed || 20;
  473. ui.instance.overflowY = function(el) {
  474. do { if((/auto|scroll/).test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-y'))) return el; el = el.parent(); } while (el[0].parentNode);
  475. return $(document);
  476. }(this);
  477. ui.instance.overflowX = function(el) {
  478. do { if((/auto|scroll/).test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-x'))) return el; el = el.parent(); } while (el[0].parentNode);
  479. return $(document);
  480. }(this);
  481. if(ui.instance.overflowY[0] != document && ui.instance.overflowY[0].tagName != 'HTML') ui.instance.overflowYstart = ui.instance.overflowY[0].scrollTop;
  482. if(ui.instance.overflowX[0] != document && ui.instance.overflowX[0].tagName != 'HTML') ui.instance.overflowXstart = ui.instance.overflowX[0].scrollLeft;
  483. },
  484. sort: function(e, ui) {
  485. var o = ui.options;
  486. var i = ui.instance;
  487. if(i.overflowY[0] != document && i.overflowY[0].tagName != 'HTML') {
  488. if(i.overflowY[0].offsetHeight - (ui.position.top - i.overflowY[0].scrollTop + i.clickOffset.top) < o.scrollSensitivity)
  489. i.overflowY[0].scrollTop = i.overflowY[0].scrollTop + o.scrollSpeed;
  490. if((ui.position.top - i.overflowY[0].scrollTop + i.clickOffset.top) < o.scrollSensitivity)
  491. i.overflowY[0].scrollTop = i.overflowY[0].scrollTop - o.scrollSpeed;
  492. } else {
  493. //$(document.body).append('<p>'+(e.pageY - $(document).scrollTop())+'</p>');
  494. if(e.pageY - $(document).scrollTop() < o.scrollSensitivity)
  495. $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
  496. if($(window).height() - (e.pageY - $(document).scrollTop()) < o.scrollSensitivity)
  497. $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
  498. }
  499. if(i.overflowX[0] != document && i.overflowX[0].tagName != 'HTML') {
  500. if(i.overflowX[0].offsetWidth - (ui.position.left - i.overflowX[0].scrollLeft + i.clickOffset.left) < o.scrollSensitivity)
  501. i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft + o.scrollSpeed;
  502. if((ui.position.top - i.overflowX[0].scrollLeft + i.clickOffset.left) < o.scrollSensitivity)
  503. i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft - o.scrollSpeed;
  504. } else {
  505. if(e.pageX - $(document).scrollLeft() < o.scrollSensitivity)
  506. $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
  507. if($(window).width() - (e.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
  508. $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
  509. }
  510. //ui.instance.recallOffset(e);
  511. i.offset = {
  512. left: i.mouse.start.left - i.originalPosition.left + (i.overflowXstart !== undefined ? i.overflowXstart - i.overflowX[0].scrollLeft : 0),
  513. top: i.mouse.start.top - i.originalPosition.top + (i.overflowYstart !== undefined ? i.overflowYstart - i.overflowX[0].scrollTop : 0)
  514. };
  515. }
  516. });
  517. })(jQuery);
  518. /*
  519.  * jQuery UI Accordion
  520.  * 
  521.  * Copyright (c) 2007, 2008 Jörn Zaefferer
  522.  * Dual licensed under the MIT (MIT-LICENSE.txt)
  523.  * and GPL (GPL-LICENSE.txt) licenses.
  524.  *
  525.  * http://docs.jquery.com/UI/Accordion
  526.  *
  527.  * Depends:
  528.  * ui.core.js
  529.  *
  530.  * Revision: $Id: ui.accordion.js 5433 2008-05-04 20:07:17Z joern.zaefferer $
  531.  */
  532. ;(function($) {
  533. $.widget("ui.accordion", {
  534. init: function() {
  535. var options = this.options;
  536. if ( options.navigation ) {
  537. var current = this.element.find("a").filter(options.navigationFilter);
  538. if ( current.length ) {
  539. if ( current.filter(options.header).length ) {
  540. options.active = current;
  541. } else {
  542. options.active = current.parent().parent().prev();
  543. current.addClass("current");
  544. }
  545. }
  546. }
  547. // calculate active if not specified, using the first header
  548. options.headers = this.element.find(options.header);
  549. options.active = findActive(options.headers, options.active);
  550. if (!this.element.hasClass("ui-accordion")) {
  551. this.element.addClass("ui-accordion");
  552. $("<span class='ui-accordion-left'/>").insertBefore(options.headers);
  553. $("<span class='ui-accordion-right'/>").appendTo(options.headers);
  554. options.headers.addClass("ui-accordion-header").attr("tabindex", "0");
  555. }
  556. var maxHeight;
  557. if ( options.fillSpace ) {
  558. maxHeight = this.element.parent().height();
  559. options.headers.each(function() {
  560. maxHeight -= $(this).outerHeight();
  561. });
  562. var maxPadding = 0;
  563. options.headers.next().each(function() {
  564. maxPadding = Math.max(maxPadding, $(this).innerHeight() - $(this).height());
  565. }).height(maxHeight - maxPadding);
  566. } else if ( options.autoHeight ) {
  567. maxHeight = 0;
  568. options.headers.next().each(function() {
  569. maxHeight = Math.max(maxHeight, $(this).outerHeight());
  570. }).height(maxHeight);
  571. }
  572. options.headers
  573. .not(options.active || "")
  574. .next()
  575. .hide();
  576. options.active.parent().andSelf().addClass(options.selectedClass);
  577. if (options.event) {
  578. this.element.bind((options.event) + ".accordion", clickHandler);
  579. }
  580. },
  581. activate: function(index) {
  582. // call clickHandler with custom event
  583. clickHandler.call(this.element[0], {
  584. target: findActive( this.options.headers, index )[0]
  585. });
  586. },
  587. destroy: function() {
  588. this.options.headers.next().css("display", "");
  589. if ( this.options.fillSpace || this.options.autoHeight ) {
  590. this.options.headers.next().css("height", "");
  591. }
  592. $.removeData(this.element[0], "accordion");
  593. this.element.removeClass("ui-accordion").unbind(".accordion");
  594. }
  595. });
  596. function scopeCallback(callback, scope) {
  597. return function() {
  598. return callback.apply(scope, arguments);
  599. };
  600. };
  601. function completed(cancel) {
  602. // if removed while animated data can be empty
  603. if (!$.data(this, "accordion")) {
  604. return;
  605. }
  606. var instance = $.data(this, "accordion");
  607. var options = instance.options;
  608. options.running = cancel ? 0 : --options.running;
  609. if ( options.running ) {
  610. return;
  611. }
  612. if ( options.clearStyle ) {
  613. options.toShow.add(options.toHide).css({
  614. height: "",
  615. overflow: ""
  616. });
  617. }
  618. $(this).triggerHandler("accordionchange", [options.data], options.change);
  619. }
  620. function toggle(toShow, toHide, data, clickedActive, down) {
  621. var options = $.data(this, "accordion").options;
  622. options.toShow = toShow;
  623. options.toHide = toHide;
  624. options.data = data;
  625. var complete = scopeCallback(completed, this);
  626. // count elements to animate
  627. options.running = toHide.size() === 0 ? toShow.size() : toHide.size();
  628. if ( options.animated ) {
  629. if ( !options.alwaysOpen && clickedActive ) {
  630. $.ui.accordion.animations[options.animated]({
  631. toShow: jQuery([]),
  632. toHide: toHide,
  633. complete: complete,
  634. down: down,
  635. autoHeight: options.autoHeight
  636. });
  637. } else {
  638. $.ui.accordion.animations[options.animated]({
  639. toShow: toShow,
  640. toHide: toHide,
  641. complete: complete,
  642. down: down,
  643. autoHeight: options.autoHeight
  644. });
  645. }
  646. } else {
  647. if ( !options.alwaysOpen && clickedActive ) {
  648. toShow.toggle();
  649. } else {
  650. toHide.hide();
  651. toShow.show();
  652. }
  653. complete(true);
  654. }
  655. }
  656. function clickHandler(event) {
  657. var options = $.data(this, "accordion").options;
  658. if (options.disabled) {
  659. return false;
  660. }
  661. // called only when using activate(false) to close all parts programmatically
  662. if ( !event.target && !options.alwaysOpen ) {
  663. options.active.parent().andSelf().toggleClass(options.selectedClass);
  664. var toHide = options.active.next(),
  665. data = {
  666. instance: this,
  667. options: options,
  668. newHeader: jQuery([]),
  669. oldHeader: options.active,
  670. newContent: jQuery([]),
  671. oldContent: toHide
  672. },
  673. toShow = (options.active = $([]));
  674. toggle.call(this, toShow, toHide, data );
  675. return false;
  676. }
  677. // get the click target
  678. var clicked = $(event.target);
  679. // due to the event delegation model, we have to check if one
  680. // of the parent elements is our actual header, and find that
  681. if ( clicked.parents(options.header).length ) {
  682. while ( !clicked.is(options.header) ) {
  683. clicked = clicked.parent();
  684. }
  685. }
  686. var clickedActive = clicked[0] == options.active[0];
  687. // if animations are still active, or the active header is the target, ignore click
  688. if (options.running || (options.alwaysOpen && clickedActive)) {
  689. return false;
  690. }
  691. if (!clicked.is(options.header)) {
  692. return;
  693. }
  694. // switch classes
  695. options.active.parent().andSelf().toggleClass(options.selectedClass);
  696. if ( !clickedActive ) {
  697. clicked.parent().andSelf().addClass(options.selectedClass);
  698. }
  699. // find elements to show and hide
  700. var toShow = clicked.next(),
  701. toHide = options.active.next(),
  702. //data = [clicked, options.active, toShow, toHide],
  703. data = {
  704. instance: this,
  705. options: options,
  706. newHeader: clicked,
  707. oldHeader: options.active,
  708. newContent: toShow,
  709. oldContent: toHide
  710. },
  711. down = options.headers.index( options.active[0] ) > options.headers.index( clicked[0] );
  712. options.active = clickedActive ? $([]) : clicked;
  713. toggle.call(this, toShow, toHide, data, clickedActive, down );
  714. return false;
  715. };
  716. function findActive(headers, selector) {
  717. return selector != undefined
  718. ? typeof selector == "number"
  719. ? headers.filter(":eq(" + selector + ")")
  720. : headers.not(headers.not(selector))
  721. : selector === false
  722. ? $([])
  723. : headers.filter(":eq(0)");
  724. }
  725. $.extend($.ui.accordion, {
  726. defaults: {
  727. selectedClass: "selected",
  728. alwaysOpen: true,
  729. animated: 'slide',
  730. event: "click",
  731. header: "a",
  732. autoHeight: true,
  733. running: 0,
  734. navigationFilter: function() {
  735. return this.href.toLowerCase() == location.href.toLowerCase();
  736. }
  737. },
  738. animations: {
  739. slide: function(options, additions) {
  740. options = $.extend({
  741. easing: "swing",
  742. duration: 300
  743. }, options, additions);
  744. if ( !options.toHide.size() ) {
  745. options.toShow.animate({height: "show"}, options);
  746. return;
  747. }
  748. var hideHeight = options.toHide.height(),
  749. showHeight = options.toShow.height(),
  750. difference = showHeight / hideHeight;
  751. options.toShow.css({ height: 0, overflow: 'hidden' }).show();
  752. options.toHide.filter(":hidden").each(options.complete).end().filter(":visible").animate({height:"hide"},{
  753. step: function(now) {
  754. var current = (hideHeight - now) * difference;
  755. if ($.browser.msie || $.browser.opera) {
  756. current = Math.ceil(current);
  757. }
  758. options.toShow.height( current );
  759. },
  760. duration: options.duration,
  761. easing: options.easing,
  762. complete: function() {
  763. if ( !options.autoHeight ) {
  764. options.toShow.css("height", "auto");
  765. }
  766. options.complete();
  767. }
  768. });
  769. },
  770. bounceslide: function(options) {
  771. this.slide(options, {
  772. easing: options.down ? "bounceout" : "swing",
  773. duration: options.down ? 1000 : 200
  774. });
  775. },
  776. easeslide: function(options) {
  777. this.slide(options, {
  778. easing: "easeinout",
  779. duration: 700
  780. });
  781. }
  782. }
  783. });
  784. // deprecated, use accordion("activate", index) instead
  785. $.fn.activate = function(index) {
  786. return this.accordion("activate", index);
  787. };
  788. })(jQuery);
  789. /*
  790.  * jQuery UI Dialog
  791.  *
  792.  * Copyright (c) 2008 Richard D. Worth (rdworth.org)
  793.  * Dual licensed under the MIT (MIT-LICENSE.txt)
  794.  * and GPL (GPL-LICENSE.txt) licenses.
  795.  * 
  796.  * http://docs.jquery.com/UI/Dialog
  797.  *
  798.  * Depends:
  799.  * ui.core.js
  800.  * ui.draggable.js
  801.  * ui.resizable.js
  802.  *
  803.  * Revision: $Id: ui.dialog.js 5433 2008-05-04 20:07:17Z joern.zaefferer $
  804.  */
  805. ;(function($) {
  806. var setDataSwitch = {
  807. "dragStart": "start.draggable",
  808. "drag": "drag.draggable",
  809. "dragStop": "stop.draggable",
  810. "maxHeight": "maxHeight.resizable",
  811. "minHeight": "minHeight.resizable",
  812. "maxWidth": "maxWidth.resizable",
  813. "minWidth": "minWidth.resizable",
  814. "resizeStart": "start.resizable",
  815. "resize": "drag.resizable",
  816. "resizeStop": "stop.resizable"
  817. };
  818. $.widget("ui.dialog", {
  819. init: function() {
  820. var self = this;
  821. var options = this.options;
  822. var uiDialogContent = $(this.element).addClass('ui-dialog-content');
  823. if (!uiDialogContent.parent().length) {
  824. uiDialogContent.appendTo('body');
  825. }
  826. uiDialogContent
  827. .wrap(document.createElement('div'))
  828. .wrap(document.createElement('div'));
  829. var uiDialogContainer = uiDialogContent.parent().addClass('ui-dialog-container').css({position: 'relative'});
  830. var uiDialog = this.uiDialog = uiDialogContainer.parent().hide()
  831. .addClass('ui-dialog')
  832. .css({position: 'absolute', width: options.width, height: options.height, overflow: 'hidden'}); 
  833. var classNames = uiDialogContent.attr('className').split(' ');
  834. // Add content classes to dialog, to inherit theme at top level of element
  835. $.each(classNames, function(i, className) {
  836. if (className != 'ui-dialog-content')
  837. uiDialog.addClass(className);
  838. });
  839. if ($.fn.resizable) {
  840. uiDialog.append('<div class="ui-resizable-n ui-resizable-handle"></div>')
  841. .append('<div class="ui-resizable-s ui-resizable-handle"></div>')
  842. .append('<div class="ui-resizable-e ui-resizable-handle"></div>')
  843. .append('<div class="ui-resizable-w ui-resizable-handle"></div>')
  844. .append('<div class="ui-resizable-ne ui-resizable-handle"></div>')
  845. .append('<div class="ui-resizable-se ui-resizable-handle"></div>')
  846. .append('<div class="ui-resizable-sw ui-resizable-handle"></div>')
  847. .append('<div class="ui-resizable-nw ui-resizable-handle"></div>');
  848. uiDialog.resizable({
  849. maxWidth: options.maxWidth,
  850. maxHeight: options.maxHeight,
  851. minWidth: options.minWidth,
  852. minHeight: options.minHeight,
  853. start: options.resizeStart,
  854. resize: options.resize,
  855. stop: function(e, ui) {
  856. options.resizeStop && options.resizeStop.apply(this, arguments);
  857. $.ui.dialog.overlay.resize();
  858. }
  859. });
  860. if (!options.resizable)
  861. uiDialog.resizable('disable');
  862. }
  863. uiDialogContainer.prepend('<div class="ui-dialog-titlebar"></div>');
  864. var uiDialogTitlebar = $('.ui-dialog-titlebar', uiDialogContainer);
  865. this.uiDialogTitlebar = uiDialogTitlebar;
  866. var title = (options.title) ? options.title : (uiDialogContent.attr('title')) ? uiDialogContent.attr('title') : '';
  867. uiDialogTitlebar.append('<span class="ui-dialog-title">' + title + '</span>');
  868. uiDialogTitlebar.append('<a href="#" class="ui-dialog-titlebar-close"><span>X</span></a>');
  869. this.uiDialogTitlebarClose = $('.ui-dialog-titlebar-close', uiDialogTitlebar)
  870. .hover(function() { $(this).addClass('ui-dialog-titlebar-close-hover'); }, 
  871. function() { $(this).removeClass('ui-dialog-titlebar-close-hover'); }
  872. )
  873. .mousedown(function(ev) {
  874. ev.stopPropagation();
  875. })
  876. .click(function() {
  877. self.close();
  878. return false;
  879. });
  880. // setting tabindex makes the div focusable
  881. // setting outline to 0 prevents a border on focus in Mozilla
  882. uiDialog.attr('tabindex', -1).css('outline', 0).keydown(function(ev) {
  883. if (options.closeOnEscape) {
  884. var ESC = 27;
  885. ev.keyCode && ev.keyCode == ESC && self.close();
  886. }
  887. });
  888. var hasButtons = false;
  889. $.each(options.buttons, function() { return !(hasButtons = true); });
  890. if (hasButtons) {
  891. var uiDialogButtonPane = $('<div class="ui-dialog-buttonpane"/>')
  892. .appendTo(uiDialog);
  893. $.each(options.buttons, function(name, fn) {
  894. $(document.createElement('button'))
  895. .text(name)
  896. .click(function() { fn.apply(self.element, arguments) })
  897. .appendTo(uiDialogButtonPane);
  898. });
  899. }
  900. if ($.fn.draggable) {
  901. uiDialog.draggable({
  902. handle: '.ui-dialog-titlebar',
  903. start: function(e, ui) {
  904. self.activate();
  905. options.dragStart && options.dragStart.apply(this, arguments);
  906. },
  907. drag: options.drag,
  908. stop: function(e, ui) {
  909. options.dragStop && options.dragStop.apply(this, arguments);
  910. $.ui.dialog.overlay.resize();
  911. }
  912. });
  913. if (!options.draggable)
  914. uiDialog.draggable('disable')
  915. }
  916. uiDialog.mousedown(function() {
  917. self.activate();
  918. });
  919. uiDialogTitlebar.click(function() {
  920. self.activate();
  921. });
  922. options.bgiframe && $.fn.bgiframe && uiDialog.bgiframe();
  923. if (options.autoOpen) {
  924. this.open();
  925. };
  926. },
  927. setData: function(event, key, value){
  928. setDataSwitch[key] && this.uiDialog.data(setDataSwitch[key], value);
  929. switch (key) {
  930. case "draggable":
  931. this.uiDialog.draggable(value ? 'enable' : 'disable');
  932. break;
  933. case "height":
  934. this.uiDialog.height(value);
  935. break;
  936. case "position":
  937. this.position(value);
  938. break;
  939. case "resizable":
  940. this.uiDialog.resizable(value ? 'enable' : 'disable');
  941. break;
  942. case "title":
  943. $(".ui-dialog-title", this.uiDialogTitlebar).text(value);
  944. break;
  945. case "width":
  946. this.uiDialog.width(value);
  947. break;
  948. }
  949. this.options[key] = value;
  950. },
  951. position: function(pos) {
  952. var wnd = $(window), doc = $(document), minTop = top = doc.scrollTop(), left = doc.scrollLeft();
  953. if ($.inArray(pos, ['center','top','right','bottom','left']) >= 0) {
  954. pos = [pos == 'right' || pos == 'left' ? pos : 'center', pos == 'top' || pos == 'bottom' ? pos : 'middle'];
  955. }
  956. if (pos.constructor != Array) {
  957. pos == ['center', 'middle']
  958. }
  959. if (pos[0].constructor == Number) {
  960. left += pos[0];
  961. } else {
  962. switch (pos[0]) {
  963. case 'left':
  964. left += 0;
  965. break;
  966. case 'right':
  967. left += (wnd.width()) - (this.uiDialog.width());
  968. break;
  969. case 'center':
  970. default:
  971. left += (wnd.width() / 2) - (this.uiDialog.width() / 2);
  972. }
  973. }
  974. if (pos[1].constructor == Number) {
  975. top += pos[1];
  976. } else {
  977. switch (pos[1]) {
  978. case 'top':
  979. top += 0;
  980. break;
  981. case 'bottom':
  982. top += (wnd.height()) - (this.uiDialog.height());
  983. break;
  984. case 'middle':
  985. default:
  986. top += (wnd.height() / 2) - (this.uiDialog.height() / 2);
  987. }
  988. }
  989. top = top < minTop ? minTop : top;
  990. this.uiDialog.css({top: top, left: left});
  991. },
  992. open: function() {
  993. this.overlay = this.options.modal ? new $.ui.dialog.overlay(self) : null;
  994. this.uiDialog.appendTo('body');
  995. this.position(this.options.position);
  996. this.uiDialog.show();
  997. this.moveToTop();
  998. this.activate();
  999. // CALLBACK: open
  1000. var openEV = null;
  1001. var openUI = {
  1002. options: this.options
  1003. };
  1004. this.uiDialogTitlebarClose.focus();
  1005. $(this.element).triggerHandler("dialogopen", [openEV, openUI], this.options.open);
  1006. },
  1007. activate: function() {
  1008. // Move modeless dialogs to the top when they're activated. Even
  1009. // if there is a modal dialog in the window, the modeless dialog
  1010. // should be on top because it must have been opened after the modal
  1011. // dialog. Modal dialogs don't get moved to the top because that
  1012. // would make any modeless dialogs that it spawned unusable until
  1013. // the modal dialog is closed.
  1014. !this.options.modal && this.moveToTop();
  1015. },
  1016. moveToTop: function() {
  1017. var maxZ = this.options.zIndex, options = this.options;
  1018. $('.ui-dialog:visible').each(function() {
  1019. maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10) || options.zIndex);
  1020. });
  1021. this.overlay && this.overlay.$el.css('z-index', ++maxZ);
  1022. this.uiDialog.css('z-index', ++maxZ);
  1023. },
  1024. close: function() {
  1025. this.overlay && this.overlay.destroy();
  1026. this.uiDialog.hide();
  1027. // CALLBACK: close
  1028. var closeEV = null;
  1029. var closeUI = {
  1030. options: this.options
  1031. };
  1032. $(this.element).triggerHandler("dialogclose", [closeEV, closeUI], this.options.close);
  1033. $.ui.dialog.overlay.resize();
  1034. },
  1035. destroy: function() {
  1036. this.overlay && this.overlay.destroy();
  1037. this.uiDialog.hide();
  1038. $(this.element).unbind('.dialog').removeClass('ui-dialog-content').hide().appendTo('body');
  1039. this.uiDialog.remove();
  1040. $.removeData(this.element, "dialog");
  1041. }
  1042. });
  1043. $.extend($.ui.dialog, {
  1044. defaults: {
  1045. autoOpen: true,
  1046. bgiframe: false,
  1047. buttons: {},
  1048. closeOnEscape: true,
  1049. draggable: true,
  1050. height: 200,
  1051. minHeight: 100,
  1052. minWidth: 150,
  1053. modal: false,
  1054. overlay: {},
  1055. position: 'center',
  1056. resizable: true,
  1057. width: 300,
  1058. zIndex: 1000
  1059. },
  1060. overlay: function(dialog) {
  1061. this.$el = $.ui.dialog.overlay.create(dialog);
  1062. }
  1063. });
  1064. $.extend($.ui.dialog.overlay, {
  1065. instances: [],
  1066. events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
  1067. function(e) { return e + '.dialog-overlay'; }).join(' '),
  1068. create: function(dialog) {
  1069. if (this.instances.length === 0) {
  1070. // prevent use of anchors and inputs
  1071. $('a, :input').bind(this.events, function() {
  1072. // allow use of the element if inside a dialog and
  1073. // - there are no modal dialogs
  1074. // - there are modal dialogs, but we are in front of the topmost modal
  1075. var allow = false;
  1076. var $dialog = $(this).parents('.ui-dialog');
  1077. if ($dialog.length) {
  1078. var $overlays = $('.ui-dialog-overlay');
  1079. if ($overlays.length) {
  1080. var maxZ = parseInt($overlays.css('z-index'), 10);
  1081. $overlays.each(function() {
  1082. maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10));
  1083. });
  1084. allow = parseInt($dialog.css('z-index'), 10) > maxZ;
  1085. } else {
  1086. allow = true;
  1087. }
  1088. }
  1089. return allow;
  1090. });
  1091. // allow closing by pressing the escape key
  1092. $(document).bind('keydown.dialog-overlay', function(e) {
  1093. var ESC = 27;
  1094. e.keyCode && e.keyCode == ESC && dialog.close(); 
  1095. });
  1096. // handle window resize
  1097. $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
  1098. }
  1099. var $el = $('<div/>').appendTo(document.body)
  1100. .addClass('ui-dialog-overlay').css($.extend({
  1101. borderWidth: 0, margin: 0, padding: 0,
  1102. position: 'absolute', top: 0, left: 0,
  1103. width: this.width(),
  1104. height: this.height()
  1105. }, dialog.options.overlay));
  1106. dialog.options.bgiframe && $.fn.bgiframe && $el.bgiframe();
  1107. this.instances.push($el);
  1108. return $el;
  1109. },
  1110. destroy: function($el) {
  1111. this.instances.splice($.inArray(this.instances, $el), 1);
  1112. if (this.instances.length === 0) {
  1113. $('a, :input').add([document, window]).unbind('.dialog-overlay');
  1114. }
  1115. $el.remove();
  1116. },
  1117. height: function() {
  1118. if ($.browser.msie && $.browser.version < 7) {
  1119. var scrollHeight = Math.max(
  1120. document.documentElement.scrollHeight,
  1121. document.body.scrollHeight
  1122. );
  1123. var offsetHeight = Math.max(
  1124. document.documentElement.offsetHeight,
  1125. document.body.offsetHeight
  1126. );
  1127. if (scrollHeight < offsetHeight) {
  1128. return $(window).height() + 'px';
  1129. } else {
  1130. return scrollHeight + 'px';
  1131. }
  1132. } else {
  1133. return $(document).height() + 'px';
  1134. }
  1135. },
  1136. width: function() {
  1137. if ($.browser.msie && $.browser.version < 7) {
  1138. var scrollWidth = Math.max(
  1139. document.documentElement.scrollWidth,
  1140. document.body.scrollWidth
  1141. );
  1142. var offsetWidth = Math.max(
  1143. document.documentElement.offsetWidth,
  1144. document.body.offsetWidth
  1145. );
  1146. if (scrollWidth < offsetWidth) {
  1147. return $(window).width() + 'px';
  1148. } else {
  1149. return scrollWidth + 'px';
  1150. }
  1151. } else {
  1152. return $(document).width() + 'px';
  1153. }
  1154. },
  1155. resize: function() {
  1156. /* If the dialog is draggable and the user drags it past the
  1157.  * right edge of the window, the document becomes wider so we
  1158.  * need to stretch the overlay. If the user then drags the
  1159.  * dialog back to the left, the document will become narrower,
  1160.  * so we need to shrink the overlay to the appropriate size.
  1161.  * This is handled by shrinking the overlay before setting it
  1162.  * to the full document size.
  1163.  */
  1164. var $overlays = $([]);
  1165. $.each($.ui.dialog.overlay.instances, function() {
  1166. $overlays = $overlays.add(this);
  1167. });
  1168. $overlays.css({
  1169. width: 0,
  1170. height: 0
  1171. }).css({
  1172. width: $.ui.dialog.overlay.width(),
  1173. height: $.ui.dialog.overlay.height()
  1174. });
  1175. }
  1176. });
  1177. $.extend($.ui.dialog.overlay.prototype, {
  1178. destroy: function() {
  1179. $.ui.dialog.overlay.destroy(this.$el);
  1180. }
  1181. });
  1182. })(jQuery);
  1183. /*
  1184.  * jQuery UI Slider
  1185.  *
  1186.  * Copyright (c) 2008 Paul Bakaus
  1187.  * Dual licensed under the MIT (MIT-LICENSE.txt)
  1188.  * and GPL (GPL-LICENSE.txt) licenses.
  1189.  * 
  1190.  * http://docs.jquery.com/UI/Slider
  1191.  *
  1192.  * Depends:
  1193.  * ui.core.js
  1194.  *
  1195.  * Revision: $Id: ui.slider.js 5437 2008-05-04 20:25:49Z joern.zaefferer $
  1196.  */
  1197. ;(function($) {
  1198. $.widget("ui.slider", {
  1199. init: function() {
  1200. var self = this;
  1201. this.element.addClass("ui-slider");
  1202. this.initBoundaries();
  1203. // Initialize mouse and key events for interaction
  1204. this.handle = $(this.options.handle, this.element);
  1205. if (!this.handle.length) {
  1206. self.handle = self.generated = $(self.options.handles || [0]).map(function() {
  1207. var handle = $("<div/>").addClass("ui-slider-handle").appendTo(self.element);
  1208. if (this.id)
  1209. handle.attr("id", this.id);
  1210. return handle[0];
  1211. });
  1212. }
  1213. $(this.handle)
  1214. .mouse({
  1215. executor: this,
  1216. delay: this.options.delay,
  1217. distance: this.options.distance,
  1218. dragPrevention: this.options.prevention ? this.options.prevention.toLowerCase().split(',') : ['input','textarea','button','select','option'],
  1219. start: this.start,
  1220. stop: this.stop,
  1221. drag: this.drag,
  1222. condition: function(e, handle) {
  1223. if(!this.disabled) {
  1224. if(this.currentHandle) this.blur(this.currentHandle);
  1225. this.focus(handle,1);
  1226. return !this.disabled;
  1227. }
  1228. }
  1229. })
  1230. .wrap('<a href="javascript:void(0)" style="cursor:default;"></a>')
  1231. .parent()
  1232. .bind('focus', function(e) { self.focus(this.firstChild); })
  1233. .bind('blur', function(e) { self.blur(this.firstChild); })
  1234. .bind('keydown', function(e) {
  1235. if(/(37|38|39|40)/.test(e.keyCode)) {
  1236. self.moveTo({
  1237. x: /(37|39)/.test(e.keyCode) ? (e.keyCode == 37 ? '-' : '+') + '=' + self.oneStep(1) : null,
  1238. y: /(38|40)/.test(e.keyCode) ? (e.keyCode == 38 ? '-' : '+') + '=' + self.oneStep(2) : null
  1239. }, this.firstChild);
  1240. }
  1241. })
  1242. ;
  1243. // Prepare dynamic properties for later use
  1244. this.actualSize = { width: this.element.outerWidth() , height: this.element.outerHeight() };
  1245. // Bind the click to the slider itself
  1246. this.element.bind('mousedown.slider', function(e) {
  1247. self.click.apply(self, [e]);
  1248. self.currentHandle.data("mouse").trigger(e);
  1249. self.firstValue = self.firstValue + 1; //This is for always triggering the change event
  1250. });
  1251. // Move the first handle to the startValue
  1252. $.each(this.options.handles || [], function(index, handle) {
  1253. self.moveTo(handle.start, index, true);
  1254. });
  1255. if (!isNaN(this.options.startValue))
  1256. this.moveTo(this.options.startValue, 0, true);
  1257. this.previousHandle = $(this.handle[0]); //set the previous handle to the first to allow clicking before selecting the handle
  1258. if(this.handle.length == 2 && this.options.range) this.createRange();
  1259. },
  1260. setData: function(event, key, value) {
  1261. this.options[key] = value;
  1262. if (/min|max|steps/.test(key)) {
  1263. this.initBoundaries();
  1264. }
  1265. },
  1266. initBoundaries: function() {
  1267. var element = this.element[0];
  1268. var o = this.options;
  1269. $.extend(o, {
  1270. axis: o.axis || (element.offsetWidth < element.offsetHeight ? 'vertical' : 'horizontal'),
  1271. max: !isNaN(parseInt(o.max,10)) ? { x: parseInt(o.max, 10), y: parseInt(o.max, 10) } : ({ x: o.max && o.max.x || 100, y: o.max && o.max.y || 100 }),
  1272. min: !isNaN(parseInt(o.min,10)) ? { x: parseInt(o.min, 10), y: parseInt(o.min, 10) } : ({ x: o.min && o.min.x || 0, y: o.min && o.min.y || 0 })
  1273. });
  1274. //Prepare the real maxValue
  1275. o.realMax = {
  1276. x: o.max.x - o.min.x,
  1277. y: o.max.y - o.min.y
  1278. };
  1279. //Calculate stepping based on steps
  1280. o.stepping = {
  1281. x: o.stepping && o.stepping.x || parseInt(o.stepping, 10) || (o.steps ? o.realMax.x/(o.steps.x || parseInt(o.steps, 10) || o.realMax.x) : 0),
  1282. y: o.stepping && o.stepping.y || parseInt(o.stepping, 10) || (o.steps ? o.realMax.y/(o.steps.y || parseInt(o.steps, 10) || o.realMax.y) : 0)
  1283. };
  1284. },
  1285. plugins: {},
  1286. createRange: function() {
  1287. this.rangeElement = $('<div></div>')
  1288. .addClass('ui-slider-range')
  1289. .css({ position: 'absolute' })
  1290. .appendTo(this.element);
  1291. this.updateRange();
  1292. },
  1293. updateRange: function() {
  1294. var prop = this.options.axis == "vertical" ? "top" : "left";
  1295. var size = this.options.axis == "vertical" ? "height" : "width";
  1296. this.rangeElement.css(prop, parseInt($(this.handle[0]).css(prop),10) + this.handleSize(0, this.options.axis == "vertical" ? 2 : 1)/2);
  1297. this.rangeElement.css(size, parseInt($(this.handle[1]).css(prop),10) - parseInt($(this.handle[0]).css(prop),10));
  1298. },
  1299. getRange: function() {
  1300. return this.rangeElement ? this.convertValue(parseInt(this.rangeElement.css(this.options.axis == "vertical" ? "height" : "width"),10)) : null;
  1301. },
  1302. ui: function(e) {
  1303. return {
  1304. instance: this,
  1305. options: this.options,
  1306. handle: this.currentHandle,
  1307. value: this.options.axis != "both" || !this.options.axis ? Math.round(this.value(null,this.options.axis == "vertical" ? 2 : 1)) : {
  1308. x: Math.round(this.value(null,1)),
  1309. y: Math.round(this.value(null,2))
  1310. },
  1311. range: this.getRange()
  1312. };
  1313. },
  1314. propagate: function(n,e) {
  1315. $.ui.plugin.call(this, n, [e, this.ui()]);
  1316. this.element.triggerHandler(n == "slide" ? n : "slide"+n, [e, this.ui()], this.options[n]);
  1317. },
  1318. destroy: function() {
  1319. this.element
  1320. .removeClass("ui-slider ui-slider-disabled")
  1321. .removeData("slider")
  1322. .unbind(".slider");
  1323. this.handle.mouse("destroy");
  1324. this.generated && this.generated.remove();
  1325. },
  1326. enable: function() {
  1327. this.element.removeClass("ui-slider-disabled");
  1328. this.disabled = false;
  1329. },
  1330. disable: function() {
  1331. this.element.addClass("ui-slider-disabled");
  1332. this.disabled = true;
  1333. },
  1334. focus: function(handle,hard) {
  1335. this.currentHandle = $(handle).addClass('ui-slider-handle-active');
  1336. if (hard)
  1337. this.currentHandle.parent()[0].focus();
  1338. },
  1339. blur: function(handle) {
  1340. $(handle).removeClass('ui-slider-handle-active');
  1341. if(this.currentHandle && this.currentHandle[0] == handle) { this.previousHandle = this.currentHandle; this.currentHandle = null; };
  1342. },
  1343. value: function(handle, axis) {
  1344. if(this.handle.length == 1) this.currentHandle = this.handle;
  1345. if(!axis) axis = this.options.axis == "vertical" ? 2 : 1;
  1346. var value = ((parseInt($(handle != undefined && handle !== null ? this.handle[handle] || handle : this.currentHandle).css(axis == 1 ? "left" : "top"),10) / (this.actualSize[axis == 1 ? "width" : "height"] - this.handleSize(handle,axis))) * this.options.realMax[axis == 1 ? "x" : "y"]) + this.options.min[axis == 1 ? "x" : "y"];
  1347. var o = this.options;
  1348. if (o.stepping[axis == 1 ? "x" : "y"]) {
  1349. value = Math.round(value / o.stepping[axis == 1 ? "x" : "y"]) * o.stepping[axis == 1 ? "x" : "y"];
  1350. }
  1351. return value;
  1352. },
  1353. convertValue: function(value,axis) {
  1354. if(!axis) axis = this.options.axis == "vertical" ? 2 : 1;
  1355. return this.options.min[axis == 1 ? "x" : "y"] + (value / (this.actualSize[axis == 1 ? "width" : "height"] - this.handleSize(null,axis))) * this.options.realMax[axis == 1 ? "x" : "y"];
  1356. },
  1357. translateValue: function(value,axis) {
  1358. if(!axis) axis = this.options.axis == "vertical" ? 2 : 1;
  1359. return ((value - this.options.min[axis == 1 ? "x" : "y"]) / this.options.realMax[axis == 1 ? "x" : "y"]) * (this.actualSize[axis == 1 ? "width" : "height"] - this.handleSize(null,axis));
  1360. },
  1361. handleSize: function(handle,axis) {
  1362. if(!axis) axis = this.options.axis == "vertical" ? 2 : 1;
  1363. return $(handle != undefined && handle !== null ? this.handle[handle] : this.currentHandle)[0][axis == 1 ? "offsetWidth" : "offsetHeight"];
  1364. },
  1365. click: function(e) {
  1366. // This method is only used if:
  1367. // - The user didn't click a handle
  1368. // - The Slider is not disabled
  1369. // - There is a current, or previous selected handle (otherwise we wouldn't know which one to move)
  1370. var pointer = [e.pageX,e.pageY];
  1371. var clickedHandle = false;
  1372. this.handle.each(function() {
  1373. if(this == e.target)
  1374. clickedHandle = true;
  1375. });
  1376. if (clickedHandle || this.disabled || !(this.currentHandle || this.previousHandle))
  1377. return;
  1378. // If a previous handle was focussed, focus it again
  1379. if (!this.currentHandle && this.previousHandle)
  1380. this.focus(this.previousHandle, true);
  1381. // Move focussed handle to the clicked position
  1382. this.offset = this.element.offset();
  1383. // propagate only for distance > 0, otherwise propagation is done my drag
  1384. this.moveTo({
  1385. y: this.convertValue(e.pageY - this.offset.top - this.currentHandle.outerHeight()/2),
  1386. x: this.convertValue(e.pageX - this.offset.left - this.currentHandle.outerWidth()/2)
  1387. }, null, !this.options.distance);
  1388. },
  1389. start: function(e, handle) {
  1390. var o = this.options;
  1391. // This is a especially ugly fix for strange blur events happening on mousemove events
  1392. if (!this.currentHandle)
  1393. this.focus(this.previousHandle, true); 
  1394. this.offset = this.element.offset();
  1395. this.handleOffset = this.currentHandle.offset();
  1396. this.clickOffset = { top: e.pageY - this.handleOffset.top, left: e.pageX - this.handleOffset.left };
  1397. this.firstValue = this.value();
  1398. this.propagate('start', e);
  1399. return false;
  1400. },
  1401. stop: function(e) {
  1402. this.propagate('stop', e);
  1403. if (this.firstValue != this.value())
  1404. this.propagate('change', e);
  1405. this.focus(this.currentHandle, true); //This is a especially ugly fix for strange blur events happening on mousemove events
  1406. return false;
  1407. },
  1408. oneStep: function(axis) {
  1409. if(!axis) axis = this.options.axis == "vertical" ? 2 : 1;
  1410. return this.options.stepping[axis == 1 ? "x" : "y"] ? this.options.stepping[axis == 1 ? "x" : "y"] : (this.options.realMax[axis == 1 ? "x" : "y"] / this.actualSize[axis == 1 ? "width" : "height"]) * 5;
  1411. },
  1412. translateRange: function(value,axis) {
  1413. if (this.rangeElement) {
  1414. if (this.currentHandle[0] == this.handle[0] && value >= this.translateValue(this.value(1),axis))
  1415. value = this.translateValue(this.value(1,axis) - this.oneStep(axis), axis);
  1416. if (this.currentHandle[0] == this.handle[1] && value <= this.translateValue(this.value(0),axis))
  1417. value = this.translateValue(this.value(0,axis) + this.oneStep(axis));
  1418. }
  1419. if (this.options.handles) {
  1420. var handle = this.options.handles[this.handleIndex()];
  1421. if (value < this.translateValue(handle.min,axis)) {
  1422. value = this.translateValue(handle.min,axis);
  1423. } else if (value > this.translateValue(handle.max,axis)) {
  1424. value = this.translateValue(handle.max,axis);
  1425. }
  1426. }
  1427. return value;
  1428. },
  1429. handleIndex: function() {
  1430. return this.handle.index(this.currentHandle[0])
  1431. },
  1432. translateLimits: function(value,axis) {
  1433. if(!axis) axis = this.options.axis == "vertical" ? 2 : 1;
  1434. if (value >= this.actualSize[axis == 1 ? "width" : "height"] - this.handleSize(null,axis))
  1435. value = this.actualSize[axis == 1 ? "width" : "height"] - this.handleSize(null,axis);
  1436. if (value <= 0)
  1437. value = 0;
  1438. return value;
  1439. },
  1440. drag: function(e, handle) {
  1441. var o = this.options;
  1442. var position = { top: e.pageY - this.offset.top - this.clickOffset.top, left: e.pageX - this.offset.left - this.clickOffset.left};
  1443. if(!this.currentHandle) this.focus(this.previousHandle, true); //This is a especially ugly fix for strange blur events happening on mousemove events
  1444. position.left = this.translateLimits(position.left,1);
  1445. position.top = this.translateLimits(position.top,2);
  1446. if (o.stepping.x) {
  1447. var value = this.convertValue(position.left,1);
  1448. value = Math.round(value / o.stepping.x) * o.stepping.x;
  1449. position.left = this.translateValue(value, 1);
  1450. }
  1451. if (o.stepping.y) {
  1452. var value = this.convertValue(position.top,2);
  1453. value = Math.round(value / o.stepping.y) * o.stepping.y;
  1454. position.top = this.translateValue(value, 2);
  1455. }
  1456. position.left = this.translateRange(position.left, 1);
  1457. position.top = this.translateRange(position.top, 2);
  1458. if(o.axis != "vertical") this.currentHandle.css({ left: position.left });
  1459. if(o.axis != "horizontal") this.currentHandle.css({ top: position.top });
  1460. if (this.rangeElement)
  1461. this.updateRange();
  1462. this.propagate('slide', e);
  1463. return false;
  1464. },
  1465. moveTo: function(value, handle, noPropagation) {
  1466. var o = this.options;
  1467. if (handle == undefined && !this.currentHandle && this.handle.length != 1)
  1468. return false; //If no handle has been passed, no current handle is available and we have multiple handles, return false
  1469. if (handle == undefined && !this.currentHandle)
  1470. handle = 0; //If only one handle is available, use it
  1471. if (handle != undefined)
  1472. this.currentHandle = this.previousHandle = $(this.handle[handle] || handle);
  1473. if(value.x !== undefined && value.y !== undefined) {
  1474. var x = value.x;
  1475. var y = value.y;
  1476. } else {
  1477. var x = value, y = value;
  1478. }
  1479. if(x && x.constructor != Number) {
  1480. var me = /^-=/.test(x), pe = /^+=/.test(x);
  1481. if (me) {
  1482. x = this.value(null,1) - parseInt(x.replace('-=', ''), 10);
  1483. } else if (pe) {
  1484. x = this.value(null,1) + parseInt(x.replace('+=', ''), 10);
  1485. }
  1486. }
  1487. if(y && y.constructor != Number) {
  1488. var me = /^-=/.test(y), pe = /^+=/.test(y);
  1489. if (me) {
  1490. y = this.value(null,2) - parseInt(y.replace('-=', ''), 10);
  1491. } else if (pe) {
  1492. y = this.value(null,2) + parseInt(y.replace('+=', ''), 10);
  1493. }
  1494. }
  1495. if(o.axis != "vertical" && x) {
  1496. if(o.stepping.x) x = Math.round(x / o.stepping.x) * o.stepping.x;
  1497. x = this.translateValue(x, 1);
  1498. x = this.translateLimits(x, 1);
  1499. x = this.translateRange(x, 1);
  1500. this.currentHandle.css({ left: x });
  1501. }
  1502. if(o.axis != "horizontal" && y) {
  1503. if(o.stepping.y) y = Math.round(y / o.stepping.y) * o.stepping.y;
  1504. y = this.translateValue(y, 2);
  1505. y = this.translateLimits(y, 2);
  1506. y = this.translateRange(y, 2);
  1507. this.currentHandle.css({ top: y });
  1508. }
  1509. if (this.rangeElement)
  1510. this.updateRange();
  1511. if (!noPropagation) {
  1512. this.propagate('start', null);
  1513. this.propagate('stop', null);
  1514. this.propagate('change', null);
  1515. this.propagate("slide", null);
  1516. }
  1517. }
  1518. });
  1519. $.ui.slider.getter = "value";
  1520. $.ui.slider.defaults = {
  1521. handle: ".ui-slider-handle",
  1522. distance: 1
  1523. };
  1524. })(jQuery);
  1525. /*
  1526.  * jQuery UI Tabs
  1527.  *
  1528.  * Copyright (c) 2007, 2008 Klaus Hartl (stilbuero.de)
  1529.  * Dual licensed under the MIT (MIT-LICENSE.txt)
  1530.  * and GPL (GPL-LICENSE.txt) licenses.
  1531.  *
  1532.  * http://docs.jquery.com/UI/Tabs
  1533.  *
  1534.  * Depends:
  1535.  * ui.core.js
  1536.  *
  1537.  * Revision: $Id: ui.tabs.js 5439 2008-05-04 23:46:46Z klaus.hartl $
  1538.  */
  1539. ;(function($) {
  1540. $.widget("ui.tabs", {
  1541. init: function() {
  1542. var self = this;
  1543. this.options.event += '.tabs'; // namespace event
  1544. $(this.element).bind('setData.tabs', function(event, key, value) {
  1545. if ((/^selected/).test(key))
  1546. self.select(value);
  1547. else {
  1548. self.options[key] = value;
  1549. self.tabify();
  1550. }
  1551. }).bind('getData.tabs', function(event, key) {
  1552. return self.options[key];
  1553. });
  1554. // create tabs
  1555. this.tabify(true);
  1556. },
  1557. length: function() {
  1558. return this.$tabs.length;
  1559. },
  1560. tabId: function(a) {
  1561. return a.title && a.title.replace(/s/g, '_').replace(/[^A-Za-z0-9-_:.]/g, '')
  1562. || this.options.idPrefix + $.data(a);
  1563. },
  1564. ui: function(tab, panel) {
  1565. return {
  1566. instance: this,
  1567. options: this.options,
  1568. tab: tab,
  1569. panel: panel
  1570. };
  1571. },
  1572. tabify: function(init) {
  1573. this.$lis = $('li:has(a[href])', this.element);
  1574. this.$tabs = this.$lis.map(function() { return $('a', this)[0]; });
  1575. this.$panels = $([]);
  1576. var self = this, o = this.options;
  1577. this.$tabs.each(function(i, a) {
  1578. // inline tab
  1579. if (a.hash && a.hash.replace('#', '')) // Safari 2 reports '#' for an empty hash
  1580. self.$panels = self.$panels.add(a.hash);
  1581. // remote tab
  1582. else if ($(a).attr('href') != '#') { // prevent loading the page itself if href is just "#"
  1583. $.data(a, 'href.tabs', a.href); // required for restore on destroy
  1584. $.data(a, 'load.tabs', a.href); // mutable
  1585. var id = self.tabId(a);
  1586. a.href = '#' + id;
  1587. var $panel = $('#' + id);
  1588. if (!$panel.length) {
  1589. $panel = $(o.panelTemplate).attr('id', id).addClass(o.panelClass)
  1590. .insertAfter( self.$panels[i - 1] || self.element );
  1591. $panel.data('destroy.tabs', true);
  1592. }
  1593. self.$panels = self.$panels.add( $panel );
  1594. }
  1595. // invalid tab href
  1596. else
  1597. o.disabled.push(i + 1);
  1598. });
  1599. if (init) {
  1600. // attach necessary classes for styling if not present
  1601. $(this.element).hasClass(o.navClass) || $(this.element).addClass(o.navClass);
  1602. this.$panels.each(function() {
  1603. var $this = $(this);
  1604. $this.hasClass(o.panelClass) || $this.addClass(o.panelClass);
  1605. });
  1606. // Try to retrieve selected tab:
  1607. // 1. from fragment identifier in url if present
  1608. // 2. from cookie
  1609. // 3. from selected class attribute on <li>
  1610. // 4. otherwise use given "selected" option
  1611. // 5. check if tab is disabled
  1612. this.$tabs.each(function(i, a) {
  1613. if (location.hash) {
  1614. if (a.hash == location.hash) {
  1615. o.selected = i;
  1616. // prevent page scroll to fragment
  1617. //if (($.browser.msie || $.browser.opera) && !o.remote) {
  1618. if ($.browser.msie || $.browser.opera) {
  1619. var $toShow = $(location.hash), toShowId = $toShow.attr('id');
  1620. $toShow.attr('id', '');
  1621. setTimeout(function() {
  1622. $toShow.attr('id', toShowId); // restore id
  1623. }, 500);
  1624. }
  1625. scrollTo(0, 0);
  1626. return false; // break
  1627. }
  1628. } else if (o.cookie) {
  1629. var index = parseInt($.cookie('ui-tabs' + $.data(self.element)),10);
  1630. if (index && self.$tabs[index]) {
  1631. o.selected = index;
  1632. return false; // break
  1633. }
  1634. } else if ( self.$lis.eq(i).hasClass(o.selectedClass) ) {
  1635. o.selected = i;
  1636. return false; // break
  1637. }
  1638. });
  1639. // highlight selected tab
  1640. this.$panels.addClass(o.hideClass);
  1641. this.$lis.removeClass(o.selectedClass);
  1642. if (o.selected !== null) {
  1643. this.$panels.eq(o.selected).show().removeClass(o.hideClass); // use show and remove class to show in any case no matter how it has been hidden before
  1644. this.$lis.eq(o.selected).addClass(o.selectedClass);
  1645. // seems to be expected behavior that the show callback is fired
  1646. var onShow = function() {
  1647.     $(self.element).triggerHandler('tabsshow',
  1648.         [self.ui(self.$tabs[o.selected], self.$panels[o.selected])], o.show);
  1649. }; 
  1650.                     // load if remote tab
  1651.      if ($.data(this.$tabs[o.selected], 'load.tabs'))
  1652.      this.load(o.selected, onShow);
  1653.      // just trigger show event
  1654.      else
  1655.          onShow();
  1656.     
  1657. }
  1658. // Take disabling tabs via class attribute from HTML
  1659. // into account and update option properly...
  1660. o.disabled = $.unique(o.disabled.concat(
  1661. $.map(this.$lis.filter('.' + o.disabledClass),
  1662. function(n, i) { return self.$lis.index(n); } )
  1663. )).sort();
  1664. // clean up to avoid memory leaks in certain versions of IE 6
  1665. $(window).bind('unload', function() {
  1666. self.$tabs.unbind('.tabs');
  1667. self.$lis = self.$tabs = self.$panels = null;
  1668. });
  1669. }
  1670. // disable tabs
  1671. for (var i = 0, li; li = this.$lis[i]; i++)
  1672. $(li)[$.inArray(i, o.disabled) != -1 && !$(li).hasClass(o.selectedClass) ? 'addClass' : 'removeClass'](o.disabledClass);
  1673. // reset cache if switching from cached to not cached
  1674. if (o.cache === false)
  1675. this.$tabs.removeData('cache.tabs');
  1676. // set up animations
  1677. var hideFx, showFx, baseFx = { 'min-width': 0, duration: 1 }, baseDuration = 'normal';
  1678. if (o.fx && o.fx.constructor == Array)
  1679. hideFx = o.fx[0] || baseFx, showFx = o.fx[1] || baseFx;
  1680. else
  1681. hideFx = showFx = o.fx || baseFx;
  1682. // reset some styles to maintain print style sheets etc.
  1683. var resetCSS = { display: '', overflow: '', height: '' };
  1684. if (!$.browser.msie) // not in IE to prevent ClearType font issue
  1685. resetCSS.opacity = '';
  1686. // Hide a tab, animation prevents browser scrolling to fragment,
  1687. // $show is optional.
  1688. function hideTab(clicked, $hide, $show) {
  1689. $hide.animate(hideFx, hideFx.duration || baseDuration, function() { //
  1690. $hide.addClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
  1691. if ($.browser.msie && hideFx.opacity)
  1692. $hide[0].style.filter = '';
  1693. if ($show)
  1694. showTab(clicked, $show, $hide);
  1695. });
  1696. }
  1697. // Show a tab, animation prevents browser scrolling to fragment,
  1698. // $hide is optional.
  1699. function showTab(clicked, $show, $hide) {
  1700. if (showFx === baseFx)
  1701. $show.css('display', 'block'); // prevent occasionally occuring flicker in Firefox cause by gap between showing and hiding the tab panels
  1702. $show.animate(showFx, showFx.duration || baseDuration, function() {
  1703. $show.removeClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
  1704. if ($.browser.msie && showFx.opacity)
  1705. $show[0].style.filter = '';
  1706. // callback
  1707. $(self.element).triggerHandler('tabsshow',
  1708.     [self.ui(clicked, $show[0])], o.show);
  1709. });
  1710. }
  1711. // switch a tab
  1712. function switchTab(clicked, $li, $hide, $show) {
  1713. /*if (o.bookmarkable && trueClick) { // add to history only if true click occured, not a triggered click
  1714. $.ajaxHistory.update(clicked.hash);
  1715. }*/
  1716. $li.addClass(o.selectedClass)
  1717. .siblings().removeClass(o.selectedClass);
  1718. hideTab(clicked, $hide, $show);
  1719. }
  1720. // attach tab event handler, unbind to avoid duplicates from former tabifying...
  1721. this.$tabs.unbind('.tabs').bind(o.event, function() {
  1722. //var trueClick = e.clientX; // add to history only if true click occured, not a triggered click
  1723. var $li = $(this).parents('li:eq(0)'),
  1724. $hide = self.$panels.filter(':visible'),
  1725. $show = $(this.hash);
  1726. // If tab is already selected and not unselectable or tab disabled or 
  1727. // or is already loading or click callback returns false stop here.
  1728. // Check if click handler returns false last so that it is not executed
  1729. // for a disabled or loading tab!
  1730. if (($li.hasClass(o.selectedClass) && !o.unselect)
  1731. || $li.hasClass(o.disabledClass) 
  1732. || $(this).hasClass(o.loadingClass)
  1733. || $(self.element).triggerHandler('tabsselect', [self.ui(this, $show[0])], o.select) === false
  1734. ) {
  1735. this.blur();
  1736. return false;
  1737. }
  1738. self.options.selected = self.$tabs.index(this);
  1739. // if tab may be closed
  1740. if (o.unselect) {
  1741. if ($li.hasClass(o.selectedClass)) {
  1742. self.options.selected = null;
  1743. $li.removeClass(o.selectedClass);
  1744. self.$panels.stop();
  1745. hideTab(this, $hide);
  1746. this.blur();
  1747. return false;
  1748. } else if (!$hide.length) {
  1749. self.$panels.stop();
  1750. var a = this;
  1751. self.load(self.$tabs.index(this), function() {
  1752. $li.addClass(o.selectedClass).addClass(o.unselectClass);
  1753. showTab(a, $show);
  1754. });
  1755. this.blur();
  1756. return false;
  1757. }
  1758. }
  1759. if (o.cookie)
  1760. $.cookie('ui-tabs' + $.data(self.element), self.options.selected, o.cookie);
  1761. // stop possibly running animations
  1762. self.$panels.stop();
  1763. // show new tab
  1764. if ($show.length) {
  1765. // prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled
  1766. /*if ($.browser.msie && o.bookmarkable) {
  1767. var showId = this.hash.replace('#', '');
  1768. $show.attr('id', '');
  1769. setTimeout(function() {
  1770. $show.attr('id', showId); // restore id
  1771. }, 0);
  1772. }*/
  1773. var a = this;
  1774. self.load(self.$tabs.index(this), $hide.length ? 
  1775. function() {
  1776. switchTab(a, $li, $hide, $show);
  1777. } :
  1778. function() {
  1779. $li.addClass(o.selectedClass);
  1780. showTab(a, $show);
  1781. }
  1782. );
  1783. // Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash
  1784. /*var scrollX = window.pageXOffset || document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft || 0;
  1785. var scrollY = window.pageYOffset || document.documentElement && document.documentElement.scrollTop || document.body.scrollTop || 0;
  1786. setTimeout(function() {
  1787. scrollTo(scrollX, scrollY);
  1788. }, 0);*/
  1789. } else
  1790. throw 'jQuery UI Tabs: Mismatching fragment identifier.';
  1791. // Prevent IE from keeping other link focussed when using the back button
  1792. // and remove dotted border from clicked link. This is controlled in modern
  1793. // browsers via CSS, also blur removes focus from address bar in Firefox
  1794. // which can become a usability and annoying problem with tabsRotate.
  1795. if ($.browser.msie)
  1796. this.blur();
  1797. //return o.bookmarkable && !!trueClick; // convert trueClick == undefined to Boolean required in IE
  1798. return false;
  1799. });
  1800. // disable click if event is configured to something else
  1801. if (!(/^click/).test(o.event))
  1802. this.$tabs.bind('click.tabs', function() { return false; });
  1803. },
  1804. add: function(url, label, index) {
  1805. if (index == undefined) 
  1806. index = this.$tabs.length; // append by default
  1807. var o = this.options;
  1808. var $li = $(o.tabTemplate.replace(/#{href}/, url).replace(/#{label}/, label));
  1809. $li.data('destroy.tabs', true);
  1810. var id = url.indexOf('#') == 0 ? url.replace('#', '') : this.tabId( $('a:first-child', $li)[0] );
  1811. // try to find an existing element before creating a new one
  1812. var $panel = $('#' + id);
  1813. if (!$panel.length) {
  1814. $panel = $(o.panelTemplate).attr('id', id)
  1815. .addClass(o.panelClass).addClass(o.hideClass);
  1816. $panel.data('destroy.tabs', true);
  1817. }
  1818. if (index >= this.$lis.length) {
  1819. $li.appendTo(this.element);
  1820. $panel.appendTo(this.element[0].parentNode);
  1821. } else {
  1822. $li.insertBefore(this.$lis[index]);
  1823. $panel.insertBefore(this.$panels[index]);
  1824. }
  1825. o.disabled = $.map(o.disabled,
  1826. function(n, i) { return n >= index ? ++n : n });
  1827. this.tabify();
  1828. if (this.$tabs.length == 1) {
  1829. $li.addClass(o.selectedClass);
  1830. $panel.removeClass(o.hideClass);
  1831. var href = $.data(this.$tabs[0], 'load.tabs');
  1832. if (href)
  1833. this.load(index, href);
  1834. }
  1835. // callback
  1836. $(this.element).triggerHandler('tabsadd',
  1837. [this.ui(this.$tabs[index], this.$panels[index])], o.add
  1838. );
  1839. },
  1840. remove: function(index) {
  1841. var o = this.options, $li = this.$lis.eq(index).remove(),
  1842. $panel = this.$panels.eq(index).remove();
  1843. // If selected tab was removed focus tab to the right or
  1844. // in case the last tab was removed the tab to the left.
  1845. if ($li.hasClass(o.selectedClass) && this.$tabs.length > 1)
  1846. this.select(index + (index + 1 < this.$tabs.length ? 1 : -1));
  1847. o.disabled = $.map($.grep(o.disabled, function(n, i) { return n != index; }),
  1848. function(n, i) { return n >= index ? --n : n });
  1849. this.tabify();
  1850. // callback
  1851. $(this.element).triggerHandler('tabsremove',
  1852. [this.ui($li.find('a')[0], $panel[0])], o.remove
  1853. );
  1854. },
  1855. enable: function(index) {
  1856. var o = this.options;
  1857. if ($.inArray(index, o.disabled) == -1)
  1858. return;
  1859. var $li = this.$lis.eq(index).removeClass(o.disabledClass);
  1860. if ($.browser.safari) { // fix disappearing tab (that used opacity indicating disabling) after enabling in Safari 2...
  1861. $li.css('display', 'inline-block');
  1862. setTimeout(function() {
  1863. $li.css('display', 'block');
  1864. }, 0);
  1865. }
  1866. o.disabled = $.grep(o.disabled, function(n, i) { return n != index; });
  1867. // callback
  1868. $(this.element).triggerHandler('tabsenable',