DEV: reduces memory footprint of tests - step 1 (#7591)

This commit is contained in:
Joffrey JAFFEUX
2019-05-28 12:15:12 +02:00
committed by GitHub
parent 07b80d491b
commit 6decdfce5c
41 changed files with 655 additions and 430 deletions

View File

@ -1,5 +1,10 @@
export default Ember.Controller.extend({ export default Ember.Controller.extend({
logs: [],
adminBackups: Ember.inject.controller(), adminBackups: Ember.inject.controller(),
status: Ember.computed.alias("adminBackups.model") status: Ember.computed.alias("adminBackups.model"),
init() {
this._super(...arguments);
this.logs = [];
}
}); });

View File

@ -1,6 +1,10 @@
export default Ember.Controller.extend({ export default Ember.Controller.extend({
titleSorting: ["title"],
emailTemplates: null, emailTemplates: null,
sortedTemplates: Ember.computed.sort("emailTemplates", "titleSorting"),
sortedTemplates: Ember.computed.sort("emailTemplates", "titleSorting") init() {
this._super(...arguments);
this.titleSorting = ["title"];
}
}); });

View File

@ -1,7 +1,12 @@
import { ajax } from "discourse/lib/ajax"; import { ajax } from "discourse/lib/ajax";
export default Ember.Controller.extend({ export default Ember.Controller.extend({
sortedEmojis: Ember.computed.sort("model", "emojiSorting"), sortedEmojis: Ember.computed.sort("model", "emojiSorting"),
emojiSorting: ["name"],
init() {
this._super(...arguments);
this.emojiSorting = ["name"];
},
actions: { actions: {
emojiUploaded(emoji) { emojiUploaded(emoji) {

View File

@ -6,10 +6,14 @@ import computed from "ember-addons/ember-computed-decorators";
export default Ember.Controller.extend({ export default Ember.Controller.extend({
loading: false, loading: false,
filters: null, filters: null,
userHistoryActions: [],
filtersExists: Ember.computed.gt("filterCount", 0), filtersExists: Ember.computed.gt("filterCount", 0),
init() {
this._super(...arguments);
this.userHistoryActions = [];
},
filterActionIdChanged: function() { filterActionIdChanged: function() {
const filterActionId = this.filterActionId; const filterActionId = this.filterActionId;
if (filterActionId) { if (filterActionId) {

View File

@ -5,12 +5,19 @@ export default Ember.Controller.extend({
period: DEFAULT_PERIOD, period: DEFAULT_PERIOD,
searchType: "all", searchType: "all",
searchTypeOptions: [ init() {
this._super(...arguments);
this.searchTypeOptions = [
{ {
id: "all", id: "all",
name: I18n.t("admin.logs.search_logs.types.all_search_types") name: I18n.t("admin.logs.search_logs.types.all_search_types")
}, },
{ id: "header", name: I18n.t("admin.logs.search_logs.types.header") }, { id: "header", name: I18n.t("admin.logs.search_logs.types.header") },
{ id: "full_page", name: I18n.t("admin.logs.search_logs.types.full_page") } {
] id: "full_page",
name: I18n.t("admin.logs.search_logs.types.full_page")
}
];
}
}); });

View File

@ -6,16 +6,23 @@ export default Ember.Controller.extend({
period: DEFAULT_PERIOD, period: DEFAULT_PERIOD,
searchType: "all", searchType: "all",
searchTypeOptions: [ init() {
this._super(...arguments);
this.searchTypeOptions = [
{ {
id: "all", id: "all",
name: I18n.t("admin.logs.search_logs.types.all_search_types") name: I18n.t("admin.logs.search_logs.types.all_search_types")
}, },
{ id: "header", name: I18n.t("admin.logs.search_logs.types.header") }, { id: "header", name: I18n.t("admin.logs.search_logs.types.header") },
{ id: "full_page", name: I18n.t("admin.logs.search_logs.types.full_page") }, {
id: "full_page",
name: I18n.t("admin.logs.search_logs.types.full_page")
},
{ {
id: "click_through_only", id: "click_through_only",
name: I18n.t("admin.logs.search_logs.types.click_through_only") name: I18n.t("admin.logs.search_logs.types.click_through_only")
} }
] ];
}
}); });

View File

@ -7,9 +7,13 @@ export default Ember.Controller.extend(GrantBadgeController, {
user: Ember.computed.alias("adminUser.model"), user: Ember.computed.alias("adminUser.model"),
userBadges: Ember.computed.alias("model"), userBadges: Ember.computed.alias("model"),
allBadges: Ember.computed.alias("badges"), allBadges: Ember.computed.alias("badges"),
sortedBadges: Ember.computed.sort("model", "badgeSortOrder"), sortedBadges: Ember.computed.sort("model", "badgeSortOrder"),
badgeSortOrder: ["granted_at:desc"],
init() {
this._super(...arguments);
this.badgeSortOrder = ["granted_at:desc"];
},
@computed("model", "model.[]", "model.expandedBadges.[]") @computed("model", "model.[]", "model.expandedBadges.[]")
groupedBadges() { groupedBadges() {

View File

@ -5,10 +5,14 @@ const MAX_FIELDS = 20;
export default Ember.Controller.extend({ export default Ember.Controller.extend({
fieldTypes: null, fieldTypes: null,
createDisabled: Ember.computed.gte("model.length", MAX_FIELDS), createDisabled: Ember.computed.gte("model.length", MAX_FIELDS),
fieldSortOrder: ["position"],
sortedFields: Ember.computed.sort("model", "fieldSortOrder"), sortedFields: Ember.computed.sort("model", "fieldSortOrder"),
init() {
this._super(...arguments);
this.fieldSortOrder = ["position"];
},
actions: { actions: {
createField() { createField() {
const f = this.store.createRecord("user-field", { const f = this.store.createRecord("user-field", {

View File

@ -4,9 +4,14 @@ import computed from "ember-addons/ember-computed-decorators";
export default Ember.Controller.extend({ export default Ember.Controller.extend({
pingDisabled: false, pingDisabled: false,
incomingEventIds: [],
incomingCount: Ember.computed.alias("incomingEventIds.length"), incomingCount: Ember.computed.alias("incomingEventIds.length"),
init() {
this._super(...arguments);
this.incomingEventIds = [];
},
@computed("incomingCount") @computed("incomingCount")
hasIncoming(incomingCount) { hasIncoming(incomingCount) {
return incomingCount > 0; return incomingCount > 0;

View File

@ -121,13 +121,18 @@ export default Ember.Controller.extend(ModalFunctionality, {
urlPlaceholder: "https://github.com/discourse/sample_theme", urlPlaceholder: "https://github.com/discourse/sample_theme",
advancedVisible: false, advancedVisible: false,
themesController: Ember.inject.controller("adminCustomizeThemes"), themesController: Ember.inject.controller("adminCustomizeThemes"),
createTypes: [
{ name: I18n.t("admin.customize.theme.theme"), value: THEMES },
{ name: I18n.t("admin.customize.theme.component"), value: COMPONENTS }
],
selectedType: Ember.computed.alias("themesController.currentTab"), selectedType: Ember.computed.alias("themesController.currentTab"),
component: Ember.computed.equal("selectedType", COMPONENTS), component: Ember.computed.equal("selectedType", COMPONENTS),
init() {
this._super(...arguments);
this.createTypes = [
{ name: I18n.t("admin.customize.theme.theme"), value: THEMES },
{ name: I18n.t("admin.customize.theme.component"), value: COMPONENTS }
];
},
@computed("themesController.installedThemes") @computed("themesController.installedThemes")
themes(installedThemes) { themes(installedThemes) {
return POPULAR_THEMES.map(t => { return POPULAR_THEMES.map(t => {

View File

@ -3,10 +3,13 @@ import computed from "ember-addons/ember-computed-decorators";
export default Ember.Mixin.create({ export default Ember.Mixin.create({
queryParams: ["period"], queryParams: ["period"],
period: "monthly", period: "monthly",
availablePeriods: ["yearly", "quarterly", "monthly", "weekly"], init() {
this._super(...arguments);
this.availablePeriods = ["yearly", "quarterly", "monthly", "weekly"];
},
@computed("period") @computed("period")
startDate(period) { startDate(period) {

View File

@ -6,13 +6,13 @@ import { escapeExpression } from "discourse/lib/utilities";
import highlightSyntax from "discourse/lib/highlight-syntax"; import highlightSyntax from "discourse/lib/highlight-syntax";
const THEME_UPLOAD_VAR = 2; const THEME_UPLOAD_VAR = 2;
const FIELDS_IDS = [0, 1, 5];
export const THEMES = "themes"; export const THEMES = "themes";
export const COMPONENTS = "components"; export const COMPONENTS = "components";
const SETTINGS_TYPE_ID = 5; const SETTINGS_TYPE_ID = 5;
const Theme = RestModel.extend({ const Theme = RestModel.extend({
FIELDS_IDS: [0, 1, 5],
isActive: Ember.computed.or("default", "user_selectable"), isActive: Ember.computed.or("default", "user_selectable"),
isPendingUpdates: Ember.computed.gt("remote_theme.commits_behind", 0), isPendingUpdates: Ember.computed.gt("remote_theme.commits_behind", 0),
hasEditedFields: Ember.computed.gt("editedFields.length", 0), hasEditedFields: Ember.computed.gt("editedFields.length", 0),
@ -118,7 +118,7 @@ const Theme = RestModel.extend({
let hash = {}; let hash = {};
fields.forEach(field => { fields.forEach(field => {
if (!field.type_id || this.FIELDS_IDS.includes(field.type_id)) { if (!field.type_id || FIELDS_IDS.includes(field.type_id)) {
hash[this.getKey(field)] = field; hash[this.getKey(field)] = field;
} }
}); });

View File

@ -4,7 +4,12 @@ import Category from "discourse/models/category";
import computed from "ember-addons/ember-computed-decorators"; import computed from "ember-addons/ember-computed-decorators";
export default buildCategoryPanel("general", { export default buildCategoryPanel("general", {
foregroundColors: ["FFFFFF", "000000"], init() {
this._super(...arguments);
this.foregroundColors = ["FFFFFF", "000000"];
},
canSelectParentCategory: Ember.computed.not( canSelectParentCategory: Ember.computed.not(
"category.isUncategorizedCategory" "category.isUncategorizedCategory"
), ),

View File

@ -7,7 +7,12 @@ export default DropdownSelectBoxComponent.extend({
showFullTitle: false, showFullTitle: false,
allowInitialValueMutation: false, allowInitialValueMutation: false,
allowAutoSelectFirst: false, allowAutoSelectFirst: false,
headerIcon: ["wrench"],
init() {
this._super(...arguments);
this.headerIcon = ["wrench"];
},
autoHighlight() {}, autoHighlight() {},

View File

@ -1,13 +1,20 @@
import { default as computed } from "ember-addons/ember-computed-decorators"; import { default as computed } from "ember-addons/ember-computed-decorators";
export default Ember.Component.extend({ export default Ember.Component.extend({
visibilityLevelOptions: [ init() {
this._super(...arguments);
this.visibilityLevelOptions = [
{ {
name: I18n.t("admin.groups.manage.interaction.visibility_levels.public"), name: I18n.t(
"admin.groups.manage.interaction.visibility_levels.public"
),
value: 0 value: 0
}, },
{ {
name: I18n.t("admin.groups.manage.interaction.visibility_levels.members"), name: I18n.t(
"admin.groups.manage.interaction.visibility_levels.members"
),
value: 1 value: 1
}, },
{ {
@ -15,18 +22,21 @@ export default Ember.Component.extend({
value: 2 value: 2
}, },
{ {
name: I18n.t("admin.groups.manage.interaction.visibility_levels.owners"), name: I18n.t(
"admin.groups.manage.interaction.visibility_levels.owners"
),
value: 3 value: 3
} }
], ];
aliasLevelOptions: [ this.aliasLevelOptions = [
{ name: I18n.t("groups.alias_levels.nobody"), value: 0 }, { name: I18n.t("groups.alias_levels.nobody"), value: 0 },
{ name: I18n.t("groups.alias_levels.only_admins"), value: 1 }, { name: I18n.t("groups.alias_levels.only_admins"), value: 1 },
{ name: I18n.t("groups.alias_levels.mods_and_admins"), value: 2 }, { name: I18n.t("groups.alias_levels.mods_and_admins"), value: 2 },
{ name: I18n.t("groups.alias_levels.members_mods_and_admins"), value: 3 }, { name: I18n.t("groups.alias_levels.members_mods_and_admins"), value: 3 },
{ name: I18n.t("groups.alias_levels.everyone"), value: 99 } { name: I18n.t("groups.alias_levels.everyone"), value: 99 }
], ];
},
@computed("siteSettings.email_in", "model.automatic", "currentUser.admin") @computed("siteSettings.email_in", "model.automatic", "currentUser.admin")
showEmailSettings(emailIn, automatic, isAdmin) { showEmailSettings(emailIn, automatic, isAdmin) {

View File

@ -1,7 +1,10 @@
import computed from "ember-addons/ember-computed-decorators"; import computed from "ember-addons/ember-computed-decorators";
export default Ember.Component.extend({ export default Ember.Component.extend({
trustLevelOptions: [ init() {
this._super(...arguments);
this.trustLevelOptions = [
{ {
name: I18n.t("admin.groups.manage.membership.trust_levels_none"), name: I18n.t("admin.groups.manage.membership.trust_levels_none"),
value: 0 value: 0
@ -10,7 +13,8 @@ export default Ember.Component.extend({
{ name: 2, value: 2 }, { name: 2, value: 2 },
{ name: 3, value: 3 }, { name: 3, value: 3 },
{ name: 4, value: 4 } { name: 4, value: 4 }
], ];
},
@computed("model.visibility_level", "model.public_admission") @computed("model.visibility_level", "model.public_admission")
disableMembershipRequestSetting(visibility_level, publicAdmission) { disableMembershipRequestSetting(visibility_level, publicAdmission) {

View File

@ -31,44 +31,47 @@ const IN_OPTIONS_MAPPING = { images: "with" };
export default Ember.Component.extend({ export default Ember.Component.extend({
classNames: ["search-advanced-options"], classNames: ["search-advanced-options"],
inOptionsForUsers: [ init() {
this._super(...arguments);
this.inOptionsForUsers = [
{ name: I18n.t("search.advanced.filters.unseen"), value: "unseen" }, { name: I18n.t("search.advanced.filters.unseen"), value: "unseen" },
{ name: I18n.t("search.advanced.filters.posted"), value: "posted" }, { name: I18n.t("search.advanced.filters.posted"), value: "posted" },
{ name: I18n.t("search.advanced.filters.watching"), value: "watching" }, { name: I18n.t("search.advanced.filters.watching"), value: "watching" },
{ name: I18n.t("search.advanced.filters.tracking"), value: "tracking" }, { name: I18n.t("search.advanced.filters.tracking"), value: "tracking" },
{ name: I18n.t("search.advanced.filters.bookmarks"), value: "bookmarks" } { name: I18n.t("search.advanced.filters.bookmarks"), value: "bookmarks" }
], ];
inOptionsForAll: [ this.inOptionsForAll = [
{ name: I18n.t("search.advanced.filters.first"), value: "first" }, { name: I18n.t("search.advanced.filters.first"), value: "first" },
{ name: I18n.t("search.advanced.filters.pinned"), value: "pinned" }, { name: I18n.t("search.advanced.filters.pinned"), value: "pinned" },
{ name: I18n.t("search.advanced.filters.unpinned"), value: "unpinned" }, { name: I18n.t("search.advanced.filters.unpinned"), value: "unpinned" },
{ name: I18n.t("search.advanced.filters.wiki"), value: "wiki" }, { name: I18n.t("search.advanced.filters.wiki"), value: "wiki" },
{ name: I18n.t("search.advanced.filters.images"), value: "images" } { name: I18n.t("search.advanced.filters.images"), value: "images" }
], ];
statusOptions: [ this.statusOptions = [
{ name: I18n.t("search.advanced.statuses.open"), value: "open" }, { name: I18n.t("search.advanced.statuses.open"), value: "open" },
{ name: I18n.t("search.advanced.statuses.closed"), value: "closed" }, { name: I18n.t("search.advanced.statuses.closed"), value: "closed" },
{ name: I18n.t("search.advanced.statuses.archived"), value: "archived" }, { name: I18n.t("search.advanced.statuses.archived"), value: "archived" },
{ name: I18n.t("search.advanced.statuses.noreplies"), value: "noreplies" }, {
name: I18n.t("search.advanced.statuses.noreplies"),
value: "noreplies"
},
{ {
name: I18n.t("search.advanced.statuses.single_user"), name: I18n.t("search.advanced.statuses.single_user"),
value: "single_user" value: "single_user"
} }
], ];
postTimeOptions: [ this.postTimeOptions = [
{ name: I18n.t("search.advanced.post.time.before"), value: "before" }, { name: I18n.t("search.advanced.post.time.before"), value: "before" },
{ name: I18n.t("search.advanced.post.time.after"), value: "after" } { name: I18n.t("search.advanced.post.time.after"), value: "after" }
], ];
init() {
this._super(...arguments);
this._init(); this._init();
Ember.run.scheduleOnce("afterRender", () => {
this._update(); Ember.run.scheduleOnce("afterRender", () => this._update());
});
}, },
@observes("searchTerm") @observes("searchTerm")

View File

@ -88,32 +88,35 @@ export default Ember.Component.extend({
Ember.run.scheduleOnce("afterRender", this, this._focusUrl); Ember.run.scheduleOnce("afterRender", this, this._focusUrl);
}, },
didInsertElement() { _mouseDownHandler(event) {
this._super(...arguments); if (!this.element || this.isDestroying || this.isDestroyed) {
return;
const $html = $("html"); }
$html.on("mousedown.outside-share-link", e => {
// Use mousedown instead of click so this event is handled before routing occurs when a // Use mousedown instead of click so this event is handled before routing occurs when a
// link is clicked (which is a click event) while the share dialog is showing. // link is clicked (which is a click event) while the share dialog is showing.
if (this.$().has(e.target).length !== 0) { if ($(this.element).has(event.target).length !== 0) {
return;
}
this.send("close");
return true;
},
_clickHandler(event) {
if (!this.element || this.isDestroying || this.isDestroyed) {
return; return;
} }
this.send("close");
return true;
});
$html.on(
"click.discourse-share-link",
"button[data-share-url], .post-info .post-date[data-share-url]",
e => {
// if they want to open in a new tab, let it so // if they want to open in a new tab, let it so
if (wantsNewWindow(e)) { if (wantsNewWindow(event)) {
return true; return true;
} }
e.preventDefault(); event.preventDefault();
const $currentTarget = $(e.currentTarget); const $currentTarget = $(event.currentTarget);
const url = $currentTarget.data("share-url"); const url = $currentTarget.data("share-url");
const postNumber = $currentTarget.data("post-number"); const postNumber = $currentTarget.data("post-number");
const postId = $currentTarget.closest("article").data("post-id"); const postId = $currentTarget.closest("article").data("post-id");
@ -123,34 +126,54 @@ export default Ember.Component.extend({
// use native webshare only when the user clicks on the "chain" icon // use native webshare only when the user clicks on the "chain" icon
if (!$currentTarget.hasClass("post-date")) { if (!$currentTarget.hasClass("post-date")) {
nativeShare({ url }).then(null, () => nativeShare({ url }).then(null, () => this._showUrl($currentTarget, url));
this._showUrl($currentTarget, url)
);
} else { } else {
this._showUrl($currentTarget, url); this._showUrl($currentTarget, url);
} }
return false; return false;
} },
);
$html.on("keydown.share-view", e => { _keydownHandler(event) {
if (e.keyCode === 27) { if (!this.element || this.isDestroying || this.isDestroyed) {
return;
}
if (event.keyCode === 27) {
this.send("close"); this.send("close");
} }
}); },
this.appEvents.on("share:url", (url, $target) => _shareUrlHandler(url, $target) {
this._showUrl($target, url) this._showUrl($target, url);
},
didInsertElement() {
this._super(...arguments);
const $html = $("html");
$html.on("mousedown.outside-share-link", this._mouseDownHandler.bind(this));
$html.on(
"click.discourse-share-link",
"button[data-share-url], .post-info .post-date[data-share-url]",
this._clickHandler.bind(this)
); );
$html.on("keydown.share-view", this._keydownHandler);
this.appEvents.on("share:url", this._shareUrlHandler);
}, },
willDestroyElement() { willDestroyElement() {
this._super(...arguments); this._super(...arguments);
$("html") $("html")
.off("click.discourse-share-link") .off("click.discourse-share-link", this._clickHandler)
.off("mousedown.outside-share-link") .off("mousedown.outside-share-link", this._mouseDownHandler)
.off("keydown.share-view"); .off("keydown.share-view", this._keydownHandler);
this.appEvents.off("share:url", this._shareUrlHandler);
}, },
actions: { actions: {

View File

@ -5,9 +5,14 @@ export default DropdownSelectBoxComponent.extend({
classNames: "tags-admin-dropdown", classNames: "tags-admin-dropdown",
showFullTitle: false, showFullTitle: false,
allowInitialValueMutation: false, allowInitialValueMutation: false,
headerIcon: ["bars", "caret-down"],
actionsMapping: null, actionsMapping: null,
init() {
this._super(...arguments);
this.headerIcon = ["bars", "caret-down"];
},
autoHighlight() {}, autoHighlight() {},
computeContent() { computeContent() {

View File

@ -13,8 +13,13 @@ export default Ember.Controller.extend(
loading: true, loading: true,
saving: false, saving: false,
selectedBadgeId: null, selectedBadgeId: null,
allBadges: [],
userBadges: [], init() {
this._super(...arguments);
this.allBadges = [];
this.userBadges = [];
},
@computed("topicController.selectedPosts") @computed("topicController.selectedPosts")
post() { post() {

View File

@ -16,9 +16,19 @@ export default Ember.Controller.extend(ModalFunctionality, {
existingTopic: Ember.computed.equal("selection", "existing_topic"), existingTopic: Ember.computed.equal("selection", "existing_topic"),
newMessage: Ember.computed.equal("selection", "new_message"), newMessage: Ember.computed.equal("selection", "new_message"),
existingMessage: Ember.computed.equal("selection", "existing_message"), existingMessage: Ember.computed.equal("selection", "existing_message"),
moveTypes: ["newTopic", "existingTopic", "newMessage", "existingMessage"],
participants: null, participants: null,
init() {
this._super(...arguments);
this.saveAttrNames = [
"newTopic",
"existingTopic",
"newMessage",
"existingMessage"
];
},
topicController: Ember.inject.controller("topic"), topicController: Ember.inject.controller("topic"),
selectedPostsCount: Ember.computed.alias( selectedPostsCount: Ember.computed.alias(
"topicController.selectedPostsCount" "topicController.selectedPostsCount"

View File

@ -16,7 +16,11 @@ export default Ember.Controller.extend(
CanCheckEmails, CanCheckEmails,
PreferencesTabController, PreferencesTabController,
{ {
saveAttrNames: ["name", "title"], init() {
this._super(...arguments);
this.saveAttrNames = ["name", "title"];
},
canEditName: setting("enable_names"), canEditName: setting("enable_names"),
canSaveUser: true, canSaveUser: true,

View File

@ -3,12 +3,16 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
import computed from "ember-addons/ember-computed-decorators"; import computed from "ember-addons/ember-computed-decorators";
export default Ember.Controller.extend(PreferencesTabController, { export default Ember.Controller.extend(PreferencesTabController, {
saveAttrNames: [ init() {
this._super(...arguments);
this.saveAttrNames = [
"muted_category_ids", "muted_category_ids",
"watched_category_ids", "watched_category_ids",
"tracked_category_ids", "tracked_category_ids",
"watched_first_post_category_ids" "watched_first_post_category_ids"
], ];
},
@computed( @computed(
"model.watchedCategories", "model.watchedCategories",

View File

@ -18,7 +18,10 @@ export default Ember.Controller.extend(PreferencesTabController, {
EMAIL_LEVELS.ONLY_WHEN_AWAY EMAIL_LEVELS.ONLY_WHEN_AWAY
), ),
saveAttrNames: [ init() {
this._super(...arguments);
this.saveAttrNames = [
"email_level", "email_level",
"email_messages_level", "email_messages_level",
"mailing_list_mode", "mailing_list_mode",
@ -28,7 +31,32 @@ export default Ember.Controller.extend(PreferencesTabController, {
"email_previous_replies", "email_previous_replies",
"digest_after_minutes", "digest_after_minutes",
"include_tl0_in_digests" "include_tl0_in_digests"
], ];
this.previousRepliesOptions = [
{ name: I18n.t("user.email_previous_replies.always"), value: 0 },
{ name: I18n.t("user.email_previous_replies.unless_emailed"), value: 1 },
{ name: I18n.t("user.email_previous_replies.never"), value: 2 }
];
this.emailLevelOptions = [
{ name: I18n.t("user.email_level.always"), value: EMAIL_LEVELS.ALWAYS },
{
name: I18n.t("user.email_level.only_when_away"),
value: EMAIL_LEVELS.ONLY_WHEN_AWAY
},
{ name: I18n.t("user.email_level.never"), value: EMAIL_LEVELS.NEVER }
];
this.digestFrequencies = [
{ name: I18n.t("user.email_digests.every_30_minutes"), value: 30 },
{ name: I18n.t("user.email_digests.every_hour"), value: 60 },
{ name: I18n.t("user.email_digests.daily"), value: 1440 },
{ name: I18n.t("user.email_digests.weekly"), value: 10080 },
{ name: I18n.t("user.email_digests.every_month"), value: 43200 },
{ name: I18n.t("user.email_digests.every_six_months"), value: 259200 }
];
},
@computed() @computed()
frequencyEstimate() { frequencyEstimate() {
@ -50,30 +78,6 @@ export default Ember.Controller.extend(PreferencesTabController, {
]; ];
}, },
previousRepliesOptions: [
{ name: I18n.t("user.email_previous_replies.always"), value: 0 },
{ name: I18n.t("user.email_previous_replies.unless_emailed"), value: 1 },
{ name: I18n.t("user.email_previous_replies.never"), value: 2 }
],
emailLevelOptions: [
{ name: I18n.t("user.email_level.always"), value: EMAIL_LEVELS.ALWAYS },
{
name: I18n.t("user.email_level.only_when_away"),
value: EMAIL_LEVELS.ONLY_WHEN_AWAY
},
{ name: I18n.t("user.email_level.never"), value: EMAIL_LEVELS.NEVER }
],
digestFrequencies: [
{ name: I18n.t("user.email_digests.every_30_minutes"), value: 30 },
{ name: I18n.t("user.email_digests.every_hour"), value: 60 },
{ name: I18n.t("user.email_digests.daily"), value: 1440 },
{ name: I18n.t("user.email_digests.weekly"), value: 10080 },
{ name: I18n.t("user.email_digests.every_month"), value: 43200 },
{ name: I18n.t("user.email_digests.every_six_months"), value: 259200 }
],
@computed() @computed()
emailFrequencyInstructions() { emailFrequencyInstructions() {
if (this.siteSettings.email_time_window_mins) { if (this.siteSettings.email_time_window_mins) {

View File

@ -3,7 +3,10 @@ import { NotificationLevels } from "discourse/lib/notification-levels";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
export default Ember.Controller.extend(PreferencesTabController, { export default Ember.Controller.extend(PreferencesTabController, {
saveAttrNames: [ init() {
this._super(...arguments);
this.saveAttrNames = [
"muted_usernames", "muted_usernames",
"ignored_usernames", "ignored_usernames",
"new_topic_duration_minutes", "new_topic_duration_minutes",
@ -11,9 +14,9 @@ export default Ember.Controller.extend(PreferencesTabController, {
"notification_level_when_replying", "notification_level_when_replying",
"like_notification_frequency", "like_notification_frequency",
"allow_private_messages" "allow_private_messages"
], ];
likeNotificationFrequencies: [ this.likeNotificationFrequencies = [
{ name: I18n.t("user.like_notification_frequency.always"), value: 0 }, { name: I18n.t("user.like_notification_frequency.always"), value: 0 },
{ {
name: I18n.t("user.like_notification_frequency.first_time_and_daily"), name: I18n.t("user.like_notification_frequency.first_time_and_daily"),
@ -21,21 +24,39 @@ export default Ember.Controller.extend(PreferencesTabController, {
}, },
{ name: I18n.t("user.like_notification_frequency.first_time"), value: 2 }, { name: I18n.t("user.like_notification_frequency.first_time"), value: 2 },
{ name: I18n.t("user.like_notification_frequency.never"), value: 3 } { name: I18n.t("user.like_notification_frequency.never"), value: 3 }
], ];
autoTrackDurations: [ this.autoTrackDurations = [
{ name: I18n.t("user.auto_track_options.never"), value: -1 }, { name: I18n.t("user.auto_track_options.never"), value: -1 },
{ name: I18n.t("user.auto_track_options.immediately"), value: 0 }, { name: I18n.t("user.auto_track_options.immediately"), value: 0 },
{ name: I18n.t("user.auto_track_options.after_30_seconds"), value: 30000 }, {
name: I18n.t("user.auto_track_options.after_30_seconds"),
value: 30000
},
{ name: I18n.t("user.auto_track_options.after_1_minute"), value: 60000 }, { name: I18n.t("user.auto_track_options.after_1_minute"), value: 60000 },
{ name: I18n.t("user.auto_track_options.after_2_minutes"), value: 120000 }, {
{ name: I18n.t("user.auto_track_options.after_3_minutes"), value: 180000 }, name: I18n.t("user.auto_track_options.after_2_minutes"),
{ name: I18n.t("user.auto_track_options.after_4_minutes"), value: 240000 }, value: 120000
{ name: I18n.t("user.auto_track_options.after_5_minutes"), value: 300000 }, },
{ name: I18n.t("user.auto_track_options.after_10_minutes"), value: 600000 } {
], name: I18n.t("user.auto_track_options.after_3_minutes"),
value: 180000
},
{
name: I18n.t("user.auto_track_options.after_4_minutes"),
value: 240000
},
{
name: I18n.t("user.auto_track_options.after_5_minutes"),
value: 300000
},
{
name: I18n.t("user.auto_track_options.after_10_minutes"),
value: 600000
}
];
notificationLevelsForReplying: [ this.notificationLevelsForReplying = [
{ {
name: I18n.t("topic.notifications.watching.title"), name: I18n.t("topic.notifications.watching.title"),
value: NotificationLevels.WATCHING value: NotificationLevels.WATCHING
@ -48,9 +69,9 @@ export default Ember.Controller.extend(PreferencesTabController, {
name: I18n.t("topic.notifications.regular.title"), name: I18n.t("topic.notifications.regular.title"),
value: NotificationLevels.REGULAR value: NotificationLevels.REGULAR
} }
], ];
considerNewTopicOptions: [ this.considerNewTopicOptions = [
{ name: I18n.t("user.new_topic_duration.not_viewed"), value: -1 }, { name: I18n.t("user.new_topic_duration.not_viewed"), value: -1 },
{ name: I18n.t("user.new_topic_duration.after_1_day"), value: 60 * 24 }, { name: I18n.t("user.new_topic_duration.after_1_day"), value: 60 * 24 },
{ name: I18n.t("user.new_topic_duration.after_2_days"), value: 60 * 48 }, { name: I18n.t("user.new_topic_duration.after_2_days"), value: 60 * 48 },
@ -63,7 +84,8 @@ export default Ember.Controller.extend(PreferencesTabController, {
value: 2 * 7 * 60 * 24 value: 2 * 7 * 60 * 24
}, },
{ name: I18n.t("user.new_topic_duration.last_here"), value: -2 } { name: I18n.t("user.new_topic_duration.last_here"), value: -2 }
], ];
},
actions: { actions: {
save() { save() {

View File

@ -4,7 +4,10 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
import { cookAsync } from "discourse/lib/text"; import { cookAsync } from "discourse/lib/text";
export default Ember.Controller.extend(PreferencesTabController, { export default Ember.Controller.extend(PreferencesTabController, {
saveAttrNames: [ init() {
this._super(...arguments);
this.saveAttrNames = [
"bio_raw", "bio_raw",
"website", "website",
"location", "location",
@ -13,7 +16,8 @@ export default Ember.Controller.extend(PreferencesTabController, {
"profile_background_upload_url", "profile_background_upload_url",
"card_background_upload_url", "card_background_upload_url",
"date_of_birth" "date_of_birth"
], ];
},
@computed("model.user_fields.@each.value") @computed("model.user_fields.@each.value")
userFields() { userFields() {

View File

@ -3,12 +3,16 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
import computed from "ember-addons/ember-computed-decorators"; import computed from "ember-addons/ember-computed-decorators";
export default Ember.Controller.extend(PreferencesTabController, { export default Ember.Controller.extend(PreferencesTabController, {
saveAttrNames: [ init() {
this._super(...arguments);
this.saveAttrNames = [
"muted_tags", "muted_tags",
"tracked_tags", "tracked_tags",
"watched_tags", "watched_tags",
"watching_first_post_tags" "watching_first_post_tags"
], ];
},
@computed( @computed(
"model.watched_tags.[]", "model.watched_tags.[]",

View File

@ -4,10 +4,16 @@ import showModal from "discourse/lib/show-modal";
import User from "discourse/models/user"; import User from "discourse/models/user";
export default Ember.Controller.extend(PreferencesTabController, { export default Ember.Controller.extend(PreferencesTabController, {
saveAttrNames: ["muted_usernames", "ignored_usernames"],
ignoredUsernames: Ember.computed.alias("model.ignored_usernames"), ignoredUsernames: Ember.computed.alias("model.ignored_usernames"),
userIsMemberOrAbove: Ember.computed.gte("model.trust_level", 2), userIsMemberOrAbove: Ember.computed.gte("model.trust_level", 2),
ignoredEnabled: Ember.computed.or("userIsMemberOrAbove", "model.staff"), ignoredEnabled: Ember.computed.or("userIsMemberOrAbove", "model.staff"),
init() {
this._super(...arguments);
this.saveAttrNames = ["muted_usernames", "ignored_usernames"];
},
actions: { actions: {
ignoredUsernamesChanged(previous, current) { ignoredUsernamesChanged(previous, current) {
if (current.length > previous.length) { if (current.length > previous.length) {

View File

@ -9,6 +9,12 @@ import {
import Ember from "ember"; import Ember from "ember";
export default Ember.Controller.extend(ModalFunctionality, Ember.Evented, { export default Ember.Controller.extend(ModalFunctionality, Ember.Evented, {
init() {
this._super(...arguments);
this.categoriesSorting = ["position"];
},
@on("init") @on("init")
_fixOrder() { _fixOrder() {
this.fixIndices(); this.fixIndices();
@ -20,7 +26,6 @@ export default Ember.Controller.extend(ModalFunctionality, Ember.Evented, {
return categories.map(c => bufProxy.create({ content: c })); return categories.map(c => bufProxy.create({ content: c }));
}, },
categoriesSorting: ["position"],
categoriesOrdered: Ember.computed.sort( categoriesOrdered: Ember.computed.sort(
"categoriesBuffered", "categoriesBuffered",
"categoriesSorting" "categoriesSorting"

View File

@ -4,7 +4,6 @@ import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
export default Ember.Controller.extend({ export default Ember.Controller.extend({
sortProperties: ["totalCount:desc", "id"],
sortedByCount: true, sortedByCount: true,
sortedByName: false, sortedByName: false,
@ -12,6 +11,12 @@ export default Ember.Controller.extend({
groupedByCategory: Ember.computed.notEmpty("model.extras.categories"), groupedByCategory: Ember.computed.notEmpty("model.extras.categories"),
groupedByTagGroup: Ember.computed.notEmpty("model.extras.tag_groups"), groupedByTagGroup: Ember.computed.notEmpty("model.extras.tag_groups"),
init() {
this._super(...arguments);
this.sortProperties = ["totalCount:desc", "id"];
},
@computed("groupedByCategory", "groupedByTagGroup") @computed("groupedByCategory", "groupedByTagGroup")
otherTagsTitleKey(groupedByCategory, groupedByTagGroup) { otherTagsTitleKey(groupedByCategory, groupedByTagGroup) {
if (!groupedByCategory && !groupedByTagGroup) { if (!groupedByCategory && !groupedByTagGroup) {

View File

@ -2,5 +2,10 @@ export default Ember.Controller.extend({
user: Ember.inject.controller(), user: Ember.inject.controller(),
username: Ember.computed.alias("user.model.username_lower"), username: Ember.computed.alias("user.model.username_lower"),
sortedBadges: Ember.computed.sort("model", "badgeSortOrder"), sortedBadges: Ember.computed.sort("model", "badgeSortOrder"),
badgeSortOrder: ["badge.badge_type.sort_order", "badge.name"]
init() {
this._super(...arguments);
this.badgeSortOrder = ["badge.badge_type.sort_order", "badge.name"];
}
}); });

View File

@ -6,11 +6,16 @@ export default Ember.Controller.extend({
hideCategory: false, hideCategory: false,
showPosters: false, showPosters: false,
newIncoming: [],
incomingCount: 0, incomingCount: 0,
channel: null, channel: null,
tagsForUser: null, tagsForUser: null,
init() {
this._super(...arguments);
this.newIncoming = [];
},
_showFooter: function() { _showFooter: function() {
this.set("application.showFooter", !this.get("model.canLoadMore")); this.set("application.showFooter", !this.get("model.canLoadMore"));
}.observes("model.canLoadMore"), }.observes("model.canLoadMore"),

View File

@ -1,11 +1,10 @@
import { ajax } from "discourse/lib/ajax"; import { ajax } from "discourse/lib/ajax";
// We use this class to track how long posts in a topic are on the screen. // We use this class to track how long posts in a topic are on the screen.
const PAUSE_UNLESS_SCROLLED = 1000 * 60 * 3; const PAUSE_UNLESS_SCROLLED = 1000 * 60 * 3;
const MAX_TRACKING_TIME = 1000 * 60 * 6; const MAX_TRACKING_TIME = 1000 * 60 * 6;
const ANON_MAX_TOPIC_IDS = 5; const ANON_MAX_TOPIC_IDS = 5;
const getTime = () => new Date().getTime();
export default class { export default class {
constructor(topicTrackingState, siteSettings, session, currentUser) { constructor(topicTrackingState, siteSettings, session, currentUser) {
this.topicTrackingState = topicTrackingState; this.topicTrackingState = topicTrackingState;
@ -27,7 +26,7 @@ export default class {
// Create an interval timer if we don't have one. // Create an interval timer if we don't have one.
if (!this._interval) { if (!this._interval) {
this._interval = setInterval(() => this.tick(), 1000); this._interval = setInterval(() => this.tick(), 1000);
$(window).on("scroll.screentrack", () => this.scrolled()); $(window).on("scroll.screentrack", this.scrolled.bind(this));
} }
this._topicId = topicId; this._topicId = topicId;
@ -40,7 +39,7 @@ export default class {
return; return;
} }
$(window).off("scroll.screentrack"); $(window).off("scroll.screentrack", this.scrolled);
this.tick(); this.tick();
this.flush(); this.flush();
this.reset(); this.reset();
@ -61,7 +60,7 @@ export default class {
// Reset our timers // Reset our timers
reset() { reset() {
const now = getTime(); const now = this._getTime();
this._lastTick = now; this._lastTick = now;
this._lastScrolled = now; this._lastScrolled = now;
this._lastFlush = 0; this._lastFlush = 0;
@ -75,7 +74,7 @@ export default class {
} }
scrolled() { scrolled() {
this._lastScrolled = getTime(); this._lastScrolled = this._getTime();
} }
registerAnonCallback(cb) { registerAnonCallback(cb) {
@ -225,4 +224,8 @@ export default class {
}); });
} }
} }
_getTime() {
return (this._time = this._time || new Date().getTime());
}
} }

View File

@ -14,7 +14,12 @@ const Group = RestModel.extend({
limit: 50, limit: 50,
offset: 0, offset: 0,
user_count: 0, user_count: 0,
owners: [],
init() {
this._super(...arguments);
this.owners = [];
},
hasOwners: Ember.computed.notEmpty("owners"), hasOwners: Ember.computed.notEmpty("owners"),

View File

@ -8,6 +8,12 @@ import PreloadStore from "preload-store";
const Site = RestModel.extend({ const Site = RestModel.extend({
isReadOnly: Ember.computed.alias("is_readonly"), isReadOnly: Ember.computed.alias("is_readonly"),
init() {
this._super(...arguments);
this.topicCountDesc = ["topic_count:desc"];
},
@computed("notification_types") @computed("notification_types")
notificationLookup(notificationTypes) { notificationLookup(notificationTypes) {
const result = []; const result = [];
@ -24,7 +30,6 @@ const Site = RestModel.extend({
return postActionTypes.filterBy("is_flag", true); return postActionTypes.filterBy("is_flag", true);
}, },
topicCountDesc: ["topic_count:desc"],
categoriesByCount: Ember.computed.sort("categories", "topicCountDesc"), categoriesByCount: Ember.computed.sort("categories", "topicCountDesc"),
collectUserFields(fields) { collectUserFields(fields) {

View File

@ -5,7 +5,12 @@ export default DropdownSelectBoxComponent.extend({
classNames: "categories-admin-dropdown", classNames: "categories-admin-dropdown",
showFullTitle: false, showFullTitle: false,
allowInitialValueMutation: false, allowInitialValueMutation: false,
headerIcon: ["bars"],
init() {
this._super(...arguments);
this.headerIcon = ["bars"];
},
autoHighlight() {}, autoHighlight() {},

View File

@ -2,9 +2,15 @@ import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-bo
export default DropdownSelectBoxComponent.extend({ export default DropdownSelectBoxComponent.extend({
classNames: "group-members-dropdown", classNames: "group-members-dropdown",
headerIcon: ["bars"],
showFullTitle: false, showFullTitle: false,
allowInitialValueMutation: false, allowInitialValueMutation: false,
init() {
this._super(...arguments);
this.headerIcon = ["bars"];
},
autoHighlight() {}, autoHighlight() {},
computeContent() { computeContent() {

View File

@ -18,29 +18,26 @@ export default Ember.Mixin.create({
willDestroyElement() { willDestroyElement() {
this._super(...arguments); this._super(...arguments);
$(document).off("mousedown.select-kit"); $(document).off("mousedown.select-kit", this._mouseDownHandler);
if (this.$header().length) { if (this.$header().length) {
this.$header() this.$header()
.off("blur.select-kit") .off("blur.select-kit", this._blurHeaderHandler)
.off("focus.select-kit") .off("focus.select-kit", this._focusHeaderHandler)
.off("keypress.select-kit") .off("keydown.select-kit", this._keydownHeaderHandler)
.off("keydown.select-kit"); .off("keypress.select-kit", this._keypressHeaderHandler);
} }
if (this.$filterInput().length) { if (this.$filterInput().length) {
this.$filterInput() this.$filterInput()
.off("change.select-kit") .off("change.select-kit", this._changeFilterInputHandler)
.off("keydown.select-kit") .off("keydown.select-kit", this._keydownFilterInputHandler)
.off("keypress.select-kit") .off("keypress.select-kit", this._keypressFilterInputHandler)
.off("focusout.select-kit"); .off("focusout.select-kit", this._focusoutFilterInputHandler);
} }
}, },
didInsertElement() { _mouseDownHandler(event) {
this._super(...arguments);
$(document).on("mousedown.select-kit", event => {
if (!this.element || this.isDestroying || this.isDestroyed) { if (!this.element || this.isDestroying || this.isDestroyed) {
return true; return true;
} }
@ -52,21 +49,20 @@ export default Ember.Mixin.create({
} else { } else {
this.didClickOutside(event); this.didClickOutside(event);
} }
},
return true; _blurHeaderHandler() {
});
this.$header()
.on("blur.select-kit", () => {
if (!this.isExpanded && this.isFocused) { if (!this.isExpanded && this.isFocused) {
this.close(); this.close();
} }
}) },
.on("focus.select-kit", event => {
_focusHeaderHandler(event) {
this.set("isFocused", true); this.set("isFocused", true);
this._destroyEvent(event); this._destroyEvent(event);
}) },
.on("keydown.select-kit", event => {
_keydownHeaderHandler(event) {
if (document.activeElement !== this.$header()[0]) return event; if (document.activeElement !== this.$header()[0]) return event;
const keyCode = event.keyCode || event.which; const keyCode = event.keyCode || event.which;
@ -74,8 +70,7 @@ export default Ember.Mixin.create({
if (keyCode === this.keys.TAB && event.shiftKey) { if (keyCode === this.keys.TAB && event.shiftKey) {
this.unfocus(event); this.unfocus(event);
} }
if (keyCode === this.keys.TAB && !event.shiftKey) if (keyCode === this.keys.TAB && !event.shiftKey) this.tabFromHeader(event);
this.tabFromHeader(event);
if (Ember.isEmpty(this.filter) && keyCode === this.keys.BACKSPACE) if (Ember.isEmpty(this.filter) && keyCode === this.keys.BACKSPACE)
this.backspaceFromHeader(event); this.backspaceFromHeader(event);
if (keyCode === this.keys.ESC) this.escapeFromHeader(event); if (keyCode === this.keys.ESC) this.escapeFromHeader(event);
@ -89,8 +84,9 @@ export default Ember.Mixin.create({
this.leftAndRightFromHeader(event); this.leftAndRightFromHeader(event);
} }
return event; return event;
}) },
.on("keypress.select-kit", event => {
_keypressHeaderHandler(event) {
const keyCode = event.keyCode || event.which; const keyCode = event.keyCode || event.which;
if (keyCode === this.keys.ENTER) return true; if (keyCode === this.keys.ENTER) return true;
@ -109,19 +105,9 @@ export default Ember.Mixin.create({
}); });
return false; return false;
}); },
this.$filterInput() _keydownFilterInputHandler(event) {
.on("change.select-kit", event => {
this.send("onFilterComputedContent", $(event.target).val());
})
.on("keypress.select-kit", event => {
event.stopPropagation();
})
.on("focusout.select-kit", event => {
this.onFilterInputFocusout(event);
})
.on("keydown.select-kit", event => {
const keyCode = event.keyCode || event.which; const keyCode = event.keyCode || event.which;
if ( if (
@ -135,8 +121,7 @@ export default Ember.Mixin.create({
if (keyCode === this.keys.TAB && event.shiftKey) { if (keyCode === this.keys.TAB && event.shiftKey) {
this.unfocus(event); this.unfocus(event);
} }
if (keyCode === this.keys.TAB && !event.shiftKey) if (keyCode === this.keys.TAB && !event.shiftKey) this.tabFromFilter(event);
this.tabFromFilter(event);
if (keyCode === this.keys.ESC) this.escapeFromFilter(event); if (keyCode === this.keys.ESC) this.escapeFromFilter(event);
if (keyCode === this.keys.ENTER) this.enterFromFilter(event); if (keyCode === this.keys.ENTER) this.enterFromFilter(event);
if ([this.keys.UP, this.keys.DOWN].includes(keyCode)) if ([this.keys.UP, this.keys.DOWN].includes(keyCode))
@ -148,7 +133,34 @@ export default Ember.Mixin.create({
) { ) {
this.leftAndRightFromFilter(event); this.leftAndRightFromFilter(event);
} }
}); },
_changeFilterInputHandler(event) {
this.send("onFilterComputedContent", $(event.target).val());
},
_keypressFilterInputHandler(event) {
event.stopPropagation();
},
_focusoutFilterInputHandler(event) {
this.onFilterInputFocusout(event);
},
didInsertElement() {
this._super(...arguments);
$(document).on("mousedown.select-kit", this._mouseDownHandler);
this.$header()
.on("blur.select-kit", this._blurHeaderHandler.bind(this))
.on("focus.select-kit", this._focusHeaderHandler.bind(this))
.on("keydown.select-kit", this._keydownHeaderHandler.bind(this))
.on("keypress.select-kit", this._keypressHeaderHandler);
this.$filterInput()
.on("change.select-kit", this._changeFilterInputHandler.bind(this))
.on("keypress.select-kit", this._keypressFilterInputHandler)
.on("focusout.select-kit", this._focusoutFilterInputHandler.bind(this))
.on("keydown.select-kit", this._keydownFilterInputHandler.bind(this));
}, },
didPressTab(event) { didPressTab(event) {

View File

@ -64,6 +64,7 @@ QUnit.module("lib:keyboard-shortcuts", {
afterEach() { afterEach() {
$("#qunit-scratch").html(""); $("#qunit-scratch").html("");
testMouseTrap = undefined;
} }
}); });

View File

@ -65,8 +65,6 @@ d.write(
"<style>#ember-testing-container { position: absolute; background: white; bottom: 0; right: 0; width: 640px; height: 384px; overflow: auto; z-index: 9999; border: 1px solid #ccc; } #ember-testing { zoom: 50%; }</style>" "<style>#ember-testing-container { position: absolute; background: white; bottom: 0; right: 0; width: 640px; height: 384px; overflow: auto; z-index: 9999; border: 1px solid #ccc; } #ember-testing { zoom: 50%; }</style>"
); );
Ember.Test.adapter = window.QUnitAdapter.create();
Discourse.rootElement = "#ember-testing"; Discourse.rootElement = "#ember-testing";
Discourse.setupForTesting(); Discourse.setupForTesting();
Discourse.injectTestHelpers(); Discourse.injectTestHelpers();

View File

@ -2,8 +2,10 @@
// except for the little snippet from StackOverflow // except for the little snippet from StackOverflow
// //
// http://stackoverflow.com/questions/263743/how-to-get-caret-position-in-textarea // http://stackoverflow.com/questions/263743/how-to-get-caret-position-in-textarea
var clone, getCaret; var clone = null;
getCaret = function(el) {
$.fn.caret = function(elem) {
var getCaret = function(el) {
var r, rc, re; var r, rc, re;
if (el.selectionStart) { if (el.selectionStart) {
return el.selectionStart; return el.selectionStart;
@ -18,12 +20,9 @@ getCaret = function(el) {
return rc.text.length; return rc.text.length;
} }
return 0; return 0;
}; };
clone = null; return getCaret(elem || this[0]);
$.fn.caret = function() {
return getCaret(this[0]);
}; };
/** /**
@ -99,7 +98,7 @@ $.fn.caretPosition = function(options) {
pos = pos =
options && (options.pos || options.pos === 0) options && (options.pos || options.pos === 0)
? options.pos ? options.pos
: getCaret(textarea[0]); : $.caret(textarea[0]);
val = textarea.val().replace("\r", ""); val = textarea.val().replace("\r", "");
if (options && options.key) { if (options && options.key) {