Commit 511a352b authored by Sean Hammond's avatar Sean Hammond

Merge pull request #3041 from hypothesis/focus-sidebar-for-new-annots

Focus input field after creating a new annotation
parents 0053227a dbbeadf8
......@@ -36,6 +36,13 @@ module.exports = class Host extends Guest
# Show the UI
@frame.css('display', '')
this.on 'beforeAnnotationCreated', (annotation) ->
# When a new non-highlight annotation is created, focus
# the sidebar so that the text editor can be focused as
# soon as the annotation card appears
if !annotation.$highlight
app[0].contentWindow.focus()
destroy: ->
@frame.remove()
super
......@@ -10,8 +10,9 @@ describe 'Host', ->
CrossFrame = null
fakeCrossFrame = null
createHost = (options={}) ->
element = document.createElement('div')
createHost = (options={}, element=null) ->
if !element
element = document.createElement('div')
return new Host(element, options)
beforeEach ->
......@@ -41,6 +42,34 @@ describe 'Host', ->
host.publish('panelReady')
assert.equal(host.frame.css('display'), '')
describe 'focus', ->
element = null
frame = null
host = null
beforeEach ->
element = document.createElement('div')
document.body.appendChild(element)
host = createHost({}, element)
frame = element.querySelector('[name=hyp_sidebar_frame]')
sinon.spy(frame.contentWindow, 'focus')
afterEach ->
frame.contentWindow.focus.restore()
element.parentNode.removeChild(element)
it 'focuses the sidebar when a new annotation is created', ->
host.publish('beforeAnnotationCreated', [{
$highlight: false,
}])
assert.called(frame.contentWindow.focus)
it 'does not focus the sidebar when a new highlight is created', ->
host.publish('beforeAnnotationCreated', [{
$highlight: true,
}])
assert.notCalled(frame.contentWindow.focus)
describe 'options', ->
it 'disables highlighting if showHighlights: false is given', (done) ->
host = createHost(showHighlights: false)
......
......@@ -34,7 +34,7 @@ var loadMathJax = function() {
* the markdown editor.
*/
// @ngInject
module.exports = function($filter, $sanitize, $sce, $timeout) {
module.exports = function($filter, $sanitize, $sce) {
return {
link: function(scope, elem, attr, ctrl) {
if (!(typeof ctrl !== "undefined" && ctrl !== null)) { return; }
......@@ -63,6 +63,16 @@ module.exports = function($filter, $sanitize, $sce, $timeout) {
input.focus();
}
function focusInput() {
// When the visibility of the editor changes, focus it.
// A timeout is used so that focus() is not called until
// the visibility change has been applied (by adding or removing
// the relevant CSS classes)
setTimeout(function () {
input.focus();
}, 0);
}
scope.insertBold = function() {
updateState(function (state) {
return commands.toggleSpanStyle(state, '**', '**', 'Bold');
......@@ -145,7 +155,7 @@ module.exports = function($filter, $sanitize, $sce, $timeout) {
return ctrl.$render();
} else {
input.style.height = output.style.height;
return $timeout(function() { return input.focus(); });
focusInput();
}
}
};
......@@ -265,12 +275,12 @@ module.exports = function($filter, $sanitize, $sce, $timeout) {
// Reset height of output div in case it has been changed.
// Re-render when it becomes uneditable.
// Auto-focus the input box when the widget becomes editable.
return scope.$watch('readOnly', function(readOnly) {
scope.$watch('readOnly', function(readOnly) {
scope.preview = false;
output.style.height = "";
ctrl.$render();
if (!readOnly) {
input.focus();
focusInput();
}
});
},
......
......@@ -229,7 +229,10 @@ module.exports = [
ctrl.container = thread
if ctrl.isNew()
# Scroll the sidebar to show new annotations.
$location.hash(ctrl.id)
# Note that only top level annotation cards have their ID set
annotationCard = document.getElementById(ctrl.id)
if annotationCard
annotationCard.scrollIntoView();
scope.$digest()
controller: ThreadController
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment