442 lines
12 KiB
Plaintext
442 lines
12 KiB
Plaintext
//= require jquery
|
|
//= require jquery_ujs
|
|
//= require_tree .
|
|
|
|
"use strict";
|
|
|
|
var _Lobsters = Class.extend({
|
|
curUser: null,
|
|
|
|
storyFlagReasons: { <%= Vote::STORY_REASONS.map{|k,v|
|
|
"#{k.inspect}: #{v.inspect}" }.join(", ") %> },
|
|
commentDownvoteReasons: { <%= Vote::COMMENT_REASONS.map{|k,v|
|
|
"#{k.inspect}: #{v.inspect}" }.join(", ") %> },
|
|
|
|
upvoteStory: function(voterEl) {
|
|
Lobsters.vote("story", voterEl, 1);
|
|
},
|
|
flagStory: function(voterEl) {
|
|
Lobsters._showDownvoteWhyAt("story", voterEl, function(k) {
|
|
Lobsters.vote("story", voterEl, -1, k); });
|
|
},
|
|
hideStory: function(hiderEl) {
|
|
if (!Lobsters.curUser)
|
|
return Lobsters.bounceToLogin();
|
|
|
|
var li = $(hiderEl).closest(".story, .comment");
|
|
var act;
|
|
|
|
if (li.hasClass("hidden")) {
|
|
act = "unhide";
|
|
li.removeClass("hidden");
|
|
hiderEl.innerHTML = "hide";
|
|
}
|
|
else {
|
|
act = "hide";
|
|
li.addClass("hidden");
|
|
hiderEl.innerHTML = "unhide";
|
|
}
|
|
|
|
$.post("/stories/" + li.attr("data-shortid") + "/" + act);
|
|
},
|
|
|
|
upvoteComment: function(voterEl) {
|
|
Lobsters.vote("comment", voterEl, 1);
|
|
},
|
|
downvoteComment: function(voterEl) {
|
|
Lobsters._showDownvoteWhyAt("comment", voterEl, function(k) {
|
|
Lobsters.vote("comment", voterEl, -1, k); });
|
|
},
|
|
_showDownvoteWhyAt: function(thingType, voterEl, onChooseWhy) {
|
|
if (!Lobsters.curUser)
|
|
return Lobsters.bounceToLogin();
|
|
|
|
var li = $(voterEl).closest(".story, .comment");
|
|
if (li.hasClass("downvoted")) {
|
|
/* already upvoted, neutralize */
|
|
Lobsters.vote(thingType, voterEl, -1, null);
|
|
return;
|
|
}
|
|
|
|
if ($("#downvote_why"))
|
|
$("#downvote_why").remove();
|
|
if ($("#downvote_why_shadow"))
|
|
$("#downvote_why_shadow").remove();
|
|
|
|
var sh = $("<div id=\"downvote_why_shadow\"></div>");
|
|
$(voterEl).after(sh);
|
|
sh.click(function() {
|
|
$("#downvote_why_shadow").remove();
|
|
$("#downvote_why").remove();
|
|
});
|
|
|
|
var d = $("<div id=\"downvote_why\"></div>");
|
|
|
|
var reasons;
|
|
if (thingType == "comment")
|
|
reasons = Lobsters.commentDownvoteReasons;
|
|
else
|
|
reasons = Lobsters.storyFlagReasons;
|
|
|
|
$.each(reasons, function(k, v) {
|
|
var a = $("<a href=\"#\"" + (k == "" ? " class=\"cancelreason\"" : "") +
|
|
">" + v + "</a>");
|
|
|
|
a.click(function() {
|
|
$("#downvote_why").remove();
|
|
$("#downvote_why_shadow").remove();
|
|
|
|
if (k != "")
|
|
onChooseWhy(k);
|
|
|
|
return false;
|
|
});
|
|
|
|
d.append(a);
|
|
});
|
|
|
|
$(voterEl).after(d);
|
|
|
|
d.position({
|
|
my: "left top",
|
|
at: "left bottom",
|
|
offset: "-2 -2",
|
|
of: $(voterEl),
|
|
collision: "none",
|
|
});
|
|
|
|
/* XXX: why is this needed? */
|
|
if (thingType == "story")
|
|
d.css("left", $(voterEl).position().left);
|
|
},
|
|
|
|
vote: function(thingType, voterEl, point, reason) {
|
|
if (!Lobsters.curUser)
|
|
return Lobsters.bounceToLogin();
|
|
|
|
var li = $(voterEl).closest(".story, .comment");
|
|
var scoreDiv = li.find("div.score").get(0);
|
|
var score = parseInt(scoreDiv.innerHTML);
|
|
var action = "";
|
|
|
|
if (li.hasClass("upvoted") && point > 0) {
|
|
/* already upvoted, neutralize */
|
|
li.removeClass("upvoted");
|
|
score--;
|
|
action = "unvote";
|
|
}
|
|
else if (li.hasClass("downvoted") && point < 0) {
|
|
/* already downvoted, neutralize */
|
|
li.removeClass("downvoted");
|
|
score++;
|
|
action = "unvote";
|
|
}
|
|
else if (point > 0) {
|
|
if (li.hasClass("downvoted"))
|
|
/* flip flop */
|
|
score++;
|
|
|
|
li.removeClass("downvoted").addClass("upvoted");
|
|
score++;
|
|
action = "upvote";
|
|
}
|
|
else if (point < 0) {
|
|
if (li.hasClass("upvoted"))
|
|
/* flip flop */
|
|
score--;
|
|
|
|
li.removeClass("upvoted").addClass("downvoted");
|
|
score--;
|
|
action = "downvote";
|
|
}
|
|
|
|
scoreDiv.innerHTML = score;
|
|
|
|
if (action == "upvote" || action == "unvote") {
|
|
li.find(".reason").html("");
|
|
|
|
if (action == "unvote" && thingType == "story" && point < 0)
|
|
li.find(".flagger").text("flag");
|
|
}
|
|
else if (action == "downvote" && thingType == "comment")
|
|
li.find(".reason").html("| " +
|
|
Lobsters.commentDownvoteReasons[reason].toLowerCase());
|
|
else if (action == "downvote" && thingType == "story")
|
|
li.find(".flagger").text("unflag");
|
|
|
|
$.post("/" + (thingType == "story" ? "stories" : thingType + "s") + "/" +
|
|
li.attr("data-shortid") + "/" +
|
|
action, { reason: reason });
|
|
},
|
|
|
|
postComment: function(form) {
|
|
$.post($(form).attr("action"), $(form).serializeArray(), function(data) {
|
|
if ($(form).find('#parent_comment_short_id').length) {
|
|
$(form).closest('.comment').replaceWith($.parseHTML(data));
|
|
} else {
|
|
if ($(form).attr("id").match(/^edit_comment_.+$/)) {
|
|
$(form).parent(".comment").replaceWith($.parseHTML(data));
|
|
} else {
|
|
$(form).closest('.comment').after($.parseHTML(data));
|
|
$(form).find('textarea').val('');
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
previewComment: function(form) {
|
|
var params = $(form).serializeArray();
|
|
params.push({"name": "preview", "value": "true"});
|
|
$.post($(form).attr("action"), params, function(data) {
|
|
var da = $.parseHTML(data);
|
|
var ta = $(da).find("textarea");
|
|
$(form).closest(".comment").replaceWith(da);
|
|
autosize(ta);
|
|
});
|
|
},
|
|
|
|
previewStory: function(form) {
|
|
$("#inside").load("/stories/preview", $(form).serializeArray());
|
|
},
|
|
|
|
moderateStory: function(link) {
|
|
var reason = prompt("Moderation reason:");
|
|
if (reason == null || reason == "")
|
|
return false;
|
|
|
|
var link = $(link);
|
|
|
|
/* $.rails.handleMethod() */
|
|
var href = $.rails.href(link),
|
|
method = link.data('method'),
|
|
target = link.attr('target'),
|
|
csrf_token = $("meta[name=csrf-token]").attr("content"),
|
|
csrf_param = $("meta[name=csrf-param]").attr("content"),
|
|
form = $("<form method=\"post\" action=\"" + href + "\"></form>"),
|
|
metadata_input = "<input name=\"_method\" value=\"" + method +
|
|
"\" type=\"hidden\" />";
|
|
|
|
if (csrf_param !== undefined && csrf_token !== undefined)
|
|
metadata_input += "<input name=\"" + csrf_param + "\" value=\"" +
|
|
csrf_token + "\" type=\"hidden\" />";
|
|
|
|
if (target)
|
|
form.attr("target", target);
|
|
|
|
var r = $("<input type=\"hidden\" name=\"reason\" />");
|
|
r.val(reason);
|
|
form.append(r);
|
|
|
|
form.hide().append(metadata_input).appendTo('body');
|
|
form.submit();
|
|
|
|
return false;
|
|
},
|
|
|
|
fetchURLTitle: function(button, url_field, title_field) {
|
|
if (url_field.val() == "")
|
|
return;
|
|
|
|
var old_value = button.val();
|
|
button.prop("disabled", true);
|
|
button.val("Fetching...");
|
|
|
|
$.post("/stories/fetch_url_attributes", {
|
|
fetch_url: url_field.val(),
|
|
})
|
|
.success(function(data) {
|
|
if (data) {
|
|
if (data.title)
|
|
title_field.val(data.title.substr(0, title_field.maxLength));
|
|
if (data.url)
|
|
url_field.val(data.url);
|
|
}
|
|
|
|
button.val(old_value);
|
|
button.prop("disabled", false);
|
|
})
|
|
.error(function() {
|
|
button.val(old_value);
|
|
button.prop("disabled", false);
|
|
});
|
|
},
|
|
|
|
bounceToLogin: function() {
|
|
document.location = "/login?return=" +
|
|
encodeURIComponent(document.location);
|
|
return false;
|
|
},
|
|
});
|
|
|
|
var Lobsters = new _Lobsters();
|
|
|
|
$(document).ready(function() {
|
|
$(".comment a.downvoter").click(function() {
|
|
Lobsters.downvoteComment(this);
|
|
return false;
|
|
});
|
|
$(".comment a.upvoter").click(function() {
|
|
Lobsters.upvoteComment(this);
|
|
return false;
|
|
});
|
|
|
|
$("li.story a.flagger").click(function() {
|
|
Lobsters.flagStory(this);
|
|
return false;
|
|
});
|
|
$("li.story a.upvoter").click(function() {
|
|
Lobsters.upvoteStory(this);
|
|
return false;
|
|
});
|
|
$("li.story a.hider").click(function() {
|
|
Lobsters.hideStory(this);
|
|
return false;
|
|
});
|
|
|
|
$("li.story a.mod_story_link").click(function() {
|
|
return Lobsters.moderateStory(this);
|
|
}),
|
|
|
|
$(document).on("click", "a.comment_replier", function() {
|
|
if (!Lobsters.curUser) {
|
|
Lobsters.bounceToLogin();
|
|
return false;
|
|
}
|
|
|
|
var comment = $(this).closest(".comment");
|
|
if ($("#reply_form_" + comment.attr("id")).length > 0)
|
|
return false;
|
|
|
|
var sel = "";
|
|
if (window.getSelection)
|
|
sel = window.getSelection().toString();
|
|
else if (document.selection && document.selection.type != "Control")
|
|
sel = document.selection.createRange().text;
|
|
|
|
if (sel != "") {
|
|
var t = "";
|
|
$.each(sel.split("\n"), function(k, v) {
|
|
t += (t == "" ? "" : "\n") + "> " + v;
|
|
});
|
|
sel = t;
|
|
|
|
if (sel != "")
|
|
sel += "\n\n";
|
|
}
|
|
|
|
var replies = comment.nextAll(".comments").first();
|
|
$.get("/comments/" + comment.attr("data-shortid") + "/reply",
|
|
function(data) {
|
|
var reply = $($.parseHTML(data));
|
|
reply.attr("id", "reply_form_" + comment.attr("id"));
|
|
replies.prepend(reply);
|
|
var ta = reply.find("textarea");
|
|
ta.focus().text(sel);
|
|
autosize(ta);
|
|
});
|
|
|
|
return false;
|
|
});
|
|
|
|
$(document).on("click", "button.comment-cancel", function() {
|
|
var comment = $(this).closest(".comment");
|
|
var comment_id = comment.attr("data-shortid");
|
|
if (comment_id != null && comment_id !== '') {
|
|
$.get("/comments/" + comment_id, function(data) {
|
|
comment.replaceWith($.parseHTML(data));
|
|
});
|
|
} else {
|
|
comment.remove();
|
|
}
|
|
});
|
|
|
|
$(document).on("click", "a.comment_editor", function() {
|
|
var comment = $(this).closest(".comment");
|
|
$.get("/comments/" + comment.attr("data-shortid") + "/edit",
|
|
function(data) {
|
|
comment.replaceWith($.parseHTML(data));
|
|
});
|
|
});
|
|
|
|
$(document).on("click", "a.comment_deletor", function() {
|
|
if (confirm("Are you sure you want to delete this comment?")) {
|
|
var li = $(this).closest(".comment");
|
|
$.post("/comments/" + $(li).attr("data-shortid") + "/delete",
|
|
function(d) {
|
|
$(li).replaceWith(d);
|
|
});
|
|
}
|
|
});
|
|
|
|
$(document).on("click", "a.comment_undeletor", function() {
|
|
if (confirm("Are you sure you want to undelete this comment?")) {
|
|
var li = $(this).closest(".comment");
|
|
$.post("/comments/" + $(li).attr("data-shortid") + "/undelete",
|
|
function(d) {
|
|
$(li).replaceWith(d);
|
|
});
|
|
}
|
|
});
|
|
|
|
$("#story_tags_a").select2({
|
|
formatSelection: function(what) {
|
|
return what.id;
|
|
},
|
|
matcher: function(term, text) {
|
|
return text.toUpperCase().indexOf(term.toUpperCase()) == 0;
|
|
}
|
|
});
|
|
|
|
$(document).on("click", "div.markdown_help_toggler .markdown_help_label",
|
|
function() {
|
|
$(this).parents("div.markdown_help_toggler").first().
|
|
children(".markdown_help").toggle();
|
|
});
|
|
|
|
$(document).on("click", "button.comment-post", function() {
|
|
Lobsters.postComment($(this).parents("form").first());
|
|
});
|
|
|
|
$(document).on("click", "button.comment-preview", function() {
|
|
Lobsters.previewComment($(this).parents("form").first());
|
|
});
|
|
|
|
$(document).on("click", "button.story-preview", function() {
|
|
Lobsters.previewStory($(this).parents("form").first());
|
|
});
|
|
|
|
$(document).on("blur", "#story_url", function() {
|
|
var url_tags = {
|
|
"\.pdf$": "pdf",
|
|
"[\/\.]((youtube|vimeo)\.com|youtu\.be)\/": "video",
|
|
"[\/\.](slideshare\.net|speakerdeck\.com)\/": "slides",
|
|
"[\/\.](soundcloud\.com)\/": "audio",
|
|
};
|
|
|
|
for (var u in url_tags) {
|
|
var tag = url_tags[u];
|
|
|
|
if ($("#story_url").val().match(new RegExp(u, "i"))) {
|
|
var ta = $("#story_tags_a").data("select2");
|
|
if (ta.getVal().indexOf(tag) < 0)
|
|
ta.addSelectedChoice({ id: tag });
|
|
}
|
|
}
|
|
});
|
|
|
|
$(document).on("blur", "#story_title", function() {
|
|
var m;
|
|
if (m = $("#story_title").val().match(/^(show|ask) lobste\.?rs:? (.+)$/i)) {
|
|
var ta = $("#story_tags_a").data("select2");
|
|
if (ta.getVal().indexOf(m[1].toLowerCase()) < 0)
|
|
ta.addSelectedChoice({ id: m[1].toLowerCase() });
|
|
$("#story_title").val(m[2]);
|
|
}
|
|
});
|
|
|
|
$(document).on("click", "#story_guidelines_toggler", function() {
|
|
$("#story_guidelines").toggle();
|
|
return false;
|
|
});
|
|
});
|