merge fx-team to mozilla-inbound a=merge

This commit is contained in:
Carsten "Tomcat" Book 2014-12-23 16:04:26 +01:00
Родитель 5ea9eda8dd 45b84ba902
Коммит 405ad2ed16
139 изменённых файлов: 1653 добавлений и 1195 удалений

3
.gitignore поставляемый
Просмотреть файл

@ -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

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше