Extension: tag_editcloud: Add or remove tags to the editor via clicking

This commit is contained in:
atomicdryad 2010-12-22 17:10:24 -06:00
parent 20987de933
commit 46f1746337
3 changed files with 173 additions and 0 deletions

View File

@ -0,0 +1,107 @@
<?php
/*
* Name: Tag EditCloud
* Author: AtomicDryad
* Description: Add or remove tags to the editor via clicking.
*/
/* Todo:
* Be less kludgy
* $cfgstub->board prefs
* toggle sorting method via javascript || usepref(todo2: port userpref)
* colorize used tags in cloud || always show used tags in front of cloud
* theme junk
*/
class TagEditCloud implements Extension {
var $theme;
public function receive_event(Event $event) {
global $config, $database, $page, $user;
//if(is_null($this->theme)) $this->theme = get_theme_object($this);
if($event instanceof ImageInfoBoxBuildingEvent) {
if($this->can_tag($event->image)) {
$cfgstub_sortbyname=false; // FIXME
$cfgstub_showtop=40; // Derp
$cfgstub_minuse=2; // Derp
if($cfgstub_sortbyname) {
$event->add_part($this->build_tag_map($event->image,$cfgstub_minuse,false),40);
} else {
$event->add_part($this->build_tag_map($event->image,$cfgstub_showtop,4096),40);
}
}
}
}
private function tag_link($tag) {
$u_tag = url_escape($tag);
return make_link("post/list/$u_tag/1");
}
///// build_tag_map: output cloud of clickable tags
// build_tag_map($image|false, $defcount, $maxcount|false) -- taglist sorted by usage, displaying $defcount by default, up to $maxcount via toggle.
// build_tag_map($image|false, $minusage|false) -- taglist sorted by alpha, only showing tags with usage >= $minusage
private function build_tag_map($image,$defcount,$maxcount) { //
global $database;
$html="";$cloud="";$precloud="";
$itags=Array();
$tags_min=1;
$alphasort=false;
if(!is_int($defcount)) $defcount=20;
if(!is_int($maxcount)) { // Derp this is pretty cheesy.
$maxcount=4096; // Hurrrr
$tags_min=$defcount;
$alphasort=true;
}
if ((gettype($image) == 'object') && (isset($image->tag_array)) && ($itags=$image->tag_array)) $itags=array_fill_keys(array_values($itags),true);
$result = $database->execute(" SELECT tag, FLOOR(LOG(2.7, LOG(2.7, count - ? + 1)+1)*1.5*100)/100 AS scaled, count
FROM tags WHERE count >= ? ORDER BY ".
(!$alphasort ? "count DESC":"tag").
" limit $maxcount",
array($tags_min,$tags_min)
);
$tag_data = $result->GetArray();
$counter=1;
foreach($tag_data as $row) {
if((!$alphasort)&&($counter==$defcount)) $cloud .= "<div id=\"tagcloud_extra\" style=\"display: none;\">";
$h_tag = html_escape($row['tag']);
$size = sprintf("%.2f", (float)$row['scaled']/2);
$usecount=$row['count'];
$link = $this->tag_link($row['tag']);
if($size<0.5) $size = 0.5;
if(isset($itags[$row['tag']])) {
// if($size<0.75) $size = 0.75;
$precloud .= "&nbsp;<span onclick=\"tageditcloud_toggle_tag(this)\" class=\"tag-selected\" style='font-size: ${size}em' title='$usecount'>$h_tag</span>&nbsp;\n";
} else {
$counter++;
$cloud .= "&nbsp;<span onclick=\"tageditcloud_toggle_tag(this)\" style='font-size: ${size}em' title='$usecount'>$h_tag</span>&nbsp;\n";
}
}
if ($precloud != '') $html .= "<div id=\"tagcloud_set\">$precloud</div>";
$html .="<div id=\"tagcloud_unset\">$cloud</div>";
$rem=count($tag_data)-$defcount;
// $script = "";
// $html.=$script;
if((!$alphasort)&&($counter>=$defcount)) $html .= "</div><br>[<span onclick=\"tageditcloud_toggle_extra('tagcloud_extra',this);\" style=\"color: #0000EF; font-weight:bold;\">show $rem more tags</span>]";
// $html.='<pre>'.var_export($itags,true).'</pre>';
return "<div id=\"tageditcloud\" class=\"tageditcloud\">$html</div>"; // FIXME: stupidasallhell
}
private function can_tag($image) {
global $config, $user;
return (
($config->get_bool("tag_edit_anon") || !$user->is_anonymous()) &&
($user->is_admin() || !$image->is_locked())
);
}
}
add_event_listener(new TagEditCloud());
?>

View File

@ -0,0 +1,46 @@
Array.prototype.editcloud_contains = function (ele) {
for (var i = 0; i < this.length; i++) {
if (this[i] == ele) {
return true;
}
}
return false;
};
Array.prototype.editcloud_remove = function (ele) {
var arr = new Array();
var count = 0;
for (var i = 0; i < this.length; i++) {
if (this[i] != ele) {
arr[count] = this[i];
count++;
}
}
return arr;
};
function tageditcloud_toggle_extra(obj,hide) {
var el = document.getElementById(obj);
el.style.display = (el.style.display != 'none' ? 'none' : '' );
hide.innerHTML=(el.style.display != 'none' ? 'show less tags' : 'show more tags' );
}
function tageditcloud_toggle_tag(ele) {
var thisTag = ele.innerHTML;
var taglist = document.getElementById('tag_editor');
var tags = taglist.value.split(' ');
// If tag is already listed, remove it
if (tags.editcloud_contains(thisTag)) {
tags = tags.editcloud_remove(thisTag);
ele.className = 'tag-unselected';
// Otherwise add it
} else {
tags.splice(0, 0, thisTag);
ele.className = 'tag-selected';
}
taglist.value = tags.join(' ');
document.getElementById('tags').focus();
}

View File

@ -0,0 +1,20 @@
span.tag-selected {
background:#88EE88;
}
.tageditcloud {
color: #0000FF;
}
.tageditcloud div#tagcloud_unset {
color: #0000FF;
}
.tageditcloud div#tagcloud_set {
color: #0000FF;
font-style:italic;
}
.tageditcloud div#tagcloud_extra {
color: #0000FF;
}