diff --git a/contrib/tagger/main.php b/contrib/tagger/main.php
new file mode 100644
index 00000000..7551d607
--- /dev/null
+++ b/contrib/tagger/main.php
@@ -0,0 +1,26 @@
+theme))
+ $this->theme = get_theme_object("tagger", "taggerTheme");
+ if(is_a($event,"DisplayingImageEvent")) {
+ //show tagger box
+ global $database;
+ global $page;
+
+ $tags = $database->Execute("
+ SELECT tag
+ FROM `tags`
+ WHERE count > 1
+ ORDER BY tag");
+
+ $this->theme->build($page, $tags);
+ }
+ }
+}
+add_event_listener(new tagger());
+?>
diff --git a/contrib/tagger/script.js b/contrib/tagger/script.js
new file mode 100644
index 00000000..5bd59a01
--- /dev/null
+++ b/contrib/tagger/script.js
@@ -0,0 +1,184 @@
+function byId(id) {
+ return document.getElementById(id);
+}
+
+function tagExists(tag) {
+ var tags = byId("tags");
+ tags_list = tags.value;
+ tags_array = tags_list.split(" ");
+
+ tags_list = "";
+ for (x in tags_array) {
+ if(tags_array[x] == tag) {
+ return true;
+ }
+ }
+ return false;
+}
+
+function addTag(tag) {
+ if (!tagExists(tag)) {
+ // append tag to tag box.
+ var tags = byId("tags");
+ tags.value = tags.value +" "+ tag;
+ }
+}
+
+// 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;
+ }
+}
+
+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);
+ }
+}
diff --git a/contrib/tagger/theme.php b/contrib/tagger/theme.php
new file mode 100644
index 00000000..ecb8fcbb
--- /dev/null
+++ b/contrib/tagger/theme.php
@@ -0,0 +1,16 @@
+";
+ foreach ($tags as $tag) {
+ $html .= "
";
+ }
+ $html .= "";
+
+ $page->add_block( new Block(null,
+ $html,
+ "main",
+ 1000));
+ }
+}
+?>