diff --git a/browser/components/loop/content/shared/js/mixins.js b/browser/components/loop/content/shared/js/mixins.js index 4cee26e7517..67d1a9dcb73 100644 --- a/browser/components/loop/content/shared/js/mixins.js +++ b/browser/components/loop/content/shared/js/mixins.js @@ -1,6 +1,10 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ +// This mixin should be deprecated and a new solution implemented for +// processing menus and taking care of menu positioning globally. This +// new implementation should ensure all menus are positioned using the +// same method of positioning var loop = loop || {}; loop.shared = loop.shared || {}; @@ -228,6 +232,11 @@ loop.shared.mixins = (function() { menu.style.marginTop = "auto"; } + // Added call to _repositionMenu() if it exists, to allow a component to + // add specific repositioning to a menu. + if (this._repositionMenu) { + this._repositionMenu(); + } menu.style.visibility = "visible"; }, diff --git a/browser/components/loop/content/shared/js/views.js b/browser/components/loop/content/shared/js/views.js index 439ef2e07b4..439604546a7 100644 --- a/browser/components/loop/content/shared/js/views.js +++ b/browser/components/loop/content/shared/js/views.js @@ -203,11 +203,48 @@ loop.shared.views = (function(_, mozL10n) { }, /** - * Show or hide the settings menu + * Reposition Menu if cropped + * + * Added to reposition the menu if it is cropped on the left side because of + * a long text string. This function measures how much the menu is cropped + * on the left or right and adjusts the coordinates so the menu isn't cropped. + * Also, sets the left style to auto, to prevent complexity in calculations + * + * The dropdownmenu mixin needs to be revamped, along with all components + * using dropdown menus. Components should be utilizing a global function + * for menu positions and it should be consistent throughout. + * */ - handleClick: function(event) { - event.preventDefault(); - this.toggleDropdownMenu(); + _repositionMenu: function() { + if (this.refs.menu && this.state.showMenu) { + var menuNode = this.refs.menu && this.refs.menu.getDOMNode(); + + if (menuNode) { + // Amount of pixels that the dropdown needs to stay away from the edges + // of the page body. Copied from the mixin. + var boundOffset = 4; + var menuNodeRect = menuNode.getBoundingClientRect(); + var menuComputedStyle = window.getComputedStyle(menuNode); + var documentBody = this.getDOMNode().ownerDocument.body; + var bodyRect = documentBody.getBoundingClientRect(); + var menuLeft = parseFloat(menuNodeRect.left); + var menuRight = parseFloat(menuNodeRect.right); + var bodyRight = parseFloat(bodyRect.right); + + menuNode.style.left = "auto"; + + // If menu is too close or cropped on left, move right + if (menuLeft < -boundOffset) { + menuNode.style.right = + (parseFloat(menuComputedStyle.right) + menuLeft - boundOffset) + "px"; + } + // If menu is too close or cropped on right, move left + if (menuRight > bodyRight - boundOffset) { + menuNode.style.right = + (parseFloat(menuComputedStyle.right) + (menuRight - bodyRight) + boundOffset) + "px"; + } + } + } }, /** diff --git a/browser/components/loop/content/shared/js/views.jsx b/browser/components/loop/content/shared/js/views.jsx index 20fab2b1afe..25a70699dfe 100644 --- a/browser/components/loop/content/shared/js/views.jsx +++ b/browser/components/loop/content/shared/js/views.jsx @@ -203,11 +203,48 @@ loop.shared.views = (function(_, mozL10n) { }, /** - * Show or hide the settings menu + * Reposition Menu if cropped + * + * Added to reposition the menu if it is cropped on the left side because of + * a long text string. This function measures how much the menu is cropped + * on the left or right and adjusts the coordinates so the menu isn't cropped. + * Also, sets the left style to auto, to prevent complexity in calculations + * + * The dropdownmenu mixin needs to be revamped, along with all components + * using dropdown menus. Components should be utilizing a global function + * for menu positions and it should be consistent throughout. + * */ - handleClick: function(event) { - event.preventDefault(); - this.toggleDropdownMenu(); + _repositionMenu: function() { + if (this.refs.menu && this.state.showMenu) { + var menuNode = this.refs.menu && this.refs.menu.getDOMNode(); + + if (menuNode) { + // Amount of pixels that the dropdown needs to stay away from the edges + // of the page body. Copied from the mixin. + var boundOffset = 4; + var menuNodeRect = menuNode.getBoundingClientRect(); + var menuComputedStyle = window.getComputedStyle(menuNode); + var documentBody = this.getDOMNode().ownerDocument.body; + var bodyRect = documentBody.getBoundingClientRect(); + var menuLeft = parseFloat(menuNodeRect.left); + var menuRight = parseFloat(menuNodeRect.right); + var bodyRight = parseFloat(bodyRect.right); + + menuNode.style.left = "auto"; + + // If menu is too close or cropped on left, move right + if (menuLeft < -boundOffset) { + menuNode.style.right = + (parseFloat(menuComputedStyle.right) + menuLeft - boundOffset) + "px"; + } + // If menu is too close or cropped on right, move left + if (menuRight > bodyRight - boundOffset) { + menuNode.style.right = + (parseFloat(menuComputedStyle.right) + (menuRight - bodyRight) + boundOffset) + "px"; + } + } + } }, /**