summaryrefslogtreecommitdiffstats
path: root/client/lib/popup.js
diff options
context:
space:
mode:
Diffstat (limited to 'client/lib/popup.js')
-rw-r--r--client/lib/popup.js123
1 files changed, 60 insertions, 63 deletions
diff --git a/client/lib/popup.js b/client/lib/popup.js
index b2340e04..3c39af29 100644
--- a/client/lib/popup.js
+++ b/client/lib/popup.js
@@ -1,55 +1,53 @@
// A simple tracker dependency that we invalidate every time the window is
// resized. This is used to reactively re-calculate the popup position in case
// of a window resize. This is the equivalent of a "Signal" in some other
-// programming environments.
-let windowResizeDep = new Tracker.Dependency()
-$(window).on('resize', () => windowResizeDep.changed())
+// programming environments (eg, elm).
+const windowResizeDep = new Tracker.Dependency();
+$(window).on('resize', () => windowResizeDep.changed());
window.Popup = new class {
constructor() {
// The template we use to render popups
- this.template = Template.popup
+ this.template = Template.popup;
// We only want to display one popup at a time and we keep the view object
// in this `Popup._current` variable. If there is no popup currently opened
// the value is `null`.
- this._current = null
+ this._current = null;
// It's possible to open a sub-popup B from a popup A. In that case we keep
// the data of popup A so we can return back to it. Every time we open a new
// popup the stack grows, every time we go back the stack decrease, and if
// we close the popup the stack is reseted to the empty stack [].
- this._stack = []
+ this._stack = [];
// We invalidate this internal dependency every time the top of the stack
// has changed and we want to re-render a popup with the new top-stack data.
- this._dep = new Tracker.Dependency()
+ this._dep = new Tracker.Dependency();
}
/// This function returns a callback that can be used in an event map:
- ///
/// Template.tplName.events({
- /// 'click .elementClass': Popup.open("popupName")
- /// })
- ///
+ /// 'click .elementClass': Popup.open("popupName"),
+ /// });
/// The popup inherit the data context of its parent.
open(name) {
- let self = this
- const popupName = `${name}Popup`
+ const self = this;
+ const popupName = `${name}Popup`;
function clickFromPopup(evt) {
- return $(evt.target).closest('.js-pop-over').length !== 0
+ return $(evt.target).closest('.js-pop-over').length !== 0;
}
return function(evt) {
// If a popup is already opened, clicking again on the opener element
// should close it -- and interrupt the current `open` function.
if (self.isOpen()) {
- let previousOpenerElement = self._getTopStack().openerElement
+ const previousOpenerElement = self._getTopStack().openerElement;
if (previousOpenerElement === evt.currentTarget) {
- return self.close()
+ return self.close();
} else {
- $(previousOpenerElement).removeClass('is-active')
+ $(previousOpenerElement).removeClass('is-active');
}
}
@@ -58,16 +56,16 @@ window.Popup = new class {
// if the popup has no parent, or from the parent `openerElement` if it
// has one. This allows us to position a sub-popup exactly at the same
// position than its parent.
- let openerElement
+ let openerElement;
if (clickFromPopup(evt)) {
- openerElement = self._getTopStack().openerElement
+ openerElement = self._getTopStack().openerElement;
} else {
- self._stack = []
- openerElement = evt.currentTarget
+ self._stack = [];
+ openerElement = evt.currentTarget;
}
- $(openerElement).addClass('is-active')
- evt.preventDefault()
+ $(openerElement).addClass('is-active');
+ evt.preventDefault();
// We push our popup data to the stack. The top of the stack is always
// used as the data source for our current popup.
@@ -79,7 +77,7 @@ window.Popup = new class {
depth: self._stack.length,
offset: self._getOffset(openerElement),
dataContext: this.currentData && this.currentData() || this,
- })
+ });
// If there are no popup currently opened we use the Blaze API to render
// one into the DOM. We use a reactive function as the data parameter that
@@ -90,39 +88,38 @@ window.Popup = new class {
// Otherwise if there is already a popup open we just need to invalidate
// our internal dependency, and since we just changed the top element of
// our internal stack, the popup will be updated with the new data.
- if (! self.isOpen()) {
+ if (!self.isOpen()) {
self.current = Blaze.renderWithData(self.template, () => {
- self._dep.depend()
- return _.extend(self._getTopStack(), { stack: self._stack })
- }, document.body)
+ self._dep.depend();
+ return _.extend(self._getTopStack(), { stack: self._stack });
+ }, document.body);
} else {
- self._dep.changed()
+ self._dep.changed();
}
- }
+ };
}
/// This function returns a callback that can be used in an event map:
- ///
/// Template.tplName.events({
/// 'click .elementClass': Popup.afterConfirm("popupName", function() {
/// // What to do after the user has confirmed the action
- /// })
- /// })
+ /// }),
+ /// });
afterConfirm(name, action) {
- let self = this
+ const self = this;
return function(evt, tpl) {
- let context = this.currentData && this.currentData() || this
- context.__afterConfirmAction = action
- self.open(name).call(context, evt, tpl)
- }
+ const context = this.currentData && this.currentData() || this;
+ context.__afterConfirmAction = action;
+ self.open(name).call(context, evt, tpl);
+ };
}
/// The public reactive state of the popup.
isOpen() {
- this._dep.changed()
- return !! this.current
+ this._dep.changed();
+ return Boolean(this.current);
}
/// In case the popup was opened from a parent popup we can get back to it
@@ -132,45 +129,45 @@ window.Popup = new class {
/// steps back is greater than the popup stack size, the popup will be closed.
back(n = 1) {
if (this._stack.length > n) {
- _.times(n, () => this._stack.pop())
- this._dep.changed()
+ _.times(n, () => this._stack.pop());
+ this._dep.changed();
} else {
- this.close()
+ this.close();
}
}
/// Close the current opened popup.
close() {
if (this.isOpen()) {
- Blaze.remove(this.current)
- this.current = null
+ Blaze.remove(this.current);
+ this.current = null;
- let openerElement = this._getTopStack().openerElement
- $(openerElement).removeClass('is-active')
+ const openerElement = this._getTopStack().openerElement;
+ $(openerElement).removeClass('is-active');
- this._stack = []
+ this._stack = [];
}
}
// An utility fonction that returns the top element of the internal stack
_getTopStack() {
- return this._stack[this._stack.length - 1]
+ return this._stack[this._stack.length - 1];
}
// We automatically calculate the popup offset from the reference element
// position and dimensions. We also reactively use the window dimensions to
// ensure that the popup is always visible on the screen.
_getOffset(element) {
- let $element = $(element)
+ const $element = $(element);
return () => {
- windowResizeDep.depend()
- const offset = $element.offset()
- const popupWidth = 300 + 15
+ windowResizeDep.depend();
+ const offset = $element.offset();
+ const popupWidth = 300 + 15;
return {
left: Math.min(offset.left, $(window).width() - popupWidth),
top: offset.top + $element.outerHeight(),
- }
- }
+ };
+ };
}
// We get the title from the translation files. Instead of returning the
@@ -178,22 +175,22 @@ window.Popup = new class {
// is a reactive data source, the title will be changed reactively.
_getTitle(popupName) {
return () => {
- const translationKey = `${popupName}-title`
+ const translationKey = `${popupName}-title`;
// XXX There is no public API to check if there is an available
// translation for a given key. So we try to translate the key and if the
// translation output equals the key input we deduce that no translation
// was available and returns `false`. There is a (small) risk a false
// positives.
- const title = TAPi18n.__(translationKey)
- return title !== translationKey ? title : false
- }
+ const title = TAPi18n.__(translationKey);
+ return title !== translationKey ? title : false;
+ };
}
-}
+};
// We close a potential opened popup on any left click on the document, or go
// one step back by pressing escape.
-const escapeActions = ['back', 'close']
+const escapeActions = ['back', 'close'];
_.each(escapeActions, (actionName) => {
EscapeActions.register(`popup-${actionName}`,
() => Popup[actionName](),
@@ -202,6 +199,6 @@ _.each(escapeActions, (actionName) => {
noClickEscapeOn: '.js-pop-over',
enabledOnClick: actionName === 'close',
}
- )
-})
+ );
+});