REFACTOR: Remove $.cookie in favor of a local library based on it (#10548)

This helps us out in a few ways:

1. It lessens our reliance on jQuery
2. It's slightly less code because it omits options we don't use
3. It is one less library to import and put into ES6 modules
This commit is contained in:
Robin Ward 2020-08-27 14:07:51 -04:00 committed by GitHub
parent a8502ae1c4
commit c172f2068d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 145 additions and 150 deletions

View File

@ -1,12 +1,14 @@
import Component from "@ember/component";
import cookie from "discourse/lib/cookie";
export default Component.extend({
classNames: ["create-account"],
didInsertElement() {
this._super(...arguments);
if ($.cookie("email")) {
this.set("email", $.cookie("email"));
if (cookie("email")) {
this.set("email", cookie("email"));
}
$(this.element).on("keydown.discourse-create-account", e => {

View File

@ -4,6 +4,7 @@ import I18n from "I18n";
import Component from "@ember/component";
import LogsNotice from "discourse/services/logs-notice";
import EmberObject, { computed } from "@ember/object";
import cookie, { removeCookie } from "discourse/lib/cookie";
const _pluginNotices = [];
@ -67,8 +68,8 @@ export default Component.extend({
function() {
let notices = [];
if ($.cookie("dosp") === "1") {
$.removeCookie("dosp", { path: "/" });
if (cookie("dosp") === "1") {
removeCookie("dosp", { path: "/" });
notices.push(
Notice.create({
text: I18n.t("forced_anonymous"),

View File

@ -4,6 +4,7 @@ import discourseComputed from "discourse-common/utils/decorators";
import { popupAjaxError } from "discourse/lib/ajax-error";
import showModal from "discourse/lib/show-modal";
import bootbox from "bootbox";
import cookie from "discourse/lib/cookie";
export default Component.extend({
classNames: ["group-membership-button"],
@ -30,7 +31,7 @@ export default Component.extend({
_showLoginModal() {
this.showLogin();
$.cookie("destination_url", window.location.href);
cookie("destination_url", window.location.href);
},
removeFromGroup() {

View File

@ -1,5 +1,7 @@
import { schedule } from "@ember/runloop";
import Component from "@ember/component";
import cookie from "discourse/lib/cookie";
export default Component.extend({
didInsertElement() {
this._super(...arguments);
@ -11,8 +13,8 @@ export default Component.extend({
"loginPassword",
$("#hidden-login-form input[name=password]").val()
);
} else if ($.cookie("email")) {
this.set("loginName", $.cookie("email"));
} else if (cookie("email")) {
this.set("loginName", cookie("email"));
}
schedule("afterRender", () => {

View File

@ -21,6 +21,7 @@ import { findAll } from "discourse/models/login-method";
import EmberObject from "@ember/object";
import User from "discourse/models/user";
import { Promise } from "rsvp";
import cookie, { removeCookie } from "discourse/lib/cookie";
export default Controller.extend(
ModalFunctionality,
@ -270,7 +271,7 @@ export default Controller.extend(
const destinationUrl = this.get("authOptions.destination_url");
if (!isEmpty(destinationUrl)) {
$.cookie("destination_url", destinationUrl, { path: "/" });
cookie("destination_url", destinationUrl, { path: "/" });
}
// Add the userfields to the data
@ -326,12 +327,12 @@ export default Controller.extend(
this.rejectedPasswords.pushObject(attrs.accountPassword);
}
this.set("formSubmitted", false);
$.removeCookie("destination_url");
removeCookie("destination_url");
}
},
() => {
this.set("formSubmitted", false);
$.removeCookie("destination_url");
removeCookie("destination_url");
return this.flash(I18n.t("create_account.failed"), "error");
}
);

View File

@ -7,6 +7,7 @@ import ModalFunctionality from "discourse/mixins/modal-functionality";
import { escapeExpression } from "discourse/lib/utilities";
import { extractError } from "discourse/lib/ajax-error";
import getURL from "discourse-common/lib/get-url";
import cookie from "discourse/lib/cookie";
export default Controller.extend(ModalFunctionality, {
offerHelp: null,
@ -18,8 +19,8 @@ export default Controller.extend(ModalFunctionality, {
},
onShow() {
if ($.cookie("email")) {
this.set("accountEmailOrUsername", $.cookie("email"));
if (cookie("email")) {
this.set("accountEmailOrUsername", cookie("email"));
}
},

View File

@ -17,6 +17,7 @@ import { extractError } from "discourse/lib/ajax-error";
import { SECOND_FACTOR_METHODS } from "discourse/models/user";
import { getWebauthnCredential } from "discourse/lib/webauthn";
import bootbox from "bootbox";
import cookie, { removeCookie } from "discourse/lib/cookie";
// This is happening outside of the app via popup
const AuthErrors = [
@ -187,19 +188,19 @@ export default Controller.extend(ModalFunctionality, {
hiddenLoginForm.querySelector(`input[name=${key}]`).value = value;
};
const destinationUrl = $.cookie("destination_url");
const ssoDestinationUrl = $.cookie("sso_destination_url");
const destinationUrl = cookie("destination_url");
const ssoDestinationUrl = cookie("sso_destination_url");
applyHiddenFormInputValue(this.loginName, "username");
applyHiddenFormInputValue(this.loginPassword, "password");
if (ssoDestinationUrl) {
$.removeCookie("sso_destination_url");
removeCookie("sso_destination_url");
window.location.assign(ssoDestinationUrl);
return;
} else if (destinationUrl) {
// redirect client to the original URL
$.removeCookie("destination_url");
removeCookie("destination_url");
applyHiddenFormInputValue(destinationUrl, "redirect");
} else {
@ -369,10 +370,10 @@ export default Controller.extend(ModalFunctionality, {
// Reload the page if we're authenticated
if (options.authenticated) {
const destinationUrl =
$.cookie("destination_url") || options.destination_url;
cookie("destination_url") || options.destination_url;
if (destinationUrl) {
// redirect client to the original URL
$.removeCookie("destination_url");
removeCookie("destination_url");
window.location.href = destinationUrl;
} else if (window.location.pathname === getURL("/login")) {
window.location = getURL("/");

View File

@ -0,0 +1,99 @@
import deprecated from "discourse-common/lib/deprecated";
const pluses = /\+/g;
function parseCookieValue(s) {
if (s.indexOf('"') === 0) {
// This is a quoted cookie as according to RFC2068, unescape...
s = s
.slice(1, -1)
.replace(/\\"/g, '"')
.replace(/\\\\/g, "\\");
}
try {
// Replace server-side written pluses with spaces.
// If we can't decode the cookie, ignore it, it's unusable.
// If we can't parse the cookie, ignore it, it's unusable.
s = decodeURIComponent(s.replace(pluses, " "));
return s;
} catch (e) {}
}
function cookie(key, value, options) {
// Write
if (value !== undefined) {
options = Object.assign({}, options || {});
if (typeof options.expires === "number") {
let days = options.expires,
t = (options.expires = new Date());
t.setTime(+t + days * 864e5);
}
return (document.cookie = [
encodeURIComponent(key),
"=",
encodeURIComponent(String(value)),
options.expires ? "; expires=" + options.expires.toUTCString() : "", // use expires attribute, max-age is not supported by IE
options.path ? "; path=" + options.path : "",
options.domain ? "; domain=" + options.domain : "",
options.secure ? "; secure" : ""
].join(""));
}
// Read
let result = key ? undefined : {};
// To prevent the for loop in the first place assign an empty array
// in case there are no cookies at all. Also prevents odd result when
// calling cookie().
let cookies = document.cookie ? document.cookie.split("; ") : [];
for (let i = 0, l = cookies.length; i < l; i++) {
let parts = cookies[i].split("=");
let name = decodeURIComponent(parts.shift());
let c = parts.join("=");
if (key && key === name) {
result = parseCookieValue(c);
break;
}
// Prevent storing a cookie that we couldn't decode.
if (!key && (c = parseCookieValue(c)) !== undefined) {
result[name] = c;
}
}
return result;
}
export function removeCookie(key, options) {
if (cookie(key) === undefined) {
return false;
}
// Must not alter options, thus extending a fresh object...
cookie(key, "", Object.assign({}, options || {}, { expires: -1 }));
return !cookie(key);
}
if (window && window.$) {
const depOpts = { since: "2.6.0", dropFrom: "2.7.0" };
window.$.cookie = function() {
deprecated(
"$.cookie is being removed from Discourse. Please import our cookie module and use that instead.",
depOpts
);
return cookie(...arguments);
};
window.$.removeCookie = function() {
deprecated(
"$.removeCookie is being removed from Discourse. Please import our cookie module and use that instead.",
depOpts
);
return removeCookie(...arguments);
};
}
export default cookie;

View File

@ -1,5 +1,6 @@
import I18n from "I18n";
import deprecated from "discourse-common/lib/deprecated";
import cookie, { removeCookie } from "discourse/lib/cookie";
const keySelector = "meta[name=discourse_theme_ids]";
@ -34,12 +35,12 @@ export function currentThemeId() {
export function setLocalTheme(ids, themeSeq) {
ids = ids.reject(id => !id);
if (ids && ids.length > 0) {
$.cookie("theme_ids", `${ids.join(",")}|${themeSeq}`, {
cookie("theme_ids", `${ids.join(",")}|${themeSeq}`, {
path: "/",
expires: 9999
});
} else {
$.removeCookie("theme_ids", { path: "/", expires: 1 });
removeCookie("theme_ids", { path: "/", expires: 1 });
}
}

View File

@ -31,6 +31,7 @@ import Site from "discourse/models/site";
import { NotificationLevels } from "discourse/lib/notification-levels";
import { escapeExpression } from "discourse/lib/utilities";
import { getOwner } from "discourse-common/lib/get-owner";
import cookie, { removeCookie } from "discourse/lib/cookie";
export const SECOND_FACTOR_METHODS = {
TOTP: 1,
@ -874,8 +875,8 @@ const User = RestModel.extend({
@discourseComputed("user_option.text_size_seq", "user_option.text_size")
currentTextSize(serverSeq, serverSize) {
if ($.cookie("text_size")) {
const [cookieSize, cookieSeq] = $.cookie("text_size").split("|");
if (cookie("text_size")) {
const [cookieSize, cookieSeq] = cookie("text_size").split("|");
if (cookieSeq >= serverSeq) {
return cookieSize;
}
@ -886,12 +887,12 @@ const User = RestModel.extend({
updateTextSizeCookie(newSize) {
if (newSize) {
const seq = this.get("user_option.text_size_seq");
$.cookie("text_size", `${newSize}|${seq}`, {
cookie("text_size", `${newSize}|${seq}`, {
path: "/",
expires: 9999
});
} else {
$.removeCookie("text_size", { path: "/", expires: 1 });
removeCookie("text_size", { path: "/", expires: 1 });
}
},

View File

@ -4,6 +4,7 @@ import DiscourseRoute from "discourse/routes/discourse";
import User from "discourse/models/user";
import Group from "discourse/models/group";
import bootbox from "bootbox";
import cookie from "discourse/lib/cookie";
export default DiscourseRoute.extend({
beforeModel(transition) {
@ -58,7 +59,7 @@ export default DiscourseRoute.extend({
}
});
} else {
$.cookie("destination_url", window.location.href);
cookie("destination_url", window.location.href);
this.replaceWith("login");
}
}

View File

@ -1,6 +1,7 @@
import { next } from "@ember/runloop";
import DiscourseRoute from "discourse/routes/discourse";
import Category from "discourse/models/category";
import cookie from "discourse/lib/cookie";
export default DiscourseRoute.extend({
beforeModel(transition) {
@ -58,7 +59,7 @@ export default DiscourseRoute.extend({
}
} else {
// User is not logged in
$.cookie("destination_url", window.location.href);
cookie("destination_url", window.location.href);
this.replaceWith("login");
}
},

View File

@ -13,7 +13,6 @@
//= require favcount.js
//= require jquery.ba-resize.js
//= require jquery.color.js
//= require jquery.cookie.js
//= require jquery.fileupload.js
//= require jquery.iframe-transport.js
//= require jquery.tagsinput.js

View File

@ -2,6 +2,7 @@ import I18n from "I18n";
import { acceptance, updateCurrentUser } from "helpers/qunit-helpers";
import selectKit from "helpers/select-kit-helper";
import User from "discourse/models/user";
import cookie, { removeCookie } from "discourse/lib/cookie";
function preferencesPretender(server, helper) {
server.post("/u/second_factors.json", () => {
@ -122,7 +123,7 @@ QUnit.test("update some fields", async assert => {
});
QUnit.test("font size change", async assert => {
$.removeCookie("text_size");
removeCookie("text_size");
const savePreferences = async () => {
assert.ok(!exists(".saved"), "it hasn't been saved yet");
@ -142,12 +143,12 @@ QUnit.test("font size change", async assert => {
await selectKit(".text-size .combobox").selectRowByValue("largest");
assert.ok(document.documentElement.classList.contains("text-size-largest"));
assert.equal($.cookie("text_size"), null, "cookie is not set");
assert.equal(cookie("text_size"), null, "cookie is not set");
// Click save (by default this sets for all browsers, no cookie)
await savePreferences();
assert.equal($.cookie("text_size"), null, "cookie is not set");
assert.equal(cookie("text_size"), null, "cookie is not set");
await selectKit(".text-size .combobox").expand();
await selectKit(".text-size .combobox").selectRowByValue("larger");
@ -155,15 +156,15 @@ QUnit.test("font size change", async assert => {
await savePreferences();
assert.equal($.cookie("text_size"), "larger|1", "cookie is set");
assert.equal(cookie("text_size"), "larger|1", "cookie is set");
await click(".text-size input[type=checkbox]");
await selectKit(".text-size .combobox").expand();
await selectKit(".text-size .combobox").selectRowByValue("largest");
await savePreferences();
assert.equal($.cookie("text_size"), null, "cookie is removed");
assert.equal(cookie("text_size"), null, "cookie is removed");
$.removeCookie("text_size");
removeCookie("text_size");
});
QUnit.test("username", async assert => {

View File

@ -1,117 +0,0 @@
/*!
* jQuery Cookie Plugin v1.4.1
* https://github.com/carhartl/jquery-cookie
*
* Copyright 2013 Klaus Hartl
* Released under the MIT license
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// CommonJS
factory(require('jquery'));
} else {
// Browser globals
factory(jQuery);
}
}(function ($) {
var pluses = /\+/g;
function encode(s) {
return config.raw ? s : encodeURIComponent(s);
}
function decode(s) {
return config.raw ? s : decodeURIComponent(s);
}
function stringifyCookieValue(value) {
return encode(config.json ? JSON.stringify(value) : String(value));
}
function parseCookieValue(s) {
if (s.indexOf('"') === 0) {
// This is a quoted cookie as according to RFC2068, unescape...
s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
}
try {
// Replace server-side written pluses with spaces.
// If we can't decode the cookie, ignore it, it's unusable.
// If we can't parse the cookie, ignore it, it's unusable.
s = decodeURIComponent(s.replace(pluses, ' '));
return config.json ? JSON.parse(s) : s;
} catch(e) {}
}
function read(s, converter) {
var value = config.raw ? s : parseCookieValue(s);
return $.isFunction(converter) ? converter(value) : value;
}
var config = $.cookie = function (key, value, options) {
// Write
if (value !== undefined && !$.isFunction(value)) {
options = $.extend({}, config.defaults, options);
if (typeof options.expires === 'number') {
var days = options.expires, t = options.expires = new Date();
t.setTime(+t + days * 864e+5);
}
return (document.cookie = [
encode(key), '=', stringifyCookieValue(value),
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
options.path ? '; path=' + options.path : '',
options.domain ? '; domain=' + options.domain : '',
options.secure ? '; secure' : ''
].join(''));
}
// Read
var result = key ? undefined : {};
// To prevent the for loop in the first place assign an empty array
// in case there are no cookies at all. Also prevents odd result when
// calling $.cookie().
var cookies = document.cookie ? document.cookie.split('; ') : [];
for (var i = 0, l = cookies.length; i < l; i++) {
var parts = cookies[i].split('=');
var name = decode(parts.shift());
var cookie = parts.join('=');
if (key && key === name) {
// If second argument (value) is a function it's a converter...
result = read(cookie, value);
break;
}
// Prevent storing a cookie that we couldn't decode.
if (!key && (cookie = read(cookie)) !== undefined) {
result[name] = cookie;
}
}
return result;
};
config.defaults = {};
$.removeCookie = function (key, options) {
if ($.cookie(key) === undefined) {
return false;
}
// Must not alter options, thus extending a fresh object...
$.cookie(key, '', $.extend({}, options, { expires: -1 }));
return !$.cookie(key);
};
}));