Change GetHrefUTF8 to GetHrefURI to make sure that we don't lose track of the

origin charset.  Bug 166996, r=dbaron,darin sr=jst
This commit is contained in:
bzbarsky%mit.edu 2003-07-01 02:59:54 +00:00
Родитель cf8e368ef2
Коммит fd57f310f1
22 изменённых файлов: 196 добавлений и 345 удалений

Просмотреть файл

@ -89,10 +89,7 @@ NS_IMETHODIMP nsHTMLLinkAccessibleWrap::GetURI(PRInt32 i, nsIURI **aURI)
nsCOMPtr<nsILink> link(do_QueryInterface(mLinkContent));
if (link) {
nsXPIDLCString hrefValue;
if (NS_SUCCEEDED(link->GetHrefUTF8(getter_Copies(hrefValue)))) {
return NS_NewURI(aURI, hrefValue, nsnull, nsnull);
}
return link->GetHrefURI(aURI);
}
return NS_ERROR_FAILURE;

Просмотреть файл

@ -3115,29 +3115,16 @@ nsGenericElement::LeaveLink(nsIPresContext* aPresContext)
nsresult
nsGenericElement::TriggerLink(nsIPresContext* aPresContext,
nsLinkVerb aVerb,
nsIURI* aBaseURL,
const nsAString& aURLSpec,
nsIURI* aOriginURI,
nsIURI* aLinkURI,
const nsAFlatString& aTargetSpec,
PRBool aClick)
{
NS_PRECONDITION(aLinkURI, "No link URI");
nsCOMPtr<nsILinkHandler> handler;
nsresult rv = aPresContext->GetLinkHandler(getter_AddRefs(handler));
if (NS_FAILED(rv) || !handler) return rv;
// Resolve url to an absolute url
nsCOMPtr<nsIURI> targetURI;
nsCAutoString docCharset;
if (mDocument &&
NS_SUCCEEDED(mDocument->GetDocumentCharacterSet(docCharset))) {
rv = NS_NewURI(getter_AddRefs(targetURI), aURLSpec,
docCharset.get(), aBaseURL);
} else {
rv = NS_NewURI(getter_AddRefs(targetURI), aURLSpec, nsnull, aBaseURL);
}
NS_ENSURE_SUCCESS(rv, rv);
// Now pass on absolute url to the click handler
if (aClick) {
nsresult proceed = NS_OK;
// Check that this page is allowed to load this URI.
@ -3145,17 +3132,15 @@ nsGenericElement::TriggerLink(nsIPresContext* aPresContext,
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv))
proceed =
securityManager->CheckLoadURI(aBaseURL, targetURI,
securityManager->CheckLoadURI(aOriginURI, aLinkURI,
nsIScriptSecurityManager::STANDARD);
// Only pass off the click event if the script security manager
// says it's ok.
if (NS_SUCCEEDED(proceed))
handler->OnLinkClick(this, aVerb, targetURI,
aTargetSpec.get());
handler->OnLinkClick(this, aVerb, aLinkURI, aTargetSpec.get());
} else {
handler->OnOverLink(this, targetURI,
aTargetSpec.get());
handler->OnOverLink(this, aLinkURI, aTargetSpec.get());
}
return rv;
}

Просмотреть файл

@ -535,19 +535,22 @@ public:
const nsAString& aValue);
/**
* Load a link, putting together the proper URL from the pieces given.
* Trigger a link with uri aLinkURI. If aClick is false, this triggers a
* mouseover on the link, otherwise it triggers a load, after doing a
* security check.
* @param aPresContext the pres context.
* @param aVerb how the link will be loaded (replace page, new window, etc.)
* @param aBaseURL the base URL to start with (content.baseURL, may be null)
* @param aURLSpec the URL of the link (may be relative)
* @param aTargetSpec the target (like target=, may be null)
* @param aOriginURI the URI the request originates from. Used as the origin
* uri for a CheckLoadURI call.
* @param aLinkURI the URI of the link
* @param aTargetSpec the target (like target=, may be empty)
* @param aClick whether this was a click or not (if false, it assumes you
* just hovered over the link)
*/
nsresult TriggerLink(nsIPresContext* aPresContext,
nsLinkVerb aVerb,
nsIURI* aBaseURL,
const nsAString& aURLSpec,
nsIURI* aOriginURI,
nsIURI* aLinkURI,
const nsAFlatString& aTargetSpec,
PRBool aClick);
/**

Просмотреть файл

@ -207,19 +207,20 @@ nsStyleLinkElement::UpdateStyleSheet(nsIDocument *aOldDocument,
return NS_OK;
}
nsAutoString url;
nsCOMPtr<nsIURI> uri;
PRBool isInline;
GetStyleSheetURL(&isInline, getter_AddRefs(uri));
GetStyleSheetURL(&isInline, url);
if (mStyleSheet && !isInline && uri) {
nsCOMPtr<nsIURI> oldURI;
nsCOMPtr<nsIDOMStyleSheet> styleSheet(do_QueryInterface(mStyleSheet));
if (styleSheet && !isInline) {
nsAutoString oldHref;
styleSheet->GetHref(oldHref);
if (oldHref.Equals(url)) {
return NS_OK; // We already loaded this stylesheet
mStyleSheet->GetURL(*getter_AddRefs(oldURI));
if (oldURI) {
PRBool equal;
nsresult rv = oldURI->Equals(uri, &equal);
if (NS_SUCCEEDED(rv) && equal) {
return NS_OK; // We already loaded this stylesheet
}
}
}
@ -228,7 +229,7 @@ nsStyleLinkElement::UpdateStyleSheet(nsIDocument *aOldDocument,
mStyleSheet = nsnull;
}
if (url.IsEmpty() && !isInline) {
if (!uri && !isInline) {
return NS_OK; // If href is empty and this is not inline style then just bail
}
@ -241,17 +242,6 @@ nsStyleLinkElement::UpdateStyleSheet(nsIDocument *aOldDocument,
return NS_OK;
}
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_OK;
if (!isInline) {
rv = NS_NewURI(getter_AddRefs(uri), url);
if (NS_FAILED(rv)) {
return NS_OK; // The URL is bad, move along, don't propagate the error (for now)
}
}
nsCOMPtr<nsIHTMLContentContainer> htmlContainer(do_QueryInterface(doc));
nsCOMPtr<nsICSSLoader> loader;
@ -286,6 +276,7 @@ nsStyleLinkElement::UpdateStyleSheet(nsIDocument *aOldDocument,
}
PRBool doneLoading;
nsresult rv = NS_OK;
if (isInline) {
PRInt32 count;
thisContent->ChildCount(count);

Просмотреть файл

@ -57,7 +57,7 @@ public:
protected:
virtual void GetStyleSheetURL(PRBool* aIsInline,
nsAString& aUrl) = 0;
nsIURI** aURI) = 0;
virtual void GetStyleSheetInfo(nsAString& aTitle,
nsAString& aType,
nsAString& aMedia,

Просмотреть файл

@ -42,6 +42,8 @@
#include "nsISupports.h"
#include "nsILinkHandler.h" // definition of nsLinkState
class nsIURI;
// IID for the nsILink interface
#define NS_ILINK_IID \
{ 0xa904ac22, 0x28fa, 0x4812, \
@ -76,18 +78,14 @@ public:
NS_IMETHOD SetLinkState(nsLinkState aState) = 0;
/**
* Get a pointer to the UTF-8 encoded canonical URL (i.e., fully
* resolved to the base URL) that this link element points to. The
* buffer returned has been allocated for and should be deleted by
* the caller.
* Get a pointer to the fully href URI (fully resolved and canonicalized,
* since it's an nsIURI object).
*
* @param aBuf [out] A pointer to be filled in with a pointer to a
* null-terminated string containing the canonical URL.
* If the element has no HREF attribute, it is set to
* nsnull.
* @return NS_OK if the out pointer is filled in
* @param aURI [out] A pointer to be filled in with a pointer to the URI
* If the element has no HREF attribute, it is set to nsnull.
* @return NS_OK if the out pointer is filled in (possibly with nsnull)
*/
NS_IMETHOD GetHrefUTF8(char** aBuf) = 0;
NS_IMETHOD GetHrefURI(nsIURI** aURI) = 0;
};

Просмотреть файл

@ -1467,17 +1467,12 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsIPresContext* aPresContext,
// nsILink interface to get a canonified URL that has been
// correctly escaped and URL-encoded for the document's charset.
nsXPIDLCString hrefCStr;
GetHrefUTF8ForAnchors(getter_Copies(hrefCStr));
nsCOMPtr<nsIURI> hrefURI;
GetHrefURIForAnchors(getter_AddRefs(hrefURI));
// Only bother to handle the mouse event if there was an href
// specified.
if (hrefCStr) {
NS_ConvertUTF8toUCS2 href(hrefCStr);
// Strip off any unneeded CF/LF (for Bug 52119)
// It can't be done in the parser because of Bug 15204
href.StripChars("\r\n");
if (hrefURI) {
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
{
@ -1527,7 +1522,7 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsIPresContext* aPresContext,
break; // let the click go through so we can handle it in JS/XUL
}
ret = TriggerLink(aPresContext, eLinkVerb_Replace, baseURL, href,
ret = TriggerLink(aPresContext, eLinkVerb_Replace, baseURL, hrefURI,
target, PR_TRUE);
*aEventStatus = nsEventStatus_eConsumeDoDefault;
@ -1577,8 +1572,8 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsIPresContext* aPresContext,
if (target.IsEmpty()) {
GetBaseTarget(target);
}
ret = TriggerLink(aPresContext, eLinkVerb_Replace,
baseURL, href, target, PR_FALSE);
ret = TriggerLink(aPresContext, eLinkVerb_Replace, baseURL,
hrefURI, target, PR_FALSE);
}
break;
@ -1598,7 +1593,7 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsIPresContext* aPresContext,
}
nsresult
nsGenericHTMLElement::GetHrefUTF8ForAnchors(char** aHref)
nsGenericHTMLElement::GetHrefURIForAnchors(nsIURI** aURI)
{
// This is used by the three nsILink implementations and
// nsHTMLStyleElement.
@ -1608,29 +1603,21 @@ nsGenericHTMLElement::GetHrefUTF8ForAnchors(char** aHref)
if (NS_CONTENT_ATTR_HAS_VALUE ==
GetAttr(kNameSpaceID_None, nsHTMLAtoms::href, relURLSpec)) {
// Clean up any leading or trailing whitespace
relURLSpec.Trim(" \t\n\r");
// Get base URL.
nsCOMPtr<nsIURI> baseURL;
GetBaseURL(getter_AddRefs(baseURL));
if (baseURL) {
// Get absolute URL.
nsCAutoString buf;
NS_MakeAbsoluteURIWithCharset(buf, relURLSpec, mDocument, baseURL,
nsHTMLUtils::IOService,
nsHTMLUtils::CharsetMgr);
*aHref = ToNewCString(buf);
}
else {
// Absolute URL is same as relative URL.
*aHref = ToNewUTF8String(relURLSpec);
// Get absolute URL.
nsCAutoString buf;
nsresult rv = NS_NewURIWithDocumentCharset(aURI, relURLSpec, mDocument,
baseURL);
if (NS_FAILED(rv)) {
*aURI = nsnull;
}
}
else {
// Absolute URL is null to say we have no HREF.
*aHref = nsnull;
*aURI = nsnull;
}
return NS_OK;

Просмотреть файл

@ -217,7 +217,7 @@ public:
// Used by A, AREA, LINK, and STYLE.
// Callers must hold a reference to nsHTMLUtils's global reference count.
nsresult GetHrefUTF8ForAnchors(char** aHref);
nsresult GetHrefURIForAnchors(nsIURI** aURI);
// Implementation for nsIHTMLContent
NS_IMETHOD SetHTMLAttribute(nsIAtom* aAttribute, const nsHTMLValue& aValue,

Просмотреть файл

@ -106,7 +106,7 @@ public:
// nsILink
NS_IMETHOD GetLinkState(nsLinkState &aState);
NS_IMETHOD SetLinkState(nsLinkState aState);
NS_IMETHOD GetHrefUTF8(char** aBuf);
NS_IMETHOD GetHrefURI(nsIURI** aURI);
NS_IMETHOD SetDocument(nsIDocument* aDocument, PRBool aDeep,
PRBool aCompileEventHandlers);
@ -164,12 +164,12 @@ NS_NewHTMLAnchorElement(nsIHTMLContent** aInstancePtrResult,
nsHTMLAnchorElement::nsHTMLAnchorElement() : mLinkState(eLinkState_Unknown)
{
nsHTMLUtils::AddRef(); // for GetHrefUTF8
nsHTMLUtils::AddRef(); // for GetHrefURI
}
nsHTMLAnchorElement::~nsHTMLAnchorElement()
{
nsHTMLUtils::Release(); // for GetHrefUTF8
nsHTMLUtils::Release(); // for GetHrefURI
}
@ -357,13 +357,17 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext* aPresContext,
NS_IMETHODIMP
nsHTMLAnchorElement::GetHref(nsAString& aValue)
{
nsXPIDLCString buf;
nsresult rv = GetHrefUTF8(getter_Copies(buf));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIURI> uri;
nsresult rv = GetHrefURI(getter_AddRefs(uri));
if (NS_FAILED(rv))
return rv;
CopyUTF8toUTF16(buf, aValue);
nsCAutoString spec;
if (uri) {
uri->GetSpec(spec);
}
CopyUTF8toUTF16(spec, aValue);
// NS_IMPL_STRING_ATTR does nothing where we have (buf == null)
return NS_OK;
}
@ -660,9 +664,9 @@ nsHTMLAnchorElement::SetLinkState(nsLinkState aState)
}
NS_IMETHODIMP
nsHTMLAnchorElement::GetHrefUTF8(char** aBuf)
nsHTMLAnchorElement::GetHrefURI(nsIURI** aURI)
{
return GetHrefUTF8ForAnchors(aBuf);
return GetHrefURIForAnchors(aURI);
}
NS_IMETHODIMP

Просмотреть файл

@ -83,7 +83,7 @@ public:
// nsILink
NS_IMETHOD GetLinkState(nsLinkState &aState);
NS_IMETHOD SetLinkState(nsLinkState aState);
NS_IMETHOD GetHrefUTF8(char** aBuf);
NS_IMETHOD GetHrefURI(nsIURI** aURI);
NS_IMETHOD StringToAttribute(nsIAtom* aAttribute,
const nsAString& aValue,
@ -140,12 +140,12 @@ NS_NewHTMLAreaElement(nsIHTMLContent** aInstancePtrResult,
nsHTMLAreaElement::nsHTMLAreaElement()
: mLinkState(eLinkState_Unknown)
{
nsHTMLUtils::AddRef(); // for GetHrefUTF8
nsHTMLUtils::AddRef(); // for GetHrefURI
}
nsHTMLAreaElement::~nsHTMLAreaElement()
{
nsHTMLUtils::Release(); // for GetHrefUTF8
nsHTMLUtils::Release(); // for GetHrefURI
}
NS_IMPL_ADDREF_INHERITED(nsHTMLAreaElement, nsGenericElement)
@ -273,14 +273,14 @@ nsHTMLAreaElement::RemoveFocus(nsIPresContext* aPresContext)
NS_IMETHODIMP
nsHTMLAreaElement::GetHref(nsAString& aValue)
{
char *buf;
nsresult rv = GetHrefUTF8(&buf);
nsCOMPtr<nsIURI> uri;
nsresult rv = GetHrefURI(getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
if (buf) {
aValue.Assign(NS_ConvertASCIItoUCS2(buf));
nsCRT::free(buf);
if (uri) {
nsCAutoString spec;
uri->GetSpec(spec);
CopyUTF8toUTF16(spec, aValue);
}
// NS_IMPL_STRING_ATTR does nothing where we have (buf == null)
return NS_OK;
}
@ -571,7 +571,7 @@ nsHTMLAreaElement::SetLinkState(nsLinkState aState)
}
NS_IMETHODIMP
nsHTMLAreaElement::GetHrefUTF8(char** aBuf)
nsHTMLAreaElement::GetHrefURI(nsIURI** aURI)
{
return GetHrefUTF8ForAnchors(aBuf);
return GetHrefURIForAnchors(aURI);
}

Просмотреть файл

@ -86,7 +86,7 @@ public:
// nsILink
NS_IMETHOD GetLinkState(nsLinkState &aState);
NS_IMETHOD SetLinkState(nsLinkState aState);
NS_IMETHOD GetHrefUTF8(char** aBuf);
NS_IMETHOD GetHrefURI(nsIURI** aURI);
NS_IMETHOD SetDocument(nsIDocument* aDocument, PRBool aDeep,
PRBool aCompileEventHandlers) {
@ -186,7 +186,7 @@ public:
protected:
virtual void GetStyleSheetURL(PRBool* aIsInline,
nsAString& aUrl);
nsIURI** aURI);
virtual void GetStyleSheetInfo(nsAString& aTitle,
nsAString& aType,
nsAString& aMedia,
@ -226,12 +226,12 @@ NS_NewHTMLLinkElement(nsIHTMLContent** aInstancePtrResult,
nsHTMLLinkElement::nsHTMLLinkElement()
: mLinkState(eLinkState_Unknown)
{
nsHTMLUtils::AddRef(); // for GetHrefUTF8
nsHTMLUtils::AddRef(); // for GetHrefURI
}
nsHTMLLinkElement::~nsHTMLLinkElement()
{
nsHTMLUtils::Release(); // for GetHrefUTF8
nsHTMLUtils::Release(); // for GetHrefURI
}
@ -320,16 +320,15 @@ NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Type, type)
NS_IMETHODIMP
nsHTMLLinkElement::GetHref(nsAString& aValue)
{
char *buf;
nsresult rv = GetHrefUTF8(&buf);
nsCOMPtr<nsIURI> uri;
nsresult rv = GetHrefURI(getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
if (buf) {
aValue.Assign(NS_ConvertUTF8toUCS2(buf));
nsCRT::free(buf);
if (uri) {
nsCAutoString spec;
uri->GetSpec(spec);
CopyUTF8toUTF16(spec, aValue);
}
// NS_IMPL_STRING_ATTR does nothing where we have (buf == null)
return NS_OK;
}
@ -375,17 +374,17 @@ nsHTMLLinkElement::SetLinkState(nsLinkState aState)
}
NS_IMETHODIMP
nsHTMLLinkElement::GetHrefUTF8(char** aBuf)
nsHTMLLinkElement::GetHrefURI(nsIURI** aURI)
{
return GetHrefUTF8ForAnchors(aBuf);
return GetHrefURIForAnchors(aURI);
}
void
nsHTMLLinkElement::GetStyleSheetURL(PRBool* aIsInline,
nsAString& aUrl)
nsIURI** aURI)
{
*aIsInline = PR_FALSE;
GetHref(aUrl);
GetHrefURIForAnchors(aURI);
return;
}

Просмотреть файл

@ -168,7 +168,7 @@ public:
protected:
void GetStyleSheetURL(PRBool* aIsInline,
nsAString& aUrl);
nsIURI** aURI);
void GetStyleSheetInfo(nsAString& aTitle,
nsAString& aType,
nsAString& aMedia,
@ -204,12 +204,12 @@ NS_NewHTMLStyleElement(nsIHTMLContent** aInstancePtrResult,
nsHTMLStyleElement::nsHTMLStyleElement()
{
nsHTMLUtils::AddRef(); // for GetHrefUTF8ForAnchors
nsHTMLUtils::AddRef(); // for GetHrefURIForAnchors
}
nsHTMLStyleElement::~nsHTMLStyleElement()
{
nsHTMLUtils::Release(); // for GetHrefUTF8ForAnchors
nsHTMLUtils::Release(); // for GetHrefURIForAnchors
}
@ -314,9 +314,9 @@ nsHTMLStyleElement::SetInnerHTML(const nsAString& aInnerHTML)
void
nsHTMLStyleElement::GetStyleSheetURL(PRBool* aIsInline,
nsAString& aUrl)
nsIURI** aURI)
{
aUrl.Truncate();
*aURI = nsnull;
*aIsInline = !HasAttr(kNameSpaceID_None, nsHTMLAtoms::src);
if (*aIsInline) {
return;
@ -328,12 +328,7 @@ nsHTMLStyleElement::GetStyleSheetURL(PRBool* aIsInline,
return;
}
char *buf;
GetHrefUTF8ForAnchors(&buf);
if (buf) {
aUrl.Assign(NS_ConvertUTF8toUCS2(buf));
nsCRT::free(buf);
}
GetHrefURIForAnchors(aURI);
return;
}

Просмотреть файл

@ -595,15 +595,14 @@ PRBool nsStyleUtil::IsHTMLLink(nsIContent *aContent, nsIAtom *aTag, nsIPresConte
// if there is no link, then this anchor is not really a linkpseudo.
// bug=23209
nsXPIDLCString href;
link->GetHrefUTF8(getter_Copies(href));
nsCOMPtr<nsIURI> hrefURI;
link->GetHrefURI(getter_AddRefs(hrefURI));
if (href) {
nsILinkHandler *linkHandler = nsnull;
aPresContext->GetLinkHandler(&linkHandler);
if (hrefURI) {
nsCOMPtr<nsILinkHandler> linkHandler;
aPresContext->GetLinkHandler(getter_AddRefs(linkHandler));
if (linkHandler) {
linkHandler->GetLinkState(href, linkState);
NS_RELEASE(linkHandler);
linkHandler->GetLinkState(hrefURI, linkState);
}
else {
// no link handler? then all links are unvisited
@ -665,16 +664,14 @@ PRBool nsStyleUtil::IsSimpleXlink(nsIContent *aContent, nsIPresContext *aPresCon
}
}
// convert here, rather than twice in NS_MakeAbsoluteURI and
// back again
nsCAutoString absHREF;
(void) NS_MakeAbsoluteURI(absHREF, NS_ConvertUCS2toUTF8(val), baseURI);
nsCOMPtr<nsIURI> absURI;
// XXX should we make sure to get the right charset off the document?
(void) NS_NewURI(getter_AddRefs(absURI), val, nsnull, baseURI);
nsILinkHandler *linkHandler = nsnull;
aPresContext->GetLinkHandler(&linkHandler);
nsCOMPtr<nsILinkHandler> linkHandler;
aPresContext->GetLinkHandler(getter_AddRefs(linkHandler));
if (linkHandler) {
linkHandler->GetLinkState(absHREF, *aState);
NS_RELEASE(linkHandler);
linkHandler->GetLinkState(absURI, *aState);
}
else {
// no link handler? then all links are unvisited

Просмотреть файл

@ -53,19 +53,14 @@ class nsString;
class nsACString;
/**
* A version of NS_MakeAbsoluteURI that's savvy to document character
* set encodings, and will recode a relative spec in the specified
* charset and URL-escape it before resolving.
*
* XXXdarin this should really return a nsIURI
* A version of NS_NewURI that's savvy to document character
* set encodings
*/
nsresult
NS_MakeAbsoluteURIWithCharset(nsACString &aResult,
const nsString& aSpec,
nsIDocument* aDocument,
nsIURI* aBaseURI = nsnull,
nsIIOService* aIOService = nsnull,
nsICharsetConverterManager* aConvMgr = nsnull);
NS_NewURIWithDocumentCharset(nsIURI** aResult,
const nsString& aSpec,
nsIDocument* aDocument,
nsIURI* aBaseURI);
class nsHTMLUtils {

Просмотреть файл

@ -58,49 +58,21 @@
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
nsresult
NS_MakeAbsoluteURIWithCharset(nsACString &aResult,
const nsString& aSpec,
nsIDocument* aDocument,
nsIURI* aBaseURI,
nsIIOService* aIOService,
nsICharsetConverterManager* aConvMgr)
NS_NewURIWithDocumentCharset(nsIURI** aResult,
const nsString& aSpec,
nsIDocument* aDocument,
nsIURI* aBaseURI)
{
// Initialize aResult in case of tragedy
aResult.Truncate();
// Sanity
NS_PRECONDITION(aBaseURI != nsnull, "no base URI");
if (! aBaseURI)
return NS_ERROR_FAILURE;
// This gets the relative spec after gyrating it through all the
// necessary encodings and escaping.
if (IsASCII(aSpec)) {
// If it's ASCII, then just copy the characters
return aBaseURI->Resolve(NS_LossyConvertUCS2toASCII(aSpec), aResult);
}
nsCOMPtr<nsIURI> absURI;
nsresult rv;
nsCAutoString originCharset; // XXX why store charset as UCS2?
NS_PRECONDITION(aResult, "Null out param");
NS_PRECONDITION(aBaseURI, "Must have a base URI");
nsCAutoString originCharset;
if (aDocument && NS_FAILED(aDocument->GetDocumentCharacterSet(originCharset)))
originCharset.Truncate();
// URI can't be encoded in UTF-16, UTF-16BE, UTF-16LE, UTF-32, UTF-32-LE,
// UTF-32LE, UTF-32BE (yet?). Truncate it and leave it to default (UTF-8)
if (originCharset[0] == 'U' &&
originCharset[1] == 'T' &&
originCharset[2] == 'F')
originCharset.Truncate();
rv = nsHTMLUtils::IOService->NewURI(NS_ConvertUCS2toUTF8(aSpec),
originCharset.get(),
aBaseURI, getter_AddRefs(absURI));
if (NS_FAILED(rv)) return rv;
return absURI->GetSpec(aResult);
return nsHTMLUtils::IOService->NewURI(NS_ConvertUCS2toUTF8(aSpec),
originCharset.get(),
aBaseURI, aResult);
}

Просмотреть файл

@ -40,8 +40,10 @@
#include "nsXMLElement.h"
#include "nsHTMLAtoms.h"
#include "nsLayoutAtoms.h"
#include "nsHTMLUtils.h"
#include "nsIDocument.h"
#include "nsIAtom.h"
#include "nsNetUtil.h"
#include "nsIEventListenerManager.h"
#include "nsIDocShell.h"
#include "nsIEventStateManager.h"
@ -97,10 +99,12 @@ NS_NewXMLElement(nsIContent** aInstancePtrResult, nsINodeInfo *aNodeInfo)
nsXMLElement::nsXMLElement() : mIsLink(PR_FALSE)
{
nsHTMLUtils::AddRef(); // for NS_NewURIWithDocumentCharset
}
nsXMLElement::~nsXMLElement()
{
nsHTMLUtils::Release(); // for NS_NewURIWithDocumentCharset
}
@ -143,17 +147,6 @@ NS_IMPL_ADDREF_INHERITED(nsXMLElement, nsGenericElement)
NS_IMPL_RELEASE_INHERITED(nsXMLElement, nsGenericElement)
static inline nsresult MakeURI(const nsACString &aSpec, nsIURI *aBase, nsIURI **aURI)
{
nsresult rv;
static NS_DEFINE_CID(ioServCID,NS_IOSERVICE_CID);
nsCOMPtr<nsIIOService> service(do_GetService(ioServCID, &rv));
if (NS_FAILED(rv))
return rv;
return service->NewURI(aSpec,nsnull,aBase,aURI);
}
NS_IMETHODIMP
nsXMLElement::GetXMLBaseURI(nsIURI **aURI)
{
@ -176,14 +169,12 @@ nsXMLElement::GetXMLBaseURI(nsIURI **aURI)
// The complex looking if above is to make sure that we do not erroneously
// think a value of "./this:that" would have a scheme of "./that"
NS_ConvertUCS2toUTF8 str(value);
rv = MakeURI(str, nsnull, aURI);
rv = NS_NewURIWithDocumentCharset(aURI, value, mDocument, nsnull);
if (NS_FAILED(rv))
break;
if (!base.IsEmpty()) { // XXXdarin base is always empty
CopyUTF16toUTF8(base, str);
NS_ConvertUTF16toUTF8 str(base);
nsCAutoString resolvedStr;
rv = (*aURI)->Resolve(str, resolvedStr);
if (NS_FAILED(rv)) break;
@ -224,7 +215,7 @@ nsXMLElement::GetXMLBaseURI(nsIURI **aURI)
*aURI = docBase.get();
NS_IF_ADDREF(*aURI); // nsCOMPtr releases this once
} else {
rv = MakeURI(NS_ConvertUCS2toUTF8(base), docBase, aURI);
rv = NS_NewURIWithDocumentCharset(aURI, base, mDocument, docBase);
}
}
@ -319,15 +310,13 @@ static nsresult DocShellToPresContext(nsIDocShell *aShell,
}
static nsresult CheckLoadURI(nsIURI *aBaseURI, const nsAString& aURI,
nsIURI **aAbsURI)
static nsresult CheckLoadURI(const nsString& aSpec, nsIURI *aBaseURI,
nsIDocument* aDocument, nsIURI **aAbsURI)
{
NS_ConvertUCS2toUTF8 str(aURI);
*aAbsURI = nsnull;
nsresult rv;
rv = MakeURI(str, aBaseURI, aAbsURI);
rv = NS_NewURIWithDocumentCharset(aAbsURI, aSpec, aDocument, aBaseURI);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIScriptSecurityManager> securityManager =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
@ -449,12 +438,12 @@ nsXMLElement::MaybeTriggerAutoLink(nsIDocShell *aShell)
value);
if (rv == NS_CONTENT_ATTR_HAS_VALUE && !value.IsEmpty()) {
nsCOMPtr<nsIURI> uri;
rv = CheckLoadURI(base,value,getter_AddRefs(uri));
rv = CheckLoadURI(value, base, mDocument, getter_AddRefs(uri));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIPresContext> pc;
rv = DocShellToPresContext(aShell,getter_AddRefs(pc));
rv = DocShellToPresContext(aShell, getter_AddRefs(pc));
if (NS_SUCCEEDED(rv)) {
rv = TriggerLink(pc, verb, base, value,
rv = TriggerLink(pc, verb, base, uri,
NS_LITERAL_STRING(""), PR_TRUE);
return SpecialAutoLoadReturn(rv,verb);
@ -506,7 +495,6 @@ nsXMLElement::HandleDOMEvent(nsIPresContext* aPresContext,
break; // let the click go through so we can handle it in JS/XUL
}
nsAutoString show, href, target;
nsIURI* baseURL = nsnull;
nsLinkVerb verb = eLinkVerb_Undefined; // basically means same as replace
nsGenericContainerElement::GetAttr(kNameSpaceID_XLink,
nsHTMLAtoms::href,
@ -539,12 +527,16 @@ nsXMLElement::HandleDOMEvent(nsIPresContext* aPresContext,
verb = eLinkVerb_Embed;
}
GetXMLBaseURI(&baseURL);
nsCOMPtr<nsIURI> baseURL;
GetXMLBaseURI(getter_AddRefs(baseURL));
nsCOMPtr<nsIURI> uri;
ret = NS_NewURIWithDocumentCharset(getter_AddRefs(uri), href,
mDocument, baseURL);
if (NS_SUCCEEDED(ret)) {
ret = TriggerLink(aPresContext, verb, baseURL, uri, target,
PR_TRUE);
}
ret = TriggerLink(aPresContext, verb, baseURL, href, target,
PR_TRUE);
NS_IF_RELEASE(baseURL);
*aEventStatus = nsEventStatus_eConsumeDoDefault;
}
}
@ -586,7 +578,6 @@ nsXMLElement::HandleDOMEvent(nsIPresContext* aPresContext,
case NS_MOUSE_ENTER_SYNTH:
{
nsAutoString href, target;
nsIURI* baseURL = nsnull;
nsGenericContainerElement::GetAttr(kNameSpaceID_XLink,
nsHTMLAtoms::href,
href);
@ -595,12 +586,17 @@ nsXMLElement::HandleDOMEvent(nsIPresContext* aPresContext,
break;
}
GetXMLBaseURI(&baseURL);
nsCOMPtr<nsIURI> baseURL;
GetXMLBaseURI(getter_AddRefs(baseURL));
ret = TriggerLink(aPresContext, eLinkVerb_Replace, baseURL, href,
target, PR_FALSE);
nsCOMPtr<nsIURI> uri;
ret = NS_NewURIWithDocumentCharset(getter_AddRefs(uri), href,
mDocument, baseURL);
if (NS_SUCCEEDED(ret)) {
ret = TriggerLink(aPresContext, eLinkVerb_Replace, baseURL, uri,
target, PR_FALSE);
}
NS_IF_RELEASE(baseURL);
*aEventStatus = nsEventStatus_eConsumeDoDefault;
}
break;

Просмотреть файл

@ -71,7 +71,7 @@ public:
protected:
void GetStyleSheetURL(PRBool* aIsInline,
nsAString& aUrl);
nsIURI** aURI);
void GetStyleSheetInfo(nsAString& aTitle,
nsAString& aType,
nsAString& aMedia,
@ -157,10 +157,10 @@ nsXMLStylesheetPI::GetCharset(nsAString& aCharset)
void
nsXMLStylesheetPI::GetStyleSheetURL(PRBool* aIsInline,
nsAString& aUrl)
nsIURI** aURI)
{
*aIsInline = PR_FALSE;
aUrl.Truncate();
*aURI = nsnull;
nsAutoString href;
GetAttrValue(NS_LITERAL_STRING("href"), href);
@ -169,10 +169,12 @@ nsXMLStylesheetPI::GetStyleSheetURL(PRBool* aIsInline,
}
nsCOMPtr<nsIURI> url, baseURL;
nsCAutoString charset;
if (mDocument) {
mDocument->GetBaseURL(getter_AddRefs(baseURL));
mDocument->GetDocumentCharacterSet(charset);
}
NS_MakeAbsoluteURI(aUrl, href, baseURL);
NS_NewURI(aURI, href, charset.get(), baseURL);
}
void

Просмотреть файл

@ -757,86 +757,26 @@ nsWebShell::OnLeaveLink()
return rv;
}
nsresult
nsWebShell::NormalizeURI(nsACString& aURLSpec)
{
nsIURI *uri = nsnull;
nsCAutoString scheme;
nsresult rv = mIOService->ExtractScheme(aURLSpec, scheme);
if (NS_FAILED(rv)) return rv;
// keep tempUri up here to keep it in scope
nsCOMPtr<nsIURI> tempUri;
// used to avoid extra work later
PRBool clearUri(PR_TRUE);
if (scheme.Equals(NS_LITERAL_CSTRING("http"))) {
if (mCachedHttpUrl)
rv = mCachedHttpUrl->SetSpec(aURLSpec);
else
rv = NS_NewURI(getter_AddRefs(mCachedHttpUrl), aURLSpec);
uri = mCachedHttpUrl;
}
else if (scheme.Equals(NS_LITERAL_CSTRING("https"))) {
if (mCachedHttpsUrl)
rv = mCachedHttpsUrl->SetSpec(aURLSpec);
else
rv = NS_NewURI(getter_AddRefs(mCachedHttpsUrl), aURLSpec);
uri = mCachedHttpsUrl;
}
else if (scheme.Equals(NS_LITERAL_CSTRING("ftp"))) {
if (mCachedFtpUrl)
rv = mCachedFtpUrl->SetSpec(aURLSpec);
else
rv = NS_NewURI(getter_AddRefs(mCachedFtpUrl), aURLSpec);
uri = mCachedFtpUrl;
} else {
rv = NS_NewURI(getter_AddRefs(tempUri), aURLSpec);
uri = tempUri;
clearUri = PR_FALSE;
}
// covers all above failures
if (NS_FAILED(rv)) return rv;
rv = uri->GetSpec(aURLSpec);
// clear out the old spec, for security reasons - old data should
// not be floating around in cached URIs!
// (but avoid doing extra work if we're just destroying the uri)
if (clearUri)
uri->SetSpec(NS_LITERAL_CSTRING(""));
return rv;
}
NS_IMETHODIMP
nsWebShell::GetLinkState(const nsACString& aLinkURI, nsLinkState& aState)
nsWebShell::GetLinkState(nsIURI* aLinkURI, nsLinkState& aState)
{
if (!aLinkURI) {
// No uri means not a link
aState = eLinkState_NotLink;
return NS_OK;
}
aState = eLinkState_Unvisited;
// no history, leave state unchanged
if (!mGlobalHistory)
return NS_OK;
// default to the given URI
nsCAutoString resolvedPath(aLinkURI);
nsresult rv;
// get the cached IO service
if (!mIOService)
mIOService = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
NormalizeURI(resolvedPath);
nsCAutoString spec;
aLinkURI->GetSpec(spec);
PRBool isVisited;
NS_ENSURE_SUCCESS(mGlobalHistory->IsVisited(resolvedPath.get(), &isVisited),
NS_ENSURE_SUCCESS(mGlobalHistory->IsVisited(spec.get(), &isVisited),
NS_ERROR_FAILURE);
if (isVisited)
aState = eLinkState_Visited;

Просмотреть файл

@ -87,7 +87,7 @@ public:
nsIURI* aURI,
const PRUnichar* aTargetSpec);
NS_IMETHOD OnLeaveLink();
NS_IMETHOD GetLinkState(const nsACString& aLinkURI, nsLinkState& aState);
NS_IMETHOD GetLinkState(nsIURI* aLinkURI, nsLinkState& aState);
NS_IMETHOD Create();
NS_IMETHOD Destroy();
@ -117,8 +117,6 @@ protected:
nsIChannel* channel,
nsresult aStatus);
nsresult NormalizeURI(nsACString& aURLSpec);
PRThread *mThread;
nsIWebShellContainer* mContainer;
@ -134,17 +132,6 @@ protected:
nsIStreamListener** aResult);
nsCOMPtr<nsICommandManager> mCommandManager;
// cached io service for NS_NewURI
nsCOMPtr<nsIIOService> mIOService;
// these are specifically cached for these
// protocols, because we're optimizing for link coloring -
// most links are http, https, or ftp
nsCOMPtr<nsIURI> mCachedHttpUrl;
nsCOMPtr<nsIURI> mCachedHttpsUrl;
nsCOMPtr<nsIURI> mCachedFtpUrl;
#ifdef DEBUG
private:

Просмотреть файл

@ -595,15 +595,14 @@ PRBool nsStyleUtil::IsHTMLLink(nsIContent *aContent, nsIAtom *aTag, nsIPresConte
// if there is no link, then this anchor is not really a linkpseudo.
// bug=23209
nsXPIDLCString href;
link->GetHrefUTF8(getter_Copies(href));
nsCOMPtr<nsIURI> hrefURI;
link->GetHrefURI(getter_AddRefs(hrefURI));
if (href) {
nsILinkHandler *linkHandler = nsnull;
aPresContext->GetLinkHandler(&linkHandler);
if (hrefURI) {
nsCOMPtr<nsILinkHandler> linkHandler;
aPresContext->GetLinkHandler(getter_AddRefs(linkHandler));
if (linkHandler) {
linkHandler->GetLinkState(href, linkState);
NS_RELEASE(linkHandler);
linkHandler->GetLinkState(hrefURI, linkState);
}
else {
// no link handler? then all links are unvisited
@ -665,16 +664,14 @@ PRBool nsStyleUtil::IsSimpleXlink(nsIContent *aContent, nsIPresContext *aPresCon
}
}
// convert here, rather than twice in NS_MakeAbsoluteURI and
// back again
nsCAutoString absHREF;
(void) NS_MakeAbsoluteURI(absHREF, NS_ConvertUCS2toUTF8(val), baseURI);
nsCOMPtr<nsIURI> absURI;
// XXX should we make sure to get the right charset off the document?
(void) NS_NewURI(getter_AddRefs(absURI), val, nsnull, baseURI);
nsILinkHandler *linkHandler = nsnull;
aPresContext->GetLinkHandler(&linkHandler);
nsCOMPtr<nsILinkHandler> linkHandler;
aPresContext->GetLinkHandler(getter_AddRefs(linkHandler));
if (linkHandler) {
linkHandler->GetLinkState(absHREF, *aState);
NS_RELEASE(linkHandler);
linkHandler->GetLinkState(absURI, *aState);
}
else {
// no link handler? then all links are unvisited

Просмотреть файл

@ -2264,8 +2264,14 @@ nsStandardURL::Init(PRUint32 urlType,
else
mOriginCharset = charset;
// an empty charset implies UTF-8
if (mOriginCharset.EqualsIgnoreCase("UTF-8"))
// URI can't be encoded in UTF-16, UTF-16BE, UTF-16LE, UTF-32, UTF-32-LE,
// UTF-32LE, UTF-32BE (yet?). Truncate mOriginCharset if it starts with
// "utf" (since an empty mOriginCharset implies UTF-8, this is safe even if
// mOriginCharset is UTF-8).
if (mOriginCharset.Length() >= 3 &&
(mOriginCharset[0] == 'U' || mOriginCharset[0] == 'u') &&
(mOriginCharset[1] == 'T' || mOriginCharset[1] == 't') &&
(mOriginCharset[2] == 'F' || mOriginCharset[2] == 'f'))
mOriginCharset.Truncate();
if (baseURI) {

Просмотреть файл

@ -138,7 +138,7 @@ public:
/**
* Get the state of a link to a given absolute URL
*/
NS_IMETHOD GetLinkState(const nsACString& aLinkURI, nsLinkState& aState) = 0;
NS_IMETHOD GetLinkState(nsIURI* aLinkURI, nsLinkState& aState) = 0;
};
#endif /* nsILinkHandler_h___ */