Tagger v2 - 20071031 1430
- Add/Remove/Applied tag indicator images. - Rewrote JS to be neater. - Removed overly complicated and not-quite-functional search limiter in favor of slightly delaying query. - SQL escaping moved to PHP for safety. - Added option "Enable Tagger." Defaults false. - Added option "Delay queries by [$int] milliseconds." Delays AJAX using timeouts, waits for additional characters. Default 250. - Added option "Limit queries returning more than [$int] tags to [$int]." Limits server hit and client-side memory overhead. Defaults 30 and 30. git-svn-id: file:///home/shish/svn/shimmie2/trunk@604 7f39781d-f577-437e-ae19-be835c7a54ca
This commit is contained in:
parent
b97a7bf912
commit
cf00965f26
BIN
contrib/tagger/images/active.png
Normal file
BIN
contrib/tagger/images/active.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 183 B |
BIN
contrib/tagger/images/add-tag.png
Normal file
BIN
contrib/tagger/images/add-tag.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 227 B |
BIN
contrib/tagger/images/inactive.png
Normal file
BIN
contrib/tagger/images/inactive.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 170 B |
BIN
contrib/tagger/images/rem-tag.png
Normal file
BIN
contrib/tagger/images/rem-tag.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 198 B |
BIN
contrib/tagger/images/tag-img.psd
Normal file
BIN
contrib/tagger/images/tag-img.psd
Normal file
Binary file not shown.
@ -15,8 +15,23 @@ class Tagger extends Extension {
|
|||||||
if(is_a($event,'DisplayingImageEvent')) {
|
if(is_a($event,'DisplayingImageEvent')) {
|
||||||
global $page, $config, $user;
|
global $page, $config, $user;
|
||||||
|
|
||||||
if($config->get_bool("tag_edit_anon") || ($user->id != $config->get_int("anon_id")))
|
if($config->get_bool("tag_edit_anon")
|
||||||
|
|| ($user->id != $config->get_int("anon_id"))
|
||||||
|
&& $config->get_bool("ext_tagger_enabled"))
|
||||||
|
{
|
||||||
$this->theme->build_tagger($page,$event);
|
$this->theme->build_tagger($page,$event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(is_a($event,'SetupBuildingEvent')) {
|
||||||
|
$sb = new SetupBlock("Tagger");
|
||||||
|
$sb->add_bool_option("ext_tagger_enabled","Enable Tagger");
|
||||||
|
$sb->add_int_option("ext_tagger_search_delay","<br/>Delay queries by ");
|
||||||
|
$sb->add_label(" milliseconds.");
|
||||||
|
$sb->add_label("<br/>Limit queries returning more than ");
|
||||||
|
$sb->add_int_option("ext_tagger_tag_max");
|
||||||
|
$sb->add_label(" tags to ");
|
||||||
|
$sb->add_int_option("ext_tagger_limit");
|
||||||
|
$event->panel->add_block($sb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} add_event_listener( new tagger());
|
} add_event_listener( new tagger());
|
||||||
@ -42,7 +57,7 @@ class TaggerXML extends Extension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".
|
$xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".
|
||||||
"<tags xmlns='http://www.w3.org/1999/xhtml'>".
|
"<tags>".
|
||||||
$tags.
|
$tags.
|
||||||
"</tags>";
|
"</tags>";
|
||||||
|
|
||||||
@ -55,11 +70,14 @@ class TaggerXML extends Extension {
|
|||||||
private function match_tag_list ($s) {
|
private function match_tag_list ($s) {
|
||||||
global $database, $config, $event;
|
global $database, $config, $event;
|
||||||
|
|
||||||
|
$max_rows = $config->get_int("ext_tagger_tag_max",30);
|
||||||
|
$limit_rows = $config->get_int("ext_tagger_limit",30);
|
||||||
|
|
||||||
$values = array();
|
$values = array();
|
||||||
|
|
||||||
// Match
|
// Match
|
||||||
$p = strlen($s) == 1? " ":"\_";
|
$p = strlen($s) == 1? " ":"_";
|
||||||
$sq = "%".$p.$s."%";
|
$sq = "%".mysql_real_escape_string($p.$s)."%";
|
||||||
$match = "concat(?,tag) LIKE ?";
|
$match = "concat(?,tag) LIKE ?";
|
||||||
array_push($values,$p,$sq);
|
array_push($values,$p,$sq);
|
||||||
// Exclude
|
// Exclude
|
||||||
@ -74,9 +92,9 @@ class TaggerXML extends Extension {
|
|||||||
// FROM based on return count
|
// FROM based on return count
|
||||||
$q_from = null;
|
$q_from = null;
|
||||||
$count = $this->count($q_where,$values);
|
$count = $this->count($q_where,$values);
|
||||||
if ($count > 60) {
|
if ($count > $max_rows) {
|
||||||
$q_from = "FROM (SELECT * FROM `tags` {$q_where} ".
|
$q_from = "FROM (SELECT * FROM `tags` {$q_where} ".
|
||||||
"ORDER BY count DESC LIMIT 0,30) AS `c_tags`";
|
"ORDER BY count DESC LIMIT 0, {$limit_rows}) AS `c_tags`";
|
||||||
$q_where = null;
|
$q_where = null;
|
||||||
$count = array("max"=>$count);
|
$count = array("max"=>$count);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3,328 +3,216 @@
|
|||||||
* Author: Artanis (Erik Youngren <artanis.00@gmail.com>) *
|
* Author: Artanis (Erik Youngren <artanis.00@gmail.com>) *
|
||||||
* Do not remove this notice. *
|
* Do not remove this notice. *
|
||||||
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
/* Tagger Window Object
|
var Tagger = {
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
initialize : function (image_id) {
|
||||||
function Tagger() {
|
// object navigation
|
||||||
// components
|
this.tag.parent = this;
|
||||||
this.t_parent = null;
|
this.position.parent = this;
|
||||||
this.t_title = null;
|
|
||||||
this.t_toolbar = null;
|
|
||||||
this.t_menu = null;
|
|
||||||
this.t_body = null;
|
|
||||||
this.t_tags = null;
|
|
||||||
this.t_form = null;
|
|
||||||
this.t_status = null;
|
|
||||||
// data
|
|
||||||
this.searchTags = null;
|
|
||||||
this.appliedTags = null;
|
|
||||||
// methods
|
|
||||||
this.initialize = initialize;
|
|
||||||
this.submit = submit;
|
|
||||||
this.getPosition = function () { return findPos(this.t_parent); };
|
|
||||||
this.setPosition = setPosition;
|
|
||||||
this.setSavedPosition = setSavedPosition;
|
|
||||||
this.getSavedPosition = getSavedPosition;
|
|
||||||
this.tagSearch = tagSearch;
|
|
||||||
this.searchRequest = searchRequest;
|
|
||||||
this.searchReceive = searchReceive;
|
|
||||||
this.tagListReceive = tagListReceive;
|
|
||||||
this.tagPublish = tagPublish;
|
|
||||||
this.prepTags = prepTags;
|
|
||||||
this.createTag = createTag;
|
|
||||||
this.buildPages = buildPages;
|
|
||||||
this.tagsToString = tagsToString;
|
|
||||||
this.toggleTag = toggleTag;
|
|
||||||
this.setAlert = setAlert;
|
|
||||||
|
|
||||||
|
|
||||||
// definitions
|
|
||||||
function initialize () {
|
|
||||||
// components
|
// components
|
||||||
this.t_parent = byId("tagger_parent");
|
this.editor.container = byId('tagger_parent');
|
||||||
this.t_title = byId("tagger_titlebar");
|
this.editor.titlebar = byId('tagger_titlebar');
|
||||||
this.t_toolbar = byId("tagger_toolbar");
|
this.editor.toolbar = byId('tagger_toolbar');
|
||||||
this.t_menu = byId("tagger_p-menu");
|
//this.editor.menu = byId('tagger_p-menu');
|
||||||
this.t_body = byId("tagger_body");
|
this.editor.body = byId('tagger_body');
|
||||||
this.t_tags = byId("tagger_tags");
|
this.editor.tags = byId('tagger_tags');
|
||||||
this.t_form = this.t_tags.parentNode;
|
this.editor.form = this.editor.tags.parentNode;
|
||||||
this.t_status = byId("tagger_statusbar");
|
this.editor.statusbar = byId('tagger_statusbar');
|
||||||
//pages
|
|
||||||
//this.buildPages();
|
|
||||||
// initial data
|
// initial data
|
||||||
ajaxXML(query+"/"+image_id,tagListReceive);
|
this.tag.image = image_id;
|
||||||
// reveal
|
this.tag.query = config.make_link("tagger/tags");
|
||||||
this.t_parent.style.display = "";
|
this.tag.list = null;
|
||||||
// dragging
|
this.tag.suggest = null;
|
||||||
DragHandler.attach(this.t_title);
|
this.tag.image_tags();
|
||||||
// set position
|
|
||||||
var pos = ( Tagger.getSavedPosition() || Tagger.getPosition() );
|
|
||||||
setPosition(pos[0],pos[1]);
|
|
||||||
// events
|
|
||||||
window.onunload = function () {Tagger.setSavedPosition(); };
|
|
||||||
|
|
||||||
}
|
// reveal
|
||||||
function submit() {
|
this.editor.container.style.display = "";
|
||||||
this.t_tags.value = Tagger.tagsToString(Tagger.appliedTags);
|
|
||||||
}
|
|
||||||
function setPosition(x,y) {
|
|
||||||
if(!x || !y) {
|
|
||||||
with(Tagger.t_parent.style) {
|
|
||||||
top = "25px";
|
|
||||||
left = "";
|
|
||||||
right = "25px";
|
|
||||||
bottom = "";
|
|
||||||
}
|
|
||||||
var pos = Tagger.getPosition();
|
|
||||||
x = pos[0];
|
|
||||||
y = pos[1];
|
|
||||||
}
|
|
||||||
with(Tagger.t_parent.style) {
|
|
||||||
top = y+"px";
|
|
||||||
left = x+"px";
|
|
||||||
right="";
|
|
||||||
bottom="";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function setSavedPosition(x,y) {
|
|
||||||
if (!x || !y) {
|
|
||||||
var p = Tagger.getPosition();
|
|
||||||
x = p[0];
|
|
||||||
y = p[1];
|
|
||||||
}
|
|
||||||
setCookie("shimmie_tagger-position",x+" "+y,14);
|
|
||||||
}
|
|
||||||
function getSavedPosition() {
|
|
||||||
var p = getCookie("shimmie_tagger-position");
|
|
||||||
if(p) {
|
|
||||||
return p.split(" ");
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function tagSearch(s,ms) {
|
|
||||||
clearTimeout(tagger_filter_timer);
|
|
||||||
tagger_filter_timer = setTimeout("Tagger.searchRequest('"+s+"')",ms);
|
|
||||||
}
|
|
||||||
function searchRequest(s) {
|
|
||||||
var s_query = !s? query+"?s" : query+"?s="+sqlescape(s);
|
|
||||||
|
|
||||||
if(!this.searchTags) {
|
|
||||||
ajaxXML(s_query,searchReceive);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
var prv_s = this.searchTags.getAttribute('query');
|
|
||||||
|
|
||||||
if(s==prv_s) {
|
|
||||||
return false;
|
|
||||||
}else if(!s || s.length <= 2 || s.length<prv_s.length ||
|
|
||||||
this.searchTags.getAttribute("max"))
|
|
||||||
{
|
|
||||||
ajaxXML(s_query,searchReceive);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
} else if(s.length > 2 && s.match(reescape(prv_s))) {
|
|
||||||
var len = this.searchTags.childNodes.length;
|
|
||||||
|
|
||||||
for (var i=len-1; i>=0; i--) {
|
|
||||||
var tag = this.searchTags.childNodes[i];
|
|
||||||
var t_name = tag.firstChild.data;
|
|
||||||
|
|
||||||
if(!t_name.match(reescape(s))) {
|
|
||||||
this.searchTags.removeChild(tag);
|
|
||||||
// TODO: Fix so back searches are not needlessly re-queried.
|
|
||||||
//tag.setAttribute("style","display:none;");
|
|
||||||
} else {
|
|
||||||
//tag.setAttribute("style","");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len != this.searchTags.childNodes.length) {
|
|
||||||
this.searchTags.setAttribute('query',s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
function searchReceive(xml) {
|
|
||||||
Tagger.searchTags = document.importNode(xml.getElementsByTagName("list")[0],true);
|
|
||||||
tagPublish(Tagger.searchTags,byId("tagger_p-search"));
|
|
||||||
|
|
||||||
if(Tagger.searchTags.getAttribute("max")) {
|
|
||||||
Tagger.setAlert("maxout","Showing "+Tagger.searchTags.getAttribute("rows")+" of "+Tagger.searchTags.getAttribute("max")+" tags");
|
|
||||||
} else {
|
|
||||||
Tagger.setAlert("maxout",false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function tagListReceive(xml) {
|
// dragging
|
||||||
Tagger.appliedTags = document.importNode(xml.getElementsByTagName("list")[0],true);
|
DragHandler.attach(this.editor.titlebar);
|
||||||
tagPublish(Tagger.appliedTags,byId("tagger_p-applied"));
|
|
||||||
}
|
// positioning
|
||||||
function tagPublish(tag_list,page) {
|
this.position.load();
|
||||||
page.innerHTML = "";
|
|
||||||
Tagger.prepTags(tag_list);
|
// events
|
||||||
page.appendChild(tag_list);
|
window.onunload = function () { Tagger.position.save(); };
|
||||||
}
|
},
|
||||||
function prepTags(tag_list) {
|
|
||||||
var len = tag_list.childNodes.length;
|
alert : function (type,text,timeout) {
|
||||||
|
var id = "tagger_alert-"+type
|
||||||
|
var t_alert = byId(id);
|
||||||
|
if (t_alert) {
|
||||||
|
if(text == false) {
|
||||||
|
// remove
|
||||||
|
t_alert.parentNode.removeChild(t_alert);
|
||||||
|
} else {
|
||||||
|
// update
|
||||||
|
t_alert.innerHTML = text;
|
||||||
|
}
|
||||||
|
} else if (text) {
|
||||||
|
// create
|
||||||
|
var t_alert = document.createElement("div");
|
||||||
|
t_alert.setAttribute("id",id);
|
||||||
|
t_alert.appendChild(document.createTextNode(text));
|
||||||
|
this.editor.statusbar.appendChild(t_alert);
|
||||||
|
if(timeout>1) {
|
||||||
|
console.log("Tagger.alert('"+type+"',false,0)");
|
||||||
|
setTimeout("Tagger.alert('"+type+"',false,0)",timeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
editor : {},
|
||||||
|
|
||||||
|
tag : {
|
||||||
|
submit : function () {
|
||||||
|
var l = this.list.childNodes.length;
|
||||||
|
var tags = Array();
|
||||||
|
for(var i=0; i<l; i++) {
|
||||||
|
var s_tag = this.list.childNodes[i].firstChild.data;
|
||||||
|
tags.push(s_tag);
|
||||||
|
}
|
||||||
|
tags = tags.join(" ");
|
||||||
|
this.parent.editor.tags.value = tags;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
for(var i=0; i<len;i++) {
|
search : function(s,ms) {
|
||||||
var tag = tag_list.childNodes[i];
|
clearTimeout(Tagger.tag.timer);
|
||||||
tag.onclick = function() { toggleTag(this); byId("tagger_filter").select(); };
|
Tagger.tag.timer = setTimeout(
|
||||||
//tag.style.display="block";
|
"Tagger.tag.ajax('"+Tagger.tag.query+"?s="+s+"',Tagger.tag.receive)",
|
||||||
tag.setAttribute("title",tag.getAttribute("count")+" uses");
|
ms);
|
||||||
}
|
},
|
||||||
}
|
|
||||||
function createTag(tag_name) {
|
receive : function (xml) {
|
||||||
if (tag_name.length>0) {
|
if(xml) {
|
||||||
var tag = document.createElement("tag");
|
Tagger.tag.suggest = document.importNode(
|
||||||
tag.setAttribute("count","0");
|
xml.responseXML.getElementsByTagName("list")[0],true);
|
||||||
tag.setAttribute("id","newTag_"+tag_name);
|
Tagger.tag.publish(Tagger.tag.suggest,byId("tagger_p-search"));
|
||||||
tag.setAttribute("count",1);
|
|
||||||
tag.setAttribute("title","New");
|
|
||||||
tag.onclick = function() { toggleTag(this); };
|
|
||||||
tag.appendChild(document.createTextNode(tag_name));
|
|
||||||
Tagger.appliedTags.appendChild(tag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function buildPages () {
|
|
||||||
var pages = getElementsByTagNames("div",byId("tagger_body"));
|
|
||||||
var len = pages.length;
|
|
||||||
for(var i=0; i<len; i++) {
|
|
||||||
this.t_menu.innerHTML += "<li onclick='Tagger.togglePages("+
|
|
||||||
"\""+pages[i].getAttribute("id")+"\")'>"+
|
|
||||||
pages[i].getAttribute('name')+"</li>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function tagsToString(tags) {
|
|
||||||
var len = tags.childNodes.length;
|
|
||||||
var str = "";
|
|
||||||
for (var i=0; i<len; i++) {
|
|
||||||
str += tags.childNodes[i].firstChild.data+" ";
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
function toggleTag(tag) {
|
|
||||||
if(tag.parentNode == Tagger.appliedTags) {
|
|
||||||
Tagger.appliedTags.removeChild(tag);
|
|
||||||
} else {
|
|
||||||
Tagger.appliedTags.appendChild(tag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function setAlert(type,arg) {
|
|
||||||
var alert = byId("tagger_alert_"+type);
|
|
||||||
if (alert) {
|
|
||||||
if (arg==false) {
|
|
||||||
//remove existing
|
|
||||||
alert.parentNode.removeChild(alert);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
//update prior
|
if(Tagger.tag.suggest.getAttribute("max")) {
|
||||||
alert.innerHTML = arg;
|
var rows = Tagger.tag.suggest.getAttribute("rows");
|
||||||
} else if (arg!=false) {
|
var max = Tagger.tag.suggest.getAttribute("max");
|
||||||
//create
|
Tagger.alert("maxout","Showing "+rows+" of "+max+" tags",0);
|
||||||
var status = document.createElement("div");
|
} else {
|
||||||
status.setAttribute("id","tagger_alert_"+type);
|
Tagger.alert("maxout",false);
|
||||||
status.innerHTML = arg;
|
}
|
||||||
Tagger.t_status.appendChild(status);
|
},
|
||||||
|
|
||||||
|
image_tags : function(xml) {
|
||||||
|
if (!xml) {
|
||||||
|
this.ajax(this.query+"/"+this.image,this.image_tags);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
Tagger.tag.list = document.importNode(
|
||||||
|
xml.responseXML.getElementsByTagName("list")[0],true);
|
||||||
|
Tagger.tag.publish(Tagger.tag.list,byId("tagger_p-applied"));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
publish : function (list, page) {
|
||||||
|
list.setAttribute("xmlns","http://www.w3.org/1999/xhtml");
|
||||||
|
|
||||||
|
var l = list.childNodes.length;
|
||||||
|
for(var i=0; i<l; i++) {
|
||||||
|
var tag = list.childNodes[i];
|
||||||
|
tag.onclick = function () {
|
||||||
|
Tagger.tag.toggle(this);
|
||||||
|
byId("tagger_filter").select();
|
||||||
|
};
|
||||||
|
tag.setAttribute("title",tag.getAttribute("count")+" uses");
|
||||||
|
}
|
||||||
|
|
||||||
|
page.innerHTML = "";
|
||||||
|
page.appendChild(list);
|
||||||
|
},
|
||||||
|
|
||||||
|
create : function (tag_name) {
|
||||||
|
if(tag_name.length > 0) {
|
||||||
|
var tag = document.createElement("tag");
|
||||||
|
tag.setAttribute("count","0");
|
||||||
|
tag.setAttribute("id","newTag_"+tag_name);
|
||||||
|
tag.setAttribute("title","New - 0 uses");
|
||||||
|
tag.onclick = function() {
|
||||||
|
Tagger.tag.toggle(this);
|
||||||
|
};
|
||||||
|
tag.appendChild(document.createTextNode(tag_name));
|
||||||
|
Tagger.tag.list.appendChild(tag);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
toggle : function (tag) {
|
||||||
|
if(tag.parentNode == this.list) {
|
||||||
|
this.list.removeChild(tag);
|
||||||
|
} else {
|
||||||
|
this.list.appendChild(tag);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ajax : function (url, callback) {
|
||||||
|
var http = (new XMLHttpRequest || new ActiveXObject("Microsoft.XMLHTTP"));
|
||||||
|
http.open("GET",url,true);
|
||||||
|
http.onreadystatechange = function () {
|
||||||
|
if(http.readyState == 4) callback(http);
|
||||||
|
};
|
||||||
|
http.send(null);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
|
position : {
|
||||||
/* AJAX
|
set : function (x,y) {
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
if (!x || !y) {
|
||||||
function ajaxXML(url, callback) {
|
with(this.parent.editor.container.style) {
|
||||||
//var http = getHTTPObject();
|
top = "25px";
|
||||||
var http = (new XMLHttpRequest() || new ActiveXObject("Microsoft.XMLHTTP"));
|
left = "";
|
||||||
http.open("GET", url, true);
|
right = "25px";
|
||||||
http.onreadystatechange = function() {
|
bottom = "";
|
||||||
if(http.readyState == 4) callback(http.responseXML);
|
}
|
||||||
}
|
var xy = this.get();
|
||||||
http.send(null);
|
x = xy[0];
|
||||||
}
|
y = xy[1];
|
||||||
|
}
|
||||||
/* Miscellaneous Code
|
with(this.parent.editor.container.style) {
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
top = y+"px";
|
||||||
|
left = x+"px";
|
||||||
// Quirksmode
|
right = "";
|
||||||
// http://www.quirksmode.org/dom/getElementsByTagNames.htmlgetElementbyId
|
bottom = "";
|
||||||
function getElementsByTagNames(list,obj) {
|
}
|
||||||
if (!obj) var obj = document;
|
},
|
||||||
var tagNames = list.split(',');
|
|
||||||
var resultArray = new Array();
|
get : function () {
|
||||||
for (var i=0;i<tagNames.length;i++) {
|
// http://www.quirksmode.org/js/findpos.html
|
||||||
var tags = obj.getElementsByTagName(tagNames[i]);
|
var left = 0;
|
||||||
for (var j=0;j<tags.length;j++) {
|
var top = 0;
|
||||||
resultArray.push(tags[j]);
|
var obj = this.parent.editor.container;
|
||||||
}
|
if(obj.offsetParent) {
|
||||||
}
|
left = obj.offsetLeft;
|
||||||
var testNode = resultArray[0];
|
top = obj.offsetTop;
|
||||||
if (!testNode) return [];
|
while (obj = obj.offsetParent) {
|
||||||
if (testNode.sourceIndex) {
|
left += obj.offsetLeft;
|
||||||
resultArray.sort(function (a,b) {
|
top += obj.offsetTop;
|
||||||
return a.sourceIndex - b.sourceIndex;
|
}
|
||||||
});
|
}
|
||||||
}
|
return [left,top];
|
||||||
else if (testNode.compareDocumentPosition) {
|
},
|
||||||
resultArray.sort(function (a,b) {
|
|
||||||
return 3 - (a.compareDocumentPosition(b) & 6);
|
save : function (x,y) {
|
||||||
});
|
if (!x || !y) {
|
||||||
}
|
var xy = this.get();
|
||||||
return resultArray;
|
x = xy[0];
|
||||||
}
|
y = xy[1];
|
||||||
// http://www.quirksmode.org/js/findpos.html
|
}
|
||||||
function findPos(obj) {
|
setCookie(config.title+"_tagger-position",x+" "+y,14);
|
||||||
var curleft = curtop = 0;
|
},
|
||||||
if (obj.offsetParent) {
|
|
||||||
curleft = obj.offsetLeft
|
load : function () {
|
||||||
curtop = obj.offsetTop
|
var p = getCookie(config.title+"_tagger-position");
|
||||||
while (obj = obj.offsetParent) {
|
if(p) {
|
||||||
curleft += obj.offsetLeft
|
var xy = p.split(" ");
|
||||||
curtop += obj.offsetTop
|
this.set(xy[0],xy[1]);
|
||||||
}
|
} else {
|
||||||
}
|
this.set();
|
||||||
return [curleft,curtop];
|
|
||||||
}
|
|
||||||
|
|
||||||
// ripped from a forum.
|
|
||||||
// todo: cite source
|
|
||||||
function reescape(str){
|
|
||||||
var resp="()?:=[]*+{}^$|/,.!\\"
|
|
||||||
var found=false
|
|
||||||
var ret=""
|
|
||||||
for(var i=0;i<str.length;i++) {
|
|
||||||
found=false
|
|
||||||
for(var j=0;j<resp.length;j++) {
|
|
||||||
if(str.charAt(i)==resp.charAt(j)) {
|
|
||||||
found=true;break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(found) {
|
|
||||||
ret+="\\"
|
|
||||||
}
|
|
||||||
ret+=str.charAt(i)
|
|
||||||
}
|
}
|
||||||
return ret
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// Modified from above
|
|
||||||
function sqlescape(str){
|
|
||||||
var resp="#%&_"
|
|
||||||
var found=false
|
|
||||||
var ret=""
|
|
||||||
for(var i=0;i<str.length;i++) {
|
|
||||||
found=false
|
|
||||||
for(var j=0;j<resp.length;j++) {
|
|
||||||
if(str.charAt(i)==resp.charAt(j)) {
|
|
||||||
found=true;break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(found) {
|
|
||||||
ret+="\\"
|
|
||||||
}
|
|
||||||
ret+=str.charAt(i)
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
@ -75,13 +75,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#tagger_parent list[id=image] tag:before {
|
#tagger_parent list[id=image] tag:before {
|
||||||
font-family: monospace;
|
content:url('./images/active.png');
|
||||||
content:"[ ]";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#tagger_parent list[id=search] tag:before {
|
#tagger_parent list[id=search] tag:before {
|
||||||
font-family: monospace;
|
content:url('./images/inactive.png');
|
||||||
content:"[ ]";
|
|
||||||
}
|
}
|
||||||
/* Hovering */
|
/* Hovering */
|
||||||
#tagger_parent tag:hover {
|
#tagger_parent tag:hover {
|
||||||
@ -89,20 +87,18 @@
|
|||||||
background-color:#ddd;
|
background-color:#ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tagger_parent list[id=image] tag:hover {
|
/*#tagger_parent list[id=image] tag:hover {
|
||||||
background-color:#faa;
|
background-color:#faa;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tagger_parent list[id=search] tag:hover {
|
#tagger_parent list[id=search] tag:hover {
|
||||||
background-color:#afa;
|
background-color:#afa;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
#tagger_parent list[id=image] tag:hover:before {
|
#tagger_parent list[id=image] tag:hover:before {
|
||||||
font-family: monospace;
|
content:url('./images/rem-tag.png');
|
||||||
content:"[\00d7]";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#tagger_parent list[id=search] tag:hover:before {
|
#tagger_parent list[id=search] tag:hover:before {
|
||||||
font-family: monospace;
|
content:url('./images/add-tag.png');
|
||||||
content:"[+]";
|
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,8 @@ class taggerTheme extends Themelet {
|
|||||||
// TODO: AJAX test and fallback.
|
// TODO: AJAX test and fallback.
|
||||||
$page->add_header("<script src='$base_href/ext/tagger/webtoolkit.drag.js' type='text/javascript'></script>");
|
$page->add_header("<script src='$base_href/ext/tagger/webtoolkit.drag.js' type='text/javascript'></script>");
|
||||||
$page->add_block(new Block(null,
|
$page->add_block(new Block(null,
|
||||||
"<script type='text/javascript'>
|
"<script type='text/javascript'>Tagger.initialize("
|
||||||
var query = '".make_link("tagger/tags")."';
|
.$event->get_image()->id.");</script>","main",1000));
|
||||||
var image_id = ".$event->get_image()->id.";
|
|
||||||
var tagger_filter_timer = null;
|
|
||||||
var Tagger = new Tagger();
|
|
||||||
Tagger.initialize();
|
|
||||||
</script>","main",1000));
|
|
||||||
|
|
||||||
// Tagger block
|
// Tagger block
|
||||||
$page->add_block( new Block(
|
$page->add_block( new Block(
|
||||||
@ -28,10 +23,12 @@ class taggerTheme extends Themelet {
|
|||||||
"main"));
|
"main"));
|
||||||
}
|
}
|
||||||
private function html($image) {
|
private function html($image) {
|
||||||
|
global $config;
|
||||||
$i_image_id = int_escape($image->id);
|
$i_image_id = int_escape($image->id);
|
||||||
$h_source = html_escape($image->source);
|
$h_source = html_escape($image->source);
|
||||||
if(isset($_GET['search'])) {$h_query = "search=".url_escape($_GET['search']);}
|
$h_query = isset($_GET['search'])? $h_query= "search=".url_escape($_GET['search']) : "";
|
||||||
else {$h_query = "";}
|
|
||||||
|
$delay = $config->get_string("ext_tagger_search_delay","250");
|
||||||
|
|
||||||
$url_form = make_link("tag_edit/set");
|
$url_form = make_link("tag_edit/set");
|
||||||
|
|
||||||
@ -41,9 +38,9 @@ class taggerTheme extends Themelet {
|
|||||||
<div id="tagger_titlebar">Tagger</div>
|
<div id="tagger_titlebar">Tagger</div>
|
||||||
|
|
||||||
<div id="tagger_toolbar">
|
<div id="tagger_toolbar">
|
||||||
<input type="text" value="" id="tagger_filter" onkeyup="Tagger.tagSearch(this.value, 500);"></input>
|
<input type="text" value="" id="tagger_filter" onkeyup="Tagger.tag.search(this.value, $delay);"></input>
|
||||||
<input type="button" value="Add" onclick="Tagger.createTag(byId('tagger_filter').value);"></input>
|
<input type="button" value="Add" onclick="Tagger.tag.create(byId('tagger_filter').value);"></input>
|
||||||
<form action="$url_form" method="POST" onsubmit="Tagger.submit();">
|
<form action="$url_form" method="POST" onsubmit="Tagger.tag.submit();">
|
||||||
<input type='hidden' name='image_id' value='$i_image_id' id="image_id"></input>
|
<input type='hidden' name='image_id' value='$i_image_id' id="image_id"></input>
|
||||||
<input type='hidden' name='query' value='$h_query'></input>
|
<input type='hidden' name='query' value='$h_query'></input>
|
||||||
<input type='hidden' name='source' value='$h_source'></input>
|
<input type='hidden' name='source' value='$h_source'></input>
|
||||||
@ -55,9 +52,9 @@ class taggerTheme extends Themelet {
|
|||||||
<br style="clear:both;"/>-->
|
<br style="clear:both;"/>-->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="tagger_body">
|
<div id="tagger_body">
|
||||||
<div id="tagger_p-applied" name="Applied Tags"></div>
|
|
||||||
<div id="tagger_p-search" name="Searched Tags"></div>
|
<div id="tagger_p-search" name="Searched Tags"></div>
|
||||||
|
<div id="tagger_p-applied" name="Applied Tags"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="tagger_statusbar"></div>
|
<div id="tagger_statusbar"></div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user