From ced91f14dd62224d0d41a6d758e28a710a715132 Mon Sep 17 00:00:00 2001 From: Artanis Date: Sun, 30 Sep 2007 08:53:47 +0000 Subject: [PATCH] Tagger: 20070930 0153 git-svn-id: file:///home/shish/svn/shimmie2/trunk@505 7f39781d-f577-437e-ae19-be835c7a54ca --- contrib/tagger/main.php | 10 +- contrib/tagger/script.js | 369 ++++++++++-------------------- contrib/tagger/style.css | 57 +++-- contrib/tagger/theme.php | 258 +++++++++++++-------- contrib/tagger/webtoolkit.drag.js | 85 +++++++ 5 files changed, 417 insertions(+), 362 deletions(-) create mode 100644 contrib/tagger/webtoolkit.drag.js diff --git a/contrib/tagger/main.php b/contrib/tagger/main.php index 0f6b3b85..b00dbbd6 100644 --- a/contrib/tagger/main.php +++ b/contrib/tagger/main.php @@ -30,14 +30,14 @@ class tagger extends Extension { $base_href = $config->get_string('base_href'); $tags_min = $config->get_int('ext-tagger_tags-min',2); - $hidden = $config->get_bool( - 'ext-tagger_respect-hidden', - true) ? "AND substring(tag,1,1) != '.' " : null; - + $hidden = $config->get_string( + 'ext-tagger_show-hidden','N')=='N' ? + " AND substring(tag,1,1) != '.' " : null; + $tags = $database->Execute(" SELECT tag FROM `tags` - WHERE count >= ? {$hidden} + WHERE count>=?{$hidden} ORDER BY tag",array($tags_min)); $this->theme->build($page, $tags); diff --git a/contrib/tagger/script.js b/contrib/tagger/script.js index 319cac28..0f868b35 100644 --- a/contrib/tagger/script.js +++ b/contrib/tagger/script.js @@ -3,9 +3,18 @@ // Do not remove this notice. // All other code copyright by their authors, see comments for details. +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ +* Tagger Management * +\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +var remove_tagme = null; +function taggerInit() { + taggerResetPos(); + tagger_tagIndicators() + DragHandler.attach(byId("tagger_titlebar")); + remove_tagme = byId('tagme'); +} function taggerResetPos() { - // In case the drag point goes off screen. tagger = byId("tagger_window"); tagger.style.top=""; @@ -22,86 +31,120 @@ function taggerResetPos() { tagger.style.bottom=""; } -function tagExists(tag) { - var tags = byId("tags"); - tags_list = tags.value; - tags_array = tags_list.split(" "); +function tagger_tagIndicators() { + tags = byId("tags"); + arObjTags = getElementsByTagNames('a',byId('tagger_body')); - tags_list = ""; - for (x in tags_array) { - if(tags_array[x] == tag) { - return true; + for (i in arObjTags) { + objTag = arObjTags[i]; + if(tagExists(objTag)) { + objTag.style.fontWeight="bold"; } } - return false; } -function toggleTag(tag,rTagme) { - if (!tagExists(tag)) { - addTag(tag); - if(rTagme && tag != "tagme") { - remTag("tagme"); +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ +* Tagging * +\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +function toggleTag(objTag) { + if(!tagExists(objTag)) { + addTag(objTag); + if (remove_tagme && objTag.attributes.tag.value != 'tagme') { + remTag(remove_tagme); } } else { - remTag(tag); - } - obj = byId("tagger_custTag"); - if(obj.value) { - obj.select(); + remTag(objTag); } + t = byId("tagger_new-tag"); + if(t.value) { t.select(); } } -function addTagById(id) { - tag = byId(id); - toggleTag(tag.value); -} - -function addTag (tag) { - var tags = byId("tags"); - var tag_link = byId("tagger_tag_"+tag); +function addTag (objTag) { + var tags = byId('tags'); - var delim = " "; - if(tags.value == "") { - delim=""; - } - tags.value = tags.value + delim + tag; - if(tag_link) { - tag_link.style.fontWeight = "bold"; + delim = tags.value==" "?"":" "; + + tags.value += delim + objTag.attributes.tag.value; + + if(objTag.value != 'Add') { + objTag.style.fontWeight = "bold"; } } -function remTag (tag) { +function remTag (objTag) { var tags = byId("tags"); - var tag_link = byId("tagger_tag_"+tag); - _tags = tags.value.split(" "); - - tags.value = ""; - for (i in _tags) { - _tag = _tags[i]; - if(_tag != tag) { - addTag(_tag); + aTags = tags.value.split(" "); + + tags.value=""; + for(i in aTags) { + aTag = aTags[i]; + if(aTag != objTag.attributes.tag.value) { + if(tags.value=="") { + tags.value += aTag; + } else { + tags.value += " "+aTag; + } } } - if(tag_link) { - tag_link.style.fontWeight = ""; + if(objTag.value != 'Add') { + objTag.style.fontWeight = ""; } } -function setTagIndicators() { - taggerResetPos(); - - tags = byId("tags"); - tags = tags.value.split(" "); - - for (x in tags) { - tag = tags[x]; - obj = byId("tagger_tag_"+tag); - if(obj) { - obj.style.fontWeight="bold"; +function tagExists(objTag) { + return byId("tags").value.match(reescape(objTag.attributes.tag.value)); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ +* Filtering * +\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +var tagger_filter_focus = false; +function tagger_filter(override) { + if(tagger_filter_focus || override) { + var filter = byId('tagger_new-tag'); + var arObjTags = getElementsByTagNames('a',byId('tagger_body')); + var prepend = filter.value.length<2? " ":"_"; + var search = prepend + reescape(filter.value); + + for(i in arObjTags) { + objTag = arObjTags[i]; + tag = prepend + objTag.attributes.tag.value; + + if(tag.match(search) && taggerFilterMode(objTag)) { + objTag.style.display=''; + } else { + objTag.style.display='none'; + } } } } +function taggerToggleMode() { + var obj = byId('tagger_mode'); + + if(obj.attributes.mode.value=='all') { + obj.attributes.mode.value='applied'; + obj.innerHTML = 'View All Tags'; + } else { + obj.attributes.mode.value='all'; + obj.innerHTML = 'View Applied Tags'; + } + tagger_filter(true); +} +function taggerFilterMode(objTag) { + var obj = byId('tagger_mode'); + if(obj.attributes.mode.value == 'all') { + return true; + } else { + return objTag.style.fontWeight=='bold'; + } +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ +* Forms * +\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ function pushSet(form_id) { var set = getSetButton(form_id); @@ -121,35 +164,11 @@ function getSetButton(form_id) { return false; } -var _f_custTag = false; -function tagger_filter(id) { - if (_f_custTag) { - var filter = byId(id); - var e; - - search = filter.value; - // set up single letter filters for first-letter matching only. - if (search.length == 1) - search = " "+search; - - tag_links = getElementsByTagNames('div',byId('tagger_body')); - - for (x in tag_links) { - tag_id = tag_links[x].id; - // remove tagger_tag from id, prepend space for first-letter matching. - tag = " "+tag_id.replace(/tagger_tag_/,""); - e = byId(tag_id); - if (!tag.match(search)) { - e.style.display = 'none'; - } else { - e.style.display = ''; - } - } - } -} +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ +* quirksmode.org * +\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -// Quirksmode.org // -// http://www.quirksmode.org/dom/getElementsByTagNames.html // +// http://www.quirksmode.org/dom/getElementsByTagNames.html function getElementsByTagNames(list,obj) { if (!obj) var obj = document; var tagNames = list.split(','); @@ -174,7 +193,8 @@ function getElementsByTagNames(list,obj) { } return resultArray; } -// http://www.quirksmode.org/js/findpos.html // + +// http://www.quirksmode.org/js/findpos.html function findPos(obj) { var curleft = curtop = 0; if (obj.offsetParent) { @@ -187,163 +207,24 @@ function findPos(obj) { } return [curleft,curtop]; } -// End // -// Drag Code // -//***************************************************************************** -// Do not remove this notice. -// -// Copyright 2001 by Mike Hall. -// See http://www.brainjar.com for terms of use. -//***************************************************************************** - -// Determine browser and version. - -function Browser() { - - var ua, s, i; - - this.isIE = false; - this.isNS = false; - this.version = null; - - ua = navigator.userAgent; - - s = "MSIE"; - if ((i = ua.indexOf(s)) >= 0) { - this.isIE = true; - this.version = parseFloat(ua.substr(i + s.length)); - return; - } - - s = "Netscape6/"; - if ((i = ua.indexOf(s)) >= 0) { - this.isNS = true; - this.version = parseFloat(ua.substr(i + s.length)); - return; - } - - // Treat any other "Gecko" browser as NS 6.1. - - s = "Gecko"; - if ((i = ua.indexOf(s)) >= 0) { - this.isNS = true; - this.version = 6.1; - return; - } +// ripped from a forum. +// todo: cite source +function reescape(str){ + var resp="()?:=[]*+{}^$|/,.!\\" + var found=false + var ret="" + for(var i=0;iget_string( - "ext-tagger_clear-tagme","N") == "Y" ?"true":"false"; - $base_href = $config->get_string("base_href"); - - $tag_html = ""; - foreach ($tags as $tag) { - $tag_name = $tag['tag']; - $tag_trunc = $this->trimTag($tag_name,20,"_"); - $tag_html .= " - "; - } - $url_more = make_link("about/tagger"); - - $html = << -Collapse this block to hide Tagger. -
-Default Location -
-About Tagger -
-
- Tagger -
-
- - - - - + public function build($event,$tags) { + // When overriding this function, take care that all tag attributes are + // maintained UNCHANGED. There are no attributes in the HTML code below + // that go unused by the javascript. If you fail to do this, + // the extension will BREAK! + // + // Now that that's sunk in, chaniging title attributes is fine. + global $config; + global $page; + + // set up data + $base_href = $config->get_string('base_href'); + $tagme = $config->get_string( + 'ext-tagger_clear-tagme','N')=="Y"? + "": + null; + $url_about = make_link("about/tagger"); + + // build floater tags + $h_tags = ""; + foreach($tags as $tag) { + $h_tags .= $this->tag_to_html($tag); + } + + $html = " + + + Collapse this block to hide Tagger + +
+ Default Location
-
-
$tag_html
-
-EOD; - $page->add_block( new Block("Tagger - Advanced Tagging", - "".$html, - "left", - 50)); + About Tagger". + // Tagger Floater + "
+
Tagger
+
+ + + + + + $tagme +
+ View Applied Tags | + Refresh Filter +
+
$h_tags
+
"; + + $page->add_block( new Block( + "Tagger", + $html, + "left")); + $page->add_header( + ""); } - public function trimTag($s,$len=80,$break=" ") { + + final public function show_about ($event) { + // The about page for Tagger. No override. Feel free to CSS it, though. + global $page; + global $config; + $base_href = $config->get_string('base_href'); + + $script1 = "$base_href/ext/tagger/script.js"; + $script2 = "$base_href/ext/tagger/webtoolkit.drag.js"; + + $html = str_replace("\"",""",str_replace("\'","'"," +
    +
  • + If Tagger is in your way, click and drag it\'s title bar to move + it to a more convienient location. +
  • + Click the links to add the tag to the image\'s tag list, when + done, press the Set button to save the tags. +
  • +
  • +

    Tagger gets all the tags with 2 or more uses, so the list can + get quite large. If you are having trouble finding the tag you + are looking for, you can enter it into the box at the top and as + you type, Tagger will remove tags that do not match to aid your + search. Usually, you\'ll only need one or two letters to trim + the list down to the tag you are looking for. +

    +

    One letter filters will look only at the first letter of the + tag. Two or more letters will search the beginning of every + word in every tag. +

    +

    If the tag is not in the list, finish typing out the tag and + click \"Add\" to add the tag to the image\'s tag list. +

    +

    Tags must have two uses to appear in Tagger\'s list, so + you'll have to enter the tag for at least one other image for it + to show up. +

    +
  • +
  • Requirements

    +

    Tagger requires javascript for its functionality. Sorry, but + there\'s no other way to accomplish the tag list + modifications. +

    +

    If you have javascript completely disabled, you will not be + able to use Tagger. +

    +

    Depending on your method of disabling javascript, you may be + able to whitelist scripts. The script files used by Tagger are + script.js and + webtoolkit.drag.js. +

    +
  • +
")); + + $page->set_title("Shimmie - About / Tagger - Advanced Tagging"); + $page->set_heading("About / Tagger - Advanced Tagging"); + $page->add_block( new Block("Author", + "Artanis (Erik Youngren <artanis.00@gmail.com>)","main",0)); + $page->add_block( new Block("Use", $html,"main",1)); + } + + + final function tag_to_html ($tag) { + // Important for script.js, no override. You can CSS this, though. + // If you must, remove the 'final' keyword, but MAKE SURE the entire + // tag is COPIED TO THE NEW FUNCTION EXACTLY! If you fail to do this, + // the extension will BREAK! + $tag_name = $tag['tag']; + $tag_id = $this->tag_id($tag_name); + $stag = $this->trimTag($tag_name,20,"_"); + + $html = " + $stag"; + + return $html; + } + + // Important for script.js, no override. + final function tag_id ($tag) { + $tag_id = ""; + $m=null; + for($i=0; $i < strlen($tag); $i++) { + $l = substr($tag,$i,1); + $m=null; + preg_match("[\pP]",$l,$m); + $tag_id .= !isset($m[0]) ? $l:"_"; + } + + return trim(str_replace("__","_",$tag_id)," _"); + } + + function trimTag($s,$len=80,$br=" ") { if(strlen($s) > $len) { $s = substr($s, 0,$len-1); - $s = substr($s,0, strrpos($s,$break))."..."; + $s = substr($s,0, strrpos($s,$br))."..."; } return $s; } - - public function show_about ($event) { - global $page; - $html = << -
  • - If Tagger is in you way, click and drag it's title bar to move it to a - more convienient location. -
  • - Click the links to add the tag to the image's tag list, when done, press - the Set button to save the tags. -
  • -
  • -

    Tagger gets all the tags in use with 2 or more uses, so the list can get - quite large. If you are having trouble finding the tag you are looking for, - you can enter it into the box at the top and as you type, Tagger will remove - tags that do not match to aid your search. Usually, you'll only need one - or two letters to trim the list down to the tag you are looking for.

    -

    If the tag is not in the list, finish typing out the tag and click "Add" - to add the tag to the image's tag list.

    -

    Tags must have two uses to appear in Tagger's list, so you'll have to - enter the tag for at least one other image for it to show up.

    -
  • -
  • -

    Tagger requires javascript for its functionality. Sorry, but there's - no other way to accomplish the tag list modifications.

    -

    If you have javascript completely disabled, you will not be able to use - Tagger.

    -

    Due to the manner in which Tagger is constructed, it will hide along with - it's block on the side bar and block behaviour will remember that - setting in shimmie's cookies.

    -
  • - -EOD; - $page->set_title("About / Extension / Tagger - Advanced Tagging"); - $page->set_heading("About / Extension / Tagger - Advanced Tagging"); - $page->add_block( new Block("Author", - "Artanis (Erik Youngren <artanis.00@gmail.com>)","main",0)); - $page->add_block( new Block("Use", $html,"main",1)); - } } + ?> diff --git a/contrib/tagger/webtoolkit.drag.js b/contrib/tagger/webtoolkit.drag.js new file mode 100644 index 00000000..3ba87507 --- /dev/null +++ b/contrib/tagger/webtoolkit.drag.js @@ -0,0 +1,85 @@ +/** +* +* Crossbrowser Drag Handler +* http://www.webtoolkit.info/ +* +* Modified by Erik Youngren to move parent node +**/ + +var DragHandler = { + + + // private property. + _oElem : null, + + + // public method. Attach drag handler to an element. + attach : function(oElem) { + oElem.onmousedown = DragHandler._dragBegin; + + // callbacks + oElem.dragBegin = new Function(); + oElem.drag = new Function(); + oElem.dragEnd = new Function(); + + return oElem; + }, + + + // private method. Begin drag process. + _dragBegin : function(e) { + var oElem = DragHandler._oElem = this; + + if (isNaN(parseInt(oElem.parentNode.style.left))) { oElem.parentNode.style.left = '0px'; } + if (isNaN(parseInt(oElem.parentNode.style.top))) { oElem.parentNode.style.top = '0px'; } + + var x = parseInt(oElem.parentNode.style.left); + var y = parseInt(oElem.parentNode.style.top); + + e = e ? e : window.event; + oElem.mouseX = e.clientX; + oElem.mouseY = e.clientY; + + oElem.dragBegin(oElem, x, y); + + document.onmousemove = DragHandler._drag; + document.onmouseup = DragHandler._dragEnd; + return false; + }, + + + // private method. Drag (move) element. + _drag : function(e) { + var oElem = DragHandler._oElem; + + var x = parseInt(oElem.parentNode.style.left); + var y = parseInt(oElem.parentNode.style.top); + + e = e ? e : window.event; + oElem.parentNode.style.left = x + (e.clientX - oElem.mouseX) + 'px'; + oElem.parentNode.style.top = y + (e.clientY - oElem.mouseY) + 'px'; + + oElem.mouseX = e.clientX; + oElem.mouseY = e.clientY; + + oElem.drag(oElem, x, y); + + return false; + }, + + + // private method. Stop drag process. + _dragEnd : function() { + var oElem = DragHandler._oElem; + + var x = parseInt(oElem.parentNode.style.left); + var y = parseInt(oElem.parentNode.style.top); + + oElem.dragEnd(oElem, x, y); + + document.onmousemove = null; + document.onmouseup = null; + DragHandler._oElem = null; + } + +}