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:
parent
e4f71fe402
commit
9e3935b3b2
33
frontend/.eslintrc
Normal file
33
frontend/.eslintrc
Normal 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
1
frontend/.gitignore
vendored
@ -1 +1,2 @@
|
||||
.sass-cache
|
||||
node_modules/
|
||||
|
@ -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
134
frontend/gulpfile.js
Normal 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"]);
|
@ -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
@ -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));
|
||||
|
@ -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";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
(function (global, document) {
|
||||
"use strict";
|
||||
|
||||
(document);
|
||||
|
||||
// Opens the general settings window.
|
||||
global.generalOpen = function() {
|
||||
|
@ -1,4 +1,7 @@
|
||||
(function (global, document) {
|
||||
"use strict";
|
||||
|
||||
(document);
|
||||
|
||||
// Opens the import window.
|
||||
global.importOpen = function() {
|
||||
|
@ -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);
|
||||
});
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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
@ -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.
|
||||
|
4
frontend/js/jquery.js
vendored
4
frontend/js/jquery.js
vendored
File diff suppressed because one or more lines are too long
@ -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;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
(function (global, document) {
|
||||
"use strict";
|
||||
|
||||
global.logout = function() {
|
||||
global.cookieDelete("commentoOwnerToken");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
(function (global, document) {
|
||||
"use strict";
|
||||
|
||||
// Get self details.
|
||||
global.selfGet = function(callback) {
|
||||
|
@ -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";
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -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
33
frontend/package.json
Normal 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
4501
frontend/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user