Merge mozilla-central to UX

This commit is contained in:
Matthew Noorenberghe 2013-09-12 01:39:29 -07:00
commit 3df5c32616
1227 changed files with 14674 additions and 6917 deletions

View File

@ -18,4 +18,4 @@
# Modifying this file will now automatically clobber the buildbot machines \o/
#
Bug 912832 - Inverse tiers and subtiers for build traversal
Bug 785884 - Implement support for temporary storage (aka shared pool)

View File

@ -481,6 +481,7 @@ public:
bool IsHyperText() const { return HasGenericType(eHyperText); }
HyperTextAccessible* AsHyperText();
bool IsHTMLBr() const { return mType == eHTMLBRType; }
bool IsHTMLFileInput() const { return mType == eHTMLFileInputType; }
bool IsHTMLListItem() const { return mType == eHTMLLiType; }

View File

@ -13,6 +13,7 @@
#include "Role.h"
#include "States.h"
#include "TextAttrs.h"
#include "TreeWalker.h"
#include "nsIClipboard.h"
#include "nsContentUtils.h"
@ -2062,6 +2063,31 @@ HyperTextAccessible::RemoveChild(Accessible* aAccessible)
return Accessible::RemoveChild(aAccessible);
}
void
HyperTextAccessible::CacheChildren()
{
// Trailing HTML br element don't play any difference. We don't need to expose
// it to AT (see bug https://bugzilla.mozilla.org/show_bug.cgi?id=899433#c16
// for details).
TreeWalker walker(this, mContent);
Accessible* child = nullptr;
Accessible* lastChild = nullptr;
while ((child = walker.NextChild())) {
if (lastChild)
AppendChild(lastChild);
lastChild = child;
}
if (lastChild) {
if (lastChild->IsHTMLBr())
Document()->UnbindFromDocument(lastChild);
else
AppendChild(lastChild);
}
}
////////////////////////////////////////////////////////////////////////////////
// HyperTextAccessible public static

View File

@ -273,6 +273,7 @@ public:
protected:
// Accessible
virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
virtual void CacheChildren() MOZ_OVERRIDE;
// HyperTextAccessible

View File

@ -33,7 +33,10 @@ class HTMLBRAccessible : public LeafAccessible
{
public:
HTMLBRAccessible(nsIContent* aContent, DocAccessible* aDoc) :
LeafAccessible(aContent, aDoc) {}
LeafAccessible(aContent, aDoc)
{
mType = eHTMLBRType;
}
// Accessible
virtual a11y::role NativeRole();

View File

@ -464,22 +464,6 @@ HTMLTextFieldAccessible::GetEditor() const
return editor.forget();
}
void
HTMLTextFieldAccessible::CacheChildren()
{
// XXX: textarea shouldn't contain anything but text leafs. Currently it may
// contain a trailing fake HTML br element added for layout needs. We don't
// need to expose it since it'd be confusing for AT.
TreeWalker walker(this, mContent);
Accessible* child = nullptr;
while ((child = walker.NextChild())) {
if (child->IsTextLeaf())
AppendChild(child);
else
Document()->UnbindFromDocument(child);
}
}
////////////////////////////////////////////////////////////////////////////////
// HTMLTextFieldAccessible: Widgets

View File

@ -142,8 +142,6 @@ public:
protected:
// Accessible
virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
virtual void CacheChildren() MOZ_OVERRIDE;
};

View File

@ -70,7 +70,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=452161
var testRun = new editableTextTestRun();
addTestEditable("input", testRun);
addTestEditable("div", testRun, '\n');
addTestEditable("div", testRun);
addTestEditable(getNode("frame").contentDocument, testRun, '\n');
testRun.run(); // Will call SimpleTest.finish();

View File

@ -1298,7 +1298,8 @@
<p>This is a quotation taken from the Mozilla Developer Center.</p>
</blockquote>
<p id="br_container"><br></p>
<!-- two BRs, one will be eaten -->
<p id="br_container"><br><br></p>
<button id="button">button</button>
<form>

View File

@ -96,12 +96,12 @@
two words
</div>
<div id="dbr3">oneword<br/><br/>two words<br/></div>
<div id="dbr3">oneword<br/><br/>two words<br/><br/></div>
<div id="e3" contenteditable="true">oneword
two words
</div>
<div id="ebr3" contenteditable="true">oneword<br/><br/>two words<br/></div>
<div id="ebr3" contenteditable="true">oneword<br/><br/>two words<br/><br/></div>
<textarea id="t3" cols="300">oneword
two words

View File

@ -74,7 +74,7 @@
testCharacterCount(IDs, 5);
testText(IDs, 0, 5, "1.foo");
testText(["testbr"], 0, 4, "foo\n");
testText(["testbr"], 0, 3, "foo");
testTextAtOffset(2, nsIAccessibleText.BOUNDARY_CHAR, "o", 2, 3, "testbr",
kOk, kOk, kOk);

View File

@ -50,6 +50,7 @@
[ 8, 8, "oneword\n", 0, 8 ],
[ 9, 18, "\n", 8, 9 ],
[ 19, 19, "two words\n", 9, 19 ]]);
testTextBeforeOffset(IDs, BOUNDARY_LINE_END,
[ [ 0, 7, "", 0, 0 ],
[ 8, 8, "oneword", 0, 7 ],
@ -96,7 +97,17 @@
testTextAfterOffset([ getAccessible("ht_1").firstChild ], BOUNDARY_LINE_END,
[ [ 0, 5, "", 5, 5 ] ]);
//////////////////////////////////////////////////////////////////////////
// foo<br> and foo<br><br>
testTextAtOffset([ getAccessible("ht_2").firstChild.firstChild ],
BOUNDARY_LINE_START,
[ [ 0, 3, "foo", 0, 3 ] ]);
testTextAtOffset([ getAccessible("ht_3").firstChild.firstChild ],
BOUNDARY_LINE_START,
[ [ 0, 3, "foo\n", 0, 4 ], [ 4, 4, "", 4, 4 ] ]);
SimpleTest.finish();
}
@ -135,16 +146,16 @@
src="data:text/html,<html><body><textarea id='ta'>hello my friend</textarea></body></html>"></iframe>
<pre>
<div id="ml_div">oneword
<div id="ml_div" style="border-style:outset;">oneword
two words
</div>
<div id="ml_divbr">oneword<br/><br/>two words<br/></div>
<div id="ml_editable" contenteditable="true">oneword
<div id="ml_divbr" style="border-style:outset;">oneword<br/><br/>two words<br/><br/></div>
<div id="ml_editable" style="border-style:outset;" contenteditable="true">oneword
two words
</div>
<div id="ml_editablebr" contenteditable="true">oneword<br/><br/>two words<br/></div>
<div id="ml_editablebr" contenteditable="true" style="border-style:outset;">oneword<br/><br/>two words<br/><br/></div>
<textarea id="ml_textarea" cols="300">oneword
two words
@ -152,5 +163,8 @@ two words
</pre>
<iframe id="ht_1" src="data:text/html,<html><body>a <a href=''>b</a> c</body></html>"></iframe>
<iframe id="ht_2" src="data:text/html,<div contentEditable='true'>foo<br/></div>"></iframe>
<iframe id="ht_3" src="data:text/html,<div contentEditable='true'>foo<br/><br/></div>"></iframe>
</body>
</html>

View File

@ -268,12 +268,12 @@
two words
</div>
<div id="ml_divbr1">oneword<br/><br/>two words<br/></div>
<div id="ml_divbr1">oneword<br/><br/>two words<br/><br/></div>
<div id="ml_ediv1" contenteditable="true">oneword
two words
</div>
<div id="ml_edivbr1" contenteditable="true">oneword<br/><br/>two words<br/></div>
<div id="ml_edivbr1" contenteditable="true">oneword<br/><br/>two words<br/><br/></div>
<textarea id="ml_t1" cols="300">oneword
two words

View File

@ -148,6 +148,9 @@ function reportMemoryUsage() {
var mgr = Cc["@mozilla.org/memory-reporter-manager;1"]
.getService(Ci.nsIMemoryReporterManager);
// XXX: this code is *so* bogus -- nsIMemoryReporter changed its |memoryUsed|
// field to |amount| *years* ago, and even bigger changes have happened
// since -- that it must just never be run.
var reporters = mgr.enumerateReporters();
if (reporters.hasMoreElements())
print("\n");
@ -376,14 +379,7 @@ function getPotentialLeaks() {
let enm = mgr.enumerateReporters();
while (enm.hasMoreElements()) {
let reporter = enm.getNext().QueryInterface(Ci.nsIMemoryReporter);
logReporter(reporter.process, reporter.path, reporter.kind, reporter.units,
reporter.amount, reporter.description);
}
let enm = mgr.enumerateMultiReporters();
while (enm.hasMoreElements()) {
let mr = enm.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
let mr = enm.getNext().QueryInterface(Ci.nsIMemoryReporter);
mr.collectReports(logReporter, null);
}

View File

@ -523,6 +523,9 @@ pref("app.update.log", true);
pref("shutdown.watchdog.timeoutSecs", -1);
#endif
// Check daily for apps updates.
pref("webapps.update.interval", 86400);
// Extensions preferences
pref("extensions.update.enabled", false);
pref("extensions.getAddons.cache.enabled", false);
@ -605,15 +608,15 @@ pref("hal.processPriorityManager.gonk.FOREGROUND.OomScoreAdjust", 134);
pref("hal.processPriorityManager.gonk.FOREGROUND.KillUnderMB", 6);
pref("hal.processPriorityManager.gonk.FOREGROUND.Nice", 1);
pref("hal.processPriorityManager.gonk.BACKGROUND_PERCEIVABLE.OomScoreAdjust", 200);
pref("hal.processPriorityManager.gonk.BACKGROUND_PERCEIVABLE.OomScoreAdjust", 400);
pref("hal.processPriorityManager.gonk.BACKGROUND_PERCEIVABLE.KillUnderMB", 7);
pref("hal.processPriorityManager.gonk.BACKGROUND_PERCEIVABLE.Nice", 7);
pref("hal.processPriorityManager.gonk.BACKGROUND_HOMESCREEN.OomScoreAdjust", 267);
pref("hal.processPriorityManager.gonk.BACKGROUND_HOMESCREEN.OomScoreAdjust", 534);
pref("hal.processPriorityManager.gonk.BACKGROUND_HOMESCREEN.KillUnderMB", 8);
pref("hal.processPriorityManager.gonk.BACKGROUND_HOMESCREEN.Nice", 18);
pref("hal.processPriorityManager.gonk.BACKGROUND.OomScoreAdjust", 400);
pref("hal.processPriorityManager.gonk.BACKGROUND.OomScoreAdjust", 667);
pref("hal.processPriorityManager.gonk.BACKGROUND.KillUnderMB", 20);
pref("hal.processPriorityManager.gonk.BACKGROUND.Nice", 18);

View File

@ -318,7 +318,7 @@ let AdbController = {
// Check if we have a remote debugging session going on. If so, we won't
// disable adb even if the screen is locked.
let isDebugging = Object.keys(DebuggerServer._connections).length > 0;
debug("isDebugging=" + isDebugging);
this.debug("isDebugging=" + isDebugging);
let enableAdb = this.remoteDebuggerEnabled &&
(!(this.lockEnabled && this.locked) || isDebugging);

View File

@ -1135,6 +1135,9 @@ window.addEventListener('ContentStart', function cr_onContentStart() {
});
window.addEventListener('ContentStart', function update_onContentStart() {
Cu.import('resource://gre/modules/WebappsUpdater.jsm');
WebappsUpdater.handleContentStart(shell);
let promptCc = Cc["@mozilla.org/updates/update-prompt;1"];
if (!promptCc) {
return;

View File

@ -73,3 +73,8 @@ contract @mozilla.org/network/protocol/about;1?what=certerror {920400b1-cf8f-476
# FilePicker.js
component {436ff8f9-0acc-4b11-8ec7-e293efba3141} FilePicker.js
contract @mozilla.org/filepicker;1 {436ff8f9-0acc-4b11-8ec7-e293efba3141}
# WebappsUpdateTimer.js
component {637b0f77-2429-49a0-915f-abf5d0db8b9a} WebappsUpdateTimer.js
contract @mozilla.org/b2g/webapps-update-timer;1 {637b0f77-2429-49a0-915f-abf5d0db8b9a}
category update-timer WebappsUpdateTimer @mozilla.org/b2g/webapps-update-timer;1,getService,background-update-timer,webapps.update.interval,86400

View File

@ -545,8 +545,8 @@ MozInputContext.prototype = {
getText: function ic_getText(offset, length) {
let self = this;
return this.createPromise(function(resolver) {
let resolverId = self.getPromiseResolverId(resolver);
return this.createPromise(function(resolve, reject) {
let resolverId = self.getPromiseResolverId({ resolve: resolve, reject: reject });
cpmm.sendAsyncMessage('Keyboard:GetText', {
contextId: self._contextId,
requestId: resolverId,
@ -574,8 +574,8 @@ MozInputContext.prototype = {
setSelectionRange: function ic_setSelectionRange(start, length) {
let self = this;
return this.createPromise(function(resolver) {
let resolverId = self.getPromiseResolverId(resolver);
return this.createPromise(function(resolve, reject) {
let resolverId = self.getPromiseResolverId({ resolve: resolve, reject: reject });
cpmm.sendAsyncMessage("Keyboard:SetSelectionRange", {
contextId: self._contextId,
requestId: resolverId,
@ -603,8 +603,8 @@ MozInputContext.prototype = {
replaceSurroundingText: function ic_replaceSurrText(text, offset, length) {
let self = this;
return this.createPromise(function(resolver) {
let resolverId = self.getPromiseResolverId(resolver);
return this.createPromise(function(resolve, reject) {
let resolverId = self.getPromiseResolverId({ resolve: resolve, reject: reject });
cpmm.sendAsyncMessage('Keyboard:ReplaceSurroundingText', {
contextId: self._contextId,
requestId: resolverId,
@ -621,8 +621,8 @@ MozInputContext.prototype = {
sendKey: function ic_sendKey(keyCode, charCode, modifiers) {
let self = this;
return this.createPromise(function(resolver) {
let resolverId = self.getPromiseResolverId(resolver);
return this.createPromise(function(resolve, reject) {
let resolverId = self.getPromiseResolverId({ resolve: resolve, reject: reject });
cpmm.sendAsyncMessage('Keyboard:SendKey', {
contextId: self._contextId,
requestId: resolverId,
@ -635,8 +635,8 @@ MozInputContext.prototype = {
setComposition: function ic_setComposition(text, cursor, clauses) {
let self = this;
return this.createPromise(function(resolver) {
let resolverId = self.getPromiseResolverId(resolver);
return this.createPromise(function(resolve, reject) {
let resolverId = self.getPromiseResolverId({ resolve: resolve, reject: reject });
cpmm.sendAsyncMessage('Keyboard:SetComposition', {
contextId: self._contextId,
requestId: resolverId,
@ -649,8 +649,8 @@ MozInputContext.prototype = {
endComposition: function ic_endComposition(text) {
let self = this;
return this.createPromise(function(resolver) {
let resolverId = self.getPromiseResolverId(resolver);
return this.createPromise(function(resolve, reject) {
let resolverId = self.getPromiseResolverId({ resolve: resolve, reject: reject });
cpmm.sendAsyncMessage('Keyboard:EndComposition', {
contextId: self._contextId,
requestId: resolverId,

View File

@ -12,6 +12,7 @@ const Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/WebappsUpdater.jsm");
const VERBOSE = 1;
let log =
@ -449,61 +450,6 @@ UpdatePrompt.prototype = {
}
},
appsUpdated: function UP_appsUpdated(aApps) {
log("appsUpdated: " + aApps.length + " apps to update");
let lock = Services.settings.createLock();
lock.set("apps.updateStatus", "check-complete", null);
this.sendChromeEvent("apps-update-check", { apps: aApps });
this._checkingApps = false;
},
// Trigger apps update check and wait for all to be done before
// notifying gaia.
onUpdateCheckStart: function UP_onUpdateCheckStart() {
log("onUpdateCheckStart (" + this._checkingApps + ")");
// Don't start twice.
if (this._checkingApps) {
return;
}
this._checkingApps = true;
let self = this;
let window = Services.wm.getMostRecentWindow("navigator:browser");
let all = window.navigator.mozApps.mgmt.getAll();
all.onsuccess = function() {
let appsCount = this.result.length;
let appsChecked = 0;
let appsToUpdate = [];
this.result.forEach(function updateApp(aApp) {
let update = aApp.checkForUpdate();
update.onsuccess = function() {
if (aApp.downloadAvailable) {
appsToUpdate.push(aApp.manifestURL);
}
appsChecked += 1;
if (appsChecked == appsCount) {
self.appsUpdated(appsToUpdate);
}
}
update.onerror = function() {
appsChecked += 1;
if (appsChecked == appsCount) {
self.appsUpdated(appsToUpdate);
}
}
});
}
all.onerror = function() {
// Could not get the app list, just notify to update nothing.
self.appsUpdated([]);
}
},
// nsIObserver
observe: function UP_observe(aSubject, aTopic, aData) {
@ -517,7 +463,7 @@ UpdatePrompt.prototype = {
Services.obs.removeObserver(this, "quit-application");
break;
case "update-check-start":
this.onUpdateCheckStart();
WebappsUpdater.updateApps();
break;
}
},

View File

@ -0,0 +1,67 @@
/* 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/. */
/**
* This component triggers an app update check even when system updates are
* disabled to make sure we always check for app updates.
*/
"use strict";
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/WebappsUpdater.jsm");
function debug(aStr) {
//dump("--*-- WebappsUpdateTimer: " + aStr);
}
function WebappsUpdateTimer() {
}
WebappsUpdateTimer.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsITimerCallback]),
classID: Components.ID("{637b0f77-2429-49a0-915f-abf5d0db8b9a}"),
notify: function(aTimer) {
try {
// We want to check app updates if system updates are disabled or
// if they update frecency is not daily.
if (Services.prefs.getBoolPref("app.update.enabled") === true &&
Services.prefs.getIntPref("app.update.interval") === 86400) {
return;
}
} catch(e) {
// That should never happen..
}
// If we are offline, wait to be online to start the update check.
if (Services.io.offline) {
debug("Network is offline. Setting up an offline status observer.");
Services.obs.addObserver(this, "network:offline-status-changed", false);
return;
}
// This will trigger app updates in b2g/components/WebappsUpdater.jsm
// that also takes care of notifying gaia.
WebappsUpdater.updateApps();
},
observe: function(aSubject, aTopic, aData) {
if (aTopic !== "network:offline-status-changed" ||
aData !== "online") {
return;
}
debug("Network is online. Checking updates.");
Services.obs.removeObserver(this, "network:offline-status-changed");
WebappsUpdater.updateApps();
}
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WebappsUpdateTimer]);

View File

@ -0,0 +1,95 @@
/* 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";
this.EXPORTED_SYMBOLS = ["WebappsUpdater"];
const Cc = Components.classes;
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
this.WebappsUpdater = {
_checkingApps: false,
_pendingEvents: [],
handleContentStart: function(aShell) {
let content = aShell.contentBrowser.contentWindow;
this._pendingEvents.forEach(aShell.sendChromeEvent);
this._pendingEvents.length = 0;
},
sendChromeEvent: function(aType, aDetail) {
let detail = aDetail || {};
detail.type = aType;
let browser = Services.wm.getMostRecentWindow("navigator:browser");
if (!browser) {
this._pendingEvents.push(detail);
dump("Warning: Couldn't send update event " + aType +
": no content browser. Will send again when content becomes available.");
return false;
}
browser.shell.sendChromeEvent(detail);
return true;
},
_appsUpdated: function(aApps) {
dump("appsUpdated: " + aApps.length + " apps to update");
let lock = Services.settings.createLock();
lock.set("apps.updateStatus", "check-complete", null);
this.sendChromeEvent("apps-update-check", { apps: aApps });
this._checkingApps = false;
},
// Trigger apps update check and wait for all to be done before
// notifying gaia.
updateApps: function() {
dump("updateApps (" + this._checkingApps + ")");
// Don't start twice.
if (this._checkingApps) {
return;
}
this._checkingApps = true;
let self = this;
let window = Services.wm.getMostRecentWindow("navigator:browser");
let all = window.navigator.mozApps.mgmt.getAll();
all.onsuccess = function() {
let appsCount = this.result.length;
let appsChecked = 0;
let appsToUpdate = [];
this.result.forEach(function updateApp(aApp) {
let update = aApp.checkForUpdate();
update.onsuccess = function() {
if (aApp.downloadAvailable) {
appsToUpdate.push(aApp.manifestURL);
}
appsChecked += 1;
if (appsChecked == appsCount) {
self._appsUpdated(appsToUpdate);
}
}
update.onerror = function() {
appsChecked += 1;
if (appsChecked == appsCount) {
self._appsUpdated(appsToUpdate);
}
}
});
}
all.onerror = function() {
// Could not get the app list, just notify to update nothing.
self._appsUpdated([]);
}
}
};

View File

@ -25,6 +25,7 @@ EXTRA_COMPONENTS += [
'ProcessGlobal.js',
'SmsProtocolHandler.js',
'TelProtocolHandler.js',
'WebappsUpdateTimer.js',
'YoutubeProtocolHandler.js',
]
@ -44,4 +45,5 @@ EXTRA_JS_MODULES += [
'Keyboard.jsm',
'SignInToWebsite.jsm',
'TelURIParser.jsm',
'WebappsUpdater.jsm',
]

View File

@ -1,4 +1,4 @@
{
"revision": "e3d925b497f5b996c9c397c200805fbcc62bc823",
"revision": "9e3d2b3f6706916168b9ad9bb96084c01df8771f",
"repo_path": "/integration/gaia-central"
}

View File

@ -733,6 +733,7 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
#ifdef MOZ_UPDATER
@BINPATH@/components/UpdatePrompt.js
#endif
@BINPATH@/components/WebappsUpdateTimer.js
@BINPATH@/components/MozKeyboard.js
@BINPATH@/components/DirectoryProvider.js
@BINPATH@/components/ActivitiesGlue.js

View File

@ -1066,7 +1066,8 @@ pref("devtools.gcli.allowSet", false);
pref("devtools.commands.dir", "");
// Disable the app manager
pref("devtools.appmanager.enabled", false);
pref("devtools.appmanager.enabled", true);
pref("devtools.appmanager.simulatorInstallPage", "https://addons.mozilla.org/firefox/addon/firefox-os-simulator/");
// Toolbox preferences
pref("devtools.toolbox.footer.height", 250);

View File

@ -46,7 +46,7 @@
accesskey="&saveLinkCmd.accesskey;"
oncommand="gContextMenu.saveLink();"/>
<menu id="context-marklinkMenu" label="&social.marklinkMenu.label;"
accesskey="&social.marklink.accesskey;">
accesskey="&social.marklinkMenu.accesskey;">
<menupopup/>
</menu>
<menuitem id="context-copyemail"
@ -252,7 +252,7 @@
accesskey="&savePageCmd.accesskey2;"
oncommand="gContextMenu.savePageAs();"/>
<menu id="context-markpageMenu" label="&social.markpageMenu.label;"
accesskey="&social.markpage.accesskey;">
accesskey="&social.markpageMenu.accesskey;">
<menupopup/>
</menu>
<menuseparator id="context-sep-viewbgimage"/>

View File

@ -12,9 +12,9 @@ var gPluginHandler = {
PREF_SESSION_PERSIST_MINUTES: "plugin.sessionPermissionNow.intervalInMinutes",
PREF_PERSISTENT_DAYS: "plugin.persistentPermissionAlways.intervalInDays",
getPluginUI: function (plugin, className) {
getPluginUI: function (plugin, anonid) {
return plugin.ownerDocument.
getAnonymousElementByAttribute(plugin, "class", className);
getAnonymousElementByAttribute(plugin, "anonid", anonid);
},
#ifdef MOZ_CRASHREPORTER
@ -236,7 +236,7 @@ var gPluginHandler = {
// The plugin binding fires this event when it is created.
// As an untrusted event, ensure that this object actually has a binding
// and make sure we don't handle it twice
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
let overlay = this.getPluginUI(plugin, "main");
if (!overlay || overlay._bindingHandled) {
return;
}
@ -264,12 +264,12 @@ var gPluginHandler = {
// plugin. Object tags can, and often do, deal with that themselves,
// so don't stomp on the page developers toes.
if (installable && !(plugin instanceof HTMLObjectElement)) {
let installStatus = doc.getAnonymousElementByAttribute(plugin, "class", "installStatus");
let installStatus = this.getPluginUI(plugin, "installStatus");
installStatus.setAttribute("installable", "true");
let iconStatus = doc.getAnonymousElementByAttribute(plugin, "class", "icon");
let iconStatus = this.getPluginUI(plugin, "icon");
iconStatus.setAttribute("installable", "true");
let installLink = doc.getAnonymousElementByAttribute(plugin, "anonid", "installPluginLink");
let installLink = this.getPluginUI(plugin, "installPluginLink");
this.addLinkClickCallback(installLink, "installSinglePlugin", plugin);
}
break;
@ -280,22 +280,22 @@ var gPluginHandler = {
break;
case "PluginVulnerableUpdatable":
let updateLink = doc.getAnonymousElementByAttribute(plugin, "anonid", "checkForUpdatesLink");
let updateLink = this.getPluginUI(plugin, "checkForUpdatesLink");
this.addLinkClickCallback(updateLink, "openPluginUpdatePage");
/* FALLTHRU */
case "PluginVulnerableNoUpdate":
case "PluginClickToPlay":
this._handleClickToPlayEvent(plugin);
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
let overlay = this.getPluginUI(plugin, "main");
let pluginName = this._getPluginInfo(plugin).pluginName;
let messageString = gNavigatorBundle.getFormattedString("PluginClickToActivate", [pluginName]);
let overlayText = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgClickToPlay");
let overlayText = this.getPluginUI(plugin, "clickToPlay");
overlayText.textContent = messageString;
if (eventType == "PluginVulnerableUpdatable" ||
eventType == "PluginVulnerableNoUpdate") {
let vulnerabilityString = gNavigatorBundle.getString(eventType);
let vulnerabilityText = doc.getAnonymousElementByAttribute(plugin, "anonid", "vulnerabilityStatus");
let vulnerabilityText = this.getPluginUI(plugin, "vulnerabilityStatus");
vulnerabilityText.textContent = vulnerabilityString;
}
shouldShowNotification = true;
@ -306,7 +306,7 @@ var gPluginHandler = {
break;
case "PluginDisabled":
let manageLink = doc.getAnonymousElementByAttribute(plugin, "anonid", "managePluginsLink");
let manageLink = this.getPluginUI(plugin, "managePluginsLink");
this.addLinkClickCallback(manageLink, "managePlugins");
shouldShowNotification = true;
break;
@ -319,7 +319,7 @@ var gPluginHandler = {
// Hide the in-content UI if it's too big. The crashed plugin handler already did this.
if (eventType != "PluginCrashed" && eventType != "PluginRemoved") {
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
let overlay = this.getPluginUI(plugin, "main");
if (overlay != null && this.isTooSmall(plugin, overlay))
overlay.style.visibility = "hidden";
}
@ -364,7 +364,7 @@ var gPluginHandler = {
},
hideClickToPlayOverlay: function(aPlugin) {
let overlay = aPlugin.ownerDocument.getAnonymousElementByAttribute(aPlugin, "class", "mainBox");
let overlay = this.getPluginUI(aPlugin, "main");
if (overlay)
overlay.style.visibility = "hidden";
},
@ -514,7 +514,7 @@ var gPluginHandler = {
let principal = doc.defaultView.top.document.nodePrincipal;
let pluginPermission = Services.perms.testPermissionFromPrincipal(principal, permissionString);
let overlay = doc.getAnonymousElementByAttribute(aPlugin, "class", "mainBox");
let overlay = this.getPluginUI(aPlugin, "main");
if (pluginPermission == Ci.nsIPermissionManager.DENY_ACTION) {
if (overlay)
@ -524,7 +524,7 @@ var gPluginHandler = {
if (overlay) {
overlay.addEventListener("click", gPluginHandler._overlayClickListener, true);
let closeIcon = doc.getAnonymousElementByAttribute(aPlugin, "anonid", "closeIcon");
let closeIcon = this.getPluginUI(aPlugin, "closeIcon");
closeIcon.addEventListener("click", function(aEvent) {
if (aEvent.button == 0 && aEvent.isTrusted)
gPluginHandler.hideClickToPlayOverlay(aPlugin);
@ -567,7 +567,7 @@ var gPluginHandler = {
let pluginInfo = this._getPluginInfo(aPlugin);
let playPreviewInfo = pluginHost.getPlayPreviewInfo(pluginInfo.mimetype);
let previewContent = doc.getAnonymousElementByAttribute(aPlugin, "class", "previewPluginContent");
let previewContent = this.getPluginUI(aPlugin, "previewPluginContent");
let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0];
if (!iframe) {
// lazy initialization of the iframe
@ -607,10 +607,9 @@ var gPluginHandler = {
let contentWindow = browser.contentWindow;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let doc = contentWindow.document;
let plugins = cwu.plugins;
for (let plugin of plugins) {
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
let overlay = this.getPluginUI(plugin, "main");
if (overlay)
overlay.removeEventListener("click", gPluginHandler._overlayClickListener, true);
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
@ -814,7 +813,7 @@ var gPluginHandler = {
break;
}
if (fallbackType == plugin.PLUGIN_CLICK_TO_PLAY) {
let overlay = contentDoc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
let overlay = this.getPluginUI(plugin, "main");
if (!overlay || overlay.style.visibility == 'hidden') {
icon = 'alert-plugins-notification-icon';
}
@ -888,9 +887,9 @@ var gPluginHandler = {
// Force a layout flush so the binding is attached.
plugin.clientTop;
let overlay = this.getPluginUI(plugin, "main");
let statusDiv = this.getPluginUI(plugin, "submitStatus");
let doc = plugin.ownerDocument;
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
let statusDiv = doc.getAnonymousElementByAttribute(plugin, "class", "submitStatus");
#ifdef MOZ_CRASHREPORTER
let status;
@ -923,7 +922,7 @@ var gPluginHandler = {
statusDiv.setAttribute("status", status);
let helpIcon = doc.getAnonymousElementByAttribute(plugin, "class", "helpIcon");
let helpIcon = this.getPluginUI(plugin, "helpIcon");
this.addLinkClickCallback(helpIcon, "openHelpPage");
// If we're showing the link to manually trigger report submission, we'll
@ -959,12 +958,12 @@ var gPluginHandler = {
}
#endif
let crashText = doc.getAnonymousElementByAttribute(plugin, "class", "msgCrashedText");
let crashText = this.getPluginUI(plugin, "crashedText");
crashText.textContent = messageString;
let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
let link = doc.getAnonymousElementByAttribute(plugin, "class", "reloadLink");
let link = this.getPluginUI(plugin, "reloadLink");
this.addLinkClickCallback(link, "reloadPage", browser);
let notificationBox = gBrowser.getNotificationBox(browser);

View File

@ -1654,12 +1654,12 @@ SocialMarks = {
{
type: "link",
id: "context-marklinkMenu",
label: "social.marklink.label"
label: "social.marklinkMenu.label"
},
{
type: "page",
id: "context-markpageMenu",
label: "social.markpage.label"
label: "social.markpageMenu.label"
}
];
for (let cfg of contextMenus) {

View File

@ -89,7 +89,7 @@ function onCrash() {
let plugin = gBrowser.contentDocument.getElementById("plugin");
let elt = gPluginHandler.getPluginUI.bind(gPluginHandler, plugin);
let style =
gBrowser.contentWindow.getComputedStyle(elt("msg msgPleaseSubmit"));
gBrowser.contentWindow.getComputedStyle(elt("pleaseSubmit"));
is(style.display,
currentRun.shouldSubmissionUIBeVisible ? "block" : "none",
"Submission UI visibility should be correct");

View File

@ -252,12 +252,12 @@ function checkSocialUI(win) {
{
type: "link",
id: "context-marklinkMenu",
label: "social.marklink.label"
label: "social.marklinkMenu.label"
},
{
type: "page",
id: "context-markpageMenu",
label: "social.markpage.label"
label: "social.markpageMenu.label"
}
];

View File

@ -90,6 +90,8 @@ static RedirEntry kRedirMap[] = {
{ "healthreport", "chrome://browser/content/abouthealthreport/abouthealth.xhtml",
nsIAboutModule::ALLOW_SCRIPT },
#endif
{ "app-manager", "chrome://browser/content/devtools/app-manager/index.xul",
nsIAboutModule::ALLOW_SCRIPT },
{ "customizing", "chrome://browser/content/customizableui/aboutCustomizing.xhtml",
nsIAboutModule::ALLOW_SCRIPT },
};

View File

@ -109,6 +109,7 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
#ifdef MOZ_SERVICES_HEALTHREPORT
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "healthreport", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
#endif
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "app-manager", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "customizing", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
#if defined(XP_WIN)
{ NS_IEHISTORYENUMERATOR_CONTRACTID, &kNS_WINIEHISTORYENUMERATOR_CID },

View File

@ -3,13 +3,11 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
browser.jar:
* content/browser/preferences/in-content/preferences.js
content/browser/preferences/in-content/preferences.js
content/browser/preferences/in-content/landing.xul
* content/browser/preferences/in-content/preferences.xul
* content/browser/preferences/in-content/main.xul
content/browser/preferences/in-content/main.js
* content/browser/preferences/in-content/tabs.xul
* content/browser/preferences/in-content/tabs.js
* content/browser/preferences/in-content/main.js
content/browser/preferences/in-content/privacy.xul
* content/browser/preferences/in-content/privacy.js
* content/browser/preferences/in-content/advanced.xul

View File

@ -13,11 +13,7 @@
<label class="landingButton-label">&paneGeneral.title;</label>
</button>
<button label="&paneTabs.title;" class="landingButton"
oncommand="gotoPref('paneTabs');">
<image class="landingButton-icon" type="tabs"/>
<label class="landingButton-label">&paneTabs.title;</label>
</button>
<button label="&paneContent.title;" class="landingButton"
oncommand="gotoPref('paneContent');">

View File

@ -6,15 +6,11 @@ XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
"resource:///modules/DownloadsCommon.jsm");
var gMainPane = {
_pane: null,
/**
* Initialization of this.
*/
init: function ()
{
this._pane = document.getElementById("paneMain");
// set up the "use current page" label-changing listener
this._updateUseCurrentButton();
window.addEventListener("focus", this._updateUseCurrentButton.bind(this), false);
@ -27,6 +23,20 @@ var gMainPane = {
Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService)
.notifyObservers(window, "main-pane-loaded", null);
//Functionality for "Show tabs in taskbar" on Win XP
#ifdef XP_WIN
try {
let sysInfo = Cc["@mozilla.org/system-info;1"].
getService(Ci.nsIPropertyBag2);
let ver = parseFloat(sysInfo.getProperty("version"));
let showTabsInTaskbar = document.getElementById("showTabsInTaskbar");
showTabsInTaskbar.hidden = ver < 6.1 || (ver >= 6.1 && history.state != "tabs");
} catch (ex) {}
#endif
},
setupDownloadsWindowOptions: function ()
@ -475,5 +485,28 @@ var gMainPane = {
option.removeAttribute("disabled");
startupPref.updateElements(); // select the correct index in the startup menulist
}
},
// TABS
/**
* Determines where a link which opens a new window will open.
*
* @returns |true| if such links should be opened in new tabs
*/
readLinkTarget: function() {
var openNewWindow = document.getElementById("browser.link.open_newwindow");
return openNewWindow.value != 2;
},
/**
* Determines where a link which opens a new window will open.
*
* @returns 2 if such links should be opened in new windows,
* 3 if such links should be opened in new tabs
*/
writeLinkTarget: function() {
var linkTargeting = document.getElementById("linkTargeting");
return linkTargeting.checked ? 3 : 2;
}
};

View File

@ -49,6 +49,47 @@
name="browser.download.folderList"
type="int"/>
<!-- Tab preferences
Preferences:
browser.link.open_newwindow
1 opens such links in the most recent window or tab,
2 opens such links in a new window,
3 opens such links in a new tab
browser.tabs.loadInBackground
- true if display should switch to a new tab which has been opened from a
link, false if display shouldn't switch
browser.tabs.warnOnClose
- true if when closing a window with multiple tabs the user is warned and
allowed to cancel the action, false to just close the window
browser.tabs.warnOnOpen
- true if the user should be warned if he attempts to open a lot of tabs at
once (e.g. a large folder of bookmarks), false otherwise
browser.taskbar.previews.enable
- true if tabs are to be shown in the Windows 7 taskbar
-->
<preference id="browser.link.open_newwindow"
name="browser.link.open_newwindow"
type="int"/>
<preference id="browser.tabs.loadInBackground"
name="browser.tabs.loadInBackground"
type="bool"
inverted="true"/>
<preference id="browser.tabs.warnOnClose"
name="browser.tabs.warnOnClose"
type="bool"/>
<preference id="browser.tabs.warnOnOpen"
name="browser.tabs.warnOnOpen"
type="bool"/>
<preference id="browser.sessionstore.restore_on_demand"
name="browser.sessionstore.restore_on_demand"
type="bool"/>
#ifdef XP_WIN
<preference id="browser.taskbar.previews.enable"
name="browser.taskbar.previews.enable"
type="bool"/>
#endif
</preferences>
<hbox class="heading" data-category="paneGeneral" hidden="true">
@ -166,3 +207,42 @@
accesskey="&alwaysAsk.accesskey;"/>
</radiogroup>
</groupbox>
<!-- Tab preferences -->
<groupbox data-category="paneGeneral" hidden="true">
<caption label="&tabsGroup.label;"/>
<checkbox id="linkTargeting" label="&newWindowsAsTabs.label;"
accesskey="&newWindowsAsTabs.accesskey;"
preference="browser.link.open_newwindow"
onsyncfrompreference="return gMainPane.readLinkTarget();"
onsynctopreference="return gMainPane.writeLinkTarget();"
class="indent"/>
<checkbox id="warnCloseMultiple" label="&warnCloseMultipleTabs.label;"
accesskey="&warnCloseMultipleTabs.accesskey;"
preference="browser.tabs.warnOnClose"
class="indent"/>
<checkbox id="warnOpenMany" label="&warnOpenManyTabs.label;"
accesskey="&warnOpenManyTabs.accesskey;"
preference="browser.tabs.warnOnOpen"
class="indent"/>
<checkbox id="restoreOnDemand" label="&restoreTabsOnDemand.label;"
accesskey="&restoreTabsOnDemand.accesskey;"
preference="browser.sessionstore.restore_on_demand"
class="indent"/>
<checkbox id="switchToNewTabs" label="&switchToNewTabs.label;"
accesskey="&switchToNewTabs.accesskey;"
preference="browser.tabs.loadInBackground"
class="indent"/>
#ifdef XP_WIN
<checkbox id="showTabsInTaskbar" label="&showTabsInTaskbar.label;"
accesskey="&showTabsInTaskbar.accesskey;"
preference="browser.taskbar.previews.enable"
class="indent"/>
#endif
</groupbox>

View File

@ -18,9 +18,6 @@ function init_all() {
window.addEventListener("popstate", onStatePopped, true);
updateCommands();
gMainPane.init();
#ifdef XP_WIN
gTabsPane.init();
#endif
gPrivacyPane.init();
gAdvancedPane.init();
gApplicationsPane.init();

View File

@ -91,7 +91,6 @@
<prefpane flex="1" id="mainPrefPane">
#include landing.xul
#include main.xul
#include tabs.xul
#include privacy.xul
#include advanced.xul
#include applications.xul

View File

@ -1,63 +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/. */
var gTabsPane = {
/*
* Preferences:
*
* browser.link.open_newwindow
* - determines where pages which would open in a new window are opened:
* 1 opens such links in the most recent window or tab,
* 2 opens such links in a new window,
* 3 opens such links in a new tab
* browser.tabs.loadInBackground
* - true if display should switch to a new tab which has been opened from a
* link, false if display shouldn't switch
* browser.tabs.warnOnClose
* - true if when closing a window with multiple tabs the user is warned and
* allowed to cancel the action, false to just close the window
* browser.tabs.warnOnOpen
* - true if the user should be warned if he attempts to open a lot of tabs at
* once (e.g. a large folder of bookmarks), false otherwise
* browser.taskbar.previews.enable
* - true if tabs are to be shown in the Windows 7 taskbar
*/
#ifdef XP_WIN
/**
* Initialize any platform-specific UI.
*/
init: function () {
try {
let sysInfo = Cc["@mozilla.org/system-info;1"].
getService(Ci.nsIPropertyBag2);
let ver = parseFloat(sysInfo.getProperty("version"));
let showTabsInTaskbar = document.getElementById("showTabsInTaskbar");
showTabsInTaskbar.hidden = ver < 6.1 || (ver >= 6.1 && history.state != "tabs");
} catch (ex) {}
},
#endif
/**
* Determines where a link which opens a new window will open.
*
* @returns |true| if such links should be opened in new tabs
*/
readLinkTarget: function() {
var openNewWindow = document.getElementById("browser.link.open_newwindow");
return openNewWindow.value != 2;
},
/**
* Determines where a link which opens a new window will open.
*
* @returns 2 if such links should be opened in new windows,
* 3 if such links should be opened in new tabs
*/
writeLinkTarget: function() {
var linkTargeting = document.getElementById("linkTargeting");
return linkTargeting.checked ? 3 : 2;
}
};

View File

@ -1,76 +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/. -->
<script type="application/javascript"
src="chrome://browser/content/preferences/in-content/tabs.js"/>
<preferences id="tabsPreferences">
<preference id="browser.link.open_newwindow"
name="browser.link.open_newwindow"
type="int"/>
<preference id="browser.tabs.loadInBackground"
name="browser.tabs.loadInBackground"
type="bool"
inverted="true"/>
<preference id="browser.tabs.warnOnClose"
name="browser.tabs.warnOnClose"
type="bool"/>
<preference id="browser.tabs.warnOnOpen"
name="browser.tabs.warnOnOpen"
type="bool"/>
<preference id="browser.sessionstore.restore_on_demand"
name="browser.sessionstore.restore_on_demand"
type="bool"/>
#ifdef XP_WIN
<preference id="browser.taskbar.previews.enable"
name="browser.taskbar.previews.enable"
type="bool"/>
#endif
</preferences>
<hbox class="heading" data-category="paneTabs" hidden="true">
<image class="preference-icon" type="tabs"/>
<html:h1>&paneTabs.title;</html:h1>
</hbox>
<checkbox id="linkTargeting" label="&newWindowsAsTabs.label;"
data-category="paneTabs" hidden="true"
accesskey="&newWindowsAsTabs.accesskey;"
preference="browser.link.open_newwindow"
onsyncfrompreference="return gTabsPane.readLinkTarget();"
onsynctopreference="return gTabsPane.writeLinkTarget();"
class="indent"/>
<checkbox id="warnCloseMultiple" label="&warnCloseMultipleTabs.label;"
data-category="paneTabs" hidden="true"
accesskey="&warnCloseMultipleTabs.accesskey;"
preference="browser.tabs.warnOnClose"
class="indent"/>
<checkbox id="warnOpenMany" label="&warnOpenManyTabs.label;"
data-category="paneTabs" hidden="true"
accesskey="&warnOpenManyTabs.accesskey;"
preference="browser.tabs.warnOnOpen"
class="indent"/>
<checkbox id="restoreOnDemand" label="&restoreTabsOnDemand.label;"
data-category="paneTabs" hidden="true"
accesskey="&restoreTabsOnDemand.accesskey;"
preference="browser.sessionstore.restore_on_demand"
class="indent"/>
<checkbox id="switchToNewTabs" label="&switchToNewTabs.label;"
data-category="paneTabs" hidden="true"
accesskey="&switchToNewTabs.accesskey;"
preference="browser.tabs.loadInBackground"
class="indent"/>
#ifdef XP_WIN
<checkbox id="showTabsInTaskbar" label="&showTabsInTaskbar.label;"
data-category="paneTabs" hidden="true"
accesskey="&showTabsInTaskbar.accesskey;"
preference="browser.taskbar.previews.enable"
class="indent"/>
#endif

View File

@ -69,14 +69,14 @@ function test() {
});
testOnWindow({}, function(win) {
testPopupBlockerMenuItem(false, win,
testPopupBlockerMenuItem(false, win, function() {
testOnWindow({private: true}, function(win) {
testPopupBlockerMenuItem(true, win,
testPopupBlockerMenuItem(true, win, function() {
testOnWindow({}, function(win) {
testPopupBlockerMenuItem(false, win, finishTest);
})
);
});
})
);
});
});
}

View File

@ -61,7 +61,7 @@ let DomStorage = {
// Check if we're allowed to store sessionStorage data.
let isHTTPS = principal.URI && principal.URI.schemeIs("https");
if (aFullData || SessionStore.checkPrivacyLevel(isHTTPS, isPinned)) {
let origin = principal.extendedOrigin;
let origin = principal.jarPrefix + principal.origin;
// Don't read a host twice.
if (!(origin in data)) {

View File

@ -678,12 +678,12 @@ let SessionStoreInternal = {
break;
case "TabPinned":
// If possible, update cached data without having to invalidate it
TabStateCache.update(aEvent.originalTarget, "pinned", true);
TabStateCache.updateField(aEvent.originalTarget, "pinned", true);
this.saveStateDelayed(win);
break;
case "TabUnpinned":
// If possible, update cached data without having to invalidate it
TabStateCache.update(aEvent.originalTarget, "pinned", false);
TabStateCache.updateField(aEvent.originalTarget, "pinned", false);
this.saveStateDelayed(win);
break;
}
@ -1330,7 +1330,7 @@ let SessionStoreInternal = {
}
// If possible, update cached data without having to invalidate it
TabStateCache.update(aTab, "hidden", false);
TabStateCache.updateField(aTab, "hidden", false);
// Default delay of 2 seconds gives enough time to catch multiple TabShow
// events due to changing groups in Panorama.
@ -1345,7 +1345,7 @@ let SessionStoreInternal = {
}
// If possible, update cached data without having to invalidate it
TabStateCache.update(aTab, "hidden", true);
TabStateCache.updateField(aTab, "hidden", true);
// Default delay of 2 seconds gives enough time to catch multiple TabHide
// events due to changing groups in Panorama.
@ -1665,7 +1665,6 @@ let SessionStoreInternal = {
},
setTabValue: function ssi_setTabValue(aTab, aKey, aStringValue) {
TabStateCache.delete(aTab);
// If the tab hasn't been restored, then set the data there, otherwise we
// could lose newly added data.
let saveTo;
@ -1679,12 +1678,13 @@ let SessionStoreInternal = {
aTab.__SS_extdata = {};
saveTo = aTab.__SS_extdata;
}
saveTo[aKey] = aStringValue;
TabStateCache.updateField(aTab, "extData", saveTo);
this.saveStateDelayed(aTab.ownerDocument.defaultView);
},
deleteTabValue: function ssi_deleteTabValue(aTab, aKey) {
TabStateCache.delete(aTab);
// We want to make sure that if data is accessed early, we attempt to delete
// that data from __SS_data as well. Otherwise we'll throw in cases where
// data can be set or read.
@ -1696,9 +1696,19 @@ let SessionStoreInternal = {
deleteFrom = aTab.linkedBrowser.__SS_data.extData;
}
if (deleteFrom && deleteFrom[aKey])
if (deleteFrom && aKey in deleteFrom) {
delete deleteFrom[aKey];
this.saveStateDelayed(aTab.ownerDocument.defaultView);
// Keep the extData object only if it is not empty, to save
// a little disk space when serializing the tab state later.
if (Object.keys(deleteFrom).length) {
TabStateCache.updateField(aTab, "extData", deleteFrom);
} else {
TabStateCache.removeField(aTab, "extData");
}
this.saveStateDelayed(aTab.ownerDocument.defaultView);
}
},
persistTabAttribute: function ssi_persistTabAttribute(aName) {
@ -4639,7 +4649,7 @@ let TabStateCache = {
* @param {string} aField The field to update.
* @param {*} aValue The new value to place in the field.
*/
update: function(aKey, aField, aValue) {
updateField: function(aKey, aField, aValue) {
let key = this._normalizeToBrowser(aKey);
let data = this._data.get(key);
if (data) {
@ -4648,6 +4658,22 @@ let TabStateCache = {
TabStateCacheTelemetry.recordAccess(!!data);
},
/**
* Remove a given field from a cached tab state.
*
* @param {XULElement} aKey The tab or the associated browser.
* If the tab/browser is not present, do nothing.
* @param {string} aField The field to remove.
*/
removeField: function(aKey, aField) {
let key = this._normalizeToBrowser(aKey);
let data = this._data.get(key);
if (data && aField in data) {
delete data[aField];
}
TabStateCacheTelemetry.recordAccess(!!data);
},
_normalizeToBrowser: function(aKey) {
let nodeName = aKey.localName;
if (nodeName == "tab") {

View File

@ -35,8 +35,9 @@
xhr.send(null);
}
function done() {
var event = document.createEvent("MessageEvent");
event.initMessageEvent("461743", true, false, "done", location.href, "", window);
var event = new MessageEvent('461743', { bubbles: true, cancelable: false,
data: "done", origin: location.href,
source: window });
document.dispatchEvent(event);
frames[0].document.removeEventListener("DOMNodeInserted", loadChrome, true);
frames[0].document.removeEventListener("DOMNodeInserted", delay, true);

View File

@ -44,8 +44,9 @@
}
document.getElementById("state").textContent = "done";
var event = document.createEvent("MessageEvent");
event.initMessageEvent("464620_a", true, false, "done", location.href, "", window);
var event = new MessageEvent('464620_a', { bubbles: true, cancelable: false,
data: "done", origin: location.href,
source: window });
document.dispatchEvent(event);
}
</script>

View File

@ -48,8 +48,9 @@
}
document.getElementById("state").textContent = "done";
var event = document.createEvent("MessageEvent");
event.initMessageEvent("464620_b", true, false, "done", location.href, "", window);
var event = new MessageEvent('464620_b', { bubbles: true, cancelable: false,
data: "done", origin: location.href,
source: window });
document.dispatchEvent(event);
}
</script>

View File

@ -2293,6 +2293,10 @@ let GroupItems = {
// Given some sort of identifier, returns the appropriate groupItem.
// Currently only supports groupItem ids.
groupItem: function GroupItems_groupItem(a) {
if (!this.groupItems) {
// uninit has been called
return null;
}
var result = null;
this.groupItems.forEach(function(candidate) {
if (candidate.id == a)

View File

@ -3,6 +3,7 @@ const ObservableObject = require("devtools/shared/observable-object");
const promise = require("sdk/core/promise");
const {EventEmitter} = Cu.import("resource:///modules/devtools/shared/event-emitter.js");
const {generateUUID} = Cc['@mozilla.org/uuid-generator;1'].getService(Ci.nsIUUIDGenerator);
/**
* IndexedDB wrapper that just save project objects
@ -96,7 +97,13 @@ const AppProjects = {
addPackaged: function(folder) {
let project = {
type: "packaged",
location: folder.path
location: folder.path,
// We need a unique id, that is the app origin,
// in order to identify the app when being installed on the device.
// The packaged app local path is a valid id, but only on the client.
// This origin will be used to generate the true id of an app:
// its manifest URL.
packagedAppOrigin: generateUUID().toString().slice(1, -1)
};
return IDB.add(project).then(function () {
store.object.projects.push(project);

View File

@ -7,12 +7,14 @@ const Ci = Components.interfaces;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource:///modules/devtools/gDevTools.jsm");
const {Simulator} = Cu.import("resource://gre/modules/devtools/Simulator.jsm")
const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const {require} = devtools;
const {ConnectionManager, Connection} = require("devtools/client/connection-manager");
const ConnectionStore = require("devtools/app-manager/connection-store");
const DeviceStore = require("devtools/app-manager/device-store");
const simulatorsStore = require("devtools/app-manager/simulators-store");
let UI = {
init: function() {
@ -43,6 +45,7 @@ let UI = {
this.store = Utils.mergeStores({
"device": new DeviceStore(this.connection),
"connection": new ConnectionStore(this.connection),
"simulators": simulatorsStore,
});
let pre = document.querySelector("#logs > pre");
@ -96,4 +99,47 @@ let UI = {
Services.prefs.setCharPref("devtools.debugger.remote-host", host);
Services.prefs.setIntPref("devtools.debugger.remote-port", port);
},
showSimulatorList: function() {
document.body.classList.add("show-simulators");
},
cancelShowSimulatorList: function() {
document.body.classList.remove("show-simulators");
},
installSimulator: function() {
let url = Services.prefs.getCharPref("devtools.appmanager.simulatorInstallPage");
window.open(url);
},
startSimulator: function(version) {
let port = ConnectionManager.getFreeTCPPort();
let simulator = Simulator.getByVersion(version);
if (!simulator) {
this.connection.log("Error: can't find simulator: " + version);
return;
}
if (!simulator.launch) {
this.connection.log("Error: invalid simulator: " + version);
return;
}
this.connection.log("Found simulator: " + version);
this.connection.log("Starting simulator...");
this.simulator = simulator;
this.simulator.launch({ port: port })
.then(() => {
this.connection.log("Simulator ready. Connecting.");
this.connection.port = port;
this.connection.host = "localhost";
this.connection.once("connected", function() {
this.connection.log("Connected to simulator.");
this.connection.keepConnecting = false;
});
this.connection.keepConnecting = true;
this.connection.connect();
});
document.body.classList.remove("show-simulators");
},
}

View File

@ -38,9 +38,9 @@
<span>&connection.notConnected;</span>
<button class="action-primary left" onclick="UI.connect()" id="connect-button" template='{"type":"localizedContent","property":"connection.connectTo","paths":["connection.host","connection.port"]}'></button>
<button class="right" onclick="UI.editConnectionParameters()">&connection.changeHostAndPort;</button>
<div id="start-simulator-box" template='{"type":"attribute","path":"simulators.versions.length","name":"simulators-count"}'>
<div id="start-simulator-box">
<span>&connection.or;</span>
<button id="start-simulator-button" class="action-primary" onclick="UI.startSimulator()">&connection.startSimulator;</button>
<button id="start-simulator-button" class="action-primary" onclick="UI.showSimulatorList()">&connection.startSimulator;</button>
</div>
</div>
</div>
@ -81,6 +81,25 @@
</div>
</div>
<!-- Simulator -->
<div id="banner-simulators" class="banner" template='{"type":"attribute","path":"simulators.versions.length","name":"simulator-count"}'>
<div class="connected-indicator"></div>
<div class="banner-box">
<div class="banner-content">
<div class="no-simulator">
<span>&connection.noSimulatorInstalled;</span>
<button class="action-primary" onclick="UI.installSimulator()">&connection.installFirstSimulator;</button>
</div>
<div class="found-simulator">
<span template-loop='{"arrayPath":"simulators.versions","childSelector":"#simulator-item-template"}'></span>
<button class="action-primary" onclick="UI.installSimulator()">&connection.installAnotherSimulator;</button>
</div>
<button class="action-cancel" onclick="UI.cancelShowSimulatorList()">&connection.cancel;</button>
</div>
</div>
</div>
<!-- Logs -->
<div id="banner-logs">
<div id="logs" class="banner-box">
@ -92,6 +111,14 @@
</div>
</body>
<template id="simulator-item-template">
<span>
<button class="simulator-item" onclick="UI.startSimulator(this.dataset.version)" template='{"type":"attribute","path":"version","name":"data-version"}'>
<span template='{"type":"textContent", "path":"version"}'></span>
</button>
</span>
</template>
<script type="application/javascript;version=1.8" src="utils.js"></script>
<script type="application/javascript;version=1.8" src="template.js"></script>
<script type="application/javascript;version=1.8" src="connection-footer.js"></script>

View File

@ -167,7 +167,13 @@ let UI = {
openToolbox: function(manifest) {
this._getTargetForApp(manifest).then((target) => {
gDevTools.showToolbox(target, "webconsole", devtools.Toolbox.HostType.WINDOW);
gDevTools.showToolbox(target,
null,
devtools.Toolbox.HostType.WINDOW).then(toolbox => {
this.connection.once(Connection.Events.DISCONNECTED, () => {
toolbox.destroy();
});
});
}, console.error);
},

View File

@ -14,6 +14,8 @@ const {AppProjects} = require("devtools/app-manager/app-projects");
const {AppValidator} = require("devtools/app-manager/app-validator");
const {Services} = Cu.import("resource://gre/modules/Services.jsm");
const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
const {installHosted, installPackaged} = require("devtools/app-actor-front");
const promise = require("sdk/core/promise");
window.addEventListener("message", function(event) {
@ -163,6 +165,39 @@ let UI = {
}
},
install: function(button, location) {
button.dataset.originalTextContent = button.textContent;
button.textContent = Utils.l10n("project.installing");
button.disabled = true;
let project = AppProjects.get(location);
let install;
if (project.type == "packaged") {
install = installPackaged(this.connection.client, this.listTabsResponse.webappsActor, project.location, project.packagedAppOrigin);
} else {
let manifestURLObject = Services.io.newURI(project.location, null, null);
let origin = Services.io.newURI(manifestURLObject.prePath, null, null);
let appId = origin.host;
let metadata = {
origin: origin.spec,
manifestURL: project.location
};
install = installHosted(this.connection.client, this.listTabsResponse.webappsActor, appId, metadata, project.manifest);
}
install.then(function () {
button.disabled = false;
button.textContent = Utils.l10n("project.installed");
setTimeout(function() {
button.textContent = button.dataset.originalTextContent;
}, 1500);
},
function (res) {
button.disabled = false;
let message = res.error + ": " + res.message;
alert(message);
this.connection.log(message);
});
},
start: function(location) {
let project = AppProjects.get(location);
let request = {
@ -223,8 +258,11 @@ let UI = {
this._getTargetForApp(manifest).then((target) => {
gDevTools.showToolbox(target,
null,
devtools.Toolbox.HostType.WINDOW,
this.connection.uid);
devtools.Toolbox.HostType.WINDOW).then(toolbox => {
this.connection.once(Connection.Events.DISCONNECTED, () => {
toolbox.destroy();
});
});
}, console.error);
},

View File

@ -25,7 +25,7 @@
<div id="new-packaged-project" onclick="UI.addPackaged()">&projects.addPackaged;</div>
<div id="new-hosted-project">&projects.addHosted;
<form onsubmit="UI.addHosted(); return false;" id="new-hosted-project-wrapper">
<input value="" id="url-input" type="url" pattern="https?://.+" placeholder="&projects.hostedManifestPlaceHolder;" size="50" />
<input value="" id="url-input" type="url" pattern="https?://.+" placeholder="&projects.hostedManifestPlaceHolder2;" size="50" />
<div onclick="UI.addHosted()" id="new-hosted-project-click"></div>
<input type="submit" hidden="true"></input>
</form>
@ -71,14 +71,10 @@
</div>
<div class="project-buttons">
<button class="project-button-refresh" onclick="UI.update(this.dataset.location)" template='{"type":"attribute","path":"location","name":"data-location"}'>&projects.reloadFiles;</button>
<!-- Not available until bug 911785 is fixed
<button class="device-action project-button-install" onclick="UI.install(this, this.dataset.location)" template='{"type":"attribute","path":"location","name":"data-location"}'>&projects.installApp;</button>
-->
<button class="device-action project-button-start" onclick="UI.start(this.dataset.location)" template='{"type":"attribute","path":"location","name":"data-location"}'>&projects.startApp;</button>
<button class="device-action project-button-stop" onclick="UI.stop(this.dataset.location)" template='{"type":"attribute","path":"location","name":"data-location"}'>&projects.stopApp;</button>
<!-- Not available until bug 911785 is fixed
<button class="device-action project-button-debug" onclick="UI.openToolbox(this.dataset.location)" template='{"type":"attribute","path":"location","name":"data-location"}'>&projects.debugApp;</button>
-->
</div>
<div class="project-errors" template='{"type":"textContent","path":"errors"}'></div>
<div class="project-warnings" template='{"type":"textContent","path":"warnings"}'></div>

View File

@ -0,0 +1,21 @@
/* 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/. */
const {Cu} = require("chrome");
const ObservableObject = require("devtools/shared/observable-object");
const {Simulator} = Cu.import("resource://gre/modules/devtools/Simulator.jsm");
let store = new ObservableObject({versions:[]});
function feedStore() {
store.object.versions = Simulator.availableVersions().map(v => {
return {version:v}
});
}
Simulator.on("register", feedStore);
Simulator.on("unregister", feedStore);
feedStore();
module.exports = store;

View File

@ -378,7 +378,7 @@ let gDevToolsBrowser = {
* Open the App Manager
*/
openAppManager: function(gBrowser) {
gBrowser.selectedTab = gBrowser.addTab("chrome://browser/content/devtools/app-manager/index.xul");
gBrowser.selectedTab = gBrowser.addTab("about:app-manager");
},
/**

View File

@ -1,14 +1,21 @@
<!DOCTYPE html>
<div id="id1"></div>
<div id="id2"></div>
<div id="id3">
<ul class="aList">
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
<li class="item">
<span id="id4"></span>
</li>
</ul>
</div>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>select last selected test</title>
</head>
<body>
<div id="id1"></div>
<div id="id2"></div>
<div id="id3">
<ul class="aList">
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
<li class="item">
<span id="id4"></span>
</li>
</ul>
</div>
</body>
</html>

View File

@ -30,23 +30,39 @@ function test() {
}
function endTests() {
toolbox.destroy();
toolbox = inspector = page1 = page2 = null;
gBrowser.removeCurrentTab();
finish();
executeSoon(() => {
toolbox.destroy();
toolbox = inspector = page1 = page2 = null;
gBrowser.removeCurrentTab();
finish();
});
}
function testReSelectingAnElement(id, callback) {
function loadPageAnd(page, callback) {
inspector.once("markuploaded", () => {
executeSoon(callback);
});
if (page) {
content.location = page;
} else {
content.location.reload();
}
}
function reloadAndReselect(id, callback) {
let div = content.document.getElementById(id);
inspector.selection.setNode(div);
inspector.once("inspector-updated", () => {
is(inspector.selection.node, div);
inspector.once("markuploaded", () => {
loadPageAnd(false, () => {
is(inspector.selection.node.id, id, "Node re-selected after reload");
callback();
executeSoon(callback);
});
content.location.reload();
});
inspector.selection.setNode(div);
}
// Test that nodes selected on the test page remain selected after reload
@ -54,10 +70,10 @@ function test() {
{
// Select a few nodes and check they are re-selected after reload of the same
// page
testReSelectingAnElement("id1", () => {
testReSelectingAnElement("id2", () => {
testReSelectingAnElement("id3", () => {
testReSelectingAnElement("id4", testBodySelectedOnNavigate);
reloadAndReselect("id1", () => {
reloadAndReselect("id2", () => {
reloadAndReselect("id3", () => {
reloadAndReselect("id4", testBodySelectedOnNavigate);
});
});
});
@ -68,15 +84,16 @@ function test() {
function testBodySelectedOnNavigate() {
// Last node selected was id4, go to a different page and check body is
// selected
inspector.once("markuploaded", () => {
is(
inspector.selection.node.tagName.toLowerCase(),
"body",
"Node not found, selecting body"
);
testSameNodeSelectedOnNavigateAwayAndBack();
loadPageAnd(page2, () => {
executeSoon(() => {
is(
inspector.selection.node.tagName.toLowerCase(),
"body",
"Node not found, body selected"
);
executeSoon(testSameNodeSelectedOnNavigateAwayAndBack);
});
});
content.location = page2;
}
// Test that the node selected on page 1 gets selected again after a navigation
@ -85,19 +102,25 @@ function test() {
// On page2, select id5
let id = "id5";
let div = content.document.getElementById(id);
inspector.selection.setNode(div);
inspector.once("inspector-updated", () => {
is(inspector.selection.node.id, id);
// go to page1 but do not select anything
inspector.once("markuploaded", () => {
// go back to page2 and check id5 is still the current selection
inspector.once("markuploaded", () => {
is(inspector.selection.node.id, id, "Node re-selected after navigation");
endTests();
executeSoon(() => {
// go to page1 but do not select anything
loadPageAnd(page1, () => {
executeSoon(() => {
// go back to page2 and check id5 is still the current selection
loadPageAnd(page2, () => {
is(inspector.selection.node.id, id, "Node re-selected after navigation");
executeSoon(endTests);
});
});
});
content.location = page2;
});
content.location = page1;
});
inspector.selection.setNode(div);
}
}

View File

@ -1,3 +1,10 @@
<!DOCTYPE html>
<div id="id5"></div>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>select last selected test</title>
</head>
<body>
<div id="id5"></div>
</body>
</html>

View File

@ -234,9 +234,11 @@ ResponsiveUI.prototype = {
onPageUnload: function() {
if (this.closing)
return;
this.touchEnableBefore = this.touchEventHandler.enabled;
this.disableTouch();
delete this.touchEventHandler;
if (this.touchEventHandler) {
this.touchEnableBefore = this.touchEventHandler.enabled;
this.disableTouch();
delete this.touchEventHandler;
}
},
/**

View File

@ -1041,7 +1041,9 @@ CssRuleView.prototype = {
this.element.parentNode.removeChild(this.element);
}
this.elementStyle.destroy();
if (this.elementStyle) {
this.elementStyle.destroy();
}
this.popup.destroy();
},
@ -1210,6 +1212,11 @@ CssRuleView.prototype = {
return this._showPseudoElements;
},
_getRuleViewHeaderClassName: function(isPseudo) {
let baseClassName = "theme-gutter ruleview-header";
return isPseudo ? baseClassName + " ruleview-expandable-header" : baseClassName;
},
/**
* Creates editor UI for each of the rules in _elementStyle.
*/
@ -1230,7 +1237,7 @@ CssRuleView.prototype = {
if (seenPseudoElement && !seenNormalElement && !rule.pseudoElement) {
seenNormalElement = true;
let div = this.doc.createElementNS(HTML_NS, "div");
div.className = "theme-gutter ruleview-header";
div.className = this._getRuleViewHeaderClassName();
div.textContent = this.selectedElementLabel;
this.element.appendChild(div);
}
@ -1238,7 +1245,7 @@ CssRuleView.prototype = {
let inheritedSource = rule.inheritedSource;
if (inheritedSource != lastInheritedSource) {
let div = this.doc.createElementNS(HTML_NS, "div");
div.className = "theme-gutter ruleview-header";
div.className = this._getRuleViewHeaderClassName();
div.textContent = inheritedSource;
lastInheritedSource = inheritedSource;
this.element.appendChild(div);
@ -1248,8 +1255,11 @@ CssRuleView.prototype = {
seenPseudoElement = true;
let div = this.doc.createElementNS(HTML_NS, "div");
div.className = "theme-gutter ruleview-header";
div.className = this._getRuleViewHeaderClassName(true);
div.textContent = this.pseudoElementLabel;
div.addEventListener("dblclick", () => {
this.togglePseudoElementVisibility(!this.showPseudoElements);
}, false);
let twisty = this.pseudoElementTwisty =
this.doc.createElementNS(HTML_NS, "span");

View File

@ -50,7 +50,11 @@
}
.ruleview-header {
vertical-align:middle;
vertical-align: middle;
height: 1.5em;
line-height: 1.5em;
}
}
.ruleview-header.ruleview-expandable-header {
cursor: pointer;
}

View File

@ -48,7 +48,10 @@ function testTopLeft()
ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are collapsed by twisty");
expander.click();
ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are expanded again");
expander.click();
// Make sure that dblclicking on the header container also toggles the pseudo elements
EventUtils.synthesizeMouseAtCenter(gutters[0], {clickCount: 2}, inspector.sidebar.getWindowForTab("ruleview"));
ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are collapsed by dblclicking");
let defaultView = element.ownerDocument.defaultView;
let elementRule = elementRules[0];

View File

@ -765,6 +765,7 @@ bin/libfreebl_32int64_3.so
@BINPATH@/webapprt/modules/Startup.jsm
@BINPATH@/webapprt/modules/WebappRT.jsm
@BINPATH@/webapprt/modules/WebappsHandler.jsm
@BINPATH@/webapprt/modules/RemoteDebugger.jsm
#endif
#ifdef MOZ_METRO

View File

@ -670,9 +670,9 @@ just addresses the organization to follow, e.g. "This site is run by " -->
<!ENTITY social.chatBar.label "Focus chats">
<!ENTITY social.chatBar.accesskey "c">
<!ENTITY social.markpage.accesskey "P">
<!ENTITY social.markpageMenu.accesskey "P">
<!ENTITY social.markpageMenu.label "Save Page To…">
<!ENTITY social.marklink.accesskey "L">
<!ENTITY social.marklinkMenu.accesskey "L">
<!ENTITY social.marklinkMenu.label "Save Link To…">
<!ENTITY getUserMedia.selectCamera.label "Camera to share:">

View File

@ -430,10 +430,10 @@ social.turnOff.accesskey=T
social.turnOn.label=Turn on %S
social.turnOn.accesskey=T
# LOCALIZATION NOTE (social.markpage.label): %S is the name of the social provider
social.markpage.label=Save Page to %S
# LOCALIZATION NOTE (social.marklink.label): %S is the name of the social provider
social.marklink.label=Save Link to %S
# LOCALIZATION NOTE (social.markpageMenu.label): %S is the name of the social provider
social.markpageMenu.label=Save Page to %S
# LOCALIZATION NOTE (social.marklinkMenu.label): %S is the name of the social provider
social.marklinkMenu.label=Save Link to %S
# LOCALIZATION NOTE (social.error.message): %1$S is brandShortName (e.g. Firefox), %2$S is the name of the social provider
social.error.message=%1$S is unable to connect with %2$S right now.

View File

@ -32,6 +32,9 @@
<!ENTITY connection.disconnecting "Disconnecting…">
<!ENTITY connection.cancel "Cancel">
<!ENTITY connection.or "or">
<!ENTITY connection.noSimulatorInstalled "No simulator installed.">
<!ENTITY connection.installFirstSimulator "Install simulator.">
<!ENTITY connection.installAnotherSimulator "Add">
<!ENTITY projects.localApps "Local Apps">
<!ENTITY projects.addApp "Add">
@ -45,5 +48,5 @@
<!ENTITY projects.startApp "Start">
<!ENTITY projects.stopApp "Stop">
<!ENTITY projects.debugApp "Debug">
<!ENTITY projects.hostedManifestPlaceHolder "http://example.com/app/webapp.manifest">
<!ENTITY projects.hostedManifestPlaceHolder2 "http://example.com/app/manifest.webapp">
<!ENTITY projects.noProject "No project linked. Add a new packaged app below (a directory) or a hosted app (link to a manifest file).">

View File

@ -11,6 +11,8 @@ device.deviceSize=Device size: %1$Sx%2$S (%3$S DPI)
connection.connectedToDevice=Connected to %1$S
connection.connectTo=Connect to %1$S:%2$S
project.filePickerTitle=Select a webapp folder
project.installing=Installing...
project.installed=Installed!
validator.nonExistingFolder=The project folder doesn't exists
validator.expectProjectFolder=The project folder ends up being a file
validator.wrongManifestFileName=Packaged apps require a manifest file that can only be named 'manifest.webapp' at project root folder

View File

@ -19,3 +19,4 @@
<!ENTITY showTabsInTaskbar.label "Show tab previews in the Windows taskbar">
<!ENTITY showTabsInTaskbar.accesskey "k">
<!ENTITY tabsGroup.label "Tabs">

View File

@ -11,27 +11,32 @@ def test(mod, path, entity = None):
"other-licenses/branding/firefox",
"browser/branding/official",
"services/sync"):
return False
if mod != "browser" and mod != "extensions/spellcheck":
# we only have exceptions for browser and extensions/spellcheck
return True
return "ignore"
if mod not in ("browser", "browser/metro", "extensions/spellcheck"):
# we only have exceptions for browser, metro and extensions/spellcheck
return "error"
if not entity:
# the only files to ignore are spell checkers and search
if mod == "extensions/spellcheck":
return False
return "ignore"
# browser
return not (re.match(r"searchplugins\/.+\.xml", path) or
re.match(r"chrome\/help\/images\/[A-Za-z-_]+\.png", path))
return "ignore" if re.match(r"searchplugins\/.+\.xml", path) else "error"
if mod == "extensions/spellcheck":
# l10n ships en-US dictionary or something, do compare
return True
return "error"
if path == "defines.inc":
return entity != "MOZ_LANGPACK_CONTRIBUTORS"
return "ignore" if entity == "MOZ_LANGPACK_CONTRIBUTORS" else "error"
if path != "chrome/browser-region/region.properties":
if mod == "browser" and path == "chrome/browser-region/region.properties":
# only region.properties exceptions remain, compare all others
return True
return not (re.match(r"browser\.search\.order\.[1-9]", entity) or
re.match(r"browser\.contentHandlers\.types\.[0-5]", entity) or
re.match(r"gecko\.handlerService\.schemes\.", entity) or
re.match(r"gecko\.handlerService\.defaultHandlersVersion", entity))
return ("ignore"
if (re.match(r"browser\.search\.order\.[1-9]", entity) or
re.match(r"browser\.contentHandlers\.types\.[0-5]", entity) or
re.match(r"gecko\.handlerService\.schemes\.", entity) or
re.match(r"gecko\.handlerService\.defaultHandlersVersion", entity))
else "error")
if mod == "browser/metro" and path == "chrome/region.properties":
return ("ignore"
if re.match(r"browser\.search\.order\.[1-9]", entity)
else "error")
return "error"

View File

@ -20,6 +20,8 @@ var ContextUI = {
init: function init() {
Elements.browsers.addEventListener('URLChanged', this, true);
Elements.browsers.addEventListener("AlertActive", this, true);
Elements.browsers.addEventListener("AlertClose", this, true);
Elements.tabList.addEventListener('TabSelect', this, true);
Elements.panelUI.addEventListener('ToolPanelShown', this, false);
Elements.panelUI.addEventListener('ToolPanelHidden', this, false);
@ -325,6 +327,10 @@ var ContextUI = {
case "ToolPanelHidden":
this.dismiss();
break;
case "AlertActive":
case "AlertClose":
ContentAreaObserver.updateContentArea();
break;
case "touchstart":
if (!BrowserUI.isStartTabVisible) {
this.dismiss();

View File

@ -46,9 +46,17 @@ var APZCObserver = {
let windowUtils = Browser.selectedBrowser.contentWindow.
QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils);
// findElementWithViewId will throw if it can't find it
let element;
try {
element = windowUtils.findElementWithViewId(ROOT_ID);
} catch (e) {
// Not present; nothing to do here
break;
}
windowUtils.setDisplayPortForElement(0, 0, ContentAreaObserver.width,
ContentAreaObserver.height,
windowUtils.findElementWithViewId(ROOT_ID));
element);
break;
case 'TabOpen': {
let browser = aEvent.originalTarget.linkedBrowser;

View File

@ -53,6 +53,7 @@
// Fire notification closed event.
let event = new Event('AlertClose');
event.notification = aItem;
this.dispatchEvent(event);
return aItem;

View File

@ -67,9 +67,6 @@
<method name="_clearFormatting">
<body>
<![CDATA[
if (!this._mayFormat)
return;
let controller = this.editor.selectionController;
let selection = controller.getSelection(controller.SELECTION_URLSECONDARY);
selection.removeAllRanges();
@ -417,6 +414,7 @@
switch (aData) {
case "browser.urlbar.formatting.enabled":
this._mayFormat = Services.prefs.getBoolPref(aData);
if (!this._mayFormat) this._clearFormatting();
break;
case "browser.urlbar.trimURLs":
this._mayTrimURLs = Services.prefs.getBoolPref(aData);
@ -433,6 +431,12 @@
<handlers>
<!-- Entering editing mode -->
<handler event="focus" phase="capturing">
<![CDATA[
this.beginEditing();
]]>
</handler>
<handler event="input" phase="capturing">
<![CDATA[
// Ensures that paste-and-go actually brings the URL bar into editing mode

View File

@ -1143,9 +1143,12 @@ Browser.MainDragger.prototype = {
},
_hideScrollbars: function _hideScrollbars() {
this._scrollScales.x = 0, this._scrollScales.y = 0;
this._scrollScales.x = 0;
this._scrollScales.y = 0;
this._horizontalScrollbar.removeAttribute("panning");
this._verticalScrollbar.removeAttribute("panning");
this._horizontalScrollbar.removeAttribute("width");
this._verticalScrollbar.removeAttribute("height");
this._horizontalScrollbar.style.MozTransform = "";
this._verticalScrollbar.style.MozTransform = "";
}

View File

@ -57,6 +57,7 @@ var Downloads = {
Services.obs.addObserver(this, "dl-request", true);
this._notificationBox = Browser.getNotificationBox();
this._notificationBox.addEventListener('AlertClose', this.handleEvent, true);
this._progress = new DownloadProgressListener(this);
this.manager.addListener(this._progress);
@ -225,6 +226,7 @@ var Downloads = {
accessKey: "",
callback: function() {
Downloads.cancelDownload(aDownload);
Downloads._downloadProgressIndicator.reset();
}
}
];
@ -397,6 +399,7 @@ var Downloads = {
accessKey: "",
callback: function() {
Downloads.cancelDownloads();
Downloads._downloadProgressIndicator.reset();
}
}
];
@ -431,6 +434,17 @@ var Downloads = {
}
},
handleEvent: function handleEvent(aEvent) {
switch (aEvent.type) {
case "AlertClose":
if (aEvent.notification.value == "download-complete" &&
!Downloads._notificationBox.getNotificationWithValue("download-complete")) {
Downloads._downloadProgressIndicator.reset();
}
break;
}
},
observe: function (aSubject, aTopic, aData) {
let message = "";
let msgTitle = "";
@ -459,7 +473,6 @@ var Downloads = {
this._showDownloadCompleteToast(download);
this._showDownloadCompleteNotification(download);
}
this._downloadProgressIndicator.reset();
this._progressNotificationInfo.clear();
this._downloadCount = 0;
this._notificationBox.removeNotification(this._progressNotification);
@ -469,7 +482,6 @@ var Downloads = {
case "dl-failed":
download = aSubject.QueryInterface(Ci.nsIDownload);
this._showDownloadFailedNotification(download);
this._downloadProgressIndicator.reset();
break;
case "dl-request":
setTimeout(function() {

View File

@ -36,6 +36,8 @@ MOCHITEST_METRO_FILES = \
browser_tilegrid.xul \
browser_topsites.js \
browser_urlbar.js \
browser_urlbar_highlightURLs.js \
browser_urlbar_trimURLs.js \
$(NULL)
ifndef MOZ_DEBUG

View File

@ -0,0 +1,171 @@
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const kHighlightPref = "browser.urlbar.formatting.enabled";
var gHighlightPrefValue;
function test() {
runTests();
}
function setUp() {
gHighlightPrefValue = SpecialPowers.getBoolPref(kHighlightPref);
SpecialPowers.setBoolPref(kHighlightPref, true);
yield addTab("about:blank");
}
function tearDown() {
SpecialPowers.setBoolPref(kHighlightPref, gHighlightPrefValue);
Browser.closeTab(Browser.selectedTab, { forceClose: true });
}
function testHighlight(aExpected) {
let urlbar = BrowserUI._edit;
urlbar.value = aExpected.replace(/[<>]/g, "");
let selectionController = urlbar.editor.selectionController;
let selection = selectionController.getSelection(selectionController.SELECTION_URLSECONDARY);
let value = urlbar.editor.rootElement.textContent;
let result = "";
for (let i = 0; i < selection.rangeCount; i++) {
let range = selection.getRangeAt(i).toString();
let pos = value.indexOf(range);
result += value.substring(0, pos) + "<" + range + ">";
value = value.substring(pos + range.length);
}
result += value;
is(result, aExpected, "test highight");
}
gTests.push({
desc: "Domain-based URIs (not in editing mode)",
setUp: setUp,
tearDown: tearDown,
run: function () {
let testcases = [
"<https://>mozilla.org",
"<https://>mözilla.org",
"<https://>mozilla.imaginatory",
"<https://www.>mozilla.org",
"<https://sub.>mozilla.org",
"<https://sub1.sub2.sub3.>mozilla.org",
"<www.>mozilla.org",
"<sub.>mozilla.org",
"<sub1.sub2.sub3.>mozilla.org",
"<http://ftp.>mozilla.org",
"<ftp://ftp.>mozilla.org",
"<https://sub.>mozilla.org",
"<https://sub1.sub2.sub3.>mozilla.org",
"<https://user:pass@sub1.sub2.sub3.>mozilla.org",
"<https://user:pass@>mozilla.org",
"<https://>mozilla.org</file.ext>",
"<https://>mozilla.org</sub/file.ext>",
"<https://>mozilla.org</sub/file.ext?foo>",
"<https://>mozilla.org</sub/file.ext?foo&bar>",
"<https://>mozilla.org</sub/file.ext?foo&bar#top>",
"<https://>mozilla.org</sub/file.ext?foo&bar#top>",
"<https://sub.>mozilla.org<:666/file.ext>",
"<sub.>mozilla.org<:666/file.ext>",
"localhost<:666/file.ext>",
"mailto:admin@mozilla.org",
"gopher://mozilla.org/",
"about:config",
"jar:http://mozilla.org/example.jar!/",
"view-source:http://mozilla.org/",
"foo9://mozilla.org/",
"foo+://mozilla.org/",
"foo.://mozilla.org/",
"foo-://mozilla.org/"
];
testcases.forEach(testHighlight);
}
});
gTests.push({
desc: "IP-based URIs (not in editing mode)",
setUp: setUp,
tearDown: tearDown,
run: function () {
let ips = [
"192.168.1.1",
"[::]",
"[::1]",
"[1::]",
"[::]",
"[::1]",
"[1::]",
"[1:2:3:4:5:6:7::]",
"[::1:2:3:4:5:6:7]",
"[1:2:a:B:c:D:e:F]",
"[1::8]",
"[1:2::8]",
"[fe80::222:19ff:fe11:8c76]",
"[0000:0123:4567:89AB:CDEF:abcd:ef00:0000]",
"[::192.168.1.1]",
"[1::0.0.0.0]",
"[1:2::255.255.255.255]",
"[1:2:3::255.255.255.255]",
"[1:2:3:4::255.255.255.255]",
"[1:2:3:4:5::255.255.255.255]",
"[1:2:3:4:5:6:255.255.255.255]"
];
let formats = [
"{ip}</file.ext>",
"{ip}<:666/file.ext>",
"<https://>{ip}",
"<https://>{ip}</file.ext>",
"<https://user:pass@>{ip}<:666/file.ext>",
"<http://user:pass@>{ip}<:666/file.ext>"
];
function testHighlightAllFormats(aIP) {
formats.forEach((aFormat) => testHighlight(aFormat.replace("{ip}", aIP)));
}
ips.forEach(testHighlightAllFormats);
}
});
gTests.push({
desc: "no highlighting (in editing mode)",
setUp: setUp,
tearDown: tearDown,
run: function () {
testHighlight("<https://>mozilla.org");
BrowserUI._edit.focus();
testHighlight("https://mozilla.org");
Browser.selectedBrowser.focus();
testHighlight("<https://>mozilla.org");
}
});
gTests.push({
desc: "no higlighting (pref disabled)",
setUp: setUp,
tearDown: tearDown,
run: function () {
testHighlight("<https://>mozilla.org");
SpecialPowers.setBoolPref(kHighlightPref, false);
testHighlight("https://mozilla.org");
SpecialPowers.setBoolPref(kHighlightPref, true);
testHighlight("<https://>mozilla.org");
}
});

View File

@ -0,0 +1,141 @@
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const kTrimPref = "browser.urlbar.trimURLs";
var gTrimPrefValue;
function test() {
runTests();
}
function setUp() {
gTrimPrefValue = SpecialPowers.getBoolPref(kTrimPref);
SpecialPowers.setBoolPref(kTrimPref, true);
yield addTab("about:blank");
}
function tearDown() {
SpecialPowers.setBoolPref(kTrimPref, gTrimPrefValue);
Browser.closeTab(Browser.selectedTab, { forceClose: true });
}
function testTrim(aOriginal, aTarget) {
let urlbar = BrowserUI._edit;
urlbar.value = aOriginal;
urlbar.valueIsTyped = false;
is(urlbar.value, aTarget || aOriginal, "url bar value set");
}
gTests.push({
desc: "URIs - trimming (pref enabled)",
setUp: setUp,
tearDown: tearDown,
run: function () {
let testcases = [
["http://mozilla.org/", "mozilla.org"],
["https://mozilla.org/", "https://mozilla.org"],
["http://mözilla.org/", "mözilla.org"],
["http://mozilla.imaginatory/", "mozilla.imaginatory"],
["http://www.mozilla.org/", "www.mozilla.org"],
["http://sub.mozilla.org/", "sub.mozilla.org"],
["http://sub1.sub2.sub3.mozilla.org/", "sub1.sub2.sub3.mozilla.org"],
["http://mozilla.org/file.ext", "mozilla.org/file.ext"],
["http://mozilla.org/sub/", "mozilla.org/sub/"],
["http://ftp.mozilla.org/", "http://ftp.mozilla.org"],
["http://ftp1.mozilla.org/", "http://ftp1.mozilla.org"],
["http://ftp42.mozilla.org/", "http://ftp42.mozilla.org"],
["http://ftpx.mozilla.org/", "ftpx.mozilla.org"],
["ftp://ftp.mozilla.org/", "ftp://ftp.mozilla.org"],
["ftp://ftp1.mozilla.org/", "ftp://ftp1.mozilla.org"],
["ftp://ftp42.mozilla.org/", "ftp://ftp42.mozilla.org"],
["ftp://ftpx.mozilla.org/", "ftp://ftpx.mozilla.org"],
["https://user:pass@mozilla.org/", "https://user:pass@mozilla.org"],
["http://user:pass@mozilla.org/", "http://user:pass@mozilla.org"],
["http://sub.mozilla.org:666/", "sub.mozilla.org:666"],
["https://[fe80::222:19ff:fe11:8c76]/file.ext"],
["http://[fe80::222:19ff:fe11:8c76]/", "[fe80::222:19ff:fe11:8c76]"],
["https://user:pass@[fe80::222:19ff:fe11:8c76]:666/file.ext"],
["http://user:pass@[fe80::222:19ff:fe11:8c76]:666/file.ext"],
["mailto:admin@mozilla.org"],
["gopher://mozilla.org/"],
["about:config"],
["jar:http://mozilla.org/example.jar!/"],
["view-source:http://mozilla.org/"]
];
for (let [original, target] of testcases)
testTrim(original, target);
}
});
gTests.push({
desc: "URIs - no trimming (pref disabled)",
setUp: setUp,
tearDown: tearDown,
run: function () {
SpecialPowers.setBoolPref(kTrimPref, false);
testTrim("http://mozilla.org/");
SpecialPowers.setBoolPref(kTrimPref, true);
testTrim("http://mozilla.org/", "mozilla.org");
}
});
gTests.push({
desc: "Loaded URI - copy/paste behavior",
setUp: setUp,
tearDown: tearDown,
run: function () {
let urlbar = BrowserUI._edit;
BrowserUI.goToURI("http://example.com/");
let pageLoaded = yield waitForCondition(
() => Browser.selectedBrowser.currentURI.spec == "http://example.com/");
ok(pageLoaded, "expected page should have loaded");
is(urlbar.value, "example.com", "trimmed value set");
yield showNavBar();
function clipboardCondition(aExpected) {
return () => aExpected == SpecialPowers.getClipboardData("text/unicode");
}
// Value set by browser -- should copy entire url (w/ scheme) on full select
urlbar.focus();
urlbar.select();
CommandUpdater.doCommand("cmd_copy");
let copy = yield waitForCondition(clipboardCondition("http://example.com/"));
ok(copy, "should copy entire url (w/ scheme) on full select");
// Value set by browser -- should copy selected text on partial select
urlbar.focus();
urlbar.select();
urlbar.selectionStart = 2;
CommandUpdater.doCommand("cmd_copy");
copy = yield waitForCondition(clipboardCondition("ample.com"));
ok(copy, "should copy selected text on partial select");
// Value set by user -- should not copy full string
urlbar.valueIsTyped = true;
urlbar.focus();
urlbar.select();
CommandUpdater.doCommand("cmd_copy");
copy = yield waitForCondition(clipboardCondition("example.com"));
ok(copy, "should not copy full string");
}
});

View File

@ -46,7 +46,8 @@
.ruleview-warning {
background: url("chrome://browser/skin/devtools/alerticon-warning.png");
-moz-margin-start: 5px;
vertical-align: middle;
display: inline-block;
vertical-align: top;
width: 13px;
height: 12px;
}

View File

@ -49,11 +49,6 @@
background-position: 0 0;
}
.preference-icon[type="tabs"],
.landingButton-icon[type="tabs"] {
background-position: -32px 0;
}
.preference-icon[type="content"],
.landingButton-icon[type="content"] {
background-position: -64px 0;

View File

@ -50,7 +50,8 @@
.ruleview-warning {
background: url("chrome://browser/skin/devtools/alerticon-warning.png");
-moz-margin-start: 5px;
vertical-align: middle;
display: inline-block;
vertical-align: top;
width: 13px;
height: 12px;
}

View File

@ -52,11 +52,6 @@
background-position: 0 0;
}
.preference-icon[type="tabs"],
.landingButton-icon[type="tabs"] {
background-position: -32px 0;
}
.preference-icon[type="content"],
.landingButton-icon[type="content"] {
background-position: -64px 0;

View File

@ -33,10 +33,12 @@
display: flex;
}
body.show-simulators .banner,
body.edit-connection .banner {
display: none !important;
}
body.show-simulators #banner-simulators,
body.edit-connection #banner-editing {
display: flex !important;
}
@ -70,10 +72,6 @@ body.edit-connection #banner-editing {
display: inline;
}
#start-simulator-box[simulators-count="0"] {
display: none;
}
/************** PIXELS **************/
* {
@ -193,8 +191,18 @@ button.action-cancel {
background: linear-gradient(to bottom, #69B8FF, #339FFF );
}
#banner-simulators .connected-indicator,
#banner-disconnected .connected-indicator,
#banner-editing .connected-indicator,
#banner-disconnecting .connected-indicator {
background: linear-gradient(to bottom, #375A87, #1C4375 );
}
#banner-simulators .banner-content > * {
display: inline-block;
}
#banner-simulators[simulator-count="0"] .found-simulator,
#banner-simulators:not([simulator-count="0"]) .no-simulator {
display: none;
}

View File

@ -46,7 +46,8 @@
.ruleview-warning {
background: url("chrome://browser/skin/devtools/alerticon-warning.png");
-moz-margin-start: 5px;
vertical-align: middle;
display: inline-block;
vertical-align: top;
width: 13px;
height: 12px;
}

View File

@ -52,11 +52,6 @@
background-position: 0 0;
}
.preference-icon[type="tabs"],
.landingButton-icon[type="tabs"] {
background-position: -32px 0;
}
.preference-icon[type="content"],
.landingButton-icon[type="content"] {
background-position: -64px 0;

View File

@ -19,7 +19,7 @@ def get_range_for(compilation_unit, debug_info):
if 'DW_TAG_compile_unit' in nfo:
search_cu = True
elif 'DW_TAG_' in nfo or not nfo.strip():
if name == compilation_unit:
if name == compilation_unit and ranges != '':
return int(ranges, 16)
name = ranges = ''
search_cu = False

View File

@ -20,7 +20,7 @@ interface nsIContentSecurityPolicy;
[ptr] native JSPrincipals(JSPrincipals);
[ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
[scriptable, builtinclass, uuid(dbda8bb0-3023-4aec-ad98-8e9931a29d70)]
[scriptable, builtinclass, uuid(551bf53d-203c-4ac4-8c0b-40aa7b5f1ad6)]
interface nsIPrincipal : nsISerializable
{
/**
@ -162,19 +162,19 @@ interface nsIPrincipal : nsISerializable
[noscript] attribute nsIContentSecurityPolicy csp;
/**
* Returns the extended origin of the principal.
* The extended origin is a string that has more information than the origin
* and can be used to isolate data or permissions between different
* principals while taking into account parameters like the app id or the
* fact that the principal is embedded in a mozbrowser.
* Some principals will return the origin for extendedOrigin.
* Some principals will assert if you try to access the extendedOrigin.
* Returns the jar prefix of the principal.
* The jar prefix is a string that can be used to isolate data or
* permissions between different principals while taking into account
* parameters like the app id or the fact that the principal is embedded in
* a mozbrowser.
* Some principals will return an empty string.
* Some principals will assert if you try to access the jarPrefix.
*
* The extendedOrigin is intended to be an opaque identifier. It is
* currently "human-readable" but no callers should assume it will stay
* as is and it might be crypto-hashed at some point.
* The jarPrefix is intended to be an opaque identifier. It is currently
* "human-readable" but no callers should assume it will stay as is and
* it might be crypto-hashed at some point.
*/
readonly attribute AUTF8String extendedOrigin;
readonly attribute AUTF8String jarPrefix;
/**
* The base domain of the codebase URI to which this principal pertains

View File

@ -10,7 +10,7 @@ interface nsIURI;
interface nsIChannel;
interface nsIDocShell;
[scriptable, uuid(ae486501-ec57-4ec8-a565-6880ca4ae6c4)]
[scriptable, uuid(d6475e53-9ece-4dc0-940c-095ac3d85363)]
interface nsIScriptSecurityManager : nsIXPCSecurityManager
{
///////////////// Security Checks //////////////////
@ -229,13 +229,12 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
const unsigned long UNKNOWN_APP_ID = 4294967295; // UINT32_MAX
/**
* Returns the extended origin for the uri.
* Returns the jar prefix for the app.
* appId can be NO_APP_ID or a valid app id. appId should not be
* UNKNOWN_APP_ID.
* inMozBrowser has to be true if the uri is inside a mozbrowser iframe.
* inMozBrowser has to be true if the app is inside a mozbrowser iframe.
*/
AUTF8String getExtendedOrigin(in nsIURI uri, in unsigned long appId,
in boolean inMozBrowser);
AUTF8String getJarPrefix(in unsigned long appId, in boolean inMozBrowser);
};
%{C++

View File

@ -65,7 +65,7 @@ public:
NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval);
NS_IMETHOD SubsumesIgnoringDomain(nsIPrincipal* other, bool* _retval);
NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal);
NS_IMETHOD GetExtendedOrigin(nsACString& aExtendedOrigin);
NS_IMETHOD GetJarPrefix(nsACString& aJarPrefix);
NS_IMETHOD GetAppStatus(uint16_t* aAppStatus);
NS_IMETHOD GetAppId(uint32_t* aAppStatus);
NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement);
@ -148,7 +148,7 @@ public:
NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval);
NS_IMETHOD SubsumesIgnoringDomain(nsIPrincipal* other, bool* _retval);
NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal);
NS_IMETHOD GetExtendedOrigin(nsACString& aExtendedOrigin);
NS_IMETHOD GetJarPrefix(nsACString& aJarPrefix);
NS_IMETHOD GetAppStatus(uint16_t* aAppStatus);
NS_IMETHOD GetAppId(uint32_t* aAppStatus);
NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement);

View File

@ -526,9 +526,9 @@ public:
namespace mozilla {
void
GetExtendedOrigin(nsIURI* aURI, uint32_t aAppid,
bool aInMozBrowser,
nsACString& aExtendedOrigin);
GetJarPrefix(uint32_t aAppid,
bool aInMozBrowser,
nsACString& aJarPrefix);
} // namespace mozilla

View File

@ -259,9 +259,10 @@ nsNullPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsP
}
NS_IMETHODIMP
nsNullPrincipal::GetExtendedOrigin(nsACString& aExtendedOrigin)
nsNullPrincipal::GetJarPrefix(nsACString& aJarPrefix)
{
return GetOrigin(getter_Copies(aExtendedOrigin));
aJarPrefix.Truncate();
return NS_OK;
}
NS_IMETHODIMP

View File

@ -424,11 +424,11 @@ nsPrincipal::SetDomain(nsIURI* aDomain)
}
NS_IMETHODIMP
nsPrincipal::GetExtendedOrigin(nsACString& aExtendedOrigin)
nsPrincipal::GetJarPrefix(nsACString& aJarPrefix)
{
MOZ_ASSERT(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
mozilla::GetExtendedOrigin(mCodebase, mAppId, mInMozBrowser, aExtendedOrigin);
mozilla::GetJarPrefix(mAppId, mInMozBrowser, aJarPrefix);
return NS_OK;
}
@ -773,9 +773,10 @@ nsExpandedPrincipal::GetWhiteList(nsTArray<nsCOMPtr<nsIPrincipal> >** aWhiteList
}
NS_IMETHODIMP
nsExpandedPrincipal::GetExtendedOrigin(nsACString& aExtendedOrigin)
nsExpandedPrincipal::GetJarPrefix(nsACString& aJarPrefix)
{
return GetOrigin(getter_Copies(aExtendedOrigin));
aJarPrefix.Truncate();
return NS_OK;
}
NS_IMETHODIMP

View File

@ -2004,7 +2004,7 @@ nsScriptSecurityManager::old_doGetObjectPrincipal(JS::Handle<JSObject*> aObj,
}
}
js::Class *jsClass = js::GetObjectClass(obj);
const js::Class *jsClass = js::GetObjectClass(obj);
do {
// Note: jsClass is set before this loop, and also at the
@ -2778,32 +2778,26 @@ nsScriptSecurityManager::InitPrefs()
namespace mozilla {
void
GetExtendedOrigin(nsIURI* aURI, uint32_t aAppId, bool aInMozBrowser,
nsACString& aExtendedOrigin)
GetJarPrefix(uint32_t aAppId, bool aInMozBrowser, nsACString& aJarPrefix)
{
MOZ_ASSERT(aURI);
MOZ_ASSERT(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
if (aAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
aAppId = nsIScriptSecurityManager::NO_APP_ID;
}
nsAutoCString origin;
nsPrincipal::GetOriginForURI(aURI, getter_Copies(origin));
aJarPrefix.Truncate();
// Fallback.
if (aAppId == nsIScriptSecurityManager::NO_APP_ID && !aInMozBrowser) {
aExtendedOrigin.Assign(origin);
return;
}
// aExtendedOrigin = appId + "+" + { 't', 'f' } "+" + origin;
aExtendedOrigin.Truncate();
aExtendedOrigin.AppendInt(aAppId);
aExtendedOrigin.Append('+');
aExtendedOrigin.Append(aInMozBrowser ? 't' : 'f');
aExtendedOrigin.Append('+');
aExtendedOrigin.Append(origin);
// aJarPrefix = appId + "+" + { 't', 'f' } + "+";
aJarPrefix.AppendInt(aAppId);
aJarPrefix.Append('+');
aJarPrefix.Append(aInMozBrowser ? 't' : 'f');
aJarPrefix.Append('+');
return;
}
@ -2811,13 +2805,12 @@ GetExtendedOrigin(nsIURI* aURI, uint32_t aAppId, bool aInMozBrowser,
} // namespace mozilla
NS_IMETHODIMP
nsScriptSecurityManager::GetExtendedOrigin(nsIURI* aURI,
uint32_t aAppId,
bool aInMozBrowser,
nsACString& aExtendedOrigin)
nsScriptSecurityManager::GetJarPrefix(uint32_t aAppId,
bool aInMozBrowser,
nsACString& aJarPrefix)
{
MOZ_ASSERT(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
mozilla::GetExtendedOrigin(aURI, aAppId, aInMozBrowser, aExtendedOrigin);
mozilla::GetJarPrefix(aAppId, aInMozBrowser, aJarPrefix);
return NS_OK;
}

View File

@ -81,7 +81,7 @@ nsSecurityNameSet::InitializeNameSet(nsIScriptContext* aScriptContext)
break;
obj = proto;
}
JSClass *objectClass = JS_GetClass(obj);
const JSClass *objectClass = JS_GetClass(obj);
JS::Rooted<JS::Value> v(cx);
if (!JS_GetProperty(cx, global, "netscape", &v))

View File

@ -166,9 +166,10 @@ nsSystemPrincipal::SetSecurityPolicy(void* aSecurityPolicy)
}
NS_IMETHODIMP
nsSystemPrincipal::GetExtendedOrigin(nsACString& aExtendedOrigin)
nsSystemPrincipal::GetJarPrefix(nsACString& aJarPrefix)
{
return GetOrigin(getter_Copies(aExtendedOrigin));
aJarPrefix.Truncate();
return NS_OK;
}
NS_IMETHODIMP

View File

@ -11,8 +11,8 @@ MOCHITEST_FILES = test_bug423375.html \
test_app_principal_equality.html \
$(NULL)
# extendedOrigin test doesn't work on Windows, see bug 776296.
# jarPrefix test doesn't work on Windows, see bug 776296.
ifneq ($(OS_ARCH),WINNT)
MOCHITEST_CHROME_FILES = test_principal_extendedorigin_appid_appstatus.html \
MOCHITEST_CHROME_FILES = test_principal_jarprefix_origin_appid_appstatus.html \
$(NULL)
endif

View File

@ -21,10 +21,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=470804
Passing a null targetURL to checkLoadURIWithPrincipal shouldn't crash
**/
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
const nsIScriptSecurityManager = Components.interfaces.nsIScriptSecurityManager;
var secMan = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(nsIScriptSecurityManager);
const nsIScriptSecurityManager = SpecialPowers.Ci.nsIScriptSecurityManager;
var secMan = SpecialPowers.Services.scriptSecurityManager;
var principal = SpecialPowers.wrap(document).nodePrincipal;
isnot(principal, undefined, "Should have a principal");
isnot(principal, null, "Should have a non-null principal");

View File

@ -5,7 +5,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=758258
-->
<head>
<meta charset="utf-8">
<title>Test for nsIPrincipal extendedOrigin, appStatus and appId</title>
<title>Test for nsIPrincipal jarPrefix, origin, appStatus and appId</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
</head>
@ -294,20 +294,20 @@ function checkIFrame(aFrame, data) {
}
if (!data.isapp && !data.browser) {
is(principal.extendedOrigin, principal.origin,
'extendedOrigin should return the origin for non-app and non-browsers principals');
is(principal.jarPrefix, "",
'jarPrefix should return an empty string for non-app and non-browsers principals');
} else {
isnot(principal.extendedOrigin, principal.origin,
'extendedOrigin should not return the origin for apps or mozbrowsers');
isnot(principal.jarPrefix, "",
'jarPrefix should not return an empty string for apps or mozbrowsers');
}
if (data.test.indexOf("eo-unique") != -1) {
is(eoList.indexOf(principal.extendedOrigin), -1,
"extendedOrigin should be unique");
is(eoList.indexOf(principal.jarPrefix + principal.origin), -1,
"extended origin should be unique");
}
if (data.test.indexOf("eo-as-last") != -1) {
is(principal.extendedOrigin, eoList[eoList.length-1],
"extendedOrigin should be the same as the last inserted one");
is(principal.jarPrefix + principal.origin, eoList[eoList.length-1],
"extended origin should be the same as the last inserted one");
}
is(principal.isInBrowserElement, !!data.browser,
@ -325,17 +325,19 @@ function checkIFrame(aFrame, data) {
"check childPrincipal.isInBrowserElement");
if (data.test.indexOf("child-has-same-eo") != -1) {
is(childPrincipal.extendedOrigin, principal.extendedOrigin,
"child should have the same extendedOrigin as parent");
is(childPrincipal.jarPrefix + childPrincipal.origin,
principal.jarPrefix + principal.origin,
"child should have the same extended origin as parent");
is(childPrincipal.appStatus, principal.appStatus,
"child should have the same appStatus if it has the same extendedOrigin");
"child should have the same appStatus if it has the same extended origin");
is(childPrincipal.appId, principal.appId,
"child should have the same appId if it has the same extendedOrigin");
"child should have the same appId if it has the same extended origin");
}
if (data.test.indexOf("child-has-different-eo") != -1) {
isnot(childPrincipal.extendedOrigin, principal.extendedOrigin,
"child should not have the same extendedOrigin as parent");
isnot(childPrincipal.jarPrefix + childPrincipal.origin,
principal.jarPrefix + principal.origin,
"child should not have the same extended origin as parent");
}
if (data.test.indexOf("child-has-same-appstatus") != -1) {
@ -359,7 +361,7 @@ function checkIFrame(aFrame, data) {
}
}
eoList.push(principal.extendedOrigin);
eoList.push(principal.jarPrefix + principal.origin);
checkedCount++;
if (checkedCount == checksTodo) {
@ -373,8 +375,10 @@ function checkIFrame(aFrame, data) {
is('appStatus' in document.nodePrincipal, true,
'appStatus should be present in nsIPrincipal');
is('extendedOrigin' in document.nodePrincipal, true,
'extendedOrigin should be present in nsIPrincipal');
is('jarPrefix' in document.nodePrincipal, true,
'jarPrefix should be present in nsIPrincipal');
is('origin' in document.nodePrincipal, true,
'origin should be present in nsIPrincipal');
is('appId' in document.nodePrincipal, true,
'appId should be present in nsIPrincipal');

View File

@ -257,11 +257,11 @@ static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
static PLDHashTable sEventListenerManagersHash;
class DOMEventListenerManagersHashReporter MOZ_FINAL : public MemoryReporterBase
class DOMEventListenerManagersHashReporter MOZ_FINAL : public MemoryUniReporter
{
public:
DOMEventListenerManagersHashReporter()
: MemoryReporterBase(
: MemoryUniReporter(
"explicit/dom/event-listener-managers-hash",
KIND_HEAP,
UNITS_BYTES,

Some files were not shown because too many files have changed in this diff Show More