--- a/javascript/taggr.js Thu Jan 17 01:56:04 2008 +0000
+++ b/javascript/taggr.js Sun Jan 20 01:07:02 2008 +0000
@@ -1,11 +1,24 @@
+/*
+ * dir-list manipulation
+ */
function toggle_dir (header_a_tag) {
var div = Element.next(header_a_tag);
if (div._have_contents) {
- if (div.visible())
+ if (div.visible()) {
Effect.BlindUp(div, {duration: 0.5});
- else
+ func = hide_tag_image;
+ } else {
Effect.BlindDown(div, {duration: 0.5});
+ func = show_tag_image;
+ }
+
+ Element.up(header_a_tag)._images.each(function(key){
+ $("img_" + key)._tags.each(function(tag){
+ func(tag, key);
+ });
+ });
+
} else {
new Ajax.Updater(div, "taggr2.py", {
@@ -22,37 +35,296 @@
}
}
-function new_tag (tag_name) {
- var tag_images = Builder.node("td", {className:"tag_images"});
+var g_last_select;
+function image_click (img, ev) {
+ var updiv = img.up(2);
- $("tag_table").appendChild(
- Builder.node("tr", [
- Builder.node("td", {className:"tag"}, [
- tag_name
- ]),
- tag_images
- ])
- );
+ if (img.hasClassName("selection")) {
+ img.removeClassName("selection");
+
+ } else if (ev.shiftKey && g_last_select && g_last_select.up(2) == updiv) {
+ var from = Math.min(img._offset, g_last_select._offset);
+ var to = Math.max(img._offset, g_last_select._offset);
+
+ for (var i = from; i <= to; i++) {
+ $("img_" + updiv._images[i]).addClassName("selection");
+ }
+
+ g_last_select = img;
+ } else {
+
+ g_last_select = img;
+ img.addClassName("selection");
+ }
}
-function image_dropped (img, tag, e) {
-}
-
-function image_loaded (img) {
+function selection_clear () {
+ $$(".selection").each(function(e){
+ e.removeClassName("selection");
+ });
}
-function image_click (img, ev) {
+/*
+ * image-loading callback
+ */
+function image_info (img, offset, key, tags) {
+ img._key = key;
+ img._tags = $A(tags);
+ img._offset = offset;
+
+ img._tags.each(function(tag){
+ if (!$('tag_' + tag + '_images'))
+ new_tag(tag);
+ tag_add_image(img, null, tag, false);
+ });
+
+ var dir = img.up(2);
+
+ if (!dir._images)
+ dir._images = new Array();
+
+ dir._images.push(img._key);
}
-function init () {
+/*
+ * tag list manipulation code
+ */
+function _tag_name (tag_name) {
+ var tag_name_p = Builder.node("p", {id:"tag_" + tag_name + "_name", className: "draggable tag_name"}, [tag_name]);
+
+ tag_name_p._tag = tag_name;
+
+ return tag_name_p;
}
+function new_tag (tag_name) {
+ var tag_images = Builder.node("td", {className:"tag_images", id:"tag_" + tag_name + "_images"});
+
+ tag_images._tag = tag_name;
+ tag_images._visibleCount = 0;
+ tag_images._images = new Array();
+
+ var tag_row = Builder.node("tr", {className:"tag_row", id:"tag_" + tag_name}, [
+ Builder.node("td", {className:"tag", id:"tag_" + tag_name + "_tags"}, [
+ _tag_name(tag_name)
+ ]),
+ tag_images
+ ]);
+
+ tag_row._tag = tag_name;
+ tag_row._tags = new Array(tag_name);
+
+ $("tag_table").appendChild(tag_row);
+}
+
+function tag_add_tag (new_tag, tag) {
+ var tag_row = $("tag_" + tag);
+
+ if (tag_row._tags.indexOf(new_tag) != -1)
+ return false;
+
+ tag_row._tags.push(new_tag);
+
+ $("tag_" + tag + "_tags").appendChild(_tag_name(new_tag));
+
+/*
+ new Ajax.Request("taggr2.py", {
+ parameters: {
+ act: 'tag',
+ tag: new_tag,
+ img: $("tag_" + tag + "_images")._images,
+ },
+ method: 'get'
+ });
+*/
+}
+
+function tag_remove_tag (tag_name) {
+ var tag_row = $("tag_" + tag_name + "_name").up(1);
+ array_remove(tag_row._tags, tag_name);
+
+ $("tag_" + tag_row._tag + "_tags").removeChild($("tag_" + tag_name + "_name"));
+
+ if (tag_row._tags.length == 0)
+ $("tag_table").removeChild(tag_row);
+}
+
+function get_tag (tag_name, postfix) {
+ return $("tag_" + $("tag_" + tag_name).up(1)._tag + "_" + postfix);
+}
+
+function tag_add_image (orig_img, copy_img, tag, saveToDB) {
+ var tag_images = $('tag_' + tag + '_images');
+
+ if (tag_images._images.indexOf(orig_img._key) != -1)
+ return false;
+
+ if (!copy_img)
+ copy_img = image_copy(orig_img);
+
+ tag_images._images.push(orig_img._key)
+ orig_img._tags.push(tag);
+
+ copy_img.id = "tag_" + tag + "_img_" + orig_img._key
+ copy_img._tag = tag;
+
+ tag_images.appendChild(copy_img);
+ tag_images._visibleCount++;
+
+ if (saveToDB) {
+ new Ajax.Request("taggr2.py", {
+ parameters: {
+ act: 'tag',
+ img: orig_img._key,
+ tag: tag,
+ },
+ method: 'get'
+
+ });
+ }
+}
+
+function tag_add_images (images, tag_name) {
+ var tag_images = $('tag_' + tag_name + '_images');
+ var copy_img, img_keys = new Array();
+
+ images.each(function(orig_img){
+ tag_add_image(orig_img, null, tag_name, false);
+ img_keys.push(orig_img._key);
+ });
+
+ new Ajax.Request("taggr2.py", {
+ parameters: {
+ act: 'tag',
+ img: img_keys,
+ tag: tag_name,
+ },
+ method: 'get'
+
+ });
+}
+
+function tag_remove_image (img_key, tag_name) {
+ var tag_images = $("tag_" + tag_name + "_images");
+
+ tag_images.removeChild($("tag_" + tag_name + "_img_" + img_key));
+ array_remove(tag_images._images, img_key);
+
+ if (tag_images._images.length == 0)
+ $("tag_" + tag_name).hide();
+
+ new Ajax.Request("taggr2.py", {
+ parameters: {
+ act: 'untag',
+ img: img_key,
+ tag: tag_name,
+ },
+ method: 'get',
+ });
+}
+
+function hide_tag_image (tag, img) {
+ $("tagimg_" + tag + "_" + img).hide();
+
+ if (--$("tag_" + tag + "_images")._visibleCount == 0)
+ $("tag_" + tag).hide();
+}
+
+function show_tag_image (tag, img) {
+ $("tagimg_" + tag + "_" + img).hide();
+
+ if ($("tag_" + tag + "_images")._visibleCount++ == 0)
+ $("tag_" + tag).show();
+}
+
+/*
+ * Frontend image drag code
+ */
+var g_ghost;
+function drag_start (e) {
+ if (e.hasClassName("image") || e.hasClassName("tag_image"))
+ g_ghost = image_copy(e);
+ else {
+ var name;
+
+ if (e.hasClassName("tag_name"))
+ name = e._tag;
+ else
+ name = $F($('new_tag'));
+
+ g_ghost = Builder.node("span", {className: 'dragged'}, [name]);
+ }
+
+ $('taggr').appendChild(g_ghost);
+
+ g_ghost.style.position = "absolute";
+}
+
+function drag_move (e, ev) {
+ g_ghost.style.left = ev.pointerX() - g_offset.left + "px";
+ g_ghost.style.top = ev.pointerY() - g_offset.top + "px";
+}
+
+function drag_end_drop (e, s, ev) {
+ g_ghost.style.position = "static";
+ $('taggr').removeChild(g_ghost);
+
+ if (e.hasClassName("image") || e.hasClassName("tag_image")) {
+ var selection = $$(".selection");
+
+ if (selection.length)
+ tag_add_images($$(".selection"), s._tag);
+ else
+ tag_add_image(e, g_ghost, s._tag, true);
+
+/*
+ if (!tag_add_image(e, g_ghost, s._tag, true))
+ // it was already in there
+ Effect.Shake("tagimg_" + s._tag + "_" + g_ghost._key);
+*/
+ } else if (e.hasClassName("tag_name")) {
+ null; // breakpoint
+ } else {
+ tag_add_tag($F($('new_tag')), s._tag);
+ }
+}
+
+function drag_end_fail (e, ev) {
+ if (e.hasClassName("tag_image")) {
+ tag_remove_image(e._key, e._tag);
+ $('taggr').removeChild(g_ghost);
+ } else if (e.hasClassName("tag_name")) {
+ tag_remove_tag(e._tag);
+ } else {
+ $('taggr').removeChild(g_ghost);
+ }
+}
+
+function drag_cleanup (e, ev) {
+ g_ghost = null;
+}
+
+function drag_hover (e, s, ev) {
+ s.addClassName("hover");
+}
+
+function drag_unhover (e, s, ev) {
+ s.removeClassName("hover");
+}
+
+/*
+ * Backend image click/drag code
+ */
+
var g_drag, g_hover, g_start, g_offset, g_targets;
function check_mouse_down (ev) {
var e = ev.element();
+
+ if (!ev.isLeftClick())
+ return true;
- if (e.hasClassName("image")) {
+ if (e.hasClassName("image") || e.hasClassName("draggable") || e.hasClassName("tag_image")) {
g_drag = e;
g_start = false;
@@ -65,7 +337,7 @@
g_hover = null;
- g_targets = $$(".tag_images");
+ g_targets = $$(".tag_row");
} else if (e.hasClassName("directory_link")) {
toggle_dir(e);
@@ -88,8 +360,13 @@
drag_end_fail(g_drag, ev);
drag_cleanup(g_drag);
- } else
- image_click(g_drag, ev);
+ } else if (g_drag.hasClassName("image") || g_drag.hasClassName("tag_image")) {
+ // in case image_click blocks and we get a mouse_move during it
+ var tmp = g_drag;
+ g_drag = null;
+
+ image_click(tmp, ev);
+ }
g_start = null;
g_drag = null;
@@ -124,6 +401,7 @@
if (Position.withinIncludingScrolloffsets(g_targets[i], px, py)) {
drag_hover(g_drag, g_targets[i], ev);
g_hover = g_targets[i];
+ break;
}
}
@@ -133,10 +411,10 @@
}
function check_drag_hover (ev) {
- var e = ev.element();
if (g_start) {
+ var e = ev.element();
- if (e.hasClassName("tag_images")) {
+ if (e.hasClassName("tag_row")) {
drag_hover(g_drag, e, ev);
g_hover = e;
}
@@ -144,8 +422,8 @@
}
function check_drag_nohover (ev) {
+ if (g_start) {
var e = ev.element();
- if (g_start) {
if (g_hover && e == g_hover) {
drag_unhover(g_drag, g_hover, ev);
@@ -154,64 +432,33 @@
}
}
-var g_ghost;
-function drag_start (e) {
- g_ghost = Builder.node("img", {
- src: e.src
+/*
+ * utility code
+ */
+function image_copy (img) {
+ copy = Builder.node("img", {
+ src: img.src,
+ className: "tag_image",
});
- g_ghost._key = e.id;
-
- $('taggr').appendChild(g_ghost);
-
- g_ghost.style.position = "absolute";
-}
-
-function drag_move (e, ev) {
- g_ghost.style.left = ev.pointerX() - g_offset.left + "px";
- g_ghost.style.top = ev.pointerY() - g_offset.top + "px";
+ copy._key = img._key;
+ copy._tags = img._tags;
+
+ return copy;
}
-function drag_end_drop (e, s, ev) {
- if (!s.images)
- s.images = new Array();
-
- if (s.images.indexOf(g_ghost._key) != -1)
- return drag_end_fail();
-
- g_ghost.id = s.id + "_" + g_ghost._key
-
- s.images.push(g_ghost._key)
-
- $('taggr').removeChild(g_ghost);
- s.appendChild(g_ghost);
-
- g_ghost.style.position = "static";
+function array_remove (a, i) {
+ a.splice(a.indexOf(i), 1);
}
-function drag_end_fail (e, ev) {
- $('taggr').removeChild(g_ghost);
-}
-
-function drag_cleanup (e, ev) {
- g_ghost = null;
-}
-
-function drag_hover (e, s, ev) {
- s.addClassName("hover");
-}
-
-function drag_unhover (e, s, ev) {
- s.removeClassName("hover");
-}
-
-Event.observe(window, "load", init);
+/*
+ * events
+ */
Event.observe(document, "mousedown", check_mouse_down);
Event.observe(document, "mouseup", check_mouse_up);
Event.observe(document, "mousemove", check_mouse_move);
Event.observe(document, "mouseover", check_drag_hover);
Event.observe(document, "mouseout", check_drag_nohover);
-Event.observe(document, "dragenter", check_drag_hover);
+Event.observe(document, "dragenter", check_drag_hover); // worth a try...
Event.observe(document, "dragexit", check_drag_nohover);
-