diff -r 000000000000 -r 40c8f766c9b8 src/cm/media/js/lib/yui/yui3.0.0/examples/dd/portal-drag.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cm/media/js/lib/yui/yui3.0.0/examples/dd/portal-drag.html Mon Nov 23 15:14:29 2009 +0100 @@ -0,0 +1,1314 @@ + + + + + YUI Library Examples: Drag & Drop: Portal Style Example + + + + + + + + + + + + + + +
+
+
+

+ + YUI 3.x Home - + +

+
+ + +
+ + + +
+
+
+
+

YUI Library Examples: Drag & Drop: Portal Style Example

+
+
+ + +
+
+
+
+ +

Drag & Drop: Portal Style Example

+ +
+
+

Portal style example using Drag & Drop Event Bubbling and Animation.

+
+ +
+
+ +

+ + + View example in new window. + + +

+ + +
+
+
+ +

Full HTML Source

+ +
  1. <body>
  2. <div id="doc3" class="yui-t2">
  3. <div id="hd"><h1>YUI 3.0 Portal Example</h1></div>
  4. <div id="bd">
  5. <div id="yui-main">
  6. <div class="yui-b">
  7. <div class="yui-g">
  8. <div id="play">
  9. <ul class="list" id="list1"></ul>
  10. <ul class="list" id="list2"></ul>
  11. <ul class="list" id="list3"></ul>
  12. </div>
  13. </div>
  14. </div>
  15. </div>
  16. <div class="yui-b">
  17. <div id="feeds">
  18. <p>Drag a news feed into one of the columns.</p>
  19. <ul></ul>
  20. </div>
  21. </div>
  22. </div>
  23. <div id="ft">Built with <a href="http://developer.yahoo.com/yui/3/">YUI 3.0</a>: <a href="http://developer.yahoo.com/yui/3/yui">Core</a>, Loader, Get, <a href="http://developer.yahoo.com/yui/3/cookie">Cookie</a>, <a href="http://developer.yahoo.com/yui/3/animation">Animation</a>, <a href="http://developer.yahoo.com/yui/3/io">IO</a>, <a href="http://developer.yahoo.com/yui/3/json">JSON</a> &amp; <a href="http://developer.yahoo.com/yui/3/dd">DD</a>.</div>
  24. </div>
  25. <script src="assets/portal.js"></script>
  26. </body>
<body>
+<div id="doc3" class="yui-t2">
+    <div id="hd"><h1>YUI 3.0 Portal Example</h1></div>
+    <div id="bd">
+        <div id="yui-main">
+	        <div class="yui-b">
+                <div class="yui-g">
+                    <div id="play">
+                        <ul class="list" id="list1"></ul>
+                        <ul class="list" id="list2"></ul>
+                        <ul class="list" id="list3"></ul>
+                    </div>
+	            </div>
+            </div>
+	    </div>
+	    <div class="yui-b">
+            <div id="feeds">
+                <p>Drag a news feed into one of the columns.</p>
+                <ul></ul>
+            </div>
+        </div>
+    </div>
+    <div id="ft">Built with <a href="http://developer.yahoo.com/yui/3/">YUI 3.0</a>: <a href="http://developer.yahoo.com/yui/3/yui">Core</a>, Loader, Get, <a href="http://developer.yahoo.com/yui/3/cookie">Cookie</a>, <a href="http://developer.yahoo.com/yui/3/animation">Animation</a>, <a href="http://developer.yahoo.com/yui/3/io">IO</a>, <a href="http://developer.yahoo.com/yui/3/json">JSON</a> &amp; <a href="http://developer.yahoo.com/yui/3/dd">DD</a>.</div>
+</div>
+<script src="assets/portal.js"></script>
+</body>

Full Javascript Source

+ +
  1. //Use loader to grab the modules needed
  2. YUI(yuiConfig).use('dd', 'anim', 'io', 'cookie', 'json', function(Y) {
  3. //Make this an Event Target so we can bubble to it
  4. var Portal = function() {
  5. Portal.superclass.constructor.apply(this, arguments);
  6. };
  7. Portal.NAME = 'portal';
  8. Y.extend(Portal, Y.Base);
  9. //This is our new bubble target..
  10. Y.Portal = new Portal();
  11.  
  12.  
  13. //Setup some private variables..
  14. var goingUp = false, lastY = 0, trans = {};
  15.  
  16. //The list of feeds that we are going to use
  17. var feeds = {
  18. 'ynews': {
  19. id: 'ynews',
  20. title: 'Yahoo! US News',
  21. url: 'rss.news.yahoo.com/rss/us'
  22. },
  23. 'yui': {
  24. id: 'yui',
  25. title: 'YUI Blog',
  26. url: 'feeds.yuiblog.com/YahooUserInterfaceBlog'
  27. },
  28. 'slashdot': {
  29. id: 'slashdot',
  30. title: 'Slashdot',
  31. url: 'rss.slashdot.org/Slashdot/slashdot'
  32. },
  33. 'ajaxian': {
  34. id: 'ajaxian',
  35. title: 'Ajaxian',
  36. url: 'feeds.feedburner.com/ajaxian'
  37. },
  38. 'daringfireball': {
  39. id: 'daringfireball',
  40. title: 'Daring Fireball',
  41. url: 'daringfireball.net/index.xml'
  42. },
  43. 'wiredtech': {
  44. id: 'wiredtech',
  45. title: 'Wire: Tech Biz',
  46. url: 'www.wired.com/rss/techbiz.xml'
  47. },
  48. 'techcrunch': {
  49. id: 'techcrunch',
  50. title: 'TechCrunch',
  51. url: 'feedproxy.google.com/Techcrunch'
  52. },
  53. 'smashing': {
  54. id: 'smashing',
  55. title: 'Smashing Magazine',
  56. url: 'www.smashingmagazine.com/wp-rss.php'
  57. }
  58. };
  59.  
  60. //Setup the config for IO to use flash
  61. Y.io.transport({
  62. id: 'flash',
  63. yid: Y.id,
  64. src: buildDir + 'io/io.swf?stamp=' + (new Date()).getTime()
  65. });
  66.  
  67. //Simple method for stopping event propagation
  68. //Using this so we can detach it later
  69. var stopper = function(e) {
  70. e.stopPropagation();
  71. };
  72.  
  73. //Get the order, placement and minned state of the modules and save them to a cookie
  74. var _setCookies = function() {
  75. var dds = Y.DD.DDM._drags;
  76. var list = {};
  77. //Walk all the drag elements
  78. Y.each(dds, function(v, k) {
  79. var par = v.get('node').get('parentNode');
  80. //Find all the lists with drag items in them
  81. if (par.test('ul.list')) {
  82. if (!list[par.get('id')]) {
  83. list[par.get('id')] = [];
  84. }
  85. }
  86. });
  87. //Walk the list
  88. Y.each(list, function(v, k) {
  89. //Get all the li's in the list
  90. var lis = Y.all('#' + k + ' li.item');
  91. lis.each(function(v2, k2) {
  92. //Get the drag instance for the list item
  93. var dd = Y.DD.DDM.getDrag('#' + v2.get('id'));
  94. //Get the mod node
  95. var mod = dd.get('node').query('div.mod');
  96. //Is it minimized
  97. var min = (mod.hasClass('minned')) ? true : false;
  98. //Setup the cookie data
  99. list[k][list[k].length] = { id: dd.get('data').id, min: min };
  100. });
  101. });
  102. //JSON encode the cookie data
  103. var cookie = Y.JSON.stringify(list);
  104. //Set the sub-cookie
  105. Y.Cookie.setSub('yui', 'portal', cookie);
  106. };
  107.  
  108. //Helper method for creating the feed DD on the left
  109. var _createFeedDD = function(node, data) {
  110. //Create the DD instance
  111. var dd = new Y.DD.Drag({
  112. node: node,
  113. data: data,
  114. bubbles: Y.Portal
  115. }).plug(Y.Plugin.DDProxy, {
  116. moveOnEnd: false,
  117. borderStyle: 'none'
  118. });
  119. //Setup some stopper events
  120. dd.on('drag:start', _handleStart);
  121. dd.on('drag:end', stopper);
  122. dd.on('drag:drophit', stopper);
  123. };
  124.  
  125. //Handle the node:click event
  126. /* {{{ */
  127. var _nodeClick = function(e) {
  128. //Is the target an href?
  129. if (e.target.test('a')) {
  130. var a = e.target, anim = null, div = a.get('parentNode').get('parentNode');
  131. //Did they click on the min button
  132. if (a.hasClass('min')) {
  133. //Get some node references
  134. var ul = div.query('ul'),
  135. h2 = div.query('h2'),
  136. h = h2.get('offsetHeight'),
  137. hUL = ul.get('offsetHeight'),
  138. inner = div.query('div.inner');
  139.  
  140. //Create an anim instance on this node.
  141. anim = new Y.Anim({
  142. node: inner
  143. });
  144. //Is it expanded?
  145. if (!div.hasClass('minned')) {
  146. //Set the vars for collapsing it
  147. anim.setAttrs({
  148. to: {
  149. height: 0
  150. },
  151. duration: '.25',
  152. easing: Y.Easing.easeOut,
  153. iteration: 1
  154. });
  155. //On the end, toggle the minned class
  156. //Then set the cookies for state
  157. anim.on('end', function() {
  158. div.toggleClass('minned');
  159. _setCookies();
  160. });
  161. } else {
  162. //Set the vars for expanding it
  163. anim.setAttrs({
  164. to: {
  165. height: (hUL)
  166. },
  167. duration: '.25',
  168. easing: Y.Easing.easeOut,
  169. iteration: 1
  170. });
  171. //Toggle the minned class
  172. //Then set the cookies for state
  173. div.toggleClass('minned');
  174. _setCookies();
  175. }
  176. //Run the animation
  177. anim.run();
  178.  
  179. }
  180. //Was close clicked?
  181. if (a.hasClass('close')) {
  182. //Get some Node references..
  183. var li = div.get('parentNode'),
  184. id = li.get('id'),
  185. dd = Y.DD.DDM.getDrag('#' + id),
  186. data = dd.get('data'),
  187. item = Y.Node.get('#' + data.id);
  188.  
  189. //Destroy the DD instance.
  190. dd.destroy();
  191. //Setup the animation for making it disappear
  192. anim = new Y.Anim({
  193. node: div,
  194. to: {
  195. opacity: 0
  196. },
  197. duration: '.25',
  198. easing: Y.Easing.easeOut
  199. });
  200. anim.on('end', function() {
  201. //On end of the first anim, setup another to make it collapse
  202. var anim = new Y.Anim({
  203. node: div,
  204. to: {
  205. height: 0
  206. },
  207. duration: '.25',
  208. easing: Y.Easing.easeOut
  209. });
  210. anim.on('end', function() {
  211. //Remove it from the document
  212. li.get('parentNode').removeChild(li);
  213. item.removeClass('disabled');
  214. //Setup a drag instance on the feed list
  215. _createFeedDD(item, data);
  216. _setCookies();
  217.  
  218. });
  219. //Run the animation
  220. anim.run();
  221. });
  222. //Run the animation
  223. anim.run();
  224. }
  225. //Stop the click
  226. e.halt();
  227. }
  228. };
  229. /* }}} */
  230.  
  231. //This creates the module, either from a drag event or from the cookie load
  232. var setupModDD = function(mod, data, dd) {
  233. var node = mod;
  234. //Listen for the click so we can react to the buttons
  235. node.query('h2').on('click', _nodeClick);
  236.  
  237. //Remove the event's on the original drag instance
  238. dd.detachAll('drag:start');
  239. dd.detachAll('drag:end');
  240. dd.detachAll('drag:drophit');
  241.  
  242. //It's a target
  243. dd.set('target', true);
  244. //Setup the handles
  245. dd.addHandle('h2').addInvalid('a');
  246. //Remove the mouse listeners on this node
  247. dd._unprep();
  248. //Update a new node
  249. dd.set('node', mod);
  250. //Reset the mouse handlers
  251. dd._prep();
  252.  
  253. //The Yahoo! Pipes URL
  254. var url = 'http:/'+'/pipes.yahooapis.com/pipes/pipe.run?_id=6b7b2c6a32f5a12e7259c36967052387&_render=json&url=http:/'+'/' + data.url;
  255. //Start the XDR request
  256. var id = Y.io(url, {
  257. method: 'GET',
  258. xdr: {
  259. use:'flash'
  260. },
  261. //XDR Listeners
  262. on: {
  263. success: function(id, data) {
  264. //On success get the feed data
  265. var d = feeds[trans[id]],
  266. //Node reference
  267. inner = d.mod.query('div.inner'),
  268. //Parse the JSON data
  269. oRSS = Y.JSON.parse(data.responseText),
  270. html = '';
  271.  
  272. //Did we get data?
  273. if (oRSS && oRSS.count) {
  274. //Walk the list and create the news list
  275. Y.each(oRSS.value.items, function(v, k) {
  276. if (k < 5) {
  277. html += '<li><a href="' + v.link + '" target="_blank">' + v.title + '</a>';
  278. }
  279. });
  280. }
  281. //Set the innerHTML of the module
  282. inner.set('innerHTML', '<ul>' + html + '</ul>');
  283. if (Y.DD.DDM.activeDrag) {
  284. //If we are still dragging, update the proxy element too..
  285. var proxy_inner = Y.DD.DDM.activeDrag.get('dragNode').query('div.inner');
  286. proxy_inner.set('innerHTML', '<ul>' + html + '</ul>');
  287.  
  288. }
  289. },
  290. failure: function(id, data) {
  291. //Something failed..
  292. alert('Feed failed to load..' + id + ' :: ' + data);
  293. }
  294. }
  295. });
  296. //Keep track of the transaction
  297. feeds[data.id].trans = id;
  298. feeds[data.id].mod = mod;
  299. trans[id.id] = data.id;
  300. };
  301.  
  302.  
  303. //Helper method to create the markup for the module..
  304. var createMod = function(feed) {
  305. var str = '<li class="item">' +
  306. '<div class="mod">' +
  307. '<h2><strong>' + feed.title + '</strong> <a title="minimize module" class="min" href="#"> </a>' +
  308. '<a title="close module" class="close" href="#"></a></h2>' +
  309. '<div class="inner">' +
  310. ' <div class="loading">Feed loading, please wait..</div>' +
  311. '</div>' +
  312. '</div>' +
  313. '</li>';
  314. return Y.Node.create(str);
  315. };
  316.  
  317. //Handle the start Drag event on the left side
  318. var _handleStart = function(e) {
  319. //Stop the event
  320. stopper(e);
  321. //Some private vars
  322. var drag = this,
  323. list3 = Y.Node.get('#list1'),
  324. mod = createMod(drag.get('data'));
  325.  
  326. //Add it to the first list
  327. list3.appendChild(mod);
  328. //Set the item on the left column disabled.
  329. drag.get('node').addClass('disabled');
  330. //Set the node on the instance
  331. drag.set('node', mod);
  332. //Add some styles to the proxy node.
  333. drag.get('dragNode').setStyles({
  334. opacity: '.5',
  335. borderStyle: 'none',
  336. width: '320px',
  337. height: '61px'
  338. });
  339. //Update the innerHTML of the proxy with the innerHTML of the module
  340. drag.get('dragNode').set('innerHTML', drag.get('node').get('innerHTML'));
  341. //set the inner module to hidden
  342. drag.get('node').query('div.mod').setStyle('visibility', 'hidden');
  343. //add a class for styling
  344. drag.get('node').addClass('moving');
  345. //Setup the DD instance
  346. setupModDD(mod, drag.get('data'), drag);
  347.  
  348. //Remove the listener
  349. this.detach('drag:start', _handleStart);
  350. };
  351.  
  352. //Walk through the feeds list and create the list on the left
  353. var feedList = Y.Node.get('#feeds ul');
  354. Y.each(feeds, function(v, k) {
  355. var li = Y.Node.create('<li id="' + k + '">' + v.title + '</li>');
  356. feedList.appendChild(li);
  357. //Create the DD instance for this item
  358. _createFeedDD(li, v);
  359. });
  360.  
  361. //This does the calculations for when and where to move a module
  362. var _moveMod = function(drag, drop) {
  363. if (drag.get('node').hasClass('item')) {
  364. var dragNode = drag.get('node'),
  365. dropNode = drop.get('node'),
  366. append = false,
  367. padding = 30,
  368. xy = drag.mouseXY,
  369. region = drop.region,
  370. middle1 = region.top + ((region.bottom - region.top) / 2),
  371. middle2 = region.left + ((region.right - region.left) / 2),
  372. dir = false,
  373. dir1 = false,
  374. dir2 = false;
  375.  
  376. //We could do something a little more fancy here, but we won't ;)
  377. if ((xy[1] < (region.top + padding))) {
  378. dir1 = 'top';
  379. }
  380. if ((region.bottom - padding) < xy[1]) {
  381. dir1 = 'bottom';
  382. }
  383. if ((region.right - padding) < xy[0]) {
  384. dir2 = 'right';
  385. }
  386. if ((xy[0] < (region.left + padding))) {
  387. dir2 = 'left';
  388. }
  389. dir = dir2;
  390. if (dir2 === false) {
  391. dir = dir1;
  392. }
  393. switch (dir) {
  394. case 'top':
  395. var next = dropNode.get('nextSibling');
  396. if (next) {
  397. dropNode = next;
  398. } else {
  399. append = true;
  400. }
  401. break;
  402. case 'bottom':
  403. break;
  404. case 'right':
  405. case 'left':
  406. break;
  407. }
  408.  
  409.  
  410. if ((dropNode !== null) && dir) {
  411. if (dropNode && dropNode.get('parentNode')) {
  412. if (!append) {
  413. dropNode.get('parentNode').insertBefore(dragNode, dropNode);
  414. } else {
  415. dropNode.get('parentNode').appendChild(dragNode);
  416. }
  417. }
  418. }
  419. //Resync all the targets because something moved..
  420. Y.Lang.later(50, Y, function() {
  421. Y.DD.DDM.syncActiveShims(true);
  422. });
  423. }
  424. };
  425.  
  426. /*
  427.   Handle the drop:enter event
  428.   Now when we get a drop enter event, we check to see if the target is an LI, then we know it's out module.
  429.   Here is where we move the module around in the DOM.
  430.   */
  431. Y.Portal.on('drop:enter', function(e) {
  432. if (!e.drag || !e.drop || (e.drop !== e.target)) {
  433. return false;
  434. }
  435. if (e.drop.get('node').get('tagName').toLowerCase() === 'li') {
  436. if (e.drop.get('node').hasClass('item')) {
  437. _moveMod(e.drag, e.drop);
  438. }
  439. }
  440. });
  441.  
  442. //Handle the drag:drag event
  443. //On drag we need to know if they are moved up or down so we can place the module in the proper DOM location.
  444. Y.Portal.on('drag:drag', function(e) {
  445. var y = e.target.mouseXY[1];
  446. if (y < lastY) {
  447. goingUp = true;
  448. } else {
  449. goingUp = false;
  450. }
  451. lastY = y;
  452. });
  453.  
  454. /*
  455.   Handle the drop:hit event
  456.   Now that we have a drop on the target, we check to see if the drop was not on a LI.
  457.   This means they dropped on the empty space of the UL.
  458.   */
  459. Y.Portal.on('drag:drophit', function(e) {
  460. var drop = e.drop.get('node'),
  461. drag = e.drag.get('node');
  462.  
  463. if (drop.get('tagName').toLowerCase() !== 'li') {
  464. if (!drop.contains(drag)) {
  465. drop.appendChild(drag);
  466. }
  467. }
  468. });
  469.  
  470. //Handle the drag:start event
  471. //Use some CSS here to make our dragging better looking.
  472. Y.Portal.on('drag:start', function(e) {
  473. var drag = e.target;
  474. if (drag.target) {
  475. drag.target.set('locked', true);
  476. }
  477. drag.get('dragNode').set('innerHTML', drag.get('node').get('innerHTML'));
  478. drag.get('dragNode').setStyle('opacity','.5');
  479. drag.get('node').query('div.mod').setStyle('visibility', 'hidden');
  480. drag.get('node').addClass('moving');
  481. });
  482.  
  483. //Handle the drag:end event
  484. //Replace some of the styles we changed on start drag.
  485. Y.Portal.on('drag:end', function(e) {
  486. var drag = e.target;
  487. if (drag.target) {
  488. drag.target.set('locked', false);
  489. }
  490. drag.get('node').setStyle('visibility', '');
  491. drag.get('node').query('div.mod').setStyle('visibility', '');
  492. drag.get('node').removeClass('moving');
  493. drag.get('dragNode').set('innerHTML', '');
  494. _setCookies();
  495. });
  496.  
  497.  
  498. //Handle going over a UL, for empty lists
  499. Y.Portal.on('drop:over', function(e) {
  500. var drop = e.drop.get('node'),
  501. drag = e.drag.get('node');
  502.  
  503. if (drop.get('tagName').toLowerCase() !== 'li') {
  504. if (!drop.contains(drag)) {
  505. drop.appendChild(drag);
  506. Y.Lang.later(50, Y, function() {
  507. Y.DD.DDM.syncActiveShims(true);
  508. });
  509. }
  510. }
  511. });
  512.  
  513. //Create simple targets for the main lists..
  514. var uls = Y.all('#play ul.list');
  515. uls.each(function(v, k) {
  516. var tar = new Y.DD.Drop({
  517. node: v,
  518. padding: '20 0',
  519. bubbles: Y.Portal
  520. });
  521. });
  522.  
  523.  
  524. Y.on('io:xdrReady', function() {
  525. //Get the cookie data
  526. var cookie = Y.Cookie.getSub('yui', 'portal');
  527. if (cookie) {
  528. //JSON parse the stored data
  529. var obj = Y.JSON.parse(cookie);
  530.  
  531. //Walk the data
  532. Y.each(obj, function(v, k) {
  533. //Get the node for the list
  534. var list = Y.Node.get('#' + k);
  535. //Walk the items in this list
  536. Y.each(v, function(v2, k2) {
  537. //Get the drag for it
  538. var drag = Y.DD.DDM.getDrag('#' + v2.id);
  539. //Create the module
  540. var mod = createMod(drag.get('data'));
  541. if (v2.min) {
  542. //If it's minned add some CSS
  543. mod.query('div.mod').addClass('minned');
  544. mod.query('div.inner').setStyle('height', '0px');
  545. }
  546. //Add it to the list
  547. list.appendChild(mod);
  548. //Set the drag listeners
  549. drag.get('node').addClass('disabled');
  550. drag.set('node', mod);
  551. drag.set('dragNode', Y.DD.DDM._proxy);
  552. drag.detachAll('drag:start');
  553. drag.detachAll('drag:end');
  554. drag.detachAll('drag:drophit');
  555. drag._unprep();
  556. //Setup the new Drag listeners
  557. setupModDD(mod, drag.get('data'), drag);
  558. });
  559. });
  560. }
  561. });
  562.  
  563. });
//Use loader to grab the modules needed
+YUI(yuiConfig).use('dd', 'anim', 'io', 'cookie', 'json', function(Y) {
+    //Make this an Event Target so we can bubble to it
+    var Portal = function() {
+        Portal.superclass.constructor.apply(this, arguments);
+    };
+    Portal.NAME = 'portal';
+    Y.extend(Portal, Y.Base);
+    //This is our new bubble target..
+    Y.Portal = new Portal();
+ 
+ 
+    //Setup some private variables..
+    var goingUp = false, lastY = 0, trans = {};
+ 
+    //The list of feeds that we are going to use
+    var feeds = {
+        'ynews': {
+            id: 'ynews',
+            title: 'Yahoo! US News',
+            url: 'rss.news.yahoo.com/rss/us'
+        },
+        'yui': {
+            id: 'yui',
+            title: 'YUI Blog',
+            url: 'feeds.yuiblog.com/YahooUserInterfaceBlog'
+        },
+        'slashdot': {
+            id: 'slashdot',
+            title: 'Slashdot',
+            url: 'rss.slashdot.org/Slashdot/slashdot'
+        },
+        'ajaxian': {
+            id: 'ajaxian',
+            title: 'Ajaxian',
+            url: 'feeds.feedburner.com/ajaxian'
+        },
+        'daringfireball': {
+            id: 'daringfireball',
+            title: 'Daring Fireball',
+            url: 'daringfireball.net/index.xml'
+        },
+        'wiredtech': {
+            id: 'wiredtech',
+            title: 'Wire: Tech Biz',
+            url: 'www.wired.com/rss/techbiz.xml'
+        },
+        'techcrunch': {
+            id: 'techcrunch',
+            title: 'TechCrunch',
+            url: 'feedproxy.google.com/Techcrunch'
+        },
+        'smashing': {
+            id: 'smashing',
+            title: 'Smashing Magazine',
+            url: 'www.smashingmagazine.com/wp-rss.php'
+        }
+    };
+ 
+    //Setup the config for IO to use flash
+	Y.io.transport({
+		id: 'flash',
+		yid: Y.id,
+		src: buildDir + 'io/io.swf?stamp=' + (new Date()).getTime()
+    });
+ 
+    //Simple method for stopping event propagation
+    //Using this so we can detach it later
+    var stopper = function(e) {
+        e.stopPropagation();
+    };
+ 
+    //Get the order, placement and minned state of the modules and save them to a cookie
+    var _setCookies = function() {
+        var dds = Y.DD.DDM._drags;
+        var list = {};
+        //Walk all the drag elements
+        Y.each(dds, function(v, k) {
+            var par = v.get('node').get('parentNode');
+            //Find all the lists with drag items in them
+            if (par.test('ul.list')) {
+                if (!list[par.get('id')]) {
+                    list[par.get('id')] = [];
+                }
+            }
+        });
+        //Walk the list
+        Y.each(list, function(v, k) {
+            //Get all the li's in the list
+            var lis = Y.all('#' + k + ' li.item');
+            lis.each(function(v2, k2) {
+                //Get the drag instance for the list item
+                var dd = Y.DD.DDM.getDrag('#' + v2.get('id'));
+                //Get the mod node
+                var mod = dd.get('node').query('div.mod');
+                //Is it minimized
+                var min = (mod.hasClass('minned')) ? true : false;
+                //Setup the cookie data
+                list[k][list[k].length] = { id: dd.get('data').id, min: min };
+            });
+        });
+        //JSON encode the cookie data
+        var cookie = Y.JSON.stringify(list);
+        //Set the sub-cookie
+        Y.Cookie.setSub('yui', 'portal', cookie);
+    };
+ 
+    //Helper method for creating the feed DD on the left
+    var _createFeedDD = function(node, data) {
+        //Create the DD instance
+        var dd = new Y.DD.Drag({
+            node: node,
+            data: data,
+            bubbles: Y.Portal
+        }).plug(Y.Plugin.DDProxy, {
+            moveOnEnd: false,
+            borderStyle: 'none'
+        });
+        //Setup some stopper events
+        dd.on('drag:start', _handleStart);
+        dd.on('drag:end', stopper);
+        dd.on('drag:drophit', stopper);
+    };
+ 
+    //Handle the node:click event
+    /* {{{ */
+    var _nodeClick = function(e) {
+        //Is the target an href?
+        if (e.target.test('a')) {
+            var a = e.target, anim = null, div = a.get('parentNode').get('parentNode');
+            //Did they click on the min button
+            if (a.hasClass('min')) {
+                //Get some node references
+                var ul = div.query('ul'),
+                    h2 = div.query('h2'),
+                h = h2.get('offsetHeight'),
+                hUL = ul.get('offsetHeight'),
+                inner = div.query('div.inner');
+ 
+                //Create an anim instance on this node.
+                anim = new Y.Anim({
+                    node: inner
+                });
+                //Is it expanded?
+                if (!div.hasClass('minned')) {
+                    //Set the vars for collapsing it
+                    anim.setAttrs({
+                        to: {
+                            height: 0
+                        },
+                        duration: '.25',
+                        easing: Y.Easing.easeOut,
+                        iteration: 1
+                    });
+                    //On the end, toggle the minned class
+                    //Then set the cookies for state
+                    anim.on('end', function() {
+                        div.toggleClass('minned');
+                        _setCookies();
+                    });
+                } else {
+                    //Set the vars for expanding it
+                    anim.setAttrs({
+                        to: {
+                            height: (hUL)
+                        },
+                        duration: '.25',
+                        easing: Y.Easing.easeOut,
+                        iteration: 1
+                    });
+                    //Toggle the minned class
+                    //Then set the cookies for state
+                    div.toggleClass('minned');
+                    _setCookies();
+                }
+                //Run the animation
+                anim.run();
+ 
+            }
+            //Was close clicked?
+            if (a.hasClass('close')) {
+                //Get some Node references..
+                var li = div.get('parentNode'),
+                    id = li.get('id'),
+                    dd = Y.DD.DDM.getDrag('#' + id),
+                    data = dd.get('data'),
+                    item = Y.Node.get('#' + data.id);
+ 
+                //Destroy the DD instance.
+                dd.destroy();
+                //Setup the animation for making it disappear
+                anim = new Y.Anim({
+                    node: div,
+                    to: {
+                        opacity: 0
+                    },
+                    duration: '.25',
+                    easing: Y.Easing.easeOut
+                });
+                anim.on('end', function() {
+                    //On end of the first anim, setup another to make it collapse
+                    var anim = new Y.Anim({
+                        node: div,
+                        to: {
+                            height: 0
+                        },
+                        duration: '.25',
+                        easing: Y.Easing.easeOut
+                    });
+                    anim.on('end', function() {
+                        //Remove it from the document
+                        li.get('parentNode').removeChild(li);
+                        item.removeClass('disabled');
+                        //Setup a drag instance on the feed list
+                        _createFeedDD(item, data);
+                        _setCookies();
+ 
+                    });
+                    //Run the animation
+                    anim.run();
+                });
+                //Run the animation
+                anim.run();
+            }
+            //Stop the click
+            e.halt();
+        }
+    };
+    /* }}} */
+ 
+    //This creates the module, either from a drag event or from the cookie load
+    var setupModDD = function(mod, data, dd) {
+        var node = mod;
+        //Listen for the click so we can react to the buttons
+        node.query('h2').on('click', _nodeClick);
+ 
+        //Remove the event's on the original drag instance
+        dd.detachAll('drag:start');
+        dd.detachAll('drag:end');
+        dd.detachAll('drag:drophit');
+ 
+        //It's a target
+        dd.set('target', true);
+        //Setup the handles
+        dd.addHandle('h2').addInvalid('a');
+        //Remove the mouse listeners on this node
+        dd._unprep();
+        //Update a new node
+        dd.set('node', mod);
+        //Reset the mouse handlers
+        dd._prep();
+ 
+        //The Yahoo! Pipes URL
+        var url = 'http:/'+'/pipes.yahooapis.com/pipes/pipe.run?_id=6b7b2c6a32f5a12e7259c36967052387&_render=json&url=http:/'+'/' + data.url;
+        //Start the XDR request
+        var id = Y.io(url, {
+            method: 'GET',
+            xdr: { 
+			    use:'flash'
+		    },
+            //XDR Listeners
+		    on: { 
+			    success: function(id, data) {
+                    //On success get the feed data
+                    var d = feeds[trans[id]],
+                    //Node reference
+                    inner = d.mod.query('div.inner'),
+                    //Parse the JSON data
+                    oRSS = Y.JSON.parse(data.responseText),
+                    html = '';
+ 
+                    //Did we get data?
+		            if (oRSS && oRSS.count) {
+                        //Walk the list and create the news list
+			            Y.each(oRSS.value.items, function(v, k) {
+                            if (k < 5) {
+                                html += '<li><a href="' + v.link + '" target="_blank">' + v.title + '</a>';
+                            }
+                        });
+		            }
+                    //Set the innerHTML of the module
+                    inner.set('innerHTML', '<ul>' + html + '</ul>');
+                    if (Y.DD.DDM.activeDrag) {
+                        //If we are still dragging, update the proxy element too..
+                        var proxy_inner = Y.DD.DDM.activeDrag.get('dragNode').query('div.inner');
+                        proxy_inner.set('innerHTML', '<ul>' + html + '</ul>');
+ 
+                    }
+                },
+			    failure: function(id, data) {
+                    //Something failed..
+                    alert('Feed failed to load..' + id + ' :: ' + data);
+                }
+		    }
+        });
+        //Keep track of the transaction
+        feeds[data.id].trans = id;
+        feeds[data.id].mod = mod;
+        trans[id.id] = data.id;
+    };
+ 
+ 
+    //Helper method to create the markup for the module..
+    var createMod = function(feed) {
+        var str = '<li class="item">' +
+                    '<div class="mod">' + 
+                        '<h2><strong>' + feed.title + '</strong> <a title="minimize module" class="min" href="#"> </a>' +
+                        '<a title="close module" class="close" href="#"></a></h2>' +
+                        '<div class="inner">' +
+                        '    <div class="loading">Feed loading, please wait..</div>' + 
+                        '</div>' +
+                    '</div>' +
+                '</li>';
+        return Y.Node.create(str);
+    };
+ 
+    //Handle the start Drag event on the left side
+    var _handleStart = function(e) {
+        //Stop the event
+        stopper(e);
+        //Some private vars
+        var drag = this,
+            list3 = Y.Node.get('#list1'),
+            mod = createMod(drag.get('data'));
+ 
+        //Add it to the first list
+        list3.appendChild(mod);
+        //Set the item on the left column disabled.
+        drag.get('node').addClass('disabled');
+        //Set the node on the instance
+        drag.set('node', mod);
+        //Add some styles to the proxy node.
+        drag.get('dragNode').setStyles({
+            opacity: '.5',
+            borderStyle: 'none',
+            width: '320px',
+            height: '61px'
+        });
+        //Update the innerHTML of the proxy with the innerHTML of the module
+        drag.get('dragNode').set('innerHTML', drag.get('node').get('innerHTML'));
+        //set the inner module to hidden
+        drag.get('node').query('div.mod').setStyle('visibility', 'hidden');
+        //add a class for styling
+        drag.get('node').addClass('moving');
+        //Setup the DD instance
+        setupModDD(mod, drag.get('data'), drag);
+ 
+        //Remove the listener
+        this.detach('drag:start', _handleStart);
+    };
+ 
+    //Walk through the feeds list and create the list on the left
+    var feedList = Y.Node.get('#feeds ul');
+    Y.each(feeds, function(v, k) {
+        var li = Y.Node.create('<li id="' + k + '">' + v.title + '</li>');
+        feedList.appendChild(li);
+        //Create the DD instance for this item
+        _createFeedDD(li, v);
+    });
+ 
+    //This does the calculations for when and where to move a module
+    var _moveMod = function(drag, drop) {
+        if (drag.get('node').hasClass('item')) {
+            var dragNode = drag.get('node'),
+                dropNode = drop.get('node'),
+                append = false,
+                padding = 30,
+                xy = drag.mouseXY,
+                region = drop.region,
+                middle1 = region.top + ((region.bottom - region.top) / 2),
+                middle2 = region.left + ((region.right - region.left) / 2),
+                dir = false,
+                dir1 = false,
+                dir2 = false;
+ 
+                //We could do something a little more fancy here, but we won't ;)
+                if ((xy[1] < (region.top + padding))) {
+                    dir1 = 'top';
+                }
+                if ((region.bottom - padding) < xy[1]) {
+                    dir1 = 'bottom';
+                }
+                if ((region.right - padding) < xy[0]) {
+                    dir2 = 'right';
+                }
+                if ((xy[0] < (region.left + padding))) {
+                    dir2 = 'left';
+                }
+                dir = dir2;
+                if (dir2 === false) {
+                    dir = dir1;
+                }
+                switch (dir) {
+                    case 'top':
+                        var next = dropNode.get('nextSibling');
+                        if (next) {
+                            dropNode = next;
+                        } else {
+                            append = true;
+                        }
+                        break;
+                    case 'bottom':
+                        break;
+                    case 'right':
+                    case 'left':
+                        break;
+                }
+ 
+ 
+            if ((dropNode !== null) && dir) {
+                if (dropNode && dropNode.get('parentNode')) {
+                    if (!append) {
+                        dropNode.get('parentNode').insertBefore(dragNode, dropNode);
+                    } else {
+                        dropNode.get('parentNode').appendChild(dragNode);
+                    }
+                }
+            }
+            //Resync all the targets because something moved..
+            Y.Lang.later(50, Y, function() {
+                Y.DD.DDM.syncActiveShims(true);
+            });
+        }
+    };
+ 
+    /*
+    Handle the drop:enter event
+    Now when we get a drop enter event, we check to see if the target is an LI, then we know it's out module.
+    Here is where we move the module around in the DOM.    
+    */
+    Y.Portal.on('drop:enter', function(e) {
+        if (!e.drag || !e.drop || (e.drop !== e.target)) {
+            return false;
+        }
+        if (e.drop.get('node').get('tagName').toLowerCase() === 'li') {
+            if (e.drop.get('node').hasClass('item')) {
+                _moveMod(e.drag, e.drop);
+            }
+        }
+    });
+ 
+    //Handle the drag:drag event
+    //On drag we need to know if they are moved up or down so we can place the module in the proper DOM location.
+    Y.Portal.on('drag:drag', function(e) {
+        var y = e.target.mouseXY[1];
+        if (y < lastY) {
+            goingUp = true;
+        } else {
+            goingUp = false;
+        }
+        lastY = y;
+    });
+ 
+    /*
+    Handle the drop:hit event
+    Now that we have a drop on the target, we check to see if the drop was not on a LI.
+    This means they dropped on the empty space of the UL.
+    */
+    Y.Portal.on('drag:drophit', function(e) {
+        var drop = e.drop.get('node'),
+            drag = e.drag.get('node');
+ 
+        if (drop.get('tagName').toLowerCase() !== 'li') {
+            if (!drop.contains(drag)) {
+                drop.appendChild(drag);
+            }
+        }
+    });
+ 
+    //Handle the drag:start event
+    //Use some CSS here to make our dragging better looking.
+    Y.Portal.on('drag:start', function(e) {
+        var drag = e.target;
+        if (drag.target) {
+            drag.target.set('locked', true);
+        }
+        drag.get('dragNode').set('innerHTML', drag.get('node').get('innerHTML'));
+        drag.get('dragNode').setStyle('opacity','.5');
+        drag.get('node').query('div.mod').setStyle('visibility', 'hidden');
+        drag.get('node').addClass('moving');
+    });
+ 
+    //Handle the drag:end event
+    //Replace some of the styles we changed on start drag.
+    Y.Portal.on('drag:end', function(e) {
+        var drag = e.target;
+        if (drag.target) {
+            drag.target.set('locked', false);
+        }
+        drag.get('node').setStyle('visibility', '');
+        drag.get('node').query('div.mod').setStyle('visibility', '');
+        drag.get('node').removeClass('moving');
+        drag.get('dragNode').set('innerHTML', '');
+        _setCookies();
+    });
+ 
+ 
+    //Handle going over a UL, for empty lists
+    Y.Portal.on('drop:over', function(e) {
+        var drop = e.drop.get('node'),
+            drag = e.drag.get('node');
+ 
+        if (drop.get('tagName').toLowerCase() !== 'li') {
+            if (!drop.contains(drag)) {
+                drop.appendChild(drag);
+                Y.Lang.later(50, Y, function() {
+                    Y.DD.DDM.syncActiveShims(true);
+                });
+            }
+        }
+    });
+ 
+    //Create simple targets for the main lists..
+    var uls = Y.all('#play ul.list');
+    uls.each(function(v, k) {
+        var tar = new Y.DD.Drop({
+            node: v,
+            padding: '20 0',
+            bubbles: Y.Portal
+        });
+    });
+ 
+ 
+    Y.on('io:xdrReady', function() {
+        //Get the cookie data
+        var cookie = Y.Cookie.getSub('yui', 'portal');
+        if (cookie) {
+            //JSON parse the stored data
+            var obj = Y.JSON.parse(cookie);
+ 
+            //Walk the data
+            Y.each(obj, function(v, k) {
+                //Get the node for the list
+                var list = Y.Node.get('#' + k);
+                //Walk the items in this list
+                Y.each(v, function(v2, k2) {
+                    //Get the drag for it
+                    var drag = Y.DD.DDM.getDrag('#' + v2.id);
+                    //Create the module
+                    var mod = createMod(drag.get('data'));
+                    if (v2.min) {
+                        //If it's minned add some CSS
+                        mod.query('div.mod').addClass('minned');
+                        mod.query('div.inner').setStyle('height', '0px');
+                    }
+                    //Add it to the list
+                    list.appendChild(mod);
+                    //Set the drag listeners
+                    drag.get('node').addClass('disabled');
+                    drag.set('node', mod);
+                    drag.set('dragNode', Y.DD.DDM._proxy);
+                    drag.detachAll('drag:start');
+                    drag.detachAll('drag:end');
+                    drag.detachAll('drag:drophit');
+                    drag._unprep();
+                    //Setup the new Drag listeners
+                    setupModDD(mod, drag.get('data'), drag);
+                });
+            });
+        }
+    });
+ 
+});
+ +
+ +
+
+ + + +
+ +
+

Copyright © 2009 Yahoo! Inc. All rights reserved.

+

Privacy Policy - + Terms of Service - + Copyright Policy - + Job Openings

+
+
+ + + + + +