author | Carsten "Tomcat" Book <cbook@mozilla.com> |
Tue, 07 Jan 2014 09:35:50 +0100 | |
changeset 162243 | e7a366c1036c8f61372a462b6bc4a8620f852fa7 |
parent 162242 | ce917d3dd7c8a100f43a645241d8feb711cd1dc6 |
child 162250 | c50558a3a6160ea8fcda1d0cb849b7153d682bf6 |
child 162267 | 972dd693614f7af7f23e8087bda4dd8ce3da4a60 |
child 162345 | 5734ebc705fdeab0f0590f48e2ba8218b6949c75 |
push id | 25942 |
push user | cbook@mozilla.com |
push date | Tue, 07 Jan 2014 08:38:37 +0000 |
treeherder | mozilla-central@e7a366c1036c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 935815 |
milestone | 29.0a1 |
first release with | nightly linux32
e7a366c1036c
/
29.0a1
/
20140107030202
/
files
nightly linux64
e7a366c1036c
/
29.0a1
/
20140107030202
/
files
nightly mac
e7a366c1036c
/
29.0a1
/
20140107030202
/
files
nightly win32
e7a366c1036c
/
29.0a1
/
20140107030202
/
files
nightly win64
e7a366c1036c
/
29.0a1
/
20140107030202
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
29.0a1
/
20140107030202
/
pushlog to previous
nightly linux64
29.0a1
/
20140107030202
/
pushlog to previous
nightly mac
29.0a1
/
20140107030202
/
pushlog to previous
nightly win32
29.0a1
/
20140107030202
/
pushlog to previous
nightly win64
29.0a1
/
20140107030202
/
pushlog to previous
|
--- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -197,26 +197,18 @@ <panel id="UITourTooltip" type="arrow" hidden="true" noautofocus="true" noautohide="true" align="start" orient="vertical" role="alert"> - <hbox> - <vbox> - <image id="UITourTooltipIcon"/> - </vbox> - <vbox flex="1"> - <label id="UITourTooltipTitle" flex="1"/> - <description id="UITourTooltipDescription" flex="1"/> - <hbox id="UITourTooltipButtons" flex="1" align="end"/> - </vbox> - </hbox> + <label id="UITourTooltipTitle" flex="1"/> + <description id="UITourTooltipDescription" flex="1"/> </panel> <panel id="UITourHighlightContainer" hidden="true" noautofocus="true" noautohide="true" consumeoutsideclicks="false"> <box id="UITourHighlight"></box> </panel>
--- a/browser/modules/UITour.jsm +++ b/browser/modules/UITour.jsm @@ -17,17 +17,16 @@ XPCOMUtils.defineLazyModuleGetter(this, XPCOMUtils.defineLazyModuleGetter(this, "PermissionsUtils", "resource://gre/modules/PermissionsUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI", "resource:///modules/CustomizableUI.jsm"); const UITOUR_PERMISSION = "uitour"; const PREF_PERM_BRANCH = "browser.uitour."; -const MAX_BUTTONS = 4; this.UITour = { originTabs: new WeakMap(), pinnedTabs: new WeakMap(), urlbarCapture: new WeakMap(), appMenuOpenForAnnotation: new Set(), @@ -121,44 +120,17 @@ this.UITour = { case "showInfo": { let targetPromise = this.getTarget(window, data.target, true); targetPromise.then(target => { if (!target.node) { Cu.reportError("UITour: Target could not be resolved: " + data.target); return; } - - let iconURL = null; - if (typeof data.icon == "string") - iconURL = this.resolveURL(contentDocument, data.icon); - - let buttons = []; - if (Array.isArray(data.buttons) && data.buttons.length > 0) { - for (let buttonData of data.buttons) { - if (typeof buttonData == "object" && - typeof buttonData.label == "string" && - typeof buttonData.callbackID == "string") { - let button = { - label: buttonData.label, - callbackID: buttonData.callbackID, - }; - - if (typeof buttonData.icon == "string") - button.iconURL = this.resolveURL(contentDocument, buttonData.icon); - - buttons.push(button); - - if (buttons.length == MAX_BUTTONS) - break; - } - } - } - - this.showInfo(contentDocument, target, data.title, data.text, iconURL, buttons); + this.showInfo(target, data.title, data.text); }).then(null, Cu.reportError); break; } case "hideInfo": { this.hideInfo(window); break; } @@ -326,68 +298,28 @@ this.UITour = { if (aDocument.defaultView.top != aDocument.defaultView) return false; let uri = aDocument.documentURIObject; if (uri.schemeIs("chrome")) return true; - if (!this.isSafeScheme(uri)) + let allowedSchemes = new Set(["https"]); + if (!Services.prefs.getBoolPref("browser.uitour.requireSecure")) + allowedSchemes.add("http"); + + if (!allowedSchemes.has(uri.scheme)) return false; this.importPermissions(); let permission = Services.perms.testPermission(uri, UITOUR_PERMISSION); return permission == Services.perms.ALLOW_ACTION; }, - isSafeScheme: function(aURI) { - let allowedSchemes = new Set(["https"]); - if (!Services.prefs.getBoolPref("browser.uitour.requireSecure")) - allowedSchemes.add("http"); - - if (!allowedSchemes.has(aURI.scheme)) - return false; - - return true; - }, - - resolveURL: function(aDocument, aURL) { - try { - let uri = Services.io.newURI(aURL, null, aDocument.documentURIObject); - - if (!this.isSafeScheme(uri)) - return null; - - return uri.spec; - } catch (e) {} - - return null; - }, - - sendPageCallback: function(aDocument, aCallbackID, aData = {}) { - let detail = Cu.createObjectIn(aDocument.defaultView); - detail.data = Cu.createObjectIn(detail); - - for (let key of Object.keys(aData)) - detail.data[key] = aData[key]; - - Cu.makeObjectPropsNormal(detail.data); - Cu.makeObjectPropsNormal(detail); - - detail.callbackID = aCallbackID; - - let event = new aDocument.defaultView.CustomEvent("mozUITourResponse", { - bubbles: true, - detail: detail - }); - - aDocument.dispatchEvent(event); - }, - getTarget: function(aWindow, aTargetName, aSticky = false) { let deferred = Promise.defer(); if (typeof aTargetName != "string" || !aTargetName) { deferred.reject("Invalid target name specified"); return deferred.promise; } if (aTargetName == "pinnedTab") { @@ -569,76 +501,46 @@ this.UITour = { let highlighter = aWindow.document.getElementById("UITourHighlight"); highlighter.parentElement.hidePopup(); highlighter.removeAttribute("active"); this._setAppMenuStateForAnnotation(aWindow, "highlight", false); }, - showInfo: function(aContentDocument, aAnchor, aTitle = "", aDescription = "", aIconURL = "", aButtons = []) { + showInfo: function(aAnchor, aTitle, aDescription) { function showInfoPanel(aAnchorEl) { aAnchorEl.focus(); let document = aAnchorEl.ownerDocument; let tooltip = document.getElementById("UITourTooltip"); let tooltipTitle = document.getElementById("UITourTooltipTitle"); let tooltipDesc = document.getElementById("UITourTooltipDescription"); - let tooltipIcon = document.getElementById("UITourTooltipIcon"); - let tooltipButtons = document.getElementById("UITourTooltipButtons"); if (tooltip.state == "open") { tooltip.hidePopup(); } - tooltipTitle.textContent = aTitle || ""; - tooltipDesc.textContent = aDescription || ""; - tooltipIcon.src = aIconURL || ""; - tooltipIcon.hidden = !aIconURL; - - while (tooltipButtons.firstChild) - tooltipButtons.firstChild.remove(); - - for (let button of aButtons) { - let el = document.createElement("button"); - el.setAttribute("label", button.label); - if (button.iconURL) - el.setAttribute("image", button.iconURL); - - let callbackID = button.callbackID; - el.addEventListener("command", event => { - tooltip.hidePopup(); - this.sendPageCallback(aContentDocument, callbackID); - }); - - tooltipButtons.appendChild(el); - } - - tooltipButtons.hidden = !aButtons.length; + tooltipTitle.textContent = aTitle; + tooltipDesc.textContent = aDescription; tooltip.hidden = false; let alignment = "bottomcenter topright"; tooltip.openPopup(aAnchorEl, alignment); } this._setAppMenuStateForAnnotation(aAnchor.node.ownerDocument.defaultView, "info", this.targetIsInAppMenu(aAnchor), showInfoPanel.bind(this, aAnchor.node)); }, hideInfo: function(aWindow) { - let document = aWindow.document; - - let tooltip = document.getElementById("UITourTooltip"); + let tooltip = aWindow.document.getElementById("UITourTooltip"); tooltip.hidePopup(); this._setAppMenuStateForAnnotation(aWindow, "info", false); - - let tooltipButtons = document.getElementById("UITourTooltipButtons"); - while (tooltipButtons.firstChild) - tooltipButtons.firstChild.remove(); }, showMenu: function(aWindow, aMenuName, aOpenCallback = null) { function openMenuButton(aId) { let menuBtn = aWindow.document.getElementById(aId); if (!menuBtn || !menuBtn.boxObject) { aOpenCallback(); return;
--- a/browser/modules/test/browser.ini +++ b/browser/modules/test/browser.ini @@ -1,10 +1,10 @@ [DEFAULT] support-files = head.js [browser_NetworkPrioritizer.js] [browser_SignInToWebsite.js] [browser_UITour.js] -support-files = uitour.* image.png +support-files = uitour.* [browser_taskbar_preview.js] run-if = os == "win"
--- a/browser/modules/test/browser_UITour.js +++ b/browser/modules/test/browser_UITour.js @@ -1,15 +1,14 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; let gTestTab; -let gContentWindow; let gContentAPI; Components.utils.import("resource:///modules/UITour.jsm"); function is_hidden(element) { var style = element.ownerDocument.defaultView.getComputedStyle(element, ""); if (style.display == "none") return true; @@ -62,33 +61,32 @@ function loadTestPage(callback, host = " url = url.replace("chrome://mochitests/content/", host); gTestTab = gBrowser.addTab(url); gBrowser.selectedTab = gTestTab; gTestTab.linkedBrowser.addEventListener("load", function onLoad() { gTestTab.linkedBrowser.removeEventListener("load", onLoad); - gContentWindow = Components.utils.waiveXrays(gTestTab.linkedBrowser.contentDocument.defaultView); - gContentAPI = gContentWindow.Mozilla.UITour; + let contentWindow = Components.utils.waiveXrays(gTestTab.linkedBrowser.contentDocument.defaultView); + gContentAPI = contentWindow.Mozilla.UITour; - waitForFocus(callback, gContentWindow); + waitForFocus(callback, contentWindow); }, true); } function test() { Services.prefs.setBoolPref("browser.uitour.enabled", true); let testUri = Services.io.newURI("http://example.com", null, null); Services.perms.add(testUri, "uitour", Services.perms.ALLOW_ACTION); waitForExplicitFinish(); registerCleanupFunction(function() { delete window.UITour; - delete window.gContentWindow; delete window.gContentAPI; if (gTestTab) gBrowser.removeTab(gTestTab); delete window.gTestTab; Services.prefs.clearUserPref("browser.uitour.enabled", true); Services.perms.remove("example.com", "uitour"); }); @@ -282,26 +280,21 @@ let tests = [ gContentAPI.showHighlight("urlbar", "__UNSUPPORTED__"); waitForElementToBeVisible(highlight, checkUnsupportedEffect, "Highlight should be shown after showHighlight()"); }, function test_info_1(done) { let popup = document.getElementById("UITourTooltip"); let title = document.getElementById("UITourTooltipTitle"); let desc = document.getElementById("UITourTooltipDescription"); - let icon = document.getElementById("UITourTooltipIcon"); - let buttons = document.getElementById("UITourTooltipButtons"); - popup.addEventListener("popupshown", function onPopupShown() { popup.removeEventListener("popupshown", onPopupShown); is(popup.popupBoxObject.anchorNode, document.getElementById("urlbar"), "Popup should be anchored to the urlbar"); is(title.textContent, "test title", "Popup should have correct title"); is(desc.textContent, "test text", "Popup should have correct description text"); - is(icon.src, "", "Popup should have no icon"); - is(buttons.hasChildNodes(), false, "Popup should have no buttons"); popup.addEventListener("popuphidden", function onPopupHidden() { popup.removeEventListener("popuphidden", onPopupHidden); popup.addEventListener("popupshown", function onPopupShown() { popup.removeEventListener("popupshown", onPopupShown); done(); }); @@ -313,26 +306,21 @@ let tests = [ }); gContentAPI.showInfo("urlbar", "test title", "test text"); }, function test_info_2(done) { let popup = document.getElementById("UITourTooltip"); let title = document.getElementById("UITourTooltipTitle"); let desc = document.getElementById("UITourTooltipDescription"); - let icon = document.getElementById("UITourTooltipIcon"); - let buttons = document.getElementById("UITourTooltipButtons"); - popup.addEventListener("popupshown", function onPopupShown() { popup.removeEventListener("popupshown", onPopupShown); is(popup.popupBoxObject.anchorNode, document.getElementById("urlbar"), "Popup should be anchored to the urlbar"); is(title.textContent, "urlbar title", "Popup should have correct title"); is(desc.textContent, "urlbar text", "Popup should have correct description text"); - is(icon.src, "", "Popup should have no icon"); - is(buttons.hasChildNodes(), false, "Popup should have no buttons"); gContentAPI.showInfo("search", "search title", "search text"); executeSoon(function() { is(popup.popupBoxObject.anchorNode, document.getElementById("searchbar"), "Popup should be anchored to the searchbar"); is(title.textContent, "search title", "Popup should have correct title"); is(desc.textContent, "search text", "Popup should have correct description text"); done(); @@ -384,124 +372,16 @@ let tests = [ gContentAPI.hideMenu("appMenu"); ok(!PanelUI.panel.hasAttribute("noautohide"), "@noautohide on the menu panel should have been cleaned up on close"); done(); }, "Info should move to the appMenu button"); }); }, "Info should be shown after showInfo() for fixed menu panel items"); }); }, - function test_info_icon(done) { - let popup = document.getElementById("UITourTooltip"); - let title = document.getElementById("UITourTooltipTitle"); - let desc = document.getElementById("UITourTooltipDescription"); - let icon = document.getElementById("UITourTooltipIcon"); - let buttons = document.getElementById("UITourTooltipButtons"); - - popup.addEventListener("popupshown", function onPopupShown() { - popup.removeEventListener("popupshown", onPopupShown); - - is(title.textContent, "a title", "Popup should have correct title"); - is(desc.textContent, "some text", "Popup should have correct description text"); - - let imageURL = getRootDirectory(gTestPath) + "image.png"; - imageURL = imageURL.replace("chrome://mochitests/content/", "https://example.com/"); - is(icon.src, imageURL, "Popup should have correct icon shown"); - - is(buttons.hasChildNodes(), false, "Popup should have no buttons"); - - done(); - }); - - gContentAPI.showInfo("urlbar", "a title", "some text", "image.png"); - }, - function test_info_buttons_1(done) { - let popup = document.getElementById("UITourTooltip"); - let title = document.getElementById("UITourTooltipTitle"); - let desc = document.getElementById("UITourTooltipDescription"); - let icon = document.getElementById("UITourTooltipIcon"); - - popup.addEventListener("popupshown", function onPopupShown() { - popup.removeEventListener("popupshown", onPopupShown); - - is(title.textContent, "another title", "Popup should have correct title"); - is(desc.textContent, "moar text", "Popup should have correct description text"); - - let imageURL = getRootDirectory(gTestPath) + "image.png"; - imageURL = imageURL.replace("chrome://mochitests/content/", "https://example.com/"); - is(icon.src, imageURL, "Popup should have correct icon shown"); - - let buttons = document.getElementById("UITourTooltipButtons"); - is(buttons.childElementCount, 2, "Popup should have two buttons"); - - is(buttons.childNodes[0].getAttribute("label"), "Button 1", "First button should have correct label"); - is(buttons.childNodes[0].getAttribute("image"), "", "First button should have no image"); - - is(buttons.childNodes[1].getAttribute("label"), "Button 2", "Second button should have correct label"); - is(buttons.childNodes[1].getAttribute("image"), imageURL, "Second button should have correct image"); - - popup.addEventListener("popuphidden", function onPopupHidden() { - popup.removeEventListener("popuphidden", onPopupHidden); - ok(true, "Popup should close automatically"); - - executeSoon(function() { - is(gContentWindow.callbackResult, "button1", "Correct callback should have been called"); - - done(); - }); - }); - - EventUtils.synthesizeMouseAtCenter(buttons.childNodes[0], {}, window); - }); - - let buttons = gContentWindow.makeButtons(); - gContentAPI.showInfo("urlbar", "another title", "moar text", "./image.png", buttons); - }, - function test_info_buttons_2(done) { - let popup = document.getElementById("UITourTooltip"); - let title = document.getElementById("UITourTooltipTitle"); - let desc = document.getElementById("UITourTooltipDescription"); - let icon = document.getElementById("UITourTooltipIcon"); - - popup.addEventListener("popupshown", function onPopupShown() { - popup.removeEventListener("popupshown", onPopupShown); - - is(title.textContent, "another title", "Popup should have correct title"); - is(desc.textContent, "moar text", "Popup should have correct description text"); - - let imageURL = getRootDirectory(gTestPath) + "image.png"; - imageURL = imageURL.replace("chrome://mochitests/content/", "https://example.com/"); - is(icon.src, imageURL, "Popup should have correct icon shown"); - - let buttons = document.getElementById("UITourTooltipButtons"); - is(buttons.childElementCount, 2, "Popup should have two buttons"); - - is(buttons.childNodes[0].getAttribute("label"), "Button 1", "First button should have correct label"); - is(buttons.childNodes[0].getAttribute("image"), "", "First button should have no image"); - - is(buttons.childNodes[1].getAttribute("label"), "Button 2", "Second button should have correct label"); - is(buttons.childNodes[1].getAttribute("image"), imageURL, "Second button should have correct image"); - - popup.addEventListener("popuphidden", function onPopupHidden() { - popup.removeEventListener("popuphidden", onPopupHidden); - ok(true, "Popup should close automatically"); - - executeSoon(function() { - is(gContentWindow.callbackResult, "button2", "Correct callback should have been called"); - - done(); - }); - }); - - EventUtils.synthesizeMouseAtCenter(buttons.childNodes[1], {}, window); - }); - - let buttons = gContentWindow.makeButtons(); - gContentAPI.showInfo("urlbar", "another title", "moar text", "./image.png", buttons); - }, function test_pinnedTab(done) { is(UITour.pinnedTabs.get(window), null, "Should not already have a pinned tab"); gContentAPI.addPinnedTab(); let tabInfo = UITour.pinnedTabs.get(window); isnot(tabInfo, null, "Should have recorded data about a pinned tab after addPinnedTab()"); isnot(tabInfo.tab, null, "Should have added a pinned tab after addPinnedTab()"); is(tabInfo.tab.pinned, true, "Tab should be marked as pinned");
deleted file mode 100644 index 597c7fd2cbd328857894d0d4aefcdafcb9feea36..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@<O00001
--- a/browser/modules/test/uitour.html +++ b/browser/modules/test/uitour.html @@ -1,31 +1,15 @@ <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>UITour test</title> <script type="application/javascript" src="uitour.js"> </script> - <script type="application/javascript"> - var callbackResult; - function makeCallback(name) { - return (function() { - callbackResult = name; - }); - } - - // Defined in content to avoid weird issues when crossing between chrome/content. - function makeButtons() { - return [ - {label: "Button 1", callback: makeCallback("button1")}, - {label: "Button 2", callback: makeCallback("button2"), icon: "image.png"} - ]; - } - </script> </head> <body> <h1>UITour tests</h1> <p>Because Firefox is...</p> <p>Never gonna let you down</p> <p>Never gonna give you up</p> </body> </html>
--- a/browser/modules/test/uitour.js +++ b/browser/modules/test/uitour.js @@ -20,80 +20,47 @@ if (typeof Mozilla == 'undefined') { var themeIntervalId = null; function _stopCyclingThemes() { if (themeIntervalId) { clearInterval(themeIntervalId); themeIntervalId = null; } } + function _sendEvent(action, data) { var event = new CustomEvent('mozUITour', { bubbles: true, detail: { action: action, data: data || {} } }); - + console.log("Sending mozUITour event: ", event); document.dispatchEvent(event); } - function _generateCallbackID() { - return Math.random().toString(36).replace(/[^a-z]+/g, ''); - } - - function _waitForCallback(callback) { - var id = _generateCallbackID(); - - function listener(event) { - if (typeof event.detail != "object") - return; - if (event.detail.callbackID != id) - return; - - document.removeEventListener("mozUITourResponse", listener); - callback(event.detail.data); - } - document.addEventListener("mozUITourResponse", listener); - - return id; - } - Mozilla.UITour.DEFAULT_THEME_CYCLE_DELAY = 10 * 1000; Mozilla.UITour.showHighlight = function(target, effect) { _sendEvent('showHighlight', { target: target, effect: effect }); }; Mozilla.UITour.hideHighlight = function() { _sendEvent('hideHighlight'); }; - Mozilla.UITour.showInfo = function(target, title, text, icon, buttons) { - var buttonData = []; - if (Array.isArray(buttons)) { - for (var i = 0; i < buttons.length; i++) { - buttonData.push({ - label: buttons[i].label, - icon: buttons[i].icon, - callbackID: _waitForCallback(buttons[i].callback) - }); - } - } - + Mozilla.UITour.showInfo = function(target, title, text) { _sendEvent('showInfo', { target: target, title: title, - text: text, - icon: icon, - buttons: buttonData + text: text }); }; Mozilla.UITour.hideInfo = function() { _sendEvent('hideInfo'); }; Mozilla.UITour.previewTheme = function(theme) {
--- a/browser/themes/shared/UITour.inc.css +++ b/browser/themes/shared/UITour.inc.css @@ -17,33 +17,21 @@ background-image: radial-gradient(50% 100%, rgba(0,149,220,0.4) 50%, rgba(0,149,220,0.6) 100%); border-radius: 40px; border: 1px solid white; box-shadow: 0 0 3px 0 rgba(0,0,0,0.5); min-height: 32px; min-width: 32px; } -#UITourTooltipIcon { - width: 48px; - height: 48px; - padding: 8px; +#UITourTooltip { + max-width: 20em; } #UITourTooltipTitle { font-size: 130%; font-weight: bold; margin: 0 0 5px 0; } #UITourTooltipDescription { max-width: 20em; } - -#UITourTooltipButtons { - height: 5em; -} - -#UITourTooltipButtons > button[image] > .button-box > .button-icon { - width: 16px; - height: 16px; - -moz-margin-end: 5px; -}