Bug 324093: make needsHomePageOverride return true only for new profiles, instead of every version bump, r=mconnor

This commit is contained in:
gavin%gavinsharp.com 2006-01-21 20:12:47 +00:00
parent 76b73fa44a
commit d694d48b6a
3 changed files with 143 additions and 46 deletions

View File

@ -55,6 +55,8 @@ REQUIRES = xpcom \
uconv \
pref \
dom \
content \
htmlparser \
intl \
windowwatcher \
unicharutil \

View File

@ -66,6 +66,17 @@
#include "nsIDOMCharacterData.h"
#include "nsIDOMNodeList.h"
#include "nsIDOM3Node.h"
#include "nsIDOMDocumentTraversal.h"
#include "nsIDOMTreeWalker.h"
#include "nsIDOMNodeFilter.h"
#include "nsIDOMDocumentFragment.h"
#include "nsIParser.h"
#include "nsParserCIID.h"
#include "nsIFragmentContentSink.h"
#include "nsIContentSink.h"
#include "nsIDocument.h"
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
/* These are defined in nsBookmarksService.cpp */
extern nsIRDFResource *kRDF_type;
@ -146,8 +157,9 @@ protected:
// helpers
NS_METHOD HandleRDFItem (nsIRDFDataSource *aDS, nsIRDFResource *itemResource,
nsIRDFResource *aLinkResource, nsIRDFResource *aTitleResource);
NS_METHOD FindTextInNode (nsIDOMNode *aParentNode, nsAString &aString);
NS_METHOD FindTextInChildNodes (nsIDOMNode *aNode, nsAString &aString);
NS_METHOD ParseHTMLFragment(nsAString &aFragString, nsIDocument* aTargetDocument, nsIDOMNode **outNode);
PRBool IsLinkValid(const PRUnichar *aURI);
nsBookmarksService *mBMSVC;
@ -462,44 +474,79 @@ nsFeedLoadListener::TryParseAsRDF ()
return NS_OK;
}
//
// find the first node below aParentNode that is a TEXT_NODE,
// and return it
//
nsresult
nsFeedLoadListener::FindTextInNode (nsIDOMNode *aParentNode, nsAString &aString)
nsFeedLoadListener::ParseHTMLFragment(nsAString &aFragString,
nsIDocument* aTargetDocument,
nsIDOMNode **outNode)
{
NS_ENSURE_ARG(aParentNode);
NS_ENSURE_ARG(aTargetDocument);
nsresult rv;
nsCOMPtr<nsIDOMNode> childNode;
rv = aParentNode->GetFirstChild(getter_AddRefs(childNode));
if (!childNode) return NS_OK;
nsCOMPtr<nsIParser> parser;
parser = do_CreateInstance(kCParserCID, &rv);
if (NS_FAILED(rv)) return rv;
// create the html fragment sink
nsCOMPtr<nsIContentSink> sink;
sink = do_CreateInstance(NS_HTMLFRAGMENTSINK2_CONTRACTID);
NS_ENSURE_TRUE(sink, NS_ERROR_FAILURE);
nsCOMPtr<nsIFragmentContentSink> fragSink(do_QueryInterface(sink));
NS_ENSURE_TRUE(fragSink, NS_ERROR_FAILURE);
fragSink->SetTargetDocument(aTargetDocument);
// parse the fragment
parser->SetContentSink(sink);
parser->Parse(aFragString, (void*)0, NS_LITERAL_CSTRING("text/html"), PR_FALSE, PR_TRUE, eDTDMode_fragment);
// get the fragment node
nsCOMPtr<nsIDOMDocumentFragment> contextfrag;
rv = fragSink->GetFragment(getter_AddRefs(contextfrag));
NS_ENSURE_SUCCESS(rv, rv);
rv = CallQueryInterface (contextfrag, outNode);
return rv;
}
// find all of the text and CDATA nodes below aNode and return them as a string
nsresult
nsFeedLoadListener::FindTextInChildNodes (nsIDOMNode *aNode, nsAString &aString)
{
NS_ENSURE_ARG(aNode);
nsresult rv;
nsCOMPtr<nsIDOMDocument> aDoc;
aNode->GetOwnerDocument(getter_AddRefs(aDoc));
nsCOMPtr<nsIDOMDocumentTraversal> trav = do_QueryInterface(aDoc, &rv);
if (NS_FAILED(rv)) return rv;
PRUint16 nodeType = 0;
do {
rv = childNode->GetNodeType(&nodeType);
if (nodeType == nsIDOMNode::TEXT_NODE ||
nodeType == nsIDOMNode::CDATA_SECTION_NODE)
break;
nsCOMPtr<nsIDOMTreeWalker> walker;
rv = trav->CreateTreeWalker(aNode,
nsIDOMNodeFilter::SHOW_TEXT | nsIDOMNodeFilter::SHOW_CDATA_SECTION,
nsnull, PR_TRUE, getter_AddRefs(walker));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDOMNode> temp;
rv = childNode->GetNextSibling(getter_AddRefs(temp));
if (NS_FAILED(rv)) return rv;
childNode = temp;
} while (childNode);
if (nodeType == nsIDOMNode::TEXT_NODE ||
nodeType == nsIDOMNode::CDATA_SECTION_NODE)
{
nsCOMPtr<nsIDOMCharacterData> charTextNode = do_QueryInterface(childNode);
if (charTextNode)
return charTextNode->GetData(aString);
nsCOMPtr<nsIDOMNode> currentNode;
walker->GetCurrentNode(getter_AddRefs(currentNode));
nsCOMPtr<nsIDOMCharacterData> charTextNode;
nsAutoString tempString;
while (currentNode) {
charTextNode = do_QueryInterface(currentNode);
if (charTextNode) {
charTextNode->GetData(tempString);
aString.Append(tempString);
}
walker->NextNode(getter_AddRefs(currentNode));
}
return NS_ERROR_FAILURE;
if (aString.IsEmpty()) {
return NS_ERROR_FAILURE;
} else {
return NS_OK;
}
}
nsresult
@ -672,12 +719,59 @@ nsFeedLoadListener::TryParseAsSimpleRSS ()
rv = childNode->GetNodeName (childNname);
if (childNname.Equals(NS_LITERAL_STRING("title"))) {
rv = FindTextInNode (childNode, titleStr);
if (isAtom) {
/* Atom titles can contain HTML, so we need to find and remove it */
nsCOMPtr<nsIDOMElement> titleElem = do_QueryInterface(childNode);
if (!titleElem) break; // out of while(childNode) loop
nsAutoString titleMode; // Atom 0.3 only
nsAutoString titleType;
titleElem->GetAttribute(NS_LITERAL_STRING("type"), titleType);
titleElem->GetAttribute(NS_LITERAL_STRING("mode"), titleMode);
/* No one does this in <title> except standards pedants making test feeds,
* Atom 0.3 is deprecated, and RFC 4287 doesn't allow it
*/
if (titleMode.EqualsLiteral("base64")) {
break; // out of while(childNode) loop
}
/* Cover Atom 0.3 and RFC 4287 together */
if (titleType.EqualsLiteral("text") ||
titleType.EqualsLiteral("text/plain") ||
titleType.IsEmpty())
{
rv = FindTextInChildNodes(childNode, titleStr);
} else if (titleType.EqualsLiteral("html") || // RFC 4287
(titleType.EqualsLiteral("text/html") && // Atom 0.3
!titleMode.EqualsLiteral("xml")) ||
titleMode.EqualsLiteral("escaped")) // Atom 0.3
{
nsAutoString escapedHTMLStr;
rv = FindTextInChildNodes(childNode, escapedHTMLStr);
if (NS_FAILED(rv)) break; // out of while(childNode) loop
nsCOMPtr<nsIDOMNode> newNode;
nsCOMPtr<nsIDocument> doc = do_QueryInterface(xmldoc);
ParseHTMLFragment(escapedHTMLStr, doc, getter_AddRefs(newNode));
rv = FindTextInChildNodes(newNode, titleStr);
}else if (titleType.EqualsLiteral("xhtml") || // RFC 4287
titleType.EqualsLiteral("application/xhtml") || // Atom 0.3
titleMode.EqualsLiteral("xml")) // Atom 0.3
{
rv = FindTextInChildNodes(childNode, titleStr);
} else {
break; // out of while(childNode) loop
}
} else {
rv = FindTextInChildNodes(childNode, titleStr);
}
if (NS_FAILED(rv)) break;
} else if (childNname.Equals(NS_LITERAL_STRING("pubDate")) ||
childNname.Equals(NS_LITERAL_STRING("updated")))
{
rv = FindTextInNode (childNode, dateStr);
rv = FindTextInChildNodes (childNode, dateStr);
if (NS_FAILED(rv)) break;
} else if (!isAtom && childNname.Equals(NS_LITERAL_STRING("guid"))) {
nsCOMPtr<nsIDOMElement> linkElem = do_QueryInterface(childNode);
@ -688,7 +782,7 @@ nsFeedLoadListener::TryParseAsSimpleRSS ()
// Ignore failures. isPermaLink defaults to true.
if (!isPermaLink.Equals(NS_LITERAL_STRING("false"))) {
// in node's TEXT
rv = FindTextInNode (childNode, linkStr);
rv = FindTextInChildNodes (childNode, linkStr);
if (NS_FAILED(rv)) break;
}
} else if (childNname.Equals(NS_LITERAL_STRING("link"))) {
@ -724,12 +818,13 @@ nsFeedLoadListener::TryParseAsSimpleRSS ()
}
} else if (linkStr.IsEmpty()) {
// in node's TEXT
rv = FindTextInNode (childNode, linkStr);
rv = FindTextInChildNodes (childNode, linkStr);
if (NS_FAILED(rv)) break;
}
}
}
if (!titleStr.IsEmpty() && !linkStr.IsEmpty())
break;
@ -738,7 +833,12 @@ nsFeedLoadListener::TryParseAsSimpleRSS ()
childNode = temp;
if (!childNode || NS_FAILED(rv)) break;
}
// Clean up whitespace
titleStr.CompressWhitespace();
linkStr.Trim("\b\t\r\n ");
dateStr.CompressWhitespace();
if (titleStr.IsEmpty() && !dateStr.IsEmpty())
titleStr.Assign(dateStr);

View File

@ -106,24 +106,19 @@ function resolveURIInternal(aCmdLine, aArgument) {
}
function needHomepageOverride(prefb) {
var savedmstone;
var savedmstone = null;
try {
savedmstone = prefb.getCharPref("browser.startup.homepage_override.mstone");
}
catch (e) {
}
if (savedmstone == "ignore")
return false;
} catch (e) {}
var mstone = Components.classes["@mozilla.org/network/protocol;1?name=http"]
.getService(nsIHttpProtocolHandler).misc;
if (mstone == savedmstone)
return false;
if (mstone != savedmstone)
prefb.setCharPref("browser.startup.homepage_override.mstone", mstone);
prefb.setCharPref("browser.startup.homepage_override.mstone", mstone);
return true;
// Return true if the pref didn't exist (i.e. new profile)
return !savedmstone;
}
function openWindow(parent, url, target, features, args) {