Tagger: 20070930 0153

git-svn-id: file:///home/shish/svn/shimmie2/trunk@505 7f39781d-f577-437e-ae19-be835c7a54ca
This commit is contained in:
Artanis 2007-09-30 08:53:47 +00:00
parent 6f69f52614
commit ced91f14dd
5 changed files with 417 additions and 362 deletions

View File

@ -30,14 +30,14 @@ class tagger extends Extension {
$base_href = $config->get_string('base_href'); $base_href = $config->get_string('base_href');
$tags_min = $config->get_int('ext-tagger_tags-min',2); $tags_min = $config->get_int('ext-tagger_tags-min',2);
$hidden = $config->get_bool( $hidden = $config->get_string(
'ext-tagger_respect-hidden', 'ext-tagger_show-hidden','N')=='N' ?
true) ? "AND substring(tag,1,1) != '.' " : null; " AND substring(tag,1,1) != '.' " : null;
$tags = $database->Execute(" $tags = $database->Execute("
SELECT tag SELECT tag
FROM `tags` FROM `tags`
WHERE count >= ? {$hidden} WHERE count>=?{$hidden}
ORDER BY tag",array($tags_min)); ORDER BY tag",array($tags_min));
$this->theme->build($page, $tags); $this->theme->build($page, $tags);

View File

@ -3,9 +3,18 @@
// Do not remove this notice. // Do not remove this notice.
// All other code copyright by their authors, see comments for details. // 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() { function taggerResetPos() {
// In case the drag point goes off screen.
tagger = byId("tagger_window"); tagger = byId("tagger_window");
tagger.style.top=""; tagger.style.top="";
@ -22,86 +31,120 @@ function taggerResetPos() {
tagger.style.bottom=""; tagger.style.bottom="";
} }
function tagExists(tag) { function tagger_tagIndicators() {
var tags = byId("tags"); tags = byId("tags");
tags_list = tags.value; arObjTags = getElementsByTagNames('a',byId('tagger_body'));
tags_array = tags_list.split(" ");
tags_list = ""; for (i in arObjTags) {
for (x in tags_array) { objTag = arObjTags[i];
if(tags_array[x] == tag) { if(tagExists(objTag)) {
return true; objTag.style.fontWeight="bold";
} }
} }
return false;
} }
function toggleTag(tag,rTagme) { /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
if (!tagExists(tag)) { * Tagging *
addTag(tag); \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
if(rTagme && tag != "tagme") {
remTag("tagme"); function toggleTag(objTag) {
if(!tagExists(objTag)) {
addTag(objTag);
if (remove_tagme && objTag.attributes.tag.value != 'tagme') {
remTag(remove_tagme);
} }
} else { } else {
remTag(tag); remTag(objTag);
}
obj = byId("tagger_custTag");
if(obj.value) {
obj.select();
} }
t = byId("tagger_new-tag");
if(t.value) { t.select(); }
} }
function addTagById(id) { function addTag (objTag) {
tag = byId(id); var tags = byId('tags');
toggleTag(tag.value);
}
function addTag (tag) {
var tags = byId("tags");
var tag_link = byId("tagger_tag_"+tag);
var delim = " "; delim = tags.value==" "?"":" ";
if(tags.value == "") {
delim=""; tags.value += delim + objTag.attributes.tag.value;
}
tags.value = tags.value + delim + tag; if(objTag.value != 'Add') {
if(tag_link) { objTag.style.fontWeight = "bold";
tag_link.style.fontWeight = "bold";
} }
} }
function remTag (tag) { function remTag (objTag) {
var tags = byId("tags"); var tags = byId("tags");
var tag_link = byId("tagger_tag_"+tag);
_tags = tags.value.split(" "); aTags = tags.value.split(" ");
tags.value = ""; tags.value="";
for (i in _tags) { for(i in aTags) {
_tag = _tags[i]; aTag = aTags[i];
if(_tag != tag) { if(aTag != objTag.attributes.tag.value) {
addTag(_tag); if(tags.value=="") {
tags.value += aTag;
} else {
tags.value += " "+aTag;
}
} }
} }
if(tag_link) { if(objTag.value != 'Add') {
tag_link.style.fontWeight = ""; objTag.style.fontWeight = "";
} }
} }
function setTagIndicators() { function tagExists(objTag) {
taggerResetPos(); return byId("tags").value.match(reescape(objTag.attributes.tag.value));
}
tags = byId("tags");
tags = tags.value.split(" "); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* Filtering *
for (x in tags) { \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
tag = tags[x];
obj = byId("tagger_tag_"+tag); var tagger_filter_focus = false;
if(obj) { function tagger_filter(override) {
obj.style.fontWeight="bold"; 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) { function pushSet(form_id) {
var set = getSetButton(form_id); var set = getSetButton(form_id);
@ -121,35 +164,11 @@ function getSetButton(form_id) {
return false; return false;
} }
var _f_custTag = false; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
function tagger_filter(id) { * quirksmode.org *
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 // // http://www.quirksmode.org/dom/getElementsByTagNames.html
// http://www.quirksmode.org/dom/getElementsByTagNames.html //
function getElementsByTagNames(list,obj) { function getElementsByTagNames(list,obj) {
if (!obj) var obj = document; if (!obj) var obj = document;
var tagNames = list.split(','); var tagNames = list.split(',');
@ -174,7 +193,8 @@ function getElementsByTagNames(list,obj) {
} }
return resultArray; return resultArray;
} }
// http://www.quirksmode.org/js/findpos.html //
// http://www.quirksmode.org/js/findpos.html
function findPos(obj) { function findPos(obj) {
var curleft = curtop = 0; var curleft = curtop = 0;
if (obj.offsetParent) { if (obj.offsetParent) {
@ -187,163 +207,24 @@ function findPos(obj) {
} }
return [curleft,curtop]; return [curleft,curtop];
} }
// End //
// Drag Code // // ripped from a forum.
//***************************************************************************** // todo: cite source
// Do not remove this notice. function reescape(str){
// var resp="()?:=[]*+{}^$|/,.!\\"
// Copyright 2001 by Mike Hall. var found=false
// See http://www.brainjar.com for terms of use. var ret=""
//***************************************************************************** for(var i=0;i<str.length;i++) {
found=false
// Determine browser and version. for(var j=0;j<resp.length;j++) {
if(str.charAt(i)==resp.charAt(j)) {
function Browser() { found=true;break
}
var ua, s, i; }
if(found) {
this.isIE = false; ret+="\\"
this.isNS = false; }
this.version = null; ret+=str.charAt(i)
}
ua = navigator.userAgent; return ret
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;
}
} }
var browser = new Browser();
// Global object to hold drag information.
var dragObj = new Object();
dragObj.zIndex = 0;
function dragStart(event, id) {
var el;
var x, y;
// If an element id was given, find it. Otherwise use the element being
// clicked on.
if (id)
dragObj.elNode = document.getElementById(id);
else {
if (browser.isIE)
dragObj.elNode = window.event.srcElement;
if (browser.isNS)
dragObj.elNode = event.target;
// If this is a text node, use its parent element.
if (dragObj.elNode.nodeType == 3)
dragObj.elNode = dragObj.elNode.parentNode;
}
// Get cursor position with respect to the page.
if (browser.isIE) {
x = window.event.clientX + document.documentElement.scrollLeft
+ document.body.scrollLeft;
y = window.event.clientY + document.documentElement.scrollTop
+ document.body.scrollTop;
}
if (browser.isNS) {
x = event.clientX + window.scrollX;
y = event.clientY + window.scrollY;
}
// Save starting positions of cursor and element.
dragObj.cursorStartX = x;
dragObj.cursorStartY = y;
dragObj.elStartLeft = parseInt(dragObj.elNode.style.left, 10);
dragObj.elStartTop = parseInt(dragObj.elNode.style.top, 10);
if (isNaN(dragObj.elStartLeft)) dragObj.elStartLeft = 0;
if (isNaN(dragObj.elStartTop)) dragObj.elStartTop = 0;
// Update element's z-index.
dragObj.elNode.style.zIndex = ++dragObj.zIndex;
// Capture mousemove and mouseup events on the page.
if (browser.isIE) {
document.attachEvent("onmousemove", dragGo);
document.attachEvent("onmouseup", dragStop);
window.event.cancelBubble = true;
window.event.returnValue = false;
}
if (browser.isNS) {
document.addEventListener("mousemove", dragGo, true);
document.addEventListener("mouseup", dragStop, true);
event.preventDefault();
}
}
function dragGo(event) {
var x, y;
// Get cursor position with respect to the page.
if (browser.isIE) {
x = window.event.clientX + document.documentElement.scrollLeft
+ document.body.scrollLeft;
y = window.event.clientY + document.documentElement.scrollTop
+ document.body.scrollTop;
}
if (browser.isNS) {
x = event.clientX + window.scrollX;
y = event.clientY + window.scrollY;
}
// Move drag element by the same amount the cursor has moved.
dragObj.elNode.style.left = (dragObj.elStartLeft + x - dragObj.cursorStartX) + "px";
dragObj.elNode.style.top = (dragObj.elStartTop + y - dragObj.cursorStartY) + "px";
if (browser.isIE) {
window.event.cancelBubble = true;
window.event.returnValue = false;
}
if (browser.isNS)
event.preventDefault();
}
function dragStop(event) {
// Stop capturing mousemove and mouseup events.
if (browser.isIE) {
document.detachEvent("onmousemove", dragGo);
document.detachEvent("onmouseup", dragStop);
}
if (browser.isNS) {
document.removeEventListener("mousemove", dragGo, true);
document.removeEventListener("mouseup", dragStop, true);
}
}
// End //

View File

@ -4,40 +4,48 @@
* Do not remove this notice. * * Do not remove this notice. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#Tagger {
text-align:left;
}
#tagger_window { #tagger_window {
position:fixed; position:fixed;
text-align:left; text-align:left;
min-width:250px;
} }
#tagger_titlebar { #tagger_titlebar {
font-weight:bold;
text-align:center;
position:relative;
top:-0em;
padding:.25em;
border:2px solid;
-moz-border-radius:1em;
background-image:none;
background-color:#DDDDDD; background-color:#DDDDDD;
margin-bottom:.5em; background-image:none;
border:2px solid;
cursor:move; cursor:move;
font-weight:bold;
/*margin-bottom:.5em;*/
-moz-border-radius:2em 2em 0 0;
padding:.25em;
position:relative;
text-align:center;
top:-0em;
} }
#tagger_body, #tagger_filter { #tagger_body {
overflow:scroll; background-color:#EEEEEE;
padding:1em;
border:2px solid; border:2px solid;
border-top:none; border-top:none;
background-color:white; overflow:scroll;
padding:1em;
max-height:200px;
} }
#tagger_filter { #tagger_filter {
overflow:hidden; background-color:#EEEEEE;
-moz-border-radius:1em 1em 0 0;
border:2px solid; border:2px solid;
border-bottom:none; border-bottom:none;
border-top:none;
margin-bottom:-1px; margin-bottom:-1px;
text-align:center; /*-moz-border-radius:1em 1em 0 0;*/
padding:1em;
padding-bottom:1px; padding-bottom:1px;
text-align:center;
} }
#tagger_filter input { #tagger_filter input {
width:auto; width:auto;
@ -45,9 +53,20 @@
#tagger_body a { #tagger_body a {
font-size:1.25em; font-size:1.25em;
display:block;
cursor:pointer;
} }
#Tagger li { #Use #Tagger {
margin-bottom:1em; -moz-column-gap:20px;
width:20em; -moz-column-count:3;
}
#Use #Tagger li {
margin-bottom:1em;
max-width:30em;
}
#Tagger .tagger_js {
cursor:pointer;
} }

View File

@ -4,108 +4,178 @@
// Do not remove this notice. // Do not remove this notice.
class taggerTheme extends Themelet { class taggerTheme extends Themelet {
public function build ($page, $tags) {
global $config;
$tagme = $config->get_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 .= "
<div id='tagger_tag_".$tag_name."'>
<a style='cursor:pointer;'
onclick='toggleTag(&quot;".$tag_name."&quot;,".$tagme.");'
title='Add &quot;".$tag_name."&quot; to the tag list'>".$tag_trunc."
</a>
</div>";
}
$url_more = make_link("about/tagger");
$html = <<<EOD
<img style='display:none;' src='$base_href/ext/tagger/onload.gif'
onload='setTagIndicators();'/>
<span style="font-size:.7em;">Collapse this block to hide Tagger.</span>
<br/>
<a onclick="taggerResetPos();" style="cursor:pointer;">Default Location</a>
<hr/>
<a href='$url_more'>About Tagger</a>
<div id="tagger_window" style="bottom:25px;right:25px;">
<div id="tagger_titlebar" title="Drag to move"
onmousedown="dragStart(event,&quot;tagger_window&quot;);">
Tagger
</div>
<div id="tagger_filter">
<input type="text" id="tagger_custTag" value="" onfocus="_f_custTag = true;" public function build($event,$tags) {
onblur="_f_custTag = false;" // When overriding this function, take care that all tag attributes are
onkeyup="tagger_filter(&quot;tagger_custTag&quot;)" size='12'> // maintained UNCHANGED. There are no attributes in the HTML code below
</input> // that go unused by the javascript. If you fail to do this,
<input type="button" value="Add" // the extension will BREAK!
onclick="addTagById(&quot;tagger_custTag&quot;)"> //
</input> <input type="button" onclick="pushSet(&quot;imgdata&quot;);" // Now that that's sunk in, chaniging title attributes is fine.
value="Set"> global $config;
</input> global $page;
// set up data
$base_href = $config->get_string('base_href');
$tagme = $config->get_string(
'ext-tagger_clear-tagme','N')=="Y"?
"<input type='hidden' id='tagme' tag='tagme'></input>":
null;
$url_about = make_link("about/tagger");
// build floater tags
$h_tags = "";
foreach($tags as $tag) {
$h_tags .= $this->tag_to_html($tag);
}
$html = "
<img src='$base_href/ext/tagger/onload.gif' style='display:none;'
onload='taggerInit();' />
<span style='font-size:0.7em;'>
Collapse this block to hide Tagger
</span>
<br/>
<a onclick='taggerResetPos();' class='tagger_js'>Default Location</a>
<hr/> <hr/>
</div> <a href='$url_about'>About Tagger</a>".
<div id="tagger_body" style="height:200px;">$tag_html</div> // Tagger Floater
</div> "<div id='tagger_window'>
EOD; <div id='tagger_titlebar' title='Drag to move'>Tagger</div>
$page->add_block( new Block("Tagger - Advanced Tagging", <div id='tagger_filter'>
"".$html, <input type='text' id='tagger_new-tag' value='' size='12'
"left", onfocus='tagger_filter_focus = true;'
50)); onblur='tagger_filter_focus = false;'
onkeyup='tagger_filter();' focus='' title='Type to search' >
</input>
<input type='button' value='Add' tag='' title='Add typed tag'
onclick='
this.attributes.tag.value=
byId(\"tagger_new-tag\").value;
toggleTag(this);'>
</input>
<input type='button' value='Set' onclick='pressSet();'
title='Save tags'></input>
$tagme
<hr/>
<a id='tagger_mode' class='tagger_js' mode='all'
onclick='taggerToggleMode()'>View Applied Tags</a> |
<a onclick='tagger_tagIndicators(); tagger_filter(true);'
class='tagger_js' >Refresh Filter</a>
</div>
<div id='tagger_body'>$h_tags</div>
</div>";
$page->add_block( new Block(
"Tagger",
$html,
"left"));
$page->add_header(
"<script
src='$base_href/ext/tagger/webtoolkit.drag.js'
type='text/javascript'></script>");
} }
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("\"","&quot;",str_replace("\'","&#39;","
<ul id='Tagger'>
<li>
If Tagger is in your way, click and drag it\'s title bar to move
it to a more convienient location.
<li>
Click the links to add the tag to the image\'s tag list, when
done, press the Set button to save the tags.
</li>
<li>
<p>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.
</p>
<p>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.
</p>
<p>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.
</p>
<p>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.
</p>
</li>
<li><h4>Requirements</h4>
<p>Tagger requires javascript for its functionality. Sorry, but
there\'s no other way to accomplish the tag list
modifications.
</p>
<p>If you have javascript completely disabled, you will not be
able to use Tagger.
</p>
<p>Depending on your method of disabling javascript, you may be
able to whitelist scripts. The script files used by Tagger are
<a href='$script1'>script.js</a> and
<a href='$script2'>webtoolkit.drag.js</a>.
</p>
</li>
</ul>"));
$page->set_title("Shimmie - About / Tagger - Advanced Tagging");
$page->set_heading("About / Tagger - Advanced Tagging");
$page->add_block( new Block("Author",
"Artanis (Erik Youngren &lt;artanis.00@gmail.com&gt;)","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 <A>
// 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 = "
<a id='$tag_id' title='Apply &quot;$tag_name&quot;' tag='$tag_name'
onclick='toggleTag(this)'>$stag</a>";
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) { if(strlen($s) > $len) {
$s = substr($s, 0,$len-1); $s = substr($s, 0,$len-1);
$s = substr($s,0, strrpos($s,$break))."..."; $s = substr($s,0, strrpos($s,$br))."...";
} }
return $s; return $s;
} }
public function show_about ($event) {
global $page;
$html = <<<EOD
<ul id="Tagger">
<li>
If Tagger is in you way, click and drag it&#39;s title bar to move it to a
more convienient location.
<li>
Click the links to add the tag to the image&#39;s tag list, when done, press
the Set button to save the tags.
</li>
<li>
<p>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&#39;ll only need one
or two letters to trim the list down to the tag you are looking for.</p>
<p>If the tag is not in the list, finish typing out the tag and click "Add"
to add the tag to the image&#39;s tag list.</p>
<p>Tags must have two uses to appear in Tagger&#39;s list, so you'll have to
enter the tag for at least one other image for it to show up.</p>
</li>
<li>
<p>Tagger requires javascript for its functionality. Sorry, but there&#39;s
no other way to accomplish the tag list modifications.</p>
<p>If you have javascript completely disabled, you will not be able to use
Tagger.</p>
<p>Due to the manner in which Tagger is constructed, it will hide along with
it&#39;s block on the side bar and block behaviour will remember that
setting in shimmie&#39;s cookies.</p>
</li>
</ul>
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 &lt;artanis.00@gmail.com&gt;)","main",0));
$page->add_block( new Block("Use", $html,"main",1));
}
} }
?> ?>

View File

@ -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;
}
}