_index.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. var MUB = {
  2. _uid : 0
  3. ,_minRoot : '/min/?'
  4. ,checkRewrite : function () {
  5. var testUri = location.pathname.replace(/\/[^\/]*$/, '/rewriteTest.js').substr(1);
  6. function fail() {
  7. $('#minRewriteFailed')[0].className = 'topNote';
  8. };
  9. $.ajax({
  10. url : '../f=' + testUri + '&' + (new Date()).getTime()
  11. ,success : function (data) {
  12. if (data === '1') {
  13. MUB._minRoot = '/min/';
  14. $('span.minRoot').html('/min/');
  15. } else
  16. fail();
  17. }
  18. ,error : fail
  19. });
  20. }
  21. /**
  22. * Get markup for new source LI element
  23. */
  24. ,newLi : function () {
  25. return '<li id="li' + MUB._uid + '">http://' + location.host + '/<input type=text size=20>'
  26. + ' <button title="Remove">x</button> <button title="Include Earlier">&uarr;</button>'
  27. + ' <button title="Include Later">&darr;</button> <span></span></li>';
  28. }
  29. /**
  30. * Add new empty source LI and attach handlers to buttons
  31. */
  32. ,addLi : function () {
  33. $('#sources').append(MUB.newLi());
  34. var li = $('#li' + MUB._uid)[0];
  35. $('button[title=Remove]', li).click(function () {
  36. $('#results').hide();
  37. var hadValue = !!$('input', li)[0].value;
  38. $(li).remove();
  39. });
  40. $('button[title$=Earlier]', li).click(function () {
  41. $(li).prev('li').find('input').each(function () {
  42. $('#results').hide();
  43. // this = previous li input
  44. var tmp = this.value;
  45. this.value = $('input', li).val();
  46. $('input', li).val(tmp);
  47. MUB.updateAllTestLinks();
  48. });
  49. });
  50. $('button[title$=Later]', li).click(function () {
  51. $(li).next('li').find('input').each(function () {
  52. $('#results').hide();
  53. // this = next li input
  54. var tmp = this.value;
  55. this.value = $('input', li).val();
  56. $('input', li).val(tmp);
  57. MUB.updateAllTestLinks();
  58. });
  59. });
  60. ++MUB._uid;
  61. }
  62. /**
  63. * In the context of a source LI element, this will analyze the URI in
  64. * the INPUT and check the URL on the site.
  65. */
  66. ,liUpdateTestLink : function () { // call in context of li element
  67. if (! $('input', this)[0].value)
  68. return;
  69. var li = this;
  70. $('span', this).html('');
  71. var url = 'http://' + location.host + '/'
  72. + $('input', this)[0].value.replace(/^\//, '');
  73. $.ajax({
  74. url : url
  75. ,complete : function (xhr, stat) {
  76. if ('success' == stat)
  77. $('span', li).html('&#x2713;');
  78. else {
  79. $('span', li).html('<button><b>404! </b> recheck</button>')
  80. .find('button').click(function () {
  81. MUB.liUpdateTestLink.call(li);
  82. });
  83. }
  84. }
  85. ,dataType : 'text'
  86. });
  87. }
  88. /**
  89. * Check all source URLs
  90. */
  91. ,updateAllTestLinks : function () {
  92. $('#sources li').each(MUB.liUpdateTestLink);
  93. }
  94. /**
  95. * In a given array of strings, find the character they all have at
  96. * a particular index
  97. * @param Array arr array of strings
  98. * @param Number pos index to check
  99. * @return mixed a common char or '' if any do not match
  100. */
  101. ,getCommonCharAtPos : function (arr, pos) {
  102. var i
  103. ,l = arr.length
  104. ,c = arr[0].charAt(pos);
  105. if (c === '' || l === 1)
  106. return c;
  107. for (i = 1; i < l; ++i)
  108. if (arr[i].charAt(pos) !== c)
  109. return '';
  110. return c;
  111. }
  112. /**
  113. * Get the shortest URI to minify the set of source files
  114. * @param Array sources URIs
  115. */
  116. ,getBestUri : function (sources) {
  117. var pos = 0
  118. ,base = ''
  119. ,c;
  120. while (true) {
  121. c = MUB.getCommonCharAtPos(sources, pos);
  122. if (c === '')
  123. break;
  124. else
  125. base += c;
  126. ++pos;
  127. }
  128. base = base.replace(/[^\/]+$/, '');
  129. var uri = MUB._minRoot + 'f=' + sources.join(',');
  130. if (base.charAt(base.length - 1) === '/') {
  131. // we have a base dir!
  132. var basedSources = sources
  133. ,i
  134. ,l = sources.length;
  135. for (i = 0; i < l; ++i) {
  136. basedSources[i] = sources[i].substr(base.length);
  137. }
  138. base = base.substr(0, base.length - 1);
  139. var bUri = MUB._minRoot + 'b=' + base + '&f=' + basedSources.join(',');
  140. //window.console && console.log([uri, bUri]);
  141. uri = uri.length < bUri.length
  142. ? uri
  143. : bUri;
  144. }
  145. return uri;
  146. }
  147. /**
  148. * Create the Minify URI for the sources
  149. */
  150. ,update : function () {
  151. MUB.updateAllTestLinks();
  152. var sources = []
  153. ,ext = false
  154. ,fail = false;
  155. $('#sources input').each(function () {
  156. var m, val;
  157. if (! fail && this.value && (m = this.value.match(/\.(css|js)$/))) {
  158. var thisExt = m[1];
  159. if (ext === false)
  160. ext = thisExt;
  161. else if (thisExt !== ext) {
  162. fail = true;
  163. return alert('extensions must match!');
  164. }
  165. this.value = this.value.replace(/^\//, '');
  166. if (-1 != $.inArray(this.value, sources)) {
  167. fail = true;
  168. return alert('duplicate file!');
  169. }
  170. sources.push(this.value);
  171. }
  172. });
  173. if (fail || ! sources.length)
  174. return;
  175. $('#groupConfig').val(" 'keyName' => array('//" + sources.join("', '//") + "'),");
  176. var uri = MUB.getBestUri(sources)
  177. ,uriH = uri.replace(/</, '&lt;').replace(/>/, '&gt;').replace(/&/, '&amp;');
  178. $('#uriA').html(uriH)[0].href = uri;
  179. $('#uriHtml').val(
  180. ext === 'js'
  181. ? '<script type="text/javascript" src="' + uriH + '"></script>'
  182. : '<link type="text/css" rel="stylesheet" href="' + uriH + '" />'
  183. );
  184. $('#results').show();
  185. }
  186. /**
  187. * Handler for the "Add file +" button
  188. */
  189. ,addButtonClick : function () {
  190. $('#results').hide();
  191. MUB.addLi();
  192. MUB.updateAllTestLinks();
  193. $('#update').show().click(MUB.update);
  194. $('#sources li:last input')[0].focus();
  195. }
  196. /**
  197. * Runs on DOMready
  198. */
  199. ,init : function () {
  200. $('#app').show();
  201. $('#sources').html('');
  202. $('#add button').click(MUB.addButtonClick);
  203. // make easier to copy text out of
  204. $('#uriHtml, #groupConfig').click(function () {
  205. this.select();
  206. }).focus(function () {
  207. this.select();
  208. });
  209. $('a.ext').attr({target:'_blank'});
  210. if (location.hash) {
  211. // make links out of URIs from bookmarklet
  212. $('#getBm').hide();
  213. $('#bmUris').html('<p><strong>Found by bookmarklet:</strong> /<a href=#>'
  214. + location.hash.substr(1).split(',').join('</a> | /<a href=#>')
  215. + '</a></p>'
  216. );
  217. $('#bmUris a').click(function () {
  218. MUB.addButtonClick();
  219. $('#sources li:last input').val(this.innerHTML)
  220. MUB.liUpdateTestLink.call($('#sources li:last')[0]);
  221. $('#results').hide();
  222. return false;
  223. }).attr({title:'Add file +'});
  224. } else {
  225. // copy bookmarklet code into href
  226. var bmUri = location.pathname.replace(/\/[^\/]*$/, '/bm.js').substr(1);
  227. $.ajax({
  228. url : '../?f=' + bmUri
  229. ,success : function (code) {
  230. $('#bm')[0].href = code
  231. .replace('%BUILDER_URL%', location.href)
  232. .replace(/\n/g, ' ');
  233. }
  234. ,dataType : 'text'
  235. });
  236. $.browser.msie && $('#getBm p:last').append(' Sorry, not supported in MSIE!');
  237. MUB.addButtonClick();
  238. }
  239. MUB.checkRewrite();
  240. }
  241. };
  242. window.onload = MUB.init;