Version bump

This commit is contained in:
Neil Lalonde 2021-01-28 12:55:34 -05:00
commit f83eaad496
No known key found for this signature in database
GPG Key ID: FF871CA9037D0A91
387 changed files with 5967 additions and 4096 deletions

View File

@ -1,3 +1,4 @@
app/assets/javascripts/discourse-loader.js
app/assets/javascripts/env.js
app/assets/javascripts/main_include_admin.js
app/assets/javascripts/vendor.js

View File

@ -1,9 +1,7 @@
{
"extends": "eslint-config-discourse",
"rules": {
"discourse-ember/global-ember": 2,
"no-duplicate-imports": 2,
"sort-imports": 2
"discourse-ember/global-ember": 2
},
"globals": {
"moduleFor": "off",
@ -14,6 +12,6 @@
"currentURL": "off",
"invisible": "off",
"visible": "off",
"count": "off",
"count": "off"
}
}

View File

@ -65,7 +65,7 @@ jobs:
if: env.BUILD_TYPE != 'LINT'
run: |
sudo apt-get update
sudo apt-get -yqq install postgresql-client libpq-dev jpegoptim optipng jhead
sudo apt-get -yqq install postgresql-client libpq-dev jpegoptim optipng jhead pngcrush pngquant
wget -qO- https://raw.githubusercontent.com/discourse/discourse_docker/master/image/base/install-pngquant | sudo sh
- name: Update imagemagick

View File

@ -6,6 +6,7 @@ config/locales/**/*.yml
!config/locales/**/*.en*.yml
script/import_scripts/**/*.yml
app/assets/javascripts/discourse-loader.js
app/assets/javascripts/env.js
app/assets/javascripts/main_include_admin.js
app/assets/javascripts/vendor.js

View File

@ -167,6 +167,7 @@ group :test, :development do
gem 'parallel_tests'
gem 'rswag-specs'
gem 'json_schemer'
end
group :development do

View File

@ -43,7 +43,7 @@ GEM
annotate (3.1.1)
activerecord (>= 3.2, < 7.0)
rake (>= 10.4, < 14.0)
ast (2.4.1)
ast (2.4.2)
aws-eventstream (1.1.0)
aws-partitions (1.390.0)
aws-sdk-core (3.109.2)
@ -72,10 +72,10 @@ GEM
rack (>= 0.9.0)
binding_of_caller (1.0.0)
debug_inspector (>= 0.0.1)
bootsnap (1.5.1)
bootsnap (1.6.0)
msgpack (~> 1.0)
builder (3.2.4)
bullet (6.1.2)
bullet (6.1.3)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
byebug (11.1.3)
@ -93,7 +93,7 @@ GEM
crack (0.4.5)
rexml
crass (1.0.6)
css_parser (1.7.1)
css_parser (1.8.0)
addressable
debug_inspector (1.0.0)
diff-lcs (1.4.4)
@ -114,6 +114,8 @@ GEM
in_threads (~> 1.3)
progress (~> 3.0, >= 3.0.1)
docile (1.3.5)
ecma-re-validator (0.3.0)
regexp_parser (~> 2.0)
email_reply_trimmer (0.1.13)
ember-data-source (3.0.2)
ember-source (>= 2, < 3.0)
@ -141,6 +143,7 @@ GEM
globalid (0.4.2)
activesupport (>= 4.2.0)
guess_html_encoding (0.0.11)
hana (1.3.7)
hashdiff (1.0.1)
hashie (4.1.0)
highline (2.0.3)
@ -159,9 +162,15 @@ GEM
json (2.5.1)
json-schema (2.8.1)
addressable (>= 2.4)
json_schemer (0.2.17)
ecma-re-validator (~> 0.3)
hana (~> 1.3)
regexp_parser (~> 2.0)
uri_template (~> 0.7)
jwt (2.2.2)
kgio (2.11.3)
libv8 (8.4.255.0)
libv8 (8.4.255.0-universal-darwin-20)
libv8 (8.4.255.0-x86_64-darwin-18)
libv8 (8.4.255.0-x86_64-darwin-19)
libv8 (8.4.255.0-x86_64-darwin-20)
@ -177,7 +186,7 @@ GEM
logstash-event (1.2.02)
logstash-logger (0.26.1)
logstash-event (~> 1.2)
logster (2.9.4)
logster (2.9.5)
loofah (2.9.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
@ -197,13 +206,13 @@ GEM
mini_scheduler (0.13.0)
sidekiq (>= 4.2.3)
mini_sql (1.0.1)
mini_suffix (0.3.0)
mini_suffix (0.3.2)
ffi (~> 1.9)
minitest (5.14.3)
mocha (1.12.0)
mock_redis (0.27.3)
ruby2_keywords
msgpack (1.3.3)
msgpack (1.4.1)
multi_json (1.15.0)
multi_xml (0.6.0)
multipart-post (2.1.1)
@ -212,6 +221,8 @@ GEM
nokogiri (1.11.1)
mini_portile2 (~> 2.5.0)
racc (~> 1.4)
nokogiri (1.11.1-arm64-darwin)
racc (~> 1.4)
nokogiri (1.11.1-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.11.1-x86_64-linux)
@ -225,7 +236,7 @@ GEM
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
oj (3.11.0)
oj (3.11.1)
omniauth (1.9.1)
hashie (>= 3.4.6)
rack (>= 1.6.2, < 3)
@ -273,7 +284,7 @@ GEM
pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (4.0.6)
puma (5.1.1)
puma (5.2.0)
nio4r (~> 2.0)
r2 (0.2.7)
racc (1.5.2)
@ -364,7 +375,7 @@ GEM
rubocop-ast (>= 1.2.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.4.0)
rubocop-ast (1.4.1)
parser (>= 2.7.1.5)
rubocop-discourse (2.4.1)
rubocop (>= 1.1.0)
@ -395,9 +406,9 @@ GEM
seed-fu (2.3.9)
activerecord (>= 3.1)
activesupport (>= 3.1)
shoulda-matchers (4.5.0)
shoulda-matchers (4.5.1)
activesupport (>= 4.2.0)
sidekiq (6.1.2)
sidekiq (6.1.3)
connection_pool (>= 2.2.2)
rack (~> 2.0)
redis (>= 4.2.0)
@ -416,7 +427,7 @@ GEM
sprockets (>= 3.0.0)
sshkey (2.0.0)
stackprof (0.2.16)
test-prof (0.12.2)
test-prof (1.0.0)
thor (1.1.0)
thread_safe (0.3.6)
tilt (2.0.10)
@ -432,6 +443,7 @@ GEM
kgio (~> 2.6)
raindrops (~> 0.7)
uniform_notifier (1.13.2)
uri_template (0.7.0)
webmock (3.11.1)
addressable (>= 2.3.6)
crack (>= 0.3.2)
@ -444,6 +456,7 @@ GEM
zeitwerk (2.4.2)
PLATFORMS
arm64-darwin-20
ruby
x86_64-darwin-18
x86_64-darwin-19
@ -494,6 +507,7 @@ DEPENDENCIES
htmlentities
http_accept_language
json
json_schemer
listen
lograge
logstash-event
@ -575,4 +589,4 @@ DEPENDENCIES
yaml-lint
BUNDLED WITH
2.2.3
2.2.6

View File

@ -10,6 +10,7 @@ export default Component.extend({
_editor: null,
_skipContentChangeEvent: null,
disabled: false,
htmlPlaceholder: false,
@observes("editorId")
editorIdChanged() {
@ -86,6 +87,10 @@ export default Component.extend({
loadedAce.config.set("loadWorkerFromBlob", false);
loadedAce.config.set("workerPath", getURL("/javascripts/ace")); // Do not use CDN for workers
if (this.htmlPlaceholder) {
this._overridePlaceholder(loadedAce);
}
if (!this.element || this.isDestroying || this.isDestroyed) {
return;
}
@ -131,4 +136,32 @@ export default Component.extend({
}
},
},
_overridePlaceholder(loadedAce) {
const originalPlaceholderSetter =
loadedAce.config.$defaultOptions.editor.placeholder.set;
loadedAce.config.$defaultOptions.editor.placeholder.set = function () {
if (!this.$updatePlaceholder) {
const originalRendererOn = this.renderer.on;
this.renderer.on = function () {};
originalPlaceholderSetter.call(this, ...arguments);
this.renderer.on = originalRendererOn;
const originalUpdatePlaceholder = this.$updatePlaceholder;
this.$updatePlaceholder = function () {
originalUpdatePlaceholder.call(this, ...arguments);
if (this.renderer.placeholderNode) {
this.renderer.placeholderNode.innerHTML = this.$placeholder || "";
}
}.bind(this);
this.on("input", this.$updatePlaceholder);
}
this.$updatePlaceholder();
};
},
});

View File

@ -10,7 +10,7 @@ export default Component.extend({
const model = this.model;
const rawData = this.get("model.data");
var data = {
let data = {
labels: rawData.map((r) => r.x),
datasets: [
{

View File

@ -2,6 +2,7 @@ import Component from "@ember/component";
import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators";
import { fmt } from "discourse/lib/computed";
import { isDocumentRTL } from "discourse/lib/text-direction";
import { next } from "@ember/runloop";
export default Component.extend({
@ -43,9 +44,17 @@ export default Component.extend({
@discourseComputed("currentTargetName", "fieldName")
placeholder(targetName, fieldName) {
return fieldName && fieldName === "color_definitions"
? I18n.t("admin.customize.theme.color_definitions.placeholder")
: "";
if (fieldName && fieldName === "color_definitions") {
const example =
":root {\n" +
" --mytheme-tertiary-or-quaternary: #{dark-light-choose($tertiary, $quaternary)};\n" +
"}";
return I18n.t("admin.customize.theme.color_definitions.placeholder", {
example: isDocumentRTL() ? `<div dir="ltr">${example}</div>` : example,
});
}
return "";
},
@discourseComputed("fieldName", "currentTargetName", "theme")

View File

@ -0,0 +1,26 @@
import Component from "@ember/component";
import { action } from "@ember/object";
import { ajax } from "discourse/lib/ajax";
export default Component.extend({
newFeatures: null,
releaseNotesLink: null,
init() {
this._super(...arguments);
ajax("/admin/dashboard/new-features.json").then((json) => {
this.setProperties({
newFeatures: json.new_features,
releaseNotesLink: json.release_notes_link,
});
});
},
@action
dismissNewFeatures() {
ajax("/admin/dashboard/mark-new-features-as-seen.json", {
type: "PUT",
}).then(() => this.set("newFeatures", null));
},
});

View File

@ -94,9 +94,9 @@ export default Component.extend({
_splitValues(values, delimiter) {
if (values && values.length) {
const keys = ["key", "secret"];
var res = [];
let res = [];
values.split(delimiter).forEach(function (str) {
var object = {};
let object = {};
str.split("|").forEach(function (a, i) {
object[keys[i]] = a;
});

View File

@ -110,7 +110,7 @@ export default Controller.extend(bufferedProperty("model"), {
const data = {};
const buffered = this.buffered;
fields.forEach(function (field) {
var d = buffered.get(field);
let d = buffered.get(field);
if (boolFields.includes(field)) {
d = !!d;
}

View File

@ -53,17 +53,18 @@ export default Controller.extend({
// Only confirm if we already been saved
if (f.get("id")) {
bootbox.confirm(I18n.t("admin.user_fields.delete_confirm"), function (
result
) {
if (result) {
f.destroyRecord()
.then(function () {
model.removeObject(f);
})
.catch(popupAjaxError);
bootbox.confirm(
I18n.t("admin.user_fields.delete_confirm"),
function (result) {
if (result) {
f.destroyRecord()
.then(function () {
model.removeObject(f);
})
.catch(popupAjaxError);
}
}
});
);
} else {
model.removeObject(f);
}

View File

@ -396,7 +396,6 @@ export default Controller.extend(CanCheckEmails, {
destroy() {
const postCount = this.get("model.post_count");
const maxPostCount = this.siteSettings.delete_all_posts_max;
const user = this.model;
const message = I18n.t("admin.user.delete_confirm");
const location = document.location.pathname;
@ -422,13 +421,9 @@ export default Controller.extend(CanCheckEmails, {
}
} else {
bootbox.alert(I18n.t("admin.user.delete_failed"));
if (data.user) {
user.setProperties(data.user);
}
}
})
.catch(() => {
AdminUser.find(user.get("id")).then((u) => user.setProperties(u));
bootbox.alert(I18n.t("admin.user.delete_failed"));
});
};
@ -601,8 +596,10 @@ export default Controller.extend(CanCheckEmails, {
I18n.t("admin.user.sso.confirm_delete"),
I18n.t("no_value"),
I18n.t("yes_value"),
() => {
return this.model.deleteSSORecord();
(confirmed) => {
if (confirmed) {
return this.model.deleteSSORecord();
}
}
);
},

View File

@ -1,9 +1,9 @@
import { registerUnbound } from "discourse-common/lib/helpers";
registerUnbound("value-at-tl", function (data, params) {
var tl = parseInt(params.level, 10);
let tl = parseInt(params.level, 10);
if (data) {
var item = data.find(function (d) {
let item = data.find(function (d) {
return parseInt(d.x, 10) === tl;
});
if (item) {

View File

@ -14,6 +14,7 @@ AdminDashboard.reopenClass({
return ajax("/admin/dashboard.json").then((json) => {
const model = AdminDashboard.create();
model.set("version_check", json.version_check);
return model;
});
},

View File

@ -264,7 +264,17 @@ const AdminUser = User.extend({
return ajax(`/admin/users/${this.id}.json`, {
type: "DELETE",
data: formData,
});
})
.then((data) => {
if (!data.deleted && data.user) {
this.setProperties(data.user);
}
return data;
})
.catch(() => {
this.find(this.id).then((u) => this.setProperties(u));
});
},
merge(formData) {

View File

@ -14,7 +14,7 @@ export default DiscourseRoute.extend({
Badge.findAll().then(function (badges) {
controller.set("badges", badges);
if (badges.length > 0) {
var grantableBadges = controller.get("grantableBadges");
let grantableBadges = controller.get("grantableBadges");
if (grantableBadges.length > 0) {
controller.set("selectedBadgeId", grantableBadges[0].get("id"));
}

View File

@ -33,8 +33,8 @@ export default Service.extend({
return AdminUser.find(userId).then((au) => this.spammerDetails(au));
},
deleteUser(id) {
AdminUser.find(id).then((user) => user.destroy({ deletePosts: true }));
deleteUser(id, formData) {
return AdminUser.find(id).then((user) => user.destroy(formData));
},
spammerDetails(adminUser) {

View File

@ -5,7 +5,7 @@
{{#if readOnly}}
{{input type="text" name="name" value=buffered.name disabled=true}}
<p class="help">
{{#link-to "adminSiteText.edit" (concat textCustomizationPrefix "name")}}
{{#link-to "adminSiteText" (query-params q=(concat textCustomizationPrefix "name"))}}
{{i18n "admin.badges.read_only_setting_help"}}
{{/link-to}}
</p>
@ -70,7 +70,7 @@
{{#if buffered.system}}
{{textarea name="description" value=buffered.description disabled=true}}
<p class="help">
{{#link-to "adminSiteText.edit" (concat textCustomizationPrefix "description")}}
{{#link-to "adminSiteText" (query-params q=(concat textCustomizationPrefix "description"))}}
{{i18n "admin.badges.read_only_setting_help"}}
{{/link-to}}
</p>
@ -84,7 +84,7 @@
{{#if buffered.system}}
{{textarea name="long_description" value=buffered.long_description disabled=true}}
<p class="help">
{{#link-to "adminSiteText.edit" (concat textCustomizationPrefix "long_description")}}
{{#link-to "adminSiteText" (query-params q=(concat textCustomizationPrefix "long_description"))}}
{{i18n "admin.badges.read_only_setting_help"}}
{{/link-to}}
</p>

View File

@ -87,4 +87,4 @@
<pre class="field-error">{{error}}</pre>
{{/if}}
{{ace-editor content=activeSection editorId=editorId mode=activeSectionMode autofocus="true" placeholder=placeholder}}
{{ace-editor content=activeSection editorId=editorId mode=activeSectionMode autofocus="true" placeholder=placeholder htmlPlaceholder=true}}

View File

@ -0,0 +1,13 @@
<div class="admin-new-feature-item">
<div class="new-feature-emoji">{{item.emoji}}</div>
<div class="new-feature-content">
<div class="header">
{{#if item.link}}
<a href={{item.link}} target="_blank" rel="noopener noreferrer">{{item.title}}</a>
{{else}}
{{item.title}}
{{/if}}
</div>
<div class="feature-description">{{item.description}}</div>
</div>
</div>

View File

@ -0,0 +1,21 @@
{{#if newFeatures}}
<div class="section dashboard-new-features">
<div class="section-title">
<h2>{{replace-emoji (i18n "admin.dashboard.new_features.title") }}</h2>
</div>
<div class="section-body">
{{#each newFeatures as |feature|}}
{{dashboard-new-feature-item item=feature}}
{{/each}}
</div>
<div class="section-footer">
{{#if releaseNotesLink}}
<a rel="noopener noreferrer" target="_blank" href={{releaseNotesLink}} class="btn btn-primary new-features-release-notes">
{{i18n "admin.dashboard.new_features.learn_more"}}
</a>
{{/if}}
{{d-button label="admin.dashboard.new_features.dismiss" class="new-features-dismiss" action=dismissNewFeatures }}
</div>
</div>
{{/if}}

View File

@ -1,3 +1,5 @@
{{dashboard-new-features}}
{{plugin-outlet name="admin-dashboard-top"}}
{{#if showVersionChecks}}

View File

@ -2,10 +2,10 @@
//Copyright (c) 2007-2009, MIT Style License <browser-update.org/LICENSE.txt>
(function () {
var $buo = function () {
let $buo = function () {
// Sometimes we have to resort to parsing the user agent string. :(
if (navigator && navigator.userAgent) {
var ua = navigator.userAgent;
let ua = navigator.userAgent;
// we don't ask Googlebot to update their browser
if (
@ -22,10 +22,10 @@
}
document.getElementsByTagName("body")[0].className += " crawler";
var mainElement = document.getElementById("main");
var noscriptElements = document.getElementsByTagName("noscript");
let mainElement = document.getElementById("main");
let noscriptElements = document.getElementsByTagName("noscript");
// find the element with the "data-path" attribute set
for (var i = 0; i < noscriptElements.length; ++i) {
for (let i = 0; i < noscriptElements.length; ++i) {
if (noscriptElements[i].getAttribute("data-path")) {
// noscriptElements[i].innerHTML contains encoded HTML
if (noscriptElements[i].childNodes.length > 0) {
@ -36,7 +36,7 @@
}
// retrieve localized browser upgrade text
var t = I18n.t("browser_update"); // eslint-disable-line no-undef
let t = I18n.t("browser_update"); // eslint-disable-line no-undef
if (t.indexOf(".browser_update]") !== -1) {
// very old browsers might fail to load even translations
t =
@ -44,13 +44,13 @@
}
// create the notification div HTML
var div = document.createElement("div");
let div = document.createElement("div");
div.className = "buorg";
div.innerHTML = "<div>" + t + "</div>";
// create the notification div stylesheet
var sheet = document.createElement("style");
var style =
let sheet = document.createElement("style");
let style =
".buorg {position:absolute; z-index:111111; width:100%; top:0px; left:0px; background:#FDF2AB; text-align:left; font-family: sans-serif; color:#000; font-size: 14px;} .buorg div {padding: 8px;} .buorg a, .buorg a:visited {color:#E25600; text-decoration: underline;} @media print { .buorg { display: none !important; } }";
// insert the div and stylesheet into the DOM

View File

@ -14,6 +14,12 @@ export function isTesting() {
return Ember.testing || environment === "testing";
}
// Generally means "before we migrated to Ember CLI"
let _isLegacy = Ember.VERSION.startsWith("3.12");
export function isLegacyEmber() {
return _isLegacy;
}
export function isDevelopment() {
return environment === "development";
}

View File

@ -32,8 +32,8 @@ AttributeHook.prototype.unhook = function (node, prop, next) {
return;
}
var colonPosition = prop.indexOf(":");
var localName = colonPosition > -1 ? prop.substr(colonPosition + 1) : prop;
let colonPosition = prop.indexOf(":");
let localName = colonPosition > -1 ? prop.substr(colonPosition + 1) : prop;
node.removeAttributeNS(this.namespace, localName);
};

View File

@ -1,14 +1,17 @@
import { debounce, run } from "@ember/runloop";
import { isTesting } from "discourse-common/config/environment";
import { debounce, next, run } from "@ember/runloop";
import { isLegacyEmber, isTesting } from "discourse-common/config/environment";
/**
Debounce a Javascript function. This means if it's called many times in a time limit it
should only be executed once (at the end of the limit counted from the last call made).
Original function will be called with the context and arguments from the last call made.
**/
let testingFunc = isLegacyEmber() ? run : next;
export default function () {
if (isTesting()) {
return run(...arguments);
return testingFunc(...arguments);
} else {
return debounce(...arguments);
}

View File

@ -15,9 +15,9 @@ export default function getURL(url) {
return url;
}
const found = url.indexOf(baseUri);
const found = url.startsWith(baseUri);
if (found >= 0 && found < 3) {
if (found) {
return url;
}
if (url[0] !== "/") {

View File

@ -22,7 +22,7 @@ const _helpers = {};
function rawGet(ctx, property, options) {
if (options.types && options.data.view) {
var view = options.data.view;
let view = options.data.view;
return view.getStream
? view.getStream(property).value()
: view.getAttr(property);

View File

@ -47,7 +47,7 @@ export function deepEqual(obj1, obj2) {
if (Object.keys(obj1).length !== Object.keys(obj2).length) {
return false;
}
for (var prop in obj1) {
for (let prop in obj1) {
if (!deepEqual(obj1[prop], obj2[prop])) {
return false;
}

View File

@ -29,24 +29,22 @@ export function registerRawHelpers(hbs, handlebarsClass) {
};
// #each .. in support (as format is transformed to this)
hbs.registerHelper("each", function (
localName,
inKeyword,
contextName,
options
) {
if (typeof contextName === "undefined") {
return;
hbs.registerHelper(
"each",
function (localName, inKeyword, contextName, options) {
if (typeof contextName === "undefined") {
return;
}
let list = get(this, contextName);
let output = [];
for (let i = 0; i < list.length; i++) {
let innerContext = {};
innerContext[localName] = list[i];
output.push(options.fn(innerContext));
}
return output.join("");
}
var list = get(this, contextName);
var output = [];
for (var i = 0; i < list.length; i++) {
let innerContext = {};
innerContext[localName] = list[i];
output.push(options.fn(innerContext));
}
return output.join("");
});
);
function stringCompatHelper(fn) {
const old = hbs.helpers[fn];

View File

@ -6,7 +6,7 @@ import Handlebars from "handlebars";
const RawHandlebars = Handlebars.create();
function buildPath(blk, args) {
var result = {
let result = {
type: "PathExpression",
data: false,
depth: blk.path.depth,
@ -22,7 +22,7 @@ function buildPath(blk, args) {
}
function replaceGet(ast) {
var visitor = new Handlebars.Visitor();
let visitor = new Handlebars.Visitor();
visitor.mutating = true;
visitor.MustacheStatement = function (mustache) {
@ -42,7 +42,7 @@ function replaceGet(ast) {
// This allows us to use the same syntax in all templates
visitor.BlockStatement = function (block) {
if (block.path.original === "each" && block.params.length === 1) {
var paramName = block.program.blockParams[0];
let paramName = block.program.blockParams[0];
block.params = [
buildPath(block, { original: paramName }),
{ type: "CommentStatement", value: "in" },
@ -74,10 +74,10 @@ if (Handlebars.Compiler) {
RawHandlebars.JavaScriptCompiler.prototype.namespace = "RawHandlebars";
RawHandlebars.precompile = function (value, asObject) {
var ast = Handlebars.parse(value);
let ast = Handlebars.parse(value);
replaceGet(ast);
var options = {
let options = {
knownHelpers: {
get: true,
},
@ -87,7 +87,7 @@ if (Handlebars.Compiler) {
asObject = asObject === undefined ? true : asObject;
var environment = new RawHandlebars.Compiler().compile(ast, options);
let environment = new RawHandlebars.Compiler().compile(ast, options);
return new RawHandlebars.JavaScriptCompiler().compile(
environment,
options,
@ -97,20 +97,20 @@ if (Handlebars.Compiler) {
};
RawHandlebars.compile = function (string) {
var ast = Handlebars.parse(string);
let ast = Handlebars.parse(string);
replaceGet(ast);
// this forces us to rewrite helpers
var options = { data: true, stringParams: true };
var environment = new RawHandlebars.Compiler().compile(ast, options);
var templateSpec = new RawHandlebars.JavaScriptCompiler().compile(
let options = { data: true, stringParams: true };
let environment = new RawHandlebars.Compiler().compile(ast, options);
let templateSpec = new RawHandlebars.JavaScriptCompiler().compile(
environment,
options,
undefined,
true
);
var t = RawHandlebars.template(templateSpec);
let t = RawHandlebars.template(templateSpec);
t.isMethod = false;
return t;

View File

@ -111,7 +111,7 @@ export function buildResolver(baseName) {
);
});
var module;
let module;
if (moduleName) {
module = requirejs(moduleName, null, null, true /* force sync */);
if (module && module["default"]) {
@ -200,7 +200,7 @@ export function buildResolver(baseName) {
findPluginMobileTemplate(parsedName) {
if (_options.mobileView) {
var pluginParsedName = this.parseName(
let pluginParsedName = this.parseName(
parsedName.fullName.replace(
"template:",
"template:javascripts/mobile/"
@ -212,7 +212,7 @@ export function buildResolver(baseName) {
findMobileTemplate(parsedName) {
if (_options.mobileView) {
var mobileParsedName = this.parseName(
let mobileParsedName = this.parseName(
parsedName.fullName.replace("template:", "template:mobile/")
);
return this.findTemplate(mobileParsedName);
@ -241,15 +241,15 @@ export function buildResolver(baseName) {
},
findUnderscoredTemplate(parsedName) {
var decamelized = parsedName.fullNameWithoutType.decamelize();
var underscored = decamelized.replace(/\-/g, "_");
let decamelized = parsedName.fullNameWithoutType.decamelize();
let underscored = decamelized.replace(/\-/g, "_");
return Ember.TEMPLATES[underscored];
},
// Try to find a template within a special admin namespace, e.g. adminEmail => admin/templates/email
// (similar to how discourse lays out templates)
findAdminTemplate(parsedName) {
var decamelized = parsedName.fullNameWithoutType.decamelize();
let decamelized = parsedName.fullNameWithoutType.decamelize();
if (decamelized.indexOf("components") === 0) {
let comPath = `admin/templates/${decamelized}`;
const compTemplate =

View File

@ -12,7 +12,7 @@ export default function decoratorAlias(fn, errorMessage) {
configurable: desc.configurable,
writable: desc.writable,
initializer: function () {
var value = extractValue(desc);
let value = extractValue(desc);
return fn.apply(null, params.concat(value));
},
};

View File

@ -51,7 +51,7 @@ export function readOnly(target, name, desc) {
enumerable: desc.enumerable,
configurable: desc.configurable,
initializer: function () {
var value = extractValue(desc);
let value = extractValue(desc);
return value.readOnly();
},
};

View File

@ -10,7 +10,7 @@ export default function handleDescriptor(target, key, desc, params = []) {
let computedDescriptor;
if (desc.writable) {
var val = extractValue(desc);
let val = extractValue(desc);
if (typeof val === "object") {
let value = {};
if (val.get) {

View File

@ -6,7 +6,7 @@ const Handlebars = require("handlebars");
const RawHandlebars = Handlebars.create();
function buildPath(blk, args) {
var result = {
let result = {
type: "PathExpression",
data: false,
depth: blk.path.depth,
@ -22,7 +22,7 @@ function buildPath(blk, args) {
}
function replaceGet(ast) {
var visitor = new Handlebars.Visitor();
let visitor = new Handlebars.Visitor();
visitor.mutating = true;
visitor.MustacheStatement = function (mustache) {
@ -42,7 +42,7 @@ function replaceGet(ast) {
// This allows us to use the same syntax in all templates
visitor.BlockStatement = function (block) {
if (block.path.original === "each" && block.params.length === 1) {
var paramName = block.program.blockParams[0];
let paramName = block.program.blockParams[0];
block.params = [
buildPath(block, { original: paramName }),
{ type: "CommentStatement", value: "in" },
@ -71,10 +71,10 @@ RawHandlebars.JavaScriptCompiler.prototype.compiler =
RawHandlebars.JavaScriptCompiler.prototype.namespace = "RawHandlebars";
RawHandlebars.precompile = function (value, asObject) {
var ast = Handlebars.parse(value);
let ast = Handlebars.parse(value);
replaceGet(ast);
var options = {
let options = {
knownHelpers: {
get: true,
},
@ -84,7 +84,7 @@ RawHandlebars.precompile = function (value, asObject) {
asObject = asObject === undefined ? true : asObject;
var environment = new RawHandlebars.Compiler().compile(ast, options);
let environment = new RawHandlebars.Compiler().compile(ast, options);
return new RawHandlebars.JavaScriptCompiler().compile(
environment,
options,
@ -94,20 +94,20 @@ RawHandlebars.precompile = function (value, asObject) {
};
RawHandlebars.compile = function (string) {
var ast = Handlebars.parse(string);
let ast = Handlebars.parse(string);
replaceGet(ast);
// this forces us to rewrite helpers
var options = { data: true, stringParams: true };
var environment = new RawHandlebars.Compiler().compile(ast, options);
var templateSpec = new RawHandlebars.JavaScriptCompiler().compile(
let options = { data: true, stringParams: true };
let environment = new RawHandlebars.Compiler().compile(ast, options);
let templateSpec = new RawHandlebars.JavaScriptCompiler().compile(
environment,
options,
undefined,
true
);
var t = RawHandlebars.template(templateSpec);
let t = RawHandlebars.template(templateSpec);
t.isMethod = false;
return t;

View File

@ -26,7 +26,8 @@ const Discourse = Application.extend({
const init = module.default;
const oldInitialize = init.initialize;
init.initialize = () => oldInitialize.call(init, this.__container__, this);
init.initialize = (app) => oldInitialize.call(init, app.__container__, app);
return init;
},

View File

@ -1,4 +1,10 @@
import Component from "@ember/component";
import { or } from "@ember/object/computed";
export default Component.extend({
classNames: "activation-controls",
canEditEmail: or(
"siteSettings.enable_local_logins",
"siteSettings.email_editable"
),
});

View File

@ -5,12 +5,12 @@ import discourseComputed from "discourse-common/utils/decorators";
// https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
function b64EncodeUnicode(str) {
return btoa(
encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function toSolidBytes(
match,
p1
) {
return String.fromCharCode("0x" + p1);
})
encodeURIComponent(str).replace(
/%([0-9A-F]{2})/g,
function toSolidBytes(match, p1) {
return String.fromCharCode("0x" + p1);
}
)
);
}

View File

@ -10,7 +10,7 @@ export default Component.extend({
@discourseComputed("topicList.loaded")
loaded() {
var topicList = this.topicList;
let topicList = this.topicList;
if (topicList) {
return topicList.get("loaded");
} else {

View File

@ -0,0 +1,57 @@
import Component from "@ember/component";
import I18n from "I18n";
import { action } from "@ember/object";
import { getOwner } from "discourse-common/lib/get-owner";
import { or } from "@ember/object/computed";
export default Component.extend({
tagName: "",
init() {
this._super(...arguments);
this.loadLocalDates();
},
get postLocalDateFormatted() {
return this.postLocalDate().format(I18n.t("dates.long_no_year"));
},
showPostLocalDate: or("postDetectedLocalDate", "postDetectedLocalTime"),
loadLocalDates() {
let postEl = document.querySelector(`[data-post-id="${this.postId}"]`);
let localDateEl = null;
if (postEl) {
localDateEl = postEl.querySelector(".discourse-local-date");
}
this.setProperties({
postDetectedLocalDate: localDateEl ? localDateEl.dataset.date : null,
postDetectedLocalTime: localDateEl ? localDateEl.dataset.time : null,
postDetectedLocalTimezone: localDateEl
? localDateEl.dataset.timezone
: null,
});
},
postLocalDate() {
const bookmarkController = getOwner(this).lookup("controller:bookmark");
let parsedPostLocalDate = bookmarkController._parseCustomDateTime(
this.postDetectedLocalDate,
this.postDetectedLocalTime,
this.postDetectedLocalTimezone
);
if (!this.postDetectedLocalTime) {
return bookmarkController.startOfDay(parsedPostLocalDate);
}
return parsedPostLocalDate;
},
@action
setReminder() {
return this.onChange(this.postLocalDate());
},
});

View File

@ -536,10 +536,10 @@ export default Component.extend({
_warnMentionedGroups($preview) {
schedule("afterRender", () => {
var found = this.warnedGroupMentions || [];
let found = this.warnedGroupMentions || [];
$preview.find(".mention-group.notify").each((idx, e) => {
const $e = $(e);
var name = $e.data("name");
let name = $e.data("name");
if (found.indexOf(name) === -1) {
this.groupsMentioned([
{

View File

@ -184,7 +184,7 @@ class Toolbar {
if (button.shortcut) {
const mac = /Mac|iPod|iPhone|iPad/.test(navigator.platform);
const mod = mac ? "Meta" : "Ctrl";
var shortcutTitle = `${mod}+${button.shortcut}`;
let shortcutTitle = `${mod}+${button.shortcut}`;
// Mac users are used to glyphs for shortcut keys
if (mac) {

View File

@ -1,3 +1,4 @@
import { computed } from "@ember/object";
import Component from "@ember/component";
import I18n from "I18n";
import afterTransition from "discourse/lib/after-transition";
@ -12,10 +13,16 @@ export default Component.extend({
"modalStyle",
"hasPanels",
],
attributeBindings: ["data-keyboard", "aria-modal"],
attributeBindings: [
"data-keyboard",
"aria-modal",
"role",
"ariaLabelledby:aria-labelledby",
],
dismissable: true,
title: null,
subtitle: null,
role: "dialog",
init() {
this._super(...arguments);
@ -33,6 +40,10 @@ export default Component.extend({
// Inform screenreaders of the modal
"aria-modal": "true",
ariaLabelledby: computed("title", function () {
return this.title ? "discourse-modal-title" : null;
}),
@on("didInsertElement")
setUp() {
$("html").on("keyup.discourse-modal", (e) => {

View File

@ -28,7 +28,7 @@ export default Component.extend({
@observes("lastShownAt")
bounce() {
if (this.lastShownAt) {
var $elem = $(this.element);
let $elem = $(this.element);
if (!this.animateAttribute) {
this.animateAttribute = $elem.css("left") === "auto" ? "right" : "left";
}
@ -51,7 +51,7 @@ export default Component.extend({
},
bounceLeft($elem) {
for (var i = 0; i < 5; i++) {
for (let i = 0; i < 5; i++) {
$elem
.animate({ left: "+=" + this.bouncePixels }, this.bounceDelay)
.animate({ left: "-=" + this.bouncePixels }, this.bounceDelay);
@ -59,7 +59,7 @@ export default Component.extend({
},
bounceRight($elem) {
for (var i = 0; i < 5; i++) {
for (let i = 0; i < 5; i++) {
$elem
.animate({ right: "-=" + this.bouncePixels }, this.bounceDelay)
.animate({ right: "+=" + this.bouncePixels }, this.bounceDelay);

View File

@ -56,7 +56,7 @@ export default Component.extend({
},
_showUrl($target, url) {
const $currentTargetOffset = $target.offset();
const currentTargetOffset = $target.offset();
const $this = $(this.element);
if (isEmpty(url)) {
@ -69,7 +69,7 @@ export default Component.extend({
}
const shareLinkWidth = $this.width();
let x = $currentTargetOffset.left - shareLinkWidth / 2;
let x = currentTargetOffset.left - shareLinkWidth / 2;
if (x < 25) {
x = 25;
}
@ -78,15 +78,18 @@ export default Component.extend({
}
const header = $(".d-header");
let y = $currentTargetOffset.top - ($this.height() + 20);
let y = currentTargetOffset.top - ($this.height() + 20);
if (y < header.offset().top + header.height()) {
y = $currentTargetOffset.top + 10;
y = currentTargetOffset.top + 10;
}
$this.css({ top: "" + y + "px" });
this.element.style.top = `${y}px`;
if (!this.site.mobileView) {
$this.css({ left: "" + x + "px" });
this.element.style.left = `${x}px`;
if (document.documentElement.classList.contains("rtl")) {
this.element.style.right = "unset";
}
}
this.set("link", url);
this.set("visible", true);

View File

@ -107,6 +107,8 @@ export default Component.extend(bufferedProperty("model"), {
this.allGroups.forEach((group) => {
if (groupIds.includes(group.id)) {
updatedPermissions[group.name] = PermissionType.FULL;
} else {
delete updatedPermissions[group.name];
}
});

View File

@ -1,13 +1,26 @@
import { reads } from "@ember/object/computed";
import Component from "@ember/component";
import { propertyEqual } from "discourse/lib/computed";
export default Component.extend({
init() {
this._super(...arguments);
this.set("elementId", `tap_tile_${this.tileId}`);
},
classNames: ["tap-tile"],
classNameBindings: ["active"],
attributeBindings: ["role", "ariaPressed", "tabIndex"],
role: "button",
tabIndex: 0,
ariaPressed: reads("active"),
click() {
this.onChange(this.tileId);
},

View File

@ -226,12 +226,6 @@ export default Component.extend({
return this.unhandledRowClick(e, topic);
},
actions: {
toggleBookmark() {
this.topic.toggleBookmark().finally(() => this.renderTopicListItem());
},
},
unhandledRowClick() {},
navigateToTopic,

View File

@ -163,9 +163,9 @@ export default Component.extend(LoadMore, {
},
click(e) {
var self = this;
var onClick = function (sel, callback) {
var target = $(e.target).closest(sel);
let self = this;
let onClick = function (sel, callback) {
let target = $(e.target).closest(sel);
if (target.length === 1) {
callback.apply(self, [target]);

View File

@ -12,7 +12,7 @@ export default Component.extend({
@discourseComputed("badge", "user")
badgeUrl() {
// NOTE: I tried using a link-to helper here but the queryParams mean it fails
var username = this.get("user.username_lower") || "";
let username = this.get("user.username_lower") || "";
username = username !== "" ? "?username=" + username : "";
return this.get("badge.url") + username;
},

View File

@ -1,5 +1,4 @@
import { REMINDER_TYPES, formattedReminderTime } from "discourse/lib/bookmark";
import { and, or } from "@ember/object/computed";
import { isEmpty, isPresent } from "@ember/utils";
import { next, schedule } from "@ember/runloop";
import { AUTO_DELETE_PREFERENCES } from "discourse/models/bookmark";
@ -10,6 +9,7 @@ import ModalFunctionality from "discourse/mixins/modal-functionality";
import { Promise } from "rsvp";
import { action } from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import { and } from "@ember/object/computed";
import bootbox from "bootbox";
import discourseComputed from "discourse-common/utils/decorators";
import { popupAjaxError } from "discourse/lib/ajax-error";
@ -62,9 +62,7 @@ export default Controller.extend(ModalFunctionality, {
customReminderTime: null,
lastCustomReminderDate: null,
lastCustomReminderTime: null,
postDetectedLocalDate: null,
postDetectedLocalTime: null,
postDetectedLocalTimezone: null,
postLocalDate: null,
mouseTrap: null,
userTimezone: null,
showOptions: false,
@ -95,6 +93,8 @@ export default Controller.extend(ModalFunctionality, {
this._initializeExistingBookmarkData();
}
this.loadLocalDates();
schedule("afterRender", () => {
if (this.site.isMobileDevice) {
document.getElementById("bookmark-name").blur();
@ -240,11 +240,6 @@ export default Controller.extend(ModalFunctionality, {
showLastCustom: and("lastCustomReminderTime", "lastCustomReminderDate"),
showPostLocalDate: or(
"model.postDetectedLocalDate",
"model.postDetectedLocalTime"
),
get showLaterToday() {
let later = this.laterToday();
return (
@ -302,8 +297,22 @@ export default Controller.extend(ModalFunctionality, {
return this.nextMonth().format(I18n.t("dates.long_no_year"));
},
get postLocalDateFormatted() {
return this.postLocalDate().format(I18n.t("dates.long_no_year"));
loadLocalDates() {
let postEl = document.querySelector(
`[data-post-id="${this.model.postId}"]`
);
let localDateEl = null;
if (postEl) {
localDateEl = postEl.querySelector(".discourse-local-date");
}
if (localDateEl) {
this.setProperties({
postDetectedLocalDate: localDateEl.dataset.date,
postDetectedLocalTime: localDateEl.dataset.time,
postDetectedLocalTimezone: localDateEl.dataset.timezone,
});
}
},
@discourseComputed("userTimezone")
@ -442,7 +451,7 @@ export default Controller.extend(ModalFunctionality, {
case REMINDER_TYPES.LAST_CUSTOM:
return this.parsedLastCustomReminderDatetime;
case REMINDER_TYPES.POST_LOCAL_DATE:
return this.postLocalDate();
return this.postLocalDate;
}
},
@ -454,20 +463,6 @@ export default Controller.extend(ModalFunctionality, {
return this.startOfDay(this.now().add(1, "month"));
},
postLocalDate() {
let parsedPostLocalDate = this._parseCustomDateTime(
this.model.postDetectedLocalDate,
this.model.postDetectedLocalTime,
this.model.postDetectedLocalTimezone
);
if (!this.model.postDetectedLocalTime) {
return this.startOfDay(parsedPostLocalDate);
}
return parsedPostLocalDate;
},
tomorrow() {
return this.startOfDay(this.now().add(1, "day"));
},
@ -572,4 +567,13 @@ export default Controller.extend(ModalFunctionality, {
return this.saveAndClose();
}
},
@action
selectPostLocalDate(date) {
this.setProperties({
selectedReminderType: this.reminderTypes.POST_LOCAL_DATE,
postLocalDate: date,
});
return this.saveAndClose();
},
});

View File

@ -727,7 +727,7 @@ export default Controller.extend({
}
}
var staged = false;
let staged = false;
// TODO: This should not happen in model
const imageSizes = {};

View File

@ -19,15 +19,6 @@ export default DiscoveryController.extend({
canEdit: reads("currentUser.staff"),
@discourseComputed("model.categories.[].featuredTopics.length")
latestTopicOnly() {
return (
this.get("model.categories").find(
(c) => c.get("featuredTopics.length") > 1
) === undefined
);
},
@discourseComputed("model.parentCategory")
categoryPageStyle(parentCategory) {
let style = this.site.mobileView

View File

@ -1,3 +1,4 @@
import { and, readOnly } from "@ember/object/computed";
import discourseComputed, { on } from "discourse-common/utils/decorators";
import Category from "discourse/models/category";
import Controller from "@ember/controller";
@ -7,7 +8,6 @@ import { NotificationLevels } from "discourse/lib/notification-levels";
import PermissionType from "discourse/models/permission-type";
import bootbox from "bootbox";
import { extractError } from "discourse/lib/ajax-error";
import { readOnly } from "@ember/object/computed";
import { underscore } from "@ember/string";
export default Controller.extend({
@ -15,11 +15,12 @@ export default Controller.extend({
saving: false,
deleting: false,
panels: null,
hiddenTooltip: true,
showTooltip: false,
createdCategory: false,
expandedMenu: false,
mobileView: readOnly("site.mobileView"),
parentParams: null,
showDeleteReason: and("showTooltip", "model.cannot_delete_reason"),
@on("init")
_initPanels() {
@ -143,7 +144,7 @@ export default Controller.extend({
},
toggleDeleteTooltip() {
this.toggleProperty("hiddenTooltip");
this.toggleProperty("showTooltip");
},
goBack() {

View File

@ -77,9 +77,9 @@ export default Controller.extend({
@discourseComputed("context", "context_id")
searchContextDescription(context, id) {
var name = id;
let name = id;
if (context === "category") {
var category = Category.findById(id);
let category = Category.findById(id);
if (!category) {
return;
}
@ -322,7 +322,7 @@ export default Controller.extend({
},
loadMore() {
var page = this.page;
let page = this.page;
if (
this.get("model.grouped_search_result.more_full_page_results") &&
!this.loading &&

View File

@ -142,13 +142,22 @@ export default Controller.extend({
destroyGroup() {
this.set("destroying", true);
const model = this.model;
let message = I18n.t("admin.groups.delete_confirm");
if (model.has_messages && model.message_count > 0) {
message = I18n.t("admin.groups.delete_with_messages_confirm", {
count: model.message_count,
});
}
bootbox.confirm(
I18n.t("admin.groups.delete_confirm"),
message,
I18n.t("no_value"),
I18n.t("yes_value"),
(confirmed) => {
if (confirmed) {
this.model
model
.destroy()
.then(() => this.transitionToRoute("groups.index"))
.catch((error) => {

View File

@ -17,7 +17,7 @@ import { sanitizeAsync } from "discourse/lib/text";
function customTagArray(fieldName) {
return computed(fieldName, function () {
var val = this.get(fieldName);
let val = this.get(fieldName);
if (!val) {
return val;
}
@ -194,7 +194,7 @@ export default Controller.extend(ModalFunctionality, {
if (displayingInline) {
return this.isEitherRevisionHidden ? "hidden-revision-either" : null;
} else {
var result = [];
let result = [];
if (prevHidden) {
result.push("hidden-revision-previous");
}
@ -227,7 +227,7 @@ export default Controller.extend(ModalFunctionality, {
@discourseComputed("model.category_id_changes")
previousCategory(changes) {
if (changes) {
var category = Category.findById(changes["previous"]);
let category = Category.findById(changes["previous"]);
return categoryBadgeHTML(category, { allowUncategorized: true });
}
},
@ -235,7 +235,7 @@ export default Controller.extend(ModalFunctionality, {
@discourseComputed("model.category_id_changes")
currentCategory(changes) {
if (changes) {
var category = Category.findById(changes["current"]);
let category = Category.findById(changes["current"]);
return categoryBadgeHTML(category, { allowUncategorized: true });
}
},

View File

@ -403,6 +403,8 @@ export default Controller.extend(ModalFunctionality, {
skipConfirmation,
});
showModal("createAccount", { modalClass: "create-account" });
next(() => {
showModal("createAccount", { modalClass: "create-account" });
});
},
});

View File

@ -62,7 +62,7 @@ export default Controller.extend({
@discourseComputed()
frequencyEstimate() {
var estimate = this.get("model.mailing_list_posts_per_day");
let estimate = this.get("model.mailing_list_posts_per_day");
if (!estimate || estimate < 2) {
return I18n.t("user.mailing_list_mode.few_per_day");
} else {

View File

@ -153,7 +153,7 @@ export default Controller.extend({
"themeId"
)
currentSchemeCanBeSelected(userThemes, userColorSchemes, themeId) {
if (!userThemes) {
if (!userThemes || !themeId) {
return false;
}

View File

@ -15,7 +15,7 @@ export default Controller.extend(ModalFunctionality, Evented, {
this.categoriesSorting = ["position"];
},
@discourseComputed("site.categories")
@discourseComputed("site.categories.[]")
categoriesBuffered(categories) {
const bufProxy = EmberObjectProxy.extend(BufferedProxy);
return categories.map((c) => bufProxy.create({ content: c }));

View File

@ -72,7 +72,7 @@ export default Controller.extend({
}
const joinedTags = tags.slice(0, displayN).join(", ");
var more = Math.max(0, tags.length - displayN);
let more = Math.max(0, tags.length - displayN);
const tagsString =
more === 0

View File

@ -702,9 +702,9 @@ export default Controller.extend(bufferedProperty("model"), {
if (!this.currentUser) {
return bootbox.alert(I18n.t("bookmarks.not_bookmarked"));
} else if (post) {
return post.toggleBookmark();
return this._togglePostBookmark(post);
} else {
return this.model.toggleBookmark().then((changedIds) => {
return this._toggleTopicBookmark(this.model).then((changedIds) => {
if (!changedIds) {
return;
}
@ -1167,6 +1167,107 @@ export default Controller.extend(bufferedProperty("model"), {
}
},
_togglePostBookmark(post) {
return new Promise((resolve) => {
let modalController = showModal("bookmark", {
model: {
postId: post.id,
id: post.bookmark_id,
reminderAt: post.bookmark_reminder_at,
autoDeletePreference: post.bookmark_auto_delete_preference,
name: post.bookmark_name,
},
title: post.bookmark_id
? "post.bookmarks.edit"
: "post.bookmarks.create",
modalClass: "bookmark-with-reminder",
});
modalController.setProperties({
onCloseWithoutSaving: () => {
resolve({ closedWithoutSaving: true });
post.appEvents.trigger("post-stream:refresh", { id: post.id });
},
afterSave: (savedData) => {
post.createBookmark(savedData);
resolve({ closedWithoutSaving: false });
},
afterDelete: (topicBookmarked) => {
post.deleteBookmark(topicBookmarked);
},
});
});
},
_toggleTopicBookmark() {
if (this.model.bookmarking) {
return Promise.resolve();
}
this.model.set("bookmarking", true);
const bookmark = !this.model.bookmarked;
let posts = this.model.postStream.posts;
return this.model.firstPost().then((firstPost) => {
const toggleBookmarkOnServer = () => {
if (bookmark) {
return this._togglePostBookmark(firstPost).then((opts) => {
this.model.set("bookmarking", false);
if (opts && opts.closedWithoutSaving) {
return;
}
return this.model.afterTopicBookmarked(firstPost);
});
} else {
return this.model
.deleteBookmark()
.then(() => {
this.model.toggleProperty("bookmarked");
this.model.set("bookmark_reminder_at", null);
let clearedBookmarkProps = {
bookmarked: false,
bookmark_id: null,
bookmark_name: null,
bookmark_reminder_at: null,
};
if (posts) {
const updated = [];
posts.forEach((post) => {
if (post.bookmarked) {
post.setProperties(clearedBookmarkProps);
updated.push(post.id);
}
});
firstPost.setProperties(clearedBookmarkProps);
return updated;
}
})
.catch(popupAjaxError)
.finally(() => this.model.set("bookmarking", false));
}
};
const unbookmarkedPosts = [];
if (!bookmark && posts) {
posts.forEach(
(post) => post.bookmarked && unbookmarkedPosts.push(post)
);
}
return new Promise((resolve) => {
if (unbookmarkedPosts.length > 1) {
bootbox.confirm(
I18n.t("bookmarks.confirm_clear"),
I18n.t("no_value"),
I18n.t("yes_value"),
(confirmed) =>
confirmed ? toggleBookmarkOnServer().then(resolve) : resolve()
);
} else {
toggleBookmarkOnServer().then(resolve);
}
});
});
},
togglePinnedState() {
this.send("togglePinnedForUser");
},

View File

@ -16,7 +16,7 @@ export default Controller.extend({
@observes("userActionType", "model.stream.itemsLoaded")
_showFooter: function () {
var showFooter;
let showFooter;
if (this.userActionType) {
const stat = (this.get("model.stats") || []).find(
(s) => s.action_type === this.userActionType

View File

@ -40,7 +40,7 @@ export default Controller.extend({
bulkOperation(operation) {
const selected = this.selected;
var params = { type: operation };
let params = { type: operation };
if (this.isGroup) {
params.group = this.groupFilter;
}

View File

@ -3,7 +3,11 @@ import EmberObject, { computed, set } from "@ember/object";
import { alias, and, gt, not, or } from "@ember/object/computed";
import CanCheckEmails from "discourse/mixins/can-check-emails";
import User from "discourse/models/user";
import I18n from "I18n";
import bootbox from "bootbox";
import discourseComputed from "discourse-common/utils/decorators";
import getURL from "discourse-common/lib/get-url";
import { iconHTML } from "discourse-common/lib/icon-library";
import { isEmpty } from "@ember/utils";
import optionalService from "discourse/lib/optional-service";
import { prioritizeNameInUx } from "discourse/lib/settings";
@ -168,7 +172,57 @@ export default Controller.extend(CanCheckEmails, {
},
adminDelete() {
this.adminTools.deleteUser(this.get("model.id"));
const userId = this.get("model.id");
const message = I18n.t("admin.user.delete_confirm");
const location = document.location.pathname;
const performDestroy = (block) => {
bootbox.dialog(I18n.t("admin.user.deleting_user"));
let formData = { context: location };
if (block) {
formData["block_email"] = true;
formData["block_urls"] = true;
formData["block_ip"] = true;
}
formData["delete_posts"] = true;
this.adminTools
.deleteUser(userId, formData)
.then((data) => {
if (data.deleted) {
document.location = getURL("/admin/users/list/active");
} else {
bootbox.alert(I18n.t("admin.user.delete_failed"));
}
})
.catch(() => bootbox.alert(I18n.t("admin.user.delete_failed")));
};
const buttons = [
{
label: I18n.t("composer.cancel"),
class: "btn",
link: true,
},
{
label:
`${iconHTML("exclamation-triangle")} ` +
I18n.t("admin.user.delete_and_block"),
class: "btn btn-danger",
callback: function () {
performDestroy(true);
},
},
{
label: I18n.t("admin.user.delete_dont_block"),
class: "btn btn-primary",
callback: function () {
performDestroy(false);
},
},
];
bootbox.dialog(message, buttons, { classes: "delete-user-modal" });
},
updateNotificationLevel(level) {

View File

@ -16,7 +16,7 @@ export function replaceCategoryLinkRenderer(fn) {
}
function categoryStripe(color, classes) {
var style = color ? "style='background-color: #" + color + ";'" : "";
let style = color ? "style='background-color: #" + color + ";'" : "";
return "<span class='" + classes + "' " + style + "></span>";
}
@ -65,7 +65,7 @@ export function categoryBadgeHTML(category, opts) {
}
export function categoryLinkHTML(category, options) {
var categoryOptions = {};
let categoryOptions = {};
// TODO: This is a compatibility layer with the old helper structure.
// Can be removed once we migrate to `registerUnbound` fully

View File

@ -7,7 +7,7 @@ import { registerUnbound } from "discourse-common/lib/helpers";
update the dates on a regular interval.
**/
registerUnbound("format-date", function (val, params) {
var leaveAgo,
let leaveAgo,
format = "medium",
title = true;
@ -22,7 +22,7 @@ registerUnbound("format-date", function (val, params) {
}
if (val) {
var date = new Date(val);
let date = new Date(val);
return htmlSafe(
autoUpdatingRelativeAge(date, {
format: format,

View File

@ -1,13 +1,13 @@
import { htmlHelper } from "discourse-common/lib/helpers";
function renderSpinner(cssClass) {
var html = "<div class='spinner";
let html = "<div class='spinner";
if (cssClass) {
html += " " + cssClass;
}
return html + "'></div>";
}
var spinnerHTML = renderSpinner();
let spinnerHTML = renderSpinner();
export default htmlHelper((params) => {
const hash = params.hash;

View File

@ -1,7 +1,7 @@
import { registerUnbound } from "discourse-common/lib/helpers";
registerUnbound("shorten-url", function (url) {
var matches = url.match(/\//g);
let matches = url.match(/\//g);
if (matches && matches.length === 3) {
url = url.replace(/\/$/, "");

View File

@ -1,6 +1,9 @@
// backwards compatibility for plugins that depend on this initializer
import { setDefaultOwner } from "discourse-common/lib/get-owner";
export default {
name: "inject-objects",
initialize() {},
initialize(container, app) {
// This is required for Ember CLI tests to work
setDefaultOwner(app.__container__);
},
};

View File

@ -4,7 +4,7 @@
SO: http://stackoverflow.com/questions/9943435/css3-animation-end-techniques
**/
var dummy = document.createElement("div"),
let dummy = document.createElement("div"),
eventNameHash = {
webkit: "webkitTransitionEnd",
Moz: "transitionend",
@ -12,8 +12,8 @@ var dummy = document.createElement("div"),
ms: "MSTransitionEnd",
};
var transitionEnd = (function () {
var retValue;
let transitionEnd = (function () {
let retValue;
retValue = "transitionend";
Object.keys(eventNameHash).some(function (vendor) {
if (vendor + "TransitionProperty" in dummy.style) {

View File

@ -15,8 +15,8 @@ export function replaceSpan($elem, categorySlug, categoryLink, type) {
export function categoryHashtagTriggerRule(textarea, opts) {
const result = caretRowCol(textarea);
const row = result.rowNum;
var col = result.colNum;
var line = textarea.value.split("\n")[row - 1];
let col = result.colNum;
let line = textarea.value.split("\n")[row - 1];
if (opts && opts.backSpace) {
col = col - 1;

View File

@ -37,7 +37,7 @@ function searchTags(term, categories, limit) {
data: { limit: limit, q },
});
var returnVal = CANCELLED_STATUS;
let returnVal = CANCELLED_STATUS;
oldSearch
.then((r) => {
@ -91,8 +91,8 @@ export function search(term, siteSettings) {
}
const limit = 5;
var categories = Category.search(term, { limit });
var numOfCategories = categories.length;
let categories = Category.search(term, { limit });
let numOfCategories = categories.length;
categories = categories.map((category) => {
return { model: category, text: Category.slugFor(category, SEPARATOR, 2) };

View File

@ -27,7 +27,7 @@ const Mobile = {
localStorage.removeItem("mobileView");
}
if (localStorage.mobileView) {
var savedValue = localStorage.mobileView === "true";
let savedValue = localStorage.mobileView === "true";
if (savedValue !== this.mobileView) {
this.reloadPage(savedValue);
}

View File

@ -1,5 +1,5 @@
// for android we test webkit
var hiddenProperty =
let hiddenProperty =
document.hidden !== undefined
? "hidden"
: document.webkitHidden !== undefined

View File

@ -737,10 +737,10 @@ class PluginApi {
* example:
*
* api.addUserMenuGlyph({
* label: 'awesome.label',
* title: 'awesome.label',
* className: 'my-class',
* icon: 'my-icon',
* href: `/some/path`
* data: { url: `/some/path` },
* });
*
*/
@ -1227,11 +1227,11 @@ let _pluginv01;
// from http://stackoverflow.com/questions/6832596/how-to-compare-software-version-number-using-js-only-number
function cmpVersions(a, b) {
var i, diff;
var regExStrip0 = /(\.0+)+$/;
var segmentsA = a.replace(regExStrip0, "").split(".");
var segmentsB = b.replace(regExStrip0, "").split(".");
var l = Math.min(segmentsA.length, segmentsB.length);
let i, diff;
let regExStrip0 = /(\.0+)+$/;
let segmentsA = a.replace(regExStrip0, "").split(".");
let segmentsB = b.replace(regExStrip0, "").split(".");
let l = Math.min(segmentsA.length, segmentsB.length);
for (i = 0; i < l; i++) {
diff = parseInt(segmentsA[i], 10) - parseInt(segmentsB[i], 10);

View File

@ -93,7 +93,7 @@ function positioningWorkaround($fixedElement) {
const fixedElement = $fixedElement[0];
const oldHeight = fixedElement.style.height;
var originalScrollTop = 0;
let originalScrollTop = 0;
let lastTouchedElement = null;
positioningWorkaround.blur = function (evt) {
@ -114,7 +114,7 @@ function positioningWorkaround($fixedElement) {
}
};
var blurredNow = function (evt) {
let blurredNow = function (evt) {
// we cannot use evt.relatedTarget to get the last focused element in safari iOS
// document.activeElement is also unreliable (iOS does not mark buttons as focused)
// so instead, we store the last touched element and check against it
@ -145,11 +145,11 @@ function positioningWorkaround($fixedElement) {
positioningWorkaround.blur(evt);
};
var blurred = function (evt) {
let blurred = function (evt) {
discourseDebounce(this, blurredNow, evt, INPUT_DELAY);
};
var positioningHack = function (evt) {
let positioningHack = function (evt) {
let _this = this;
if (evt === undefined) {
@ -203,7 +203,7 @@ function positioningWorkaround($fixedElement) {
}, delay);
};
var lastTouched = function (evt) {
let lastTouched = function (evt) {
if (evt && evt.target) {
lastTouchedElement = evt.target;
}
@ -231,7 +231,7 @@ function positioningWorkaround($fixedElement) {
};
positioningWorkaround.touchstartEvent = function (element) {
var triggerHack = positioningHack.bind(element);
let triggerHack = positioningHack.bind(element);
triggerHack();
};

View File

@ -29,3 +29,7 @@ export function siteDir() {
}
return _siteDir;
}
export function isDocumentRTL() {
return siteDir() === "rtl";
}

View File

@ -6,7 +6,7 @@ import { emailValid } from "discourse/lib/utilities";
import { isTesting } from "discourse-common/config/environment";
import { userPath } from "discourse/lib/url";
var cache = {},
let cache = {},
cacheKey,
cacheTime,
currentTerm,
@ -23,7 +23,7 @@ function performSearch(
groupMembersOf,
resultsFn
) {
var cached = cache[term];
let cached = cache[term];
if (cached) {
resultsFn(cached);
return;
@ -52,7 +52,7 @@ function performSearch(
},
});
var returnVal = CANCELLED_STATUS;
let returnVal = CANCELLED_STATUS;
oldSearch
.then(function (r) {
@ -81,7 +81,7 @@ function performSearch(
});
}
var debouncedSearch = function (
let debouncedSearch = function (
term,
topicId,
categoryId,
@ -113,7 +113,7 @@ function organizeResults(r, options) {
return r;
}
var exclude = options.exclude || [],
let exclude = options.exclude || [],
limit = options.limit || 5,
users = [],
emails = [],
@ -182,7 +182,7 @@ export default function userSearch(options) {
options.term = options.term.substring(1);
}
var term = options.term || "",
let term = options.term || "",
includeGroups = options.includeGroups,
includeMentionableGroups = options.includeMentionableGroups,
includeMessageableGroups = options.includeMessageableGroups,

View File

@ -97,7 +97,7 @@ export function tinyAvatar(avatarTemplate, options) {
}
export function postUrl(slug, topicId, postNumber) {
var url = getURL("/t/");
let url = getURL("/t/");
if (slug) {
url += slug + "/";
} else {
@ -190,11 +190,11 @@ export function selectedElement() {
// Determine the row and col of the caret in an element
export function caretRowCol(el) {
var cp = caretPosition(el);
var rows = el.value.slice(0, cp).split("\n");
var rowNum = rows.length;
let cp = caretPosition(el);
let rows = el.value.slice(0, cp).split("\n");
let rowNum = rows.length;
var colNum =
let colNum =
cp -
rows.splice(0, rowNum - 1).reduce(function (sum, row) {
return sum + row.length + 1;
@ -205,7 +205,7 @@ export function caretRowCol(el) {
// Determine the position of the caret in an element
export function caretPosition(el) {
var r, rc, re;
let r, rc, re;
if (el.selectionStart) {
return el.selectionStart;
}
@ -227,7 +227,7 @@ export function caretPosition(el) {
// Set the caret's position
export function setCaretPosition(ctrl, pos) {
var range;
let range;
if (ctrl.setSelectionRange) {
ctrl.focus();
ctrl.setSelectionRange(pos, pos);
@ -421,7 +421,7 @@ export function areCookiesEnabled() {
// see: https://github.com/Modernizr/Modernizr/blob/400db4043c22af98d46e1d2b9cbc5cb062791192/feature-detects/cookies.js
try {
document.cookie = "cookietest=1";
var ret = document.cookie.indexOf("cookietest=") !== -1;
let ret = document.cookie.indexOf("cookietest=") !== -1;
document.cookie = "cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT";
return ret;
} catch (e) {

View File

@ -113,7 +113,7 @@ export function mapRoutes() {
// can define admin routes.
Object.keys(requirejs._eak_seen).forEach(function (key) {
if (/route-map$/.test(key)) {
var module = requirejs(key, null, null, true);
let module = requirejs(key, null, null, true);
if (!module || !module.default) {
throw new Error(key + " must export a route map.");
}

View File

@ -3,8 +3,11 @@ import { NotificationLevels } from "discourse/lib/notification-levels";
import Topic from "discourse/models/topic";
import { alias } from "@ember/object/computed";
import { on } from "discourse-common/utils/decorators";
import { inject as service } from "@ember/service";
export default Mixin.create({
router: service(),
bulkSelectEnabled: false,
selected: null,

View File

@ -67,7 +67,7 @@ const Singleton = Mixin.create({
// Returns OR sets a property on the singleton instance.
currentProp(property, value) {
var instance = this.current();
let instance = this.current();
if (!instance) {
return;
}

View File

@ -312,7 +312,7 @@ const Category = RestModel.extend({
},
});
var _uncategorized;
let _uncategorized;
Category.reopenClass({
slugEncoded() {
@ -508,7 +508,7 @@ Category.reopenClass({
},
search(term, opts) {
var limit = 5;
let limit = 5;
if (opts) {
if (opts.limit === 0) {
@ -529,8 +529,8 @@ Category.reopenClass({
const categories = Category.listByActivity();
const length = categories.length;
var i;
var data = [];
let i;
let data = [];
const done = () => {
return data.length === limit;

View File

@ -177,7 +177,7 @@ NavItem.reopenClass({
return null;
}
var args = { name: filterType, hasIcon: filterType === "unread" };
let args = { name: filterType, hasIcon: filterType === "unread" };
if (opts.category) {
args.category = opts.category;
}

View File

@ -16,7 +16,6 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
import { postUrl } from "discourse/lib/utilities";
import { propertyEqual } from "discourse/lib/computed";
import { resolveShareUrl } from "discourse/helpers/share-url";
import showModal from "discourse/lib/show-modal";
import { userPath } from "discourse/lib/url";
const Post = RestModel.extend({
@ -304,58 +303,24 @@ const Post = RestModel.extend({
return ajax(`/posts/${this.id}/unhide`, { type: "PUT" });
},
toggleBookmark() {
let postEl = document.querySelector(`[data-post-id="${this.id}"]`);
let localDateEl = null;
if (postEl) {
localDateEl = postEl.querySelector(".discourse-local-date");
}
return new Promise((resolve) => {
let controller = showModal("bookmark", {
model: {
postId: this.id,
id: this.bookmark_id,
reminderAt: this.bookmark_reminder_at,
autoDeletePreference: this.bookmark_auto_delete_preference,
name: this.bookmark_name,
postDetectedLocalDate: localDateEl ? localDateEl.dataset.date : null,
postDetectedLocalTime: localDateEl ? localDateEl.dataset.time : null,
postDetectedLocalTimezone: localDateEl
? localDateEl.dataset.timezone
: null,
},
title: this.bookmark_id
? "post.bookmarks.edit"
: "post.bookmarks.create",
modalClass: "bookmark-with-reminder",
});
controller.setProperties({
onCloseWithoutSaving: () => {
resolve({ closedWithoutSaving: true });
this.appEvents.trigger("post-stream:refresh", { id: this.id });
},
afterSave: (savedData) => {
this.setProperties({
"topic.bookmarked": true,
bookmarked: true,
bookmark_reminder_at: savedData.reminderAt,
bookmark_reminder_type: savedData.reminderType,
bookmark_auto_delete_preference: savedData.autoDeletePreference,
bookmark_name: savedData.name,
bookmark_id: savedData.id,
});
resolve({ closedWithoutSaving: false });
this.appEvents.trigger("page:bookmark-post-toggled", this);
this.appEvents.trigger("post-stream:refresh", { id: this.id });
},
afterDelete: (topicBookmarked) => {
this.set("topic.bookmarked", topicBookmarked);
this.clearBookmark();
this.appEvents.trigger("page:bookmark-post-toggled", this);
},
});
createBookmark(data) {
this.setProperties({
"topic.bookmarked": true,
bookmarked: true,
bookmark_reminder_at: data.reminderAt,
bookmark_reminder_type: data.reminderType,
bookmark_auto_delete_preference: data.autoDeletePreference,
bookmark_name: data.name,
bookmark_id: data.id,
});
this.appEvents.trigger("page:bookmark-post-toggled", this);
this.appEvents.trigger("post-stream:refresh", { id: this.id });
},
deleteBookmark(bookmarked) {
this.set("topic.bookmarked", bookmarked);
this.clearBookmark();
this.appEvents.trigger("page:bookmark-post-toggled", this);
},
clearBookmark() {

View File

@ -114,9 +114,9 @@ export default EmberObject.extend({
},
find(type, findArgs, opts) {
var adapter = this.adapterFor(type);
let adapter = this.adapterFor(type);
return adapter.find(this, type, findArgs, opts).then((result) => {
var hydrated = this._hydrateFindResults(result, type, findArgs, opts);
let hydrated = this._hydrateFindResults(result, type, findArgs, opts);
if (result.extras) {
hydrated.set("extras", result.extras);
@ -139,7 +139,7 @@ export default EmberObject.extend({
hydrated.set(
"content",
hydrated.get("content").map((item) => {
var staleItem = stale.content.findBy(primaryKey, item.get(primaryKey));
let staleItem = stale.content.findBy(primaryKey, item.get(primaryKey));
if (staleItem) {
staleItem.setProperties(item);
} else {

View File

@ -291,7 +291,7 @@ const TopicTrackingState = EmberObject.extend({
if (split.length >= 4) {
filter = split[split.length - 1];
// c/cat/subcat/6/l/latest
var category = Category.findSingleBySlug(
let category = Category.findSingleBySlug(
split.splice(1, split.length - 4).join("/")
);
this.set("filterCategory", category);

View File

@ -11,7 +11,6 @@ import Session from "discourse/models/session";
import Site from "discourse/models/site";
import User from "discourse/models/user";
import { ajax } from "discourse/lib/ajax";
import bootbox from "bootbox";
import { deepMerge } from "discourse-common/lib/object";
import discourseComputed from "discourse-common/utils/decorators";
import { emojiUnescape } from "discourse/lib/text";
@ -404,73 +403,8 @@ const Topic = RestModel.extend({
}
},
toggleBookmark() {
if (this.bookmarking) {
return Promise.resolve();
}
this.set("bookmarking", true);
const bookmark = !this.bookmarked;
let posts = this.postStream.posts;
return this.firstPost().then((firstPost) => {
const toggleBookmarkOnServer = () => {
if (bookmark) {
return firstPost.toggleBookmark().then((opts) => {
this.set("bookmarking", false);
if (opts.closedWithoutSaving) {
return;
}
return this.afterTopicBookmarked(firstPost);
});
} else {
return ajax(`/t/${this.id}/remove_bookmarks`, { type: "PUT" })
.then(() => {
this.toggleProperty("bookmarked");
this.set("bookmark_reminder_at", null);
let clearedBookmarkProps = {
bookmarked: false,
bookmark_id: null,
bookmark_name: null,
bookmark_reminder_at: null,
};
if (posts) {
const updated = [];
posts.forEach((post) => {
if (post.bookmarked) {
post.setProperties(clearedBookmarkProps);
updated.push(post.id);
}
});
firstPost.setProperties(clearedBookmarkProps);
return updated;
}
})
.catch(popupAjaxError)
.finally(() => this.set("bookmarking", false));
}
};
const unbookmarkedPosts = [];
if (!bookmark && posts) {
posts.forEach(
(post) => post.bookmarked && unbookmarkedPosts.push(post)
);
}
return new Promise((resolve) => {
if (unbookmarkedPosts.length > 1) {
bootbox.confirm(
I18n.t("bookmarks.confirm_clear"),
I18n.t("no_value"),
I18n.t("yes_value"),
(confirmed) =>
confirmed ? toggleBookmarkOnServer().then(resolve) : resolve()
);
} else {
toggleBookmarkOnServer().then(resolve);
}
});
});
deleteBookmark() {
return ajax(`/t/${this.id}/remove_bookmarks`, { type: "PUT" });
},
createGroupInvite(group) {

View File

@ -27,7 +27,7 @@ UserBadge.reopenClass({
if (json.users === undefined) {
json.users = [];
}
var users = {};
let users = {};
json.users.forEach(function (userJson) {
users[userJson.id] = User.create(userJson);
});
@ -36,7 +36,7 @@ UserBadge.reopenClass({
if (json.topics === undefined) {
json.topics = [];
}
var topics = {};
let topics = {};
json.topics.forEach(function (topicJson) {
topics[topicJson.id] = Topic.create(topicJson);
});
@ -45,13 +45,13 @@ UserBadge.reopenClass({
if (json.badges === undefined) {
json.badges = [];
}
var badges = {};
let badges = {};
Badge.createFromJson(json).forEach(function (badge) {
badges[badge.get("id")] = badge;
});
// Create UserBadge object(s).
var userBadges = [];
let userBadges = [];
if ("user_badge" in json) {
userBadges = [json.user_badge];
} else {
@ -61,9 +61,9 @@ UserBadge.reopenClass({
}
userBadges = userBadges.map(function (userBadgeJson) {
var userBadge = UserBadge.create(userBadgeJson);
let userBadge = UserBadge.create(userBadgeJson);
var grantedAtDate = Date.parse(userBadge.get("granted_at"));
let grantedAtDate = Date.parse(userBadge.get("granted_at"));
userBadge.set("grantedAt", grantedAtDate);
userBadge.set("badge", badges[userBadge.get("badge_id")]);
@ -102,7 +102,7 @@ UserBadge.reopenClass({
if (!username) {
return Promise.resolve([]);
}
var url = "/user-badges/" + username + ".json";
let url = "/user-badges/" + username + ".json";
if (options && options.grouped) {
url += "?grouped=true";
}

View File

@ -342,7 +342,7 @@ const User = RestModel.extend({
data[s] = this.get(`user_option.${s}`);
});
var updatedState = {};
let updatedState = {};
["muted", "regular", "watched", "tracked", "watched_first_post"].forEach(
(s) => {

View File

@ -1,5 +1,5 @@
import Application from "@ember/application";
import Ember from "ember";
import { isLegacyEmber } from "discourse-common/config/environment";
import { registerRouter } from "discourse/mapping-router";
let originalBuildInstance;
@ -12,8 +12,7 @@ export default {
let router = registerRouter(app);
container.registry.register("router:main", router);
// TODO: Remove this once we've upgraded Ember everywhere
if (Ember.VERSION.startsWith("3.12")) {
if (isLegacyEmber()) {
// HACK to fix: https://github.com/emberjs/ember.js/issues/10310
originalBuildInstance =
originalBuildInstance || Application.prototype.buildInstance;

View File

@ -3,8 +3,8 @@ export default {
initialize: function () {
$('script[type="text/x-handlebars"]').each(function () {
var $this = $(this);
var name = $this.attr("name") || $this.data("template-name");
let $this = $(this);
let name = $this.attr("name") || $this.data("template-name");
if (window.console) {
window.console.log(

View File

@ -157,7 +157,7 @@ export default (filterArg, params) => {
canCreateTopic: canCreateTopic,
});
var topicOpts = {
let topicOpts = {
model: topics,
category,
period:

View File

@ -13,6 +13,7 @@ export default DiscourseRoute.extend({
controller.setProperties({
parentParams,
selectedTab: transition.to.params.tab,
showTooltip: false,
});
},
});

View File

@ -30,7 +30,7 @@ export default DiscourseRoute.extend({
model(params) {
const cached = getTransient("lastSearch");
var args = { q: params.q };
let args = { q: params.q };
if (params.context_id && !args.skip_context) {
args.search_context = {
type: params.context,

Some files were not shown because too many files have changed in this diff Show More