diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js index 23f76db53f..866a62b7da 100644 --- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js +++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js @@ -76,6 +76,10 @@ 'content-change': '_handleContentChange', }, + keyBindings: { + 'ctrl+s meta+s': '_handleSaveShortcut', + }, + attached() { this._getEditPrefs().then(prefs => { this._prefs = prefs; }); }, @@ -179,5 +183,10 @@ _handleContentChange(e) { if (e.detail.value) { this.set('_newContent', e.detail.value); } }, + + _handleSaveShortcut(e) { + e.preventDefault(); + if (!this._saveDisabled) { this._saveEdit(); } + }, }); })(); diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html index 5f76a17c86..18ff1f50b0 100644 --- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html +++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html @@ -299,5 +299,48 @@ suite('gr-editor-view tests', () => { element._viewEditInChangeView(); assert.equal(navStub.lastCall.args[1], element.EDIT_NAME); }); + + suite('keyboard shortcuts', () => { + // Used as the spy on the handler for each entry in keyBindings. + let handleSpy; + + suite('_handleSaveShortcut', () => { + let saveStub; + setup(() => { + handleSpy = sandbox.spy(element, '_handleSaveShortcut'); + saveStub = sandbox.stub(element, '_saveEdit'); + }); + + test('save enabled', () => { + element._content = ''; + element._newContent = '_test'; + MockInteractions.pressAndReleaseKeyOn(element, 83, 'ctrl', 's'); + flushAsynchronousOperations(); + + assert.isTrue(handleSpy.calledOnce); + assert.isTrue(saveStub.calledOnce); + + MockInteractions.pressAndReleaseKeyOn(element, 83, 'meta', 's'); + flushAsynchronousOperations(); + + assert.equal(handleSpy.callCount, 2); + assert.equal(saveStub.callCount, 2); + }); + + test('save disabled', () => { + MockInteractions.pressAndReleaseKeyOn(element, 83, 'ctrl', 's'); + flushAsynchronousOperations(); + + assert.isTrue(handleSpy.calledOnce); + assert.isFalse(saveStub.called); + + MockInteractions.pressAndReleaseKeyOn(element, 83, 'meta', 's'); + flushAsynchronousOperations(); + + assert.equal(handleSpy.callCount, 2); + assert.isFalse(saveStub.called); + }); + }); + }); });