mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge mozilla-central to UX
This commit is contained in:
commit
3df5c32616
2
CLOBBER
2
CLOBBER
@ -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)
|
||||
|
@ -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; }
|
||||
|
@ -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
|
||||
|
||||
|
@ -273,6 +273,7 @@ public:
|
||||
protected:
|
||||
// Accessible
|
||||
virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
|
||||
virtual void CacheChildren() MOZ_OVERRIDE;
|
||||
|
||||
// HyperTextAccessible
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
||||
|
@ -142,8 +142,6 @@ public:
|
||||
protected:
|
||||
// Accessible
|
||||
virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
|
||||
|
||||
virtual void CacheChildren() MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
},
|
||||
|
67
b2g/components/WebappsUpdateTimer.js
Normal file
67
b2g/components/WebappsUpdateTimer.js
Normal 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]);
|
95
b2g/components/WebappsUpdater.jsm
Normal file
95
b2g/components/WebappsUpdater.jsm
Normal 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([]);
|
||||
}
|
||||
}
|
||||
};
|
@ -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',
|
||||
]
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"revision": "e3d925b497f5b996c9c397c200805fbcc62bc823",
|
||||
"revision": "9e3d2b3f6706916168b9ad9bb96084c01df8771f",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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"/>
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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");
|
||||
|
@ -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"
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -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 },
|
||||
};
|
||||
|
@ -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 },
|
||||
|
@ -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
|
||||
|
@ -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');">
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
@ -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
|
@ -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);
|
||||
})
|
||||
);
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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") {
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
},
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
},
|
||||
|
||||
|
@ -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);
|
||||
},
|
||||
|
||||
|
@ -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>
|
||||
|
21
browser/devtools/app-manager/simulators-store.js
Normal file
21
browser/devtools/app-manager/simulators-store.js
Normal 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;
|
@ -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");
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -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>
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
@ -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;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
|
@ -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:">
|
||||
|
@ -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.
|
||||
|
@ -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).">
|
||||
|
@ -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
|
||||
|
@ -19,3 +19,4 @@
|
||||
|
||||
<!ENTITY showTabsInTaskbar.label "Show tab previews in the Windows taskbar">
|
||||
<!ENTITY showTabsInTaskbar.accesskey "k">
|
||||
<!ENTITY tabsGroup.label "Tabs">
|
||||
|
@ -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"
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -53,6 +53,7 @@
|
||||
|
||||
// Fire notification closed event.
|
||||
let event = new Event('AlertClose');
|
||||
event.notification = aItem;
|
||||
this.dispatchEvent(event);
|
||||
|
||||
return aItem;
|
||||
|
@ -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
|
||||
|
@ -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 = "";
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
});
|
||||
|
141
browser/metro/base/tests/mochitest/browser_urlbar_trimURLs.js
Normal file
141
browser/metro/base/tests/mochitest/browser_urlbar_trimURLs.js
Normal 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");
|
||||
}
|
||||
});
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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++
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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');
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user