зеркало из https://github.com/mozilla/gecko-dev.git
Bug 935815 - [Australis] UITour: Allow adding a button with an action to the info panel. r=MattN
This commit is contained in:
Родитель
311b5a3e1d
Коммит
97236f2f4c
|
@ -202,8 +202,16 @@
|
||||||
align="start"
|
align="start"
|
||||||
orient="vertical"
|
orient="vertical"
|
||||||
role="alert">
|
role="alert">
|
||||||
|
<hbox>
|
||||||
|
<vbox>
|
||||||
|
<image id="UITourTooltipIcon"/>
|
||||||
|
</vbox>
|
||||||
|
<vbox flex="1">
|
||||||
<label id="UITourTooltipTitle" flex="1"/>
|
<label id="UITourTooltipTitle" flex="1"/>
|
||||||
<description id="UITourTooltipDescription" flex="1"/>
|
<description id="UITourTooltipDescription" flex="1"/>
|
||||||
|
<hbox id="UITourTooltipButtons" flex="1" align="end"/>
|
||||||
|
</vbox>
|
||||||
|
</hbox>
|
||||||
</panel>
|
</panel>
|
||||||
<panel id="UITourHighlightContainer"
|
<panel id="UITourHighlightContainer"
|
||||||
hidden="true"
|
hidden="true"
|
||||||
|
|
|
@ -22,6 +22,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
|
||||||
|
|
||||||
const UITOUR_PERMISSION = "uitour";
|
const UITOUR_PERMISSION = "uitour";
|
||||||
const PREF_PERM_BRANCH = "browser.uitour.";
|
const PREF_PERM_BRANCH = "browser.uitour.";
|
||||||
|
const MAX_BUTTONS = 4;
|
||||||
|
|
||||||
|
|
||||||
this.UITour = {
|
this.UITour = {
|
||||||
|
@ -137,7 +138,34 @@ this.UITour = {
|
||||||
Cu.reportError("UITour: Target could not be resolved: " + data.target);
|
Cu.reportError("UITour: Target could not be resolved: " + data.target);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.showInfo(target, data.title, data.text);
|
|
||||||
|
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);
|
||||||
}).then(null, Cu.reportError);
|
}).then(null, Cu.reportError);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -315,11 +343,7 @@ this.UITour = {
|
||||||
if (uri.schemeIs("chrome"))
|
if (uri.schemeIs("chrome"))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
let allowedSchemes = new Set(["https"]);
|
if (!this.isSafeScheme(uri))
|
||||||
if (!Services.prefs.getBoolPref("browser.uitour.requireSecure"))
|
|
||||||
allowedSchemes.add("http");
|
|
||||||
|
|
||||||
if (!allowedSchemes.has(uri.scheme))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
this.importPermissions();
|
this.importPermissions();
|
||||||
|
@ -327,6 +351,50 @@ this.UITour = {
|
||||||
return permission == Services.perms.ALLOW_ACTION;
|
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) {
|
getTarget: function(aWindow, aTargetName, aSticky = false) {
|
||||||
let deferred = Promise.defer();
|
let deferred = Promise.defer();
|
||||||
if (typeof aTargetName != "string" || !aTargetName) {
|
if (typeof aTargetName != "string" || !aTargetName) {
|
||||||
|
@ -522,7 +590,7 @@ this.UITour = {
|
||||||
this._setAppMenuStateForAnnotation(aWindow, "highlight", false);
|
this._setAppMenuStateForAnnotation(aWindow, "highlight", false);
|
||||||
},
|
},
|
||||||
|
|
||||||
showInfo: function(aAnchor, aTitle, aDescription) {
|
showInfo: function(aContentDocument, aAnchor, aTitle = "", aDescription = "", aIconURL = "", aButtons = []) {
|
||||||
function showInfoPanel(aAnchorEl) {
|
function showInfoPanel(aAnchorEl) {
|
||||||
aAnchorEl.focus();
|
aAnchorEl.focus();
|
||||||
|
|
||||||
|
@ -530,13 +598,37 @@ this.UITour = {
|
||||||
let tooltip = document.getElementById("UITourTooltip");
|
let tooltip = document.getElementById("UITourTooltip");
|
||||||
let tooltipTitle = document.getElementById("UITourTooltipTitle");
|
let tooltipTitle = document.getElementById("UITourTooltipTitle");
|
||||||
let tooltipDesc = document.getElementById("UITourTooltipDescription");
|
let tooltipDesc = document.getElementById("UITourTooltipDescription");
|
||||||
|
let tooltipIcon = document.getElementById("UITourTooltipIcon");
|
||||||
|
let tooltipButtons = document.getElementById("UITourTooltipButtons");
|
||||||
|
|
||||||
if (tooltip.state == "open") {
|
if (tooltip.state == "open") {
|
||||||
tooltip.hidePopup();
|
tooltip.hidePopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
tooltipTitle.textContent = aTitle;
|
tooltipTitle.textContent = aTitle || "";
|
||||||
tooltipDesc.textContent = aDescription;
|
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;
|
||||||
|
|
||||||
tooltip.hidden = false;
|
tooltip.hidden = false;
|
||||||
let alignment = "bottomcenter topright";
|
let alignment = "bottomcenter topright";
|
||||||
|
@ -553,9 +645,15 @@ this.UITour = {
|
||||||
},
|
},
|
||||||
|
|
||||||
hideInfo: function(aWindow) {
|
hideInfo: function(aWindow) {
|
||||||
let tooltip = aWindow.document.getElementById("UITourTooltip");
|
let document = aWindow.document;
|
||||||
|
|
||||||
|
let tooltip = document.getElementById("UITourTooltip");
|
||||||
tooltip.hidePopup();
|
tooltip.hidePopup();
|
||||||
this._setAppMenuStateForAnnotation(aWindow, "info", false);
|
this._setAppMenuStateForAnnotation(aWindow, "info", false);
|
||||||
|
|
||||||
|
let tooltipButtons = document.getElementById("UITourTooltipButtons");
|
||||||
|
while (tooltipButtons.firstChild)
|
||||||
|
tooltipButtons.firstChild.remove();
|
||||||
},
|
},
|
||||||
|
|
||||||
showMenu: function(aWindow, aMenuName, aOpenCallback = null) {
|
showMenu: function(aWindow, aMenuName, aOpenCallback = null) {
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
support-files =
|
support-files =
|
||||||
head.js
|
head.js
|
||||||
|
uitour.*
|
||||||
|
image.png
|
||||||
|
|
||||||
[browser_NetworkPrioritizer.js]
|
[browser_NetworkPrioritizer.js]
|
||||||
[browser_SignInToWebsite.js]
|
[browser_SignInToWebsite.js]
|
||||||
[browser_UITour.js]
|
[browser_UITour.js]
|
||||||
support-files = uitour.*
|
|
||||||
skip-if = os == "linux" # Intermittent failures, bug 951965
|
skip-if = os == "linux" # Intermittent failures, bug 951965
|
||||||
[browser_UITour2.js]
|
[browser_UITour2.js]
|
||||||
support-files = uitour.*
|
[browser_UITour3.js]
|
||||||
[browser_taskbar_preview.js]
|
[browser_taskbar_preview.js]
|
||||||
run-if = os == "win"
|
run-if = os == "win"
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
let gTestTab;
|
let gTestTab;
|
||||||
let gContentAPI;
|
let gContentAPI;
|
||||||
|
let gContentWindow;
|
||||||
|
|
||||||
Components.utils.import("resource:///modules/UITour.jsm");
|
Components.utils.import("resource:///modules/UITour.jsm");
|
||||||
|
|
||||||
|
@ -21,10 +22,10 @@ function loadTestPage(callback, host = "https://example.com/") {
|
||||||
gTestTab.linkedBrowser.addEventListener("load", function onLoad() {
|
gTestTab.linkedBrowser.addEventListener("load", function onLoad() {
|
||||||
gTestTab.linkedBrowser.removeEventListener("load", onLoad);
|
gTestTab.linkedBrowser.removeEventListener("load", onLoad);
|
||||||
|
|
||||||
let contentWindow = Components.utils.waiveXrays(gTestTab.linkedBrowser.contentDocument.defaultView);
|
gContentWindow = Components.utils.waiveXrays(gTestTab.linkedBrowser.contentDocument.defaultView);
|
||||||
gContentAPI = contentWindow.Mozilla.UITour;
|
gContentAPI = gContentWindow.Mozilla.UITour;
|
||||||
|
|
||||||
waitForFocus(callback, contentWindow);
|
waitForFocus(callback, gContentWindow);
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ function test() {
|
||||||
|
|
||||||
registerCleanupFunction(function() {
|
registerCleanupFunction(function() {
|
||||||
delete window.UITour;
|
delete window.UITour;
|
||||||
|
delete window.gContentWindow;
|
||||||
delete window.gContentAPI;
|
delete window.gContentAPI;
|
||||||
if (gTestTab)
|
if (gTestTab)
|
||||||
gBrowser.removeTab(gTestTab);
|
gBrowser.removeTab(gTestTab);
|
||||||
|
@ -240,11 +242,16 @@ let tests = [
|
||||||
let popup = document.getElementById("UITourTooltip");
|
let popup = document.getElementById("UITourTooltip");
|
||||||
let title = document.getElementById("UITourTooltipTitle");
|
let title = document.getElementById("UITourTooltipTitle");
|
||||||
let desc = document.getElementById("UITourTooltipDescription");
|
let desc = document.getElementById("UITourTooltipDescription");
|
||||||
|
let icon = document.getElementById("UITourTooltipIcon");
|
||||||
|
let buttons = document.getElementById("UITourTooltipButtons");
|
||||||
|
|
||||||
popup.addEventListener("popupshown", function onPopupShown() {
|
popup.addEventListener("popupshown", function onPopupShown() {
|
||||||
popup.removeEventListener("popupshown", onPopupShown);
|
popup.removeEventListener("popupshown", onPopupShown);
|
||||||
is(popup.popupBoxObject.anchorNode, document.getElementById("urlbar"), "Popup should be anchored to the urlbar");
|
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(title.textContent, "test title", "Popup should have correct title");
|
||||||
is(desc.textContent, "test text", "Popup should have correct description text");
|
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.addEventListener("popuphidden", function onPopupHidden() {
|
||||||
popup.removeEventListener("popuphidden", onPopupHidden);
|
popup.removeEventListener("popuphidden", onPopupHidden);
|
||||||
|
@ -266,11 +273,16 @@ let tests = [
|
||||||
let popup = document.getElementById("UITourTooltip");
|
let popup = document.getElementById("UITourTooltip");
|
||||||
let title = document.getElementById("UITourTooltipTitle");
|
let title = document.getElementById("UITourTooltipTitle");
|
||||||
let desc = document.getElementById("UITourTooltipDescription");
|
let desc = document.getElementById("UITourTooltipDescription");
|
||||||
|
let icon = document.getElementById("UITourTooltipIcon");
|
||||||
|
let buttons = document.getElementById("UITourTooltipButtons");
|
||||||
|
|
||||||
popup.addEventListener("popupshown", function onPopupShown() {
|
popup.addEventListener("popupshown", function onPopupShown() {
|
||||||
popup.removeEventListener("popupshown", onPopupShown);
|
popup.removeEventListener("popupshown", onPopupShown);
|
||||||
is(popup.popupBoxObject.anchorNode, document.getElementById("urlbar"), "Popup should be anchored to the urlbar");
|
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(title.textContent, "urlbar title", "Popup should have correct title");
|
||||||
is(desc.textContent, "urlbar text", "Popup should have correct description text");
|
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");
|
gContentAPI.showInfo("search", "search title", "search text");
|
||||||
executeSoon(function() {
|
executeSoon(function() {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
let gTestTab;
|
let gTestTab;
|
||||||
let gContentAPI;
|
let gContentAPI;
|
||||||
|
let gContentWindow;
|
||||||
|
|
||||||
Components.utils.import("resource:///modules/UITour.jsm");
|
Components.utils.import("resource:///modules/UITour.jsm");
|
||||||
|
|
||||||
|
@ -21,10 +22,10 @@ function loadTestPage(callback, host = "https://example.com/") {
|
||||||
gTestTab.linkedBrowser.addEventListener("load", function onLoad() {
|
gTestTab.linkedBrowser.addEventListener("load", function onLoad() {
|
||||||
gTestTab.linkedBrowser.removeEventListener("load", onLoad);
|
gTestTab.linkedBrowser.removeEventListener("load", onLoad);
|
||||||
|
|
||||||
let contentWindow = Components.utils.waiveXrays(gTestTab.linkedBrowser.contentDocument.defaultView);
|
gContentWindow = Components.utils.waiveXrays(gTestTab.linkedBrowser.contentDocument.defaultView);
|
||||||
gContentAPI = contentWindow.Mozilla.UITour;
|
gContentAPI = gContentWindow.Mozilla.UITour;
|
||||||
|
|
||||||
waitForFocus(callback, contentWindow);
|
waitForFocus(callback, gContentWindow);
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ function test() {
|
||||||
|
|
||||||
registerCleanupFunction(function() {
|
registerCleanupFunction(function() {
|
||||||
delete window.UITour;
|
delete window.UITour;
|
||||||
|
delete window.gContentWindow;
|
||||||
delete window.gContentAPI;
|
delete window.gContentAPI;
|
||||||
if (gTestTab)
|
if (gTestTab)
|
||||||
gBrowser.removeTab(gTestTab);
|
gBrowser.removeTab(gTestTab);
|
||||||
|
|
|
@ -0,0 +1,191 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
let gTestTab;
|
||||||
|
let gContentAPI;
|
||||||
|
let gContentWindow;
|
||||||
|
|
||||||
|
Components.utils.import("resource:///modules/UITour.jsm");
|
||||||
|
|
||||||
|
function loadTestPage(callback, host = "https://example.com/") {
|
||||||
|
if (gTestTab)
|
||||||
|
gBrowser.removeTab(gTestTab);
|
||||||
|
|
||||||
|
let url = getRootDirectory(gTestPath) + "uitour.html";
|
||||||
|
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;
|
||||||
|
|
||||||
|
waitForFocus(callback, gContentWindow);
|
||||||
|
}, 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");
|
||||||
|
});
|
||||||
|
|
||||||
|
function done() {
|
||||||
|
if (gTestTab)
|
||||||
|
gBrowser.removeTab(gTestTab);
|
||||||
|
gTestTab = null;
|
||||||
|
|
||||||
|
let highlight = document.getElementById("UITourHighlightContainer");
|
||||||
|
is_element_hidden(highlight, "Highlight should be closed/hidden after UITour tab is closed");
|
||||||
|
|
||||||
|
let tooltip = document.getElementById("UITourTooltip");
|
||||||
|
is_element_hidden(tooltip, "Tooltip should be closed/hidden after UITour tab is closed");
|
||||||
|
|
||||||
|
ok(!PanelUI.panel.hasAttribute("noautohide"), "@noautohide on the menu panel should have been cleaned up");
|
||||||
|
|
||||||
|
is(UITour.pinnedTabs.get(window), null, "Any pinned tab should be closed after UITour tab is closed");
|
||||||
|
|
||||||
|
executeSoon(nextTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextTest() {
|
||||||
|
if (tests.length == 0) {
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let test = tests.shift();
|
||||||
|
info("Starting " + test.name);
|
||||||
|
loadTestPage(function() {
|
||||||
|
test(done);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
nextTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
let tests = [
|
||||||
|
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);
|
||||||
|
},
|
||||||
|
];
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 55 KiB |
|
@ -5,6 +5,22 @@
|
||||||
<title>UITour test</title>
|
<title>UITour test</title>
|
||||||
<script type="application/javascript" src="uitour.js">
|
<script type="application/javascript" src="uitour.js">
|
||||||
</script>
|
</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>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>UITour tests</h1>
|
<h1>UITour tests</h1>
|
||||||
|
|
|
@ -25,7 +25,6 @@ if (typeof Mozilla == 'undefined') {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function _sendEvent(action, data) {
|
function _sendEvent(action, data) {
|
||||||
var event = new CustomEvent('mozUITour', {
|
var event = new CustomEvent('mozUITour', {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
|
@ -34,10 +33,31 @@ if (typeof Mozilla == 'undefined') {
|
||||||
data: data || {}
|
data: data || {}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log("Sending mozUITour event: ", event);
|
|
||||||
document.dispatchEvent(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.DEFAULT_THEME_CYCLE_DELAY = 10 * 1000;
|
||||||
|
|
||||||
Mozilla.UITour.showHighlight = function(target, effect) {
|
Mozilla.UITour.showHighlight = function(target, effect) {
|
||||||
|
@ -51,11 +71,24 @@ if (typeof Mozilla == 'undefined') {
|
||||||
_sendEvent('hideHighlight');
|
_sendEvent('hideHighlight');
|
||||||
};
|
};
|
||||||
|
|
||||||
Mozilla.UITour.showInfo = function(target, title, text) {
|
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)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_sendEvent('showInfo', {
|
_sendEvent('showInfo', {
|
||||||
target: target,
|
target: target,
|
||||||
title: title,
|
title: title,
|
||||||
text: text
|
text: text,
|
||||||
|
icon: icon,
|
||||||
|
buttons: buttonData
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,10 @@
|
||||||
min-width: 32px;
|
min-width: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#UITourTooltip {
|
#UITourTooltipIcon {
|
||||||
max-width: 20em;
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
padding: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#UITourTooltipTitle {
|
#UITourTooltipTitle {
|
||||||
|
@ -35,3 +37,13 @@
|
||||||
#UITourTooltipDescription {
|
#UITourTooltipDescription {
|
||||||
max-width: 20em;
|
max-width: 20em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#UITourTooltipButtons {
|
||||||
|
height: 5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#UITourTooltipButtons > button[image] > .button-box > .button-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
-moz-margin-end: 5px;
|
||||||
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче