merge mozilla-central to b2g-inbound

This commit is contained in:
Carsten "Tomcat" Book 2015-10-08 16:18:26 +02:00
Родитель 96be99c2b7 634dc488d6
Коммит 676e56277f
406 изменённых файлов: 8040 добавлений и 6897 удалений

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

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1193206 - Building with Android support library 23.0.1
Bug 1212764 - Clobber needed for bug 957911

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

@ -985,6 +985,13 @@ UpdateAtkRelation(RelationType aType, Accessible* aAcc,
while ((tempAcc = rel.Next()))
targets.AppendElement(AccessibleWrap::GetAtkObject(tempAcc));
if (aType == RelationType::EMBEDS && aAcc->IsRoot()) {
if (ProxyAccessible* proxyDoc =
aAcc->AsRoot()->GetPrimaryRemoteTopLevelContentDoc()) {
targets.AppendElement(GetWrapperFor(proxyDoc));
}
}
if (targets.Length()) {
atkRelation = atk_relation_new(targets.Elements(),
targets.Length(), aAtkType);
@ -1121,6 +1128,10 @@ GetInterfacesForProxy(ProxyAccessible* aProxy, uint32_t aInterfaces)
interfaces |= 1 << MAI_INTERFACE_SELECTION;
}
if (aInterfaces & Interfaces::ACTION) {
interfaces |= 1 << MAI_INTERFACE_ACTION;
}
return interfaces;
}

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

@ -1364,14 +1364,15 @@ DocAccessible::ProcessInvalidationList()
continue;
}
if (!child->Parent()) {
Accessible* oldParent = child->Parent();
if (!oldParent) {
NS_ERROR("The accessible is in document but doesn't have a parent");
continue;
}
int32_t idxInParent = child->IndexInParent();
// XXX: update context flags
{
Accessible* oldParent = child->Parent();
nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(oldParent);
nsRefPtr<AccMutationEvent> hideEvent =
new AccHideEvent(child, child->GetContent(), false);
@ -1385,21 +1386,29 @@ DocAccessible::ProcessInvalidationList()
FireDelayedEvent(reorderEvent);
}
bool isReinserted = false;
{
AutoTreeMutation mut(owner);
owner->AppendChild(child);
nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(owner);
nsRefPtr<AccMutationEvent> showEvent =
new AccShowEvent(child, child->GetContent());
FireDelayedEvent(showEvent);
reorderEvent->AddSubMutationEvent(showEvent);
MaybeNotifyOfValueChange(owner);
FireDelayedEvent(reorderEvent);
isReinserted = owner->AppendChild(child);
}
child->SetRepositioned(true);
Accessible* newParent = owner;
if (!isReinserted) {
AutoTreeMutation mut(oldParent);
oldParent->InsertChildAt(idxInParent, child);
newParent = oldParent;
}
nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(newParent);
nsRefPtr<AccMutationEvent> showEvent =
new AccShowEvent(child, child->GetContent());
FireDelayedEvent(showEvent);
reorderEvent->AddSubMutationEvent(showEvent);
MaybeNotifyOfValueChange(newParent);
FireDelayedEvent(reorderEvent);
child->SetRepositioned(isReinserted);
}
mARIAOwnsInvalidationList.Clear();

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

@ -192,14 +192,8 @@ OuterDocAccessible::RemoteChildDoc() const
if (!tab)
return nullptr;
// XXX Consider managing non top level remote documents with there parent
// document.
const nsTArray<PDocAccessibleParent*>& docs = tab->ManagedPDocAccessibleParent();
size_t docCount = docs.Length();
for (size_t i = 0; i < docCount; i++) {
auto doc = static_cast<DocAccessibleParent*>(docs[i]);
if (!doc->ParentDoc())
return doc;
if (DocAccessibleParent* doc = tab->GetTopLevelDocAccessible()) {
return doc;
}
MOZ_ASSERT(false, "no top level tab document?");

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

@ -716,3 +716,20 @@ RootAccessible::HandleTreeInvalidatedEvent(nsIDOMEvent* aEvent,
aAccessible->TreeViewInvalidated(startRow, endRow, startCol, endCol);
}
#endif
ProxyAccessible*
RootAccessible::GetPrimaryRemoteTopLevelContentDoc() const
{
nsCOMPtr<nsIDocShellTreeOwner> owner;
mDocumentNode->GetDocShell()->GetTreeOwner(getter_AddRefs(owner));
NS_ENSURE_TRUE(owner, nullptr);
nsCOMPtr<nsITabParent> tabParent;
owner->GetPrimaryTabParent(getter_AddRefs(tabParent));
if (!tabParent) {
return nullptr;
}
auto tab = static_cast<dom::TabParent*>(tabParent.get());
return tab->GetTopLevelDocAccessible();
}

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

@ -42,6 +42,11 @@ public:
*/
virtual void DocumentActivated(DocAccessible* aDocument);
/**
* Return the primary remote top level document if any.
*/
ProxyAccessible* GetPrimaryRemoteTopLevelContentDoc() const;
protected:
virtual ~RootAccessible();

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

@ -50,6 +50,10 @@ InterfacesFor(Accessible* aAcc)
interfaces |= Interfaces::SELECTION;
}
if (aAcc->ActionCount()) {
interfaces |= Interfaces::ACTION;
}
return interfaces;
}

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

@ -395,6 +395,7 @@ enum Interfaces
TABLECELL = 32,
DOCUMENT = 64,
SELECTION = 128,
ACTION = 256,
};
}

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

@ -952,11 +952,13 @@ AccessibleWrap::accLocation(
if (xpAccessible->IsDefunct())
return CO_E_OBJNOTCONNECTED;
// TODO make this work with proxies.
if (xpAccessible->IsProxy())
return E_NOTIMPL;
nsIntRect rect;
if (xpAccessible->IsProxy()) {
rect = xpAccessible->Proxy()->Bounds();
} else {
rect = xpAccessible->Bounds();
}
nsIntRect rect = xpAccessible->Bounds();
*pxLeft = rect.x;
*pyTop = rect.y;
*pcxWidth = rect.width;

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

@ -1825,6 +1825,11 @@ pref("ui.key.menuAccessKeyFocuses", true);
pref("media.eme.enabled", true);
pref("media.eme.apiVisible", true);
// If decoding-via-gmp is turned on for <video>, default to using
// Adobe's GMP for decoding.
pref("media.fragmented-mp4.gmp.aac", 2);
pref("media.fragmented-mp4.gmp.h264", 2);
// Whether we should run a test-pattern through EME GMPs before assuming they'll
// decode H.264.
pref("media.gmp.trial-create.enabled", true);

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

@ -229,20 +229,14 @@ var StarUI = {
gEditItemOverlay.initPanel({ node: aNode
, hiddenRows: ["description", "location",
"loadInSidebar", "keyword"] });
"loadInSidebar", "keyword"]
, focusedElement: "preferred" });
}),
panelShown:
function SU_panelShown(aEvent) {
if (aEvent.target == this.panel) {
if (!this._element("editBookmarkPanelContent").hidden) {
let fieldToFocus = "editBMPanel_" +
gPrefService.getCharPref("browser.bookmarks.editDialog.firstEditField");
var elt = this._element(fieldToFocus);
elt.focus();
elt.select();
}
else {
if (this._element("editBookmarkPanelContent").hidden) {
// Note this isn't actually used anymore, we should remove this
// once we decide not to bring back the page bookmarked notification
this.panel.focus();

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

@ -255,6 +255,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "ReaderMode",
XPCOMUtils.defineLazyModuleGetter(this, "ReaderParent",
"resource:///modules/ReaderParent.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerParent",
"resource://gre/modules/LoginManagerParent.jsm");
var gInitialPages = [
"about:blank",
"about:newtab",
@ -1192,6 +1195,10 @@ var gBrowserInit = {
}
}, false, true);
gBrowser.addEventListener("InsecureLoginFormsStateChange", function() {
gIdentityHandler.refreshForInsecureLoginForms();
});
let uriToLoad = this._getUriToLoad();
if (uriToLoad && uriToLoad != "about:blank") {
if (uriToLoad instanceof Ci.nsISupportsArray) {
@ -4970,10 +4977,6 @@ nsBrowserAccess.prototype = {
isTabContentWindow: function (aWindow) {
return gBrowser.browsers.some(browser => browser.contentWindow == aWindow);
},
canClose() {
return CanCloseWindow();
},
}
function getTogglableToolbars() {
@ -6439,26 +6442,6 @@ var IndexedDBPromptHelper = {
}
};
function CanCloseWindow()
{
// Avoid redundant calls to canClose from showing multiple
// PermitUnload dialogs.
if (window.skipNextCanClose) {
return true;
}
for (let browser of gBrowser.browsers) {
let {permitUnload, timedOut} = browser.permitUnload();
if (timedOut) {
return true;
}
if (!permitUnload) {
return false;
}
}
return true;
}
function WindowIsClosing()
{
if (TabView.isVisible()) {
@ -6469,19 +6452,27 @@ function WindowIsClosing()
if (!closeWindow(false, warnAboutClosingWindow))
return false;
// In theory we should exit here and the Window's internal Close
// method should trigger canClose on nsBrowserAccess. However, by
// that point it's too late to be able to show a prompt for
// PermitUnload. So we do it here, when we still can.
if (CanCloseWindow()) {
// This flag ensures that the later canClose call does nothing.
// It's only needed to make tests pass, since they detect the
// prompt even when it's not actually shown.
window.skipNextCanClose = true;
// Bug 967873 - Proxy nsDocumentViewer::PermitUnload to the child process
if (gMultiProcessBrowser)
return true;
for (let browser of gBrowser.browsers) {
let ds = browser.docShell;
// Passing true to permitUnload indicates we plan on closing the window.
// This means that once unload is permitted, all further calls to
// permitUnload will be ignored. This avoids getting multiple prompts
// to unload the page.
if (ds.contentViewer && !ds.contentViewer.permitUnload(true)) {
// ... however, if the user aborts closing, we need to undo that,
// to ensure they get prompted again when we next try to close the window.
// We do this on the window's toplevel docshell instead of on the tab, so
// that all tabs we iterated before will get this reset.
window.getInterface(Ci.nsIDocShell).contentViewer.resetCloseWindow();
return false;
}
}
return false;
return true;
}
/**
@ -7006,10 +6997,7 @@ var gIdentityHandler = {
}
// Then, update the user interface with the available data.
if (this._identityBox) {
this.refreshIdentityBlock();
}
this.refreshIdentityBlock();
// NOTE: We do NOT update the identity popup (the control center) when
// we receive a new security state. If the user opened the popup and looks
@ -7017,6 +7005,20 @@ var gIdentityHandler = {
// contents.
},
/**
* This is called asynchronously when requested by the Logins module, after
* the insecure login forms state for the page has been updated.
*/
refreshForInsecureLoginForms() {
// Check this._uri because we don't want to refresh the user interface if
// this is called before the first page load in the window for any reason.
if (!this._uri) {
Cu.reportError("Unexpected early call to refreshForInsecureLoginForms.");
return;
}
this.refreshIdentityBlock();
},
/**
* Attempt to provide proper IDN treatment for host names
*/
@ -7053,6 +7055,10 @@ var gIdentityHandler = {
* Updates the identity block user interface with the data from this object.
*/
refreshIdentityBlock() {
if (!this._identityBox) {
return;
}
let icon_label = "";
let tooltip = "";
let icon_country_label = "";
@ -7121,6 +7127,11 @@ var gIdentityHandler = {
this._identityBox.classList.add("weakCipher");
}
}
if (LoginManagerParent.hasInsecureLoginForms(gBrowser.selectedBrowser)) {
// Insecure login forms can only be present on "unknown identity"
// pages, either already insecure or with mixed active content loaded.
this._identityBox.classList.add("insecureLoginForms");
}
tooltip = gNavigatorBundle.getString("identity.unknown.tooltip");
}
@ -7158,6 +7169,12 @@ var gIdentityHandler = {
connection = "secure";
}
// Determine if there are insecure login forms.
let loginforms = "secure";
if (LoginManagerParent.hasInsecureLoginForms(gBrowser.selectedBrowser)) {
loginforms = "insecure";
}
// Determine the mixed content state.
let mixedcontent = [];
if (this._isMixedPassiveContentLoaded) {
@ -7195,6 +7212,7 @@ var gIdentityHandler = {
for (let id of elementIDs) {
let element = document.getElementById(id);
updateAttribute(element, "connection", connection);
updateAttribute(element, "loginforms", loginforms);
updateAttribute(element, "ciphers", ciphers);
updateAttribute(element, "mixedcontent", mixedcontent);
updateAttribute(element, "isbroken", this._isBroken);

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

@ -119,7 +119,7 @@
accesskey="&bookmarkAllTabs.accesskey;"
command="Browser:BookmarkAllTabs"/>
<menuitem id="context_closeTabsToTheEnd" label="&closeTabsToTheEnd.label;" accesskey="&closeTabsToTheEnd.accesskey;"
oncommand="gBrowser.removeTabsToTheEndFrom(TabContextMenu.contextTab, {animate: true});"/>
oncommand="gBrowser.removeTabsToTheEndFrom(TabContextMenu.contextTab);"/>
<menuitem id="context_closeOtherTabs" label="&closeOtherTabs.label;" accesskey="&closeOtherTabs.accesskey;"
oncommand="gBrowser.removeAllTabsBut(TabContextMenu.contextTab);"/>
<menuseparator/>

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

@ -131,11 +131,6 @@ chatBrowserAccess.prototype = {
isTabContentWindow: function (aWindow) {
return this.contentWindow == aWindow;
},
canClose() {
let {BrowserUtils} = Cu.import("resource://gre/modules/BrowserUtils.jsm", {});
return BrowserUtils.canCloseWindow(window);
},
};
</script>

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

@ -1,4 +1,4 @@
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
// -*- indent-tabs-mode: nil; js-indent-level: 4 -*-
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -567,17 +567,28 @@ Sanitizer.prototype = {
openWindows: {
privateStateForNewWindow: "non-private",
_canCloseWindow: function(aWindow) {
if (aWindow.CanCloseWindow()) {
// We already showed PermitUnload for the window, so let's
// make sure we don't do it again when we actually close the
// window.
aWindow.skipNextCanClose = true;
return true;
// Bug 967873 - Proxy nsDocumentViewer::PermitUnload to the child process
if (!aWindow.gMultiProcessBrowser) {
// Cargo-culted out of browser.js' WindowIsClosing because we don't care
// about TabView or the regular 'warn me before closing windows with N tabs'
// stuff here, and more importantly, we want to set aCallerClosesWindow to true
// when calling into permitUnload:
for (let browser of aWindow.gBrowser.browsers) {
let ds = browser.docShell;
// 'true' here means we will be closing the window soon, so please don't dispatch
// another onbeforeunload event when we do so. If unload is *not* permitted somewhere,
// we will reset the flag that this triggers everywhere so that we don't interfere
// with the browser after all:
if (ds.contentViewer && !ds.contentViewer.permitUnload(true)) {
return false;
}
}
}
return true;
},
_resetAllWindowClosures: function(aWindowList) {
for (let win of aWindowList) {
win.skipNextCanClose = false;
win.getInterface(Ci.nsIDocShell).contentViewer.resetCloseWindow();
}
},
clear: Task.async(function*() {

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

@ -1190,29 +1190,25 @@
this._tabAttrModified(this.mCurrentTab, ["selected"]);
if (oldBrowser != newBrowser &&
oldBrowser.getInPermitUnload) {
oldBrowser.getInPermitUnload(inPermitUnload => {
if (!inPermitUnload) {
return;
}
// Since the user is switching away from a tab that has
// a beforeunload prompt active, we remove the prompt.
// This prevents confusing user flows like the following:
// 1. User attempts to close Firefox
// 2. User switches tabs (ingoring a beforeunload prompt)
// 3. User returns to tab, presses "Leave page"
let promptBox = this.getTabModalPromptBox(oldBrowser);
let prompts = promptBox.listPrompts();
// There might not be any prompts here if the tab was closed
// while in an onbeforeunload prompt, which will have
// destroyed aforementioned prompt already, so check there's
// something to remove, first:
if (prompts.length) {
// NB: This code assumes that the beforeunload prompt
// is the top-most prompt on the tab.
prompts[prompts.length - 1].abortPrompt();
}
});
oldBrowser.docShell &&
oldBrowser.docShell.contentViewer.inPermitUnload) {
// Since the user is switching away from a tab that has
// a beforeunload prompt active, we remove the prompt.
// This prevents confusing user flows like the following:
// 1. User attempts to close Firefox
// 2. User switches tabs (ingoring a beforeunload prompt)
// 3. User returns to tab, presses "Leave page"
let promptBox = this.getTabModalPromptBox(oldBrowser);
let prompts = promptBox.listPrompts();
// There might not be any prompts here if the tab was closed
// while in an onbeforeunload prompt, which will have
// destroyed aforementioned prompt already, so check there's
// something to remove, first:
if (prompts.length) {
// NB: This code assumes that the beforeunload prompt
// is the top-most prompt on the tab.
prompts[prompts.length - 1].abortPrompt();
}
}
oldBrowser._urlbarFocused = (gURLBar && gURLBar.focused);
@ -2081,13 +2077,12 @@
<method name="removeTabsToTheEndFrom">
<parameter name="aTab"/>
<parameter name="aParams"/>
<body>
<![CDATA[
if (this.warnAboutClosingTabs(this.closingTabsEnum.TO_END, aTab)) {
let tabs = this.getTabsToTheEndFrom(aTab);
for (let i = tabs.length - 1; i >= 0; --i) {
this.removeTab(tabs[i], aParams);
this.removeTab(tabs[i], {animate: true});
}
}
]]>
@ -2135,7 +2130,6 @@
if (aParams) {
var animate = aParams.animate;
var byMouse = aParams.byMouse;
var skipPermitUnload = aParams.skipPermitUnload;
}
// Handle requests for synchronously removing an already
@ -2148,7 +2142,7 @@
var isLastTab = (this.tabs.length - this._removingTabs.length == 1);
if (!this._beginRemoveTab(aTab, false, null, true, skipPermitUnload))
if (!this._beginRemoveTab(aTab, false, null, true))
return;
if (!aTab.pinned && !aTab.hidden && aTab._fullyOpen && byMouse)
@ -2196,7 +2190,6 @@
<parameter name="aTabWillBeMoved"/>
<parameter name="aCloseWindowWithLastTab"/>
<parameter name="aCloseWindowFastpath"/>
<parameter name="aSkipPermitUnload"/>
<body>
<![CDATA[
if (aTab.closing ||
@ -2227,20 +2220,23 @@
newTab = true;
}
if (!aTab._pendingPermitUnload && !aTabWillBeMoved && !aSkipPermitUnload) {
// We need to block while calling permitUnload() because it
// processes the event queue and may lead to another removeTab()
// call before permitUnload() returns.
aTab._pendingPermitUnload = true;
let {permitUnload} = browser.permitUnload();
delete aTab._pendingPermitUnload;
// If we were closed during onbeforeunload, we return false now
// so we don't (try to) close the same tab again. Of course, we
// also stop if the unload was cancelled by the user:
if (aTab.closing || !permitUnload) {
// NB: deliberately keep the _closedDuringPermitUnload set to
// true so we keep exiting early in case of multiple calls.
return false;
if (!aTab._pendingPermitUnload && !aTabWillBeMoved) {
let ds = browser.docShell;
if (ds && ds.contentViewer) {
// We need to block while calling permitUnload() because it
// processes the event queue and may lead to another removeTab()
// call before permitUnload() returns.
aTab._pendingPermitUnload = true;
let permitUnload = ds.contentViewer.permitUnload();
delete aTab._pendingPermitUnload;
// If we were closed during onbeforeunload, we return false now
// so we don't (try to) close the same tab again. Of course, we
// also stop if the unload was cancelled by the user:
if (aTab.closing || !permitUnload) {
// NB: deliberately keep the _closedDuringPermitUnload set to
// true so we keep exiting early in case of multiple calls.
return false;
}
}
}
@ -4058,19 +4054,13 @@
}
case "DOMWindowClose": {
if (this.tabs.length == 1) {
// We already did PermitUnload in the content process
// for this tab (the only one in the window). So we don't
// need to do it again for any tabs.
window.skipNextCanClose = true;
window.close();
return;
}
let tab = this.getTabForBrowser(browser);
if (tab) {
// Skip running PermitUnload since it already happened in
// the content process.
this.removeTab(tab, {skipPermitUnload: true});
this.removeTab(tab);
}
break;
}
@ -4354,18 +4344,12 @@
if (!event.isTrusted)
return;
if (this.tabs.length == 1) {
// We already did PermitUnload in nsGlobalWindow::Close
// for this tab. There are no other tabs we need to do
// PermitUnload for.
window.skipNextCanClose = true;
if (this.tabs.length == 1)
return;
}
var tab = this._getTabForContentWindow(event.target);
if (tab) {
// Skip running PermitUnload since it already happened.
this.removeTab(tab, {skipPermitUnload: true});
this.removeTab(tab);
event.preventDefault();
}
]]>

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

@ -13,6 +13,6 @@ add_task(function* test_settingsOpen() {
Services.obs.notifyObservers(principal, "notifications-open-settings", null);
let tab = yield tabPromise;
ok(tab, "The notification settings tab opened");
BrowserTestUtils.removeTab(tab);
yield BrowserTestUtils.removeTab(tab);
});
});

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

@ -133,6 +133,7 @@ skip-if = e10s # Bug 1093153 - no about:home support yet
[browser_action_searchengine_alias.js]
[browser_addKeywordSearch.js]
[browser_search_favicon.js]
skip-if = e10s # Bug 1212647
[browser_alltabslistener.js]
[browser_audioTabIcon.js]
[browser_autocomplete_a11y_label.js]
@ -147,6 +148,7 @@ skip-if = e10s # Bug 1101993 - times out for unknown reasons when run in the dir
[browser_backButtonFitts.js]
skip-if = os == "mac" # The Fitt's Law back button is not supported on OS X
[browser_beforeunload_duplicate_dialogs.js]
skip-if = e10s # bug 967873 means permitUnload doesn't work in e10s mode
[browser_blob-channelname.js]
[browser_bookmark_titles.js]
skip-if = buildapp == 'mulet' || toolkit == "windows" # Disabled on Windows due to frequent failures (bugs 825739, 841341)
@ -267,7 +269,7 @@ tags = mcb
tags = mcb
[browser_bug906190.js]
tags = mcb
skip-if = buildapp == "mulet" || e10s # Bug 1093642 - test manipulates content and relies on content focus
skip-if = buildapp == "mulet" || e10s || os == "linux" # Bug 1093642 - test manipulates content and relies on content focus, Bug 1212520 - Re-enable on Linux
[browser_mixedContentFromOnunload.js]
tags = mcb
[browser_mixedContentFramesOnHttp.js]
@ -321,6 +323,7 @@ skip-if = e10s # Bug 863514 - no gesture support.
[browser_homeDrop.js]
skip-if = buildapp == 'mulet'
[browser_identity_UI.js]
[browser_insecureLoginForms.js]
[browser_keywordBookmarklets.js]
skip-if = e10s # Bug 1102025 - different principals for the bookmarklet only in e10s mode (unclear if test or 'real' issue)
[browser_keywordSearch.js]

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

@ -22,7 +22,7 @@ function test() {
function addTab(aURI, aIndex) {
var tab = gBrowser.addTab(aURI);
if (aIndex == 0)
gBrowser.removeTab(gBrowser.tabs[0], {skipPermitUnload: true});
gBrowser.removeTab(gBrowser.tabs[0]);
tab.linkedBrowser.addEventListener("load", function (event) {
event.currentTarget.removeEventListener("load", arguments.callee, true);
@ -41,14 +41,14 @@ function doTabsTest() {
var scheme = closedTab.linkedBrowser.currentURI.scheme;
Array.slice(gBrowser.tabs).forEach(function (aTab) {
if (aTab != closedTab && aTab.linkedBrowser.currentURI.scheme == scheme)
gBrowser.removeTab(aTab, {skipPermitUnload: true});
gBrowser.removeTab(aTab);
});
}, true);
gBrowser.removeTab(gBrowser.tabs[0], {skipPermitUnload: true});
gBrowser.removeTab(gBrowser.tabs[0]);
is(gBrowser.tabs.length, 1, "Related tabs are not closed unexpectedly");
gBrowser.addTab("about:blank");
gBrowser.removeTab(gBrowser.tabs[0], {skipPermitUnload: true});
gBrowser.removeTab(gBrowser.tabs[0]);
finish();
}

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

@ -99,7 +99,7 @@ function checkBookmarksPanel(invoker, phase)
if (currentInvoker < invokers.length) {
checkBookmarksPanel(invokers[currentInvoker], 1);
} else {
gBrowser.removeTab(gBrowser.selectedTab, {skipPermitUnload: true});
gBrowser.removeCurrentTab();
PlacesUtils.bookmarks.removeItem(bookmarkId);
executeSoon(finish);
}

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

@ -1,4 +1,4 @@
add_task(function*() {
function test() {
is(gBrowser.tabs.length, 1, "one tab is open");
gBrowser.selectedBrowser.focus();
@ -6,15 +6,11 @@ add_task(function*() {
var tab = gBrowser.selectedTab;
gPrefService.setBoolPref("browser.tabs.closeWindowWithLastTab", false);
let tabClosedPromise = BrowserTestUtils.removeTab(tab, {dontRemove: true});
EventUtils.synthesizeKey("w", { accelKey: true });
yield tabClosedPromise;
is(tab.parentNode, null, "ctrl+w removes the tab");
is(gBrowser.tabs.length, 1, "a new tab has been opened");
is(document.activeElement, gURLBar.inputField, "location bar is focused for the new tab");
if (gPrefService.prefHasUserValue("browser.tabs.closeWindowWithLastTab"))
gPrefService.clearUserPref("browser.tabs.closeWindowWithLastTab");
});
}

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

@ -18,13 +18,10 @@ function record(aName) {
if (actual.length == expected.length) {
is(actual.toString(), expected.toString(),
"got events and progress notifications in expected order");
executeSoon(function(tab) {
gBrowser.removeTab(tab);
gBrowser.removeTabsProgressListener(progressListener);
gBrowser.tabContainer.removeEventListener("TabOpen", TabOpen, false);
finish();
}.bind(null, tab));
gBrowser.removeTab(tab);
gBrowser.removeTabsProgressListener(progressListener);
gBrowser.tabContainer.removeEventListener("TabOpen", TabOpen, false);
finish();
}
}

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

@ -6,14 +6,14 @@ function test() {
childTab1 = gBrowser.addTab("about:blank", { relatedToCurrent: true });
gBrowser.selectedTab = childTab1;
gBrowser.removeTab(gBrowser.selectedTab, { skipPermitUnload: true });
gBrowser.removeCurrentTab();
is(idx(gBrowser.selectedTab), idx(tab1),
"closing a tab next to its parent selects the parent");
childTab1 = gBrowser.addTab("about:blank", { relatedToCurrent: true });
gBrowser.selectedTab = tab2;
gBrowser.selectedTab = childTab1;
gBrowser.removeTab(gBrowser.selectedTab, { skipPermitUnload: true });
gBrowser.removeCurrentTab();
is(idx(gBrowser.selectedTab), idx(tab2),
"closing a tab next to its parent doesn't select the parent if another tab had been selected ad interim");
@ -21,14 +21,14 @@ function test() {
childTab1 = gBrowser.addTab("about:blank", { relatedToCurrent: true });
childTab2 = gBrowser.addTab("about:blank", { relatedToCurrent: true });
gBrowser.selectedTab = childTab1;
gBrowser.removeTab(gBrowser.selectedTab, { skipPermitUnload: true });
gBrowser.removeCurrentTab();
is(idx(gBrowser.selectedTab), idx(childTab2),
"closing a tab next to its parent selects the next tab with the same parent");
gBrowser.removeTab(gBrowser.selectedTab, { skipPermitUnload: true });
gBrowser.removeCurrentTab();
is(idx(gBrowser.selectedTab), idx(tab2),
"closing the last tab in a set of child tabs doesn't go back to the parent");
gBrowser.removeTab(tab2, { skipPermitUnload: true });
gBrowser.removeTab(tab2);
}
function idx(tab) {

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

@ -14,13 +14,6 @@ function testAttrib(elem, attrib, attribValue, msg) {
function test() {
waitForExplicitFinish();
// Ensure TabView has been initialized already. Otherwise it could
// activate at an unexpected time and show/hide tabs.
TabView._initFrame(runTest);
}
function runTest() {
is(gBrowser.tabs.length, 1, "one tab is open initially");
// Add several new tabs in sequence, hiding some, to ensure that the

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

@ -5,12 +5,6 @@
function test() {
waitForExplicitFinish();
// Ensure TabView has been initialized already. Otherwise it could
// activate at an unexpected time and show/hide tabs.
TabView._initFrame(runTest);
}
function runTest() {
// establish initial state
is(gBrowser.tabs.length, 1, "we start with one tab");

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

@ -1,5 +1,4 @@
function test () {
requestLongerTimeout(2);
waitForExplicitFinish();
var isHTTPS = false;

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

@ -7,12 +7,6 @@
function test() {
waitForExplicitFinish();
// Ensure TabView has been initialized already. Otherwise it could
// activate at an unexpected time and show/hide tabs.
TabView._initFrame(runTest);
}
function runTest() {
// Add a tab that will get removed and hidden
let testTab = gBrowser.addTab("about:blank", {skipAnimation: true});
is(gBrowser.visibleTabs.length, 2, "just added a tab, so 2 tabs");

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

@ -0,0 +1,92 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Load directly from the browser-chrome support files of login tests.
const testUrlPath =
"://example.com/browser/toolkit/components/passwordmgr/test/browser/";
/**
* Waits for the given number of occurrences of InsecureLoginFormsStateChange
* on the given browser element.
*/
function waitForInsecureLoginFormsStateChange(browser, count) {
return BrowserTestUtils.waitForEvent(browser, "InsecureLoginFormsStateChange",
false, () => --count == 0);
}
/**
* Checks the insecure login forms logic for the identity block.
*/
add_task(function* test_simple() {
for (let scheme of ["http", "https"]) {
let tab = gBrowser.addTab(scheme + testUrlPath + "form_basic.html");
let browser = tab.linkedBrowser;
yield Promise.all([
BrowserTestUtils.switchTab(gBrowser, tab),
BrowserTestUtils.browserLoaded(browser),
// One event is triggered by pageshow and one by DOMFormHasPassword.
waitForInsecureLoginFormsStateChange(browser, 2),
]);
let { gIdentityHandler } = gBrowser.ownerGlobal;
gIdentityHandler._identityBox.click();
document.getElementById("identity-popup-security-expander").click();
if (scheme == "http") {
let identityBoxImage = gBrowser.ownerGlobal
.getComputedStyle(document.getElementById("page-proxy-favicon"), "")
.getPropertyValue("list-style-image");
let securityViewBG = gBrowser.ownerGlobal
.getComputedStyle(document.getElementById("identity-popup-securityView"), "")
.getPropertyValue("background-image");
let securityContentBG = gBrowser.ownerGlobal
.getComputedStyle(document.getElementById("identity-popup-security-content"), "")
.getPropertyValue("background-image");
is(identityBoxImage,
"url(\"chrome://browser/skin/identity-mixed-active-loaded.svg\")",
"Using expected icon image in the identity block");
is(securityViewBG,
"url(\"chrome://browser/skin/controlcenter/mcb-disabled.svg\")",
"Using expected icon image in the Control Center main view");
is(securityContentBG,
"url(\"chrome://browser/skin/controlcenter/mcb-disabled.svg\")",
"Using expected icon image in the Control Center subview");
}
// Messages should be visible when the scheme is HTTP, and invisible when
// the scheme is HTTPS.
is(Array.every(document.querySelectorAll("[when-loginforms=insecure]"),
element => !is_hidden(element)),
scheme == "http",
"The relevant messages should visible or hidden.");
gIdentityHandler._identityPopup.hidden = true;
gBrowser.removeTab(tab);
}
});
/**
* Checks that the insecure login forms logic does not regress mixed content
* blocking messages when mixed active content is loaded.
*/
add_task(function* test_mixedcontent() {
yield new Promise(resolve => SpecialPowers.pushPrefEnv({
"set": [["security.mixed_content.block_active_content", false]],
}, resolve));
// Load the page with the subframe in a new tab.
let tab = gBrowser.addTab("https" + testUrlPath + "insecure_test.html");
let browser = tab.linkedBrowser;
yield Promise.all([
BrowserTestUtils.switchTab(gBrowser, tab),
BrowserTestUtils.browserLoaded(browser),
// Two events are triggered by pageshow and one by DOMFormHasPassword.
waitForInsecureLoginFormsStateChange(browser, 3),
]);
assertMixedContentBlockingState(browser, { activeLoaded: true,
activeBlocked: false,
passiveLoaded: false });
gBrowser.removeTab(tab);
});

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

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
add_task(function*() {
function test() {
is(gBrowser.tabs.length, 1, "one tab is open initially");
// Add several new tabs in sequence, interrupted by selecting a
@ -10,29 +10,26 @@ add_task(function*() {
// returning a list of opened tabs for verifying the expected order.
// The new tab behaviour is documented in bug 465673
let tabs = [];
let promises = [];
function addTab(aURL, aReferrer) {
let tab = gBrowser.addTab(aURL, {referrerURI: aReferrer});
tabs.push(tab);
return BrowserTestUtils.browserLoaded(tab.linkedBrowser);
tabs.push(gBrowser.addTab(aURL, {referrerURI: aReferrer}));
}
yield addTab("http://mochi.test:8888/#0");
addTab("http://mochi.test:8888/#0");
gBrowser.selectedTab = tabs[0];
yield addTab("http://mochi.test:8888/#1");
yield addTab("http://mochi.test:8888/#2", gBrowser.currentURI);
yield addTab("http://mochi.test:8888/#3", gBrowser.currentURI);
addTab("http://mochi.test:8888/#1");
addTab("http://mochi.test:8888/#2", gBrowser.currentURI);
addTab("http://mochi.test:8888/#3", gBrowser.currentURI);
gBrowser.selectedTab = tabs[tabs.length - 1];
gBrowser.selectedTab = tabs[0];
yield addTab("http://mochi.test:8888/#4", gBrowser.currentURI);
addTab("http://mochi.test:8888/#4", gBrowser.currentURI);
gBrowser.selectedTab = tabs[3];
yield addTab("http://mochi.test:8888/#5", gBrowser.currentURI);
addTab("http://mochi.test:8888/#5", gBrowser.currentURI);
gBrowser.removeTab(tabs.pop());
yield addTab("about:blank", gBrowser.currentURI);
addTab("about:blank", gBrowser.currentURI);
gBrowser.moveTabTo(gBrowser.selectedTab, 1);
yield addTab("http://mochi.test:8888/#6", gBrowser.currentURI);
yield addTab();
yield addTab("http://mochi.test:8888/#7");
addTab("http://mochi.test:8888/#6", gBrowser.currentURI);
addTab();
addTab("http://mochi.test:8888/#7");
function testPosition(tabNum, expectedPosition, msg) {
is(Array.indexOf(gBrowser.tabs, tabs[tabNum]), expectedPosition, msg);
@ -49,4 +46,4 @@ add_task(function*() {
testPosition(8, 9, "tab without referrer opens at the end");
tabs.forEach(gBrowser.removeTab, gBrowser);
});
}

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

@ -18,5 +18,5 @@ function test() {
"gBrowser.selectTabAtIndex(-3) selects expected tab");
for (let i = 0; i < 9; i++)
gBrowser.removeTab(gBrowser.selectedTab, {skipPermitUnload: true});
gBrowser.removeCurrentTab();
}

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

@ -2,11 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
add_task(function* () {
// Ensure TabView has been initialized already. Otherwise it could
// activate at an unexpected time and show/hide tabs.
yield new Promise(resolve => TabView._initFrame(resolve));
function test() {
// There should be one tab when we start the test
let [origTab] = gBrowser.visibleTabs;
@ -104,5 +100,4 @@ add_task(function* () {
if (tabViewWindow)
tabViewWindow.GroupItems.groupItems[0].close();
});
}

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

@ -5,12 +5,6 @@
function test() {
waitForExplicitFinish();
// Ensure TabView has been initialized already. Otherwise it could
// activate at an unexpected time and show/hide tabs.
TabView._initFrame(runTest);
}
function runTest() {
let tabOne = gBrowser.addTab("about:blank");
let tabTwo = gBrowser.addTab("http://mochi.test:8888/");
gBrowser.selectedTab = tabTwo;

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

@ -5,12 +5,6 @@
function test() {
waitForExplicitFinish();
// Ensure TabView has been initialized already. Otherwise it could
// activate at an unexpected time and show/hide tabs.
TabView._initFrame(runTest);
}
function runTest() {
// There should be one tab when we start the test
let [origTab] = gBrowser.visibleTabs;
is(gBrowser.visibleTabs.length, 1, "1 tab should be open");

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

@ -2,11 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
add_task(function* test() {
// Ensure TabView has been initialized already. Otherwise it could
// activate at an unexpected time and show/hide tabs.
yield new Promise(resolve => TabView._initFrame(resolve));
function test() {
// There should be one tab when we start the test
let [origTab] = gBrowser.visibleTabs;
is(gBrowser.visibleTabs.length, 1, "there is one visible tab");
@ -55,5 +51,4 @@ add_task(function* test() {
gBrowser.removeTab(testTab);
gBrowser.removeTab(pinned);
});
}

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

@ -2,11 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
add_task(function* test() {
// Ensure TabView has been initialized already. Otherwise it could
// activate at an unexpected time and show/hide tabs.
yield new Promise(resolve => TabView._initFrame(resolve));
function test() {
gPrefService.setBoolPref("browser.ctrlTab.previews", true);
let [origTab] = gBrowser.visibleTabs;
@ -34,7 +30,7 @@ add_task(function* test() {
if (gPrefService.prefHasUserValue("browser.ctrlTab.previews"))
gPrefService.clearUserPref("browser.ctrlTab.previews");
});
}
function pressCtrlTab(aShiftKey) {
EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true, shiftKey: !!aShiftKey });

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

@ -888,6 +888,13 @@ function assertMixedContentBlockingState(tabbrowser, states = {}) {
}
}
if (activeLoaded || activeBlocked || passiveLoaded) {
doc.getElementById("identity-popup-security-expander").click();
is(Array.filter(doc.querySelectorAll("[observes=identity-popup-mcb-learn-more]"),
element => !is_hidden(element)).length, 1,
"The 'Learn more' link should be visible once.");
}
gIdentityHandler._identityPopup.hidden = true;
}

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

@ -416,7 +416,7 @@ function loadIntoTab(tab, url, callback) {
function ensureBrowserTabClosed(tab) {
let promise = ensureEventFired(gBrowser.tabContainer, "TabClose");
gBrowser.removeTab(tab, {skipPermitUnload: true});
gBrowser.removeTab(tab);
return promise;
}

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

@ -41,6 +41,7 @@
<description when-mixedcontent="active-loaded">&identity.activeLoaded;</description>
<description class="identity-popup-warning-yellow"
when-ciphers="weak">&identity.weakEncryption;</description>
<description when-loginforms="insecure">&identity.insecureLoginForms;</description>
</vbox>
</vbox>
<button id="identity-popup-security-expander"
@ -116,7 +117,11 @@
when-connection="secure secure-ev"/>
<!-- Connection is Not Secure -->
<description when-connection="not-secure">&identity.description.insecure;</description>
<description when-connection="not-secure"
and-when-loginforms="secure">&identity.description.insecure;</description>
<!-- Insecure login forms -->
<description when-loginforms="insecure">&identity.description.insecureLoginForms;</description>
<!-- Weak Cipher -->
<description when-ciphers="weak">&identity.description.weakCipher;</description>
@ -138,8 +143,14 @@
class="identity-popup-warning-yellow">&identity.description.passiveLoaded3; <label observes="identity-popup-mcb-learn-more"/></description>
<!-- Active Mixed Content Blocking Disabled -->
<description when-mixedcontent="active-loaded">&identity.description.activeLoaded;</description>
<description when-mixedcontent="active-loaded">&identity.description.activeLoaded2; <label observes="identity-popup-mcb-learn-more"/></description>
<description when-mixedcontent="active-loaded"
and-when-loginforms="secure">&identity.description.activeLoaded;</description>
<description when-mixedcontent="active-loaded"
and-when-loginforms="secure">&identity.description.activeLoaded2; <label observes="identity-popup-mcb-learn-more"/></description>
<!-- Show only the first message when there are insecure login forms,
and make sure the Learn More link is included. -->
<description when-mixedcontent="active-loaded"
and-when-loginforms="insecure">&identity.description.activeLoaded; <label observes="identity-popup-mcb-learn-more"/></description>
<!-- Buttons to enable/disable mixed content blocking. -->
<button when-mixedcontent="active-blocked"

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

@ -15,10 +15,10 @@ button::-moz-focus-inner {
z-index: 1020; /* required to have it superimposed to the video element */
border: 0;
left: 1.2rem;
right: .7rem;
height: 2.6rem;
right: 1.2rem;
height: 2.4rem;
position: absolute;
bottom: 1.5rem;
bottom: 1.2rem;
}
html[dir="rtl"] .conversation-toolbar {
@ -48,11 +48,11 @@ html[dir="rtl"] .conversation-toolbar > li {
.conversation-toolbar .btn {
background-position: center;
background-size: 28px;
background-size: 24px;
background-repeat: no-repeat;
background-color: transparent;
height: 28px;
width: 33px;
height: 24px;
width: 24px;
}
.conversation-toolbar-media-btn-group-box {
@ -855,8 +855,8 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
}
.standalone-room-wrapper > .media-layout {
/* 50px is the header, 3em is the footer. */
height: calc(100% - 50px - 3em);
/* 50px is the header, 10px is the bottom margin. */
height: calc(100% - 50px - 10px);
margin: 0 10px;
}
@ -977,8 +977,8 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
@media screen and (max-width:640px) {
.standalone-room-wrapper > .media-layout {
/* 50px is height of header, 25px is height of footer. */
height: calc(100% - 50px - 25px);
/* 50px is height of header, 10px is bottom margin. */
height: calc(100% - 50px - 10px);
}
.media-layout > .media-wrapper {
@ -1427,8 +1427,8 @@ html[dir="rtl"] .text-chat-entry.received .text-chat-arrow {
left: 0;
}
.standalone .room-conversation-wrapper .video-layout-wrapper {
/* 50px: header's height; 25px: footer's height */
height: calc(100% - 50px - 25px);
/* 50px: header's height; 10px: bottom margin */
height: calc(100% - 50px - 10px);
}
.standalone .room-conversation .video_wrapper.remote_wrapper {
width: 100%;

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

@ -25,7 +25,8 @@ npm_install:
# assets
.PHONY: dist
dist:
cp -pr content dist
mkdir -p dist
cp -pR content dist
NODE_ENV="production" $(NODE_LOCAL_BIN)/webpack \
-p -v --display-errors
sed 's#webappEntryPoint.js#js/standalone.js#' \

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

@ -57,74 +57,27 @@ body,
z-index: 1000;
}
/* Footer */
/* Mozilla Logo */
.footer-logo {
width: 100px;
margin: 0 auto;
height: 30px;
.focus-stream > .standalone-moz-logo {
width: 50px;
height: 13px;
background-size: contain;
background-image: url("../img/mozilla-logo.svg#logo-white");
background-repeat: no-repeat;
}
.rooms-footer {
background: #000;
margin: 0 10px;
text-align: left;
height: 3em;
position: relative;
}
html[dir="rtl"] .rooms-footer {
text-align: right;
}
.rooms-footer p {
/* Right-margin offset to account for .footer-logo plus 20px. */
/* Zero other margins due to 1em margin from reset.css. */
margin: 0 120px 0 0;
/* Vertically align in the middle. */
position: absolute;
top: 50%;
transform: translate(0, -50%);
bottom: 1.2rem;
right: 1.2rem;
left: auto;
}
html[dir="rtl"] .rooms-footer p {
margin: 0 0 0 120px;
}
.rooms-footer a {
color: #555;
}
.rooms-footer .footer-logo {
/* Vertically-align in the middle. */
position: absolute;
top: 50%;
transform: translate(0, -50%);
/* Align to the right. */
right: 0;
}
html[dir="rtl"] .rooms-footer .footer-logo {
left: 0;
html[dir="rtl"] .focus-stream > .standalone-moz-logo {
left: 1.2rem;
right: auto;
}
@media screen and (max-width:640px) {
.rooms-footer {
font-size: 80%;
height: 25px;
text-align: center;
}
.rooms-footer p {
margin: 0;
width: 100%;
}
.rooms-footer .footer-logo {
.focus-stream > .standalone-moz-logo {
display: none;
}
}

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

@ -416,20 +416,6 @@ loop.standaloneRoomViews = (function(mozL10n) {
}
});
var StandaloneRoomFooter = React.createClass({displayName: "StandaloneRoomFooter",
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired
},
render: function() {
return (
React.createElement("footer", {className: "rooms-footer"},
React.createElement("div", {className: "footer-logo"})
)
);
}
});
var StandaloneRoomView = React.createClass({displayName: "StandaloneRoomView",
mixins: [
Backbone.Events,
@ -678,14 +664,26 @@ loop.standaloneRoomViews = (function(mozL10n) {
publishStream: this.publishStream,
show: true,
video: {enabled: !this.state.videoMuted,
visible: this._roomIsActive()}})
),
React.createElement(StandaloneRoomFooter, {dispatcher: this.props.dispatcher})
visible: this._roomIsActive()}}),
React.createElement(StandaloneMozLogo, {dispatcher: this.props.dispatcher})
)
)
);
}
});
var StandaloneMozLogo = React.createClass({displayName: "StandaloneMozLogo",
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired
},
render: function() {
return (
React.createElement("div", {className: "standalone-moz-logo"})
);
}
});
var StandaloneRoomControllerView = React.createClass({displayName: "StandaloneRoomControllerView",
mixins: [
loop.store.StoreMixin("activeRoomStore")
@ -726,7 +724,6 @@ loop.standaloneRoomViews = (function(mozL10n) {
StandaloneHandleUserAgentView: StandaloneHandleUserAgentView,
StandaloneRoomControllerView: StandaloneRoomControllerView,
StandaloneRoomFailureView: StandaloneRoomFailureView,
StandaloneRoomFooter: StandaloneRoomFooter,
StandaloneRoomHeader: StandaloneRoomHeader,
StandaloneRoomInfoArea: StandaloneRoomInfoArea,
StandaloneRoomView: StandaloneRoomView,

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

@ -416,20 +416,6 @@ loop.standaloneRoomViews = (function(mozL10n) {
}
});
var StandaloneRoomFooter = React.createClass({
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired
},
render: function() {
return (
<footer className="rooms-footer">
<div className="footer-logo" />
</footer>
);
}
});
var StandaloneRoomView = React.createClass({
mixins: [
Backbone.Events,
@ -679,13 +665,25 @@ loop.standaloneRoomViews = (function(mozL10n) {
show={true}
video={{enabled: !this.state.videoMuted,
visible: this._roomIsActive()}} />
<StandaloneMozLogo dispatcher={this.props.dispatcher}/>
</sharedViews.MediaLayoutView>
<StandaloneRoomFooter dispatcher={this.props.dispatcher} />
</div>
);
}
});
var StandaloneMozLogo = React.createClass({
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired
},
render: function() {
return (
<div className="standalone-moz-logo" />
);
}
});
var StandaloneRoomControllerView = React.createClass({
mixins: [
loop.store.StoreMixin("activeRoomStore")
@ -726,7 +724,6 @@ loop.standaloneRoomViews = (function(mozL10n) {
StandaloneHandleUserAgentView: StandaloneHandleUserAgentView,
StandaloneRoomControllerView: StandaloneRoomControllerView,
StandaloneRoomFailureView: StandaloneRoomFailureView,
StandaloneRoomFooter: StandaloneRoomFooter,
StandaloneRoomHeader: StandaloneRoomHeader,
StandaloneRoomInfoArea: StandaloneRoomInfoArea,
StandaloneRoomView: StandaloneRoomView,

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

@ -315,7 +315,8 @@ var BookmarkPropertiesPanel = {
switch (this._action) {
case ACTION_EDIT:
gEditItemOverlay.initPanel({ node: this._node
, hiddenRows: this._hiddenRows });
, hiddenRows: this._hiddenRows
, focusedElement: "first" });
acceptButton.disabled = gEditItemOverlay.readOnly;
break;
case ACTION_ADD:
@ -323,7 +324,8 @@ var BookmarkPropertiesPanel = {
// Edit the new item
gEditItemOverlay.initPanel({ node: this._node
, hiddenRows: this._hiddenRows
, postData: this._postData });
, postData: this._postData
, focusedElement: "first" });
// Empty location field if the uri is about:blank, this way inserting a new
// url will be easier for the user, Accept button will be automatically

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

@ -56,12 +56,13 @@ var gEditItemOverlay = {
PlacesUIUtils.isContentsReadOnly(parent);
}
}
let focusedElement = aInitInfo.focusedElement;
return this._paneInfo = { itemId, itemGuid, isItem,
isURI, uri, title,
isBookmark, isFolderShortcut, isParentReadOnly,
bulkTagging, uris,
visibleRows, postData, isTag };
visibleRows, postData, isTag, focusedElement };
},
get initialized() {
@ -181,7 +182,7 @@ var gEditItemOverlay = {
let { itemId, itemGuid, isItem,
isURI, uri, title,
isBookmark, bulkTagging, uris,
visibleRows } = this._setPaneInfo(aInfo);
visibleRows, focusedElement } = this._setPaneInfo(aInfo);
let showOrCollapse =
(rowId, isAppropriateForInput, nameInHiddenRows = null) => {
@ -252,6 +253,24 @@ var gEditItemOverlay = {
window.addEventListener("unload", this, false);
this._observersAdded = true;
}
// The focusedElement possible values are:
// * preferred: focus the field that the user touched first the last
// time the pane was shown (either namePicker or tagsField)
// * first: focus the first non collapsed textbox
// Note: since all controls are collapsed by default, we don't get the
// default XUL dialog behavior, that selects the first control, so we set
// the focus explicitly.
let elt;
if (focusedElement === "preferred") {
elt = this._element(gPrefService.getCharPref("browser.bookmarks.editDialog.firstEditField"));
} else if (focusedElement === "first") {
elt = document.querySelector("textbox:not([collapsed=true])");
}
if (elt) {
elt.focus();
elt.select();
}
},
/**

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

@ -322,6 +322,15 @@ var withBookmarksDialog = Task.async(function* (autoCancel, openFn, taskFn) {
yield waitForCondition(() => dialogWin.gEditItemOverlay.initialized,
"EditItemOverlay should be initialized");
// Check the first textbox is focused.
let doc = dialogWin.document;
let elt = doc.querySelector("textbox:not([collapsed=true])");
if (elt) {
info("waiting for focus on the first textfield");
yield waitForCondition(() => doc.activeElement == elt.inputField,
"The first non collapsed textbox should have been focused");
}
info("withBookmarksDialog: executing the task");
try {
yield taskFn(dialogWin);
@ -331,7 +340,7 @@ var withBookmarksDialog = Task.async(function* (autoCancel, openFn, taskFn) {
ok(false, "The test should have closed the dialog!");
}
info("withBookmarksDialog: canceling the dialog");
dialogWin.document.documentElement.cancelDialog();
doc.documentElement.cancelDialog();
}
}
});

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

@ -6,10 +6,6 @@ add_task(function* () {
/** Bug 607016 - If a tab is never restored, attributes (eg. hidden) aren't updated correctly **/
ignoreAllUncaughtExceptions();
// Ensure TabView has been initialized already. Otherwise it could
// activate at an unexpected time and show/hide tabs.
yield new Promise(resolve => TabView._initFrame(resolve));
// Set the pref to true so we know exactly how many tabs should be restoring at
// any given time. This guarantees that a finishing load won't start another.
Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);

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

@ -7,12 +7,6 @@
function test() {
waitForExplicitFinish();
// Ensure TabView has been initialized already. Otherwise it could
// activate at an unexpected time and show/hide tabs.
TabView._initFrame(runTest);
}
function runTest() {
// We speed up the interval between session saves to ensure that the test
// runs quickly.
Services.prefs.setIntPref("browser.sessionstore.interval", 2000);

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

@ -39,18 +39,11 @@ var RemotePrompt = {
let tabPrompt = window.gBrowser.getTabModalPromptBox(browser)
let callbackInvoked = false;
let newPrompt;
let needRemove = false;
let promptId = args._remoteId;
function onPromptClose(forceCleanup) {
// It's possible that we removed the prompt during the
// appendPrompt call below. In that case, newPrompt will be
// undefined. We set the needRemove flag to remember to remove
// it right after we've finished adding it.
if (newPrompt)
tabPrompt.removePrompt(newPrompt);
else
needRemove = true;
PromptUtils.fireDialogEvent(window, "DOMModalDialogClosed", browser);
browser.messageManager.sendAsyncMessage("Prompt:Close", args);
@ -76,10 +69,6 @@ var RemotePrompt = {
newPrompt = tabPrompt.appendPrompt(args, onPromptClose);
if (needRemove) {
tabPrompt.removePrompt(newPrompt);
}
// TODO since we don't actually open a window, need to check if
// there's other stuff in nsWindowWatcher::OpenWindowInternal
// that we might need to do here as well.

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

@ -765,7 +765,7 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
#forward-button > .toolbarbutton-icon {
background-clip: padding-box;
padding-left: 9px;
padding-left: calc(var(--backbutton-urlbar-overlap) + 4px);
padding-right: 3px;
border: 1px solid #9a9a9a;
border-left-style: none;
@ -1206,7 +1206,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
-moz-appearance: none;
list-style-image: url("chrome://browser/skin/reload-stop-go.png");
padding: 0 9px;
margin-inline-start: 2px;
margin-inline-start: 5px;
border-inline-start: 1px solid var(--urlbar-separator-color);
border-image: linear-gradient(transparent 15%,
var(--urlbar-separator-color) 15%,

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

@ -8,7 +8,6 @@ browser.jar:
#include ../shared/jar.inc.mn
skin/classic/browser/sanitizeDialog.css
skin/classic/browser/aboutSessionRestore-window-icon.png
skin/classic/browser/aboutCertError.css
skin/classic/browser/aboutCertError_sectionCollapsed.png
skin/classic/browser/aboutCertError_sectionCollapsed-rtl.png
skin/classic/browser/aboutCertError_sectionExpanded.png

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

@ -1,72 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
html {
background: -moz-Dialog;
}
body {
margin: 0;
padding: 0 1em;
color: -moz-FieldText;
font: message-box;
}
h1 {
margin: 0 0 .6em 0;
border-bottom: 1px solid ThreeDLightShadow;
font-size: 160%;
}
h2 {
font-size: 130%;
}
#errorPageContainer {
position: relative;
min-width: 13em;
max-width: 52em;
margin: 4em auto;
border: 1px solid #FFBD09; /* pale yellow extracted from yellow passport icon */
border-radius: 10px;
padding: 3em;
-moz-padding-start: 30px;
background: url("chrome://global/skin/icons/sslWarning.png") left 0 no-repeat -moz-Field;
background-origin: content-box;
}
#errorPageContainer:-moz-dir(rtl) {
background-position: right 0;
}
#errorTitle {
-moz-margin-start: 80px;
}
#errorLongContent {
-moz-margin-start: 80px;
}
.expander > button {
-moz-padding-start: 20px;
-moz-margin-start: -20px;
background: url("chrome://browser/skin/aboutCertError_sectionExpanded.png") left center no-repeat;
border: none;
font: inherit;
color: inherit;
cursor: pointer;
}
.expander > button:-moz-dir(rtl) {
background-position: right center;
}
.expander[collapsed] > button {
background-image: url("chrome://browser/skin/aboutCertError_sectionCollapsed.png");
}
.expander[collapsed] > button:-moz-dir(rtl) {
background-image: url("chrome://browser/skin/aboutCertError_sectionCollapsed-rtl.png");
}

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

@ -1898,8 +1898,7 @@ richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-
margin: 0;
list-style-image: url("chrome://browser/skin/reload-stop-go.png");
padding: 0 9px;
margin-inline-start: 2px;
border-inline-end-style: none;
margin-inline-start: 5px;
border-inline-start: 1px solid var(--urlbar-separator-color);
border-image: linear-gradient(transparent 15%,
var(--urlbar-separator-color) 15%,

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

@ -7,7 +7,6 @@ browser.jar:
#include ../shared/jar.inc.mn
skin/classic/browser/sanitizeDialog.css
skin/classic/browser/aboutSessionRestore-window-icon.png
skin/classic/browser/aboutCertError.css
skin/classic/browser/aboutCertError_sectionCollapsed.png
skin/classic/browser/aboutCertError_sectionCollapsed-rtl.png
skin/classic/browser/aboutCertError_sectionExpanded.png

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

@ -5,7 +5,7 @@
%endif
/* Hide all conditional elements by default. */
:-moz-any([when-connection],[when-mixedcontent],[when-ciphers]) {
:-moz-any([when-connection],[when-mixedcontent],[when-ciphers],[when-loginforms]) {
display: none;
}
@ -15,6 +15,8 @@
#identity-popup[connection=secure] [when-connection~=secure],
#identity-popup[connection=chrome] [when-connection~=chrome],
#identity-popup[connection=file] [when-connection~=file],
/* Show insecure login forms messages when needed. */
#identity-popup[loginforms=insecure] [when-loginforms=insecure],
/* Show weak cipher messages when needed. */
#identity-popup[ciphers=weak] [when-ciphers~=weak],
/* Show mixed content warnings when needed */
@ -28,6 +30,14 @@
display: inherit;
}
/* Hide redundant messages based on insecure login forms presence. */
#identity-popup[loginforms=secure] [and-when-loginforms=insecure] {
display: none;
}
#identity-popup[loginforms=insecure] [and-when-loginforms=secure] {
display: none;
}
/* Hide 'not secure' message in subview when weak cipher or mixed content messages are shown. */
#identity-popup-securityView-body:-moz-any([mixedcontent],[ciphers]) > description[when-connection=not-secure],
/* Hide 'passive-loaded (only)' message when there is mixed passive content loaded and active blocked. */
@ -219,6 +229,8 @@
background-image: url(chrome://browser/skin/controlcenter/conn-degraded.svg);
}
#identity-popup[loginforms=insecure] #identity-popup-securityView,
#identity-popup[loginforms=insecure] #identity-popup-security-content,
#identity-popup[mixedcontent~=active-loaded][isbroken] #identity-popup-securityView,
#identity-popup[mixedcontent~=active-loaded][isbroken] #identity-popup-security-content {
background-image: url(chrome://browser/skin/controlcenter/mcb-disabled.svg);

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

@ -123,6 +123,7 @@
list-style-image: url(chrome://browser/skin/identity-secure.svg);
}
.insecureLoginForms > #identity-icons > #page-proxy-favicon[pageproxystate="valid"],
.mixedActiveContent > #identity-icons > #page-proxy-favicon[pageproxystate="valid"] {
list-style-image: url(chrome://browser/skin/identity-mixed-active-loaded.svg);
}

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

@ -7,6 +7,7 @@
# be specified once. As a result, the source file paths are relative
# to the location of the actual manifest.
skin/classic/browser/aboutCertError.css (../shared/aboutCertError.css)
skin/classic/browser/aboutNetError.css (../shared/aboutNetError.css)
skin/classic/browser/aboutNetError_info.svg (../shared/aboutNetError_info.svg)
skin/classic/browser/aboutNetError_alert.svg (../shared/aboutNetError_alert.svg)

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

@ -99,7 +99,7 @@
}
@conditionalForwardWithUrlbar@ > #forward-button[disabled] + #urlbar > #notification-popup-box {
padding-left: 7px;
padding-left: calc(var(--backbutton-urlbar-overlap) + 3px);
}
/* This changes the direction of the main notification box on the url bar. */

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

@ -1,72 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
html {
background: -moz-Dialog;
}
body {
margin: 0;
padding: 0 1em;
color: -moz-FieldText;
font: message-box;
}
h1 {
margin: 0 0 .6em 0;
border-bottom: 1px solid ThreeDLightShadow;
font-size: 160%;
}
h2 {
font-size: 130%;
}
#errorPageContainer {
position: relative;
min-width: 13em;
max-width: 52em;
margin: 4em auto;
border: 1px solid #FFBD09; /* pale yellow extracted from yellow passport icon */
border-radius: 10px;
padding: 3em;
-moz-padding-start: 30px;
background: url("chrome://global/skin/icons/sslWarning.png") left 0 no-repeat -moz-Field;
background-origin: content-box;
}
#errorPageContainer:-moz-dir(rtl) {
background-position: right 0;
}
#errorTitle {
-moz-margin-start: 80px;
}
#errorLongContent {
-moz-margin-start: 80px;
}
.expander > button {
-moz-padding-start: 20px;
-moz-margin-start: -20px;
background: url("chrome://browser/skin/aboutCertError_sectionExpanded.png") left center no-repeat;
border: none;
font: inherit;
color: inherit;
cursor: pointer;
}
.expander > button:-moz-dir(rtl) {
background-position: right center;
}
.expander[collapsed] > button {
background-image: url("chrome://browser/skin/aboutCertError_sectionCollapsed.png");
}
.expander[collapsed] > button:-moz-dir(rtl) {
background-image: url("chrome://browser/skin/aboutCertError_sectionCollapsed-rtl.png");
}

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

@ -12,25 +12,23 @@
%include windowsShared.inc
%filter substitution
%define toolbarShadowColor hsla(209,67%,12%,0.35)
%define navbarTextboxCustomBorder border-color: rgba(0,0,0,.32);
%define forwardTransitionLength 150ms
%define conditionalForwardWithUrlbar window:not([chromehidden~="toolbar"]) #urlbar-wrapper
%define conditionalForwardWithUrlbarWidth 30
:root {
--space-above-tabbar: 15px;
--backbutton-urlbar-overlap: 5px;
--backbutton-urlbar-overlap: 6px;
--toolbarbutton-vertical-inner-padding: 2px;
--toolbarbutton-vertical-outer-padding: 8px;
--toolbarbutton-hover-background: rgba(0,0,0,.1);
--toolbarbutton-hover-bordercolor: rgba(0,0,0,.1);
--toolbarbutton-hover-bordercolor: rgba(0,0,0,.2);
--toolbarbutton-hover-boxshadow: none;
--toolbarbutton-active-background: rgba(0,0,0,.15);
--toolbarbutton-active-bordercolor: rgba(0,0,0,.15);
--toolbarbutton-active-bordercolor: rgba(0,0,0,.3);
--toolbarbutton-active-boxshadow: 0 0 0 1px rgba(0,0,0,.15) inset;
--toolbarbutton-checkedhover-backgroundcolor: rgba(0,0,0,.1);
@ -51,18 +49,6 @@
--urlbar-separator-color: hsla(0,0%,16%,.2);
}
#nav-bar[brighttext] {
--toolbarbutton-hover-background: rgba(255,255,255,.15);
--toolbarbutton-hover-bordercolor: rgba(255,255,255,.15);
--toolbarbutton-hover-boxshadow: none;
--toolbarbutton-active-background: rgba(255,255,255,.3);
--toolbarbutton-active-bordercolor: rgba(255,255,255,.3);
--toolbarbutton-active-boxshadow: 0 0 0 1px rgba(255,255,255,.3) inset;
--toolbarbutton-checkedhover-backgroundcolor: rgba(255,255,255,.2);
}
#menubar-items {
-moz-box-orient: vertical; /* for flex hack */
}
@ -727,6 +713,8 @@ toolbar[brighttext] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon,
@conditionalForwardWithUrlbar@ > .toolbarbutton-1:-moz-any([disabled],:not([open]):not([disabled]):not(:active)) > .toolbarbutton-icon {
padding: var(--toolbarbutton-vertical-inner-padding) 6px;
background-origin: padding-box !important;
background-clip: padding-box !important;
border: 1px solid transparent;
border-radius: 1px;
transition-property: background-color, border-color, box-shadow;
@ -856,10 +844,6 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
opacity: .3;
}
@conditionalForwardWithUrlbar@ > .toolbarbutton-1:-moz-any([disabled],:not([open]):not([disabled]):not(:active)) > .toolbarbutton-icon {
border-color: hsla(210,4%,10%,.1);
}
.findbar-button:not(:-moz-any([checked="true"],[disabled="true"])):hover > .toolbarbutton-text,
#nav-bar .toolbarbutton-1:not([disabled=true]) > .toolbarbutton-menubutton-button[open] + .toolbarbutton-menubutton-dropmarker > .dropmarker-icon,
#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any(:hover,[open]) > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
@ -919,6 +903,15 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
/* unified back/forward button */
:-moz-any(#back-button, #forward-button) > .toolbarbutton-icon {
border-color: var(--urlbar-border-color-hover) !important;
}
:-moz-any(#back-button, #forward-button):not(:hover):not(:active):not([open=true]) > .toolbarbutton-icon,
:-moz-any(#back-button, #forward-button)[disabled=true] > .toolbarbutton-icon {
background-color: rgba(255,255,255,.15) !important;
}
#forward-button {
-moz-box-align: stretch; /* let the button shape grow vertically with the location bar */
padding: 0 !important;
@ -929,12 +922,13 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
}
#forward-button > .toolbarbutton-icon {
background-clip: padding-box !important;
border-left-style: none !important;
border-radius: 0 !important;
padding-left: 9px !important;
padding-left: calc(var(--backbutton-urlbar-overlap) + 3px) !important;
padding-right: 3px !important;
width: 31px !important; /* horizontal padding + border + actual icon width */
% icon width + border + horizontal padding without --backbutton-urlbar-overlap
%define forwardButtonWidth 25
width: calc(@forwardButtonWidth@px + var(--backbutton-urlbar-overlap)) !important;
}
@conditionalForwardWithUrlbar@:not([switchingtabs]) > #forward-button {
@ -942,7 +936,7 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
}
@conditionalForwardWithUrlbar@ > #forward-button[disabled] {
margin-left: -@conditionalForwardWithUrlbarWidth@px;
margin-left: calc(-@forwardButtonWidth@px - var(--backbutton-urlbar-overlap));
}
@conditionalForwardWithUrlbar@:hover:not([switchingtabs]) > #forward-button[disabled] {
@ -952,7 +946,7 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
@conditionalForwardWithUrlbar@:not(:hover) > #forward-button[disabled] {
/* when not hovered anymore, trigger a new transition to hide the forward button immediately */
margin-left: -@conditionalForwardWithUrlbarWidth@.01px;
margin-left: calc(-@forwardButtonWidth@.01px - var(--backbutton-urlbar-overlap));
}
#back-button {
@ -963,8 +957,6 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
position: relative !important;
z-index: 1 !important;
border-radius: 0 10000px 10000px 0 !important;
--toolbarbutton-hover-boxshadow: 0 1px 0 0 hsla(210,4%,10%,.25),
0 0 0 1px hsla(210,4%,10%,.25);
}
#back-button:-moz-locale-dir(rtl) {
@ -977,64 +969,8 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
#back-button > .toolbarbutton-icon {
border-radius: 10000px !important;
background-clip: padding-box !important;
background-color: hsla(210,25%,98%,.08) !important;
padding: 6px !important;
border-style: none !important;
width: 30px !important; /* horizontal padding + border + actual icon width */
box-shadow: 0 1px 0 0 hsla(210,4%,10%,.25),
0 0 0 1px hsla(210,4%,10%,.25);
transition-property: background-color, box-shadow !important;
transition-duration: 250ms !important;
}
#back-button:not([disabled="true"]):not([open="true"]):not(:active):hover > .toolbarbutton-icon {
background-color: hsla(210,4%,10%,.08) !important;
}
#back-button:not([disabled="true"]):hover:active > .toolbarbutton-icon,
#back-button[open="true"] > .toolbarbutton-icon {
background-color: hsla(210,4%,10%,.12) !important;
box-shadow: 0 1px 0 0 hsla(210,4%,10%,.25),
0 0 0 1px hsla(210,4%,10%,.25),
0 1px 0 0 hsla(210,80%,20%,.1) inset !important;
}
@media (-moz-os-version: windows-xp),
(-moz-os-version: windows-vista),
(-moz-os-version: windows-win7) {
#back-button > .toolbarbutton-icon {
background-image: linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.1)) !important;
box-shadow: 0 1px 0 hsla(0,0%,100%,.3) inset,
0 0 0 1px hsla(0,0%,100%,.3) inset,
0 0 0 1px hsla(210,54%,20%,.25),
0 1px 0 hsla(210,54%,20%,.35) !important;
}
#back-button:not([disabled="true"]):not([open="true"]):not(:active):hover > .toolbarbutton-icon {
background-color: hsla(210,48%,96%,.75) !important;
box-shadow: 0 1px 0 hsla(0,0%,100%,.3) inset,
0 0 0 1px hsla(0,0%,100%,.3) inset,
0 0 0 1px hsla(210,54%,20%,.3),
0 1px 0 hsla(210,54%,20%,.4),
0 0 4px hsla(210,54%,20%,.2) !important;
}
#back-button:not([disabled="true"]):hover:active > .toolbarbutton-icon,
#back-button[open="true"] > .toolbarbutton-icon {
background-color: hsla(210,54%,20%,.15) !important;
box-shadow: 0 1px 1px hsla(210,54%,20%,.1) inset,
0 0 1px hsla(210,54%,20%,.2) inset,
0 0 0 1px hsla(210,54%,20%,.4),
0 1px 0 hsla(210,54%,20%,.2) !important;
transition: none;
}
#main-window:not([customizing]) #back-button[disabled] > .toolbarbutton-icon {
box-shadow: 0 0 0 1px hsla(210,54%,20%,.55),
0 1px 0 hsla(210,54%,20%,.65) !important;
transition: none;
}
width: 32px !important; /* icon width + horizontal padding + border */
}
#back-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
@ -1173,13 +1109,46 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
/* ::::: Location Bar ::::: */
#nav-bar {
--urlbar-border-color: ThreeDShadow;
--urlbar-border-color-hover: var(--urlbar-border-color);
}
#nav-bar:-moz-lwtheme {
--urlbar-border-color: rgba(0,0,0,.32);
}
@media (-moz-windows-default-theme) {
@media (-moz-os-version: windows-vista),
(-moz-os-version: windows-win7),
(-moz-os-version: windows-win8) {
#nav-bar:not(:-moz-lwtheme) {
--urlbar-border-color: hsla(210,54%,20%,.25) hsla(210,54%,20%,.27) hsla(210,54%,20%,.3);
--urlbar-border-color-hover: hsla(210,54%,20%,.35) hsla(210,54%,20%,.37) hsla(210,54%,20%,.4);
}
}
@media (-moz-os-version: windows-win10) {
#nav-bar:not(:-moz-lwtheme) {
--urlbar-border-color: hsl(0,0%,90%);
--urlbar-border-color-hover: hsl(0,0%,80%);
}
}
}
#urlbar,
.searchbar-textbox {
-moz-appearance: none;
margin: 0 3px;
padding: 0;
background-clip: padding-box;
border: 1px solid ThreeDShadow;
border: 1px solid;
border-color: var(--urlbar-border-color);
}
#urlbar:hover,
.searchbar-textbox:hover {
border-color: var(--urlbar-border-color-hover);
}
/* overlap the urlbar's border */
@ -1190,7 +1159,6 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
@media (-moz-windows-default-theme) {
#urlbar,
.searchbar-textbox {
@navbarTextboxCustomBorder@
border-radius: 1px;
}
@ -1199,31 +1167,19 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
(-moz-os-version: windows-win8) {
#urlbar:not(:-moz-lwtheme),
.searchbar-textbox:not(:-moz-lwtheme) {
border-color: hsla(210,54%,20%,.25) hsla(210,54%,20%,.27) hsla(210,54%,20%,.3);
box-shadow: 0 1px 0 hsla(0,0%,0%,.01) inset,
0 1px 0 hsla(0,0%,100%,.1);
}
#urlbar:not(:-moz-lwtheme):hover,
.searchbar-textbox:not(:-moz-lwtheme):hover {
border-color: hsla(210,54%,20%,.35) hsla(210,54%,20%,.37) hsla(210,54%,20%,.4);
}
}
@media (-moz-os-version: windows-win10) {
#urlbar:not(:-moz-lwtheme),
.searchbar-textbox:not(:-moz-lwtheme) {
border-color: hsl(0,0%,90%);
padding: 1px;
transition-property: border-color, box-shadow;
transition-duration: .1s;
}
#urlbar:not(:-moz-lwtheme):hover,
.searchbar-textbox:not(:-moz-lwtheme):hover {
border-color: hsl(0,0%,80%);
}
#urlbar:not(:-moz-lwtheme)[focused],
.searchbar-textbox:not(:-moz-lwtheme)[focused] {
box-shadow: 0 0 0 1px Highlight inset;
@ -1260,7 +1216,6 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
#urlbar:-moz-lwtheme,
.searchbar-textbox:-moz-lwtheme {
background-color: rgba(255,255,255,.8);
@navbarTextboxCustomBorder@
color: black;
}
@ -1301,7 +1256,7 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
}
:root {
--backbutton-urlbar-overlap: 8px;
--backbutton-urlbar-overlap: 9px;
}
}
@ -1609,7 +1564,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
border-style: none;
list-style-image: url("chrome://browser/skin/reload-stop-go.png");
padding: 0 9px;
margin-inline-start: 2px;
margin-inline-start: 5px;
border-inline-start: 1px solid var(--urlbar-separator-color);
border-image: linear-gradient(transparent 15%,
var(--urlbar-separator-color) 15%,

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

@ -7,7 +7,6 @@ browser.jar:
#include ../shared/jar.inc.mn
skin/classic/browser/sanitizeDialog.css
skin/classic/browser/aboutSessionRestore-window-icon.png
skin/classic/browser/aboutCertError.css
skin/classic/browser/aboutCertError_sectionCollapsed.png
skin/classic/browser/aboutCertError_sectionCollapsed-rtl.png
skin/classic/browser/aboutCertError_sectionExpanded.png

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -27,10 +27,6 @@
# - PYTHON, the path to the python executable
# - ACDEFINES, which contains a set of -Dvar=name to be used during
# preprocessing
# - MOZ_CHROME_FILE_FORMAT, which defines whether to use file copies or
# symbolic links
# - JAR_MN_TARGETS, which defines the targets to use for jar manifest
# processing, see further below
# - INSTALL_MANIFESTS, which defines the list of base directories handled
# by install manifests, see further below
# - MANIFEST_TARGETS, which defines the file paths of chrome manifests, see
@ -42,7 +38,6 @@
# Targets to be triggered for a default build
default: $(addprefix install-,$(INSTALL_MANIFESTS))
default: $(addprefix jar-,$(JAR_MN_TARGETS))
# Explicit files to be built for a default build
default: $(addprefix $(TOPOBJDIR)/,$(MANIFEST_TARGETS))
@ -53,6 +48,12 @@ default: $(TOPOBJDIR)/dist/bin/webapprt/webapprt.ini
# Targets from the recursive make backend to be built for a default build
default: $(TOPOBJDIR)/config/makefiles/xpidl/xpidl
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
# Mac builds require to copy things in dist/bin/*.app
default:
$(MAKE) -C $(TOPOBJDIR)/$(MOZ_BUILD_APP)/app repackage
endif
.PHONY: FORCE
# Extra define to trigger some workarounds. We should strive to limit the
@ -95,52 +96,6 @@ $(addprefix install-,$(INSTALL_MANIFESTS)): install-%: $(TOPOBJDIR)/config/build
$(MOZ_DEBUG_DEFINES) \
install_$(subst /,_,$*)
# Install files from jar manifests. Ideally, they would be using install
# manifests, but the code to read jar manifests and emit appropriate
# install manifests is not there yet.
# Things missing:
# - DEFINES from config/config.mk
# - L10N
# - -e when USE_EXTENSION_MANIFEST is set in moz.build
#
# The list given in JAR_MN_TARGETS corresponds to the list of `jar-%` targets
# to be processed, with the `jar-` prefix stripped.
# The Makefile is expected to specify the source jar manifest as a dependency
# to each target. There is no expectation that the `jar-%` target name matches
# the source file name in any way. For example:
# JAR_MN_TARGETS = foo
# jar-foo: /path/to/some/jar.mn
# Additionally, extra defines can be specified for the processing of the jar
# manifest by settig the `defines` variable specifically for the given target.
# For example:
# jar-foo: defines = -Dqux=foo
# The default base path where files are going to be installed is `dist/bin`.
# It is possible to use a different path by setting the `install_target`
# variable. For example:
# jar-foo: install_target = dist/bin/foo
# When processing jar manifests, relative paths given inside a jar manifest
# can be resolved from an object directory. The default path for that object
# directory is the translation of the jar manifest directory path from the
# source directory to the object directory. That is, for
# $(TOPSRCDIR)/path/to/jar.mn, the default would be $(TOPOBJDIR)/path/to.
# In case a different path must be used for the object directory, the `objdir`
# variable can be set. For example:
# jar-foo: objdir=/some/other/path
jar-%: objdir ?= $(dir $(patsubst $(TOPSRCDIR)%,$(TOPOBJDIR)%,$<))
jar-%: install_target ?= dist/bin
jar-%:
cd $(objdir) && \
$(PYTHON) -m mozbuild.action.jar_maker \
-j $(TOPOBJDIR)/$(install_target)/chrome \
-t $(TOPSRCDIR) \
-f $(MOZ_CHROME_FILE_FORMAT) \
-c $(dir $<)/en-US \
-DAB_CD=en-US \
$(defines) \
$(ACDEFINES) \
$(MOZ_DEBUG_DEFINES) \
$<
# Create some chrome manifests
# This rule is forced to run every time because it may be updating files that
# already exit.
@ -159,13 +114,6 @@ $(addprefix $(TOPOBJDIR)/,$(MANIFEST_TARGETS)): FORCE
# Below is a set of additional dependencies and variables used to build things
# that are not supported by data in moz.build.
# GENERATED_FILES are not supported yet, and even if they were, the
# dependencies are missing information.
$(foreach p,linux osx windows,jar-browser-themes-$(p)-jar.mn): \
jar-browser-themes-%-jar.mn: \
$(TOPOBJDIR)/browser/themes/%/tab-selected-end.svg \
$(TOPOBJDIR)/browser/themes/%/tab-selected-start.svg
# Files to build with the recursive backend and simply copy
$(TOPOBJDIR)/dist/bin/greprefs.js: $(TOPOBJDIR)/modules/libpref/greprefs.js
$(TOPOBJDIR)/dist/bin/platform.ini: $(TOPOBJDIR)/toolkit/xre/platform.ini

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

@ -2,7 +2,10 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import configobj, sys
import configobj
import sys
import re
from StringIO import StringIO
try:
(file, section, key) = sys.argv[1:]
@ -10,7 +13,10 @@ except ValueError:
print "Usage: printconfigsetting.py <file> <section> <setting>"
sys.exit(1)
c = configobj.ConfigObj(file)
with open(file) as fh:
content = re.sub('^\s*;', '#', fh.read(), flags=re.M)
c = configobj.ConfigObj(StringIO(content))
try:
s = c[section]

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

@ -164,6 +164,7 @@ devtools.jar:
* skin/themes/common.css (themes/common.css)
* skin/themes/dark-theme.css (themes/dark-theme.css)
* skin/themes/light-theme.css (themes/light-theme.css)
skin/themes/variables.css (themes/variables.css)
skin/themes/images/add.svg (themes/images/add.svg)
skin/themes/images/filters.svg (themes/images/filters.svg)
skin/themes/images/filter-swatch.svg (themes/images/filter-swatch.svg)

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

@ -23,6 +23,11 @@ add_task(function*() {
parentContainer.elt.scrollIntoView(true);
info("Testing putting an element back in it's original place");
yield dragElementToOriginalLocation("#firstChild", inspector);
is(parent.children[0].id, "firstChild", "#firstChild is still the first child of #test");
is(parent.children[1].id, "middleChild", "#middleChild is still the second child of #test");
info("Testing switching elements inside their parent");
yield moveElementDown("#firstChild", "#middleChild", inspector);
@ -95,6 +100,27 @@ function* dragContainer(selector, targetOffset, inspector) {
return updated;
};
function* dragElementToOriginalLocation(selector, inspector) {
let el = yield getContainerForSelector(selector, inspector);
let height = el.tagLine.getBoundingClientRect().height;
info("Picking up and putting back down " + selector);
function onMutation() {
ok(false, "Mutation received from dragging a node back to its location");
}
inspector.on("markupmutation", onMutation);
yield dragContainer(selector, {x: 0, y: 0}, inspector);
// Wait a bit to make sure the event never fires.
// This doesn't need to catch *all* cases, since the mutation
// will cause failure later in the test when it checks element ordering.
yield new Promise(resolve => {
setTimeout(resolve, 500);
});
inspector.off("markupmutation", onMutation);
}
function* moveElementDown(selector, next, inspector) {
let onMutated = inspector.once("markupmutation");
let uiUpdate = inspector.once("inspector-updated");
@ -106,6 +132,7 @@ function* moveElementDown(selector, next, inspector) {
yield dragContainer(selector, {x: 0, y: Math.round(height) + 2}, inspector);
yield onMutated;
let mutations = yield onMutated;
is(mutations.length, 2, "2 mutations");
yield uiUpdate;
};

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

@ -107,8 +107,7 @@ function removeTab(aTab, aWindow) {
let targetWindow = aWindow || window;
let targetBrowser = targetWindow.gBrowser;
// browser_net_pane-toggle.js relies on synchronous removeTab behavior.
targetBrowser.removeTab(aTab, {skipPermitUnload: true});
targetBrowser.removeTab(aTab);
}
function waitForNavigation(aTarget) {

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

@ -14,7 +14,6 @@
"use strict";
const {cssTokenizer} = require("devtools/client/sourceeditor/css-tokenizer");
const {Cc, Ci, Cu} = require("chrome");
Cu.importGlobalProperties(["CSS"]);
const promise = require("promise");
@ -43,6 +42,85 @@ const BLANK_LINE_RX = /^[ \t]*(?:\r\n|\n|\r|\f|$)/;
// bypass the property name validity heuristic.
const COMMENT_PARSING_HEURISTIC_BYPASS_CHAR = "!";
/**
* A generator function that lexes a CSS source string, yielding the
* CSS tokens. Comment tokens are dropped.
*
* @param {String} CSS source string
* @yield {CSSToken} The next CSSToken that is lexed
* @see CSSToken for details about the returned tokens
*/
function* cssTokenizer(string) {
let lexer = DOMUtils.getCSSLexer(string);
while (true) {
let token = lexer.nextToken();
if (!token) {
break;
}
// None of the existing consumers want comments.
if (token.tokenType !== "comment") {
yield token;
}
}
}
/**
* Pass |string| to the CSS lexer and return an array of all the
* returned tokens. Comment tokens are not included. In addition to
* the usual information, each token will have starting and ending
* line and column information attached. Specifically, each token
* has an additional "loc" attribute. This attribute is an object
* of the form {line: L, column: C}. Lines and columns are both zero
* based.
*
* It's best not to add new uses of this function. In general it is
* simpler and better to use the CSSToken offsets, rather than line
* and column. Also, this function lexes the entire input string at
* once, rather than lazily yielding a token stream. Use
* |cssTokenizer| or |DOMUtils.getCSSLexer| instead.
*
* @param{String} string The input string.
* @return {Array} An array of tokens (@see CSSToken) that have
* line and column information.
*/
function cssTokenizerWithLineColumn(string) {
let lexer = DOMUtils.getCSSLexer(string);
let result = [];
let prevToken = undefined;
while (true) {
let token = lexer.nextToken();
let lineNumber = lexer.lineNumber;
let columnNumber = lexer.columnNumber;
if (prevToken) {
prevToken.loc.end = {
line: lineNumber,
column: columnNumber
};
}
if (!token) {
break;
}
if (token.tokenType === "comment") {
// We've already dealt with the previous token's location.
prevToken = undefined;
} else {
let startLoc = {
line: lineNumber,
column: columnNumber
};
token.loc = {start: startLoc};
result.push(token);
prevToken = token;
}
}
return result;
}
/**
* Escape a comment body. Find the comment start and end strings in a
* string and inserts backslashes so that the resulting text can
@ -992,6 +1070,8 @@ function parseSingleValue(value) {
};
}
exports.cssTokenizer = cssTokenizer;
exports.cssTokenizerWithLineColumn = cssTokenizerWithLineColumn;
exports.escapeCSSComment = escapeCSSComment;
// unescapeCSSComment is exported for testing.
exports._unescapeCSSComment = unescapeCSSComment;

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

@ -17,6 +17,7 @@ DevToolsModules(
'AppCacheUtils.jsm',
'autocomplete-popup.js',
'browser-loader.js',
'css-parsing-utils.js',
'Curl.jsm',
'DeveloperToolbar.jsm',
'devices.js',

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

@ -8,7 +8,7 @@
var Cu = Components.utils;
Cu.import("resource://gre/modules/devtools/Loader.jsm");
const {escapeCSSComment, _unescapeCSSComment} =
devtools.require("devtools/client/styleinspector/css-parsing-utils");
devtools.require("devtools/client/shared/css-parsing-utils");
const TEST_DATA = [
{

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

@ -6,9 +6,9 @@
"use strict";
var Cu = Components.utils;
const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
const {require} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const {parseDeclarations, _parseCommentDeclarations} =
require("devtools/client/styleinspector/css-parsing-utils");
require("devtools/client/shared/css-parsing-utils");
const TEST_DATA = [
// Simple test

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

@ -6,13 +6,13 @@
"use strict";
var Cu = Components.utils;
const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
const {require} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const {
parsePseudoClassesAndAttributes,
SELECTOR_ATTRIBUTE,
SELECTOR_ELEMENT,
SELECTOR_PSEUDO_CLASS
} = require("devtools/client/styleinspector/css-parsing-utils");
} = require("devtools/client/shared/css-parsing-utils");
const TEST_DATA = [
// Test that a null input throws an exception

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

@ -6,8 +6,8 @@
"use strict";
var Cu = Components.utils;
const {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
const {parseSingleValue} = require("devtools/client/styleinspector/css-parsing-utils");
const {require} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const {parseSingleValue} = require("devtools/client/shared/css-parsing-utils");
const TEST_DATA = [
{input: null, throws: true},

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

@ -8,7 +8,7 @@
var Cu = Components.utils;
Cu.import("resource://gre/modules/devtools/Loader.jsm");
const {parseDeclarations, RuleRewriter} =
devtools.require("devtools/client/styleinspector/css-parsing-utils");
devtools.require("devtools/client/shared/css-parsing-utils");
const TEST_DATA = [
{

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

@ -10,6 +10,11 @@ skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_attribute-parsing-02.js]
[test_bezierCanvas.js]
[test_cubicBezier.js]
[test_escapeCSSComment.js]
[test_parseDeclarations.js]
[test_parsePseudoClassesAndAttributes.js]
[test_parseSingleValue.js]
[test_rewriteDeclarations.js]
[test_undoStack.js]
[test_VariablesView_filtering-without-controller.js]
[test_VariablesView_getString_promise.js]

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

@ -14,12 +14,13 @@ const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
loader.lazyRequireGetter(this, "Services");
loader.lazyImporter(this, "gDevTools", "resource:///modules/devtools/client/framework/gDevTools.jsm");
const themeURIs = {
light: "chrome://devtools/skin/themes/light-theme.css",
dark: "chrome://devtools/skin/themes/dark-theme.css"
const VARIABLES_URI = "chrome://devtools/skin/themes/variables.css";
const THEME_SELECTOR_STRINGS = {
light: ":root.theme-light {",
dark: ":root.theme-dark {"
}
const cachedThemes = {};
let variableFileContents;
/**
* Returns a string of the file found at URI
@ -37,19 +38,29 @@ function readURI (uri) {
}
/**
* Takes a theme name and either returns it from the cache,
* or fetches the theme CSS file and caches it.
* Takes a theme name and returns the contents of its variable rule block.
* The first time this runs fetches the variables CSS file and caches it.
*/
function getThemeFile (name) {
// Use the cached theme, or generate it
let themeFile = cachedThemes[name] || readURI(themeURIs[name]).match(/--theme-.*: .*;/g).join("\n");
// Cache if not already cached
if (!cachedThemes[name]) {
cachedThemes[name] = themeFile;
if (!variableFileContents) {
variableFileContents = readURI(VARIABLES_URI);
}
return themeFile;
// If there's no theme expected for this name, use `light` as default.
let selector = THEME_SELECTOR_STRINGS[name] ||
THEME_SELECTOR_STRINGS["light"];
// This is a pretty naive way to find the contents between:
// selector {
// name: val;
// }
// There is test coverage for this feature (browser_theme.js)
// so if an } is introduced in the variables file it will catch that.
let theme = variableFileContents;
theme = theme.substring(theme.indexOf(selector));
theme = theme.substring(0, theme.indexOf("}"));
return theme;
}
/**
@ -66,17 +77,11 @@ const getTheme = exports.getTheme = () => Services.prefs.getCharPref("devtools.t
*/
const getColor = exports.getColor = (type, theme) => {
let themeName = theme || getTheme();
// If there's no theme URIs for this theme, use `light` as default.
if (!themeURIs[themeName]) {
themeName = "light";
}
let themeFile = getThemeFile(themeName);
let match;
let match = themeFile.match(new RegExp("--theme-" + type + ": (.*);"));
// Return the appropriate variable in the theme, or otherwise, null.
return (match = themeFile.match(new RegExp("--theme-" + type + ": (.*);"))) ? match[1] : null;
return match ? match[1] : null;
};
/**

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

@ -14,7 +14,7 @@ const { Cu } = require("chrome");
const { ViewHelpers } = Cu.import("resource:///modules/devtools/client/shared/widgets/ViewHelpers.jsm", {});
const STRINGS_URI = "chrome://browser/locale/devtools/filterwidget.properties";
const L10N = new ViewHelpers.L10N(STRINGS_URI);
const {cssTokenizer} = require("devtools/client/sourceeditor/css-tokenizer");
const {cssTokenizer} = require("devtools/client/shared/css-parsing-utils");
loader.lazyGetter(this, "asyncStorage",
() => require("devtools/shared/shared/async-storage"));

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

@ -4,10 +4,10 @@
const { Cc, Ci, Cu } = require('chrome');
const {cssTokenizer, cssTokenizerWithLineColumn} =
require("devtools/client/sourceeditor/css-tokenizer");
require("devtools/client/shared/css-parsing-utils");
/**
* Here is what this file (+ ./css-tokenizer.js) do.
* Here is what this file (+ css-parsing-utils.js) do.
*
* The main objective here is to provide as much suggestions to the user editing
* a stylesheet in Style Editor. The possible things that can be suggested are:
@ -22,7 +22,7 @@ const {cssTokenizer, cssTokenizerWithLineColumn} =
* edited by the user, figure out what token or word is being written and last
* but the most difficult, what is being edited.
*
* The file 'css-tokenizer' helps in converting the CSS into meaningful tokens,
* The file 'css-parsing-utils' helps to convert the CSS into meaningful tokens,
* each having a certain type associated with it. These tokens help us to figure
* out the currently edited word and to write a CSS state machine to figure out
* what the user is currently editing. By that, I mean, whether he is editing a

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

@ -1,95 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {Cc, Ci} = require("chrome");
loader.lazyGetter(this, "DOMUtils", () => {
return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
});
/**
* A generator function that lexes a CSS source string, yielding the
* CSS tokens. Comment tokens are dropped.
*
* @param {String} CSS source string
* @yield {CSSToken} The next CSSToken that is lexed
* @see CSSToken for details about the returned tokens
*/
function* cssTokenizer(string) {
let lexer = DOMUtils.getCSSLexer(string);
while (true) {
let token = lexer.nextToken();
if (!token) {
break;
}
// None of the existing consumers want comments.
if (token.tokenType !== "comment") {
yield token;
}
}
}
exports.cssTokenizer = cssTokenizer;
/**
* Pass |string| to the CSS lexer and return an array of all the
* returned tokens. Comment tokens are not included. In addition to
* the usual information, each token will have starting and ending
* line and column information attached. Specifically, each token
* has an additional "loc" attribute. This attribute is an object
* of the form {line: L, column: C}. Lines and columns are both zero
* based.
*
* It's best not to add new uses of this function. In general it is
* simpler and better to use the CSSToken offsets, rather than line
* and column. Also, this function lexes the entire input string at
* once, rather than lazily yielding a token stream. Use
* |cssTokenizer| or |DOMUtils.getCSSLexer| instead.
*
* @param{String} string The input string.
* @return {Array} An array of tokens (@see CSSToken) that have
* line and column information.
*/
function cssTokenizerWithLineColumn(string) {
let lexer = DOMUtils.getCSSLexer(string);
let result = [];
let prevToken = undefined;
while (true) {
let token = lexer.nextToken();
let lineNumber = lexer.lineNumber;
let columnNumber = lexer.columnNumber;
if (prevToken) {
prevToken.loc.end = {
line: lineNumber,
column: columnNumber
};
}
if (!token) {
break;
}
if (token.tokenType === "comment") {
// We've already dealt with the previous token's location.
prevToken = undefined;
} else {
let startLoc = {
line: lineNumber,
column: columnNumber
};
token.loc = {start: startLoc};
result.push(token);
prevToken = token;
}
}
return result;
}
exports.cssTokenizerWithLineColumn = cssTokenizerWithLineColumn;

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

@ -7,7 +7,6 @@
DevToolsModules(
'autocomplete.js',
'css-autocompleter.js',
'css-tokenizer.js',
'debugger.js',
'editor.js'
)

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

@ -28,8 +28,8 @@ function runCodeMirrorTest(browser) {
'function check() { ' +
' var doc = content.document; var out = doc.getElementById("status"); ' +
' if (!out || !out.classList.contains("done")) { return setTimeout(check, 100); }' +
' sendAsyncMessage("done", { failed: content.wrappedJSObject.failed });' +
' sendSyncMessage("done", { failed: content.wrappedJSObject.failed });' +
'}' +
'check();'
, true);
}
}

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

@ -5,11 +5,9 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
DevToolsModules(
'computed-view.js',
'css-parsing-utils.js',
'rule-view.js',
'style-inspector-menu.js',
'style-inspector-overlays.js',

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

@ -33,7 +33,7 @@ const {
SELECTOR_ATTRIBUTE,
SELECTOR_ELEMENT,
SELECTOR_PSEUDO_CLASS
} = require("devtools/client/styleinspector/css-parsing-utils");
} = require("devtools/client/shared/css-parsing-utils");
loader.lazyRequireGetter(this, "overlays",
"devtools/client/styleinspector/style-inspector-overlays");
loader.lazyRequireGetter(this, "EventEmitter",

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

@ -1,4 +0,0 @@
{
// Extend from the common devtools xpcshell eslintrc config.
"extends": "../../../../.eslintrc.xpcshell"
}

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

@ -1,12 +0,0 @@
[DEFAULT]
tags = devtools
head =
tail =
firefox-appdir = browser
skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_escapeCSSComment.js]
[test_parseDeclarations.js]
[test_parsePseudoClassesAndAttributes.js]
[test_parseSingleValue.js]
[test_rewriteDeclarations.js]

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

@ -10,7 +10,7 @@ const {Cc, Ci, Cu} = require("chrome");
const {setTimeout, clearTimeout} =
Cu.import("resource://gre/modules/Timer.jsm", {});
const {parseDeclarations} =
require("devtools/client/styleinspector/css-parsing-utils");
require("devtools/client/shared/css-parsing-utils");
const promise = require("promise");
loader.lazyServiceGetter(this, "domUtils",

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

@ -3,47 +3,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Colors are taken from:
* https://developer.mozilla.org/en-US/docs/Tools/DevToolsColors.
* Changes should be kept in sync with commandline.css and commandline.inc.css.
*/
:root {
--theme-body-background: #14171a;
--theme-sidebar-background: #181d20;
--theme-contrast-background: #b28025;
--theme-tab-toolbar-background: #252c33;
--theme-toolbar-background: #343c45;
--theme-selection-background: #1d4f73;
--theme-selection-background-semitransparent: rgba(29, 79, 115, .5);
--theme-selection-color: #f5f7fa;
--theme-splitter-color: black;
--theme-comment: #757873;
--theme-body-color: #8fa1b2;
--theme-body-color-alt: #b6babf;
--theme-content-color1: #a9bacb;
--theme-content-color2: #8fa1b2;
--theme-content-color3: #5f7387;
--theme-highlight-green: #70bf53;
--theme-highlight-blue: #46afe3;
--theme-highlight-bluegrey: #5e88b0;
--theme-highlight-purple: #6b7abb;
--theme-highlight-lightorange: #d99b28;
--theme-highlight-orange: #d96629;
--theme-highlight-red: #eb5368;
--theme-highlight-pink: #df80ff;
/* Colors used in Graphs, like performance tools. Mostly similar to some "highlight-*" colors. */
--theme-graphs-green: #70bf53;
--theme-graphs-blue: #46afe3;
--theme-graphs-bluegrey: #5e88b0;
--theme-graphs-purple: #df80ff;
--theme-graphs-yellow: #d99b28;
--theme-graphs-red: #eb5368;
--theme-graphs-grey: #757873;
}
@import url(variables.css);
.theme-body {
background: var(--theme-body-background);

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

@ -3,47 +3,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Colors are taken from:
* https://developer.mozilla.org/en-US/docs/Tools/DevToolsColors.
* Changes should be kept in sync with commandline.css and commandline.inc.css.
*/
:root {
--theme-body-background: #fcfcfc;
--theme-sidebar-background: #f7f7f7;
--theme-contrast-background: #e6b064;
--theme-tab-toolbar-background: #ebeced;
--theme-toolbar-background: #f0f1f2;
--theme-selection-background: #4c9ed9;
--theme-selection-background-semitransparent: rgba(76, 158, 217, .23);
--theme-selection-color: #f5f7fa;
--theme-splitter-color: #aaaaaa;
--theme-comment: #757873;
--theme-body-color: #18191a;
--theme-body-color-alt: #585959;
--theme-content-color1: #292e33;
--theme-content-color2: #8fa1b2;
--theme-content-color3: #667380;
--theme-highlight-green: #2cbb0f;
--theme-highlight-blue: #0088cc;
--theme-highlight-bluegrey: #0072ab;
--theme-highlight-purple: #5b5fff;
--theme-highlight-lightorange: #d97e00;
--theme-highlight-orange: #f13c00;
--theme-highlight-red: #ed2655;
--theme-highlight-pink: #b82ee5;
/* Colors used in Graphs, like performance tools. Similar colors to Chrome's timeline. */
--theme-graphs-green: #85d175;
--theme-graphs-blue: #83b7f6;
--theme-graphs-bluegrey: #0072ab;
--theme-graphs-purple: #b693eb;
--theme-graphs-yellow: #efc052;
--theme-graphs-red: #e57180;
--theme-graphs-grey: #cccccc;
}
@import url(variables.css);
.theme-body {
background: var(--theme-body-background);

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

@ -0,0 +1,91 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Variable declarations for light and dark devtools themes.
* Colors are taken from:
* https://developer.mozilla.org/en-US/docs/Tools/DevToolsColors.
* Changes should be kept in sync with commandline.css and commandline.inc.css.
*/
/* IMPORTANT NOTE:
* This file is parsed in js (see client/shared/theme.js)
* so the formatting should be consistent (i.e. no '}' inside a rule).
*/
:root.theme-light {
--theme-body-background: #fcfcfc;
--theme-sidebar-background: #f7f7f7;
--theme-contrast-background: #e6b064;
--theme-tab-toolbar-background: #ebeced;
--theme-toolbar-background: #f0f1f2;
--theme-selection-background: #4c9ed9;
--theme-selection-background-semitransparent: rgba(76, 158, 217, .23);
--theme-selection-color: #f5f7fa;
--theme-splitter-color: #aaaaaa;
--theme-comment: #757873;
--theme-body-color: #18191a;
--theme-body-color-alt: #585959;
--theme-content-color1: #292e33;
--theme-content-color2: #8fa1b2;
--theme-content-color3: #667380;
--theme-highlight-green: #2cbb0f;
--theme-highlight-blue: #0088cc;
--theme-highlight-bluegrey: #0072ab;
--theme-highlight-purple: #5b5fff;
--theme-highlight-lightorange: #d97e00;
--theme-highlight-orange: #f13c00;
--theme-highlight-red: #ed2655;
--theme-highlight-pink: #b82ee5;
/* Colors used in Graphs, like performance tools. Similar colors to Chrome's timeline. */
--theme-graphs-green: #85d175;
--theme-graphs-blue: #83b7f6;
--theme-graphs-bluegrey: #0072ab;
--theme-graphs-purple: #b693eb;
--theme-graphs-yellow: #efc052;
--theme-graphs-red: #e57180;
--theme-graphs-grey: #cccccc;
}
:root.theme-dark {
--theme-body-background: #14171a;
--theme-sidebar-background: #181d20;
--theme-contrast-background: #b28025;
--theme-tab-toolbar-background: #252c33;
--theme-toolbar-background: #343c45;
--theme-selection-background: #1d4f73;
--theme-selection-background-semitransparent: rgba(29, 79, 115, .5);
--theme-selection-color: #f5f7fa;
--theme-splitter-color: black;
--theme-comment: #757873;
--theme-body-color: #8fa1b2;
--theme-body-color-alt: #b6babf;
--theme-content-color1: #a9bacb;
--theme-content-color2: #8fa1b2;
--theme-content-color3: #5f7387;
--theme-highlight-green: #70bf53;
--theme-highlight-blue: #46afe3;
--theme-highlight-bluegrey: #5e88b0;
--theme-highlight-purple: #6b7abb;
--theme-highlight-lightorange: #d99b28;
--theme-highlight-orange: #d96629;
--theme-highlight-red: #eb5368;
--theme-highlight-pink: #df80ff;
/* Colors used in Graphs, like performance tools. Mostly similar to some "highlight-*" colors. */
--theme-graphs-green: #70bf53;
--theme-graphs-blue: #46afe3;
--theme-graphs-bluegrey: #5e88b0;
--theme-graphs-purple: #df80ff;
--theme-graphs-yellow: #d99b28;
--theme-graphs-red: #eb5368;
--theme-graphs-grey: #757873;
}

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

@ -2662,7 +2662,23 @@ var WalkerActor = protocol.ActorClass({
return null;
}
parent.rawNode.insertBefore(node.rawNode, sibling ? sibling.rawNode : null);
let rawNode = node.rawNode;
let rawParent = parent.rawNode;
let rawSibling = sibling ? sibling.rawNode : null;
// Don't bother inserting a node if the document position isn't going
// to change. This prevents needless iframes reloading and mutations.
if (rawNode.parentNode === rawParent) {
let currentNextSibling = this.nextSibling(node);
currentNextSibling = currentNextSibling ? currentNextSibling.rawNode :
null;
if (rawNode === rawSibling || currentNextSibling === rawSibling) {
return;
}
}
rawParent.insertBefore(rawNode, rawSibling);
}, {
request: {
node: Arg(0, "domnode"),

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

@ -26,7 +26,7 @@ loader.lazyGetter(this, "DOMUtils", () => {
});
loader.lazyGetter(this, "RuleRewriter", () => {
return require("devtools/client/styleinspector/css-parsing-utils").RuleRewriter;
return require("devtools/client/shared/css-parsing-utils").RuleRewriter;
});
// The PageStyle actor flattens the DOM CSS objects a little bit, merging

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

@ -39,36 +39,63 @@ addTest(function setup() {
});
});
addTest(function testRearrange() {
let longlist = null;
let nodeA = null;
let nextNode = null;
addAsyncTest(function* testRearrange() {
let longlist = yield gWalker.querySelector(gWalker.rootNode, "#longlist");
let children = yield gWalker.children(longlist);
let nodeA = children.nodes[0];
is(nodeA.id, "a", "Got the expected node.");
promiseDone(gWalker.querySelector(gWalker.rootNode, "#longlist").then(listFront => {
longlist = listFront;
}).then(() => {
return gWalker.children(longlist);
}).then(response => {
nodeA = response.nodes[0];
is(nodeA.id, "a", "Got the expected node.");
// Move nodeA to the end of the list.
return gWalker.insertBefore(nodeA, longlist, null);
}).then(() => {
ok(!gInspectee.querySelector("#a").nextSibling, "a should now be at the end of the list.");
return gWalker.children(longlist);
}).then(response => {
is(nodeA, response.nodes[response.nodes.length - 1], "a should now be the last returned child.");
// Now move it to the middle of the list.
nextNode = response.nodes[13];
return gWalker.insertBefore(nodeA, longlist, nextNode);
}).then(response => {
let sibling = new inspector._documentWalker(gInspectee.querySelector("#a"), window).nextSibling();
is(sibling, nextNode.rawNode(), "Node should match the expected next node.");
return gWalker.children(longlist);
}).then(response => {
is(nodeA, response.nodes[13], "a should be where we expect it.");
is(nextNode, response.nodes[14], "next node should be where we expect it.");
}).then(runNextTest));
// Move nodeA to the end of the list.
yield gWalker.insertBefore(nodeA, longlist, null);
ok(!gInspectee.querySelector("#a").nextSibling, "a should now be at the end of the list.");
children = yield gWalker.children(longlist);
is(nodeA, children.nodes[children.nodes.length - 1], "a should now be the last returned child.");
// Now move it to the middle of the list.
let nextNode = children.nodes[13];
yield gWalker.insertBefore(nodeA, longlist, nextNode);
let sibling =
new inspector._documentWalker(gInspectee.querySelector("#a"), window).nextSibling();
is(sibling, nextNode.rawNode(), "Node should match the expected next node.");
children = yield gWalker.children(longlist);
is(nodeA, children.nodes[13], "a should be where we expect it.");
is(nextNode, children.nodes[14], "next node should be where we expect it.");
runNextTest();
});
addAsyncTest(function* testInsertInvalidInput() {
let longlist = yield gWalker.querySelector(gWalker.rootNode, "#longlist");
let children = yield gWalker.children(longlist);
let nodeA = children.nodes[0];
let nextSibling = children.nodes[1];
// Now move it to the original location and make sure no mutation happens.
let hasMutated = false;
let observer = new gInspectee.defaultView.MutationObserver(() => {
hasMutated = true;
});
observer.observe(longlist.rawNode(), {
childList: true,
});
yield gWalker.insertBefore(nodeA, longlist, nodeA);
ok(!hasMutated, "hasn't mutated");
hasMutated = false;
yield gWalker.insertBefore(nodeA, longlist, nextSibling);
ok(!hasMutated, "still hasn't mutated after inserting before nextSibling");
hasMutated = false;
yield gWalker.insertBefore(nodeA, longlist);
ok(hasMutated, "has mutated after inserting with null sibling");
hasMutated = false;
yield gWalker.insertBefore(nodeA, longlist);
ok(!hasMutated, "hasn't mutated after inserting with null sibling again");
observer.disconnect();
runNextTest();
});
addTest(function cleanup() {
@ -77,7 +104,6 @@ addTest(function cleanup() {
runNextTest();
});
</script>
</head>
<body>

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

@ -5004,6 +5004,7 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
case NS_ERROR_CLIENT_REQUEST_OPAQUE_INTERCEPTION:
case NS_ERROR_BAD_OPAQUE_REDIRECT_INTERCEPTION:
case NS_ERROR_INTERCEPTION_CANCELED:
case NS_ERROR_REJECTED_RESPONSE_INTERCEPTION:
// ServiceWorker intercepted request, but something went wrong.
nsContentUtils::MaybeReportInterceptionErrorToConsole(GetDocument(),
aError);
@ -7669,6 +7670,7 @@ nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
aStatus == NS_ERROR_INTERCEPTED_USED_RESPONSE ||
aStatus == NS_ERROR_CLIENT_REQUEST_OPAQUE_INTERCEPTION ||
aStatus == NS_ERROR_INTERCEPTION_CANCELED ||
aStatus == NS_ERROR_REJECTED_RESPONSE_INTERCEPTION ||
NS_ERROR_GET_MODULE(aStatus) == NS_ERROR_MODULE_SECURITY) {
// Errors to be shown for any frame
DisplayLoadError(aStatus, url, nullptr, aChannel);
@ -7772,7 +7774,7 @@ nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal,
mTiming->NotifyBeforeUnload();
bool okToUnload;
rv = mContentViewer->PermitUnload(&okToUnload);
rv = mContentViewer->PermitUnload(false, &okToUnload);
if (NS_SUCCEEDED(rv) && !okToUnload) {
// The user chose not to unload the page, interrupt the load.
@ -10111,7 +10113,7 @@ nsDocShell::InternalLoad(nsIURI* aURI,
// protocol handler deals with this for javascript: URLs.
if (!isJavaScript && aFileName.IsVoid() && mContentViewer) {
bool okToUnload;
rv = mContentViewer->PermitUnload(&okToUnload);
rv = mContentViewer->PermitUnload(false, &okToUnload);
if (NS_SUCCEEDED(rv) && !okToUnload) {
// The user chose not to unload the page, interrupt the

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

@ -31,7 +31,7 @@ class nsDOMNavigationTiming;
[ptr] native nsDOMNavigationTimingPtr(nsDOMNavigationTiming);
[ref] native nsIContentViewerTArray(nsTArray<nsCOMPtr<nsIContentViewer> >);
[scriptable, builtinclass, uuid(91b6c1f3-fc5f-43a9-88f4-9286bd19387f)]
[scriptable, builtinclass, uuid(702e0a92-7d63-490e-b5ee-d247e6bd4588)]
interface nsIContentViewer : nsISupports
{
@ -46,8 +46,12 @@ interface nsIContentViewer : nsISupports
/**
* Checks if the document wants to prevent unloading by firing beforeunload on
* the document, and if it does, prompts the user. The result is returned.
*
* @param aCallerClosesWindow indicates that the current caller will close the
* window. If the method returns true, all subsequent calls will be
* ignored.
*/
boolean permitUnload();
boolean permitUnload([optional] in boolean aCallerClosesWindow);
/**
* Exposes whether we're blocked in a call to permitUnload.
@ -59,7 +63,8 @@ interface nsIContentViewer : nsISupports
* track of whether the user has responded to a prompt.
* Used internally by the scriptable version to ensure we only prompt once.
*/
[noscript,nostdcall] boolean permitUnloadInternal(inout boolean aShouldPrompt);
[noscript,nostdcall] boolean permitUnloadInternal(in boolean aCallerClosesWindow,
inout boolean aShouldPrompt);
/**
* Exposes whether we're in the process of firing the beforeunload event.
@ -67,6 +72,16 @@ interface nsIContentViewer : nsISupports
*/
readonly attribute boolean beforeUnloadFiring;
/**
* Works in tandem with permitUnload, if the caller decides not to close the
* window it indicated it will, it is the caller's responsibility to reset
* that with this method.
*
* @Note this method is only meant to be called on documents for which the
* caller has indicated that it will close the window. If that is not the case
* the behavior of this method is undefined.
*/
void resetCloseWindow();
void pageHide(in boolean isUnload);
/**

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

@ -103,6 +103,7 @@ skip-if = e10s
skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
[browser_multiple_pushState.js]
[browser_onbeforeunload_navigation.js]
skip-if = e10s
[browser_search_notification.js]
[browser_timelineMarkers-01.js]
[browser_timelineMarkers-02.js]

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

@ -10,7 +10,6 @@ SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunlo
var loadExpected = TEST_PAGE;
var testTab;
var testsLength;
var loadStarted = false;
var tabStateListener = {
@ -41,10 +40,6 @@ function onTabLoaded(event) {
return;
}
if (!testsLength) {
testsLength = testTab.linkedBrowser.contentWindow.wrappedJSObject.testFns.length;
}
is(loadedPage, loadExpected, "Loaded the expected page");
if (contentWindow) {
is(contentWindow.document, event.target, "Same doc");
@ -107,9 +102,47 @@ function onTabModalDialogLoaded(node) {
// Listen for the dialog being created
Services.obs.addObserver(onTabModalDialogLoaded, "tabmodal-dialog-loaded", false);
var testFns = [
function(e) {
e.target.location.href = 'otherpage-href-set.html';
return "stop";
},
function(e) {
e.target.location.reload();
return "stop";
},
function(e) {
e.target.location.replace('otherpage-location-replaced.html');
return "stop";
},
function(e) {
var link = e.target.createElement('a');
link.href = "otherpage.html";
e.target.body.appendChild(link);
link.click();
return "stop";
},
function(e) {
var link = e.target.createElement('a');
link.href = "otherpage.html";
link.setAttribute("target", "_blank");
e.target.body.appendChild(link);
link.click();
return "stop";
},
function(e) {
var link = e.target.createElement('a');
link.href = e.target.location.href;
e.target.body.appendChild(link);
link.setAttribute("target", "somearbitrarywindow");
link.click();
return "stop";
},
];
function runNextTest() {
currentTest++;
if (currentTest >= testsLength) {
if (currentTest >= testFns.length) {
if (!stayingOnPage) {
finish();
return;
@ -138,10 +171,10 @@ function runCurrentTest() {
contentWindow.dialogWasInvoked = false;
originalLocation = contentWindow.location.href;
// And run this test:
info("Running test with onbeforeunload " + contentWindow.wrappedJSObject.testFns[currentTest].toSource());
contentWindow.onbeforeunload = contentWindow.wrappedJSObject.testFns[currentTest];
info("Running test with onbeforeunload " + testFns[currentTest].toSource());
contentWindow.onbeforeunload = testFns[currentTest];
loadStarted = false;
testTab.linkedBrowser.loadURI(TARGETED_PAGE);
contentWindow.location.href = TARGETED_PAGE;
}
var onAfterPageLoad = runNextTest;

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

@ -7,44 +7,4 @@
<body>
Waiting for onbeforeunload to hit...
</body>
<script>
var testFns = [
function(e) {
e.target.location.href = 'otherpage-href-set.html';
return "stop";
},
function(e) {
e.target.location.reload();
return "stop";
},
function(e) {
e.target.location.replace('otherpage-location-replaced.html');
return "stop";
},
function(e) {
var link = e.target.createElement('a');
link.href = "otherpage.html";
e.target.body.appendChild(link);
link.click();
return "stop";
},
function(e) {
var link = e.target.createElement('a');
link.href = "otherpage.html";
link.setAttribute("target", "_blank");
e.target.body.appendChild(link);
link.click();
return "stop";
},
function(e) {
var link = e.target.createElement('a');
link.href = e.target.location.href;
e.target.body.appendChild(link);
link.setAttribute("target", "somearbitrarywindow");
link.click();
return "stop";
},
];
</script>
</html>

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

@ -31,8 +31,8 @@ function makeTimelineTest(frameScriptName, url) {
info(message.data.message);
});
mm.addMessageListener("browser:test:finish", function(ignore) {
gBrowser.removeCurrentTab();
finish();
gBrowser.removeCurrentTab();
});
});
}

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

@ -37,6 +37,7 @@ AudioChannelAgent::AudioChannelAgent()
: mAudioChannelType(AUDIO_AGENT_CHANNEL_ERROR)
, mInnerWindowID(0)
, mIsRegToService(false)
, mNotifyPlayback(false)
{
}
@ -49,7 +50,7 @@ void
AudioChannelAgent::Shutdown()
{
if (mIsRegToService) {
NotifyStoppedPlaying(nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY);
NotifyStoppedPlaying();
}
}
@ -162,11 +163,12 @@ NS_IMETHODIMP AudioChannelAgent::NotifyStartedPlaying(uint32_t aNotifyPlayback,
service->GetState(mWindow, mAudioChannelType, aVolume, aMuted);
mNotifyPlayback = aNotifyPlayback;
mIsRegToService = true;
return NS_OK;
}
NS_IMETHODIMP AudioChannelAgent::NotifyStoppedPlaying(uint32_t aNotifyPlayback)
NS_IMETHODIMP AudioChannelAgent::NotifyStoppedPlaying()
{
if (mAudioChannelType == AUDIO_AGENT_CHANNEL_ERROR ||
!mIsRegToService) {
@ -174,7 +176,7 @@ NS_IMETHODIMP AudioChannelAgent::NotifyStoppedPlaying(uint32_t aNotifyPlayback)
}
nsRefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
service->UnregisterAudioChannelAgent(this, aNotifyPlayback);
service->UnregisterAudioChannelAgent(this, mNotifyPlayback);
mIsRegToService = false;
return NS_OK;
}

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