Bug 907079 - Simplify reader mode style popup logic, including removing the use of the window.history API. r=mfinkle

--HG--
extra : rebase_source : 8466fd81f0a55c0ea7cf608622f6805741c21a3a
This commit is contained in:
Margaret Leibovic 2015-01-28 17:43:07 +01:00
Родитель 87b8d47c5d
Коммит 0be0977efe
2 изменённых файлов: 40 добавлений и 89 удалений

Просмотреть файл

@ -51,12 +51,11 @@ let AboutReader = function(mm, win) {
win.addEventListener("unload", this, false);
win.addEventListener("scroll", this, false);
win.addEventListener("popstate", this, false);
win.addEventListener("resize", this, false);
doc.addEventListener("visibilitychange", this, false);
this._setupAllDropdowns();
this._setupStyleDropdown();
this._setupButton("toggle-button", this._onReaderToggle.bind(this));
this._setupButton("share-button", this._onShare.bind(this));
@ -202,10 +201,6 @@ AboutReader.prototype = {
this._setToolbarVisibility(isScrollingUp);
this._scrollOffset = aEvent.pageY;
break;
case "popstate":
if (!aEvent.state)
this._closeAllDropdowns();
break;
case "resize":
this._updateImageMargins();
break;
@ -405,9 +400,8 @@ AboutReader.prototype = {
},
_setToolbarVisibility: function Reader_setToolbarVisibility(visible) {
let win = this._win;
if (win.history.state)
win.history.back();
let dropdown = this._doc.getElementById("style-dropdown");
dropdown.classList.remove("open");
if (!this._toolbarEnabled)
return;
@ -697,97 +691,53 @@ AboutReader.prototype = {
}, true);
},
_setupAllDropdowns: function Reader_setupAllDropdowns() {
_setupStyleDropdown: function Reader_setupStyleDropdown() {
let doc = this._doc;
let win = this._win;
let dropdowns = doc.getElementsByClassName("dropdown");
let dropdown = doc.getElementById("style-dropdown");
for (let i = dropdowns.length - 1; i >= 0; i--) {
let dropdown = dropdowns[i];
let dropdownToggle = dropdown.querySelector(".dropdown-toggle");
let dropdownPopup = dropdown.querySelector(".dropdown-popup");
let dropdownArrow = dropdown.querySelector(".dropdown-arrow");
let dropdownToggle = dropdown.getElementsByClassName("dropdown-toggle")[0];
let dropdownPopup = dropdown.getElementsByClassName("dropdown-popup")[0];
let updatePopupPosition = function() {
let popupWidth = dropdownPopup.offsetWidth + 30;
let arrowWidth = dropdownArrow.offsetWidth;
let toggleWidth = dropdownToggle.offsetWidth;
let toggleLeft = dropdownToggle.offsetLeft;
if (!dropdownToggle || !dropdownPopup)
continue;
let popupShift = (toggleWidth - popupWidth) / 2;
let popupLeft = Math.max(0, Math.min(win.innerWidth - popupWidth, toggleLeft + popupShift));
dropdownPopup.style.left = popupLeft + "px";
let dropdownArrow = doc.createElement("div");
dropdownArrow.className = "dropdown-arrow";
dropdownPopup.appendChild(dropdownArrow);
let arrowShift = (toggleWidth - arrowWidth) / 2;
let arrowLeft = toggleLeft - popupLeft + arrowShift;
dropdownArrow.style.left = arrowLeft + "px";
};
let updatePopupPosition = function() {
let popupWidth = dropdownPopup.offsetWidth + 30;
let arrowWidth = dropdownArrow.offsetWidth;
let toggleWidth = dropdownToggle.offsetWidth;
let toggleLeft = dropdownToggle.offsetLeft;
win.addEventListener("resize", event => {
if (!event.isTrusted)
return;
let popupShift = (toggleWidth - popupWidth) / 2;
let popupLeft = Math.max(0, Math.min(win.innerWidth - popupWidth, toggleLeft + popupShift));
dropdownPopup.style.left = popupLeft + "px";
// Wait for reflow before calculating the new position of the popup.
win.setTimeout(updatePopupPosition, 0);
}, true);
let arrowShift = (toggleWidth - arrowWidth) / 2;
let arrowLeft = toggleLeft - popupLeft + arrowShift;
dropdownArrow.style.left = arrowLeft + "px";
};
dropdownToggle.addEventListener("click", event => {
if (!event.isTrusted)
return;
win.addEventListener("resize", function(aEvent) {
if (!aEvent.isTrusted)
return;
event.stopPropagation();
// Wait for reflow before calculating the new position of the popup.
win.setTimeout(updatePopupPosition, 0);
}, true);
if (!this._getToolbarVisibility())
return;
dropdownToggle.addEventListener("click", function(aEvent) {
if (!aEvent.isTrusted)
return;
aEvent.stopPropagation();
if (!this._getToolbarVisibility())
return;
let dropdownClasses = dropdown.classList;
if (dropdownClasses.contains("open")) {
win.history.back();
} else {
updatePopupPosition();
if (!this._closeAllDropdowns())
this._pushDropdownState();
dropdownClasses.add("open");
}
}.bind(this), true);
}
},
_pushDropdownState: function Reader_pushDropdownState() {
// FIXME: We're getting a NS_ERROR_UNEXPECTED error when we try
// to do win.history.pushState() here (see bug 682296). This is
// a workaround that allows us to push history state on the target
// content document.
let doc = this._doc;
let body = doc.body;
if (this._pushStateScript)
body.removeChild(this._pushStateScript);
this._pushStateScript = doc.createElement('script');
this._pushStateScript.type = "text/javascript";
this._pushStateScript.innerHTML = 'history.pushState({ dropdown: 1 }, document.title);';
body.appendChild(this._pushStateScript);
},
_closeAllDropdowns : function Reader_closeAllDropdowns() {
let dropdowns = this._doc.querySelectorAll(".dropdown.open");
for (let i = dropdowns.length - 1; i >= 0; i--) {
dropdowns[i].classList.remove("open");
}
return (dropdowns.length > 0)
if (dropdown.classList.contains("open")) {
dropdown.classList.remove("open");
} else {
dropdown.classList.add("open");
}
}, true);
}
};

Просмотреть файл

@ -26,7 +26,7 @@
<ul id="reader-toolbar" class="toolbar toolbar-hidden">
<li><a id="share-button" class="button share-button" href="#"></a></li>
<ul class="dropdown">
<ul id="style-dropdown" class="dropdown">
<li><a class="dropdown-toggle button style-button" href="#"></a></li>
<li class="dropdown-popup">
<ul id="font-type-buttons"></ul>
@ -34,6 +34,7 @@
<ul id="font-size-buttons" class="segmented-button"></ul>
<hr></hr>
<ul id="color-scheme-buttons" class="segmented-button"></ul>
<div class="dropdown-arrow"/>
</li>
</ul>
<li><a id="toggle-button" class="button toggle-button" href="#"></a></li>