mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
merge the last green changeset on fx-team to m-c
This commit is contained in:
commit
456dc55387
@ -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 \
|
||||
|
54
browser/base/content/test/browser_canonizeURL.js
Normal file
54
browser/base/content/test/browser_canonizeURL.js
Normal 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();
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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 }
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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"/>
|
||||
|
@ -52,8 +52,6 @@ endif
|
||||
|
||||
CPPSRCS = nsProfileMigrator.cpp \
|
||||
nsBrowserProfileMigratorUtils.cpp \
|
||||
nsNetscapeProfileMigratorBase.cpp \
|
||||
nsSeamonkeyProfileMigrator.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifneq ($(OS_ARCH),OS2)
|
||||
|
@ -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(®FileExists);
|
||||
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(), ®))) {
|
||||
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", ®Info))
|
||||
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;
|
||||
}
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
@ -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;
|
||||
|
@ -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);"
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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'…
|
||||
|
||||
|
2809
config/gtscc.c
2809
config/gtscc.c
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
8
content/events/test/file_bug679494.html
Normal file
8
content/events/test/file_bug679494.html
Normal file
@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 679494</title>
|
||||
</head>
|
||||
<body>
|
||||
There and back again.
|
||||
</body>
|
||||
</html>
|
37
content/events/test/test_bug679494.xul
Normal file
37
content/events/test/test_bug679494.xul
Normal 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>
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
116
content/html/content/src/nsHTMLTableElement.h
Normal file
116
content/html/content/src/nsHTMLTableElement.h
Normal 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;
|
||||
}
|
||||
};
|
||||
|
@ -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)) ||
|
||||
|
@ -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.
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
@ -51,6 +51,7 @@ interface nsIDOMMessageEvent : nsIDOMEvent
|
||||
/**
|
||||
* Custom string data associated with this event.
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
readonly attribute jsval data;
|
||||
|
||||
/**
|
||||
|
@ -74,7 +74,6 @@ interface nsIDOMSVGSVGElement
|
||||
nsIDOMSVGFitToViewBox,
|
||||
nsIDOMSVGZoomAndPan,
|
||||
events::nsIDOMEventTarget,
|
||||
css::nsIDOMDocumentCSS
|
||||
*/
|
||||
{
|
||||
readonly attribute nsIDOMSVGAnimatedLength x;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
126
dom/system/unix/nsQTMDeviceMotionSystem.cpp
Normal file
126
dom/system/unix/nsQTMDeviceMotionSystem.cpp
Normal 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();
|
||||
}
|
100
dom/system/unix/nsQTMDeviceMotionSystem.h
Normal file
100
dom/system/unix/nsQTMDeviceMotionSystem.h
Normal 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 */
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
22
gfx/cairo/fixup-unbounded.patch
Normal file
22
gfx/cairo/fixup-unbounded.patch
Normal 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);
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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; }
|
||||
|
@ -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;
|
||||
}
|
||||
|
12
js/src/xpconnect/tests/unit/test_bug677864.js
Normal file
12
js/src/xpconnect/tests/unit/test_bug677864.js
Normal 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');
|
||||
}
|
@ -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]
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
40
layout/reftests/bugs/175190-1-ref.html
Normal file
40
layout/reftests/bugs/175190-1-ref.html
Normal 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>
|
41
layout/reftests/bugs/175190-1.html
Normal file
41
layout/reftests/bugs/175190-1.html
Normal 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>
|
26
layout/reftests/bugs/186317-1-ref.html
Normal file
26
layout/reftests/bugs/186317-1-ref.html
Normal 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>
|
24
layout/reftests/bugs/186317-1.html
Normal file
24
layout/reftests/bugs/186317-1.html
Normal 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>
|
20
layout/reftests/bugs/260406-1-ref.html
Normal file
20
layout/reftests/bugs/260406-1-ref.html
Normal 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>
|
20
layout/reftests/bugs/260406-1.html
Normal file
20
layout/reftests/bugs/260406-1.html
Normal 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>
|
BIN
layout/reftests/bugs/260406.gif
Normal file
BIN
layout/reftests/bugs/260406.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 954 B |
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Before Width: | Height: | Size: 1017 B After Width: | Height: | Size: 1017 B |
28
layout/reftests/svg/dynamic-filter-contents-01b.svg
Normal file
28
layout/reftests/svg/dynamic-filter-contents-01b.svg
Normal 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 |
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
66
layout/reftests/text-overflow/two-value-syntax-ref.html
Normal file
66
layout/reftests/text-overflow/two-value-syntax-ref.html
Normal 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:<left> <right></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> …||…</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>
|
75
layout/reftests/text-overflow/two-value-syntax.html
Normal file
75
layout/reftests/text-overflow/two-value-syntax.html
Normal 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:<left> <right></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>
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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*
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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",
|
||||
|
14
layout/xul/base/reftest/image-scaling-min-height-1-ref.xul
Normal file
14
layout/xul/base/reftest/image-scaling-min-height-1-ref.xul
Normal 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>
|
14
layout/xul/base/reftest/image-scaling-min-height-1.xul
Normal file
14
layout/xul/base/reftest/image-scaling-min-height-1.xul
Normal 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>
|
@ -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
|
||||
|
@ -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":
|
||||
|
@ -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;
|
||||
|
@ -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 |
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user