dom/tests/mochitest/ajax/mochikit/MochiKit/Sortable.js

Thu, 15 Jan 2015 15:55:04 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:55:04 +0100
branch
TOR_BUG_9701
changeset 9
a63d609f5ebe
permissions
-rw-r--r--

Back out 97036ab72558 which inappropriately compared turds to third parties.

michael@0 1 /***
michael@0 2 Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
michael@0 3 Mochi-ized By Thomas Herve (_firstname_@nimail.org)
michael@0 4
michael@0 5 See scriptaculous.js for full license.
michael@0 6
michael@0 7 ***/
michael@0 8
michael@0 9 if (typeof(dojo) != 'undefined') {
michael@0 10 dojo.provide('MochiKit.Sortable');
michael@0 11 dojo.require('MochiKit.Base');
michael@0 12 dojo.require('MochiKit.DOM');
michael@0 13 dojo.require('MochiKit.Iter');
michael@0 14 }
michael@0 15
michael@0 16 if (typeof(JSAN) != 'undefined') {
michael@0 17 JSAN.use("MochiKit.Base", []);
michael@0 18 JSAN.use("MochiKit.DOM", []);
michael@0 19 JSAN.use("MochiKit.Iter", []);
michael@0 20 }
michael@0 21
michael@0 22 try {
michael@0 23 if (typeof(MochiKit.Base) == 'undefined' ||
michael@0 24 typeof(MochiKit.DOM) == 'undefined' ||
michael@0 25 typeof(MochiKit.Iter) == 'undefined') {
michael@0 26 throw "";
michael@0 27 }
michael@0 28 } catch (e) {
michael@0 29 throw "MochiKit.DragAndDrop depends on MochiKit.Base, MochiKit.DOM and MochiKit.Iter!";
michael@0 30 }
michael@0 31
michael@0 32 if (typeof(MochiKit.Sortable) == 'undefined') {
michael@0 33 MochiKit.Sortable = {};
michael@0 34 }
michael@0 35
michael@0 36 MochiKit.Sortable.NAME = 'MochiKit.Sortable';
michael@0 37 MochiKit.Sortable.VERSION = '1.4';
michael@0 38
michael@0 39 MochiKit.Sortable.__repr__ = function () {
michael@0 40 return '[' + this.NAME + ' ' + this.VERSION + ']';
michael@0 41 };
michael@0 42
michael@0 43 MochiKit.Sortable.toString = function () {
michael@0 44 return this.__repr__();
michael@0 45 };
michael@0 46
michael@0 47 MochiKit.Sortable.EXPORT = [
michael@0 48 ];
michael@0 49
michael@0 50 MochiKit.Sortable.EXPORT_OK = [
michael@0 51 ];
michael@0 52
michael@0 53 MochiKit.Base.update(MochiKit.Sortable, {
michael@0 54 /***
michael@0 55
michael@0 56 Manage sortables. Mainly use the create function to add a sortable.
michael@0 57
michael@0 58 ***/
michael@0 59 sortables: {},
michael@0 60
michael@0 61 _findRootElement: function (element) {
michael@0 62 while (element.tagName.toUpperCase() != "BODY") {
michael@0 63 if (element.id && MochiKit.Sortable.sortables[element.id]) {
michael@0 64 return element;
michael@0 65 }
michael@0 66 element = element.parentNode;
michael@0 67 }
michael@0 68 },
michael@0 69
michael@0 70 /** @id MochiKit.Sortable.options */
michael@0 71 options: function (element) {
michael@0 72 element = MochiKit.Sortable._findRootElement(MochiKit.DOM.getElement(element));
michael@0 73 if (!element) {
michael@0 74 return;
michael@0 75 }
michael@0 76 return MochiKit.Sortable.sortables[element.id];
michael@0 77 },
michael@0 78
michael@0 79 /** @id MochiKit.Sortable.destroy */
michael@0 80 destroy: function (element){
michael@0 81 var s = MochiKit.Sortable.options(element);
michael@0 82 var b = MochiKit.Base;
michael@0 83 var d = MochiKit.DragAndDrop;
michael@0 84
michael@0 85 if (s) {
michael@0 86 MochiKit.Signal.disconnect(s.startHandle);
michael@0 87 MochiKit.Signal.disconnect(s.endHandle);
michael@0 88 b.map(function (dr) {
michael@0 89 d.Droppables.remove(dr);
michael@0 90 }, s.droppables);
michael@0 91 b.map(function (dr) {
michael@0 92 dr.destroy();
michael@0 93 }, s.draggables);
michael@0 94
michael@0 95 delete MochiKit.Sortable.sortables[s.element.id];
michael@0 96 }
michael@0 97 },
michael@0 98
michael@0 99 /** @id MochiKit.Sortable.create */
michael@0 100 create: function (element, options) {
michael@0 101 element = MochiKit.DOM.getElement(element);
michael@0 102 var self = MochiKit.Sortable;
michael@0 103
michael@0 104 /** @id MochiKit.Sortable.options */
michael@0 105 options = MochiKit.Base.update({
michael@0 106
michael@0 107 /** @id MochiKit.Sortable.element */
michael@0 108 element: element,
michael@0 109
michael@0 110 /** @id MochiKit.Sortable.tag */
michael@0 111 tag: 'li', // assumes li children, override with tag: 'tagname'
michael@0 112
michael@0 113 /** @id MochiKit.Sortable.dropOnEmpty */
michael@0 114 dropOnEmpty: false,
michael@0 115
michael@0 116 /** @id MochiKit.Sortable.tree */
michael@0 117 tree: false,
michael@0 118
michael@0 119 /** @id MochiKit.Sortable.treeTag */
michael@0 120 treeTag: 'ul',
michael@0 121
michael@0 122 /** @id MochiKit.Sortable.overlap */
michael@0 123 overlap: 'vertical', // one of 'vertical', 'horizontal'
michael@0 124
michael@0 125 /** @id MochiKit.Sortable.constraint */
michael@0 126 constraint: 'vertical', // one of 'vertical', 'horizontal', false
michael@0 127 // also takes array of elements (or ids); or false
michael@0 128
michael@0 129 /** @id MochiKit.Sortable.containment */
michael@0 130 containment: [element],
michael@0 131
michael@0 132 /** @id MochiKit.Sortable.handle */
michael@0 133 handle: false, // or a CSS class
michael@0 134
michael@0 135 /** @id MochiKit.Sortable.only */
michael@0 136 only: false,
michael@0 137
michael@0 138 /** @id MochiKit.Sortable.hoverclass */
michael@0 139 hoverclass: null,
michael@0 140
michael@0 141 /** @id MochiKit.Sortable.ghosting */
michael@0 142 ghosting: false,
michael@0 143
michael@0 144 /** @id MochiKit.Sortable.scroll */
michael@0 145 scroll: false,
michael@0 146
michael@0 147 /** @id MochiKit.Sortable.scrollSensitivity */
michael@0 148 scrollSensitivity: 20,
michael@0 149
michael@0 150 /** @id MochiKit.Sortable.scrollSpeed */
michael@0 151 scrollSpeed: 15,
michael@0 152
michael@0 153 /** @id MochiKit.Sortable.format */
michael@0 154 format: /^[^_]*_(.*)$/,
michael@0 155
michael@0 156 /** @id MochiKit.Sortable.onChange */
michael@0 157 onChange: MochiKit.Base.noop,
michael@0 158
michael@0 159 /** @id MochiKit.Sortable.onUpdate */
michael@0 160 onUpdate: MochiKit.Base.noop,
michael@0 161
michael@0 162 /** @id MochiKit.Sortable.accept */
michael@0 163 accept: null
michael@0 164 }, options);
michael@0 165
michael@0 166 // clear any old sortable with same element
michael@0 167 self.destroy(element);
michael@0 168
michael@0 169 // build options for the draggables
michael@0 170 var options_for_draggable = {
michael@0 171 revert: true,
michael@0 172 ghosting: options.ghosting,
michael@0 173 scroll: options.scroll,
michael@0 174 scrollSensitivity: options.scrollSensitivity,
michael@0 175 scrollSpeed: options.scrollSpeed,
michael@0 176 constraint: options.constraint,
michael@0 177 handle: options.handle
michael@0 178 };
michael@0 179
michael@0 180 if (options.starteffect) {
michael@0 181 options_for_draggable.starteffect = options.starteffect;
michael@0 182 }
michael@0 183
michael@0 184 if (options.reverteffect) {
michael@0 185 options_for_draggable.reverteffect = options.reverteffect;
michael@0 186 } else if (options.ghosting) {
michael@0 187 options_for_draggable.reverteffect = function (innerelement) {
michael@0 188 innerelement.style.top = 0;
michael@0 189 innerelement.style.left = 0;
michael@0 190 };
michael@0 191 }
michael@0 192
michael@0 193 if (options.endeffect) {
michael@0 194 options_for_draggable.endeffect = options.endeffect;
michael@0 195 }
michael@0 196
michael@0 197 if (options.zindex) {
michael@0 198 options_for_draggable.zindex = options.zindex;
michael@0 199 }
michael@0 200
michael@0 201 // build options for the droppables
michael@0 202 var options_for_droppable = {
michael@0 203 overlap: options.overlap,
michael@0 204 containment: options.containment,
michael@0 205 hoverclass: options.hoverclass,
michael@0 206 onhover: self.onHover,
michael@0 207 tree: options.tree,
michael@0 208 accept: options.accept
michael@0 209 }
michael@0 210
michael@0 211 var options_for_tree = {
michael@0 212 onhover: self.onEmptyHover,
michael@0 213 overlap: options.overlap,
michael@0 214 containment: options.containment,
michael@0 215 hoverclass: options.hoverclass,
michael@0 216 accept: options.accept
michael@0 217 }
michael@0 218
michael@0 219 // fix for gecko engine
michael@0 220 MochiKit.DOM.removeEmptyTextNodes(element);
michael@0 221
michael@0 222 options.draggables = [];
michael@0 223 options.droppables = [];
michael@0 224
michael@0 225 // drop on empty handling
michael@0 226 if (options.dropOnEmpty || options.tree) {
michael@0 227 new MochiKit.DragAndDrop.Droppable(element, options_for_tree);
michael@0 228 options.droppables.push(element);
michael@0 229 }
michael@0 230 MochiKit.Base.map(function (e) {
michael@0 231 // handles are per-draggable
michael@0 232 var handle = options.handle ?
michael@0 233 MochiKit.DOM.getFirstElementByTagAndClassName(null,
michael@0 234 options.handle, e) : e;
michael@0 235 options.draggables.push(
michael@0 236 new MochiKit.DragAndDrop.Draggable(e,
michael@0 237 MochiKit.Base.update(options_for_draggable,
michael@0 238 {handle: handle})));
michael@0 239 new MochiKit.DragAndDrop.Droppable(e, options_for_droppable);
michael@0 240 if (options.tree) {
michael@0 241 e.treeNode = element;
michael@0 242 }
michael@0 243 options.droppables.push(e);
michael@0 244 }, (self.findElements(element, options) || []));
michael@0 245
michael@0 246 if (options.tree) {
michael@0 247 MochiKit.Base.map(function (e) {
michael@0 248 new MochiKit.DragAndDrop.Droppable(e, options_for_tree);
michael@0 249 e.treeNode = element;
michael@0 250 options.droppables.push(e);
michael@0 251 }, (self.findTreeElements(element, options) || []));
michael@0 252 }
michael@0 253
michael@0 254 // keep reference
michael@0 255 self.sortables[element.id] = options;
michael@0 256
michael@0 257 options.lastValue = self.serialize(element);
michael@0 258 options.startHandle = MochiKit.Signal.connect(MochiKit.DragAndDrop.Draggables, 'start',
michael@0 259 MochiKit.Base.partial(self.onStart, element));
michael@0 260 options.endHandle = MochiKit.Signal.connect(MochiKit.DragAndDrop.Draggables, 'end',
michael@0 261 MochiKit.Base.partial(self.onEnd, element));
michael@0 262 },
michael@0 263
michael@0 264 /** @id MochiKit.Sortable.onStart */
michael@0 265 onStart: function (element, draggable) {
michael@0 266 var self = MochiKit.Sortable;
michael@0 267 var options = self.options(element);
michael@0 268 options.lastValue = self.serialize(options.element);
michael@0 269 },
michael@0 270
michael@0 271 /** @id MochiKit.Sortable.onEnd */
michael@0 272 onEnd: function (element, draggable) {
michael@0 273 var self = MochiKit.Sortable;
michael@0 274 self.unmark();
michael@0 275 var options = self.options(element);
michael@0 276 if (options.lastValue != self.serialize(options.element)) {
michael@0 277 options.onUpdate(options.element);
michael@0 278 }
michael@0 279 },
michael@0 280
michael@0 281 // return all suitable-for-sortable elements in a guaranteed order
michael@0 282
michael@0 283 /** @id MochiKit.Sortable.findElements */
michael@0 284 findElements: function (element, options) {
michael@0 285 return MochiKit.Sortable.findChildren(
michael@0 286 element, options.only, options.tree ? true : false, options.tag);
michael@0 287 },
michael@0 288
michael@0 289 /** @id MochiKit.Sortable.findTreeElements */
michael@0 290 findTreeElements: function (element, options) {
michael@0 291 return MochiKit.Sortable.findChildren(
michael@0 292 element, options.only, options.tree ? true : false, options.treeTag);
michael@0 293 },
michael@0 294
michael@0 295 /** @id MochiKit.Sortable.findChildren */
michael@0 296 findChildren: function (element, only, recursive, tagName) {
michael@0 297 if (!element.hasChildNodes()) {
michael@0 298 return null;
michael@0 299 }
michael@0 300 tagName = tagName.toUpperCase();
michael@0 301 if (only) {
michael@0 302 only = MochiKit.Base.flattenArray([only]);
michael@0 303 }
michael@0 304 var elements = [];
michael@0 305 MochiKit.Base.map(function (e) {
michael@0 306 if (e.tagName &&
michael@0 307 e.tagName.toUpperCase() == tagName &&
michael@0 308 (!only ||
michael@0 309 MochiKit.Iter.some(only, function (c) {
michael@0 310 return MochiKit.DOM.hasElementClass(e, c);
michael@0 311 }))) {
michael@0 312 elements.push(e);
michael@0 313 }
michael@0 314 if (recursive) {
michael@0 315 var grandchildren = MochiKit.Sortable.findChildren(e, only, recursive, tagName);
michael@0 316 if (grandchildren && grandchildren.length > 0) {
michael@0 317 elements = elements.concat(grandchildren);
michael@0 318 }
michael@0 319 }
michael@0 320 }, element.childNodes);
michael@0 321 return elements;
michael@0 322 },
michael@0 323
michael@0 324 /** @id MochiKit.Sortable.onHover */
michael@0 325 onHover: function (element, dropon, overlap) {
michael@0 326 if (MochiKit.DOM.isParent(dropon, element)) {
michael@0 327 return;
michael@0 328 }
michael@0 329 var self = MochiKit.Sortable;
michael@0 330
michael@0 331 if (overlap > .33 && overlap < .66 && self.options(dropon).tree) {
michael@0 332 return;
michael@0 333 } else if (overlap > 0.5) {
michael@0 334 self.mark(dropon, 'before');
michael@0 335 if (dropon.previousSibling != element) {
michael@0 336 var oldParentNode = element.parentNode;
michael@0 337 element.style.visibility = 'hidden'; // fix gecko rendering
michael@0 338 dropon.parentNode.insertBefore(element, dropon);
michael@0 339 if (dropon.parentNode != oldParentNode) {
michael@0 340 self.options(oldParentNode).onChange(element);
michael@0 341 }
michael@0 342 self.options(dropon.parentNode).onChange(element);
michael@0 343 }
michael@0 344 } else {
michael@0 345 self.mark(dropon, 'after');
michael@0 346 var nextElement = dropon.nextSibling || null;
michael@0 347 if (nextElement != element) {
michael@0 348 var oldParentNode = element.parentNode;
michael@0 349 element.style.visibility = 'hidden'; // fix gecko rendering
michael@0 350 dropon.parentNode.insertBefore(element, nextElement);
michael@0 351 if (dropon.parentNode != oldParentNode) {
michael@0 352 self.options(oldParentNode).onChange(element);
michael@0 353 }
michael@0 354 self.options(dropon.parentNode).onChange(element);
michael@0 355 }
michael@0 356 }
michael@0 357 },
michael@0 358
michael@0 359 _offsetSize: function (element, type) {
michael@0 360 if (type == 'vertical' || type == 'height') {
michael@0 361 return element.offsetHeight;
michael@0 362 } else {
michael@0 363 return element.offsetWidth;
michael@0 364 }
michael@0 365 },
michael@0 366
michael@0 367 /** @id MochiKit.Sortable.onEmptyHover */
michael@0 368 onEmptyHover: function (element, dropon, overlap) {
michael@0 369 var oldParentNode = element.parentNode;
michael@0 370 var self = MochiKit.Sortable;
michael@0 371 var droponOptions = self.options(dropon);
michael@0 372
michael@0 373 if (!MochiKit.DOM.isParent(dropon, element)) {
michael@0 374 var index;
michael@0 375
michael@0 376 var children = self.findElements(dropon, {tag: droponOptions.tag,
michael@0 377 only: droponOptions.only});
michael@0 378 var child = null;
michael@0 379
michael@0 380 if (children) {
michael@0 381 var offset = self._offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
michael@0 382
michael@0 383 for (index = 0; index < children.length; index += 1) {
michael@0 384 if (offset - self._offsetSize(children[index], droponOptions.overlap) >= 0) {
michael@0 385 offset -= self._offsetSize(children[index], droponOptions.overlap);
michael@0 386 } else if (offset - (self._offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
michael@0 387 child = index + 1 < children.length ? children[index + 1] : null;
michael@0 388 break;
michael@0 389 } else {
michael@0 390 child = children[index];
michael@0 391 break;
michael@0 392 }
michael@0 393 }
michael@0 394 }
michael@0 395
michael@0 396 dropon.insertBefore(element, child);
michael@0 397
michael@0 398 self.options(oldParentNode).onChange(element);
michael@0 399 droponOptions.onChange(element);
michael@0 400 }
michael@0 401 },
michael@0 402
michael@0 403 /** @id MochiKit.Sortable.unmark */
michael@0 404 unmark: function () {
michael@0 405 var m = MochiKit.Sortable._marker;
michael@0 406 if (m) {
michael@0 407 MochiKit.Style.hideElement(m);
michael@0 408 }
michael@0 409 },
michael@0 410
michael@0 411 /** @id MochiKit.Sortable.mark */
michael@0 412 mark: function (dropon, position) {
michael@0 413 // mark on ghosting only
michael@0 414 var d = MochiKit.DOM;
michael@0 415 var self = MochiKit.Sortable;
michael@0 416 var sortable = self.options(dropon.parentNode);
michael@0 417 if (sortable && !sortable.ghosting) {
michael@0 418 return;
michael@0 419 }
michael@0 420
michael@0 421 if (!self._marker) {
michael@0 422 self._marker = d.getElement('dropmarker') ||
michael@0 423 document.createElement('DIV');
michael@0 424 MochiKit.Style.hideElement(self._marker);
michael@0 425 d.addElementClass(self._marker, 'dropmarker');
michael@0 426 self._marker.style.position = 'absolute';
michael@0 427 document.getElementsByTagName('body').item(0).appendChild(self._marker);
michael@0 428 }
michael@0 429 var offsets = MochiKit.Position.cumulativeOffset(dropon);
michael@0 430 self._marker.style.left = offsets.x + 'px';
michael@0 431 self._marker.style.top = offsets.y + 'px';
michael@0 432
michael@0 433 if (position == 'after') {
michael@0 434 if (sortable.overlap == 'horizontal') {
michael@0 435 self._marker.style.left = (offsets.x + dropon.clientWidth) + 'px';
michael@0 436 } else {
michael@0 437 self._marker.style.top = (offsets.y + dropon.clientHeight) + 'px';
michael@0 438 }
michael@0 439 }
michael@0 440 MochiKit.Style.showElement(self._marker);
michael@0 441 },
michael@0 442
michael@0 443 _tree: function (element, options, parent) {
michael@0 444 var self = MochiKit.Sortable;
michael@0 445 var children = self.findElements(element, options) || [];
michael@0 446
michael@0 447 for (var i = 0; i < children.length; ++i) {
michael@0 448 var match = children[i].id.match(options.format);
michael@0 449
michael@0 450 if (!match) {
michael@0 451 continue;
michael@0 452 }
michael@0 453
michael@0 454 var child = {
michael@0 455 id: encodeURIComponent(match ? match[1] : null),
michael@0 456 element: element,
michael@0 457 parent: parent,
michael@0 458 children: [],
michael@0 459 position: parent.children.length,
michael@0 460 container: self._findChildrenElement(children[i], options.treeTag.toUpperCase())
michael@0 461 }
michael@0 462
michael@0 463 /* Get the element containing the children and recurse over it */
michael@0 464 if (child.container) {
michael@0 465 self._tree(child.container, options, child)
michael@0 466 }
michael@0 467
michael@0 468 parent.children.push (child);
michael@0 469 }
michael@0 470
michael@0 471 return parent;
michael@0 472 },
michael@0 473
michael@0 474 /* Finds the first element of the given tag type within a parent element.
michael@0 475 Used for finding the first LI[ST] within a L[IST]I[TEM].*/
michael@0 476 _findChildrenElement: function (element, containerTag) {
michael@0 477 if (element && element.hasChildNodes) {
michael@0 478 containerTag = containerTag.toUpperCase();
michael@0 479 for (var i = 0; i < element.childNodes.length; ++i) {
michael@0 480 if (element.childNodes[i].tagName.toUpperCase() == containerTag) {
michael@0 481 return element.childNodes[i];
michael@0 482 }
michael@0 483 }
michael@0 484 }
michael@0 485 return null;
michael@0 486 },
michael@0 487
michael@0 488 /** @id MochiKit.Sortable.tree */
michael@0 489 tree: function (element, options) {
michael@0 490 element = MochiKit.DOM.getElement(element);
michael@0 491 var sortableOptions = MochiKit.Sortable.options(element);
michael@0 492 options = MochiKit.Base.update({
michael@0 493 tag: sortableOptions.tag,
michael@0 494 treeTag: sortableOptions.treeTag,
michael@0 495 only: sortableOptions.only,
michael@0 496 name: element.id,
michael@0 497 format: sortableOptions.format
michael@0 498 }, options || {});
michael@0 499
michael@0 500 var root = {
michael@0 501 id: null,
michael@0 502 parent: null,
michael@0 503 children: new Array,
michael@0 504 container: element,
michael@0 505 position: 0
michael@0 506 }
michael@0 507
michael@0 508 return MochiKit.Sortable._tree(element, options, root);
michael@0 509 },
michael@0 510
michael@0 511 /**
michael@0 512 * Specifies the sequence for the Sortable.
michael@0 513 * @param {Node} element Element to use as the Sortable.
michael@0 514 * @param {Object} newSequence New sequence to use.
michael@0 515 * @param {Object} options Options to use fro the Sortable.
michael@0 516 */
michael@0 517 setSequence: function (element, newSequence, options) {
michael@0 518 var self = MochiKit.Sortable;
michael@0 519 var b = MochiKit.Base;
michael@0 520 element = MochiKit.DOM.getElement(element);
michael@0 521 options = b.update(self.options(element), options || {});
michael@0 522
michael@0 523 var nodeMap = {};
michael@0 524 b.map(function (n) {
michael@0 525 var m = n.id.match(options.format);
michael@0 526 if (m) {
michael@0 527 nodeMap[m[1]] = [n, n.parentNode];
michael@0 528 }
michael@0 529 n.parentNode.removeChild(n);
michael@0 530 }, self.findElements(element, options));
michael@0 531
michael@0 532 b.map(function (ident) {
michael@0 533 var n = nodeMap[ident];
michael@0 534 if (n) {
michael@0 535 n[1].appendChild(n[0]);
michael@0 536 delete nodeMap[ident];
michael@0 537 }
michael@0 538 }, newSequence);
michael@0 539 },
michael@0 540
michael@0 541 /* Construct a [i] index for a particular node */
michael@0 542 _constructIndex: function (node) {
michael@0 543 var index = '';
michael@0 544 do {
michael@0 545 if (node.id) {
michael@0 546 index = '[' + node.position + ']' + index;
michael@0 547 }
michael@0 548 } while ((node = node.parent) != null);
michael@0 549 return index;
michael@0 550 },
michael@0 551
michael@0 552 /** @id MochiKit.Sortable.sequence */
michael@0 553 sequence: function (element, options) {
michael@0 554 element = MochiKit.DOM.getElement(element);
michael@0 555 var self = MochiKit.Sortable;
michael@0 556 var options = MochiKit.Base.update(self.options(element), options || {});
michael@0 557
michael@0 558 return MochiKit.Base.map(function (item) {
michael@0 559 return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
michael@0 560 }, MochiKit.DOM.getElement(self.findElements(element, options) || []));
michael@0 561 },
michael@0 562
michael@0 563 /**
michael@0 564 * Serializes the content of a Sortable. Useful to send this content through a XMLHTTPRequest.
michael@0 565 * These options override the Sortable options for the serialization only.
michael@0 566 * @param {Node} element Element to serialize.
michael@0 567 * @param {Object} options Serialization options.
michael@0 568 */
michael@0 569 serialize: function (element, options) {
michael@0 570 element = MochiKit.DOM.getElement(element);
michael@0 571 var self = MochiKit.Sortable;
michael@0 572 options = MochiKit.Base.update(self.options(element), options || {});
michael@0 573 var name = encodeURIComponent(options.name || element.id);
michael@0 574
michael@0 575 if (options.tree) {
michael@0 576 return MochiKit.Base.flattenArray(MochiKit.Base.map(function (item) {
michael@0 577 return [name + self._constructIndex(item) + "[id]=" +
michael@0 578 encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
michael@0 579 }, self.tree(element, options).children)).join('&');
michael@0 580 } else {
michael@0 581 return MochiKit.Base.map(function (item) {
michael@0 582 return name + "[]=" + encodeURIComponent(item);
michael@0 583 }, self.sequence(element, options)).join('&');
michael@0 584 }
michael@0 585 }
michael@0 586 });
michael@0 587
michael@0 588 // trunk compatibility
michael@0 589 MochiKit.Sortable.Sortable = MochiKit.Sortable;

mercurial