You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

app.js 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. var Gogits = {
  2. "PageIsSignup": false
  3. };
  4. (function ($) {
  5. // extend jQuery ajax, set csrf token value
  6. var ajax = $.ajax;
  7. $.extend({
  8. ajax: function (url, options) {
  9. if (typeof url === 'object') {
  10. options = url;
  11. url = undefined;
  12. }
  13. options = options || {};
  14. url = options.url;
  15. var csrftoken = $('meta[name=_csrf]').attr('content');
  16. var headers = options.headers || {};
  17. var domain = document.domain.replace(/\./ig, '\\.');
  18. if (!/^(http:|https:).*/.test(url) || eval('/^(http:|https:)\\/\\/(.+\\.)*' + domain + '.*/').test(url)) {
  19. headers = $.extend(headers, {'X-Csrf-Token': csrftoken});
  20. }
  21. options.headers = headers;
  22. var callback = options.success;
  23. options.success = function (data) {
  24. if (data.once) {
  25. // change all _once value if ajax data.once exist
  26. $('[name=_once]').val(data.once);
  27. }
  28. if (callback) {
  29. callback.apply(this, arguments);
  30. }
  31. };
  32. return ajax(url, options);
  33. },
  34. changeHash: function (hash) {
  35. if (history.pushState) {
  36. history.pushState(null, null, hash);
  37. }
  38. else {
  39. location.hash = hash;
  40. }
  41. },
  42. deSelect: function () {
  43. if (window.getSelection) {
  44. window.getSelection().removeAllRanges();
  45. } else {
  46. document.selection.empty();
  47. }
  48. }
  49. });
  50. $.fn.extend({
  51. toggleHide: function () {
  52. $(this).addClass("hidden");
  53. },
  54. toggleShow: function () {
  55. $(this).removeClass("hidden");
  56. }
  57. })
  58. }(jQuery));
  59. (function ($) {
  60. Gogits.showTab = function (selector, index) {
  61. if (!index) {
  62. index = 0;
  63. }
  64. $(selector).tab("show");
  65. $(selector).find("li:eq(" + index + ") a").tab("show");
  66. };
  67. Gogits.validateForm = function (selector, options) {
  68. var $form = $(selector);
  69. options = options || {};
  70. options.showErrors = function (map, list) {
  71. var $error = $form.find('.form-error').addClass('hidden');
  72. $('.has-error').removeClass("has-error");
  73. $error.text(list[0].message).show().removeClass("hidden");
  74. $(list[0].element).parents(".form-group").addClass("has-error");
  75. };
  76. $form.validate(options);
  77. };
  78. // ----- init elements
  79. Gogits.initModals = function () {
  80. var modals = $("[data-toggle=modal]");
  81. if (modals.length < 1) {
  82. return;
  83. }
  84. $.each(modals, function (i, item) {
  85. var hide = $(item).data('modal');
  86. $(item).modal(hide ? hide : "hide");
  87. });
  88. };
  89. Gogits.initTooltips = function () {
  90. $("body").tooltip({
  91. selector: "[data-toggle=tooltip]"
  92. //container: "body"
  93. });
  94. };
  95. Gogits.initPopovers = function () {
  96. var hideAllPopovers = function () {
  97. $('[data-toggle=popover]').each(function () {
  98. $(this).popover('hide');
  99. });
  100. };
  101. $(document).on('click', function (e) {
  102. var $e = $(e.target);
  103. if ($e.data('toggle') == 'popover' || $e.parents("[data-toggle=popover], .popover").length > 0) {
  104. return;
  105. }
  106. hideAllPopovers();
  107. });
  108. $("body").popover({
  109. selector: "[data-toggle=popover]"
  110. });
  111. };
  112. Gogits.initTabs = function () {
  113. var $tabs = $('[data-init=tabs]');
  114. $tabs.tab("show");
  115. $tabs.find("li:eq(0) a").tab("show");
  116. };
  117. // fix dropdown inside click
  118. Gogits.initDropDown = function () {
  119. $('.dropdown-menu.no-propagation').on('click', function (e) {
  120. e.stopPropagation();
  121. });
  122. };
  123. // render markdown
  124. Gogits.renderMarkdown = function () {
  125. var $md = $('.markdown');
  126. var $pre = $md.find('pre > code').parent();
  127. $pre.addClass('prettyprint linenums');
  128. prettyPrint();
  129. // Set anchor.
  130. var headers = {};
  131. $md.find('h1, h2, h3, h4, h5, h6').each(function () {
  132. var node = $(this);
  133. var val = encodeURIComponent(node.text().toLowerCase().replace(/[^\w\- ]/g, '').replace(/[ ]/g, '-'));
  134. var name = val;
  135. if (headers[val] > 0) {
  136. name = val + '-' + headers[val];
  137. }
  138. if (headers[val] == undefined) {
  139. headers[val] = 1;
  140. } else {
  141. headers[val] += 1;
  142. }
  143. node = node.wrap('<div id="' + name + '" class="anchor-wrap" ></div>');
  144. node.append('<a class="anchor" href="#' + name + '"><span class="octicon octicon-link"></span></a>');
  145. });
  146. };
  147. Gogits.renderCodeView = function () {
  148. function selectRange($list, $select, $from) {
  149. $list.removeClass('active');
  150. if ($from) {
  151. var a = parseInt($select.attr('rel').substr(1));
  152. var b = parseInt($from.attr('rel').substr(1));
  153. var c;
  154. if (a != b) {
  155. if (a > b) {
  156. c = a;
  157. a = b;
  158. b = c;
  159. }
  160. var classes = [];
  161. for (i = a; i <= b; i++) {
  162. classes.push('.L' + i);
  163. }
  164. $list.filter(classes.join(',')).addClass('active');
  165. $.changeHash('#L' + a + '-' + 'L' + b);
  166. return
  167. }
  168. }
  169. $select.addClass('active');
  170. $.changeHash('#' + $select.attr('rel'));
  171. }
  172. $(document).on('click', '.lines-num span', function (e) {
  173. var $select = $(this);
  174. var $list = $select.parent().siblings('.lines-code').find('ol.linenums > li');
  175. selectRange($list, $list.filter('[rel=' + $select.attr('rel') + ']'), (e.shiftKey ? $list.filter('.active').eq(0) : null));
  176. $.deSelect();
  177. });
  178. $('.code-view .lines-code > pre').each(function () {
  179. var $pre = $(this);
  180. var $lineCode = $pre.parent();
  181. var $lineNums = $lineCode.siblings('.lines-num');
  182. if ($lineNums.length > 0) {
  183. var nums = $pre.find('ol.linenums > li').length;
  184. for (var i = 1; i <= nums; i++) {
  185. $lineNums.append('<span id="L' + i + '" rel="L' + i + '">' + i + '</span>');
  186. }
  187. }
  188. });
  189. $(window).on('hashchange',function (e) {
  190. var m = window.location.hash.match(/^#(L\d+)\-(L\d+)$/);
  191. var $list = $('.code-view ol.linenums > li');
  192. if (m) {
  193. var $first = $list.filter('.' + m[1]);
  194. selectRange($list, $first, $list.filter('.' + m[2]));
  195. $("html, body").scrollTop($first.offset().top - 200);
  196. return;
  197. }
  198. m = window.location.hash.match(/^#(L\d+)$/);
  199. if (m) {
  200. var $first = $list.filter('.' + m[1]);
  201. selectRange($list, $first);
  202. $("html, body").scrollTop($first.offset().top - 200);
  203. }
  204. }).trigger('hashchange');
  205. };
  206. })(jQuery);
  207. // ajax utils
  208. (function ($) {
  209. Gogits.ajaxDelete = function (url, data, success) {
  210. data = data || {};
  211. data._method = "DELETE";
  212. $.ajax({
  213. url: url,
  214. data: data,
  215. method: "POST",
  216. dataType: "json",
  217. success: function (json) {
  218. if (success) {
  219. success(json);
  220. }
  221. }
  222. })
  223. }
  224. })(jQuery);
  225. function initCore() {
  226. Gogits.initTooltips();
  227. Gogits.initPopovers();
  228. Gogits.initTabs();
  229. Gogits.initModals();
  230. Gogits.initDropDown();
  231. Gogits.renderMarkdown();
  232. Gogits.renderCodeView();
  233. }
  234. function initRegister() {
  235. $.getScript("/js/jquery.validate.min.js", function () {
  236. Gogits.validateForm("#login-card", {
  237. rules: {
  238. "username": {
  239. required: true,
  240. maxlength: 30
  241. },
  242. "email": {
  243. required: true,
  244. email: true
  245. },
  246. "passwd": {
  247. required: true,
  248. minlength: 6,
  249. maxlength: 30
  250. },
  251. "re-passwd": {
  252. required: true,
  253. equalTo: "input[name=passwd]"
  254. }
  255. }
  256. });
  257. });
  258. }
  259. function initUserSetting() {
  260. $('#ssh-keys .delete').confirmation({
  261. singleton: true,
  262. onConfirm: function (e, $this) {
  263. Gogits.ajaxDelete("", {"id": $this.data("del")}, function (json) {
  264. if (json.ok) {
  265. window.location.reload();
  266. } else {
  267. alert(json.err);
  268. }
  269. });
  270. }
  271. });
  272. }
  273. function initRepository() {
  274. // clone group button script
  275. (function () {
  276. var $clone = $('.clone-group-btn');
  277. if ($clone.length) {
  278. var $url = $('.clone-group-url');
  279. $clone.find('button[data-link]').on("click",function (e) {
  280. var $this = $(this);
  281. if (!$this.hasClass('btn-primary')) {
  282. $clone.find('.input-group-btn .btn-primary').removeClass('btn-primary').addClass("btn-default");
  283. $(this).addClass('btn-primary').removeClass('btn-default');
  284. $url.val($this.data("link"));
  285. $clone.find('span.clone-url').text($this.data('link'));
  286. }
  287. }).eq(0).trigger("click");
  288. // todo copy to clipboard
  289. }
  290. })();
  291. // watching script
  292. (function () {
  293. var $watch = $('#repo-watching'),
  294. watchLink = $watch.data("watch"),
  295. unwatchLink = $watch.data("unwatch");
  296. $watch.on('click', '.to-watch',function () {
  297. if ($watch.hasClass("watching")) {
  298. return false;
  299. }
  300. $.get(watchLink, function (json) {
  301. if (json.ok) {
  302. $watch.find('.text-primary').removeClass('text-primary');
  303. $watch.find('.to-watch h4').addClass('text-primary');
  304. $watch.find('.fa-eye-slash').removeClass('fa-eye-slash').addClass('fa-eye');
  305. $watch.removeClass("no-watching").addClass("watching");
  306. }
  307. });
  308. return false;
  309. }).on('click', '.to-unwatch', function () {
  310. if ($watch.hasClass("no-watching")) {
  311. return false;
  312. }
  313. $.get(unwatchLink, function (json) {
  314. if (json.ok) {
  315. $watch.find('.text-primary').removeClass('text-primary');
  316. $watch.find('.to-unwatch h4').addClass('text-primary');
  317. $watch.find('.fa-eye').removeClass('fa-eye').addClass('fa-eye-slash');
  318. $watch.removeClass("watching").addClass("no-watching");
  319. }
  320. });
  321. return false;
  322. });
  323. })();
  324. // repo diff counter
  325. (function () {
  326. var $counter = $('.diff-counter');
  327. if ($counter.length < 1) {
  328. return;
  329. }
  330. $counter.each(function (i, item) {
  331. var $item = $(item);
  332. var addLine = $item.find('span[data-line].add').data("line");
  333. var delLine = $item.find('span[data-line].del').data("line");
  334. var addPercent = parseFloat(addLine) / (parseFloat(addLine) + parseFloat(delLine)) * 100;
  335. $item.find(".bar .add").css("width", addPercent + "%");
  336. });
  337. }());
  338. }
  339. function initInstall() {
  340. // database type change
  341. $('#install-database').on("change", function () {
  342. var val = $(this).val();
  343. if (val != "sqlite") {
  344. $('.server-sql').show();
  345. $('.sqlite-setting').addClass("hide");
  346. if (val == "pgsql") {
  347. $('.pgsql-setting').removeClass("hide");
  348. } else {
  349. $('.pgsql-setting').addClass("hide");
  350. }
  351. } else {
  352. $('.server-sql').hide();
  353. $('.sqlite-setting').removeClass("hide");
  354. }
  355. });
  356. }
  357. function initIssue() {
  358. // close button
  359. (function () {
  360. var $closeBtn = $('#issue-close-btn');
  361. var $openBtn = $('#issue-open-btn');
  362. $('#issue-reply-content').on("keyup", function () {
  363. if ($(this).val().length) {
  364. $closeBtn.text($closeBtn.data("text"));
  365. $openBtn.text($openBtn.data("text"));
  366. } else {
  367. $closeBtn.text($closeBtn.data("origin"));
  368. $openBtn.text($openBtn.data("origin"));
  369. }
  370. });
  371. }());
  372. // issue edit mode
  373. (function () {
  374. $("#issue-edit-btn").on("click", function () {
  375. $('#issue h1.title,#issue .issue-main > .issue-content .content,#issue-edit-btn').toggleHide();
  376. $('#issue-edit-title,#issue-edit-content,.issue-edit-cancel,.issue-edit-save').toggleShow();
  377. });
  378. $('.issue-edit-cancel').on("click", function () {
  379. $('#issue h1.title,#issue .issue-main > .issue-content .content,#issue-edit-btn').toggleShow();
  380. $('#issue-edit-title,#issue-edit-content,.issue-edit-cancel,.issue-edit-save').toggleHide();
  381. })
  382. }());
  383. }
  384. (function ($) {
  385. $(function () {
  386. initCore();
  387. var body = $("#body");
  388. if (body.data("page") == "user-signup") {
  389. initRegister();
  390. }
  391. if (body.data("page") == "user") {
  392. initUserSetting();
  393. }
  394. if ($('.repo-nav').length) {
  395. initRepository();
  396. }
  397. if ($('#install-card').length) {
  398. initInstall();
  399. }
  400. if ($('#issue').length) {
  401. initIssue();
  402. }
  403. });
  404. })(jQuery);