_index.js 9.2 KB

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