mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 10:00:54 +00:00
Bug 481335. Cache the href URI of <html:a> once we resolve it. r+sr=sicking
This commit is contained in:
parent
a7fbf9a901
commit
eb4ceff899
@ -51,10 +51,14 @@
|
||||
#include "nsTPtrArray.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsIURI.h"
|
||||
#ifdef MOZ_SVG
|
||||
#include "nsISVGValue.h"
|
||||
#endif
|
||||
|
||||
#define MISC_STR_PTR(_cont) \
|
||||
reinterpret_cast<void*>((_cont)->mStringBits & NS_ATTRVALUE_POINTERVALUE_MASK)
|
||||
|
||||
nsTPtrArray<const nsAttrValue::EnumTable>* nsAttrValue::sEnumTableArray = nsnull;
|
||||
|
||||
nsAttrValue::nsAttrValue()
|
||||
@ -250,6 +254,16 @@ nsAttrValue::SetTo(const nsAttrValue& aOther)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case eFloatValue:
|
||||
{
|
||||
cont->mFloatValue = otherCont->mFloatValue;
|
||||
break;
|
||||
}
|
||||
case eLazyURIValue:
|
||||
{
|
||||
NS_IF_ADDREF(cont->mURI = otherCont->mURI);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
NS_NOTREACHED("unknown type stored in MiscContainer");
|
||||
@ -257,8 +271,7 @@ nsAttrValue::SetTo(const nsAttrValue& aOther)
|
||||
}
|
||||
}
|
||||
|
||||
void* otherPtr =
|
||||
reinterpret_cast<void*>(otherCont->mStringBits & NS_ATTRVALUE_POINTERVALUE_MASK);
|
||||
void* otherPtr = MISC_STR_PTR(otherCont);
|
||||
if (otherPtr) {
|
||||
if (static_cast<ValueBaseType>(otherCont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) ==
|
||||
eStringBase) {
|
||||
@ -326,8 +339,7 @@ nsAttrValue::ToString(nsAString& aResult) const
|
||||
MiscContainer* cont = nsnull;
|
||||
if (BaseType() == eOtherBase) {
|
||||
cont = GetMiscContainer();
|
||||
void* ptr =
|
||||
reinterpret_cast<void*>(cont->mStringBits & NS_ATTRVALUE_POINTERVALUE_MASK);
|
||||
void* ptr = MISC_STR_PTR(cont);
|
||||
if (ptr) {
|
||||
if (static_cast<ValueBaseType>(cont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) ==
|
||||
eStringBase) {
|
||||
@ -434,6 +446,16 @@ nsAttrValue::ToString(nsAString& aResult) const
|
||||
aResult = str;
|
||||
break;
|
||||
}
|
||||
// No need to do for eLazyURIValue, since that always stores the
|
||||
// original string.
|
||||
#ifdef DEBUG
|
||||
case eLazyURIValue:
|
||||
{
|
||||
NS_NOTREACHED("Shouldn't get here");
|
||||
aResult.Truncate();
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
aResult.Truncate();
|
||||
@ -577,6 +599,22 @@ nsAttrValue::HashValue() const
|
||||
return NS_PTR_TO_INT32(cont->mSVGValue);
|
||||
}
|
||||
#endif
|
||||
case eFloatValue:
|
||||
{
|
||||
// XXX this is crappy, but oh well
|
||||
return cont->mFloatValue;
|
||||
}
|
||||
case eLazyURIValue:
|
||||
{
|
||||
NS_ASSERTION(static_cast<ValueBaseType>(cont->mStringBits &
|
||||
NS_ATTRVALUE_BASETYPE_MASK) ==
|
||||
eStringBase,
|
||||
"Unexpected type");
|
||||
nsStringBuffer* str = static_cast<nsStringBuffer*>(MISC_STR_PTR(cont));
|
||||
NS_ASSERTION(str, "How did that happen?");
|
||||
PRUint32 len = str->StorageSize()/sizeof(PRUnichar) - 1;
|
||||
return nsCRT::BufferHashCode(static_cast<PRUnichar*>(str->Data()), len);
|
||||
}
|
||||
default:
|
||||
{
|
||||
NS_NOTREACHED("unknown type stored in MiscContainer");
|
||||
@ -672,6 +710,15 @@ nsAttrValue::Equals(const nsAttrValue& aOther) const
|
||||
return thisCont->mSVGValue == otherCont->mSVGValue;
|
||||
}
|
||||
#endif
|
||||
case eFloatValue:
|
||||
{
|
||||
return thisCont->mFloatValue == otherCont->mFloatValue;
|
||||
}
|
||||
case eLazyURIValue:
|
||||
{
|
||||
needsStringComparison = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
NS_NOTREACHED("unknown type stored in MiscContainer");
|
||||
@ -1117,6 +1164,58 @@ PRBool nsAttrValue::ParseFloatValue(const nsAString& aString)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool nsAttrValue::ParseLazyURIValue(const nsAString& aString)
|
||||
{
|
||||
ResetIfSet();
|
||||
|
||||
if (EnsureEmptyMiscContainer()) {
|
||||
MiscContainer* cont = GetMiscContainer();
|
||||
cont->mURI = nsnull;
|
||||
cont->mType = eLazyURIValue;
|
||||
|
||||
// Don't use SetMiscAtomOrString because atomizing URIs is not
|
||||
// likely to do us much good.
|
||||
nsStringBuffer* buf = GetStringBuffer(aString);
|
||||
if (!buf) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
cont->mStringBits = reinterpret_cast<PtrBits>(buf) | eStringBase;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
nsAttrValue::CacheURIValue(nsIURI* aURI)
|
||||
{
|
||||
NS_PRECONDITION(Type() == eLazyURIValue, "wrong type");
|
||||
NS_PRECONDITION(!GetMiscContainer()->mURI, "Why are we being called?");
|
||||
NS_IF_ADDREF(GetMiscContainer()->mURI = aURI);
|
||||
}
|
||||
|
||||
void
|
||||
nsAttrValue::DropCachedURI()
|
||||
{
|
||||
NS_PRECONDITION(Type() == eLazyURIValue, "wrong type");
|
||||
NS_IF_RELEASE(GetMiscContainer()->mURI);
|
||||
}
|
||||
|
||||
const nsCheapString
|
||||
nsAttrValue::GetURIStringValue() const
|
||||
{
|
||||
NS_PRECONDITION(Type() == eLazyURIValue, "wrong type");
|
||||
NS_PRECONDITION(static_cast<ValueBaseType>(GetMiscContainer()->mStringBits &
|
||||
NS_ATTRVALUE_BASETYPE_MASK) ==
|
||||
eStringBase,
|
||||
"Unexpected type");
|
||||
NS_PRECONDITION(MISC_STR_PTR(GetMiscContainer()),
|
||||
"Should have a string buffer here!");
|
||||
return nsCheapString(static_cast<nsStringBuffer*>
|
||||
(MISC_STR_PTR(GetMiscContainer())));
|
||||
}
|
||||
|
||||
void
|
||||
nsAttrValue::SetMiscAtomOrString(const nsAString* aValue)
|
||||
{
|
||||
@ -1145,7 +1244,7 @@ void
|
||||
nsAttrValue::ResetMiscAtomOrString()
|
||||
{
|
||||
MiscContainer* cont = GetMiscContainer();
|
||||
void* ptr = reinterpret_cast<void*>(cont->mStringBits & NS_ATTRVALUE_POINTERVALUE_MASK);
|
||||
void* ptr = MISC_STR_PTR(cont);
|
||||
if (ptr) {
|
||||
if (static_cast<ValueBaseType>(cont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) ==
|
||||
eStringBase) {
|
||||
@ -1182,6 +1281,11 @@ nsAttrValue::EnsureEmptyMiscContainer()
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case eLazyURIValue:
|
||||
{
|
||||
NS_IF_RELEASE(cont->mURI);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
|
@ -54,6 +54,7 @@ typedef unsigned long PtrBits;
|
||||
class nsAString;
|
||||
class nsIAtom;
|
||||
class nsICSSStyleRule;
|
||||
class nsIURI;
|
||||
class nsISVGValue;
|
||||
class nsIDocument;
|
||||
template<class E> class nsCOMArray;
|
||||
@ -120,6 +121,7 @@ public:
|
||||
,eSVGValue = 0x12
|
||||
#endif
|
||||
,eFloatValue = 0x13
|
||||
,eLazyURIValue = 0x14
|
||||
};
|
||||
|
||||
ValueType Type() const;
|
||||
@ -153,6 +155,10 @@ public:
|
||||
inline nsISVGValue* GetSVGValue() const;
|
||||
#endif
|
||||
inline float GetFloatValue() const;
|
||||
inline nsIURI* GetURIValue() const;
|
||||
const nsCheapString GetURIStringValue() const;
|
||||
void CacheURIValue(nsIURI* aURI);
|
||||
void DropCachedURI();
|
||||
|
||||
// Methods to get access to atoms we may have
|
||||
// Returns the number of atoms we have; 0 if we have none. It's OK
|
||||
@ -257,6 +263,12 @@ public:
|
||||
*/
|
||||
PRBool ParseFloatValue(const nsAString& aString);
|
||||
|
||||
/**
|
||||
* Parse a lazy URI. This just sets up the storage for the URI; it
|
||||
* doesn't actually allocate it.
|
||||
*/
|
||||
PRBool ParseLazyURIValue(const nsAString& aString);
|
||||
|
||||
private:
|
||||
// These have to be the same as in ValueType
|
||||
enum ValueBaseType {
|
||||
@ -285,6 +297,7 @@ private:
|
||||
nsISVGValue* mSVGValue;
|
||||
#endif
|
||||
float mFloatValue;
|
||||
nsIURI* mURI;
|
||||
};
|
||||
};
|
||||
|
||||
@ -390,6 +403,13 @@ nsAttrValue::GetFloatValue() const
|
||||
return GetMiscContainer()->mFloatValue;
|
||||
}
|
||||
|
||||
inline nsIURI*
|
||||
nsAttrValue::GetURIValue() const
|
||||
{
|
||||
NS_PRECONDITION(Type() == eLazyURIValue, "wrong type");
|
||||
return GetMiscContainer()->mURI;
|
||||
}
|
||||
|
||||
inline nsAttrValue::ValueBaseType
|
||||
nsAttrValue::BaseType() const
|
||||
{
|
||||
|
@ -1060,24 +1060,7 @@ nsGenericHTMLElement::GetHrefURIForAnchors(nsIURI** aURI) const
|
||||
// Get href= attribute (relative URI).
|
||||
|
||||
// We use the nsAttrValue's copy of the URI string to avoid copying.
|
||||
const nsAttrValue* attr = mAttrsAndChildren.GetAttr(nsGkAtoms::href);
|
||||
if (attr) {
|
||||
// Get base URI.
|
||||
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
|
||||
|
||||
// Get absolute URI.
|
||||
nsresult rv = nsContentUtils::NewURIWithDocumentCharset(aURI,
|
||||
attr->GetStringValue(),
|
||||
GetOwnerDoc(),
|
||||
baseURI);
|
||||
if (NS_FAILED(rv)) {
|
||||
*aURI = nsnull;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Absolute URI is null to say we have no HREF.
|
||||
*aURI = nsnull;
|
||||
}
|
||||
GetURIAttr(nsGkAtoms::href, nsnull, aURI);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -2156,51 +2139,72 @@ nsGenericHTMLElement::SetFloatAttr(nsIAtom* aAttr, float aValue)
|
||||
nsresult
|
||||
nsGenericHTMLElement::GetURIAttr(nsIAtom* aAttr, nsIAtom* aBaseAttr, nsAString& aResult)
|
||||
{
|
||||
nsAutoString attrValue;
|
||||
if (!GetAttr(kNameSpaceID_None, aAttr, attrValue)) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
PRBool hadAttr = GetURIAttr(aAttr, aBaseAttr, getter_AddRefs(uri));
|
||||
if (!hadAttr) {
|
||||
aResult.Truncate();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!uri) {
|
||||
// Just return the attr value
|
||||
GetAttr(kNameSpaceID_None, aAttr, aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCAutoString spec;
|
||||
uri->GetSpec(spec);
|
||||
CopyUTF8toUTF16(spec, aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsGenericHTMLElement::GetURIAttr(nsIAtom* aAttr, nsIAtom* aBaseAttr,
|
||||
nsIURI** aURI) const
|
||||
{
|
||||
*aURI = nsnull;
|
||||
|
||||
const nsAttrValue* attr = mAttrsAndChildren.GetAttr(aAttr);
|
||||
if (!attr) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool isURIAttr = (attr->Type() == nsAttrValue::eLazyURIValue);
|
||||
|
||||
if (isURIAttr && (*aURI = attr->GetURIValue())) {
|
||||
NS_ADDREF(*aURI);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
|
||||
nsresult rv;
|
||||
|
||||
if (aBaseAttr) {
|
||||
nsAutoString baseAttrValue;
|
||||
if (GetAttr(kNameSpaceID_None, aBaseAttr, baseAttrValue)) {
|
||||
nsCOMPtr<nsIURI> baseAttrURI;
|
||||
rv = nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(baseAttrURI),
|
||||
baseAttrValue, GetOwnerDoc(),
|
||||
baseURI);
|
||||
nsresult rv =
|
||||
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(baseAttrURI),
|
||||
baseAttrValue, GetOwnerDoc(),
|
||||
baseURI);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Just use the attr value as the result...
|
||||
aResult = attrValue;
|
||||
|
||||
return NS_OK;
|
||||
return PR_TRUE;
|
||||
}
|
||||
baseURI.swap(baseAttrURI);
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> attrURI;
|
||||
rv = nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(attrURI),
|
||||
attrValue, GetOwnerDoc(),
|
||||
baseURI);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Just use the attr value as the result...
|
||||
aResult = attrValue;
|
||||
// Don't care about return value. If it fails, we still want to
|
||||
// return PR_TRUE, and *aURI will be null.
|
||||
nsContentUtils::NewURIWithDocumentCharset(aURI,
|
||||
isURIAttr ?
|
||||
attr->GetURIStringValue() :
|
||||
attr->GetStringValue(),
|
||||
GetOwnerDoc(), baseURI);
|
||||
|
||||
return NS_OK;
|
||||
if (isURIAttr) {
|
||||
const_cast<nsAttrValue*>(attr)->CacheURIValue(*aURI);
|
||||
}
|
||||
|
||||
NS_ASSERTION(attrURI,
|
||||
"nsContentUtils::NewURIWithDocumentCharset return value lied");
|
||||
|
||||
nsCAutoString spec;
|
||||
attrURI->GetSpec(spec);
|
||||
CopyUTF8toUTF16(spec, aResult);
|
||||
return NS_OK;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -687,6 +687,15 @@ protected:
|
||||
*/
|
||||
NS_HIDDEN_(nsresult) GetURIAttr(nsIAtom* aAttr, nsIAtom* aBaseAttr, nsAString& aResult);
|
||||
|
||||
/**
|
||||
* Helper for GetURIAttr and GetHrefURIForAnchors which returns an
|
||||
* nsIURI in the out param..
|
||||
*
|
||||
* @return PR_TRUE if we had the attr, PR_FALSE otherwise.
|
||||
*/
|
||||
NS_HIDDEN_(PRBool) GetURIAttr(nsIAtom* aAttr, nsIAtom* aBaseAttr,
|
||||
nsIURI** aURI) const;
|
||||
|
||||
/**
|
||||
* This method works like GetURIAttr, except that it supports multiple
|
||||
* URIs separated by whitespace (one or more U+0020 SPACE characters).
|
||||
|
@ -131,10 +131,16 @@ public:
|
||||
PRBool aNotify);
|
||||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify);
|
||||
virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
protected:
|
||||
void ResetLinkCacheState();
|
||||
|
||||
// The cached visited state
|
||||
nsLinkState mLinkState;
|
||||
};
|
||||
@ -223,13 +229,9 @@ nsHTMLAnchorElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
void
|
||||
nsHTMLAnchorElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc) {
|
||||
if (IsInDoc()) {
|
||||
RegUnRegAccessKey(PR_FALSE);
|
||||
doc->ForgetLink(this);
|
||||
// If this link is ever reinserted into a document, it might
|
||||
// be under a different xml:base, so forget the cached state now
|
||||
mLinkState = eLinkState_Unknown;
|
||||
ResetLinkCacheState();
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
@ -464,14 +466,7 @@ nsHTMLAnchorElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsAutoString val;
|
||||
GetHref(val);
|
||||
if (!val.Equals(aValue)) {
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc) {
|
||||
doc->ForgetLink(this);
|
||||
// The change to 'href' will cause style reresolution which will
|
||||
// eventually recompute the link state and re-add this element
|
||||
// to the link map if necessary.
|
||||
}
|
||||
SetLinkState(eLinkState_Unknown);
|
||||
ResetLinkCacheState();
|
||||
}
|
||||
}
|
||||
|
||||
@ -495,11 +490,7 @@ nsHTMLAnchorElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify)
|
||||
{
|
||||
if (aAttribute == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) {
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc) {
|
||||
doc->ForgetLink(this);
|
||||
}
|
||||
SetLinkState(eLinkState_Unknown);
|
||||
ResetLinkCacheState();
|
||||
}
|
||||
|
||||
if (aAttribute == nsGkAtoms::accesskey &&
|
||||
@ -509,3 +500,34 @@ nsHTMLAnchorElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
|
||||
return nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLAnchorElement::ParseAttribute(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::href) {
|
||||
return aResult.ParseLazyURIValue(aValue);
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
|
||||
aResult);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLAnchorElement::ResetLinkCacheState()
|
||||
{
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc) {
|
||||
doc->ForgetLink(this);
|
||||
}
|
||||
mLinkState = eLinkState_Unknown;
|
||||
|
||||
// Clear our cached URI _after_ we ForgetLink(), since ForgetLink()
|
||||
// wants that URI.
|
||||
const nsAttrValue* attr = mAttrsAndChildren.GetAttr(nsGkAtoms::href);
|
||||
if (attr && attr->Type() == nsAttrValue::eLazyURIValue) {
|
||||
const_cast<nsAttrValue*>(attr)->DropCachedURI();
|
||||
}
|
||||
}
|
||||
|
@ -130,6 +130,7 @@ _TEST_FILES = test_bug589.html \
|
||||
test_bug347174_xslp.html \
|
||||
347174transformable.xml \
|
||||
347174transform.xsl \
|
||||
test_bug481335.xhtml \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
71
content/html/content/test/test_bug481335.xhtml
Normal file
71
content/html/content/test/test_bug481335.xhtml
Normal file
@ -0,0 +1,71 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=481335
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 481335</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=481335">Mozilla Bug 481335</a>
|
||||
<p id="display">
|
||||
<a id="t">A link</a>
|
||||
<iframe id="i"></iframe>
|
||||
</p>
|
||||
<p id="newparent" xml:base="http://www.example.com/"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
/** Test for Bug 481335 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var rand = Date.now() + "-" + Math.random();
|
||||
|
||||
is($("t").href, "",
|
||||
"Unexpected href before set");
|
||||
is($("t").href, "",
|
||||
"Unexpected cached href before set");
|
||||
|
||||
$("t").setAttribute("href", rand);
|
||||
is($("t").href,
|
||||
window.location.href.replace(/test_bug481335.xhtml/, rand),
|
||||
"Unexpected href after set");
|
||||
is($("t").href,
|
||||
window.location.href.replace(/test_bug481335.xhtml/, rand),
|
||||
"Unexpected cached href after set");
|
||||
var unvisitedColor = document.defaultView.getComputedStyle($("t"), "").color;
|
||||
var visitedColor;
|
||||
|
||||
function afterSecondLoad() {
|
||||
todo(document.defaultView.getComputedStyle($("t"), "").color == visitedColor,
|
||||
"Should be visited now");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function afterFirstLoad() {
|
||||
visitedColor = document.defaultView.getComputedStyle($("t"), "").color;
|
||||
todo(visitedColor != unvisitedColor, "Why are the colors the same?");
|
||||
$("newparent").appendChild($("t"));
|
||||
is($("t").href, "http://www.example.com/" + rand,
|
||||
"Unexpected href after move");
|
||||
is($("t").href, "http://www.example.com/" + rand,
|
||||
"Unexpected cached href after move");
|
||||
is(document.defaultView.getComputedStyle($("t"), "").color, unvisitedColor,
|
||||
"Should be unvisited now");
|
||||
|
||||
$("i").onload = afterSecondLoad;
|
||||
$("i").src = $("t").href;
|
||||
}
|
||||
|
||||
addLoadEvent(function() {
|
||||
$("i").onload = afterFirstLoad;
|
||||
$("i").src = $("t").href;
|
||||
});
|
||||
]]>
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user