Merge mozilla-central to tracemonkey.

This commit is contained in:
Robert Sayre 2009-07-16 11:46:05 -04:00
commit 46f17eb174
66 changed files with 3442 additions and 498 deletions

View File

@ -1507,17 +1507,12 @@ SessionStoreService.prototype = {
_updateCookieHosts: function sss_updateCookieHosts(aWindow) {
var hosts = this._windows[aWindow.__SSi]._hosts = {};
// get all possible subdomain levels for a given URL
var _this = this;
// get the domain for each URL
function extractHosts(aEntry) {
if (/^https?:\/\/(?:[^@\/\s]+@)?([\w.-]+)/.test(aEntry.url) &&
!hosts[RegExp.$1] && _this._checkPrivacyLevel(_this._getURIFromString(aEntry.url).schemeIs("https"))) {
var host = RegExp.$1;
var ix;
for (ix = host.indexOf(".") + 1; ix; ix = host.indexOf(".", ix) + 1) {
hosts[host.substr(ix)] = true;
if (/^https?:\/\/(?:[^@\/\s]+@)?([\w.-]+)/.test(aEntry.url)) {
if (!hosts[RegExp.$1] && this._checkPrivacyLevel(this._getURIFromString(aEntry.url).schemeIs("https"))) {
hosts[RegExp.$1] = true;
}
hosts[host] = true;
}
else if (/^file:\/\/([^\/]*)/.test(aEntry.url)) {
hosts[RegExp.$1] = true;
@ -1526,8 +1521,8 @@ SessionStoreService.prototype = {
aEntry.children.forEach(extractHosts);
}
}
this._windows[aWindow.__SSi].tabs.forEach(function(aTabData) { aTabData.entries.forEach(extractHosts); });
this._windows[aWindow.__SSi].tabs.forEach(function(aTabData) { aTabData.entries.forEach(extractHosts, this); }, this);
},
/**
@ -1536,36 +1531,59 @@ SessionStoreService.prototype = {
* array of Window references
*/
_updateCookies: function sss_updateCookies(aWindows) {
var cookiesEnum = Cc["@mozilla.org/cookiemanager;1"].
getService(Ci.nsICookieManager).enumerator;
function addCookieToHash(aHash, aHost, aPath, aName, aCookie) {
// lazily build up a 3-dimensional hash, with
// aHost, aPath, and aName as keys
if (!aHash[aHost])
aHash[aHost] = {};
if (!aHash[aHost][aPath])
aHash[aHost][aPath] = {};
if (!aHash[aHost][aPath][aName])
aHash[aHost][aPath][aName] = {};
aHash[aHost][aPath][aName] = aCookie;
}
var cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
// collect the cookies per window
for (var i = 0; i < aWindows.length; i++)
aWindows[i].cookies = [];
var jscookies = {};
// MAX_EXPIRY should be 2^63-1, but JavaScript can't handle that precision
var MAX_EXPIRY = Math.pow(2, 62);
while (cookiesEnum.hasMoreElements()) {
var cookie = cookiesEnum.getNext().QueryInterface(Ci.nsICookie2);
if (cookie.isSession && this._checkPrivacyLevel(cookie.isSecure)) {
var jscookie = null;
aWindows.forEach(function(aWindow) {
if (aWindow._hosts && aWindow._hosts[cookie.rawHost]) {
// serialize the cookie when it's first needed
if (!jscookie) {
jscookie = { host: cookie.host, value: cookie.value };
aWindows.forEach(function(aWindow) {
for (var host in aWindow._hosts) {
var list = cm.getCookiesFromHost(host);
while (list.hasMoreElements()) {
var cookie = list.getNext().QueryInterface(Ci.nsICookie2);
if (cookie.isSession && this._checkPrivacyLevel(cookie.isSecure)) {
// use the cookie's host, path, and name as keys into a hash,
// to make sure we serialize each cookie only once
var isInHash = false;
try {
if (jscookies[cookie.host][cookie.path][cookie.name])
isInHash = true;
} catch (e) {
// not in hash yet
}
if (!isInHash) {
var jscookie = { "host": cookie.host, "value": cookie.value };
// only add attributes with non-default values (saving a few bits)
if (cookie.path) jscookie.path = cookie.path;
if (cookie.name) jscookie.name = cookie.name;
if (cookie.isSecure) jscookie.secure = true;
if (cookie.isHttpOnly) jscookie.httponly = true;
if (cookie.expiry < MAX_EXPIRY) jscookie.expiry = cookie.expiry;
addCookieToHash(jscookies, cookie.host, cookie.path, cookie.name, jscookie);
}
aWindow.cookies.push(jscookie);
aWindow.cookies.push(jscookies[cookie.host][cookie.path][cookie.name]);
}
});
}
}
}
}, this);
// don't include empty cookie sections
for (i = 0; i < aWindows.length; i++)
if (aWindows[i].cookies.length == 0)

View File

@ -64,6 +64,8 @@ _BROWSER_TEST_FILES = \
browser_394759_privatebrowsing.js \
browser_408470.js \
browser_408470_sample.html \
browser_423132.js \
browser_423132_sample.html \
browser_447951.js \
browser_447951_sample.html \
browser_448741.js \

View File

@ -0,0 +1,107 @@
/* ***** 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 sessionstore test code.
*
* The Initial Developer of the Original Code is
* Daniel Witte <dwitte@mozilla.com>.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 ***** */
function test() {
// test that cookies are stored and restored correctly by sessionstore,
// bug 423132.
// test setup
waitForExplicitFinish();
let cs = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
cs.removeAll();
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
// make sure that sessionstore.js can be forced to be created by setting
// the interval pref to 0
gPrefService.setIntPref("browser.sessionstore.interval", 0);
const testURL = "http://localhost:8888/browser/" +
"browser/components/sessionstore/test/browser/browser_423132_sample.html";
// open a new window
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", "about:blank");
// make sure sessionstore saves the cookie data, then close the window
newWin.addEventListener("load", function (aEvent) {
newWin.removeEventListener("load", arguments.callee, false);
newWin.gBrowser.selectedBrowser.loadURI(testURL, null, null);
newWin.gBrowser.addEventListener("load", function (aEvent) {
newWin.gBrowser.removeEventListener("load", arguments.callee, true);
// get the sessionstore state for the window
let state = ss.getWindowState(newWin);
// verify our cookie got set during pageload
let e = cs.enumerator;
let cookie;
let i = 0;
while (e.hasMoreElements()) {
cookie = e.getNext().QueryInterface(Ci.nsICookie);
i++;
}
is(i, 1, "expected one cookie");
// remove the cookie
cs.removeAll();
// restore the window state
ss.setWindowState(newWin, state, true);
// at this point, the cookie should be restored...
e = cs.enumerator;
let cookie2;
while (e.hasMoreElements()) {
cookie2 = e.getNext().QueryInterface(Ci.nsICookie);
if (cookie.name == cookie2.name)
break;
}
is(cookie.name, cookie2.name, "cookie name successfully restored");
is(cookie.value, cookie2.value, "cookie value successfully restored");
is(cookie.path, cookie2.path, "cookie path successfully restored");
// clean up
gPrefService.clearUserPref("browser.sessionstore.interval");
cs.removeAll();
newWin.close();
finish();
}, true);
}, false);
}

View File

@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">
// generate an enormous random number...
var r = Math.floor(Math.random() * Math.pow(2, 62)).toString();
// ... and use it to set a randomly named cookie
document.cookie = r + "=value; path=/ohai";
</script>
<body>
</body>
</html>

View File

@ -1,4 +1,4 @@
#
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#

View File

@ -85,7 +85,7 @@ nsSMILAnimationController::~nsSMILAnimationController()
nsSMILAnimationController* NS_NewSMILAnimationController(nsIDocument* aDoc)
{
nsSMILAnimationController* animationController =
nsSMILAnimationController* animationController =
new nsSMILAnimationController();
NS_ENSURE_TRUE(animationController, nsnull);
@ -241,7 +241,7 @@ nsSMILAnimationController::StartTimer()
// Run the first sample manually
Sample();
//
//
// XXX Make this self-tuning. Sounds like control theory to me and not
// something I'm familiar with.
//
@ -267,7 +267,7 @@ RemoveCompositorFromTable(nsSMILCompositor* aCompositor,
void* aData)
{
nsSMILCompositorTable* lastCompositorTable =
static_cast<nsSMILCompositorTable*>(aData);
static_cast<nsSMILCompositorTable*>(aData);
lastCompositorTable->RemoveEntry(aCompositor->GetKey());
return PL_DHASH_NEXT;
}
@ -312,7 +312,7 @@ nsSMILAnimationController::DoSample(PRBool aSkipUnchangedContainers)
// STEP 2: (i) Sample the timed elements AND
// (ii) Create a table of compositors
//
//
// (i) Here we sample the timed elements (fetched from the
// nsISMILAnimationElements) which determine from the active time if the
// element is active and what its simple time etc. is. This information is
@ -331,7 +331,7 @@ nsSMILAnimationController::DoSample(PRBool aSkipUnchangedContainers)
// save iterating over the animation elements twice.
// Create the compositor table
nsAutoPtr<nsSMILCompositorTable>
nsAutoPtr<nsSMILCompositorTable>
currentCompositorTable(new nsSMILCompositorTable());
if (!currentCompositorTable)
return;
@ -371,12 +371,12 @@ nsSMILAnimationController::DoSample(PRBool aSkipUnchangedContainers)
/*static*/ PR_CALLBACK PLDHashOperator
nsSMILAnimationController::SampleTimeContainer(TimeContainerPtrKey* aKey,
void* aData)
{
{
NS_ENSURE_TRUE(aKey, PL_DHASH_NEXT);
NS_ENSURE_TRUE(aKey->GetKey(), PL_DHASH_NEXT);
NS_ENSURE_TRUE(aData, PL_DHASH_NEXT);
SampleTimeContainerParams* params =
SampleTimeContainerParams* params =
static_cast<SampleTimeContainerParams*>(aData);
nsSMILTimeContainer* container = aKey->GetKey();
@ -441,7 +441,7 @@ nsSMILAnimationController::AddAnimationToCompositorTable(
return;
nsSMILCompositor* result = aCompositorTable->PutEntry(key);
// Add this animationElement's animation function to the compositor's list of
// animation functions.
result->AddAnimationFunction(&aElement->AnimationFunction());
@ -506,7 +506,7 @@ nsSMILAnimationController::AddChild(nsSMILTimeContainer& aChild)
if (!mPauseState && mChildContainerTable.Count() == 1) {
StartTimer();
}
return NS_OK;
}

View File

@ -53,7 +53,7 @@ class nsIDocument;
//----------------------------------------------------------------------
// nsSMILAnimationController
//
//
// The animation controller maintains the animation timer and determines the
// sample times and sample rate for all SMIL animations in a document. There is
// at most one animation controller per nsDocument so that frame-rate tuning can
@ -74,7 +74,7 @@ public:
virtual void Pause(PRUint32 aType);
virtual void Resume(PRUint32 aType);
virtual nsSMILTime GetParentTime() const;
// Methods for registering and enumerating animation elements
void RegisterAnimationElement(nsISMILAnimationElement* aAnimationElement);
void UnregisterAnimationElement(nsISMILAnimationElement* aAnimationElement);
@ -118,7 +118,7 @@ protected:
TimeContainerHashtable* mActiveContainers;
nsSMILCompositorTable* mCompositorTable;
};
// Factory methods
friend nsSMILAnimationController*
NS_NewSMILAnimationController(nsIDocument* aDoc);
@ -159,14 +159,14 @@ protected:
AnimationElementHashtable mAnimationElementTable;
TimeContainerHashtable mChildContainerTable;
PRPackedBool mResampleNeeded;
// Store raw ptr to mDocument. It owns the controller, so controller
// shouldn't outlive it
nsIDocument* mDocument;
// Contains compositors used in our last sample. We keep this around
// so we can detect when an element/attribute used to be animated,
// but isn't anymore for some reason. (e.g. if its <animate> element is
// but isn't anymore for some reason. (e.g. if its <animate> element is
// removed or retargeted)
nsAutoPtr<nsSMILCompositorTable> mLastCompositorTable;
};

View File

@ -188,8 +188,8 @@ nsSMILAnimationFunction::SampleAt(nsSMILTime aSampleTime,
const nsSMILTimeValue& aSimpleDuration,
PRUint32 aRepeatIteration)
{
if (mHasChanged || mLastValue || mSampleTime != aSampleTime ||
mSimpleDuration.CompareTo(aSimpleDuration) ||
if (mHasChanged || mLastValue || mSampleTime != aSampleTime ||
mSimpleDuration.CompareTo(aSimpleDuration) ||
mRepeatIteration != aRepeatIteration) {
mHasChanged = PR_TRUE;
}
@ -250,12 +250,12 @@ nsSMILAnimationFunction::ComposeResult(const nsISMILAttr& aSMILAttr,
// (Otherwise, we're probably just frozen.)
if (mIsActive) {
NS_ENSURE_TRUE(mSampleTime >= 0,);
NS_ENSURE_TRUE(mSimpleDuration.IsResolved() ||
NS_ENSURE_TRUE(mSimpleDuration.IsResolved() ||
mSimpleDuration.IsIndefinite(),);
}
nsSMILValue result(aResult.mType);
if (mSimpleDuration.IsIndefinite() ||
(HasAttr(nsGkAtoms::values) && values.Length() == 1)) {
@ -339,7 +339,7 @@ nsSMILAnimationFunction::WillReplace() const
* here we return false for to animation as it builds on the underlying value
* unless its a frozen to animation.
*/
return !(IsAdditive() || IsToAnimation()) ||
return !(IsAdditive() || IsToAnimation()) ||
(IsToAnimation() && mIsFrozen && !mHasChanged);
}
@ -371,7 +371,7 @@ nsSMILAnimationFunction::InterpolateResult(const nsSMILValueArray& aValues,
return NS_ERROR_FAILURE;
}
if ((!IsToAnimation() && aValues.Length() < 2) ||
if ((!IsToAnimation() && aValues.Length() < 2) ||
(IsToAnimation() && aValues.Length() != 1)) {
NS_ERROR("Unexpected number of values.");
return NS_ERROR_FAILURE;
@ -411,7 +411,7 @@ nsSMILAnimationFunction::InterpolateResult(const nsSMILValueArray& aValues,
(PRUint32) floor(simpleProgress * (aValues.Length()));
aResult = aValues[index];
return NS_OK;
}
}
// Get the normalised progress between adjacent values
double intervalProgress;
@ -423,7 +423,7 @@ nsSMILAnimationFunction::InterpolateResult(const nsSMILValueArray& aValues,
intervalProgress = simpleProgress;
ScaleIntervalProgress(intervalProgress, 0, 1);
} else {
if (GetCalcMode() == CALC_PACED) {
if (GetCalcMode() == CALC_PACED) {
rv = ComputePacedPosition(aValues, simpleProgress, intervalProgress,
from, to);
NS_ENSURE_SUCCESS(rv,rv);
@ -588,7 +588,7 @@ nsSMILAnimationFunction::ScaleSimpleProgress(double& aProgress)
return;
}
aProgress = (i + (aProgress - intervalStart) / intervalLength) *
aProgress = (i + (aProgress - intervalStart) / intervalLength) *
1.0 / double(numTimes - 1);
}
@ -607,7 +607,7 @@ nsSMILAnimationFunction::ScaleIntervalProgress(double& aProgress,
if (!HasAttr(nsGkAtoms::keySplines))
return;
NS_ASSERTION(aIntervalIndex >= 0 &&
NS_ASSERTION(aIntervalIndex >= 0 &&
aIntervalIndex < (PRUint32)mKeySplines.Length(),
"Invalid interval index.");
NS_ASSERTION(aNumIntervals >= 1, "Invalid number of intervals.");
@ -656,7 +656,7 @@ nsSMILAnimationFunction::ParseAttr(nsIAtom* aAttName,
{
nsAutoString attValue;
if (GetAttr(aAttName, attValue)) {
nsresult rv =
nsresult rv =
aSMILAttr.ValueFromString(attValue, mAnimationElement, aResult);
if (NS_FAILED(rv))
return PR_FALSE;
@ -740,14 +740,14 @@ nsSMILAnimationFunction::GetValues(const nsISMILAttr& aSMILAttr,
CheckKeySplines(result.Length());
result.SwapElements(aResult);
return NS_OK;
}
inline PRBool
nsSMILAnimationFunction::IsToAnimation() const
{
return !HasAttr(nsGkAtoms::values) &&
return !HasAttr(nsGkAtoms::values) &&
HasAttr(nsGkAtoms::to) &&
!HasAttr(nsGkAtoms::from);
}
@ -894,7 +894,7 @@ nsSMILAnimationFunction::SetAccumulate(const nsAString& aAccumulate,
nsAttrValue& aResult)
{
mHasChanged = PR_TRUE;
PRBool parseResult =
PRBool parseResult =
aResult.ParseEnumValue(aAccumulate, sAccumulateTable, PR_TRUE);
SET_FLAG(mErrorFlags, BF_ACCUMULATE, !parseResult);
return parseResult ? NS_OK : NS_ERROR_FAILURE;
@ -912,7 +912,7 @@ nsSMILAnimationFunction::SetAdditive(const nsAString& aAdditive,
nsAttrValue& aResult)
{
mHasChanged = PR_TRUE;
PRBool parseResult
PRBool parseResult
= aResult.ParseEnumValue(aAdditive, sAdditiveTable, PR_TRUE);
SET_FLAG(mErrorFlags, BF_ADDITIVE, !parseResult);
return parseResult ? NS_OK : NS_ERROR_FAILURE;
@ -930,7 +930,7 @@ nsSMILAnimationFunction::SetCalcMode(const nsAString& aCalcMode,
nsAttrValue& aResult)
{
mHasChanged = PR_TRUE;
PRBool parseResult
PRBool parseResult
= aResult.ParseEnumValue(aCalcMode, sCalcModeTable, PR_TRUE);
SET_FLAG(mErrorFlags, BF_CALC_MODE, !parseResult);
return parseResult ? NS_OK : NS_ERROR_FAILURE;

View File

@ -174,7 +174,7 @@ public:
* operations by only composing those animation that will affect the final
* result.
*/
/**
* Indicates if the animation is currently active. Inactive animations will
* not contribute to the composed result.
@ -183,7 +183,7 @@ public:
*/
PRBool IsActive() const
{
/*
/*
* - Frozen animations should be considered active for the purposes of
* compositing.
* - This function does not assume that our nsSMILValues (by/from/to/values)
@ -323,7 +323,7 @@ protected:
PRPackedBool mHasChanged;
nsSMILTime mBeginTime; // document time
// The owning animation element. This is used for sorting based on document
// position and for fetching attribute values stored in the element.
// Raw pointer is OK here, because this nsSMILAnimationFunction can't outlive

View File

@ -136,7 +136,7 @@ nsSMILCompositor::ComposeAttribute()
changed = PR_TRUE;
}
*/
if (curAnimFunc->WillReplace()) {
--i;
break;
@ -165,7 +165,7 @@ nsSMILCompositor::ComposeAttribute()
nsresult rv = smilAttr->SetAnimValue(resultValue);
if (NS_FAILED(rv)) {
NS_WARNING("nsISMILAttr::SetAnimValue failed");
}
}
}
void

View File

@ -93,7 +93,7 @@ public:
// Adds the given animation function to this Compositor's list of functions
void AddAnimationFunction(nsSMILAnimationFunction* aFunc);
// Composes the attribute's current value with the list of animation
// functions, and assigns the resulting value to this compositor's target
// attribute

View File

@ -88,7 +88,7 @@ nsSMILFloatType::ComputeDistance(const nsSMILValue& aFrom,
{
NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
const double &from = aFrom.mU.mDouble;
const double &to = aTo.mU.mDouble;

View File

@ -45,7 +45,7 @@
//
// This class is essentially a structure consisting of a begin and end time. It
// is used for representing the current interval and also for storing past
// intervals for the purpose of hyperlinking back in time.
// intervals for the purpose of hyperlinking back in time.
//
// For an overview of how this class is related to other SMIL time classes see
// the documentstation in nsSMILTimeValue.h

View File

@ -40,7 +40,7 @@
#define NEWTON_ITERATIONS 4
const double nsSMILKeySpline::kSampleStepSize =
const double nsSMILKeySpline::kSampleStepSize =
1.0 / double(kSplineTableSize - 1);
nsSMILKeySpline::nsSMILKeySpline(double aX1,
@ -78,7 +78,8 @@ nsSMILKeySpline::CalcBezier(double aT,
double aA1,
double aA2)
{
return A(aA1, aA2) * pow(aT,3) + B(aA1, aA2)*aT*aT + C(aA1) * aT;
// use Horner's scheme to evaluate the Bezier polynomial
return ((A(aA1, aA2)*aT + B(aA1, aA2))*aT + C(aA1))*aT;
}
/*static*/ double
@ -86,7 +87,7 @@ nsSMILKeySpline::GetSlope(double aT,
double aA1,
double aA2)
{
double denom = (3.0 * A(aA1, aA2)*aT*aT + 2.0 * B(aA1, aA2) * aT + C(aA1));
double denom = (3.0 * A(aA1, aA2)*aT*aT + 2.0 * B(aA1, aA2) * aT + C(aA1));
return (denom == 0.0) ? 0.0 : 1.0 / denom;
}
@ -102,7 +103,7 @@ nsSMILKeySpline::GetTForX(double aX) const
// to converge to a good accuracy. By taking an initial guess in this way we
// only need 3~4 iterations depending on the size of the table.
for (i = 0; i < kSplineTableSize - 2 && mSampleValues[i] < aX; ++i);
double currentT =
double currentT =
double(i) * kSampleStepSize + (aX - mSampleValues[i]) * kSampleStepSize;
// Refine with Newton-Raphson iteration

View File

@ -80,7 +80,7 @@ private:
{
return 1.0 - 3.0 * aA2 + 3.0 * aA1;
}
static double
B(double aA1, double aA2)
{

View File

@ -223,7 +223,7 @@ nsSMILParserUtils::ParseKeyTimes(const nsAString& aSpec,
SkipWsp(start, end);
if (start == end)
break;
if (*start++ != ';') {
rv = NS_ERROR_FAILURE;
break;
@ -238,7 +238,7 @@ nsSMILParserUtils::ParseKeyTimes(const nsAString& aSpec,
nsresult
nsSMILParserUtils::ParseValues(const nsAString& aSpec,
const nsISMILAnimationElement* aSrcElement,
const nsISMILAttr& aAttribute,
const nsISMILAttr& aAttribute,
nsTArray<nsSMILValue>& aValuesArray)
{
nsresult rv = NS_ERROR_FAILURE;
@ -275,7 +275,7 @@ nsSMILParserUtils::ParseValues(const nsAString& aSpec,
++substr_end;
nsSMILValue newValue;
rv = aAttribute.ValueFromString(Substring(start, substr_end),
rv = aAttribute.ValueFromString(Substring(start, substr_end),
aSrcElement, newValue);
if (NS_FAILED(rv))
break;
@ -305,7 +305,7 @@ nsSMILParserUtils::ParseRepeatCount(const nsAString& aSpec,
spec.EndReading(end);
SkipWsp(start, end);
if (start != end)
{
if (ConsumeSubstring(start, end, "indefinite")) {
@ -343,7 +343,7 @@ nsSMILParserUtils::ParseRepeatCount(const nsAString& aSpec,
nsresult
nsSMILParserUtils::ParseClockValue(const nsAString& aSpec,
nsSMILTimeValue* aResult,
nsSMILTimeValue* aResult,
PRUint32 aFlags, // = 0
PRBool* aIsMedia) // = nsnull
{
@ -568,7 +568,7 @@ nsSMILParserUtils::ParseMetricMultiplicand(nsACString::const_iterator& aSpec,
size_t len = aEnd.get() - aSpec.get();
nsACString::const_iterator spec(aSpec);
if (len) {
switch (*spec++)
{

View File

@ -102,7 +102,7 @@ public:
* (according to aFlags), an error code otherwise.
*/
static nsresult ParseClockValue(const nsAString& aSpec,
nsSMILTimeValue* aResult,
nsSMILTimeValue* aResult,
PRUint32 aFlags = 0,
PRBool* aIsMedia = nsnull);

View File

@ -43,7 +43,7 @@
//----------------------------------------------------------------------
// nsSMILTimeContainer
//
//
// Common base class for a time base that can be paused, resumed, and sampled.
//
class nsSMILTimeContainer

View File

@ -91,10 +91,10 @@ nsSMILTimeValueSpec::SetSpec(const nsAString& aStringSpec)
if (NS_FAILED(rv) || (!clockTime.IsResolved() && !clockTime.IsIndefinite()))
return NS_ERROR_FAILURE;
if (clockTime.IsResolved())
mOffset = clockTime.GetMillis();
if (mOwner) {
nsSMILInstanceTime instance(clockTime, this);
mOwner->AddInstanceTime(instance, mIsBegin);

View File

@ -185,7 +185,7 @@ nsSMILTimedElement::GetStartTime() const
if (!startTime.IsResolved()) {
startTime.SetIndefinite();
}
return startTime;
}
@ -237,7 +237,7 @@ nsSMILTimedElement::SampleAt(nsSMILTime aDocumentTime)
nsSMILTimeValue beginAfter;
beginAfter.SetMillis(LL_MININT);
mElementState =
mElementState =
(NS_SUCCEEDED(GetNextInterval(beginAfter, PR_TRUE, mCurrentInterval)))
? STATE_WAITING
: STATE_POSTACTIVE;
@ -262,7 +262,7 @@ nsSMILTimedElement::SampleAt(nsSMILTime aDocumentTime)
CheckForEarlyEnd(docTime);
if (mCurrentInterval.mEnd.CompareTo(docTime) <= 0) {
nsSMILInterval newInterval;
mElementState =
mElementState =
(NS_SUCCEEDED(GetNextInterval(mCurrentInterval.mEnd,
PR_FALSE,
newInterval)))
@ -442,7 +442,7 @@ nsSMILTimedElement::SetSimpleDuration(const nsAString& aDurSpec)
nsSMILTimeValue duration;
PRBool isMedia;
nsresult rv;
rv = nsSMILParserUtils::ParseClockValue(aDurSpec, &duration,
nsSMILParserUtils::kClockValueAllowIndefinite, &isMedia);
@ -450,7 +450,7 @@ nsSMILTimedElement::SetSimpleDuration(const nsAString& aDurSpec)
mSimpleDur.SetIndefinite();
return NS_ERROR_FAILURE;
}
if (duration.IsResolved() && duration.GetMillis() == 0L) {
mSimpleDur.SetIndefinite();
return NS_ERROR_FAILURE;
@ -487,7 +487,7 @@ nsSMILTimedElement::SetMin(const nsAString& aMinSpec)
nsSMILTimeValue duration;
PRBool isMedia;
nsresult rv;
rv = nsSMILParserUtils::ParseClockValue(aMinSpec, &duration, 0, &isMedia);
if (isMedia) {
@ -498,7 +498,7 @@ nsSMILTimedElement::SetMin(const nsAString& aMinSpec)
mMin.SetMillis(0L);
return NS_ERROR_FAILURE;
}
if (duration.GetMillis() < 0L) {
mMin.SetMillis(0L);
return NS_ERROR_FAILURE;
@ -523,7 +523,7 @@ nsSMILTimedElement::SetMax(const nsAString& aMaxSpec)
nsSMILTimeValue duration;
PRBool isMedia;
nsresult rv;
rv = nsSMILParserUtils::ParseClockValue(aMaxSpec, &duration,
nsSMILParserUtils::kClockValueAllowIndefinite, &isMedia);
@ -534,7 +534,7 @@ nsSMILTimedElement::SetMax(const nsAString& aMaxSpec)
mMax.SetIndefinite();
return NS_ERROR_FAILURE;
}
if (duration.IsResolved() && duration.GetMillis() <= 0L) {
mMax.SetIndefinite();
return NS_ERROR_FAILURE;
@ -557,7 +557,7 @@ nsresult
nsSMILTimedElement::SetRestart(const nsAString& aRestartSpec)
{
nsAttrValue temp;
PRBool parseResult
PRBool parseResult
= temp.ParseEnumValue(aRestartSpec, sRestartModeTable, PR_TRUE);
mRestartMode = parseResult
? nsSMILRestartMode(temp.GetEnumValue())
@ -577,7 +577,7 @@ nsresult
nsSMILTimedElement::SetRepeatCount(const nsAString& aRepeatCountSpec)
{
nsSMILRepeatCount newRepeatCount;
nsresult rv =
nsresult rv =
nsSMILParserUtils::ParseRepeatCount(aRepeatCountSpec, newRepeatCount);
if (NS_SUCCEEDED(rv)) {
@ -587,7 +587,7 @@ nsSMILTimedElement::SetRepeatCount(const nsAString& aRepeatCountSpec)
}
UpdateCurrentInterval();
return rv;
}
@ -611,7 +611,7 @@ nsSMILTimedElement::SetRepeatDur(const nsAString& aRepeatDurSpec)
mRepeatDur.SetUnresolved();
return NS_ERROR_FAILURE;
}
mRepeatDur = duration;
UpdateCurrentInterval();
@ -631,7 +631,7 @@ nsSMILTimedElement::SetFillMode(const nsAString& aFillModeSpec)
PRUint16 previousFillMode = mFillMode;
nsAttrValue temp;
PRBool parseResult =
PRBool parseResult =
temp.ParseEnumValue(aFillModeSpec, sFillModeTable, PR_TRUE);
mFillMode = parseResult
? nsSMILFillMode(temp.GetEnumValue())
@ -665,7 +665,7 @@ nsSMILTimedElement::SetBeginOrEndSpec(const nsAString& aSpec,
{
nsRefPtr<nsSMILTimeValueSpec> spec;
SMILTimeValueSpecList& timeSpecsList = aIsBegin ? mBeginSpecs : mEndSpecs;
nsTArray<nsSMILInstanceTime>& instancesList
nsTArray<nsSMILInstanceTime>& instancesList
= aIsBegin ? mBeginInstances : mEndInstances;
timeSpecsList.Clear();
@ -712,7 +712,7 @@ nsSMILTimedElement::GetNextInterval(const nsSMILTimeValue& aBeginAfter,
{
static nsSMILTimeValue zeroTime;
zeroTime.SetMillis(0L);
nsSMILTimeValue beginAfter = aBeginAfter;
nsSMILTimeValue tempBegin;
nsSMILTimeValue tempEnd;
@ -751,7 +751,7 @@ nsSMILTimedElement::GetNextInterval(const nsSMILTimeValue& aBeginAfter,
tempEnd = CalcActiveEnd(tempBegin, indefiniteEnd);
} else {
//
//
// Start searching from the beginning again.
//
endPos = 0;
@ -760,9 +760,9 @@ nsSMILTimedElement::GetNextInterval(const nsSMILTimeValue& aBeginAfter,
endPos, tempEnd);
if ((!aFirstInterval && tempEnd.CompareTo(aBeginAfter) == 0) ||
(aFirstInterval && tempEnd.CompareTo(tempBegin) == 0 &&
(aFirstInterval && tempEnd.CompareTo(tempBegin) == 0 &&
endPos <= endMaxPos)) {
endFound =
endFound =
GetNextGreaterOrEqual(mEndInstances, tempBegin, endPos, tempEnd);
}
@ -772,12 +772,12 @@ nsSMILTimedElement::GetNextInterval(const nsSMILTimeValue& aBeginAfter,
if (mEndHasEventConditions || mEndInstances.Length() == 0) {
tempEnd.SetUnresolved();
} else {
//
//
// This is a little counter-intuitive but according to SMILANIM, if
// all the ends are before the begin, we _don't_ just assume an
// infinite end, it's actually a bad interval. ASV however will just
// use an infinite end.
//
//
return NS_ERROR_FAILURE;
}
}
@ -928,7 +928,7 @@ nsSMILTimedElement::ActiveTimeToSimpleTime(nsSMILTime aActiveTime,
if (mSimpleDur.IsIndefinite() || mSimpleDur.GetMillis() == 0L) {
aRepeatIteration = 0;
result = aActiveTime;
} else {
} else {
result = aActiveTime % mSimpleDur.GetMillis();
aRepeatIteration = (PRUint32)(aActiveTime / mSimpleDur.GetMillis());
}
@ -960,8 +960,8 @@ nsSMILTimedElement::CheckForEarlyEnd(const nsSMILTimeValue& aDocumentTime)
while (GetNextGreaterOrEqual(mBeginInstances, mCurrentInterval.mBegin,
position, nextBegin)
&& nextBegin.CompareTo(mCurrentInterval.mBegin) == 0);
if (nextBegin.IsResolved() &&
if (nextBegin.IsResolved() &&
nextBegin.CompareTo(mCurrentInterval.mBegin) > 0 &&
nextBegin.CompareTo(mCurrentInterval.mEnd) < 0 &&
nextBegin.CompareTo(aDocumentTime) <= 0) {
@ -1027,7 +1027,7 @@ nsSMILTimedElement::SampleSimpleTime(nsSMILTime aActiveTime)
{
if (mClient) {
PRUint32 repeatIteration;
nsSMILTime simpleTime =
nsSMILTime simpleTime =
ActiveTimeToSimpleTime(aActiveTime, repeatIteration);
mClient->SampleAt(simpleTime, mSimpleDur, repeatIteration);
}
@ -1043,10 +1043,10 @@ nsSMILTimedElement::SampleFillValue()
return;
PRUint32 repeatIteration;
nsSMILTime activeTime =
nsSMILTime activeTime =
mCurrentInterval.mEnd.GetMillis() - mCurrentInterval.mBegin.GetMillis();
nsSMILTime simpleTime =
nsSMILTime simpleTime =
ActiveTimeToSimpleTime(activeTime, repeatIteration);
if (simpleTime == 0L) {

View File

@ -60,7 +60,7 @@ class nsSMILTimedElement
public:
nsSMILTimedElement();
/**
/**
* Methods for supporting the nsIDOMElementTimeControl interface.
*/
@ -92,7 +92,7 @@ public:
nsresult EndElementAt(double aOffsetSeconds,
const nsSMILTimeContainer* aContainer);
/**
/**
* Methods for supporting the nsSVGAnimationElement interface.
*/
@ -130,7 +130,7 @@ public:
return mSimpleDur;
}
/**
/**
* Internal SMIL methods
*/

View File

@ -49,16 +49,29 @@
NS_IMPL_ADDREF_INHERITED(nsSVGAnimationElement, nsSVGAnimationElementBase)
NS_IMPL_RELEASE_INHERITED(nsSVGAnimationElement, nsSVGAnimationElementBase)
NS_INTERFACE_MAP_BEGIN(nsSVGAnimationElement)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGAnimationElement)
NS_INTERFACE_MAP_ENTRY(nsISMILAnimationElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMElementTimeControl)
NS_INTERFACE_MAP_END_INHERITING(nsSVGAnimationElementBase)
// Cycle collection magic -- based on nsSVGUseElement
NS_IMPL_CYCLE_COLLECTION_CLASS(nsSVGAnimationElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsSVGAnimationElement,
nsSVGAnimationElementBase)
tmp->mHrefTarget.Unlink();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsSVGAnimationElement,
nsSVGAnimationElementBase)
tmp->mHrefTarget.Traverse(&cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
//----------------------------------------------------------------------
// Implementation
nsSVGAnimationElement::nsSVGAnimationElement(nsINodeInfo *aNodeInfo)
: nsSVGAnimationElementBase(aNodeInfo),
mHrefTarget(this),
mTimedDocumentRoot(nsnull)
{
}
@ -100,17 +113,13 @@ nsIContent*
nsSVGAnimationElement::GetTargetElementContent()
{
if (HasAttr(kNameSpaceID_XLink, nsGkAtoms::href)) {
// XXXdholbert: Use xlink:href attr to look up target element here.
// Note: Need to check for updated target element each sample, because
// the existing target's ID might've changed, or another element
// with the same ID might've been inserted earlier in the DOM tree.
NS_NOTYETIMPLEMENTED("nsSVGAnimationElement::GetTargetElementContent for "
"xlink:href-targeted animations");
return nsnull;
return mHrefTarget.get();
}
NS_ABORT_IF_FALSE(!mHrefTarget.get(),
"We shouldn't have an xlink:href target "
"if we don't have an xlink:href attribute");
// No "xlink:href" attribute --> target is my parent.
// No "xlink:href" attribute --> I should target my parent.
return nsSVGUtils::GetParentElement(this);
}
@ -223,6 +232,9 @@ nsSVGAnimationElement::BindToTree(nsIDocument* aDocument,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers)
{
NS_ABORT_IF_FALSE(!mHrefTarget.get(),
"Shouldn't have href-target yet "
"(or it should've been cleared)");
nsresult rv = nsSVGAnimationElementBase::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
@ -252,6 +264,17 @@ nsSVGAnimationElement::BindToTree(nsIDocument* aDocument,
if (controller) {
controller->RegisterAnimationElement(this);
}
const nsAttrValue* href = mAttrsAndChildren.GetAttr(nsGkAtoms::href,
kNameSpaceID_XLink);
if (href) {
nsAutoString hrefStr;
href->ToString(hrefStr);
// Pass in |aParent| instead of |this| -- first argument is only used
// for a call to GetCurrentDoc(), and |this| might not have a current
// document yet.
UpdateHrefTarget(aParent, hrefStr);
}
}
AnimationNeedsResample();
@ -274,6 +297,8 @@ nsSVGAnimationElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
mTimedDocumentRoot = nsnull;
}
mHrefTarget.Unlink();
AnimationNeedsResample();
nsSVGAnimationElementBase::UnbindFromTree(aDeep, aNullParent);
@ -300,7 +325,7 @@ nsSVGAnimationElement::ParseAttribute(PRInt32 aNamespaceID,
nsresult rv = NS_ERROR_FAILURE;
// First let the animation function try to parse it...
PRBool foundMatch =
PRBool foundMatch =
AnimationFunction().SetAttr(aAttribute, aValue, aResult, &rv);
// ... and if that didn't recognize the attribute, let the timed element
@ -308,7 +333,7 @@ nsSVGAnimationElement::ParseAttribute(PRInt32 aNamespaceID,
if (!foundMatch) {
foundMatch = mTimedElement.SetAttr(aAttribute, aValue, aResult, &rv);
}
if (foundMatch) {
AnimationNeedsResample();
if (NS_FAILED(rv)) {
@ -319,8 +344,17 @@ nsSVGAnimationElement::ParseAttribute(PRInt32 aNamespaceID,
}
}
return nsSVGAnimationElementBase::ParseAttribute(aNamespaceID, aAttribute,
aValue, aResult);
PRBool returnVal =
nsSVGAnimationElementBase::ParseAttribute(aNamespaceID, aAttribute,
aValue, aResult);
if (aNamespaceID == kNameSpaceID_XLink &&
aAttribute == nsGkAtoms::href &&
IsInDoc()) {
// NOTE: If we fail the IsInDoc call, it's ok -- we'll update the target
// on next BindToTree call.
UpdateHrefTarget(this, aValue);
}
return returnVal;
}
nsresult
@ -336,6 +370,10 @@ nsSVGAnimationElement::UnsetAttr(PRInt32 aNamespaceID,
mTimedElement.UnsetAttr(aAttribute)) {
AnimationNeedsResample();
}
} else if (aNamespaceID == kNameSpaceID_XLink) {
if (aAttribute == nsGkAtoms::href) {
mHrefTarget.Unlink();
}
}
return NS_OK;
@ -395,3 +433,14 @@ nsSVGAnimationElement::EndElementAt(float offset)
return rv;
}
void
nsSVGAnimationElement::UpdateHrefTarget(nsIContent* aNodeForContext,
const nsAString& aHrefStr)
{
nsCOMPtr<nsIURI> targetURI;
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI),
aHrefStr, GetOwnerDoc(), baseURI);
mHrefTarget.Reset(aNodeForContext, targetURI);
}

View File

@ -41,6 +41,7 @@
#include "nsSVGElement.h"
#include "nsAutoPtr.h"
#include "nsReferencedElement.h"
#include "nsIDOMSVGAnimationElement.h"
#include "nsIDOMElementTimeControl.h"
#include "nsISMILAnimationElement.h"
@ -59,8 +60,11 @@ protected:
nsresult Init();
public:
// interfaces:
// interfaces:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsSVGAnimationElement,
nsSVGAnimationElementBase)
NS_DECL_NSIDOMSVGANIMATIONELEMENT
NS_DECL_NSIDOMELEMENTTIMECONTROL
@ -91,6 +95,30 @@ public:
virtual nsSMILTimeContainer* GetTimeContainer();
protected:
void UpdateHrefTarget(nsIContent* aNodeForContext,
const nsAString& aHrefStr);
class TargetReference : public nsReferencedElement {
public:
TargetReference(nsSVGAnimationElement* aAnimationElement) :
mAnimationElement(aAnimationElement) {}
protected:
// We need to be notified when target changes, in order to request a
// sample (which will clear animation effects from old target and apply
// them to the new target).
virtual void ContentChanged(nsIContent* aFrom, nsIContent* aTo) {
nsReferencedElement::ContentChanged(aFrom, aTo);
mAnimationElement->AnimationNeedsResample();
}
// We need to override IsPersistent to get persistent tracking (beyond the
// first time the target changes)
virtual PRBool IsPersistent() { return PR_TRUE; }
private:
nsSVGAnimationElement* const mAnimationElement;
};
TargetReference mHrefTarget;
nsSMILTimedElement mTimedElement;
nsSMILTimeContainer* mTimedDocumentRoot;
};

View File

@ -101,9 +101,9 @@ public:
mParams[i] = aParams[i];
}
}
TransformType mTransformType;
float mParams[6];
};

View File

@ -91,7 +91,7 @@ nsSVGTransformSMILAttr::GetBaseValue() const
nsSMILValue val(type);
if (val.IsNull())
return val;
nsIDOMSVGTransformList *list = mVal->mBaseVal.get();
PRUint32 numItems = 0;
@ -104,7 +104,7 @@ nsSVGTransformSMILAttr::GetBaseValue() const
NS_ENSURE_SUCCESS(rv,nsSMILValue());
}
}
return val;
}
@ -166,7 +166,7 @@ nsSVGTransformSMILAttr::ParseValue(const nsAString& aSpec,
float params[3] = { 0.f };
PRInt32 numParsed = ParseParameterList(aSpec, params, 3);
nsSVGSMILTransform::TransformType transformType;
if (aTransformType == nsGkAtoms::translate) {
// tx [ty=0]
if (numParsed != 1 && numParsed != 2)
@ -343,7 +343,7 @@ nsSVGTransformSMILAttr::AppendSVGTransformToSMILValue(
}
if (transformType != nsSVGSMILTransform::TRANSFORM_MATRIX) {
rv =
rv =
type->AppendTransform(nsSVGSMILTransform(transformType, params), aValue);
}

View File

@ -54,7 +54,7 @@ nsSVGTransformSMILType::Init(nsSMILValue &aValue) const
"Invalid nsSMILValue of SVG transform type: NULL data member.");
if (aValue.mType != this || !aValue.mU.mPtr) {
// Different type, or no data member: allocate memory and set type
// Different type, or no data member: allocate memory and set type
TransformArray* transforms = new TransformArray(1);
NS_ENSURE_TRUE(transforms, NS_ERROR_OUT_OF_MEMORY);
aValue.mU.mPtr = transforms;
@ -85,7 +85,7 @@ nsSVGTransformSMILType::Assign(nsSMILValue& aDest,
NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types.");
NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value.");
const TransformArray* srcTransforms =
const TransformArray* srcTransforms =
static_cast<const TransformArray*>(aSrc.mU.mPtr);
TransformArray* dstTransforms = static_cast<TransformArray*>(aDest.mU.mPtr);
@ -181,13 +181,13 @@ nsSVGTransformSMILType::ComputeDistance(const nsSMILValue& aFrom,
const nsSMILValue& aTo,
double& aDistance) const
{
NS_PRECONDITION(aFrom.mType == aTo.mType,
NS_PRECONDITION(aFrom.mType == aTo.mType,
"Can't compute difference between different SMIL types.");
NS_PRECONDITION(aFrom.mType == this, "Unexpected SMIL type.");
const TransformArray* fromTransforms =
const TransformArray* fromTransforms =
static_cast<const TransformArray*>(aFrom.mU.mPtr);
const TransformArray* toTransforms =
const TransformArray* toTransforms =
static_cast<const TransformArray*>(aTo.mU.mPtr);
// ComputeDistance is only used for calculating distances between single
@ -252,9 +252,9 @@ nsSVGTransformSMILType::Interpolate(const nsSMILValue& aStartVal,
"Unexpected type for interpolation.");
NS_PRECONDITION(aResult.mType == this, "Unexpected result type.");
const TransformArray& startTransforms =
const TransformArray& startTransforms =
(*static_cast<const TransformArray*>(aStartVal.mU.mPtr));
const TransformArray& endTransforms
const TransformArray& endTransforms
(*static_cast<const TransformArray*>(aEndVal.mU.mPtr));
// We may have 0..n transforms in the start transform array (the base
@ -284,7 +284,7 @@ nsSVGTransformSMILType::Interpolate(const nsSMILValue& aStartVal,
if (!startParams) {
startParams = identityParams;
}
const float* endParams = endTransform.mParams;
// Interpolate between the params
@ -299,7 +299,7 @@ nsSVGTransformSMILType::Interpolate(const nsSMILValue& aStartVal,
nsSVGSMILTransform resultTransform(endTransform.mTransformType, newParams);
// Clear the way for it in the result array
TransformArray& dstTransforms =
TransformArray& dstTransforms =
(*static_cast<TransformArray*>(aResult.mU.mPtr));
dstTransforms.Clear();
@ -318,9 +318,9 @@ nsSVGTransformSMILType::GetNumTransforms(const nsSMILValue& aValue) const
{
NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value.");
const TransformArray& transforms =
const TransformArray& transforms =
*static_cast<const TransformArray*>(aValue.mU.mPtr);
return transforms.Length();
}
@ -330,14 +330,14 @@ nsSVGTransformSMILType::GetTransformAt(PRUint32 aIndex,
{
NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value.");
const TransformArray& transforms =
const TransformArray& transforms =
*static_cast<const TransformArray*>(aValue.mU.mPtr);
if (aIndex >= transforms.Length()) {
NS_ERROR("Attempting to access invalid transform.");
return nsnull;
}
return &transforms[aIndex];
}

View File

@ -686,7 +686,7 @@ static nsDOMClassInfoData sClassInfoData[] = {
ELEMENT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(HTMLBaseFontElement, nsHTMLElementSH,
ELEMENT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(HTMLBodyElement, nsHTMLElementSH,
NS_DEFINE_CLASSINFO_DATA(HTMLBodyElement, nsHTMLBodyElementSH,
ELEMENT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(HTMLButtonElement, nsHTMLElementSH,
ELEMENT_SCRIPTABLE_FLAGS)
@ -5203,6 +5203,74 @@ DefineInterfaceConstants(JSContext *cx, JSObject *obj, const nsIID *aIID)
return NS_OK;
}
NS_IMETHODIMP
nsHTMLBodyElementSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext
*cx, JSObject *obj, jsval id, PRUint32 flags,
JSObject **objp, PRBool *_retval)
{
if (id == sOnhashchange_id) {
// Special handling so |"onhashchange" in document.body| returns true.
jsid interned_id;
if (!JS_ValueToId(cx, id, &interned_id) ||
!JS_DefinePropertyById(cx, obj, interned_id, JSVAL_VOID,
nsnull, nsnull, JSPROP_ENUMERATE)) {
*_retval = PR_FALSE;
return NS_ERROR_FAILURE;
}
*objp = obj;
return NS_OK;
}
return nsHTMLElementSH::NewResolve(wrapper, cx, obj, id, flags, objp,
_retval);
}
NS_IMETHODIMP
nsHTMLBodyElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
JSContext *cx, JSObject *obj, jsval id,
jsval *vp, PRBool *_retval)
{
if (id == sOnhashchange_id) {
// Forward the request to the Window.
jsid interned_id;
if (!JS_ValueToId(cx, id, &interned_id) ||
!JS_GetPropertyById(cx, JS_GetGlobalForObject(cx, obj),
interned_id, vp)) {
*_retval = PR_FALSE;
return NS_ERROR_FAILURE;
}
return NS_OK;
}
return nsHTMLElementSH::GetProperty(wrapper, cx, obj, id, vp, _retval);
}
NS_IMETHODIMP
nsHTMLBodyElementSH::SetProperty(nsIXPConnectWrappedNative *wrapper,
JSContext *cx, JSObject *obj,
jsval id, jsval *vp, PRBool *_retval)
{
if (id == sOnhashchange_id) {
// Forward the request to the Window.
jsid interned_id;
if (!JS_ValueToId(cx, id, &interned_id) ||
!JS_SetPropertyById(cx, JS_GetGlobalForObject(cx, obj),
interned_id, vp)) {
*_retval = PR_FALSE;
return NS_ERROR_FAILURE;
}
return NS_OK;
}
return nsHTMLElementSH::SetProperty(wrapper, cx, obj, id, vp, _retval);
}
class nsDOMConstructor : public nsIDOMDOMConstructor
{
protected:
@ -6383,6 +6451,21 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
return NS_OK;
}
if (id == sOnhashchange_id) {
// Special handling so |"onhashchange" in window| returns true
jsid interned_id;
if (!JS_ValueToId(cx, id, &interned_id) ||
!JS_DefinePropertyById(cx, obj, interned_id, JSVAL_VOID,
nsnull, nsnull, JSPROP_ENUMERATE)) {
*_retval = PR_FALSE;
return NS_ERROR_FAILURE;
}
*objp = obj;
return NS_OK;
}
if (flags & JSRESOLVE_ASSIGNING) {
if (IsReadonlyReplaceable(id) ||
(!(flags & JSRESOLVE_QUALIFIED) && IsWritableReplaceable(id))) {

View File

@ -999,6 +999,35 @@ public:
}
};
class nsHTMLBodyElementSH : public nsHTMLElementSH
{
protected:
nsHTMLBodyElementSH(nsDOMClassInfoData* aData) : nsHTMLElementSH(aData)
{
}
virtual ~nsHTMLBodyElementSH()
{
}
public:
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, PRUint32 flags,
JSObject **objp, PRBool *_retval);
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp,
PRBool *_retval);
NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsval id, jsval *vp, PRBool *_retval);
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
{
return new nsHTMLBodyElementSH(aData);
}
};
// HTMLFormElement helper

View File

@ -51,6 +51,7 @@ _TEST_FILES = test_offsets.html \
test_domWindowUtils_scrollXY.html \
test_497898.html \
497633.html \
test_bug504220.html \
$(NULL)
libs:: $(_TEST_FILES)

View File

@ -0,0 +1,67 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=504220
-->
<head>
<title>Test for Bug 504220</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body onload="run_test();">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=504220">Mozilla Bug 504220</a>
<p id="display"></p>
<div id="content">
<iframe id="frame" style="height:100px; width:100px; border:0"></iframe>
<div id="status" style="display: none"></div>
</div>
<pre id="test">
<script type="application/javascript;version=1.7">
/** Test for Bug 504220 **/
function run_test() {
ok("onhashchange" in document.body,
"document.body should contain 'onhashchange'.");
ok("onhashchange" in window, "window should contain 'onhashchange'.");
// window.onhashchange should mirror document.body.onhashchange.
var func = function() { return 42; };
document.body.onhashchange = func;
is(window.onhashchange, func);
// Likewise, document.body.hashchange should mirror window.onhashchange
numEvents = 0;
var func2 = function() { numEvents++; gGen.next() };
window.onhashchange = func2;
is(document.body.onhashchange, func2);
SimpleTest.waitForExplicitFinish();
function waitForHashchange() {
// Change the document's hash. If we've been running this test manually,
// the hash might already be "#foo", so we need to check in order to be
// sure we trigger a hashchange.
if (location.hash != "#foo")
location.hash = "#foo";
else
location.hash = "#bar";
yield;
is(numEvents, 1, "Exactly one hashchange should have been fired.");
SimpleTest.finish();
yield;
}
var gGen = waitForHashchange();
gGen.next();
}
</script>
</pre>
</body>
</html>

View File

@ -109,7 +109,7 @@ public:
// clean up static objects that may have been cached
static void Shutdown();
static CTFontRef CreateCopyWithDisabledLigatures(CTFontRef aFont);
static CTFontRef CreateCTFontWithDisabledLigatures(ATSFontRef aFont, CGFloat aSize);
protected:
const gfxFontStyle *mFontStyle;

View File

@ -77,6 +77,26 @@ static PRLogModuleInfo *gCoreTextTextRunLog = PR_NewLogModule("coreTextTextRun")
CTFontDescriptorRef gfxCoreTextFont::sDefaultFeaturesDescriptor = NULL;
CTFontDescriptorRef gfxCoreTextFont::sDisableLigaturesDescriptor = NULL;
#ifdef DEBUG_jonathan
static void dumpFontDescCallback(const void *key, const void *value, void *context)
{
CFStringRef attribute = (CFStringRef)key;
CFTypeRef setting = (CFTypeRef)value;
fprintf(stderr, "attr: "); CFShow(attribute);
fprintf(stderr, " = "); CFShow(setting);
fprintf(stderr, "\n");
}
static void
dumpFontDescriptor(CTFontRef font)
{
CTFontDescriptorRef desc = CTFontCopyFontDescriptor(font);
CFDictionaryRef dict = CTFontDescriptorCopyAttributes(desc);
CFRelease(desc);
CFDictionaryApplyFunction(dict, &dumpFontDescCallback, 0);
CFRelease(dict);
}
#endif
gfxCoreTextFont::gfxCoreTextFont(MacOSFontEntry *aFontEntry,
const gfxFontStyle *aFontStyle,
@ -451,9 +471,9 @@ gfxCoreTextFont::CreateDefaultFeaturesDescriptor()
CFRelease(attributesDict);
}
// Create a copy of a CTFontRef, with the Common Ligatures feature disabled [static]
// Create a CTFontRef for an ATS font ref, with the Common Ligatures feature disabled [static]
CTFontRef
gfxCoreTextFont::CreateCopyWithDisabledLigatures(CTFontRef aFontRef)
gfxCoreTextFont::CreateCTFontWithDisabledLigatures(ATSFontRef aFontRef, CGFloat aSize)
{
if (sDisableLigaturesDescriptor == NULL) {
// initialize cached descriptor to turn off the Common Ligatures feature
@ -499,16 +519,11 @@ gfxCoreTextFont::CreateCopyWithDisabledLigatures(CTFontRef aFontRef)
CFRelease(featuresArray);
sDisableLigaturesDescriptor =
CTFontDescriptorCreateWithAttributes(attributesDict);
CTFontDescriptorCreateCopyWithAttributes(GetDefaultFeaturesDescriptor(), attributesDict);
CFRelease(attributesDict);
}
aFontRef =
CTFontCreateCopyWithAttributes(aFontRef,
0.0,
NULL,
sDisableLigaturesDescriptor);
return aFontRef;
return CTFontCreateWithPlatformFont(aFontRef, aSize, NULL, sDisableLigaturesDescriptor);
}
void
@ -759,19 +774,20 @@ gfxCoreTextFontGroup::InitTextRun(gfxTextRun *aTextRun,
if (disableLigatures) {
// For letterspacing (or maybe other situations) we need to make a copy of the CTFont
// with the ligature feature disabled
CTFontRef mainCTFont = mainFont->GetCTFont();
mainCTFont = gfxCoreTextFont::CreateCopyWithDisabledLigatures(mainCTFont);
CTFontRef ctFont =
gfxCoreTextFont::CreateCTFontWithDisabledLigatures(mainFont->GetATSFont(),
CTFontGetSize(mainFont->GetCTFont()));
// Set up the initial font, for the (common) case of a monostyled textRun
attrObj =
CFDictionaryCreate(kCFAllocatorDefault,
(const void**) &kCTFontAttributeName,
(const void**) &mainCTFont,
(const void**) &ctFont,
1, // count of attributes
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
// Having created the dict, we're finished with our modified copy of the CTFont
CFRelease(mainCTFont);
// Having created the dict, we're finished with our ligature-disabled CTFontRef
CFRelease(ctFont);
} else {
attrObj = mainFont->GetAttributesDictionary();
CFRetain(attrObj);
@ -813,7 +829,8 @@ gfxCoreTextFontGroup::InitTextRun(gfxTextRun *aTextRun,
if (matchedFont != mainFont) {
CTFontRef matchedCTFont = matchedFont->GetCTFont();
if (disableLigatures)
matchedCTFont = gfxCoreTextFont::CreateCopyWithDisabledLigatures(matchedCTFont);
matchedCTFont = gfxCoreTextFont::CreateCTFontWithDisabledLigatures(matchedFont->GetATSFont(),
CTFontGetSize(matchedCTFont));
// if necessary, make a mutable copy of the string
if (!mutableStringObj) {
mutableStringObj =

View File

@ -163,7 +163,7 @@ public:
void clear();
};
#ifdef JS_JIT_SPEW
#if defined(JS_JIT_SPEW) || defined(MOZ_NO_VARADIC_MACROS)
enum LC_TMBits {
/* Output control bits for all non-Nanojit code. Only use bits 16
@ -177,6 +177,16 @@ enum LC_TMBits {
LC_TMRegexp = 1<<22
};
#endif
#ifdef MOZ_NO_VARADIC_MACROS
#define debug_only_stmt(action) /* */
static void debug_only_printf(int mask, const char *fmt, ...) {}
#define debug_only_print0(mask, str) /* */
#elif defined(JS_JIT_SPEW)
// Top level logging controller object.
extern nanojit::LogControl js_LogController;
@ -228,8 +238,7 @@ public:
}
};
#if defined(_MSC_VER) || (defined(__GNUC__) && __GNUC__ >= 4)
#if defined(_MSC_VER) && _MSC_VER >= 1400 || (defined(__GNUC__) && __GNUC__ >= 4)
#define USE_TRACE_TYPE_ENUM
#endif
@ -246,7 +255,7 @@ public:
* this requirement is correctly enforced by these compilers.
*/
enum JSTraceType_
#ifdef _MSC_VER
#if defined(_MSC_VER) && _MSC_VER >= 1400
: int8_t
#endif
{

View File

@ -92,6 +92,13 @@
# define JS_EXTERN_DATA(__type) extern __declspec(dllexport) __type
# define JS_EXPORT_DATA(__type) __declspec(dllexport) __type
#elif defined(__SYMBIAN32__)
# define JS_EXTERN_API(__type) extern EXPORT_C __type
# define JS_EXPORT_API(__type) EXPORT_C __type
# define JS_EXTERN_DATA(__type) extern EXPORT_C __type
# define JS_EXPORT_DATA(__type) EXPORT_C __type
#else /* Unix */
# ifdef HAVE_VISIBILITY_ATTRIBUTE
@ -117,6 +124,8 @@
# endif
#elif defined(XP_OS2) && defined(__declspec)
# define JS_IMPORT_API(__x) __declspec(dllimport) __x
#elif defined(__SYMBIAN32__)
# define JS_IMPORT_API(__x) IMPORT_C __x
#else
# define JS_IMPORT_API(__x) JS_EXPORT_API (__x)
#endif
@ -125,6 +134,12 @@
# define JS_IMPORT_DATA(__x) __declspec(dllimport) __x
#elif defined(XP_OS2) && defined(__declspec)
# define JS_IMPORT_DATA(__x) __declspec(dllimport) __x
#elif defined(__SYMBIAN32__)
# if defined(__CW32__)
# define JS_IMPORT_DATA(__x) __declspec(dllimport) __x
# else
# define JS_IMPORT_DATA(__x) IMPORT_C __x
# endif
#else
# define JS_IMPORT_DATA(__x) JS_EXPORT_DATA (__x)
#endif
@ -280,6 +295,9 @@
#ifdef _MSC_VER
# include "jscpucfg.h" /* We can't auto-detect MSVC configuration */
# if _MSC_VER < 1400
# define MOZ_NO_VARADIC_MACROS
# endif
#else
# include "jsautocfg.h" /* Use auto-detected configuration */
#endif

View File

@ -790,9 +790,9 @@ namespace nanojit
// Used for debug printing, if needed
verbose_only(
ReverseLister *pp_init = NULL,
*pp_after_sf1 = NULL,
*pp_after_sf2 = NULL;
ReverseLister *pp_init = NULL;
ReverseLister *pp_after_sf1 = NULL;
ReverseLister *pp_after_sf2 = NULL;
)
// set up backwards pipeline: assembler -> StackFilter -> LirReader

View File

@ -95,7 +95,7 @@ namespace nanojit {
#define isSPorFP(r) ( (r)==SP || (r)==FP )
#if defined(_MSC_VER) && _MSC_VER < 1400
#ifdef MOZ_NO_VARADIC_MACROS
static void asm_output(const char *f, ...) {}
#define gpn(r) regNames[(r)]
#define fpn(r) regNames[(r)]

View File

@ -76,7 +76,7 @@
#include <windows.h>
#endif
#if defined(DEBUG) || defined(_MSC_VER) && _MSC_VER < 1400
#if defined(DEBUG) || defined(MOZ_NO_VARADIC_MACROS)
#if !defined _DEBUG
#define _DEBUG
#endif

View File

@ -131,7 +131,7 @@ namespace nanojit
const uint32_t MAXARGS = 8;
#if defined(_MSC_VER) && _MSC_VER < 1400
#ifdef MOZ_NO_VARADIC_MACROS
static void NanoAssertMsgf(bool a,const char *f,...) {}
static void NanoAssertMsg(bool a,const char *m) {}
static void NanoAssert(bool a) {}
@ -180,7 +180,7 @@ namespace nanojit
#define NJ_PROFILE 1
#endif
#if defined(_MSC_VER) && _MSC_VER < 1400
#ifdef MOZ_NO_VARADIC_MACROS
#include <stdio.h>
#define verbose_outputf if (_logc->lcbits & LC_Assembly) \
Assembler::outputf

View File

@ -0,0 +1,18 @@
<html>
<head>
<title>bug 502795 - letterspace with downloaded font</title>
</head>
<style type="text/css">
@font-face {
font-family: test;
src: url(../fonts/MarkA.ttf);
}
p {
font-family: test;
font-size: 24pt;
}
</style>
<body>
<p>A</p>
</body>
</html>

View File

@ -0,0 +1,21 @@
<html>
<head>
<title>bug 502795 - letterspace with downloaded font</title>
</head>
<style type="text/css">
@font-face {
font-family: test;
src: url(../fonts/MarkA.ttf);
}
p {
font-family: test;
font-size: 24pt;
letter-spacing: 10px;
}
</style>
<!-- with letterspacing, the downloaded font will fail to render
via coretext due to bug 502795 -->
<body>
<p>A</p>
</body>
</html>

View File

@ -1275,5 +1275,6 @@ fails-if(MOZ_WIDGET_TOOLKIT!="cocoa") == 488692-1.html 488692-1-ref.html # needs
== 495385-5.html 495385-5-ref.html
== 498228-1.xul 498228-1-ref.xul
== 496032-1.html 496032-1-ref.html
== 502795-1.html 502795-1-ref.html
== 503364-1a.html 503364-1-ref.html
== 503364-1b.html 503364-1-ref.html

View File

@ -0,0 +1,43 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS 2.1: Font matching algorithm (reference)</title>
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
</head>
<body>
<div style="font-family: FontDoesNotExist">
Every line of text in this page should be in the same font.
</div>
<div style="font-family: FontDoesNotExist">
Every line of text in this page should be in the same font.
</div>
<div style="font-family: FontDoesNotExist">
Every line of text in this page should be in the same font.
</div>
<div style="font-family: FontDoesNotExist">
Every line of text in this page should be in the same font.
</div>
<div style="font-family: FontDoesNotExist">
Every line of text in this page should be in the same font.
</div>
<div style="font-family: FontDoesNotExist">
Every line of text in this page should be in the same font.
</div>
<div style="font-family: FontDoesNotExist">
Every line of text in this page should be in the same font.
</div>
<div style="font-family: FontDoesNotExist">
Every line of text in this page should be in the same font.
</div>
</body>
</html>

View File

@ -0,0 +1,61 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS 2.1: Font matching algorithm</title>
<link rel="author" title="L. David Baron" href="http://dbaron.org/" />
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
<link rel="help" href="http://www.w3.org/TR/CSS21/fonts.html#algorithm" />
<meta name="assert" content="That the 'UA-dependent default 'font-family'' described in step (5) does not vary based on the ancestor's font-family property." />
</head>
<body>
<div style="font-family: Arial, Helvetica, sans-serif">
<div style="font-family: FontDoesNotExist">
Every line of text in this page should be in the same font.
</div>
</div>
<div style="font-family: Arial, Helvetica">
<div style="font-family: FontDoesNotExist">
Every line of text in this page should be in the same font.
</div>
</div>
<div style="font-family: Arial">
<div style="font-family: FontDoesNotExist">
Every line of text in this page should be in the same font.
</div>
</div>
<div style="font-family: Times New Roman, Times, serif">
<div style="font-family: FontDoesNotExist">
Every line of text in this page should be in the same font.
</div>
</div>
<div style="font-family: Times New Roman, Times">
<div style="font-family: FontDoesNotExist">
Every line of text in this page should be in the same font.
</div>
</div>
<div style="font-family: Times New Roman">
<div style="font-family: FontDoesNotExist">
Every line of text in this page should be in the same font.
</div>
</div>
<div style="font-family: Courier New, Courier, monospace">
<div style="font-family: FontDoesNotExist">
Every line of text in this page should be in the same font.
</div>
</div>
<div style="font-family: Verdana">
<div style="font-family: FontDoesNotExist">
Every line of text in this page should be in the same font.
</div>
</div>
</body>
</html>

View File

@ -0,0 +1 @@
== CSS21-t1502-no-inherited-font-family.xhtml CSS21-t1502-no-inherited-font-family-ref.xhtml

View File

@ -71,6 +71,9 @@ include floats/reftest.list
# font-face
include font-face/reftest.list
# font matching
include font-matching/reftest.list
# forms
include forms/reftest.list

View File

@ -2,8 +2,9 @@
xmlns:xlink="http://www.w3.org/1999/xlink"
class="reftest-wait"
onload="setTimeAndSnapshot(2.5, false)">
<!-- This test checks a basic animation with "xlink:href" targeting -->
<script xlink:href="smil-util.js" type="text/javascript"/>
<rect id="theRect" x="15" y="15" width="200" height="50" fill="blue" />
<animate xlink:href="#theRect" attributeName="height"
from="50" to="200" begin="0s" dur="2s" fill="freeze"/>
<rect id="blueRect" x="15" y="15" width="200" height="100" fill="blue"/>
<animate xlink:href="#blueRect" attributeName="height"
to="200" begin="0s" dur="2s" fill="freeze"/>
</svg>

Before

Width:  |  Height:  |  Size: 425 B

After

Width:  |  Height:  |  Size: 490 B

View File

@ -0,0 +1,18 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="reftest-wait"
onload="go()">
<!-- This test checks our behavior when "xlink:href" is modified -->
<script xlink:href="smil-util.js" type="text/javascript"/>
<script type="text/javascript">
function go() {
var anim = document.getElementById("anim");
anim.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#blueRect");
setTimeAndSnapshot(2.5, false)
}
</script>
<rect id="redRect" x="15" y="15" width="200" height="100" fill="red"/>
<rect id="blueRect" x="15" y="15" width="200" height="100" fill="blue"/>
<animate id="anim" xlink:href="#redRect" attributeName="height"
to="200" begin="0s" dur="2s" fill="freeze"/>
</svg>

After

Width:  |  Height:  |  Size: 782 B

View File

@ -0,0 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="reftest-wait"
onload="setTimeAndSnapshot(2.5, false)">
<!-- This test checks our behavior with animations that target nodes
other than their parents. -->
<script xlink:href="smil-util.js" type="text/javascript"/>
<rect id="blueRect" x="15" y="15" width="200" height="100" fill="blue"/>
<animate id="anim" xlink:href="#redRect" attributeName="height"
to="0" begin="0s" dur="2s" fill="freeze"/>
<rect id="redRect" x="15" y="215" width="200" height="100" fill="red">
<animate id="anim" xlink:href="#blueRect" attributeName="height"
to="200" begin="0s" dur="2s" fill="freeze"/>
</rect>
</svg>

After

Width:  |  Height:  |  Size: 746 B

View File

@ -0,0 +1,20 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="reftest-wait"
onload="go()">
<!-- This test checks our behavior with animations that are initially
href-targeted, but lose their href attribute. -->
<script xlink:href="smil-util.js" type="text/javascript"/>
<script type="text/javascript">
function go() {
var anim = document.getElementById("anim");
anim.removeAttributeNS("http://www.w3.org/1999/xlink", "href");
setTimeAndSnapshot(2.5, false)
}
</script>
<rect id="blueRect" x="15" y="15" width="200" height="100" fill="blue">
<animate id="anim" xlink:href="#redRect" attributeName="height"
to="200" begin="0s" dur="2s" fill="freeze"/>
</rect>
<rect id="redRect" x="15" y="215" width="200" height="0" fill="red"/>
</svg>

After

Width:  |  Height:  |  Size: 843 B

View File

@ -0,0 +1,21 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="reftest-wait"
onload="go()">
<!-- This test checks our behavior with animations that initially
have no 'xlink:href' attribute, but receive one via scripting. -->
<script xlink:href="smil-util.js" type="text/javascript"/>
<script type="text/javascript">
function go() {
var anim = document.getElementById("anim");
anim.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#blueRect");
setTimeAndSnapshot(2.5, false)
}
</script>
<rect id="blueRect" x="15" y="15" width="200" height="100" fill="blue">
</rect>
<rect id="redRect" x="15" y="215" width="200" height="0" fill="red">
<animate id="anim" attributeName="height"
to="200" begin="0s" dur="2s" fill="freeze"/>
</rect>
</svg>

After

Width:  |  Height:  |  Size: 852 B

View File

@ -0,0 +1,18 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="reftest-wait"
onload="go()">
<!-- This test checks our behavior with an 'xlink:href'-targeted animation
when the target's ID is changed (which makes it no longer the target) -->
<script xlink:href="smil-util.js" type="text/javascript"/>
<script type="text/javascript">
function go() {
var rect = document.getElementById("blueRect");
rect.setAttributeNS(null, "id", "differentBlueRect");
setTimeAndSnapshot(2.5, false)
}
</script>
<rect id="blueRect" x="15" y="15" width="200" height="200" fill="blue"/>
<animate id="anim" xlink:href="#blueRect" attributeName="height"
to="0" begin="0s" dur="2s" fill="freeze"/>
</svg>

After

Width:  |  Height:  |  Size: 779 B

View File

@ -0,0 +1,18 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="reftest-wait"
onload="go()">
<!-- This test checks our behavior with an 'xlink:href'-targeted animation
when the target's ID is removed (which makes it no longer the target) -->
<script xlink:href="smil-util.js" type="text/javascript"/>
<script type="text/javascript">
function go() {
var rect = document.getElementById("blueRect");
rect.removeAttributeNS(null, "id");
setTimeAndSnapshot(2.5, false)
}
</script>
<rect id="blueRect" x="15" y="15" width="200" height="200" fill="blue"/>
<animate id="anim" xlink:href="#blueRect" attributeName="height"
to="0" begin="0s" dur="2s" fill="freeze"/>
</svg>

After

Width:  |  Height:  |  Size: 761 B

View File

@ -0,0 +1,20 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="reftest-wait"
onload="go()">
<!-- This test checks our behavior with an 'xlink:href'-targeted animation
when an earlier node suddenly obtains the target ID string (thereby
becoming the new animation target). -->
<script xlink:href="smil-util.js" type="text/javascript"/>
<script type="text/javascript">
function go() {
var rect = document.getElementById("myLaterRect");
rect.setAttributeNS(null, "id", "myRect");
setTimeAndSnapshot(2.5, false)
}
</script>
<rect id="myLaterRect" x="15" y="15" width="200" height="0" fill="blue"/>
<rect id="myRect" x="15" y="215" width="200" height="0" fill="red"/>
<animate id="anim" xlink:href="#myRect" attributeName="height"
to="200" begin="0s" dur="2s" fill="freeze"/>
</svg>

After

Width:  |  Height:  |  Size: 884 B

View File

@ -0,0 +1,19 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="reftest-wait"
onload="go()">
<!-- This test checks our behavior with an 'xlink:href'-targeted animation
where there's initially no matching target, but then an element's ID is
set to match (making it the target) -->
<script xlink:href="smil-util.js" type="text/javascript"/>
<script type="text/javascript">
function go() {
var rect = document.getElementById("rect");
rect.setAttributeNS(null, "id", "blueRect");
setTimeAndSnapshot(2.5, false)
}
</script>
<rect id="rect" x="15" y="15" width="200" height="100" fill="blue"/>
<animate id="anim" xlink:href="#blueRect" attributeName="height"
to="200" begin="0s" dur="2s" fill="freeze"/>
</svg>

After

Width:  |  Height:  |  Size: 809 B

View File

@ -69,16 +69,25 @@ fails == anim-fillopacity-1.svg anim-standard-ref.svg # non-length-numeric va
== anim-remove-7.svg anim-standard-ref.svg
== anim-retarget-1.svg anim-standard-ref.svg
== anim-retarget-2.svg anim-standard-ref.svg
fails == anim-retarget-3.svg anim-standard-ref.svg # href support
== anim-retarget-3.svg anim-standard-ref.svg
== anim-retarget-4.svg anim-standard-ref.svg
fails == anim-retarget-5.svg anim-standard-ref.svg # href support
fails == anim-retarget-6.svg anim-standard-ref.svg # href support
fails == anim-retarget-7.svg anim-standard-ref.svg # href support
== anim-retarget-5.svg anim-standard-ref.svg
== anim-retarget-6.svg anim-standard-ref.svg
== anim-retarget-7.svg anim-standard-ref.svg
== anim-retarget-8.svg anim-standard-ref.svg
fails == anim-strokecolor-1.svg anim-standard-ref.svg # color support
fails == anim-strokewidth-1.svg anim-standard-ref.svg # color support
fails == anim-targethref-1.svg anim-standard-ref.svg # href support
== anim-targethref-1.svg anim-standard-ref.svg
== anim-targethref-2.svg anim-standard-ref.svg
== anim-targethref-3.svg anim-standard-ref.svg
== anim-targethref-4.svg anim-standard-ref.svg
== anim-targethref-5.svg anim-standard-ref.svg
== anim-targethref-6.svg anim-standard-ref.svg
== anim-targethref-7.svg anim-standard-ref.svg
== anim-targethref-8.svg anim-standard-ref.svg
== anim-targethref-9.svg anim-standard-ref.svg
== anim-width-done-1a.svg anim-standard-ref.svg
== anim-width-done-1b.svg anim-standard-ref.svg

View File

@ -215,31 +215,21 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
// XXX Are there other things like this?
aRuleData->mFontData->mFamilyFromHTML = PR_FALSE;
}
else if (iProp == eCSSProperty_color ||
iProp == eCSSProperty_background_color ||
iProp == eCSSProperty_border_top_color ||
iProp == eCSSProperty_border_right_color_value ||
iProp == eCSSProperty_border_right_color_ltr_source ||
iProp == eCSSProperty_border_right_color_rtl_source ||
iProp == eCSSProperty_border_bottom_color ||
iProp == eCSSProperty_border_left_color_value ||
iProp == eCSSProperty_border_left_color_ltr_source ||
iProp == eCSSProperty_border_left_color_rtl_source ||
iProp == eCSSProperty__moz_column_rule_color ||
iProp == eCSSProperty_outline_color) {
if (ShouldIgnoreColors(aRuleData)) {
if (iProp == eCSSProperty_background_color) {
// Force non-'transparent' background
// colors to the user's default.
if (target->IsNonTransparentColor()) {
target->SetColorValue(aRuleData->
mPresContext->
DefaultBackgroundColor());
}
} else {
// Ignore 'color', 'border-*-color', etc.
*target = nsCSSValue();
if (nsCSSProps::PropHasFlags(iProp,
CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED) &&
ShouldIgnoreColors(aRuleData))
{
if (iProp == eCSSProperty_background_color) {
// Force non-'transparent' background
// colors to the user's default.
if (target->IsNonTransparentColor()) {
target->SetColorValue(aRuleData->
mPresContext->
DefaultBackgroundColor());
}
} else {
// Ignore 'color', 'border-*-color', etc.
*target = nsCSSValue();
}
}
}
@ -247,6 +237,9 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
} break;
case eCSSType_Rect: {
NS_ABORT_IF_FALSE(!nsCSSProps::PropHasFlags(iProp,
CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED),
"this case needs to handle color properties");
const nsCSSRect* val = RectAtCursor(cursor);
NS_ASSERTION(val->HasValue(), "oops");
nsCSSRect* target = static_cast<nsCSSRect*>(prop);
@ -262,6 +255,9 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
} break;
case eCSSType_ValuePair: {
NS_ABORT_IF_FALSE(!nsCSSProps::PropHasFlags(iProp,
CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED),
"this case needs to handle color properties");
const nsCSSValuePair* val = ValuePairAtCursor(cursor);
NS_ASSERTION(val->mXValue.GetUnit() != eCSSUnit_Null ||
val->mYValue.GetUnit() != eCSSUnit_Null, "oops");
@ -305,14 +301,11 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
NS_ASSERTION(val, "oops");
*target = val;
if (iProp == eCSSProperty_background_image ||
iProp == eCSSProperty_border_top_colors ||
iProp == eCSSProperty_border_right_colors ||
iProp == eCSSProperty_border_bottom_colors ||
iProp == eCSSProperty_border_left_colors) {
if (ShouldIgnoreColors(aRuleData)) {
*target = nsnull;
}
if (nsCSSProps::PropHasFlags(iProp,
CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED) &&
ShouldIgnoreColors(aRuleData))
{
*target = nsnull;
}
}
cursor += CDBPointerStorage_advance;

File diff suppressed because it is too large Load Diff

View File

@ -60,6 +60,9 @@
#define CSS_PROPERTY_APPLIES_TO_FIRST_LINE (1<<3)
#define CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE \
(CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | CSS_PROPERTY_APPLIES_TO_FIRST_LINE)
// Note that 'background-color' is ignored differently from the other
// properties that have this set, but that's just special-cased.
#define CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED (1<<4)
class nsCSSProps {
public:

View File

@ -9,7 +9,7 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<style type="text/css">
#one, #three { background: blue; color: yellow; border: thin solid red; -moz-column-rule: 2px solid green; }
#one, #three { background: blue; color: yellow; border: thin solid red; -moz-column-rule: 2px solid green; text-shadow: 2px 2px green; }
#two { background: transparent; border: thin solid; }
#five, #six {border: thick solid red; -moz-border-start-color:green; -moz-border-end-color:blue}
#seven {
@ -90,7 +90,9 @@ function part1()
isnot(cs1.borderBottomColor, cs2.borderBottomColor,
"border-top-color applies");
isnot(cs1.MozColumnRuleColor, cs2.MozColumnRuleColor,
"-moz-column-rule-color applies");
"-moz-column-rule-color applies");
isnot(cs1.textShadow, cs2.textShadow,
"text-shadow applies");
is(cs1.borderTopColor, cs3.borderTopColor, "border-top-color applies");
is(cs1.borderRightColor, cs3.borderRightColor,
"border-right-color applies");
@ -100,6 +102,8 @@ function part1()
"border-top-color applies");
is(cs1.MozColumnRuleColor, cs3.MozColumnRuleColor,
"-moz-column-rule-color applies");
is(cs1.TextShadow, cs3.TextShadow,
"text-shadow applies");
isnot(cs5.borderRightColor, cs2.borderRightColor,
"-moz-border-end-color applies");
isnot(cs5.borderLeftColor, cs2.borderLeftColor,
@ -168,6 +172,8 @@ function part2()
"border-bottom-color is blocked");
is(cs1.MozColumnRuleColor, cs2.MozColumnRuleColor,
"-moz-column-rule-color is blocked");
is(cs1.TextShadow, cs2.TextShadow,
"text-shadow is blocked");
is(cs3.backgroundColor, cs1.backgroundColor, "background-color transparency preserved (opaque)");
is(cs3.color, cs4.color, "color is blocked");
is(cs3.borderTopColor, cs4.borderTopColor, "border-top-color is blocked");

View File

@ -38,10 +38,12 @@ function run() {
function should_apply(q) {
ok(query_applies(q), q + " should apply");
test_serialization(q, true, true);
}
function should_not_apply(q) {
ok(!query_applies(q), q + " should not apply");
test_serialization(q, true, false);
}
/*
@ -69,6 +71,7 @@ function run() {
function query_should_be_parseable(q) {
ok(query_is_parseable(q), "query " + q + " should be parseable");
test_serialization(q, false, false);
}
function query_should_not_be_parseable(q) {
@ -86,6 +89,7 @@ function run() {
function expression_should_be_parseable(e) {
ok(expression_is_parseable(e),
"expression " + e + " should be parseable");
test_serialization("all and (" + e + ")", false, false);
}
function expression_should_not_be_parseable(e) {
@ -93,6 +97,20 @@ function run() {
"expression " + e + " should not be parseable");
}
function test_serialization(q, test_application, should_apply) {
style.setAttribute("media", q);
var ser1 = style.sheet.media.mediaText;
isnot(ser1, "", "serialization of '" + q + "' should not be empty");
style.setAttribute("media", ser1);
var ser2 = style.sheet.media.mediaText;
is(ser2, ser1, "parse+serialize of '" + q + "' should be idempotent");
if (test_application) {
var applies = body_cs.getPropertyValue("text-decoration") == "underline";
is(applies, should_apply,
"Media query '" + q + "' should apply after serialize + reparse");
}
}
// The no-type syntax doesn't mix with the not and only keywords.
query_should_be_parseable("(orientation)");
query_should_not_be_parseable("not (orientation)");
@ -276,7 +294,9 @@ function run() {
}
var is_monochrome = query_applies("all and (min-monochrome: 1)");
test_serialization("all and (min-monochrome: 1)", true, is_monochrome);
var is_color = query_applies("all and (min-color: 1)");
test_serialization("all and (min-color: 1)", true, is_color);
isnot(is_monochrome, is_color, "should be either monochrome or color");
function depth_query(prefix, depth) {

View File

@ -7,28 +7,27 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body onload="run()">
<p id="display"><iframe id="iframe" src="about:blank"></iframe></p>
<p id="display"><iframe id="iframe" src="about:blank"></iframe><iframe id="cloneiframe" src="about:blank"></iframe></p>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
var cloneiframe;
function run() {
var iframe = document.getElementById("iframe");
var ifwin = iframe.contentWindow;
var ifdoc = iframe.contentDocument;
function setup_style() {
var style_elem = ifdoc.createElement("style");
style_elem.setAttribute("type", "text/css");
ifdoc.getElementsByTagName("head")[0].appendChild(style_elem);
var style_text = ifdoc.createTextNode("");
style_elem.appendChild(style_text);
return style_text;
}
cloneiframe = document.getElementById("cloneiframe");
var style_text = setup_style();
var style_elem = ifdoc.createElement("style");
style_elem.setAttribute("type", "text/css");
ifdoc.getElementsByTagName("head")[0].appendChild(style_elem);
var style_text = ifdoc.createTextNode("");
style_elem.appendChild(style_text);
var gCounter = 0;
@ -104,6 +103,52 @@ function run() {
ifdoc.body.innerHTML = "";
style_text.data = "";
// And now test that when we clone the style sheet, we end up
// with the same selector (serializes to same string, and
// matches the same things).
zi = ++gCounter;
var style_sheet = "data:text/css," +
escape(namespaces + selector + "{ z-index: " + zi + " }");
var style_sheet_link =
"<link rel='stylesheet' href='" + style_sheet + "'>";
var html_doc = "<!DOCTYPE HTML>" +
style_sheet_link + style_sheet_link +
"<body>" + body_contents;
var docurl = "data:text/html," + escape(html_doc);
defer_clonedoc_tests(docurl, function() {
var clonedoc = cloneiframe.contentDocument;
var clonewin = cloneiframe.contentWindow;
var links = clonedoc.getElementsByTagName("link");
// cause a clone
links[1].sheet.insertRule("#nonexistent { color: purple}", idx + 1);
// remove the uncloned sheet
links[0].parentNode.removeChild(links[0]);
var should_match = match_fn(clonedoc);
var should_not_match = notmatch_fn(clonedoc);
if (should_match.length + should_not_match.length == 0) {
ok(false, "nothing to check");
}
for (var i = 0; i < should_match.length; ++i) {
var e = should_match[i];
is(clonewin.getComputedStyle(e, "").zIndex, zi,
"element in " + body_contents + " matched clone of " +
selector);
}
for (var i = 0; i < should_not_match.length; ++i) {
var e = should_not_match[i];
is(clonewin.getComputedStyle(e, "").zIndex, "auto",
"element in " + body_contents + " did not match clone of " +
selector);
}
var ser3 = links[0].sheet.cssRules[idx].selectorText;
is(ser3, ser1,
"selector " + selector + " serializes correctly after cloning");
});
}
function should_serialize_to(selector, serialization)
@ -117,14 +162,55 @@ function run() {
function test_parseable(selector)
{
var zi = ++gCounter;
ifdoc.body.innerHTML = "<p></p>";
var zi = ++gCounter;
style_text.data = "p, " + selector + "{ z-index: " + zi + " }";
var should_match = ifdoc.getElementsByTagName("p")[0];
is(ifwin.getComputedStyle(should_match, "").zIndex, zi,
"selector " + selector + " was parsed");
// Test that it serializes to something that is also parseable.
var ser1 = style_elem.sheet.cssRules[0].selectorText;
zi = ++gCounter;
style_text.data = ser1 + "{ z-index: " + zi + " }";
is(ifwin.getComputedStyle(should_match, "").zIndex, zi,
"serialization " + ser1 + " of selector p, " + selector +
" was parsed");
var ser2 = style_elem.sheet.cssRules[0].selectorText;
is(ser2, ser1,
"parse+serialize of selector " + selector + " is idempotent");
ifdoc.body.innerHTML = "";
style_text.data = "";
// Test that it clones to the same thing it serializes to.
zi = ++gCounter;
var style_sheet = "data:text/css," +
escape("p, " + selector + "{ z-index: " + zi + " }");
var style_sheet_link =
"<link rel='stylesheet' href='" + style_sheet + "'>";
var html_doc = "<!DOCTYPE HTML>" +
style_sheet_link + style_sheet_link +
"<p></p>";
var docurl = "data:text/html," + escape(html_doc);
defer_clonedoc_tests(docurl, function() {
var clonedoc = cloneiframe.contentDocument;
var clonewin = cloneiframe.contentWindow;
var links = clonedoc.getElementsByTagName("link");
// cause a clone
links[1].sheet.insertRule("#nonexistent { color: purple}", 0);
// remove the uncloned sheet
links[0].parentNode.removeChild(links[0]);
should_match = clonedoc.getElementsByTagName("p")[0];
is(clonewin.getComputedStyle(should_match, "").zIndex, zi,
"selector " + selector + " was cloned correctly");
var ser3 = links[0].sheet.cssRules[1].selectorText;
is(ser3, ser1,
"selector " + selector + " serializes correctly after cloning");
});
}
function test_balanced_unparseable(selector)
@ -513,8 +599,8 @@ function run() {
xul_default_ns);
test_selector_in_html("html|a", single_a, set_single, empty_set,
xul_default_ns + html_ns);
// Type selectors inside :not() bring in default namespaces, but
// non-type selectors don't.
// Type selectors inside :not() bring in default namespaces, but
// non-type selectors don't.
test_selector_in_html("*|a:not(*)", single_a, set_single, empty_set,
xul_default_ns);
test_selector_in_html("*|a:not(a)", single_a, set_single, empty_set,
@ -546,7 +632,36 @@ function run() {
test_selector_in_html("html|a:not(*|a)", single_a, empty_set, set_single,
xul_default_ns + html_ns);
SimpleTest.finish();
run_deferred_tests();
}
var deferred_tests = [];
function defer_clonedoc_tests(docurl, onloadfunc)
{
deferred_tests.push( { docurl: docurl, onloadfunc: onloadfunc } );
}
function run_deferred_tests()
{
if (deferred_tests.length == 0) {
SimpleTest.finish();
return;
}
cloneiframe.onload = deferred_tests_onload;
cloneiframe.src = deferred_tests[0].docurl;
}
function deferred_tests_onload(event)
{
if (event.target != cloneiframe)
return;
deferred_tests[0].onloadfunc();
deferred_tests.shift();
run_deferred_tests();
}
</script>

View File

@ -44,7 +44,7 @@
* access of cookie objects
*/
[scriptable, uuid(8587f4e0-870c-11dd-ad8b-0800200c9a66)]
[scriptable, uuid(05c420e5-03d0-4c7b-a605-df7ebe5ca326)]
interface nsICookie2 : nsICookie
{
@ -84,5 +84,13 @@ interface nsICookie2 : nsICookie
*/
readonly attribute PRInt64 creationTime;
/**
* the last time the cookie was accessed (i.e. created,
* modified, or read by the server), in microseconds
* since midnight (00:00:00), January 1, 1970 UTC.
*
* note that this time may be approximate.
*/
readonly attribute PRInt64 lastAccessed;
};

View File

@ -44,7 +44,7 @@ interface nsIFile;
* Additions to the frozen nsICookieManager
*/
[scriptable, uuid(5047cab4-9cb2-4927-a4ab-77422bc3bc67)]
[scriptable, uuid(d1e9e50f-b78b-4e3b-a474-f3cbca59b013)]
interface nsICookieManager2 : nsICookieManager
{
/**
@ -110,6 +110,24 @@ interface nsICookieManager2 : nsICookieManager
*/
unsigned long countCookiesFromHost(in ACString aHost);
/**
* Returns an enumerator of cookies that would be returned to a given host,
* ignoring the cookie flags isDomain, isSecure, and isHttpOnly. Thus, for a
* host "weather.yahoo.com", host or domain cookies for "weather.yahoo.com"
* and "yahoo.com" would be returned, while a cookie for "my.weather.yahoo.com"
* would not.
*
* @param aHost
* the host string to look for, e.g. "google.com". this should consist
* of only the host portion of a URI, and should not contain a leading
* dot, a port, etc.
*
* @return an nsISimpleEnumerator of nsICookie2 objects.
*
* @see countCookiesFromHost
*/
nsISimpleEnumerator getCookiesFromHost(in ACString aHost);
/**
* Import an old-style cookie file. Imported cookies will be added to the
* existing database. If the database contains any cookies the same as those

View File

@ -143,6 +143,7 @@ NS_IMETHODIMP nsCookie::GetIsHttpOnly(PRBool *aHttpOnly) { *aHttpOnly = IsHttp
NS_IMETHODIMP nsCookie::GetStatus(nsCookieStatus *aStatus) { *aStatus = 0; return NS_OK; }
NS_IMETHODIMP nsCookie::GetPolicy(nsCookiePolicy *aPolicy) { *aPolicy = 0; return NS_OK; }
NS_IMETHODIMP nsCookie::GetCreationTime(PRInt64 *aCreation){ *aCreation = CreationID(); return NS_OK; }
NS_IMETHODIMP nsCookie::GetLastAccessed(PRInt64 *aTime) { *aTime = LastAccessed(); return NS_OK; }
// compatibility method, for use with the legacy nsICookie interface.
// here, expires == 0 denotes a session cookie.

View File

@ -139,6 +139,7 @@ struct nsListIter
{
nsListIter() {}
explicit
nsListIter(nsCookieEntry *aEntry)
: entry(aEntry)
, prev(nsnull)
@ -2169,6 +2170,35 @@ nsCookieService::CountCookiesFromHost(const nsACString &aHost,
return NS_OK;
}
// get an enumerator of cookies stored by a particular host. this is provided by the
// nsICookieManager2 interface.
NS_IMETHODIMP
nsCookieService::GetCookiesFromHost(const nsACString &aHost,
nsISimpleEnumerator **aEnumerator)
{
nsCOMArray<nsICookie> cookieList(mMaxCookiesPerHost);
nsCAutoString hostWithDot(NS_LITERAL_CSTRING(".") + aHost);
PRInt64 currentTime = PR_Now() / PR_USEC_PER_SEC;
const char *currentDot = hostWithDot.get();
const char *nextDot = currentDot + 1;
do {
nsCookieEntry *entry = mHostTable->GetEntry(currentDot);
for (nsListIter iter(entry); iter.current; ++iter) {
// only append non-expired cookies
if (iter.current->Expiry() > currentTime)
cookieList.AppendObject(iter.current);
}
currentDot = nextDot;
if (currentDot)
nextDot = strchr(currentDot + 1, '.');
} while (currentDot);
return NS_NewArrayEnumerator(aEnumerator, cookieList);
}
// find an exact cookie specified by host, name, and path that hasn't expired.
PRBool
nsCookieService::FindCookie(const nsAFlatCString &aHost,

View File

@ -74,6 +74,7 @@ class nsCookieEntry : public PLDHashEntryHdr
typedef const char* KeyTypePointer;
// do nothing with aHost - we require mHead to be set before we're live!
explicit
nsCookieEntry(KeyTypePointer aHost)
: mHead(nsnull)
{