diff options
Diffstat (limited to 'client/lib/popup.js')
-rw-r--r-- | client/lib/popup.js | 204 |
1 files changed, 0 insertions, 204 deletions
diff --git a/client/lib/popup.js b/client/lib/popup.js index 8a55c2df..8095fbd2 100644 --- a/client/lib/popup.js +++ b/client/lib/popup.js @@ -206,207 +206,3 @@ escapeActions.forEach(actionName => { }, ); }); - -// Prevent @member mentions on Add Comment input field -// from closing card, part 5. -// This duplicate below of above popup function is needed, because at -// wekan/components/main/editor.js at bottom is popping up visible -// @member mention, and it seems to trigger closing also card popup, -// so in below closing popup is disabled. -window.PopupNoClose = new (class { - constructor() { - // The template we use to render popups - 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; - - // 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 = []; - - // 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 function returns a callback that can be used in an event map: - /// Template.tplName.events({ - /// 'click .elementClass': Popup.open("popupName"), - /// }); - /// The popup inherit the data context of its parent. - open(name) { - const self = this; - const popupName = `${name}Popup`; - function clickFromPopup(evt) { - 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()) { - const previousOpenerElement = self._getTopStack().openerElement; - if (previousOpenerElement === evt.currentTarget) { - self.close(); - return; - } else { - $(previousOpenerElement).removeClass('is-active'); - } - } - */ - // We determine the `openerElement` (the DOM element that is being clicked - // and the one we take in reference to position the popup) from the event - // 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; - if (clickFromPopup(evt)) { - openerElement = self._getTopStack().openerElement; - } else { - self._stack = []; - openerElement = evt.currentTarget; - } - $(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. - self._stack.push({ - popupName, - openerElement, - hasPopupParent: clickFromPopup(evt), - title: self._getTitle(popupName), - depth: self._stack.length, - offset: self._getOffset(openerElement), - dataContext: (this && 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 - // return the complete along with its top element and depends on our - // internal dependency that is being invalidated every time the top - // element of the stack has changed and we want to update the popup. - // - // 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()) { - self.current = Blaze.renderWithData( - self.template, - () => { - self._dep.depend(); - return { ...self._getTopStack(), stack: self._stack }; - }, - document.body, - ); - } else { - 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) { - const self = this; - - return function(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 Boolean(this.current); - } - - /// In case the popup was opened from a parent popup we can get back to it - /// with this `Popup.back()` function. You can go back several steps at once - /// by providing a number to this function, e.g. `Popup.back(2)`. In this case - /// intermediate popup won't even be rendered on the DOM. If the number of - /// 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(); - } - // else { - // this.close(); - //} - } - - /// Close the current opened popup. - /* - close() { - if (this.isOpen()) { - Blaze.remove(this.current); - this.current = null; - - const openerElement = this._getTopStack().openerElement; - $(openerElement).removeClass('is-active'); - - this._stack = []; - } - } - */ - - getOpenerComponent() { - const { openerElement } = Template.parentData(4); - return BlazeComponent.getComponentForElement(openerElement); - } - - // An utility fonction that returns the top element of the internal stack - _getTopStack() { - 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) { - const $element = $(element); - return () => { - Utils.windowResizeDep.depend(); - - if (Utils.isMiniScreen()) return { left: 0, top: 0 }; - - 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 - // result, we return a function that compute the result and since `TAPi18n.__` - // is a reactive data source, the title will be changed reactively. - _getTitle(popupName) { - return () => { - 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); - // when popup showed as full of small screen, we need a default header to clearly see [X] button - const defaultTitle = Utils.isMiniScreen() ? '' : false; - return title !== translationKey ? title : defaultTitle; - }; - } -})(); |