diff options
| author | marktaiwan <mark.taiwan@gmail.com> | 2015-02-24 16:04:00 +0800 |
|---|---|---|
| committer | czaks <marcin@6irc.net> | 2016-05-05 12:29:11 +0200 |
| commit | af91ddf63737fb368c77860d9762cc062690c713 (patch) | |
| tree | 256905436f84dae14fa3582820a6f69e052b36a0 /js/post-menu.js | |
| parent | e3dbca561601e39ca9235575ae55f5f7075d3fd9 (diff) | |
Split post menu into own function
Diffstat (limited to 'js/post-menu.js')
| -rw-r--r-- | js/post-menu.js | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/js/post-menu.js b/js/post-menu.js new file mode 100644 index 00000000..edf66ebb --- /dev/null +++ b/js/post-menu.js @@ -0,0 +1,209 @@ +/* + * post-menu.js - adds dropdown menu to posts + * + * Creates a global Menu object with four public methods: + * + * Menu.onclick(fnc) + * registers a function to be executed after button click, before the menu is displayed + * Menu.add_item(id, text[, title]) + * adds an item to the top level of menu + * Menu.add_submenu(id, text) + * creates and returns a List object through which to manipulate the content of the submenu + * Menu.get_submenu(id) + * returns the submenu with the specified id from the top level menu + * + * The List object contains all the methods from Menu except onclick() + * + * Example usage: + * Menu.add_item('filter-menu-hide', 'Hide post'); + * Menu.add_item('filter-menu-unhide', 'Unhide post'); + * + * submenu = Menu.add_submenu('filter-menu-add', 'Add filter'); + * submenu.add_item('filter-add-post-plus', 'Post +', 'Hide post and all replies'); + * submenu.add_item('filter-add-id', 'ID'); + * + * Usage: + * $config['additional_javascript'][] = 'js/jquery.min.js'; + * $config['additional_javascript'][] = 'js/post-menu.js'; + */ +(function () { + +var List = function (menuId, text) { + this.id = menuId; + this.text = text; + this.items = []; + + this.add_item = function (itemId, text, title) { + this.items.push(new Item(itemId, text, title)); + }; + this.list_items = function () { + var array = []; + var i, length, obj, $ele; + + if ($.isEmptyObject(this.items)) + return; + + length = this.items.length; + for (i = 0; i < length; i++) { + obj = this.items[i]; + + $ele = $('<li>', {id: obj.id}).text(obj.text); + if ('title' in obj) $ele.attr('title', obj.title); + + if (obj instanceof Item) { + $ele.addClass('post-item'); + } else { + $ele.addClass('post-submenu'); + + $ele.prepend(obj.list_items()); + $ele.append($('<span>', {class: 'post-menu-arrow'}).text('»')); + } + + array.push($ele); + } + + return $('<ul>').append(array); + }; + this.add_submenu = function (menuId, text) { + var ele = new List(menuId, text); + this.items.push(ele); + return ele; + }; + this.get_submenu = function (menuId) { + for (var i = 0; i < this.items.length; i++) { + if ((this.items[i] instanceof Item) || this.items[i].id != menuId) continue; + return this.items[i]; + } + }; +}; + +var Item = function (itemId, text, title) { + this.id = itemId; + this.text = text; + + // optional + if (typeof title != 'undefined') this.title = title; +}; + +function buildMenu(e) { + var pos = $(e.target).offset(); + var i, length; + + var $menu = $('<div class="post-menu"></div>').append(mainMenu.list_items()); + + // execute registered click handlers + length = onclick_callbacks.length; + for (i = 0; i < length; i++) { + onclick_callbacks[i](e, $menu); + } + + // set menu position and append to page + $menu.css({top: pos.top, left: pos.left + 20}); + $('body').append($menu); +} + +function addButton(post) { + var $ele = $(post); + $ele.find('input.delete').after( + $('<a>', {href: '#', class: 'post-btn', title: 'Post menu'}).text('▶') + ); +} + + +/* * * * * * * * * * + Public methods + * * * * * * * * * */ +var Menu = {}; +var mainMenu = new List(); +var onclick_callbacks = []; + +Menu.onclick = function (fnc) { + onclick_callbacks.push(fnc); +}; + +Menu.add_item = function (itemId, text, title) { + mainMenu.add_item(itemId, text, title); +}; + +Menu.add_submenu = function (menuId, text) { + return mainMenu.add_submenu(menuId, text); +}; + +Menu.get_submenu = function (id) { + return mainMenu.get_submenu(id); +}; + + +/* * * * * * * * + Initialize + * * * * * * * */ + +/* Styling + */ +var $ele, cssStyle, cssString; + +$ele = $('<div>').addClass('post reply').hide().appendTo('body'); +cssStyle = $ele.css(['border-top-color']); +cssStyle.hoverBg = $('body').css('background-color'); +$ele.remove(); + +cssString = + '\n/*** Generated by post-menu ***/\n' + + '.post-menu {position: absolute; font-size: 12px; line-height: 1.3em;}\n' + + '.post-menu ul {\n' + + ' background-color: '+ cssStyle['border-top-color'] +'; border: 1px solid #666;\n' + + ' list-style: none; padding: 0; margin: 0; white-space: nowrap;\n}\n' + + '.post-menu .post-submenu{white-space: normal; width: 90px;}' + + '.post-menu .post-submenu>ul{white-space: nowrap; width: auto;}' + + '.post-menu li {cursor: pointer; position: relative; padding: 4px 4px; vertical-align: middle;}\n' + + '.post-menu li:hover {background-color: '+ cssStyle.hoverBg +';}\n' + + '.post-menu ul ul {display: none; position: absolute;}\n' + + '.post-menu li:hover>ul {display: block; left: 100%; margin-top: -3px;}\n' + + '.post-menu-arrow {float: right; margin-left: 10px;}\n' + + '.post-menu.hidden, .post-menu .hidden {display: none;}\n' + + '.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' + + '.post-btn:hover {opacity: 1;}\n' + + '.post-btn-open {transform: rotate(90deg);}\n'; + +if (!$('style.generated-css').length) $('<style class="generated-css">').appendTo('head'); +$('style.generated-css').html($('style.generated-css').html() + cssString); + +/* Add buttons + */ +$('.reply:not(.hidden), .thread>.op').each(function () { + addButton(this); + }); + + /* event handlers + */ +$('form[name=postcontrols]').on('click', '.post-btn', function (e) { + e.preventDefault(); + var post = e.target.parentElement.parentElement; + $('.post-menu').remove(); + + if ($(e.target).hasClass('post-btn-open')) { + $('.post-btn-open').removeClass('post-btn-open'); + } else { + // close previous button + $('.post-btn-open').removeClass('post-btn-open'); + $(post).find('.post-btn').addClass('post-btn-open'); + + buildMenu(e); + } +}); + +$(document).on('click', function (e){ + if ($(e.target).hasClass('post-btn') || $(e.target).hasClass('post-submenu')) + return; + + $('.post-menu').remove(); + $('.post-btn-open').removeClass('post-btn-open'); +}); + +// on new posts +$(document).on('new_post', function (e, post) { + addButton(post); +}); + +window.Menu = Menu; +})(); |
