jquery.desktop.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. //
  2. // Namespace - Module Pattern.
  3. //
  4. var JQD = (function($, window, document, undefined) {
  5. // Expose innards of JQD.
  6. return {
  7. go: function() {
  8. for (var i in JQD.init) {
  9. JQD.init[i]();
  10. }
  11. },
  12. init: {
  13. frame_breaker: function() {
  14. if (window.location !== window.top.location) {
  15. window.top.location = window.location;
  16. }
  17. },
  18. //
  19. // Initialize the clock.
  20. //
  21. clock: function() {
  22. var clock = $('#clock');
  23. if (!clock.length) {
  24. return;
  25. }
  26. // Date variables.
  27. var date_obj = new Date();
  28. var hour = date_obj.getHours();
  29. var minute = date_obj.getMinutes();
  30. var day = date_obj.getDate();
  31. var year = date_obj.getFullYear();
  32. var suffix = 'AM';
  33. // Array for weekday.
  34. var weekday = [
  35. 'Sunday',
  36. 'Monday',
  37. 'Tuesday',
  38. 'Wednesday',
  39. 'Thursday',
  40. 'Friday',
  41. 'Saturday'
  42. ];
  43. // Array for month.
  44. var month = [
  45. 'January',
  46. 'February',
  47. 'March',
  48. 'April',
  49. 'May',
  50. 'June',
  51. 'July',
  52. 'August',
  53. 'September',
  54. 'October',
  55. 'November',
  56. 'December'
  57. ];
  58. // Assign weekday, month, date, year.
  59. weekday = weekday[date_obj.getDay()];
  60. month = month[date_obj.getMonth()];
  61. // AM or PM?
  62. if (hour >= 12) {
  63. suffix = 'PM';
  64. }
  65. // Convert to 12-hour.
  66. if (hour > 12) {
  67. hour = hour - 12;
  68. }
  69. else if (hour === 0) {
  70. // Display 12:XX instead of 0:XX.
  71. hour = 12;
  72. }
  73. // Leading zero, if needed.
  74. if (minute < 10) {
  75. minute = '0' + minute;
  76. }
  77. // Build two HTML strings.
  78. var clock_time = weekday + ' ' + hour + ':' + minute + ' ' + suffix;
  79. var clock_date = month + ' ' + day + ', ' + year;
  80. // Shove in the HTML.
  81. clock.html(clock_time).attr('title', clock_date);
  82. // Update every 60 seconds.
  83. setTimeout(JQD.init.clock, 60000);
  84. },
  85. //
  86. // Initialize the desktop.
  87. //
  88. desktop: function() {
  89. // Alias to document.
  90. var d = $(document);
  91. // Cancel mousedown.
  92. d.mousedown(function(ev) {
  93. var tags = ['a', 'button', 'input', 'select', 'textarea', 'tr'];
  94. if (!$(ev.target).closest(tags).length) {
  95. JQD.util.clear_active();
  96. ev.preventDefault();
  97. ev.stopPropagation();
  98. }
  99. });
  100. // Cancel right-click.
  101. d.on('contextmenu', function() {
  102. return false;
  103. });
  104. // Relative or remote links?
  105. d.on('click', 'a', function(ev) {
  106. var url = $(this).attr('href');
  107. this.blur();
  108. if (url.match(/^#/)) {
  109. ev.preventDefault();
  110. ev.stopPropagation();
  111. }
  112. else {
  113. $(this).attr('target', '_blank');
  114. }
  115. });
  116. // Make top menus active.
  117. d.on('mousedown', 'a.menu_trigger', function() {
  118. if ($(this).next('ul.menu').is(':hidden')) {
  119. JQD.util.clear_active();
  120. $(this).addClass('active').next('ul.menu').show();
  121. }
  122. else {
  123. JQD.util.clear_active();
  124. }
  125. });
  126. // Transfer focus, if already open.
  127. d.on('mouseenter', 'a.menu_trigger', function() {
  128. if ($('ul.menu').is(':visible')) {
  129. JQD.util.clear_active();
  130. $(this).addClass('active').next('ul.menu').show();
  131. }
  132. });
  133. // Cancel single-click.
  134. d.on('mousedown', 'a.icon', function() {
  135. // Highlight the icon.
  136. JQD.util.clear_active();
  137. $(this).addClass('active');
  138. });
  139. // Respond to double-click.
  140. d.on('dblclick', 'a.icon', function() {
  141. // Get the link's target.
  142. var x = $(this).attr('href');
  143. var y = $(x).find('a').attr('href');
  144. // Show the taskbar button.
  145. if ($(x).is(':hidden')) {
  146. $(x).remove().appendTo('#dock');
  147. $(x).show('fast');
  148. }
  149. // Bring window to front.
  150. JQD.util.window_flat();
  151. $(y).addClass('window_stack').show();
  152. });
  153. // Make icons draggable.
  154. d.on('mouseenter', 'a.icon', function() {
  155. $(this).off('mouseenter').draggable({
  156. revert: true,
  157. containment: 'parent'
  158. });
  159. });
  160. // Taskbar buttons.
  161. d.on('click', '#dock a', function() {
  162. // Get the link's target.
  163. var x = $($(this).attr('href'));
  164. // Hide, if visible.
  165. if (x.is(':visible')) {
  166. x.hide();
  167. }
  168. else {
  169. // Bring window to front.
  170. JQD.util.window_flat();
  171. x.show().addClass('window_stack');
  172. }
  173. });
  174. // Focus active window.
  175. d.on('mousedown', 'div.window', function() {
  176. // Bring window to front.
  177. JQD.util.window_flat();
  178. $(this).addClass('window_stack');
  179. });
  180. // Make windows draggable.
  181. d.on('mouseenter', 'div.window', function() {
  182. $(this).off('mouseenter').draggable({
  183. // Confine to desktop.
  184. // Movable via top bar only.
  185. cancel: 'a',
  186. containment: 'parent',
  187. handle: 'div.window_top'
  188. }).resizable({
  189. containment: 'parent',
  190. minWidth: 400,
  191. minHeight: 200
  192. });
  193. });
  194. // Double-click top bar to resize, ala Windows OS.
  195. d.on('dblclick', 'div.window_top', function() {
  196. JQD.util.window_resize(this);
  197. });
  198. // Double click top bar icon to close, ala Windows OS.
  199. d.on('dblclick', 'div.window_top img', function() {
  200. // Traverse to the close button, and hide its taskbar button.
  201. $($(this).closest('div.window_top').find('a.window_close').attr('href')).hide('fast');
  202. // Close the window itself.
  203. $(this).closest('div.window').hide();
  204. // Stop propagation to window's top bar.
  205. return false;
  206. });
  207. // Minimize the window.
  208. d.on('click', 'a.window_min', function() {
  209. $(this).closest('div.window').hide();
  210. });
  211. // Maximize or restore the window.
  212. d.on('click', 'a.window_resize', function() {
  213. JQD.util.window_resize(this);
  214. });
  215. // Close the window.
  216. d.on('click', 'a.window_close', function() {
  217. $(this).closest('div.window').hide();
  218. $($(this).attr('href')).hide('fast');
  219. });
  220. // Show desktop button, ala Windows OS.
  221. d.on('mousedown', '#show_desktop', function() {
  222. // If any windows are visible, hide all.
  223. if ($('div.window:visible').length) {
  224. $('div.window').hide();
  225. }
  226. else {
  227. // Otherwise, reveal hidden windows that are open.
  228. $('#dock li:visible a').each(function() {
  229. $($(this).attr('href')).show();
  230. });
  231. }
  232. });
  233. $('table.data').each(function() {
  234. // Add zebra striping, ala Mac OS X.
  235. $(this).find('tbody tr:odd').addClass('zebra');
  236. });
  237. d.on('mousedown', 'table.data tr', function() {
  238. // Clear active state.
  239. JQD.util.clear_active();
  240. // Highlight row, ala Mac OS X.
  241. $(this).closest('tr').addClass('active');
  242. });
  243. },
  244. wallpaper: function() {
  245. // Add wallpaper last, to prevent blocking.
  246. if ($('#desktop').length) {
  247. $('body').prepend('<img id="wallpaper" class="abs" src="/shares/jqueryDesktop/images/misc/wallpaper.jpg" />');
  248. }
  249. }
  250. },
  251. util: {
  252. //
  253. // Clear active states, hide menus.
  254. //
  255. clear_active: function() {
  256. $('a.active, tr.active').removeClass('active');
  257. $('ul.menu').hide();
  258. },
  259. //
  260. // Zero out window z-index.
  261. //
  262. window_flat: function() {
  263. $('div.window').removeClass('window_stack');
  264. },
  265. //
  266. // Resize modal window.
  267. //
  268. window_resize: function(el) {
  269. // Nearest parent window.
  270. var win = $(el).closest('div.window');
  271. // Is it maximized already?
  272. if (win.hasClass('window_full')) {
  273. // Restore window position.
  274. win.removeClass('window_full').css({
  275. 'top': win.attr('data-t'),
  276. 'left': win.attr('data-l'),
  277. 'right': win.attr('data-r'),
  278. 'bottom': win.attr('data-b'),
  279. 'width': win.attr('data-w'),
  280. 'height': win.attr('data-h')
  281. });
  282. }
  283. else {
  284. win.attr({
  285. // Save window position.
  286. 'data-t': win.css('top'),
  287. 'data-l': win.css('left'),
  288. 'data-r': win.css('right'),
  289. 'data-b': win.css('bottom'),
  290. 'data-w': win.css('width'),
  291. 'data-h': win.css('height')
  292. }).addClass('window_full').css({
  293. // Maximize dimensions.
  294. 'top': '0',
  295. 'left': '0',
  296. 'right': '0',
  297. 'bottom': '0',
  298. 'width': '100%',
  299. 'height': '100%'
  300. });
  301. }
  302. // Bring window to front.
  303. JQD.util.window_flat();
  304. win.addClass('window_stack');
  305. }
  306. }
  307. };
  308. // Pass in jQuery.
  309. })(jQuery, this, this.document);
  310. //
  311. // Kick things off.
  312. //
  313. jQuery(document).ready(function() {
  314. JQD.go();
  315. });