You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

360 lines
11 KiB

/* (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
*
* All Rights Reserved. See copyright.txt for details and a complete list of authors.
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
*
* $Id$
*
* Include file for wikiplugin_annotation.php
*
*/
(function ($) {
$.fn.imageAnnotation = function (toCreate, showLinks) {
var $container = this,
containerId = $container.attr("id"),
$editor = $container.find(".editor"),
$list = $container.parent().find(".list-box"),
editable = $editor.length > 0 && toCreate.length === 0, // default to not edit if there are existing annotations
containerOffset = $container.offset(),
dirty = false;
$(".minimize", $editor).click(function () {
endEdit(false);
return false;
});
$(".delete", $editor).click(function (event) {
handleDelete();
event.preventDefault();
return false;
});
$("#" + containerId + "-editable").change(function () {
editable = $(this).prop("checked");
return false;
}).prop("checked", editable);
// events for the container, click and mousemove
$container.click(function (event) {
if (editable) {
if (selected[containerId]) {
if (event.target.id == containerId)
endEdit(false);
return;
}
containerOffset = $(this).offset(); // reset the offset each time in case the DOM has changed
if (!active) {
active = {
obj: null,
link: null,
x1: event.pageX - containerOffset.left,
x2: event.pageX - containerOffset.left,
y1: event.pageY - containerOffset.top,
y2: event.pageY - containerOffset.top,
value: 'New annotation',
target: ''
};
initAnnotation(active);
positionize(active);
dirty = true;
} else {
active.y2 = event.pageY - containerOffset.top;
active.x2 = event.pageX - containerOffset.left;
positionize(active);
activateAnnotation(active);
beginEdit(event, active);
active = null;
serializeAnnotations(annotations);
}
} else {
}
}).mousemove(function (event) {
if (active == null)
return;
containerOffset = $(this).offset();
active.x2 = event.pageX - containerOffset.left;
active.y2 = event.pageY - containerOffset.top;
positionize(active);
});
// set up events on the popup form
$("form", $editor).submit(function () {
endEdit(true);
return false;
}).find("input, textarea").keyup(function (event) {
if (event.keyCode == 27) { // escape key
endEdit(false);
}
});
// submit event on the save form
$("form.save-annotations", $container.parent()).submit(function () {
if (selected[containerId]) {
endEdit(true);
}
// saving
dirty = false;
});
// helper functions //
//////////////////////
var active = null;
var selected = {};
var annotations = {};
var nextid = 0;
var initAnnotation = function (o) {
o.obj = $("<div />").addClass("annotation")[0];
$container.prepend(o.obj);
},
activateAnnotation = function (o) {
var newone = false;
if (!o.obj.id) {
o.id = o.obj.id = "annotation-" + nextid++;
annotations[o.id] = o;
o.cid = containerId;
newone = true;
}
var $obj = $(o.obj);
var x1 = o.x1;
var x2 = o.x2;
var y1 = o.y1;
var y2 = o.y2;
o.x1 = Math.min(x1, x2);
o.x2 = Math.max(x1, x2);
o.y1 = Math.min(y1, y2);
o.y2 = Math.max(y1, y2);
var content = "<p>" + o.value.replace(/%%%/g, "<br>") + "</p>";
if (showLinks && o.target) {
content += "<a href='" + o.target + "'>" + o.target + "</a>";
}
//$obj.popover('destroy');
$obj.popover({
content: content,
trigger: "hover",
html: true,
delay: { "show": 0, "hide": 100 } // need a small delay so you can roll over the popover
});
if ($list.length && newone) {
var $div = $("<div class='annotation-link' />");
var $a = $("<a href='#'/>") // link that goes below the image
.text(o.value.replace(/(.*)%%%.*/, "$1"))
.click(function (e) {
if (editable) {
beginEdit(e, o);
} else {
var offset = $(o.obj).offset();
offset.left -= 20;
offset.top -= 40;
$('html, body').animate({
scrollTop: offset.top,
scrollLeft: offset.left
});
}
})
.mouseover(function (e) {
highlight(o.id)
})
.mouseout(function (e) {
if (!selected[containerId] || selected[containerId].obj.id != o.id) unhighlight(o.id)
});
$div.append($a).appendTo($list);
o.link = $a[0];
}
o.obj.onmouseover = function (e) {
highlight(o.id)
};
o.obj.onmouseout = function (e) {
if (!selected[containerId] || selected[containerId].obj.id != o.id) unhighlight(o.id)
};
o.obj.onclick = function (e) {
if (editable) {
if (!active) beginEdit(e, o);
} else {
if (o.target) {
location.href = o.target;
}
}
return false;
};
},
createAnnotation = function (o) {
initAnnotation(o);
activateAnnotation(o);
positionize(o);
},
positionize = function (o) {
o.obj.style.top = (Math.min(o.y1, o.y2)) + "px";
o.obj.style.left = (Math.min(o.x1, o.x2)) + "px";
o.obj.style.width = Math.abs(o.x1 - o.x2) + "px";
o.obj.style.height = Math.abs(o.y1 - o.y2) + "px";
},
highlight = function (id) {
var o = annotations[id];
$(o.obj).addClass("selected");
},
unhighlight = function (id) {
var o = annotations[id];
$(o.obj).removeClass("selected");
},
beginEdit = function (event, o) {
var $obj = $(o.obj),
pos = $obj.position(),
offset = $obj.offsetParent().offset();
var left = pos.left,
formLeft = offset.left + left + $editor.outerWidth() - window.scrollX;
if (formLeft > window.innerWidth) {
left += window.innerWidth - formLeft;
}
var top = pos.top + $obj.outerHeight(),
formTop = offset.top + top + $editor.outerHeight() - window.scrollY;
if (formTop > window.innerHeight) {
top += window.innerHeight - formTop;
}
$("textarea[name=label]", $editor).val(o.value.replace(/%%%/g, "\n")).select().focus();
$("input[name=link]", $editor).val(o.target);
$editor.css({
top: top + "px",
left: left + "px",
zIndex: 1
})
.show();
selected[containerId] = o;
highlight(o.id);
},
endEdit = function (store) {
var o = selected[containerId];
selected[containerId] = null;
if (store) {
var newValue = $("textarea[name=label]", $editor).val().replace(/\n/g, "%%%");
if (o.value != newValue || o.target != $("input[name=link]", $editor).val()) {
dirty = true;
}
o.value = newValue;
o.target = $("input[name=link]", $editor).val();
if ($list.length) {
o.link.innerHTML = o.value.replace(/%%%/g, "<br>");
}
serializeAnnotations(annotations);
activateAnnotation(o);
}
$editor.hide();
unhighlight(o.id);
return false;
},
handleDelete = function () {
var o = selected[containerId];
endEdit(false);
o.obj.parentNode.removeChild(o.obj);
if ($list.length) {
o.link.parentNode.removeChild(o.link);
}
annotations[o.id] = null;
selected[containerId] = null;
serializeAnnotations(annotations);
},
serializeAnnotations = function (data) {
var row, str = "";
for (var k in data) {
row = data[k];
if (row == null || row.cid != containerId || !data.hasOwnProperty(k)) {
continue;
}
str += "(" + (Math.round(row.x1)) + "," + (Math.round(row.y1)) + "),(" + (Math.round(row.x2)) + "," + (Math.round(row.y2)) + ") ";
str += row.value + " [" + row.target + "]\n";
}
$("#" + containerId + "-content").val(str);
};
// finally initialise the annotations
for (var k = 0; k < toCreate.length; ++k) {
createAnnotation(toCreate[k]);
serializeAnnotations(annotations);
}
$(window).on("beforeunload", function () {
if (dirty) {
return tr("you have unsaved changes to your annotations, are you sure you want to leave this page wihtout saving?");
}
});
};
})(jQuery);