ljr/livejournal/htdocs/js/commentmanage.js

619 lines
17 KiB
JavaScript
Raw Normal View History

2019-02-05 21:49:12 +00:00
var LJVAR;
if (! LJVAR) LJVAR = new Object();
// called by S2:
function setStyle (did, attr, val) {
if (! document.getElementById) return;
var de = document.getElementById(did);
if (! de) return;
if (de.style)
de.style[attr] = val
}
// called by S2:
function setInner (did, val) {
if (! document.getElementById) return;
var de = document.getElementById(did);
if (! de) return;
de.innerHTML = val;
}
// called by S2:
function hideElement (did) {
if (! document.getElementById) return;
var de = document.getElementById(did);
if (! de) return;
de.style.display = 'none';
}
// called by S2:
function setAttr (did, attr, classname) {
if (! document.getElementById) return;
var de = document.getElementById(did);
if (! de) return;
de.setAttribute(attr, classname);
}
function getXTR () {
var xtr;
var ex;
if (typeof(XMLHttpRequest) != "undefined") {
xtr = new XMLHttpRequest();
} else {
try {
xtr = new ActiveXObject("Msxml2.XMLHTTP.4.0");
} catch (ex) {
try {
xtr = new ActiveXObject("Msxml2.XMLHTTP");
} catch (ex) {
}
}
}
// let me explain this. Opera 8 does XMLHttpRequest, but not setRequestHeader.
// no problem, we thought: we'll test for setRequestHeader and if it's not present
// then fall back to the old behavior (treat it as not working). BUT --- IE6 won't
// let you even test for setRequestHeader without throwing an exception (you need
// to call .open on the .xtr first or something)
try {
if (xtr && ! xtr.setRequestHeader)
xtr = null;
} catch (ex) { }
return xtr;
}
// push new element 'ne' after sibling 'oe' old element
function addAfter (oe, ne) {
if (oe.nextSibling) {
oe.parentNode.insertBefore(ne, oe.nextSibling);
} else {
oe.parentNode.appendChild(ne);
}
}
// hsv to rgb
// h, s, v = [0, 1), [0, 1], [0, 1]
// r, g, b = [0, 255], [0, 255], [0, 255]
function hsv_to_rgb (h, s, v)
{
if (s == 0) {
v *= 255;
return [v,v,v];
}
h *= 6;
var i = Math.floor(h);
var f = h - i;
var p = v * (1 - s);
var q = v * (1 - s * f);
var t = v * (1 - s * (1 - f));
v = Math.floor(v * 255 + 0.5);
t = Math.floor(t * 255 + 0.5);
p = Math.floor(p * 255 + 0.5);
q = Math.floor(q * 255 + 0.5);
if (i == 0) return [v,t,p];
if (i == 1) return [q,v,p];
if (i == 2) return [p,v,t];
if (i == 3) return [p,q,v];
if (i == 4) return [t,p,v];
return [v,p,q];
}
// stops the bubble
function stopBubble (e) {
if (e.stopPropagation)
e.stopPropagation();
if ("cancelBubble" in e)
e.cancelBubble = true;
}
// stops the bubble, as well as the default action
function stopEvent (e) {
stopBubble(e);
if (e.preventDefault)
e.preventDefault();
if ("returnValue" in e)
e.returnValue = false;
return false;
}
function scrollTop () {
if (window.innerHeight)
return window.pageYOffset;
if (document.documentElement && document.documentElement.scrollTop)
return document.documentElement.scrollTop;
if (document.body)
return document.body.scrollTop;
}
function scrollLeft () {
if (window.innerWidth)
return window.pageXOffset;
if (document.documentElement && document.documentElement.scrollLeft)
return document.documentElement.scrollLeft;
if (document.body)
return document.body.scrollLeft;
}
function getElementPos (obj)
{
var pos = new Object();
if (!obj)
return null;
var it;
it = obj;
pos.x = 0;
if (it.offsetParent) {
while (it.offsetParent) {
pos.x += it.offsetLeft;
it = it.offsetParent;
}
}
else if (it.x)
pos.x += it.x;
it = obj;
pos.y = 0;
if (it.offsetParent) {
while (it.offsetParent) {
pos.y += it.offsetTop;
it = it.offsetParent;
}
}
else if (it.y)
pos.y += it.y;
return pos;
}
// returns the mouse position of the event, or failing that, the top-left
// of the event's target element. (or the fallBack element, which takes
// precendence over the event's target element if specified)
function getEventPos (e, fallBack)
{
var pos = { x:0, y:0 };
if (!e) var e = window.event;
if (e.pageX && e.pageY) {
// useful case (relative to document)
pos.x = e.pageX;
pos.y = e.pageY;
}
else if (e.clientX && e.clientY) {
// IE case (relative to viewport, so need scroll info)
pos.x = e.clientX + scrollLeft();
pos.y = e.clientY + scrollTop();
} else {
var targ = fallBack || getTarget(e);
var pos = getElementPos(targ);
return pos;
}
return pos;
}
var curPopup = null;
var curPopup_id = 0;
function killPopup () {
if (!curPopup)
return true;
var popup = curPopup;
curPopup = null;
var opp = 1.0;
var fade = function () {
opp -= 0.15;
if (opp <= 0.1) {
popup.parentNode.removeChild(popup);
} else {
popup.style.filter = "alpha(opacity=" + Math.floor(opp * 100) + ")";
popup.style.opacity = opp;
window.setTimeout(fade, 20);
}
};
fade();
return true;
}
var pendingReqs = new Object ();
function deleteComment (ditemid) {
var hasopt = function (opt) {
var el = document.getElementById("ljpopdel" + ditemid + opt);
if (!el) return false;
if (el.checked) return true;
return false;
};
var opt_delthread = hasopt("thread");
var opt_ban = hasopt("ban");
var opt_spam = hasopt("spam");
killPopup();
var todel = document.getElementById("ljcmt" + ditemid);
var col = 0;
var pulse = 0;
var is_deleted = 0;
var is_error = 0;
var xtr = getXTR();
if (! xtr) {
alert("JS_ASSERT: no xtr now, but earlier?");
return false;
}
pendingReqs[ditemid] = xtr;
var state_callback = function () {
if (xtr.readyState != 4)
return;
if (xtr.status == 200) {
var val = eval(xtr.responseText);
is_deleted = val;
if (! is_deleted) is_error = 1;
} else {
alert("Error contacting server to delete comment.");
is_error = 1;
}
};
var error_callback = function () {
alert("Error deleting " + ditemid);
is_error = 1;
};
xtr.onreadystatechange = state_callback;
xtr.open("POST", "/delcomment.bml?mode=js&journal=" + LJ_cmtinfo.journal + "&id=" + ditemid, true);
var postdata = "confirm=1";
if (opt_ban) postdata += "&ban=1";
if (opt_spam) postdata += "&spam=1";
if (opt_delthread) postdata += "&delthread=1";
xtr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xtr.send(postdata);
var flash = function () {
var rgb = hsv_to_rgb(0, Math.cos((pulse + 1) / 2), 1);
pulse += 3.14159 / 5;
var color = "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")";
todel.style.border = "2px solid " + color;
if (is_error) {
todel.style.border = "";
// and let timer expire
} else if (is_deleted) {
removeComment(ditemid, opt_delthread);
} else {
window.setTimeout(flash, 50);
}
};
window.setTimeout(flash, 5);
}
function removeComment (ditemid, killChildren) {
var todel = document.getElementById("ljcmt" + ditemid);
if (todel) {
todel.style.display = 'none';
var userhook = window["userhook_delete_comment_ARG"];
if (userhook)
userhook(ditemid);
}
if (killChildren) {
var com = LJ_cmtinfo ? LJ_cmtinfo[ditemid] : null;
for (var i = 0; i < com.rc.length; i++) {
removeComment(com.rc[i], true);
}
}
}
function docClicked (e) {
if (!curPopup)
return true;
killPopup();
return true;
}
function createDeleteFunction (ae, dItemid) {
return function (e) {
if (!e) e = window.event;
var FS = arguments.callee;
var finalHeight = 100;
if (e.shiftKey || (curPopup && curPopup_id != dItemid)) {
killPopup();
}
var doIT = 0;
// immediately delete on shift key
if (e.shiftKey) {
doIT = 1;
} else {
if (! LJ_cmtinfo)
return true;
var com = LJ_cmtinfo[dItemid];
var remoteUser = LJ_cmtinfo["remote"];
if (!com || !remoteUser)
return true;
var canAdmin = LJ_cmtinfo["canAdmin"];
var clickTarget = getTarget(e);
var used_keyboard = clickTarget.nodeName == "A";
var pos = used_keyboard ? getElementPos(ae) : getEventPos(e);
var lx = pos.x + 5 - 250;
if (lx < 5) lx = 5;
var de;
if (curPopup && curPopup_id == dItemid) {
de = curPopup;
de.style.left = lx + "px";
de.style.top = (pos.y + 5) + "px";
return stopEvent(e);
}
de = document.createElement("div");
de.style.textAlign = "left";
de.className = 'ljcmtmanage';
de.style.height = "10px";
de.style.overflow = "hidden";
de.style.position = "absolute";
de.style.left = lx + "px";
de.style.top = (pos.y + 5) + "px";
de.style.width = "250px";
regEvent(de, "click", function (e) {
e = e || window.event;
stopBubble(e);
return true;
});
var inHTML = "<form style='display: inline' id='ljdelopts" + dItemid + "'><span style='font-face: Arial; font-size: 8pt'><b>Delete comment?</b><br />";
var lbl;
if (remoteUser != "" && com.u != "" && com.u != remoteUser && canAdmin) {
lbl = "ljpopdel" + dItemid + "ban";
inHTML += "<input type='checkbox' value='ban' id='" + lbl + "'> <label for='" + lbl + "'>Ban <b>" + com.u + "</b> from commenting</label><br />";
} else {
finalHeight -= 15;
}
if (remoteUser != com.u && canAdmin) {
lbl = "ljpopdel" + dItemid + "spam";
inHTML += "<input type='checkbox' value='spam' id='" + lbl + "'> <label for='" + lbl + "'>Mark this comment as spam</label><br />";
} else {
finalHeight -= 15;
}
if (com.rc && com.rc.length && canAdmin) {
lbl = "ljpopdel" + dItemid + "thread";
inHTML += "<input type='checkbox' value='thread' id='" + lbl + "'> <label for='" + lbl + "'>Delete thread (all subcomments)</label><br />";
} else {
finalHeight -= 15;
}
inHTML += "<input type='button' value='Delete' onclick='deleteComment(" + dItemid + ");' /> <input type='button' value='Cancel' onclick='killPopup()' /></span><br /><span style='font-face: Arial; font-size: 8pt'><i>shift-click to delete without options</i></span></form>";
de.innerHTML = inHTML;
// we do this so keyboard tab order is correct:
addAfter(ae, de);
curPopup = de;
curPopup_id = dItemid;
var height = 10;
var grow = function () {
height += 7;
if (height > finalHeight) {
de.style.height = null;
de.style.filter = "";
de.style.opacity = 1.0;
} else {
de.style.height = height + "px";
window.setTimeout(grow, 20);
}
};
grow();
}
if (doIT) {
deleteComment(dItemid);
}
return stopEvent(e);
}
}
function poofAt (pos) {
var de = document.createElement("div");
de.style.position = "absolute";
de.style.background = "#FFF";
de.style.overflow = "hidden";
var opp = 1.0;
var top = pos.y;
var left = pos.x;
var width = 5;
var height = 5;
document.body.appendChild(de);
var fade = function () {
opp -= 0.15;
width += 10;
height += 10;
top -= 5;
left -= 5;
if (opp <= 0.1) {
de.parentNode.removeChild(de);
} else {
de.style.left = left + "px";
de.style.top = top + "px";
de.style.height = height + "px";
de.style.width = width + "px";
de.style.filter = "alpha(opacity=" + Math.floor(opp * 100) + ")";
de.style.opacity = opp;
window.setTimeout(fade, 20);
}
};
fade();
}
function getTarget (ev) {
var target;
if (ev.target)
target = ev.target;
else if (ev.srcElement)
target = ev.srcElement;
// Safari bug:
if (target && target.nodeType == 3)
target = target.parentNode;
return target;
}
function updateLink (ae, resObj, clickTarget) {
ae.href = resObj.newurl;
var userhook = window["userhook_" + resObj.mode + "_comment_ARG"];
var did_something = 0;
if (clickTarget && clickTarget.src && clickTarget.src == resObj.oldimage) {
clickTarget.src = resObj.newimage;
did_something = 1;
}
if (userhook) {
userhook(resObj.id);
did_something = 1;
}
// if all else fails, at least remove the link so they're not as confused
if (! did_something) {
if (ae && ae.style)
ae.style.display = 'none';
if (clickTarget && clickTarget.style)
clickTarget.style.dispay = 'none';
}
}
var tsInProg = new Object(); // dict of { ditemid => 1 }
function createModerationFunction (ae, dItemid) {
return function (e) {
if (!e) e = window.event;
if (tsInProg[dItemid])
return stopEvent(e);
tsInProg[dItemid] = 1;
var clickTarget = getTarget(e);
var used_keyboard = clickTarget.nodeName == "A";
var imgTarget;
var imgs = ae.getElementsByTagName("img");
if (imgs.length)
imgTarget = imgs[0]
if (! clickTarget || typeof(clickTarget) != "object")
return true;
var clickPos = used_keyboard ? getElementPos(imgTarget || ae) : getEventPos(e);
var de = document.createElement("img");
de.style.position = "absolute";
de.width = 17;
de.height = 17;
de.src = LJVAR.imgprefix + "/hourglass.gif";
de.style.top = (clickPos.y - 8) + "px";
de.style.left = (clickPos.x - 8) + "px";
document.body.appendChild(de);
var xtr = getXTR();
var state_callback = function () {
if (xtr.readyState != 4) return;
document.body.removeChild(de);
var rpcRes;
if (xtr.status == 200) {
var resObj = eval(xtr.responseText);
if (resObj) {
poofAt(clickPos);
updateLink(ae, resObj, imgTarget);
tsInProg[dItemid] = 0;
} else {
tsInProg[dItemid] = 0;
}
} else {
alert("Error contacting server.");
tsInProg[dItemid] = 0;
}
};
xtr.onreadystatechange = state_callback;
var postUrl = ae.href.replace(/http:\/\/.+?\//, "/");
xtr.open("POST", postUrl + "&jsmode=1", true);
var postdata = "confirm=Y";
xtr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xtr.send(postdata);
return stopEvent(e);
};
}
function setupAjax () {
var ct = document.links.length;
for (var i=0; i<ct; i++) {
var ae = document.links[i];
if (ae.href.indexOf("talkscreen.bml") != -1) {
ae.onclick = createModerationFunction(ae, dItemid);
} else if (ae.href.indexOf("delcomment.bml") != -1) {
var findIDre = /id=(\d+)/;
var reMatch = findIDre.exec(ae.href);
if (! reMatch) return true;
var dItemid = reMatch[1];
var todel = document.getElementById("ljcmt" + dItemid);
if (! todel) return true;
ae.onclick = createDeleteFunction(ae, dItemid);
}
}
}
function regEvent (target, evt, func) {
if (! target) return;
if (target.attachEvent)
target.attachEvent("on"+evt, func);
if (target.addEventListener)
target.addEventListener(evt, func, false);
}
if (document.getElementById && getXTR()) {
regEvent(window, "load", setupAjax);
regEvent(document, "click", docClicked);
document.write("<style> div.ljcmtmanage { color: #000; background: #e0e0e0; border: 2px solid #000; padding: 3px; }</style>");
}