merge fx-team to mozilla-inbound a=merge
|
@ -67,3 +67,6 @@ GPATH
|
||||||
|
|
||||||
# Git clone directory for updating web-platform-tests
|
# Git clone directory for updating web-platform-tests
|
||||||
testing/web-platform/sync/
|
testing/web-platform/sync/
|
||||||
|
|
||||||
|
# Android Gradle artifacts.
|
||||||
|
mobile/android/gradle/.gradle
|
||||||
|
|
|
@ -93,3 +93,6 @@ GPATH
|
||||||
# including the following three lines
|
# including the following three lines
|
||||||
^browser/components/loop/standalone/content/legal/styles/.*\.css$
|
^browser/components/loop/standalone/content/legal/styles/.*\.css$
|
||||||
^browser/components/loop/standalone/content/legal/terms/en_US\.html$
|
^browser/components/loop/standalone/content/legal/terms/en_US\.html$
|
||||||
|
|
||||||
|
# Android Gradle artifacts.
|
||||||
|
^mobile/android/gradle/.gradle
|
||||||
|
|
|
@ -479,11 +479,9 @@ SocialShare = {
|
||||||
},
|
},
|
||||||
|
|
||||||
get iframe() {
|
get iframe() {
|
||||||
// first element is our menu vbox.
|
// panel.firstChild is our toolbar hbox, panel.lastChild is the iframe
|
||||||
if (this.panel.childElementCount == 1)
|
// container hbox used for an interstitial "loading" graphic
|
||||||
return null;
|
return this.panel.lastChild.firstChild;
|
||||||
else
|
|
||||||
return this.panel.lastChild;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
uninit: function () {
|
uninit: function () {
|
||||||
|
@ -505,7 +503,7 @@ SocialShare = {
|
||||||
iframe.setAttribute("tooltip", "aHTMLTooltip");
|
iframe.setAttribute("tooltip", "aHTMLTooltip");
|
||||||
iframe.setAttribute("disableglobalhistory", "true");
|
iframe.setAttribute("disableglobalhistory", "true");
|
||||||
iframe.setAttribute("flex", "1");
|
iframe.setAttribute("flex", "1");
|
||||||
panel.appendChild(iframe);
|
panel.lastChild.appendChild(iframe);
|
||||||
iframe.addEventListener("load", function _firstload() {
|
iframe.addEventListener("load", function _firstload() {
|
||||||
iframe.removeEventListener("load", _firstload, true);
|
iframe.removeEventListener("load", _firstload, true);
|
||||||
iframe.messageManager.loadFrameScript("chrome://browser/content/content.js", true);
|
iframe.messageManager.loadFrameScript("chrome://browser/content/content.js", true);
|
||||||
|
@ -537,13 +535,13 @@ SocialShare = {
|
||||||
// remove everything before the add-share-provider button (which should also
|
// remove everything before the add-share-provider button (which should also
|
||||||
// be lastChild if any share providers were added)
|
// be lastChild if any share providers were added)
|
||||||
let addButton = document.getElementById("add-share-provider");
|
let addButton = document.getElementById("add-share-provider");
|
||||||
while (hbox.firstChild != addButton) {
|
while (hbox.lastChild != addButton) {
|
||||||
hbox.removeChild(hbox.firstChild);
|
hbox.removeChild(hbox.lastChild);
|
||||||
}
|
}
|
||||||
let selectedProvider = this.getSelectedProvider();
|
let selectedProvider = this.getSelectedProvider();
|
||||||
for (let provider of providers) {
|
for (let provider of providers) {
|
||||||
let button = document.createElement("toolbarbutton");
|
let button = document.createElement("toolbarbutton");
|
||||||
button.setAttribute("class", "toolbarbutton share-provider-button");
|
button.setAttribute("class", "toolbarbutton-1 share-provider-button");
|
||||||
button.setAttribute("type", "radio");
|
button.setAttribute("type", "radio");
|
||||||
button.setAttribute("group", "share-providers");
|
button.setAttribute("group", "share-providers");
|
||||||
button.setAttribute("image", provider.iconURL);
|
button.setAttribute("image", provider.iconURL);
|
||||||
|
@ -554,7 +552,7 @@ SocialShare = {
|
||||||
if (provider == selectedProvider) {
|
if (provider == selectedProvider) {
|
||||||
this.defaultButton = button;
|
this.defaultButton = button;
|
||||||
}
|
}
|
||||||
hbox.insertBefore(button, addButton);
|
hbox.appendChild(button);
|
||||||
}
|
}
|
||||||
if (!this.defaultButton) {
|
if (!this.defaultButton) {
|
||||||
this.defaultButton = addButton;
|
this.defaultButton = addButton;
|
||||||
|
@ -682,48 +680,40 @@ SocialShare = {
|
||||||
|
|
||||||
let shareEndpoint = OpenGraphBuilder.generateEndpointURL(provider.shareURL, pageData);
|
let shareEndpoint = OpenGraphBuilder.generateEndpointURL(provider.shareURL, pageData);
|
||||||
|
|
||||||
|
this._dynamicResizer.stop();
|
||||||
let size = provider.getPageSize("share");
|
let size = provider.getPageSize("share");
|
||||||
if (size) {
|
if (size) {
|
||||||
this._dynamicResizer.stop();
|
// let the css on the share panel define width, but height
|
||||||
|
// calculations dont work on all sites, so we allow that to be
|
||||||
|
// defined.
|
||||||
|
delete size.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we've already loaded this provider/page share endpoint, we don't want
|
// if we've already loaded this provider/page share endpoint, we don't want
|
||||||
// to add another load event listener.
|
// to add another load event listener.
|
||||||
let reload = true;
|
|
||||||
let endpointMatch = shareEndpoint == iframe.getAttribute("src");
|
let endpointMatch = shareEndpoint == iframe.getAttribute("src");
|
||||||
let docLoaded = iframe.contentDocument && iframe.contentDocument.readyState == "complete";
|
if (endpointMatch) {
|
||||||
if (endpointMatch && docLoaded) {
|
this._dynamicResizer.start(iframe.parentNode, iframe, size);
|
||||||
reload = shareEndpoint != iframe.contentDocument.location.spec;
|
|
||||||
}
|
|
||||||
if (!reload) {
|
|
||||||
if (!size)
|
|
||||||
this._dynamicResizer.start(this.panel, iframe);
|
|
||||||
iframe.docShell.isActive = true;
|
iframe.docShell.isActive = true;
|
||||||
iframe.docShell.isAppTab = true;
|
iframe.docShell.isAppTab = true;
|
||||||
let evt = iframe.contentDocument.createEvent("CustomEvent");
|
let evt = iframe.contentDocument.createEvent("CustomEvent");
|
||||||
evt.initCustomEvent("OpenGraphData", true, true, JSON.stringify(pageData));
|
evt.initCustomEvent("OpenGraphData", true, true, JSON.stringify(pageData));
|
||||||
iframe.contentDocument.documentElement.dispatchEvent(evt);
|
iframe.contentDocument.documentElement.dispatchEvent(evt);
|
||||||
} else {
|
} else {
|
||||||
|
iframe.parentNode.setAttribute("loading", "true");
|
||||||
// first time load, wait for load and dispatch after load
|
// first time load, wait for load and dispatch after load
|
||||||
iframe.addEventListener("load", function panelBrowserOnload(e) {
|
iframe.addEventListener("load", function panelBrowserOnload(e) {
|
||||||
iframe.removeEventListener("load", panelBrowserOnload, true);
|
iframe.removeEventListener("load", panelBrowserOnload, true);
|
||||||
iframe.docShell.isActive = true;
|
iframe.docShell.isActive = true;
|
||||||
iframe.docShell.isAppTab = true;
|
iframe.docShell.isAppTab = true;
|
||||||
|
iframe.parentNode.removeAttribute("loading");
|
||||||
// to support standard share endpoints mimick window.open by setting
|
// to support standard share endpoints mimick window.open by setting
|
||||||
// window.opener, some share endpoints rely on w.opener to know they
|
// window.opener, some share endpoints rely on w.opener to know they
|
||||||
// should close the window when done.
|
// should close the window when done.
|
||||||
iframe.contentWindow.opener = iframe.contentWindow;
|
iframe.contentWindow.opener = iframe.contentWindow;
|
||||||
setTimeout(function() {
|
|
||||||
if (size) {
|
SocialShare._dynamicResizer.start(iframe.parentNode, iframe, size);
|
||||||
let panel = SocialShare.panel;
|
|
||||||
let {width, height} = size;
|
|
||||||
width += panel.boxObject.width - iframe.boxObject.width;
|
|
||||||
height += panel.boxObject.height - iframe.boxObject.height;
|
|
||||||
panel.sizeTo(width, height);
|
|
||||||
} else {
|
|
||||||
SocialShare._dynamicResizer.start(iframe.parentNode, iframe);
|
|
||||||
}
|
|
||||||
}, 0);
|
|
||||||
let evt = iframe.contentDocument.createEvent("CustomEvent");
|
let evt = iframe.contentDocument.createEvent("CustomEvent");
|
||||||
evt.initCustomEvent("OpenGraphData", true, true, JSON.stringify(pageData));
|
evt.initCustomEvent("OpenGraphData", true, true, JSON.stringify(pageData));
|
||||||
iframe.contentDocument.documentElement.dispatchEvent(evt);
|
iframe.contentDocument.documentElement.dispatchEvent(evt);
|
||||||
|
@ -747,9 +737,18 @@ SocialShare = {
|
||||||
showDirectory: function() {
|
showDirectory: function() {
|
||||||
this._createFrame();
|
this._createFrame();
|
||||||
let iframe = this.iframe;
|
let iframe = this.iframe;
|
||||||
|
if (iframe.getAttribute("src") == "about:providerdirectory")
|
||||||
|
return;
|
||||||
iframe.removeAttribute("origin");
|
iframe.removeAttribute("origin");
|
||||||
|
iframe.parentNode.setAttribute("loading", "true");
|
||||||
|
iframe.addEventListener("DOMContentLoaded", function _dcl(e) {
|
||||||
|
iframe.removeEventListener("DOMContentLoaded", _dcl, true);
|
||||||
|
iframe.parentNode.removeAttribute("loading");
|
||||||
|
}, true);
|
||||||
|
|
||||||
iframe.addEventListener("load", function panelBrowserOnload(e) {
|
iframe.addEventListener("load", function panelBrowserOnload(e) {
|
||||||
iframe.removeEventListener("load", panelBrowserOnload, true);
|
iframe.removeEventListener("load", panelBrowserOnload, true);
|
||||||
|
|
||||||
hookWindowCloseForPanelClose(iframe.contentWindow);
|
hookWindowCloseForPanelClose(iframe.contentWindow);
|
||||||
SocialShare._dynamicResizer.start(iframe.parentNode, iframe);
|
SocialShare._dynamicResizer.start(iframe.parentNode, iframe);
|
||||||
|
|
||||||
|
|
|
@ -287,17 +287,22 @@
|
||||||
<panel id="social-share-panel"
|
<panel id="social-share-panel"
|
||||||
class="social-panel"
|
class="social-panel"
|
||||||
type="arrow"
|
type="arrow"
|
||||||
orient="horizontal"
|
orient="vertical"
|
||||||
onpopupshowing="SocialShare.onShowing()"
|
onpopupshowing="SocialShare.onShowing()"
|
||||||
onpopuphidden="SocialShare.onHidden()"
|
onpopuphidden="SocialShare.onHidden()"
|
||||||
hidden="true">
|
hidden="true">
|
||||||
<vbox class="social-share-toolbar">
|
<hbox class="social-share-toolbar">
|
||||||
<arrowscrollbox id="social-share-provider-buttons" orient="vertical" flex="1">
|
<toolbarbutton id="manage-share-providers" class="toolbarbutton share-provider-button"
|
||||||
|
tooltiptext="&social.addons.label;"
|
||||||
|
oncommand="BrowserOpenAddonsMgr('addons://list/service');
|
||||||
|
this.parentNode.parentNode.hidePopup();"/>
|
||||||
|
<arrowscrollbox id="social-share-provider-buttons" orient="horizontal" flex="1" pack="end">
|
||||||
<toolbarbutton id="add-share-provider" class="toolbarbutton share-provider-button" type="radio"
|
<toolbarbutton id="add-share-provider" class="toolbarbutton share-provider-button" type="radio"
|
||||||
group="share-providers" tooltiptext="&findShareServices.label;"
|
group="share-providers" tooltiptext="&findShareServices.label;"
|
||||||
oncommand="SocialShare.showDirectory()"/>
|
oncommand="SocialShare.showDirectory()"/>
|
||||||
</arrowscrollbox>
|
</arrowscrollbox>
|
||||||
</vbox>
|
</hbox>
|
||||||
|
<hbox id="share-container" flex="1"/>
|
||||||
</panel>
|
</panel>
|
||||||
|
|
||||||
<panel id="social-notification-panel"
|
<panel id="social-notification-panel"
|
||||||
|
|
|
@ -14,6 +14,12 @@ function test() {
|
||||||
};
|
};
|
||||||
runSocialTestWithProvider(manifest, function (finishcb) {
|
runSocialTestWithProvider(manifest, function (finishcb) {
|
||||||
SocialSidebar.show();
|
SocialSidebar.show();
|
||||||
|
// disable transitions for the test
|
||||||
|
let panel = document.getElementById("social-flyout-panel");
|
||||||
|
registerCleanupFunction(function () {
|
||||||
|
panel.removeAttribute("animate");
|
||||||
|
});
|
||||||
|
panel.setAttribute("animate", "false");
|
||||||
runSocialTests(tests, undefined, undefined, finishcb);
|
runSocialTests(tests, undefined, undefined, finishcb);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -21,8 +27,7 @@ function test() {
|
||||||
var tests = {
|
var tests = {
|
||||||
testOpenCloseFlyout: function(next) {
|
testOpenCloseFlyout: function(next) {
|
||||||
let panel = document.getElementById("social-flyout-panel");
|
let panel = document.getElementById("social-flyout-panel");
|
||||||
panel.addEventListener("popupshowing", function onShowing() {
|
ensureEventFired(panel, "popupshown").then(() => {
|
||||||
panel.removeEventListener("popupshowing", onShowing);
|
|
||||||
is(panel.firstChild.contentDocument.readyState, "complete", "panel is loaded prior to showing");
|
is(panel.firstChild.contentDocument.readyState, "complete", "panel is loaded prior to showing");
|
||||||
});
|
});
|
||||||
let port = SocialSidebar.provider.getWorkerPort();
|
let port = SocialSidebar.provider.getWorkerPort();
|
||||||
|
@ -75,8 +80,7 @@ var tests = {
|
||||||
is(cs.height, "400px", "should be 400px high");
|
is(cs.height, "400px", "should be 400px high");
|
||||||
is(iframe.boxObject.height, 400, "iframe should now be 400px high");
|
is(iframe.boxObject.height, 400, "iframe should now be 400px high");
|
||||||
|
|
||||||
iframe.contentWindow.addEventListener("resize", function _doneHandler() {
|
ensureEventFired(iframe.contentWindow, "resize").then(() => {
|
||||||
iframe.contentWindow.removeEventListener("resize", _doneHandler, false);
|
|
||||||
cs = iframe.contentWindow.getComputedStyle(body);
|
cs = iframe.contentWindow.getComputedStyle(body);
|
||||||
|
|
||||||
is(cs.width, "500px", "should now be 500px wide");
|
is(cs.width, "500px", "should now be 500px wide");
|
||||||
|
@ -86,7 +90,7 @@ var tests = {
|
||||||
panel.hidePopup();
|
panel.hidePopup();
|
||||||
port.close();
|
port.close();
|
||||||
next();
|
next();
|
||||||
}, false);
|
});
|
||||||
SocialFlyout.dispatchPanelEvent("socialTest-MakeWider");
|
SocialFlyout.dispatchPanelEvent("socialTest-MakeWider");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -117,13 +121,12 @@ var tests = {
|
||||||
if (e.data.result != "shown")
|
if (e.data.result != "shown")
|
||||||
return;
|
return;
|
||||||
let iframe = panel.firstChild;
|
let iframe = panel.firstChild;
|
||||||
iframe.contentDocument.addEventListener("SocialTest-DoneCloseSelf", function _doneHandler() {
|
ensureEventFired(iframe.contentDocument, "SocialTest-DoneCloseSelf").then(() => {
|
||||||
iframe.contentDocument.removeEventListener("SocialTest-DoneCloseSelf", _doneHandler, false);
|
|
||||||
port.close();
|
port.close();
|
||||||
is(panel.state, "closed", "flyout should have closed itself");
|
is(panel.state, "closed", "flyout should have closed itself");
|
||||||
Services.prefs.setBoolPref(ALLOW_SCRIPTS_TO_CLOSE_PREF, oldAllowScriptsToClose);
|
Services.prefs.setBoolPref(ALLOW_SCRIPTS_TO_CLOSE_PREF, oldAllowScriptsToClose);
|
||||||
next();
|
next();
|
||||||
}, false);
|
});
|
||||||
is(panel.state, "open", "flyout should be open");
|
is(panel.state, "open", "flyout should be open");
|
||||||
SocialFlyout.dispatchPanelEvent("socialTest-CloseSelf");
|
SocialFlyout.dispatchPanelEvent("socialTest-CloseSelf");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
</head>
|
</head>
|
||||||
<body style="width: 400px; height: 400px; margin: 0; overflow: hidden;" onload="pingWorker();">
|
<body style="width: 400px; height: 400px; margin: 0; overflow: hidden;" onload="pingWorker();">
|
||||||
<p>This is a test social flyout panel.</p>
|
<p>This is a test social flyout panel.</p>
|
||||||
<a id="traversal" href="http://mochi.test">test link</a>
|
<a id="traversal" href="https://test.example.com">test link</a>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
|
@ -1000,6 +1000,32 @@
|
||||||
class="search-setting-button search-panel-header"
|
class="search-setting-button search-panel-header"
|
||||||
label="&changeSearchSettings.button;"/>
|
label="&changeSearchSettings.button;"/>
|
||||||
</content>
|
</content>
|
||||||
|
<implementation>
|
||||||
|
<method name="updateHeader">
|
||||||
|
<body><![CDATA[
|
||||||
|
let currentEngine = Services.search.currentEngine;
|
||||||
|
let uri = currentEngine.iconURI;
|
||||||
|
if (uri) {
|
||||||
|
uri = uri.spec;
|
||||||
|
this.setAttribute("src", PlacesUtils.getImageURLForResolution(window, uri));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// If the default has just been changed to a provider without icon,
|
||||||
|
// avoid showing the icon of the previous default provider.
|
||||||
|
this.removeAttribute("src");
|
||||||
|
}
|
||||||
|
|
||||||
|
const kBundleURI = "chrome://browser/locale/search.properties";
|
||||||
|
let bundle = Services.strings.createBundle(kBundleURI);
|
||||||
|
let headerText = bundle.formatStringFromName("searchHeader",
|
||||||
|
[currentEngine.name], 1);
|
||||||
|
document.getAnonymousElementByAttribute(this, "anonid", "searchbar-engine-name")
|
||||||
|
.setAttribute("value", headerText);
|
||||||
|
document.getAnonymousElementByAttribute(this, "anonid", "searchbar-engine")
|
||||||
|
.engine = currentEngine;
|
||||||
|
]]></body>
|
||||||
|
</method>
|
||||||
|
</implementation>
|
||||||
<handlers>
|
<handlers>
|
||||||
<handler event="popupshowing"><![CDATA[
|
<handler event="popupshowing"><![CDATA[
|
||||||
// First handle deciding if we are showing the reduced version of the
|
// First handle deciding if we are showing the reduced version of the
|
||||||
|
@ -1022,26 +1048,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show the current default engine in the top header of the panel.
|
// Show the current default engine in the top header of the panel.
|
||||||
let currentEngine = Services.search.currentEngine;
|
this.updateHeader();
|
||||||
let uri = currentEngine.iconURI;
|
|
||||||
if (uri) {
|
|
||||||
uri = uri.spec;
|
|
||||||
this.setAttribute("src", PlacesUtils.getImageURLForResolution(window, uri));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// If the default has just been changed to a provider without icon,
|
|
||||||
// avoid showing the icon of the previous default provider.
|
|
||||||
this.removeAttribute("src");
|
|
||||||
}
|
|
||||||
|
|
||||||
const kBundleURI = "chrome://browser/locale/search.properties";
|
|
||||||
let bundle = Services.strings.createBundle(kBundleURI);
|
|
||||||
let headerText = bundle.formatStringFromName("searchHeader",
|
|
||||||
[currentEngine.name], 1);
|
|
||||||
document.getAnonymousElementByAttribute(this, "anonid", "searchbar-engine-name")
|
|
||||||
.setAttribute("value", headerText);
|
|
||||||
document.getAnonymousElementByAttribute(this, "anonid", "searchbar-engine")
|
|
||||||
.engine = currentEngine;
|
|
||||||
|
|
||||||
// Update the 'Search for <keywords> with:" header.
|
// Update the 'Search for <keywords> with:" header.
|
||||||
let headerSearchText =
|
let headerSearchText =
|
||||||
|
@ -1074,6 +1081,8 @@
|
||||||
|
|
||||||
let addEngines = gBrowser.selectedBrowser.engines;
|
let addEngines = gBrowser.selectedBrowser.engines;
|
||||||
if (addEngines && addEngines.length > 0) {
|
if (addEngines && addEngines.length > 0) {
|
||||||
|
const kBundleURI = "chrome://browser/locale/search.properties";
|
||||||
|
let bundle = Services.strings.createBundle(kBundleURI);
|
||||||
for (let engine of addEngines) {
|
for (let engine of addEngines) {
|
||||||
let button = document.createElementNS(kXULNS, "button");
|
let button = document.createElementNS(kXULNS, "button");
|
||||||
let label = bundle.formatStringFromName("cmd_addFoundEngine",
|
let label = bundle.formatStringFromName("cmd_addFoundEngine",
|
||||||
|
@ -1109,8 +1118,9 @@
|
||||||
hiddenList = [];
|
hiddenList = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let currentEngineName = Services.search.currentEngine.name;
|
||||||
let engines = Services.search.getVisibleEngines()
|
let engines = Services.search.getVisibleEngines()
|
||||||
.filter(e => e.name != currentEngine.name &&
|
.filter(e => e.name != currentEngineName &&
|
||||||
hiddenList.indexOf(e.name) == -1);
|
hiddenList.indexOf(e.name) == -1);
|
||||||
|
|
||||||
let header = document.getAnonymousElementByAttribute(this, "anonid",
|
let header = document.getAnonymousElementByAttribute(this, "anonid",
|
||||||
|
|
|
@ -784,6 +784,22 @@ let MozLoopServiceInternal = {
|
||||||
}, pc.id);
|
}, pc.id);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getChatWindowID: function(conversationWindowData) {
|
||||||
|
// Try getting a window ID that can (re-)identify this conversation, or resort
|
||||||
|
// to a globally unique one as a last resort.
|
||||||
|
// XXX We can clean this up once rooms and direct contact calling are the only
|
||||||
|
// two modes left.
|
||||||
|
let windowId = ("contact" in conversationWindowData) ?
|
||||||
|
conversationWindowData.contact._guid || gLastWindowId++ :
|
||||||
|
conversationWindowData.roomToken || conversationWindowData.callId ||
|
||||||
|
gLastWindowId++;
|
||||||
|
return windowId.toString();
|
||||||
|
},
|
||||||
|
|
||||||
|
getChatURL: function(chatWindowId) {
|
||||||
|
return "about:loopconversation#" + chatWindowId;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the chat window
|
* Opens the chat window
|
||||||
*
|
*
|
||||||
|
@ -794,20 +810,11 @@ let MozLoopServiceInternal = {
|
||||||
openChatWindow: function(conversationWindowData) {
|
openChatWindow: function(conversationWindowData) {
|
||||||
// So I guess the origin is the loop server!?
|
// So I guess the origin is the loop server!?
|
||||||
let origin = this.loopServerUri;
|
let origin = this.loopServerUri;
|
||||||
// Try getting a window ID that can (re-)identify this conversation, or resort
|
let windowId = this.getChatWindowID(conversationWindowData);
|
||||||
// to a globally unique one as a last resort.
|
|
||||||
// XXX We can clean this up once rooms and direct contact calling are the only
|
|
||||||
// two modes left.
|
|
||||||
let windowId = ("contact" in conversationWindowData) ?
|
|
||||||
conversationWindowData.contact._guid || gLastWindowId++ :
|
|
||||||
conversationWindowData.roomToken || conversationWindowData.callId ||
|
|
||||||
gLastWindowId++;
|
|
||||||
// Store the id as a string, as that's what we use elsewhere.
|
|
||||||
windowId = windowId.toString();
|
|
||||||
|
|
||||||
gConversationWindowData.set(windowId, conversationWindowData);
|
gConversationWindowData.set(windowId, conversationWindowData);
|
||||||
|
|
||||||
let url = "about:loopconversation#" + windowId;
|
let url = this.getChatURL(windowId);
|
||||||
|
|
||||||
let callback = chatbox => {
|
let callback = chatbox => {
|
||||||
// We need to use DOMContentLoaded as otherwise the injection will happen
|
// We need to use DOMContentLoaded as otherwise the injection will happen
|
||||||
|
@ -1099,36 +1106,7 @@ this.MozLoopService = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Resume the tour (re-opening the tab, if necessary) if someone else joins
|
LoopRooms.on("joined", this.maybeResumeTourOnRoomJoined.bind(this));
|
||||||
// a room of ours and it's currently open.
|
|
||||||
LoopRooms.on("joined", (e, room, participant) => {
|
|
||||||
let isOwnerInRoom = false;
|
|
||||||
let isOtherInRoom = false;
|
|
||||||
|
|
||||||
if (!this.getLoopPref("gettingStarted.resumeOnFirstJoin")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!room.participants) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The particpant that joined isn't necessarily included in room.participants (depending on
|
|
||||||
// when the broadcast happens) so concatenate.
|
|
||||||
for (let participant of room.participants.concat(participant)) {
|
|
||||||
if (participant.owner) {
|
|
||||||
isOwnerInRoom = true;
|
|
||||||
} else {
|
|
||||||
isOtherInRoom = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isOwnerInRoom || !isOtherInRoom) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.resumeTour("open");
|
|
||||||
});
|
|
||||||
|
|
||||||
// If expiresTime is not in the future and the user hasn't
|
// If expiresTime is not in the future and the user hasn't
|
||||||
// previously authenticated then skip registration.
|
// previously authenticated then skip registration.
|
||||||
|
@ -1144,6 +1122,49 @@ this.MozLoopService = {
|
||||||
return deferredInitialization.promise;
|
return deferredInitialization.promise;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maybe resume the tour (re-opening the tab, if necessary) if someone else joins
|
||||||
|
* a room of ours and it's currently open.
|
||||||
|
*/
|
||||||
|
maybeResumeTourOnRoomJoined: function(e, room, participant) {
|
||||||
|
let isOwnerInRoom = false;
|
||||||
|
let isOtherInRoom = false;
|
||||||
|
|
||||||
|
if (!this.getLoopPref("gettingStarted.resumeOnFirstJoin")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!room.participants) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The particpant that joined isn't necessarily included in room.participants (depending on
|
||||||
|
// when the broadcast happens) so concatenate.
|
||||||
|
for (let participant of room.participants.concat(participant)) {
|
||||||
|
if (participant.owner) {
|
||||||
|
isOwnerInRoom = true;
|
||||||
|
} else {
|
||||||
|
isOtherInRoom = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isOwnerInRoom || !isOtherInRoom) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the room chatbox is still actually open using its URL
|
||||||
|
let chatboxesForRoom = [...Chat.chatboxes].filter(chatbox => {
|
||||||
|
return chatbox.src == MozLoopServiceInternal.getChatURL(room.roomToken);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!chatboxesForRoom.length) {
|
||||||
|
log.warn("Tried to resume the tour from a join when the chatbox was closed", room);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.resumeTour("open");
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The core of the initialization work that happens once the browser is ready
|
* The core of the initialization work that happens once the browser is ready
|
||||||
* (after a timer when called during startup).
|
* (after a timer when called during startup).
|
||||||
|
|
|
@ -467,6 +467,9 @@
|
||||||
|
|
||||||
aEvent.preventDefault();
|
aEvent.preventDefault();
|
||||||
aEvent.stopPropagation();
|
aEvent.stopPropagation();
|
||||||
|
|
||||||
|
if (this.hasAttribute("oneoffui"))
|
||||||
|
this.openSuggestionsPanel();
|
||||||
]]></body>
|
]]></body>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
|
@ -647,10 +650,9 @@
|
||||||
|
|
||||||
<field name="_ignoreFocus">false</field>
|
<field name="_ignoreFocus">false</field>
|
||||||
|
|
||||||
<method name="selectEngine">
|
<method name="rebuildPopup">
|
||||||
<body><![CDATA[
|
<body><![CDATA[
|
||||||
// Override this method to avoid accidentally changing the default
|
this._textbox.popup.updateHeader();
|
||||||
// engine using the keyboard shortcuts of the old UI.
|
|
||||||
]]></body>
|
]]></body>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
|
@ -914,7 +916,11 @@
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
// Don't open search popup if history popup is open
|
// Don't open search popup if history popup is open
|
||||||
if (!this.popupOpen) {
|
if (!this.popupOpen) {
|
||||||
document.getBindingParent(this).searchButton.open = true;
|
let searchBox = document.getBindingParent(this);
|
||||||
|
if (searchBox.hasAttribute("oneoffui"))
|
||||||
|
searchBox.openSuggestionsPanel();
|
||||||
|
else
|
||||||
|
searchBox.searchButton.open = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -980,8 +986,54 @@
|
||||||
if (!list)
|
if (!list)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// accel + up/down changes the default engine and shouldn't affect
|
||||||
|
// the selection on the one-off buttons.
|
||||||
|
#ifdef XP_MACOSX
|
||||||
|
if (aEvent.metaKey)
|
||||||
|
#else
|
||||||
|
if (aEvent.ctrlKey)
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
|
||||||
let selectedButton = this.getSelectedOneOff();
|
let selectedButton = this.getSelectedOneOff();
|
||||||
|
|
||||||
|
// Alt + up/down is very similar to (shift +) tab but differs in that
|
||||||
|
// it loops through the list, whereas tab will move the focus out.
|
||||||
|
if (aEvent.altKey &&
|
||||||
|
(aEvent.keyCode == KeyEvent.DOM_VK_DOWN ||
|
||||||
|
aEvent.keyCode == KeyEvent.DOM_VK_UP)) {
|
||||||
|
let forward = aEvent.keyCode == KeyEvent.DOM_VK_DOWN;
|
||||||
|
if (selectedButton) {
|
||||||
|
// cycle though the list of one-off buttons.
|
||||||
|
selectedButton.removeAttribute("selected");
|
||||||
|
if (forward)
|
||||||
|
selectedButton = selectedButton.nextSibling;
|
||||||
|
else
|
||||||
|
selectedButton = selectedButton.previousSibling;
|
||||||
|
|
||||||
|
// Avoid selecting dummy buttons.
|
||||||
|
if (selectedButton && selectedButton.classList.contains("dummy"))
|
||||||
|
selectedButton = null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// If no selection, select the first or last one-off button.
|
||||||
|
if (forward) {
|
||||||
|
selectedButton = list.firstChild;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
selectedButton = list.lastChild;
|
||||||
|
while (selectedButton.classList.contains("dummy"))
|
||||||
|
selectedButton = selectedButton.previousSibling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (selectedButton)
|
||||||
|
selectedButton.setAttribute("selected", "true");
|
||||||
|
|
||||||
|
aEvent.preventDefault();
|
||||||
|
aEvent.stopPropagation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If the last suggestion is selected, DOWN selects the first one-off.
|
// If the last suggestion is selected, DOWN selects the first one-off.
|
||||||
if (aEvent.keyCode == KeyEvent.DOM_VK_DOWN &&
|
if (aEvent.keyCode == KeyEvent.DOM_VK_DOWN &&
|
||||||
popup.selectedIndex + 1 == popup.view.rowCount) {
|
popup.selectedIndex + 1 == popup.view.rowCount) {
|
||||||
|
|
|
@ -71,7 +71,7 @@ function CheckLockState() {
|
||||||
|
|
||||||
let sYes = Strings.GetStringFromName("runtimedetails_checkyes");
|
let sYes = Strings.GetStringFromName("runtimedetails_checkyes");
|
||||||
let sNo = Strings.GetStringFromName("runtimedetails_checkno");
|
let sNo = Strings.GetStringFromName("runtimedetails_checkno");
|
||||||
let sUnknown = Strings.GetStringFromName("runtimedetails_checkunkown");
|
let sUnknown = Strings.GetStringFromName("runtimedetails_checkunknown");
|
||||||
let sNotUSB = Strings.GetStringFromName("runtimedetails_notUSBDevice");
|
let sNotUSB = Strings.GetStringFromName("runtimedetails_notUSBDevice");
|
||||||
|
|
||||||
flipCertPerfButton.setAttribute("disabled", "true");
|
flipCertPerfButton.setAttribute("disabled", "true");
|
||||||
|
|
|
@ -65,7 +65,7 @@ addons_status_installing=installing
|
||||||
|
|
||||||
runtimedetails_checkno=no
|
runtimedetails_checkno=no
|
||||||
runtimedetails_checkyes=yes
|
runtimedetails_checkyes=yes
|
||||||
runtimedetails_checkunkown=unknown
|
runtimedetails_checkunknown=unknown (requires ADB Helper 0.4.0 or later)
|
||||||
runtimedetails_notUSBDevice=Not a USB device
|
runtimedetails_notUSBDevice=Not a USB device
|
||||||
|
|
||||||
# Validation status
|
# Validation status
|
||||||
|
|
|
@ -50,6 +50,38 @@ function getChromeWindow(contentWin) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let Chat = {
|
let Chat = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterator of <chatbox> elements from this module in all windows.
|
||||||
|
*/
|
||||||
|
get chatboxes() {
|
||||||
|
return function*() {
|
||||||
|
let winEnum = Services.wm.getEnumerator("navigator:browser");
|
||||||
|
while (winEnum.hasMoreElements()) {
|
||||||
|
let win = winEnum.getNext();
|
||||||
|
let chatbar = win.document.getElementById("pinnedchats");
|
||||||
|
if (!chatbar)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Make a new array instead of the live NodeList so this iterator can be
|
||||||
|
// used for closing/deleting.
|
||||||
|
let chatboxes = [c for (c of chatbar.children)];
|
||||||
|
for (let chatbox of chatboxes) {
|
||||||
|
yield chatbox;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// include standalone chat windows
|
||||||
|
winEnum = Services.wm.getEnumerator("Social:Chat");
|
||||||
|
while (winEnum.hasMoreElements()) {
|
||||||
|
let win = winEnum.getNext();
|
||||||
|
if (win.closed)
|
||||||
|
continue;
|
||||||
|
yield win.document.getElementById("chatter");
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a new chatbox.
|
* Open a new chatbox.
|
||||||
*
|
*
|
||||||
|
@ -108,26 +140,11 @@ let Chat = {
|
||||||
* The origin from which all chats should be closed.
|
* The origin from which all chats should be closed.
|
||||||
*/
|
*/
|
||||||
closeAll: function(origin) {
|
closeAll: function(origin) {
|
||||||
// close all attached chat windows
|
for (let chatbox of this.chatboxes) {
|
||||||
let winEnum = Services.wm.getEnumerator("navigator:browser");
|
if (chatbox.content.getAttribute("origin") != origin) {
|
||||||
while (winEnum.hasMoreElements()) {
|
|
||||||
let win = winEnum.getNext();
|
|
||||||
let chatbar = win.document.getElementById("pinnedchats");
|
|
||||||
if (!chatbar)
|
|
||||||
continue;
|
continue;
|
||||||
let chats = [c for (c of chatbar.children) if (c.content.getAttribute("origin") == origin)];
|
}
|
||||||
[c.close() for (c of chats)];
|
chatbox.close();
|
||||||
}
|
|
||||||
|
|
||||||
// close all standalone chat windows
|
|
||||||
winEnum = Services.wm.getEnumerator("Social:Chat");
|
|
||||||
while (winEnum.hasMoreElements()) {
|
|
||||||
let win = winEnum.getNext();
|
|
||||||
if (win.closed)
|
|
||||||
continue;
|
|
||||||
let chatOrigin = win.document.getElementById("chatter").content.getAttribute("origin");
|
|
||||||
if (origin == chatOrigin)
|
|
||||||
win.close();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -400,7 +400,7 @@ SocialErrorListener.prototype = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function sizeSocialPanelToContent(panel, iframe) {
|
function sizeSocialPanelToContent(panel, iframe, requestedSize) {
|
||||||
let doc = iframe.contentDocument;
|
let doc = iframe.contentDocument;
|
||||||
if (!doc || !doc.body) {
|
if (!doc || !doc.body) {
|
||||||
return;
|
return;
|
||||||
|
@ -408,14 +408,15 @@ function sizeSocialPanelToContent(panel, iframe) {
|
||||||
// We need an element to use for sizing our panel. See if the body defines
|
// We need an element to use for sizing our panel. See if the body defines
|
||||||
// an id for that element, otherwise use the body itself.
|
// an id for that element, otherwise use the body itself.
|
||||||
let body = doc.body;
|
let body = doc.body;
|
||||||
|
let docEl = doc.documentElement;
|
||||||
let bodyId = body.getAttribute("contentid");
|
let bodyId = body.getAttribute("contentid");
|
||||||
if (bodyId) {
|
if (bodyId) {
|
||||||
body = doc.getElementById(bodyId) || doc.body;
|
body = doc.getElementById(bodyId) || doc.body;
|
||||||
}
|
}
|
||||||
// offsetHeight/Width don't include margins, so account for that.
|
// offsetHeight/Width don't include margins, so account for that.
|
||||||
let cs = doc.defaultView.getComputedStyle(body);
|
let cs = doc.defaultView.getComputedStyle(body);
|
||||||
let width = PANEL_MIN_WIDTH;
|
let width = Math.max(PANEL_MIN_WIDTH, docEl.offsetWidth);
|
||||||
let height = PANEL_MIN_HEIGHT;
|
let height = Math.max(PANEL_MIN_HEIGHT, docEl.offsetHeight);
|
||||||
// if the panel is preloaded prior to being shown, cs will be null. in that
|
// if the panel is preloaded prior to being shown, cs will be null. in that
|
||||||
// case use the minimum size for the panel until it is shown.
|
// case use the minimum size for the panel until it is shown.
|
||||||
if (cs) {
|
if (cs) {
|
||||||
|
@ -425,19 +426,33 @@ function sizeSocialPanelToContent(panel, iframe) {
|
||||||
width = Math.max(computedWidth, width);
|
width = Math.max(computedWidth, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
// only add the extra space if the iframe has been loaded
|
// if our scrollHeight is still larger than the iframe, the css calculations
|
||||||
|
// above did not work for this site, increase the height. This can happen if
|
||||||
|
// the site increases its height for additional UI.
|
||||||
|
if (docEl.scrollHeight > iframe.boxObject.height)
|
||||||
|
height = docEl.scrollHeight;
|
||||||
|
|
||||||
|
// if a size was defined in the manifest use it as a minimum
|
||||||
|
if (requestedSize) {
|
||||||
|
if (requestedSize.height)
|
||||||
|
height = Math.max(height, requestedSize.height);
|
||||||
|
if (requestedSize.width)
|
||||||
|
width = Math.max(width, requestedSize.width);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the extra space used by the panel (toolbar, borders, etc) if the iframe
|
||||||
|
// has been loaded
|
||||||
if (iframe.boxObject.width && iframe.boxObject.height) {
|
if (iframe.boxObject.width && iframe.boxObject.height) {
|
||||||
// add extra space the panel needs if any
|
// add extra space the panel needs if any
|
||||||
width += panel.boxObject.width - iframe.boxObject.width;
|
width += panel.boxObject.width - iframe.boxObject.width;
|
||||||
height += panel.boxObject.height - iframe.boxObject.height;
|
height += panel.boxObject.height - iframe.boxObject.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
// when size is computed, we want to be sure changes are "significant" since
|
// using panel.sizeTo will ignore css transitions, set size via style
|
||||||
// some sites will resize when the iframe is resized by a small amount, making
|
if (Math.abs(panel.boxObject.width - width) >= 2)
|
||||||
// the panel slowly shrink to some minimum.
|
panel.style.width = width + "px";
|
||||||
if (Math.abs(panel.boxObject.width - width) > 2 || Math.abs(panel.boxObject.height - height) > 2) {
|
if (Math.abs(panel.boxObject.height - height) >= 2)
|
||||||
panel.sizeTo(width, height);
|
panel.style.height = height + "px";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function DynamicResizeWatcher() {
|
function DynamicResizeWatcher() {
|
||||||
|
@ -445,18 +460,18 @@ function DynamicResizeWatcher() {
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicResizeWatcher.prototype = {
|
DynamicResizeWatcher.prototype = {
|
||||||
start: function DynamicResizeWatcher_start(panel, iframe) {
|
start: function DynamicResizeWatcher_start(panel, iframe, requestedSize) {
|
||||||
this.stop(); // just in case...
|
this.stop(); // just in case...
|
||||||
let doc = iframe.contentDocument;
|
let doc = iframe.contentDocument;
|
||||||
this._mutationObserver = new iframe.contentWindow.MutationObserver(function(mutations) {
|
this._mutationObserver = new iframe.contentWindow.MutationObserver((mutations) => {
|
||||||
sizeSocialPanelToContent(panel, iframe);
|
sizeSocialPanelToContent(panel, iframe, requestedSize);
|
||||||
});
|
});
|
||||||
// Observe anything that causes the size to change.
|
// Observe anything that causes the size to change.
|
||||||
let config = {attributes: true, characterData: true, childList: true, subtree: true};
|
let config = {attributes: true, characterData: true, childList: true, subtree: true};
|
||||||
this._mutationObserver.observe(doc, config);
|
this._mutationObserver.observe(doc, config);
|
||||||
// and since this may be setup after the load event has fired we do an
|
// and since this may be setup after the load event has fired we do an
|
||||||
// initial resize now.
|
// initial resize now.
|
||||||
sizeSocialPanelToContent(panel, iframe);
|
sizeSocialPanelToContent(panel, iframe, requestedSize);
|
||||||
},
|
},
|
||||||
stop: function DynamicResizeWatcher_stop() {
|
stop: function DynamicResizeWatcher_stop() {
|
||||||
if (this._mutationObserver) {
|
if (this._mutationObserver) {
|
||||||
|
|
|
@ -1609,46 +1609,47 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
||||||
/* social share panel */
|
/* social share panel */
|
||||||
|
|
||||||
.social-share-frame {
|
.social-share-frame {
|
||||||
background: linear-gradient(to bottom, rgba(242,242,242,.99), rgba(242,242,242,.95));
|
border-top: 1px solid #f8f8f8;
|
||||||
border-left: 1px solid #f8f8f8;
|
width: 756px;
|
||||||
width: 330px;
|
|
||||||
height: 150px;
|
height: 150px;
|
||||||
/* we resize our panels dynamically, make it look nice */
|
}
|
||||||
transition: height 100ms ease-out, width 100ms ease-out;
|
|
||||||
|
#share-container {
|
||||||
|
min-width: 756px;
|
||||||
|
background-color: white;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
#share-container[loading] {
|
||||||
|
background-image: url(chrome://browser/skin/tabbrowser/pendingpaint.png);
|
||||||
|
}
|
||||||
|
#share-container > browser {
|
||||||
|
transition: opacity 150ms ease-in-out;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
#share-container[loading] > browser {
|
||||||
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.social-share-toolbar {
|
.social-share-toolbar {
|
||||||
border-right: 1px solid #dedede;
|
border-bottom: 1px solid #dedede;
|
||||||
background: linear-gradient(to bottom, rgba(247,247,247,.99), rgba(247,247,247,.95));
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-share-provider-buttons {
|
#social-share-provider-buttons {
|
||||||
border-right: 1px solid #fbfbfb;
|
padding: 0;
|
||||||
padding: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#social-share-provider-buttons > .share-provider-button {
|
|
||||||
padding: 6px;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border: none;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-share-provider-buttons > .share-provider-button[checked],
|
.share-provider-button {
|
||||||
#social-share-provider-buttons > .share-provider-button:active {
|
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
border: 1px solid #b5b5b8;
|
margin: 2px;
|
||||||
box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-share-provider-buttons > .share-provider-button[checked] {
|
.share-provider-button > .toolbarbutton-text {
|
||||||
background: linear-gradient(to bottom, #d9d9d9, #e3e3e3);
|
|
||||||
}
|
|
||||||
|
|
||||||
#social-share-provider-buttons > .share-provider-button > .toolbarbutton-text {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#social-share-provider-buttons > .share-provider-button > .toolbarbutton-icon {
|
.share-provider-button > .toolbarbutton-icon {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
min-height: 16px;
|
min-height: 16px;
|
||||||
max-height: 16px;
|
max-height: 16px;
|
||||||
|
|
|
@ -2514,46 +2514,55 @@ richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-
|
||||||
|
|
||||||
/* social share panel */
|
/* social share panel */
|
||||||
.social-share-frame {
|
.social-share-frame {
|
||||||
background: linear-gradient(to bottom, rgba(242,242,242,.99), rgba(242,242,242,.95));
|
border-top: 1px solid #f8f8f8;
|
||||||
border-left: 1px solid #f8f8f8;
|
min-width: 756px;
|
||||||
width: 330px;
|
|
||||||
height: 150px;
|
height: 150px;
|
||||||
/* we resize our panels dynamically, make it look nice */
|
/* we resize our panels dynamically, make it look nice */
|
||||||
transition: height 100ms ease-out, width 100ms ease-out;
|
}
|
||||||
|
|
||||||
|
#share-container {
|
||||||
|
min-width: 756px;
|
||||||
|
background-color: white;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
#share-container[loading] {
|
||||||
|
background-image: url(chrome://browser/skin/tabbrowser/pendingpaint.png);
|
||||||
|
}
|
||||||
|
#share-container > browser {
|
||||||
|
transition: opacity 150ms ease-in-out;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
#share-container[loading] > browser {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#manage-share-providers,
|
||||||
|
#social-sidebar-button:hover,
|
||||||
|
#social-sidebar-button:hover:active {
|
||||||
|
-moz-image-region: rect(18px, 468px, 36px, 450px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.social-share-toolbar {
|
.social-share-toolbar {
|
||||||
border-right: 1px solid #dedede;
|
border-bottom: 1px solid #dedede;
|
||||||
background: linear-gradient(to bottom, rgba(247,247,247,.99), rgba(247,247,247,.95));
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-share-provider-buttons {
|
#social-share-provider-buttons {
|
||||||
border-right: 1px solid #fbfbfb;
|
padding: 0;
|
||||||
padding: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#social-share-provider-buttons > .share-provider-button {
|
|
||||||
padding: 6px;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border: none;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-share-provider-buttons > .share-provider-button[checked],
|
.share-provider-button {
|
||||||
#social-share-provider-buttons > .share-provider-button:active {
|
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
border: 1px solid #b5b5b8;
|
margin: 2px;
|
||||||
box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-share-provider-buttons > .share-provider-button[checked] {
|
.share-provider-button > .toolbarbutton-text {
|
||||||
background: linear-gradient(to bottom, #d9d9d9, #e3e3e3);
|
|
||||||
}
|
|
||||||
|
|
||||||
#social-share-provider-buttons > .share-provider-button > .toolbarbutton-text {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#social-share-provider-buttons > .share-provider-button > .toolbarbutton-icon {
|
|
||||||
|
.share-provider-button > .toolbarbutton-icon {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
min-height: 16px;
|
min-height: 16px;
|
||||||
max-height: 16px;
|
max-height: 16px;
|
||||||
|
@ -4500,44 +4509,27 @@ menulist.translate-infobar-element > .menulist-dropmarker {
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-share-panel {
|
#social-share-panel {
|
||||||
max-height: 600px;
|
|
||||||
min-height: 100px;
|
min-height: 100px;
|
||||||
max-width: 800px;
|
|
||||||
min-width: 300px;
|
min-width: 300px;
|
||||||
|
transition: height .3s ease-in-out, width .3s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.social-share-frame:-moz-locale-dir(ltr) {
|
#share-container,
|
||||||
|
.social-share-frame {
|
||||||
border-top-left-radius: 0;
|
border-top-left-radius: 0;
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
border-top-right-radius: inherit;
|
|
||||||
border-bottom-right-radius: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.social-share-frame:-moz-locale-dir(rtl) {
|
|
||||||
border-top-left-radius: inherit;
|
|
||||||
border-bottom-left-radius: inherit;
|
border-bottom-left-radius: inherit;
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0;
|
||||||
border-bottom-right-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#social-share-panel > .social-share-toolbar:-moz-locale-dir(ltr) {
|
|
||||||
border-top-left-radius: inherit;
|
|
||||||
border-bottom-left-radius: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
#social-share-panel > .social-share-toolbar:-moz-locale-dir(rtl) {
|
|
||||||
border-top-right-radius: inherit;
|
|
||||||
border-bottom-right-radius: inherit;
|
border-bottom-right-radius: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-share-provider-buttons:-moz-locale-dir(ltr) {
|
#social-share-panel > .social-share-toolbar {
|
||||||
border-top-left-radius: inherit;
|
border-top-left-radius: inherit;
|
||||||
border-bottom-left-radius: inherit;
|
border-top-right-radius: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-share-provider-buttons:-moz-locale-dir(rtl) {
|
#social-share-provider-buttons {
|
||||||
|
border-top-left-radius: inherit;
|
||||||
border-top-right-radius: inherit;
|
border-top-right-radius: inherit;
|
||||||
border-bottom-right-radius: inherit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* === end of social toolbar provider menu === */
|
/* === end of social toolbar provider menu === */
|
||||||
|
|
|
@ -702,6 +702,7 @@ panelview .toolbarbutton-1,
|
||||||
.subviewbutton,
|
.subviewbutton,
|
||||||
.widget-overflow-list .toolbarbutton-1,
|
.widget-overflow-list .toolbarbutton-1,
|
||||||
.panelUI-grid .toolbarbutton-1 > .toolbarbutton-menubutton-button,
|
.panelUI-grid .toolbarbutton-1 > .toolbarbutton-menubutton-button,
|
||||||
|
.share-provider-button,
|
||||||
.toolbaritem-combined-buttons@inAnyPanel@ > toolbarbutton {
|
.toolbaritem-combined-buttons@inAnyPanel@ > toolbarbutton {
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
padding: 0 6px;
|
padding: 0 6px;
|
||||||
|
@ -714,6 +715,7 @@ panelview .toolbarbutton-1,
|
||||||
panelview .toolbarbutton-1,
|
panelview .toolbarbutton-1,
|
||||||
.subviewbutton,
|
.subviewbutton,
|
||||||
.widget-overflow-list .toolbarbutton-1,
|
.widget-overflow-list .toolbarbutton-1,
|
||||||
|
.share-provider-button,
|
||||||
.toolbaritem-combined-buttons@inAnyPanel@ > toolbarbutton {
|
.toolbaritem-combined-buttons@inAnyPanel@ > toolbarbutton {
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
}
|
}
|
||||||
|
@ -786,6 +788,7 @@ panelview .toolbarbutton-1@buttonStateHover@,
|
||||||
toolbarbutton.subviewbutton@buttonStateHover@,
|
toolbarbutton.subviewbutton@buttonStateHover@,
|
||||||
menu.subviewbutton@menuStateHover@,
|
menu.subviewbutton@menuStateHover@,
|
||||||
menuitem.subviewbutton@menuStateHover@,
|
menuitem.subviewbutton@menuStateHover@,
|
||||||
|
.share-provider-button@buttonStateHover@,
|
||||||
.widget-overflow-list .toolbarbutton-1@buttonStateHover@,
|
.widget-overflow-list .toolbarbutton-1@buttonStateHover@,
|
||||||
.toolbaritem-combined-buttons@inAnyPanel@ > toolbarbutton@buttonStateHover@ {
|
.toolbaritem-combined-buttons@inAnyPanel@ > toolbarbutton@buttonStateHover@ {
|
||||||
background-color: hsla(210,4%,10%,.08);
|
background-color: hsla(210,4%,10%,.08);
|
||||||
|
@ -800,6 +803,7 @@ panelview .toolbarbutton-1:-moz-any(@buttonStateActive@,[checked=true]),
|
||||||
toolbarbutton.subviewbutton@buttonStateActive@,
|
toolbarbutton.subviewbutton@buttonStateActive@,
|
||||||
menu.subviewbutton@menuStateActive@,
|
menu.subviewbutton@menuStateActive@,
|
||||||
menuitem.subviewbutton@menuStateActive@,
|
menuitem.subviewbutton@menuStateActive@,
|
||||||
|
.share-provider-button:-moz-any(@buttonStateActive@,[checked=true]),
|
||||||
.widget-overflow-list .toolbarbutton-1@buttonStateActive@,
|
.widget-overflow-list .toolbarbutton-1@buttonStateActive@,
|
||||||
.toolbaritem-combined-buttons@inAnyPanel@ > toolbarbutton@buttonStateActive@ {
|
.toolbaritem-combined-buttons@inAnyPanel@ > toolbarbutton@buttonStateActive@ {
|
||||||
background-color: hsla(210,4%,10%,.12);
|
background-color: hsla(210,4%,10%,.12);
|
||||||
|
|
|
@ -8,21 +8,24 @@
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#manage-share-providers,
|
||||||
|
#social-sidebar-button {
|
||||||
|
list-style-image: url("chrome://browser/skin/Toolbar.png");
|
||||||
|
-moz-image-region: rect(0, 468px, 18px, 450px);
|
||||||
|
}
|
||||||
|
|
||||||
#social-sidebar-button {
|
#social-sidebar-button {
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
list-style-image: url(chrome://browser/skin/social/gear_default.png);
|
|
||||||
border: none;
|
border: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 2px;
|
margin: 2px;
|
||||||
}
|
}
|
||||||
|
#manage-share-providers > .toolbarbutton-icon,
|
||||||
#social-sidebar-button > .toolbarbutton-icon {
|
#social-sidebar-button > .toolbarbutton-icon {
|
||||||
min-height: 16px;
|
min-height: 18px;
|
||||||
min-width: 16px;
|
min-width: 18px;
|
||||||
}
|
|
||||||
#social-sidebar-button:hover,
|
|
||||||
#social-sidebar-button:hover:active {
|
|
||||||
list-style-image: url(chrome://browser/skin/social/gear_clicked.png);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-sidebar-button > .toolbarbutton-menu-dropmarker {
|
#social-sidebar-button > .toolbarbutton-menu-dropmarker {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1573,46 +1573,46 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
||||||
|
|
||||||
/* social share panel */
|
/* social share panel */
|
||||||
|
|
||||||
#social-share-panel > iframe {
|
.social-share-frame {
|
||||||
background: linear-gradient(to bottom, #f0f4f7, #fafbfc);
|
min-width: 756px;
|
||||||
width: 300px;
|
|
||||||
height: 150px;
|
height: 150px;
|
||||||
}
|
}
|
||||||
|
#share-container {
|
||||||
|
min-width: 756px;
|
||||||
|
background-color: white;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
#share-container[loading] {
|
||||||
|
background-image: url(chrome://browser/skin/tabbrowser/pendingpaint.png);
|
||||||
|
}
|
||||||
|
#share-container > browser {
|
||||||
|
transition: opacity 150ms ease-in-out;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
#share-container[loading] > browser {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.social-share-toolbar {
|
.social-share-toolbar {
|
||||||
border-right: 1px solid #e2e5e8;
|
border-bottom: 1px solid #e2e5e8;
|
||||||
background: linear-gradient(to bottom, #ffffff, #f5f7fa);
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-share-provider-buttons {
|
#social-share-provider-buttons {
|
||||||
padding: 6px;
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-share-provider-buttons > .share-provider-button {
|
.share-provider-button {
|
||||||
-moz-appearance: none;
|
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
margin: 1px;
|
margin: 2px;
|
||||||
border: none;
|
|
||||||
background: none;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-share-provider-buttons > .share-provider-button[checked="true"]:not([disabled="true"]),
|
.share-provider-button > .toolbarbutton-text {
|
||||||
#social-share-provider-buttons > .share-provider-button:hover,
|
|
||||||
#social-share-provider-buttons > .share-provider-button:active {
|
|
||||||
padding: 4px;
|
|
||||||
border: 1px solid #aeb8c1;
|
|
||||||
box-shadow: inset 1px 1px 1px rgba(10, 31, 51, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#social-share-provider-buttons > .share-provider-button[checked="true"]:not([disabled="true"]) {
|
|
||||||
background: linear-gradient(to bottom, rgba(230,232,234,.65), #d2d5d9);
|
|
||||||
}
|
|
||||||
|
|
||||||
#social-share-provider-buttons > .share-provider-button > .toolbarbutton-text {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#social-share-provider-buttons > .share-provider-button > .toolbarbutton-icon {
|
.share-provider-button > .toolbarbutton-icon {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
min-height: 16px;
|
min-height: 16px;
|
||||||
max-height: 16px;
|
max-height: 16px;
|
||||||
|
@ -1632,52 +1632,26 @@ toolbarbutton[type="socialmark"] > .toolbarbutton-icon {
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-share-panel {
|
#social-share-panel {
|
||||||
max-height: 600px;
|
|
||||||
min-height: 100px;
|
min-height: 100px;
|
||||||
max-width: 800px;
|
min-width: 766px;
|
||||||
min-width: 300px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#share-container,
|
||||||
.social-share-frame {
|
.social-share-frame {
|
||||||
background: linear-gradient(to bottom, #f0f4f7, #fafbfc);
|
|
||||||
width: 330px;
|
|
||||||
height: 150px;
|
|
||||||
/* we resize our panels dynamically, make it look nice */
|
|
||||||
transition: height 100ms ease-out, width 100ms ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.social-share-frame:-moz-locale-dir(ltr) {
|
|
||||||
border-top-left-radius: 0;
|
border-top-left-radius: 0;
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
border-top-right-radius: inherit;
|
|
||||||
border-bottom-right-radius: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.social-share-frame:-moz-locale-dir(rtl) {
|
|
||||||
border-top-left-radius: inherit;
|
|
||||||
border-bottom-left-radius: inherit;
|
border-bottom-left-radius: inherit;
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0;
|
||||||
border-bottom-right-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#social-share-panel > .social-share-toolbar:-moz-locale-dir(ltr) {
|
|
||||||
border-top-left-radius: inherit;
|
|
||||||
border-bottom-left-radius: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
#social-share-panel > .social-share-toolbar:-moz-locale-dir(rtl) {
|
|
||||||
border-top-right-radius: inherit;
|
|
||||||
border-bottom-right-radius: inherit;
|
border-bottom-right-radius: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-share-provider-buttons:-moz-locale-dir(ltr) {
|
#social-share-panel > .social-share-toolbar {
|
||||||
border-top-left-radius: inherit;
|
border-top-left-radius: inherit;
|
||||||
border-bottom-left-radius: inherit;
|
border-top-right-radius: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#social-share-provider-buttons:-moz-locale-dir(rtl) {
|
#social-share-provider-buttons {
|
||||||
|
border-top-left-radius: inherit;
|
||||||
border-top-right-radius: inherit;
|
border-top-right-radius: inherit;
|
||||||
border-bottom-right-radius: inherit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* social recommending panel */
|
/* social recommending panel */
|
||||||
|
|
|
@ -686,6 +686,8 @@ browser.jar:
|
||||||
skin/classic/aero/browser/tabbrowser/tab-background-end@2x.png (tabbrowser/tab-background-end@2x.png)
|
skin/classic/aero/browser/tabbrowser/tab-background-end@2x.png (tabbrowser/tab-background-end@2x.png)
|
||||||
skin/classic/aero/browser/tabbrowser/tab-overflow-indicator.png (../shared/tabbrowser/tab-overflow-indicator.png)
|
skin/classic/aero/browser/tabbrowser/tab-overflow-indicator.png (../shared/tabbrowser/tab-overflow-indicator.png)
|
||||||
|
|
||||||
|
skin/classic/aero/browser/tabbrowser/pendingpaint.png (../shared/tabbrowser/pendingpaint.png)
|
||||||
|
|
||||||
# NOTE: The following two files (tab-selected-end.svg, tab-selected-start.svg) get pre-processed in
|
# NOTE: The following two files (tab-selected-end.svg, tab-selected-start.svg) get pre-processed in
|
||||||
# Makefile.in with a non-default marker of "%" and the result of that gets packaged.
|
# Makefile.in with a non-default marker of "%" and the result of that gets packaged.
|
||||||
skin/classic/aero/browser/tabbrowser/tab-selected-end.svg (tab-selected-end-aero.svg)
|
skin/classic/aero/browser/tabbrowser/tab-selected-end.svg (tab-selected-end-aero.svg)
|
||||||
|
|
|
@ -36,6 +36,11 @@ support-files =
|
||||||
print_postdata.sjs
|
print_postdata.sjs
|
||||||
test-form_sjis.html
|
test-form_sjis.html
|
||||||
timelineMarkers-04.html
|
timelineMarkers-04.html
|
||||||
|
browser_timelineMarkers-frame-02.js
|
||||||
|
browser_timelineMarkers-frame-03.js
|
||||||
|
browser_timelineMarkers-frame-04.js
|
||||||
|
head.js
|
||||||
|
frame-head.js
|
||||||
|
|
||||||
[browser_bug134911.js]
|
[browser_bug134911.js]
|
||||||
skip-if = e10s # Bug ?????? - BrowserSetForcedCharacterSet() in browser.js references docShell
|
skip-if = e10s # Bug ?????? - BrowserSetForcedCharacterSet() in browser.js references docShell
|
||||||
|
@ -98,8 +103,5 @@ skip-if = e10s
|
||||||
[browser_search_notification.js]
|
[browser_search_notification.js]
|
||||||
[browser_timelineMarkers-01.js]
|
[browser_timelineMarkers-01.js]
|
||||||
[browser_timelineMarkers-02.js]
|
[browser_timelineMarkers-02.js]
|
||||||
skip-if = e10s
|
|
||||||
[browser_timelineMarkers-03.js]
|
[browser_timelineMarkers-03.js]
|
||||||
skip-if = e10s
|
|
||||||
[browser_timelineMarkers-04.js]
|
[browser_timelineMarkers-04.js]
|
||||||
skip-if = e10s
|
|
||||||
|
|
|
@ -3,9 +3,6 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// Test that the docShell profile timeline API returns the right markers when
|
|
||||||
// restyles, reflows and paints occur
|
|
||||||
|
|
||||||
let URL = '<!DOCTYPE html><style>' +
|
let URL = '<!DOCTYPE html><style>' +
|
||||||
'body {margin:0; padding: 0;} ' +
|
'body {margin:0; padding: 0;} ' +
|
||||||
'div {width:100px;height:100px;background:red;} ' +
|
'div {width:100px;height:100px;background:red;} ' +
|
||||||
|
@ -13,157 +10,6 @@ let URL = '<!DOCTYPE html><style>' +
|
||||||
'.change-color {width:50px;height:50px;background:yellow;} ' +
|
'.change-color {width:50px;height:50px;background:yellow;} ' +
|
||||||
'.add-class {}' +
|
'.add-class {}' +
|
||||||
'</style><div></div>';
|
'</style><div></div>';
|
||||||
|
URL = "data:text/html;charset=utf8," + encodeURIComponent(URL);
|
||||||
|
|
||||||
let TESTS = [{
|
let test = makeTimelineTest("browser_timelineMarkers-frame-02.js", URL);
|
||||||
desc: "Changing the width of the test element",
|
|
||||||
searchFor: "Paint",
|
|
||||||
setup: function(div) {
|
|
||||||
div.setAttribute("class", "resize-change-color");
|
|
||||||
},
|
|
||||||
check: function(markers) {
|
|
||||||
ok(markers.length > 0, "markers were returned");
|
|
||||||
console.log(markers);
|
|
||||||
info(JSON.stringify(markers.filter(m => m.name == "Paint")));
|
|
||||||
ok(markers.some(m => m.name == "Reflow"), "markers includes Reflow");
|
|
||||||
ok(markers.some(m => m.name == "Paint"), "markers includes Paint");
|
|
||||||
for (let marker of markers.filter(m => m.name == "Paint")) {
|
|
||||||
// This change should generate at least one rectangle.
|
|
||||||
ok(marker.rectangles.length >= 1, "marker has one rectangle");
|
|
||||||
// One of the rectangles should contain the div.
|
|
||||||
ok(marker.rectangles.some(r => rectangleContains(r, 0, 0, 100, 100)));
|
|
||||||
}
|
|
||||||
ok(markers.some(m => m.name == "Styles"), "markers includes Restyle");
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
desc: "Changing the test element's background color",
|
|
||||||
searchFor: "Paint",
|
|
||||||
setup: function(div) {
|
|
||||||
div.setAttribute("class", "change-color");
|
|
||||||
},
|
|
||||||
check: function(markers) {
|
|
||||||
ok(markers.length > 0, "markers were returned");
|
|
||||||
ok(!markers.some(m => m.name == "Reflow"), "markers doesn't include Reflow");
|
|
||||||
ok(markers.some(m => m.name == "Paint"), "markers includes Paint");
|
|
||||||
for (let marker of markers.filter(m => m.name == "Paint")) {
|
|
||||||
// This change should generate at least one rectangle.
|
|
||||||
ok(marker.rectangles.length >= 1, "marker has one rectangle");
|
|
||||||
// One of the rectangles should contain the div.
|
|
||||||
ok(marker.rectangles.some(r => rectangleContains(r, 0, 0, 50, 50)));
|
|
||||||
}
|
|
||||||
ok(markers.some(m => m.name == "Styles"), "markers includes Restyle");
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
desc: "Changing the test element's classname",
|
|
||||||
searchFor: "Paint",
|
|
||||||
setup: function(div) {
|
|
||||||
div.setAttribute("class", "change-color add-class");
|
|
||||||
},
|
|
||||||
check: function(markers) {
|
|
||||||
ok(markers.length > 0, "markers were returned");
|
|
||||||
ok(!markers.some(m => m.name == "Reflow"), "markers doesn't include Reflow");
|
|
||||||
ok(!markers.some(m => m.name == "Paint"), "markers doesn't include Paint");
|
|
||||||
ok(markers.some(m => m.name == "Styles"), "markers includes Restyle");
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
desc: "sync console.time/timeEnd",
|
|
||||||
searchFor: "ConsoleTime",
|
|
||||||
setup: function(div, docShell) {
|
|
||||||
content.console.time("FOOBAR");
|
|
||||||
content.console.timeEnd("FOOBAR");
|
|
||||||
let markers = docShell.popProfileTimelineMarkers();
|
|
||||||
is(markers.length, 1, "Got one marker");
|
|
||||||
is(markers[0].name, "ConsoleTime", "Got ConsoleTime marker");
|
|
||||||
is(markers[0].causeName, "FOOBAR", "Got ConsoleTime FOOBAR detail");
|
|
||||||
content.console.time("FOO");
|
|
||||||
content.setTimeout(() => {
|
|
||||||
content.console.time("BAR");
|
|
||||||
content.setTimeout(() => {
|
|
||||||
content.console.timeEnd("FOO");
|
|
||||||
content.console.timeEnd("BAR");
|
|
||||||
}, 100);
|
|
||||||
}, 100);
|
|
||||||
},
|
|
||||||
check: function(markers) {
|
|
||||||
is(markers.length, 2, "Got 2 markers");
|
|
||||||
is(markers[0].name, "ConsoleTime", "Got first ConsoleTime marker");
|
|
||||||
is(markers[0].causeName, "FOO", "Got ConsoleTime FOO detail");
|
|
||||||
is(markers[1].name, "ConsoleTime", "Got second ConsoleTime marker");
|
|
||||||
is(markers[1].causeName, "BAR", "Got ConsoleTime BAR detail");
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
|
|
||||||
let test = Task.async(function*() {
|
|
||||||
waitForExplicitFinish();
|
|
||||||
|
|
||||||
yield openUrl("data:text/html;charset=utf8," + encodeURIComponent(URL));
|
|
||||||
|
|
||||||
let docShell = content.QueryInterface(Ci.nsIInterfaceRequestor)
|
|
||||||
.getInterface(Ci.nsIWebNavigation)
|
|
||||||
.QueryInterface(Ci.nsIDocShell);
|
|
||||||
|
|
||||||
let div = content.document.querySelector("div");
|
|
||||||
|
|
||||||
info("Start recording");
|
|
||||||
docShell.recordProfileTimelineMarkers = true;
|
|
||||||
|
|
||||||
for (let {desc, searchFor, setup, check} of TESTS) {
|
|
||||||
|
|
||||||
info("Running test: " + desc);
|
|
||||||
|
|
||||||
info("Flushing the previous markers if any");
|
|
||||||
docShell.popProfileTimelineMarkers();
|
|
||||||
|
|
||||||
info("Running the test setup function");
|
|
||||||
let onMarkers = waitForMarkers(docShell, searchFor);
|
|
||||||
setup(div, docShell);
|
|
||||||
info("Waiting for new markers on the docShell");
|
|
||||||
let markers = yield onMarkers;
|
|
||||||
|
|
||||||
info("Running the test check function");
|
|
||||||
check(markers);
|
|
||||||
}
|
|
||||||
|
|
||||||
info("Stop recording");
|
|
||||||
docShell.recordProfileTimelineMarkers = false;
|
|
||||||
|
|
||||||
gBrowser.removeCurrentTab();
|
|
||||||
finish();
|
|
||||||
});
|
|
||||||
|
|
||||||
function openUrl(url) {
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
window.focus();
|
|
||||||
|
|
||||||
let tab = window.gBrowser.selectedTab = window.gBrowser.addTab(url);
|
|
||||||
let linkedBrowser = tab.linkedBrowser;
|
|
||||||
|
|
||||||
linkedBrowser.addEventListener("load", function onload() {
|
|
||||||
linkedBrowser.removeEventListener("load", onload, true);
|
|
||||||
resolve(tab);
|
|
||||||
}, true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function waitForMarkers(docshell, searchFor) {
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
let waitIterationCount = 0;
|
|
||||||
let maxWaitIterationCount = 10; // Wait for 2sec maximum
|
|
||||||
let markers = [];
|
|
||||||
|
|
||||||
let interval = setInterval(() => {
|
|
||||||
let newMarkers = docshell.popProfileTimelineMarkers();
|
|
||||||
markers = [...markers, ...newMarkers];
|
|
||||||
if (newMarkers.some(m => m.name == searchFor) ||
|
|
||||||
waitIterationCount > maxWaitIterationCount) {
|
|
||||||
clearInterval(interval);
|
|
||||||
resolve(markers);
|
|
||||||
}
|
|
||||||
waitIterationCount++;
|
|
||||||
}, 200);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function rectangleContains(rect, x, y, width, height) {
|
|
||||||
return rect.x <= x && rect.y <= y && rect.width >= width &&
|
|
||||||
rect.height >= height;
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,139 +3,6 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// Test that the docShell profile timeline API returns the right
|
let URL = "data:text/html;charset=utf-8,<p>Test page</p>";
|
||||||
// markers for DOM events.
|
|
||||||
|
|
||||||
let TESTS = [{
|
let test = makeTimelineTest("browser_timelineMarkers-frame-03.js", URL);
|
||||||
desc: "Event dispatch with single handler",
|
|
||||||
setup: function() {
|
|
||||||
content.document.body.addEventListener("dog",
|
|
||||||
function(e) { console.log("hi"); },
|
|
||||||
true);
|
|
||||||
content.document.body.dispatchEvent(new Event("dog"));
|
|
||||||
},
|
|
||||||
check: function(markers) {
|
|
||||||
is(markers.length, 1, "Got 1 marker");
|
|
||||||
is(markers[0].type, "dog", "Got dog event name");
|
|
||||||
is(markers[0].eventPhase, 2, "Got phase 2");
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
desc: "Event dispatch with a second handler",
|
|
||||||
setup: function() {
|
|
||||||
content.document.body.addEventListener("dog",
|
|
||||||
function(e) { console.log("hi"); },
|
|
||||||
false);
|
|
||||||
content.document.body.dispatchEvent(new Event("dog"));
|
|
||||||
},
|
|
||||||
check: function(markers) {
|
|
||||||
is(markers.length, 2, "Got 2 markers");
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
desc: "Event targeted at child",
|
|
||||||
setup: function() {
|
|
||||||
let child = content.document.body.firstElementChild;
|
|
||||||
child.addEventListener("dog", function(e) { });
|
|
||||||
child.dispatchEvent(new Event("dog"));
|
|
||||||
},
|
|
||||||
check: function(markers) {
|
|
||||||
is(markers.length, 2, "Got 2 markers");
|
|
||||||
is(markers[0].eventPhase, 1, "Got phase 1 marker");
|
|
||||||
is(markers[1].eventPhase, 2, "Got phase 2 marker");
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
desc: "Event dispatch on a new document",
|
|
||||||
setup: function() {
|
|
||||||
let doc = content.document.implementation.createHTMLDocument("doc");
|
|
||||||
let p = doc.createElement("p");
|
|
||||||
p.innerHTML = "inside";
|
|
||||||
doc.body.appendChild(p);
|
|
||||||
|
|
||||||
p.addEventListener("zebra", function(e) {console.log("hi");});
|
|
||||||
p.dispatchEvent(new Event("zebra"));
|
|
||||||
},
|
|
||||||
check: function(markers) {
|
|
||||||
is(markers.length, 1, "Got 1 marker");
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
desc: "Event dispatch on window",
|
|
||||||
setup: function() {
|
|
||||||
let doc = content.window.addEventListener("aardvark", function(e) {
|
|
||||||
console.log("I like ants!");
|
|
||||||
});
|
|
||||||
|
|
||||||
content.window.dispatchEvent(new Event("aardvark"));
|
|
||||||
},
|
|
||||||
check: function(markers) {
|
|
||||||
is(markers.length, 1, "Got 1 marker");
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
|
|
||||||
let test = Task.async(function*() {
|
|
||||||
waitForExplicitFinish();
|
|
||||||
|
|
||||||
yield openUrl("data:text/html;charset=utf-8,<p>Test page</p>");
|
|
||||||
|
|
||||||
let docShell = content.QueryInterface(Ci.nsIInterfaceRequestor)
|
|
||||||
.getInterface(Ci.nsIWebNavigation)
|
|
||||||
.QueryInterface(Ci.nsIDocShell);
|
|
||||||
|
|
||||||
info("Start recording");
|
|
||||||
docShell.recordProfileTimelineMarkers = true;
|
|
||||||
|
|
||||||
for (let {desc, setup, check} of TESTS) {
|
|
||||||
|
|
||||||
info("Running test: " + desc);
|
|
||||||
|
|
||||||
info("Flushing the previous markers if any");
|
|
||||||
docShell.popProfileTimelineMarkers();
|
|
||||||
|
|
||||||
info("Running the test setup function");
|
|
||||||
let onMarkers = waitForMarkers(docShell);
|
|
||||||
setup();
|
|
||||||
info("Waiting for new markers on the docShell");
|
|
||||||
let markers = yield onMarkers;
|
|
||||||
|
|
||||||
info("Running the test check function");
|
|
||||||
check(markers.filter(m => m.name == "DOMEvent"));
|
|
||||||
}
|
|
||||||
|
|
||||||
info("Stop recording");
|
|
||||||
docShell.recordProfileTimelineMarkers = false;
|
|
||||||
|
|
||||||
gBrowser.removeCurrentTab();
|
|
||||||
finish();
|
|
||||||
});
|
|
||||||
|
|
||||||
function openUrl(url) {
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
window.focus();
|
|
||||||
|
|
||||||
let tab = window.gBrowser.selectedTab = window.gBrowser.addTab(url);
|
|
||||||
let linkedBrowser = tab.linkedBrowser;
|
|
||||||
|
|
||||||
linkedBrowser.addEventListener("load", function onload() {
|
|
||||||
linkedBrowser.removeEventListener("load", onload, true);
|
|
||||||
resolve(tab);
|
|
||||||
}, true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function waitForMarkers(docshell) {
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
let waitIterationCount = 0;
|
|
||||||
let maxWaitIterationCount = 10; // Wait for 2sec maximum
|
|
||||||
|
|
||||||
let interval = setInterval(() => {
|
|
||||||
let markers = docshell.popProfileTimelineMarkers();
|
|
||||||
if (markers.length > 0) {
|
|
||||||
clearInterval(interval);
|
|
||||||
resolve(markers);
|
|
||||||
}
|
|
||||||
if (waitIterationCount > maxWaitIterationCount) {
|
|
||||||
clearInterval(interval);
|
|
||||||
resolve([]);
|
|
||||||
}
|
|
||||||
waitIterationCount++;
|
|
||||||
}, 200);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,91 +3,6 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// Test that the docShell profile timeline API returns the right
|
const URL = "http://mochi.test:8888/browser/docshell/test/browser/timelineMarkers-04.html";
|
||||||
// markers for XMLHttpRequest events.
|
|
||||||
|
|
||||||
let TESTS = [{
|
let test = makeTimelineTest("browser_timelineMarkers-frame-04.js", URL);
|
||||||
desc: "Event dispatch from XMLHttpRequest",
|
|
||||||
setup: function() {
|
|
||||||
content.dispatchEvent(new Event("dog"));
|
|
||||||
},
|
|
||||||
check: function(markers) {
|
|
||||||
// One subtlety here is that we have five events: the event we
|
|
||||||
// inject in "setup", plus the four state transition events. The
|
|
||||||
// first state transition is reported synchronously and so should
|
|
||||||
// show up as a nested marker.
|
|
||||||
is(markers.length, 5, "Got 5 markers");
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
|
|
||||||
let test = Task.async(function*() {
|
|
||||||
waitForExplicitFinish();
|
|
||||||
|
|
||||||
const testDir = "http://mochi.test:8888/browser/docshell/test/browser/";
|
|
||||||
const testName = "timelineMarkers-04.html";
|
|
||||||
|
|
||||||
yield openUrl(testDir + testName);
|
|
||||||
|
|
||||||
let docShell = content.QueryInterface(Ci.nsIInterfaceRequestor)
|
|
||||||
.getInterface(Ci.nsIWebNavigation)
|
|
||||||
.QueryInterface(Ci.nsIDocShell);
|
|
||||||
|
|
||||||
info("Start recording");
|
|
||||||
docShell.recordProfileTimelineMarkers = true;
|
|
||||||
|
|
||||||
for (let {desc, setup, check} of TESTS) {
|
|
||||||
|
|
||||||
info("Running test: " + desc);
|
|
||||||
|
|
||||||
info("Flushing the previous markers if any");
|
|
||||||
docShell.popProfileTimelineMarkers();
|
|
||||||
|
|
||||||
info("Running the test setup function");
|
|
||||||
let onMarkers = waitForDOMMarkers(docShell, 5);
|
|
||||||
setup();
|
|
||||||
info("Waiting for new markers on the docShell");
|
|
||||||
let markers = yield onMarkers;
|
|
||||||
|
|
||||||
info("Running the test check function");
|
|
||||||
check(markers);
|
|
||||||
}
|
|
||||||
|
|
||||||
info("Stop recording");
|
|
||||||
docShell.recordProfileTimelineMarkers = false;
|
|
||||||
|
|
||||||
gBrowser.removeCurrentTab();
|
|
||||||
finish();
|
|
||||||
});
|
|
||||||
|
|
||||||
function openUrl(url) {
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
window.focus();
|
|
||||||
|
|
||||||
let tab = window.gBrowser.selectedTab = window.gBrowser.addTab(url);
|
|
||||||
let linkedBrowser = tab.linkedBrowser;
|
|
||||||
|
|
||||||
linkedBrowser.addEventListener("load", function onload() {
|
|
||||||
linkedBrowser.removeEventListener("load", onload, true);
|
|
||||||
resolve(tab);
|
|
||||||
}, true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function waitForDOMMarkers(docshell, numExpected) {
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
let waitIterationCount = 0;
|
|
||||||
let maxWaitIterationCount = 10; // Wait for 2sec maximum
|
|
||||||
let markers = [];
|
|
||||||
|
|
||||||
let interval = setInterval(() => {
|
|
||||||
let newMarkers = docshell.popProfileTimelineMarkers();
|
|
||||||
markers = [...markers, ...newMarkers.filter(m => m.name == "DOMEvent")];
|
|
||||||
if (markers.length >= numExpected
|
|
||||||
|| waitIterationCount > maxWaitIterationCount) {
|
|
||||||
clearInterval(interval);
|
|
||||||
resolve(markers);
|
|
||||||
}
|
|
||||||
waitIterationCount++;
|
|
||||||
}, 200);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Test that the docShell profile timeline API returns the right markers when
|
||||||
|
// restyles, reflows and paints occur
|
||||||
|
|
||||||
|
function rectangleContains(rect, x, y, width, height) {
|
||||||
|
return rect.x <= x && rect.y <= y && rect.width >= width &&
|
||||||
|
rect.height >= height;
|
||||||
|
}
|
||||||
|
|
||||||
|
let TESTS = [{
|
||||||
|
desc: "Changing the width of the test element",
|
||||||
|
searchFor: "Paint",
|
||||||
|
setup: function(docShell) {
|
||||||
|
let div = content.document.querySelector("div");
|
||||||
|
div.setAttribute("class", "resize-change-color");
|
||||||
|
},
|
||||||
|
check: function(markers) {
|
||||||
|
ok(markers.length > 0, "markers were returned");
|
||||||
|
console.log(markers);
|
||||||
|
info(JSON.stringify(markers.filter(m => m.name == "Paint")));
|
||||||
|
ok(markers.some(m => m.name == "Reflow"), "markers includes Reflow");
|
||||||
|
ok(markers.some(m => m.name == "Paint"), "markers includes Paint");
|
||||||
|
for (let marker of markers.filter(m => m.name == "Paint")) {
|
||||||
|
// This change should generate at least one rectangle.
|
||||||
|
ok(marker.rectangles.length >= 1, "marker has one rectangle");
|
||||||
|
// One of the rectangles should contain the div.
|
||||||
|
ok(marker.rectangles.some(r => rectangleContains(r, 0, 0, 100, 100)));
|
||||||
|
}
|
||||||
|
ok(markers.some(m => m.name == "Styles"), "markers includes Restyle");
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
desc: "Changing the test element's background color",
|
||||||
|
searchFor: "Paint",
|
||||||
|
setup: function(docShell) {
|
||||||
|
let div = content.document.querySelector("div");
|
||||||
|
div.setAttribute("class", "change-color");
|
||||||
|
},
|
||||||
|
check: function(markers) {
|
||||||
|
ok(markers.length > 0, "markers were returned");
|
||||||
|
ok(!markers.some(m => m.name == "Reflow"), "markers doesn't include Reflow");
|
||||||
|
ok(markers.some(m => m.name == "Paint"), "markers includes Paint");
|
||||||
|
for (let marker of markers.filter(m => m.name == "Paint")) {
|
||||||
|
// This change should generate at least one rectangle.
|
||||||
|
ok(marker.rectangles.length >= 1, "marker has one rectangle");
|
||||||
|
// One of the rectangles should contain the div.
|
||||||
|
ok(marker.rectangles.some(r => rectangleContains(r, 0, 0, 50, 50)));
|
||||||
|
}
|
||||||
|
ok(markers.some(m => m.name == "Styles"), "markers includes Restyle");
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
desc: "Changing the test element's classname",
|
||||||
|
searchFor: "Paint",
|
||||||
|
setup: function(docShell) {
|
||||||
|
let div = content.document.querySelector("div");
|
||||||
|
div.setAttribute("class", "change-color add-class");
|
||||||
|
},
|
||||||
|
check: function(markers) {
|
||||||
|
ok(markers.length > 0, "markers were returned");
|
||||||
|
ok(!markers.some(m => m.name == "Reflow"), "markers doesn't include Reflow");
|
||||||
|
ok(!markers.some(m => m.name == "Paint"), "markers doesn't include Paint");
|
||||||
|
ok(markers.some(m => m.name == "Styles"), "markers includes Restyle");
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
desc: "sync console.time/timeEnd",
|
||||||
|
searchFor: "ConsoleTime",
|
||||||
|
setup: function(docShell) {
|
||||||
|
content.console.time("FOOBAR");
|
||||||
|
content.console.timeEnd("FOOBAR");
|
||||||
|
let markers = docShell.popProfileTimelineMarkers();
|
||||||
|
is(markers.length, 1, "Got one marker");
|
||||||
|
is(markers[0].name, "ConsoleTime", "Got ConsoleTime marker");
|
||||||
|
is(markers[0].causeName, "FOOBAR", "Got ConsoleTime FOOBAR detail");
|
||||||
|
content.console.time("FOO");
|
||||||
|
content.setTimeout(() => {
|
||||||
|
content.console.time("BAR");
|
||||||
|
content.setTimeout(() => {
|
||||||
|
content.console.timeEnd("FOO");
|
||||||
|
content.console.timeEnd("BAR");
|
||||||
|
}, 100);
|
||||||
|
}, 100);
|
||||||
|
},
|
||||||
|
check: function(markers) {
|
||||||
|
is(markers.length, 2, "Got 2 markers");
|
||||||
|
is(markers[0].name, "ConsoleTime", "Got first ConsoleTime marker");
|
||||||
|
is(markers[0].causeName, "FOO", "Got ConsoleTime FOO detail");
|
||||||
|
is(markers[1].name, "ConsoleTime", "Got second ConsoleTime marker");
|
||||||
|
is(markers[1].causeName, "BAR", "Got ConsoleTime BAR detail");
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
timelineContentTest(TESTS);
|
|
@ -0,0 +1,91 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Test that the docShell profile timeline API returns the right
|
||||||
|
// markers for DOM events.
|
||||||
|
|
||||||
|
let TESTS = [{
|
||||||
|
desc: "Event dispatch with single handler",
|
||||||
|
searchFor: 'DOMEvent',
|
||||||
|
setup: function(docShell) {
|
||||||
|
content.document.body.addEventListener("dog",
|
||||||
|
function(e) { console.log("hi"); },
|
||||||
|
true);
|
||||||
|
content.document.body.dispatchEvent(new content.Event("dog"));
|
||||||
|
},
|
||||||
|
check: function(markers) {
|
||||||
|
markers = markers.filter(m => m.name == 'DOMEvent');
|
||||||
|
is(markers.length, 1, "Got 1 marker");
|
||||||
|
is(markers[0].type, "dog", "Got dog event name");
|
||||||
|
is(markers[0].eventPhase, 2, "Got phase 2");
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
desc: "Event dispatch with a second handler",
|
||||||
|
searchFor: function(markers) {
|
||||||
|
return markers.filter(m => m.name == 'DOMEvent').length >= 2;
|
||||||
|
},
|
||||||
|
setup: function(docShell) {
|
||||||
|
content.document.body.addEventListener("dog",
|
||||||
|
function(e) { console.log("hi"); },
|
||||||
|
false);
|
||||||
|
content.document.body.dispatchEvent(new content.Event("dog"));
|
||||||
|
},
|
||||||
|
check: function(markers) {
|
||||||
|
markers = markers.filter(m => m.name == 'DOMEvent');
|
||||||
|
is(markers.length, 2, "Got 2 markers");
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
desc: "Event targeted at child",
|
||||||
|
searchFor: function(markers) {
|
||||||
|
return markers.filter(m => m.name == 'DOMEvent').length >= 2;
|
||||||
|
},
|
||||||
|
setup: function(docShell) {
|
||||||
|
let child = content.document.body.firstElementChild;
|
||||||
|
child.addEventListener("dog", function(e) { });
|
||||||
|
child.dispatchEvent(new content.Event("dog"));
|
||||||
|
},
|
||||||
|
check: function(markers) {
|
||||||
|
markers = markers.filter(m => m.name == 'DOMEvent');
|
||||||
|
is(markers.length, 2, "Got 2 markers");
|
||||||
|
is(markers[0].eventPhase, 1, "Got phase 1 marker");
|
||||||
|
is(markers[1].eventPhase, 2, "Got phase 2 marker");
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
desc: "Event dispatch on a new document",
|
||||||
|
searchFor: function(markers) {
|
||||||
|
return markers.filter(m => m.name == 'DOMEvent').length >= 2;
|
||||||
|
},
|
||||||
|
setup: function(docShell) {
|
||||||
|
let doc = content.document.implementation.createHTMLDocument("doc");
|
||||||
|
let p = doc.createElement("p");
|
||||||
|
p.innerHTML = "inside";
|
||||||
|
doc.body.appendChild(p);
|
||||||
|
|
||||||
|
p.addEventListener("zebra", function(e) {console.log("hi");});
|
||||||
|
p.dispatchEvent(new content.Event("zebra"));
|
||||||
|
},
|
||||||
|
check: function(markers) {
|
||||||
|
markers = markers.filter(m => m.name == 'DOMEvent');
|
||||||
|
is(markers.length, 1, "Got 1 marker");
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
desc: "Event dispatch on window",
|
||||||
|
searchFor: function(markers) {
|
||||||
|
return markers.filter(m => m.name == 'DOMEvent').length >= 2;
|
||||||
|
},
|
||||||
|
setup: function(docShell) {
|
||||||
|
let doc = content.window.addEventListener("aardvark", function(e) {
|
||||||
|
console.log("I like ants!");
|
||||||
|
});
|
||||||
|
|
||||||
|
content.window.dispatchEvent(new content.Event("aardvark"));
|
||||||
|
},
|
||||||
|
check: function(markers) {
|
||||||
|
markers = markers.filter(m => m.name == 'DOMEvent');
|
||||||
|
is(markers.length, 1, "Got 1 marker");
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
timelineContentTest(TESTS);
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Test that the docShell profile timeline API returns the right
|
||||||
|
// markers for XMLHttpRequest events.
|
||||||
|
|
||||||
|
let TESTS = [{
|
||||||
|
desc: "Event dispatch from XMLHttpRequest",
|
||||||
|
searchFor: function(markers) {
|
||||||
|
return markers.filter(m => m.name == "DOMEvent").length >= 5;
|
||||||
|
},
|
||||||
|
setup: function(docShell) {
|
||||||
|
content.dispatchEvent(new content.Event("dog"));
|
||||||
|
},
|
||||||
|
check: function(markers) {
|
||||||
|
markers = markers.filter(m => m.name == "DOMEvent");
|
||||||
|
// One subtlety here is that we have five events: the event we
|
||||||
|
// inject in "setup", plus the four state transition events. The
|
||||||
|
// first state transition is reported synchronously and so should
|
||||||
|
// show up as a nested marker.
|
||||||
|
is(markers.length, 5, "Got 5 markers");
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
timelineContentTest(TESTS);
|
|
@ -0,0 +1,105 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Functions that are automatically loaded as frame scripts for
|
||||||
|
// timeline tests.
|
||||||
|
|
||||||
|
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||||
|
let { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
|
||||||
|
let { Promise } = Cu.import('resource://gre/modules/Promise.jsm', {});
|
||||||
|
|
||||||
|
// Functions that look like mochitest functions but forward to the
|
||||||
|
// browser process.
|
||||||
|
|
||||||
|
this.ok = function(value, message) {
|
||||||
|
sendAsyncMessage("browser:test:ok", {
|
||||||
|
value: !!value,
|
||||||
|
message: message});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.is = function(v1, v2, message) {
|
||||||
|
ok(v1 == v2, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.info = function(message) {
|
||||||
|
sendAsyncMessage("browser:test:info", {message: message});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.finish = function() {
|
||||||
|
sendAsyncMessage("browser:test:finish");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start a task that runs some timeline tests in the ordinary way.
|
||||||
|
*
|
||||||
|
* @param array tests
|
||||||
|
* The tests to run. This is an array where each element
|
||||||
|
* is of the form { desc, searchFor, setup, check }.
|
||||||
|
*
|
||||||
|
* desc is the test description, a string.
|
||||||
|
* searchFor is a string or a function
|
||||||
|
* If a string, then when a marker with this name is
|
||||||
|
* found, marker-reading is stopped.
|
||||||
|
* If a function, then the accumulated marker array is
|
||||||
|
* passed to it, and marker reading stops when it returns
|
||||||
|
* true.
|
||||||
|
* setup is a function that takes the docshell as an argument.
|
||||||
|
* It should start the test.
|
||||||
|
* check is a function that takes an array of markers
|
||||||
|
* as an argument and checks the results of the test.
|
||||||
|
*/
|
||||||
|
this.timelineContentTest = function(tests) {
|
||||||
|
Task.spawn(function*() {
|
||||||
|
let docShell = content.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
|
.getInterface(Ci.nsIWebNavigation)
|
||||||
|
.QueryInterface(Ci.nsIDocShell);
|
||||||
|
|
||||||
|
info("Start recording");
|
||||||
|
docShell.recordProfileTimelineMarkers = true;
|
||||||
|
|
||||||
|
for (let {desc, searchFor, setup, check} of tests) {
|
||||||
|
|
||||||
|
info("Running test: " + desc);
|
||||||
|
|
||||||
|
info("Flushing the previous markers if any");
|
||||||
|
docShell.popProfileTimelineMarkers();
|
||||||
|
|
||||||
|
info("Running the test setup function");
|
||||||
|
let onMarkers = timelineWaitForMarkers(docShell, searchFor);
|
||||||
|
setup(docShell);
|
||||||
|
info("Waiting for new markers on the docShell");
|
||||||
|
let markers = yield onMarkers;
|
||||||
|
|
||||||
|
info("Running the test check function");
|
||||||
|
check(markers);
|
||||||
|
}
|
||||||
|
|
||||||
|
info("Stop recording");
|
||||||
|
docShell.recordProfileTimelineMarkers = false;
|
||||||
|
finish();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function timelineWaitForMarkers(docshell, searchFor) {
|
||||||
|
if (typeof(searchFor) == "string") {
|
||||||
|
let f = function (markers) {
|
||||||
|
return markers.some(m => m.name == searchFor);
|
||||||
|
};
|
||||||
|
searchFor = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
let waitIterationCount = 0;
|
||||||
|
let maxWaitIterationCount = 10; // Wait for 2sec maximum
|
||||||
|
let markers = [];
|
||||||
|
|
||||||
|
let interval = content.setInterval(() => {
|
||||||
|
let newMarkers = docshell.popProfileTimelineMarkers();
|
||||||
|
markers = [...markers, ...newMarkers];
|
||||||
|
if (searchFor(markers) || waitIterationCount > maxWaitIterationCount) {
|
||||||
|
content.clearInterval(interval);
|
||||||
|
resolve(markers);
|
||||||
|
}
|
||||||
|
waitIterationCount++;
|
||||||
|
}, 200);
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
/* Helper function for timeline tests. Returns an async task that is
|
||||||
|
* suitable for use as a particular timeline test.
|
||||||
|
* @param string frameScriptName
|
||||||
|
* Base name of the frame script file.
|
||||||
|
* @param string url
|
||||||
|
* URL to load.
|
||||||
|
*/
|
||||||
|
function makeTimelineTest(frameScriptName, url) {
|
||||||
|
info("in timelineTest");
|
||||||
|
return Task.async(function*() {
|
||||||
|
info("in in timelineTest");
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
yield timelineTestOpenUrl(url);
|
||||||
|
|
||||||
|
const here = "chrome://mochitests/content/browser/docshell/test/browser/";
|
||||||
|
|
||||||
|
let mm = gBrowser.selectedBrowser.messageManager;
|
||||||
|
mm.loadFrameScript(here + "frame-head.js", false);
|
||||||
|
mm.loadFrameScript(here + frameScriptName, false);
|
||||||
|
|
||||||
|
// Set up some listeners so that timeline tests running in the
|
||||||
|
// content process can forward their results to the main process.
|
||||||
|
mm.addMessageListener("browser:test:ok", function(message) {
|
||||||
|
ok(message.data.value, message.data.message);
|
||||||
|
});
|
||||||
|
mm.addMessageListener("browser:test:info", function(message) {
|
||||||
|
info(message.data.message);
|
||||||
|
});
|
||||||
|
mm.addMessageListener("browser:test:finish", function(ignore) {
|
||||||
|
finish();
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open a URL for a timeline test. */
|
||||||
|
function timelineTestOpenUrl(url) {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
window.focus();
|
||||||
|
|
||||||
|
let tab = window.gBrowser.selectedTab = window.gBrowser.addTab(url);
|
||||||
|
let linkedBrowser = tab.linkedBrowser;
|
||||||
|
|
||||||
|
linkedBrowser.addEventListener("load", function onload() {
|
||||||
|
linkedBrowser.removeEventListener("load", onload, true);
|
||||||
|
resolve(tab);
|
||||||
|
}, true);
|
||||||
|
});
|
||||||
|
}
|
|
@ -30,6 +30,8 @@ if CONFIG['MOZ_JEMALLOC3']:
|
||||||
GENERATED_INCLUDES += ['../jemalloc/src/include']
|
GENERATED_INCLUDES += ['../jemalloc/src/include']
|
||||||
if CONFIG['_MSC_VER']:
|
if CONFIG['_MSC_VER']:
|
||||||
LOCAL_INCLUDES += ['/memory/jemalloc/src/include/msvc_compat']
|
LOCAL_INCLUDES += ['/memory/jemalloc/src/include/msvc_compat']
|
||||||
|
if not CONFIG['HAVE_INTTYPES_H']:
|
||||||
|
LOCAL_INCLUDES += ['/memory/jemalloc/src/include/msvc_compat/C99']
|
||||||
|
|
||||||
if CONFIG['MOZ_REPLACE_MALLOC']:
|
if CONFIG['MOZ_REPLACE_MALLOC']:
|
||||||
SOURCES += [
|
SOURCES += [
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
From 9c6a8d3b0cc14fd26b119ad08f190e537771464f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Guilherme Goncalves <guilherme.p.gonc@gmail.com>
|
||||||
|
Date: Wed, 17 Dec 2014 14:46:35 -0200
|
||||||
|
Subject: [PATCH] Move variable declaration to the top its block for MSVC
|
||||||
|
compatibility.
|
||||||
|
|
||||||
|
---
|
||||||
|
src/arena.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/arena.c b/src/arena.c
|
||||||
|
index bf78995..1eb4000 100644
|
||||||
|
--- a/src/arena.c
|
||||||
|
+++ b/src/arena.c
|
||||||
|
@@ -2022,6 +2022,7 @@ arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk, void *ptr,
|
||||||
|
* following run, then merge the first part with the existing
|
||||||
|
* allocation.
|
||||||
|
*/
|
||||||
|
+ arena_run_t *run;
|
||||||
|
size_t flag_dirty, splitsize, usize;
|
||||||
|
|
||||||
|
usize = s2u(size + extra);
|
||||||
|
@@ -2030,8 +2031,7 @@ arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk, void *ptr,
|
||||||
|
assert(usize >= usize_min);
|
||||||
|
splitsize = usize - oldsize;
|
||||||
|
|
||||||
|
- arena_run_t *run = &arena_miscelm_get(chunk,
|
||||||
|
- pageind+npages)->run;
|
||||||
|
+ run = &arena_miscelm_get(chunk, pageind+npages)->run;
|
||||||
|
arena_run_split_large(arena, run, splitsize, zero);
|
||||||
|
|
||||||
|
size = oldsize + splitsize;
|
||||||
|
--
|
||||||
|
2.1.3
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
From 4dd4193c59ff3f77e4ab36214ec63425ca834323 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Guilherme Goncalves <guilherme.p.gonc@gmail.com>
|
||||||
|
Date: Thu, 18 Dec 2014 15:01:21 +0900
|
||||||
|
Subject: [PATCH] Add a isblank definition for MSVC < 2013
|
||||||
|
|
||||||
|
---
|
||||||
|
include/jemalloc/internal/jemalloc_internal_decls.h | 7 +++++++
|
||||||
|
1 file changed, 7 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/include/jemalloc/internal/jemalloc_internal_decls.h b/include/jemalloc/internal/jemalloc_internal_decls.h
|
||||||
|
index fb2effb..65f2e4b 100644
|
||||||
|
--- a/include/jemalloc/internal/jemalloc_internal_decls.h
|
||||||
|
+++ b/include/jemalloc/internal/jemalloc_internal_decls.h
|
||||||
|
@@ -52,6 +52,13 @@ typedef intptr_t ssize_t;
|
||||||
|
# define __func__ __FUNCTION__
|
||||||
|
/* Disable warnings about deprecated system functions. */
|
||||||
|
# pragma warning(disable: 4996)
|
||||||
|
+#if _MSC_VER < 1800
|
||||||
|
+static int
|
||||||
|
+isblank(int c)
|
||||||
|
+{
|
||||||
|
+ return (c == '\t' || c == ' ');
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
#else
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
2.1.3
|
||||||
|
|
|
@ -52,6 +52,13 @@ typedef intptr_t ssize_t;
|
||||||
# define __func__ __FUNCTION__
|
# define __func__ __FUNCTION__
|
||||||
/* Disable warnings about deprecated system functions. */
|
/* Disable warnings about deprecated system functions. */
|
||||||
# pragma warning(disable: 4996)
|
# pragma warning(disable: 4996)
|
||||||
|
#if _MSC_VER < 1800
|
||||||
|
static int
|
||||||
|
isblank(int c)
|
||||||
|
{
|
||||||
|
return (c == '\t' || c == ' ');
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2022,6 +2022,7 @@ arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk, void *ptr,
|
||||||
* following run, then merge the first part with the existing
|
* following run, then merge the first part with the existing
|
||||||
* allocation.
|
* allocation.
|
||||||
*/
|
*/
|
||||||
|
arena_run_t *run;
|
||||||
size_t flag_dirty, splitsize, usize;
|
size_t flag_dirty, splitsize, usize;
|
||||||
|
|
||||||
usize = s2u(size + extra);
|
usize = s2u(size + extra);
|
||||||
|
@ -2030,8 +2031,7 @@ arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk, void *ptr,
|
||||||
assert(usize >= usize_min);
|
assert(usize >= usize_min);
|
||||||
splitsize = usize - oldsize;
|
splitsize = usize - oldsize;
|
||||||
|
|
||||||
arena_run_t *run = &arena_miscelm_get(chunk,
|
run = &arena_miscelm_get(chunk, pageind+npages)->run;
|
||||||
pageind+npages)->run;
|
|
||||||
arena_run_split_large(arena, run, splitsize, zero);
|
arena_run_split_large(arena, run, splitsize, zero);
|
||||||
|
|
||||||
size = oldsize + splitsize;
|
size = oldsize + splitsize;
|
||||||
|
|
|
@ -15,6 +15,8 @@ git describe --long --abbrev=40 > VERSION
|
||||||
rm -rf .git .gitignore .gitattributes autom4te.cache .autom4te.cfg
|
rm -rf .git .gitignore .gitattributes autom4te.cache .autom4te.cfg
|
||||||
|
|
||||||
patch -p1 < ../0001-Dont-overwrite-VERSION-on-a-git-repository.patch
|
patch -p1 < ../0001-Dont-overwrite-VERSION-on-a-git-repository.patch
|
||||||
|
patch -p1 < ../0002-Move-variable-declaration-to-the-top-its-block-for-M.patch
|
||||||
|
patch -p1 < ../0003-Add-a-isblank-definition-for-MSVC-2013.patch
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
hg addremove -q src
|
hg addremove -q src
|
||||||
|
|
|
@ -29,5 +29,7 @@ DEFINES['MOZ_REPLACE_JEMALLOC'] = True
|
||||||
GENERATED_INCLUDES += ['../../jemalloc/src/include']
|
GENERATED_INCLUDES += ['../../jemalloc/src/include']
|
||||||
if CONFIG['_MSC_VER']:
|
if CONFIG['_MSC_VER']:
|
||||||
LOCAL_INCLUDES += ['/memory/jemalloc/src/include/msvc_compat']
|
LOCAL_INCLUDES += ['/memory/jemalloc/src/include/msvc_compat']
|
||||||
|
if not CONFIG['HAVE_INTTYPES_H']:
|
||||||
|
LOCAL_INCLUDES += ['/memory/jemalloc/src/include/msvc_compat/C99']
|
||||||
|
|
||||||
DISABLE_STL_WRAPPING = True
|
DISABLE_STL_WRAPPING = True
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
project.buildDir = "${topobjdir}/mobile/android/gradle/app/build"
|
|
||||||
|
|
||||||
apply plugin: 'android'
|
|
||||||
|
|
||||||
android {
|
|
||||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
|
||||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
|
||||||
|
|
||||||
defaultConfig {
|
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
buildTypes {
|
|
||||||
release {
|
|
||||||
runProguard false
|
|
||||||
proguardFile getDefaultProguardFile('proguard-android.txt')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compileOptions {
|
|
||||||
sourceCompatibility JavaVersion.VERSION_1_7
|
|
||||||
targetCompatibility JavaVersion.VERSION_1_7
|
|
||||||
}
|
|
||||||
|
|
||||||
android {
|
|
||||||
lintOptions {
|
|
||||||
abortOnError false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
main {
|
|
||||||
manifest {
|
|
||||||
srcFile "${topobjdir}/mobile/android/base/AndroidManifest.xml"
|
|
||||||
}
|
|
||||||
|
|
||||||
assets {
|
|
||||||
srcDir "${topobjdir}/dist/fennec/assets"
|
|
||||||
}
|
|
||||||
|
|
||||||
jniLibs {
|
|
||||||
srcDir "${topobjdir}/dist/fennec/lib"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
androidTest {
|
|
||||||
java {
|
|
||||||
srcDir "${topobjdir}/mobile/android/gradle/app/src/androidTest/robocop_harness/java"
|
|
||||||
srcDir "${topobjdir}/mobile/android/gradle/app/src/androidTest/robocop/java"
|
|
||||||
srcDir "${topobjdir}/mobile/android/gradle/app/src/androidTest/background/java"
|
|
||||||
srcDir "${topobjdir}/mobile/android/gradle/app/src/androidTest/browser/java"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compile project(':base')
|
|
||||||
androidTestCompile fileTree(dir: "../../../build/mobile/robocop", include: ['*.jar'])
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
project.buildDir = "${topobjdir}/mobile/android/gradle/base/build"
|
project.buildDir = "${topobjdir}/mobile/android/gradle/base/build"
|
||||||
|
|
||||||
apply plugin: 'android-library'
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||||
|
@ -14,7 +14,7 @@ android {
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
runProguard false
|
minifyEnabled false
|
||||||
proguardFile getDefaultProguardFile('proguard-android.txt')
|
proguardFile getDefaultProguardFile('proguard-android.txt')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,6 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
res {
|
res {
|
||||||
srcDir "newtablet/res"
|
|
||||||
srcDir "../branding/unofficial/res"
|
srcDir "../branding/unofficial/res"
|
||||||
srcDir "${topobjdir}/mobile/android/base/res"
|
srcDir "${topobjdir}/mobile/android/base/res"
|
||||||
// The main resources are symlinked in here.
|
// The main resources are symlinked in here.
|
||||||
|
|
|
@ -18,10 +18,10 @@ The debug APK will be at
|
||||||
The ``$OBJDIR/mobile/android/gradle`` directory can be imported into IntelliJ as
|
The ``$OBJDIR/mobile/android/gradle`` directory can be imported into IntelliJ as
|
||||||
follows:
|
follows:
|
||||||
|
|
||||||
- File > Import Project
|
- File > Import Project...
|
||||||
- [select ``$OBJDIR/mobile/android/gradle``]
|
- [select ``$OBJDIR/mobile/android/gradle``]
|
||||||
- Import project from external model > Gradle
|
- Import project from external model > Gradle
|
||||||
- [select Use default Gradle wrapper]
|
- [select Use customizable Gradle wrapper]
|
||||||
|
|
||||||
When prompted, do not add any files to git. You may need to re-open the
|
When prompted, do not add any files to git. You may need to re-open the
|
||||||
project, or restart IntelliJ, to pick up a compiler language-level change.
|
project, or restart IntelliJ, to pick up a compiler language-level change.
|
||||||
|
@ -42,11 +42,11 @@ Caveats
|
||||||
How the Gradle project is laid out
|
How the Gradle project is laid out
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
||||||
To the greatest extent possible, the Gradle configuration lives in the source
|
To the greatest extent possible, the Gradle configuration lives in the object
|
||||||
directory. The only Gradle configuration that lives in the object directory is
|
directory.
|
||||||
installed when building the ``mobile/android/gradle`` directory.
|
|
||||||
|
|
||||||
At the time of writing, their are three sub-modules: *app*, *base*, and *thirdparty*.
|
At the time of writing, their are three main sub-modules: *app*, *base*, and
|
||||||
|
*thirdparty*, and several smaller sub-modules.
|
||||||
|
|
||||||
*app* is the Fennec wrapper; it generates the **org.mozilla.fennec.R** resource
|
*app* is the Fennec wrapper; it generates the **org.mozilla.fennec.R** resource
|
||||||
package. *base* is the Gecko code; it generates the **org.mozilla.gecko.R**
|
package. *base* is the Gecko code; it generates the **org.mozilla.gecko.R**
|
||||||
|
|
|
@ -547,7 +547,6 @@ if CONFIG['MOZ_ANDROID_NEW_TABLET_UI'] and max_sdk_version >= 11:
|
||||||
'tabs/TabStripItemView.java',
|
'tabs/TabStripItemView.java',
|
||||||
'tabs/TabStripView.java'
|
'tabs/TabStripView.java'
|
||||||
]
|
]
|
||||||
ANDROID_RES_DIRS += [ SRCDIR + '/newtablet/res' ]
|
|
||||||
|
|
||||||
gbjar.sources += sync_java_files
|
gbjar.sources += sync_java_files
|
||||||
gbjar.extra_jars += [
|
gbjar.extra_jars += [
|
||||||
|
|
До Ширина: | Высота: | Размер: 159 B После Ширина: | Высота: | Размер: 159 B |
До Ширина: | Высота: | Размер: 589 B После Ширина: | Высота: | Размер: 589 B |
До Ширина: | Высота: | Размер: 404 B После Ширина: | Высота: | Размер: 404 B |
До Ширина: | Высота: | Размер: 771 B После Ширина: | Высота: | Размер: 771 B |
До Ширина: | Высота: | Размер: 133 B После Ширина: | Высота: | Размер: 133 B |
До Ширина: | Высота: | Размер: 808 B После Ширина: | Высота: | Размер: 808 B |
До Ширина: | Высота: | Размер: 236 B После Ширина: | Высота: | Размер: 236 B |
До Ширина: | Высота: | Размер: 231 B После Ширина: | Высота: | Размер: 231 B |
До Ширина: | Высота: | Размер: 122 B После Ширина: | Высота: | Размер: 122 B |
До Ширина: | Высота: | Размер: 172 B После Ширина: | Высота: | Размер: 172 B |
До Ширина: | Высота: | Размер: 145 B После Ширина: | Высота: | Размер: 145 B |
До Ширина: | Высота: | Размер: 130 B После Ширина: | Высота: | Размер: 130 B |
До Ширина: | Высота: | Размер: 456 B После Ширина: | Высота: | Размер: 456 B |
До Ширина: | Высота: | Размер: 299 B После Ширина: | Высота: | Размер: 299 B |
До Ширина: | Высота: | Размер: 551 B После Ширина: | Высота: | Размер: 551 B |
До Ширина: | Высота: | Размер: 132 B После Ширина: | Высота: | Размер: 132 B |
До Ширина: | Высота: | Размер: 581 B После Ширина: | Высота: | Размер: 581 B |
До Ширина: | Высота: | Размер: 192 B После Ширина: | Высота: | Размер: 192 B |
До Ширина: | Высота: | Размер: 192 B После Ширина: | Высота: | Размер: 192 B |
До Ширина: | Высота: | Размер: 112 B После Ширина: | Высота: | Размер: 112 B |
До Ширина: | Высота: | Размер: 147 B После Ширина: | Высота: | Размер: 147 B |
До Ширина: | Высота: | Размер: 129 B После Ширина: | Высота: | Размер: 129 B |
До Ширина: | Высота: | Размер: 170 B После Ширина: | Высота: | Размер: 170 B |
До Ширина: | Высота: | Размер: 754 B После Ширина: | Высота: | Размер: 754 B |
До Ширина: | Высота: | Размер: 475 B После Ширина: | Высота: | Размер: 475 B |
До Ширина: | Высота: | Размер: 995 B После Ширина: | Высота: | Размер: 995 B |
До Ширина: | Высота: | Размер: 135 B После Ширина: | Высота: | Размер: 135 B |
До Ширина: | Высота: | Размер: 1.0 KiB После Ширина: | Высота: | Размер: 1.0 KiB |
До Ширина: | Высота: | Размер: 245 B После Ширина: | Высота: | Размер: 245 B |
До Ширина: | Высота: | Размер: 240 B После Ширина: | Высота: | Размер: 240 B |
До Ширина: | Высота: | Размер: 127 B После Ширина: | Высота: | Размер: 127 B |
До Ширина: | Высота: | Размер: 197 B После Ширина: | Высота: | Размер: 197 B |
До Ширина: | Высота: | Размер: 164 B После Ширина: | Высота: | Размер: 164 B |
До Ширина: | Высота: | Размер: 209 B После Ширина: | Высота: | Размер: 209 B |
До Ширина: | Высота: | Размер: 1006 B После Ширина: | Высота: | Размер: 1006 B |
До Ширина: | Высота: | Размер: 661 B После Ширина: | Высота: | Размер: 661 B |
До Ширина: | Высота: | Размер: 1.3 KiB После Ширина: | Высота: | Размер: 1.3 KiB |
До Ширина: | Высота: | Размер: 137 B После Ширина: | Высота: | Размер: 137 B |
До Ширина: | Высота: | Размер: 1016 B После Ширина: | Высота: | Размер: 1016 B |
До Ширина: | Высота: | Размер: 334 B После Ширина: | Высота: | Размер: 334 B |
До Ширина: | Высота: | Размер: 334 B После Ширина: | Высота: | Размер: 334 B |
До Ширина: | Высота: | Размер: 232 B После Ширина: | Высота: | Размер: 232 B |
До Ширина: | Высота: | Размер: 197 B После Ширина: | Высота: | Размер: 197 B |
До Ширина: | Высота: | Размер: 897 B После Ширина: | Высота: | Размер: 897 B |
До Ширина: | Высота: | Размер: 641 B После Ширина: | Высота: | Размер: 641 B |
До Ширина: | Высота: | Размер: 629 B После Ширина: | Высота: | Размер: 629 B |
До Ширина: | Высота: | Размер: 436 B После Ширина: | Высота: | Размер: 436 B |
До Ширина: | Высота: | Размер: 1.1 KiB После Ширина: | Высота: | Размер: 1.1 KiB |
До Ширина: | Высота: | Размер: 744 B После Ширина: | Высота: | Размер: 744 B |
До Ширина: | Высота: | Размер: 1.5 KiB После Ширина: | Высота: | Размер: 1.5 KiB |