зеркало из https://github.com/mozilla/gecko-dev.git
Merge backout.
This commit is contained in:
Коммит
c0ed906c04
2
CLOBBER
2
CLOBBER
|
@ -17,4 +17,4 @@
|
|||
#
|
||||
# Modifying this file will now automatically clobber the buildbot machines \o/
|
||||
#
|
||||
Bug 859894: Hopefully the final WebIDL clobber.
|
||||
Bug 856358: Needs a clobber because it renames an IDL file. See also bug 860894.
|
||||
|
|
|
@ -3,6 +3,8 @@ dnl Local autoconf macros used with mozilla
|
|||
dnl The contents of this file are under the Public Domain.
|
||||
dnl
|
||||
|
||||
builtin(include, build/autoconf/acwinpaths.m4)dnl
|
||||
builtin(include, build/autoconf/hooks.m4)dnl
|
||||
builtin(include, build/autoconf/config.status.m4)dnl
|
||||
builtin(include, build/autoconf/toolchain.m4)dnl
|
||||
builtin(include, build/autoconf/ccache.m4)dnl
|
||||
|
@ -14,7 +16,6 @@ builtin(include, build/autoconf/altoptions.m4)dnl
|
|||
builtin(include, build/autoconf/mozprog.m4)dnl
|
||||
builtin(include, build/autoconf/mozheader.m4)dnl
|
||||
builtin(include, build/autoconf/mozcommonheader.m4)dnl
|
||||
builtin(include, build/autoconf/acwinpaths.m4)dnl
|
||||
builtin(include, build/autoconf/lto.m4)dnl
|
||||
builtin(include, build/autoconf/gcc-pr49911.m4)dnl
|
||||
builtin(include, build/autoconf/gcc-pr39608.m4)dnl
|
||||
|
|
|
@ -42,11 +42,24 @@ SmsProtocolHandler.prototype = {
|
|||
|
||||
newChannel: function Proto_newChannel(aURI) {
|
||||
let number = TelURIParser.parseURI('sms', aURI.spec);
|
||||
let body = "";
|
||||
let query = aURI.spec.split("?")[1];
|
||||
|
||||
if (number) {
|
||||
if (query) {
|
||||
let params = query.split("&");
|
||||
params.forEach(function(aParam) {
|
||||
let [name, value] = aParam.split("=");
|
||||
if (name === "body") {
|
||||
body = decodeURIComponent(value);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (number || body) {
|
||||
cpmm.sendAsyncMessage("sms-handler", {
|
||||
number: number,
|
||||
type: "websms/sms" });
|
||||
number: number || "",
|
||||
type: "websms/sms",
|
||||
body: body });
|
||||
}
|
||||
|
||||
throw Components.results.NS_ERROR_ILLEGAL_VALUE;
|
||||
|
|
|
@ -351,6 +351,8 @@
|
|||
@BINPATH@/components/BrowserElementParent.js
|
||||
@BINPATH@/components/ContactManager.js
|
||||
@BINPATH@/components/ContactManager.manifest
|
||||
@BINPATH@/components/NavigatorPropertyHelper.js
|
||||
@BINPATH@/components/NavigatorPropertyHelper.manifest
|
||||
@BINPATH@/components/PermissionSettings.js
|
||||
@BINPATH@/components/PermissionSettings.manifest
|
||||
@BINPATH@/components/PermissionPromptService.js
|
||||
|
|
|
@ -108,26 +108,24 @@ static bool IsArg(const char* arg, const char* s)
|
|||
|
||||
#ifdef XP_WIN
|
||||
/*
|
||||
* AttachToTestsConsole - Windows helper for when we are running
|
||||
* AttachToTestHarness - Windows helper for when we are running
|
||||
* in the immersive environment. Firefox is launched by Windows in
|
||||
* response to a request by metrotestharness, which is launched by
|
||||
* runtests.py. As such stdout in fx doesn't point to the right
|
||||
* stream. This helper touches up stdout such that test output gets
|
||||
* routed to the console the tests are run in.
|
||||
* routed to a named pipe metrotestharness creates and dumps to its
|
||||
* stdout.
|
||||
*/
|
||||
static void AttachToTestsConsole(DWORD aProcessId)
|
||||
static void AttachToTestHarness()
|
||||
{
|
||||
if (!AttachConsole(aProcessId)) {
|
||||
OutputDebugStringW(L"Could not attach to console.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
HANDLE winOut = CreateFileA("CONOUT$",
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
// attach to the metrotestharness named logging pipe
|
||||
HANDLE winOut = CreateFileA("\\\\.\\pipe\\metrotestharness",
|
||||
GENERIC_WRITE,
|
||||
FILE_SHARE_WRITE, 0,
|
||||
OPEN_EXISTING, 0, 0);
|
||||
|
||||
if (winOut == INVALID_HANDLE_VALUE) {
|
||||
OutputDebugStringW(L"Could not attach to console.\n");
|
||||
OutputDebugStringW(L"Could not create named logging pipe.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -355,15 +353,6 @@ static int do_main(int argc, char* argv[], nsIFile *xreDirectory)
|
|||
if (isspace(*ptr)) {
|
||||
*ptr = '\0';
|
||||
ptr++;
|
||||
// Check for the console id the metrotestharness passes in, we need
|
||||
// to connect up to this so test output goes to the right place.
|
||||
if (ptr && !strncmp(ptr, kMetroConsoleIdParam, strlen(kMetroConsoleIdParam))) {
|
||||
DWORD processId = strtol(ptr + strlen(kMetroConsoleIdParam), nullptr, 10);
|
||||
if (processId > 0) {
|
||||
AttachToTestsConsole(processId);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
newArgv[newArgc] = ptr;
|
||||
newArgc++;
|
||||
continue;
|
||||
|
@ -372,6 +361,10 @@ static int do_main(int argc, char* argv[], nsIFile *xreDirectory)
|
|||
}
|
||||
if (ptr == newArgv[newArgc-1])
|
||||
newArgc--;
|
||||
|
||||
// attach browser stdout to metrotestharness stdout
|
||||
AttachToTestHarness();
|
||||
|
||||
int result = XRE_main(newArgc, newArgv, appData, mainFlags);
|
||||
XRE_FreeAppData(appData);
|
||||
return result;
|
||||
|
|
|
@ -1014,8 +1014,8 @@ pref("services.sync.prefs.sync.security.OCSP.disable_button.managecrl", true);
|
|||
pref("services.sync.prefs.sync.security.OCSP.enabled", true);
|
||||
pref("services.sync.prefs.sync.security.OCSP.require", true);
|
||||
pref("services.sync.prefs.sync.security.default_personal_cert", true);
|
||||
pref("services.sync.prefs.sync.security.enable_ssl3", true);
|
||||
pref("services.sync.prefs.sync.security.enable_tls", true);
|
||||
pref("services.sync.prefs.sync.security.security.tls.version.min", true);
|
||||
pref("services.sync.prefs.sync.security.security.tls.version.max", true);
|
||||
pref("services.sync.prefs.sync.signon.rememberSignons", true);
|
||||
pref("services.sync.prefs.sync.spellchecker.dictionary", true);
|
||||
pref("services.sync.prefs.sync.xpinstall.whitelist.required", true);
|
||||
|
|
|
@ -140,7 +140,8 @@ a {
|
|||
}
|
||||
|
||||
#defaultSnippet1,
|
||||
#defaultSnippet2 {
|
||||
#defaultSnippet2,
|
||||
#rightsSnippet {
|
||||
display: block;
|
||||
min-height: 38px;
|
||||
background: 30px center no-repeat;
|
||||
|
@ -148,8 +149,13 @@ a {
|
|||
-moz-padding-start: 79px;
|
||||
}
|
||||
|
||||
#rightsSnippet[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#defaultSnippet1:-moz-dir(rtl),
|
||||
#defaultSnippet2:-moz-dir(rtl) {
|
||||
#defaultSnippet2:-moz-dir(rtl),
|
||||
#rightsSnippet:-moz-dir(rtl) {
|
||||
background-position: right 30px center;
|
||||
}
|
||||
|
||||
|
@ -351,7 +357,8 @@ body[narrow] #restorePreviousSession::before {
|
|||
*/
|
||||
@media not all and (max-resolution: 1dppx) {
|
||||
#defaultSnippet1,
|
||||
#defaultSnippet2 {
|
||||
#defaultSnippet2,
|
||||
#rightsSnippet {
|
||||
background-size: 40px;
|
||||
}
|
||||
|
||||
|
|
|
@ -273,10 +273,6 @@ function setupSearchEngine()
|
|||
if (searchEngineInfo && searchEngineInfo.image) {
|
||||
logoElt.parentNode.hidden = false;
|
||||
logoElt.src = searchEngineInfo.image;
|
||||
#ifdef XP_MACOSX
|
||||
if (searchEngineInfo.imageHD && !window.matchMedia("(max-resolution: 1dppx)").matches)
|
||||
logoElt.src = searchEngineInfo.imageHD;
|
||||
#endif
|
||||
logoElt.alt = searchEngineName;
|
||||
searchText.placeholder = "";
|
||||
}
|
||||
|
@ -347,6 +343,19 @@ function loadSnippets()
|
|||
let _snippetsShown = false;
|
||||
function showSnippets()
|
||||
{
|
||||
let snippetsElt = document.getElementById("snippets");
|
||||
|
||||
// Show about:rights notification, if needed.
|
||||
let showRights = document.documentElement.getAttribute("showKnowYourRights");
|
||||
if (showRights) {
|
||||
let rightsElt = document.getElementById("rightsSnippet");
|
||||
let anchor = rightsElt.getElementsByTagName("a")[0];
|
||||
anchor.href = "about:rights";
|
||||
snippetsElt.appendChild(rightsElt);
|
||||
rightsElt.removeAttribute("hidden");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gSnippetsMap)
|
||||
throw new Error("Snippets map has not properly been initialized");
|
||||
if (_snippetsShown) {
|
||||
|
@ -357,7 +366,6 @@ function showSnippets()
|
|||
}
|
||||
_snippetsShown = true;
|
||||
|
||||
let snippetsElt = document.getElementById("snippets");
|
||||
let snippets = gSnippetsMap.get("snippets");
|
||||
// If there are remotely fetched snippets, try to to show them.
|
||||
if (snippets) {
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
<span id="defaultSnippet1">&abouthome.defaultSnippet1.v1;</span>
|
||||
<span id="defaultSnippet2">&abouthome.defaultSnippet2.v1;</span>
|
||||
</div>
|
||||
<span id="rightsSnippet" hidden="true">&abouthome.rightsSnippet;</span>
|
||||
<div id="snippets"/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -177,7 +177,7 @@ let gGestureSupport = {
|
|||
* The swipe gesture start event.
|
||||
*/
|
||||
_setupSwipeGesture: function GS__setupSwipeGesture(aEvent) {
|
||||
if (!this._swipeNavigatesHistory(aEvent) || !gHistorySwipeAnimation.active)
|
||||
if (!this._swipeNavigatesHistory(aEvent))
|
||||
return;
|
||||
|
||||
let canGoBack = gHistorySwipeAnimation.canGoBack();
|
||||
|
@ -534,15 +534,10 @@ let gHistorySwipeAnimation = {
|
|||
* by the platform/configuration.
|
||||
*/
|
||||
init: function HSA_init() {
|
||||
if (!this._isSupported() || this._getMaxSnapshots() < 1)
|
||||
if (!this._isSupported())
|
||||
return;
|
||||
|
||||
gBrowser.addEventListener("pagehide", this, false);
|
||||
gBrowser.addEventListener("pageshow", this, false);
|
||||
gBrowser.addEventListener("popstate", this, false);
|
||||
gBrowser.tabContainer.addEventListener("TabClose", this, false);
|
||||
|
||||
this.active = true;
|
||||
this.active = false;
|
||||
this.isLTR = document.documentElement.mozMatchesSelector(
|
||||
":-moz-locale-dir(ltr)");
|
||||
this._trackedSnapshots = [];
|
||||
|
@ -550,6 +545,16 @@ let gHistorySwipeAnimation = {
|
|||
this._boxWidth = -1;
|
||||
this._maxSnapshots = this._getMaxSnapshots();
|
||||
this._lastSwipeDir = "";
|
||||
|
||||
// We only want to activate history swipe animations if we store snapshots.
|
||||
// If we don't store any, we handle horizontal swipes without animations.
|
||||
if (this._maxSnapshots > 0) {
|
||||
this.active = true;
|
||||
gBrowser.addEventListener("pagehide", this, false);
|
||||
gBrowser.addEventListener("pageshow", this, false);
|
||||
gBrowser.addEventListener("popstate", this, false);
|
||||
gBrowser.tabContainer.addEventListener("TabClose", this, false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -581,10 +586,12 @@ let gHistorySwipeAnimation = {
|
|||
this._historyIndex = gBrowser.webNavigation.sessionHistory.index;
|
||||
this._canGoBack = this.canGoBack();
|
||||
this._canGoForward = this.canGoForward();
|
||||
this._takeSnapshot();
|
||||
this._installPrevAndNextSnapshots();
|
||||
this._addBoxes();
|
||||
this._lastSwipeDir = "";
|
||||
if (this.active) {
|
||||
this._takeSnapshot();
|
||||
this._installPrevAndNextSnapshots();
|
||||
this._addBoxes();
|
||||
this._lastSwipeDir = "";
|
||||
}
|
||||
}
|
||||
this.updateAnimation(0);
|
||||
},
|
||||
|
|
|
@ -317,26 +317,6 @@ SocialUI = {
|
|||
}
|
||||
},
|
||||
|
||||
disableWithConfirmation: function SocialUI_disableWithConfirmation() {
|
||||
let brandShortName = document.getElementById("bundle_brand").getString("brandShortName");
|
||||
let dialogTitle = gNavigatorBundle.getFormattedString("social.remove.confirmationOK",
|
||||
[Social.provider.name]);
|
||||
let text = gNavigatorBundle.getFormattedString("social.remove.confirmationLabel",
|
||||
[Social.provider.name, brandShortName]);
|
||||
let okButtonText = dialogTitle;
|
||||
|
||||
let ps = Services.prompt;
|
||||
let flags = ps.BUTTON_TITLE_IS_STRING * ps.BUTTON_POS_0 +
|
||||
ps.BUTTON_TITLE_CANCEL * ps.BUTTON_POS_1 +
|
||||
ps.BUTTON_POS_0_DEFAULT;
|
||||
|
||||
let confirmationIndex = ps.confirmEx(null, dialogTitle, text, flags,
|
||||
okButtonText, null, null, null, {});
|
||||
if (confirmationIndex == 0) {
|
||||
Social.deactivateFromOrigin(Social.provider.origin);
|
||||
}
|
||||
},
|
||||
|
||||
get _chromeless() {
|
||||
// Is this a popup window that doesn't want chrome shown?
|
||||
let docElem = document.documentElement;
|
||||
|
|
|
@ -2276,7 +2276,15 @@ function BrowserOnAboutPageLoad(doc) {
|
|||
|
||||
// Inject search engine and snippets URL.
|
||||
let docElt = doc.documentElement;
|
||||
// set the following attributes BEFORE searchEngineURL, which triggers to
|
||||
// show the snippets when it's set.
|
||||
docElt.setAttribute("snippetsURL", AboutHomeUtils.snippetsURL);
|
||||
if (AboutHomeUtils.showKnowYourRights) {
|
||||
docElt.setAttribute("showKnowYourRights", "true");
|
||||
// Set pref to indicate we've shown the notification.
|
||||
let currentVersion = Services.prefs.getIntPref("browser.rights.version");
|
||||
Services.prefs.setBoolPref("browser.rights." + currentVersion + ".shown", true);
|
||||
}
|
||||
docElt.setAttribute("snippetsVersion", AboutHomeUtils.snippetsVersion);
|
||||
docElt.setAttribute("searchEngineName",
|
||||
AboutHomeUtils.defaultSearchEngine.name);
|
||||
|
|
|
@ -9,14 +9,14 @@ XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
|||
XPCOMUtils.defineLazyModuleGetter(this, "AboutHomeUtils",
|
||||
"resource:///modules/AboutHomeUtils.jsm");
|
||||
|
||||
let gRightsVersion = Services.prefs.getIntPref("browser.rights.version");
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
// Ensure we don't pollute prefs for next tests.
|
||||
try {
|
||||
Services.prefs.clearUserPref("network.cookies.cookieBehavior");
|
||||
} catch (ex) {}
|
||||
try {
|
||||
Services.prefs.clearUserPref("network.cookie.lifetimePolicy");
|
||||
} catch (ex) {}
|
||||
Services.prefs.clearUserPref("network.cookies.cookieBehavior");
|
||||
Services.prefs.clearUserPref("network.cookie.lifetimePolicy");
|
||||
Services.prefs.clearUserPref("browser.rights.override");
|
||||
Services.prefs.clearUserPref("browser.rights." + gRightsVersion + ".shown");
|
||||
});
|
||||
|
||||
let gTests = [
|
||||
|
@ -200,6 +200,50 @@ let gTests = [
|
|||
}
|
||||
},
|
||||
|
||||
{
|
||||
desc: "Check if the 'Know Your Rights default snippet is shown when 'browser.rights.override' pref is set",
|
||||
beforeRun: function ()
|
||||
{
|
||||
Services.prefs.setBoolPref("browser.rights.override", false);
|
||||
},
|
||||
setup: function () { },
|
||||
run: function (aSnippetsMap)
|
||||
{
|
||||
let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
|
||||
let showRights = AboutHomeUtils.showKnowYourRights;
|
||||
|
||||
ok(showRights, "AboutHomeUtils.showKnowYourRights should be TRUE");
|
||||
|
||||
let snippetsElt = doc.getElementById("snippets");
|
||||
ok(snippetsElt, "Found snippets element");
|
||||
is(snippetsElt.getElementsByTagName("a")[0].href, "about:rights", "Snippet link is present.");
|
||||
|
||||
Services.prefs.clearUserPref("browser.rights.override");
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
desc: "Check if the 'Know Your Rights default snippet is NOT shown when 'browser.rights.override' pref is NOT set",
|
||||
beforeRun: function ()
|
||||
{
|
||||
Services.prefs.setBoolPref("browser.rights.override", true);
|
||||
},
|
||||
setup: function () { },
|
||||
run: function (aSnippetsMap)
|
||||
{
|
||||
let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
|
||||
let rightsData = AboutHomeUtils.knowYourRightsData;
|
||||
|
||||
ok(!rightsData, "AboutHomeUtils.knowYourRightsData should be FALSE");
|
||||
|
||||
let snippetsElt = doc.getElementById("snippets");
|
||||
ok(snippetsElt, "Found snippets element");
|
||||
ok(snippetsElt.getElementsByTagName("a")[0].href != "about:rights", "Snippet link should not point to about:rights.");
|
||||
|
||||
Services.prefs.clearUserPref("browser.rights.override");
|
||||
}
|
||||
}
|
||||
|
||||
];
|
||||
|
||||
function test()
|
||||
|
@ -210,6 +254,9 @@ function test()
|
|||
for (let test of gTests) {
|
||||
info(test.desc);
|
||||
|
||||
if (test.beforeRun)
|
||||
yield test.beforeRun();
|
||||
|
||||
let tab = yield promiseNewTabLoadEvent("about:home", "DOMContentLoaded");
|
||||
|
||||
// Must wait for both the snippets map and the browser attributes, since
|
||||
|
|
|
@ -110,7 +110,7 @@ function test1() {
|
|||
|
||||
var plugin = getTestPlugin();
|
||||
ok(plugin, "Should have a test plugin");
|
||||
plugin.disabled = false;
|
||||
plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
|
||||
plugin.blocklisted = false;
|
||||
prepareTest(test2, gTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ function test2() {
|
|||
|
||||
var plugin = getTestPlugin();
|
||||
ok(plugin, "Should have a test plugin");
|
||||
plugin.disabled = true;
|
||||
plugin.enabledState = Ci.nsIPluginTag.STATE_DISABLED;
|
||||
prepareTest(test3, gTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ function test4(tab, win) {
|
|||
|
||||
function prepareTest5() {
|
||||
var plugin = getTestPlugin();
|
||||
plugin.disabled = false;
|
||||
plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
|
||||
plugin.blocklisted = true;
|
||||
prepareTest(test5, gTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ function test7() {
|
|||
ok(gTestBrowser.missingPlugins.has("application/x-test"), "Test 7, Should know about application/x-test");
|
||||
|
||||
var plugin = getTestPlugin();
|
||||
plugin.disabled = false;
|
||||
plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
|
||||
plugin.blocklisted = false;
|
||||
Services.prefs.setBoolPref("plugins.click_to_play", true);
|
||||
|
||||
|
@ -523,7 +523,7 @@ function test14() {
|
|||
ok(objLoadingContent.activated, "Test 14, Plugin should be activated");
|
||||
|
||||
var plugin = getTestPlugin();
|
||||
plugin.disabled = false;
|
||||
plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
|
||||
plugin.blocklisted = false;
|
||||
Services.prefs.setBoolPref("plugins.click_to_play", true);
|
||||
prepareTest(test15, gTestRoot + "plugin_alternate_content.html");
|
||||
|
|
|
@ -20,7 +20,7 @@ browser.jar:
|
|||
content/browser/aboutDialog.css (content/aboutDialog.css)
|
||||
content/browser/aboutRobots.xhtml (content/aboutRobots.xhtml)
|
||||
content/browser/abouthome/aboutHome.xhtml (content/abouthome/aboutHome.xhtml)
|
||||
* content/browser/abouthome/aboutHome.js (content/abouthome/aboutHome.js)
|
||||
content/browser/abouthome/aboutHome.js (content/abouthome/aboutHome.js)
|
||||
* content/browser/abouthome/aboutHome.css (content/abouthome/aboutHome.css)
|
||||
content/browser/abouthome/noise.png (content/abouthome/noise.png)
|
||||
content/browser/abouthome/snippet1.png (content/abouthome/snippet1.png)
|
||||
|
|
|
@ -20,8 +20,4 @@ EXTRA_PP_COMPONENTS = \
|
|||
|
||||
EXTRA_JS_MODULES = distribution.js
|
||||
|
||||
ifdef MOZILLA_OFFICIAL
|
||||
DEFINES += -DOFFICIAL_BUILD=1
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -56,6 +56,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
|
|||
XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
|
||||
"resource:///modules/RecentWindow.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
|
||||
const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser";
|
||||
const PREF_PLUGINS_UPDATEURL = "plugins.update.url";
|
||||
|
||||
|
@ -236,7 +239,8 @@ BrowserGlue.prototype = {
|
|||
this._onPlacesShutdown();
|
||||
break;
|
||||
case "idle":
|
||||
if (this._idleService.idleTime > BOOKMARKS_BACKUP_IDLE_TIME * 1000)
|
||||
if ((this._idleService.idleTime > BOOKMARKS_BACKUP_IDLE_TIME * 1000) &&
|
||||
this._shouldBackupBookmarks())
|
||||
this._backupBookmarks();
|
||||
break;
|
||||
case "distribution-customization-complete":
|
||||
|
@ -297,7 +301,8 @@ BrowserGlue.prototype = {
|
|||
|
||||
reporter.onInit().then(function record() {
|
||||
try {
|
||||
reporter.getProvider("org.mozilla.searches").recordSearch(data,
|
||||
let name = subject.QueryInterface(Ci.nsISearchEngine).name;
|
||||
reporter.getProvider("org.mozilla.searches").recordSearch(name,
|
||||
"urlbar");
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
|
@ -516,11 +521,6 @@ BrowserGlue.prototype = {
|
|||
|
||||
// All initial windows have opened.
|
||||
_onWindowsRestored: function BG__onWindowsRestored() {
|
||||
// Show about:rights notification, if needed.
|
||||
if (this._shouldShowRights()) {
|
||||
this._showRightsNotification();
|
||||
}
|
||||
|
||||
// Show update notification, if needed.
|
||||
if (Services.prefs.prefHasUserValue("app.update.postupdate"))
|
||||
this._showUpdateNotification();
|
||||
|
@ -746,78 +746,6 @@ BrowserGlue.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* _shouldShowRights - Determines if the user should be shown the
|
||||
* about:rights notification. The notification should *not* be shown if
|
||||
* we've already shown the current version, or if the override pref says to
|
||||
* never show it. The notification *should* be shown if it's never been seen
|
||||
* before, if a newer version is available, or if the override pref says to
|
||||
* always show it.
|
||||
*/
|
||||
_shouldShowRights: function BG__shouldShowRights() {
|
||||
// Look for an unconditional override pref. If set, do what it says.
|
||||
// (true --> never show, false --> always show)
|
||||
try {
|
||||
return !Services.prefs.getBoolPref("browser.rights.override");
|
||||
} catch (e) { }
|
||||
// Ditto, for the legacy EULA pref.
|
||||
try {
|
||||
return !Services.prefs.getBoolPref("browser.EULA.override");
|
||||
} catch (e) { }
|
||||
|
||||
#ifndef OFFICIAL_BUILD
|
||||
// Non-official builds shouldn't shouldn't show the notification.
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// Look to see if the user has seen the current version or not.
|
||||
var currentVersion = Services.prefs.getIntPref("browser.rights.version");
|
||||
try {
|
||||
return !Services.prefs.getBoolPref("browser.rights." + currentVersion + ".shown");
|
||||
} catch (e) { }
|
||||
|
||||
// Legacy: If the user accepted a EULA, we won't annoy them with the
|
||||
// equivalent about:rights page until the version changes.
|
||||
try {
|
||||
return !Services.prefs.getBoolPref("browser.EULA." + currentVersion + ".accepted");
|
||||
} catch (e) { }
|
||||
|
||||
// We haven't shown the notification before, so do so now.
|
||||
return true;
|
||||
},
|
||||
|
||||
_showRightsNotification: function BG__showRightsNotification() {
|
||||
// Stick the notification onto the selected tab of the active browser window.
|
||||
var win = this.getMostRecentBrowserWindow();
|
||||
var notifyBox = win.gBrowser.getNotificationBox();
|
||||
|
||||
var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
|
||||
var rightsBundle = Services.strings.createBundle("chrome://global/locale/aboutRights.properties");
|
||||
|
||||
var buttonLabel = rightsBundle.GetStringFromName("buttonLabel");
|
||||
var buttonAccessKey = rightsBundle.GetStringFromName("buttonAccessKey");
|
||||
var productName = brandBundle.GetStringFromName("brandFullName");
|
||||
var notifyRightsText = rightsBundle.formatStringFromName("notifyRightsText", [productName], 1);
|
||||
|
||||
var buttons = [
|
||||
{
|
||||
label: buttonLabel,
|
||||
accessKey: buttonAccessKey,
|
||||
popup: null,
|
||||
callback: function(aNotificationBar, aButton) {
|
||||
win.openUILinkIn("about:rights", "tab");
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
// Set pref to indicate we've shown the notification.
|
||||
var currentVersion = Services.prefs.getIntPref("browser.rights.version");
|
||||
Services.prefs.setBoolPref("browser.rights." + currentVersion + ".shown", true);
|
||||
|
||||
var notification = notifyBox.appendNotification(notifyRightsText, "about-rights", null, notifyBox.PRIORITY_INFO_LOW, buttons);
|
||||
notification.persistence = -1; // Until user closes it
|
||||
},
|
||||
|
||||
_showUpdateNotification: function BG__showUpdateNotification() {
|
||||
Services.prefs.clearUserPref("app.update.postupdate");
|
||||
|
||||
|
@ -981,126 +909,129 @@ BrowserGlue.prototype = {
|
|||
importBookmarks = true;
|
||||
} catch(ex) {}
|
||||
|
||||
// Check if Safe Mode or the user has required to restore bookmarks from
|
||||
// default profile's bookmarks.html
|
||||
var restoreDefaultBookmarks = false;
|
||||
try {
|
||||
restoreDefaultBookmarks =
|
||||
Services.prefs.getBoolPref("browser.bookmarks.restore_default_bookmarks");
|
||||
if (restoreDefaultBookmarks) {
|
||||
// Ensure that we already have a bookmarks backup for today.
|
||||
this._backupBookmarks();
|
||||
importBookmarks = true;
|
||||
}
|
||||
} catch(ex) {}
|
||||
Task.spawn(function() {
|
||||
// Check if Safe Mode or the user has required to restore bookmarks from
|
||||
// default profile's bookmarks.html
|
||||
var restoreDefaultBookmarks = false;
|
||||
try {
|
||||
restoreDefaultBookmarks =
|
||||
Services.prefs.getBoolPref("browser.bookmarks.restore_default_bookmarks");
|
||||
if (restoreDefaultBookmarks) {
|
||||
// Ensure that we already have a bookmarks backup for today.
|
||||
if (this._shouldBackupBookmarks())
|
||||
yield this._backupBookmarks();
|
||||
importBookmarks = true;
|
||||
}
|
||||
} catch(ex) {}
|
||||
|
||||
// If the user did not require to restore default bookmarks, or import
|
||||
// from bookmarks.html, we will try to restore from JSON
|
||||
if (importBookmarks && !restoreDefaultBookmarks && !importBookmarksHTML) {
|
||||
// get latest JSON backup
|
||||
var bookmarksBackupFile = PlacesUtils.backups.getMostRecent("json");
|
||||
if (bookmarksBackupFile) {
|
||||
// restore from JSON backup
|
||||
PlacesUtils.restoreBookmarksFromJSONFile(bookmarksBackupFile);
|
||||
importBookmarks = false;
|
||||
}
|
||||
else {
|
||||
// We have created a new database but we don't have any backup available
|
||||
importBookmarks = true;
|
||||
var dirService = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties);
|
||||
var bookmarksHTMLFile = dirService.get("BMarks", Ci.nsILocalFile);
|
||||
if (bookmarksHTMLFile.exists()) {
|
||||
// If bookmarks.html is available in current profile import it...
|
||||
importBookmarksHTML = true;
|
||||
// If the user did not require to restore default bookmarks, or import
|
||||
// from bookmarks.html, we will try to restore from JSON
|
||||
if (importBookmarks && !restoreDefaultBookmarks && !importBookmarksHTML) {
|
||||
// get latest JSON backup
|
||||
var bookmarksBackupFile = PlacesUtils.backups.getMostRecent("json");
|
||||
if (bookmarksBackupFile) {
|
||||
// restore from JSON backup
|
||||
PlacesUtils.restoreBookmarksFromJSONFile(bookmarksBackupFile);
|
||||
importBookmarks = false;
|
||||
}
|
||||
else {
|
||||
// ...otherwise we will restore defaults
|
||||
restoreDefaultBookmarks = true;
|
||||
// We have created a new database but we don't have any backup available
|
||||
importBookmarks = true;
|
||||
var dirService = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties);
|
||||
var bookmarksHTMLFile = dirService.get("BMarks", Ci.nsILocalFile);
|
||||
if (bookmarksHTMLFile.exists()) {
|
||||
// If bookmarks.html is available in current profile import it...
|
||||
importBookmarksHTML = true;
|
||||
}
|
||||
else {
|
||||
// ...otherwise we will restore defaults
|
||||
restoreDefaultBookmarks = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If bookmarks are not imported, then initialize smart bookmarks. This
|
||||
// happens during a common startup.
|
||||
// Otherwise, if any kind of import runs, smart bookmarks creation should be
|
||||
// delayed till the import operations has finished. Not doing so would
|
||||
// cause them to be overwritten by the newly imported bookmarks.
|
||||
if (!importBookmarks) {
|
||||
// Now apply distribution customized bookmarks.
|
||||
// This should always run after Places initialization.
|
||||
this._distributionCustomizer.applyBookmarks();
|
||||
this.ensurePlacesDefaultQueriesInitialized();
|
||||
}
|
||||
else {
|
||||
// An import operation is about to run.
|
||||
// Don't try to recreate smart bookmarks if autoExportHTML is true or
|
||||
// smart bookmarks are disabled.
|
||||
var autoExportHTML = false;
|
||||
try {
|
||||
autoExportHTML = Services.prefs.getBoolPref("browser.bookmarks.autoExportHTML");
|
||||
} catch(ex) {}
|
||||
var smartBookmarksVersion = 0;
|
||||
try {
|
||||
smartBookmarksVersion = Services.prefs.getIntPref("browser.places.smartBookmarksVersion");
|
||||
} catch(ex) {}
|
||||
if (!autoExportHTML && smartBookmarksVersion != -1)
|
||||
Services.prefs.setIntPref("browser.places.smartBookmarksVersion", 0);
|
||||
|
||||
// Get bookmarks.html file location
|
||||
var dirService = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties);
|
||||
|
||||
var bookmarksURI = null;
|
||||
if (restoreDefaultBookmarks) {
|
||||
// User wants to restore bookmarks.html file from default profile folder
|
||||
bookmarksURI = NetUtil.newURI("resource:///defaults/profile/bookmarks.html");
|
||||
// If bookmarks are not imported, then initialize smart bookmarks. This
|
||||
// happens during a common startup.
|
||||
// Otherwise, if any kind of import runs, smart bookmarks creation should be
|
||||
// delayed till the import operations has finished. Not doing so would
|
||||
// cause them to be overwritten by the newly imported bookmarks.
|
||||
if (!importBookmarks) {
|
||||
// Now apply distribution customized bookmarks.
|
||||
// This should always run after Places initialization.
|
||||
this._distributionCustomizer.applyBookmarks();
|
||||
this.ensurePlacesDefaultQueriesInitialized();
|
||||
}
|
||||
else {
|
||||
var bookmarksFile = dirService.get("BMarks", Ci.nsILocalFile);
|
||||
if (bookmarksFile.exists())
|
||||
bookmarksURI = NetUtil.newURI(bookmarksFile);
|
||||
}
|
||||
|
||||
if (bookmarksURI) {
|
||||
// Import from bookmarks.html file.
|
||||
// An import operation is about to run.
|
||||
// Don't try to recreate smart bookmarks if autoExportHTML is true or
|
||||
// smart bookmarks are disabled.
|
||||
var autoExportHTML = false;
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromURL(bookmarksURI.spec, true).then(null,
|
||||
function onFailure() {
|
||||
Cu.reportError("Bookmarks.html file could be corrupt.");
|
||||
}
|
||||
).then(
|
||||
function onComplete() {
|
||||
// Now apply distribution customized bookmarks.
|
||||
// This should always run after Places initialization.
|
||||
this._distributionCustomizer.applyBookmarks();
|
||||
// Ensure that smart bookmarks are created once the operation is
|
||||
// complete.
|
||||
this.ensurePlacesDefaultQueriesInitialized();
|
||||
}.bind(this)
|
||||
);
|
||||
} catch (err) {
|
||||
Cu.reportError("Bookmarks.html file could be corrupt. " + err);
|
||||
autoExportHTML = Services.prefs.getBoolPref("browser.bookmarks.autoExportHTML");
|
||||
} catch(ex) {}
|
||||
var smartBookmarksVersion = 0;
|
||||
try {
|
||||
smartBookmarksVersion = Services.prefs.getIntPref("browser.places.smartBookmarksVersion");
|
||||
} catch(ex) {}
|
||||
if (!autoExportHTML && smartBookmarksVersion != -1)
|
||||
Services.prefs.setIntPref("browser.places.smartBookmarksVersion", 0);
|
||||
|
||||
// Get bookmarks.html file location
|
||||
var dirService = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties);
|
||||
|
||||
var bookmarksURI = null;
|
||||
if (restoreDefaultBookmarks) {
|
||||
// User wants to restore bookmarks.html file from default profile folder
|
||||
bookmarksURI = NetUtil.newURI("resource:///defaults/profile/bookmarks.html");
|
||||
}
|
||||
}
|
||||
else {
|
||||
Cu.reportError("Unable to find bookmarks.html file.");
|
||||
else {
|
||||
var bookmarksFile = dirService.get("BMarks", Ci.nsILocalFile);
|
||||
if (bookmarksFile.exists())
|
||||
bookmarksURI = NetUtil.newURI(bookmarksFile);
|
||||
}
|
||||
|
||||
if (bookmarksURI) {
|
||||
// Import from bookmarks.html file.
|
||||
try {
|
||||
BookmarkHTMLUtils.importFromURL(bookmarksURI.spec, true).then(null,
|
||||
function onFailure() {
|
||||
Cu.reportError("Bookmarks.html file could be corrupt.");
|
||||
}
|
||||
).then(
|
||||
function onComplete() {
|
||||
// Now apply distribution customized bookmarks.
|
||||
// This should always run after Places initialization.
|
||||
this._distributionCustomizer.applyBookmarks();
|
||||
// Ensure that smart bookmarks are created once the operation is
|
||||
// complete.
|
||||
this.ensurePlacesDefaultQueriesInitialized();
|
||||
}.bind(this)
|
||||
);
|
||||
} catch (err) {
|
||||
Cu.reportError("Bookmarks.html file could be corrupt. " + err);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Cu.reportError("Unable to find bookmarks.html file.");
|
||||
}
|
||||
|
||||
// Reset preferences, so we won't try to import again at next run
|
||||
if (importBookmarksHTML)
|
||||
Services.prefs.setBoolPref("browser.places.importBookmarksHTML", false);
|
||||
if (restoreDefaultBookmarks)
|
||||
Services.prefs.setBoolPref("browser.bookmarks.restore_default_bookmarks",
|
||||
false);
|
||||
}
|
||||
|
||||
// Reset preferences, so we won't try to import again at next run
|
||||
if (importBookmarksHTML)
|
||||
Services.prefs.setBoolPref("browser.places.importBookmarksHTML", false);
|
||||
if (restoreDefaultBookmarks)
|
||||
Services.prefs.setBoolPref("browser.bookmarks.restore_default_bookmarks",
|
||||
false);
|
||||
}
|
||||
|
||||
// Initialize bookmark archiving on idle.
|
||||
// Once a day, either on idle or shutdown, bookmarks are backed up.
|
||||
if (!this._isIdleObserver) {
|
||||
this._idleService.addIdleObserver(this, BOOKMARKS_BACKUP_IDLE_TIME);
|
||||
this._isIdleObserver = true;
|
||||
}
|
||||
// Initialize bookmark archiving on idle.
|
||||
// Once a day, either on idle or shutdown, bookmarks are backed up.
|
||||
if (!this._isIdleObserver) {
|
||||
this._idleService.addIdleObserver(this, BOOKMARKS_BACKUP_IDLE_TIME);
|
||||
this._isIdleObserver = true;
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1118,55 +1049,77 @@ BrowserGlue.prototype = {
|
|||
this._isIdleObserver = false;
|
||||
}
|
||||
|
||||
this._backupBookmarks();
|
||||
let waitingForBackupToComplete = true;
|
||||
if (this._shouldBackupBookmarks()) {
|
||||
waitingForBackupToComplete = false;
|
||||
this._backupBookmarks().then(
|
||||
function onSuccess() {
|
||||
waitingForBackupToComplete = true;
|
||||
},
|
||||
function onFailure() {
|
||||
Cu.reportError("Unable to backup bookmarks.");
|
||||
waitingForBackupToComplete = true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Backup bookmarks to bookmarks.html to support apps that depend
|
||||
// on the legacy format.
|
||||
try {
|
||||
// If this fails to get the preference value, we don't export.
|
||||
if (Services.prefs.getBoolPref("browser.bookmarks.autoExportHTML")) {
|
||||
// Exceptionally, since this is a non-default setting and HTML format is
|
||||
// discouraged in favor of the JSON backups, we spin the event loop on
|
||||
// shutdown, to wait for the export to finish. We cannot safely spin
|
||||
// the event loop on shutdown until we include a watchdog to prevent
|
||||
// potential hangs (bug 518683). The asynchronous shutdown operations
|
||||
// will then be handled by a shutdown service (bug 435058).
|
||||
let shutdownComplete = false;
|
||||
BookmarkHTMLUtils.exportToFile(FileUtils.getFile("BMarks", [])).then(
|
||||
function onSuccess() {
|
||||
shutdownComplete = true;
|
||||
},
|
||||
function onFailure() {
|
||||
// There is no point in reporting errors since we are shutting down.
|
||||
shutdownComplete = true;
|
||||
}
|
||||
);
|
||||
let thread = Services.tm.currentThread;
|
||||
while (!shutdownComplete) {
|
||||
thread.processNextEvent(true);
|
||||
let waitingForHTMLExportToComplete = true;
|
||||
// If this fails to get the preference value, we don't export.
|
||||
if (Services.prefs.getBoolPref("browser.bookmarks.autoExportHTML")) {
|
||||
// Exceptionally, since this is a non-default setting and HTML format is
|
||||
// discouraged in favor of the JSON backups, we spin the event loop on
|
||||
// shutdown, to wait for the export to finish. We cannot safely spin
|
||||
// the event loop on shutdown until we include a watchdog to prevent
|
||||
// potential hangs (bug 518683). The asynchronous shutdown operations
|
||||
// will then be handled by a shutdown service (bug 435058).
|
||||
waitingForHTMLExportToComplete = false;
|
||||
BookmarkHTMLUtils.exportToFile(FileUtils.getFile("BMarks", [])).then(
|
||||
function onSuccess() {
|
||||
waitingForHTMLExportToComplete = true;
|
||||
},
|
||||
function onFailure() {
|
||||
Cu.reportError("Unable to auto export html.");
|
||||
waitingForHTMLExportToComplete = true;
|
||||
}
|
||||
}
|
||||
} catch(ex) { /* Don't export */ }
|
||||
);
|
||||
}
|
||||
|
||||
let thread = Services.tm.currentThread;
|
||||
while (!waitingForBackupToComplete || !waitingForHTMLExportToComplete) {
|
||||
thread.processNextEvent(true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Backup bookmarks if needed.
|
||||
* Determine whether to backup bookmarks or not.
|
||||
* @return true if bookmarks should be backed up, false if not.
|
||||
*/
|
||||
_backupBookmarks: function BG__backupBookmarks() {
|
||||
_shouldBackupBookmarks: function BG__shouldBackupBookmarks() {
|
||||
let lastBackupFile = PlacesUtils.backups.getMostRecent();
|
||||
|
||||
// Backup bookmarks if there are no backups or the maximum interval between
|
||||
// Should backup bookmarks if there are no backups or the maximum interval between
|
||||
// backups elapsed.
|
||||
if (!lastBackupFile ||
|
||||
new Date() - PlacesUtils.backups.getDateForFile(lastBackupFile) > BOOKMARKS_BACKUP_INTERVAL) {
|
||||
return (!lastBackupFile ||
|
||||
new Date() - PlacesUtils.backups.getDateForFile(lastBackupFile) > BOOKMARKS_BACKUP_INTERVAL);
|
||||
},
|
||||
|
||||
/**
|
||||
* Backup bookmarks.
|
||||
*/
|
||||
_backupBookmarks: function BG__backupBookmarks() {
|
||||
return Task.spawn(function() {
|
||||
// Backup bookmarks if there are no backups or the maximum interval between
|
||||
// backups elapsed.
|
||||
let maxBackups = BOOKMARKS_BACKUP_MAX_BACKUPS;
|
||||
try {
|
||||
maxBackups = Services.prefs.getIntPref("browser.bookmarks.max_backups");
|
||||
}
|
||||
catch(ex) { /* Use default. */ }
|
||||
|
||||
PlacesUtils.backups.create(maxBackups); // Don't force creation.
|
||||
}
|
||||
yield PlacesUtils.backups.create(maxBackups); // Don't force creation.
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -470,7 +470,7 @@ var PlacesOrganizer = {
|
|||
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||
let fpCallback = function fpCallback_done(aResult) {
|
||||
if (aResult != Ci.nsIFilePicker.returnCancel) {
|
||||
PlacesUtils.backups.saveBookmarksToJSONFile(fp.file);
|
||||
BookmarkJSONUtils.exportToFile(fp.file);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -706,10 +706,6 @@ var gAdvancedPane = {
|
|||
/*
|
||||
* Preferences:
|
||||
*
|
||||
* security.enable_ssl3
|
||||
* - true if SSL 3 encryption is enabled, false otherwise
|
||||
* security.enable_tls
|
||||
* - true if TLS encryption is enabled, false otherwise
|
||||
* security.default_personal_cert
|
||||
* - a string:
|
||||
* "Select Automatically" select a certificate automatically when a site
|
||||
|
|
|
@ -91,9 +91,6 @@
|
|||
<preference id="browser.search.update" name="browser.search.update" type="bool"/>
|
||||
|
||||
<!-- Encryption tab -->
|
||||
<preference id="security.enable_ssl3" name="security.enable_ssl3" type="bool"/>
|
||||
<preference id="security.enable_tls" name="security.enable_tls" type="bool"/>
|
||||
|
||||
<preference id="security.default_personal_cert" name="security.default_personal_cert" type="string"/>
|
||||
|
||||
<preference id="security.disable_button.openCertManager"
|
||||
|
@ -124,7 +121,7 @@
|
|||
#endif
|
||||
<tab id="networkTab" label="&networkTab.label;" helpTopic="prefs-advanced-network"/>
|
||||
<tab id="updateTab" label="&updateTab.label;" helpTopic="prefs-advanced-update"/>
|
||||
<tab id="encryptionTab" label="&encryptionTab.label;" helpTopic="prefs-advanced-encryption"/>
|
||||
<tab id="encryptionTab" label="&certificateTab.label;" helpTopic="prefs-advanced-encryption"/>
|
||||
</tabs>
|
||||
|
||||
<tabpanels flex="1">
|
||||
|
@ -384,39 +381,9 @@
|
|||
</groupbox>
|
||||
</tabpanel>
|
||||
|
||||
<!-- Encryption -->
|
||||
<!-- Certificates -->
|
||||
<tabpanel id="encryptionPanel" orient="vertical">
|
||||
|
||||
<!-- Protocols -->
|
||||
<groupbox id="protocolsGroup">
|
||||
<caption label="&protocols.label;"/>
|
||||
|
||||
<grid>
|
||||
<columns>
|
||||
<column flex="1"/>
|
||||
<column flex="1"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<hbox>
|
||||
<checkbox id="useSSL3" label="&useSSL3.label;"
|
||||
accesskey="&useSSL3.accesskey;"
|
||||
preference="security.enable_ssl3"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<checkbox id="useTLS1" label="&useTLS1.label;"
|
||||
accesskey="&useTLS1.accesskey;"
|
||||
preference="security.enable_tls"/>
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</groupbox>
|
||||
|
||||
<!-- Certificates -->
|
||||
<groupbox id="certificatesGroup">
|
||||
<caption id="CertGroupCaption" label="&certificates.label;"/>
|
||||
|
||||
<description id="CertSelectionDesc" control="certSelection">&certSelection.description;</description>
|
||||
|
||||
<!--
|
||||
|
@ -426,7 +393,7 @@
|
|||
-->
|
||||
<radiogroup id="certSelection" orient="horizontal" preftype="string"
|
||||
preference="security.default_personal_cert"
|
||||
aria-labelledby="CertGroupCaption CertSelectionDesc">
|
||||
aria-labelledby="CertSelectionDesc">
|
||||
<radio label="&certs.auto;" accesskey="&certs.auto.accesskey;"
|
||||
value="Select Automatically"/>
|
||||
<radio label="&certs.ask;" accesskey="&certs.ask.accesskey;"
|
||||
|
@ -462,7 +429,6 @@
|
|||
#ifdef XP_MACOSX
|
||||
</vbox>
|
||||
#endif
|
||||
</groupbox>
|
||||
</tabpanel>
|
||||
|
||||
</tabpanels>
|
||||
|
|
|
@ -680,10 +680,6 @@ var gAdvancedPane = {
|
|||
/*
|
||||
* Preferences:
|
||||
*
|
||||
* security.enable_ssl3
|
||||
* - true if SSL 3 encryption is enabled, false otherwise
|
||||
* security.enable_tls
|
||||
* - true if TLS encryption is enabled, false otherwise
|
||||
* security.default_personal_cert
|
||||
* - a string:
|
||||
* "Select Automatically" select a certificate automatically when a site
|
||||
|
|
|
@ -103,13 +103,6 @@
|
|||
type="bool"/>
|
||||
|
||||
<!-- Encryption tab -->
|
||||
<preference id="security.enable_ssl3"
|
||||
name="security.enable_ssl3"
|
||||
type="bool"/>
|
||||
<preference id="security.enable_tls"
|
||||
name="security.enable_tls"
|
||||
type="bool"/>
|
||||
|
||||
<preference id="security.default_personal_cert"
|
||||
name="security.default_personal_cert"
|
||||
type="string"/>
|
||||
|
@ -146,7 +139,7 @@
|
|||
#endif
|
||||
<tab id="networkTab" label="&networkTab.label;" helpTopic="prefs-advanced-network"/>
|
||||
<tab id="updateTab" label="&updateTab.label;" helpTopic="prefs-advanced-update"/>
|
||||
<tab id="encryptionTab" label="&encryptionTab.label;" helpTopic="prefs-advanced-encryption"/>
|
||||
<tab id="encryptionTab" label="&certificateTab.label;" helpTopic="prefs-advanced-encryption"/>
|
||||
</tabs>
|
||||
|
||||
<tabpanels flex="1">
|
||||
|
@ -403,39 +396,9 @@
|
|||
</groupbox>
|
||||
</tabpanel>
|
||||
|
||||
<!-- Encryption -->
|
||||
<!-- Certificates -->
|
||||
<tabpanel id="encryptionPanel" orient="vertical">
|
||||
|
||||
<!-- Protocols -->
|
||||
<groupbox id="protocolsGroup">
|
||||
<caption label="&protocols.label;"/>
|
||||
|
||||
<grid>
|
||||
<columns>
|
||||
<column flex="1"/>
|
||||
<column flex="1"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<hbox>
|
||||
<checkbox id="useSSL3" label="&useSSL3.label;"
|
||||
accesskey="&useSSL3.accesskey;"
|
||||
preference="security.enable_ssl3"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<checkbox id="useTLS1" label="&useTLS1.label;"
|
||||
accesskey="&useTLS1.accesskey;"
|
||||
preference="security.enable_tls"/>
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</groupbox>
|
||||
|
||||
<!-- Certificates -->
|
||||
<groupbox id="certificatesGroup">
|
||||
<caption id="CertGroupCaption" label="&certificates.label;"/>
|
||||
|
||||
<description id="CertSelectionDesc" control="certSelection">&certSelection.description;</description>
|
||||
|
||||
<!--
|
||||
|
@ -445,7 +408,7 @@
|
|||
-->
|
||||
<radiogroup id="certSelection" orient="horizontal" preftype="string"
|
||||
preference="security.default_personal_cert"
|
||||
aria-labelledby="CertGroupCaption CertSelectionDesc">
|
||||
aria-labelledby="CertSelectionDesc">
|
||||
<radio label="&certs.auto;" accesskey="&certs.auto.accesskey;"
|
||||
value="Select Automatically"/>
|
||||
<radio label="&certs.ask;" accesskey="&certs.ask.accesskey;"
|
||||
|
@ -481,7 +444,6 @@
|
|||
#ifdef XP_MACOSX
|
||||
</vbox>
|
||||
#endif
|
||||
</groupbox>
|
||||
</tabpanel>
|
||||
</tabpanels>
|
||||
</tabbox>
|
||||
|
|
|
@ -22,4 +22,6 @@ DIRS += [
|
|||
'framework',
|
||||
'profiler',
|
||||
'fontinspector',
|
||||
|
||||
]
|
||||
|
||||
|
|
|
@ -120,6 +120,7 @@ MOCHITEST_BROWSER_FILES = \
|
|||
browser_console_variables_view.js \
|
||||
browser_console_variables_view_while_debugging.js \
|
||||
browser_console.js \
|
||||
browser_longstring_hang.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
@ -221,6 +222,7 @@ MOCHITEST_BROWSER_FILES += \
|
|||
test-bug-821877-csperrors.html \
|
||||
test-bug-821877-csperrors.html^headers^ \
|
||||
test-eval-in-stackframe.html \
|
||||
test-bug-859170-longstring-hang.html \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -13,6 +13,7 @@ function test()
|
|||
const TEST_URI2 = "http://example.org/browser/browser/devtools/webconsole/test/test-console.html";
|
||||
|
||||
let hud;
|
||||
let msgForLocation1;
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
|
@ -22,7 +23,6 @@ function test()
|
|||
openConsole(gBrowser.selectedTab, pageLoad1);
|
||||
}, true);
|
||||
|
||||
|
||||
function pageLoad1(aHud)
|
||||
{
|
||||
hud = aHud;
|
||||
|
@ -30,60 +30,63 @@ function test()
|
|||
hud.jsterm.clearOutput();
|
||||
hud.jsterm.execute("window.location.href");
|
||||
|
||||
waitForSuccess(waitForLocation1);
|
||||
}
|
||||
info("wait for window.location.href");
|
||||
|
||||
let waitForLocation1 = {
|
||||
name: "window.location.href result is displayed",
|
||||
validatorFn: function()
|
||||
{
|
||||
let node = hud.outputNode.getElementsByClassName("webconsole-msg-output")[0];
|
||||
return node && node.textContent.indexOf(TEST_URI1) > -1;
|
||||
},
|
||||
successFn: function()
|
||||
{
|
||||
let node = hud.outputNode.getElementsByClassName("webconsole-msg-input")[0];
|
||||
isnot(node.textContent.indexOf("window.location.href"), -1,
|
||||
"jsterm input is also displayed");
|
||||
|
||||
is(hud.outputNode.textContent.indexOf("Permission denied"), -1,
|
||||
"no permission denied errors");
|
||||
msgForLocation1 = {
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "window.location.href jsterm input",
|
||||
text: "window.location.href",
|
||||
category: CATEGORY_INPUT,
|
||||
},
|
||||
{
|
||||
name: "window.location.href result is displayed",
|
||||
text: TEST_URI1,
|
||||
category: CATEGORY_OUTPUT,
|
||||
},
|
||||
]
|
||||
};
|
||||
|
||||
waitForMessages(msgForLocation1).then(() => {
|
||||
gBrowser.selectedBrowser.addEventListener("load", onPageLoad2, true);
|
||||
content.location = TEST_URI2;
|
||||
},
|
||||
failureFn: finishTestWithError,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function onPageLoad2() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onPageLoad2, true);
|
||||
|
||||
is(hud.outputNode.textContent.indexOf("Permission denied"), -1,
|
||||
"no permission denied errors");
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
hud.jsterm.execute("window.location.href");
|
||||
|
||||
waitForSuccess(waitForLocation2);
|
||||
}
|
||||
info("wait for window.location.href after page navigation");
|
||||
|
||||
let waitForLocation2 = {
|
||||
name: "window.location.href result is displayed after page navigation",
|
||||
validatorFn: function()
|
||||
{
|
||||
let node = hud.outputNode.getElementsByClassName("webconsole-msg-output")[0];
|
||||
return node && node.textContent.indexOf(TEST_URI2) > -1;
|
||||
},
|
||||
successFn: function()
|
||||
{
|
||||
let node = hud.outputNode.getElementsByClassName("webconsole-msg-input")[0];
|
||||
isnot(node.textContent.indexOf("window.location.href"), -1,
|
||||
"jsterm input is also displayed");
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "window.location.href jsterm input",
|
||||
text: "window.location.href",
|
||||
category: CATEGORY_INPUT,
|
||||
},
|
||||
{
|
||||
name: "window.location.href result is displayed",
|
||||
text: TEST_URI2,
|
||||
category: CATEGORY_OUTPUT,
|
||||
},
|
||||
]
|
||||
}).then(() => {
|
||||
is(hud.outputNode.textContent.indexOf("Permission denied"), -1,
|
||||
"no permission denied errors");
|
||||
|
||||
gBrowser.goBack();
|
||||
waitForSuccess(waitForBack);
|
||||
},
|
||||
failureFn: finishTestWithError,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
let waitForBack = {
|
||||
name: "go back",
|
||||
|
@ -94,36 +97,17 @@ function test()
|
|||
successFn: function()
|
||||
{
|
||||
hud.jsterm.clearOutput();
|
||||
hud.jsterm.execute("window.location.href");
|
||||
executeSoon(() => {
|
||||
hud.jsterm.execute("window.location.href");
|
||||
});
|
||||
|
||||
waitForSuccess(waitForLocation3);
|
||||
info("wait for window.location.href after goBack()");
|
||||
waitForMessages(msgForLocation1).then(() => executeSoon(() => {
|
||||
is(hud.outputNode.textContent.indexOf("Permission denied"), -1,
|
||||
"no permission denied errors");
|
||||
finishTest();
|
||||
}));
|
||||
},
|
||||
failureFn: finishTestWithError,
|
||||
failureFn: finishTest,
|
||||
};
|
||||
|
||||
let waitForLocation3 = {
|
||||
name: "window.location.href result is displayed after goBack()",
|
||||
validatorFn: function()
|
||||
{
|
||||
let node = hud.outputNode.getElementsByClassName("webconsole-msg-output")[0];
|
||||
return node && node.textContent.indexOf(TEST_URI1) > -1;
|
||||
},
|
||||
successFn: function()
|
||||
{
|
||||
let node = hud.outputNode.getElementsByClassName("webconsole-msg-input")[0];
|
||||
isnot(node.textContent.indexOf("window.location.href"), -1,
|
||||
"jsterm input is also displayed");
|
||||
is(hud.outputNode.textContent.indexOf("Permission denied"), -1,
|
||||
"no permission denied errors");
|
||||
|
||||
executeSoon(finishTest);
|
||||
},
|
||||
failureFn: finishTestWithError,
|
||||
};
|
||||
|
||||
function finishTestWithError()
|
||||
{
|
||||
info("output content: " + hud.outputNode.textContent);
|
||||
finishTest();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ function consoleOpened(hud)
|
|||
|
||||
// Check for network requests.
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.onload = () => info("xhr loaded, status is: " + xhr.status);
|
||||
xhr.onload = () => console.log("xhr loaded, status is: " + xhr.status);
|
||||
xhr.open("get", TEST_URI, true);
|
||||
xhr.send();
|
||||
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that very long strings do not hang the browser.
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
let DebuggerServer = Cu.import("resource://gre/modules/devtools/dbg-server.jsm",
|
||||
{}).DebuggerServer;
|
||||
|
||||
addTab("http://example.com/browser/browser/devtools/webconsole/test/test-bug-859170-longstring-hang.html");
|
||||
|
||||
let hud = null;
|
||||
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openConsole(null, performTest);
|
||||
}, true);
|
||||
|
||||
function performTest(aHud)
|
||||
{
|
||||
hud = aHud;
|
||||
|
||||
info("wait for the initial long string");
|
||||
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "find 'foobar', no 'foobaz', in long string output",
|
||||
text: "foobar",
|
||||
noText: "foobaz",
|
||||
category: CATEGORY_WEBDEV,
|
||||
longString: true,
|
||||
},
|
||||
],
|
||||
}).then(onInitialString);
|
||||
}
|
||||
|
||||
function onInitialString(aResults)
|
||||
{
|
||||
let msg = [...aResults[0].matched][0];
|
||||
ok(msg, "console.log result message element");
|
||||
|
||||
let clickable = msg.querySelector(".longStringEllipsis");
|
||||
ok(clickable, "long string ellipsis is shown");
|
||||
|
||||
scrollToVisible(clickable);
|
||||
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow);
|
||||
|
||||
info("wait for long string expansion");
|
||||
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "find 'foobaz' after expand, but no 'boom!' at the end",
|
||||
text: "foobaz",
|
||||
noText: "boom!",
|
||||
category: CATEGORY_WEBDEV,
|
||||
longString: false,
|
||||
},
|
||||
{
|
||||
text: "too long to be displayed",
|
||||
longString: false,
|
||||
},
|
||||
],
|
||||
}).then(finishTest);
|
||||
});
|
||||
}
|
||||
|
||||
function scrollToVisible(aNode)
|
||||
{
|
||||
let richListBoxNode = aNode.parentNode;
|
||||
while (richListBoxNode.tagName != "richlistbox") {
|
||||
richListBoxNode = richListBoxNode.parentNode;
|
||||
}
|
||||
|
||||
let boxObject = richListBoxNode.scrollBoxObject;
|
||||
let nsIScrollBoxObject = boxObject.QueryInterface(Ci.nsIScrollBoxObject);
|
||||
nsIScrollBoxObject.ensureElementIsVisible(aNode);
|
||||
}
|
||||
}
|
|
@ -20,100 +20,97 @@ function test() {
|
|||
|
||||
function consoleOpened(hud) {
|
||||
// Check that css warnings are not coalesced if they come from different lines.
|
||||
waitForSuccess({
|
||||
name: "css warnings displayed",
|
||||
validatorFn: function()
|
||||
{
|
||||
return hud.outputNode.querySelectorAll(".webconsole-msg-cssparser")
|
||||
.length == 2;
|
||||
},
|
||||
successFn: testCSSRepeats.bind(null, hud),
|
||||
failureFn: finishTest,
|
||||
});
|
||||
}
|
||||
info("waiting for 2 css warnings");
|
||||
|
||||
function repeatCountForNode(aNode) {
|
||||
return aNode.querySelector(".webconsole-msg-repeat").getAttribute("value");
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "two css warnings",
|
||||
category: CATEGORY_CSS,
|
||||
count: 2,
|
||||
repeats: 1,
|
||||
}],
|
||||
}).then(testCSSRepeats.bind(null, hud));
|
||||
}
|
||||
|
||||
function testCSSRepeats(hud) {
|
||||
let msgs = hud.outputNode.querySelectorAll(".webconsole-msg-cssparser");
|
||||
is(repeatCountForNode(msgs[0]), 1, "no repeats for the first css warning");
|
||||
is(repeatCountForNode(msgs[1]), 1, "no repeats for the second css warning");
|
||||
|
||||
browser.addEventListener("load", function onLoad() {
|
||||
browser.removeEventListener("load", onLoad, true);
|
||||
testAfterReload(hud);
|
||||
|
||||
info("wait for repeats after page reload");
|
||||
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "two css warnings, repeated twice",
|
||||
category: CATEGORY_CSS,
|
||||
repeats: 2,
|
||||
count: 2,
|
||||
}],
|
||||
}).then(testCSSRepeatsAfterReload.bind(null, hud));
|
||||
}, true);
|
||||
content.location.reload();
|
||||
}
|
||||
|
||||
function testAfterReload(hud) {
|
||||
let repeats;
|
||||
waitForSuccess({
|
||||
name: "message repeats increased",
|
||||
validatorFn: () => {
|
||||
repeats = hud.outputNode.querySelectorAll(".webconsole-msg-cssparser " +
|
||||
".webconsole-msg-repeat");
|
||||
return repeats.length == 2 &&
|
||||
repeats[0].getAttribute("value") == 2 &&
|
||||
repeats[1].getAttribute("value") == 2;
|
||||
},
|
||||
successFn: testCSSRepeatsAfterReload.bind(null, hud),
|
||||
failureFn: () => {
|
||||
let repeats0 = repeats[0] ? repeats[0].getAttribute("value") : "undefined";
|
||||
let repeats1 = repeats[1] ? repeats[1].getAttribute("value") : "undefined";
|
||||
info("repeats.length " + repeats.length);
|
||||
info("repeats[0] value " + repeats0);
|
||||
info("repeats[1] value " + repeats1);
|
||||
finishTest();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function testCSSRepeatsAfterReload(hud) {
|
||||
let msgs = hud.outputNode.querySelectorAll(".webconsole-msg-cssparser");
|
||||
is(msgs.length, 2, "two css warnings after reload");
|
||||
is(repeatCountForNode(msgs[0]), 2, "two repeats for the first css warning");
|
||||
is(repeatCountForNode(msgs[1]), 2, "two repeats for the second css warning");
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
hud.jsterm.clearOutput(true);
|
||||
content.wrappedJSObject.testConsole();
|
||||
|
||||
waitForSuccess({
|
||||
name: "console API messages displayed",
|
||||
validatorFn: function()
|
||||
{
|
||||
return hud.outputNode.querySelectorAll(".webconsole-msg-console")
|
||||
.length == 3;
|
||||
},
|
||||
successFn: testConsoleRepeats.bind(null, hud),
|
||||
failureFn: finishTest,
|
||||
});
|
||||
info("wait for repeats with the console API");
|
||||
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "console.log 'foo repeat' repeated twice",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
repeats: 2,
|
||||
},
|
||||
{
|
||||
name: "console.log 'foo repeat' repeated once",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
repeats: 1,
|
||||
},
|
||||
{
|
||||
name: "console.error 'foo repeat' repeated once",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_ERROR,
|
||||
repeats: 1,
|
||||
},
|
||||
],
|
||||
}).then(testConsoleRepeats.bind(null, hud));
|
||||
}
|
||||
|
||||
function testConsoleRepeats(hud) {
|
||||
let msgs = hud.outputNode.querySelectorAll(".webconsole-msg-console");
|
||||
is(repeatCountForNode(msgs[0]), 2, "repeats for the first console message");
|
||||
is(repeatCountForNode(msgs[1]), 1,
|
||||
"no repeats for the second console log message");
|
||||
is(repeatCountForNode(msgs[2]), 1, "no repeats for the console.error message");
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
hud.jsterm.clearOutput(true);
|
||||
hud.jsterm.execute("undefined");
|
||||
content.console.log("undefined");
|
||||
|
||||
waitForSuccess({
|
||||
name: "messages displayed",
|
||||
validatorFn: function()
|
||||
{
|
||||
return hud.outputNode.querySelector(".webconsole-msg-console");
|
||||
},
|
||||
successFn: function() {
|
||||
is(hud.outputNode.childNodes.length, 3,
|
||||
"correct number of messages displayed");
|
||||
executeSoon(finishTest);
|
||||
},
|
||||
failureFn: finishTest,
|
||||
});
|
||||
info("make sure console API messages are not coalesced with jsterm output");
|
||||
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "'undefined' jsterm input message",
|
||||
text: "undefined",
|
||||
category: CATEGORY_INPUT,
|
||||
repeats: 1,
|
||||
},
|
||||
{
|
||||
name: "'undefined' jsterm output message",
|
||||
text: "undefined",
|
||||
category: CATEGORY_OUTPUT,
|
||||
repeats: 1,
|
||||
},
|
||||
{
|
||||
name: "'undefined' console.log message",
|
||||
text: "undefined",
|
||||
category: CATEGORY_WEBDEV,
|
||||
repeats: 1,
|
||||
},
|
||||
],
|
||||
}).then(finishTest);
|
||||
}
|
||||
|
|
|
@ -76,6 +76,8 @@ function onpopupshown2(aEvent)
|
|||
menupopups[1].addEventListener("popuphidden", function _onhidden(aEvent) {
|
||||
menupopups[1].removeEventListener(aEvent.type, _onhidden, false);
|
||||
|
||||
info("menupopups[1] hidden");
|
||||
|
||||
// Reopen the context menu.
|
||||
menupopups[1].addEventListener("popupshown", onpopupshown2b, false);
|
||||
executeSoon(function() {
|
||||
|
@ -105,6 +107,8 @@ function onpopupshown2b(aEvent)
|
|||
menupopups[1].addEventListener("popuphidden", function _onhidden(aEvent) {
|
||||
menupopups[1].removeEventListener(aEvent.type, _onhidden, false);
|
||||
|
||||
info("menupopups[1] hidden");
|
||||
|
||||
// Switch to tab 1 and open the Web Console context menu from there.
|
||||
gBrowser.selectedTab = tabs[runCount*2];
|
||||
waitForFocus(function() {
|
||||
|
@ -119,7 +123,7 @@ function onpopupshown2b(aEvent)
|
|||
menupopups[0] = huds[0].ui.rootElement.querySelector("menupopup");
|
||||
|
||||
menupopups[0].addEventListener("popupshown", onpopupshown1, false);
|
||||
menupopups[0].openPopup();
|
||||
executeSoon(() => menupopups[0].openPopup());
|
||||
}, tabs[runCount*2].linkedBrowser.contentWindow);
|
||||
}, false);
|
||||
|
||||
|
@ -143,6 +147,8 @@ function onpopupshown1(aEvent)
|
|||
menupopups[0].addEventListener("popuphidden", function _onhidden(aEvent) {
|
||||
menupopups[0].removeEventListener(aEvent.type, _onhidden, false);
|
||||
|
||||
info("menupopups[0] hidden");
|
||||
|
||||
gBrowser.selectedTab = tabs[runCount*2 + 1];
|
||||
waitForFocus(function() {
|
||||
// Reopen the context menu from tab 2.
|
||||
|
@ -174,10 +180,13 @@ function onpopupshown2c(aEvent)
|
|||
menupopups[1].addEventListener("popuphidden", function _onhidden(aEvent) {
|
||||
menupopups[1].removeEventListener(aEvent.type, _onhidden, false);
|
||||
|
||||
info("menupopups[1] hidden");
|
||||
|
||||
// Done if on second run
|
||||
closeConsole(gBrowser.selectedTab, function() {
|
||||
if (runCount == 0) {
|
||||
runCount++;
|
||||
info("start second run");
|
||||
executeSoon(test);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,<p>test for bug 642108.";
|
||||
const LOG_LIMIT = 20;
|
||||
const CATEGORY_CSS = 1;
|
||||
const SEVERITY_WARNING = 1;
|
||||
|
||||
function test() {
|
||||
addTab(TEST_URI);
|
||||
|
|
|
@ -16,6 +16,22 @@ Components.utils.import("resource://gre/modules/devtools/Console.jsm", tempScope
|
|||
let console = tempScope.console;
|
||||
let Promise = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {}).Promise;
|
||||
|
||||
let gPendingOutputTest = 0;
|
||||
|
||||
// The various categories of messages.
|
||||
const CATEGORY_NETWORK = 0;
|
||||
const CATEGORY_CSS = 1;
|
||||
const CATEGORY_JS = 2;
|
||||
const CATEGORY_WEBDEV = 3;
|
||||
const CATEGORY_INPUT = 4;
|
||||
const CATEGORY_OUTPUT = 5;
|
||||
|
||||
// The possible message severities.
|
||||
const SEVERITY_ERROR = 0;
|
||||
const SEVERITY_WARNING = 1;
|
||||
const SEVERITY_INFO = 2;
|
||||
const SEVERITY_LOG = 3;
|
||||
|
||||
const WEBCONSOLE_STRINGS_URI = "chrome://browser/locale/devtools/webconsole.properties";
|
||||
let WCU_l10n = new WebConsoleUtils.l10n(WEBCONSOLE_STRINGS_URI);
|
||||
|
||||
|
@ -230,11 +246,53 @@ function waitForOpenContextMenu(aContextMenu, aOptions) {
|
|||
eventDetails, targetElement.ownerDocument.defaultView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump the output of all open Web Consoles - used only for debugging purposes.
|
||||
*/
|
||||
function dumpConsoles()
|
||||
{
|
||||
if (gPendingOutputTest) {
|
||||
console.log("dumpConsoles");
|
||||
for each (let hud in HUDService.hudReferences) {
|
||||
if (!hud.outputNode) {
|
||||
console.debug("no output content for", hud.hudId);
|
||||
continue;
|
||||
}
|
||||
|
||||
console.debug("output content for", hud.hudId);
|
||||
for (let elem of hud.outputNode.childNodes) {
|
||||
let text = getMessageElementText(elem);
|
||||
let repeats = elem.querySelector(".webconsole-msg-repeat");
|
||||
if (repeats) {
|
||||
repeats = repeats.getAttribute("value");
|
||||
}
|
||||
console.debug("date", elem.timestamp,
|
||||
"class", elem.className,
|
||||
"category", elem.category,
|
||||
"severity", elem.severity,
|
||||
"repeats", repeats,
|
||||
"clipboardText", elem.clipboardText,
|
||||
"text", text);
|
||||
}
|
||||
}
|
||||
|
||||
gPendingOutputTest = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
browser = hudId = hud = filterBox = outputNode = cs = null;
|
||||
|
||||
dumpConsoles();
|
||||
|
||||
if (HUDConsoleUI.browserConsole) {
|
||||
let hud = HUDConsoleUI.browserConsole;
|
||||
|
||||
if (hud.jsterm) {
|
||||
hud.jsterm.clearOutput(true);
|
||||
}
|
||||
|
||||
HUDConsoleUI.toggleBrowserConsole().then(finishTest);
|
||||
return;
|
||||
}
|
||||
|
@ -244,6 +302,7 @@ function finishTest()
|
|||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
if (hud.jsterm) {
|
||||
hud.jsterm.clearOutput(true);
|
||||
}
|
||||
|
@ -255,6 +314,8 @@ function finishTest()
|
|||
|
||||
function tearDown()
|
||||
{
|
||||
dumpConsoles();
|
||||
|
||||
if (HUDConsoleUI.browserConsole) {
|
||||
HUDConsoleUI.toggleBrowserConsole();
|
||||
}
|
||||
|
@ -767,3 +828,176 @@ function openDebugger(aOptions = {})
|
|||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full text displayed by a Web Console message.
|
||||
*
|
||||
* @param nsIDOMElement aElement
|
||||
* The message element from the Web Console output.
|
||||
* @return string
|
||||
* The full text displayed by the given message element.
|
||||
*/
|
||||
function getMessageElementText(aElement)
|
||||
{
|
||||
let text = aElement.textContent;
|
||||
let labels = aElement.querySelectorAll("label");
|
||||
for (let label of labels) {
|
||||
text += " " + label.getAttribute("value");
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for messages in the Web Console output.
|
||||
*
|
||||
* @param object aOptions
|
||||
* Options for what you want to wait for:
|
||||
* - webconsole: the webconsole instance you work with.
|
||||
* - messages: an array of objects that tells which messages to wait for.
|
||||
* Properties:
|
||||
* - text: string or RegExp to match the textContent of each new
|
||||
* message.
|
||||
* - repeats: the number of message repeats, as displayed by the Web
|
||||
* Console.
|
||||
* - category: match message category. See CATEGORY_* constants at
|
||||
* the top of this file.
|
||||
* - severity: match message severity. See SEVERITY_* constants at
|
||||
* the top of this file.
|
||||
* - count: how many unique web console messages should be matched by
|
||||
* this rule.
|
||||
* @return object
|
||||
* A Promise object is returned once the messages you want are found.
|
||||
*/
|
||||
function waitForMessages(aOptions)
|
||||
{
|
||||
gPendingOutputTest++;
|
||||
let webconsole = aOptions.webconsole;
|
||||
let rules = WebConsoleUtils.cloneObject(aOptions.messages, true);
|
||||
let rulesMatched = 0;
|
||||
let listenerAdded = false;
|
||||
let deferred = Promise.defer();
|
||||
|
||||
function checkText(aRule, aText)
|
||||
{
|
||||
let result;
|
||||
if (typeof aRule == "string") {
|
||||
result = aText.indexOf(aRule) > -1;
|
||||
}
|
||||
else if (aRule instanceof RegExp) {
|
||||
result = aRule.test(aText);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function checkMessage(aRule, aElement)
|
||||
{
|
||||
let elemText = getMessageElementText(aElement);
|
||||
|
||||
if (aRule.text && !checkText(aRule.text, elemText)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aRule.noText && checkText(aRule.noText, elemText)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aRule.category) {
|
||||
if (aElement.category != aRule.category) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (aRule.severity) {
|
||||
if (aElement.severity != aRule.severity) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (aRule.repeats) {
|
||||
let repeats = aElement.querySelector(".webconsole-msg-repeat");
|
||||
if (!repeats || repeats.getAttribute("value") != aRule.repeats) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
let longString = !!aElement.querySelector(".longStringEllipsis");
|
||||
if ("longString" in aRule && aRule.longString != longString) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let count = aRule.count || 1;
|
||||
if (!aRule.matched) {
|
||||
aRule.matched = new Set();
|
||||
}
|
||||
aRule.matched.add(aElement);
|
||||
|
||||
return aRule.matched.size == count;
|
||||
}
|
||||
|
||||
function onMessagesAdded(aEvent, aNewElements)
|
||||
{
|
||||
for (let elem of aNewElements) {
|
||||
for (let rule of rules) {
|
||||
if (rule._ruleMatched) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let matched = checkMessage(rule, elem);
|
||||
if (matched) {
|
||||
rule._ruleMatched = true;
|
||||
rulesMatched++;
|
||||
ok(1, "matched rule: " + displayRule(rule));
|
||||
if (maybeDone()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function maybeDone()
|
||||
{
|
||||
if (rulesMatched == rules.length) {
|
||||
if (listenerAdded) {
|
||||
webconsole.ui.off("messages-added", onMessagesAdded);
|
||||
webconsole.ui.off("messages-updated", onMessagesAdded);
|
||||
}
|
||||
gPendingOutputTest--;
|
||||
deferred.resolve(rules);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function testCleanup() {
|
||||
if (rulesMatched == rules.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (webconsole.ui) {
|
||||
webconsole.ui.off("messages-added", onMessagesAdded);
|
||||
}
|
||||
|
||||
for (let rule of rules) {
|
||||
if (!rule._ruleMatched) {
|
||||
ok(false, "failed to match rule: " + displayRule(rule));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function displayRule(aRule)
|
||||
{
|
||||
return aRule.name || aRule.text;
|
||||
}
|
||||
|
||||
executeSoon(() => {
|
||||
onMessagesAdded("messages-added", webconsole.outputNode.childNodes);
|
||||
if (rulesMatched != rules.length) {
|
||||
listenerAdded = true;
|
||||
registerCleanupFunction(testCleanup);
|
||||
webconsole.ui.on("messages-added", onMessagesAdded);
|
||||
webconsole.ui.on("messages-updated", onMessagesAdded);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head><meta charset="utf-8">
|
||||
<title>Web Console test for bug 859170 - very long strings hang the browser</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="application/javascript">
|
||||
(function() {
|
||||
var longString = "abbababazomglolztest";
|
||||
for (var i = 0; i < 10; i++) {
|
||||
longString += longString + longString;
|
||||
}
|
||||
|
||||
longString = "foobar" + (new Array(20000)).join("a") + "foobaz" +
|
||||
longString + "boom!";
|
||||
console.log(longString);
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<p>Web Console test for bug 859170 - very long strings hang the browser.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -171,6 +171,9 @@ const FILTER_PREFS_PREFIX = "devtools.webconsole.filter.";
|
|||
// The minimum font size.
|
||||
const MIN_FONT_SIZE = 10;
|
||||
|
||||
// The maximum length of strings to be displayed by the Web Console.
|
||||
const MAX_LONG_STRING_LENGTH = 200000;
|
||||
|
||||
const PREF_CONNECTION_TIMEOUT = "devtools.debugger.remote-timeout";
|
||||
|
||||
/**
|
||||
|
@ -199,6 +202,8 @@ function WebConsoleFrame(aWebConsoleOwner)
|
|||
|
||||
this._outputTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
this._outputTimerInitialized = false;
|
||||
|
||||
EventEmitter.decorate(this);
|
||||
}
|
||||
|
||||
WebConsoleFrame.prototype = {
|
||||
|
@ -879,14 +884,15 @@ WebConsoleFrame.prototype = {
|
|||
* @private
|
||||
* @param nsIDOMNode aNode
|
||||
* The message node to be filtered or not.
|
||||
* @returns boolean
|
||||
* True if the message is filtered, false otherwise.
|
||||
* @returns nsIDOMNode|null
|
||||
* Returns the duplicate node if the message was filtered, null
|
||||
* otherwise.
|
||||
*/
|
||||
_filterRepeatedMessage: function WCF__filterRepeatedMessage(aNode)
|
||||
{
|
||||
let repeatNode = aNode.getElementsByClassName("webconsole-msg-repeat")[0];
|
||||
if (!repeatNode) {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
let uid = repeatNode._uid;
|
||||
|
@ -905,7 +911,7 @@ WebConsoleFrame.prototype = {
|
|||
aNode.classList.contains("webconsole-msg-error"))) {
|
||||
let lastMessage = this.outputNode.lastChild;
|
||||
if (!lastMessage) {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
let lastRepeatNode = lastMessage
|
||||
|
@ -917,10 +923,10 @@ WebConsoleFrame.prototype = {
|
|||
|
||||
if (dupeNode) {
|
||||
this.mergeFilteredMessageNode(dupeNode, aNode);
|
||||
return true;
|
||||
return dupeNode;
|
||||
}
|
||||
|
||||
return false;
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1316,7 +1322,7 @@ WebConsoleFrame.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Inform user that the Web Console API has been replaced by a script
|
||||
* Inform user that the window.console API has been replaced by a script
|
||||
* in a content page.
|
||||
*/
|
||||
logWarningAboutReplacedAPI: function WCF_logWarningAboutReplacedAPI()
|
||||
|
@ -1326,6 +1332,16 @@ WebConsoleFrame.prototype = {
|
|||
this.outputMessage(CATEGORY_JS, node);
|
||||
},
|
||||
|
||||
/**
|
||||
* Inform user that the string he tries to view is too long.
|
||||
*/
|
||||
logWarningAboutStringTooLong: function WCF_logWarningAboutStringTooLong()
|
||||
{
|
||||
let node = this.createMessageNode(CATEGORY_JS, SEVERITY_WARNING,
|
||||
l10n.getStr("longStringTooLong"));
|
||||
this.outputMessage(CATEGORY_JS, node);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle the network events coming from the remote Web Console.
|
||||
*
|
||||
|
@ -1692,10 +1708,20 @@ WebConsoleFrame.prototype = {
|
|||
let hudIdSupportsString = WebConsoleUtils.supportsString(this.hudId);
|
||||
|
||||
// Output the current batch of messages.
|
||||
let newMessages = new Set();
|
||||
let updatedMessages = new Set();
|
||||
for (let item of batch) {
|
||||
let node = this._outputMessageFromQueue(hudIdSupportsString, item);
|
||||
if (node) {
|
||||
lastVisibleNode = node;
|
||||
let result = this._outputMessageFromQueue(hudIdSupportsString, item);
|
||||
if (result) {
|
||||
if (result.isRepeated) {
|
||||
updatedMessages.add(result.isRepeated);
|
||||
}
|
||||
else {
|
||||
newMessages.add(result.node);
|
||||
}
|
||||
if (result.visible && result.node == this.outputNode.lastChild) {
|
||||
lastVisibleNode = result.node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1736,6 +1762,13 @@ WebConsoleFrame.prototype = {
|
|||
scrollBox.scrollTop -= oldScrollHeight - scrollBox.scrollHeight;
|
||||
}
|
||||
|
||||
if (newMessages.size) {
|
||||
this.emit("messages-added", newMessages);
|
||||
}
|
||||
if (updatedMessages.size) {
|
||||
this.emit("messages-updated", updatedMessages);
|
||||
}
|
||||
|
||||
// If the queue is not empty, schedule another flush.
|
||||
if (this._outputQueue.length > 0) {
|
||||
this._initOutputTimer();
|
||||
|
@ -1772,9 +1805,12 @@ WebConsoleFrame.prototype = {
|
|||
* The HUD ID as an nsISupportsString.
|
||||
* @param array aItem
|
||||
* An item from the output queue - this item represents a message.
|
||||
* @return nsIDOMElement|undefined
|
||||
* The DOM element of the message if the message is visible, undefined
|
||||
* otherwise.
|
||||
* @return object
|
||||
* An object that holds the following properties:
|
||||
* - node: the DOM element of the message.
|
||||
* - isRepeated: the DOM element of the original message, if this is
|
||||
* a repeated message, otherwise null.
|
||||
* - visible: boolean that tells if the message is visible.
|
||||
*/
|
||||
_outputMessageFromQueue:
|
||||
function WCF__outputMessageFromQueue(aHudIdSupportsString, aItem)
|
||||
|
@ -1785,7 +1821,7 @@ WebConsoleFrame.prototype = {
|
|||
methodOrNode.apply(this, args || []) :
|
||||
methodOrNode;
|
||||
if (!node) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
let afterNode = node._outputAfterNode;
|
||||
|
@ -1797,14 +1833,16 @@ WebConsoleFrame.prototype = {
|
|||
|
||||
let isRepeated = this._filterRepeatedMessage(node);
|
||||
|
||||
let lastVisible = !isRepeated && !isFiltered;
|
||||
let visible = !isRepeated && !isFiltered;
|
||||
if (!isRepeated) {
|
||||
this.outputNode.insertBefore(node,
|
||||
afterNode ? afterNode.nextSibling : null);
|
||||
this._pruneCategoriesQueue[node.category] = true;
|
||||
if (afterNode) {
|
||||
lastVisible = this.outputNode.lastChild == node;
|
||||
}
|
||||
|
||||
let nodeID = node.getAttribute("id");
|
||||
Services.obs.notifyObservers(aHudIdSupportsString,
|
||||
"web-console-message-created", nodeID);
|
||||
|
||||
}
|
||||
|
||||
if (node._onOutput) {
|
||||
|
@ -1812,11 +1850,11 @@ WebConsoleFrame.prototype = {
|
|||
delete node._onOutput;
|
||||
}
|
||||
|
||||
let nodeID = node.getAttribute("id");
|
||||
Services.obs.notifyObservers(aHudIdSupportsString,
|
||||
"web-console-message-created", nodeID);
|
||||
|
||||
return lastVisible ? node : null;
|
||||
return {
|
||||
visible: visible,
|
||||
node: node,
|
||||
isRepeated: isRepeated,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -2241,7 +2279,8 @@ WebConsoleFrame.prototype = {
|
|||
}
|
||||
|
||||
let longString = this.webConsoleClient.longString(aActor);
|
||||
longString.substring(longString.initial.length, longString.length,
|
||||
let toIndex = Math.min(longString.length, MAX_LONG_STRING_LENGTH);
|
||||
longString.substring(longString.initial.length, toIndex,
|
||||
function WCF__onSubstring(aResponse) {
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("WCF__longStringClick substring failure: " +
|
||||
|
@ -2257,7 +2296,13 @@ WebConsoleFrame.prototype = {
|
|||
aMessage.category == CATEGORY_OUTPUT) {
|
||||
aMessage.clipboardText = aMessage.textContent;
|
||||
}
|
||||
});
|
||||
|
||||
this.emit("messages-updated", new Set([aMessage]));
|
||||
|
||||
if (toIndex != longString.length) {
|
||||
this.logWarningAboutStringTooLong();
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -3453,7 +3498,8 @@ JSTerm.prototype = {
|
|||
}
|
||||
|
||||
let client = this.webConsoleClient.longString(grip);
|
||||
client.substring(grip.initial.length, grip.length, (aResponse) => {
|
||||
let toIndex = Math.min(grip.length, MAX_LONG_STRING_LENGTH);
|
||||
client.substring(grip.initial.length, toIndex, (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("JST__fetchVarLongString substring failure: " +
|
||||
aResponse.error + ": " + aResponse.message);
|
||||
|
@ -3464,6 +3510,10 @@ JSTerm.prototype = {
|
|||
aVar.setGrip(grip.initial + aResponse.substring);
|
||||
aVar.hideArrow();
|
||||
aVar._retrieved = true;
|
||||
|
||||
if (toIndex != grip.length) {
|
||||
this.hud.logWarningAboutStringTooLong();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -514,6 +514,8 @@
|
|||
@BINPATH@/components/PermissionSettings.manifest
|
||||
@BINPATH@/components/ContactManager.js
|
||||
@BINPATH@/components/ContactManager.manifest
|
||||
@BINPATH@/components/NavigatorPropertyHelper.js
|
||||
@BINPATH@/components/NavigatorPropertyHelper.manifest
|
||||
@BINPATH@/components/AlarmsManager.js
|
||||
@BINPATH@/components/AlarmsManager.manifest
|
||||
@BINPATH@/components/TCPSocket.js
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
text in <a/> will be linked to the featured add-ons on addons.mozilla.org
|
||||
-->
|
||||
<!ENTITY abouthome.defaultSnippet2.v1 "It's easy to customize your Firefox exactly the way you want it. <a>Choose from thousands of add-ons</a>.">
|
||||
<!-- LOCALIZATION NOTE (abouthome.rightsSnippet): text in <a/> will be linked to about:rights -->
|
||||
<!ENTITY abouthome.rightsSnippet "&brandFullName; is free and open source software from the non-profit Mozilla Foundation. <a>Know your rights…</a>">
|
||||
|
||||
<!ENTITY abouthome.bookmarksButton.label "Bookmarks">
|
||||
<!ENTITY abouthome.historyButton.label "History">
|
||||
|
|
|
@ -180,6 +180,10 @@ ToolboxWebconsole.tooltip=Web Console
|
|||
# from the server.
|
||||
longStringEllipsis=[…]
|
||||
|
||||
# LOCALIZATION NOTE (longStringTooLong): The string displayed after the user
|
||||
# tries to expand a long string.
|
||||
longStringTooLong=The string you are trying to view is too long to be displayed by the Web Console.
|
||||
|
||||
# LOCALIZATION NOTE (executeEmptyInput): This is displayed when the user tries
|
||||
# to execute code, but the input is empty.
|
||||
executeEmptyInput=No value to execute.
|
||||
|
|
|
@ -115,14 +115,7 @@
|
|||
<!ENTITY offlineAppsListRemove.accesskey "R">
|
||||
<!ENTITY offlineAppRemove.confirm "Remove offline data">
|
||||
|
||||
<!ENTITY encryptionTab.label "Encryption">
|
||||
|
||||
<!ENTITY protocols.label "Protocols">
|
||||
<!ENTITY useSSL3.label "Use SSL 3.0">
|
||||
<!ENTITY useSSL3.accesskey "3">
|
||||
<!ENTITY useTLS1.label "Use TLS 1.0">
|
||||
<!ENTITY useTLS1.accesskey "1">
|
||||
<!ENTITY certificates.label "Certificates">
|
||||
<!ENTITY certificateTab.label "Certificates">
|
||||
<!ENTITY certSelection.description "When a server requests my personal certificate:">
|
||||
<!ENTITY certs.auto "Select one automatically">
|
||||
<!ENTITY certs.auto.accesskey "l">
|
||||
|
|
|
@ -264,7 +264,7 @@ TopSitesView.prototype = {
|
|||
if (!iconURLfromSiteURL) {
|
||||
return;
|
||||
}
|
||||
aTileNode.iconSrc = iconURLfromSiteURL;
|
||||
aTileNode.iconSrc = iconURLfromSiteURL.spec;
|
||||
let faviconURL = (PlacesUtils.favicons.getFaviconLinkForIcon(iconURLfromSiteURL)).spec;
|
||||
let xpFaviconURI = Util.makeURI(faviconURL.replace("moz-anno:favicon:",""));
|
||||
ColorUtils.getForegroundAndBackgroundIconColors(xpFaviconURI, function(foreground, background) {
|
||||
|
@ -398,15 +398,15 @@ let TopSitesStartView = {
|
|||
},
|
||||
|
||||
show: function show() {
|
||||
this._grid.arrangeItems(3, 3);
|
||||
this._grid.arrangeItems();
|
||||
},
|
||||
};
|
||||
|
||||
let TopSitesSnappedView = {
|
||||
get _grid() { return document.getElementById("snapped-topsite-grid"); },
|
||||
get _grid() { return document.getElementById("snapped-topsites-grid"); },
|
||||
|
||||
show: function show() {
|
||||
this._grid.arrangeItems(1, 8);
|
||||
this._grid.arrangeItems();
|
||||
},
|
||||
|
||||
init: function() {
|
||||
|
@ -415,8 +415,19 @@ let TopSitesSnappedView = {
|
|||
let topsitesVbox = document.getElementById("snapped-topsites");
|
||||
topsitesVbox.setAttribute("hidden", "true");
|
||||
}
|
||||
Services.obs.addObserver(this, "metro_viewstate_dom_snapped", false);
|
||||
},
|
||||
|
||||
uninit: function uninit() {
|
||||
this._view.destruct();
|
||||
Services.obs.removeObserver(this, "metro_viewstate_dom_snapped");
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case "metro_viewstate_dom_snapped":
|
||||
this._grid.arrangeItems();
|
||||
break;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -112,7 +112,6 @@ var Appbar = {
|
|||
string: '',
|
||||
xPos: x,
|
||||
yPos: y,
|
||||
forcePosition: true,
|
||||
leftAligned: true,
|
||||
bottomAligned: true
|
||||
}
|
||||
|
|
|
@ -52,11 +52,8 @@
|
|||
this.clearSelection();
|
||||
}
|
||||
this._selectedItem = wasSelected ? null : anItem;
|
||||
if(anItem.selected) {
|
||||
anItem.removeAttribute("selected");
|
||||
} else {
|
||||
anItem.setAttribute("selected", true);
|
||||
}
|
||||
anItem.selected = !wasSelected;
|
||||
|
||||
this._fireOnSelectionChange();
|
||||
]]>
|
||||
</body>
|
||||
|
@ -325,15 +322,15 @@
|
|||
<field name="_itemHeightRenderThreshold">10</field>
|
||||
|
||||
<method name="arrangeItems">
|
||||
<parameter name="aNumRows"/>
|
||||
<parameter name="aNumColumns"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (this.itemCount <= 0)
|
||||
if (this.itemCount <= 0) {
|
||||
return;
|
||||
}
|
||||
let item = this.getItemAtIndex(0);
|
||||
if (item == null)
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
let gridItemRect = item.getBoundingClientRect();
|
||||
|
||||
// cap the number of times we reschedule calling arrangeItems
|
||||
|
@ -376,24 +373,25 @@
|
|||
container = this.parentNode.getBoundingClientRect();
|
||||
|
||||
// If we don't have valid dimensions we can't arrange yet
|
||||
if (!container.height || !gridItemRect.height)
|
||||
if (!container.height || !gridItemRect.height) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We favor overflowing horizontally, not vertically
|
||||
let maxRowCount = Math.floor(container.height / gridItemRect.height) - 1;
|
||||
|
||||
if (aNumRows) {
|
||||
this._rowCount = aNumRows;
|
||||
} else {
|
||||
this._rowCount = this.getAttribute("rows");
|
||||
this._columnCount = this.getAttribute("columns");
|
||||
|
||||
if (!this._rowCount) {
|
||||
this._rowCount = Math.min(this.itemCount, maxRowCount);
|
||||
}
|
||||
if (aNumColumns) {
|
||||
this._columnCount = aNumColumns;
|
||||
} else {
|
||||
if (!this._columnCount){
|
||||
this._columnCount = Math.ceil(this.itemCount / this._rowCount);
|
||||
}
|
||||
|
||||
this._grid.style.width = (this._columnCount * gridItemRect.width) + "px";
|
||||
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
@ -508,7 +506,9 @@
|
|||
onset="this._icon.src = val; this.setAttribute('iconURI', val);"
|
||||
onget="return this._icon.src;" />
|
||||
|
||||
<property name="selected" onget="return this.hasAttribute('selected');" />
|
||||
<property name="selected"
|
||||
onget="return this.hasAttribute('selected');"
|
||||
onset="if (val) this.setAttribute('selected', val); else this.removeAttribute('selected');" />
|
||||
<property name="url"
|
||||
onget="return this.getAttribute('value')"
|
||||
onset="this.setAttribute('value', val);"/>
|
||||
|
@ -527,6 +527,10 @@
|
|||
<method name="refresh">
|
||||
<body>
|
||||
<![CDATA[
|
||||
// Prevent an exception in case binding is not done yet.
|
||||
if (!this._icon)
|
||||
return;
|
||||
|
||||
// Seed the binding properties from bound-node attribute values
|
||||
// Usage: node.refresh()
|
||||
// - reinitializes all binding properties from their associated attributes
|
||||
|
|
|
@ -90,31 +90,6 @@
|
|||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_onContextMenu">
|
||||
<parameter name="aEvent"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
// forward this over. frame script will treat this like
|
||||
// a bubbling contextmenu event.
|
||||
Browser.selectedTab.browser.messageManager.sendAsyncMessage("Browser:InvokeContextAtPoint", {
|
||||
xPos: aEvent.clientX, yPos: aEvent.clientY });
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="handleEvent">
|
||||
<parameter name="aEvent"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
switch (aEvent.type) {
|
||||
case 'contextmenu':
|
||||
this._onContextMenu(aEvent);
|
||||
break;
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="addDebugRect">
|
||||
<parameter name="aLeft"/>
|
||||
<parameter name="aTop"/>
|
||||
|
|
|
@ -569,8 +569,12 @@ var BrowserUI = {
|
|||
break;
|
||||
case "metro_viewstate_changed":
|
||||
this._adjustDOMforViewState();
|
||||
if (aData == "snapped")
|
||||
if (aData == "snapped") {
|
||||
FlyoutPanelsUI.hide();
|
||||
// Order matters (need grids to get dimensions, etc), now
|
||||
// let snapped grid know to refresh/redraw
|
||||
Services.obs.notifyObservers(null, "metro_viewstate_dom_snapped", null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
@ -1362,6 +1366,7 @@ var StartUI = {
|
|||
|
||||
sections: [
|
||||
"TopSitesStartView",
|
||||
"TopSitesSnappedView",
|
||||
"BookmarksStartView",
|
||||
"HistoryStartView",
|
||||
"RemoteTabsStartView"
|
||||
|
|
|
@ -260,7 +260,7 @@
|
|||
<scrollbox id="start-scrollbox" orient="horizontal" flex="1">
|
||||
<vbox id="start-topsites" class="meta-section">
|
||||
<label class="meta-section-title" value="&startTopSitesHeader.label;"/>
|
||||
<richgrid id="start-topsites-grid" seltype="multiple" flex="1"/>
|
||||
<richgrid id="start-topsites-grid" rows="3" columns="3" seltype="multiple" flex="1"/>
|
||||
</vbox>
|
||||
<vbox id="start-bookmarks" class="meta-section">
|
||||
<label class="meta-section-title" value="&startBookmarksHeader.label;"
|
||||
|
@ -283,7 +283,7 @@
|
|||
<scrollbox id="snapped-scrollbox" orient="vertical" flex="1">
|
||||
<vbox id="snapped-topsites">
|
||||
<label class="meta-section-title" value="&startTopSitesHeader.label;"/>
|
||||
<!-- TODO bug 835999 -->
|
||||
<richgrid id="snapped-topsites-grid" rows="8" columns="1" flex="1"/>
|
||||
</vbox>
|
||||
<label class="meta-section-title" value="&startBookmarksHeader.label;"
|
||||
onclick="PanelUI.show('bookmarks-container');"/>
|
||||
|
|
|
@ -42,9 +42,6 @@ var ContextMenuHandler = {
|
|||
case "Browser:ContextCommand":
|
||||
this._onContextCommand(aMessage);
|
||||
break;
|
||||
case "Browser:InvokeContextAtPoint":
|
||||
this._onContextAtPoint(aMessage);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -79,18 +76,6 @@ var ContextMenuHandler = {
|
|||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Handler for selection overlay context menu events.
|
||||
*/
|
||||
_onContextAtPoint: function _onContextAtPoint(aMessage) {
|
||||
// we need to find popupNode as if the context menu were
|
||||
// invoked on underlying content.
|
||||
let { element, frameX, frameY } =
|
||||
elementFromPoint(aMessage.json.xPos, aMessage.json.yPos);
|
||||
this._processPopupNode(element, frameX, frameY,
|
||||
Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH);
|
||||
},
|
||||
|
||||
/******************************************************
|
||||
* Event handlers
|
||||
*/
|
||||
|
|
|
@ -535,17 +535,7 @@ var SelectionHandler = {
|
|||
this._contentWindow = contentWindow;
|
||||
this._contentOffset = offset;
|
||||
this._domWinUtils = utils;
|
||||
this._targetIsEditable = false;
|
||||
if (this._isTextInput(this._targetElement)) {
|
||||
this._targetIsEditable = true;
|
||||
// Since we have an overlay, focus will not get set, so set it. There
|
||||
// are ways around this if this causes trouble - we have the selection
|
||||
// controller, so we can turn selection display on manually. (Selection
|
||||
// display is setup on edits when focus changes.) I think web pages will
|
||||
// prefer that focus be set when we are interacting with selection in
|
||||
// the element.
|
||||
this._targetElement.focus();
|
||||
}
|
||||
this._targetIsEditable = this._isTextInput(this._targetElement);
|
||||
return true;
|
||||
},
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ var AutofillMenuUI = {
|
|||
|
||||
_positionOptions: function _positionOptions() {
|
||||
return {
|
||||
forcePosition: true,
|
||||
bottomAligned: false,
|
||||
leftAligned: true,
|
||||
xPos: this._anchorRect.x,
|
||||
|
@ -77,7 +76,6 @@ var ContextMenuUI = {
|
|||
_popupState: null,
|
||||
__menuPopup: null,
|
||||
_defaultPositionOptions: {
|
||||
forcePosition: true,
|
||||
bottomAligned: true,
|
||||
rightAligned: false,
|
||||
centerHorizontally: true,
|
||||
|
@ -242,9 +240,7 @@ var MenuControlUI = {
|
|||
let position = this._currentControl.menupopup.position || "after_start";
|
||||
let rect = this._currentControl.getBoundingClientRect();
|
||||
|
||||
let options = {
|
||||
forcePosition: true
|
||||
};
|
||||
let options = {};
|
||||
|
||||
// TODO: Detect text direction and flip for RTL.
|
||||
|
||||
|
@ -361,7 +357,7 @@ MenuPopup.prototype = {
|
|||
document.dispatchEvent(event);
|
||||
});
|
||||
|
||||
let popupFrom = (aPositionOptions.forcePosition && !aPositionOptions.bottomAligned) ? "above" : "below";
|
||||
let popupFrom = !aPositionOptions.bottomAligned ? "above" : "below";
|
||||
this._panel.setAttribute("showingfrom", popupFrom);
|
||||
|
||||
// Ensure the panel actually gets shifted before getting animated
|
||||
|
@ -417,48 +413,14 @@ MenuPopup.prototype = {
|
|||
this._commands.setAttribute("left-hand", leftHand);
|
||||
}
|
||||
|
||||
if (aPositionOptions.forcePosition) {
|
||||
if (aPositionOptions.rightAligned)
|
||||
aX -= width;
|
||||
if (aPositionOptions.rightAligned)
|
||||
aX -= width;
|
||||
|
||||
if (aPositionOptions.bottomAligned)
|
||||
aY -= height;
|
||||
if (aPositionOptions.bottomAligned)
|
||||
aY -= height;
|
||||
|
||||
if (aPositionOptions.centerHorizontally)
|
||||
aX -= halfWidth;
|
||||
} else {
|
||||
let hLeft = (aX - halfWidth - width - kPositionPadding) > kPositionPadding;
|
||||
let hRight = (aX + width + kPositionPadding) < screenWidth;
|
||||
let hCenter = (aX - halfWidth - kPositionPadding) > kPositionPadding;
|
||||
|
||||
let vTop = (aY - height - kPositionPadding) > kPositionPadding;
|
||||
let vCenter = (aY - halfHeight - kPositionPadding) > kPositionPadding &&
|
||||
aY + halfHeight < screenHeight;
|
||||
let vBottom = (aY + height + kPositionPadding) < screenHeight;
|
||||
|
||||
if (leftHand && hLeft && vCenter) {
|
||||
dump('leftHand && hLeft && vCenter\n');
|
||||
aX -= (width + halfWidth);
|
||||
aY -= halfHeight;
|
||||
} else if (!leftHand && hRight && vCenter) {
|
||||
dump('!leftHand && hRight && vCenter\n');
|
||||
aX += kPositionPadding;
|
||||
aY -= halfHeight;
|
||||
} else if (vBottom && hCenter) {
|
||||
dump('vBottom && hCenter\n');
|
||||
aX -= halfWidth;
|
||||
} else if (vTop && hCenter) {
|
||||
dump('vTop && hCenter\n');
|
||||
aX -= halfWidth;
|
||||
aY -= height;
|
||||
} else if (hCenter && vCenter) {
|
||||
dump('hCenter && vCenter\n');
|
||||
aX -= halfWidth;
|
||||
aY -= halfHeight;
|
||||
} else {
|
||||
dump('None, left hand: ' + leftHand + '!\n');
|
||||
}
|
||||
}
|
||||
if (aPositionOptions.centerHorizontally)
|
||||
aX -= halfWidth;
|
||||
|
||||
if (aX < 0) {
|
||||
aX = 0;
|
||||
|
|
|
@ -107,7 +107,6 @@ var SelectHelperUI = {
|
|||
let p1 = browser.ptBrowserToClient(aRect.right, aRect.bottom);
|
||||
|
||||
return {
|
||||
forcePosition: true,
|
||||
xPos: p0.x,
|
||||
yPos: p1.y,
|
||||
bottomAligned: false,
|
||||
|
|
|
@ -351,6 +351,8 @@ var SelectionHelperUI = {
|
|||
if (!this.isActive) {
|
||||
this._init(aBrowser);
|
||||
this._setupDebugOptions();
|
||||
} else {
|
||||
this._hideMonocles();
|
||||
}
|
||||
|
||||
this._lastPoint = { xPos: aX, yPos: aY };
|
||||
|
|
|
@ -60,7 +60,6 @@ gTests.push({
|
|||
let promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, span, 85, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
@ -74,7 +73,6 @@ gTests.push({
|
|||
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
|
||||
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// The wait is needed to give time to populate the clipboard.
|
||||
let string = "";
|
||||
|
@ -95,7 +93,6 @@ gTests.push({
|
|||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, link, 40, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
@ -109,7 +106,6 @@ gTests.push({
|
|||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
win.getSelection().removeAllRanges();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -119,7 +115,6 @@ gTests.push({
|
|||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, link, 40, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
@ -132,7 +127,6 @@ gTests.push({
|
|||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// context in input with no selection, no data on clipboard
|
||||
|
@ -143,7 +137,6 @@ gTests.push({
|
|||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, input, 20, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
@ -158,7 +151,6 @@ gTests.push({
|
|||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// context in input with selection copied to clipboard
|
||||
|
@ -169,7 +161,6 @@ gTests.push({
|
|||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, input, 20, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
@ -182,9 +173,14 @@ gTests.push({
|
|||
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
|
||||
|
||||
yield popupPromise;
|
||||
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
|
||||
|
||||
let string = SpecialPowers.getClipboardData("text/unicode");
|
||||
// The wait is needed to give time to populate the clipboard.
|
||||
let string = "";
|
||||
yield waitForCondition(function () {
|
||||
string = SpecialPowers.getClipboardData("text/unicode");
|
||||
return string === "hello";
|
||||
});
|
||||
|
||||
ok(string === "hello", "copied selected text");
|
||||
|
||||
emptyClipboard();
|
||||
|
@ -197,7 +193,6 @@ gTests.push({
|
|||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, input, 20, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
@ -209,7 +204,6 @@ gTests.push({
|
|||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// context in input with no selection, data on clipboard
|
||||
|
@ -220,7 +214,6 @@ gTests.push({
|
|||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, input, 20, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
@ -228,14 +221,11 @@ gTests.push({
|
|||
// selected text context:
|
||||
checkContextUIMenuItemVisibility(["context-cut",
|
||||
"context-copy",
|
||||
"context-paste",
|
||||
"context-select",
|
||||
"context-select-all"]);
|
||||
"context-paste"]);
|
||||
|
||||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// context in input with selection cut to clipboard
|
||||
|
@ -248,7 +238,6 @@ gTests.push({
|
|||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, input, 20, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
@ -261,9 +250,14 @@ gTests.push({
|
|||
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
|
||||
|
||||
yield popupPromise;
|
||||
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
|
||||
|
||||
let string = SpecialPowers.getClipboardData("text/unicode");
|
||||
// The wait is needed to give time to populate the clipboard.
|
||||
let string = "";
|
||||
yield waitForCondition(function () {
|
||||
string = SpecialPowers.getClipboardData("text/unicode");
|
||||
return string === "hello";
|
||||
});
|
||||
|
||||
let inputValue = input.value;
|
||||
ok(string === "hello", "cut selected text in clipboard");
|
||||
ok(inputValue === ", I'm sorry but I must be going.", "cut selected text from input value");
|
||||
|
@ -280,7 +274,6 @@ gTests.push({
|
|||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, input, 20, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
@ -291,7 +284,6 @@ gTests.push({
|
|||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// context in empty input, no data on clipboard (??)
|
||||
|
@ -304,7 +296,6 @@ gTests.push({
|
|||
promise = waitForEvent(Elements.tray, "transitionend");
|
||||
sendContextMenuClickToElement(win, input, 20, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should *not* be visible
|
||||
ok(!ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
@ -346,12 +337,15 @@ gTests.push({
|
|||
let promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClick(225, 310);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible and at a specific position
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
is(ContextMenuUI._panel.left, 97.5, "left");
|
||||
is(ContextMenuUI._panel.top, 227, "top");
|
||||
|
||||
let notificationBox = Browser.getNotificationBox();
|
||||
let notification = notificationBox.getNotificationWithValue("popup-blocked");
|
||||
let notificationHeight = notification.boxObject.height;
|
||||
|
||||
checkContextMenuPositionRange(ContextMenuUI._panel, 65, 80, notificationHeight + 155, notificationHeight + 180);
|
||||
|
||||
ContextMenuUI._menuPopup.hide();
|
||||
|
||||
|
@ -385,7 +379,6 @@ gTests.push({
|
|||
let promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToWindow(win, 10, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
purgeEventQueue();
|
||||
|
||||
|
@ -421,9 +414,7 @@ gTests.push({
|
|||
let popupPromise = waitForEvent(document, "popuphidden");
|
||||
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
|
||||
yield popupPromise;
|
||||
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
|
||||
yield downloadPromise;
|
||||
ok(downloadPromise && !(downloadPromise instanceof Error), "promise error");
|
||||
|
||||
purgeEventQueue();
|
||||
|
||||
|
@ -435,7 +426,6 @@ gTests.push({
|
|||
let promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToWindow(win, 20, 20);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
menuItem = document.getElementById("context-copy-image");
|
||||
|
@ -444,7 +434,6 @@ gTests.push({
|
|||
popupPromise = waitForEvent(document, "popuphidden");
|
||||
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
|
||||
yield popupPromise;
|
||||
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
|
||||
|
||||
purgeEventQueue();
|
||||
|
||||
|
@ -458,7 +447,6 @@ gTests.push({
|
|||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToWindow(win, 30, 30);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
menuItem = document.getElementById("context-copy-image-loc");
|
||||
|
@ -467,7 +455,6 @@ gTests.push({
|
|||
popupPromise = waitForEvent(document, "popuphidden");
|
||||
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
|
||||
yield popupPromise;
|
||||
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
|
||||
|
||||
purgeEventQueue();
|
||||
|
||||
|
@ -484,7 +471,8 @@ gTests.push({
|
|||
let strLength = new Object();
|
||||
xfer.getTransferData("text/unicode", str, strLength);
|
||||
str = str.value.QueryInterface(Components.interfaces.nsISupportsString);
|
||||
ok(str == "chrome://mochitests/content/metro/res/image01.png", "url copied");
|
||||
|
||||
ok(str == chromeRoot + "res/image01.png", "url copied");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Open image in new tab
|
||||
|
@ -492,7 +480,6 @@ gTests.push({
|
|||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToWindow(win, 40, 40);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
menuItem = document.getElementById("context-open-image-tab");
|
||||
|
@ -503,8 +490,6 @@ gTests.push({
|
|||
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
|
||||
yield popupPromise;
|
||||
let event = yield tabPromise;
|
||||
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
|
||||
ok(tabPromise && !(tabPromise instanceof Error), "promise error");
|
||||
|
||||
purgeEventQueue();
|
||||
|
||||
|
@ -538,88 +523,75 @@ gTests.push({
|
|||
let promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(frame1.contentDocument.defaultView, link1, 85, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
checkContextMenuPositionRange(ContextMenuUI._panel, 290, 300, 160, 175);
|
||||
checkContextMenuPositionRange(ContextMenuUI._panel, 265, 280, 175, 190);
|
||||
|
||||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
frame1.contentDocument.defaultView.scrollBy(0, 200);
|
||||
|
||||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(frame1.contentDocument.defaultView, link1, 85, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
checkContextMenuPositionRange(ContextMenuUI._panel, 290, 300, 85, 90);
|
||||
checkContextMenuPositionRange(ContextMenuUI._panel, 265, 280, 95, 110);
|
||||
|
||||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
let rlink1 = win.document.getElementById("rlink1");
|
||||
|
||||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, rlink1, 40, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
checkContextMenuPositionRange(ContextMenuUI._panel, 640, 650, 540, 555);
|
||||
checkContextMenuPositionRange(ContextMenuUI._panel, 295, 310, 540, 555);
|
||||
|
||||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
win.scrollBy(0, 200);
|
||||
|
||||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(win, rlink1, 40, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
checkContextMenuPositionRange(ContextMenuUI._panel, 640, 650, 340, 355);
|
||||
checkContextMenuPositionRange(ContextMenuUI._panel, 295, 310, 340, 355);
|
||||
|
||||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
let link2 = frame1.contentDocument.getElementById("link2");
|
||||
|
||||
promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(frame1.contentDocument.defaultView, link2, 85, 10);
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
|
||||
// should be visible
|
||||
ok(ContextMenuUI._menuPopup._visible, "is visible");
|
||||
|
||||
info(ContextMenuUI._panel.left);
|
||||
info(ContextMenuUI._panel.top);
|
||||
|
||||
checkContextMenuPositionRange(ContextMenuUI._panel, 290, 300, 75, 85);
|
||||
checkContextMenuPositionRange(ContextMenuUI._panel, 265, 280, 110, 125);
|
||||
|
||||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
ok(promise && !(promise instanceof Error), "promise error");
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<body bgcolor=white>
|
||||
|
||||
Hello there. <a href="#hello">hello there.</a>
|
||||
<center>
|
||||
<div style="margin-left: 280px;">
|
||||
|
||||
<iframe id="frame1" width="800" height="600" src="text-block.html"></iframe>
|
||||
|
||||
|
@ -50,5 +50,5 @@ Hello there. <a id="rlink1" href="#hello">hello there.</a>
|
|||
<br />
|
||||
<br />
|
||||
|
||||
</center>
|
||||
</div>
|
||||
</body></html>
|
|
@ -46,14 +46,6 @@ function equalNumbers(){
|
|||
return true;
|
||||
}
|
||||
|
||||
function waitForMs(aDelay) {
|
||||
let deferred = Promise.defer();
|
||||
let timerID = setTimeout(function(){
|
||||
deferred.resolve(true);
|
||||
}, aDelay || 0);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function getPromisedDbResult(aStatement) {
|
||||
let dbConnection = Downloads.manager.DBConnection;
|
||||
let statement = ("string" == typeof aStatement) ?
|
||||
|
@ -120,6 +112,7 @@ let gDownloadRowTemplate = {
|
|||
// Test Infrastructure
|
||||
|
||||
function test() {
|
||||
DownloadsPanelView._view.clearDownloads();
|
||||
PanelUI.show("downloads-container");
|
||||
runTests();
|
||||
}
|
||||
|
@ -255,10 +248,6 @@ gTests.push({
|
|||
|
||||
yield isReady;
|
||||
|
||||
if (!isReady || isReady instanceof Error){
|
||||
ok(false, "DownloadsReady event never fired");
|
||||
}
|
||||
|
||||
let count = downloadslist.children.length;
|
||||
is(count, 0, "Zero items in grid view with empty downloads db");
|
||||
}
|
||||
|
|
|
@ -31,23 +31,29 @@ gTests.push({
|
|||
let doc = tab.browser.contentDocument;
|
||||
let text = doc.getElementById("text")
|
||||
let rect0 = text.getBoundingClientRect();
|
||||
text.focus();
|
||||
let rect0browserY = Math.floor(tab.browser.ptClientToBrowser(rect0.left, rect0.top).y);
|
||||
|
||||
// Simulate touch
|
||||
SelectionHelperUI.attachToCaret(tab.browser, rect0.left + 5, rect0.top + 5);
|
||||
|
||||
// "Show" the keyboard.
|
||||
MetroUtils.keyboardHeight = 100;
|
||||
MetroUtils.keyboardVisible = true;
|
||||
Services.obs.notifyObservers(null, "metro_softkeyboard_shown", null);
|
||||
|
||||
let event = yield waitForEvent(window, "MozDeckOffsetChanged");
|
||||
is(event.detail, 100, "deck offset by keyboard height");
|
||||
|
||||
let rect1 = text.getBoundingClientRect();
|
||||
is(rect1.top, rect0.top - 100, "text field moves up by 100px");
|
||||
let rect1browserY = Math.floor(tab.browser.ptClientToBrowser(rect1.left, rect1.top).y);
|
||||
is(rect1browserY, rect0browserY + 100, "text field moves up by 100px");
|
||||
|
||||
// "Hide" the keyboard.
|
||||
MetroUtils.keyboardHeight = 0;
|
||||
MetroUtils.keyboardVisible = false;
|
||||
Services.obs.notifyObservers(null, "metro_softkeyboard_hidden", null);
|
||||
|
||||
let rect2 = text.getBoundingClientRect();
|
||||
is(rect2.top, rect0.top, "text field moves back to the original position");
|
||||
yield waitForEvent(window, "MozDeckOffsetChanged");
|
||||
|
||||
finish();
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ gTests.push({
|
|||
|
||||
let tab = yield addTab(chromeRoot + "browser_plugin_input.html");
|
||||
|
||||
yield hideContextUI();
|
||||
|
||||
let doc = tab.browser.contentDocument;
|
||||
let plugin = doc.getElementById("plugin1");
|
||||
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
|
|
|
@ -20,6 +20,8 @@ gTests.push({
|
|||
|
||||
let tab = yield addTab(chromeRoot + "browser_plugin_input.html");
|
||||
|
||||
yield hideContextUI();
|
||||
|
||||
let doc = tab.browser.contentDocument;
|
||||
let plugin = doc.getElementById("plugin1");
|
||||
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
|
|
|
@ -193,6 +193,7 @@ gTests.push({
|
|||
is(grid.selectedIndex, 1, "selectedIndex is correct");
|
||||
|
||||
grid.toggleItemSelection(grid.children[1]);
|
||||
ok(!grid.children[1].selected, "toggleItemSelection sets falsy selected prop on previously-selected item");
|
||||
is(grid.selectedIndex, -1, "selectedIndex reports correctly with nothing selected");
|
||||
|
||||
// item selection
|
||||
|
@ -221,7 +222,7 @@ gTests.push({
|
|||
info("calling selectItem, currently it is:" + grid.children[0].selected);
|
||||
// Note: A richgrid in seltype=single mode fires "select" events from selectItem
|
||||
grid.selectItem(grid.children[0]);
|
||||
info("/calling selectItem, now it is:" + grid.children[0].selected);
|
||||
info("calling selectItem, now it is:" + grid.children[0].selected);
|
||||
yield waitForMs(0);
|
||||
|
||||
is(handlerStub.callCount, 1, "select event handler was called when we selected an item");
|
||||
|
|
|
@ -15,7 +15,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm
|
|||
const serverRoot = "http://example.com/browser/metro/";
|
||||
const baseURI = "http://mochi.test:8888/browser/metro/";
|
||||
const chromeRoot = getRootDirectory(gTestPath);
|
||||
const kDefaultWait = 10000;
|
||||
const kDefaultWait = 2000;
|
||||
const kDefaultInterval = 50;
|
||||
|
||||
/*=============================================================================
|
||||
|
@ -237,7 +237,7 @@ function waitForCondition(aCondition, aTimeoutMs, aIntervalMs) {
|
|||
try {
|
||||
condition = aCondition();
|
||||
} catch (e) {
|
||||
deferred.reject( new Error("Got exception while attempting to test conditino: " + e) );
|
||||
deferred.reject( new Error("Got exception while attempting to test condition: " + e) );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -475,14 +475,19 @@ function runTests() {
|
|||
Task.spawn(function() {
|
||||
while((gCurrentTest = gTests.shift())){
|
||||
info(gCurrentTest.desc);
|
||||
if ('function' == typeof gCurrentTest.setUp) {
|
||||
yield Task.spawn(gCurrentTest.setUp.bind(gCurrentTest));
|
||||
try {
|
||||
if ('function' == typeof gCurrentTest.setUp) {
|
||||
yield Task.spawn(gCurrentTest.setUp.bind(gCurrentTest));
|
||||
}
|
||||
yield Task.spawn(gCurrentTest.run.bind(gCurrentTest));
|
||||
if ('function' == typeof gCurrentTest.tearDown) {
|
||||
yield Task.spawn(gCurrentTest.tearDown.bind(gCurrentTest));
|
||||
}
|
||||
} catch (ex) {
|
||||
ok(false, "runTests: Task failed - " + ex);
|
||||
} finally {
|
||||
info("END "+gCurrentTest.desc);
|
||||
}
|
||||
yield Task.spawn(gCurrentTest.run.bind(gCurrentTest));
|
||||
if ('function' == typeof gCurrentTest.tearDown) {
|
||||
yield Task.spawn(gCurrentTest.tearDown.bind(gCurrentTest));
|
||||
}
|
||||
info("END "+gCurrentTest.desc);
|
||||
}
|
||||
finish();
|
||||
});
|
||||
|
|
|
@ -28,6 +28,12 @@ static const WCHAR* kFirefoxExe = L"firefox.exe";
|
|||
static const WCHAR* kDefaultMetroBrowserIDPathKey = L"FirefoxURL";
|
||||
static const WCHAR* kDemoMetroBrowserIDPathKey = L"Mozilla.Firefox.URL";
|
||||
|
||||
// Logging pipe handle
|
||||
HANDLE gTestOutputPipe = INVALID_HANDLE_VALUE;
|
||||
// Logging pipe read buffer
|
||||
#define PIPE_BUFFER_SIZE 4096
|
||||
char buffer[PIPE_BUFFER_SIZE + 1];
|
||||
|
||||
CString sAppParams;
|
||||
CString sFirefoxPath;
|
||||
|
||||
|
@ -156,12 +162,36 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
static void AddConsoleIdToParams()
|
||||
static bool SetupTestOutputPipe()
|
||||
{
|
||||
DWORD dwId = GetCurrentProcessId();
|
||||
CString tmp;
|
||||
tmp.Format(L" testconsoleid=%d", dwId);
|
||||
sAppParams += tmp;
|
||||
SECURITY_ATTRIBUTES saAttr;
|
||||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
saAttr.bInheritHandle = TRUE;
|
||||
saAttr.lpSecurityDescriptor = NULL;
|
||||
|
||||
gTestOutputPipe =
|
||||
CreateNamedPipeW(L"\\\\.\\pipe\\metrotestharness",
|
||||
PIPE_ACCESS_INBOUND,
|
||||
PIPE_TYPE_BYTE|PIPE_WAIT,
|
||||
1,
|
||||
PIPE_BUFFER_SIZE,
|
||||
PIPE_BUFFER_SIZE, 0, NULL);
|
||||
|
||||
if (gTestOutputPipe == INVALID_HANDLE_VALUE) {
|
||||
Log(L"Failed to create named logging pipe.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ReadPipe()
|
||||
{
|
||||
DWORD numBytesRead;
|
||||
while (ReadFile(gTestOutputPipe, buffer, PIPE_BUFFER_SIZE, &numBytesRead, NULL) &&
|
||||
numBytesRead) {
|
||||
buffer[numBytesRead] = '\0';
|
||||
printf("%s", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static bool Launch()
|
||||
|
@ -249,6 +279,12 @@ static bool Launch()
|
|||
FlushFileBuffers(hTestFile);
|
||||
CloseHandle(hTestFile);
|
||||
|
||||
// Create a named stdout pipe for the browser
|
||||
if (!SetupTestOutputPipe()) {
|
||||
Fail(L"SetupTestOutputPipe failed (errno=%d)", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Launch firefox
|
||||
hr = activateMgr->ActivateApplication(appModelID, L"", AO_NOERRORUI, &processID);
|
||||
if (FAILED(hr)) {
|
||||
|
@ -268,13 +304,24 @@ static bool Launch()
|
|||
|
||||
MSG msg;
|
||||
DWORD waitResult = WAIT_TIMEOUT;
|
||||
while ((waitResult = WaitForSingleObject(child, 10)) != WAIT_OBJECT_0) {
|
||||
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
HANDLE handles[2] = { child, gTestOutputPipe };
|
||||
while ((waitResult = MsgWaitForMultipleObjects(2, handles, FALSE, INFINITE, QS_ALLINPUT)) != WAIT_OBJECT_0) {
|
||||
if (waitResult == WAIT_FAILED) {
|
||||
Log(L"Wait failed (errno=%d)", GetLastError());
|
||||
break;
|
||||
} else if (waitResult == WAIT_OBJECT_0 + 1) {
|
||||
ReadPipe();
|
||||
} else if (waitResult == WAIT_OBJECT_0 + 2 &&
|
||||
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
ReadPipe();
|
||||
CloseHandle(gTestOutputPipe);
|
||||
CloseHandle(child);
|
||||
|
||||
Log(L"Exiting.");
|
||||
return true;
|
||||
}
|
||||
|
@ -307,7 +354,6 @@ int wmain(int argc, WCHAR* argv[])
|
|||
if (sFirefoxPath.GetLength()) {
|
||||
Log(L"firefoxpath: '%s'", sFirefoxPath);
|
||||
}
|
||||
AddConsoleIdToParams();
|
||||
Log(L"args: '%s'", sAppParams);
|
||||
Launch();
|
||||
|
||||
|
|
|
@ -858,6 +858,11 @@ setting[type="directory"] > .preferences-alignment {
|
|||
visibility: collapse;
|
||||
}
|
||||
|
||||
/*tile content should be on same line in snapped view */
|
||||
#snapped-topsites-grid > richgriditem > .richgrid-item-content {
|
||||
-moz-box-orient: horizontal;
|
||||
}
|
||||
|
||||
/* if snapped, hide the fullscreen awesome screen, if viewstate is anything
|
||||
* other than snapped, hide the snapped awesome screen */
|
||||
#start[viewstate="snapped"],
|
||||
|
@ -981,9 +986,9 @@ setting[type="directory"] > .preferences-alignment {
|
|||
.overlay-button {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
margin-top: -66px;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
margin-top: -65px;
|
||||
width: 118px;
|
||||
height: 118px;
|
||||
background-color: hsla(210,30%,10%,.2);
|
||||
background-size: 60px;
|
||||
background-repeat: no-repeat;
|
||||
|
@ -998,14 +1003,22 @@ setting[type="directory"] > .preferences-alignment {
|
|||
}
|
||||
|
||||
#overlay-back {
|
||||
left: -72px;
|
||||
background-image: url(chrome://browser/skin/images/overlay-back.png);
|
||||
background-position: right 6px center;
|
||||
}
|
||||
|
||||
#overlay-plus {
|
||||
right: -72px;
|
||||
background-image: url(chrome://browser/skin/images/overlay-plus.png);
|
||||
}
|
||||
|
||||
#overlay-back:-moz-locale-dir(ltr),
|
||||
#overlay-plus:-moz-locale-dir(rtl) {
|
||||
left: -70px;
|
||||
background-position: right 6px center;
|
||||
}
|
||||
|
||||
#overlay-plus:-moz-locale-dir(ltr),
|
||||
#overlay-back:-moz-locale-dir(rtl) {
|
||||
right: -70px;
|
||||
background-position: left 6px center;
|
||||
}
|
||||
|
||||
|
@ -1013,26 +1026,30 @@ setting[type="directory"] > .preferences-alignment {
|
|||
box-shadow: none;
|
||||
}
|
||||
|
||||
#overlay-back[disabled] {
|
||||
#overlay-back[disabled]:-moz-locale-dir(ltr),
|
||||
#overlay-plus[disabled]:-moz-locale-dir(rtl) {
|
||||
transform: translateX(-60px);
|
||||
}
|
||||
|
||||
#overlay-plus[disabled] {
|
||||
#overlay-plus[disabled]:-moz-locale-dir(ltr),
|
||||
#overlay-back[disabled]:-moz-locale-dir(rtl) {
|
||||
transform: translateX(60px);
|
||||
}
|
||||
|
||||
.overlay-button:not([disabled]):hover {
|
||||
background-color: hsla(210,30%,10%,.4);
|
||||
background-size: 78px;
|
||||
background-size: 90px;
|
||||
border-color: hsla(0,0%,100%,.9);
|
||||
}
|
||||
|
||||
#overlay-back:not([disabled]):hover {
|
||||
#overlay-back:not([disabled]):-moz-locale-dir(ltr):hover,
|
||||
#overlay-plus:not([disabled]):-moz-locale-dir(rtl):hover {
|
||||
background-position: right 12px center;
|
||||
transform: translateX(40px) scale(1.2);
|
||||
}
|
||||
|
||||
#overlay-plus:not([disabled]):hover {
|
||||
#overlay-plus:not([disabled]):-moz-locale-dir(ltr):hover,
|
||||
#overlay-back:not([disabled]):-moz-locale-dir(rtl):hover {
|
||||
background-position: left 12px center;
|
||||
transform: translateX(-40px) scale(1.2);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,46 @@ this.AboutHomeUtils = {
|
|||
name: defaultEngine.name,
|
||||
searchURL: submission.uri.spec
|
||||
});
|
||||
},
|
||||
|
||||
/*
|
||||
* showKnowYourRights - Determines if the user should be shown the
|
||||
* about:rights notification. The notification should *not* be shown if
|
||||
* we've already shown the current version, or if the override pref says to
|
||||
* never show it. The notification *should* be shown if it's never been seen
|
||||
* before, if a newer version is available, or if the override pref says to
|
||||
* always show it.
|
||||
*/
|
||||
get showKnowYourRights() {
|
||||
// Look for an unconditional override pref. If set, do what it says.
|
||||
// (true --> never show, false --> always show)
|
||||
try {
|
||||
return !Services.prefs.getBoolPref("browser.rights.override");
|
||||
} catch (e) { }
|
||||
// Ditto, for the legacy EULA pref.
|
||||
try {
|
||||
return !Services.prefs.getBoolPref("browser.EULA.override");
|
||||
} catch (e) { }
|
||||
|
||||
#ifndef MOZILLA_OFFICIAL
|
||||
// Non-official builds shouldn't show the notification.
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// Look to see if the user has seen the current version or not.
|
||||
var currentVersion = Services.prefs.getIntPref("browser.rights.version");
|
||||
try {
|
||||
return !Services.prefs.getBoolPref("browser.rights." + currentVersion + ".shown");
|
||||
} catch (e) { }
|
||||
|
||||
// Legacy: If the user accepted a EULA, we won't annoy them with the
|
||||
// equivalent about:rights page until the version changes.
|
||||
try {
|
||||
return !Services.prefs.getBoolPref("browser.EULA." + currentVersion + ".accepted");
|
||||
} catch (e) { }
|
||||
|
||||
// We haven't shown the notification before, so do so now.
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ include $(DEPTH)/config/autoconf.mk
|
|||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
EXTRA_JS_MODULES = \
|
||||
AboutHomeUtils.jsm \
|
||||
BrowserNewTabPreloader.jsm \
|
||||
openLocationLastURL.jsm \
|
||||
NetworkPrioritizer.jsm \
|
||||
|
@ -25,6 +24,7 @@ EXTRA_JS_MODULES = \
|
|||
$(NULL)
|
||||
|
||||
EXTRA_PP_JS_MODULES = \
|
||||
AboutHomeUtils.jsm \
|
||||
RecentWindow.jsm \
|
||||
$(NULL)
|
||||
|
||||
|
@ -36,4 +36,8 @@ EXTRA_JS_MODULES += \
|
|||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZILLA_OFFICIAL
|
||||
DEFINES += -DMOZILLA_OFFICIAL=1
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -75,9 +75,24 @@ case "$target" in
|
|||
mipsel)
|
||||
target_name=mipsel-linux-android-$version
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([target cpu is not supported])
|
||||
;;
|
||||
esac
|
||||
case "$host_cpu" in
|
||||
i*86)
|
||||
android_toolchain="$android_ndk"/toolchains/$target_name/prebuilt/$kernel_name-x86
|
||||
;;
|
||||
x86_64)
|
||||
android_toolchain="$android_ndk"/toolchains/$target_name/prebuilt/$kernel_name-x86_64
|
||||
if ! test -d "$android_toolchain" ; then
|
||||
android_toolchain="$android_ndk"/toolchains/$target_name/prebuilt/$kernel_name-x86
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([No known toolchain for your host cpu])
|
||||
;;
|
||||
esac
|
||||
android_toolchain="$android_ndk"/toolchains/$target_name/prebuilt/$kernel_name-x86
|
||||
|
||||
if test -d "$android_toolchain" ; then
|
||||
android_gnu_compiler_version=$version
|
||||
break
|
||||
|
@ -91,8 +106,11 @@ case "$target" in
|
|||
else
|
||||
AC_MSG_RESULT([$android_toolchain])
|
||||
fi
|
||||
NSPR_CONFIGURE_ARGS="$NSPR_CONFIGURE_ARGS --with-android-toolchain=$android_toolchain"
|
||||
fi
|
||||
|
||||
NSPR_CONFIGURE_ARGS="$NSPR_CONFIGURE_ARGS --with-android-version=$android_version"
|
||||
|
||||
if test -z "$android_platform" ; then
|
||||
AC_MSG_CHECKING([for android platform directory])
|
||||
|
||||
|
@ -115,6 +133,7 @@ case "$target" in
|
|||
else
|
||||
AC_MSG_ERROR([not found. You have to specify --with-android-platform=/path/to/ndk/platform.])
|
||||
fi
|
||||
NSPR_CONFIGURE_ARGS="$NSPR_CONFIGURE_ARGS --with-android-platform=$android_platform"
|
||||
fi
|
||||
|
||||
dnl Old NDK support. If minimum requirement is changed to NDK r8b,
|
||||
|
@ -167,11 +186,8 @@ case "$target" in
|
|||
ANDROID_NDK="${android_ndk}"
|
||||
ANDROID_TOOLCHAIN="${android_toolchain}"
|
||||
ANDROID_PLATFORM="${android_platform}"
|
||||
ANDROID_VERSION="${android_version}"
|
||||
|
||||
AC_DEFINE(ANDROID)
|
||||
AC_DEFINE_UNQUOTED(ANDROID_VERSION, $android_version)
|
||||
AC_SUBST(ANDROID_VERSION)
|
||||
CROSS_COMPILE=1
|
||||
AC_SUBST(ANDROID_NDK)
|
||||
AC_SUBST(ANDROID_TOOLCHAIN)
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
dnl This Source Code Form is subject to the terms of the Mozilla Public
|
||||
dnl License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
dnl Output the contents of config.log when configure exits with an
|
||||
dnl error code.
|
||||
define([MOZ_CONFIG_LOG_TRAP],
|
||||
[changequote(<<<, >>>)dnl
|
||||
trap '[ "$?" != 0 ] && echo "------ config.log ------" && tail -n 25 config.log' EXIT
|
||||
changequote([, ])dnl
|
||||
])
|
||||
|
||||
dnl Wrap AC_INIT_PREPARE to add the above trap.
|
||||
define([_MOZ_AC_INIT_PREPARE], defn([AC_INIT_PREPARE]))
|
||||
define([AC_INIT_PREPARE],
|
||||
[_MOZ_AC_INIT_PREPARE($1)
|
||||
MOZ_CONFIG_LOG_TRAP
|
||||
])
|
||||
|
||||
dnl Disable the trap when running sub-configures.
|
||||
define([_MOZ_AC_OUTPUT_SUBDIRS], defn([AC_OUTPUT_SUBDIRS]))
|
||||
define([AC_OUTPUT_SUBDIRS],
|
||||
[trap '' EXIT
|
||||
_MOZ_AC_OUTPUT_SUBDIRS($1)
|
||||
MOZ_CONFIG_LOG_TRAP
|
||||
])
|
|
@ -16,6 +16,7 @@ CPPSRCS := \
|
|||
|
||||
TESTSRCS := \
|
||||
TestMustOverride.cpp \
|
||||
TestStackClass.cpp \
|
||||
$(NULL)
|
||||
|
||||
OBJS := $(patsubst %.cpp,%.o,$(CPPSRCS))
|
||||
|
@ -30,7 +31,7 @@ $(OBJS): %.o: %.cpp Makefile
|
|||
|
||||
$(PLUGIN): $(OBJS)
|
||||
rm -f $@
|
||||
$(CXX) -shared -o $@ $(CXXFLAGS) $(LDFLAGS) $(OBJS)
|
||||
$(CXX) -shared -o $@ $(CXXFLAGS) $(LDFLAGS) $(OBJS) -lclangASTMatchers
|
||||
|
||||
TESTFLAGS := -fsyntax-only -Xclang -verify \
|
||||
-Xclang -load -Xclang $(CURDIR)/$(PLUGIN) \
|
||||
|
|
|
@ -4,9 +4,12 @@
|
|||
#include "clang/AST/ASTConsumer.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/RecursiveASTVisitor.h"
|
||||
#include "clang/ASTMatchers/ASTMatchers.h"
|
||||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/FrontendPluginRegistry.h"
|
||||
#include "clang/Frontend/MultiplexConsumer.h"
|
||||
#include "clang/Sema/Sema.h"
|
||||
|
||||
#define CLANG_VERSION_FULL (CLANG_VERSION_MAJOR * 100 + CLANG_VERSION_MINOR)
|
||||
|
@ -15,11 +18,37 @@ using namespace llvm;
|
|||
using namespace clang;
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace clang::ast_matchers;
|
||||
class DiagnosticsMatcher {
|
||||
public:
|
||||
DiagnosticsMatcher();
|
||||
|
||||
ASTConsumer *makeASTConsumer() {
|
||||
return astMatcher.newASTConsumer();
|
||||
}
|
||||
|
||||
private:
|
||||
class StackClassChecker : public MatchFinder::MatchCallback {
|
||||
public:
|
||||
virtual void run(const MatchFinder::MatchResult &Result);
|
||||
};
|
||||
|
||||
StackClassChecker stackClassChecker;
|
||||
MatchFinder astMatcher;
|
||||
};
|
||||
|
||||
class MozChecker : public ASTConsumer, public RecursiveASTVisitor<MozChecker> {
|
||||
DiagnosticsEngine &Diag;
|
||||
const CompilerInstance &CI;
|
||||
DiagnosticsMatcher matcher;
|
||||
public:
|
||||
MozChecker(const CompilerInstance &CI) : Diag(CI.getDiagnostics()), CI(CI) {}
|
||||
|
||||
ASTConsumer *getOtherConsumer() {
|
||||
return matcher.makeASTConsumer();
|
||||
}
|
||||
|
||||
virtual void HandleTranslationUnit(ASTContext &ctx) {
|
||||
TraverseDecl(ctx.getTranslationUnitDecl());
|
||||
}
|
||||
|
@ -58,6 +87,16 @@ public:
|
|||
if (hasCustomAnnotation(*M, "moz_must_override"))
|
||||
must_overrides.push_back(*M);
|
||||
}
|
||||
|
||||
// While we are looping over parent classes, we'll also check to make sure
|
||||
// that the subclass has the annotation if the superclass does.
|
||||
if (hasCustomAnnotation(parent, "moz_stack_class") &&
|
||||
!hasCustomAnnotation(d, "moz_stack_class")) {
|
||||
unsigned badInheritID = Diag.getDiagnosticIDs()->getCustomDiagID(
|
||||
DiagnosticIDs::Error, "%0 inherits from a stack class %1");
|
||||
Diag.Report(d->getLocation(), badInheritID)
|
||||
<< d->getDeclName() << parent->getDeclName();
|
||||
}
|
||||
}
|
||||
|
||||
for (OverridesVector::iterator it = must_overrides.begin();
|
||||
|
@ -84,11 +123,78 @@ public:
|
|||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
namespace ast_matchers {
|
||||
|
||||
/// This matcher will match any class with the stack class assertion or an
|
||||
/// array of such classes.
|
||||
AST_MATCHER(QualType, stackClassAggregate) {
|
||||
QualType t = Node;
|
||||
while (const ArrayType *arrTy = t->getAsArrayTypeUnsafe())
|
||||
t = arrTy->getElementType();
|
||||
CXXRecordDecl *clazz = t->getAsCXXRecordDecl();
|
||||
return clazz && MozChecker::hasCustomAnnotation(clazz, "moz_stack_class");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
DiagnosticsMatcher::DiagnosticsMatcher() {
|
||||
// Stack class assertion: non-local variables of a stack class are forbidden
|
||||
// (non-localness checked in the callback)
|
||||
astMatcher.addMatcher(varDecl(hasType(stackClassAggregate())).bind("node"),
|
||||
&stackClassChecker);
|
||||
// Stack class assertion: new stack class is forbidden (unless placement new)
|
||||
astMatcher.addMatcher(newExpr(hasType(pointerType(
|
||||
pointee(stackClassAggregate())
|
||||
))).bind("node"), &stackClassChecker);
|
||||
// Stack class assertion: a stack-class field is permitted only if it's a
|
||||
// member of a class with the annotation
|
||||
astMatcher.addMatcher(fieldDecl(hasType(stackClassAggregate())).bind("field"),
|
||||
&stackClassChecker);
|
||||
}
|
||||
|
||||
void DiagnosticsMatcher::StackClassChecker::run(
|
||||
const MatchFinder::MatchResult &Result) {
|
||||
DiagnosticsEngine &Diag = Result.Context->getDiagnostics();
|
||||
unsigned stackID = Diag.getDiagnosticIDs()->getCustomDiagID(
|
||||
DiagnosticIDs::Error, "variable of type %0 only valid on the stack");
|
||||
if (const VarDecl *d = Result.Nodes.getNodeAs<VarDecl>("node")) {
|
||||
// Ignore the match if it's a local variable.
|
||||
if (d->hasLocalStorage())
|
||||
return;
|
||||
Diag.Report(d->getLocation(), stackID) << d->getType();
|
||||
} else if (const CXXNewExpr *expr =
|
||||
Result.Nodes.getNodeAs<CXXNewExpr>("node")) {
|
||||
// If it's placement new, then this match doesn't count.
|
||||
if (expr->getNumPlacementArgs() > 0)
|
||||
return;
|
||||
Diag.Report(expr->getStartLoc(), stackID) << expr->getAllocatedType();
|
||||
} else if (const FieldDecl *field =
|
||||
Result.Nodes.getNodeAs<FieldDecl>("field")) {
|
||||
// AST matchers don't let me get the class that contains a field...
|
||||
const RecordDecl *parent = field->getParent();
|
||||
if (!MozChecker::hasCustomAnnotation(parent, "moz_stack_class")) {
|
||||
// We use a more verbose error message here.
|
||||
unsigned stackID = Diag.getDiagnosticIDs()->getCustomDiagID(
|
||||
DiagnosticIDs::Error,
|
||||
"member of type %0 in class %1 that is not a stack class");
|
||||
Diag.Report(field->getLocation(), stackID) << field->getType() <<
|
||||
parent->getDeclName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MozCheckAction : public PluginASTAction {
|
||||
public:
|
||||
ASTConsumer *CreateASTConsumer(CompilerInstance &CI, StringRef fileName) {
|
||||
return new MozChecker(CI);
|
||||
MozChecker *checker = new MozChecker(CI);
|
||||
|
||||
ASTConsumer *consumers[] = { checker, checker->getOtherConsumer() };
|
||||
return new MultiplexConsumer(consumers);
|
||||
}
|
||||
|
||||
bool ParseArgs(const CompilerInstance &CI,
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
#define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class")))
|
||||
#include <stddef.h>
|
||||
|
||||
struct MOZ_STACK_CLASS Stack {
|
||||
int i;
|
||||
void *operator new(size_t x) { return 0; }
|
||||
void *operator new(size_t blah, char *buffer) { return buffer; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct MOZ_STACK_CLASS TemplateClass {
|
||||
T i;
|
||||
};
|
||||
|
||||
void gobble(void *) { }
|
||||
|
||||
void misuseStackClass(int len) {
|
||||
Stack valid;
|
||||
Stack alsoValid[2];
|
||||
static Stack notValid; // expected-error {{variable of type 'Stack' only valid on the stack}}
|
||||
static Stack alsoNotValid[2]; // expected-error {{variable of type 'Stack [2]' only valid on the stack}}
|
||||
|
||||
gobble(&valid);
|
||||
gobble(¬Valid);
|
||||
gobble(&alsoValid[0]);
|
||||
|
||||
gobble(new Stack); // expected-error {{variable of type 'Stack' only valid on the stack}}
|
||||
gobble(new Stack[10]); // expected-error {{variable of type 'Stack' only valid on the stack}}
|
||||
gobble(new TemplateClass<int>); // expected-error {{variable of type 'TemplateClass<int>' only valid on the stack}}
|
||||
gobble(len <= 5 ? &valid : new Stack); // expected-error {{variable of type 'Stack' only valid on the stack}}
|
||||
|
||||
char buffer[sizeof(Stack)];
|
||||
gobble(new (buffer) Stack);
|
||||
}
|
||||
|
||||
Stack notValid; // expected-error {{variable of type 'Stack' only valid on the stack}}
|
||||
struct RandomClass {
|
||||
Stack nonstaticMember; // expected-error {{member of type 'Stack' in class 'RandomClass' that is not a stack class}}
|
||||
static Stack staticMember; // expected-error {{variable of type 'Stack' only valid on the stack}}
|
||||
};
|
||||
struct MOZ_STACK_CLASS RandomStackClass {
|
||||
Stack nonstaticMember;
|
||||
static Stack staticMember; // expected-error {{variable of type 'Stack' only valid on the stack}}
|
||||
};
|
||||
|
||||
struct BadInherit : Stack {}; // expected-error {{'BadInherit' inherits from a stack class 'Stack'}}
|
||||
struct MOZ_STACK_CLASS GoodInherit : Stack {};
|
|
@ -15,7 +15,8 @@ import tarfile
|
|||
import subprocess
|
||||
import platform
|
||||
import sys
|
||||
import simplejson
|
||||
import json
|
||||
import collections
|
||||
|
||||
def check_run(args):
|
||||
r = subprocess.call(args)
|
||||
|
@ -74,26 +75,16 @@ def build_one_stage(env, stage_dir, is_stage_one):
|
|||
with_env(env, f)
|
||||
|
||||
def build_tooltool_manifest():
|
||||
def key_sort(item):
|
||||
item = item[0]
|
||||
if item == 'size':
|
||||
return 0
|
||||
if item == 'digest':
|
||||
return 1
|
||||
if item == 'algorithm':
|
||||
return 3
|
||||
return 4
|
||||
|
||||
basedir = os.path.split(os.path.realpath(sys.argv[0]))[0]
|
||||
tooltool = basedir + '/tooltool.py'
|
||||
setup = basedir + '/setup.sh'
|
||||
manifest = 'clang.manifest'
|
||||
check_run(['python', tooltool, '-m', manifest, 'add',
|
||||
setup, 'clang.tar.bz2'])
|
||||
data = simplejson.load(file(manifest))
|
||||
data = json.load(file(manifest), object_pairs_hook=collections.OrderedDict)
|
||||
data = [{'clang_version' : 'r%s' % llvm_revision }] + data
|
||||
out = file(manifest,'w')
|
||||
simplejson.dump(data, out, indent=0, item_sort_key=key_sort)
|
||||
json.dump(data, out, indent=0)
|
||||
out.write('\n')
|
||||
|
||||
assert data[2]['filename'] == 'clang.tar.bz2'
|
||||
|
|
|
@ -2485,6 +2485,7 @@ if test -n "$MOZ_LINKER"; then
|
|||
AC_DEFINE(MOZ_LINKER)
|
||||
fi
|
||||
AC_SUBST(MOZ_ENABLE_SZIP)
|
||||
AC_SUBST(MOZ_SZIP_FLAGS)
|
||||
|
||||
dnl Only one oddball right now (QNX), but this gives us flexibility
|
||||
dnl if any other platforms need to override this in the future.
|
||||
|
@ -3963,7 +3964,7 @@ MOZ_ARG_WITH_BOOL(system-nss,
|
|||
_USE_SYSTEM_NSS=1 )
|
||||
|
||||
if test -n "$_USE_SYSTEM_NSS"; then
|
||||
AM_PATH_NSS(3.14.3, [MOZ_NATIVE_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
|
||||
AM_PATH_NSS(3.15, [MOZ_NATIVE_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
|
||||
fi
|
||||
|
||||
if test -n "$MOZ_NATIVE_NSS"; then
|
||||
|
@ -4377,7 +4378,7 @@ if test -f "${srcdir}/${MOZ_BUILD_APP}/configure.in" ; then
|
|||
_subconfigure_subdir="$1"
|
||||
_subconfigure_config_args="$ac_configure_args"
|
||||
}
|
||||
tmpscript=`python -c 'import os, tempfile; print tempfile.mktemp(prefix="subscript.").replace(os.sep, "/")'` || exit 1
|
||||
tmpscript=`$PYTHON -c 'import os, tempfile; print tempfile.mktemp(prefix="subscript.").replace(os.sep, "/")'` || exit 1
|
||||
m4 "${srcdir}/build/autoconf/subconfigure.m4" \
|
||||
"${srcdir}/build/autoconf/altoptions.m4" \
|
||||
"${srcdir}/${MOZ_BUILD_APP}/configure.in" > $tmpscript
|
||||
|
@ -9334,7 +9335,7 @@ if test -n "$_WRAP_MALLOC"; then
|
|||
fi
|
||||
|
||||
if test -z "$MOZ_NATIVE_NSPR"; then
|
||||
ac_configure_args="$_SUBDIR_CONFIG_ARGS --with-dist-prefix=$MOZ_BUILD_ROOT/dist --with-mozilla --with-android-version=$ANDROID_VERSION"
|
||||
ac_configure_args="$_SUBDIR_CONFIG_ARGS --with-dist-prefix=$MOZ_BUILD_ROOT/dist --with-mozilla"
|
||||
if test -z "$MOZ_DEBUG"; then
|
||||
ac_configure_args="$ac_configure_args --disable-debug"
|
||||
else
|
||||
|
|
|
@ -650,8 +650,7 @@ public:
|
|||
already_AddRefed<Attr> RemoveAttributeNode(Attr& aOldAttr,
|
||||
ErrorResult& aError);
|
||||
Attr* GetAttributeNodeNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aLocalName,
|
||||
ErrorResult& aError);
|
||||
const nsAString& aLocalName);
|
||||
already_AddRefed<Attr> SetAttributeNodeNS(Attr& aNewAttr,
|
||||
ErrorResult& aError);
|
||||
|
||||
|
@ -1065,8 +1064,7 @@ protected:
|
|||
}
|
||||
|
||||
Attr* GetAttributeNodeNSInternal(const nsAString& aNamespaceURI,
|
||||
const nsAString& aLocalName,
|
||||
ErrorResult& aError);
|
||||
const nsAString& aLocalName);
|
||||
|
||||
void RegisterFreezableElement() {
|
||||
OwnerDoc()->RegisterFreezableElement(this);
|
||||
|
@ -1413,11 +1411,9 @@ NS_IMETHOD GetAttributeNodeNS(const nsAString& namespaceURI, \
|
|||
const nsAString& localName, \
|
||||
nsIDOMAttr** _retval) MOZ_FINAL \
|
||||
{ \
|
||||
mozilla::ErrorResult rv; \
|
||||
NS_IF_ADDREF(*_retval = Element::GetAttributeNodeNS(namespaceURI, \
|
||||
localName, \
|
||||
rv)); \
|
||||
return rv.ErrorCode(); \
|
||||
localName)); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD SetAttributeNodeNS(nsIDOMAttr* newAttr, \
|
||||
nsIDOMAttr** _retval) MOZ_FINAL \
|
||||
|
|
|
@ -30,42 +30,6 @@ NS_NewElement(nsIContent** aResult,
|
|||
nsresult
|
||||
NS_NewXMLElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
|
||||
/**
|
||||
* aNodeInfoManager must not be null.
|
||||
*/
|
||||
nsresult
|
||||
NS_NewTextNode(nsIContent **aResult, nsNodeInfoManager *aNodeInfoManager);
|
||||
|
||||
/**
|
||||
* aNodeInfoManager must not be null.
|
||||
*/
|
||||
nsresult
|
||||
NS_NewCommentNode(nsIContent **aResult, nsNodeInfoManager *aNodeInfoManager);
|
||||
|
||||
/**
|
||||
* aNodeInfoManager must not be null.
|
||||
*/
|
||||
nsresult
|
||||
NS_NewXMLProcessingInstruction(nsIContent** aInstancePtrResult,
|
||||
nsNodeInfoManager *aNodeInfoManager,
|
||||
const nsAString& aTarget,
|
||||
const nsAString& aData);
|
||||
|
||||
/**
|
||||
* aNodeInfoManager must not be null.
|
||||
*/
|
||||
nsresult
|
||||
NS_NewXMLStylesheetProcessingInstruction(nsIContent** aInstancePtrResult,
|
||||
nsNodeInfoManager *aNodeInfoManager,
|
||||
const nsAString& aData);
|
||||
|
||||
/**
|
||||
* aNodeInfoManager must not be null.
|
||||
*/
|
||||
nsresult
|
||||
NS_NewXMLCDATASection(nsIContent** aInstancePtrResult,
|
||||
nsNodeInfoManager *aNodeInfoManager);
|
||||
|
||||
nsresult
|
||||
NS_NewHTMLElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
mozilla::dom::FromParser aFromParser);
|
||||
|
|
|
@ -97,6 +97,7 @@ class nsScriptObjectTracer;
|
|||
class nsStringHashKey;
|
||||
class nsTextFragment;
|
||||
class nsViewportInfo;
|
||||
class nsIFrame;
|
||||
|
||||
struct JSContext;
|
||||
struct JSPropertyDescriptor;
|
||||
|
@ -2115,6 +2116,21 @@ public:
|
|||
int32_t& aOutStartOffset,
|
||||
int32_t& aOutEndOffset);
|
||||
|
||||
/**
|
||||
* Takes a frame for anonymous content within a text control (<input> or
|
||||
* <textarea>), and returns an offset in the text content, adjusted for a
|
||||
* trailing <br> frame.
|
||||
*
|
||||
* @param aOffsetFrame Frame for the text content in which the offset
|
||||
* lies
|
||||
* @param aOffset Offset as calculated by GetContentOffsetsFromPoint
|
||||
* @param aOutOffset Output adjusted offset
|
||||
*
|
||||
* @see GetSelectionInTextControl for the original basis of this function.
|
||||
*/
|
||||
static int32_t GetAdjustedOffsetInTextControl(nsIFrame* aOffsetFrame,
|
||||
int32_t aOffset);
|
||||
|
||||
static nsIEditor* GetHTMLEditor(nsPresContext* aPresContext);
|
||||
|
||||
/**
|
||||
|
@ -2252,7 +2268,7 @@ typedef nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
|
|||
nsContentUtils::DropJSObjects(NS_CYCLE_COLLECTION_UPCAST(obj, clazz))
|
||||
|
||||
|
||||
class NS_STACK_CLASS nsCxPusher
|
||||
class MOZ_STACK_CLASS nsCxPusher
|
||||
{
|
||||
public:
|
||||
nsCxPusher();
|
||||
|
@ -2286,7 +2302,7 @@ private:
|
|||
#endif
|
||||
};
|
||||
|
||||
class NS_STACK_CLASS nsAutoScriptBlocker {
|
||||
class MOZ_STACK_CLASS nsAutoScriptBlocker {
|
||||
public:
|
||||
nsAutoScriptBlocker(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) {
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
|
@ -2299,7 +2315,7 @@ private:
|
|||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class NS_STACK_CLASS nsAutoScriptBlockerSuppressNodeRemoved :
|
||||
class MOZ_STACK_CLASS nsAutoScriptBlockerSuppressNodeRemoved :
|
||||
public nsAutoScriptBlocker {
|
||||
public:
|
||||
nsAutoScriptBlockerSuppressNodeRemoved() {
|
||||
|
@ -2314,7 +2330,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class NS_STACK_CLASS nsAutoMicroTask
|
||||
class MOZ_STACK_CLASS nsAutoMicroTask
|
||||
{
|
||||
public:
|
||||
nsAutoMicroTask()
|
||||
|
@ -2334,7 +2350,7 @@ namespace mozilla {
|
|||
* passed as a parameter. AutoJSContext will take care of finding the most
|
||||
* appropriate JS context and release it when leaving the stack.
|
||||
*/
|
||||
class NS_STACK_CLASS AutoJSContext {
|
||||
class MOZ_STACK_CLASS AutoJSContext {
|
||||
public:
|
||||
AutoJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
|
||||
operator JSContext*();
|
||||
|
@ -2357,7 +2373,7 @@ private:
|
|||
* SafeAutoJSContext is similar to AutoJSContext but will only return the safe
|
||||
* JS context. That means it will never call ::GetCurrentJSContext().
|
||||
*/
|
||||
class NS_STACK_CLASS SafeAutoJSContext : public AutoJSContext {
|
||||
class MOZ_STACK_CLASS SafeAutoJSContext : public AutoJSContext {
|
||||
public:
|
||||
SafeAutoJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
|
||||
};
|
||||
|
@ -2376,7 +2392,7 @@ public:
|
|||
* NB: This will not push a null cx even if aCx is null. Make sure you know what
|
||||
* you're doing.
|
||||
*/
|
||||
class NS_STACK_CLASS AutoPushJSContext {
|
||||
class MOZ_STACK_CLASS AutoPushJSContext {
|
||||
nsCxPusher mPusher;
|
||||
JSContext* mCx;
|
||||
|
||||
|
|
|
@ -490,7 +490,7 @@ private:
|
|||
nsISupports *mParent;
|
||||
};
|
||||
|
||||
class NS_STACK_CLASS nsDOMFileInternalUrlHolder {
|
||||
class MOZ_STACK_CLASS nsDOMFileInternalUrlHolder {
|
||||
public:
|
||||
nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile, nsIPrincipal* aPrincipal
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
|
|
|
@ -1951,11 +1951,10 @@ public:
|
|||
const nsAString& aQualifiedName,
|
||||
mozilla::ErrorResult& rv);
|
||||
already_AddRefed<mozilla::dom::DocumentFragment>
|
||||
CreateDocumentFragment(mozilla::ErrorResult& rv) const;
|
||||
already_AddRefed<nsTextNode> CreateTextNode(const nsAString& aData,
|
||||
mozilla::ErrorResult& rv) const;
|
||||
CreateDocumentFragment() const;
|
||||
already_AddRefed<nsTextNode> CreateTextNode(const nsAString& aData) const;
|
||||
already_AddRefed<mozilla::dom::Comment>
|
||||
CreateComment(const nsAString& aData, mozilla::ErrorResult& rv) const;
|
||||
CreateComment(const nsAString& aData) const;
|
||||
already_AddRefed<mozilla::dom::ProcessingInstruction>
|
||||
CreateProcessingInstruction(const nsAString& target, const nsAString& data,
|
||||
mozilla::ErrorResult& rv) const;
|
||||
|
@ -2431,7 +2430,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocument, NS_IDOCUMENT_IID)
|
|||
* event is dispatched, if necessary, when the outermost mozAutoSubtreeModified
|
||||
* object is deleted.
|
||||
*/
|
||||
class NS_STACK_CLASS mozAutoSubtreeModified
|
||||
class MOZ_STACK_CLASS mozAutoSubtreeModified
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
@ -2468,7 +2467,7 @@ private:
|
|||
nsCOMPtr<nsIDocument> mSubtreeOwner;
|
||||
};
|
||||
|
||||
class NS_STACK_CLASS nsAutoSyncOperation
|
||||
class MOZ_STACK_CLASS nsAutoSyncOperation
|
||||
{
|
||||
public:
|
||||
nsAutoSyncOperation(nsIDocument* aDocument);
|
||||
|
@ -2494,14 +2493,6 @@ NS_NewImageDocument(nsIDocument** aInstancePtrResult);
|
|||
nsresult
|
||||
NS_NewVideoDocument(nsIDocument** aInstancePtrResult);
|
||||
|
||||
already_AddRefed<mozilla::dom::DocumentFragment>
|
||||
NS_NewDocumentFragment(nsNodeInfoManager* aNodeInfoManager,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
nsresult
|
||||
NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
|
||||
nsNodeInfoManager *aNodeInfoManager);
|
||||
|
||||
// Note: it's the caller's responsibility to create or get aPrincipal as needed
|
||||
// -- this method will not attempt to get a principal based on aDocumentURI.
|
||||
// Also, both aDocumentURI and aBaseURI must not be null.
|
||||
|
|
|
@ -25,7 +25,7 @@ interface nsIURI;
|
|||
* interface to mirror this interface when changing it.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(e2ef99fe-f7d3-422f-a7b4-834e8bdde710)]
|
||||
[scriptable, uuid(24a35de3-40e4-498e-9c1b-2fd0a2d4cae5)]
|
||||
interface nsIObjectLoadingContent : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -149,16 +149,6 @@ interface nsIObjectLoadingContent : nsISupports
|
|||
*/
|
||||
[noscript] void initializeFromChannel(in nsIRequest request);
|
||||
|
||||
/**
|
||||
* Requests the plugin instance for scripting, attempting to spawn it if
|
||||
* appropriate.
|
||||
*
|
||||
* The first time content js tries to access a pre-empted plugin
|
||||
* (click-to-play or play preview), an event is dispatched.
|
||||
*/
|
||||
[noscript] nsNPAPIPluginInstancePtr
|
||||
scriptRequestPluginInstance(in bool callerIsContentJS);
|
||||
|
||||
/**
|
||||
* The URL of the data/src loaded in the object. This may be null (i.e.
|
||||
* an <embed> with no src).
|
||||
|
|
|
@ -15,7 +15,7 @@ class nsIContent;
|
|||
* See the documentation of nsIParserUtils::sanitize for documentation
|
||||
* about the default behavior and the configuration options of this sanitizer.
|
||||
*/
|
||||
class NS_STACK_CLASS nsTreeSanitizer {
|
||||
class MOZ_STACK_CLASS nsTreeSanitizer {
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ static const int32_t kViewportDefaultScreenWidth = 980;
|
|||
* Information retrieved from the <meta name="viewport"> tag. See
|
||||
* nsContentUtils::GetViewportInfo for more information on this functionality.
|
||||
*/
|
||||
class NS_STACK_CLASS nsViewportInfo
|
||||
class MOZ_STACK_CLASS nsViewportInfo
|
||||
{
|
||||
public:
|
||||
nsViewportInfo(uint32_t aDisplayWidth, uint32_t aDisplayHeight) :
|
||||
|
|
|
@ -117,7 +117,6 @@ Attr::SetOwnerDocument(nsIDocument* aDocument)
|
|||
GetNodeInfo(mNodeInfo->NameAtom(), mNodeInfo->GetPrefixAtom(),
|
||||
mNodeInfo->NamespaceID(),
|
||||
nsIDOMNode::ATTRIBUTE_NODE);
|
||||
NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ASSERTION(newNodeInfo, "GetNodeInfo lies");
|
||||
mNodeInfo.swap(newNodeInfo);
|
||||
|
||||
|
|
|
@ -15,27 +15,6 @@
|
|||
using namespace mozilla;
|
||||
using namespace dom;
|
||||
|
||||
nsresult
|
||||
NS_NewCommentNode(nsIContent** aInstancePtrResult,
|
||||
nsNodeInfoManager *aNodeInfoManager)
|
||||
{
|
||||
NS_PRECONDITION(aNodeInfoManager, "Missing nodeinfo manager");
|
||||
|
||||
*aInstancePtrResult = nullptr;
|
||||
|
||||
nsCOMPtr<nsINodeInfo> ni = aNodeInfoManager->GetCommentNodeInfo();
|
||||
NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
Comment *instance = new Comment(ni.forget());
|
||||
if (!instance) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(*aInstancePtrResult = instance);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
|
|
|
@ -15,14 +15,27 @@ namespace dom {
|
|||
class Comment : public nsGenericDOMDataNode,
|
||||
public nsIDOMComment
|
||||
{
|
||||
public:
|
||||
Comment(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsGenericDOMDataNode(aNodeInfo)
|
||||
private:
|
||||
void Init()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::COMMENT_NODE,
|
||||
"Bad NodeType in aNodeInfo");
|
||||
SetIsDOMBinding();
|
||||
}
|
||||
|
||||
public:
|
||||
Comment(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsGenericDOMDataNode(aNodeInfo)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
Comment(nsNodeInfoManager* aNodeInfoManager)
|
||||
: nsGenericDOMDataNode(aNodeInfoManager->GetCommentNodeInfo())
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
virtual ~Comment();
|
||||
|
||||
// nsISupports
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "nsContentUtils.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "DocumentType.h"
|
||||
#include "nsTextNode.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -219,9 +220,7 @@ DOMImplementation::CreateHTMLDocument(const nsAString& aTitle,
|
|||
rv = head->AppendChildTo(title, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIContent> titleText;
|
||||
rv = NS_NewTextNode(getter_AddRefs(titleText), doc->NodeInfoManager());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsRefPtr<nsTextNode> titleText = new nsTextNode(doc->NodeInfoManager());
|
||||
rv = titleText->SetText(aTitle, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = title->AppendChildTo(titleText, false);
|
||||
|
|
|
@ -18,54 +18,9 @@
|
|||
#include "nsContentUtils.h"
|
||||
#include "mozilla/dom/DocumentFragmentBinding.h"
|
||||
|
||||
nsresult
|
||||
NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
|
||||
nsNodeInfoManager *aNodeInfoManager)
|
||||
{
|
||||
mozilla::ErrorResult rv;
|
||||
*aInstancePtrResult = NS_NewDocumentFragment(aNodeInfoManager, rv).get();
|
||||
return rv.ErrorCode();
|
||||
}
|
||||
|
||||
already_AddRefed<mozilla::dom::DocumentFragment>
|
||||
NS_NewDocumentFragment(nsNodeInfoManager* aNodeInfoManager,
|
||||
mozilla::ErrorResult& aRv)
|
||||
{
|
||||
using namespace mozilla::dom;
|
||||
|
||||
if (!aNodeInfoManager) {
|
||||
aRv.Throw(NS_ERROR_INVALID_ARG);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo =
|
||||
aNodeInfoManager->GetNodeInfo(nsGkAtoms::documentFragmentNodeName,
|
||||
nullptr, kNameSpaceID_None,
|
||||
nsIDOMNode::DOCUMENT_FRAGMENT_NODE);
|
||||
if (!nodeInfo) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<DocumentFragment> it = new DocumentFragment(nodeInfo.forget());
|
||||
return it.forget();
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
DocumentFragment::DocumentFragment(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: FragmentOrElement(aNodeInfo), mHost(nullptr)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mNodeInfo->NodeType() ==
|
||||
nsIDOMNode::DOCUMENT_FRAGMENT_NODE &&
|
||||
mNodeInfo->Equals(nsGkAtoms::documentFragmentNodeName,
|
||||
kNameSpaceID_None),
|
||||
"Bad NodeType in aNodeInfo");
|
||||
|
||||
SetIsDOMBinding();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
DocumentFragment::WrapNode(JSContext *aCx, JSObject *aScope)
|
||||
{
|
||||
|
|
|
@ -37,7 +37,35 @@ public:
|
|||
// interface nsIDOMDocumentFragment
|
||||
// NS_DECL_NSIDOCUMENTFRAGMENT Empty
|
||||
|
||||
DocumentFragment(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
private:
|
||||
void Init()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mNodeInfo->NodeType() ==
|
||||
nsIDOMNode::DOCUMENT_FRAGMENT_NODE &&
|
||||
mNodeInfo->Equals(nsGkAtoms::documentFragmentNodeName,
|
||||
kNameSpaceID_None),
|
||||
"Bad NodeType in aNodeInfo");
|
||||
|
||||
SetIsDOMBinding();
|
||||
}
|
||||
|
||||
public:
|
||||
DocumentFragment(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: FragmentOrElement(aNodeInfo), mHost(nullptr)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
DocumentFragment(nsNodeInfoManager* aNodeInfoManager)
|
||||
: FragmentOrElement(aNodeInfoManager->GetNodeInfo(
|
||||
nsGkAtoms::documentFragmentNodeName,
|
||||
nullptr, kNameSpaceID_None,
|
||||
nsIDOMNode::DOCUMENT_FRAGMENT_NODE)),
|
||||
mHost(nullptr)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
virtual ~DocumentFragment()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -50,10 +50,6 @@ NS_NewDOMDocumentType(nsNodeInfoManager* aNodeInfoManager,
|
|||
kNameSpaceID_None,
|
||||
nsIDOMNode::DOCUMENT_TYPE_NODE,
|
||||
aName);
|
||||
if (!ni) {
|
||||
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<mozilla::dom::DocumentType> docType =
|
||||
new mozilla::dom::DocumentType(ni.forget(), aPublicId, aSystemId, aInternalSubset);
|
||||
|
|
|
@ -129,6 +129,7 @@
|
|||
#include "nsXBLService.h"
|
||||
#include "nsContentCID.h"
|
||||
#include "nsITextControlElement.h"
|
||||
#include "mozilla/dom/DocumentFragment.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -876,20 +877,18 @@ Element::RemoveAttributeNS(const nsAString& aNamespaceURI,
|
|||
|
||||
Attr*
|
||||
Element::GetAttributeNodeNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aLocalName,
|
||||
ErrorResult& aError)
|
||||
const nsAString& aLocalName)
|
||||
{
|
||||
OwnerDoc()->WarnOnceAbout(nsIDocument::eGetAttributeNodeNS);
|
||||
|
||||
return GetAttributeNodeNSInternal(aNamespaceURI, aLocalName, aError);
|
||||
return GetAttributeNodeNSInternal(aNamespaceURI, aLocalName);
|
||||
}
|
||||
|
||||
Attr*
|
||||
Element::GetAttributeNodeNSInternal(const nsAString& aNamespaceURI,
|
||||
const nsAString& aLocalName,
|
||||
ErrorResult& aError)
|
||||
const nsAString& aLocalName)
|
||||
{
|
||||
return Attributes()->GetNamedItemNS(aNamespaceURI, aLocalName, aError);
|
||||
return Attributes()->GetNamedItemNS(aNamespaceURI, aLocalName);
|
||||
}
|
||||
|
||||
already_AddRefed<Attr>
|
||||
|
@ -1829,7 +1828,6 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
|
|||
ni = mNodeInfo->NodeInfoManager()->GetNodeInfo(aName, aPrefix,
|
||||
aNamespaceID,
|
||||
nsIDOMNode::ATTRIBUTE_NODE);
|
||||
NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = mAttrsAndChildren.SetAndTakeAttr(ni, aParsedValue);
|
||||
}
|
||||
|
@ -1864,9 +1862,8 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
|
|||
|
||||
nsAutoString ns;
|
||||
nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNamespaceID, ns);
|
||||
ErrorResult rv;
|
||||
Attr* attrNode =
|
||||
GetAttributeNodeNSInternal(ns, nsDependentAtomString(aName), rv);
|
||||
GetAttributeNodeNSInternal(ns, nsDependentAtomString(aName));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = aName;
|
||||
|
@ -1995,8 +1992,7 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
if (hasMutationListeners) {
|
||||
nsAutoString ns;
|
||||
nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNameSpaceID, ns);
|
||||
ErrorResult rv;
|
||||
attrNode = GetAttributeNodeNSInternal(ns, nsDependentAtomString(aName), rv);
|
||||
attrNode = GetAttributeNodeNSInternal(ns, nsDependentAtomString(aName));
|
||||
}
|
||||
|
||||
// Clear binding to nsIDOMMozNamedAttrMap
|
||||
|
@ -3398,13 +3394,8 @@ Element::SetOuterHTML(const nsAString& aOuterHTML, ErrorResult& aError)
|
|||
localName = nsGkAtoms::body;
|
||||
namespaceID = kNameSpaceID_XHTML;
|
||||
}
|
||||
nsCOMPtr<nsIDOMDocumentFragment> df;
|
||||
aError = NS_NewDocumentFragment(getter_AddRefs(df),
|
||||
OwnerDoc()->NodeInfoManager());
|
||||
if (aError.Failed()) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIContent> fragment = do_QueryInterface(df);
|
||||
nsRefPtr<DocumentFragment> fragment =
|
||||
new DocumentFragment(OwnerDoc()->NodeInfoManager());
|
||||
nsContentUtils::ParseFragmentHTML(aOuterHTML,
|
||||
fragment,
|
||||
localName,
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* in which case no updates will be called. The constructor also takes a
|
||||
* boolean that can be set to false to prevent notifications.
|
||||
*/
|
||||
class NS_STACK_CLASS mozAutoDocUpdate
|
||||
class MOZ_STACK_CLASS mozAutoDocUpdate
|
||||
{
|
||||
public:
|
||||
mozAutoDocUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType,
|
||||
|
@ -63,7 +63,7 @@ private:
|
|||
* but then have inner mozAutoDocUpdate call the last EndUpdate before.
|
||||
* we remove that blocker. See bug 423269.
|
||||
*/
|
||||
class NS_STACK_CLASS mozAutoDocConditionalContentUpdateBatch
|
||||
class MOZ_STACK_CLASS mozAutoDocConditionalContentUpdateBatch
|
||||
{
|
||||
public:
|
||||
mozAutoDocConditionalContentUpdateBatch(nsIDocument* aDocument,
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "nsString.h"
|
||||
#include "nsAttrValue.h"
|
||||
|
||||
class NS_STACK_CLASS nsAttrValueOrString
|
||||
class MOZ_STACK_CLASS nsAttrValueOrString
|
||||
{
|
||||
public:
|
||||
nsAttrValueOrString(const nsAString& aValue)
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
#include "nsDOMDataTransfer.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
class NS_STACK_CLASS DragDataProducer
|
||||
class MOZ_STACK_CLASS DragDataProducer
|
||||
{
|
||||
public:
|
||||
DragDataProducer(nsPIDOMWindow* aWindow,
|
||||
|
|
|
@ -434,7 +434,7 @@ protected:
|
|||
*/
|
||||
class nsCacheableFuncStringContentList;
|
||||
|
||||
class NS_STACK_CLASS nsFuncStringCacheKey {
|
||||
class MOZ_STACK_CLASS nsFuncStringCacheKey {
|
||||
public:
|
||||
nsFuncStringCacheKey(nsINode* aRootNode,
|
||||
nsContentListMatchFunc aFunc,
|
||||
|
|
|
@ -101,6 +101,7 @@
|
|||
#include "nsIFormControl.h"
|
||||
#include "nsIForm.h"
|
||||
#include "nsIFragmentContentSink.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
#include "nsIIdleService.h"
|
||||
#include "nsIImageLoadingContent.h"
|
||||
|
@ -157,6 +158,7 @@
|
|||
#include "nsSVGFeatures.h"
|
||||
#include "nsTextEditorState.h"
|
||||
#include "nsTextFragment.h"
|
||||
#include "nsTextNode.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsUnicharUtilCIID.h"
|
||||
#include "nsUnicodeProperties.h"
|
||||
|
@ -2929,7 +2931,7 @@ nsContentUtils::NameChanged(nsINodeInfo* aNodeInfo, nsIAtom* aName,
|
|||
aNodeInfo->NamespaceID(),
|
||||
aNodeInfo->NodeType(),
|
||||
aNodeInfo->GetExtraName()).get();
|
||||
return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -4152,7 +4154,7 @@ nsContentUtils::CreateContextualFragment(nsINode* aContextNode,
|
|||
|
||||
if (isHTML) {
|
||||
nsRefPtr<DocumentFragment> frag =
|
||||
NS_NewDocumentFragment(document->NodeInfoManager(), aRv);
|
||||
new DocumentFragment(document->NodeInfoManager());
|
||||
|
||||
nsCOMPtr<nsIContent> contextAsContent = do_QueryInterface(aContextNode);
|
||||
if (contextAsContent && !contextAsContent->IsElement()) {
|
||||
|
@ -4478,14 +4480,12 @@ nsContentUtils::SetNodeTextContent(nsIContent* aContent,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> textContent;
|
||||
nsresult rv = NS_NewTextNode(getter_AddRefs(textContent),
|
||||
aContent->NodeInfo()->NodeInfoManager());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsRefPtr<nsTextNode> textContent =
|
||||
new nsTextNode(aContent->NodeInfo()->NodeInfoManager());
|
||||
|
||||
textContent->SetText(aValue, true);
|
||||
|
||||
rv = aContent->AppendChildTo(textContent, true);
|
||||
nsresult rv = aContent->AppendChildTo(textContent, true);
|
||||
mb.NodesAdded();
|
||||
return rv;
|
||||
}
|
||||
|
@ -6751,6 +6751,40 @@ nsContentUtils::TraceWrapper(nsWrapperCache* aCache, TraceCallback aCallback,
|
|||
}
|
||||
}
|
||||
|
||||
// static
|
||||
int32_t
|
||||
nsContentUtils::GetAdjustedOffsetInTextControl(nsIFrame* aOffsetFrame,
|
||||
int32_t aOffset)
|
||||
{
|
||||
// The structure of the anonymous frames within a text control frame is
|
||||
// an optional block frame, followed by an optional br frame.
|
||||
|
||||
// If the offset frame has a child, then this frame is the block which
|
||||
// has the text frames (containing the content) as its children. This will
|
||||
// be the case if we click to the right of any of the text frames, or at the
|
||||
// bottom of the text area.
|
||||
nsIFrame* firstChild = aOffsetFrame->GetFirstPrincipalChild();
|
||||
if (firstChild) {
|
||||
// In this case, the passed-in offset is incorrect, and we want the length
|
||||
// of the entire content in the text control frame.
|
||||
return firstChild->GetContent()->Length();
|
||||
}
|
||||
|
||||
if (aOffsetFrame->GetPrevSibling() &&
|
||||
!aOffsetFrame->GetNextSibling()) {
|
||||
// In this case, we're actually within the last frame, which is a br
|
||||
// frame. Our offset should therefore be the length of the first child of
|
||||
// our parent.
|
||||
int32_t aOutOffset =
|
||||
aOffsetFrame->GetParent()->GetFirstPrincipalChild()->GetContent()->Length();
|
||||
return aOutOffset;
|
||||
}
|
||||
|
||||
// Otherwise, we're within one of the text frames, in which case our offset
|
||||
// has already been correctly calculated.
|
||||
return aOffset;
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsContentUtils::GetSelectionInTextControl(Selection* aSelection,
|
||||
|
|
|
@ -349,10 +349,8 @@ nsDOMAttributeMap::RemoveNamedItem(const nsAString& aName,
|
|||
|
||||
|
||||
Attr*
|
||||
nsDOMAttributeMap::GetItemAt(uint32_t aIndex, nsresult *aResult)
|
||||
nsDOMAttributeMap::GetItemAt(uint32_t aIndex)
|
||||
{
|
||||
*aResult = NS_OK;
|
||||
|
||||
Attr* node = nullptr;
|
||||
|
||||
const nsAttrName* name;
|
||||
|
@ -363,12 +361,7 @@ nsDOMAttributeMap::GetItemAt(uint32_t aIndex, nsresult *aResult)
|
|||
ni = mContent->NodeInfo()->NodeInfoManager()->
|
||||
GetNodeInfo(name->LocalName(), name->GetPrefix(), name->NamespaceID(),
|
||||
nsIDOMNode::ATTRIBUTE_NODE);
|
||||
if (ni) {
|
||||
node = GetAttribute(ni, true);
|
||||
}
|
||||
else {
|
||||
*aResult = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
node = GetAttribute(ni, true);
|
||||
}
|
||||
|
||||
return node;
|
||||
|
@ -377,9 +370,8 @@ nsDOMAttributeMap::GetItemAt(uint32_t aIndex, nsresult *aResult)
|
|||
NS_IMETHODIMP
|
||||
nsDOMAttributeMap::Item(uint32_t aIndex, nsIDOMAttr** aReturn)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_IF_ADDREF(*aReturn = GetItemAt(aIndex, &rv));
|
||||
return rv;
|
||||
NS_IF_ADDREF(*aReturn = GetItemAt(aIndex));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -402,17 +394,15 @@ nsDOMAttributeMap::GetNamedItemNS(const nsAString& aNamespaceURI,
|
|||
const nsAString& aLocalName,
|
||||
nsIDOMAttr** aReturn)
|
||||
{
|
||||
ErrorResult rv;
|
||||
NS_IF_ADDREF(*aReturn = GetNamedItemNS(aNamespaceURI, aLocalName, rv));
|
||||
return rv.ErrorCode();
|
||||
NS_IF_ADDREF(*aReturn = GetNamedItemNS(aNamespaceURI, aLocalName));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Attr*
|
||||
nsDOMAttributeMap::GetNamedItemNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aLocalName,
|
||||
ErrorResult& aError)
|
||||
const nsAString& aLocalName)
|
||||
{
|
||||
nsCOMPtr<nsINodeInfo> ni = GetAttrNodeInfo(aNamespaceURI, aLocalName, aError);
|
||||
nsCOMPtr<nsINodeInfo> ni = GetAttrNodeInfo(aNamespaceURI, aLocalName);
|
||||
if (!ni) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -422,8 +412,7 @@ nsDOMAttributeMap::GetNamedItemNS(const nsAString& aNamespaceURI,
|
|||
|
||||
already_AddRefed<nsINodeInfo>
|
||||
nsDOMAttributeMap::GetAttrNodeInfo(const nsAString& aNamespaceURI,
|
||||
const nsAString& aLocalName,
|
||||
mozilla::ErrorResult& aError)
|
||||
const nsAString& aLocalName)
|
||||
{
|
||||
if (!mContent) {
|
||||
return nullptr;
|
||||
|
@ -452,9 +441,6 @@ nsDOMAttributeMap::GetAttrNodeInfo(const nsAString& aNamespaceURI,
|
|||
ni = mContent->NodeInfo()->NodeInfoManager()->
|
||||
GetNodeInfo(nameAtom, name->GetPrefix(), nameSpaceID,
|
||||
nsIDOMNode::ATTRIBUTE_NODE);
|
||||
if (!ni) {
|
||||
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
return ni.forget();
|
||||
}
|
||||
|
@ -471,11 +457,7 @@ nsDOMAttributeMap::RemoveNamedItemNS(const nsAString& aNamespaceURI,
|
|||
NS_ENSURE_ARG_POINTER(aReturn);
|
||||
*aReturn = nullptr;
|
||||
|
||||
ErrorResult error;
|
||||
nsCOMPtr<nsINodeInfo> ni = GetAttrNodeInfo(aNamespaceURI, aLocalName, error);
|
||||
if (error.Failed()) {
|
||||
return error.ErrorCode();
|
||||
}
|
||||
nsCOMPtr<nsINodeInfo> ni = GetAttrNodeInfo(aNamespaceURI, aLocalName);
|
||||
|
||||
if (!ni) {
|
||||
return NS_ERROR_DOM_NOT_FOUND_ERR;
|
||||
|
|
|
@ -138,7 +138,7 @@ public:
|
|||
*/
|
||||
uint32_t Enumerate(AttrCache::EnumReadFunction aFunc, void *aUserArg) const;
|
||||
|
||||
mozilla::dom::Attr* GetItemAt(uint32_t aIndex, nsresult *rv);
|
||||
mozilla::dom::Attr* GetItemAt(uint32_t aIndex);
|
||||
mozilla::dom::Attr* GetNamedItem(const nsAString& aAttrName);
|
||||
|
||||
static nsDOMAttributeMap* FromSupports(nsISupports* aSupports)
|
||||
|
@ -161,8 +161,7 @@ public:
|
|||
NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMAttributeMap)
|
||||
|
||||
mozilla::dom::Attr* GetNamedItemNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aLocalName,
|
||||
mozilla::ErrorResult& aError);
|
||||
const nsAString& aLocalName);
|
||||
|
||||
already_AddRefed<mozilla::dom::Attr> SetNamedItemNS(nsIDOMAttr *aNode,
|
||||
mozilla::ErrorResult& aError)
|
||||
|
@ -191,8 +190,7 @@ private:
|
|||
|
||||
already_AddRefed<nsINodeInfo>
|
||||
GetAttrNodeInfo(const nsAString& aNamespaceURI,
|
||||
const nsAString& aLocalName,
|
||||
mozilla::ErrorResult& aError);
|
||||
const nsAString& aLocalName);
|
||||
|
||||
mozilla::dom::Attr* GetAttribute(nsINodeInfo* aNodeInfo, bool aNsAware);
|
||||
|
||||
|
|
|
@ -202,6 +202,9 @@
|
|||
#include "nsDOMEvent.h"
|
||||
#include "nsIContentPermissionPrompt.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsITextControlElement.h"
|
||||
#include "nsIDOMNSEditableElement.h"
|
||||
#include "nsIEditor.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -1849,6 +1852,13 @@ nsDocument::Init()
|
|||
mRadioGroups.Init();
|
||||
mCustomPrototypes.Init();
|
||||
|
||||
// If after creation the owner js global is not set for a document
|
||||
// we use the default compartment for this document, instead of creating
|
||||
// wrapper in some random compartment when the document is exposed to js
|
||||
// via some events.
|
||||
mScopeObject = do_GetWeakReference(xpc::GetNativeForGlobal(xpc::GetJunkScope()));
|
||||
MOZ_ASSERT(mScopeObject);
|
||||
|
||||
// Force initialization.
|
||||
nsINode::nsSlots* slots = Slots();
|
||||
|
||||
|
@ -4775,75 +4785,49 @@ nsIDocument::CreateElementNS(const nsAString& aNamespaceURI,
|
|||
NS_IMETHODIMP
|
||||
nsDocument::CreateTextNode(const nsAString& aData, nsIDOMText** aReturn)
|
||||
{
|
||||
ErrorResult rv;
|
||||
*aReturn = nsIDocument::CreateTextNode(aData, rv).get();
|
||||
return rv.ErrorCode();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::CreateTextNode(const nsAString& aData, nsIContent** aReturn)
|
||||
{
|
||||
ErrorResult rv;
|
||||
*aReturn = nsIDocument::CreateTextNode(aData, rv).get();
|
||||
return rv.ErrorCode();
|
||||
*aReturn = nsIDocument::CreateTextNode(aData).get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<nsTextNode>
|
||||
nsIDocument::CreateTextNode(const nsAString& aData, ErrorResult& rv) const
|
||||
nsIDocument::CreateTextNode(const nsAString& aData) const
|
||||
{
|
||||
nsCOMPtr<nsIContent> content;
|
||||
nsresult res = NS_NewTextNode(getter_AddRefs(content), mNodeInfoManager);
|
||||
if (NS_FAILED(res)) {
|
||||
rv.Throw(res);
|
||||
return nullptr;
|
||||
}
|
||||
nsRefPtr<nsTextNode> text = new nsTextNode(mNodeInfoManager);
|
||||
// Don't notify; this node is still being created.
|
||||
content->SetText(aData, false);
|
||||
return static_cast<nsTextNode*>(content.forget().get());
|
||||
text->SetText(aData, false);
|
||||
return text.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::CreateDocumentFragment(nsIDOMDocumentFragment** aReturn)
|
||||
{
|
||||
ErrorResult rv;
|
||||
*aReturn = nsIDocument::CreateDocumentFragment(rv).get();
|
||||
return rv.ErrorCode();
|
||||
*aReturn = nsIDocument::CreateDocumentFragment().get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<DocumentFragment>
|
||||
nsIDocument::CreateDocumentFragment(ErrorResult& rv) const
|
||||
nsIDocument::CreateDocumentFragment() const
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocumentFragment> frag;
|
||||
nsresult res = NS_NewDocumentFragment(getter_AddRefs(frag), mNodeInfoManager);
|
||||
if (NS_FAILED(res)) {
|
||||
rv.Throw(res);
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<DocumentFragment*>(frag.forget().get());
|
||||
nsRefPtr<DocumentFragment> frag = new DocumentFragment(mNodeInfoManager);
|
||||
return frag.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::CreateComment(const nsAString& aData, nsIDOMComment** aReturn)
|
||||
{
|
||||
ErrorResult rv;
|
||||
*aReturn = nsIDocument::CreateComment(aData, rv).get();
|
||||
return rv.ErrorCode();
|
||||
*aReturn = nsIDocument::CreateComment(aData).get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Unfortunately, bareword "Comment" is ambiguous with some Mac system headers.
|
||||
already_AddRefed<dom::Comment>
|
||||
nsIDocument::CreateComment(const nsAString& aData, ErrorResult& rv) const
|
||||
nsIDocument::CreateComment(const nsAString& aData) const
|
||||
{
|
||||
nsCOMPtr<nsIContent> comment;
|
||||
nsresult res = NS_NewCommentNode(getter_AddRefs(comment), mNodeInfoManager);
|
||||
if (NS_FAILED(res)) {
|
||||
rv.Throw(res);
|
||||
return nullptr;
|
||||
}
|
||||
nsRefPtr<dom::Comment> comment = new dom::Comment(mNodeInfoManager);
|
||||
|
||||
// Don't notify; this node is still being created.
|
||||
comment->SetText(aData, false);
|
||||
return static_cast<dom::Comment*>(comment.forget().get());
|
||||
return comment.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -4870,18 +4854,12 @@ nsIDocument::CreateCDATASection(const nsAString& aData,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
nsresult res = NS_NewXMLCDATASection(getter_AddRefs(content),
|
||||
mNodeInfoManager);
|
||||
if (NS_FAILED(res)) {
|
||||
rv.Throw(res);
|
||||
return nullptr;
|
||||
}
|
||||
nsRefPtr<CDATASection> cdata = new CDATASection(mNodeInfoManager);
|
||||
|
||||
// Don't notify; this node is still being created.
|
||||
content->SetText(aData, false);
|
||||
cdata->SetText(aData, false);
|
||||
|
||||
return static_cast<CDATASection*>(content.forget().get());
|
||||
return cdata.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -4910,15 +4888,10 @@ nsIDocument::CreateProcessingInstruction(const nsAString& aTarget,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
res = NS_NewXMLProcessingInstruction(getter_AddRefs(content),
|
||||
mNodeInfoManager, aTarget, aData);
|
||||
if (NS_FAILED(res)) {
|
||||
rv.Throw(res);
|
||||
return nullptr;
|
||||
}
|
||||
nsRefPtr<ProcessingInstruction> pi =
|
||||
NS_NewXMLProcessingInstruction(mNodeInfoManager, aTarget, aData);
|
||||
|
||||
return static_cast<ProcessingInstruction*>(content.forget().get());
|
||||
return pi.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -5941,8 +5914,6 @@ nsDocument::SetTitle(const nsAString& aTitle)
|
|||
titleInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::title, nullptr,
|
||||
kNameSpaceID_XHTML,
|
||||
nsIDOMNode::ELEMENT_NODE);
|
||||
if (!titleInfo)
|
||||
return NS_OK;
|
||||
title = NS_NewHTMLTitleElement(titleInfo.forget());
|
||||
if (!title)
|
||||
return NS_OK;
|
||||
|
@ -6595,6 +6566,12 @@ nsIDocument::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv)
|
|||
case nsIDOMNode::COMMENT_NODE:
|
||||
case nsIDOMNode::DOCUMENT_TYPE_NODE:
|
||||
{
|
||||
// Don't allow adopting a node's anonymous subtree out from under it.
|
||||
if (adoptedNode->AsContent()->IsRootOfAnonymousSubtree()) {
|
||||
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// We don't want to adopt an element into its own contentDocument or into
|
||||
// a descendant contentDocument, so we check if the frameElement of this
|
||||
// document or any of its parents is the adopted node or one of its
|
||||
|
@ -6616,7 +6593,9 @@ nsIDocument::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv)
|
|||
// Remove from parent.
|
||||
nsCOMPtr<nsINode> parent = adoptedNode->GetParentNode();
|
||||
if (parent) {
|
||||
parent->RemoveChildAt(parent->IndexOf(adoptedNode), true);
|
||||
int32_t idx = parent->IndexOf(adoptedNode);
|
||||
MOZ_ASSERT(idx >= 0);
|
||||
parent->RemoveChildAt(idx, true);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -9342,7 +9321,10 @@ nsIDocument::CaretPositionFromPoint(float aX, float aY)
|
|||
|
||||
nsCOMPtr<nsIContent> node = offsets.content;
|
||||
uint32_t offset = offsets.offset;
|
||||
if (node && node->IsInNativeAnonymousSubtree()) {
|
||||
nsCOMPtr<nsIContent> anonNode = node;
|
||||
bool nodeIsAnonymous = node && node->IsInNativeAnonymousSubtree();
|
||||
if (nodeIsAnonymous) {
|
||||
node = ptFrame->GetContent();
|
||||
nsIContent* nonanon = node->FindFirstNonChromeOnlyAccessContent();
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> input = do_QueryInterface(nonanon);
|
||||
nsCOMPtr<nsIDOMHTMLTextAreaElement> textArea = do_QueryInterface(nonanon);
|
||||
|
@ -9350,6 +9332,7 @@ nsIDocument::CaretPositionFromPoint(float aX, float aY)
|
|||
if (textArea || (input &&
|
||||
NS_SUCCEEDED(input->MozIsTextField(false, &isText)) &&
|
||||
isText)) {
|
||||
offset = nsContentUtils::GetAdjustedOffsetInTextControl(ptFrame, offset);
|
||||
node = nonanon;
|
||||
} else {
|
||||
node = nullptr;
|
||||
|
|
|
@ -817,8 +817,6 @@ public:
|
|||
int32_t aNamespaceID,
|
||||
nsIContent **aResult);
|
||||
|
||||
nsresult CreateTextNode(const nsAString& aData, nsIContent** aReturn);
|
||||
|
||||
virtual NS_HIDDEN_(nsresult) Sanitize();
|
||||
|
||||
virtual NS_HIDDEN_(void) EnumerateSubDocuments(nsSubDocEnumFunc aCallback,
|
||||
|
|
|
@ -742,7 +742,7 @@ AllDescendantsOfType(nsIDocShellTreeItem* aParentItem, int32_t aType)
|
|||
* A class that automatically sets mInShow to false when it goes
|
||||
* out of scope.
|
||||
*/
|
||||
class NS_STACK_CLASS AutoResetInShow {
|
||||
class MOZ_STACK_CLASS AutoResetInShow {
|
||||
private:
|
||||
nsFrameLoader* mFrameLoader;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
|
|
|
@ -85,6 +85,35 @@ nsNodeInfoManager::NodeInfoInnerKeyCompare(const void *key1, const void *key2)
|
|||
}
|
||||
|
||||
|
||||
static void* PR_CALLBACK
|
||||
AllocTable(void* pool, PRSize size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static void PR_CALLBACK
|
||||
FreeTable(void* pool, void* item)
|
||||
{
|
||||
free(item);
|
||||
}
|
||||
|
||||
static PLHashEntry* PR_CALLBACK
|
||||
AllocEntry(void* pool, const void* key)
|
||||
{
|
||||
return (PLHashEntry*)malloc(sizeof(PLHashEntry));
|
||||
}
|
||||
|
||||
static void PR_CALLBACK
|
||||
FreeEntry(void* pool, PLHashEntry* he, PRUintn flag)
|
||||
{
|
||||
if (flag == HT_FREE_ENTRY) {
|
||||
free(he);
|
||||
}
|
||||
}
|
||||
|
||||
static PLHashAllocOps allocOps =
|
||||
{ AllocTable, FreeTable, AllocEntry, FreeEntry };
|
||||
|
||||
nsNodeInfoManager::nsNodeInfoManager()
|
||||
: mDocument(nullptr),
|
||||
mNonDocumentNodeInfos(0),
|
||||
|
@ -107,7 +136,7 @@ nsNodeInfoManager::nsNodeInfoManager()
|
|||
|
||||
mNodeInfoHash = PL_NewHashTable(32, GetNodeInfoInnerHashValue,
|
||||
NodeInfoInnerKeyCompare,
|
||||
PL_CompareValues, nullptr, nullptr);
|
||||
PL_CompareValues, &allocOps, nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -222,11 +251,10 @@ nsNodeInfoManager::GetNodeInfo(nsIAtom *aName, nsIAtom *aPrefix,
|
|||
|
||||
nsRefPtr<nsNodeInfo> newNodeInfo =
|
||||
new nsNodeInfo(aName, aPrefix, aNamespaceID, aNodeType, aExtraName, this);
|
||||
NS_ENSURE_TRUE(newNodeInfo, nullptr);
|
||||
|
||||
PLHashEntry *he;
|
||||
he = PL_HashTableAdd(mNodeInfoHash, &newNodeInfo->mInner, newNodeInfo);
|
||||
NS_ENSURE_TRUE(he, nullptr);
|
||||
MOZ_ASSERT(he, "PL_HashTableAdd() failed");
|
||||
|
||||
// Have to do the swap thing, because already_AddRefed<nsNodeInfo>
|
||||
// doesn't cast to already_AddRefed<nsINodeInfo>
|
||||
|
|
|
@ -258,7 +258,7 @@ nsNodeUtils::LastRelease(nsINode* aNode)
|
|||
delete aNode;
|
||||
}
|
||||
|
||||
struct NS_STACK_CLASS nsHandlerData
|
||||
struct MOZ_STACK_CLASS nsHandlerData
|
||||
{
|
||||
uint16_t mOperation;
|
||||
nsCOMPtr<nsIDOMNode> mSource;
|
||||
|
@ -433,7 +433,6 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
|
|||
nodeInfo->NamespaceID(),
|
||||
nodeInfo->NodeType(),
|
||||
nodeInfo->GetExtraName());
|
||||
NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nodeInfo = newNodeInfo;
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
#include "nsWidgetsCID.h"
|
||||
#include "nsContentCID.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
||||
|
||||
|
@ -2345,10 +2346,21 @@ nsObjectLoadingContent::PluginCrashed(nsIPluginTag* aPluginTag,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsObjectLoadingContent::ScriptRequestPluginInstance(bool aCallerIsContentJS,
|
||||
nsresult
|
||||
nsObjectLoadingContent::ScriptRequestPluginInstance(JSContext* aCx,
|
||||
nsNPAPIPluginInstance **aResult)
|
||||
{
|
||||
// The below methods pull the cx off the stack, so make sure they match.
|
||||
//
|
||||
// NB: Sometimes there's a null cx on the stack, in which case |cx| is the
|
||||
// safe JS context. But in that case, IsCallerChrome() will return true,
|
||||
// so the ensuing expression is short-circuited.
|
||||
MOZ_ASSERT_IF(nsContentUtils::GetCurrentJSContext(),
|
||||
aCx == nsContentUtils::GetCurrentJSContext());
|
||||
bool callerIsContentJS = (!nsContentUtils::IsCallerChrome() &&
|
||||
!nsContentUtils::IsCallerXBL() &&
|
||||
js::IsContextRunningJS(aCx));
|
||||
|
||||
nsCOMPtr<nsIContent> thisContent =
|
||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
|
||||
|
@ -2357,7 +2369,7 @@ nsObjectLoadingContent::ScriptRequestPluginInstance(bool aCallerIsContentJS,
|
|||
// The first time content script attempts to access placeholder content, fire
|
||||
// an event. Fallback types >= eFallbackClickToPlay are plugin-replacement
|
||||
// types, see header.
|
||||
if (aCallerIsContentJS && !mScriptRequested &&
|
||||
if (callerIsContentJS && !mScriptRequested &&
|
||||
InActiveDocument(thisContent) && mType == eType_Null &&
|
||||
mFallbackType >= eFallbackClickToPlay) {
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
|
@ -2628,27 +2640,7 @@ nsObjectLoadingContent::NotifyContentObjectWrapper()
|
|||
return;
|
||||
}
|
||||
|
||||
JSAutoCompartment ac(cx, obj);
|
||||
|
||||
nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
|
||||
JSObject* canonicalPrototype = nullptr;
|
||||
if (thisContent->IsDOMBinding()) {
|
||||
canonicalPrototype =
|
||||
GetCanonicalPrototype(cx, JS_GetGlobalForObject(cx, obj));
|
||||
} else{
|
||||
nsContentUtils::XPConnect()->
|
||||
GetWrappedNativeOfNativeObject(cx, sgo->GetGlobalJSObject(), thisContent,
|
||||
NS_GET_IID(nsISupports),
|
||||
getter_AddRefs(wrapper));
|
||||
}
|
||||
|
||||
nsHTMLPluginObjElementSH::SetupProtoChain(cx, obj, wrapper, canonicalPrototype);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
nsObjectLoadingContent::GetCanonicalPrototype(JSContext* aCx, JSObject* aGlobal)
|
||||
{
|
||||
return nullptr;
|
||||
SetupProtoChain(cx, obj);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -2874,48 +2866,197 @@ nsObjectLoadingContent::LegacyCall(JSContext* aCx,
|
|||
return JS::UndefinedValue();
|
||||
}
|
||||
|
||||
JS::Value retval;
|
||||
bool otherRetval;
|
||||
nsresult rv =
|
||||
nsHTMLPluginObjElementSH::DoCall(nullptr, aCx, obj, args.Length(),
|
||||
args.Elements(), &retval, aThisVal,
|
||||
&otherRetval);
|
||||
nsRefPtr<nsNPAPIPluginInstance> pi;
|
||||
nsresult rv = ScriptRequestPluginInstance(aCx, getter_AddRefs(pi));
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return JS::UndefinedValue();
|
||||
}
|
||||
|
||||
if (!otherRetval) {
|
||||
// if there's no plugin around for this object, throw.
|
||||
if (!pi) {
|
||||
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
return JS::UndefinedValue();
|
||||
}
|
||||
|
||||
JSObject *pi_obj;
|
||||
JSObject *pi_proto;
|
||||
|
||||
rv = GetPluginJSObject(aCx, obj, pi, &pi_obj, &pi_proto);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return JS::UndefinedValue();
|
||||
}
|
||||
|
||||
if (!pi_obj) {
|
||||
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
return JS::UndefinedValue();
|
||||
}
|
||||
|
||||
JS::Value retval;
|
||||
bool ok = ::JS::Call(aCx, aThisVal, pi_obj, args.Length(),
|
||||
args.Elements(), &retval);
|
||||
if (!ok) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return JS::UndefinedValue();
|
||||
}
|
||||
|
||||
Telemetry::Accumulate(Telemetry::PLUGIN_CALLED_DIRECTLY, true);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
nsObjectLoadingContent::SetupProtoChain(JSContext* aCx, JSObject* aObject)
|
||||
{
|
||||
// We get called on random compartments here for some reason
|
||||
// (perhaps because WrapObject can happen on a random compartment?)
|
||||
// so make sure to enter the compartment of aObject.
|
||||
JSAutoCompartment ac(aCx, aObject);
|
||||
MOZ_ASSERT(nsCOMPtr<nsIContent>(do_QueryInterface(
|
||||
static_cast<nsIObjectLoadingContent*>(this)))->IsDOMBinding());
|
||||
if (nsContentUtils::IsSafeToRunScript()) {
|
||||
nsHTMLPluginObjElementSH::SetupProtoChain(aCx, aObject, nullptr,
|
||||
GetCanonicalPrototype(aCx,
|
||||
JS_GetGlobalForObject(aCx, aObject)));
|
||||
} else {
|
||||
|
||||
if (mType != eType_Plugin) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!nsContentUtils::IsSafeToRunScript()) {
|
||||
// This may be null if the JS context is not a DOM context. That's ok, we'll
|
||||
// use the safe context from XPConnect in the runnable.
|
||||
nsCOMPtr<nsIScriptContext> scriptContext = GetScriptContextFromJSContext(aCx);
|
||||
|
||||
nsRefPtr<nsHTMLPluginObjElementSH::SetupProtoChainRunner> runner =
|
||||
new nsHTMLPluginObjElementSH::SetupProtoChainRunner(nullptr,
|
||||
scriptContext,
|
||||
this);
|
||||
nsRefPtr<SetupProtoChainRunner> runner =
|
||||
new SetupProtoChainRunner(scriptContext, this);
|
||||
nsContentUtils::AddScriptRunner(runner);
|
||||
return;
|
||||
}
|
||||
|
||||
// We get called on random compartments here for some reason
|
||||
// (perhaps because WrapObject can happen on a random compartment?)
|
||||
// so make sure to enter the compartment of aObject.
|
||||
MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
|
||||
|
||||
JSAutoRequest ar(aCx);
|
||||
JSAutoCompartment ac(aCx, aObject);
|
||||
|
||||
nsRefPtr<nsNPAPIPluginInstance> pi;
|
||||
nsresult rv = ScriptRequestPluginInstance(aCx, getter_AddRefs(pi));
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pi) {
|
||||
// No plugin around for this object.
|
||||
return;
|
||||
}
|
||||
|
||||
JSObject *pi_obj; // XPConnect-wrapped peer object, when we get it.
|
||||
JSObject *pi_proto; // 'pi.__proto__'
|
||||
|
||||
rv = GetPluginJSObject(aCx, aObject, pi, &pi_obj, &pi_proto);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pi_obj) {
|
||||
// Didn't get a plugin instance JSObject, nothing we can do then.
|
||||
return;
|
||||
}
|
||||
|
||||
// If we got an xpconnect-wrapped plugin object, set obj's
|
||||
// prototype's prototype to the scriptable plugin.
|
||||
|
||||
JSObject *my_proto =
|
||||
GetDOMClass(aObject)->mGetProto(aCx, JS_GetGlobalForObject(aCx, aObject));
|
||||
MOZ_ASSERT(my_proto);
|
||||
|
||||
// Set 'this.__proto__' to pi
|
||||
if (!::JS_SetPrototype(aCx, aObject, pi_obj)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pi_proto && js::GetObjectClass(pi_proto) != &js::ObjectClass) {
|
||||
// The plugin wrapper has a proto that's not Object.prototype, set
|
||||
// 'pi.__proto__.__proto__' to the original 'this.__proto__'
|
||||
if (pi_proto != my_proto && !::JS_SetPrototype(aCx, pi_proto, my_proto)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// 'pi' didn't have a prototype, or pi's proto was
|
||||
// 'Object.prototype' (i.e. pi is an NPRuntime wrapped JS object)
|
||||
// set 'pi.__proto__' to the original 'this.__proto__'
|
||||
if (!::JS_SetPrototype(aCx, pi_obj, my_proto)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Before this proto dance the objects involved looked like this:
|
||||
//
|
||||
// this.__proto__.__proto__
|
||||
// ^ ^ ^
|
||||
// | | |__ Object.prototype
|
||||
// | |
|
||||
// | |__ WebIDL prototype (shared)
|
||||
// |
|
||||
// |__ WebIDL object
|
||||
//
|
||||
// pi.__proto__
|
||||
// ^ ^
|
||||
// | |__ Object.prototype or some other object
|
||||
// |
|
||||
// |__ Plugin NPRuntime JS object wrapper
|
||||
//
|
||||
// Now, after the above prototype setup the prototype chain should
|
||||
// look like this if pi.__proto__ was Object.prototype:
|
||||
//
|
||||
// this.__proto__.__proto__.__proto__
|
||||
// ^ ^ ^ ^
|
||||
// | | | |__ Object.prototype
|
||||
// | | |
|
||||
// | | |__ WebIDL prototype (shared)
|
||||
// | |
|
||||
// | |__ Plugin NPRuntime JS object wrapper
|
||||
// |
|
||||
// |__ WebIDL object
|
||||
//
|
||||
// or like this if pi.__proto__ was some other object:
|
||||
//
|
||||
// this.__proto__.__proto__.__proto__.__proto__
|
||||
// ^ ^ ^ ^ ^
|
||||
// | | | | |__ Object.prototype
|
||||
// | | | |
|
||||
// | | | |__ WebIDL prototype (shared)
|
||||
// | | |
|
||||
// | | |__ old pi.__proto__
|
||||
// | |
|
||||
// | |__ Plugin NPRuntime JS object wrapper
|
||||
// |
|
||||
// |__ WebIDL object
|
||||
//
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
nsObjectLoadingContent::GetPluginJSObject(JSContext *cx, JSObject *obj,
|
||||
nsNPAPIPluginInstance *plugin_inst,
|
||||
JSObject **plugin_obj,
|
||||
JSObject **plugin_proto)
|
||||
{
|
||||
*plugin_obj = nullptr;
|
||||
*plugin_proto = nullptr;
|
||||
|
||||
JSAutoRequest ar(cx);
|
||||
|
||||
// NB: We need an AutoEnterCompartment because we can be called from
|
||||
// nsObjectFrame when the plugin loads after the JS object for our content
|
||||
// node has been created.
|
||||
JSAutoCompartment ac(cx, obj);
|
||||
|
||||
if (plugin_inst) {
|
||||
plugin_inst->GetJSObject(cx, plugin_obj);
|
||||
if (*plugin_obj) {
|
||||
if (!::JS_GetPrototype(cx, *plugin_obj, plugin_proto)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2946,7 +3087,7 @@ nsObjectLoadingContent::TeardownProtoChain()
|
|||
}
|
||||
// Unwrap while checking the jsclass - if the prototype is a wrapper for
|
||||
// an NP object, that counts too.
|
||||
if (JS_GetClass(js::UnwrapObject(proto)) == &sNPObjectJSWrapperClass) {
|
||||
if (JS_GetClass(js::UncheckedUnwrap(proto)) == &sNPObjectJSWrapperClass) {
|
||||
// We found an NPObject on the proto chain, get its prototype...
|
||||
if (!::JS_GetPrototype(cx, proto, &proto)) {
|
||||
return;
|
||||
|
@ -2970,15 +3111,45 @@ nsObjectLoadingContent::DoNewResolve(JSContext* aCx, JSHandleObject aObject,
|
|||
{
|
||||
// We don't resolve anything; we just try to make sure we're instantiated
|
||||
|
||||
bool callerIsContentJS = (!nsContentUtils::IsCallerChrome() &&
|
||||
!nsContentUtils::IsCallerXBL() &&
|
||||
js::IsContextRunningJS(aCx));
|
||||
|
||||
nsRefPtr<nsNPAPIPluginInstance> pi;
|
||||
nsresult rv = ScriptRequestPluginInstance(callerIsContentJS,
|
||||
getter_AddRefs(pi));
|
||||
nsresult rv = ScriptRequestPluginInstance(aCx, getter_AddRefs(pi));
|
||||
if (NS_FAILED(rv)) {
|
||||
return mozilla::dom::Throw<true>(aCx, rv);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// SetupProtoChainRunner implementation
|
||||
nsObjectLoadingContent::SetupProtoChainRunner::SetupProtoChainRunner(
|
||||
nsIScriptContext* scriptContext,
|
||||
nsObjectLoadingContent* aContent)
|
||||
: mContext(scriptContext)
|
||||
, mContent(aContent)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsObjectLoadingContent::SetupProtoChainRunner::Run()
|
||||
{
|
||||
// XXXbz Does it really matter what JSContext we use here? Seems
|
||||
// like we could just always use the safe context....
|
||||
nsCxPusher pusher;
|
||||
JSContext* cx = mContext ? mContext->GetNativeContext()
|
||||
: nsContentUtils::GetSafeJSContext();
|
||||
pusher.Push(cx);
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
CallQueryInterface(mContent.get(), getter_AddRefs(content));
|
||||
JSObject* obj = content->GetWrapper();
|
||||
if (!obj) {
|
||||
// No need to set up our proto chain if we don't even have an object
|
||||
return NS_OK;
|
||||
}
|
||||
nsObjectLoadingContent* objectLoadingContent =
|
||||
static_cast<nsObjectLoadingContent*>(mContent.get());
|
||||
objectLoadingContent->SetupProtoChain(cx, obj);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsObjectLoadingContent::SetupProtoChainRunner, nsIRunnable)
|
||||
|
||||
|
|
|
@ -136,8 +136,6 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||
* object by placing it on the prototype chain of our element,
|
||||
* between the element itself and its most-derived DOM prototype.
|
||||
*
|
||||
* GetCanonicalPrototype returns this most-derived DOM prototype.
|
||||
*
|
||||
* SetupProtoChain handles actually inserting the plug-in
|
||||
* scriptable object into the proto chain if needed.
|
||||
*
|
||||
|
@ -145,13 +143,6 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||
* page is looking up a property name on our object and make sure
|
||||
* that our plug-in, if any, is instantiated.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the canonical prototype for this content for the given global. Only
|
||||
* returns non-null for objects that are on WebIDL bindings.
|
||||
*/
|
||||
virtual JSObject* GetCanonicalPrototype(JSContext* aCx, JSObject* aGlobal);
|
||||
|
||||
// Helper for WebIDL node wrapping
|
||||
void SetupProtoChain(JSContext* aCx, JSObject* aObject);
|
||||
|
||||
|
@ -443,6 +434,34 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||
*/
|
||||
nsObjectFrame* GetExistingFrame();
|
||||
|
||||
// Helper class for SetupProtoChain
|
||||
class SetupProtoChainRunner MOZ_FINAL : public nsIRunnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
SetupProtoChainRunner(nsIScriptContext* scriptContext,
|
||||
nsObjectLoadingContent* aContent);
|
||||
|
||||
NS_IMETHOD Run();
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIScriptContext> mContext;
|
||||
// We store an nsIObjectLoadingContent because we can
|
||||
// unambiguously refcount that.
|
||||
nsRefPtr<nsIObjectLoadingContent> mContent;
|
||||
};
|
||||
|
||||
// Utility getter for getting our nsNPAPIPluginInstance in a safe way.
|
||||
nsresult ScriptRequestPluginInstance(JSContext* aCx,
|
||||
nsNPAPIPluginInstance** aResult);
|
||||
|
||||
// Utility method for getting our plugin JSObject
|
||||
static nsresult GetPluginJSObject(JSContext *cx, JSObject *obj,
|
||||
nsNPAPIPluginInstance *plugin_inst,
|
||||
JSObject **plugin_obj,
|
||||
JSObject **plugin_proto);
|
||||
|
||||
// The final listener for mChannel (uriloader, pluginstreamlistener, etc.)
|
||||
nsCOMPtr<nsIStreamListener> mFinalListener;
|
||||
|
||||
|
|
|
@ -1392,7 +1392,7 @@ nsRange::SelectNodeContents(nsINode& aNode, ErrorResult& aRv)
|
|||
// start/end points in the future, we can switchover relatively
|
||||
// easy.
|
||||
|
||||
class NS_STACK_CLASS RangeSubtreeIterator
|
||||
class MOZ_STACK_CLASS RangeSubtreeIterator
|
||||
{
|
||||
private:
|
||||
|
||||
|
@ -1796,9 +1796,7 @@ nsRange::CutContents(dom::DocumentFragment** aFragment)
|
|||
// If aFragment isn't null, create a temporary fragment to hold our return.
|
||||
nsRefPtr<dom::DocumentFragment> retval;
|
||||
if (aFragment) {
|
||||
ErrorResult error;
|
||||
retval = NS_NewDocumentFragment(doc->NodeInfoManager(), error);
|
||||
NS_ENSURE_SUCCESS(error.ErrorCode(), error.ErrorCode());
|
||||
retval = new dom::DocumentFragment(doc->NodeInfoManager());
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> commonCloneAncestor = retval.get();
|
||||
|
||||
|
@ -2239,10 +2237,7 @@ nsRange::CloneContents(ErrorResult& aRv)
|
|||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(document));
|
||||
|
||||
nsRefPtr<dom::DocumentFragment> clonedFrag =
|
||||
NS_NewDocumentFragment(doc->NodeInfoManager(), aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
new dom::DocumentFragment(doc->NodeInfoManager());
|
||||
|
||||
nsCOMPtr<nsIDOMNode> commonCloneAncestor = clonedFrag.get();
|
||||
if (!commonCloneAncestor) {
|
||||
|
|
|
@ -256,7 +256,7 @@ protected:
|
|||
*/
|
||||
nsINode* GetRegisteredCommonAncestor();
|
||||
|
||||
struct NS_STACK_CLASS AutoInvalidateSelection
|
||||
struct MOZ_STACK_CLASS AutoInvalidateSelection
|
||||
{
|
||||
AutoInvalidateSelection(nsRange* aRange) : mRange(aRange)
|
||||
{
|
||||
|
|
|
@ -90,29 +90,6 @@ private:
|
|||
nsCOMPtr<nsIAtom> mAttrName;
|
||||
};
|
||||
|
||||
nsresult
|
||||
NS_NewTextNode(nsIContent** aInstancePtrResult,
|
||||
nsNodeInfoManager *aNodeInfoManager)
|
||||
{
|
||||
NS_PRECONDITION(aNodeInfoManager, "Missing nodeInfoManager");
|
||||
|
||||
*aInstancePtrResult = nullptr;
|
||||
|
||||
nsCOMPtr<nsINodeInfo> ni = aNodeInfoManager->GetTextNodeInfo();
|
||||
if (!ni) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsTextNode *instance = new nsTextNode(ni.forget());
|
||||
if (!instance) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(*aInstancePtrResult = instance);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsTextNode::~nsTextNode()
|
||||
{
|
||||
}
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче