merge fx-team to mozilla-central

This commit is contained in:
Rob Campbell 2011-11-15 13:57:15 -08:00
commit bf422e9c17
800 changed files with 20263 additions and 8104 deletions

10
.gitignore vendored
View File

@ -13,11 +13,11 @@ ID
.*.sw[a-z]
# User files that may appear at the root
.mozconfig
mozconfig
configure
config.cache
config.log
/.mozconfig*
/mozconfig
/configure
/config.cache
/config.log
# Empty marker file that's generated when we check out NSS
security/manager/.nss.checkout

View File

@ -65,7 +65,7 @@ tier_base_dirs = \
$(NULL)
ifndef LIBXUL_SDK
ifeq ($(OS_TARGET),Android)
ifeq (android,$(MOZ_WIDGET_TOOLKIT))
tier_base_dirs += other-licenses/android
endif

View File

@ -238,7 +238,8 @@ nsAccDocManager::OnProgressChange(nsIWebProgress *aWebProgress,
NS_IMETHODIMP
nsAccDocManager::OnLocationChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest, nsIURI *aLocation)
nsIRequest *aRequest, nsIURI *aLocation,
PRUint32 aFlags)
{
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
return NS_OK;

View File

@ -65,7 +65,7 @@ pref("extensions.minCompatibleAppVersion", "4.0");
// Preferences for AMO integration
pref("extensions.getAddons.cache.enabled", true);
pref("extensions.getAddons.maxResults", 15);
pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/guid:%IDS%?src=firefox&appOS=%OS%&appVersion=%VERSION%&tMain=%TIME_MAIN%&tFirstPaint=%TIME_FIRST_PAINT%&tSessionRestored=%TIME_SESSION_RESTORED%");
pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/guid:%IDS%?src=firefox&appOS=%OS%&appVersion=%VERSION%");
pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/firefox/search?q=%TERMS%");
pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%?src=firefox");
pref("extensions.webservice.discoverURL", "https://services.addons.mozilla.org/%LOCALE%/firefox/discovery/pane/%VERSION%/%OS%");

View File

@ -140,7 +140,7 @@ let RemoteTabViewer = {
, "folderPicker"
, "loadInSidebar"
, "keyword" ]
});
}, window.top);
},
bookmarkSelectedTabs: function() {
@ -160,7 +160,7 @@ let RemoteTabViewer = {
, type: "folder"
, URIList: URIs
, hiddenRows: [ "description" ]
});
}, window.top);
}
},

View File

@ -388,13 +388,13 @@ var PlacesCommandHook = {
, "loadInSidebar"
, "folderPicker"
, "keyword" ]
});
}, window);
}
else {
PlacesUIUtils.showBookmarkDialog({ action: "edit"
, type: "bookmark"
, itemId: itemId
});
}, window);
}
},
@ -427,7 +427,7 @@ var PlacesCommandHook = {
, type: "folder"
, URIList: pages
, hiddenRows: [ "description" ]
});
}, window);
}
},
@ -478,7 +478,7 @@ var PlacesCommandHook = {
, hiddenRows: [ "feedLocation"
, "siteLocation"
, "description" ]
});
}, window);
},
/**

View File

@ -362,8 +362,8 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
position: fixed;
top: 0;
left: 0;
min-width: 100%;
min-height: 100%;
width: 100%;
height: 100%;
}
#full-screen-warning-container[fade-warning-out] {

View File

@ -3165,7 +3165,7 @@ var bookmarksButtonObserver = {
, "loadInSidebar"
, "folderPicker"
, "keyword" ]
});
}, window);
} catch(ex) { }
},
@ -4586,7 +4586,7 @@ var XULBrowserWindow = {
}
},
onLocationChange: function (aWebProgress, aRequest, aLocationURI) {
onLocationChange: function (aWebProgress, aRequest, aLocationURI, aFlags) {
var location = aLocationURI ? aLocationURI.spec : "";
this._hostChanged = true;
@ -5052,7 +5052,8 @@ var TabsProgressListener = {
}
},
onLocationChange: function (aBrowser, aWebProgress, aRequest, aLocationURI) {
onLocationChange: function (aBrowser, aWebProgress, aRequest, aLocationURI,
aFlags) {
// Filter out any sub-frame loads
if (aBrowser.contentWindow == aWebProgress.DOMWindow)
FullZoom.onLocationChange(aLocationURI, false, aBrowser);
@ -5793,7 +5794,7 @@ function contentAreaClick(event, isPanelClick)
, "location"
, "folderPicker"
, "keyword" ]
});
}, window);
event.preventDefault();
return true;
}
@ -6840,7 +6841,7 @@ function AddKeywordForSearchField() {
, hiddenRows: [ "location"
, "loadInSidebar"
, "folderPicker" ]
});
}, window);
}
function SwitchDocumentDirection(aWindow) {

View File

@ -976,7 +976,7 @@
</hbox>
<hbox id="full-screen-warning-container" hidden="true" fadeout="true">
<hbox style="min-width: 100%;" pack="center"> <!-- Inner hbox needed due to bug 579776. -->
<hbox style="width: 100%;" pack="center"> <!-- Inner hbox needed due to bug 579776. -->
<hbox id="full-screen-warning-message">
<description id="full-screen-warning-text" value="&domFullScreenWarning.label;"></description>
</hbox>

View File

@ -1408,13 +1408,13 @@ nsContextMenu.prototype = {
, "loadInSidebar"
, "folderPicker"
, "keyword" ]
});
}, window.top);
}
else {
PlacesUIUtils.showBookmarkDialog({ action: "edit"
, type: "bookmark"
, itemId: itemId
});
}, window.top);
}
},

View File

@ -608,7 +608,8 @@
this.mStatus = aStatus;
},
onLocationChange: function (aWebProgress, aRequest, aLocation) {
onLocationChange: function (aWebProgress, aRequest, aLocation,
aFlags) {
// OnLocationChange is called for both the top-level content
// and the subframes.
let topLevel = aWebProgress.DOMWindow == this.mBrowser.contentWindow;
@ -641,7 +642,8 @@
if (!this.mBlank) {
this._callProgressListeners("onLocationChange",
[aWebProgress, aRequest, aLocation]);
[aWebProgress, aRequest, aLocation,
aFlags]);
}
if (topLevel)
@ -890,7 +892,8 @@
var securityUI = this.mCurrentBrowser.securityUI;
this._callProgressListeners(null, "onLocationChange",
[webProgress, null, loc], true, false);
[webProgress, null, loc, 0], true,
false);
if (securityUI) {
this._callProgressListeners(null, "onSecurityChange",

View File

@ -17,7 +17,7 @@ var gFrontProgressListener = {
gFrontNotificationsPos++;
},
onLocationChange: function (aWebProgress, aRequest, aLocationURI) {
onLocationChange: function (aWebProgress, aRequest, aLocationURI, aFlags) {
var state = "onLocationChange";
info("FrontProgress: " + state + " " + aLocationURI.spec);
ok(gFrontNotificationsPos < gFrontNotifications.length, "Got an expected notification for the front notifications listener");
@ -53,7 +53,8 @@ var gAllProgressListener = {
}
},
onLocationChange: function (aBrowser, aWebProgress, aRequest, aLocationURI) {
onLocationChange: function (aBrowser, aWebProgress, aRequest, aLocationURI,
aFlags) {
var state = "onLocationChange";
info("AllProgress: " + state + " " + aLocationURI.spec);
ok(aBrowser == gTestBrowser, state + " notification came from the correct browser");

View File

@ -1,5 +1,6 @@
function test() {
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
// test the main (normal) browser window
testCustomize(window, testChromeless);

View File

@ -1,5 +1,6 @@
function test() {
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
testCustomize(window, finish);
}

View File

@ -32,7 +32,13 @@ function test() {
testVal("http://mozilla.org/sub/", "mozilla.org/sub/");
testVal("http://ftp.mozilla.org/", "http://ftp.mozilla.org");
testVal("http://ftp1.mozilla.org/", "http://ftp1.mozilla.org");
testVal("http://ftp42.mozilla.org/", "http://ftp42.mozilla.org");
testVal("http://ftpx.mozilla.org/", "ftpx.mozilla.org");
testVal("ftp://ftp.mozilla.org/", "ftp://ftp.mozilla.org");
testVal("ftp://ftp1.mozilla.org/", "ftp://ftp1.mozilla.org");
testVal("ftp://ftp42.mozilla.org/", "ftp://ftp42.mozilla.org");
testVal("ftp://ftpx.mozilla.org/", "ftp://ftpx.mozilla.org");
testVal("https://user:pass@mozilla.org/", "https://user:pass@mozilla.org");
testVal("http://user:pass@mozilla.org/", "http://user:pass@mozilla.org");

View File

@ -635,8 +635,10 @@ function openPrefsHelp() {
}
function trimURL(aURL) {
// This function must not modify the given URL such that calling
// nsIURIFixup::createFixupURI with the result will produce a different URI.
return aURL /* remove single trailing slash for http/https/ftp URLs */
.replace(/^((?:http|https|ftp):\/\/[^/]+)\/$/, "$1")
/* remove http:// unless the host starts with "ftp." or contains "@" */
.replace(/^http:\/\/((?!ftp\.)[^\/@]+(?:\/|$))/, "$1");
/* remove http:// unless the host starts with "ftp\d*\." or contains "@" */
.replace(/^http:\/\/((?!ftp\d*\.)[^\/@]+(?:\/|$))/, "$1");
}

View File

@ -72,7 +72,7 @@ var panelProgressListener = {
}
,
onLocationChange : function(aWebProgress, aRequest, aLocation) {
onLocationChange : function(aWebProgress, aRequest, aLocation, aFlags) {
UpdateBackForwardCommands(getPanelBrowser().webNavigation);
},

View File

@ -44,7 +44,6 @@ include $(DEPTH)/config/autoconf.mk
MODULE = browserabout
LIBRARY_NAME = browserabout_s
FORCE_STATIC_LIB = 1
FORCE_USE_PIC = 1
ifndef MOZ_MEMORY
USE_STATIC_LIBS = 1
endif

View File

@ -50,7 +50,6 @@ DIRS = tests
endif
FORCE_STATIC_LIB = 1
FORCE_USE_PIC = 1
# Because we are an application component, link against the CRT statically
# (on Windows, but only if we're not building our own CRT for jemalloc)

View File

@ -44,7 +44,6 @@ include $(DEPTH)/config/autoconf.mk
MODULE = browser_feeds
LIBRARY_NAME = browser_feeds_s
FORCE_STATIC_LIB = 1
FORCE_USE_PIC = 1
ifndef MOZ_MEMORY
USE_STATIC_LIBS = 1
endif

View File

@ -44,7 +44,6 @@ include $(DEPTH)/config/autoconf.mk
MODULE = migration
LIBRARY_NAME = migration_s
FORCE_STATIC_LIB = 1
FORCE_USE_PIC = 1
ifndef MOZ_MEMORY
USE_STATIC_LIBS = 1
endif

View File

@ -309,10 +309,11 @@ PlacesController.prototype = {
, hiddenRows: [ "description"
, "keyword"
, "location"
, "folderPicker"
, "loadInSidebar" ]
, uri: NetUtil.newURI(node.uri)
, title: node.title
}, window.top, true);
}, window.top);
break;
}
},
@ -768,7 +769,7 @@ PlacesController.prototype = {
, type: aType
, defaultInsertionPoint: ip
, hiddenRows: [ "folderPicker" ]
}, window);
}, window.top);
if (performed) {
// Select the new item.
let insertedNodeId = PlacesUtils.bookmarks

View File

@ -64,7 +64,8 @@ var gTabsListener = {
"Tab has been opened in current browser window");
},
onLocationChange: function(aBrowser, aWebProgress, aRequest, aLocationURI) {
onLocationChange: function(aBrowser, aWebProgress, aRequest, aLocationURI,
aFlags) {
var spec = aLocationURI.spec;
ok(true, spec);
// When a new tab is opened, location is first set to "about:blank", so

View File

@ -40,6 +40,7 @@
function test() {
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
const BOOKMARKS_SIDEBAR_ID = "viewBookmarksSidebar";
const BOOKMARKS_SIDEBAR_TREE_ID = "bookmarks-view";

View File

@ -45,7 +45,6 @@ include $(DEPTH)/config/autoconf.mk
MODULE = privatebrowsing
LIBRARY_NAME = privatebrowsing_s
FORCE_STATIC_LIB = 1
FORCE_USE_PIC = 1
ifndef MOZ_MEMORY
USE_STATIC_LIBS = 1
endif

View File

@ -57,14 +57,14 @@ function PROT_MalwareWarden() {
this.prefs_.addObserver(kMalwareWardenEnabledPref, malwareWardenPrefObserver);
// Add a test chunk to the database
var testData = "mozilla.com/firefox/its-an-attack.html";
var testData = "mozilla.org/firefox/its-an-attack.html";
var testUpdate =
"n:1000\ni:test-malware-simple\nad:1\n" +
"a:1:32:" + testData.length + "\n" +
testData;
testData = "mozilla.com/firefox/its-a-trap.html";
testData = "mozilla.org/firefox/its-a-trap.html";
testUpdate +=
"n:1000\ni:test-phish-simple\nad:1\n" +
"a:1:32:" + testData.length + "\n" +

View File

@ -8,7 +8,7 @@ function test() {
// Navigate to malware site. Can't use an onload listener here since
// error pages don't fire onload
window.addEventListener("DOMContentLoaded", testMalware, true);
content.location = "http://www.mozilla.com/firefox/its-an-attack.html";
content.location = "http://www.mozilla.org/firefox/its-an-attack.html";
}
function testMalware() {
@ -23,7 +23,7 @@ function testMalware() {
// Now launch the phishing test
window.addEventListener("DOMContentLoaded", testPhishing, true);
content.location = "http://www.mozilla.com/firefox/its-a-trap.html";
content.location = "http://www.mozilla.org/firefox/its-a-trap.html";
}
function testPhishing() {

View File

@ -37,7 +37,7 @@ function testNormal_PopupListener() {
// Now launch the phishing test. Can't use onload here because error pages don't
// fire normal load events.
content.location = "http://www.mozilla.com/firefox/its-a-trap.html";
content.location = "http://www.mozilla.org/firefox/its-a-trap.html";
setTimeout(testPhishing, 2000);
}

View File

@ -2305,7 +2305,7 @@ SessionStoreService.prototype = {
if (aEntry.children) {
aEntry.children.forEach(function(entry) {
this._extractHostsForCookies(entry, aHosts, aCheckPrivacy, aIsPinned);
this._extractHostsForCookiesFromEntry(entry, aHosts, aCheckPrivacy, aIsPinned);
}, this);
}
},

View File

@ -38,16 +38,9 @@
#include "nsIShellService.idl"
[scriptable, uuid(16e7e8da-8bef-4f41-be5f-045b2e9918e1)]
[scriptable, uuid(89b0a761-d9a0-4c39-ab83-d81566459a31)]
interface nsIWindowsShellService : nsIShellService
{
/**
* The number of unread mail messages for the current user.
*
* @return The number of unread (new) mail messages for the current user.
*/
readonly attribute unsigned long unreadMailCount;
/**
* Provides the shell service an opportunity to do some Win7+ shortcut
* maintenance needed on initial startup of the browser.

View File

@ -44,7 +44,6 @@ include $(DEPTH)/config/autoconf.mk
MODULE = shellservice
FORCE_STATIC_LIB = 1
FORCE_USE_PIC = 1
ifndef MOZ_MEMORY
USE_STATIC_LIBS = 1
endif

View File

@ -235,7 +235,8 @@ nsMacShellService::OnProgressChange(nsIWebProgress* aWebProgress,
NS_IMETHODIMP
nsMacShellService::OnLocationChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
nsIURI* aLocation)
nsIURI* aLocation,
PRUint32 aFlags)
{
return NS_OK;
}

View File

@ -803,66 +803,6 @@ nsWindowsShellService::SetDesktopBackgroundColor(PRUint32 aColor)
return NS_OK;
}
NS_IMETHODIMP
nsWindowsShellService::GetUnreadMailCount(PRUint32* aCount)
{
*aCount = 0;
HKEY accountKey;
if (GetMailAccountKey(&accountKey)) {
DWORD type, unreadCount;
DWORD len = sizeof unreadCount;
DWORD res = ::RegQueryValueExW(accountKey, L"MessageCount", 0,
&type, (LPBYTE)&unreadCount, &len);
if (REG_SUCCEEDED(res))
*aCount = unreadCount;
// Close the key we opened.
::RegCloseKey(accountKey);
}
return NS_OK;
}
bool
nsWindowsShellService::GetMailAccountKey(HKEY* aResult)
{
NS_NAMED_LITERAL_STRING(unread,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\UnreadMail\\");
HKEY mailKey;
DWORD res = ::RegOpenKeyExW(HKEY_CURRENT_USER, unread.get(), 0,
KEY_ENUMERATE_SUB_KEYS, &mailKey);
PRInt32 i = 0;
do {
PRUnichar subkeyName[MAX_BUF];
DWORD len = sizeof subkeyName;
res = ::RegEnumKeyExW(mailKey, i++, subkeyName, &len, NULL, NULL,
NULL, NULL);
if (REG_SUCCEEDED(res)) {
HKEY accountKey;
res = ::RegOpenKeyExW(mailKey, PromiseFlatString(subkeyName).get(),
0, KEY_READ, &accountKey);
if (REG_SUCCEEDED(res)) {
*aResult = accountKey;
// Close the key we opened.
::RegCloseKey(mailKey);
return true;
}
}
else
break;
}
while (1);
// Close the key we opened.
::RegCloseKey(mailKey);
return false;
}
NS_IMETHODIMP
nsWindowsShellService::OpenApplicationWithURI(nsILocalFile* aApplication,
const nsACString& aURI)

View File

@ -59,8 +59,6 @@ public:
protected:
bool IsDefaultBrowserVista(bool* aIsDefaultBrowser);
bool GetMailAccountKey(HKEY* aResult);
private:
bool mCheckedThisSession;
};

View File

@ -111,11 +111,12 @@ function (aTitle, aContentURL, aCustomizeURL, aPersist)
, hiddenRows: [ "description"
, "keyword"
, "location"
, "folderPicker"
, "loadInSidebar" ]
, uri: uri
, title: aTitle
, loadBookmarkInSidebar: true
}, win, true);
}, win);
}
nsSidebar.prototype.validateSearchEngine =

View File

@ -0,0 +1,12 @@
export INCLUDE=/d/msvs10/vc/include:/d/msvs10/vc/atlmfc/include:/d/sdks/v7.0/include:/d/sdks/v7.0/include/atl:/d/msvs8/VC/PlatformSDK/include:/d/sdks/dx10/include
export LIBPATH=/d/msvs10/vc/lib:/d/msvs10/vc/atlmfc/lib:/c/WINDOWS/Microsoft.NET/Framework/v2.0.50727
export LIB=/d/msvs10/vc/lib:/d/msvs10/vc/atlmfc/lib:/d/sdks/v7.0/lib:/d/msvs8/VC/PlatformSDK/lib:/d/msvs8/SDK/v2.0/lib:/d/mozilla-build/atlthunk_compat:/d/sdks/dx10/lib/x86
export PATH="/d/msvs10/VSTSDB/Deploy:/d/msvs10/Common7/IDE/:/d/msvs10/VC/BIN:/d/msvs10/Common7/Tools:/d/msvs10/VC/VCPackages:${PATH}"
export WIN32_REDIST_DIR=/d/msvs10/VC/redist/x86/Microsoft.VC100.CRT
mk_add_options "export LIB=$LIB"
mk_add_options "export LIBPATH=$LIBPATH"
mk_add_options "export PATH=$PATH"
mk_add_options "export INCLUDE=$INCLUDE"
mk_add_options "export WIN32_REDIST_DIR=$WIN32_REDIST_DIR"

View File

@ -4,6 +4,7 @@
function test()
{
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
let nodes = [
{nodeId: "i1111", result: "i1 i11 i111 i1111"},

View File

@ -684,6 +684,7 @@ uninstall/uninst.exe
uninstall/uninstall.exe
xpicleanup@BIN_SUFFIX@
#ifdef MOZ_OMNIJAR
omni.jar
chrome/af.jar
chrome/af.manifest
chrome/ar.jar
@ -1087,6 +1088,7 @@ xpicleanup@BIN_SUFFIX@
#else
components/binary.manifest
omni.jar
omni.ja
#endif
#ifdef XP_MACOSX
../Plug-Ins/PrintPDE.plugin/Contents/Info.plist

View File

@ -56,7 +56,7 @@ endif
DIRS += pgo
ifdef ENABLE_TESTS
ifeq (Android,$(OS_TARGET))
ifeq (android,$(MOZ_WIDGET_TOOLKIT))
DIRS += mobile/sutagent/android \
mobile/sutagent/android/watcher \
mobile/sutagent/android/ffxcp \

View File

@ -52,7 +52,6 @@ import sys
import threading
import tempfile
import sqlite3
import zipfile
SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0])))
sys.path.insert(0, SCRIPT_DIR)
@ -98,69 +97,6 @@ _log.setLevel(logging.INFO)
_log.addHandler(handler)
class ZipFileReader(object):
"""
Class to read zip files in Python 2.5 and later. Limited to only what we
actually use.
"""
def __init__(self, filename):
self._zipfile = zipfile.ZipFile(filename, "r")
def __del__(self):
self._zipfile.close()
def _getnormalizedpath(self, path):
"""
Gets a normalized path from 'path' (or the current working directory if
'path' is None). Also asserts that the path exists.
"""
if path is None:
path = os.curdir
path = os.path.normpath(os.path.expanduser(path))
assert os.path.isdir(path)
return path
def _extractname(self, name, path):
"""
Extracts a file with the given name from the zip file to the given path.
Also creates any directories needed along the way.
"""
filename = os.path.normpath(os.path.join(path, name))
if name.endswith("/"):
os.makedirs(filename)
else:
path = os.path.split(filename)[0]
if not os.path.isdir(path):
os.makedirs(path)
with open(filename, "wb") as dest:
dest.write(self._zipfile.read(name))
def namelist(self):
return self._zipfile.namelist()
def read(self, name):
return self._zipfile.read(name)
def extract(self, name, path = None):
if hasattr(self._zipfile, "extract"):
return self._zipfile.extract(name, path)
# This will throw if name is not part of the zip file.
self._zipfile.getinfo(name)
self._extractname(name, self._getnormalizedpath(path))
def extractall(self, path = None):
if hasattr(self._zipfile, "extractall"):
return self._zipfile.extractall(path)
path = self._getnormalizedpath(path)
for name in self._zipfile.namelist():
self._extractname(name, path)
#################
# PROFILE SETUP #
#################
@ -418,6 +354,7 @@ user_pref("javascript.options.showInConsole", true);
user_pref("devtools.errorconsole.enabled", true);
user_pref("layout.debug.enable_data_xbl", true);
user_pref("browser.EULA.override", true);
user_pref("javascript.options.jit_hardening", true);
user_pref("gfx.color_management.force_srgb", true);
user_pref("network.manage-offline-status", false);
user_pref("test.mousescroll", true);
@ -1052,7 +989,7 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
os.makedirs(extensionsRootDir)
if os.path.isfile(extensionSource):
reader = ZipFileReader(extensionSource)
reader = automationutils.ZipFileReader(extensionSource)
for filename in reader.namelist():
# Sanity check the zip file.

View File

@ -36,11 +36,13 @@
#
# ***** END LICENSE BLOCK ***** */
import glob, logging, os, platform, shutil, subprocess, sys
from __future__ import with_statement
import glob, logging, os, platform, shutil, subprocess, sys, tempfile, urllib2, zipfile
import re
from urlparse import urlparse
__all__ = [
"ZipFileReader",
"addCommonOptions",
"checkForCrashes",
"dumpLeakLog",
@ -70,6 +72,68 @@ DEBUGGER_INFO = {
}
}
class ZipFileReader(object):
"""
Class to read zip files in Python 2.5 and later. Limited to only what we
actually use.
"""
def __init__(self, filename):
self._zipfile = zipfile.ZipFile(filename, "r")
def __del__(self):
self._zipfile.close()
def _getnormalizedpath(self, path):
"""
Gets a normalized path from 'path' (or the current working directory if
'path' is None). Also asserts that the path exists.
"""
if path is None:
path = os.curdir
path = os.path.normpath(os.path.expanduser(path))
assert os.path.isdir(path)
return path
def _extractname(self, name, path):
"""
Extracts a file with the given name from the zip file to the given path.
Also creates any directories needed along the way.
"""
filename = os.path.normpath(os.path.join(path, name))
if name.endswith("/"):
os.makedirs(filename)
else:
path = os.path.split(filename)[0]
if not os.path.isdir(path):
os.makedirs(path)
with open(filename, "wb") as dest:
dest.write(self._zipfile.read(name))
def namelist(self):
return self._zipfile.namelist()
def read(self, name):
return self._zipfile.read(name)
def extract(self, name, path = None):
if hasattr(self._zipfile, "extract"):
return self._zipfile.extract(name, path)
# This will throw if name is not part of the zip file.
self._zipfile.getinfo(name)
self._extractname(name, self._getnormalizedpath(path))
def extractall(self, path = None):
if hasattr(self._zipfile, "extractall"):
return self._zipfile.extractall(path)
path = self._getnormalizedpath(path)
for name in self._zipfile.namelist():
self._extractname(name, path)
log = logging.getLogger()
def isURL(thing):
@ -102,7 +166,6 @@ def addCommonOptions(parser, defaults={}):
def checkForCrashes(dumpDir, symbolsPath, testName=None):
stackwalkPath = os.environ.get('MINIDUMP_STACKWALK', None)
stackwalkCGI = os.environ.get('MINIDUMP_STACKWALK_CGI', None)
# try to get the caller's filename if no test name is given
if testName is None:
try:
@ -110,70 +173,70 @@ def checkForCrashes(dumpDir, symbolsPath, testName=None):
except:
testName = "unknown"
foundCrash = False
# Check preconditions
dumps = glob.glob(os.path.join(dumpDir, '*.dmp'))
for d in dumps:
log.info("PROCESS-CRASH | %s | application crashed (minidump found)", testName)
print "Crash dump filename: " + d
if symbolsPath and stackwalkPath and os.path.exists(stackwalkPath):
p = subprocess.Popen([stackwalkPath, d, symbolsPath],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(out, err) = p.communicate()
if len(out) > 3:
# minidump_stackwalk is chatty, so ignore stderr when it succeeds.
print out
else:
print "stderr from minidump_stackwalk:"
print err
if p.returncode != 0:
print "minidump_stackwalk exited with return code %d" % p.returncode
elif stackwalkCGI and symbolsPath and isURL(symbolsPath):
f = None
try:
f = open(d, "rb")
sys.path.append(os.path.join(os.path.dirname(__file__), "poster.zip"))
from poster.encode import multipart_encode
from poster.streaminghttp import register_openers
import urllib2
register_openers()
datagen, headers = multipart_encode({"minidump": f,
"symbols": symbolsPath})
request = urllib2.Request(stackwalkCGI, datagen, headers)
result = urllib2.urlopen(request).read()
if len(result) > 3:
print result
if len(dumps) == 0:
return False
foundCrash = False
removeSymbolsPath = False
# If our symbols are at a remote URL, download them now
if isURL(symbolsPath):
print "Downloading symbols from: " + symbolsPath
removeSymbolsPath = True
# Get the symbols and write them to a temporary zipfile
data = urllib2.urlopen(symbolsPath)
symbolsFile = tempfile.TemporaryFile()
symbolsFile.write(data.read())
# extract symbols to a temporary directory (which we'll delete after
# processing all crashes)
symbolsPath = tempfile.mkdtemp()
zfile = ZipFileReader(symbolsFile)
zfile.extractall(symbolsPath)
try:
for d in dumps:
log.info("PROCESS-CRASH | %s | application crashed (minidump found)", testName)
print "Crash dump filename: " + d
if symbolsPath and stackwalkPath and os.path.exists(stackwalkPath):
# run minidump stackwalk
p = subprocess.Popen([stackwalkPath, d, symbolsPath],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(out, err) = p.communicate()
if len(out) > 3:
# minidump_stackwalk is chatty, so ignore stderr when it succeeds.
print out
else:
print "stackwalkCGI returned nothing."
finally:
if f:
f.close()
else:
if not symbolsPath:
print "No symbols path given, can't process dump."
if not stackwalkPath and not stackwalkCGI:
print "Neither MINIDUMP_STACKWALK nor MINIDUMP_STACKWALK_CGI is set, can't process dump."
print "stderr from minidump_stackwalk:"
print err
if p.returncode != 0:
print "minidump_stackwalk exited with return code %d" % p.returncode
else:
if stackwalkPath and not os.path.exists(stackwalkPath):
if not symbolsPath:
print "No symbols path given, can't process dump."
if not stackwalkPath:
print "MINIDUMP_STACKWALK not set, can't process dump."
elif stackwalkPath and not os.path.exists(stackwalkPath):
print "MINIDUMP_STACKWALK binary not found: %s" % stackwalkPath
elif stackwalkCGI and not isURL(stackwalkCGI):
print "MINIDUMP_STACKWALK_CGI is not a URL: %s" % stackwalkCGI
elif symbolsPath and not isURL(symbolsPath):
print "symbolsPath is not a URL: %s" % symbolsPath
dumpSavePath = os.environ.get('MINIDUMP_SAVE_PATH', None)
if dumpSavePath:
shutil.move(d, dumpSavePath)
print "Saved dump as %s" % os.path.join(dumpSavePath,
os.path.basename(d))
else:
os.remove(d)
extra = os.path.splitext(d)[0] + ".extra"
if os.path.exists(extra):
os.remove(extra)
foundCrash = True
dumpSavePath = os.environ.get('MINIDUMP_SAVE_PATH', None)
if dumpSavePath:
shutil.move(d, dumpSavePath)
print "Saved dump as %s" % os.path.join(dumpSavePath,
os.path.basename(d))
else:
os.remove(d)
extra = os.path.splitext(d)[0] + ".extra"
if os.path.exists(extra):
os.remove(extra)
foundCrash = True
finally:
if removeSymbolsPath:
shutil.rmtree(symbolsPath)
return foundCrash
def getFullPath(directory, path):
"Get an absolute path relative to 'directory'."
return os.path.normpath(os.path.join(directory, os.path.expanduser(path)))

View File

@ -256,11 +256,11 @@ class DeviceManagerADB(DeviceManager):
# failure: None
def killProcess(self, appname):
procs = self.getProcessList()
for proc in procs:
if (proc[1] == appname):
p = self.runCmd(["shell", "ps"])
for (pid, name, user) in procs:
if name == appname:
p = self.runCmdAs(["shell", "kill", pid])
return p.stdout.read()
return None
return None
# external function
# returns:
@ -506,6 +506,12 @@ class DeviceManagerADB(DeviceManager):
args.insert(0, "adb")
return subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
def runCmdAs(self, args):
if self.useRunAs:
args.insert(1, "run-as")
args.insert(2, self.packageName)
return self.runCmd(args)
def checkCmd(self, args):
args.insert(0, "adb")
return subprocess.check_call(args)

View File

@ -135,7 +135,7 @@ http://fxfeeds.mozilla.com:80
# Prevent safebrowsing tests from hitting the network for its-a-trap.html and
# its-an-attack.html.
http://www.mozilla.com:80
http://www.mozilla.org:80
#
# These are subdomains of <ält.example.org>.

Binary file not shown.

View File

@ -46,7 +46,6 @@ MODULE = chrome
LIBRARY_NAME = chrome_s
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
FORCE_USE_PIC = 1
EXPORTS_NAMESPACES = mozilla/chrome

View File

@ -84,6 +84,7 @@ XULRUNNER_STUB_NAME = @XULRUNNER_STUB_NAME@
MOZ_CHROME_FILE_FORMAT = @MOZ_CHROME_FILE_FORMAT@
MOZ_OMNIJAR = @MOZ_OMNIJAR@
OMNIJAR_NAME = @OMNIJAR_NAME@
MOZ_WIDGET_TOOLKIT = @MOZ_WIDGET_TOOLKIT@
MOZ_GFX_OPTIMIZE_MOBILE = @MOZ_GFX_OPTIMIZE_MOBILE@
@ -139,6 +140,7 @@ MOZ_UPDATE_PACKAGING = @MOZ_UPDATE_PACKAGING@
MOZ_DISABLE_PARENTAL_CONTROLS = @MOZ_DISABLE_PARENTAL_CONTROLS@
NS_ENABLE_TSF = @NS_ENABLE_TSF@
MOZ_SPELLCHECK = @MOZ_SPELLCHECK@
MOZ_JAVA_COMPOSITOR = @MOZ_JAVA_COMPOSITOR@
MOZ_PROFILELOCKING = @MOZ_PROFILELOCKING@
MOZ_FEEDS = @MOZ_FEEDS@
MOZ_TOOLKIT_SEARCH = @MOZ_TOOLKIT_SEARCH@

View File

@ -289,6 +289,56 @@ arm-android-eabi)
;;
esac
MOZ_ARG_WITH_STRING(gonk,
[ --with-gonk=DIR
location of gonk dir],
gonkdir=$withval)
if test -n "$gonkdir" ; then
kernel_name=`uname -s | tr "[[:upper:]]" "[[:lower:]]"`
gonk_toolchain="$gonkdir"/prebuilt/$kernel_name-x86/toolchain/arm-eabi-4.4.3
dnl set up compilers
AS="$gonk_toolchain"/bin/"$android_tool_prefix"-as
CC="$gonk_toolchain"/bin/"$android_tool_prefix"-gcc
CXX="$gonk_toolchain"/bin/"$android_tool_prefix"-g++
CPP="$gonk_toolchain"/bin/"$android_tool_prefix"-cpp
LD="$gonk_toolchain"/bin/"$android_tool_prefix"-ld
AR="$gonk_toolchain"/bin/"$android_tool_prefix"-ar
RANLIB="$gonk_toolchain"/bin/"$android_tool_prefix"-ranlib
STRIP="$gonk_toolchain"/bin/"$android_tool_prefix"-strip
STLPORT_CPPFLAGS="-I$gonkdir/ndk/sources/cxx-stl/stlport/stlport/"
STLPORT_LIBS="-lstlport"
CPPFLAGS="-DANDROID -I$gonkdir/bionic/libc/include/ -I$gonkdir/bionic/libc/kernel/common -I$gonkdir/bionic/libc/arch-arm/include -I$gonkdir/bionic/libc/kernel/arch-arm -I$gonkdir/bionic/libm/include -I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/hardware/libhardware/include -I$gonkdir/system/core/include -I$gonkdir/bionic -I$gonkdir/frameworks/base/include $STLPORT_CPPFLAGS $CPPFLAGS"
CFLAGS="-mandroid -fno-short-enums -fno-exceptions $CFLAGS"
CXXFLAGS="-mandroid -fno-short-enums -fno-exceptions $CXXFLAGS"
LIBS="$LIBS $STLPORT_LIBS"
dnl Add -llog by default, since we use it all over the place.
LDFLAGS="-mandroid -L$gonkdir/out/target/product/$GONK_PRODUCT/obj/lib -Wl,-rpath-link=$gonkdir/out/target/product/$GONK_PRODUCT/obj/lib --sysroot=$gonkdir/out/target/product/$GONK_PRODUCT/obj/ -llog $LDFLAGS"
dnl prevent cross compile section from using these flags as host flags
if test -z "$HOST_CPPFLAGS" ; then
HOST_CPPFLAGS=" "
fi
if test -z "$HOST_CFLAGS" ; then
HOST_CFLAGS=" "
fi
if test -z "$HOST_CXXFLAGS" ; then
HOST_CXXFLAGS=" "
fi
if test -z "$HOST_LDFLAGS" ; then
HOST_LDFLAGS=" "
fi
AC_DEFINE(ANDROID)
CROSS_COMPILE=1
MOZ_CHROME_FILE_FORMAT=omni
ZLIB_DIR=yes
direct_nspr_config=1
else
case "$target" in
*-android*|*-linuxandroid*)
if test -z "$android_ndk" ; then
@ -419,6 +469,8 @@ case "$target" in
;;
esac
fi
AC_SUBST(ANDROID_NDK)
AC_SUBST(ANDROID_TOOLCHAIN)
AC_SUBST(ANDROID_PLATFORM)
@ -1325,8 +1377,6 @@ fi
# but that breaks when you have a 64 bit kernel with a 32 bit userland.
OS_TEST="${target_cpu}"
_COMPILER_PREFIX=
HOST_OS_ARCH=`echo $host_os | sed -e 's|/|_|g'`
#######################################################################
@ -1708,6 +1758,48 @@ fi # CPU_ARCH = arm
AC_SUBST(HAVE_ARM_SIMD)
AC_SUBST(HAVE_ARM_NEON)
dnl =================================================================
dnl Set up and test static assertion macros used to avoid AC_TRY_RUN,
dnl which is bad when cross compiling.
dnl =================================================================
if test "$COMPILE_ENVIRONMENT"; then
configure_static_assert_macros='
#define CONFIGURE_STATIC_ASSERT(condition) CONFIGURE_STATIC_ASSERT_IMPL(condition, __LINE__)
#define CONFIGURE_STATIC_ASSERT_IMPL(condition, line) CONFIGURE_STATIC_ASSERT_IMPL2(condition, line)
#define CONFIGURE_STATIC_ASSERT_IMPL2(condition, line) typedef int static_assert_line_##line[(condition) ? 1 : -1]
'
dnl test that the macros actually work:
AC_MSG_CHECKING(that static assertion macros used in autoconf tests work)
AC_CACHE_VAL(ac_cv_static_assertion_macros_work,
[AC_LANG_SAVE
AC_LANG_C
ac_cv_static_assertion_macros_work="yes"
AC_TRY_COMPILE([$configure_static_assert_macros],
[CONFIGURE_STATIC_ASSERT(1)],
,
ac_cv_static_assertion_macros_work="no")
AC_TRY_COMPILE([$configure_static_assert_macros],
[CONFIGURE_STATIC_ASSERT(0)],
ac_cv_static_assertion_macros_work="no",
)
AC_LANG_CPLUSPLUS
AC_TRY_COMPILE([$configure_static_assert_macros],
[CONFIGURE_STATIC_ASSERT(1)],
,
ac_cv_static_assertion_macros_work="no")
AC_TRY_COMPILE([$configure_static_assert_macros],
[CONFIGURE_STATIC_ASSERT(0)],
ac_cv_static_assertion_macros_work="no",
)
AC_LANG_RESTORE
])
AC_MSG_RESULT("$ac_cv_static_assertion_macros_work")
if test "$ac_cv_static_assertion_macros_work" = "no"; then
AC_MSG_ERROR([Compiler cannot compile macros used in autoconf tests.])
fi
fi # COMPILE_ENVIRONMENT
dnl ========================================================
dnl Android libstdc++, placed here so it can use MOZ_ARCH
dnl computed above.
@ -1767,8 +1859,8 @@ if test "$GNU_CC"; then
DSO_CFLAGS=''
DSO_PIC_CFLAGS='-fPIC'
ASFLAGS="$ASFLAGS -fPIC"
_MOZ_RTTI_FLAGS_ON=${_COMPILER_PREFIX}-frtti
_MOZ_RTTI_FLAGS_OFF=${_COMPILER_PREFIX}-fno-rtti
_MOZ_RTTI_FLAGS_ON=-frtti
_MOZ_RTTI_FLAGS_OFF=-fno-rtti
# Turn on GNU specific features
# -Wall - turn on all warnings
@ -1844,13 +1936,44 @@ if test "$GNU_CXX"; then
_DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -include $(DEPTH)/mozilla-config.h'
_USE_CPP_INCLUDE_FLAG=1
# Recent clang and gcc support C++11 deleted functions without warnings if
# compiling with -std=c++0x or -std=gnu++0x (or c++11 or gnu++11 in very new
# versions). We can't use -std=c++0x yet, so gcc's support must remain
# unused. But clang's warning can be disabled, so when compiling with clang
# we use it to opt out of the warning, enabling (macro-encapsulated) use of
# deleted function syntax.
if test "$CLANG_CXX"; then
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-c++0x-extensions"
fi
AC_CACHE_CHECK(whether the compiler supports -Wno-extended-offsetof,
ac_has_wno_extended_offsetof,
[
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
_SAVE_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS -Wno-extended-offsetof"
AC_TRY_COMPILE([$configure_static_assert_macros
#ifndef __has_warning
#define __has_warning(x) 0
#endif],
[CONFIGURE_STATIC_ASSERT(__has_warning("-Wextended-offsetof"))],
ac_has_wno_extended_offsetof="yes",
ac_has_wno_extended_offsetof="no")
CXXFLAGS="$_SAVE_CXXFLAGS"
AC_LANG_RESTORE
])
if test "$ac_has_wno_extended_offsetof" = "yes"; then
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-extended-offsetof"
fi
AC_CACHE_CHECK(whether the compiler supports -Wno-invalid-offsetof,
ac_has_wno_invalid_offsetof,
[
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
_SAVE_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS ${_COMPILER_PREFIX}-Wno-invalid-offsetof"
CXXFLAGS="$CXXFLAGS -Wno-invalid-offsetof"
AC_TRY_COMPILE([],
[return(0);],
ac_has_wno_invalid_offsetof="yes",
@ -1859,7 +1982,7 @@ if test "$GNU_CXX"; then
AC_LANG_RESTORE
])
if test "$ac_has_wno_invalid_offsetof" = "yes"; then
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} ${_COMPILER_PREFIX}-Wno-invalid-offsetof"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-invalid-offsetof"
fi
AC_CACHE_CHECK(whether the compiler supports -Wno-variadic-macros,
@ -1868,7 +1991,7 @@ if test "$GNU_CXX"; then
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
_SAVE_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS ${_COMPILER_PREFIX}-Wno-variadic-macros"
CXXFLAGS="$CXXFLAGS -Wno-variadic-macros"
AC_TRY_COMPILE([],
[return(0);],
ac_has_wno_variadic_macros="yes",
@ -1877,7 +2000,7 @@ if test "$GNU_CXX"; then
AC_LANG_RESTORE
])
if test "$ac_has_wno_variadic_macros" = "yes"; then
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} ${_COMPILER_PREFIX}-Wno-variadic-macros"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-variadic-macros"
fi
AC_CACHE_CHECK(whether the compiler supports -Werror=return-type,
@ -1942,48 +2065,6 @@ LOOP_INPUT
fi # GNU_CC
fi # COMPILE_ENVIRONMENT
dnl =================================================================
dnl Set up and test static assertion macros used to avoid AC_TRY_RUN,
dnl which is bad when cross compiling.
dnl =================================================================
if test "$COMPILE_ENVIRONMENT"; then
configure_static_assert_macros='
#define CONFIGURE_STATIC_ASSERT(condition) CONFIGURE_STATIC_ASSERT_IMPL(condition, __LINE__)
#define CONFIGURE_STATIC_ASSERT_IMPL(condition, line) CONFIGURE_STATIC_ASSERT_IMPL2(condition, line)
#define CONFIGURE_STATIC_ASSERT_IMPL2(condition, line) typedef int static_assert_line_##line[(condition) ? 1 : -1]
'
dnl test that the macros actually work:
AC_MSG_CHECKING(that static assertion macros used in autoconf tests work)
AC_CACHE_VAL(ac_cv_static_assertion_macros_work,
[AC_LANG_SAVE
AC_LANG_C
ac_cv_static_assertion_macros_work="yes"
AC_TRY_COMPILE([$configure_static_assert_macros],
[CONFIGURE_STATIC_ASSERT(1)],
,
ac_cv_static_assertion_macros_work="no")
AC_TRY_COMPILE([$configure_static_assert_macros],
[CONFIGURE_STATIC_ASSERT(0)],
ac_cv_static_assertion_macros_work="no",
)
AC_LANG_CPLUSPLUS
AC_TRY_COMPILE([$configure_static_assert_macros],
[CONFIGURE_STATIC_ASSERT(1)],
,
ac_cv_static_assertion_macros_work="no")
AC_TRY_COMPILE([$configure_static_assert_macros],
[CONFIGURE_STATIC_ASSERT(0)],
ac_cv_static_assertion_macros_work="no",
)
AC_LANG_RESTORE
])
AC_MSG_RESULT("$ac_cv_static_assertion_macros_work")
if test "$ac_cv_static_assertion_macros_work" = "no"; then
AC_MSG_ERROR([Compiler cannot compile macros used in autoconf tests.])
fi
fi # COMPILE_ENVIRONMENT
dnl ========================================================
dnl Checking for 64-bit OS
dnl ========================================================
@ -2376,7 +2457,11 @@ ia64*-hpux*)
*-android*|*-linuxandroid*)
AC_DEFINE(NO_PW_GECOS)
no_x=yes
_PLATFORM_DEFAULT_TOOLKIT=cairo-android
if test -n "$gonkdir"; then
_PLATFORM_DEFAULT_TOOLKIT=cairo-gonk
else
_PLATFORM_DEFAULT_TOOLKIT=cairo-android
fi
TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"'
MOZ_GFX_OPTIMIZE_MOBILE=1
@ -4577,6 +4662,7 @@ MOZ_REFLOW_PERF=
MOZ_SAFE_BROWSING=
MOZ_HELP_VIEWER=
MOZ_SPELLCHECK=1
MOZ_JAVA_COMPOSITOR=
MOZ_SVG_DLISTS=
MOZ_TOOLKIT_SEARCH=1
MOZ_UI_LOCALE=en-US
@ -4762,7 +4848,8 @@ MOZ_ARG_HEADER(Toolkit Options)
-o "$_DEFAULT_TOOLKIT" = "cairo-os2" \
-o "$_DEFAULT_TOOLKIT" = "cairo-cocoa" \
-o "$_DEFAULT_TOOLKIT" = "cairo-uikit" \
-o "$_DEFAULT_TOOLKIT" = "cairo-android"
-o "$_DEFAULT_TOOLKIT" = "cairo-android" \
-o "$_DEFAULT_TOOLKIT" = "cairo-gonk"
then
dnl nglayout only supports building with one toolkit,
dnl so ignore everything after the first comma (",").
@ -4885,6 +4972,15 @@ cairo-android)
MOZ_INSTRUMENT_EVENT_LOOP=1
;;
cairo-gonk)
AC_DEFINE(MOZ_WIDGET_GONK)
MOZ_WIDGET_TOOLKIT=gonk
TK_CFLAGS='$(MOZ_CAIRO_CFLAGS)'
TK_LIBS='$(MOZ_CAIRO_LIBS)'
MOZ_WEBGL=1
MOZ_PDF_PRINTING=1
;;
esac
AC_SUBST(MOZ_PDF_PRINTING)
@ -7165,7 +7261,9 @@ dnl We need to wrap dlopen and related functions on Android because we use
dnl our own linker.
if test "$OS_TARGET" = Android; then
WRAP_LDFLAGS="${WRAP_LDFLAGS} -L$_objdir/dist/lib -lmozutils"
WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=dlopen,--wrap=dlclose,--wrap=dlerror,--wrap=dlsym,--wrap=dladdr"
if test "$MOZ_WIDGET_TOOLKIT" = android; then
WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=dlopen,--wrap=dlclose,--wrap=dlerror,--wrap=dlsym,--wrap=dladdr"
fi
fi
dnl ========================================================
@ -7217,6 +7315,17 @@ if test -n "$MOZ_TRACEVIS"; then
AC_DEFINE(MOZ_TRACEVIS)
fi
dnl ========================================================
dnl = Use incremental GC
dnl ========================================================
JSGC_INCREMENTAL=1
MOZ_ARG_DISABLE_BOOL(gcincremental,
[ --disable-gcincremental Disable incremental GC],
JSGC_INCREMENTAL= )
if test -n "$JSGC_INCREMENTAL"; then
AC_DEFINE(JSGC_INCREMENTAL)
fi
dnl ========================================================
dnl ETW - Event Tracing for Windows
dnl ========================================================
@ -7557,6 +7666,8 @@ elif test "$MOZ_CHROME_FILE_FORMAT" = "jar"; then
AC_DEFINE(MOZ_CHROME_FILE_FORMAT_JAR)
fi
OMNIJAR_NAME=omni.ja
AC_SUBST(OMNIJAR_NAME)
AC_SUBST(MOZ_OMNIJAR)
dnl ========================================================
@ -7705,7 +7816,7 @@ MOZ_ARG_DISABLE_BOOL(pedantic,
_PEDANTIC= )
if test "$_PEDANTIC"; then
_SAVE_CXXFLAGS=$CXXFLAGS
CXXFLAGS="$CXXFLAGS ${_WARNINGS_CXXFLAGS} ${_COMPILER_PREFIX}-pedantic ${_COMPILER_PREFIX}-Wno-long-long"
CXXFLAGS="$CXXFLAGS -pedantic ${_WARNINGS_CXXFLAGS} -Wno-long-long"
AC_MSG_CHECKING([whether C++ compiler has -pedantic long long bug])
AC_TRY_COMPILE([$configure_static_assert_macros],
[CONFIGURE_STATIC_ASSERT(sizeof(long long) == 8)],
@ -7715,8 +7826,8 @@ if test "$_PEDANTIC"; then
case "$result" in
no)
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} ${_COMPILER_PREFIX}-pedantic ${_COMPILER_PREFIX}-Wno-long-long"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} ${_COMPILER_PREFIX}-pedantic ${_COMPILER_PREFIX}-Wno-long-long"
_WARNINGS_CFLAGS="-pedantic ${_WARNINGS_CFLAGS} -Wno-long-long"
_WARNINGS_CXXFLAGS="-pedantic ${_WARNINGS_CXXFLAGS} -Wno-long-long"
;;
yes)
AC_MSG_ERROR([Your compiler appears to have a known bug where long long is miscompiled when using -pedantic. Reconfigure using --disable-pedantic. ])
@ -8026,8 +8137,6 @@ if test "$MOZ_TREE_CAIRO"; then
SANITY_CHECKING_FEATURE="#undef CAIRO_DO_SANITY_CHECKING"
fi
PNG_FUNCTIONS_FEATURE="#define CAIRO_HAS_PNG_FUNCTIONS 1"
AC_SUBST(PS_SURFACE_FEATURE)
AC_SUBST(PDF_SURFACE_FEATURE)
AC_SUBST(SVG_SURFACE_FEATURE)
@ -8323,6 +8432,7 @@ AC_SUBST(IBMBIDI)
AC_SUBST(MOZ_UNIVERSALCHARDET)
AC_SUBST(ACCESSIBILITY)
AC_SUBST(MOZ_SPELLCHECK)
AC_SUBST(MOZ_JAVA_COMPOSITOR)
AC_SUBST(MOZ_USER_DIR)
AC_SUBST(MOZ_CRASHREPORTER)
AC_SUBST(MOZ_UPDATER)
@ -8835,20 +8945,22 @@ if test "$MOZ_TREE_FREETYPE"; then
AC_OUTPUT_SUBDIRS(modules/freetype2)
fi
dnl ========================================================
dnl = Setup a nice relatively clean build environment for
dnl = sub-configures.
dnl ========================================================
CC="$_SUBDIR_CC"
CXX="$_SUBDIR_CXX"
CFLAGS="$_SUBDIR_CFLAGS"
CPPFLAGS="$_SUBDIR_CPPFLAGS"
CXXFLAGS="$_SUBDIR_CXXFLAGS"
LDFLAGS="$_SUBDIR_LDFLAGS"
HOST_CC="$_SUBDIR_HOST_CC"
HOST_CFLAGS="$_SUBDIR_HOST_CFLAGS"
HOST_LDFLAGS="$_SUBDIR_HOST_LDFLAGS"
RC=
if test -z "$direct_nspr_config"; then
dnl ========================================================
dnl = Setup a nice relatively clean build environment for
dnl = sub-configures.
dnl ========================================================
CC="$_SUBDIR_CC"
CXX="$_SUBDIR_CXX"
CFLAGS="$_SUBDIR_CFLAGS"
CPPFLAGS="$_SUBDIR_CPPFLAGS"
CXXFLAGS="$_SUBDIR_CXXFLAGS"
LDFLAGS="$_SUBDIR_LDFLAGS"
HOST_CC="$_SUBDIR_HOST_CC"
HOST_CFLAGS="$_SUBDIR_HOST_CFLAGS"
HOST_LDFLAGS="$_SUBDIR_HOST_LDFLAGS"
RC=
fi
unset MAKEFILES
unset CONFIG_FILES
@ -8897,6 +9009,23 @@ if test -z "$MOZ_NATIVE_NSPR"; then
rm -f config/autoconf.mk.bak
fi
if test -n "$direct_nspr_config"; then
dnl ========================================================
dnl = Setup a nice relatively clean build environment for
dnl = sub-configures.
dnl ========================================================
CC="$_SUBDIR_CC"
CXX="$_SUBDIR_CXX"
CFLAGS="$_SUBDIR_CFLAGS"
CPPFLAGS="$_SUBDIR_CPPFLAGS"
CXXFLAGS="$_SUBDIR_CXXFLAGS"
LDFLAGS="$_SUBDIR_LDFLAGS"
HOST_CC="$_SUBDIR_HOST_CC"
HOST_CFLAGS="$_SUBDIR_HOST_CFLAGS"
HOST_LDFLAGS="$_SUBDIR_HOST_LDFLAGS"
RC=
fi
# Run the SpiderMonkey 'configure' script.
dist=$MOZ_BUILD_ROOT/dist
ac_configure_args="$_SUBDIR_CONFIG_ARGS"

View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<script>
function boom()
{
var mo = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mo");
var t1 = document.createTextNode("123456 ");
mo.appendChild(t1);
document.body.appendChild(mo);
var t2 = document.createTextNode("x");
document.body.appendChild(t2);
var r1 = document.createRange();
r1.setEnd(t1, 7);
var r3 = document.createRange();
r3.setStart(t1, 7);
document.documentElement.offsetHeight;
var r2 = document.createRange();
r2.setStart(t1, 0);
r2.setEnd(t2, 0);
r2.deleteContents();
}
</script>
</head>
<body onload="boom();"></body>
</html>

View File

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<script>
function boom()
{
var mo = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mo");
var t1 = document.createTextNode("123456 ");
mo.appendChild(t1);
document.body.appendChild(mo);
var t2 = document.createTextNode("x");
document.body.appendChild(t2);
var r1 = document.createRange();
r1.setEnd(t1, 7);
var r3 = document.createRange();
r3.setStart(t1, 7);
document.documentElement.offsetHeight;
t1.splitText(t1.length);
}
</script>
</head>
<body onload="boom();"></body>
</html>

View File

@ -98,3 +98,5 @@ load 679689-1.html
load 682463.html
load 693212.xhtml
load 698974-1.html
load 700090-1.html
load 700090-2.html

View File

@ -110,17 +110,6 @@ public:
return mState;
}
/**
* Request an update of the link state for this element. This will
* make sure that if the element is a link at all then either
* NS_EVENT_STATE_VISITED or NS_EVENT_STATE_UNVISITED is set in
* mState, and a history lookup kicked off if needed to find out
* whether the link is really visited. This method will NOT send any
* state change notifications. If you want them to happen for this
* call, you need to handle them yourself.
*/
virtual void RequestLinkStateUpdate();
/**
* Ask this element to update its state. If aNotify is false, then
* state change notifications will not be dispatched; in that
@ -132,6 +121,11 @@ public:
* removing it from the document).
*/
void UpdateState(bool aNotify);
/**
* Method to update mState with link state information. This does not notify.
*/
void UpdateLinkState(nsEventStates aState);
protected:
/**
@ -142,11 +136,6 @@ protected:
*/
virtual nsEventStates IntrinsicState() const;
/**
* Method to update mState with link state information. This does not notify.
*/
void UpdateLinkState(nsEventStates aState);
/**
* Method to add state bits. This should be called from subclass
* constructors to set up our event state correctly at construction

View File

@ -1735,6 +1735,12 @@ public:
*/
static bool HasPluginWithUncontrolledEventDispatch(nsIContent* aContent);
/**
* Returns the root document in a document hierarchy. Normally this will
* be the chrome document.
*/
static nsIDocument* GetRootDocument(nsIDocument* aDoc);
/**
* Returns the time limit on handling user input before
* nsEventStateManager::IsHandlingUserInput() stops returning true.

View File

@ -166,6 +166,7 @@ public:
// &&-ed in, this is safe.
mAllowDNSPrefetch(true),
mIsBeingUsedAsImage(false),
mHasLinksToUpdate(false),
mPartID(0)
{
SetInDocument();
@ -1489,7 +1490,7 @@ public:
/**
* This method is similar to GetElementById() from nsIDOMDocument but it
* returns a mozilla::dom::Element instead of a nsIDOMElement.
* It prevents converting nsIDOMElement to mozill:dom::Element which is
* It prevents converting nsIDOMElement to mozilla::dom::Element which is
* already converted from mozilla::dom::Element.
*/
virtual Element* GetElementById(const nsAString& aElementId) = 0;
@ -1554,6 +1555,17 @@ public:
virtual nsresult SetNavigationTiming(nsDOMNavigationTiming* aTiming) = 0;
virtual Element* FindImageMap(const nsAString& aNormalizedMapName) = 0;
// Add aLink to the set of links that need their status resolved.
void RegisterPendingLinkUpdate(mozilla::dom::Link* aLink);
// Remove aLink from the set of links that need their status resolved.
// This function must be called when links are removed from the document.
void UnregisterPendingLinkUpdate(mozilla::dom::Link* aElement);
// Update state on links in mLinksToUpdate. This function must
// be called prior to selector matching.
void FlushPendingLinkUpdates();
#define DEPRECATED_OPERATION(_op) e##_op,
enum DeprecatedOperations {
@ -1644,6 +1656,11 @@ protected:
// These are non-owning pointers, the elements are responsible for removing
// themselves when they go away.
nsAutoPtr<nsTHashtable<nsPtrHashKey<nsIContent> > > mFreezableElements;
// The set of all links that need their status resolved. Links must add themselves
// to this set by calling RegisterPendingLinkUpdate when added to a document and must
// remove themselves by calling UnregisterPendingLinkUpdate when removed from a document.
nsTHashtable<nsPtrHashKey<mozilla::dom::Link> > mLinksToUpdate;
// SMIL Animation Controller, lazily-initialized in GetAnimationController
nsRefPtr<nsSMILAnimationController> mAnimationController;
@ -1724,6 +1741,9 @@ protected:
// file, etc.
bool mIsSyntheticDocument;
// True if this document has links whose state needs updating
bool mHasLinksToUpdate;
// The document's script global object, the object from which the
// document can get its script context and scope. This is the
// *inner* window object.

View File

@ -51,7 +51,7 @@ class nsIDocument;
[ptr] native nsINodePtr(nsINode);
[ptr] native nsIDocumentPtr(nsIDocument);
[scriptable, uuid(c0da5b87-0ba7-4d7c-8cb3-fcb02af4253d)]
[scriptable, uuid(82adaeca-63ee-44eb-830a-e1678bb8745e)]
interface nsIDocumentEncoderNodeFixup : nsISupports
{
/**
@ -272,6 +272,7 @@ interface nsIDocumentEncoder : nsISupports
* @param aNode The node to encode.
*/
void setNode(in nsIDOMNode aNode);
[noscript] void setNativeNode(in nsINodePtr aNode);
/**
* If the container is set to a non-null value, then its

View File

@ -42,6 +42,7 @@ interface nsIChannel;
interface nsIStreamListener;
interface nsIURI;
interface nsIDocument;
interface nsIFrame;
/**
* This interface represents a content node that loads images. The interface
@ -65,7 +66,7 @@ interface nsIDocument;
* sufficient, when combined with the imageBlockingStatus information.)
*/
[scriptable, uuid(95c74255-df9a-4060-b5a0-0d111fcafe08)]
[scriptable, uuid(f7debb84-2854-4731-a57b-1bd752ad71f8)]
interface nsIImageLoadingContent : imgIDecoderObserver
{
/**
@ -128,6 +129,18 @@ interface nsIImageLoadingContent : imgIDecoderObserver
*/
imgIRequest getRequest(in long aRequestType);
/**
* Used to notify the image loading content node that a frame has been
* created.
*/
[notxpcom] void frameCreated(in nsIFrame aFrame);
/**
* Used to notify the image loading content node that a frame has been
* destroyed.
*/
[notxpcom] void frameDestroyed(in nsIFrame aFrame);
/**
* Used to find out what type of request one is dealing with (eg
* which request got passed through to the imgIDecoderObserver

View File

@ -109,6 +109,9 @@ public:
* changes or false if it should not.
*/
void ResetLinkState(bool aNotify);
// This method nevers returns a null element.
Element* GetElement() const { return mElement; }
protected:
virtual ~Link();

View File

@ -5893,6 +5893,20 @@ nsContentUtils::HasPluginWithUncontrolledEventDispatch(nsIContent* aContent)
return result;
}
/* static */
nsIDocument*
nsContentUtils::GetRootDocument(nsIDocument* aDoc)
{
if (!aDoc) {
return nsnull;
}
nsIDocument* doc = aDoc;
while (doc->GetParentDocument()) {
doc = doc->GetParentDocument();
}
return doc;
}
// static
void
nsContentUtils::ReleaseWrapper(nsISupports* aScriptObjectHolder,

View File

@ -51,6 +51,17 @@
NS_IMPL_ISUPPORTS1(nsDataDocumentContentPolicy, nsIContentPolicy)
// Helper method for ShouldLoad()
// Checks a URI for the given flags. Returns true if the URI has the flags,
// and false if not (or if we weren't able to tell).
static bool
HasFlags(nsIURI* aURI, PRUint32 aURIFlags)
{
bool hasFlags;
nsresult rv = NS_URIChainHasFlags(aURI, aURIFlags, &hasFlags);
return NS_SUCCEEDED(rv) && hasFlags;
}
NS_IMETHODIMP
nsDataDocumentContentPolicy::ShouldLoad(PRUint32 aContentType,
nsIURI *aContentLocation,
@ -87,21 +98,26 @@ nsDataDocumentContentPolicy::ShouldLoad(PRUint32 aContentType,
}
if (doc->IsBeingUsedAsImage()) {
// Allow local resources for SVG-as-an-image documents, but disallow
// everything else, to prevent data leakage
bool hasFlags;
nsresult rv = NS_URIChainHasFlags(aContentLocation,
nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
&hasFlags);
if (NS_FAILED(rv) || !hasFlags) {
// resource is not local (or we couldn't tell) - reject!
// We only allow SVG images to load content from URIs that are local and
// also satisfy one of the following conditions:
// - URI inherits security context, e.g. data URIs
// OR
// - URI loadable by subsumers, e.g. moz-filedata URIs
// Any URI that doesn't meet these requirements will be rejected below.
if (!HasFlags(aContentLocation,
nsIProtocolHandler::URI_IS_LOCAL_RESOURCE) ||
(!HasFlags(aContentLocation,
nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT) &&
!HasFlags(aContentLocation,
nsIProtocolHandler::URI_LOADABLE_BY_SUBSUMERS))) {
*aDecision = nsIContentPolicy::REJECT_TYPE;
// report error, if we can.
// Report error, if we can.
if (node) {
nsIPrincipal* requestingPrincipal = node->NodePrincipal();
nsRefPtr<nsIURI> principalURI;
rv = requestingPrincipal->GetURI(getter_AddRefs(principalURI));
nsresult rv =
requestingPrincipal->GetURI(getter_AddRefs(principalURI));
if (NS_SUCCEEDED(rv) && principalURI) {
nsScriptSecurityManager::ReportError(
nsnull, NS_LITERAL_STRING("CheckSameOriginError"), principalURI,
@ -112,8 +128,8 @@ nsDataDocumentContentPolicy::ShouldLoad(PRUint32 aContentType,
doc->GetDocumentURI()) {
// Check for (& disallow) recursive image-loads
bool isRecursiveLoad;
rv = aContentLocation->EqualsExceptRef(doc->GetDocumentURI(),
&isRecursiveLoad);
nsresult rv = aContentLocation->EqualsExceptRef(doc->GetDocumentURI(),
&isRecursiveLoad);
if (NS_FAILED(rv) || isRecursiveLoad) {
NS_WARNING("Refusing to recursively load image");
*aDecision = nsIContentPolicy::REJECT_TYPE;
@ -122,12 +138,12 @@ nsDataDocumentContentPolicy::ShouldLoad(PRUint32 aContentType,
return NS_OK;
}
// Allow all loads for non-external-resource documents
if (!doc->GetDisplayDocument()) {
// Allow all loads for non-resource documents
if (!doc->IsResourceDoc()) {
return NS_OK;
}
// For external resources, blacklist some load types
// For resource documents, blacklist some load types
if (aContentType == nsIContentPolicy::TYPE_OBJECT ||
aContentType == nsIContentPolicy::TYPE_DOCUMENT ||
aContentType == nsIContentPolicy::TYPE_SUBDOCUMENT ||

View File

@ -1554,6 +1554,8 @@ nsDocument::nsDocument(const char* aContentType)
// Start out mLastStyleSheetSet as null, per spec
SetDOMStringToNull(mLastStyleSheetSet);
mLinksToUpdate.Init();
}
static PLDHashOperator
@ -1952,6 +1954,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
if (tmp->mAnimationController) {
tmp->mAnimationController->Unlink();
}
tmp->mPendingTitleChangeEvent.Revoke();
tmp->mInUnlinkOrDeletion = false;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@ -3222,6 +3226,7 @@ nsDocument::DeleteShell()
if (IsEventHandlingEnabled()) {
RevokeAnimationFrameNotifications();
}
mPresShell = nsnull;
}
@ -7970,6 +7975,41 @@ nsIDocument::EnumerateFreezableElements(FreezableElementEnumerator aEnumerator,
mFreezableElements->EnumerateEntries(EnumerateFreezables, &data);
}
void
nsIDocument::RegisterPendingLinkUpdate(Link* aLink)
{
mLinksToUpdate.PutEntry(aLink);
mHasLinksToUpdate = true;
}
void
nsIDocument::UnregisterPendingLinkUpdate(Link* aLink)
{
if (!mHasLinksToUpdate)
return;
mLinksToUpdate.RemoveEntry(aLink);
}
static PLDHashOperator
EnumeratePendingLinkUpdates(nsPtrHashKey<Link>* aEntry, void* aData)
{
aEntry->GetKey()->GetElement()->UpdateLinkState(aEntry->GetKey()->LinkState());
return PL_DHASH_NEXT;
}
void
nsIDocument::FlushPendingLinkUpdates()
{
if (!mHasLinksToUpdate)
return;
nsAutoScriptBlocker scriptBlocker;
mLinksToUpdate.EnumerateEntries(EnumeratePendingLinkUpdates, nsnull);
mLinksToUpdate.Clear();
mHasLinksToUpdate = false;
}
already_AddRefed<nsIDocument>
nsIDocument::CreateStaticClone(nsISupports* aCloneContainer)
{
@ -8534,19 +8574,6 @@ GetCommonAncestor(nsIDocument* aDoc1, nsIDocument* aDoc2)
return parent;
}
// Returns the root document in a document hierarchy.
static nsIDocument*
GetRootDocument(nsIDocument* aDoc)
{
if (!aDoc)
return nsnull;
nsIDocument* doc = aDoc;
while (doc->GetParentDocument()) {
doc = doc->GetParentDocument();
}
return doc;
}
class nsCallRequestFullScreen : public nsRunnable
{
public:
@ -8621,8 +8648,8 @@ nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
}
// Remember the root document, so that if a full-screen document is hidden
// we can reset full-screen state the remaining visible full-screen documents.
sFullScreenRootDoc = do_GetWeakReference(GetRootDocument(this));
// we can reset full-screen state in the remaining visible full-screen documents.
sFullScreenRootDoc = do_GetWeakReference(nsContentUtils::GetRootDocument(this));
// Set the full-screen element. This sets the full-screen style on the
// element, and the full-screen-ancestor styles on ancestors of the element

View File

@ -301,6 +301,14 @@ nsDocumentEncoder::SetNode(nsIDOMNode* aNode)
return NS_OK;
}
NS_IMETHODIMP
nsDocumentEncoder::SetNativeNode(nsINode* aNode)
{
mNodeIsContainer = false;
mNode = aNode;
return NS_OK;
}
NS_IMETHODIMP
nsDocumentEncoder::SetContainerNode(nsIDOMNode *aContainer)
{

View File

@ -1381,8 +1381,8 @@ nsFrameLoader::MaybeCreateDocShell()
return NS_ERROR_UNEXPECTED;
}
if (doc->GetDisplayDocument() || !doc->IsActive()) {
// Don't allow subframe loads in external reference documents, nor
if (doc->IsResourceDoc() || !doc->IsActive()) {
// Don't allow subframe loads in resource documents, nor
// in non-active documents.
return NS_ERROR_NOT_AVAILABLE;
}

View File

@ -52,6 +52,10 @@
#include "nsIConsoleService.h"
#include "nsIProtocolHandler.h"
#ifdef ANDROID
#include <android/log.h>
#endif
static bool
IsChromeProcess()
{
@ -279,6 +283,9 @@ nsFrameMessageManager::SendAsyncMessage(const nsAString& aMessageName,
NS_IMETHODIMP
nsFrameMessageManager::Dump(const nsAString& aStr)
{
#ifdef ANDROID
__android_log_print(ANDROID_LOG_INFO, "Gecko", NS_ConvertUTF16toUTF8(aStr).get());
#endif
fputs(NS_ConvertUTF16toUTF8(aStr).get(), stdout);
fflush(stdout);
return NS_OK;

View File

@ -1248,11 +1248,6 @@ Element::NotifyStateChange(nsEventStates aStates)
}
}
void
Element::RequestLinkStateUpdate()
{
}
void
Element::UpdateLinkState(nsEventStates aState)
{
@ -5385,6 +5380,7 @@ inline static nsresult FindMatchingElements(nsINode* aRoot,
nsIDocument* doc = aRoot->OwnerDoc();
TreeMatchContext matchingContext(false, nsRuleWalker::eRelevantLinkUnvisited,
doc);
doc->FlushPendingLinkUpdates();
// Fast-path selectors involving IDs. We can only do this if aRoot
// is in the document and the document is not in quirks mode, since
@ -5493,6 +5489,7 @@ nsGenericElement::MozMatchesSelector(const nsAString& aSelector, nsresult* aResu
*aResult = ParseSelectorList(this, aSelector, getter_Transfers(selectorList));
if (NS_SUCCEEDED(*aResult)) {
OwnerDoc()->FlushPendingLinkUpdates();
TreeMatchContext matchingContext(false,
nsRuleWalker::eRelevantLinkUnvisited,
OwnerDoc());

View File

@ -72,6 +72,7 @@
#include "nsIDOMNode.h"
#include "nsContentUtils.h"
#include "nsLayoutUtils.h"
#include "nsIContentPolicy.h"
#include "nsContentPolicyUtils.h"
#include "nsEventDispatcher.h"
@ -115,7 +116,9 @@ nsImageLoadingContent::nsImageLoadingContent()
mNewRequestsWillNeedAnimationReset(false),
mPendingRequestNeedsResetAnimation(false),
mCurrentRequestNeedsResetAnimation(false),
mStateChangerDepth(0)
mStateChangerDepth(0),
mCurrentRequestRegistered(false),
mPendingRequestRegistered(false)
{
if (!nsContentUtils::GetImgLoader()) {
mLoadingEnabled = false;
@ -328,7 +331,6 @@ nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
nsIDocument* doc = GetOurDocument();
nsIPresShell* shell = doc ? doc->GetShell() : nsnull;
if (shell) {
// We need to figure out whether to kick off decoding
bool doRequestDecode = false;
@ -372,6 +374,18 @@ nsImageLoadingContent::OnStopRequest(imgIRequest* aRequest, bool aLastPart)
return NS_OK;
}
NS_IMETHODIMP
nsImageLoadingContent::OnImageIsAnimated(imgIRequest *aRequest)
{
bool* requestFlag = GetRegisteredFlagForRequest(aRequest);
if (requestFlag) {
nsLayoutUtils::RegisterImageRequest(GetFramePresContext(),
aRequest, requestFlag);
}
return NS_OK;
}
NS_IMETHODIMP
nsImageLoadingContent::OnDiscard(imgIRequest *aRequest)
{
@ -501,6 +515,44 @@ nsImageLoadingContent::GetRequest(PRInt32 aRequestType,
return NS_OK;
}
NS_IMETHODIMP_(void)
nsImageLoadingContent::FrameCreated(nsIFrame* aFrame)
{
NS_ASSERTION(aFrame, "aFrame is null");
// We need to make sure that our image request is registered, if it should
// be registered.
nsPresContext* presContext = aFrame->PresContext();
if (mCurrentRequest) {
nsLayoutUtils::RegisterImageRequestIfAnimated(presContext, mCurrentRequest,
&mCurrentRequestRegistered);
}
if (mPendingRequest) {
nsLayoutUtils::RegisterImageRequestIfAnimated(presContext, mPendingRequest,
&mPendingRequestRegistered);
}
}
NS_IMETHODIMP_(void)
nsImageLoadingContent::FrameDestroyed(nsIFrame* aFrame)
{
NS_ASSERTION(aFrame, "aFrame is null");
// We need to make sure that our image request is deregistered.
if (mCurrentRequest) {
nsLayoutUtils::DeregisterImageRequest(GetFramePresContext(),
mCurrentRequest,
&mCurrentRequestRegistered);
}
if (mPendingRequest) {
nsLayoutUtils::DeregisterImageRequest(GetFramePresContext(),
mPendingRequest,
&mPendingRequestRegistered);
}
}
NS_IMETHODIMP
nsImageLoadingContent::GetRequestType(imgIRequest* aRequest,
@ -867,6 +919,23 @@ nsImageLoadingContent::GetOurDocument()
return thisContent->OwnerDoc();
}
nsIFrame*
nsImageLoadingContent::GetOurPrimaryFrame()
{
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
return thisContent->GetPrimaryFrame();
}
nsPresContext* nsImageLoadingContent::GetFramePresContext()
{
nsIFrame* frame = GetOurPrimaryFrame();
if (!frame) {
return nsnull;
}
return frame->PresContext();
}
nsresult
nsImageLoadingContent::StringToURI(const nsAString& aSpec,
nsIDocument* aDocument,
@ -986,6 +1055,11 @@ nsImageLoadingContent::ClearCurrentRequest(nsresult aReason)
NS_ABORT_IF_FALSE(!mCurrentURI,
"Shouldn't have both mCurrentRequest and mCurrentURI!");
// Deregister this image from the refresh driver so it no longer receives
// notifications.
nsLayoutUtils::DeregisterImageRequest(GetFramePresContext(), mCurrentRequest,
&mCurrentRequestRegistered);
// Clean up the request.
UntrackImage(mCurrentRequest);
mCurrentRequest->CancelAndForgetObserver(aReason);
@ -1009,12 +1083,29 @@ nsImageLoadingContent::ClearPendingRequest(nsresult aReason)
nsCxPusher pusher;
pusher.PushNull();
// Deregister this image from the refresh driver so it no longer receives
// notifications.
nsLayoutUtils::DeregisterImageRequest(GetFramePresContext(), mPendingRequest,
&mPendingRequestRegistered);
UntrackImage(mPendingRequest);
mPendingRequest->CancelAndForgetObserver(aReason);
mPendingRequest = nsnull;
mPendingRequestNeedsResetAnimation = false;
}
bool*
nsImageLoadingContent::GetRegisteredFlagForRequest(imgIRequest* aRequest)
{
if (aRequest == mCurrentRequest) {
return &mCurrentRequestRegistered;
} else if (aRequest == mPendingRequest) {
return &mPendingRequestRegistered;
} else {
return nsnull;
}
}
bool
nsImageLoadingContent::HaveSize(imgIRequest *aImage)
{

View File

@ -146,6 +146,24 @@ protected:
*/
nsIDocument* GetOurDocument();
/**
* Helper function to get the frame associated with this content. Not named
* GetPrimaryFrame to prevent ambiguous method names in subclasses.
*
* @return The frame which we belong to, or nsnull if it doesn't exist.
*/
nsIFrame* GetOurPrimaryFrame();
/**
* Helper function to get the PresContext associated with this content's
* frame. Not named GetPresContext to prevent ambiguous method names in
* subclasses.
*
* @return The nsPresContext associated with our frame, or nsnull if either
* the frame doesn't exist, or the frame's prescontext doesn't exist.
*/
nsPresContext* GetFramePresContext();
/**
* CancelImageRequests is called by subclasses when they want to
* cancel all image requests (for example when the subclass is
@ -302,6 +320,16 @@ protected:
void ClearCurrentRequest(nsresult aReason);
void ClearPendingRequest(nsresult aReason);
/**
* Retrieve a pointer to the 'registered with the refresh driver' flag for
* which a particular image request corresponds.
*
* @returns A pointer to the boolean flag for a given image request, or
* |nsnull| if the request is not either |mPendingRequest| or
* |mCurrentRequest|.
*/
bool* GetRegisteredFlagForRequest(imgIRequest* aRequest);
/**
* Static helper method to tell us if we have the size of a request. The
* image may be null.
@ -382,6 +410,11 @@ private:
/* The number of nested AutoStateChangers currently tracking our state. */
PRUint8 mStateChangerDepth;
// Flags to indicate whether each of the current and pending requests are
// registered with the refresh driver.
bool mCurrentRequestRegistered;
bool mPendingRequestRegistered;
};
#endif // nsImageLoadingContent_h__

View File

@ -286,7 +286,7 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument,
NS_ASSERTION(aInfo->mDetails->mType ==
CharacterDataChangeInfo::Details::eSplit,
"only a split can start before the end");
NS_ASSERTION(static_cast<PRUint32>(mStartOffset) <= aInfo->mChangeEnd,
NS_ASSERTION(static_cast<PRUint32>(mStartOffset) <= aInfo->mChangeEnd + 1,
"mStartOffset is beyond the end of this node");
newStartOffset = static_cast<PRUint32>(mStartOffset) - aInfo->mChangeStart;
newStartNode = aInfo->mDetails->mNextSibling;
@ -313,7 +313,7 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument,
NS_ASSERTION(aInfo->mDetails->mType ==
CharacterDataChangeInfo::Details::eSplit,
"only a split can start before the end");
NS_ASSERTION(static_cast<PRUint32>(mEndOffset) <= aInfo->mChangeEnd,
NS_ASSERTION(static_cast<PRUint32>(mEndOffset) <= aInfo->mChangeEnd + 1,
"mEndOffset is beyond the end of this node");
newEndOffset = static_cast<PRUint32>(mEndOffset) - aInfo->mChangeStart;
newEndNode = aInfo->mDetails->mNextSibling;

View File

@ -106,6 +106,12 @@ nsStubImageDecoderObserver::OnDiscard(imgIRequest *aRequest)
return NS_OK;
}
NS_IMETHODIMP
nsStubImageDecoderObserver::OnImageIsAnimated(imgIRequest *aRequest)
{
return NS_OK;
}
NS_IMETHODIMP
nsStubImageDecoderObserver::FrameChanged(imgIContainer *aContainer,
const nsIntRect *aDirtyRect)

View File

@ -521,6 +521,7 @@ _TEST_FILES2 = \
test_bug692434.html \
file_bug692434.xml \
test_bug693875.html \
test_nodelist_holes.html \
$(NULL)
_CHROME_FILES = \

View File

@ -0,0 +1,42 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=699826
-->
<head>
<title>Test for Bug 699826</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=699826">Mozilla Bug 699826</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 699826 **/
HTMLCollection.prototype[0] = "PASSProto0";
HTMLCollection.prototype[1] = "PASSProto1";
var list = document.getElementsByTagName("testtag");
is(list[0], "PASSProto0", "Should expose proto properties on the list");
is(list[1], "PASSProto1", "Should expose more proto properties on the list");
var testtag = document.createElement("testtag");
document.body.appendChild(testtag);
is(list[0], testtag, "Should expose elements in the list");
is(list[1], "PASSProto1", "Should expose proto properties out of range on the list");
testtag.parentNode.removeChild(testtag);
is(list[0], "PASSProto0", "Should expose proto properties on the list after removal");
is(list[1], "PASSProto1", "Should expose more proto properties on the list after removal");
</script>
</pre>
</body>
</html>

View File

@ -53,4 +53,5 @@ DOMCI_DATA(WebGLRenderbuffer, void)
DOMCI_DATA(WebGLUniformLocation, void)
DOMCI_DATA(WebGLActiveInfo, void)
DOMCI_DATA(WebGLExtension, void)
DOMCI_DATA(WebGLExtensionStandardDerivatives, void)
DOMCI_DATA(WebGLExtensionLoseContext, void)

View File

@ -81,6 +81,7 @@ _TEST_FILES_0 = \
test_2d.composite.uncovered.image.source-in.html \
test_2d.composite.uncovered.image.source-out.html \
test_2d.drawImage.zerocanvas.html \
test_toDataURL_alpha.html \
test_toDataURL_lowercase_ascii.html \
test_toDataURL_parameters.html \
test_mozGetAsFile.html \

View File

@ -0,0 +1,206 @@
<!DOCTYPE html>
<html>
<head>
<title>Canvas test: toDataURL parameters (Bug 564388)</title>
<script src="/MochiKit/MochiKit.js"></script>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
</head>
<body>
<p>
For image types that do not support an alpha channel, the image must be
composited onto a solid black background using the source-over operator,
and the resulting image must be the one used to create the data: URL.
</p>
<p> See:
<a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-canvas-todataurl">
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-canvas-todataurl
</a>
</p>
<p>Mozilla
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=650720">Bug 650720</a>
</p>
<p class="output">Output:</p>
<!--
Author's note:
To add more cases to this test:
- To add a row (another color value)
* Add a row to the table below, using the canvas id format
(c<row>-<col>)
* Update runTests to include the new row in the loop
- To add a column (another image format)
* Add a column to the table below, using the canvas id format above
* Update runTests to call do_canvas, passing your column number,
the image format, and any options to pass to the toDataUrl function
Vaguely derived from Philip Taylor's toDataURL.jpeg.alpha test:
http://philip.html5.org/tests/canvas/suite/tests/toDataURL.jpeg.alpha.html
-->
<table>
<tr>
<th>Type:</th>
<th>image/png</th>
<th>image/jpeg</th>
<th>image/bmp<br />(24 bpp)</th>
<th>image/bmp<br />(32 bpp)</th>
</tr>
<tr>
<td id="c1">rgba(128, 255, 128, 0.5)</td>
<td><canvas id="c1-1" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c1-2" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c1-3" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c1-4" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
</tr>
<tr>
<td id="c2">rgba(255, 128, 128, 0.75)</td>
<td><canvas id="c2-1" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c2-2" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c2-3" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c2-4" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
</tr>
<tr>
<td id="c3">rgba(128, 128, 255, 0.25)</td>
<td><canvas id="c3-1" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c3-2" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c3-3" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c3-4" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
</tr>
<tr>
<td id="c4">rgba(255, 255, 255, 1.0)</td>
<td><canvas id="c4-1" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c4-2" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c4-3" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c4-4" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
</tr>
<tr>
<td id="c5">rgba(255, 255, 255, 0)</td>
<td><canvas id="c5-1" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c5-2" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c5-3" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c5-4" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
</tr>
<tr>
<td id="c6">rgba(0, 0, 0, 1.0)</td>
<td><canvas id="c6-1" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c6-2" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c6-3" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c6-4" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
</tr>
<tr>
<td id="c7">rgba(0, 0, 0, 0)</td>
<td><canvas id="c7-1" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c7-2" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c7-3" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
<td><canvas id="c7-4" class="output" width="100" height="50">
<p class="fallback">FAIL (fallback content)</p></canvas></td>
</tr>
</table>
<script>
var finishedTests = [];
function isPixel(ctx, x,y, r,g,b,a, d)
{
var pos = x + "," + y;
var colour = r + "," + g + "," + b + "," + a;
var pixel = ctx.getImageData(x, y, 1, 1);
var pr = pixel.data[0],
pg = pixel.data[1],
pb = pixel.data[2],
pa = pixel.data[3];
ok(r-d <= pr && pr <= r+d &&
g-d <= pg && pg <= g+d &&
b-d <= pb && pb <= b+d &&
a-d <= pa && pa <= a+d,
"pixel "+pos+" of "+ctx.canvas.id+" is "+pr+","+pg+","+pb+","+pa+
"; expected "+colour+" +/- "+d);
}
function do_canvas(row, col, type, options)
{
finishedTests[row + '_' + col] = false;
var canvas = document.getElementById('c' + row + '-' + col);
var ctx = canvas.getContext('2d');
ctx.fillStyle = document.getElementById('c' + row).textContent;
ctx.fillRect(0, 0, 100, 50);
var data = canvas.toDataURL(type, options);
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, 100, 50);
var img = new Image();
var color = document.getElementById('c' + row).textContent;
color = color.substr(5, color.length - 6); // strip off the 'argb()'
var colors = color.replace(' ', '', 'g').split(',');
var r = colors[0]*colors[3],
g = colors[1]*colors[3],
b = colors[2]*colors[3];
img.onload = function ()
{
ctx.drawImage(img, 0, 0);
isPixel(ctx, 50,25, r,g,b,255, 8);
finishedTests[row + '_' + col] = true;
};
img.src = data;
}
function checkFinished()
{
for (var t in finishedTests) {
if (!finishedTests[t]) {
setTimeout(checkFinished, 500);
return;
}
}
SimpleTest.finish();
}
function runTests()
{
for (var row = 1; row <= 7; row++) {
do_canvas(row, 1, 'image/png');
do_canvas(row, 2, 'image/jpeg');
do_canvas(row, 3, 'image/bmp');
do_canvas(row, 4, 'image/bmp', '-moz-parse-options:bpp=32');
}
setTimeout(checkFinished, 500);
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(runTests);
</script>
</html>

View File

@ -120,6 +120,7 @@
#include "nsPLDOMEvent.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/FromParser.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -665,15 +666,13 @@ nsGenericHTMLElement::GetOffsetParent(nsIDOMElement** aOffsetParent)
return NS_OK;
}
NS_IMETHODIMP
nsGenericHTMLElement::GetInnerHTML(nsAString& aInnerHTML)
nsresult
nsGenericHTMLElement::GetMarkup(bool aIncludeSelf, nsAString& aMarkup)
{
aInnerHTML.Truncate();
aMarkup.Truncate();
nsIDocument* doc = OwnerDoc();
nsresult rv = NS_OK;
nsAutoString contentType;
if (IsInHTMLDocument()) {
contentType.AssignLiteral("text/html");
@ -698,21 +697,37 @@ nsGenericHTMLElement::GetInnerHTML(nsAString& aInnerHTML)
NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
rv = docEncoder->NativeInit(doc, contentType,
nsIDocumentEncoder::OutputEncodeBasicEntities |
// Output DOM-standard newlines
nsIDocumentEncoder::OutputLFLineBreak |
// Don't do linebreaking that's not present in
// the source
nsIDocumentEncoder::OutputRaw);
nsresult rv = docEncoder->NativeInit(doc, contentType,
nsIDocumentEncoder::OutputEncodeBasicEntities |
// Output DOM-standard newlines
nsIDocumentEncoder::OutputLFLineBreak |
// Don't do linebreaking that's not present in
// the source
nsIDocumentEncoder::OutputRaw);
NS_ENSURE_SUCCESS(rv, rv);
docEncoder->SetNativeContainerNode(this);
rv = docEncoder->EncodeToString(aInnerHTML);
doc->SetCachedEncoder(docEncoder.forget());
if (aIncludeSelf) {
docEncoder->SetNativeNode(this);
} else {
docEncoder->SetNativeContainerNode(this);
}
rv = docEncoder->EncodeToString(aMarkup);
if (!aIncludeSelf) {
doc->SetCachedEncoder(docEncoder.forget());
}
return rv;
}
nsresult
nsGenericHTMLElement::GetInnerHTML(nsAString& aInnerHTML) {
return GetMarkup(false, aInnerHTML);
}
NS_IMETHODIMP
nsGenericHTMLElement::GetOuterHTML(nsAString& aOuterHTML) {
return GetMarkup(true, aOuterHTML);
}
void
nsGenericHTMLElement::FireMutationEventsForDirectParsing(nsIDocument* aDoc,
nsIContent* aDest,
@ -740,8 +755,6 @@ nsGenericHTMLElement::SetInnerHTML(const nsAString& aInnerHTML)
{
nsIDocument* doc = OwnerDoc();
nsresult rv = NS_OK;
// Batch possible DOMSubtreeModified events.
mozAutoSubtreeModified subtree(doc, nsnull);
@ -758,8 +771,7 @@ nsGenericHTMLElement::SetInnerHTML(const nsAString& aInnerHTML)
nsAutoScriptLoaderDisabler sld(doc);
nsCOMPtr<nsIDOMDocumentFragment> df;
nsresult rv = NS_OK;
if (doc->IsHTML()) {
PRInt32 oldChildCount = GetChildCount();
rv = nsContentUtils::ParseFragmentHTML(aInnerHTML,
@ -772,6 +784,7 @@ nsGenericHTMLElement::SetInnerHTML(const nsAString& aInnerHTML)
// HTML5 parser has notified, but not fired mutation events.
FireMutationEventsForDirectParsing(doc, this, oldChildCount);
} else {
nsCOMPtr<nsIDOMDocumentFragment> df;
rv = nsContentUtils::CreateContextualFragment(this, aInnerHTML,
true,
getter_AddRefs(df));
@ -789,6 +802,71 @@ nsGenericHTMLElement::SetInnerHTML(const nsAString& aInnerHTML)
return rv;
}
NS_IMETHODIMP
nsGenericHTMLElement::SetOuterHTML(const nsAString& aOuterHTML)
{
nsINode* parent = GetNodeParent();
if (!parent) {
return NS_OK;
}
if (parent->NodeType() == nsIDOMNode::DOCUMENT_NODE) {
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
}
if (OwnerDoc()->IsHTML()) {
nsIAtom* localName;
PRInt32 namespaceID;
if (parent->IsElement()) {
localName = static_cast<nsIContent*>(parent)->Tag();
namespaceID = static_cast<nsIContent*>(parent)->GetNameSpaceID();
} else {
NS_ASSERTION(parent->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE,
"How come the parent isn't a document, a fragment or an element?");
localName = nsGkAtoms::body;
namespaceID = kNameSpaceID_XHTML;
}
nsCOMPtr<nsIDOMDocumentFragment> df;
nsresult rv = NS_NewDocumentFragment(getter_AddRefs(df),
OwnerDoc()->NodeInfoManager());
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIContent> fragment = do_QueryInterface(df);
nsContentUtils::ParseFragmentHTML(aOuterHTML,
fragment,
localName,
namespaceID,
OwnerDoc()->GetCompatibilityMode() ==
eCompatibility_NavQuirks,
PR_TRUE);
parent->ReplaceChild(fragment, this, &rv);
return rv;
}
nsCOMPtr<nsINode> context;
if (parent->IsElement()) {
context = parent;
} else {
NS_ASSERTION(parent->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE,
"How come the parent isn't a document, a fragment or an element?");
nsCOMPtr<nsINodeInfo> info =
OwnerDoc()->NodeInfoManager()->GetNodeInfo(nsGkAtoms::body,
nsnull,
kNameSpaceID_XHTML,
nsIDOMNode::ELEMENT_NODE);
context = NS_NewHTMLBodyElement(info.forget(), FROM_PARSER_FRAGMENT);
}
nsCOMPtr<nsIDOMDocumentFragment> df;
nsresult rv = nsContentUtils::CreateContextualFragment(context,
aOuterHTML,
PR_TRUE,
getter_AddRefs(df));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsINode> fragment = do_QueryInterface(df);
parent->ReplaceChild(fragment, this, &rv);
return rv;
}
enum nsAdjacentPosition {
eBeforeBegin,
eAfterBegin,

View File

@ -132,6 +132,8 @@ public:
nsresult GetOffsetParent(nsIDOMElement** aOffsetParent);
NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML);
NS_IMETHOD SetInnerHTML(const nsAString& aInnerHTML);
NS_IMETHOD GetOuterHTML(nsAString& aOuterHTML);
NS_IMETHOD SetOuterHTML(const nsAString& aOuterHTML);
NS_IMETHOD InsertAdjacentHTML(const nsAString& aPosition,
const nsAString& aText);
nsresult ScrollIntoView(bool aTop, PRUint8 optional_argc);
@ -161,6 +163,10 @@ public:
nsresult ClearDataset();
nsresult GetContextMenu(nsIDOMHTMLMenuElement** aContextMenu);
protected:
nsresult GetMarkup(bool aIncludeSelf, nsAString& aMarkup);
public:
// Implementation for nsIContent
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
@ -1571,6 +1577,12 @@ protected:
NS_SCRIPTABLE NS_IMETHOD SetSpellcheck(bool aSpellcheck) { \
return _to SetSpellcheck(aSpellcheck); \
} \
NS_SCRIPTABLE NS_IMETHOD GetOuterHTML(nsAString& aOuterHTML) { \
return _to GetOuterHTML(aOuterHTML); \
} \
NS_SCRIPTABLE NS_IMETHOD SetOuterHTML(const nsAString& aOuterHTML) { \
return _to SetOuterHTML(aOuterHTML); \
} \
NS_SCRIPTABLE NS_IMETHOD InsertAdjacentHTML(const nsAString& position, const nsAString& text) { \
return _to InsertAdjacentHTML(position, text); \
} \

View File

@ -118,7 +118,6 @@ public:
virtual bool IsLink(nsIURI** aURI) const;
virtual void GetLinkTarget(nsAString& aTarget);
virtual nsLinkState GetLinkState() const;
virtual void RequestLinkStateUpdate();
virtual already_AddRefed<nsIURI> GetHrefURI() const;
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
@ -216,9 +215,13 @@ nsHTMLAnchorElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
NS_ENSURE_SUCCESS(rv, rv);
// Prefetch links
if (aDocument && nsHTMLDNSPrefetch::IsAllowed(OwnerDoc())) {
nsHTMLDNSPrefetch::PrefetchLow(this);
if (aDocument) {
aDocument->RegisterPendingLinkUpdate(this);
if (nsHTMLDNSPrefetch::IsAllowed(OwnerDoc())) {
nsHTMLDNSPrefetch::PrefetchLow(this);
}
}
return rv;
}
@ -228,6 +231,11 @@ nsHTMLAnchorElement::UnbindFromTree(bool aDeep, bool aNullParent)
// If this link is ever reinserted into a document, it might
// be under a different xml:base, so forget the cached state now.
Link::ResetLinkState(false);
nsIDocument* doc = GetCurrentDoc();
if (doc) {
doc->UnregisterPendingLinkUpdate(this);
}
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}
@ -389,12 +397,6 @@ nsHTMLAnchorElement::GetLinkState() const
return Link::GetLinkState();
}
void
nsHTMLAnchorElement::RequestLinkStateUpdate()
{
UpdateLinkState(Link::LinkState());
}
already_AddRefed<nsIURI>
nsHTMLAnchorElement::GetHrefURI() const
{

View File

@ -99,7 +99,6 @@ public:
virtual bool IsLink(nsIURI** aURI) const;
virtual void GetLinkTarget(nsAString& aTarget);
virtual nsLinkState GetLinkState() const;
virtual void RequestLinkStateUpdate();
virtual already_AddRefed<nsIURI> GetHrefURI() const;
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
@ -213,7 +212,10 @@ nsHTMLAreaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
bool aCompileEventHandlers)
{
Link::ResetLinkState(false);
if (aDocument) {
aDocument->RegisterPendingLinkUpdate(this);
}
return nsGenericHTMLElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
@ -225,6 +227,11 @@ nsHTMLAreaElement::UnbindFromTree(bool aDeep, bool aNullParent)
// If this link is ever reinserted into a document, it might
// be under a different xml:base, so forget the cached state now.
Link::ResetLinkState(false);
nsIDocument* doc = GetCurrentDoc();
if (doc) {
doc->UnregisterPendingLinkUpdate(this);
}
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}
@ -314,12 +321,6 @@ nsHTMLAreaElement::GetLinkState() const
return Link::GetLinkState();
}
void
nsHTMLAreaElement::RequestLinkStateUpdate()
{
UpdateLinkState(Link::LinkState());
}
already_AddRefed<nsIURI>
nsHTMLAreaElement::GetHrefURI() const
{

View File

@ -501,8 +501,8 @@ nsHTMLCanvasElement::GetContext(const nsAString& aContextId,
JSObject *opts = JSVAL_TO_OBJECT(aContextOptions);
JSIdArray *props = JS_Enumerate(cx, opts);
for (int i = 0; props && i < props->length; ++i) {
jsid propid = props->vector[i];
for (int i = 0; props && i < JS_IdArrayLength(cx, props); ++i) {
jsid propid = JS_IdArrayGet(cx, props, i);
jsval propname, propval;
if (!JS_IdToValue(cx, propid, &propname) ||
!JS_GetPropertyById(cx, opts, propid, &propval))

View File

@ -395,7 +395,8 @@ nsHTMLDNSPrefetch::nsDeferrals::OnProgressChange(nsIWebProgress *aProgress,
NS_IMETHODIMP
nsHTMLDNSPrefetch::nsDeferrals::OnLocationChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
nsIURI *location)
nsIURI *location,
PRUint32 aFlags)
{
return NS_OK;
}

View File

@ -1843,7 +1843,8 @@ nsHTMLFormElement::OnProgressChange(nsIWebProgress* aWebProgress,
NS_IMETHODIMP
nsHTMLFormElement::OnLocationChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
nsIURI* location)
nsIURI* location,
PRUint32 aFlags)
{
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
return NS_OK;

View File

@ -111,7 +111,6 @@ public:
virtual bool IsLink(nsIURI** aURI) const;
virtual void GetLinkTarget(nsAString& aTarget);
virtual nsLinkState GetLinkState() const;
virtual void RequestLinkStateUpdate();
virtual already_AddRefed<nsIURI> GetHrefURI() const;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
@ -213,6 +212,10 @@ nsHTMLLinkElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
aBindingParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
if (aDocument) {
aDocument->RegisterPendingLinkUpdate(this);
}
void (nsHTMLLinkElement::*update)() = &nsHTMLLinkElement::UpdateStyleSheetInternal;
nsContentUtils::AddScriptRunner(NS_NewRunnableMethod(this, update));
@ -246,6 +249,9 @@ nsHTMLLinkElement::UnbindFromTree(bool aDeep, bool aNullParent)
// Once we have XPCOMGC we shouldn't need to call UnbindFromTree during Unlink
// and so this messy event dispatch can go away.
nsCOMPtr<nsIDocument> oldDoc = GetCurrentDoc();
if (oldDoc) {
oldDoc->UnregisterPendingLinkUpdate(this);
}
CreateAndDispatchEvent(oldDoc, NS_LITERAL_STRING("DOMLinkRemoved"));
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
UpdateStyleSheetInternal(oldDoc);
@ -379,12 +385,6 @@ nsHTMLLinkElement::GetLinkState() const
return Link::GetLinkState();
}
void
nsHTMLLinkElement::RequestLinkStateUpdate()
{
UpdateLinkState(Link::LinkState());
}
already_AddRefed<nsIURI>
nsHTMLLinkElement::GetHrefURI() const
{

View File

@ -274,6 +274,9 @@ _TEST_FILES = \
test_bug583533.html \
test_restore_from_parser_fragment.html \
test_bug617528.html \
test_bug660959-1.html \
test_bug660959-2.html \
test_bug660959-3.html \
test_checked.html \
test_bug677658.html \
test_bug677463.html \
@ -286,6 +289,8 @@ _TEST_FILES = \
file_fullscreen-denied-inner.html \
file_fullscreen-hidden.html \
file_fullscreen-navigation.html \
file_fullscreen-esc-exit.html \
file_fullscreen-esc-exit-inner.html \
test_li_attributes_reflection.html \
test_ol_attributes_reflection.html \
test_bug651956.html \

View File

@ -0,0 +1,58 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=700764
Verify that an ESC key press in a subdoc of a full-screen doc causes us to
exit DOM full-screen mode.
-->
<head>
<title>Test for Bug 700764</title>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<style>
body:not(:-moz-full-screen) {
background-color: blue;
}
</style>
</head>
<body>
<script type="application/javascript">
/** Test for Bug 700764 **/
function ok(condition, msg) {
parent.ok(condition, msg);
}
function is(a, b, msg) {
parent.is(a, b, msg);
}
var escKeyReceived = false;
var escKeySent = false;
function keyHandler(event) {
if (escKeyReceived == Components.interfaces.nsIDOMKeyEvent.DOM_VK_ESC) {
escKeyReceived = true;
}
}
window.addEventListener("keydown", keyHandler, true);
window.addEventListener("keyup", keyHandler, true);
window.addEventListener("keypress", keyHandler, true);
function startTest() {
ok(!document.mozFullScreen, "Subdoc should not be in full-screen mode");
ok(parent.document.mozFullScreen, "Parent should be in full-screen mode");
escKeySent = true;
window.focus();
synthesizeKey("VK_ESCAPE", {});
}
</script>
</pre>
<p>Inner frame</p>
</body>
</html>

View File

@ -0,0 +1,63 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=700764
Verify that an ESC key press in a subdoc of a full-screen doc causes us to
exit DOM full-screen mode.
-->
<head>
<title>Test for Bug 700764</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<style>
body:-moz-full-screen, div:-moz-full-screen {
background-color: red;
}
</style>
</head>
<body onload="startTest();">
<script type="application/javascript">
function ok(condition, msg) {
opener.ok(condition, msg);
}
function is(a, b, msg) {
opener.is(a, b, msg);
}
function finish() {
opener.nextTest();
}
function fullscreenchange1(event) {
ok(document.mozFullScreen, "Should have entered full-screen mode");
document.removeEventListener("mozfullscreenchange", fullscreenchange1, false);
document.addEventListener("mozfullscreenchange", fullscreenchange2, false);
ok(!document.getElementById("subdoc").contentWindow.escKeySent, "Should not yet have sent ESC key press.");
document.getElementById("subdoc").contentWindow.startTest();
}
function fullscreenchange2(event) {
document.removeEventListener("mozfullscreenchange", fullscreenchange2, false);
ok(document.getElementById("subdoc").contentWindow.escKeySent, "Should have sent ESC key press.");
ok(!document.getElementById("subdoc").contentWindow.escKeyReceived, "ESC key press to exit should not be delivered.");
ok(!document.mozFullScreen, "Should have left full-screen mode on ESC key press");
finish();
}
function startTest() {
document.addEventListener("mozfullscreenchange", fullscreenchange1, false);
SimpleTest.waitForFocus(function() {document.body.mozRequestFullScreen();});
}
</script>
<!-- This subframe conducts the test. -->
<iframe id="subdoc" src="file_fullscreen-esc-exit-inner.html"></iframe>
</pre>
</body>
</html>

View File

@ -468,22 +468,12 @@ function reflectInt(aParameters)
}
function stringToInteger(value, nonNegative, defaultValue) {
if (nonNegative === false) {
// Parse: Ignore leading whitespace, find [+/-][numbers]
var result = /^[ \t\n\f\r]*([\+\-]?[0-9]+)/.exec(value);
if (result) {
if (-0x80000000 <= result[1] && result[1] <= 0x7FFFFFFF) {
// If the value is within allowed value range for signed integer, return value
return result[1];
}
}
} else {
var result = /^[ \t\n\f\r]*(\+?[0-9]+)/.exec(value);
if (result) {
if (0 <= result[1] && result[1] <= 0x7FFFFFFF) {
// If the value is within allowed value range for non-negative integer, return value
return result[1];
}
// Parse: Ignore leading whitespace, find [+/-][numbers]
var result = /^[ \t\n\f\r]*([\+\-]?[0-9]+)/.exec(value);
if (result) {
if ((nonNegative ? 0:-0x80000000) <= result[1] && result[1] <= 0x7FFFFFFF) {
// If the value is within allowed value range for signed/unsigned integer, return value
return result[1];
}
}
return defaultValue;
@ -551,10 +541,6 @@ function reflectInt(aParameters)
//TBD: Bug 586761: .setAttribute(attr, -2147483648) --> element[attr] == defaultValue instead of -2147483648
todo_is(element[attr], intValue, "Bug 586761: " + element.localName +
".setAttribute(value, " + v + "), " + element.localName + "[" + attr + "] ");
} else if ((v === "-0" || v == "-0xABCDEF") && nonNegative) {
//TBD: Bug 688093: Non-negative integers should return defaultValue when attempting to reflect "-0"
todo_is(element[attr], intValue, "Bug 688093: " + element.localName +
".setAttribute(" + attr + ", " + v + "), " + element.localName + "[" + attr + "] ");
} else {
is(element[attr], intValue, element.localName +
".setAttribute(" + attr + ", " + v + "), " + element.localName + "[" + attr + "] ");

View File

@ -0,0 +1,26 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=660959
-->
<head>
<title>Test for Bug 660959</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="reflect.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=660959">Mozilla Bug 660959</a>
<p id="display"></p>
<div id="content" style="display: none">
<a href="#" id="testa"></a>
</div>
<pre id="test">
<script>
is($("content").querySelector(":link, :visited"), $("testa"),
"Should find a link even in a display:none subtree");
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=660959
-->
<head>
<title>Test for Bug 660959</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="reflect.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style>
:link, :visited {
color: red;
}
</style>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=660959">Mozilla Bug 660959</a>
<p id="display"></p>
<div id="content" style="display: none">
<a href="#" id="a"></a>
</div>
<pre id="test">
<script type="application/javascript">
var a = document.getElementById("a");
is(window.getComputedStyle(a).color, "rgb(255, 0, 0)", "Link is not right color?");
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,29 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=660959
-->
<head>
<title>Test for Bug 660959</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="reflect.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=660959">Mozilla Bug 660959</a>
<p id="display"></p>
<div id="content" style="display: none">
<a href="http://www.example.com"></a>
<div id="foo">
<span id="test"></span>
</div>
</div>
<pre id="test">
<script>
is($("foo").querySelector(":link + * span, :visited + * span"), $("test"),
"Should be able to find link siblings even in a display:none subtree");
</script>
</pre>
</body>
</html>

View File

@ -36,6 +36,7 @@ SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", false);
// run in an iframe, which by default will not have the mozallowfullscreen
// attribute set, so full-screen won't work.
var gTestWindows = [
"file_fullscreen-esc-exit.html",
"file_fullscreen-denied.html",
"file_fullscreen-api.html",
"file_fullscreen-api-keys.html",

View File

@ -1600,6 +1600,16 @@ nsHTMLDocument::Open(const nsAString& aContentTypeOrUrl,
return NS_OK;
}
// No calling document.open() without a script global object
if (!mScriptGlobalObject) {
return NS_OK;
}
nsPIDOMWindow* outer = GetWindow();
if (!outer || (GetInnerWindow() != outer->GetCurrentInnerWindow())) {
return NS_OK;
}
// check whether we're in the middle of unload. If so, ignore this call.
nsCOMPtr<nsIDocShell> shell = do_QueryReferent(mDocumentContainer);
if (!shell) {

View File

@ -89,19 +89,23 @@ nsMathMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
if (aDocument && !aDocument->GetMathMLEnabled()) {
// Enable MathML and setup the style sheet during binding, not element
// construction, because we could move a MathML element from the document
// that created it to another document.
aDocument->SetMathMLEnabled();
aDocument->EnsureCatalogStyleSheet(kMathMLStyleSheetURI);
if (aDocument) {
aDocument->RegisterPendingLinkUpdate(this);
if (!aDocument->GetMathMLEnabled()) {
// Enable MathML and setup the style sheet during binding, not element
// construction, because we could move a MathML element from the document
// that created it to another document.
aDocument->SetMathMLEnabled();
aDocument->EnsureCatalogStyleSheet(kMathMLStyleSheetURI);
// Rebuild style data for the presshell, because style system
// optimizations may have taken place assuming MathML was disabled.
// (See nsRuleNode::CheckSpecifiedProperties.)
nsCOMPtr<nsIPresShell> shell = aDocument->GetShell();
if (shell) {
shell->GetPresContext()->PostRebuildAllStyleDataEvent(nsChangeHint(0));
// Rebuild style data for the presshell, because style system
// optimizations may have taken place assuming MathML was disabled.
// (See nsRuleNode::CheckSpecifiedProperties.)
nsCOMPtr<nsIPresShell> shell = aDocument->GetShell();
if (shell) {
shell->GetPresContext()->PostRebuildAllStyleDataEvent(nsChangeHint(0));
}
}
}
@ -114,6 +118,11 @@ nsMathMLElement::UnbindFromTree(bool aDeep, bool aNullParent)
// If this link is ever reinserted into a document, it might
// be under a different xml:base, so forget the cached state now.
Link::ResetLinkState(false);
nsIDocument* doc = GetCurrentDoc();
if (doc) {
doc->UnregisterPendingLinkUpdate(this);
}
nsMathMLElementBase::UnbindFromTree(aDeep, aNullParent);
}
@ -622,12 +631,6 @@ nsMathMLElement::GetLinkState() const
return Link::GetLinkState();
}
void
nsMathMLElement::RequestLinkStateUpdate()
{
UpdateLinkState(Link::LinkState());
}
already_AddRefed<nsIURI>
nsMathMLElement::GetHrefURI() const
{

View File

@ -116,7 +116,6 @@ public:
virtual bool IsLink(nsIURI** aURI) const;
virtual void GetLinkTarget(nsAString& aTarget);
virtual nsLinkState GetLinkState() const;
virtual void RequestLinkStateUpdate();
virtual already_AddRefed<nsIURI> GetHrefURI() const;
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsAString& aValue, bool aNotify)

View File

@ -501,7 +501,9 @@ class nsBuiltinDecoder : public nsMediaDecoder
}
virtual void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRUint32 aOffset) {
return mDecoderStateMachine->NotifyDataArrived(aBuffer, aLength, aOffset);
if (mDecoderStateMachine) {
mDecoderStateMachine->NotifyDataArrived(aBuffer, aLength, aOffset);
}
}
// Sets the length of the framebuffer used in MozAudioAvailable events.

View File

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" class="reftest-wait">
<script>
<![CDATA[
function boom()
{
document.documentElement.removeChild(document.getElementById("a"));
document.documentElement.removeAttribute("class");
}
]]>
</script>
<animate id="a" begin="a.end; -0.1s" end="a.begin+0.2s" onend="boom()"/>
<animate id="a" begin="a.end; -0.1s" end="a.begin+0.2s"/>
</svg>

After

Width:  |  Height:  |  Size: 398 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg">
<animate id="b" end="b.end" dur="3s" />
</svg>

After

Width:  |  Height:  |  Size: 90 B

View File

@ -42,4 +42,6 @@ load 670313-1.svg
load 678822-1.svg
load 678847-1.svg
load 678938-1.svg
load 690994-1.svg
load 697640-1.svg
load 699325-1.svg

View File

@ -1622,10 +1622,6 @@ nsSMILTimedElement::GetNextInterval(const nsSMILInterval* aPrevInterval,
beginAfter = aPrevInterval->End()->Time();
prevIntervalWasZeroDur
= aPrevInterval->End()->Time() == aPrevInterval->Begin()->Time();
if (aFixedBeginTime) {
prevIntervalWasZeroDur &=
aPrevInterval->Begin()->Time() == aFixedBeginTime->Time();
}
} else {
beginAfter.SetMillis(LL_MININT);
}
@ -1647,17 +1643,17 @@ nsSMILTimedElement::GetNextInterval(const nsSMILInterval* aPrevInterval,
tempBegin = new nsSMILInstanceTime(nsSMILTimeValue(0));
} else {
PRInt32 beginPos = 0;
// If we're updating the current interval then skip any begin time that is
// dependent on the current interval's begin time. e.g.
// <animate id="a" begin="b.begin; a.begin+2s"...
// If b's interval disappears whilst 'a' is in the waiting state the begin
// time at "a.begin+2s" should be skipped since 'a' never begun.
do {
tempBegin =
GetNextGreaterOrEqual(mBeginInstances, beginAfter, beginPos);
if (!tempBegin || !tempBegin->Time().IsDefinite()) {
return false;
}
// If we're updating the current interval then skip any begin time that is
// dependent on the current interval's begin time. e.g.
// <animate id="a" begin="b.begin; a.begin+2s"...
// If b's interval disappears whilst 'a' is in the waiting state the begin
// time at "a.begin+2s" should be skipped since 'a' never begun.
} while (aReplacedInterval &&
tempBegin->GetBaseTime() == aReplacedInterval->Begin());
}
@ -1668,37 +1664,55 @@ nsSMILTimedElement::GetNextInterval(const nsSMILInterval* aPrevInterval,
// Calculate end time
{
PRInt32 endPos = 0;
// As above with begin times, avoid creating self-referential loops
// between instance times by checking that the newly found end instance
// time is not already dependent on the end of the current interval.
do {
tempEnd =
GetNextGreaterOrEqual(mEndInstances, tempBegin->Time(), endPos);
// SMIL doesn't allow for coincident zero-duration intervals, so if the
// previous interval was zero-duration, and tempEnd is going to give us
// another zero duration interval, then look for another end to use
// instead.
if (tempEnd && prevIntervalWasZeroDur &&
tempEnd->Time() == beginAfter) {
tempEnd = GetNextGreater(mEndInstances, tempBegin->Time(), endPos);
}
// As above with begin times, avoid creating self-referential loops
// between instance times by checking that the newly found end instance
// time is not already dependent on the end of the current interval.
} while (tempEnd && aReplacedInterval &&
tempEnd->GetBaseTime() == aReplacedInterval->End());
// If the last interval ended at the same point and was zero-duration and
// this one is too, look for another end to use instead
if (tempEnd && tempEnd->Time() == tempBegin->Time() &&
prevIntervalWasZeroDur) {
tempEnd = GetNextGreater(mEndInstances, tempBegin->Time(), endPos);
}
// If all the ends are before the beginning we have a bad interval UNLESS:
// a) We never had any end attribute to begin with (and hence we should
// just use the active duration after allowing for the possibility of
// an end instance provided by a DOM call), OR
// b) We have no definite end instances (SMIL only says "if the instance
// list is empty"--but if we have indefinite/unresolved instance times
// then there must be a good reason we haven't used them (since they
// will be >= tempBegin) such as avoiding creating a self-referential
// loop. In any case, the interval should be allowed to be open.), OR
// c) We have end events which leave the interval open-ended.
bool openEndedIntervalOk = mEndSpecs.IsEmpty() ||
!HaveDefiniteEndTimes() ||
if (!tempEnd) {
// If all the ends are before the beginning we have a bad interval
// UNLESS:
// a) We never had any end attribute to begin with (the SMIL pseudocode
// places this condition earlier in the flow but that fails to allow
// for DOM calls when no "indefinite" condition is given), OR
// b) We never had any end instance times to begin with, OR
// c) We have end events which leave the interval open-ended.
bool openEndedIntervalOk = mEndSpecs.IsEmpty() ||
mEndInstances.IsEmpty() ||
EndHasEventConditions();
if (!tempEnd && !openEndedIntervalOk)
return false; // Bad interval
// The above conditions correspond with the SMIL pseudocode but SMIL
// doesn't address self-dependent instance times which we choose to
// ignore.
//
// Therefore we add a qualification of (b) above that even if
// there are end instance times but they all depend on the end of the
// current interval we should act as if they didn't exist and allow the
// open-ended interval.
//
// In the following condition we don't use |= because it doesn't provide
// short-circuit behavior.
openEndedIntervalOk = openEndedIntervalOk ||
(aReplacedInterval &&
AreEndTimesDependentOn(aReplacedInterval->End()));
if (!openEndedIntervalOk) {
return false; // Bad interval
}
}
nsSMILTimeValue intervalEnd = tempEnd
? tempEnd->Time() : nsSMILTimeValue();
@ -1710,17 +1724,21 @@ nsSMILTimedElement::GetNextInterval(const nsSMILInterval* aPrevInterval,
}
NS_ABORT_IF_FALSE(tempEnd, "Failed to get end point for next interval");
// If we get two zero-length intervals in a row we will potentially have an
// infinite loop so we break it here by searching for the next begin time
// greater than tempEnd on the next time around.
if (tempEnd->Time().IsDefinite() && tempBegin->Time() == tempEnd->Time()) {
// When we choose the interval endpoints, we don't allow coincident
// zero-duration intervals, so if we arrive here and we have a zero-duration
// interval starting at the same point as a previous zero-duration interval,
// then it must be because we've applied constraints to the active duration.
// In that case, we will potentially run into an infinite loop, so we break
// it by searching for the next interval that starts AFTER our current
// zero-duration interval.
if (prevIntervalWasZeroDur && tempEnd->Time() == beginAfter) {
if (prevIntervalWasZeroDur) {
beginAfter.SetMillis(tempEnd->Time().GetMillis() + 1);
beginAfter.SetMillis(tempBegin->Time().GetMillis() + 1);
prevIntervalWasZeroDur = false;
continue;
}
prevIntervalWasZeroDur = true;
}
prevIntervalWasZeroDur = tempBegin->Time() == tempEnd->Time();
// Check for valid interval
if (tempEnd->Time() > zeroTime ||
@ -2252,17 +2270,6 @@ nsSMILTimedElement::GetPreviousInterval() const
: mOldIntervals[mOldIntervals.Length()-1].get();
}
bool
nsSMILTimedElement::HaveDefiniteEndTimes() const
{
if (mEndInstances.IsEmpty())
return false;
// mEndInstances is sorted so if the first time is not definite then none of
// them are
return mEndInstances[0]->Time().IsDefinite();
}
bool
nsSMILTimedElement::EndHasEventConditions() const
{
@ -2273,6 +2280,21 @@ nsSMILTimedElement::EndHasEventConditions() const
return false;
}
bool
nsSMILTimedElement::AreEndTimesDependentOn(
const nsSMILInstanceTime* aBase) const
{
if (mEndInstances.IsEmpty())
return false;
for (PRUint32 i = 0; i < mEndInstances.Length(); ++i) {
if (mEndInstances[i]->GetBaseTime() != aBase) {
return false;
}
}
return true;
}
//----------------------------------------------------------------------
// Hashtable callback functions

View File

@ -525,8 +525,9 @@ protected:
const nsSMILInstanceTime* GetEffectiveBeginInstance() const;
const nsSMILInterval* GetPreviousInterval() const;
bool HasPlayed() const { return !mOldIntervals.IsEmpty(); }
bool HaveDefiniteEndTimes() const;
bool EndHasEventConditions() const;
bool AreEndTimesDependentOn(
const nsSMILInstanceTime* aBase) const;
// Reset the current interval by first passing ownership to a temporary
// variable so that if Unlink() results in us receiving a callback,

View File

@ -42,6 +42,7 @@
#include "nsContentUtils.h"
#include "nsString.h"
#include "nsSVGUtils.h"
#include "nsCharSeparatedTokenizer.h"
#include "string.h"
namespace mozilla {
@ -85,32 +86,23 @@ SVGLengthList::SetValueFromString(const nsAString& aValue)
{
SVGLengthList temp;
NS_ConvertUTF16toUTF8 value(aValue);
char* start = SkipWhitespace(value.BeginWriting());
nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
tokenizer(aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
// We can't use strtok with SVG_COMMA_WSP_DELIM because to correctly handle
// invalid input in the form of two commas without a value between them, we
// would need to know if strtok overwrote a comma or not.
nsCAutoString str; // outside loop to minimize memory churn
while (*start != '\0') {
int end = strcspn(start, SVG_COMMA_WSP_DELIM);
if (end == 0) {
// found comma in an invalid location
return NS_ERROR_DOM_SYNTAX_ERR;
}
while (tokenizer.hasMoreTokens()) {
SVGLength length;
if (!length.SetValueFromString(NS_ConvertUTF8toUTF16(start, PRUint32(end)))) {
if (!length.SetValueFromString(tokenizer.nextToken())) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
if (!temp.AppendItem(length)) {
return NS_ERROR_OUT_OF_MEMORY;
}
start = SkipWhitespace(start + end);
if (*start == ',') {
start = SkipWhitespace(start + 1);
}
}
if (tokenizer.lastTokenEndedWithSeparator()) {
return NS_ERROR_DOM_SYNTAX_ERR; // trailing comma
}
return CopyFrom(temp);
}

View File

@ -102,7 +102,9 @@ SVGNumberList::SetValueFromString(const nsAString& aValue)
if (*end != '\0' || !NS_finite(num)) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
temp.AppendItem(num);
if (!temp.AppendItem(num)) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
if (tokenizer.lastTokenEndedWithSeparator()) {
return NS_ERROR_DOM_SYNTAX_ERR; // trailing comma

View File

@ -145,6 +145,10 @@ nsSVGAElement::BindToTree(nsIDocument *aDocument, nsIContent *aParent,
aBindingParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
if (aDocument) {
aDocument->RegisterPendingLinkUpdate(this);
}
return NS_OK;
}
@ -155,6 +159,11 @@ nsSVGAElement::UnbindFromTree(bool aDeep, bool aNullParent)
// If this link is ever reinserted into a document, it might
// be under a different xml:base, so forget the cached state now.
Link::ResetLinkState(false);
nsIDocument* doc = GetCurrentDoc();
if (doc) {
doc->UnregisterPendingLinkUpdate(this);
}
nsSVGAElementBase::UnbindFromTree(aDeep, aNullParent);
}
@ -165,12 +174,6 @@ nsSVGAElement::GetLinkState() const
return Link::GetLinkState();
}
void
nsSVGAElement::RequestLinkStateUpdate()
{
UpdateLinkState(Link::LinkState());
}
already_AddRefed<nsIURI>
nsSVGAElement::GetHrefURI() const
{

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