DEV: Convert keyboard-shortcuts lib to service (#36098)

This lib file required an owner, and had a setup/teardown hooks, so it
really makes more sense as a service.

This also allows us to use `@service` injections, which are much better
than eager `.lookup()` calls. This will resolve issues we're seeing with
theme/plugin `modifyClass` calls racing with these service lookups.
This commit is contained in:
David Taylor
2025-11-19 17:04:39 +00:00
committed by GitHub
parent 878d23a1af
commit d2f5f96478
21 changed files with 140 additions and 146 deletions
@@ -1,6 +1,6 @@
import Controller from "@ember/controller";
import { PLATFORM_KEY_MODIFIER } from "discourse/lib/keyboard-shortcuts";
import { translateModKey } from "discourse/lib/utilities";
import { PLATFORM_KEY_MODIFIER } from "discourse/services/keyboard-shortcuts";
export default class AdminSearchIndexController extends Controller {
queryParams = ["filter"];
+4 -5
View File
@@ -1,15 +1,14 @@
import { tracked } from "@glimmer/tracking";
import { service } from "@ember/service";
import AdminSearchModal from "discourse/admin/components/modal/admin-search";
import KeyboardShortcuts, {
PLATFORM_KEY_MODIFIER,
} from "discourse/lib/keyboard-shortcuts";
import DiscourseRoute from "discourse/routes/discourse";
import { PLATFORM_KEY_MODIFIER } from "discourse/services/keyboard-shortcuts";
import { i18n } from "discourse-i18n";
export default class AdminRoute extends DiscourseRoute {
@service adminSidebarStateManager;
@service modal;
@service keyboardShortcuts;
@tracked initialSidebarState;
@@ -18,7 +17,7 @@ export default class AdminRoute extends DiscourseRoute {
}
activate() {
KeyboardShortcuts.addShortcut(
this.keyboardShortcuts.addShortcut(
`${PLATFORM_KEY_MODIFIER}+/`,
(event) => this.showAdminSearchModal(event),
{
@@ -38,7 +37,7 @@ export default class AdminRoute extends DiscourseRoute {
deactivate(transition) {
this.controllerFor("application").set("showTop", true);
KeyboardShortcuts.unbind({
this.keyboardShortcuts.unbind({
[`${PLATFORM_KEY_MODIFIER}+/`]: this.showAdminSearchModal,
});
@@ -33,7 +33,6 @@ import deprecated from "discourse/lib/deprecated";
import { isTesting } from "discourse/lib/environment";
import { getRegister } from "discourse/lib/get-owner";
import { hashtagAutocompleteOptions } from "discourse/lib/hashtag-autocomplete";
import { PLATFORM_KEY_MODIFIER } from "discourse/lib/keyboard-shortcuts";
import loadEmojiSearchAliases from "discourse/lib/load-emoji-search-aliases";
import loadRichEditor from "discourse/lib/load-rich-editor";
import { rovingButtonBar } from "discourse/lib/roving-button-bar";
@@ -48,6 +47,7 @@ import {
EMOJI_ALLOWED_PRECEDING_CHARS_REGEXP,
SKIP,
} from "discourse/modifiers/d-autocomplete";
import { PLATFORM_KEY_MODIFIER } from "discourse/services/keyboard-shortcuts";
import { not } from "discourse/truth-helpers";
import { i18n } from "discourse-i18n";
@@ -19,7 +19,6 @@ import RelativeTimePicker from "discourse/components/relative-time-picker";
import TimeShortcutPicker from "discourse/components/time-shortcut-picker";
import TopicTimerInfo from "discourse/components/topic-timer-info";
import icon from "discourse/helpers/d-icon";
import KeyboardShortcuts from "discourse/lib/keyboard-shortcuts";
import {
TIME_SHORTCUT_TYPES,
timeShortcuts,
@@ -30,13 +29,14 @@ import { i18n } from "discourse-i18n";
export default class EditTopicTimerForm extends Component {
@service currentUser;
@service keyboardShortcuts;
@tracked timerType;
constructor() {
super(...arguments);
KeyboardShortcuts.pause();
this.keyboardShortcuts.pause();
this._itsatrap = new ItsATrap();
}
@@ -44,7 +44,7 @@ export default class EditTopicTimerForm extends Component {
super.willDestroy(...arguments);
this._itsatrap.destroy();
KeyboardShortcuts.unpause();
this.keyboardShortcuts.unpause();
}
get showTimeOnly() {
@@ -19,7 +19,6 @@ import basePath from "discourse/helpers/base-path";
import icon from "discourse/helpers/d-icon";
import { extractError } from "discourse/lib/ajax-error";
import { formattedReminderTime } from "discourse/lib/bookmark";
import KeyboardShortcuts from "discourse/lib/keyboard-shortcuts";
import discourseLater from "discourse/lib/later";
import { sanitize } from "discourse/lib/text";
import {
@@ -42,6 +41,7 @@ export default class BookmarkModal extends Component {
@service capabilities;
@service bookmarkApi;
@service site;
@service keyboardShortcuts;
@tracked postDetectedLocalDate = null;
@tracked postDetectedLocalTime = null;
@@ -70,7 +70,7 @@ export default class BookmarkModal extends Component {
super.willDestroy(...arguments);
this._itsatrap?.destroy();
this._itsatrap = null;
KeyboardShortcuts.unpause();
this.keyboardShortcuts.unpause();
}
get bookmark() {
@@ -304,7 +304,7 @@ export default class BookmarkModal extends Component {
}
#bindKeyboardShortcuts() {
KeyboardShortcuts.pause();
this.keyboardShortcuts.pause();
Object.keys(BOOKMARK_BINDINGS).forEach((shortcut) => {
this._itsatrap.bind(shortcut, () => {
@@ -6,8 +6,8 @@ import { service } from "@ember/service";
import { htmlSafe } from "@ember/template";
import DModal from "discourse/components/d-modal";
import FilterInput from "discourse/components/filter-input";
import { extraKeyboardShortcutsHelp } from "discourse/lib/keyboard-shortcuts";
import { translateModKey } from "discourse/lib/utilities";
import { extraKeyboardShortcutsHelp } from "discourse/services/keyboard-shortcuts";
import { i18n } from "discourse-i18n";
const KEY = "keyboard_shortcuts_help";
@@ -11,7 +11,6 @@ import TextField from "discourse/components/text-field";
import DTooltip from "discourse/float-kit/components/d-tooltip";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
import KeyboardShortcuts from "discourse/lib/keyboard-shortcuts";
import {
arrayToTable,
findTableRegex,
@@ -21,6 +20,7 @@ import { i18n } from "discourse-i18n";
export default class SpreadsheetEditor extends Component {
@service dialog;
@service keyboardShortcuts;
@tracked showEditReason = false;
@tracked loading = true;
@@ -32,12 +32,12 @@ export default class SpreadsheetEditor extends Component {
constructor() {
super(...arguments);
this.loadJspreadsheet();
KeyboardShortcuts.pause();
this.keyboardShortcuts.pause();
}
willDestroy() {
super.willDestroy(...arguments);
KeyboardShortcuts.unpause();
this.keyboardShortcuts.unpause();
}
get modalAttributes() {
@@ -9,8 +9,8 @@ import DMenu from "discourse/float-kit/components/d-menu";
import concatClass from "discourse/helpers/concat-class";
import icon from "discourse/helpers/d-icon";
import { iconHTML } from "discourse/lib/icon-library";
import { PLATFORM_KEY_MODIFIER } from "discourse/lib/keyboard-shortcuts";
import { translateModKey } from "discourse/lib/utilities";
import { PLATFORM_KEY_MODIFIER } from "discourse/services/keyboard-shortcuts";
import { i18n } from "discourse-i18n";
export default class ToolbarPopupmenuOptions extends Component {
@@ -1,13 +1,5 @@
import ItsATrap from "@discourse/itsatrap";
import KeyboardShortcuts from "discourse/lib/keyboard-shortcuts";
export default {
initialize(owner) {
KeyboardShortcuts.init(ItsATrap, owner);
KeyboardShortcuts.bindEvents();
},
teardown() {
KeyboardShortcuts.teardown();
owner.lookup("service:keyboard-shortcuts");
},
};
@@ -1,7 +1,7 @@
// @ts-check
import { action } from "@ember/object";
import { PLATFORM_KEY_MODIFIER } from "discourse/lib/keyboard-shortcuts";
import { translateModKey } from "discourse/lib/utilities";
import { PLATFORM_KEY_MODIFIER } from "discourse/services/keyboard-shortcuts";
import { i18n } from "discourse-i18n";
/**
+7 -5
View File
@@ -72,9 +72,6 @@ import {
registerIconRenderer,
replaceIcon,
} from "discourse/lib/icon-library";
import KeyboardShortcuts, {
disableDefaultKeyboardShortcuts,
} from "discourse/lib/keyboard-shortcuts";
import { registerModelTransformer } from "discourse/lib/model-transformers";
import { registerNotificationTypeRenderer } from "discourse/lib/notification-types-manager";
import { addGTMPageChangedCallback } from "discourse/lib/page-tracker";
@@ -130,6 +127,7 @@ import { setNotificationsLimit } from "discourse/routes/user-notifications";
import { CUSTOM_USER_SEARCH_OPTIONS } from "discourse/select-kit/components/user-chooser";
import { modifySelectKit } from "discourse/select-kit/lib/plugin-api";
import { addComposerSaveErrorCallback } from "discourse/services/composer";
import { disableDefaultKeyboardShortcuts } from "discourse/services/keyboard-shortcuts";
import { addPostClassesCallback } from "discourse/widgets/post";
import { addDecorator } from "discourse/widgets/post-cooked";
import {
@@ -623,14 +621,18 @@ class _PluginApi {
* See KeyboardShortcuts.addShortcut documentation.
**/
addKeyboardShortcut(shortcut, callback, opts = {}) {
KeyboardShortcuts.addShortcut(shortcut, callback, opts);
this.container
.lookup("service:keyboard-shortcuts")
.addShortcut(shortcut, callback, opts);
}
/**
* See KeyboardShortcuts.unbind documentation.
**/
removeKeyboardShortcut(shortcut, callback) {
KeyboardShortcuts.unbind({ [shortcut]: callback });
this.container
.lookup("service:keyboard-shortcuts")
.unbind({ [shortcut]: callback });
}
/**
@@ -1,5 +1,7 @@
import { getOwner, setOwner } from "@ember/owner";
import { getOwner } from "@ember/owner";
import { run, throttle } from "@ember/runloop";
import Service, { service } from "@ember/service";
import ItsATrap from "@discourse/itsatrap";
import KeyboardShortcutsHelp from "discourse/components/modal/keyboard-shortcuts-help";
import { ajax } from "discourse/lib/ajax";
import domUtils from "discourse/lib/dom-utils";
@@ -141,29 +143,20 @@ function preventKeyboardEvent(event) {
event.stopPropagation();
}
export default {
init(keyTrapper, owner) {
setOwner(this, owner);
export default class KeyboardShortcutLib extends Service {
@service appEvents;
@service composer;
@service currentUser;
@service router;
@service siteSettings;
@service modal;
// Sometimes the keyboard shortcut initializer is not torn down. This makes sure
// we clear any previous test state.
if (this.keyTrapper) {
this.keyTrapper.destroy();
this.keyTrapper = null;
}
constructor() {
super(...arguments);
this.keyTrapper = new keyTrapper();
this.keyTrapper = new ItsATrap();
this._stopCallback();
this.appEvents = owner.lookup("service:app-events");
this.composer = owner.lookup("service:composer");
this.currentUser = owner.lookup("service:current-user");
this.modal = owner.lookup("service:modal");
this.router = owner.lookup("service:router");
this.searchService = owner.lookup("service:search");
this.siteSettings = owner.lookup("service:site-settings");
this.site = owner.lookup("service:site");
// Disable the shortcut if private messages are disabled
if (!this.currentUser?.can_send_private_messages) {
delete DEFAULT_BINDINGS["g m"];
@@ -172,26 +165,29 @@ export default {
if (disabledBindings.length) {
disabledBindings.forEach((binding) => delete DEFAULT_BINDINGS[binding]);
}
},
bindEvents() {
Object.keys(DEFAULT_BINDINGS).forEach((key) => {
this.bindKey(key);
});
},
this.bindEvents();
}
teardown() {
willDestroy() {
super.willDestroy(...arguments);
const prototype = Object.getPrototypeOf(this.keyTrapper);
prototype.stopCallback = this.oldStopCallback;
this.oldStopCallback = null;
this.keyTrapper?.destroy();
this.keyTrapper = null;
},
}
bindEvents() {
Object.keys(DEFAULT_BINDINGS).forEach((key) => {
this.bindKey(key);
});
}
isTornDown() {
return this.keyTrapper == null;
},
}
bindKey(key, binding = null) {
if (this.isTornDown()) {
@@ -220,7 +216,7 @@ export default {
} else if (binding.click) {
this._bindToClick(binding.click, key);
}
},
}
// for cases when you want to disable global keyboard shortcuts
// so that you can override them (e.g. inside a modal)
@@ -234,7 +230,7 @@ export default {
return;
}
combinations.forEach((combo) => this.keyTrapper.unbind(combo));
},
}
// restore global shortcuts that you have paused
unpause(combinations) {
@@ -248,7 +244,7 @@ export default {
}
combinations.forEach((combo) => this.bindKey(combo));
},
}
/**
* addShortcut(shortcut, callback, opts)
@@ -281,7 +277,7 @@ export default {
if (opts.help) {
addExtraKeyboardShortcutHelp(opts.help);
}
},
}
/**
* unbind(combinations)
@@ -295,7 +291,7 @@ export default {
*/
unbind(combinations) {
Object.keys(combinations).forEach((combo) => this.keyTrapper.unbind(combo));
},
}
toggleBookmark(event) {
const selectedPost = this._getSelectedPost();
@@ -313,7 +309,7 @@ export default {
}
this._bookmarkCurrentTopic(event);
},
}
toggleBookmarkTopic(event) {
const selectedTopicListItem = this._getSelectedTopicListItem();
@@ -324,7 +320,7 @@ export default {
}
this._bookmarkCurrentTopic(event);
},
}
_bookmarkCurrentTopic(event) {
const topic = this.currentTopic();
@@ -332,11 +328,11 @@ export default {
preventKeyboardEvent(event);
getOwner(this).lookup("controller:topic").send("toggleBookmark");
}
},
}
logout() {
getOwner(this).lookup("route:application").send("logout");
},
}
quoteReply() {
if (this.isPostTextSelected) {
@@ -352,7 +348,7 @@ export default {
);
return false;
},
}
editPost() {
if (this.siteSettings.enable_fast_edit && this.isPostTextSelected) {
@@ -363,7 +359,7 @@ export default {
}
return false;
},
}
goToNextTopic() {
nextTopicUrl().then((url) => {
@@ -371,7 +367,7 @@ export default {
DiscourseURL.routeTo(url);
}
});
},
}
goToPreviousTopic() {
previousTopicUrl().then((url) => {
@@ -379,7 +375,7 @@ export default {
DiscourseURL.routeTo(url);
}
});
},
}
goToFirstSuggestedTopic() {
const el = document.querySelector("#suggested-topics a.raw-topic-link");
@@ -399,58 +395,58 @@ export default {
}
});
}
},
}
goToFirstPost() {
this._jumpTo("jumpTop");
},
}
goToLastPost() {
this._jumpTo("jumpBottom");
},
}
goToUnreadPost() {
this._jumpTo("jumpUnread");
},
}
_jumpTo(direction) {
if (document.querySelector(".container.posts")) {
getOwner(this).lookup("controller:topic").send(direction);
}
},
}
replyToTopic() {
this._replyToPost();
return false;
},
}
selectDown() {
this._moveSelection({ direction: 1, scrollWithinPosts: true });
},
}
selectUp() {
this._moveSelection({ direction: -1, scrollWithinPosts: true });
},
}
bulkSelectItem() {
const elem = document.querySelector(
".selected input.bulk-select, .selected .select-post"
);
elem?.click();
},
}
goBack() {
history.back();
},
}
nextSection() {
this._changeSection(1);
},
}
prevSection() {
this._changeSection(-1);
},
}
printTopic(event) {
run(() => {
@@ -459,7 +455,7 @@ export default {
getOwner(this).lookup("controller:topic").print();
}
});
},
}
createTopic(event) {
if (!(this.currentUser && this.currentUser.can_create_topic)) {
@@ -506,7 +502,7 @@ export default {
action: Composer.CREATE_TOPIC,
draftKey: Composer.NEW_TOPIC_KEY,
});
},
}
focusComposer(event) {
if (event) {
@@ -514,22 +510,22 @@ export default {
event.stopPropagation();
}
this.composer.focusComposer(event);
},
}
fullscreenComposer() {
if (this.composer.get("model")) {
this.composer.toggleFullscreen();
}
},
}
pinUnpinTopic() {
getOwner(this).lookup("controller:topic").togglePinnedState();
},
}
goToPost(event) {
preventKeyboardEvent(event);
this.appEvents.trigger("topic:keyboard-trigger", { type: "jump" });
},
}
toggleSearch(event) {
this.appEvents.trigger("header:keyboard-trigger", {
@@ -538,39 +534,39 @@ export default {
});
return false;
},
}
toggleHamburgerMenu(event) {
this.appEvents.trigger("header:keyboard-trigger", {
type: "hamburger",
event,
});
},
}
showCurrentUser(event) {
this.appEvents.trigger("header:keyboard-trigger", { type: "user", event });
},
}
showHelpModal(event) {
event.preventDefault();
this.modal.show(KeyboardShortcutsHelp);
},
}
setTrackingToMuted() {
throttle(this, "_setTracking", 0, INPUT_DELAY, true);
},
}
setTrackingToRegular() {
throttle(this, "_setTracking", 1, INPUT_DELAY, true);
},
}
setTrackingToTracking() {
throttle(this, "_setTracking", 2, INPUT_DELAY, true);
},
}
setTrackingToWatching() {
throttle(this, "_setTracking", 3, INPUT_DELAY, true);
},
}
_setTracking(levelId) {
const topic = this.currentTopic();
@@ -580,7 +576,7 @@ export default {
}
topic.details.updateNotifications(levelId);
},
}
sendToTopicListItemView(action, elem) {
elem = elem || document.querySelector("tr.selected.topic-list-item");
@@ -591,7 +587,7 @@ export default {
view.send(action);
}
}
},
}
currentTopic() {
const topicController = getOwner(this).lookup("controller:topic");
@@ -601,12 +597,12 @@ export default {
return topic;
}
}
},
}
get isPostTextSelected() {
const topicController = getOwner(this).lookup("controller:topic");
return !!topicController.quoteState.postId;
},
}
sendToSelectedPost(action, elem) {
// TODO: We should keep track of the post without a CSS class
@@ -641,15 +637,15 @@ export default {
}
return false;
},
}
_bindToSelectedPost(action, binding) {
this.keyTrapper.bind(binding, () => this.sendToSelectedPost(action));
},
}
_bindToPath(path, key) {
this.keyTrapper.bind(key, () => DiscourseURL.routeTo(path));
},
}
_bindToClick(selector, binding) {
binding = binding.split(",");
@@ -670,21 +666,21 @@ export default {
selection?.click();
});
},
}
_globalBindToFunction(func, binding) {
let funcToBind = typeof func === "function" ? func : this[func];
if (typeof funcToBind === "function") {
this.keyTrapper.bindGlobal(binding, funcToBind.bind(this));
}
},
}
_bindToFunction(func, binding) {
let funcToBind = typeof func === "function" ? func : this[func];
if (typeof funcToBind === "function") {
this.keyTrapper.bind(binding, funcToBind.bind(this));
}
},
}
_moveSelection({ direction, scrollWithinPosts }) {
// Pressing a move key (J/K) very quick (i.e. keeping J or K pressed) will
@@ -840,14 +836,14 @@ export default {
const scrollRatio = direction > 0 ? 0.2 : 0.7;
this._scrollTo(articleTopPosition - window.innerHeight * scrollRatio);
},
}
_scrollTo(scrollTop) {
window.scrollTo({
top: scrollTop,
behavior: "smooth",
});
},
}
categoriesTopicsList() {
switch (this.siteSettings.desktop_category_page_style) {
@@ -865,7 +861,7 @@ export default {
default:
return [];
}
},
}
_findArticles() {
let categoriesTopicsList;
@@ -880,7 +876,7 @@ export default {
} else if ((categoriesTopicsList = this.categoriesTopicsList())) {
return categoriesTopicsList;
}
},
}
_changeSection(direction) {
if (document.querySelector(".post-stream")) {
@@ -896,7 +892,7 @@ export default {
sections[index].querySelector("a, button")?.click();
}
}
},
}
_stopCallback() {
const prototype = Object.getPrototypeOf(this.keyTrapper);
@@ -916,27 +912,27 @@ export default {
return oldCallback.call(this, e, element, combo, sequence);
};
},
}
_replyToPost() {
getOwner(this).lookup("controller:topic").send("replyToPost");
},
}
_getSelectedPost() {
return document.querySelector(".topic-post.selected article[data-post-id]");
},
}
_getSelectedTopicListItem() {
return document.querySelector("tr.selected.topic-list-item");
},
}
deferTopic() {
getOwner(this).lookup("controller:topic").send("deferTopic");
},
}
toggleAdminActions() {
document.querySelector(".toggle-admin-menu")?.click();
},
}
toggleBulkSelect() {
const bulkSelect = document.querySelector("button.bulk-select");
@@ -946,21 +942,21 @@ export default {
} else {
getOwner(this).lookup("controller:topic").send("toggleMultiSelect");
}
},
}
toggleArchivePM() {
getOwner(this).lookup("controller:topic").send("toggleArchiveMessage");
},
}
webviewKeyboardBack() {
if (capabilities.isAppWebview) {
window.history.back();
}
},
}
webviewKeyboardForward() {
if (capabilities.isAppWebview) {
window.history.forward();
}
},
};
}
}
@@ -12,13 +12,13 @@ import {
} from "@ember/test-helpers";
import { module, test } from "qunit";
import sinon from "sinon";
import { PLATFORM_KEY_MODIFIER } from "discourse/lib/keyboard-shortcuts";
import LinkLookup from "discourse/lib/link-lookup";
import { cloneJSON } from "discourse/lib/object";
import { withPluginApi } from "discourse/lib/plugin-api";
import { translateModKey } from "discourse/lib/utilities";
import Composer, { CREATE_TOPIC } from "discourse/models/composer";
import Draft from "discourse/models/draft";
import { PLATFORM_KEY_MODIFIER } from "discourse/services/keyboard-shortcuts";
import TopicFixtures from "discourse/tests/fixtures/topic";
import pretender, { response } from "discourse/tests/helpers/create-pretender";
import {
@@ -1,7 +1,7 @@
import { getOwner } from "@ember/owner";
import { click, triggerKeyEvent, visit } from "@ember/test-helpers";
import { test } from "qunit";
import sinon from "sinon";
import KeyboardShortcuts from "discourse/lib/keyboard-shortcuts";
import { withPluginApi } from "discourse/lib/plugin-api";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
@@ -27,7 +27,10 @@ acceptance("Plugin Keyboard Shortcuts - Logged In", function (needs) {
acceptance("Plugin Keyboard Shortcuts - Anonymous", function () {
test("a plugin can add a keyboard shortcut with an option", async function (assert) {
let spy = sinon.spy(KeyboardShortcuts, "_bindToPath");
let spy = sinon.spy(
getOwner(this).lookup("service:keyboard-shortcuts"),
"_bindToPath"
);
withPluginApi((api) => {
api.addKeyboardShortcut("]", () => {}, {
anonymous: true,
@@ -45,11 +45,6 @@ import { clearDesktopNotificationHandlers } from "discourse/lib/desktop-notifica
import { getOwnerWithFallback } from "discourse/lib/get-owner";
import { restoreBaseUri } from "discourse/lib/get-url";
import { cleanUpHashtagTypeClasses } from "discourse/lib/hashtag-type-registry";
import {
clearDisabledDefaultKeyboardBindings,
clearExtraKeyboardShortcutHelp,
PLATFORM_KEY_MODIFIER,
} from "discourse/lib/keyboard-shortcuts";
import { reset as resetLinkLookup } from "discourse/lib/link-lookup";
import { resetMentions } from "discourse/lib/link-mentions";
import { forceMobile, resetMobile } from "discourse/lib/mobile";
@@ -95,6 +90,11 @@ import User from "discourse/models/user";
import { clearResolverOptions } from "discourse/resolver";
import { _clearSnapshots } from "discourse/select-kit/components/composer-actions";
import { enableClearA11yAnnouncementsInTests } from "discourse/services/a11y";
import {
clearDisabledDefaultKeyboardBindings,
clearExtraKeyboardShortcutHelp,
PLATFORM_KEY_MODIFIER,
} from "discourse/services/keyboard-shortcuts";
import sessionFixtures from "discourse/tests/fixtures/session-fixtures";
import siteFixtures from "discourse/tests/fixtures/site-fixtures";
import {
@@ -1,7 +1,6 @@
import { setupTest } from "ember-qunit";
import { module, test } from "qunit";
import sinon from "sinon";
import KeyboardShortcuts from "discourse/lib/keyboard-shortcuts";
import DiscourseURL from "discourse/lib/url";
module("Unit | Utility | keyboard-shortcuts", function (hooks) {
@@ -17,21 +16,24 @@ module("Unit | Utility | keyboard-shortcuts", function (hooks) {
called = true;
});
KeyboardShortcuts.goBack();
const keyboardShortcuts = this.owner.lookup("service:keyboard-shortcuts");
keyboardShortcuts.goBack();
assert.true(called, "history.back is called");
});
test("nextSection calls _changeSection with 1", function (assert) {
let spy = sinon.spy(KeyboardShortcuts, "_changeSection");
const keyboardShortcuts = this.owner.lookup("service:keyboard-shortcuts");
let spy = sinon.spy(keyboardShortcuts, "_changeSection");
KeyboardShortcuts.nextSection();
keyboardShortcuts.nextSection();
assert.true(spy.calledWith(1), "_changeSection is called with 1");
});
test("prevSection calls _changeSection with -1", function (assert) {
let spy = sinon.spy(KeyboardShortcuts, "_changeSection");
const keyboardShortcuts = this.owner.lookup("service:keyboard-shortcuts");
let spy = sinon.spy(keyboardShortcuts, "_changeSection");
KeyboardShortcuts.prevSection();
keyboardShortcuts.prevSection();
assert.true(spy.calledWith(-1), "_changeSection is called with -1");
});
});
@@ -4,8 +4,8 @@ import { service } from "@ember/service";
import { popupAjaxError } from "discourse/lib/ajax-error";
import discourseComputed from "discourse/lib/decorators";
import { isTesting } from "discourse/lib/environment";
import { PLATFORM_KEY_MODIFIER } from "discourse/lib/keyboard-shortcuts";
import { translateModKey } from "discourse/lib/utilities";
import { PLATFORM_KEY_MODIFIER } from "discourse/services/keyboard-shortcuts";
import { i18n } from "discourse-i18n";
import { CHAT_SOUNDS } from "discourse/plugins/chat/discourse/services/chat-audio-manager";
@@ -1,5 +1,5 @@
import { PLATFORM_KEY_MODIFIER } from "discourse/lib/keyboard-shortcuts";
import { withPluginApi } from "discourse/lib/plugin-api";
import { PLATFORM_KEY_MODIFIER } from "discourse/services/keyboard-shortcuts";
import ChatModalNewMessage from "discourse/plugins/chat/discourse/components/chat/modal/new-message";
export default {
@@ -2,8 +2,8 @@ import Component from "@glimmer/component";
import { fn } from "@ember/helper";
import { service } from "@ember/service";
import DButton from "discourse/components/d-button";
import { PLATFORM_KEY_MODIFIER } from "discourse/lib/keyboard-shortcuts";
import { translateModKey } from "discourse/lib/utilities";
import { PLATFORM_KEY_MODIFIER } from "discourse/services/keyboard-shortcuts";
import { and, eq } from "discourse/truth-helpers";
import AiHelperCustomPrompt from "../components/ai-helper-custom-prompt";
@@ -1,5 +1,5 @@
import { PLATFORM_KEY_MODIFIER } from "discourse/lib/keyboard-shortcuts";
import { withPluginApi } from "discourse/lib/plugin-api";
import { PLATFORM_KEY_MODIFIER } from "discourse/services/keyboard-shortcuts";
import extractVariablesFromChatChannel from "../../lib/variables-chat-channel";
import extractVariablesFromChatThread from "../../lib/variables-chat-thread";
@@ -7,8 +7,8 @@ import {
visit,
} from "@ember/test-helpers";
import { test } from "qunit";
import { PLATFORM_KEY_MODIFIER } from "discourse/lib/keyboard-shortcuts";
import { cloneJSON } from "discourse/lib/object";
import { PLATFORM_KEY_MODIFIER } from "discourse/services/keyboard-shortcuts";
import topicFixtures from "discourse/tests/fixtures/topic";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
import selectKit from "discourse/tests/helpers/select-kit-helper";