The version of vichan running on lainchan.org
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

212 linhas
5.9KB

  1. /*
  2. * post-menu.js - adds dropdown menu to posts
  3. *
  4. * Creates a global Menu object with four public methods:
  5. *
  6. * Menu.onclick(fnc)
  7. * registers a function to be executed after button click, before the menu is displayed
  8. * Menu.add_item(id, text[, title])
  9. * adds an item to the top level of menu
  10. * Menu.add_submenu(id, text)
  11. * creates and returns a List object through which to manipulate the content of the submenu
  12. * Menu.get_submenu(id)
  13. * returns the submenu with the specified id from the top level menu
  14. *
  15. * The List object contains all the methods from Menu except onclick()
  16. *
  17. * Example usage:
  18. * Menu.add_item('filter-menu-hide', 'Hide post');
  19. * Menu.add_item('filter-menu-unhide', 'Unhide post');
  20. *
  21. * submenu = Menu.add_submenu('filter-menu-add', 'Add filter');
  22. * submenu.add_item('filter-add-post-plus', 'Post +', 'Hide post and all replies');
  23. * submenu.add_item('filter-add-id', 'ID');
  24. *
  25. * Usage:
  26. * $config['additional_javascript'][] = 'js/jquery.min.js';
  27. * $config['additional_javascript'][] = 'js/post-menu.js';
  28. */
  29. $(document).ready(function () {
  30. var List = function (menuId, text) {
  31. this.id = menuId;
  32. this.text = text;
  33. this.items = [];
  34. this.add_item = function (itemId, text, title) {
  35. this.items.push(new Item(itemId, text, title));
  36. };
  37. this.list_items = function () {
  38. var array = [];
  39. var i, length, obj, $ele;
  40. if ($.isEmptyObject(this.items))
  41. return;
  42. length = this.items.length;
  43. for (i = 0; i < length; i++) {
  44. obj = this.items[i];
  45. $ele = $('<li>', {id: obj.id}).text(obj.text);
  46. if ('title' in obj) $ele.attr('title', obj.title);
  47. if (obj instanceof Item) {
  48. $ele.addClass('post-item');
  49. } else {
  50. $ele.addClass('post-submenu');
  51. $ele.prepend(obj.list_items());
  52. $ele.append($('<span>', {class: 'post-menu-arrow'}).text('»'));
  53. }
  54. array.push($ele);
  55. }
  56. return $('<ul>').append(array);
  57. };
  58. this.add_submenu = function (menuId, text) {
  59. var ele = new List(menuId, text);
  60. this.items.push(ele);
  61. return ele;
  62. };
  63. this.get_submenu = function (menuId) {
  64. for (var i = 0; i < this.items.length; i++) {
  65. if ((this.items[i] instanceof Item) || this.items[i].id != menuId) continue;
  66. return this.items[i];
  67. }
  68. };
  69. };
  70. var Item = function (itemId, text, title) {
  71. this.id = itemId;
  72. this.text = text;
  73. // optional
  74. if (typeof title != 'undefined') this.title = title;
  75. };
  76. function buildMenu(e) {
  77. var pos = $(e.target).offset();
  78. var i, length;
  79. var $menu = $('<div class="post-menu"></div>').append(mainMenu.list_items());
  80. // execute registered click handlers
  81. length = onclick_callbacks.length;
  82. for (i = 0; i < length; i++) {
  83. onclick_callbacks[i](e, $menu);
  84. }
  85. // set menu position and append to page
  86. $menu.css({top: pos.top, left: pos.left + 20});
  87. $('body').append($menu);
  88. }
  89. function addButton(post) {
  90. var $ele = $(post);
  91. $ele.find('input.delete').after(
  92. $('<a>', {href: '#', class: 'post-btn', title: 'Post menu'}).text('▶')
  93. );
  94. }
  95. /* * * * * * * * * *
  96. Public methods
  97. * * * * * * * * * */
  98. var Menu = {};
  99. var mainMenu = new List();
  100. var onclick_callbacks = [];
  101. Menu.onclick = function (fnc) {
  102. onclick_callbacks.push(fnc);
  103. };
  104. Menu.add_item = function (itemId, text, title) {
  105. mainMenu.add_item(itemId, text, title);
  106. };
  107. Menu.add_submenu = function (menuId, text) {
  108. return mainMenu.add_submenu(menuId, text);
  109. };
  110. Menu.get_submenu = function (id) {
  111. return mainMenu.get_submenu(id);
  112. };
  113. window.Menu = Menu;
  114. /* * * * * * * *
  115. Initialize
  116. * * * * * * * */
  117. /* Styling
  118. */
  119. var $ele, cssStyle, cssString;
  120. $ele = $('<div>').addClass('post reply').hide().appendTo('body');
  121. cssStyle = $ele.css(['border-top-color']);
  122. cssStyle.hoverBg = $('body').css('background-color');
  123. $ele.remove();
  124. cssString =
  125. '\n/*** Generated by post-menu ***/\n' +
  126. '.post-menu {position: absolute; font-size: 12px; line-height: 1.3em;}\n' +
  127. '.post-menu ul {\n' +
  128. ' background-color: '+ cssStyle['border-top-color'] +'; border: 1px solid #666;\n' +
  129. ' list-style: none; padding: 0; margin: 0; white-space: nowrap;\n}\n' +
  130. '.post-menu .post-submenu{white-space: normal; width: 90px;}' +
  131. '.post-menu .post-submenu>ul{white-space: nowrap; width: auto;}' +
  132. '.post-menu li {cursor: pointer; position: relative; padding: 4px 4px; vertical-align: middle;}\n' +
  133. '.post-menu li:hover {background-color: '+ cssStyle.hoverBg +';}\n' +
  134. '.post-menu ul ul {display: none; position: absolute;}\n' +
  135. '.post-menu li:hover>ul {display: block; left: 100%; margin-top: -3px;}\n' +
  136. '.post-menu-arrow {float: right; margin-left: 10px;}\n' +
  137. '.post-menu.hidden, .post-menu .hidden {display: none;}\n' +
  138. '.post-btn {transition: transform 0.1s; width: 15px; text-align: center; font-size: 10pt; opacity: 0.8; text-decoration: none; margin: -6px 0px 0px -5px !important; display: inline-block;}\n' +
  139. '.post-btn:hover {opacity: 1;}\n' +
  140. '.post-btn-open {transform: rotate(90deg);}\n';
  141. if (!$('style.generated-css').length) $('<style class="generated-css">').appendTo('head');
  142. $('style.generated-css').html($('style.generated-css').html() + cssString);
  143. /* Add buttons
  144. */
  145. $('.reply:not(.hidden), .thread>.op').each(function () {
  146. addButton(this);
  147. });
  148. /* event handlers
  149. */
  150. $('form[name=postcontrols]').on('click', '.post-btn', function (e) {
  151. e.preventDefault();
  152. var post = e.target.parentElement.parentElement;
  153. $('.post-menu').remove();
  154. if ($(e.target).hasClass('post-btn-open')) {
  155. $('.post-btn-open').removeClass('post-btn-open');
  156. } else {
  157. // close previous button
  158. $('.post-btn-open').removeClass('post-btn-open');
  159. $(post).find('.post-btn').addClass('post-btn-open');
  160. buildMenu(e);
  161. }
  162. });
  163. $(document).on('click', function (e){
  164. if ($(e.target).hasClass('post-btn') || $(e.target).hasClass('post-submenu'))
  165. return;
  166. $('.post-menu').remove();
  167. $('.post-btn-open').removeClass('post-btn-open');
  168. });
  169. // on new posts
  170. $(document).on('new_post', function (e, post) {
  171. addButton(post);
  172. });
  173. $(document).trigger('menu_ready');
  174. });