merge the last green changeset on fx-team to m-c

This commit is contained in:
Tim Taubert 2011-08-22 08:47:16 +02:00
commit 456dc55387
429 changed files with 12899 additions and 10839 deletions

View File

@ -177,6 +177,7 @@ _BROWSER_FILES = \
browser_bug647886.js \
browser_bug655584.js \
browser_bug664672.js \
browser_canonizeURL.js \
browser_findbarClose.js \
browser_keywordBookmarklets.js \
browser_contextSearchTabPosition.js \

View File

@ -0,0 +1,54 @@
function test() {
waitForExplicitFinish();
testNext();
}
var pairs = [
["example", "http://www.example.net/"],
["ex-ample", "http://www.ex-ample.net/"],
[" example ", "http://www.example.net/"],
[" example/foo ", "http://www.example.net/foo"],
[" example/foo bar ", "http://www.example.net/foo%20bar"],
["example.net", "http://example.net/"],
["http://example", "http://example/"],
["example:8080", "http://example:8080/"],
["ex-ample.foo", "http://ex-ample.foo/"],
["example.foo/bar ", "http://example.foo/bar"],
["1.1.1.1", "http://1.1.1.1/"],
["ftp://example", "ftp://example/"],
["ftp.example.bar", "ftp://ftp.example.bar/"],
["ex ample", Services.search.originalDefaultEngine.getSubmission("ex ample").uri.spec],
];
function testNext() {
if (!pairs.length) {
finish();
return;
}
let [inputValue, expectedURL] = pairs.shift();
gBrowser.addProgressListener({
onStateChange: function onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
if (aStateFlags & Ci.nsIWebProgressListener.STATE_START &&
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) {
is(aRequest.originalURI.spec, expectedURL,
"entering '" + inputValue + "' loads expected URL");
gBrowser.removeProgressListener(this);
gBrowser.stop();
executeSoon(testNext);
}
}
});
gURLBar.addEventListener("focus", function onFocus() {
gURLBar.removeEventListener("focus", onFocus);
EventUtils.synthesizeKey("VK_RETURN", { shiftKey: true });
});
gBrowser.selectedBrowser.focus();
gURLBar.inputField.value = inputValue;
gURLBar.focus();
}

View File

@ -367,7 +367,7 @@
// Only add the suffix when the URL bar value isn't already "URL-like",
// and only if we get a keyboard event, to match user expectations.
if (!/^\s*(www|https?)\b|\/\s*$/i.test(url) &&
if (/^\s*[^.:\/\s]+(?:\/.*|\s*)$/i.test(url) &&
(aTriggeringEvent instanceof KeyEvent)) {
#ifdef XP_MACOSX
let accel = aTriggeringEvent.metaKey;
@ -402,24 +402,15 @@
// Tack www. and suffix on. If user has appended directories, insert
// suffix before them (bug 279035). Be careful not to get two slashes.
// Also, don't add the suffix if it's in the original url (bug 233853).
let firstSlash = url.indexOf("/");
let existingSuffix = url.indexOf(suffix.substring(0, suffix.length - 1));
// * Logic for slash and existing suffix (example)
// No slash, no suffix: Add suffix (mozilla)
// No slash, yes suffix: Add slash (mozilla.com)
// Yes slash, no suffix: Insert suffix (mozilla/stuff)
// Yes slash, suffix before slash: Do nothing (mozilla.com/stuff)
// Yes slash, suffix after slash: Insert suffix (mozilla/?stuff=.com)
if (firstSlash >= 0) {
if (existingSuffix == -1 || existingSuffix > firstSlash)
url = url.substring(0, firstSlash) + suffix +
url.substring(firstSlash + 1);
} else
url = url + (existingSuffix == -1 ? suffix : "/");
url = url.substring(0, firstSlash) + suffix +
url.substring(firstSlash + 1);
} else {
url = url + suffix;
}
url = "http://www." + url;
}

View File

@ -53,7 +53,6 @@
#if !defined(XP_OS2)
#include "nsOperaProfileMigrator.h"
#endif
#include "nsSeamonkeyProfileMigrator.h"
#if defined(XP_WIN) && !defined(__MINGW32__)
#include "nsIEProfileMigrator.h"
#elif defined(XP_MACOSX)
@ -85,7 +84,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGNOMEShellService, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsOperaProfileMigrator)
#endif
NS_GENERIC_FACTORY_CONSTRUCTOR(nsProfileMigrator)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSeamonkeyProfileMigrator)
#if defined(XP_WIN) && !defined(__MINGW32__)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIEProfileMigrator)
#elif defined(XP_MACOSX)
@ -114,7 +112,6 @@ NS_DEFINE_NAMED_CID(NS_SAFARIPROFILEMIGRATOR_CID);
#if !defined(XP_OS2)
NS_DEFINE_NAMED_CID(NS_OPERAPROFILEMIGRATOR_CID);
#endif
NS_DEFINE_NAMED_CID(NS_SEAMONKEYPROFILEMIGRATOR_CID);
NS_DEFINE_NAMED_CID(NS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID);
static const mozilla::Module::CIDEntry kBrowserCIDs[] = {
@ -136,7 +133,6 @@ static const mozilla::Module::CIDEntry kBrowserCIDs[] = {
#if !defined(XP_OS2)
{ &kNS_OPERAPROFILEMIGRATOR_CID, false, NULL, nsOperaProfileMigratorConstructor },
#endif
{ &kNS_SEAMONKEYPROFILEMIGRATOR_CID, false, NULL, nsSeamonkeyProfileMigratorConstructor },
{ &kNS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID, false, NULL, nsPrivateBrowsingServiceWrapperConstructor },
{ NULL }
};
@ -173,7 +169,6 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
#if !defined(XP_OS2)
{ NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "opera", &kNS_OPERAPROFILEMIGRATOR_CID },
#endif
{ NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "seamonkey", &kNS_SEAMONKEYPROFILEMIGRATOR_CID },
{ NS_PRIVATE_BROWSING_SERVICE_CONTRACTID, &kNS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID },
{ NULL }
};

View File

@ -340,9 +340,6 @@ var MigrationWizard = {
case "safari":
source = "sourceNameSafari";
break;
case "seamonkey":
source = "sourceNameSeamonkey";
break;
}
// semi-wallpaper for crash when multiple profiles exist, since we haven't initialized mSourceProfile in places

View File

@ -70,19 +70,14 @@
browser/components/migration/src/nsProfileMigrator.cpp -->
#ifdef XP_MACOSX
<radio id="safari" label="&importFromSafari.label;" accesskey="&importFromSafari.accesskey;"/>
<radio id="seamonkey" label="&importFromSeamonkey.label;" accesskey="&importFromSeamonkey.accesskey;"/>
<radio id="opera" label="&importFromOpera.label;" accesskey="&importFromOpera.accesskey;"/>
#elifdef XP_UNIX
<radio id="seamonkey" label="&importFromSeamonkey.label;" accesskey="&importFromSeamonkey.accesskey;"/>
<radio id="opera" label="&importFromOpera.label;" accesskey="&importFromOpera.accesskey;"/>
#elifdef XP_WIN
#ifndef NO_IE_MIGRATOR
<radio id="ie" label="&importFromIE.label;" accesskey="&importFromIE.accesskey;"/>
#endif
<radio id="seamonkey" label="&importFromSeamonkey.label;" accesskey="&importFromSeamonkey.accesskey;"/>
<radio id="opera" label="&importFromOpera.label;" accesskey="&importFromOpera.accesskey;"/>
#else
<radio id="seamonkey" label="&importFromSeamonkey.label;" accesskey="&importFromSeamonkey.accesskey;"/>
#endif
<radio id="fromfile" label="&importFromHTMLFile.label;" accesskey="&importFromHTMLFile.accesskey;" hidden="true"/>
<radio id="nothing" label="&importFromNothing.label;" accesskey="&importFromNothing.accesskey;" hidden="true"/>

View File

@ -52,8 +52,6 @@ endif
CPPSRCS = nsProfileMigrator.cpp \
nsBrowserProfileMigratorUtils.cpp \
nsNetscapeProfileMigratorBase.cpp \
nsSeamonkeyProfileMigrator.cpp \
$(NULL)
ifneq ($(OS_ARCH),OS2)

View File

@ -1,469 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The Browser Profile Migrator.
*
* The Initial Developer of the Original Code is Ben Goodger.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@bengoodger.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsAppDirectoryServiceDefs.h"
#include "nsBrowserProfileMigratorUtils.h"
#include "nsICookieManager2.h"
#include "nsIFile.h"
#include "nsILineInputStream.h"
#include "nsIOutputStream.h"
#include "nsIPrefBranch.h"
#include "nsIPrefLocalizedString.h"
#include "nsIPrefService.h"
#include "NSReg.h"
#include "nsIServiceManager.h"
#include "nsISupportsPrimitives.h"
#include "nsIURL.h"
#include "nsNetscapeProfileMigratorBase.h"
#include "nsNetUtil.h"
#include "prtime.h"
#include "prprf.h"
#ifdef XP_MACOSX
#define NEED_TO_FIX_4X_COOKIES 1
#define SECONDS_BETWEEN_1900_AND_1970 2208988800UL
#endif /* XP_MACOSX */
#define FILE_NAME_PREFS_5X NS_LITERAL_STRING("prefs.js")
///////////////////////////////////////////////////////////////////////////////
// nsNetscapeProfileMigratorBase
nsNetscapeProfileMigratorBase::nsNetscapeProfileMigratorBase()
{
}
static nsresult
regerr2nsresult(REGERR errCode)
{
switch (errCode) {
case REGERR_PARAM:
case REGERR_BADTYPE:
case REGERR_BADNAME:
return NS_ERROR_INVALID_ARG;
case REGERR_MEMORY:
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_ERROR_FAILURE;
}
nsresult
nsNetscapeProfileMigratorBase::GetProfileDataFromRegistry(nsILocalFile* aRegistryFile,
nsISupportsArray* aProfileNames,
nsISupportsArray* aProfileLocations)
{
nsresult rv;
REGERR errCode;
// Ensure aRegistryFile exists before open it
PRBool regFileExists = PR_FALSE;
rv = aRegistryFile->Exists(&regFileExists);
NS_ENSURE_SUCCESS(rv, rv);
if (!regFileExists)
return NS_ERROR_FILE_NOT_FOUND;
// Open It
nsCAutoString regPath;
rv = aRegistryFile->GetNativePath(regPath);
NS_ENSURE_SUCCESS(rv, rv);
if ((errCode = NR_StartupRegistry()))
return regerr2nsresult(errCode);
HREG reg;
if ((errCode = NR_RegOpen(regPath.get(), &reg))) {
NR_ShutdownRegistry();
return regerr2nsresult(errCode);
}
RKEY profilesTree;
if ((errCode = NR_RegGetKey(reg, ROOTKEY_COMMON, "Profiles", &profilesTree))) {
NR_RegClose(reg);
NR_ShutdownRegistry();
return regerr2nsresult(errCode);
}
char profileStr[MAXREGPATHLEN];
REGENUM enumState = nsnull;
while (!NR_RegEnumSubkeys(reg, profilesTree, &enumState, profileStr,
sizeof(profileStr), REGENUM_CHILDREN))
{
RKEY profileKey;
if (NR_RegGetKey(reg, profilesTree, profileStr, &profileKey))
continue;
// "migrated" is "yes" for all valid Seamonkey profiles. It is only "no"
// for 4.x profiles.
char migratedStr[3];
errCode = NR_RegGetEntryString(reg, profileKey, (char *)"migrated",
migratedStr, sizeof(migratedStr));
if ((errCode != REGERR_OK && errCode != REGERR_BUFTOOSMALL) ||
strcmp(migratedStr, "no") == 0)
continue;
// Get the profile location and add it to the locations array
REGINFO regInfo;
regInfo.size = sizeof(REGINFO);
if (NR_RegGetEntryInfo(reg, profileKey, (char *)"directory", &regInfo))
continue;
nsCAutoString dirStr;
dirStr.SetLength(regInfo.entryLength);
errCode = NR_RegGetEntryString(reg, profileKey, (char *)"directory",
dirStr.BeginWriting(), regInfo.entryLength);
// Remove trailing \0
dirStr.SetLength(regInfo.entryLength-1);
nsCOMPtr<nsILocalFile> dir;
#ifdef XP_MACOSX
rv = NS_NewNativeLocalFile(EmptyCString(), PR_TRUE, getter_AddRefs(dir));
if (NS_FAILED(rv)) break;
dir->SetPersistentDescriptor(dirStr);
#else
rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(dirStr), PR_TRUE,
getter_AddRefs(dir));
if (NS_FAILED(rv)) break;
#endif
PRBool exists;
dir->Exists(&exists);
if (exists) {
aProfileLocations->AppendElement(dir);
// Get the profile name and add it to the names array
nsString profileName;
CopyUTF8toUTF16(nsDependentCString(profileStr), profileName);
nsCOMPtr<nsISupportsString> profileNameString(
do_CreateInstance("@mozilla.org/supports-string;1"));
profileNameString->SetData(profileName);
aProfileNames->AppendElement(profileNameString);
}
}
NR_RegClose(reg);
NR_ShutdownRegistry();
return rv;
}
#define GETPREF(xform, method, value) \
nsresult rv = aBranch->method(xform->sourcePrefName, value); \
if (NS_SUCCEEDED(rv)) \
xform->prefHasValue = PR_TRUE; \
return rv;
#define SETPREF(xform, method, value) \
if (xform->prefHasValue) { \
return aBranch->method(xform->targetPrefName ? xform->targetPrefName : xform->sourcePrefName, value); \
} \
return NS_OK;
nsresult
nsNetscapeProfileMigratorBase::GetString(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
GETPREF(xform, GetCharPref, &xform->stringValue);
}
nsresult
nsNetscapeProfileMigratorBase::SetString(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
SETPREF(xform, SetCharPref, xform->stringValue);
}
nsresult
nsNetscapeProfileMigratorBase::GetWString(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
nsCOMPtr<nsIPrefLocalizedString> prefValue;
nsresult rv = aBranch->GetComplexValue(xform->sourcePrefName,
NS_GET_IID(nsIPrefLocalizedString),
getter_AddRefs(prefValue));
if (NS_SUCCEEDED(rv) && prefValue) {
nsString data;
prefValue->ToString(getter_Copies(data));
xform->stringValue = ToNewCString(NS_ConvertUTF16toUTF8(data));
xform->prefHasValue = PR_TRUE;
}
return rv;
}
nsresult
nsNetscapeProfileMigratorBase::SetWStringFromASCII(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
if (xform->prefHasValue) {
nsCOMPtr<nsIPrefLocalizedString> pls(do_CreateInstance("@mozilla.org/pref-localizedstring;1"));
NS_ConvertUTF8toUTF16 data(xform->stringValue);
pls->SetData(data.get());
return aBranch->SetComplexValue(xform->targetPrefName ? xform->targetPrefName : xform->sourcePrefName, NS_GET_IID(nsIPrefLocalizedString), pls);
}
return NS_OK;
}
nsresult
nsNetscapeProfileMigratorBase::SetWString(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
if (xform->prefHasValue) {
nsCOMPtr<nsIPrefLocalizedString> pls(do_CreateInstance("@mozilla.org/pref-localizedstring;1"));
nsAutoString data = NS_ConvertUTF8toUTF16(xform->stringValue);
pls->SetData(data.get());
return aBranch->SetComplexValue(xform->targetPrefName ? xform->targetPrefName : xform->sourcePrefName, NS_GET_IID(nsIPrefLocalizedString), pls);
}
return NS_OK;
}
nsresult
nsNetscapeProfileMigratorBase::GetBool(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
GETPREF(xform, GetBoolPref, &xform->boolValue);
}
nsresult
nsNetscapeProfileMigratorBase::SetBool(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
SETPREF(xform, SetBoolPref, xform->boolValue);
}
nsresult
nsNetscapeProfileMigratorBase::GetInt(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
GETPREF(xform, GetIntPref, &xform->intValue);
}
nsresult
nsNetscapeProfileMigratorBase::SetInt(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
SETPREF(xform, SetIntPref, xform->intValue);
}
nsresult
nsNetscapeProfileMigratorBase::CopyFile(const nsAString& aSourceFileName, const nsAString& aTargetFileName)
{
nsCOMPtr<nsIFile> sourceFile;
mSourceProfile->Clone(getter_AddRefs(sourceFile));
sourceFile->Append(aSourceFileName);
PRBool exists = PR_FALSE;
sourceFile->Exists(&exists);
if (!exists)
return NS_OK;
nsCOMPtr<nsIFile> targetFile;
mTargetProfile->Clone(getter_AddRefs(targetFile));
targetFile->Append(aTargetFileName);
targetFile->Exists(&exists);
if (exists)
targetFile->Remove(PR_FALSE);
return sourceFile->CopyTo(mTargetProfile, aTargetFileName);
}
nsresult
nsNetscapeProfileMigratorBase::ImportNetscapeBookmarks(const nsAString& aBookmarksFileName,
const PRUnichar* aImportSourceNameKey)
{
nsCOMPtr<nsIFile> bookmarksFile;
mSourceProfile->Clone(getter_AddRefs(bookmarksFile));
bookmarksFile->Append(aBookmarksFileName);
return ImportBookmarksHTML(bookmarksFile, PR_FALSE, PR_FALSE, aImportSourceNameKey);
}
nsresult
nsNetscapeProfileMigratorBase::ImportNetscapeCookies(nsIFile* aCookiesFile)
{
nsresult rv;
nsCOMPtr<nsIInputStream> cookiesStream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(cookiesStream), aCookiesFile);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsILineInputStream> lineInputStream(do_QueryInterface(cookiesStream));
// This code is copied from mozilla/netwerk/cookie/src/nsCookieManager.cpp
static NS_NAMED_LITERAL_CSTRING(kTrue, "TRUE");
nsCAutoString buffer;
PRBool isMore = PR_TRUE;
PRInt32 hostIndex = 0, isDomainIndex, pathIndex, secureIndex, expiresIndex, nameIndex, cookieIndex;
PRInt32 numInts;
PRInt64 expires;
PRBool isDomain;
PRInt64 currentTime = PR_Now() / PR_USEC_PER_SEC;
nsCOMPtr<nsICookieManager2> cookieManager(do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv));
if (NS_FAILED(rv)) return rv;
/* file format is:
*
* host \t isDomain \t path \t secure \t expires \t name \t cookie
*
* if this format isn't respected we move onto the next line in the file.
* isDomain is "TRUE" or "FALSE" (default to "FALSE")
* isSecure is "TRUE" or "FALSE" (default to "TRUE")
* expires is a PRInt64 integer
* note 1: cookie can contain tabs.
* note 2: cookies are written in order of lastAccessed time:
* most-recently used come first; least-recently-used come last.
*/
while (isMore && NS_SUCCEEDED(lineInputStream->ReadLine(buffer, &isMore))) {
if (buffer.IsEmpty() || buffer.First() == '#')
continue;
// this is a cheap, cheesy way of parsing a tab-delimited line into
// string indexes, which can be lopped off into substrings. just for
// purposes of obfuscation, it also checks that each token was found.
// todo: use iterators?
if ((isDomainIndex = buffer.FindChar('\t', hostIndex) + 1) == 0 ||
(pathIndex = buffer.FindChar('\t', isDomainIndex) + 1) == 0 ||
(secureIndex = buffer.FindChar('\t', pathIndex) + 1) == 0 ||
(expiresIndex = buffer.FindChar('\t', secureIndex) + 1) == 0 ||
(nameIndex = buffer.FindChar('\t', expiresIndex) + 1) == 0 ||
(cookieIndex = buffer.FindChar('\t', nameIndex) + 1) == 0)
continue;
// check the expirytime first - if it's expired, ignore
// nullstomp the trailing tab, to avoid copying the string
char *iter = buffer.BeginWriting();
*(iter += nameIndex - 1) = char(0);
numInts = PR_sscanf(buffer.get() + expiresIndex, "%lld", &expires);
if (numInts != 1 || expires < currentTime)
continue;
isDomain = Substring(buffer, isDomainIndex, pathIndex - isDomainIndex - 1).Equals(kTrue);
const nsDependentCSubstring host =
Substring(buffer, hostIndex, isDomainIndex - hostIndex - 1);
// check for bad legacy cookies (domain not starting with a dot, or containing a port),
// and discard
if (isDomain && !host.IsEmpty() && host.First() != '.' ||
host.FindChar(':') != -1)
continue;
// create a new nsCookie and assign the data.
rv = cookieManager->Add(host,
Substring(buffer, pathIndex, secureIndex - pathIndex - 1),
Substring(buffer, nameIndex, cookieIndex - nameIndex - 1),
Substring(buffer, cookieIndex, buffer.Length() - cookieIndex),
Substring(buffer, secureIndex, expiresIndex - secureIndex - 1).Equals(kTrue),
PR_FALSE, // isHttpOnly
PR_FALSE, // isSession
expires);
}
return rv;
}
nsresult
nsNetscapeProfileMigratorBase::GetSignonFileName(PRBool aReplace, char** aFileName)
{
nsresult rv;
if (aReplace) {
// Find out what the signons file was called, this is stored in a pref
// in Seamonkey.
nsCOMPtr<nsIPrefService> psvc(do_GetService(NS_PREFSERVICE_CONTRACTID));
psvc->ResetPrefs();
nsCOMPtr<nsIFile> sourcePrefsName;
mSourceProfile->Clone(getter_AddRefs(sourcePrefsName));
sourcePrefsName->Append(FILE_NAME_PREFS_5X);
psvc->ReadUserPrefs(sourcePrefsName);
nsCOMPtr<nsIPrefBranch> branch(do_QueryInterface(psvc));
rv = branch->GetCharPref("signon.SignonFileName", aFileName);
}
else
rv = LocateSignonsFile(aFileName);
return rv;
}
nsresult
nsNetscapeProfileMigratorBase::LocateSignonsFile(char** aResult)
{
nsCOMPtr<nsISimpleEnumerator> entries;
nsresult rv = mSourceProfile->GetDirectoryEntries(getter_AddRefs(entries));
if (NS_FAILED(rv)) return rv;
nsCAutoString fileName;
do {
PRBool hasMore = PR_FALSE;
rv = entries->HasMoreElements(&hasMore);
if (NS_FAILED(rv) || !hasMore) break;
nsCOMPtr<nsISupports> supp;
rv = entries->GetNext(getter_AddRefs(supp));
if (NS_FAILED(rv)) break;
nsCOMPtr<nsIFile> currFile(do_QueryInterface(supp));
nsCOMPtr<nsIURI> uri;
rv = NS_NewFileURI(getter_AddRefs(uri), currFile);
if (NS_FAILED(rv)) break;
nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
nsCAutoString extn;
url->GetFileExtension(extn);
if (extn.Equals("s", CaseInsensitiveCompare)) {
url->GetFileName(fileName);
break;
}
}
while (1);
*aResult = ToNewCString(fileName);
return NS_OK;
}

View File

@ -1,101 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The Browser Profile Migrator.
*
* The Initial Developer of the Original Code is Ben Goodger.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@bengoodger.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef netscapeprofilemigratorbase___h___
#define netscapeprofilemigratorbase___h___
#include "nsILocalFile.h"
#include "nsIStringBundle.h"
#include "nsISupportsArray.h"
#include "nsStringAPI.h"
class nsIFile;
class nsIPrefBranch;
class nsNetscapeProfileMigratorBase
{
public:
nsNetscapeProfileMigratorBase();
virtual ~nsNetscapeProfileMigratorBase() { }
public:
typedef nsresult(*prefConverter)(void*, nsIPrefBranch*);
struct PrefTransform {
const char* sourcePrefName;
const char* targetPrefName;
prefConverter prefGetterFunc;
prefConverter prefSetterFunc;
PRBool prefHasValue;
union {
PRInt32 intValue;
PRBool boolValue;
char* stringValue;
};
};
static nsresult GetString(void* aTransform, nsIPrefBranch* aBranch);
static nsresult SetString(void* aTransform, nsIPrefBranch* aBranch);
static nsresult GetWString(void* aTransform, nsIPrefBranch* aBranch);
static nsresult SetWString(void* aTransform, nsIPrefBranch* aBranch);
static nsresult SetWStringFromASCII(void* aTransform, nsIPrefBranch* aBranch);
static nsresult GetBool(void* aTransform, nsIPrefBranch* aBranch);
static nsresult SetBool(void* aTransform, nsIPrefBranch* aBranch);
static nsresult GetInt(void* aTransform, nsIPrefBranch* aBranch);
static nsresult SetInt(void* aTransform, nsIPrefBranch* aBranch);
protected:
nsresult GetProfileDataFromRegistry(nsILocalFile* aRegistryFile,
nsISupportsArray* aProfileNames,
nsISupportsArray* aProfileLocations);
nsresult CopyFile(const nsAString& aSourceFileName, const nsAString& aTargetFileName);
nsresult ImportNetscapeBookmarks(const nsAString& aBookmarksFileName,
const PRUnichar* aImportSourceNameKey);
nsresult ImportNetscapeCookies(nsIFile* aCookiesFile);
nsresult GetSignonFileName(PRBool aReplace, char** aFileName);
nsresult LocateSignonsFile(char** aResult);
protected:
nsCOMPtr<nsILocalFile> mSourceProfile;
nsCOMPtr<nsIFile> mTargetProfile;
};
#endif

View File

@ -162,7 +162,6 @@ NS_IMPL_ISUPPORTS1(nsProfileMigrator, nsIProfileMigrator)
#define INTERNAL_NAME_IEXPLORE "iexplore"
#define INTERNAL_NAME_MOZILLA_SUITE "apprunner"
#define INTERNAL_NAME_SEAMONKEY "seamonkey"
#define INTERNAL_NAME_OPERA "opera"
#endif
@ -243,12 +242,7 @@ nsProfileMigrator::GetDefaultBrowserMigratorKey(nsACString& aKey,
aKey = "ie";
return NS_OK;
}
if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_MOZILLA_SUITE) ||
internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_SEAMONKEY)) {
aKey = "seamonkey";
return NS_OK;
}
if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_OPERA)) {
else if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_OPERA)) {
aKey = "opera";
return NS_OK;
}
@ -267,7 +261,6 @@ nsProfileMigrator::GetDefaultBrowserMigratorKey(nsACString& aKey,
#if defined(XP_MACOSX)
CHECK_MIGRATOR("safari");
#endif
CHECK_MIGRATOR("seamonkey");
CHECK_MIGRATOR("opera");
#undef CHECK_MIGRATOR

View File

@ -1,721 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The Browser Profile Migrator.
*
* The Initial Developer of the Original Code is Ben Goodger.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@bengoodger.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsBrowserProfileMigratorUtils.h"
#include "nsDirectoryServiceDefs.h"
#include "nsIObserverService.h"
#include "nsILoginInfo.h"
#include "nsILoginManager.h"
#include "nsILoginManagerStorage.h"
#include "nsIPrefLocalizedString.h"
#include "nsIPrefService.h"
#include "nsIServiceManager.h"
#include "nsISupportsArray.h"
#include "nsISupportsPrimitives.h"
#include "nsNetCID.h"
#include "nsNetUtil.h"
#include "nsSeamonkeyProfileMigrator.h"
#include "nsIProfileMigrator.h"
///////////////////////////////////////////////////////////////////////////////
// nsSeamonkeyProfileMigrator
#define FILE_NAME_BOOKMARKS NS_LITERAL_STRING("bookmarks.html")
#define FILE_NAME_COOKIES NS_LITERAL_STRING("cookies.txt")
#define FILE_NAME_SITEPERM_OLD NS_LITERAL_STRING("cookperm.txt")
#define FILE_NAME_SITEPERM_NEW NS_LITERAL_STRING("hostperm.1")
#define FILE_NAME_CERT8DB NS_LITERAL_STRING("cert8.db")
#define FILE_NAME_KEY3DB NS_LITERAL_STRING("key3.db")
#define FILE_NAME_SECMODDB NS_LITERAL_STRING("secmod.db")
#define FILE_NAME_MIMETYPES NS_LITERAL_STRING("mimeTypes.rdf")
#define FILE_NAME_DOWNLOADS NS_LITERAL_STRING("downloads.rdf")
#define FILE_NAME_PREFS NS_LITERAL_STRING("prefs.js")
#define FILE_NAME_USER_PREFS NS_LITERAL_STRING("user.js")
#define FILE_NAME_USERCONTENT NS_LITERAL_STRING("userContent.css")
#define DIR_NAME_CHROME NS_LITERAL_STRING("chrome")
NS_IMPL_ISUPPORTS1(nsSeamonkeyProfileMigrator, nsIBrowserProfileMigrator)
nsSeamonkeyProfileMigrator::nsSeamonkeyProfileMigrator()
{
mObserverService = do_GetService("@mozilla.org/observer-service;1");
}
nsSeamonkeyProfileMigrator::~nsSeamonkeyProfileMigrator()
{
}
///////////////////////////////////////////////////////////////////////////////
// nsIBrowserProfileMigrator
NS_IMETHODIMP
nsSeamonkeyProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup, const PRUnichar* aProfile)
{
nsresult rv = NS_OK;
PRBool aReplace = aStartup ? PR_TRUE : PR_FALSE;
if (!mTargetProfile) {
GetProfilePath(aStartup, mTargetProfile);
if (!mTargetProfile) return NS_ERROR_FAILURE;
}
if (!mSourceProfile)
GetSourceProfile(aProfile);
NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);
COPY_DATA(CopyPreferences, aReplace, nsIBrowserProfileMigrator::SETTINGS);
COPY_DATA(CopyCookies, aReplace, nsIBrowserProfileMigrator::COOKIES);
COPY_DATA(CopyPasswords, aReplace, nsIBrowserProfileMigrator::PASSWORDS);
COPY_DATA(CopyOtherData, aReplace, nsIBrowserProfileMigrator::OTHERDATA);
// Need to do startup before trying to copy bookmarks, since bookmarks
// import requires a profile. Can't do it earlier because services might
// end up creating the files we try to copy above.
if (aStartup) {
rv = aStartup->DoStartup();
NS_ENSURE_SUCCESS(rv, rv);
}
COPY_DATA(CopyBookmarks, aReplace, nsIBrowserProfileMigrator::BOOKMARKS);
if (aReplace &&
(aItems & nsIBrowserProfileMigrator::SETTINGS ||
aItems & nsIBrowserProfileMigrator::COOKIES ||
aItems & nsIBrowserProfileMigrator::PASSWORDS ||
!aItems)) {
// Permissions (Images, Cookies, Popups)
rv |= CopyFile(FILE_NAME_SITEPERM_NEW, FILE_NAME_SITEPERM_NEW);
rv |= CopyFile(FILE_NAME_SITEPERM_OLD, FILE_NAME_SITEPERM_OLD);
}
NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);
return rv;
}
NS_IMETHODIMP
nsSeamonkeyProfileMigrator::GetMigrateData(const PRUnichar* aProfile,
PRBool aReplace,
PRUint16* aResult)
{
*aResult = 0;
if (!mSourceProfile) {
GetSourceProfile(aProfile);
if (!mSourceProfile)
return NS_ERROR_FILE_NOT_FOUND;
}
MigrationData data[] = { { ToNewUnicode(FILE_NAME_PREFS),
nsIBrowserProfileMigrator::SETTINGS,
PR_TRUE },
{ ToNewUnicode(FILE_NAME_USER_PREFS),
nsIBrowserProfileMigrator::SETTINGS,
PR_TRUE },
{ ToNewUnicode(FILE_NAME_COOKIES),
nsIBrowserProfileMigrator::COOKIES,
PR_FALSE },
{ ToNewUnicode(FILE_NAME_BOOKMARKS),
nsIBrowserProfileMigrator::BOOKMARKS,
PR_FALSE },
{ ToNewUnicode(FILE_NAME_DOWNLOADS),
nsIBrowserProfileMigrator::OTHERDATA,
PR_TRUE },
{ ToNewUnicode(FILE_NAME_MIMETYPES),
nsIBrowserProfileMigrator::OTHERDATA,
PR_TRUE } };
// Frees file name strings allocated above.
GetMigrateDataFromArray(data, sizeof(data)/sizeof(MigrationData),
aReplace, mSourceProfile, aResult);
// Now locate passwords
nsCString signonsFileName;
GetSignonFileName(aReplace, getter_Copies(signonsFileName));
if (!signonsFileName.IsEmpty()) {
NS_ConvertASCIItoUTF16 fileName(signonsFileName);
nsCOMPtr<nsIFile> sourcePasswordsFile;
mSourceProfile->Clone(getter_AddRefs(sourcePasswordsFile));
sourcePasswordsFile->Append(fileName);
PRBool exists;
sourcePasswordsFile->Exists(&exists);
if (exists)
*aResult |= nsIBrowserProfileMigrator::PASSWORDS;
}
return NS_OK;
}
NS_IMETHODIMP
nsSeamonkeyProfileMigrator::GetSourceExists(PRBool* aResult)
{
nsCOMPtr<nsISupportsArray> profiles;
GetSourceProfiles(getter_AddRefs(profiles));
if (profiles) {
PRUint32 count;
profiles->Count(&count);
*aResult = count > 0;
}
else
*aResult = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsSeamonkeyProfileMigrator::GetSourceHasMultipleProfiles(PRBool* aResult)
{
nsCOMPtr<nsISupportsArray> profiles;
GetSourceProfiles(getter_AddRefs(profiles));
if (profiles) {
PRUint32 count;
profiles->Count(&count);
*aResult = count > 1;
}
else
*aResult = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsSeamonkeyProfileMigrator::GetSourceProfiles(nsISupportsArray** aResult)
{
if (!mProfileNames && !mProfileLocations) {
mProfileNames = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID);
mProfileLocations = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID);
NS_ENSURE_TRUE(mProfileNames && mProfileLocations, NS_ERROR_UNEXPECTED);
// Fills mProfileNames and mProfileLocations
FillProfileDataFromSeamonkeyRegistry();
}
NS_IF_ADDREF(*aResult = mProfileNames);
return NS_OK;
}
NS_IMETHODIMP
nsSeamonkeyProfileMigrator::GetSourceHomePageURL(nsACString& aResult)
{
// Load the source pref file
nsCOMPtr<nsIPrefService> psvc(do_GetService(NS_PREFSERVICE_CONTRACTID));
psvc->ResetPrefs();
nsCOMPtr<nsIFile> sourcePrefsFile;
mSourceProfile->Clone(getter_AddRefs(sourcePrefsFile));
sourcePrefsFile->Append(FILE_NAME_PREFS);
psvc->ReadUserPrefs(sourcePrefsFile);
nsCOMPtr<nsIPrefBranch> branch(do_QueryInterface(psvc));
PRBool hasUserValue;
nsCOMPtr<nsIPrefLocalizedString> prefValue;
nsresult rv = branch->PrefHasUserValue("browser.startup.homepage", &hasUserValue);
if (NS_SUCCEEDED(rv) && hasUserValue) {
rv = branch->GetComplexValue("browser.startup.homepage",
NS_GET_IID(nsIPrefLocalizedString),
getter_AddRefs(prefValue));
if (NS_SUCCEEDED(rv) && prefValue) {
nsString data;
prefValue->ToString(getter_Copies(data));
nsCAutoString val;
val = ToNewCString(NS_ConvertUTF16toUTF8(data));
aResult.Assign(val);
}
}
psvc->ResetPrefs();
psvc->ReadUserPrefs(nsnull);
return NS_OK;
}
///////////////////////////////////////////////////////////////////////////////
// nsSeamonkeyProfileMigrator
nsresult
nsSeamonkeyProfileMigrator::GetSourceProfile(const PRUnichar* aProfile)
{
PRUint32 count;
mProfileNames->Count(&count);
for (PRUint32 i = 0; i < count; ++i) {
nsCOMPtr<nsISupportsString> str;
mProfileNames->QueryElementAt(i, NS_GET_IID(nsISupportsString),
getter_AddRefs(str));
nsString profileName;
str->GetData(profileName);
if (profileName.Equals(aProfile)) {
mProfileLocations->QueryElementAt(i, NS_GET_IID(nsILocalFile),
getter_AddRefs(mSourceProfile));
break;
}
}
return NS_OK;
}
nsresult
nsSeamonkeyProfileMigrator::FillProfileDataFromSeamonkeyRegistry()
{
// Find the Seamonkey Registry
nsCOMPtr<nsIProperties> fileLocator(do_GetService("@mozilla.org/file/directory_service;1"));
nsCOMPtr<nsILocalFile> seamonkeyRegistry;
#ifdef XP_WIN
fileLocator->Get(NS_WIN_APPDATA_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(seamonkeyRegistry));
seamonkeyRegistry->Append(NS_LITERAL_STRING("Mozilla"));
seamonkeyRegistry->Append(NS_LITERAL_STRING("registry.dat"));
#elif defined(XP_MACOSX)
fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(seamonkeyRegistry));
seamonkeyRegistry->Append(NS_LITERAL_STRING("Mozilla"));
seamonkeyRegistry->Append(NS_LITERAL_STRING("Application Registry"));
#elif defined(XP_UNIX)
fileLocator->Get(NS_UNIX_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(seamonkeyRegistry));
seamonkeyRegistry->Append(NS_LITERAL_STRING(".mozilla"));
seamonkeyRegistry->Append(NS_LITERAL_STRING("appreg"));
#elif defined(XP_OS2)
fileLocator->Get(NS_OS2_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(seamonkeyRegistry));
seamonkeyRegistry->Append(NS_LITERAL_STRING("Mozilla"));
seamonkeyRegistry->Append(NS_LITERAL_STRING("registry.dat"));
#endif
return GetProfileDataFromRegistry(seamonkeyRegistry, mProfileNames, mProfileLocations);
}
#define F(a) nsSeamonkeyProfileMigrator::a
#define MAKEPREFTRANSFORM(pref, newpref, getmethod, setmethod) \
{ pref, newpref, F(Get##getmethod), F(Set##setmethod), PR_FALSE, { -1 } }
#define MAKESAMETYPEPREFTRANSFORM(pref, method) \
{ pref, 0, F(Get##method), F(Set##method), PR_FALSE, { -1 } }
static
nsSeamonkeyProfileMigrator::PrefTransform gTransforms[] = {
MAKESAMETYPEPREFTRANSFORM("signon.SignonFileName", String),
MAKESAMETYPEPREFTRANSFORM("browser.tabs.autoHide", Bool),
MAKESAMETYPEPREFTRANSFORM("browser.tabs.loadInBackground", Bool),
MAKESAMETYPEPREFTRANSFORM("browser.enable_automatic_image_resizing", Bool),
MAKESAMETYPEPREFTRANSFORM("network.cookie.warnAboutCookies", Bool),
MAKESAMETYPEPREFTRANSFORM("network.cookie.lifetime.enabled", Bool),
MAKESAMETYPEPREFTRANSFORM("network.cookie.lifetime.behavior", Int),
MAKESAMETYPEPREFTRANSFORM("dom.disable_open_during_load", Bool),
MAKESAMETYPEPREFTRANSFORM("signon.rememberSignons", Bool),
MAKESAMETYPEPREFTRANSFORM("security.enable_ssl3", Bool),
MAKESAMETYPEPREFTRANSFORM("security.enable_tls", Bool),
MAKESAMETYPEPREFTRANSFORM("security.warn_entering_secure", Bool),
MAKESAMETYPEPREFTRANSFORM("security.warn_entering_weak", Bool),
MAKESAMETYPEPREFTRANSFORM("security.warn_leaving_secure", Bool),
MAKESAMETYPEPREFTRANSFORM("security.warn_submit_insecure", Bool),
MAKESAMETYPEPREFTRANSFORM("security.warn_viewing_mixed", Bool),
MAKESAMETYPEPREFTRANSFORM("security.default_personal_cert", String),
MAKESAMETYPEPREFTRANSFORM("security.OSCP.enabled", Int),
MAKESAMETYPEPREFTRANSFORM("security.OSCP.signingCA", String),
MAKESAMETYPEPREFTRANSFORM("security.OSCP.URL", String),
MAKESAMETYPEPREFTRANSFORM("javascript.enabled", Bool),
MAKESAMETYPEPREFTRANSFORM("dom.disable_window_move_resize", Bool),
MAKESAMETYPEPREFTRANSFORM("dom.disable_window_flip", Bool),
MAKESAMETYPEPREFTRANSFORM("dom.disable_window_open_feature.status", Bool),
MAKESAMETYPEPREFTRANSFORM("dom.disable_window_status_change", Bool),
MAKESAMETYPEPREFTRANSFORM("dom.disable_image_src_set", Bool),
MAKESAMETYPEPREFTRANSFORM("accessibility.typeaheadfind.autostart", Bool),
MAKESAMETYPEPREFTRANSFORM("accessibility.typeaheadfind.linksonly", Bool),
MAKESAMETYPEPREFTRANSFORM("network.proxy.type", Int),
MAKESAMETYPEPREFTRANSFORM("network.proxy.http", String),
MAKESAMETYPEPREFTRANSFORM("network.proxy.http_port", Int),
MAKESAMETYPEPREFTRANSFORM("network.proxy.ftp", String),
MAKESAMETYPEPREFTRANSFORM("network.proxy.ftp_port", Int),
MAKESAMETYPEPREFTRANSFORM("network.proxy.ssl", String),
MAKESAMETYPEPREFTRANSFORM("network.proxy.ssl_port", Int),
MAKESAMETYPEPREFTRANSFORM("network.proxy.socks", String),
MAKESAMETYPEPREFTRANSFORM("network.proxy.socks_port", Int),
MAKESAMETYPEPREFTRANSFORM("network.proxy.no_proxies_on", String),
MAKESAMETYPEPREFTRANSFORM("network.proxy.autoconfig_url", String),
MAKESAMETYPEPREFTRANSFORM("browser.display.foreground_color", String),
MAKESAMETYPEPREFTRANSFORM("browser.display.background_color", String),
MAKESAMETYPEPREFTRANSFORM("browser.anchor_color", String),
MAKESAMETYPEPREFTRANSFORM("browser.visited_color", String),
MAKESAMETYPEPREFTRANSFORM("browser.underline_anchors", Bool),
MAKESAMETYPEPREFTRANSFORM("browser.display.use_system_colors", Bool),
MAKESAMETYPEPREFTRANSFORM("browser.display.use_document_colors", Bool),
MAKESAMETYPEPREFTRANSFORM("browser.display.use_document_fonts", Bool),
MAKESAMETYPEPREFTRANSFORM("intl.charset.default", String),
MAKESAMETYPEPREFTRANSFORM("intl.accept_languages", String),
MAKEPREFTRANSFORM("network.image.imageBehavior", 0, Int, Image),
MAKEPREFTRANSFORM("network.cookie.cookieBehavior", 0, Int, Cookie),
MAKEPREFTRANSFORM("browser.downloadmanager.behavior", 0, Int, DownloadManager),
MAKEPREFTRANSFORM("wallet.captureForms", "formfill.enabled", Bool, Bool)
};
nsresult
nsSeamonkeyProfileMigrator::SetImage(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
nsresult rv = NS_OK;
if (xform->prefHasValue)
rv = aBranch->SetIntPref("network.image.imageBehavior", xform->intValue == 1 ? 0 : xform->intValue);
return rv;
}
nsresult
nsSeamonkeyProfileMigrator::SetCookie(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
nsresult rv = NS_OK;
if (xform->prefHasValue)
rv = aBranch->SetIntPref("network.cookie.cookieBehavior", xform->intValue == 3 ? 0 : xform->intValue);
return rv;
}
nsresult
nsSeamonkeyProfileMigrator::SetDownloadManager(void* aTransform, nsIPrefBranch* aBranch)
{
PrefTransform* xform = (PrefTransform*)aTransform;
nsresult rv = NS_OK;
if (xform->prefHasValue) {
// Seamonkey's download manager uses a single pref to control behavior:
// 0 - show download manager window
// 1 - show individual progress dialogs
// 2 - show nothing
//
// Firefox has only a download manager window, but it can behave like a progress dialog, thus:
// 0 || 1 -> show downloads window when a download starts
// 2 -> don't show anything when a download starts
// 1 -> close the downloads window as if it were a progress window when downloads complete.
//
rv |= aBranch->SetBoolPref("browser.download.manager.showWhenStarting", xform->intValue != 2);
rv |= aBranch->SetBoolPref("browser.download.manager.closeWhenDone", xform->intValue == 1);
}
return NS_OK;
}
nsresult
nsSeamonkeyProfileMigrator::TransformPreferences(const nsAString& aSourcePrefFileName,
const nsAString& aTargetPrefFileName)
{
PrefTransform* transform;
PrefTransform* end = gTransforms + sizeof(gTransforms)/sizeof(PrefTransform);
// Load the source pref file
nsCOMPtr<nsIPrefService> psvc(do_GetService(NS_PREFSERVICE_CONTRACTID));
psvc->ResetPrefs();
nsCOMPtr<nsIFile> sourcePrefsFile;
mSourceProfile->Clone(getter_AddRefs(sourcePrefsFile));
sourcePrefsFile->Append(aSourcePrefFileName);
psvc->ReadUserPrefs(sourcePrefsFile);
nsCOMPtr<nsIPrefBranch> branch(do_QueryInterface(psvc));
for (transform = gTransforms; transform < end; ++transform)
transform->prefGetterFunc(transform, branch);
nsTArray<FontPref> fontPrefs;
ReadFontsBranch(psvc, &fontPrefs);
// Now that we have all the pref data in memory, load the target pref file,
// and write it back out
psvc->ResetPrefs();
for (transform = gTransforms; transform < end; ++transform)
transform->prefSetterFunc(transform, branch);
WriteFontsBranch(psvc, &fontPrefs);
nsCOMPtr<nsIFile> targetPrefsFile;
mTargetProfile->Clone(getter_AddRefs(targetPrefsFile));
targetPrefsFile->Append(aTargetPrefFileName);
psvc->SavePrefFile(targetPrefsFile);
psvc->ResetPrefs();
psvc->ReadUserPrefs(nsnull);
return NS_OK;
}
void
nsSeamonkeyProfileMigrator::ReadFontsBranch(nsIPrefService* aPrefService,
nsTArray<FontPref>* aPrefs)
{
// Enumerate the branch
nsCOMPtr<nsIPrefBranch> branch;
aPrefService->GetBranch("font.", getter_AddRefs(branch));
PRUint32 count;
char** prefs = nsnull;
nsresult rv = branch->GetChildList("", &count, &prefs);
if (NS_FAILED(rv)) return;
for (PRUint32 i = 0; i < count; ++i) {
// Save each pref's value into an array
char* currPref = prefs[i];
PRInt32 type;
branch->GetPrefType(currPref, &type);
FontPref* pref = aPrefs->AppendElement();
pref->prefName = currPref;
pref->type = type;
switch (type) {
case nsIPrefBranch::PREF_STRING:
rv = branch->GetCharPref(currPref, &pref->stringValue);
break;
case nsIPrefBranch::PREF_BOOL:
rv = branch->GetBoolPref(currPref, &pref->boolValue);
break;
case nsIPrefBranch::PREF_INT:
rv = branch->GetIntPref(currPref, &pref->intValue);
break;
case nsIPrefBranch::PREF_INVALID:
{
nsCOMPtr<nsIPrefLocalizedString> str;
rv = branch->GetComplexValue(currPref,
NS_GET_IID(nsIPrefLocalizedString),
getter_AddRefs(str));
if (NS_SUCCEEDED(rv) && str)
str->ToString(&pref->wstringValue);
}
break;
}
if (NS_FAILED(rv))
aPrefs->RemoveElementAt(aPrefs->Length()-1);
}
}
void
nsSeamonkeyProfileMigrator::WriteFontsBranch(nsIPrefService* aPrefService,
nsTArray<FontPref>* aPrefs)
{
nsresult rv;
// Enumerate the branch
nsCOMPtr<nsIPrefBranch> branch;
aPrefService->GetBranch("font.", getter_AddRefs(branch));
PRUint32 count = aPrefs->Length();
for (PRUint32 i = 0; i < count; ++i) {
FontPref &pref = aPrefs->ElementAt(i);
switch (pref.type) {
case nsIPrefBranch::PREF_STRING:
rv = branch->SetCharPref(pref.prefName, pref.stringValue);
NS_Free(pref.stringValue);
pref.stringValue = nsnull;
break;
case nsIPrefBranch::PREF_BOOL:
rv = branch->SetBoolPref(pref.prefName, pref.boolValue);
break;
case nsIPrefBranch::PREF_INT:
rv = branch->SetIntPref(pref.prefName, pref.intValue);
break;
case nsIPrefBranch::PREF_INVALID:
nsCOMPtr<nsIPrefLocalizedString> pls(do_CreateInstance("@mozilla.org/pref-localizedstring;1"));
pls->SetData(pref.wstringValue);
rv = branch->SetComplexValue(pref.prefName,
NS_GET_IID(nsIPrefLocalizedString),
pls);
NS_Free(pref.wstringValue);
pref.wstringValue = nsnull;
break;
}
NS_Free(pref.prefName);
}
aPrefs->Clear();
}
nsresult
nsSeamonkeyProfileMigrator::CopyPreferences(PRBool aReplace)
{
nsresult rv = NS_OK;
if (!aReplace)
return rv;
rv |= TransformPreferences(FILE_NAME_PREFS, FILE_NAME_PREFS);
rv |= CopyFile(FILE_NAME_USER_PREFS, FILE_NAME_USER_PREFS);
// Security Stuff
rv |= CopyFile(FILE_NAME_CERT8DB, FILE_NAME_CERT8DB);
rv |= CopyFile(FILE_NAME_KEY3DB, FILE_NAME_KEY3DB);
rv |= CopyFile(FILE_NAME_SECMODDB, FILE_NAME_SECMODDB);
// User MIME Type overrides
rv |= CopyFile(FILE_NAME_MIMETYPES, FILE_NAME_MIMETYPES);
rv |= CopyUserContentSheet();
return rv;
}
nsresult
nsSeamonkeyProfileMigrator::CopyUserContentSheet()
{
nsCOMPtr<nsIFile> sourceUserContent;
mSourceProfile->Clone(getter_AddRefs(sourceUserContent));
sourceUserContent->Append(DIR_NAME_CHROME);
sourceUserContent->Append(FILE_NAME_USERCONTENT);
PRBool exists = PR_FALSE;
sourceUserContent->Exists(&exists);
if (!exists)
return NS_OK;
nsCOMPtr<nsIFile> targetUserContent;
mTargetProfile->Clone(getter_AddRefs(targetUserContent));
targetUserContent->Append(DIR_NAME_CHROME);
nsCOMPtr<nsIFile> targetChromeDir;
targetUserContent->Clone(getter_AddRefs(targetChromeDir));
targetUserContent->Append(FILE_NAME_USERCONTENT);
targetUserContent->Exists(&exists);
if (exists)
targetUserContent->Remove(PR_FALSE);
return sourceUserContent->CopyTo(targetChromeDir, FILE_NAME_USERCONTENT);
}
nsresult
nsSeamonkeyProfileMigrator::CopyCookies(PRBool aReplace)
{
nsresult rv;
if (aReplace)
rv = CopyFile(FILE_NAME_COOKIES, FILE_NAME_COOKIES);
else {
nsCOMPtr<nsIFile> seamonkeyCookiesFile;
mSourceProfile->Clone(getter_AddRefs(seamonkeyCookiesFile));
seamonkeyCookiesFile->Append(FILE_NAME_COOKIES);
rv = ImportNetscapeCookies(seamonkeyCookiesFile);
}
return rv;
}
nsresult
nsSeamonkeyProfileMigrator::CopyPasswords(PRBool aReplace)
{
nsresult rv;
nsCString signonsFileName;
GetSignonFileName(aReplace, getter_Copies(signonsFileName));
if (signonsFileName.IsEmpty())
return NS_ERROR_FILE_NOT_FOUND;
NS_ConvertASCIItoUTF16 fileName(signonsFileName);
if (aReplace)
rv = CopyFile(fileName, fileName);
else {
// Get the password manager, which is the destination for the passwords
// being migrated. Also create a new instance of the legacy password
// storage component, which we'll use to slurp in the signons from
// Seamonkey's signons.txt.
nsCOMPtr<nsILoginManager> pwmgr(
do_GetService("@mozilla.org/login-manager;1"));
nsCOMPtr<nsILoginManagerStorage> importer(
do_CreateInstance("@mozilla.org/login-manager/storage/legacy;1"));
nsCOMPtr<nsIFile> signonsFile;
mSourceProfile->Clone(getter_AddRefs(signonsFile));
signonsFile->Append(fileName);
importer->InitWithFile(signonsFile, nsnull);
PRUint32 count;
nsILoginInfo **logins;
rv = importer->GetAllLogins(&count, &logins);
NS_ENSURE_SUCCESS(rv, rv);
for (PRUint32 i = 0; i < count; i++) {
pwmgr->AddLogin(logins[i]);
}
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, logins);
PRUnichar **hostnames;
rv = importer->GetAllDisabledHosts(&count, &hostnames);
NS_ENSURE_SUCCESS(rv, rv);
for (PRUint32 i = 0; i < count; i++) {
pwmgr->SetLoginSavingEnabled(nsDependentString(hostnames[i]),
PR_FALSE);
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, hostnames);
}
return rv;
}
nsresult
nsSeamonkeyProfileMigrator::CopyBookmarks(PRBool aReplace)
{
nsresult rv;
if (aReplace) {
// Initialize the default bookmarks
rv = InitializeBookmarks(mTargetProfile);
NS_ENSURE_SUCCESS(rv, rv);
// Merge in the bookmarks from the source profile
nsCOMPtr<nsIFile> sourceFile;
mSourceProfile->Clone(getter_AddRefs(sourceFile));
sourceFile->Append(FILE_NAME_BOOKMARKS);
rv = ImportBookmarksHTML(sourceFile, PR_TRUE, PR_FALSE, EmptyString().get());
NS_ENSURE_SUCCESS(rv, rv);
}
else {
rv = ImportNetscapeBookmarks(FILE_NAME_BOOKMARKS,
NS_LITERAL_STRING("sourceNameSeamonkey").get());
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
nsresult
nsSeamonkeyProfileMigrator::CopyOtherData(PRBool aReplace)
{
return aReplace ? CopyFile(FILE_NAME_DOWNLOADS, FILE_NAME_DOWNLOADS) : NS_OK;
}

View File

@ -1,105 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The Browser Profile Migrator.
*
* The Initial Developer of the Original Code is Ben Goodger.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@bengoodger.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef seamonkeyprofilemigrator___h___
#define seamonkeyprofilemigrator___h___
#include "nsIBrowserProfileMigrator.h"
#include "nsILocalFile.h"
#include "nsIObserverService.h"
#include "nsISupportsArray.h"
#include "nsNetscapeProfileMigratorBase.h"
#include "nsStringAPI.h"
#include "nsTArray.h"
class nsIFile;
class nsIPrefBranch;
class nsIPrefService;
struct FontPref {
char* prefName;
PRInt32 type;
union {
char* stringValue;
PRInt32 intValue;
PRBool boolValue;
PRUnichar* wstringValue;
};
};
class nsSeamonkeyProfileMigrator : public nsNetscapeProfileMigratorBase,
public nsIBrowserProfileMigrator
{
public:
NS_DECL_NSIBROWSERPROFILEMIGRATOR
NS_DECL_ISUPPORTS
nsSeamonkeyProfileMigrator();
virtual ~nsSeamonkeyProfileMigrator();
public:
static nsresult SetImage(void* aTransform, nsIPrefBranch* aBranch);
static nsresult SetCookie(void* aTransform, nsIPrefBranch* aBranch);
static nsresult SetDownloadManager(void* aTransform, nsIPrefBranch* aBranch);
protected:
nsresult FillProfileDataFromSeamonkeyRegistry();
nsresult GetSourceProfile(const PRUnichar* aProfile);
nsresult CopyPreferences(PRBool aReplace);
nsresult TransformPreferences(const nsAString& aSourcePrefFileName,
const nsAString& aTargetPrefFileName);
void ReadFontsBranch(nsIPrefService* aPrefService,
nsTArray<FontPref>* aPrefs);
void WriteFontsBranch(nsIPrefService* aPrefService,
nsTArray<FontPref>* aPrefs);
nsresult CopyUserContentSheet();
nsresult CopyCookies(PRBool aReplace);
nsresult CopyPasswords(PRBool aReplace);
nsresult LocateSignonsFile(char** aResult);
nsresult CopyBookmarks(PRBool aReplace);
nsresult CopyOtherData(PRBool aReplace);
private:
nsCOMPtr<nsISupportsArray> mProfileNames;
nsCOMPtr<nsISupportsArray> mProfileLocations;
nsCOMPtr<nsIObserverService> mObserverService;
};
#endif

View File

@ -277,17 +277,30 @@ var PlacesOrganizer = {
* the node to set up scope from
*/
_setSearchScopeForNode: function PO__setScopeForNode(aNode) {
var itemId = aNode.itemId;
let itemId = aNode.itemId;
// Set default buttons status.
let bookmarksButton = document.getElementById("scopeBarAll");
bookmarksButton.hidden = false;
let downloadsButton = document.getElementById("scopeBarDownloads");
downloadsButton.hidden = true;
if (PlacesUtils.nodeIsHistoryContainer(aNode) ||
itemId == PlacesUIUtils.leftPaneQueries["History"]) {
PlacesQueryBuilder.setScope("history");
}
// Default to All Bookmarks for all other nodes, per bug 469437.
else
else if (itemId == PlacesUIUtils.leftPaneQueries["Downloads"]) {
downloadsButton.hidden = false;
bookmarksButton.hidden = true;
PlacesQueryBuilder.setScope("downloads");
}
else {
// Default to All Bookmarks for all other nodes, per bug 469437.
PlacesQueryBuilder.setScope("bookmarks");
}
// Enable or disable the folder scope button.
var folderButton = document.getElementById("scopeBarFolder");
let folderButton = document.getElementById("scopeBarFolder");
folderButton.hidden = !PlacesUtils.nodeIsFolder(aNode) ||
itemId == PlacesUIUtils.allBookmarksFolderId;
},
@ -901,9 +914,21 @@ var PlacesSearchBox = {
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY;
content.load([query], options);
}
else
else {
content.applyFilter(filterString);
}
break;
case "downloads": {
let query = PlacesUtils.history.getNewQuery();
query.searchTerms = filterString;
query.setTransitions([Ci.nsINavHistoryService.TRANSITION_DOWNLOAD], 1);
let options = currentOptions.clone();
// Make sure we're getting uri results.
options.resultType = currentOptions.RESULT_TYPE_URI;
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY;
content.load([query], options);
break;
}
default:
throw "Invalid filterCollection on search";
break;
@ -933,17 +958,28 @@ var PlacesSearchBox = {
/**
* Updates the display with the title of the current collection.
* @param title
* @param aTitle
* The title of the current collection.
*/
updateCollectionTitle: function PSB_updateCollectionTitle(title) {
if (title)
this.searchFilter.placeholder =
PlacesUIUtils.getFormattedString("searchCurrentDefault", [title]);
else
this.searchFilter.placeholder = this.filterCollection == "history" ?
PlacesUIUtils.getString("searchHistory") :
PlacesUIUtils.getString("searchBookmarks");
updateCollectionTitle: function PSB_updateCollectionTitle(aTitle) {
let title = "";
if (aTitle) {
title = PlacesUIUtils.getFormattedString("searchCurrentDefault",
[aTitle]);
}
else {
switch(this.filterCollection) {
case "history":
title = PlacesUIUtils.getString("searchHistory");
break;
case "downloads":
title = PlacesUIUtils.getString("searchDownloads");
break;
default:
title = PlacesUIUtils.getString("searchBookmarks");
}
}
this.searchFilter.placeholder = title;
},
/**
@ -1025,6 +1061,9 @@ var PlacesQueryBuilder = {
case "scopeBarFolder":
this.setScope("collection");
break;
case "scopeBarDownloads":
this.setScope("downloads");
break;
case "scopeBarAll":
this.setScope("bookmarks");
break;
@ -1040,7 +1079,8 @@ var PlacesQueryBuilder = {
* PSB_search()). If there is an active search, it's performed again to
* update the content tree.
* @param aScope
* the search scope, "bookmarks", "collection", or "history"
* The search scope: "bookmarks", "collection", "downloads" or
* "history".
*/
setScope: function PQB_setScope(aScope) {
// Determine filterCollection, folders, and scopeButtonId based on aScope.
@ -1072,6 +1112,10 @@ var PlacesQueryBuilder = {
PlacesUtils.toolbarFolderId,
PlacesUtils.unfiledBookmarksFolderId);
break;
case "downloads":
filterCollection = "downloads";
scopeButtonId = "scopeBarDownloads";
break;
default:
throw "Invalid search scope";
break;

View File

@ -412,18 +412,16 @@
oncommand="PlacesQueryBuilder.onScopeSelected(this);"
label="&search.scopeBookmarks.label;"
accesskey="&search.scopeBookmarks.accesskey;"/>
<!--
<toolbarbutton id="scopeBarDownloads" class="small-margin"
type="radio" group="scopeBar"
oncommand="PlacesQueryBuilder.onScopeSelected(this);"
label="&search.scopeDownloads.label;"
accesskey="&search.scopeDownloads.accesskey;"/>
-->
<toolbarbutton id="scopeBarHistory" class="small-margin"
type="radio" group="scopeBar"
oncommand="PlacesQueryBuilder.onScopeSelected(this);"
label="&search.scopeHistory.label;"
accesskey="&search.scopeHistory.accesskey;"/>
<toolbarbutton id="scopeBarDownloads" class="small-margin"
type="radio" group="scopeBar"
oncommand="PlacesQueryBuilder.onScopeSelected(this);"
label="&search.scopeDownloads.label;"
accesskey="&search.scopeDownloads.accesskey;"/>
<toolbarbutton id="scopeBarFolder" class="small-margin"
type="radio" group="scopeBar"
oncommand="PlacesQueryBuilder.onScopeSelected(this);"

View File

@ -61,67 +61,74 @@
*/
const TEST_URL = "http://dummy.mozilla.org/";
const TEST_DOWNLOAD_URL = "http://dummy.mozilla.org/dummy.pdf";
// Add your tests here. Each is a function that's called by testHelper().
var testCases = [
let gLibrary;
// All Bookmarks
function () {
var defScope = getDefaultScope(PlacesUIUtils.allBookmarksFolderId);
let testCases = [
function allBookmarksScope() {
let defScope = getDefaultScope(PlacesUIUtils.allBookmarksFolderId);
search(PlacesUIUtils.allBookmarksFolderId, "dummy", defScope);
is(selectScope("scopeBarFolder"), false,
ok(!selectScope("scopeBarFolder"),
"Folder scope should be disabled for All Bookmarks");
resetSearch(defScope);
ok(selectScope("scopeBarAll"),
"Bookmarks scope should be enabled for All Bookmarks");
resetSearch("scopeBarAll");
},
// History
function () {
var defScope = getDefaultScope(PlacesUIUtils.leftPaneQueries["History"]);
function historyScope() {
let defScope = getDefaultScope(PlacesUIUtils.leftPaneQueries["History"]);
search(PlacesUIUtils.leftPaneQueries["History"], "dummy", defScope);
is(selectScope("scopeBarFolder"), false,
ok(!selectScope("scopeBarFolder"),
"Folder scope should be disabled for History");
ok(selectScope("scopeBarAll"),
"Bookmarks scope should be enabled for History");
resetSearch("scopeBarAll");
},
function downloadsScope() {
let defScope = getDefaultScope(PlacesUIUtils.leftPaneQueries["Downloads"]);
search(PlacesUIUtils.leftPaneQueries["Downloads"], "dummy", defScope);
ok(!selectScope("scopeBarFolder"),
"Folder scope should be disabled for Downloads");
ok(!selectScope("scopeBarAll"),
"Bookmarks scope should be disabled for Downloads");
resetSearch(defScope);
},
// Toolbar folder
function () {
var defScope = getDefaultScope(bmsvc.toolbarFolder);
search(bmsvc.toolbarFolder, "dummy", defScope);
is(selectScope("scopeBarFolder"), true,
function toolbarFolderScope() {
let defScope = getDefaultScope(PlacesUtils.toolbarFolderId);
search(PlacesUtils.toolbarFolderId, "dummy", defScope);
ok(selectScope("scopeBarAll"),
"Bookmarks scope should be enabled for toolbar folder");
ok(selectScope("scopeBarFolder"),
"Folder scope should be enabled for toolbar folder");
// Ensure that folder scope is still selected after resetting and searching
// again.
resetSearch("scopeBarFolder");
search(bmsvc.toolbarFolder, "dummy", "scopeBarFolder");
search(PlacesUtils.toolbarFolderId, "dummy", "scopeBarFolder");
},
// A regular non-root subfolder
function () {
var folderId = bmsvc.createFolder(bmsvc.toolbarFolder,
"dummy folder",
bmsvc.DEFAULT_INDEX);
var defScope = getDefaultScope(folderId);
function subFolderScope() {
let folderId = PlacesUtils.bookmarks.createFolder(PlacesUtils.toolbarFolderId,
"dummy folder",
PlacesUtils.bookmarks.DEFAULT_INDEX);
let defScope = getDefaultScope(folderId);
search(folderId, "dummy", defScope);
is(selectScope("scopeBarFolder"), true,
ok(selectScope("scopeBarAll"),
"Bookmarks scope should be enabled for regularfolder");
ok(selectScope("scopeBarFolder"),
"Folder scope should be enabled for regular subfolder");
// Ensure that folder scope is still selected after resetting and searching
// again.
resetSearch("scopeBarFolder");
search(folderId, "dummy", "scopeBarFolder");
bmsvc.removeItem(folderId);
PlacesUtils.bookmarks.removeItem(folderId);
},
];
///////////////////////////////////////////////////////////////////////////////
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
var libraryWin;
///////////////////////////////////////////////////////////////////////////////
/**
* Returns the default search scope for a given folder.
*
@ -130,9 +137,14 @@ var libraryWin;
* @return the default scope when the folder is newly selected
*/
function getDefaultScope(aFolderId) {
return aFolderId === PlacesUIUtils.leftPaneQueries["History"] ?
"scopeBarHistory" :
"scopeBarAll";
switch (aFolderId) {
case PlacesUIUtils.leftPaneQueries["History"]:
return "scopeBarHistory"
case PlacesUIUtils.leftPaneQueries["Downloads"]:
return "scopeBarDownloads";
default:
return "scopeBarAll";
}
}
/**
@ -141,8 +153,8 @@ function getDefaultScope(aFolderId) {
* @return the ID of the selected scope folder button
*/
function getSelectedScopeButtonId() {
var doc = libraryWin.document;
var scopeButtons = doc.getElementById("organizerScopeBar").childNodes;
let doc = gLibrary.document;
let scopeButtons = doc.getElementById("organizerScopeBar").childNodes;
for (let i = 0; i < scopeButtons.length; i++) {
if (scopeButtons[i].checked)
return scopeButtons[i].id;
@ -158,8 +170,8 @@ function getSelectedScopeButtonId() {
* @return an nsINavHistoryQuery object
*/
function queryStringToQuery(aPlaceURI) {
var queries = {};
histsvc.queryStringToQueries(aPlaceURI, queries, {}, {});
let queries = {};
PlacesUtils.history.queryStringToQueries(aPlaceURI, queries, {}, {});
return queries.value[0];
}
@ -188,9 +200,9 @@ function resetSearch(aExpectedScopeButtonId) {
* after searching the selected scope button should be this
*/
function search(aFolderId, aSearchStr, aExpectedScopeButtonId) {
var doc = libraryWin.document;
var folderTree = doc.getElementById("placesList");
var contentTree = doc.getElementById("placeContent");
let doc = gLibrary.document;
let folderTree = doc.getElementById("placesList");
let contentTree = doc.getElementById("placeContent");
// First, ensure that selecting the folder in the left pane updates the
// content tree properly.
@ -201,10 +213,11 @@ function search(aFolderId, aSearchStr, aExpectedScopeButtonId) {
// getFolders() on a History query returns an empty array, so no use
// comparing against aFolderId in that case.
if (aFolderId !== PlacesUIUtils.leftPaneQueries["History"]) {
if (aFolderId !== PlacesUIUtils.leftPaneQueries["History"] &&
aFolderId !== PlacesUIUtils.leftPaneQueries["Downloads"]) {
// contentTree.place should be equal to contentTree.result.root.uri,
// but it's not until bug 476952 is fixed.
var query = queryStringToQuery(contentTree.result.root.uri);
let query = queryStringToQuery(contentTree.result.root.uri);
is(query.getFolders()[0], aFolderId,
"Content tree's folder should be what was selected in the left pane");
}
@ -212,27 +225,41 @@ function search(aFolderId, aSearchStr, aExpectedScopeButtonId) {
// Second, ensure that searching updates the content tree and search UI
// properly.
var searchBox = doc.getElementById("searchFilter");
let searchBox = doc.getElementById("searchFilter");
searchBox.value = aSearchStr;
libraryWin.PlacesSearchBox.search(searchBox.value);
query = queryStringToQuery(contentTree.result.root.uri);
gLibrary.PlacesSearchBox.search(searchBox.value);
let query = queryStringToQuery(contentTree.result.root.uri);
if (aSearchStr) {
is(query.searchTerms, aSearchStr,
"Content tree's searchTerms should be text in search box");
is(doc.getElementById("searchModifiers").hidden, false,
"Scope bar should not be hidden after searching");
if (getSelectedScopeButtonId() == "scopeBarHistory" ||
getSelectedScopeButtonId() == "scopeBarAll" ||
aFolderId == PlacesUtils.bookmarks.unfiledBookmarksFolder) {
let scopeButtonId = getSelectedScopeButtonId();
if (scopeButtonId == "scopeBarDownloads" ||
scopeButtonId == "scopeBarHistory" ||
scopeButtonId == "scopeBarAll" ||
aFolderId == PlacesUtils.unfiledBookmarksFolderId) {
// Check that the target node exists in the tree's search results.
var node = null;
for (var i = 0; i < contentTree.view.rowCount; i++) {
let url, count;
if (scopeButtonId == "scopeBarDownloads") {
url = TEST_DOWNLOAD_URL;
count = 1;
}
else {
url = TEST_URL;
count = scopeButtonId == "scopeBarHistory" ? 2 : 1;
}
is(contentTree.view.rowCount, count, "Found correct number of results");
let node = null;
for (let i = 0; i < contentTree.view.rowCount; i++) {
node = contentTree.view.nodeForTreeIndex(i);
if (node.uri === TEST_URL)
if (node.uri === url)
break;
}
isnot(node, null, "At least the target node should be in the tree");
is(node.uri, TEST_URL, "URI of node should match target URL");
is(node.uri, url, "URI of node should match target URL");
}
}
else {
@ -253,10 +280,10 @@ function search(aFolderId, aSearchStr, aExpectedScopeButtonId) {
* @return true if the button is enabled, false otherwise
*/
function selectScope(aScopeButtonId) {
var doc = libraryWin.document;
var button = doc.getElementById(aScopeButtonId);
let doc = gLibrary.document;
let button = doc.getElementById(aScopeButtonId);
isnot(button, null,
"Sanity check: scope button with ID " + aScopeButtonId + "should exist");
"Sanity check: scope button with ID " + aScopeButtonId + " should exist");
// Bug 469436 may hide an inappropriate scope button instead of disabling it.
if (button.disabled || button.hidden)
return false;
@ -267,21 +294,17 @@ function selectScope(aScopeButtonId) {
/**
* test() contains window-launching boilerplate that calls this to really kick
* things off. Add functions to the testCases array, and this will call them.
*
* @param aLibraryWin
* the Places Library window
*/
function testHelper(aLibraryWin) {
libraryWin = aLibraryWin;
function onLibraryAvailable() {
testCases.forEach(function (aTest) aTest());
aLibraryWin.close();
gLibrary.close();
gLibrary = null;
// Cleanup.
PlacesUtils.tagging.untagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]);
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarks.unfiledBookmarksFolder);
PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory).removeAllPages();
finish();
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
waitForClearHistory(finish);
}
///////////////////////////////////////////////////////////////////////////////
@ -291,15 +314,19 @@ function test() {
// Sanity:
ok(PlacesUtils, "PlacesUtils in context");
// Add a visit, a bookmark and a tag.
// Add visits, a bookmark and a tag.
PlacesUtils.history.addVisit(PlacesUtils._uri(TEST_URL),
Date.now() * 1000, null,
PlacesUtils.history.TRANSITION_TYPED, false, 0);
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarks.unfiledBookmarksFolder,
PlacesUtils.history.addVisit(PlacesUtils._uri(TEST_DOWNLOAD_URL),
Date.now() * 1000, null,
PlacesUtils.history.TRANSITION_DOWNLOAD, false, 0);
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
PlacesUtils._uri(TEST_URL),
PlacesUtils.bookmarks.DEFAULT_INDEX,
"dummy");
PlacesUtils.tagging.tagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]);
openLibrary(testHelper);
gLibrary = openLibrary(onLibraryAvailable);
}

View File

@ -42,6 +42,7 @@ view.sortBy.tags.accesskey=T
searchBookmarks=Search Bookmarks
searchHistory=Search History
searchDownloads=Search Downloads
searchCurrentDefault=Search in '%S'
findInPrefix=Find in '%S'…

File diff suppressed because it is too large Load Diff

View File

@ -970,6 +970,7 @@ if test -n "$_WIN32_MSVC"; then
AC_DEFINE(HAVE_IO_H)
AC_DEFINE(HAVE_SETBUF)
AC_DEFINE(HAVE_ISATTY)
AC_DEFINE(HAVE_STDCALL)
fi
fi # COMPILE_ENVIRONMENT

View File

@ -103,9 +103,11 @@ nsDOMMessageEvent::UnrootData()
}
NS_IMETHODIMP
nsDOMMessageEvent::GetData(jsval* aData)
nsDOMMessageEvent::GetData(JSContext* aCx, jsval* aData)
{
*aData = mData;
if (!JS_WrapValue(aCx, aData))
return NS_ERROR_FAILURE;
return NS_OK;
}

View File

@ -137,6 +137,8 @@ _CHROME_FILES = \
test_bug602962.xul \
test_bug617528.xul \
window_bug617528.xul \
test_bug679494.xul \
file_bug679494.html \
$(NULL)
libs:: $(_TEST_FILES)

View File

@ -0,0 +1,8 @@
<html>
<head>
<title>Test for Bug 679494</title>
</head>
<body>
There and back again.
</body>
</html>

View File

@ -0,0 +1,37 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=67949
-->
<window title="Mozilla Bug 67949" onload="doTest();"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 67949</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<body xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=67949">Mozilla Bug 67949</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe id="contentframe" src="http://mochi.test:8888/tests/content/event/test/file_679494.html"></iframe>
</div>
</body>
<script class="testbody" type="application/javascript;version=1.8"><![CDATA[
/* Test for bug 679494 */
function doTest() {
SimpleTest.waitForExplicitFinish();
var w = document.getElementById("contentframe").contentWindow;
w.addEventListener("message", function(e) {
is("test", e.data, "We got the data without a compartment mismatch assertion!");
SimpleTest.finish();
}, false);
w.postMessage("test", "*");
}
]]></script>
</window>

View File

@ -36,6 +36,7 @@
* ***** END LICENSE BLOCK ***** */
#include "nsIDOMHTMLTableCellElement.h"
#include "nsIDOMHTMLTableRowElement.h"
#include "nsHTMLTableElement.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMEventTarget.h"
#include "nsMappedAttributes.h"
@ -44,6 +45,7 @@
#include "nsStyleConsts.h"
#include "nsPresContext.h"
#include "nsRuleData.h"
#include "nsRuleWalker.h"
#include "nsIDocument.h"
#include "celldata.h"
@ -203,19 +205,15 @@ nsHTMLTableCellElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
nsresult rv = nsGenericHTMLElement::WalkContentStyleRules(aRuleWalker);
NS_ENSURE_SUCCESS(rv, rv);
// Add style information from the mapped attributes of the table
// element. This depends on the strange behavior of the
// |MapAttributesIntoRule| in nsHTMLTableElement.cpp, which is
// technically incorrect since it's violating the nsIStyleRule
// contract. However, things are OK (except for the incorrect
// dependence on display type rather than tag) since tables and cells
// match different, less specific, rules.
nsIContent* table = GetTable();
if (table) {
rv = table->WalkContentStyleRules(aRuleWalker);
nsIContent* node = GetTable();
if (node && node->IsHTML() && node->NodeInfo()->Equals(nsGkAtoms::table)) {
nsHTMLTableElement* table = static_cast<nsHTMLTableElement*>(node);
nsMappedAttributes* tableInheritedAttributes =
table->GetAttributesMappedForCell();
if (tableInheritedAttributes)
aRuleWalker->Forward(tableInheritedAttributes);
}
return rv;
return NS_OK;
}

View File

@ -34,14 +34,13 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIDOMHTMLTableElement.h"
#include "nsHTMLTableElement.h"
#include "nsIDOMHTMLTableCaptionElem.h"
#include "nsIDOMHTMLTableSectionElem.h"
#include "nsCOMPtr.h"
#include "nsIDOMEventTarget.h"
#include "nsDOMError.h"
#include "nsContentList.h"
#include "nsMappedAttributes.h"
#include "nsGenericHTMLElement.h"
#include "nsGkAtoms.h"
#include "nsStyleConsts.h"
@ -56,59 +55,7 @@
#include "nsGenericHTMLElement.h"
#include "nsIHTMLCollection.h"
/* end for collections */
class TableRowsCollection;
class nsHTMLTableElement : public nsGenericHTMLElement,
public nsIDOMHTMLTableElement
{
public:
nsHTMLTableElement(already_AddRefed<nsINodeInfo> aNodeInfo);
virtual ~nsHTMLTableElement();
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
// nsIDOMNode
NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
// nsIDOMElement
NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
// nsIDOMHTMLElement
NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
// nsIDOMHTMLTableElement
NS_DECL_NSIDOMHTMLTABLEELEMENT
virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult);
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
virtual nsXPCClassInfo* GetClassInfo();
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLTableElement,
nsGenericHTMLElement)
already_AddRefed<nsIDOMHTMLTableSectionElement> GetTHead() {
return GetSection(nsGkAtoms::thead);
}
already_AddRefed<nsIDOMHTMLTableSectionElement> GetTFoot() {
return GetSection(nsGkAtoms::tfoot);
}
nsContentList* TBodies();
protected:
already_AddRefed<nsIDOMHTMLTableSectionElement> GetSection(nsIAtom *aTag);
nsRefPtr<nsContentList> mTBodies;
nsRefPtr<TableRowsCollection> mRows;
};
#include "nsHTMLStyleSheet.h"
/* ------------------------------ TableRowsCollection -------------------------------- */
/**
@ -367,7 +314,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Table)
nsHTMLTableElement::nsHTMLTableElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: nsGenericHTMLElement(aNodeInfo)
: nsGenericHTMLElement(aNodeInfo),
mTableInheritedAttributes(TABLE_ATTRS_DIRTY)
{
}
@ -376,6 +324,7 @@ nsHTMLTableElement::~nsHTMLTableElement()
if (mRows) {
mRows->ParentDestroyed();
}
ReleaseInheritedAttributes();
}
@ -1030,219 +979,155 @@ MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
nsCompatibility mode = presContext->CompatibilityMode();
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(TableBorder)) {
const nsStyleDisplay* readDisplay = aData->mStyleContext->GetStyleDisplay();
if (readDisplay->mDisplay != NS_STYLE_DISPLAY_TABLE_CELL) {
// cellspacing
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::cellspacing);
nsCSSValue* borderSpacing = aData->ValueForBorderSpacing();
if (value && value->Type() == nsAttrValue::eInteger) {
if (borderSpacing->GetUnit() == eCSSUnit_Null)
borderSpacing->
SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
// cellspacing
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::cellspacing);
nsCSSValue* borderSpacing = aData->ValueForBorderSpacing();
if (value && value->Type() == nsAttrValue::eInteger) {
if (borderSpacing->GetUnit() == eCSSUnit_Null) {
borderSpacing->
SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
}
else if (value && value->Type() == nsAttrValue::ePercent &&
eCompatibility_NavQuirks == mode) {
// in quirks mode, treat a % cellspacing value a pixel value.
if (borderSpacing->GetUnit() == eCSSUnit_Null)
borderSpacing->
SetFloatValue(100.0f * value->GetPercentValue(), eCSSUnit_Pixel);
}
else if (value && value->Type() == nsAttrValue::ePercent &&
eCompatibility_NavQuirks == mode) {
// in quirks mode, treat a % cellspacing value a pixel value.
if (borderSpacing->GetUnit() == eCSSUnit_Null) {
borderSpacing->
SetFloatValue(100.0f * value->GetPercentValue(), eCSSUnit_Pixel);
}
}
}
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Table)) {
const nsStyleDisplay* readDisplay = aData->mStyleContext->GetStyleDisplay();
if (readDisplay->mDisplay != NS_STYLE_DISPLAY_TABLE_CELL) {
const nsAttrValue* value;
// layout
nsCSSValue* tableLayout = aData->ValueForTableLayout();
if (tableLayout->GetUnit() == eCSSUnit_Null) {
value = aAttributes->GetAttr(nsGkAtoms::layout);
if (value && value->Type() == nsAttrValue::eEnum)
tableLayout->SetIntValue(value->GetEnumValue(), eCSSUnit_Enumerated);
}
// cols
value = aAttributes->GetAttr(nsGkAtoms::cols);
if (value) {
nsCSSValue* cols = aData->ValueForCols();
if (value->Type() == nsAttrValue::eInteger)
cols->SetIntValue(value->GetIntegerValue(), eCSSUnit_Integer);
else // COLS had no value, so it refers to all columns
cols->SetIntValue(NS_STYLE_TABLE_COLS_ALL, eCSSUnit_Enumerated);
}
const nsAttrValue* value;
// layout
nsCSSValue* tableLayout = aData->ValueForTableLayout();
if (tableLayout->GetUnit() == eCSSUnit_Null) {
value = aAttributes->GetAttr(nsGkAtoms::layout);
if (value && value->Type() == nsAttrValue::eEnum)
tableLayout->SetIntValue(value->GetEnumValue(), eCSSUnit_Enumerated);
}
// cols
value = aAttributes->GetAttr(nsGkAtoms::cols);
if (value) {
nsCSSValue* cols = aData->ValueForCols();
if (value->Type() == nsAttrValue::eInteger)
cols->SetIntValue(value->GetIntegerValue(), eCSSUnit_Integer);
else // COLS had no value, so it refers to all columns
cols->SetIntValue(NS_STYLE_TABLE_COLS_ALL, eCSSUnit_Enumerated);
}
}
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Margin)) {
const nsStyleDisplay* readDisplay = aData->mStyleContext->GetStyleDisplay();
if (readDisplay->mDisplay != NS_STYLE_DISPLAY_TABLE_CELL) {
// align; Check for enumerated type (it may be another type if
// illegal)
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
// align; Check for enumerated type (it may be another type if
// illegal)
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::align);
if (value && value->Type() == nsAttrValue::eEnum) {
if (value->GetEnumValue() == NS_STYLE_TEXT_ALIGN_CENTER ||
value->GetEnumValue() == NS_STYLE_TEXT_ALIGN_MOZ_CENTER) {
nsCSSValue* marginLeft = aData->ValueForMarginLeftValue();
if (marginLeft->GetUnit() == eCSSUnit_Null)
marginLeft->SetAutoValue();
nsCSSValue* marginRight = aData->ValueForMarginRightValue();
if (marginRight->GetUnit() == eCSSUnit_Null)
marginRight->SetAutoValue();
}
}
// hspace is mapped into left and right margin,
// vspace is mapped into top and bottom margins
// - *** Quirks Mode only ***
if (eCompatibility_NavQuirks == mode) {
value = aAttributes->GetAttr(nsGkAtoms::hspace);
if (value && value->Type() == nsAttrValue::eInteger) {
nsCSSValue* marginLeft = aData->ValueForMarginLeftValue();
if (marginLeft->GetUnit() == eCSSUnit_Null)
marginLeft->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
nsCSSValue* marginRight = aData->ValueForMarginRightValue();
if (marginRight->GetUnit() == eCSSUnit_Null)
marginRight->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
}
value = aAttributes->GetAttr(nsGkAtoms::vspace);
if (value && value->Type() == nsAttrValue::eInteger) {
nsCSSValue* marginTop = aData->ValueForMarginTop();
if (marginTop->GetUnit() == eCSSUnit_Null)
marginTop->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
nsCSSValue* marginBottom = aData->ValueForMarginBottom();
if (marginBottom->GetUnit() == eCSSUnit_Null)
marginBottom->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
}
if (value && value->Type() == nsAttrValue::eEnum) {
if (value->GetEnumValue() == NS_STYLE_TEXT_ALIGN_CENTER ||
value->GetEnumValue() == NS_STYLE_TEXT_ALIGN_MOZ_CENTER) {
nsCSSValue* marginLeft = aData->ValueForMarginLeftValue();
if (marginLeft->GetUnit() == eCSSUnit_Null)
marginLeft->SetAutoValue();
nsCSSValue* marginRight = aData->ValueForMarginRightValue();
if (marginRight->GetUnit() == eCSSUnit_Null)
marginRight->SetAutoValue();
}
}
}
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Padding)) {
const nsStyleDisplay* readDisplay = aData->mStyleContext->GetStyleDisplay();
if (readDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_CELL) {
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::cellpadding);
if (value) {
nsAttrValue::ValueType valueType = value->Type();
if (valueType == nsAttrValue::eInteger || valueType == nsAttrValue::ePercent) {
// We have cellpadding. This will override our padding values if we don't
// have any set.
nsCSSValue padVal;
if (valueType == nsAttrValue::eInteger)
padVal.SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
else {
// when we support % cellpadding in standard mode, uncomment the following
float pctVal = value->GetPercentValue();
//if (eCompatibility_NavQuirks == mode) {
// in quirks mode treat a pct cellpadding value as a pixel value
padVal.SetFloatValue(100.0f * pctVal, eCSSUnit_Pixel);
//}
//else {
// padVal.SetPercentValue(pctVal);
//}
}
nsCSSValue* paddingLeft = aData->ValueForPaddingLeftValue();
if (paddingLeft->GetUnit() == eCSSUnit_Null)
*paddingLeft = padVal;
nsCSSValue* paddingRight = aData->ValueForPaddingRightValue();
if (paddingRight->GetUnit() == eCSSUnit_Null)
*paddingRight = padVal;
nsCSSValue* paddingTop = aData->ValueForPaddingTop();
if (paddingTop->GetUnit() == eCSSUnit_Null)
*paddingTop = padVal;
nsCSSValue* paddingBottom = aData->ValueForPaddingBottom();
if (paddingBottom->GetUnit() == eCSSUnit_Null)
*paddingBottom = padVal;
}
// hspace is mapped into left and right margin,
// vspace is mapped into top and bottom margins
// - *** Quirks Mode only ***
if (eCompatibility_NavQuirks == mode) {
value = aAttributes->GetAttr(nsGkAtoms::hspace);
if (value && value->Type() == nsAttrValue::eInteger) {
nsCSSValue* marginLeft = aData->ValueForMarginLeftValue();
if (marginLeft->GetUnit() == eCSSUnit_Null)
marginLeft->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
nsCSSValue* marginRight = aData->ValueForMarginRightValue();
if (marginRight->GetUnit() == eCSSUnit_Null)
marginRight->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
}
value = aAttributes->GetAttr(nsGkAtoms::vspace);
if (value && value->Type() == nsAttrValue::eInteger) {
nsCSSValue* marginTop = aData->ValueForMarginTop();
if (marginTop->GetUnit() == eCSSUnit_Null)
marginTop->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
nsCSSValue* marginBottom = aData->ValueForMarginBottom();
if (marginBottom->GetUnit() == eCSSUnit_Null)
marginBottom->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
}
}
}
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Position)) {
const nsStyleDisplay* readDisplay = aData->mStyleContext->GetStyleDisplay();
if (readDisplay->mDisplay != NS_STYLE_DISPLAY_TABLE_CELL) {
// width: value
nsCSSValue* width = aData->ValueForWidth();
if (width->GetUnit() == eCSSUnit_Null) {
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
if (value && value->Type() == nsAttrValue::eInteger)
width->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
else if (value && value->Type() == nsAttrValue::ePercent)
width->SetPercentValue(value->GetPercentValue());
}
// height: value
nsCSSValue* height = aData->ValueForHeight();
if (height->GetUnit() == eCSSUnit_Null) {
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::height);
if (value && value->Type() == nsAttrValue::eInteger)
height->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
else if (value && value->Type() == nsAttrValue::ePercent)
height->SetPercentValue(value->GetPercentValue());
}
// width: value
nsCSSValue* width = aData->ValueForWidth();
if (width->GetUnit() == eCSSUnit_Null) {
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
if (value && value->Type() == nsAttrValue::eInteger)
width->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
else if (value && value->Type() == nsAttrValue::ePercent)
width->SetPercentValue(value->GetPercentValue());
}
// height: value
nsCSSValue* height = aData->ValueForHeight();
if (height->GetUnit() == eCSSUnit_Null) {
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::height);
if (value && value->Type() == nsAttrValue::eInteger)
height->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
else if (value && value->Type() == nsAttrValue::ePercent)
height->SetPercentValue(value->GetPercentValue());
}
}
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Visibility)) {
const nsStyleDisplay* readDisplay = aData->mStyleContext->GetStyleDisplay();
if (readDisplay->mDisplay != NS_STYLE_DISPLAY_TABLE_CELL)
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
}
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Border)) {
const nsStyleDisplay* readDisplay = aData->mStyleContext->GetStyleDisplay();
if (readDisplay->mDisplay != NS_STYLE_DISPLAY_TABLE_CELL) {
// bordercolor
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::bordercolor);
nscolor color;
if (value && presContext->UseDocumentColors() &&
value->GetColorValue(color)) {
nsCSSValue* borderLeftColor = aData->ValueForBorderLeftColorValue();
if (borderLeftColor->GetUnit() == eCSSUnit_Null)
borderLeftColor->SetColorValue(color);
nsCSSValue* borderRightColor = aData->ValueForBorderRightColorValue();
if (borderRightColor->GetUnit() == eCSSUnit_Null)
borderRightColor->SetColorValue(color);
nsCSSValue* borderTopColor = aData->ValueForBorderTopColor();
if (borderTopColor->GetUnit() == eCSSUnit_Null)
borderTopColor->SetColorValue(color);
nsCSSValue* borderBottomColor = aData->ValueForBorderBottomColor();
if (borderBottomColor->GetUnit() == eCSSUnit_Null)
borderBottomColor->SetColorValue(color);
}
// bordercolor
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::bordercolor);
nscolor color;
if (value && presContext->UseDocumentColors() &&
value->GetColorValue(color)) {
nsCSSValue* borderLeftColor = aData->ValueForBorderLeftColorValue();
if (borderLeftColor->GetUnit() == eCSSUnit_Null)
borderLeftColor->SetColorValue(color);
nsCSSValue* borderRightColor = aData->ValueForBorderRightColorValue();
if (borderRightColor->GetUnit() == eCSSUnit_Null)
borderRightColor->SetColorValue(color);
nsCSSValue* borderTopColor = aData->ValueForBorderTopColor();
if (borderTopColor->GetUnit() == eCSSUnit_Null)
borderTopColor->SetColorValue(color);
nsCSSValue* borderBottomColor = aData->ValueForBorderBottomColor();
if (borderBottomColor->GetUnit() == eCSSUnit_Null)
borderBottomColor->SetColorValue(color);
}
// border
const nsAttrValue* borderValue = aAttributes->GetAttr(nsGkAtoms::border);
if (borderValue) {
// border = 1 pixel default
PRInt32 borderThickness = 1;
// border
const nsAttrValue* borderValue = aAttributes->GetAttr(nsGkAtoms::border);
if (borderValue) {
// border = 1 pixel default
PRInt32 borderThickness = 1;
if (borderValue->Type() == nsAttrValue::eInteger)
borderThickness = borderValue->GetIntegerValue();
if (borderValue->Type() == nsAttrValue::eInteger)
borderThickness = borderValue->GetIntegerValue();
// by default, set all border sides to the specified width
nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidthValue();
if (borderLeftWidth->GetUnit() == eCSSUnit_Null)
borderLeftWidth->SetFloatValue((float)borderThickness, eCSSUnit_Pixel);
nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidthValue();
if (borderRightWidth->GetUnit() == eCSSUnit_Null)
borderRightWidth->SetFloatValue((float)borderThickness, eCSSUnit_Pixel);
nsCSSValue* borderTopWidth = aData->ValueForBorderTopWidth();
if (borderTopWidth->GetUnit() == eCSSUnit_Null)
borderTopWidth->SetFloatValue((float)borderThickness, eCSSUnit_Pixel);
nsCSSValue* borderBottomWidth = aData->ValueForBorderBottomWidth();
if (borderBottomWidth->GetUnit() == eCSSUnit_Null)
borderBottomWidth->SetFloatValue((float)borderThickness, eCSSUnit_Pixel);
}
// by default, set all border sides to the specified width
nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidthValue();
if (borderLeftWidth->GetUnit() == eCSSUnit_Null)
borderLeftWidth->SetFloatValue((float)borderThickness, eCSSUnit_Pixel);
nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidthValue();
if (borderRightWidth->GetUnit() == eCSSUnit_Null)
borderRightWidth->SetFloatValue((float)borderThickness, eCSSUnit_Pixel);
nsCSSValue* borderTopWidth = aData->ValueForBorderTopWidth();
if (borderTopWidth->GetUnit() == eCSSUnit_Null)
borderTopWidth->SetFloatValue((float)borderThickness, eCSSUnit_Pixel);
nsCSSValue* borderBottomWidth = aData->ValueForBorderBottomWidth();
if (borderBottomWidth->GetUnit() == eCSSUnit_Null)
borderBottomWidth->SetFloatValue((float)borderThickness, eCSSUnit_Pixel);
}
}
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Background)) {
const nsStyleDisplay* readDisplay = aData->mStyleContext->GetStyleDisplay();
if (readDisplay->mDisplay != NS_STYLE_DISPLAY_TABLE_CELL)
nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aData);
}
nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aData);
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
}
NS_IMETHODIMP_(PRBool)
@ -1279,3 +1164,144 @@ nsHTMLTableElement::GetAttributeMappingFunction() const
{
return &MapAttributesIntoRule;
}
static void
MapInheritedTableAttributesIntoRule(const nsMappedAttributes* aAttributes,
nsRuleData* aData)
{
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Padding)) {
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::cellpadding);
if (value) {
nsAttrValue::ValueType valueType = value->Type();
if (valueType == nsAttrValue::eInteger ||
valueType == nsAttrValue::ePercent) {
// We have cellpadding. This will override our padding values if we
// don't have any set.
nsCSSValue padVal;
if (valueType == nsAttrValue::eInteger)
padVal.SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
else {
// when we support % cellpadding in standard mode, uncomment the
// following
float pctVal = value->GetPercentValue();
//if (eCompatibility_NavQuirks == mode) {
// in quirks mode treat a pct cellpadding value as a pixel value
padVal.SetFloatValue(100.0f * pctVal, eCSSUnit_Pixel);
//}
//else {
// padVal.SetPercentValue(pctVal);
//}
}
nsCSSValue* paddingLeft = aData->ValueForPaddingLeftValue();
if (paddingLeft->GetUnit() == eCSSUnit_Null)
*paddingLeft = padVal;
nsCSSValue* paddingRight = aData->ValueForPaddingRightValue();
if (paddingRight->GetUnit() == eCSSUnit_Null)
*paddingRight = padVal;
nsCSSValue* paddingTop = aData->ValueForPaddingTop();
if (paddingTop->GetUnit() == eCSSUnit_Null)
*paddingTop = padVal;
nsCSSValue* paddingBottom = aData->ValueForPaddingBottom();
if (paddingBottom->GetUnit() == eCSSUnit_Null)
*paddingBottom = padVal;
}
}
}
}
nsMappedAttributes*
nsHTMLTableElement::GetAttributesMappedForCell()
{
if (mTableInheritedAttributes) {
if (mTableInheritedAttributes == TABLE_ATTRS_DIRTY)
BuildInheritedAttributes();
if (mTableInheritedAttributes != TABLE_ATTRS_DIRTY)
return mTableInheritedAttributes;
}
return nsnull;
}
void
nsHTMLTableElement::BuildInheritedAttributes()
{
NS_ASSERTION(mTableInheritedAttributes == TABLE_ATTRS_DIRTY,
"potential leak, plus waste of work");
nsIDocument *document = GetCurrentDoc();
nsHTMLStyleSheet* sheet = document ?
document->GetAttributeStyleSheet() : nsnull;
nsRefPtr<nsMappedAttributes> newAttrs;
if (sheet) {
const nsAttrValue* value = mAttrsAndChildren.GetAttr(nsGkAtoms::cellpadding);
if (value) {
nsRefPtr<nsMappedAttributes> modifiableMapped = new
nsMappedAttributes(sheet, MapInheritedTableAttributesIntoRule);
if (modifiableMapped) {
nsAttrValue val(*value);
modifiableMapped->SetAndTakeAttr(nsGkAtoms::cellpadding, val);
}
newAttrs = sheet->UniqueMappedAttributes(modifiableMapped);
NS_ASSERTION(newAttrs, "out of memory, but handling gracefully");
if (newAttrs != modifiableMapped) {
// Reset the stylesheet of modifiableMapped so that it doesn't
// spend time trying to remove itself from the hash. There is no
// risk that modifiableMapped is in the hash since we created
// it ourselves and it didn't come from the stylesheet (in which
// case it would not have been modifiable).
modifiableMapped->DropStyleSheetReference();
}
}
mTableInheritedAttributes = newAttrs;
NS_IF_ADDREF(mTableInheritedAttributes);
}
}
nsresult
nsHTMLTableElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers)
{
ReleaseInheritedAttributes();
return nsGenericHTMLElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
}
void
nsHTMLTableElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
{
ReleaseInheritedAttributes();
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}
nsresult
nsHTMLTableElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
nsIAtom* aPrefix, const nsAString& aValue,
PRBool aNotify)
{
PRBool isCellPadding = (aAttribute == nsGkAtoms::cellpadding);
if (isCellPadding) {
ReleaseInheritedAttributes();
}
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aAttribute,
aPrefix, aValue, aNotify);
if (isCellPadding) {
BuildInheritedAttributes();
}
return rv;
}
nsresult
nsHTMLTableElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
PRBool aNotify)
{
PRBool isCellPadding = (aAttribute == nsGkAtoms::cellpadding);
if (isCellPadding) {
ReleaseInheritedAttributes();
}
return nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
}

View File

@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIDOMHTMLTableElement.h"
#include "nsGenericHTMLElement.h"
#include "nsMappedAttributes.h"
#define TABLE_ATTRS_DIRTY ((nsMappedAttributes*)0x1)
class TableRowsCollection;
class nsHTMLTableElement : public nsGenericHTMLElement,
public nsIDOMHTMLTableElement
{
public:
nsHTMLTableElement(already_AddRefed<nsINodeInfo> aNodeInfo);
virtual ~nsHTMLTableElement();
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
// nsIDOMNode
NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
// nsIDOMElement
NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
// nsIDOMHTMLElement
NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
// nsIDOMHTMLTableElement
NS_DECL_NSIDOMHTMLTABLEELEMENT
virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult);
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
virtual nsXPCClassInfo* GetClassInfo();
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers);
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
PRBool aNullParent = PR_TRUE);
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom *aName,
nsIAtom *aPrefix, const nsAString &aValue,
PRBool aNotify);
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
PRBool aNotify);
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLTableElement,
nsGenericHTMLElement)
nsMappedAttributes* GetAttributesMappedForCell();
already_AddRefed<nsIDOMHTMLTableSectionElement> GetTHead() {
return GetSection(nsGkAtoms::thead);
}
already_AddRefed<nsIDOMHTMLTableSectionElement> GetTFoot() {
return GetSection(nsGkAtoms::tfoot);
}
nsContentList* TBodies();
protected:
already_AddRefed<nsIDOMHTMLTableSectionElement> GetSection(nsIAtom *aTag);
nsRefPtr<nsContentList> mTBodies;
nsRefPtr<TableRowsCollection> mRows;
// Sentinel value of TABLE_ATTRS_DIRTY indicates that this is dirty and needs
// to be recalculated.
nsMappedAttributes *mTableInheritedAttributes;
void BuildInheritedAttributes();
void ReleaseInheritedAttributes() {
if (mTableInheritedAttributes &&
mTableInheritedAttributes != TABLE_ATTRS_DIRTY)
NS_RELEASE(mTableInheritedAttributes);
mTableInheritedAttributes = TABLE_ATTRS_DIRTY;
}
};

View File

@ -287,6 +287,20 @@ NS_IMETHODIMP nsSVGFE::GetResult(nsIDOMSVGAnimatedString * *aResult)
return GetResultImageName().ToDOMAnimatedString(aResult, this);
}
//----------------------------------------------------------------------
// nsIContent methods
NS_IMETHODIMP_(PRBool)
nsSVGFE::IsAttributeMapped(const nsIAtom* name) const
{
static const MappedAttributeEntry* const map[] = {
sFiltersMap
};
return FindAttributeDependence(name, map, NS_ARRAY_LENGTH(map)) ||
nsSVGFEBase::IsAttributeMapped(name);
}
//----------------------------------------------------------------------
// nsSVGElement methods
@ -2751,8 +2765,7 @@ NS_IMETHODIMP_(PRBool)
nsSVGFEFloodElement::IsAttributeMapped(const nsIAtom* name) const
{
static const MappedAttributeEntry* const map[] = {
sFEFloodMap,
sFiltersMap
sFEFloodMap
};
return FindAttributeDependence(name, map, NS_ARRAY_LENGTH(map)) ||

View File

@ -147,6 +147,9 @@ public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES
// nsIContent interface
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
virtual nsSVGString& GetResultImageName() = 0;
// Return a list of all image names used as sources. Default is to
// return no sources.

View File

@ -11127,13 +11127,6 @@ nsNavigator::JavaEnabled(PRBool *aReturn)
return NS_OK;
}
NS_IMETHODIMP
nsNavigator::TaintEnabled(PRBool *aReturn)
{
*aReturn = PR_FALSE;
return NS_OK;
}
void
nsNavigator::LoadingNewDocument()
{

View File

@ -39,7 +39,7 @@
#include "domstubs.idl"
[scriptable, uuid(d7758ece-f088-4701-9ae4-1450192dca38)]
[scriptable, uuid(5dd9f1f5-3347-4945-a350-4eedeb97d24c)]
interface nsIDOMNavigator : nsISupports
{
readonly attribute DOMString appCodeName;
@ -60,6 +60,5 @@ interface nsIDOMNavigator : nsISupports
readonly attribute DOMString buildID;
boolean javaEnabled();
boolean taintEnabled();
};

View File

@ -51,6 +51,7 @@ interface nsIDOMMessageEvent : nsIDOMEvent
/**
* Custom string data associated with this event.
*/
[implicit_jscontext]
readonly attribute jsval data;
/**

View File

@ -74,7 +74,6 @@ interface nsIDOMSVGSVGElement
nsIDOMSVGFitToViewBox,
nsIDOMSVGZoomAndPan,
events::nsIDOMEventTarget,
css::nsIDOMDocumentCSS
*/
{
readonly attribute nsIDOMSVGAnimatedLength x;

View File

@ -129,6 +129,7 @@ PluginModuleChild::PluginModuleChild()
memset(&mFunctions, 0, sizeof(mFunctions));
memset(&mSavedData, 0, sizeof(mSavedData));
gInstance = this;
mUserAgent.SetIsVoid(PR_TRUE);
#ifdef XP_MACOSX
mac_plugin_interposing::child::SetUpCocoaInterposing();
#endif
@ -729,7 +730,7 @@ PluginModuleChild::CleanUp()
const char*
PluginModuleChild::GetUserAgent()
{
if (!CallNPN_UserAgent(&mUserAgent))
if (mUserAgent.IsVoid() && !CallNPN_UserAgent(&mUserAgent))
return NULL;
return NullableStringGet(mUserAgent);

View File

@ -70,8 +70,8 @@ using mozilla::dom::StorageChild;
#include "nsIPrivateBrowsingService.h"
#include "nsDOMString.h"
#include "nsNetCID.h"
#include "nsIProxyObjectManager.h"
#include "mozilla/Preferences.h"
#include "nsThreadUtils.h"
using namespace mozilla;
@ -1898,6 +1898,34 @@ nsDOMStorage2::StorageType()
return nsPIDOMStorage::Unknown;
}
namespace {
class StorageNotifierRunnable : public nsRunnable
{
public:
StorageNotifierRunnable(nsISupports* aSubject)
: mSubject(aSubject)
{ }
NS_DECL_NSIRUNNABLE
private:
nsCOMPtr<nsISupports> mSubject;
};
NS_IMETHODIMP
StorageNotifierRunnable::Run()
{
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (observerService) {
observerService->NotifyObservers(mSubject, "dom-storage2-changed", nsnull);
}
return NS_OK;
}
} // anonymous namespace
void
nsDOMStorage2::BroadcastChangeNotification(const nsSubstring &aKey,
const nsSubstring &aOldValue,
@ -1917,26 +1945,8 @@ nsDOMStorage2::BroadcastChangeNotification(const nsSubstring &aKey,
return;
}
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (!observerService) {
return;
}
nsCOMPtr<nsIObserverService> observerServiceProxy;
rv = NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
NS_GET_IID(nsIObserverService),
observerService,
NS_PROXY_ASYNC | NS_PROXY_ALWAYS,
getter_AddRefs(observerServiceProxy));
if (NS_FAILED(rv)) {
return;
}
// Fire off a notification that a storage object changed.
observerServiceProxy->NotifyObservers(event,
"dom-storage2-changed",
nsnull);
nsRefPtr<StorageNotifierRunnable> r = new StorageNotifierRunnable(event);
NS_DispatchToMainThread(r);
}
NS_IMETHODIMP

View File

@ -53,9 +53,11 @@ include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
ifndef MOZ_ENABLE_QTMOBILITY
CPPSRCS = \
nsDeviceMotionSystem.cpp \
$(NULL)
endif
ifdef MOZ_MAEMO_LIBLOCATION
CPPSRCS += MaemoLocationProvider.cpp
@ -69,9 +71,10 @@ CPPSRCS += nsHapticFeedback.cpp
LOCAL_INCLUDES += $(MOZ_DBUS_CFLAGS) \
$(NULL)
ifdef MOZ_ENABLE_QTMOBILITY
MOCSRCS += moc_QTMLocationProvider.cpp
MOCSRCS += moc_QTMLocationProvider.cpp moc_nsQTMDeviceMotionSystem.cpp
CPPSRCS += $(MOCSRCS) \
QTMLocationProvider.cpp \
nsQTMDeviceMotionSystem.cpp \
$(NULL)
LOCAL_INCLUDES += $(MOZ_QT_CFLAGS) \
-I$(topsrcdir)/dom/src/geolocation \

View File

@ -0,0 +1,126 @@
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Oleg Romashin <romaxa@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "mozilla/dom/ContentChild.h"
#include "nsQTMDeviceMotionSystem.h"
#include <QObject>
#include <QtSensors/QAccelerometer>
#include <QtSensors/QRotationSensor>
#include "nsXULAppAPI.h"
using namespace mozilla;
using namespace QtMobility;
bool
MozQAccelerometerSensorFilter::filter(QAccelerometerReading* reading)
{
mSystem.DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION,
-reading->x(),
-reading->y(),
-reading->z());
return true;
}
bool
MozQRotationSensorFilter::filter(QRotationReading* reading)
{
// QRotationReading class:
// - the rotation around z axis (alpha) is given as z in QRotationReading;
// - the rotation around x axis (beta) is given as x in QRotationReading;
// - the rotation around y axis (gamma) is given as y in QRotationReading;
// See: http://doc.qt.nokia.com/qtmobility-1.0/qrotationreading.html
mSystem.DeviceMotionChanged(nsIDeviceMotionData::TYPE_ORIENTATION,
reading->z(),
reading->x(),
reading->y());
return true;
}
nsDeviceMotionSystem::nsDeviceMotionSystem()
{
if (XRE_GetProcessType() == GeckoProcessType_Default) {
mAccelerometer = new QAccelerometer();
mAccelerometerFilter = new MozQAccelerometerSensorFilter(*this);
mAccelerometer->addFilter(mAccelerometerFilter);
mRotation = new QRotationSensor();
mRotationFilter = new MozQRotationSensorFilter(*this);
mRotation->addFilter(mRotationFilter);
}
}
nsDeviceMotionSystem::~nsDeviceMotionSystem()
{
if (XRE_GetProcessType() == GeckoProcessType_Default) {
mAccelerometer->removeFilter(mAccelerometerFilter);
mAccelerometer->stop();
mRotation->removeFilter(mRotationFilter);
mRotation->stop();
delete mAccelerometer;
delete mAccelerometerFilter;
delete mRotation;
delete mRotationFilter;
}
}
void nsDeviceMotionSystem::Startup()
{
if (XRE_GetProcessType() == GeckoProcessType_Default) {
mAccelerometer->start();
if (!mAccelerometer->isActive()) {
NS_WARNING("AccelerometerSensor didn't start!");
}
mRotation->start();
if (!mRotation->isActive()) {
NS_WARNING("RotationSensor didn't start!");
}
}
else
mozilla::dom::ContentChild::GetSingleton()->
SendAddDeviceMotionListener();
}
void nsDeviceMotionSystem::Shutdown()
{
if (XRE_GetProcessType() == GeckoProcessType_Default) {
mAccelerometer->stop();
mRotation->stop();
}
else
mozilla::dom::ContentChild::GetSingleton()->
SendRemoveDeviceMotionListener();
}

View File

@ -0,0 +1,100 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Oleg Romashin <romaxa@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsDeviceMotionSystem_h
#define nsDeviceMotionSystem_h
#include <QObject>
#include <QtSensors/QAccelerometer>
#include <QtSensors/QRotationSensor>
#include "nsDeviceMotion.h"
using namespace QtMobility;
class MozQAccelerometerSensorFilter;
class MozQRotationSensorFilter;
class nsDeviceMotionSystem : public nsDeviceMotion
{
public:
nsDeviceMotionSystem();
virtual ~nsDeviceMotionSystem();
private:
virtual void Startup();
virtual void Shutdown();
QtMobility::QAccelerometer* mAccelerometer;
MozQAccelerometerSensorFilter* mAccelerometerFilter;
QtMobility::QRotationSensor* mRotation;
MozQRotationSensorFilter* mRotationFilter;
};
class MozQAccelerometerSensorFilter : public QObject, public QAccelerometerFilter
{
Q_OBJECT
public:
MozQAccelerometerSensorFilter(nsDeviceMotionSystem& aSystem) : mSystem(aSystem) {}
virtual ~MozQAccelerometerSensorFilter(){}
virtual bool filter(QAccelerometerReading* reading);
private:
bool filter(QSensorReading *reading) { return filter(static_cast<QAccelerometerReading*>(reading)); }
nsDeviceMotionSystem& mSystem;
};
class MozQRotationSensorFilter : public QObject, public QRotationFilter
{
Q_OBJECT
public:
MozQRotationSensorFilter(nsDeviceMotionSystem& aSystem) : mSystem(aSystem) {}
virtual ~MozQRotationSensorFilter(){}
virtual bool filter(QRotationReading* reading);
private:
bool filter(QSensorReading *reading) { return filter(static_cast<QRotationReading*>(reading)); }
nsDeviceMotionSystem& mSystem;
};
#endif /* nsDeviceMotionSystem_h */

View File

@ -6789,6 +6789,12 @@ nsHTMLEditRules::ReturnInListItem(nsISelection *aSelection,
NS_ENSURE_SUCCESS(res, res);
if (isEmpty && (rootNode != list) && mReturnInEmptyLIKillsList)
{
// get the list offset now -- before we might eventually split the list
nsCOMPtr<nsIDOMNode> listparent;
PRInt32 offset;
res = nsEditor::GetNodeLocation(list, address_of(listparent), &offset);
NS_ENSURE_SUCCESS(res, res);
// are we the last list item in the list?
PRBool bIsLast;
res = mHTMLEditor->IsLastEditableChild(aListItem, &bIsLast);
@ -6802,10 +6808,6 @@ nsHTMLEditRules::ReturnInListItem(nsISelection *aSelection,
}
// are we in a sublist?
nsCOMPtr<nsIDOMNode> listparent;
PRInt32 offset;
res = nsEditor::GetNodeLocation(list, address_of(listparent), &offset);
NS_ENSURE_SUCCESS(res, res);
if (nsHTMLEditUtils::IsList(listparent)) //in a sublist
{
// if so, move this list item out of this list and into the grandparent list

View File

@ -13,29 +13,57 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=674861
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=674861">Mozilla Bug 674861</a>
<p id="display"></p>
<div id="content">
<h2> Bullet List </h2>
<ul contenteditable>
<li> item 1 </li>
<li> item 2 </li>
<li> item 3 </li>
</ul>
<section id="test1">
<h2> Editable Bullet List </h2>
<ul contenteditable>
<li> item A </li>
<li> item B </li>
<li> item C </li>
</ul>
<h2> Ordered List </h2>
<ol contenteditable>
<li> item 1 </li>
<li> item 2 </li>
<li> item 3 </li>
</ol>
<h2> Editable Ordered List </h2>
<ol contenteditable>
<li> item A </li>
<li> item B </li>
<li> item C </li>
</ol>
<h2> Definition List </h2>
<dl contenteditable>
<dt> term 1 </dt>
<dd> definition 1 </dd>
<dt> term 2 </dt>
<dd> definition 2 </dd>
<dt> term 3 </dt>
<dd> definition 3 </dd>
</dl>
<h2> Editable Definition List </h2>
<dl contenteditable>
<dt> term A </dt>
<dd> definition A </dd>
<dt> term B </dt>
<dd> definition B </dd>
<dt> term C </dt>
<dd> definition C </dd>
</dl>
</section>
<section id="test2" contenteditable>
<h2> Bullet List In Editable Section </h2>
<ul>
<li> item A </li>
<li> item B </li>
<li> item C </li>
</ul>
<h2> Ordered List In Editable Section </h2>
<ol>
<li> item A </li>
<li> item B </li>
<li> item C </li>
</ol>
<h2> Definition List In Editable Section </h2>
<dl>
<dt> term A </dt>
<dd> definition A </dd>
<dt> term B </dt>
<dd> definition B </dd>
<dt> term C </dt>
<dd> definition C </dd>
</dl>
</section>
</div>
<pre id="test">
@ -82,34 +110,72 @@ function try2split(element, caretPos) {
}
function runTests() {
const ul = document.querySelector("#content ul");
const ol = document.querySelector("#content ol");
const dl = document.querySelector("#content dl");
const test1 = document.getElementById("test1");
const test2 = document.getElementById("test2");
// -----------------------------------------------------------------------
// #test1: editable lists should NOT be splittable
// -----------------------------------------------------------------------
const ul = test1.querySelector("ul");
const ol = test1.querySelector("ol");
const dl = test1.querySelector("dl");
// bullet list
ul.focus();
try2split(ul.querySelector("li"), CARET_END);
is(document.querySelectorAll("#content ul").length, 1,
"The <ul> list should not be splittable.");
is(test1.querySelectorAll("ul").length, 1,
"The <ul contenteditable> list should not be splittable.");
is(ul.querySelectorAll("li").length, 5,
"Two new <li> elements should have been created.");
// ordered list
ol.focus();
try2split(ol.querySelector("li"), CARET_END);
is(document.querySelectorAll("#content ol").length, 1,
"The <ol> list should not be splittable.");
is(test1.querySelectorAll("ol").length, 1,
"The <ol contenteditable> list should not be splittable.");
is(ol.querySelectorAll("li").length, 5,
"Two new <li> elements should have been created.");
// definition list
dl.focus();
try2split(dl.querySelector("dd"), CARET_END);
is(document.querySelectorAll("#content dl").length, 1,
"The <dl> list should not be splittable.");
is(test1.querySelectorAll("dl").length, 1,
"The <dl contenteditable> list should not be splittable.");
is(dl.querySelectorAll("dt").length, 5,
"Two new <dt> elements should have been created.");
// -----------------------------------------------------------------------
// #test2: lists in editable blocks should be splittable
// -----------------------------------------------------------------------
test2.focus();
// bullet list
try2split(test2.querySelector("ul li"), CARET_END);
is(test2.querySelectorAll("ul").length, 2,
"The <ul> list should have been splitted.");
is(test2.querySelectorAll("ul li").length, 3,
"No new <li> element should have been created.");
is(test2.querySelectorAll("ul+p").length, 1,
"A new paragraph should have been created.");
// ordered list
try2split(test2.querySelector("ol li"), CARET_END);
is(test2.querySelectorAll("ol").length, 2,
"The <ol> list should have been splitted.");
is(test2.querySelectorAll("ol li").length, 3,
"No new <li> element should have been created.");
is(test2.querySelectorAll("ol+p").length, 1,
"A new paragraph should have been created.");
// definition list
try2split(test2.querySelector("dl dd"), CARET_END);
is(test2.querySelectorAll("dl").length, 2,
"The <dl> list should have been splitted.");
is(test2.querySelectorAll("dt").length, 3,
"No new <dt> element should have been created.");
is(test2.querySelectorAll("dl+p").length, 1,
"A new paragraph should have been created.");
// done
SimpleTest.finish();
}

View File

@ -168,6 +168,7 @@ pixman-image-transform.patch: Reset the transform on pixman images when using th
fix-cairo-surface-wrapper-flush-build-warning.patch: Ensures that _cairo_surface_wrapper_flush always returns a status, to silence the build warning
fixup-unbounded.patch: Hack to work around bad assumption.
==== pixman patches ====
pixman-android-cpu-detect.patch: Add CPU detection support for Android, where we can't reliably access /proc/self/auxv.

View File

@ -1802,7 +1802,7 @@ _cairo_image_surface_fixup_unbounded_boxes (cairo_image_surface_t *dst,
struct _cairo_boxes_chunk *chunk;
int i;
if (boxes->num_boxes <= 1 && clip_region == NULL)
if (boxes->num_boxes < 1 && clip_region == NULL)
return _cairo_image_surface_fixup_unbounded (dst, extents, NULL);
_cairo_boxes_init (&clear);

View File

@ -0,0 +1,22 @@
diff --git a/gfx/cairo/cairo/src/cairo-image-surface.c b/gfx/cairo/cairo/src/cairo-image-surface.c
--- a/gfx/cairo/cairo/src/cairo-image-surface.c
+++ b/gfx/cairo/cairo/src/cairo-image-surface.c
@@ -1797,17 +1797,17 @@ _cairo_image_surface_fixup_unbounded_box
cairo_boxes_t *boxes)
{
cairo_boxes_t clear;
cairo_box_t box;
cairo_status_t status;
struct _cairo_boxes_chunk *chunk;
int i;
- if (boxes->num_boxes <= 1 && clip_region == NULL)
+ if (boxes->num_boxes < 1 && clip_region == NULL)
return _cairo_image_surface_fixup_unbounded (dst, extents, NULL);
_cairo_boxes_init (&clear);
box.p1.x = _cairo_fixed_from_int (extents->unbounded.x + extents->unbounded.width);
box.p1.y = _cairo_fixed_from_int (extents->unbounded.y);
box.p2.x = _cairo_fixed_from_int (extents->unbounded.x);
box.p2.y = _cairo_fixed_from_int (extents->unbounded.y + extents->unbounded.height);

View File

@ -191,40 +191,96 @@ ThebesLayerBufferOGL::RenderTo(const nsIntPoint& aOffset,
renderRegion = &visibleRegion;
}
mTexImage->BeginTileIteration();
if (mTexImageOnWhite) {
mTexImageOnWhite->BeginTileIteration();
NS_ASSERTION(mTexImageOnWhite->GetTileRect() == mTexImage->GetTileRect(), "component alpha textures should be the same size.");
}
nsIntRegion region(*renderRegion);
nsIntPoint origin = GetOriginOffset();
region.MoveBy(-origin); // translate into TexImage space, buffer origin might not be at texture (0,0)
// Figure out the intersecting draw region
nsIntSize texSize = mTexImage->GetSize();
nsIntRect textureRect = nsIntRect(0, 0, texSize.width, texSize.height);
textureRect.MoveBy(region.GetBounds().TopLeft());
nsIntRegion subregion;
subregion.And(region, textureRect);
if (subregion.IsEmpty()) // Region is empty, nothing to draw
return;
nsIntRegion screenRects;
nsIntRegion regionRects;
// Collect texture/screen coordinates for drawing
nsIntRegionRectIterator iter(subregion);
while (const nsIntRect* iterRect = iter.Next()) {
nsIntRect regionRect = *iterRect;
nsIntRect screenRect = regionRect;
screenRect.MoveBy(origin);
screenRects.Or(screenRects, screenRect);
regionRects.Or(regionRects, regionRect);
}
mTexImage->BeginTileIteration();
if (mTexImageOnWhite) {
NS_ASSERTION(mTexImage->GetTileCount() == mTexImageOnWhite->GetTileCount(),
"Tile count mismatch on component alpha texture");
mTexImageOnWhite->BeginTileIteration();
}
bool usingTiles = (mTexImage->GetTileCount() > 1);
do {
nsIntRect textureRect = mTexImage->GetTileRect();
textureRect.MoveBy(region.GetBounds().x, region.GetBounds().y);
nsIntRegion subregion(region);
subregion.And(region, textureRect); // region this texture is visible in
if (subregion.IsEmpty()) {
continue;
if (mTexImageOnWhite) {
NS_ASSERTION(mTexImageOnWhite->GetTileRect() == mTexImage->GetTileRect(), "component alpha textures should be the same size.");
}
nsIntRect tileRect = mTexImage->GetTileRect();
// Bind textures.
TextureImage::ScopedBindTexture texBind(mTexImage, LOCAL_GL_TEXTURE0);
TextureImage::ScopedBindTexture texOnWhiteBind(mTexImageOnWhite, LOCAL_GL_TEXTURE1);
nsIntRegionRectIterator iter(subregion);
while (const nsIntRect *iterRect = iter.Next()) {
nsIntRect regionRect = *iterRect; // one rectangle of this texture's region
// translate into the correct place for this texture sub-region
nsIntRect screenRect = regionRect;
screenRect.MoveBy(origin);
program->SetLayerQuadRect(screenRect);
// Draw texture. If we're using tiles, we do repeating manually, as texture
// repeat would cause each individual tile to repeat instead of the
// compound texture as a whole. This involves drawing at most 4 sections,
// 2 for each axis that has texture repeat.
for (int y = 0; y < (usingTiles ? 2 : 1); y++) {
for (int x = 0; x < (usingTiles ? 2 : 1); x++) {
nsIntRect currentTileRect(tileRect);
currentTileRect.MoveBy(x * texSize.width, y * texSize.height);
regionRect.MoveBy(-mTexImage->GetTileRect().TopLeft()); // get region of tile
aManager->BindAndDrawQuadWithTextureRect(program, regionRect,
textureRect.Size(),
mTexImage->GetWrapMode());
nsIntRegionRectIterator screenIter(screenRects);
nsIntRegionRectIterator regionIter(regionRects);
const nsIntRect* screenRect;
const nsIntRect* regionRect;
while ((screenRect = screenIter.Next()) &&
(regionRect = regionIter.Next())) {
nsIntRect tileScreenRect(*screenRect);
nsIntRect tileRegionRect(*regionRect);
// When we're using tiles, find the intersection between the tile
// rect and this region rect. Tiling is then handled by the
// outer for-loops and modifying the tile rect.
if (usingTiles) {
tileScreenRect.MoveBy(-origin);
tileScreenRect = tileScreenRect.Intersect(currentTileRect);
tileScreenRect.MoveBy(origin);
if (tileScreenRect.IsEmpty())
continue;
tileRegionRect = regionRect->Intersect(currentTileRect);
tileRegionRect.MoveBy(-currentTileRect.TopLeft());
}
program->SetLayerQuadRect(tileScreenRect);
aManager->BindAndDrawQuadWithTextureRect(program, tileRegionRect,
tileRect.Size(),
mTexImage->GetWrapMode());
}
}
}
if (mTexImageOnWhite)
mTexImageOnWhite->NextTile();
} while (mTexImage->NextTile());
}
@ -791,6 +847,18 @@ ShadowBufferOGL::Upload(gfxASurface* aUpdate, const nsIntRegion& aUpdated,
nsIntPoint visTopLeft = mLayer->GetVisibleRegion().GetBounds().TopLeft();
destRegion.MoveBy(-visTopLeft);
// Correct for rotation
destRegion.MoveBy(aRotation);
nsIntRect destBounds = destRegion.GetBounds();
destRegion.MoveBy((destBounds.x >= size.width) ? -size.width : 0,
(destBounds.y >= size.height) ? -size.height : 0);
// There's code to make sure that updated regions don't cross rotation
// boundaries, so assert here that this is the case
NS_ASSERTION(((destBounds.x % size.width) + destBounds.width <= size.width) &&
((destBounds.y % size.height) + destBounds.height <= size.height),
"Updated region lies across rotation boundaries!");
// NB: this gfxContext must not escape EndUpdate() below
mTexImage->DirectUpdate(aUpdate, destRegion);

View File

@ -107,8 +107,7 @@ NS_IMETHODIMP
nsThebesFontEnumerator::HaveFontFor(const char *aLangGroup,
PRBool *aResult)
{
NS_ENSURE_ARG_POINTER(*aResult);
NS_ENSURE_ARG_POINTER(*aLangGroup);
NS_ENSURE_ARG_POINTER(aResult);
*aResult = PR_TRUE;
return NS_OK;

View File

@ -575,20 +575,8 @@ BasicTextureImage::BeginUpdate(nsIntRegion& aRegion)
NS_ASSERTION(!mUpdateSurface, "BeginUpdate() without EndUpdate()?");
// determine the region the client will need to repaint
ImageFormat format =
(GetContentType() == gfxASurface::CONTENT_COLOR) ?
gfxASurface::ImageFormatRGB24 : gfxASurface::ImageFormatARGB32;
if (mTextureState != Valid)
{
// if the texture hasn't been initialized yet, or something important
// changed, we need to recreate our backing surface and force the
// client to paint everything
mUpdateRegion = nsIntRect(nsIntPoint(0, 0), mSize);
} else {
mUpdateRegion = aRegion;
}
aRegion = mUpdateRegion;
GetUpdateRegion(aRegion);
mUpdateRegion = aRegion;
nsIntRect rgnSize = mUpdateRegion.GetBounds();
if (!nsIntRect(nsIntPoint(0, 0), mSize).Contains(rgnSize)) {
@ -596,7 +584,10 @@ BasicTextureImage::BeginUpdate(nsIntRegion& aRegion)
return NULL;
}
mUpdateSurface =
ImageFormat format =
(GetContentType() == gfxASurface::CONTENT_COLOR) ?
gfxASurface::ImageFormatRGB24 : gfxASurface::ImageFormatARGB32;
mUpdateSurface =
GetSurfaceForUpdate(gfxIntSize(rgnSize.width, rgnSize.height), format);
if (!mUpdateSurface || mUpdateSurface->CairoStatus()) {
@ -609,6 +600,16 @@ BasicTextureImage::BeginUpdate(nsIntRegion& aRegion)
return mUpdateSurface;
}
void
BasicTextureImage::GetUpdateRegion(nsIntRegion& aForRegion)
{
// if the texture hasn't been initialized yet, or something important
// changed, we need to recreate our backing surface and force the
// client to paint everything
if (mTextureState != Valid)
aForRegion = nsIntRect(nsIntPoint(0, 0), mSize);
}
void
BasicTextureImage::EndUpdate()
{
@ -729,10 +730,9 @@ TiledTextureImage::~TiledTextureImage()
bool
TiledTextureImage::DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom /* = nsIntPoint(0, 0) */)
{
nsIntRect bounds = aRegion.GetBounds();
nsIntRegion region;
if (mTextureState != Valid) {
bounds = nsIntRect(0, 0, mSize.width, mSize.height);
nsIntRect bounds = nsIntRect(0, 0, mSize.width, mSize.height);
region = nsIntRegion(bounds);
} else {
region = aRegion;
@ -740,8 +740,8 @@ TiledTextureImage::DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion,
PRBool result = PR_TRUE;
for (unsigned i = 0; i < mImages.Length(); i++) {
unsigned int xPos = (i % mColumns) * mTileSize;
unsigned int yPos = (i / mColumns) * mTileSize;
int xPos = (i % mColumns) * mTileSize;
int yPos = (i / mColumns) * mTileSize;
nsIntRegion tileRegion;
tileRegion.And(region, nsIntRect(nsIntPoint(xPos,yPos), mImages[i]->GetSize())); // intersect with tile
if (tileRegion.IsEmpty())
@ -757,25 +757,66 @@ TiledTextureImage::DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion,
return result;
}
void
TiledTextureImage::GetUpdateRegion(nsIntRegion& aForRegion)
{
if (mTextureState != Valid) {
// if the texture hasn't been initialized yet, or something important
// changed, we need to recreate our backing surface and force the
// client to paint everything
aForRegion = nsIntRect(nsIntPoint(0, 0), mSize);
return;
}
nsIntRegion newRegion;
// We need to query each texture with the region it will be drawing and
// set aForRegion to be the combination of all of these regions
for (unsigned i = 0; i < mImages.Length(); i++) {
int xPos = (i % mColumns) * mTileSize;
int yPos = (i / mColumns) * mTileSize;
nsIntRect imageRect = nsIntRect(nsIntRect(nsIntPoint(xPos,yPos), mImages[i]->GetSize()));
if (aForRegion.Intersects(imageRect)) {
// Make a copy of the region
nsIntRegion subRegion;
subRegion.And(aForRegion, imageRect);
// Translate it into tile-space
subRegion.MoveBy(-xPos, -yPos);
// Query region
mImages[i]->GetUpdateRegion(subRegion);
// Translate back
subRegion.MoveBy(xPos, yPos);
// Add to the accumulated region
newRegion.Or(newRegion, subRegion);
}
}
aForRegion = newRegion;
}
gfxASurface*
TiledTextureImage::BeginUpdate(nsIntRegion& aRegion)
{
NS_ASSERTION(!mInUpdate, "nested update");
mInUpdate = PR_TRUE;
// Note, we don't call GetUpdateRegion here as if the updated region is
// fully contained in a single tile, we get to avoid iterating through
// the tiles again (and a little copying).
if (mTextureState != Valid)
{
// if the texture hasn't been initialized yet, or something important
// changed, we need to recreate our backing surface and force the
// client to paint everything
mUpdateRegion = nsIntRect(nsIntPoint(0, 0), mSize);
} else {
mUpdateRegion = aRegion;
aRegion = nsIntRect(nsIntPoint(0, 0), mSize);
}
nsIntRect bounds = aRegion.GetBounds();
for (unsigned i = 0; i < mImages.Length(); i++) {
unsigned int xPos = (i % mColumns) * mTileSize;
unsigned int yPos = (i / mColumns) * mTileSize;
int xPos = (i % mColumns) * mTileSize;
int yPos = (i / mColumns) * mTileSize;
nsIntRegion imageRegion = nsIntRegion(nsIntRect(nsIntPoint(xPos,yPos), mImages[i]->GetSize()));
// a single Image can handle this update request
@ -786,6 +827,10 @@ TiledTextureImage::BeginUpdate(nsIntRegion& aRegion)
nsRefPtr<gfxASurface> surface = mImages[i]->BeginUpdate(aRegion);
// caller expects container space
aRegion.MoveBy(xPos, yPos);
// Correct the device offset
gfxPoint offset = surface->GetDeviceOffset();
surface->SetDeviceOffset(gfxPoint(offset.x - xPos,
offset.y - yPos));
// we don't have a temp surface
mUpdateSurface = nsnull;
// remember which image to EndUpdate
@ -793,15 +838,21 @@ TiledTextureImage::BeginUpdate(nsIntRegion& aRegion)
return surface.get();
}
}
// Get the real updated region, taking into account the capabilities of
// each TextureImage tile
GetUpdateRegion(aRegion);
mUpdateRegion = aRegion;
bounds = aRegion.GetBounds();
// update covers multiple Images - create a temp surface to paint in
gfxASurface::gfxImageFormat format =
(GetContentType() == gfxASurface::CONTENT_COLOR) ?
gfxASurface::ImageFormatRGB24 : gfxASurface::ImageFormatARGB32;
nsIntRect bounds = aRegion.GetBounds();
mUpdateSurface = gfxPlatform::GetPlatform()->
CreateOffscreenSurface(gfxIntSize(bounds.width, bounds.height), gfxASurface::ContentFromFormat(format));
mUpdateSurface->SetDeviceOffset(gfxPoint(-bounds.x, -bounds.y));
return mUpdateSurface;
}
@ -820,9 +871,10 @@ TiledTextureImage::EndUpdate()
// upload tiles from temp surface
for (unsigned i = 0; i < mImages.Length(); i++) {
unsigned int xPos = (i % mColumns) * mTileSize;
unsigned int yPos = (i / mColumns) * mTileSize;
int xPos = (i % mColumns) * mTileSize;
int yPos = (i / mColumns) * mTileSize;
nsIntRect imageRect = nsIntRect(nsIntPoint(xPos,yPos), mImages[i]->GetSize());
nsIntRegion subregion;
subregion.And(mUpdateRegion, imageRect);
if (subregion.IsEmpty())
@ -842,6 +894,7 @@ TiledTextureImage::EndUpdate()
mInUpdate = PR_FALSE;
mShaderType = mImages[0]->GetShaderProgramType();
mIsRGBFormat = mImages[0]->IsRGB();
mTextureState = Valid;
}
void TiledTextureImage::BeginTileIteration()
@ -901,6 +954,11 @@ void TiledTextureImage::Resize(const nsIntSize& aSize)
mTextureState = Allocated;
}
PRUint32 TiledTextureImage::GetTileCount()
{
return mImages.Length();
}
PRBool
GLContext::ResizeOffscreenFBO(const gfxIntSize& aSize)
{

View File

@ -193,6 +193,15 @@ public:
* followed by EndUpdate().
*/
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion) = 0;
/**
* Retrieves the region that will require updating, given a
* region that needs to be updated. This can be used for
* making decisions about updating before calling BeginUpdate().
*
* |aRegion| is an inout param.
*/
virtual void GetUpdateRegion(nsIntRegion& aForRegion) {
};
/**
* Finish the active update and synchronize with the server, if
* necessary.
@ -218,6 +227,11 @@ public:
};
virtual GLuint GetTextureID() = 0;
virtual PRUint32 GetTileCount() {
return 1;
};
/**
* Set this TextureImage's size, and ensure a texture has been
* allocated. Must not be called between BeginUpdate and EndUpdate.
@ -348,6 +362,7 @@ public:
virtual void BindTexture(GLenum aTextureUnit);
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion);
virtual void GetUpdateRegion(nsIntRegion& aForRegion);
virtual void EndUpdate();
virtual bool DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom = nsIntPoint(0,0));
virtual GLuint GetTextureID() { return mTexture; };
@ -392,8 +407,10 @@ public:
~TiledTextureImage();
void DumpDiv();
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion);
virtual void GetUpdateRegion(nsIntRegion& aForRegion);
virtual void EndUpdate();
virtual void Resize(const nsIntSize& aSize);
virtual PRUint32 GetTileCount();
virtual void BeginTileIteration();
virtual PRBool NextTile();
virtual nsIntRect GetTileRect();

View File

@ -1207,27 +1207,28 @@ public:
}
}
virtual void GetUpdateRegion(nsIntRegion& aForRegion)
{
if (mTextureState != Valid) {
// if the texture hasn't been initialized yet, force the
// client to paint everything
aForRegion = nsIntRect(nsIntPoint(0, 0), mSize);
} else if (!mBackingSurface) {
// We can only draw a rectangle, not subregions due to
// the way that our texture upload functions work. If
// needed, we /could/ do multiple texture uploads if we have
// non-overlapping rects, but that's a tradeoff.
aForRegion = nsIntRegion(mUpdateRect);
}
}
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion)
{
NS_ASSERTION(!mUpdateSurface, "BeginUpdate() without EndUpdate()?");
// determine the region the client will need to repaint
if (mTextureState != Valid) {
// if the texture hasn't been initialized yet, force the
// client to paint everything
mUpdateRect = nsIntRect(nsIntPoint(0, 0), mSize);
//printf_stderr("v Forcing full paint\n");
aRegion = nsIntRegion(mUpdateRect);
} else {
mUpdateRect = aRegion.GetBounds();
if (!mBackingSurface) {
// We can only draw a rectangle, not subregions due to
// the way that our texture upload functions work. If
// needed, we /could/ do multiple texture uploads if we have
// non-overlapping rects, but that's a tradeoff.
aRegion = nsIntRegion(mUpdateRect);
}
}
GetUpdateRegion(aRegion);
mUpdateRect = aRegion.GetBounds();
//printf_stderr("BeginUpdate with updateRect [%d %d %d %d]\n", mUpdateRect.x, mUpdateRect.y, mUpdateRect.width, mUpdateRect.height);
if (!nsIntRect(nsIntPoint(0, 0), mSize).Contains(mUpdateRect)) {

View File

@ -77,36 +77,6 @@ GRE_MODULE = 1
LIBS = $(NSPR_LIBS)
ifdef GNU_CXX
ifdef INTEL_CXX
# icc gets special optimize flags
ifdef MOZ_PROFILE_GENERATE
MODULE_OPTIMIZE_FLAGS = -O0
else
MODULE_OPTIMIZE_FLAGS = -O2 -ip
endif
else # not INTEL_CXX
MODULE_OPTIMIZE_FLAGS = -O3 -fstrict-aliasing -fno-stack-protector
# We normally want -fomit-frame-pointer, but we want an explicit
# -fno-omit-frame-pointer if we're using a sampling profiler.
ifndef MOZ_PROFILING
MODULE_OPTIMIZE_FLAGS += -fomit-frame-pointer
else
MODULE_OPTIMIZE_FLAGS += -fno-omit-frame-pointer
endif
endif
else # not GNU_CXX
ifeq ($(OS_ARCH),SunOS)
MODULE_OPTIMIZE_FLAGS = -xO4
endif
ifeq ($(OS_ARCH),WINNT)
MODULE_OPTIMIZE_FLAGS = -O2
endif
endif
ifeq ($(OS_ARCH),WINNT)
NO_PROFILE_GUIDED_OPTIMIZE = 1
endif

View File

@ -1992,11 +1992,14 @@ case "$target" in
*-darwin*)
MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -o $@'
MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -o $@'
# If we're building with --enable-profiling, we need a frame pointer.
MOZ_OPTIMIZE_FLAGS="-O3 -fstrict-aliasing -fno-stack-protector"
# We normally want -fomit-frame-pointer, but we want an explicit
# -fno-omit-frame-pointer if we're using a sampling profiler.
if test -z "$MOZ_PROFILING"; then
MOZ_OPTIMIZE_FLAGS="-O3 -fomit-frame-pointer"
MOZ_OPTIMIZE_FLAGS="$MOZ_OPTIMIZE_FLAGS -fomit-frame-pointer"
else
MOZ_OPTIMIZE_FLAGS="-O3 -fno-omit-frame-pointer"
MOZ_OPTIMIZE_FLAGS="$MOZ_OPTIMIZE_FLAGS -fno-omit-frame-pointer"
fi
_PEDANTIC=
CFLAGS="$CFLAGS -fpascal-strings -fno-common"

View File

@ -2202,7 +2202,7 @@ JS_DumpBytecode(JSContext *cx, JSScript *script)
fprintf(stdout, "--- SCRIPT %s:%d ---\n", script->filename, script->lineno);
js_Disassemble(cx, script, true, &sprinter);
fprintf(stdout, "%s\n", sprinter.base);
fputs(sprinter.base, stdout);
fprintf(stdout, "--- END SCRIPT %s:%d ---\n", script->filename, script->lineno);
#endif
}

View File

@ -6699,15 +6699,22 @@ js_DumpStackFrame(JSContext *cx, StackFrame *start)
/* This should only called during live debugging. */
VOUCH_DOES_NOT_REQUIRE_STACK();
if (!start)
start = cx->maybefp();
FrameRegsIter i(cx);
while (!i.done() && i.fp() != start)
++i;
FrameRegsIter i(cx, StackIter::GO_THROUGH_SAVED);
if (!start) {
if (i.done()) {
fprintf(stderr, "no stack for cx = %p\n", (void*) cx);
return;
}
start = i.fp();
} else {
while (!i.done() && i.fp() != start)
++i;
if (i.done()) {
fprintf(stderr, "fp = %p not found in cx = %p\n", (void *)start, (void *)cx);
return;
if (i.done()) {
fprintf(stderr, "fp = %p not found in cx = %p\n",
(void *)start, (void *)cx);
return;
}
}
for (; !i.done(); ++i) {

View File

@ -458,6 +458,23 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
type = JOF_TYPE(cs->format);
switch (type) {
case JOF_BYTE:
// Scan the trynotes to find the associated catch block
// and make the try opcode look like a jump instruction
// with an offset. This simplifies code coverage analysis
// based on this disassembled output.
if (op == JSOP_TRY) {
JSTryNoteArray *trynotes = script->trynotes();
uint32 i;
for(i = 0; i < trynotes->length; i++) {
JSTryNote note = trynotes->vector[i];
if (note.kind == JSTRY_CATCH && note.start == loc + 1) {
Sprint(sp, " %u (%+d)",
(unsigned int) (loc+note.length+1),
(int) (note.length+1));
break;
}
}
}
break;
case JOF_JUMP:

View File

@ -409,11 +409,12 @@ ForceFrame::enter()
LeaveTrace(context);
JS_ASSERT(context->compartment == target->compartment());
JSCompartment *destination = context->compartment;
JSObject *scopeChain = target->getGlobal();
JS_ASSERT(scopeChain->isNative());
return context->stack.pushDummyFrame(context, REPORT_ERROR, *scopeChain, frame);
return context->stack.pushDummyFrame(context, destination, *scopeChain, frame);
}
AutoCompartment::AutoCompartment(JSContext *cx, JSObject *target)
@ -442,21 +443,8 @@ AutoCompartment::enter()
JS_ASSERT(scopeChain->isNative());
frame.construct();
/*
* Set the compartment eagerly so that pushDummyFrame associates the
* resource allocation request with 'destination' instead of 'origin'.
* (This is important when content has overflowed the stack and chrome
* is preparing to run JS to throw up a slow script dialog.) However,
* if an exception is thrown, we need it to be in origin's compartment
* so be careful to only report after restoring.
*/
context->compartment = destination;
if (!context->stack.pushDummyFrame(context, DONT_REPORT_ERROR, *scopeChain, &frame.ref())) {
context->compartment = origin;
js_ReportOverRecursed(context);
if (!context->stack.pushDummyFrame(context, destination, *scopeChain, &frame.ref()))
return false;
}
if (context->isExceptionPending())
context->wrapPendingException();

View File

@ -388,7 +388,8 @@ StackSpace::ensureEnoughSpaceToEnterTrace(JSContext *cx)
STATIC_POSTCONDITION(!return || ubound(from) >= nvals)
JS_ALWAYS_INLINE bool
StackSpace::ensureSpace(JSContext *cx, MaybeReportError report, Value *from, ptrdiff_t nvals) const
StackSpace::ensureSpace(JSContext *cx, MaybeReportError report, Value *from, ptrdiff_t nvals,
JSCompartment *dest) const
{
assertInvariants();
JS_ASSERT(from >= firstUnused());
@ -396,7 +397,7 @@ StackSpace::ensureSpace(JSContext *cx, MaybeReportError report, Value *from, ptr
JS_ASSERT(from <= commitEnd_);
#endif
if (JS_UNLIKELY(conservativeEnd_ - from < nvals))
return ensureSpaceSlow(cx, report, from, nvals);
return ensureSpaceSlow(cx, report, from, nvals, dest);
return true;
}

View File

@ -414,13 +414,16 @@ StackSpace::mark(JSTracer *trc)
}
JS_FRIEND_API(bool)
StackSpace::ensureSpaceSlow(JSContext *cx, MaybeReportError report,
Value *from, ptrdiff_t nvals) const
StackSpace::ensureSpaceSlow(JSContext *cx, MaybeReportError report, Value *from, ptrdiff_t nvals,
JSCompartment *dest) const
{
assertInvariants();
bool trusted = !cx->compartment ||
cx->compartment->principals == cx->runtime->trustedPrincipals();
/* See CX_COMPARTMENT comment. */
if (dest == (JSCompartment *)CX_COMPARTMENT)
dest = cx->compartment;
bool trusted = !dest || dest->principals == cx->runtime->trustedPrincipals();
Value *end = trusted ? trustedEnd_ : defaultEnd_;
/*
@ -548,17 +551,17 @@ ContextStack::containsSlow(const StackFrame *target) const
*/
Value *
ContextStack::ensureOnTop(JSContext *cx, MaybeReportError report, uintN nvars,
MaybeExtend extend, bool *pushedSeg)
MaybeExtend extend, bool *pushedSeg, JSCompartment *dest)
{
Value *firstUnused = space().firstUnused();
if (onTop() && extend) {
if (!space().ensureSpace(cx, report, firstUnused, nvars))
if (!space().ensureSpace(cx, report, firstUnused, nvars, dest))
return NULL;
return firstUnused;
}
if (!space().ensureSpace(cx, report, firstUnused, VALUES_PER_STACK_SEGMENT + nvars))
if (!space().ensureSpace(cx, report, firstUnused, VALUES_PER_STACK_SEGMENT + nvars, dest))
return NULL;
FrameRegs *regs;
@ -696,11 +699,12 @@ ContextStack::pushExecuteFrame(JSContext *cx, JSScript *script, const Value &thi
}
bool
ContextStack::pushDummyFrame(JSContext *cx, MaybeReportError report, JSObject &scopeChain,
DummyFrameGuard *dfg)
ContextStack::pushDummyFrame(JSContext *cx, JSCompartment *dest, JSObject &scopeChain, DummyFrameGuard *dfg)
{
JS_ASSERT(dest == scopeChain.compartment());
uintN nvars = VALUES_PER_STACK_FRAME;
Value *firstUnused = ensureOnTop(cx, report, nvars, CAN_EXTEND, &dfg->pushedSeg_);
Value *firstUnused = ensureOnTop(cx, REPORT_ERROR, nvars, CAN_EXTEND, &dfg->pushedSeg_, dest);
if (!firstUnused)
return NULL;
@ -708,6 +712,7 @@ ContextStack::pushDummyFrame(JSContext *cx, MaybeReportError report, JSObject &s
fp->initDummyFrame(cx, scopeChain);
dfg->regs_.initDummyFrame(*fp);
cx->compartment = dest;
dfg->prevRegs_ = seg_->pushRegs(dfg->regs_);
JS_ASSERT(space().firstUnused() == dfg->regs_.sp);
dfg->setPushed(*this);
@ -790,24 +795,11 @@ ContextStack::popGeneratorFrame(const GeneratorFrameGuard &gfg)
bool
ContextStack::saveFrameChain()
{
/*
* The StackSpace uses the context's current compartment to determine
* whether to allow access to the privileged end-of-stack buffer.
* However, we always want saveFrameChain to have access to this privileged
* buffer since it gets used to prepare calling trusted JS. To force this,
* we clear the current compartment (which is interpreted by ensureSpace as
* 'trusted') and either restore it on OOM or let resetCompartment()
* clobber it.
*/
JSCompartment *original = cx_->compartment;
cx_->compartment = NULL;
JSCompartment *dest = NULL;
bool pushedSeg;
if (!ensureOnTop(cx_, DONT_REPORT_ERROR, 0, CANT_EXTEND, &pushedSeg)) {
cx_->compartment = original;
js_ReportOverRecursed(cx_);
if (!ensureOnTop(cx_, REPORT_ERROR, 0, CANT_EXTEND, &pushedSeg, dest))
return false;
}
JS_ASSERT(pushedSeg);
JS_ASSERT(!hasfp());

View File

@ -44,6 +44,7 @@
#include "jsfun.h"
struct JSContext;
struct JSCompartment;
namespace js {
@ -1336,10 +1337,23 @@ class StackSpace
friend class ContextStack;
friend class StackFrame;
/*
* Except when changing compartment (see pushDummyFrame), the 'dest'
* parameter of ensureSpace is cx->compartment. Ideally, we'd just pass
* this directly (and introduce a helper that supplies cx->compartment when
* no 'dest' is given). For some compilers, this really hurts performance,
* so, instead, a trivially sinkable magic constant is used to indicate
* that dest should be cx->compartment.
*/
static const size_t CX_COMPARTMENT = 0xc;
inline bool ensureSpace(JSContext *cx, MaybeReportError report,
Value *from, ptrdiff_t nvals) const;
Value *from, ptrdiff_t nvals,
JSCompartment *dest = (JSCompartment *)CX_COMPARTMENT) const;
JS_FRIEND_API(bool) ensureSpaceSlow(JSContext *cx, MaybeReportError report,
Value *from, ptrdiff_t nvals) const;
Value *from, ptrdiff_t nvals,
JSCompartment *dest) const;
StackSegment &findContainingSegment(const StackFrame *target) const;
public:
@ -1428,7 +1442,8 @@ class ContextStack
StackSegment *pushSegment(JSContext *cx);
enum MaybeExtend { CAN_EXTEND = true, CANT_EXTEND = false };
Value *ensureOnTop(JSContext *cx, MaybeReportError report, uintN nvars,
MaybeExtend extend, bool *pushedSeg);
MaybeExtend extend, bool *pushedSeg,
JSCompartment *dest = (JSCompartment *)StackSpace::CX_COMPARTMENT);
inline StackFrame *
getCallFrame(JSContext *cx, MaybeReportError report, const CallArgs &args,
@ -1509,9 +1524,16 @@ class ContextStack
*/
bool pushGeneratorFrame(JSContext *cx, JSGenerator *gen, GeneratorFrameGuard *gfg);
/* Pushes a "dummy" frame; should be removed one day. */
bool pushDummyFrame(JSContext *cx, MaybeReportError report, JSObject &scopeChain,
DummyFrameGuard *dfg);
/*
* When changing the compartment of a cx, it is necessary to immediately
* change the scope chain to a global in the right compartment since any
* amount of general VM code can run before the first scripted frame is
* pushed (if at all). This is currently and hackily accomplished by
* pushing a "dummy frame" with the correct scope chain. On success, this
* function will change the compartment to 'scopeChain.compartment()' and
* push a dummy frame for 'scopeChain'. On failure, nothing is changed.
*/
bool pushDummyFrame(JSContext *cx, JSCompartment *dest, JSObject &scopeChain, DummyFrameGuard *dfg);
/*
* An "inline frame" may only be pushed from within the top, active
@ -1690,7 +1712,8 @@ class FrameRegsIter
}
public:
FrameRegsIter(JSContext *cx) : iter_(cx) { settle(); }
FrameRegsIter(JSContext *cx, StackIter::SavedOption opt = StackIter::STOP_AT_SAVED)
: iter_(cx, opt) { settle(); }
bool done() const { return iter_.done(); }
FrameRegsIter &operator++() { ++iter_; settle(); return *this; }

View File

@ -503,7 +503,7 @@ nsXPCComponents_InterfacesByID::GetContractID(char * *aContractID)
NS_IMETHODIMP
nsXPCComponents_InterfacesByID::GetClassDescription(char * *aClassDescription)
{
static const char classDescription[] = "XPCComponents_Interfaces";
static const char classDescription[] = "XPCComponents_InterfacesByID";
*aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
@ -1075,7 +1075,7 @@ nsXPCComponents_ClassesByID::GetContractID(char * *aContractID)
NS_IMETHODIMP
nsXPCComponents_ClassesByID::GetClassDescription(char * *aClassDescription)
{
static const char classDescription[] = "XPCComponents_Interfaces";
static const char classDescription[] = "XPCComponents_ClassesByID";
*aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
@ -1346,7 +1346,7 @@ nsXPCComponents_Results::GetContractID(char * *aContractID)
NS_IMETHODIMP
nsXPCComponents_Results::GetClassDescription(char * *aClassDescription)
{
static const char classDescription[] = "XPCComponents_Interfaces";
static const char classDescription[] = "XPCComponents_Results";
*aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
@ -1575,7 +1575,7 @@ nsXPCComponents_ID::GetContractID(char * *aContractID)
NS_IMETHODIMP
nsXPCComponents_ID::GetClassDescription(char * *aClassDescription)
{
static const char classDescription[] = "XPCComponents_Interfaces";
static const char classDescription[] = "XPCComponents_ID";
*aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
@ -1803,7 +1803,7 @@ nsXPCComponents_Exception::GetContractID(char * *aContractID)
NS_IMETHODIMP
nsXPCComponents_Exception::GetClassDescription(char * *aClassDescription)
{
static const char classDescription[] = "XPCComponents_Interfaces";
static const char classDescription[] = "XPCComponents_Exception";
*aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
@ -2098,7 +2098,7 @@ nsXPCConstructor::GetContractID(char * *aContractID)
NS_IMETHODIMP
nsXPCConstructor::GetClassDescription(char * *aClassDescription)
{
static const char classDescription[] = "XPCComponents_Interfaces";
static const char classDescription[] = "XPCConstructor";
*aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
@ -2364,7 +2364,7 @@ nsXPCComponents_Constructor::GetContractID(char * *aContractID)
NS_IMETHODIMP
nsXPCComponents_Constructor::GetClassDescription(char * *aClassDescription)
{
static const char classDescription[] = "XPCComponents_Interfaces";
static const char classDescription[] = "XPCComponents_Constructor";
*aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}

View File

@ -0,0 +1,12 @@
function check_cl(iface, desc) {
do_check_eq(iface.QueryInterface(Components.interfaces.nsIClassInfo).classDescription, desc);
}
function run_test() {
check_cl(Components, 'XPCComponents');
check_cl(Components.interfaces, 'XPCComponents_Interfaces');
check_cl(Components.interfacesByID, 'XPCComponents_InterfacesByID');
check_cl(Components.classes, 'XPCComponents_Classes');
check_cl(Components.classesByID, 'XPCComponents_ClassesByID');
check_cl(Components.results, 'XPCComponents_Results');
}

View File

@ -9,6 +9,7 @@ tail =
[test_bug604362.js]
[test_bug608142.js]
[test_bug641378.js]
[test_bug677864.js]
[test_bug_442086.js]
[test_file.js]
[test_import.js]

View File

@ -643,7 +643,8 @@ void nsCaret::InvalidateTextOverflowBlock()
nsLayoutUtils::FindNearestBlockAncestor(caretFrame);
if (block) {
const nsStyleTextReset* style = block->GetStyleTextReset();
if (style->mTextOverflow.mType != NS_STYLE_TEXT_OVERFLOW_CLIP) {
if (style->mTextOverflow.mLeft.mType != NS_STYLE_TEXT_OVERFLOW_CLIP ||
style->mTextOverflow.mRight.mType != NS_STYLE_TEXT_OVERFLOW_CLIP) {
block->InvalidateOverflowRect();
}
}

View File

@ -280,8 +280,8 @@ TextOverflow::WillProcessLines(nsDisplayListBuilder* aBuilder,
textOverflow->mBlockIsRTL =
aBlockFrame->GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL;
const nsStyleTextReset* style = aBlockFrame->GetStyleTextReset();
textOverflow->mLeft.Init(style->mTextOverflow);
textOverflow->mRight.Init(style->mTextOverflow);
textOverflow->mLeft.Init(style->mTextOverflow.mLeft);
textOverflow->mRight.Init(style->mTextOverflow.mRight);
// The left/right marker string is setup in ExamineLineFrames when a line
// has overflow on that side.
@ -429,11 +429,11 @@ TextOverflow::ExamineLineFrames(nsLineBox* aLine,
mRight.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP && rightOverflow;
do {
// Setup marker strings as needed.
if (guessLeft || guessRight) {
if (guessLeft) {
mLeft.SetupString(mBlock);
mRight.mMarkerString = mLeft.mMarkerString;
mRight.mWidth = mLeft.mWidth;
mRight.mInitialized = mLeft.mInitialized;
}
if (guessRight) {
mRight.SetupString(mBlock);
}
// If there is insufficient space for both markers then keep the one on the
@ -588,7 +588,8 @@ TextOverflow::CanHaveTextOverflow(nsDisplayListBuilder* aBuilder,
const nsStyleTextReset* style = aBlockFrame->GetStyleTextReset();
// Nothing to do for text-overflow:clip or if 'overflow-x:visible'
// or if we're just building items for event processing.
if ((style->mTextOverflow.mType == NS_STYLE_TEXT_OVERFLOW_CLIP) ||
if ((style->mTextOverflow.mLeft.mType == NS_STYLE_TEXT_OVERFLOW_CLIP &&
style->mTextOverflow.mRight.mType == NS_STYLE_TEXT_OVERFLOW_CLIP) ||
IsHorizontalOverflowVisible(aBlockFrame) ||
aBuilder->IsForEventDelivery()) {
return false;

View File

@ -188,7 +188,7 @@ class TextOverflow {
class Marker {
public:
void Init(const nsStyleTextOverflow& aStyle) {
void Init(const nsStyleTextOverflowSide& aStyle) {
mInitialized = false;
mWidth = 0;
mStyle = &aStyle;
@ -211,7 +211,7 @@ class TextOverflow {
// The marker text.
nsString mMarkerString;
// The style for this side.
const nsStyleTextOverflow* mStyle;
const nsStyleTextOverflowSide* mStyle;
// True if there is visible overflowing inline content on this side.
bool mHasOverflow;
// True if mMarkerString and mWidth have been setup from style.

View File

@ -1492,18 +1492,9 @@ nsBlockFrame::ComputeOverflowAreas(const nsHTMLReflowState& aReflowState,
nsOverflowAreas areas(bounds, bounds);
if (!IsClippingChildren(this, aReflowState)) {
PRBool inQuirks = (PresContext()->CompatibilityMode() == eCompatibility_NavQuirks);
for (line_iterator line = begin_lines(), line_end = end_lines();
line != line_end;
++line) {
// Text-shadow overflows
if (!inQuirks && line->IsInline()) {
nsRect shadowRect = nsLayoutUtils::GetTextShadowRectsUnion(
line->GetVisualOverflowArea(), this);
areas.VisualOverflow().UnionRect(areas.VisualOverflow(), shadowRect);
}
areas.UnionWith(line->GetOverflowAreas());
}

View File

@ -2560,15 +2560,6 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflo
overflowAreas.ScrollableOverflow().UnionRect(
psd->mFrame->mOverflowAreas.ScrollableOverflow(), adjustedBounds);
// Text-shadow overflow
if (mPresContext->CompatibilityMode() != eCompatibility_NavQuirks) {
nsRect shadowRect = nsLayoutUtils::GetTextShadowRectsUnion(adjustedBounds,
psd->mFrame->mFrame);
adjustedBounds.UnionRect(adjustedBounds, shadowRect);
}
// Text shadow is only part of visual overflow and not scrollable overflow.
overflowAreas.VisualOverflow().UnionRect(
psd->mFrame->mOverflowAreas.VisualOverflow(), adjustedBounds);
}

View File

@ -6628,8 +6628,7 @@ RoundOut(const gfxRect& aRect)
nsRect
nsTextFrame::ComputeTightBounds(gfxContext* aContext) const
{
if ((GetStyleContext()->HasTextDecorationLines() &&
eCompatibility_NavQuirks == PresContext()->CompatibilityMode()) ||
if (GetStyleContext()->HasTextDecorationLines() ||
(GetStateBits() & TEXT_HYPHEN_BREAK)) {
// This is conservative, but OK.
return GetVisualOverflowRect();

View File

@ -850,15 +850,6 @@ nsMathMLContainerFrame::GatherAndStoreOverflow(nsHTMLReflowMetrics* aMetrics)
// frame rectangle.
aMetrics->SetOverflowAreasToDesiredBounds();
// Text-shadow overflows.
if (PresContext()->CompatibilityMode() != eCompatibility_NavQuirks) {
nsRect frameRect(0, 0, aMetrics->width, aMetrics->height);
nsRect shadowRect = nsLayoutUtils::GetTextShadowRectsUnion(frameRect, this);
// shadows contribute only to visual overflow
nsRect& visOverflow = aMetrics->VisualOverflow();
visOverflow.UnionRect(visOverflow, shadowRect);
}
// All non-child-frame content such as nsMathMLChars (and most child-frame
// content) is included in mBoundingMetrics.
nsRect boundingBox(mBoundingMetrics.leftBearing,

View File

@ -0,0 +1,40 @@
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Test Page</title>
<style type="text/css">
<!--
td{
background-color: rgb(140,140,140);
}
-->
</style>
</head>
<body>
<table cellpadding=0 cellspacing=0 border=0 width=150>
<tr><td><img width="16" height="16"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC"
border=0></td></tr>
<tr><td><img width="16" height="16"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC"
border=0></td></tr>
</table>
<table cellpadding=0 cellspacing=0 border=0 width=150>
<tr><td><img width="16" height="16"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC"
border=0></td></tr>
<tr><td><img width="16" height="16"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC"
border=0></td></tr>
</table>
<table cellpadding=0 cellspacing=0 border=0>
<tr><td><img width="16" height="16"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC"
border=0></td></tr>
<tr><td><img width="16" height="16"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC"
border=0></td></tr>
</table>
<hr>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Test Page</title>
<style type="text/css">
<!--
.nav {
display:block;
background-color: rgb(140,140,140);
}
-->
</style>
</head>
<body>
<table cellpadding=0 cellspacing=0 border=0 width=150>
<tr><td class="nav"><a href="a.htm"><img width="16" height="16"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC"
border=0></a></td></tr>
<tr><td class="nav"><a href="a.htm"><img width="16" height="16"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC"
border=0></a></td></tr>
</table>
<table cellpadding=0 cellspacing=0 border=0 width=150>
<tr><td><a href="a.htm" class="nav"><img width="16" height="16"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC"
border=0></a></td></tr>
<tr><td><a href="a.htm" class="nav"><img width="16" height="16"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC"
border=0></a></td></tr>
</table>
<table cellpadding=0 cellspacing=0 border=0 width=150>
<tr><td><a href="a.htm"><img class="nav" width="16" height="16"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC"
border=0></a></td></tr>
<tr><td><a href="a.htm"><img class="nav" width="16" height="16"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC"
border=0></a></td></tr>
</table>
<hr>
</body>
</html>

View File

@ -0,0 +1,26 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>border crosstalk</title>
</head>
<style>
table.t1 td {border: 1px solid black}
</style>
<body >
<TABLE style="border-collapse:collapse" class="t1">
<TR><TD>1</td> <TD>2</td> <TD>3</td></tr>
</TABLE>
<table border="1">
<tr><td>1</td><td>2</td></tr>
<tr><td >3</td><td>4</td></tr>
</table>
</body>
</html>

View File

@ -0,0 +1,24 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>border crosstalk</title>
</head>
<body >
<TABLE border="1" style="border-collapse:collapse">
<TR><TD>1</td> <TD>2</td> <TD>3</td></tr>
</TABLE>
<table border="1">
<tr><td>1</td><td>2</td></tr>
<tr><td >3</td><td>4</td></tr>
</table>
</body>
</html>

View File

@ -0,0 +1,20 @@
<html>
<head>
<style type="text/css">
.forms {display:inline;}
.nn2{background-image: url("260406.gif");width:20px;height:18px;}
</style>
</head>
<body>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>P</td>
</tr>
</table>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="nn2"></td>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,20 @@
<html>
<head>
<style type="text/css">
.forms {display:inline;}
.nn2{background-image: url("260406.gif");width:20px;height:18px;}
</style>
</head>
<body>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="forms">P</td>
</tr>
</table>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="nn2"></td>
</tr>
</table>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 954 B

View File

@ -138,6 +138,7 @@ random == 99850-1b.html 99850-1-ref.html # bug 471629
== 167496-1.html 167496-1-ref.html
== 169749-1.html 169749-1-ref.html
== 172073-1.html 172073-1-ref.html
== 175190-1.html 175190-1-ref.html
== 179596-1a.html 179596-1a-ref.html
== 179596-1b.html 179596-1b-ref.html
== 179596-2.html 179596-2-ref.html
@ -146,6 +147,7 @@ random == 99850-1b.html 99850-1-ref.html # bug 471629
== 180085-1.html 180085-1-ref.html
== 180085-2.html 180085-2-ref.html
== 185388-1.html 185388-1-ref.html
== 186317-1.html 186317-1-ref.html
== 192902-1.html 192902-ref.html
== 192767-01.xul 192767-11.xul
== 192767-02.xul 192767-12.xul
@ -268,6 +270,7 @@ fails-if(Android) != 192767-17.xul 192767-37.xul
== 252920-1.html 252920-1-ref.html
== 253701-1.html 253701-1-ref.html
== 255820-1.html 255820-1-ref.html
== 260406-1.html 260406-1-ref.html
== 261826-1.xul 261826-1-ref.xul
== 262151-1.html 262151-1-ref.html
== 262998-1.html 262998-1-ref.html

View File

@ -288,6 +288,9 @@ include xul-document-load/reftest.list
# xul/
include xul/reftest.list
# xul
include ../xul/base/reftest/reftest.list
# xul grid
include ../xul/base/src/grid/reftests/reftest.list

View File

Before

Width:  |  Height:  |  Size: 1017 B

After

Width:  |  Height:  |  Size: 1017 B

View File

@ -0,0 +1,28 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg class="reftest-wait" xmlns="http://www.w3.org/2000/svg" onload="startTest()">
<defs>
<filter id="f" filterUnits="objectBoundingBox" primitiveUnits="objectBoundingBox"
x="0" y="0" width="1" height="1">
<feFlood flood-color="#ff0000" flood-opacity="0.5" result="flood"/>
<feComposite id="comp" width="1" height="1" in="flood" operator="over" in2="SourceGraphic"/>
</filter>
</defs>
<rect width="100" height="100" fill="lime" filter="url(#f)"/>
<script>
function startTest() {
document.addEventListener("MozReftestInvalidate", doTest, false);
// in case we're not gecko
setTimeout(doTest, 5000);
}
function doTest() {
document.getElementById("comp").setAttribute("color-interpolation-filters", "sRGB");
document.documentElement.removeAttribute('class');
}
</script>
</svg>

After

Width:  |  Height:  |  Size: 967 B

View File

@ -64,7 +64,8 @@ fails-if(Android) == dynamic-conditions-01.svg pass.svg # bug 652050
== dynamic-clipPath-01.svg pass.svg
== dynamic-feFlood-01.svg pass.svg
== dynamic-feImage-01.svg pass.svg
== dynamic-filter-contents-01.svg dynamic-filter-contents-01-ref.svg
== dynamic-filter-contents-01a.svg dynamic-filter-contents-01-ref.svg
== dynamic-filter-contents-01b.svg dynamic-filter-contents-01-ref.svg
== dynamic-gradient-contents-01.svg pass.svg
== dynamic-gradient-contents-02.svg pass.svg
== dynamic-inner-svg-01.svg pass.svg

View File

@ -1,7 +1,7 @@
== 121142-1a.html 121142-1-ref.html
== 121142-1b.html 121142-1-ref.html
== 121142-2.html 121142-2-ref.html
fails == 156888-1.html 156888-1-ref.html # bug 484825
== 156888-1.html 156888-1-ref.html
== 156888-2.html 156888-2-ref.html
== 162063-1.xhtml about:blank
== 203923-1.html white-space-ref.html

View File

@ -1,5 +1,5 @@
<html>
<body>
<u>hello</u><img src="http://www.mozilla.org/images/livemarks16.png"><font color="purple"><u>hello</u></font>
<u>hello</u><img src="../backgrounds/red-128-alpha-32x32.png"><font color="purple"><u>hello</u></font>
</body>
</html>

View File

@ -1,5 +1,5 @@
<html>
<body>
<u>hello<img src="http://www.mozilla.org/images/livemarks16.png"><font color="purple">hello</font></u>
<u>hello<img src="../backgrounds/red-128-alpha-32x32.png"><font color="purple">hello</font></u>
</body>
</html>

View File

@ -1,6 +1,6 @@
<!DOCTYPE HTML>
<html>
<body>
<u>hello<img src="http://www.mozilla.org/images/livemarks16.png"><span style="color: purple;">hello</span></u>
<u>hello<img src="../backgrounds/red-128-alpha-32x32.png"><span style="color: purple;">hello</span></u>
</body>
</html>

View File

@ -1,6 +1,6 @@
<!DOCTYPE HTML>
<html>
<body>
<u>hello<img src="http://www.mozilla.org/images/livemarks16.png"><font color="purple">hello</font></u>
<u>hello<img src="../backgrounds/red-128-alpha-32x32.png"><font color="purple">hello</font></u>
</body>
</html>

View File

@ -18,3 +18,4 @@ HTTP(..) == marker-shadow.html marker-shadow-ref.html
skip-if(Android) == clipped-elements.html clipped-elements-ref.html
== theme-overflow.html theme-overflow-ref.html
HTTP(..) == table-cell.html table-cell-ref.html
HTTP(..) == two-value-syntax.html two-value-syntax-ref.html

View File

@ -0,0 +1,66 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/licenses/publicdomain/
Test: text-overflow:<left> <right>
-->
<html><head>
<title>text-overflow: text-overflow:&lt;left&gt; &lt;right&gt;</title>
<style type="text/css">
@font-face {
font-family: DejaVuSansMono;
src: url(../fonts/DejaVuSansMono.woff);
}
html,body {
color:black; background-color:white; font-size:16px; padding:0; margin:0; font-family:DejaVuSansMono;
}
.test {
overflow:hidden;
width:100%;
white-space:nowrap;
}
span {
margin: 0 -2px;
}
.rlo {
unicode-bidi: bidi-override; direction:rtl;
}
.lro {
unicode-bidi: bidi-override;
}
.rtl {
direction:rtl;
}
.ltr {
direction:ltr;
}
</style>
</head><body>
<div style="float:left;">
|||||
<div class="test t1"><span>&nbsp;&#x2026;||&#x2026;</span></div>
<div class="test rtl t1"><span>&nbsp;&#x2026;||&#x2026;</span></div>
<div class="test t2"><span>&nbsp;&#x2026;||||</span></div>
<div class="test rtl t2"><span>||||&#x2026;</span></div>
<div class="test t3"><span>||||&#x2026;</span></div>
<div class="test rtl t3"><span>&nbsp;&#x2026;||||</span></div>
<div class="test t4"><span>||||.</span></div>
<div class="test rtl t4"><span>&nbsp;.||||</span></div>
<div class="test t5"><span>&nbsp;.||||</span></div>
<div class="test rtl t5"><span>||||.</span></div>
<div class="test t6"><span>&nbsp;.||,</span></div>
<div class="test rtl t6"><span>&nbsp;,||.</span></div>
<div class="test t7"><span>&nbsp;&#x2026;||,</span></div>
<div class="test rtl t7"><span>&nbsp;,||&#x2026;</span></div>
<div class="test t8"><span>&nbsp;.||&#x2026;</span></div>
<div class="test rtl t8"><span>&nbsp;&#x2026;||.</span></div>
</div>
</body>
</html>

View File

@ -0,0 +1,75 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/licenses/publicdomain/
Test: text-overflow:<left> <right>
-->
<html><head>
<title>text-overflow: text-overflow:&lt;left&gt; &lt;right&gt;</title>
<style type="text/css">
@font-face {
font-family: DejaVuSansMono;
src: url(../fonts/DejaVuSansMono.woff);
}
html,body {
color:black; background-color:white; font-size:16px; padding:0; margin:0; font-family:DejaVuSansMono;
}
.test {
overflow:hidden;
width:100%;
white-space:nowrap;
}
span {
margin: 0 -2px;
}
.rlo {
unicode-bidi: bidi-override; direction:rtl;
}
.lro {
unicode-bidi: bidi-override;
}
.rtl {
direction:rtl;
}
.ltr {
direction:ltr;
}
.t1 { text-overflow:ellipsis ellipsis; }
.t2 { text-overflow:ellipsis clip; }
.t3 { text-overflow:clip ellipsis; }
.t4 { text-overflow:clip "."; }
.t5 { text-overflow:"." clip; }
.t6 { text-overflow:"." ","; }
.t7 { text-overflow:ellipsis ","; }
.t8 { text-overflow:"." ellipsis; }
</style>
</head><body>
<div style="float:left;">
|||||
<div class="test t1"><span>||||||</span></div>
<div class="test rtl t1"><span>||||||</span></div>
<div class="test t2"><span>||||||</span></div>
<div class="test rtl t2"><span>||||||</span></div>
<div class="test t3"><span>||||||</span></div>
<div class="test rtl t3"><span>||||||</span></div>
<div class="test t4"><span>||||||</span></div>
<div class="test rtl t4"><span>||||||</span></div>
<div class="test t5"><span>||||||</span></div>
<div class="test rtl t5"><span>||||||</span></div>
<div class="test t6"><span>||||||</span></div>
<div class="test rtl t6"><span>||||||</span></div>
<div class="test t7"><span>||||||</span></div>
<div class="test rtl t7"><span>||||||</span></div>
<div class="test t8"><span>||||||</span></div>
<div class="test rtl t8"><span>||||||</span></div>
</div>
</body>
</html>

View File

@ -513,6 +513,7 @@ protected:
PRBool ParseSize();
PRBool ParseTextDecoration();
PRBool ParseTextDecorationLine(nsCSSValue& aValue);
PRBool ParseTextOverflow(nsCSSValue& aValue);
PRBool ParseShadowItem(nsCSSValue& aValue, PRBool aIsBoxShadow);
PRBool ParseShadowList(nsCSSProperty aProperty);
@ -5601,6 +5602,8 @@ CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue,
return ParseMarks(aValue);
case eCSSProperty_text_decoration_line:
return ParseTextDecorationLine(aValue);
case eCSSProperty_text_overflow:
return ParseTextOverflow(aValue);
default:
NS_ABORT_IF_FALSE(PR_FALSE, "should not reach here");
return PR_FALSE;
@ -8118,6 +8121,27 @@ CSSParserImpl::ParseTextDecorationLine(nsCSSValue& aValue)
return PR_FALSE;
}
PRBool
CSSParserImpl::ParseTextOverflow(nsCSSValue& aValue)
{
if (ParseVariant(aValue, VARIANT_INHERIT, nsnull)) {
// 'inherit' and 'initial' must be alone
return PR_TRUE;
}
nsCSSValue left;
if (!ParseVariant(left, VARIANT_KEYWORD | VARIANT_STRING,
nsCSSProps::kTextOverflowKTable))
return PR_FALSE;
nsCSSValue right;
if (ParseVariant(right, VARIANT_KEYWORD | VARIANT_STRING,
nsCSSProps::kTextOverflowKTable))
aValue.SetPairValue(left, right);
else
aValue.SetPairValue(left, left);
return PR_TRUE;
}
PRBool
CSSParserImpl::ParseTransitionProperty()

View File

@ -2211,8 +2211,9 @@ CSS_PROP_TEXTRESET(
text-overflow,
text_overflow,
TextOverflow,
CSS_PROPERTY_PARSE_VALUE,
VARIANT_HK | VARIANT_STRING,
CSS_PROPERTY_PARSE_VALUE |
CSS_PROPERTY_VALUE_PARSER_FUNCTION,
0,
kTextOverflowKTable,
offsetof(nsStyleTextReset, mTextOverflow),
eStyleAnimType_None)

View File

@ -2449,19 +2449,35 @@ nsComputedDOMStyle::DoGetTextIndent()
nsIDOMCSSValue*
nsComputedDOMStyle::DoGetTextOverflow()
{
nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
const nsStyleTextReset *style = GetStyleTextReset();
if (style->mTextOverflow.mType == NS_STYLE_TEXT_OVERFLOW_STRING) {
nsROCSSPrimitiveValue *left = GetROCSSPrimitiveValue();
if (style->mTextOverflow.mLeft.mType == NS_STYLE_TEXT_OVERFLOW_STRING) {
nsString str;
nsStyleUtil::AppendEscapedCSSString(style->mTextOverflow.mString, str);
val->SetString(str);
nsStyleUtil::AppendEscapedCSSString(style->mTextOverflow.mLeft.mString, str);
left->SetString(str);
} else {
val->SetIdent(
nsCSSProps::ValueToKeywordEnum(style->mTextOverflow.mType,
left->SetIdent(
nsCSSProps::ValueToKeywordEnum(style->mTextOverflow.mLeft.mType,
nsCSSProps::kTextOverflowKTable));
}
return val;
if (style->mTextOverflow.mLeft == style->mTextOverflow.mRight) {
return left;
}
nsROCSSPrimitiveValue *right = GetROCSSPrimitiveValue();
if (style->mTextOverflow.mRight.mType == NS_STYLE_TEXT_OVERFLOW_STRING) {
nsString str;
nsStyleUtil::AppendEscapedCSSString(style->mTextOverflow.mRight.mString, str);
right->SetString(str);
} else {
right->SetIdent(
nsCSSProps::ValueToKeywordEnum(style->mTextOverflow.mRight.mType,
nsCSSProps::kTextOverflowKTable));
}
nsDOMCSSValueList *valueList = GetROCSSValueList(PR_FALSE);
valueList->AppendCSSValue(left);
valueList->AppendCSSValue(right);
return valueList;
}
nsIDOMCSSValue*

View File

@ -3495,22 +3495,41 @@ nsRuleNode::ComputeTextResetData(void* aStartStruct,
text->SetDecorationStyle(NS_STYLE_TEXT_DECORATION_STYLE_SOLID);
}
// text-overflow: enum, string, inherit, initial
// text-overflow: pair(enum|string), inherit, initial
const nsCSSValue* textOverflowValue =
aRuleData->ValueForTextOverflow();
if (eCSSUnit_Enumerated == textOverflowValue->GetUnit() ||
eCSSUnit_Initial == textOverflowValue->GetUnit()) {
SetDiscrete(*textOverflowValue, text->mTextOverflow.mType,
canStoreInRuleTree,
SETDSC_ENUMERATED, parentText->mTextOverflow.mType,
NS_STYLE_TEXT_OVERFLOW_CLIP, 0, 0, 0, 0);
text->mTextOverflow.mString.Truncate();
if (eCSSUnit_Initial == textOverflowValue->GetUnit()) {
text->mTextOverflow = nsStyleTextOverflow();
} else if (eCSSUnit_Inherit == textOverflowValue->GetUnit()) {
canStoreInRuleTree = PR_FALSE;
text->mTextOverflow = parentText->mTextOverflow;
} else if (eCSSUnit_String == textOverflowValue->GetUnit()) {
textOverflowValue->GetStringValue(text->mTextOverflow.mString);
text->mTextOverflow.mType = NS_STYLE_TEXT_OVERFLOW_STRING;
} else if (eCSSUnit_Pair == textOverflowValue->GetUnit()) {
const nsCSSValuePair& textOverflowValue =
aRuleData->ValueForTextOverflow()->GetPairValue();
const nsCSSValue *textOverflowLeftValue = &textOverflowValue.mXValue;
if (eCSSUnit_Enumerated == textOverflowLeftValue->GetUnit()) {
SetDiscrete(*textOverflowLeftValue, text->mTextOverflow.mLeft.mType,
canStoreInRuleTree,
SETDSC_ENUMERATED, parentText->mTextOverflow.mLeft.mType,
NS_STYLE_TEXT_OVERFLOW_CLIP, 0, 0, 0, 0);
text->mTextOverflow.mLeft.mString.Truncate();
} else if (eCSSUnit_String == textOverflowLeftValue->GetUnit()) {
textOverflowLeftValue->GetStringValue(text->mTextOverflow.mLeft.mString);
text->mTextOverflow.mLeft.mType = NS_STYLE_TEXT_OVERFLOW_STRING;
}
const nsCSSValue *textOverflowRightValue = &textOverflowValue.mYValue;
if (eCSSUnit_Enumerated == textOverflowRightValue->GetUnit()) {
SetDiscrete(*textOverflowRightValue, text->mTextOverflow.mRight.mType,
canStoreInRuleTree,
SETDSC_ENUMERATED, parentText->mTextOverflow.mRight.mType,
NS_STYLE_TEXT_OVERFLOW_CLIP, 0, 0, 0, 0);
text->mTextOverflow.mRight.mString.Truncate();
} else if (eCSSUnit_String == textOverflowRightValue->GetUnit()) {
textOverflowRightValue->GetStringValue(text->mTextOverflow.mRight.mString);
text->mTextOverflow.mRight.mType = NS_STYLE_TEXT_OVERFLOW_STRING;
}
}
// unicode-bidi: enum, inherit, initial

View File

@ -1131,15 +1131,15 @@ private:
}
};
struct nsStyleTextOverflow {
nsStyleTextOverflow() : mType(NS_STYLE_TEXT_OVERFLOW_CLIP) {}
struct nsStyleTextOverflowSide {
nsStyleTextOverflowSide() : mType(NS_STYLE_TEXT_OVERFLOW_CLIP) {}
bool operator==(const nsStyleTextOverflow& aOther) const {
bool operator==(const nsStyleTextOverflowSide& aOther) const {
return mType == aOther.mType &&
(mType != NS_STYLE_TEXT_OVERFLOW_STRING ||
mString == aOther.mString);
}
bool operator!=(const nsStyleTextOverflow& aOther) const {
bool operator!=(const nsStyleTextOverflowSide& aOther) const {
return !(*this == aOther);
}
@ -1147,6 +1147,18 @@ struct nsStyleTextOverflow {
PRUint8 mType;
};
struct nsStyleTextOverflow {
bool operator==(const nsStyleTextOverflow& aOther) const {
return mLeft == aOther.mLeft && mRight == aOther.mRight;
}
bool operator!=(const nsStyleTextOverflow& aOther) const {
return !(*this == aOther);
}
nsStyleTextOverflowSide mLeft;
nsStyleTextOverflowSide mRight;
};
struct nsStyleTextReset {
nsStyleTextReset(void);
nsStyleTextReset(const nsStyleTextReset& aOther);

View File

@ -2546,9 +2546,9 @@ var gCSSProperties = {
domProp: "textOverflow",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "clip" ],
other_values: [ "ellipsis", '""', "''", '"hello"' ],
invalid_values: [ "none", "auto" ]
initial_values: [ "clip", "clip clip" ],
other_values: [ "ellipsis", '""', "''", '"hello"', 'clip ellipsis', 'clip ""', '"hello" ""', '"" ellipsis' ],
invalid_values: [ "none", "auto", '"hello" inherit', 'inherit "hello"', 'clip initial', 'initial clip', 'initial inherit', 'inherit initial', 'inherit none']
},
"text-shadow": {
domProp: "textShadow",

View File

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<html:style><![CDATA[
window { -moz-box-align: start; -moz-box-pack: start }
hbox { background: yellow }
vbox { background: blue; width: 15px; height: 15px }
]]></html:style>
<hbox><vbox /><label value="a b c d e f" /></hbox>
</window>

View File

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<html:style><![CDATA[
window { -moz-box-align: start; -moz-box-pack: start }
hbox { background: yellow }
image { background: blue; min-width: 15px; min-height: 15px }
]]></html:style>
<hbox><image /><label value="a b c d e f" /></hbox>
</window>

View File

@ -1,4 +1,5 @@
== textbox-multiline-noresize.xul textbox-multiline-ref.xul
fails-if(Android) == textbox-multiline-noresize.xul textbox-multiline-ref.xul # reference is blank on Android (due to no native theme support?)
!= textbox-multiline-resize.xul textbox-multiline-ref.xul
== popup-explicit-size.xul popup-explicit-size-ref.xul
== image-size.xul image-size-ref.xul
== image-scaling-min-height-1.xul image-scaling-min-height-1-ref.xul

View File

@ -93,10 +93,10 @@ var ContentPopupHelper = {
},
/**
* This method positioned an arrowbox on the screen using a 'virtual'
* This method positions an arrowbox on the screen using a 'virtual'
* element as referrer that match the real content element
* This method called element.getBoundingClientRect() many times and can be
* expensive, do not called it too many times.
* This method calls element.getBoundingClientRect() many times and can be
* expensive, do not call it too many times.
*/
anchorTo: function(aAnchorRect) {
let popup = this._popup;
@ -210,18 +210,21 @@ var ContentPopupHelper = {
case "PanBegin":
case "AnimatedZoomBegin":
popup.left = 0;
popup.style.visibility = "hidden";
break;
case "PanFinished":
case "AnimatedZoomEnd":
popup.style.visibility = "visible";
this.anchorTo();
break;
case "MozBeforeResize":
popup.left = 0;
popup.style.visibility = "hidden";
// When screen orientation changes, we have to ensure that
// the popup width doesn't overflow the content's visible
// area.
popup.firstChild.style.maxWidth = "0px";
break;
case "resize":

View File

@ -53,11 +53,6 @@ var ContextCommands = {
Browser.addTab(ContextHelper.popupState.linkURL, false, Browser.selectedTab);
},
saveLink: function cc_saveLink() {
let browser = ContextHelper.popupState.target;
ContentAreaUtils.saveURL(ContextHelper.popupState.linkURL, null, "SaveLinkTitle", false, true, browser.documentURI);
},
saveImage: function cc_saveImage() {
let popupState = ContextHelper.popupState;
let browser = popupState.target;

View File

@ -5,8 +5,6 @@ let Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
dump("!! remote browser loaded\n");
let WebProgressListener = {
init: function() {
let flags = Ci.nsIWebProgress.NOTIFY_LOCATION |

View File

@ -272,31 +272,33 @@ var BrowserUI = {
let awesomePanel = document.getElementById("awesome-panels");
let awesomeHeader = document.getElementById("awesome-header");
let willShowPanel = (!this._activePanel && aPanel);
if (willShowPanel) {
this.pushDialog(aPanel);
this._edit.attachController();
this._editURI();
awesomePanel.hidden = awesomeHeader.hidden = false;
};
if (aPanel) {
aPanel.open();
if (this._edit.value == "")
this._showURI();
}
let willHidePanel = (this._activePanel && !aPanel);
if (willHidePanel) {
awesomePanel.hidden = true;
awesomeHeader.hidden = false;
this._edit.reset();
this._edit.detachController();
this.popDialog();
}
if (this._activePanel)
if (this._activePanel) {
this.popDialog();
this._activePanel.close();
}
let willShowPanel = (!this._activePanel && aPanel);
if (willShowPanel) {
this._edit.attachController();
this._editURI();
awesomePanel.hidden = awesomeHeader.hidden = false;
};
if (aPanel) {
this.pushDialog(aPanel);
aPanel.open();
if (this._edit.value == "")
this._showURI();
}
// If the keyboard will cover the full screen, we do not want to show it right away.
let isReadOnly = (aPanel != AllPagesList || this._isKeyboardFullscreen() || (!willShowPanel && this._edit.readOnly));
@ -888,16 +890,16 @@ var BrowserUI = {
return;
}
// Check active panel
if (this.activePanel) {
this.activePanel = null;
// Check open dialogs
let dialog = this.activeDialog;
if (dialog && dialog != this.activePanel) {
dialog.close();
return;
}
// Check open dialogs
let dialog = this.activeDialog;
if (dialog) {
dialog.close();
// Check active panel
if (this.activePanel) {
this.activePanel = null;
return;
}
@ -1261,11 +1263,13 @@ var BrowserUI = {
break;
case "cmd_remoteTabs":
if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED) {
// We have to set activePanel before showing sync's dialog
// to make the sure the dialog stacking is correct.
this.activePanel = RemoteTabsList;
WeaveGlue.open();
} else if (!Weave.Service.isLoggedIn && !Services.prefs.getBoolPref("browser.sync.enabled")) {
// unchecked the relative command button
document.getElementById("remotetabs-button").removeAttribute("checked");
this.activePanel = null;
BrowserUI.showPanel("prefs-container");
let prefsBox = document.getElementById("prefs-list");
@ -1277,11 +1281,10 @@ var BrowserUI = {
prefsBox.scrollBoxObject.scrollTo(0, syncAreaY - prefsBoxY);
}, 0);
}
return;
} else {
this.activePanel = RemoteTabsList;
}
this.activePanel = RemoteTabsList;
break;
case "cmd_quit":
// Only close one window

View File

@ -2930,8 +2930,7 @@ Tab.prototype = {
if (isDefault) {
if (browser.scale != this._defaultZoomLevel) {
browser.scale = this._defaultZoomLevel;
}
else {
} else {
// If the scale level has not changed we want to be sure the content
// render correctly since the page refresh process could have been
// stalled during page load. In this case if the page has the exact

View File

@ -639,9 +639,6 @@
<richlistitem class="context-command" id="context-bookmark-link" type="link" onclick="ContextCommands.bookmarkLink();">
<label value="&contextBookmarkLink.label;"/>
</richlistitem>
<richlistitem class="context-command" id="context-savelink" type="link-saveable" onclick="ContextCommands.saveLink();">
<label value="&contextSaveLink.label;"/>
</richlistitem>
<richlistitem class="context-command" id="context-saveimage" type="image-loaded" onclick="ContextCommands.saveImage();">
<label value="&contextSaveImage.label;"/>
</richlistitem>

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