From 322a79739dbee9f5a9bb4e012cd75a3d034a8bad Mon Sep 17 00:00:00 2001 From: csarven Date: Fri, 14 Nov 2008 22:35:49 -0500 Subject: trac670 trac689 Favorites (duplicate id, background image, JavaScript) darcs-hash:20081115033549-eefa4-cfbca6f9c723aa63869c39d6851de7a7803f0703.gz --- actions/disfavor.php | 14 ++-- actions/favor.php | 13 ++-- js/util.js | 154 +++++++++++++++++++--------------------- js/xbImportNode.js | 46 ++++++++++++ lib/util.php | 39 ++++++++-- theme/default/display.css | 69 +++++++++--------- theme/default/icon_heart-01.png | Bin 0 -> 872 bytes theme/default/icon_heart-02.png | Bin 0 -> 805 bytes theme/default/ie7.css | 10 ++- theme/identica/display.css | 35 +-------- theme/identica/ie6.css | 8 +++ 11 files changed, 217 insertions(+), 171 deletions(-) create mode 100644 js/xbImportNode.js create mode 100644 theme/default/icon_heart-01.png create mode 100644 theme/default/icon_heart-02.png diff --git a/actions/disfavor.php b/actions/disfavor.php index 35cfd6070..6ac94d720 100644 --- a/actions/disfavor.php +++ b/actions/disfavor.php @@ -37,17 +37,17 @@ class DisfavorAction extends Action { return; } - $token = $this->trimmed('token'); + $id = $this->trimmed('notice'); + + $notice = Notice::staticGet($id); + + $token = $this->trimmed('token-'.$notice->id); if (!$token || $token != common_session_token()) { - $this->client_error(_('There was a problem with your session token. Try again, please.')); + $this->client_error(_("There was a problem with your session token. Try again, please.")); return; } - $id = $this->trimmed('notice'); - - $notice = Notice::staticGet($id); - $fave = new Fave(); $fave->user_id = $this->id; $fave->notice_id = $notice->id; @@ -69,7 +69,7 @@ class DisfavorAction extends Action { if ($this->boolean('ajax')) { common_start_html('text/xml'); common_element_start('head'); - common_element('title', _('Favor')); + common_element('title', null, _('Add to favorites')); common_element_end('head'); common_element_start('body'); common_favor_form($notice); diff --git a/actions/favor.php b/actions/favor.php index dd61899e4..82b70a35b 100644 --- a/actions/favor.php +++ b/actions/favor.php @@ -38,16 +38,17 @@ class FavorAction extends Action { return; } + $id = $this->trimmed('notice'); + + $notice = Notice::staticGet($id); + # CSRF protection - $token = $this->trimmed('token'); + $token = $this->trimmed('token-'.$notice->id); if (!$token || $token != common_session_token()) { - $this->client_error(_('There was a problem with your session token. Try again, please.')); + $this->client_error(_("There was a problem with your session token. Try again, please.")); return; } - $id = $this->trimmed('notice'); - - $notice = Notice::staticGet($id); if ($user->hasFave($notice)) { $this->client_error(_('This notice is already a favorite!')); @@ -67,7 +68,7 @@ class FavorAction extends Action { if ($this->boolean('ajax')) { common_start_html('text/xml'); common_element_start('head'); - common_element('title', _('Disfavor')); + common_element('title', null, _('Disfavor favorite')); common_element_end('head'); common_element_start('body'); common_disfavor_form($notice); diff --git a/js/util.js b/js/util.js index 111beef25..151c0d111 100644 --- a/js/util.js +++ b/js/util.js @@ -17,94 +17,86 @@ */ $(document).ready(function(){ - // count character on keyup - function counter(event){ - var maxLength = 140; - var currentLength = $("#status_textarea").val().length; - var remaining = maxLength - currentLength; - var counter = $("#counter"); - counter.text(remaining); + // count character on keyup + function counter(event){ + var maxLength = 140; + var currentLength = $("#status_textarea").val().length; + var remaining = maxLength - currentLength; + var counter = $("#counter"); + counter.text(remaining); + + if (remaining <= 0) { + counter.addClass("toomuch"); + } else { + counter.removeClass("toomuch"); + } + } - if (remaining <= 0) { - counter.attr("class", "toomuch"); - } else { - counter.attr("class", ""); - } - } + function submitonreturn(event) { + if (event.keyCode == 13) { + $("#status_form").submit(); + event.preventDefault(); + event.stopPropagation(); + return false; + } + return true; + } - function submitonreturn(event) { - if (event.keyCode == 13) { - $("#status_form").submit(); - event.preventDefault(); - event.stopPropagation(); - return false; - } - return true; - } + if ($("#status_textarea").length) { + $("#status_textarea").bind("keyup", counter); + $("#status_textarea").bind("keydown", submitonreturn); + + // run once in case there's something in there + counter(); + + // set the focus + $("#status_textarea").focus(); + } - if ($("#status_textarea").length) { - $("#status_textarea").bind("keyup", counter); - $("#status_textarea").bind("keydown", submitonreturn); + // XXX: refactor this code - // run once in case there's something in there - counter(); + var favoptions = { dataType: 'xml', + success: function(xml) { var new_form = document._importNode($('form', xml).get(0), true); + var dis = new_form.id; + var fav = dis.replace('disfavor', 'favor'); + $('form#'+fav).replaceWith(new_form); + $('form#'+dis).ajaxForm(disoptions).each(addAjaxHidden); + } + }; - // set the focus - $("#status_textarea").focus(); - } + var disoptions = { dataType: 'xml', + success: function(xml) { var new_form = document._importNode($('form', xml).get(0), true); + var fav = new_form.id; + var dis = fav.replace('favor', 'disfavor'); + $('form#'+dis).replaceWith(new_form); + $('form#'+fav).ajaxForm(favoptions).each(addAjaxHidden); + } + }; - // XXX: refactor this code + function addAjaxHidden() { + var ajax = document.createElement('input'); + ajax.setAttribute('type', 'hidden'); + ajax.setAttribute('name', 'ajax'); + ajax.setAttribute('value', 1); + this.appendChild(ajax); + } - var favoptions = {dataType: 'xml', - success: function(xml) { - var new_form = $('form.disfavor', xml).get(0); - var dis = new_form.id; - var fav = dis.replace('disfavor', 'favor'); - if (document.importNode) { - new_form = document.importNode(new_form, true); - } - $('form#'+fav).replaceWith(new_form); - $('form#'+dis).ajaxForm(disoptions).each(addAjaxHidden); - }}; - - var disoptions = {dataType: 'xml', - success: function(xml) { - var new_form = $('form.favor', xml).get(0); - var fav = new_form.id; - var dis = fav.replace('favor', 'disfavor'); - if (document.importNode) { - new_form = document.importNode(new_form, true); - } - $('form#'+dis).replaceWith(new_form); - $('form#'+fav).ajaxForm(favoptions).each(addAjaxHidden); ; - }}; - - function addAjaxHidden() { - var ajax = document.createElement('input'); - ajax.setAttribute('type', 'hidden'); - ajax.setAttribute('name', 'ajax'); - ajax.setAttribute('value', 1); - this.appendChild(ajax); - } - - $("form.favor").ajaxForm(favoptions); - $("form.disfavor").ajaxForm(disoptions); - - $("form.favor").each(addAjaxHidden); - $("form.disfavor").each(addAjaxHidden); + $("form.favor").ajaxForm(favoptions); + $("form.disfavor").ajaxForm(disoptions); + $("form.favor").each(addAjaxHidden); + $("form.disfavor").each(addAjaxHidden); }); function doreply(nick,id) { - rgx_username = /^[0-9a-zA-Z\-_.]*$/; - if (nick.match(rgx_username)) { - replyto = "@" + nick + " "; - if ($("#status_textarea").length) { - $("#status_textarea").val(replyto); - $("form#status_form input#inreplyto").val(id); - $("#status_textarea").focus(); - return false; - } - } - return true; -} - + rgx_username = /^[0-9a-zA-Z\-_.]*$/; + if (nick.match(rgx_username)) { + replyto = "@" + nick + " "; + if ($("#status_textarea").length) { + $("#status_textarea").val(replyto); + $("form#status_form input#inreplyto").val(id); + $("#status_textarea").focus(); + return false; + } + } + return true; +} \ No newline at end of file diff --git a/js/xbImportNode.js b/js/xbImportNode.js new file mode 100644 index 000000000..4ba332a68 --- /dev/null +++ b/js/xbImportNode.js @@ -0,0 +1,46 @@ +/* is this stuff defined? */ +if (!document.ELEMENT_NODE) { + document.ELEMENT_NODE = 1; + document.ATTRIBUTE_NODE = 2; + document.TEXT_NODE = 3; + document.CDATA_SECTION_NODE = 4; + document.ENTITY_REFERENCE_NODE = 5; + document.ENTITY_NODE = 6; + document.PROCESSING_INSTRUCTION_NODE = 7; + document.COMMENT_NODE = 8; + document.DOCUMENT_NODE = 9; + document.DOCUMENT_TYPE_NODE = 10; + document.DOCUMENT_FRAGMENT_NODE = 11; + document.NOTATION_NODE = 12; +} + +document._importNode = function(node, allChildren) { + /* find the node type to import */ + switch (node.nodeType) { + case document.ELEMENT_NODE: + /* create a new element */ + var newNode = document.createElement(node.nodeName); + /* does the node have any attributes to add? */ + if (node.attributes && node.attributes.length > 0) + /* add all of the attributes */ + for (var i = 0, il = node.attributes.length; i < il;) { + if (node.attributes[i].nodeName == 'class') { + newNode.className = node.getAttribute(node.attributes[i++].nodeName); + } else { + newNode.setAttribute(node.attributes[i].nodeName, node.getAttribute(node.attributes[i++].nodeName)); + } + } + /* are we going after children too, and does the node have any? */ + if (allChildren && node.childNodes && node.childNodes.length > 0) + /* recursively get all of the child nodes */ + for (var i = 0, il = node.childNodes.length; i < il;) + newNode.appendChild(document._importNode(node.childNodes[i++], allChildren)); + return newNode; + break; + case document.TEXT_NODE: + case document.CDATA_SECTION_NODE: + case document.COMMENT_NODE: + return document.createTextNode(node.nodeValue); + break; + } +}; \ No newline at end of file diff --git a/lib/util.php b/lib/util.php index cfc95cc36..e958a87ba 100644 --- a/lib/util.php +++ b/lib/util.php @@ -180,6 +180,9 @@ function common_show_header($pagetitle, $callable=NULL, $data=NULL, $headercall= common_element('script', array('type' => 'text/javascript', 'src' => common_path('js/jquery.form.js')), ' '); + common_element('script', array('type' => 'text/javascript', + 'src' => common_path('js/xbImportNode.js')), + ' '); common_element('script', array('type' => 'text/javascript', 'src' => common_path('js/util.js?version='.LACONICA_VERSION)), ' '); @@ -1809,13 +1812,25 @@ function common_disfavor_form($notice) { 'method' => 'post', 'class' => 'disfavor', 'action' => common_local_url('disfavor'))); - common_hidden('token', common_session_token()); - common_hidden('notice', $notice->id); + + common_element('input', array('type' => 'hidden', + 'name' => 'token-'. $notice->id, + 'id' => 'token-'. $notice->id, + 'class' => 'token', + 'value' => common_session_token())); + + common_element('input', array('type' => 'hidden', + 'name' => 'notice', + 'id' => 'notice-n'. $notice->id, + 'class' => 'notice', + 'value' => $notice->id)); + common_element('input', array('type' => 'submit', 'id' => 'disfavor-submit-' . $notice->id, 'name' => 'disfavor-submit-' . $notice->id, 'class' => 'disfavor', - 'value' => '♥')); + 'value' => 'Disfavor favorite', + 'title' => 'Remove this message from favorites')); common_element_end('form'); } @@ -1824,13 +1839,25 @@ function common_favor_form($notice) { 'method' => 'post', 'class' => 'favor', 'action' => common_local_url('favor'))); - common_hidden('token', common_session_token()); - common_hidden('notice', $notice->id); + + common_element('input', array('type' => 'hidden', + 'name' => 'token-'. $notice->id, + 'id' => 'token-'. $notice->id, + 'class' => 'token', + 'value' => common_session_token())); + + common_element('input', array('type' => 'hidden', + 'name' => 'notice', + 'id' => 'notice-n'. $notice->id, + 'class' => 'notice', + 'value' => $notice->id)); + common_element('input', array('type' => 'submit', 'id' => 'favor-submit-' . $notice->id, 'name' => 'favor-submit-' . $notice->id, 'class' => 'favor', - 'value' => '♡')); + 'value' => 'Add to favorites', + 'title' => 'Add this message to favorites')); common_element_end('form'); } diff --git a/theme/default/display.css b/theme/default/display.css index 8408ecd8d..91cc057fa 100644 --- a/theme/default/display.css +++ b/theme/default/display.css @@ -179,6 +179,36 @@ padding-top:2px; padding-left:30px; } + +form#disfavor, form.disfavor, +form#favor, form.favor { + float: right; +} + +/*favorites*/ +input#favor, input.favor, +input#disfavor, input.disfavor { + background-color:#fcfff5; + background-image:url(icon_heart-01.png); + background-repeat:no-repeat; + cursor: pointer; + border: 0; + width: 16px; + height:16px; + text-indent:-9999px; +} + +input#disfavor, input.disfavor { + background-image:url(icon_heart-02.png); +} + +.notice_single:hover input.favor, +.notice_single:hover input.disfavor { + background-color:#f3f8ea; +} + + + /* ----- Nav Footer ----- */ #nav_sub { clear: both; @@ -686,44 +716,9 @@ input#openid_url { line-height: 15px; } -/* ----- favor/disfavor -----*/ -form#disfavor, form.disfavor { - display: inline; - float: right; -} -input#disfavor, input.disfavor { - display: inline; - color: #C15D42; - background-color: #FBF2D7; - cursor: pointer; - border: 0; - width: auto; - } - -form#favor, form.favor { - display: inline; - float: right; -} - -input#favor, input.favor { - display: inline; - color: #C15D42; - background-color: #FBF2D7; - cursor: pointer; - border: 0; - width: auto; - } - -input.favor:hover { - background-color: #f7ebcc; -} -input.disfavor:hover { - background-color: #f7ebcc; -} - /* ----- direct message ----- */ #message_form { @@ -811,8 +806,8 @@ p.tagcloud a.smallest { font-size: 60%; } -/* ----- Mailbox ----- */ +/* ----- Mailbox ----- */ #messages { clear: both; margin: 0 auto; @@ -844,4 +839,4 @@ font-size: 60%; display: inline; margin: 0; padding: 0; - } + } \ No newline at end of file diff --git a/theme/default/icon_heart-01.png b/theme/default/icon_heart-01.png new file mode 100644 index 000000000..4e77720ca Binary files /dev/null and b/theme/default/icon_heart-01.png differ diff --git a/theme/default/icon_heart-02.png b/theme/default/icon_heart-02.png new file mode 100644 index 000000000..2fbdd7b6c Binary files /dev/null and b/theme/default/icon_heart-02.png differ diff --git a/theme/default/ie7.css b/theme/default/ie7.css index bbf52d5cf..99bc4e79f 100644 --- a/theme/default/ie7.css +++ b/theme/default/ie7.css @@ -1,6 +1,14 @@ @charset "UTF-8"; /* CSS Document */ + +input.disfavor, +input.favor { + text-indent:0; + text-align:right; + padding-left:25px; +} + #statistics dd { clear: both; } @@ -17,4 +25,4 @@ img.avatar.original, img.avatar.profile { #nav_pagination li a { padding: 6px 15px; line-height: 27px; - } \ No newline at end of file + } diff --git a/theme/identica/display.css b/theme/identica/display.css index 9d6416fb0..a3ef07f90 100644 --- a/theme/identica/display.css +++ b/theme/identica/display.css @@ -57,6 +57,7 @@ a { border-top: 1px solid #D8E2D7; } + .instructions p, .success, .error { border: 1px solid #91AA9D; color: #FCFFF5; @@ -174,21 +175,6 @@ textarea:focus, input:focus { background-color: #F3F8EA; } -input#disfavor, input.disfavor { - background-color: white; - } - -input#favor, input.favor { - background-color: white; - } - -input.favor:hover { - background-color: #F3F8EA; - } - -input.disfavor:hover { - background-color: #F3F8EA; - } #messages { border-top: 1px solid #D8E2D7; @@ -200,21 +186,4 @@ input.disfavor:hover { .message_single:hover { background-color: #F3F8EA; - } - - - - - - - - - - - - - - - - - \ No newline at end of file + } \ No newline at end of file diff --git a/theme/identica/ie6.css b/theme/identica/ie6.css index f7aebf1b0..a301f1dc5 100644 --- a/theme/identica/ie6.css +++ b/theme/identica/ie6.css @@ -4,3 +4,11 @@ #wrap { background: url(bg-header.gif) repeat-x #FCFFF5; } + + +input.disfavor, +input.favor { + text-indent:0px; + text-align:right; + padding-left:25px; +} \ No newline at end of file -- cgit v1.2.3-54-g00ecf