FIX: make composer full screen shortcut work when inputs have focus (#6907)

- Uses a Mousetrap plugin for global shortcuts
- Implemented for search `ctrl+alt+f` and composer fullscreen `shift+f11` shortcuts
This commit is contained in:
Penar Musaraj 2019-02-14 00:19:27 -05:00 committed by GitHub
parent ed6f4dfc40
commit 090e9c8432
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 76 additions and 16 deletions

View File

@ -108,6 +108,13 @@ export default Ember.Component.extend({
this._resetUpload(true);
},
@observes("focusTarget")
setFocus() {
if (this.get("focusTarget") === "editor") {
this.$("textarea").putCursorAtEnd();
}
},
@computed
markdownOptions() {
return {

View File

@ -256,15 +256,6 @@ export default Ember.Component.extend({
const mouseTrap = Mousetrap(this.$(".d-editor-input")[0]);
const shortcuts = this.get("toolbar.shortcuts");
// for some reason I am having trouble bubbling this so hack it in
mouseTrap.bind(["ctrl+alt+f"], event => {
this.appEvents.trigger("header:keyboard-trigger", {
type: "search",
event
});
return true;
});
Object.keys(shortcuts).forEach(sc => {
const button = shortcuts[sc];
mouseTrap.bind(sc, () => {
@ -323,7 +314,6 @@ export default Ember.Component.extend({
Object.keys(this.get("toolbar.shortcuts")).forEach(sc =>
mouseTrap.unbind(sc)
);
mouseTrap.unbind("ctrl+/", "command+/");
this.$(".d-editor-preview").off("click.preview");
},

View File

@ -133,9 +133,10 @@ export default Ember.Controller.extend({
@computed(
"model.replyingToTopic",
"model.creatingPrivateMessage",
"model.targetUsernames"
"model.targetUsernames",
"model.composeState"
)
focusTarget(replyingToTopic, creatingPM, usernames) {
focusTarget(replyingToTopic, creatingPM, usernames, composeState) {
if (this.capabilities.isIOS) {
return "none";
}
@ -153,6 +154,10 @@ export default Ember.Controller.extend({
return "reply";
}
if (composeState === Composer.FULLSCREEN) {
return "editor";
}
return "title";
},

View File

@ -7,7 +7,7 @@ const bindings = {
"!": { postAction: "showFlags" },
"#": { handler: "goToPost", anonymous: true },
"/": { handler: "toggleSearch", anonymous: true },
"ctrl+alt+f": { handler: "toggleSearch", anonymous: true },
"ctrl+alt+f": { handler: "toggleSearch", anonymous: true, global: true },
"=": { handler: "toggleHamburgerMenu", anonymous: true },
"?": { handler: "showHelpModal", anonymous: true },
".": { click: ".alert.alert-info.clickable", anonymous: true }, // show incoming/updated topics
@ -67,7 +67,7 @@ const bindings = {
"shift+s": { click: "#topic-footer-buttons button.share", anonymous: true }, // share topic
"shift+u": { handler: "goToUnreadPost" },
"shift+z shift+z": { handler: "logout" },
"shift+f11": { handler: "fullscreenComposer" },
"shift+f11": { handler: "fullscreenComposer", global: true },
t: { postAction: "replyAsNewTopic" },
u: { handler: "goBack", anonymous: true },
"x r": {
@ -101,7 +101,12 @@ export default {
if (binding.path) {
this._bindToPath(binding.path, key);
} else if (binding.handler) {
if (binding.global) {
// global shortcuts will trigger even while focusing on input/textarea
this._globalBindToFunction(binding.handler, key);
} else {
this._bindToFunction(binding.handler, key);
}
} else if (binding.postAction) {
this._bindToSelectedPost(binding.postAction, key);
} else if (binding.click) {
@ -399,6 +404,12 @@ export default {
});
},
_globalBindToFunction(func, binding) {
if (typeof this[func] === "function") {
this.keyTrapper.bindGlobal(binding, _.bind(this[func], this));
}
},
_bindToFunction(func, binding) {
if (typeof this[func] === "function") {
this.keyTrapper.bind(binding, _.bind(this[func], this));

View File

@ -111,7 +111,8 @@
importQuote=(action "importQuote")
togglePreview=(action "togglePreview")
showToolbar=showToolbar
afterRefresh=(action "afterRefresh")}}
afterRefresh=(action "afterRefresh")
focusTarget=focusTarget}}
<div class='submit-panel'>
{{plugin-outlet name="composer-fields-below" args=(hash model=model)}}

View File

@ -22,6 +22,7 @@
//= require jquery.sortable.js
//= require lodash.js
//= require mousetrap.js
//= require mousetrap-global-bind.js
//= require rsvp.js
//= require show-html.js
//= require break_string

View File

@ -73,6 +73,8 @@ task 'javascript:update' do
destination: 'moment-locale',
}, {
source: 'moment-timezone/builds/moment-timezone-with-data.js'
}, {
source: 'mousetrap/plugins/global-bind/mousetrap-global-bind.js'
}, {
source: 'resumablejs/resumable.js'
}, {

View File

@ -0,0 +1,43 @@
/**
* adds a bindGlobal method to Mousetrap that allows you to
* bind specific keyboard shortcuts that will still work
* inside a text input field
*
* usage:
* Mousetrap.bindGlobal('ctrl+s', _saveChanges);
*/
/* global Mousetrap:true */
(function(Mousetrap) {
var _globalCallbacks = {};
var _originalStopCallback = Mousetrap.prototype.stopCallback;
Mousetrap.prototype.stopCallback = function(e, element, combo, sequence) {
var self = this;
if (self.paused) {
return true;
}
if (_globalCallbacks[combo] || _globalCallbacks[sequence]) {
return false;
}
return _originalStopCallback.call(self, e, element, combo);
};
Mousetrap.prototype.bindGlobal = function(keys, callback, action) {
var self = this;
self.bind(keys, callback, action);
if (keys instanceof Array) {
for (var i = 0; i < keys.length; i++) {
_globalCallbacks[keys[i]] = true;
}
return;
}
_globalCallbacks[keys] = true;
};
Mousetrap.init();
}) (Mousetrap);