frontend: use gulp, eslint, code refactor

Apologies in advance for the insanely huge commit. This commit is
primarily based on Anton Linevych's amazing work found here [1]. While
he had gone through the pains of making small, atomic changes to each
file, I had put off reviewing the PR for a long time. By the time I
finally got around to it, the project had changed so much that it didn't
make sense to keep the commits the same way. So I've cherry-picked most
of his commits, with some changes here and there, and I've squashed them
into one commit.

[1] https://gitlab.com/linevych/commento-ce/tree/feature/frontend_building_improvements
This commit is contained in:
Anton Linevych 2018-06-24 04:01:21 +02:00 committed by Adhityaa Chandrasekar
parent e4f71fe402
commit 9e3935b3b2
30 changed files with 5059 additions and 395 deletions

33
frontend/.eslintrc Normal file
View File

@ -0,0 +1,33 @@
{
"env": {
"browser": true
},
"globals": {
"$": true
},
"rules": {
"no-bitwise": 2,
"camelcase": 2,
"brace-style": ["error", "1tbs"],
"curly": ["error", "all"],
"eqeqeq": ["error", "smart"],
"indent": ["error", 2],
"no-use-before-define": [
2,
{
"functions": false
}
],
"new-cap": 2,
"no-caller": 2,
"quotes": [
2,
"double"
],
"no-unused-vars": 2,
"strict": [
2,
"function"
]
}
}

1
frontend/.gitignore vendored
View File

@ -1 +1,2 @@
.sass-cache
node_modules/

View File

@ -1,117 +1,13 @@
SHELL = bash
# list of JS files to be built
JS_BUILD = jquery.js vue.js highlight.js chartist.js login.js forgot.js reset.js signup.js dashboard.js logout.js commento.js
jquery.js = jquery.js
vue.js = vue.js
highlight.js = highlight.js
chartist.js = chartist.js
login.js = utils.js http.js auth-common.js login.js
forgot.js = utils.js http.js forgot.js
reset.js = utils.js http.js reset.js
signup.js = utils.js http.js auth-common.js signup.js
dashboard.js = utils.js http.js errors.js self.js dashboard.js dashboard-setting.js dashboard-domain.js dashboard-installation.js dashboard-general.js dashboard-moderation.js dashboard-statistics.js dashboard-import.js dashboard-danger.js
logout.js = utils.js logout.js
commento.js = commento.js
# for each file in $(JS_BUILD), list its composition
BUILD_DIR = build
DEVEL_BUILD_DIR = $(BUILD_DIR)/devel
PROD_BUILD_DIR = $(BUILD_DIR)/prod
GULP = node_modules/.bin/gulp
HTML_SRC_DIR = .
HTML_SRC_FILES = $(wildcard $(HTML_SRC_DIR)/*.html)
HTML_DEVEL_BUILD_DIR = $(DEVEL_BUILD_DIR)
HTML_DEVEL_BUILD_FILES = $(patsubst $(HTML_SRC_DIR)/%, $(HTML_DEVEL_BUILD_DIR)/%, $(HTML_SRC_FILES))
HTML_PROD_BUILD_DIR = $(PROD_BUILD_DIR)
HTML_PROD_BUILD_FILES = $(patsubst $(HTML_SRC_DIR)/%, $(HTML_PROD_BUILD_DIR)/%, $(HTML_SRC_FILES))
devel:
yarn install
$(GULP) devel
HTML_MINIFIER = html-minifier
HTML_MINIFIER_FLAGS = --collapse-whitespace --remove-comments
JS_SRC_DIR = js
JS_SRC_FILES = $(wildcard $(JS_SRC_DIR)/*.js)
JS_DEVEL_BUILD_DIR = $(DEVEL_BUILD_DIR)/js
JS_DEVEL_BUILD_FILES = $(addprefix $(JS_DEVEL_BUILD_DIR)/, $(JS_BUILD))
JS_PROD_BUILD_DIR = $(PROD_BUILD_DIR)/js
JS_PROD_BUILD_FILES = $(addprefix $(JS_PROD_BUILD_DIR)/, $(JS_BUILD))
JS_MINIFIER = uglifyjs
JS_MINIFIER_FLAGS = --compress --mangle
SASS_SRC_DIR = sass
SASS_SRC_FILES = $(wildcard $(SASS_SRC_DIR)/*.scss)
CSS_DEVEL_BUILD_DIR = $(DEVEL_BUILD_DIR)/css
CSS_DEVEL_BUILD_FILES = $(patsubst $(SASS_SRC_DIR)/%.scss, $(CSS_DEVEL_BUILD_DIR)/%.css, $(SASS_SRC_FILES))
CSS_PROD_BUILD_DIR = $(PROD_BUILD_DIR)/css
CSS_PROD_BUILD_FILES = $(patsubst $(SASS_SRC_DIR)/%.scss, $(CSS_PROD_BUILD_DIR)/%.css, $(SASS_SRC_FILES))
CSS = sass
CSS_DEVEL_FLAGS =
CSS_PROD_FLAGS = $(CSS_DEVEL_FLAGS) --style compressed
IMGS_SRC_DIR = images
IMGS_SRC_FILES = $(wildcard $(IMGS_SRC_DIR)/*)
IMGS_DEVEL_BUILD_DIR = $(DEVEL_BUILD_DIR)/images
IMGS_DEVEL_BUILD_FILES = $(patsubst $(IMGS_SRC_DIR)/%, $(IMGS_DEVEL_BUILD_DIR)/%, $(IMGS_SRC_FILES))
IMGS_PROD_BUILD_DIR = $(PROD_BUILD_DIR)/images
IMGS_PROD_BUILD_FILES = $(patsubst $(IMGS_SRC_DIR)/%, $(IMGS_PROD_BUILD_DIR)/%, $(IMGS_SRC_FILES))
devel: devel-html devel-js devel-css devel-imgs
prod: devel prod-html prod-js prod-css prod-imgs
prod:
yarn install
$(GULP) prod
clean:
-rm -rf $(BUILD_DIR);
devel-html: $(HTML_DEVEL_BUILD_FILES)
$(HTML_DEVEL_BUILD_FILES): $(HTML_DEVEL_BUILD_DIR)/%.html: $(HTML_SRC_DIR)/%.html
cp $^ $@;
prod-html: $(HTML_PROD_BUILD_FILES)
$(HTML_PROD_BUILD_FILES): $(HTML_PROD_BUILD_DIR)/%.html: $(HTML_DEVEL_BUILD_DIR)/%.html
$(HTML_MINIFIER) $(HTML_MINIFIER_FLAGS) -o $@ $^;
devel-js: $(JS_DEVEL_BUILD_FILES)
.SECONDEXPANSION:
$(JS_DEVEL_BUILD_FILES): $(JS_DEVEL_BUILD_DIR)/%.js: $$(addprefix $$(JS_SRC_DIR)/, $$(%.js))
>$@; \
for f in $^; do \
printf "// %s\n" "$$f" >>$@; \
cat $$f >>$@; \
printf "\n" >>$@; \
done;
prod-js: $(JS_PROD_BUILD_FILES)
$(JS_PROD_BUILD_FILES): $(JS_PROD_BUILD_DIR)/%.js: $(JS_DEVEL_BUILD_DIR)/%.js
$(JS_MINIFIER) $(JS_MINIFIER_FLAGS) -o $@ $^;
devel-css: $(CSS_DEVEL_BUILD_FILES)
$(CSS_DEVEL_BUILD_FILES): $(CSS_DEVEL_BUILD_DIR)/%.css: $(SASS_SRC_DIR)/%.scss $(SASS_SRC_FILES)
$(CSS) $(CSS_DEVEL_FLAGS) $< $@;
prod-css: $(CSS_PROD_BUILD_FILES)
$(CSS_PROD_BUILD_FILES): $(CSS_PROD_BUILD_DIR)/%.css: $(SASS_SRC_DIR)/%.scss
$(CSS) $(CSS_PROD_FLAGS) $^ $@;
$(shell mkdir -p $(HTML_DEVEL_BUILD_DIR) $(JS_DEVEL_BUILD_DIR) $(CSS_DEVEL_BUILD_DIR) $(HTML_PROD_BUILD_DIR) $(JS_PROD_BUILD_DIR) $(CSS_PROD_BUILD_DIR))
devel-imgs: $(IMGS_DEVEL_BUILD_FILES)
$(IMGS_DEVEL_BUILD_FILES): $(IMGS_DEVEL_BUILD_DIR)/%: $(IMGS_SRC_DIR)/%
cp $^ $@;
prod-imgs: $(IMGS_PROD_BUILD_FILES)
$(IMGS_PROD_BUILD_FILES): $(IMGS_PROD_BUILD_DIR)/%: $(IMGS_SRC_DIR)/%
cp $^ $@
$(shell mkdir -p $(HTML_DEVEL_BUILD_DIR) $(JS_DEVEL_BUILD_DIR) $(CSS_DEVEL_BUILD_DIR) $(IMGS_DEVEL_BUILD_DIR) $(HTML_PROD_BUILD_DIR) $(JS_PROD_BUILD_DIR) $(CSS_PROD_BUILD_DIR) $(IMGS_PROD_BUILD_DIR))

134
frontend/gulpfile.js Normal file
View File

@ -0,0 +1,134 @@
"use strict";
const gulp = require("gulp");
const sass = require("gulp-sass");
const sourcemaps = require("gulp-sourcemaps");
const cleanCss = require("gulp-clean-css");
const htmlMinifier = require("gulp-html-minifier");
const uglify = require("gulp-uglify");
const concat = require("gulp-concat");
const rename = require("gulp-rename");
const eslint = require("gulp-eslint");
const develPath = "build/devel/";
const prodPath = "build/prod/";
const scssSrc = "./sass/*.scss";
const cssDir = "css/";
const imagesDir = "images/";
const imagesGlob = imagesDir + "**/*";
const jsDir = "js/";
const jsGlob = jsDir + "*.js";
const htmlGlob = "./*.html";
const jsCompileMap = {
"js/jquery.js": ["node_modules/jquery/dist/jquery.min.js"],
"js/vue.js": ["node_modules/vue/dist/vue.min.js"],
"js/highlight.js": ["node_modules/highlightjs/highlight.pack.min.js"],
"js/chartist.js": ["node_modules/chartist/dist/chartist.min.js"],
"js/login.js": [
"js/utils.js",
"js/http.js",
"js/auth-common.js",
"js/login.js"
],
"js/forgot.js": [
"js/utils.js",
"js/http.js",
"js/forgot.js"
],
"js/reset.js": [
"js/js/utils.js",
"js/http.js",
"js/reset.js"
],
"js/signup.js": [
"js/utils.js",
"js/http.js",
"js/auth-common.js",
"js/signup.js"
],
"js/dashboard.js": [
"js/utils.js",
"js/http.js",
"js/errors.js",
"js/self.js",
"js/dashboard.js",
"js/dashboard-setting.js",
"js/dashboard-domain.js",
"js/dashboard-installation.js",
"js/dashboard-general.js",
"js/dashboard-moderation.js",
"js/dashboard-statistics.js",
"js/dashboard-import.js",
"js/dashboard-danger.js",
],
"js/logout.js": [
"js/utils.js",
"js/logout.js"
],
"js/commento.js": ["js/commento.js"],
};
gulp.task("scss-devel", function () {
return gulp.src(scssSrc)
.pipe(sourcemaps.init())
.pipe(sass({outputStyle: "expanded"}).on("error", sass.logError))
.pipe(sourcemaps.write())
.pipe(gulp.dest(develPath + cssDir));
});
gulp.task("scss-prod", function () {
return gulp.src(scssSrc)
.pipe(sass({outputStyle: "compressed"}).on("error", sass.logError))
.pipe(cleanCss({compatibility: "ie8", level: 2}))
.pipe(gulp.dest(prodPath + cssDir));
});
gulp.task("html-devel", function () {
gulp.src([htmlGlob]).pipe(gulp.dest(develPath));
});
gulp.task("html-prod", function () {
gulp.src(htmlGlob)
.pipe(htmlMinifier({collapseWhitespace: true, removeComments: true}))
.pipe(gulp.dest(prodPath))
});
gulp.task("images-devel", function () {
gulp.src([imagesGlob]).pipe(gulp.dest(develPath + imagesDir));
});
gulp.task("images-prod", function () {
gulp.src([imagesGlob]).pipe(gulp.dest(prodPath + imagesDir));
});
gulp.task("js-devel", function () {
for (let outputFile in jsCompileMap) {
gulp.src(jsCompileMap[outputFile])
.pipe(sourcemaps.init())
.pipe(concat(outputFile))
.pipe(rename(outputFile))
.pipe(uglify())
.pipe(sourcemaps.write())
.pipe(gulp.dest(develPath))
}
});
gulp.task("js-prod", function () {
for (let outputFile in jsCompileMap) {
gulp.src(jsCompileMap[outputFile])
.pipe(concat(outputFile))
.pipe(rename(outputFile))
.pipe(uglify())
.pipe(gulp.dest(prodPath))
}
});
gulp.task("lint", function () {
return gulp.src(jsGlob)
.pipe(eslint())
.pipe(eslint.failAfterError())
});
gulp.task("devel", ["scss-devel", "html-devel", "images-devel", "lint", "js-devel"]);
gulp.task("prod", ["scss-prod", "html-prod", "images-prod", "lint", "js-prod"]);

View File

@ -1,17 +1,19 @@
(function (global, document) {
"use strict"
// Redirect the user to the dashboard if there's a cookie. If the cookie is
// invalid, they would be redirected back to the login page *after* the
// cookie is deleted.
global.loggedInRedirect = function() {
if (global.cookieGet("commentoOwnerToken") !== undefined)
if (global.cookieGet("commentoOwnerToken") !== undefined) {
document.location = global.origin + "/dashboard";
}
}
// Prefills the email field from the URL parameter.
global.prefillEmail = function() {
if (paramGet("email") != undefined) {
if (paramGet("email") !== undefined) {
$("#email").val(paramGet("email"));
$("#password").click();
}

File diff suppressed because one or more lines are too long

View File

@ -1,19 +1,20 @@
(function(global, document) {
'use strict';
"use strict";
if (global.commento === undefined) {
console.log("[commento] error: window.commento namespace not defined; maybe there's a mismatch in version between the backend and the frontend?");
return;
} else {
global = global.commento;
}
global = global.commento;
// Do not use other files like utils.js and http.js in the Makefile to build
// Do not use other files like utils.js and http.js in the gulpfile to build
// commento.js for the following reasons:
// - We don't use jQuery in the actual JavaScript payload because we need
// to be lightweight.
// - They pollute the global/window namespace (with global.post, etc.).
// That's NOT fine when we expect them source our JavaScript. For example,
// That's NOT fine when we expect them to source our JavaScript. For example,
// the user may have their own window.post defined. We don't want to
// override that.
@ -67,13 +68,12 @@
var origin = global.origin;
var cdn = global.cdn;
var root = null;
var cssOverride = undefined;
var autoInit = undefined;
var cssOverride;
var autoInit;
var isAuthenticated = false;
var comments = [];
var commenters = [];
var requireIdentification = true;
var requireModeration = true;
var isModerator = false;
var isFrozen = false;
var shownSubmitButton = {"root": false};
@ -96,16 +96,6 @@
}
function dataGet(el, key) {
return el.dataset[key];
}
function dataSet(el, key, data) {
el.dataset[key] = data;
}
function append(root, el) {
root.appendChild(el);
}
@ -122,9 +112,10 @@
function classRemove(el, cls) {
if (el !== null)
if (el !== null) {
el.classList.remove("commento-" + cls);
}
}
function create(el) {
@ -133,24 +124,26 @@
function remove(el) {
if (el !== null)
if (el !== null) {
el.parentNode.removeChild(el);
}
}
function attrGet(node, a) {
var attr = node.attributes[a];
if (attr === undefined)
if (attr === undefined) {
return undefined;
}
return attr.value;
}
function onclick(node, f, ...args) {
function onclick(node, f, arg) {
node.addEventListener("click", function() {
f(...args);
f(arg);
}, false);
}
@ -176,7 +169,7 @@
function get(url, callback) {
var xmlDoc = new XMLHttpRequest();
xmlDoc.open('GET', url, true);
xmlDoc.open("GET", url, true);
xmlDoc.onload = function() {
callback(JSON.parse(xmlDoc.response));
};
@ -186,26 +179,19 @@
function call(callback) {
if (typeof(callback) == "function")
if (typeof(callback) === "function") {
callback();
}
function rootSpinnerShow() {
var spinner = create("div");
classAdd(spinner, "loading");
append(root, spinner);
}
function cookieGet(name) {
var c = "; " + document.cookie;
var x = c.split("; " + name + "=");
if (x.length == 2)
if (x.length === 2) {
return x.pop().split(";").shift();
}
}
function cookieSet(name, value) {
@ -220,8 +206,9 @@
function commenterTokenGet() {
var commenterToken = cookieGet("commentoCommenterToken");
if (commenterToken === undefined)
if (commenterToken === undefined) {
return "anonymous";
}
return commenterToken;
}
@ -235,7 +222,7 @@
function selfGet(callback) {
var commenterToken = commenterTokenGet();
if (commenterToken == "anonymous") {
if (commenterToken === "anonymous") {
isAuthenticated = false;
call(callback);
return;
@ -273,14 +260,14 @@
attrSet(loggedContainer, "style", "display: none");
attrSet(name, "href", resp.commenter.link);
if (resp.commenter.photo == "undefined") {
if (resp.commenter.photo === "undefined") {
avatar = create("div");
avatar.style["background"] = color;
avatar.innerHTML = resp.commenter.name[0].toUpperCase();
classAdd(avatar, "avatar");
} else {
avatar = create("img");
if (resp.commenter.provider == "google") {
if (resp.commenter.provider === "google") {
attrSet(avatar, "src", resp.commenter.photo + "?sz=50");
} else {
attrSet(avatar, "src", resp.commenter.photo);
@ -303,7 +290,7 @@
function cssLoad(file, onload) {
var link = create("link");
var head = document.getElementsByTagName('head')[0];
var head = document.getElementsByTagName("head")[0];
link.type = "text/css";
attrSet(link, "href", file);
@ -357,7 +344,6 @@
return;
}
requireModeration = resp.requireModeration;
requireIdentification = resp.requireIdentification;
isModerator = resp.isModerator;
isFrozen = resp.isFrozen;
@ -448,12 +434,12 @@
append(buttons, createButton);
append(buttons, loginButton);
append(buttonsContainer, buttons);
if (!requireIdentification)
if (!requireIdentification) {
append(buttonsContainer, anonymousButton);
}
append(textareaContainer, question);
append(textareaContainer, buttonsContainer);
}
else {
} else {
onclick(textarea, global.showSubmitButton, id);
attrSet(textarea, "placeholder", "Join the discussion!");
@ -478,14 +464,15 @@
commentsArea.innerHTML = "";
if (isLocked) {
if (isAuthenticated)
if (isLocked || isFrozen) {
if (isAuthenticated) {
append(mainArea, messageCreate("This thread is locked. You cannot add new comments."));
else
} else {
append(mainArea, textareaCreate("root"));
}
else
} else {
append(mainArea, textareaCreate("root"));
}
append(mainArea, commentsArea);
append(root, mainArea);
@ -510,11 +497,10 @@
var comment = textarea.value;
if (comment == "") {
if (comment === "") {
classAdd(textarea, "red-border");
return;
}
else {
} else {
classRemove(textarea, "red-border");
}
@ -539,17 +525,19 @@
commentsRender();
var message = "";
if (resp.state == "unapproved")
if (resp.state === "unapproved") {
message = "Your comment is under moderation.";
else if (resp.state == "flagged")
} else if (resp.state === "flagged") {
message = "Your comment was flagged as spam and is under moderation.";
}
if (message != "") {
if (id == "root")
if (message !== "") {
if (id === "root") {
prepend($(ID_SUPER_CONTAINER + id), messageCreate(message));
else
} else {
append($(ID_BODY + id), messageCreate(message));
}
}
});
});
}
@ -567,8 +555,9 @@
];
var total = 0;
for (var i = 0; i < name.length; i++)
for (var i = 0; i < name.length; i++) {
total += name.charCodeAt(i);
}
var color = colors[total % colors.length];
return color;
@ -586,35 +575,30 @@
var elapsed = current - previous;
if (elapsed < msJustNow) {
return 'just now';
}
else if (elapsed < msPerMinute) {
return Math.round(elapsed/1000) + ' seconds ago';
}
else if (elapsed < msPerHour) {
return Math.round(elapsed/msPerMinute) + ' minutes ago';
}
else if (elapsed < msPerDay ) {
return Math.round(elapsed/msPerHour ) + ' hours ago';
}
else if (elapsed < msPerMonth) {
return Math.round(elapsed/msPerDay) + ' days ago';
}
else if (elapsed < msPerYear) {
return Math.round(elapsed/msPerMonth) + ' months ago';
}
else {
return Math.round(elapsed/msPerYear ) + ' years ago';
return "just now";
} else if (elapsed < msPerMinute) {
return Math.round(elapsed / 1000) + " seconds ago";
} else if (elapsed < msPerHour) {
return Math.round(elapsed / msPerMinute) + " minutes ago";
} else if (elapsed < msPerDay ) {
return Math.round(elapsed / msPerHour ) + " hours ago";
} else if (elapsed < msPerMonth) {
return Math.round(elapsed / msPerDay) + " days ago";
} else if (elapsed < msPerYear) {
return Math.round(elapsed / msPerMonth) + " months ago";
} else {
return Math.round(elapsed / msPerYear ) + " years ago";
}
}
function scorify(score) {
if (score != 1)
if (score !== 1) {
return score + " points";
else
} else {
return score + " point";
}
}
function commentsRecurse(parentMap, parentHex) {
@ -624,10 +608,12 @@
}
cur.sort(function(a, b) {
if (a.commentHex == stickyCommentHex)
if (a.commentHex === stickyCommentHex) {
return -Infinity;
if (b.commentHex == stickyCommentHex)
}
if (b.commentHex === stickyCommentHex) {
return Infinity;
}
return b.score - a.score;
});
@ -655,10 +641,11 @@
var contents = create("div");
var color = colorGet(comment.commenterHex + "-" + commenter.name);
var name;
if (commenter.link != "undefined" && commenter.link != "https://undefined" && commenter.link != "")
if (commenter.link !== "undefined" && commenter.link !== "https://undefined" && commenter.link !== "") {
name = create("a");
else
} else {
name = create("div");
}
card.id = ID_CARD + comment.commentHex;
body.id = ID_BODY + comment.commentHex;
@ -674,8 +661,9 @@
approve.id = ID_APPROVE + comment.commentHex;
remove.id = ID_REMOVE + comment.commentHex;
sticky.id = ID_STICKY + comment.commentHex;
if (children)
if (children) {
children.id = ID_CHILDREN + comment.commentHex;
}
contents.id = ID_CONTENTS + comment.commentHex;
name.id = ID_NAME + comment.commentHex;
@ -686,14 +674,15 @@
reply.title = "Reply";
approve.title = "Approve";
remove.title = "Remove";
if (stickyCommentHex == comment.commentHex) {
if (isModerator)
if (stickyCommentHex === comment.commentHex) {
if (isModerator) {
sticky.title = "Unsticky";
else
} else {
sticky.title = "This comment has been stickied";
}
else
} else {
sticky.title = "Sticky";
}
card.style["borderLeft"] = "2px solid " + color;
name.innerText = commenter.name;
@ -701,14 +690,14 @@
timeago.innerHTML = timeDifference((new Date()).getTime(), Date.parse(comment.creationDate));
score.innerText = scorify(comment.score);
if (commenter.photo == "undefined") {
if (commenter.photo === "undefined") {
avatar = create("div");
avatar.style["background"] = color;
avatar.innerHTML = commenter.name[0].toUpperCase();
classAdd(avatar, "avatar");
} else {
avatar = create("img");
if (commenter.provider == "google") {
if (commenter.provider === "google") {
attrSet(avatar, "src", commenter.photo + "?sz=50");
} else {
attrSet(avatar, "src", commenter.photo);
@ -717,10 +706,12 @@
}
classAdd(card, "card");
if (isModerator && comment.state != "approved")
if (isModerator && comment.state !== "approved") {
classAdd(card, "dark-card");
if (comment.state == "flagged")
}
if (comment.state === "flagged") {
classAdd(name, "flagged");
}
classAdd(header, "header");
classAdd(name, "name");
classAdd(subtitle, "subtitle");
@ -728,8 +719,9 @@
classAdd(score, "score");
classAdd(body, "body");
classAdd(options, "options");
if (mobileView)
if (mobileView) {
classAdd(options, "options-mobile");
}
classAdd(edit, "option-button");
classAdd(edit, "option-edit");
classAdd(reply, "option-button");
@ -745,37 +737,41 @@
classAdd(remove, "option-button");
classAdd(remove, "option-remove");
classAdd(sticky, "option-button");
if (stickyCommentHex == comment.commentHex)
if (stickyCommentHex === comment.commentHex) {
classAdd(sticky, "option-unsticky");
else
} else {
classAdd(sticky, "option-sticky");
}
if (isAuthenticated) {
if (comment.direction > 0)
if (comment.direction > 0) {
classAdd(upvote, "upvoted");
else if (comment.direction < 0)
} else if (comment.direction < 0) {
classAdd(downvote, "downvoted");
}
}
onclick(collapse, global.commentCollapse, comment.commentHex);
onclick(approve, global.commentApprove, comment.commentHex);
onclick(remove, global.commentDelete, comment.commentHex);
onclick(sticky, global.commentSticky, comment.commentHex);
if (isAuthenticated)
if (isAuthenticated) {
upDownOnclickSet(upvote, downvote, comment.commentHex, comment.direction);
else {
} else {
onclick(upvote, global.loginBoxShow);
onclick(downvote, global.loginBoxShow);
}
if (isAuthenticated || chosenAnonymous)
if (isAuthenticated || chosenAnonymous) {
onclick(reply, global.replyShow, comment.commentHex);
else
} else {
onclick(reply, global.loginBoxShow);
}
if (commenter.link != "undefined" && commenter.link != "https://undefined" && commenter.link != "")
if (commenter.link !== "undefined" && commenter.link !== "https://undefined" && commenter.link !== "") {
attrSet(name, "href", commenter.link);
}
append(options, collapse);
@ -786,26 +782,30 @@
append(options, reply);
if (isModerator) {
if (parentHex == "root")
if (parentHex === "root") {
append(options, sticky);
}
append(options, remove);
if (comment.state != "approved")
if (comment.state !== "approved") {
append(options, approve);
}
else {
if (stickyCommentHex == comment.commentHex)
} else {
if (stickyCommentHex === comment.commentHex) {
append(options, sticky);
}
}
attrSet(options, "style", "width: " + ((options.childNodes.length+1)*32) + "px;");
for (var i = 0; i < options.childNodes.length; i++)
for (var i = 0; i < options.childNodes.length; i++) {
attrSet(options.childNodes[i], "style", "right: " + (i*32) + "px;");
}
append(subtitle, score);
append(subtitle, timeago);
if (!mobileView)
if (!mobileView) {
append(header, options);
}
append(header, avatar);
append(header, name);
append(header, subtitle);
@ -847,7 +847,6 @@
var card = $(ID_CARD + commentHex);
var name = $(ID_NAME + commentHex);
var options = $(ID_OPTIONS + commentHex);
var tick = $(ID_APPROVE + commentHex);
classRemove(card, "dark-card");
@ -878,28 +877,29 @@
function nameWidthFix() {
var els = document.getElementsByClassName("commento-name");
for (var i = 0; i < els.length; i++)
for (var i = 0; i < els.length; i++) {
attrSet(els[i], "style", "max-width: " + (els[i].getBoundingClientRect()["width"] + 20) + "px;")
}
}
function upDownOnclickSet(upvote, downvote, commentHex, direction) {
if (direction > 0) {
onclick(upvote, global.vote, commentHex, 1, 0);
onclick(downvote, global.vote, commentHex, 1, -1);
}
else if (direction < 0) {
onclick(upvote, global.vote, commentHex, -1, 1);
onclick(downvote, global.vote, commentHex, -1, 0);
}
else {
onclick(upvote, global.vote, commentHex, 0, 1);
onclick(downvote, global.vote, commentHex, 0, -1);
onclick(upvote, global.vote, commentHex, [1, 0]);
onclick(downvote, global.vote, commentHex, [1, -1]);
} else if (direction < 0) {
onclick(upvote, global.vote, commentHex, [-1, 1]);
onclick(downvote, global.vote, commentHex, [-1, 0]);
} else {
onclick(upvote, global.vote, commentHex, [0, 1]);
onclick(downvote, global.vote, commentHex, [0, -1]);
}
}
global.vote = function(commentHex, oldVote, direction) {
global.vote = function(commentHex, dirs) {
var oldVote = dirs[0];
var direction = dirs[1];
var upvote = $(ID_UPVOTE + commentHex);
var downvote = $(ID_DOWNVOTE + commentHex);
var score = $(ID_SCORE + commentHex);
@ -914,20 +914,27 @@
classRemove(upvote, "upvoted");
classRemove(downvote, "downvoted");
if (direction > 0)
if (direction > 0) {
classAdd(upvote, "upvoted");
else if (direction < 0)
} else if (direction < 0) {
classAdd(downvote, "downvoted");
}
score.innerText = scorify(parseInt(score.innerText.replace(/[^\d-.]/g, "")) + direction - oldVote);
post(origin + "/api/comment/vote", json, function(resp) {});
post(origin + "/api/comment/vote", json, function(resp) {
if (!resp.success) {
errorShow(resp.message);
return;
}
});
}
global.replyShow = function(id) {
if (id in shownReply && shownReply[id])
if (id in shownReply && shownReply[id]) {
return;
}
var body = $(ID_BODY + id);
append(body, textareaCreate(id));
@ -965,8 +972,9 @@
var children = $(ID_CHILDREN + id);
var button = $(ID_COLLAPSE + id);
if (children)
if (children) {
classAdd(children, "hidden");
}
classRemove(button, "option-collapse");
classAdd(button, "option-uncollapse");
@ -981,8 +989,9 @@
var children = $(ID_CHILDREN + id);
var button = $(ID_COLLAPSE + id);
if (children)
if (children) {
classRemove(children, "hidden");
}
classRemove(button, "option-uncollapse");
classAdd(button, "option-collapse");
@ -1015,8 +1024,9 @@
global.showSubmitButton = function(id) {
if (id in shownSubmitButton && shownSubmitButton[id])
if (id in shownSubmitButton && shownSubmitButton[id]) {
return;
}
shownSubmitButton[id] = true;
@ -1037,7 +1047,8 @@
append(el, submit);
}
global.anonymousChoose = function(provider) {
global.anonymousChoose = function() {
cookieSet("commentoCommenterToken", "anonymous");
chosenAnonymous = true;
refreshAll();
@ -1178,12 +1189,13 @@
append(loginBox, oauthPretext);
append(oauthButtonsContainer, oauthButtons);
append(loginBox, oauthButtonsContainer);
if (!requireIdentification)
if (!requireIdentification) {
append(loginBox, anonymousButton);
oauthButtonsShown = true;
}
else
oauthButtonsShown = true;
} else {
oauthButtonsShown = false;
}
append(loginBox, close);
@ -1279,14 +1291,15 @@
global.passwordAsk = function() {
var loginBox = $(ID_LOGIN_BOX);
var subtitle = $(ID_LOGIN_BOX_SUBTITLE);
var emailInput = $(ID_LOGIN_BOX_EMAIL_INPUT);
var emailButton = $(ID_LOGIN_BOX_EMAIL_BUTTON);
var loginLinkContainer = $(ID_LOGIN_BOX_LOGIN_LINK_CONTAINER);
var hr = $(ID_LOGIN_BOX_HR);
var oauthButtonsContainer = $(ID_LOGIN_BOX_OAUTH_BUTTONS_CONTAINER);
var oauthPretext = $(ID_LOGIN_BOX_OAUTH_PRETEXT);
var anonymousButton = null;
if (!requireIdentification);
if (!requireIdentification){
;
}
anonymousButton = $(ID_LOGIN_BOX_ANONYMOUS_BUTTON);
remove(emailButton);
@ -1302,23 +1315,23 @@
var order, id, type, placeholder;
if (loginBoxType == "signup") {
if (loginBoxType === "signup") {
var order = ["name", "website", "password"];
var id = [ID_LOGIN_BOX_NAME_INPUT, ID_LOGIN_BOX_WEBSITE_INPUT, ID_LOGIN_BOX_PASSWORD_INPUT];
var type = ["text", "text", "password"];
var placeholder = ["Real Name", "Website (Optional)", "Password"];
}
else {
} else {
var order = ["password"];
var id = [ID_LOGIN_BOX_PASSWORD_INPUT];
var type = ["password"];
var placeholder = ["Password"];
}
if (loginBoxType == "signup")
if (loginBoxType === "signup") {
subtitle.innerText = "Finish the rest of your profile to complete."
else
} else {
subtitle.innerText = "Enter your password to log in."
}
for (var i = 0; i < order.length; i++) {
var fieldContainer = create("div");
@ -1338,15 +1351,16 @@
append(field, fieldInput);
append(fieldContainer, field);
if (order[i] == "password") {
if (order[i] === "password") {
var fieldButton = create("button");
classAdd(fieldButton, "email-button");
fieldButton.innerText = loginBoxType;
if (loginBoxType == "signup")
if (loginBoxType === "signup") {
onclick(fieldButton, global.signup);
else
} else {
onclick(fieldButton, global.login);
}
append(field, fieldButton);
}
@ -1354,11 +1368,12 @@
append(loginBox, fieldContainer);
}
if (loginBoxType == "signup")
if (loginBoxType === "signup") {
$(ID_LOGIN_BOX_NAME_INPUT).focus();
else
} else {
$(ID_LOGIN_BOX_PASSWORD_INPUT).focus();
}
}
function pageUpdate(callback) {
@ -1392,37 +1407,42 @@
lock.disabled = true;
pageUpdate(function(success) {
if (success) {
lock.disabled = false;
if (isLocked)
if (isLocked) {
lock.innerHTML = "Unlock Thread";
else
} else {
lock.innerHTML = "Lock Thread";
}
}
});
}
global.commentSticky = function(commentHex) {
if (stickyCommentHex != "none") {
if (stickyCommentHex !== "none") {
var sticky = $(ID_STICKY + stickyCommentHex);
classRemove(sticky, "option-unsticky");
classAdd(sticky, "option-sticky");
}
if (stickyCommentHex == commentHex)
if (stickyCommentHex === commentHex) {
stickyCommentHex = "none";
else
} else {
stickyCommentHex = commentHex;
}
pageUpdate(function(success) {
if (success) {
var sticky = $(ID_STICKY + commentHex);
if (stickyCommentHex == commentHex) {
if (stickyCommentHex === commentHex) {
classRemove(sticky, "option-sticky");
classAdd(sticky, "option-unsticky");
}
else {
} else {
classRemove(sticky, "option-unsticky");
classAdd(sticky, "option-sticky");
}
}
});
}
@ -1449,10 +1469,11 @@
classAdd(modTools, "mod-tools");
if (isLocked)
if (isLocked) {
lock.innerHTML = "Unlock Thread";
else
} else {
lock.innerHTML = "Lock Thread";
}
onclick(lock, global.threadLockToggle);
@ -1464,11 +1485,12 @@
global.loadCssOverride = function() {
if (cssOverride === undefined)
if (cssOverride === undefined) {
global.allShow();
else
} else {
cssLoad(cssOverride, "window.allShow()");
}
}
global.allShow = function() {
@ -1479,11 +1501,13 @@
attrSet(mainArea, "style", "");
if (isModerator)
if (isModerator) {
attrSet(modTools, "style", "");
}
if (loggedContainer)
if (loggedContainer) {
attrSet(loggedContainer, "style", "");
}
attrSet(footer, "style", "");
@ -1502,7 +1526,7 @@
}
global.loginBoxShow = function(signup) {
global.loginBoxShow = function() {
var mainArea = $(ID_MAIN_AREA);
var loginBoxContainer = $(ID_LOGIN_BOX_CONTAINER);
@ -1527,11 +1551,12 @@
autoInit = attrGet(scripts[i], "data-auto-init");
ID_ROOT = attrGet(scripts[i], "data-id-root");
if (ID_ROOT === undefined)
if (ID_ROOT === undefined) {
ID_ROOT = "commento";
}
}
}
}
global.main = function(callback) {
@ -1559,42 +1584,46 @@
var initted = false;
function init() {
if (initted)
if (initted) {
return;
}
initted = true;
dataTagsLoad();
if (autoInit == "true" || autoInit === undefined)
if (autoInit === "true" || autoInit === undefined) {
global.main(undefined);
else if (autoInit != "false")
} else if (autoInit !== "false") {
console.log("[commento] error: invalid value for data-auto-init; allowed values: true, false");
}
}
var readyLoad = function() {
var readyState = document.readyState;
if (readyState == "loading") {
if (readyState === "loading") {
// The document is still loading. The div we need to fill might not have
// been parsed yet, so let's wait and retry when the readyState changes.
// If there is more than one state change, we aren't affected because we
// have a double-call protection in init().
document.addEventListener("readystatechange", readyLoad);
}
else if (readyState == "interactive") {
} else if (readyState === "interactive") {
// The document has been parsed and DOM objects are now accessible. While
// JS, CSS, and images are still loading, we don't need to wait.
init();
}
else if (readyState == "complete") {
} else if (readyState === "complete") {
// The page has fully loaded (including JS, CSS, and images). From our
// point of view, this is practically no different from interactive.
init();
}
};
readyLoad();
}(window, document));

View File

@ -1,4 +1,5 @@
(function (global, document) {
"use strict";
// Opens the danger zone.
global.dangerOpen = function() {
@ -12,8 +13,9 @@
var data = global.dashboard.$data;
global.domainDelete(data.domains[data.cd].domain, function(success) {
if (success)
document.location = global.origin + '/dashboard';
if (success) {
document.location = global.origin + "/dashboard";
}
});
}

View File

@ -1,4 +1,5 @@
(function (global, document) {
"use strict";
// Selects a domain.
global.domainSelect = function(domain) {
@ -6,15 +7,15 @@
var domains = data.domains;
for (var i = 0; i < domains.length; i++) {
if (domains[i].domain == domain) {
global.vs("frozen", domains[i].state == "frozen");
if (domains[i].domain === domain) {
global.vs("frozen", domains[i].state === "frozen");
domains[i].selected = true;
data.cd = i;
data.importedComments = domains[i].importedComments;
}
else
} else {
domains[i].selected = false;
}
}
data.showSettings = true;
@ -28,9 +29,10 @@
var data = global.dashboard.$data;
var domains = data.domains;
for (var i = 0; i < domains.length; i++)
for (var i = 0; i < domains.length; i++) {
domains[i].selected = false;
}
}
// Creates a new domain.
@ -98,8 +100,9 @@
global.vs("domains", resp.domains);
if (callback !== undefined)
if (callback !== undefined) {
callback();
}
});
};
@ -112,8 +115,9 @@
};
global.post(global.origin + "/api/domain/update", json, function(resp) {
if (callback !== undefined)
if (callback !== undefined) {
callback(resp.success);
}
if (!resp.success) {
global.globalErrorShow(resp.message);
@ -136,8 +140,9 @@
return;
}
if (callback !== undefined)
if (callback !== undefined) {
callback(resp.success);
}
});
}

View File

@ -1,4 +1,7 @@
(function (global, document) {
"use strict";
(document);
// Opens the general settings window.
global.generalOpen = function() {

View File

@ -1,4 +1,7 @@
(function (global, document) {
"use strict";
(document);
// Opens the import window.
global.importOpen = function() {

View File

@ -1,17 +1,18 @@
(function (global, document) {
"use strict";
(document);
// Opens the installation view.
global.installationOpen = function() {
var data = global.dashboard.$data;
var html = '' +
'<div id="commento"></div>\n' +
'<script src="' + window.commentoCdn + '/js/commento.js"><\/script>\n' +
'';
var html = "" +
"<div id=\"commento\"></div>\n" +
"<script src=\"" + window.commentoCdn + "/js/commento.js\"><\/script>\n" +
"";
$("#code-div").text(html);
$('pre code').each(function(i, block) {
$("pre code").each(function(i, block) {
hljs.highlightBlock(block);
});

View File

@ -1,4 +1,7 @@
(function (global, document) {
"use strict";
(document);
// Opens the moderatiosn settings window.
global.moderationOpen = function() {
@ -20,13 +23,13 @@
var idx = -1;
for (var i = 0; i < data.domains[data.cd].moderators.length; i++) {
if (data.domains[data.cd].moderators[i].email == email) {
if (data.domains[data.cd].moderators[i].email === email) {
idx = i;
break;
}
}
if (idx == -1) {
if (idx === -1) {
data.domains[data.cd].moderators.push({"email": email, "timeAgo": "just now"});
global.buttonDisable("#new-mod-button");
global.post(global.origin + "/api/domain/moderator/new", json, function(resp) {
@ -41,8 +44,7 @@
$("#new-mod").val("");
$("#new-mod").focus();
});
}
else {
} else {
global.globalErrorShow("Already a moderator.");
}
}
@ -60,13 +62,13 @@
var idx = -1;
for (var i = 0; i < data.domains[data.cd].moderators.length; i++) {
if (data.domains[data.cd].moderators[i].email == email) {
if (data.domains[data.cd].moderators[i].email === email) {
idx = i;
break;
}
}
if (idx != -1) {
if (idx !== -1) {
data.domains[data.cd].moderators.splice(idx, 1);
global.post(global.origin + "/api/domain/moderator/delete", json, function(resp) {
if (!resp.success) {

View File

@ -1,4 +1,7 @@
(function (global, document) {
"use strict";
(document);
// Sets the vue.js toggle to select and deselect panes visually.
function settingSelectCSS(id) {
@ -6,10 +9,9 @@
var settings = data.settings;
for (var i = 0; i < settings.length; i++) {
if (settings[i].id == id) {
if (settings[i].id === id) {
settings[i].selected = true;
}
else {
} else {
settings[i].selected = false;
}
}
@ -28,9 +30,10 @@
$(".original").addClass("current");
for (var i = 0; i < settings.length; i++) {
if (id == settings[i].id)
if (id === settings[i].id) {
settings[i].open();
}
}
};
@ -39,8 +42,9 @@
var data = global.dashboard.$data;
var settings = data.settings;
for (var i = 0; i < settings.length; i++)
for (var i = 0; i < settings.length; i++) {
settings[i].selected = false;
}
}
} (window.commento, document));

View File

@ -1,35 +1,41 @@
(function (global, document) {
"use strict";
(document);
global.numberify = function(x) {
if (x == 0)
if (x === 0) {
return {"zeros": "000", "num": "", "units": ""}
}
if (x < 10)
if (x < 10) {
return {"zeros": "00", "num": x, "units": ""}
}
if (x < 100)
if (x < 100) {
return {"zeros": "0", "num": x, "units": ""}
}
if (x < 1000)
if (x < 1000) {
return {"zeros": "", "num": x, "units": ""}
}
var res;
if (x < 1000000) {
res = global.numberify((x/1000).toFixed(0))
res.units = "K"
}
else if (x < 1000000000) {
} else if (x < 1000000000) {
res = global.numberify((x/1000000).toFixed(0))
res.units = "M"
}
else if (x < 1000000000000) {
} else if (x < 1000000000000) {
res = global.numberify((x/1000000000).toFixed(0))
res.units = "B"
}
if (res.num*10 % 10 == 0)
if (res.num*10 % 10 === 0) {
res.num = Math.ceil(res.num);
}
return res;
}
@ -74,13 +80,13 @@
var labels = new Array();
for (var i = 0; i < views.length; i++) {
if ((views.length-i) % 7 == 0) {
if ((views.length-i) % 7 === 0) {
var x = (views.length-i)/7;
labels.push(x + " week" + (x > 1 ? "s" : "") + " ago");
}
else
} else {
labels.push("");
}
}
new Chartist.Line("#views-graph", {
labels: labels,
@ -92,8 +98,12 @@
series: [comments],
}, options);
data.domains[data.cd].viewsLast30Days = numberify(views.reduce(function(a, b) { return a + b; }, 0));
data.domains[data.cd].commentsLast30Days = numberify(comments.reduce(function(a, b) { return a + b; }, 0));
data.domains[data.cd].viewsLast30Days = numberify(views.reduce(function(a, b) {
return a + b;
}, 0));
data.domains[data.cd].commentsLast30Days = numberify(comments.reduce(function(a, b) {
return a + b;
}, 0));
});
}

View File

@ -1,4 +1,7 @@
(function (global, document) {
"use strict";
(document);
// Sets a vue.js field. Short for "vue set".
function vs(field, value) {
@ -82,8 +85,9 @@
data: reactiveData,
});
if (callback !== undefined)
if (callback !== undefined) {
callback();
}
};
} (window.commento, document));

View File

@ -1,9 +1,10 @@
(function (global, document) {
"use strict";
(document);
// Registers a given ID for a fade out after 5 seconds.
global.registerHide = function(id) {
var el = $(id);
setTimeout(function() {
$(id).fadeOut("fast");
}, 5000);

View File

@ -1,12 +1,15 @@
(function (global, document) {
"use strict";
(document);
// Talks to the API and sends an reset email.
global.sendResetHex = function() {
var all_ok = global.unfilledMark(["#email"], function(el) {
var allOk = global.unfilledMark(["#email"], function(el) {
el.css("border-bottom", "1px solid red");
});
if (!all_ok) {
if (!allOk) {
global.textSet("#err", "Please make sure all fields are filled.");
return;
}

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,7 @@
(function (global, document) {
"use strict";
(document);
// Performs a JSON POST request to the given url with the given data and
// calls the callback function with the JSON response.

File diff suppressed because one or more lines are too long

View File

@ -1,13 +1,15 @@
(function (global, document) {
"use strict";
(document);
// Shows messages produced from email confirmation attempts.
function displayConfirmedEmail() {
var confirmed = global.paramGet("confirmed");
if (confirmed == "true") {
if (confirmed === "true") {
$("#msg").html("Successfully confirmed! Login to continue.")
}
else if (confirmed == "false") {
} else if (confirmed === "false") {
$("#err").html("That link has expired.")
}
}
@ -17,7 +19,7 @@
function displayChangedPassword() {
var changed = global.paramGet("changed");
if (changed == "true") {
if (changed === "true") {
$("#msg").html("Password changed successfully! Login to continue.")
}
}
@ -26,7 +28,7 @@
function displaySignedUp() {
var signedUp = global.paramGet("signedUp");
if (signedUp == "true") {
if (signedUp === "true") {
$("#msg").html("Registration successful! Login to continue.")
}
}
@ -42,11 +44,11 @@
// Logs the user in and redirects to the dashboard.
global.login = function() {
var all_ok = global.unfilledMark(["#email", "#password"], function(el) {
var allOk = global.unfilledMark(["#email", "#password"], function(el) {
el.css("border-bottom", "1px solid red");
});
if (!all_ok) {
if (!allOk) {
global.textSet("#err", "Please make sure all fields are filled");
return;
}

View File

@ -1,4 +1,5 @@
(function (global, document) {
"use strict";
global.logout = function() {
global.cookieDelete("commentoOwnerToken");

View File

@ -1,16 +1,17 @@
(function (global, document) {
"use strict";
global.resetPassword = function() {
var all_ok = global.unfilledMark(["#password", "#password2"], function(el) {
var allOk = global.unfilledMark(["#password", "#password2"], function(el) {
el.css("border-bottom", "1px solid red");
});
if (!all_ok) {
if (!allOk) {
global.textSet("#err", "Please make sure all fields are filled.");
return;
}
if ($("#password").val() != $("#password2").val()) {
if ($("#password").val() !== $("#password2").val()) {
global.textSet("#err", "The two passwords do not match.");
return;
}

View File

@ -1,4 +1,5 @@
(function (global, document) {
"use strict";
// Get self details.
global.selfGet = function(callback) {

View File

@ -1,19 +1,20 @@
(function (global, document) {
"use strict"
// Signs up the user and redirects to either the login page or the email
// confirmation, depending on whether or not SMTP is configured in the
// backend.
global.signup = function() {
if ($("#password").val() != $("#password2").val()) {
if ($("#password").val() !== $("#password2").val()) {
global.textSet("#err", "The two passwords don't match");
return;
}
var all_ok = global.unfilledMark(["#email", "#name", "#password", "#password2"], function(el) {
var allOk = global.unfilledMark(["#email", "#name", "#password", "#password2"], function(el) {
el.css("border-bottom", "1px solid red");
});
if (!all_ok) {
if (!allOk) {
global.textSet("#err", "Please make sure all fields are filled");
return;
}
@ -33,10 +34,11 @@
return;
}
if (resp.confirmEmail)
if (resp.confirmEmail) {
document.locatidocumenton = global.origin + "/confirm-email";
else
} else {
document.location = global.origin + "/login?signedUp=true";
}
});
};

View File

@ -1,15 +1,17 @@
(function (global, document) {
"use strict";
// Gets a GET parameter in the current URL.
global.paramGet = function(param) {
var pageURL = decodeURIComponent(window.location.search.substring(1));
var urlVariables = pageURL.split('&');
var urlVariables = pageURL.split("&");
for (var i = 0; i < urlVariables.length; i++) {
var paramURL = urlVariables[i].split('=');
if (paramURL[0] === param)
var paramURL = urlVariables[i].split("=");
if (paramURL[0] === param) {
return paramURL[1] === undefined ? true : paramURL[1];
}
}
return null;
}
@ -42,16 +44,16 @@
// Given an array of input IDs, this function calls a callback function with
// the first unfilled ID.
global.unfilledMark = function(fields, callback) {
var all_ok = true;
var allOk = true;
for (var i = 0; i < fields.length; i++) {
var el = $(fields[i]);
if (el.val() == "") {
if (el.val() === "") {
callback(el);
}
}
return all_ok;
return allOk;
}
@ -59,8 +61,9 @@
global.cookieGet = function(name) {
var c = "; " + document.cookie;
var x = c.split("; " + name + "=");
if (x.length == 2)
if (x.length === 2) {
return x.pop().split(";").shift();
}
};
@ -72,8 +75,9 @@
expires = "; expires=" + date.toUTCString();
var cookieString = name + "=" + value + expires + "; path=/";
if (/^https:\/\//i.test(origin))
if (/^https:\/\//i.test(origin)) {
cookieString += "; secure";
}
document.cookie = cookieString;
}
@ -81,7 +85,7 @@
// Deletes a cookie.
global.cookieDelete = function(name) {
document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:01 GMT;';
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:01 GMT;";
}
@ -90,29 +94,35 @@
var seconds = Math.floor((new Date() - date) / 1000);
var interval = Math.floor(seconds / 31536000);
if (interval > 1)
if (interval > 1) {
return interval + " years ago";
}
interval = Math.floor(seconds / 2592000);
if (interval > 1)
if (interval > 1) {
return interval + " months ago";
}
interval = Math.floor(seconds / 86400);
if (interval > 1)
if (interval > 1) {
return interval + " days ago";
}
interval = Math.floor(seconds / 3600);
if (interval > 1)
if (interval > 1) {
return interval + " hours ago";
}
interval = Math.floor(seconds / 60);
if (interval > 1)
if (interval > 1) {
return interval + " minutes ago";
}
if (seconds > 5)
if (seconds > 5) {
return Math.floor(seconds) + " seconds ago";
else
} else {
return "just now";
}
}
} (window.commento, document));

File diff suppressed because one or more lines are too long

33
frontend/package.json Normal file
View File

@ -0,0 +1,33 @@
{
"name": "commento-ce",
"version": "1.0.0",
"main": "index.js",
"repository": "git@gitlab.com:commento/commento-ce.git",
"author": "Adhityaa <c.adhityaa@gmail.com> Anton Linevych anton@linevich.net",
"license": "MIT",
"private": true,
"devDependencies": {
"chartist": "0.11.0",
"fixmyjs": "2.0.0",
"gulp": "3.9.1",
"gulp-clean-css": "3.9.4",
"gulp-concat": "2.6.1",
"gulp-eslint": "5.0.0",
"gulp-html-minifier": "0.1.8",
"gulp-rename": "1.3.0",
"gulp-sass": "4.0.1",
"gulp-sourcemaps": "2.6.4",
"gulp-uglify": "3.0.0",
"highlightjs": "9.10.0",
"html-minifier": "3.5.7",
"jquery": "3.2.1",
"natives": "^1.1.6",
"normalize-scss": "7.0.1",
"sass": "1.5.1",
"uglify-js": "3.4.1",
"vue": "2.5.16"
},
"dependencies": {
"eslint": "^5.10.0"
}
}

4501
frontend/yarn.lock Normal file

File diff suppressed because it is too large Load Diff