Commit 5fa60d24 authored by Robert Knight's avatar Robert Knight

Convert `<annotation-share-dialog>` element directive to a component

As part of an effort to make it clearer how the client uses Angular,
register UI components with `component()` instead of `directive()`.

Components in Angular 1.x [1] are essentially directives with "best
practices" defaults set (restricted to elements, isolated scope, bound
to controller) and deprecated/discouraged features of $compile
disallowed. These defaults/restrictions match how we are already using
Angular for most UI components.

[1] See https://docs.angularjs.org/guide/component
parent 1c1d704c
......@@ -135,9 +135,10 @@ module.exports = angular.module('h', [
// The root component for the application
.directive('hypothesisApp', require('./directive/app'))
// UI components and helpers
// UI components
.component('annotationShareDialog', require('./directive/annotation-share-dialog'))
.directive('annotation', require('./directive/annotation').directive)
.directive('annotationShareDialog', require('./directive/annotation-share-dialog'))
.directive('annotationThread', require('./directive/annotation-thread'))
.directive('dropdownMenuBtn', require('./directive/dropdown-menu-btn'))
.directive('excerpt', require('./directive/excerpt').directive)
......
......@@ -4,73 +4,69 @@ var angular = require('angular');
var scopeTimeout = require('../util/scope-timeout');
module.exports = function () {
return {
bindToController: true,
controllerAs: 'vm',
restrict: 'E',
template: require('../templates/annotation_share_dialog.html'),
// @ngInject
controller: function ($scope, $element) {
var shareLinkInput = $element.find('input')[0];
module.exports = {
controllerAs: 'vm',
template: require('../templates/annotation_share_dialog.html'),
// @ngInject
controller: function ($scope, $element) {
var shareLinkInput = $element.find('input')[0];
$scope.$watch('vm.isOpen', function (isOpen) {
if (isOpen) {
// Focus the input and select it once the dialog has become visible
scopeTimeout($scope, function () {
shareLinkInput.focus();
shareLinkInput.select();
});
$scope.$watch('vm.isOpen', function (isOpen) {
if (isOpen) {
// Focus the input and select it once the dialog has become visible
scopeTimeout($scope, function () {
shareLinkInput.focus();
shareLinkInput.select();
});
var hideListener = function (event) {
$scope.$apply(function () {
if (!$element[0].contains(event.target)) {
document.removeEventListener('click', hideListener);
this.onClose();
}
}.bind(this));
}.bind(this);
var hideListener = function (event) {
$scope.$apply(function () {
if (!$element[0].contains(event.target)) {
document.removeEventListener('click', hideListener);
this.onClose();
}
}.bind(this));
}.bind(this);
// Stop listening for clicks outside the dialog once it is closed.
// The setTimeout() here is to ignore the initial click that opens
// the dialog.
scopeTimeout($scope, function () {
document.addEventListener('click', hideListener);
}, 0);
}
}.bind(this));
// Stop listening for clicks outside the dialog once it is closed.
// The setTimeout() here is to ignore the initial click that opens
// the dialog.
scopeTimeout($scope, function () {
document.addEventListener('click', hideListener);
}, 0);
}
}.bind(this));
this.copyToClipboard = function (event) {
var $container = angular.element(event.currentTarget).parent();
var shareLinkInput = $container.find('input')[0];
this.copyToClipboard = function (event) {
var $container = angular.element(event.currentTarget).parent();
var shareLinkInput = $container.find('input')[0];
try {
shareLinkInput.select();
try {
shareLinkInput.select();
// In some browsers, execCommand() returns false if it fails,
// in others, it may throw an exception instead.
if (!document.execCommand('copy')) {
throw new Error('Copying link failed');
}
this.copyToClipboardMessage = 'Link copied to clipboard!';
} catch (ex) {
this.copyToClipboardMessage = 'Select and copy to share.';
} finally {
setTimeout(function () {
this.copyToClipboardMessage = null;
$scope.$digest();
}.bind(this),
1000);
// In some browsers, execCommand() returns false if it fails,
// in others, it may throw an exception instead.
if (!document.execCommand('copy')) {
throw new Error('Copying link failed');
}
}.bind(this);
},
scope: {
group: '<',
uri: '<',
isPrivate: '<',
isOpen: '<',
onClose: '&',
},
};
this.copyToClipboardMessage = 'Link copied to clipboard!';
} catch (ex) {
this.copyToClipboardMessage = 'Select and copy to share.';
} finally {
setTimeout(function () {
this.copyToClipboardMessage = null;
$scope.$digest();
}.bind(this),
1000);
}
}.bind(this);
},
bindings: {
group: '<',
uri: '<',
isPrivate: '<',
isOpen: '<',
onClose: '&',
},
};
......@@ -13,7 +13,7 @@ describe('annotationShareDialog', function () {
before(function () {
angular.module('app', [])
.directive('annotationShareDialog',
.component('annotationShareDialog',
require('../annotation-share-dialog'))
.value('urlEncodeFilter', function (val) { return val; });
});
......
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