Use What's Related tab provided by Alexa Internet. Resolves What's Related data on a per url basis (used to be on domain only). Bug 50594.

This commit is contained in:
slamm%netscape.com 2000-08-28 23:24:28 +00:00
parent 75784d00bd
commit fb6fa3c0c5
7 changed files with 200 additions and 303 deletions

View File

@ -36,7 +36,6 @@ CHROME_CONTENT = \
$(NULL)
CHROME_L10N = \
locale/en-US/related-panel.dtd \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -1 +0,0 @@
en-US:related-panel.dtd

View File

@ -1 +0,0 @@
related-panel.dtd

View File

@ -1,5 +0,0 @@
<!-- extracted from ./related-panel.xul -->
<!ENTITY related.row.label "Related Links">
<!ENTITY sitemap.row.label "Sitemap">
<!ENTITY lastsearch.row.label "Last Search Results">

View File

@ -33,7 +33,6 @@ CHROME_CONTENT = \
$(NULL)
CHROME_L10N = \
.\locale\en-US\related-panel.dtd \
$(NULL)
include <$(DEPTH)\config\rules.mak>

View File

@ -10,14 +10,13 @@
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
* The Original Code is from Alexa Internet (www.alexa.com).
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
* The Initial Developer of the Original Code is Alexa Internet.
* Portions created by Alexa Internet are Copyright (C) 2000 Alexa
* Internet. All Rights Reserved.
*
* Contributor(s):
* Contributor(s):
*/
/*
@ -25,277 +24,230 @@
*/
var kUnknownReasonUrl = 'about:blank';
var kMAMIUrl = 'http://client.alexa.com/MAMI/ns_whats_related/ns_whats_related.htm?';
function debug(msg)
{
var kNoHTTPReasonUrl = kMAMIUrl + 'req_type=secure_intranet';
var kSkipDomainReasonUrl = kMAMIUrl + 'req_type=blocked_list';
var kDataPrefixUrl = kMAMIUrl;
var oNavObserver = null;
function debug(msg) {
// uncomment for noise
// dump(msg);
dump("-+- related-panel: " + msg + "\n");
}
// get handle to the BrowserAppCore in the content area.
var appCore = window._content.appCore;
// The content window that we're supposed to be observing.
var ContentWindow = window._content;
// The related links handler
var Handler = Components.classes["component://netscape/related-links-handler"].createInstance();
Handler = Handler.QueryInterface(Components.interfaces.nsIRelatedLinksHandler);
// Our observer object
var Observer = {
Observe: function(subject, topic, data) {
debug("Observer.Observe(" + subject + ", " + topic + ", " + data + ")\n");
if (subject != ContentWindow)
{
debug("subject was not content window, ignoring\n");
return;
}
refetchRelatedLinks(Handler, data);
}
}
function
skipRelatedLinksDomain(newDomain)
// Our observer of Navigation Messages
function NavObserver(oDisplayFrame,oContentWindow)
{
var skipDomainFlag = false;
if (newDomain[newDomain.length - 1] == '/')
{
newDomain = newDomain.substring(0, newDomain.length - 1);
this.m_oDisplayFrame = oDisplayFrame;
this.m_oContentWindow = oContentWindow;
this.m_sWindowID = ''+parseInt(Math.random()*32767);
this.m_sLastDataUrl = 'about:blank'; // The last url that we drove our display to.
}
NavObserver.prototype.Observe =
function (oSubject, sMessage, sContextUrl)
{
debug("Observer("+sMessage+", "+sContextUrl+")");
try {
if (oSubject != this.m_oContentWindow) {
// only pay attention to our client window.
return;
}
var bReferrer = (this.m_oContentWindow.document.referrer)?true:false;
if ((sMessage == 'EndDocumentLoad')
&& (sContextUrl != this.m_oContentWindow.location)) {
// we were redirected...
sContextUrl = '' + this.m_oContentWindow.location;
bReferrer = true;
}
this.TrackContext(sContextUrl, bReferrer);
} catch(ex) {
}
}
NavObserver.prototype.GetCDT =
function (bReferrer)
{
var sCDT = '';
sCDT += 't=' +(bReferrer?'1':'0');
sCDT += '&pane=nswr6';
sCDT += '&wid='+this.m_sWindowID;
return escape(sCDT);
}
NavObserver.prototype.TrackContext =
function (sContextUrl, bReferrer)
{
debug("TrackContext(" + sContextUrl + ", " + (bReferrer?"true":"false") + ")");
if (sContextUrl != this.m_sLastContextUrl && this.m_oDisplayFrame) {
var sDataUrl = this.TranslateContext(sContextUrl,bReferrer);
debug("TrackContext: setting iframe to " + sDataUrl);
this.m_oDisplayFrame.setAttribute('src', sDataUrl);
this.m_sLastContextUrl = sContextUrl;
}
}
NavObserver.prototype.TranslateContext =
function (sUrl, bReferrer)
{
debug("TranslateContext(" + sUrl + ", " + (bReferrer?"true":"false") + ")");
if (!sUrl || ('string' != typeof(sUrl))
|| ('' == sUrl) || sUrl == 'about:blank') {
debug('TranlateContext: bad argument')
return kUnknownReasonUrl;
}
try
{
// Strip off any query strings (Don't want to be too nosy).
var nQueryPart = sUrl.indexOf('?');
if (nQueryPart != 1) {
sUrl = sUrl.slice(0, nQueryPart);
}
// We can only get related links data on HTTP URLs
if (0 != sUrl.indexOf("http://")) {
debug('TranlateContext: non-http argument:('+sUrl+')');
return kNoHTTPReasonUrl;
}
// ...and non-intranet sites(those that have a '.' in the domain)
var sUrlSuffix = sUrl.substr(7); // strip off "http://" prefix
var nFirstSlash = sUrlSuffix.indexOf('/');
var nFirstDot = sUrlSuffix.indexOf('.');
if (-1 == nFirstDot) {
debug('TranlateContext: no "." in url');
return kNoHTTPReasonUrl;
}
if ((nFirstSlash < nFirstDot) && (-1 != nFirstSlash)) {
debug('TranlateContext: no "." in domain');
return kNoHTTPReasonUrl;
}
// url is http, non-intranet url: see if the domain is in their blocked list.
var nPortOffset = sUrlSuffix.indexOf(":");
var nFirstSlash = sUrlSuffix.indexOf("/");
var nDomainEnd = (((nPortOffset >=0) && (nPortOffset <= nFirstSlash))
? nPortOffset : nFirstSlash);
var sDomain = sUrlSuffix;
if (-1 != nDomainEnd) {
sDomain = sUrlSuffix.substr(0,nDomainEnd);
}
if (DomainInSkipList(sDomain)) {
debug('TranlateContext: argument in skip-list');
return kSkipDomainReasonUrl;
} else {
// ok! it is a good url!
var sFinalUrl = kDataPrefixUrl;
sFinalUrl += 'cdt='+this.GetCDT(bReferrer);
sFinalUrl += '&url='+sUrl;
return sFinalUrl;
}
}
function DomainInSkipList(sDomain)
{
var bSkipDomainFlag = false;
if ('/' == sDomain[sDomain.length - 1]) {
sDomain = sDomain.substring(0, sDomain.length - 1);
}
try {
var pref = Components.classes["component://netscape/preferences"];
if (pref) pref = pref.getService();
if (pref) pref = pref.QueryInterface(Components.interfaces.nsIPref);
if (pref)
{
var domainList = pref.CopyCharPref("browser.related.disabledForDomains");
if ((domainList) && (domainList != ""))
{
debug("\nProposed New Domain: '" + newDomain + "'\n");
debug("Skip Domain List: '" + domainList + "'\n");
if (pref) pref = pref.getService();
if (pref) pref = pref.QueryInterface(Components.interfaces.nsIPref);
if (pref) {
var sDomainList = pref.CopyCharPref("browser.related.disabledForDomains");
if ((sDomainList) && (sDomainList != "")) {
debug("\nProposed New Domain: '" + sDomain + "'\n");
debug("Skip Domain List: '" + sDomainList + "'\n");
var domains = domainList.split(","); // split on commas
for (var x=0; x < domains.length; x++)
{
var aDomain = newDomain;
var aDomains = sDomainList.split(",");
var domain = domains[x];
debug("Skip Domain #" + x + ": " + domain + "\n");
// split on commas
for (var x=0; x < aDomains.length; x++) {
var sDomainCopy = sDomain;
if (domain[0] == '*') // wildcard match
{
var sTestDomain = aDomains[x];
debug("Skip Domain #" + x + ": " + sTestDomain + "\n");
if ('*' == sTestDomain[0]) { // wildcard match
debug(" Wildcard domain.\n");
domain = domain.substring(1); // strip off the asterisk
if (aDomain.length > domain.length)
{
aDomain = aDomain.substring(newDomain.length-domain.length);
// strip off the asterisk
sTestDomain = sTestDomain.substring(1);
if (sDomainCopy.length > sTestDomain.length) {
var sDomainIndex = sDomain.length - sTestDomain.length;
sDomainCopy = sDomainCopy.substring(sDomainIndex);
}
}
if (aDomain.lastIndexOf(domain) == 0)
{
debug(" Skip this domain '" + aDomain + "'\n");
if (0 == sDomainCopy.lastIndexOf(sTestDomain)) {
debug(" Skip this domain '" + sDomainCopy + "'\n");
skipDomainFlag = true;
bSkipDomainFlag = true;
break;
}
}
}
}
} catch(ex) {
}
catch(ex)
{
}
return(skipDomainFlag);
return(bSkipDomainFlag);
}
function refetchRelatedLinks(Handler, data)
{
var newSite = "" + data;
// if we're looking at a translated page, get RL data for the true site
if (newSite.indexOf("http://levis.alis.com:8080/") == 0)
{
var matchStr = "AlisTargetURI="; // this is expected to be the last argument
var targetOffset = data.indexOf(matchStr);
if (targetOffset > 0)
{
targetOffset += matchStr.length;
newSite = newSite.substr(targetOffset);
data = newSite;
}
}
// we can only get related links data on HTTP URLs
if (newSite.indexOf("http://") != 0)
{
debug("Unable to fetch related links data on non-HTTP URL.\n");
return(false);
}
newSite = newSite.substr(7); // strip off "http://" prefix
var portOffset = newSite.indexOf(":");
var slashOffset = newSite.indexOf("/");
var theOffset = ((portOffset >=0) && (portOffset <= slashOffset)) ? portOffset : slashOffset;
if (theOffset >= 0) newSite = newSite.substr(0, theOffset);
var currentSite = "";
if (Handler.URL != null)
{
currentSite = Handler.URL.substr(7); // strip off "http://" prefix
portOffset = currentSite.indexOf(":");
slashOffset = currentSite.indexOf("/");
theOffset = ((portOffset >=0) && (portOffset <= slashOffset)) ? portOffset : slashOffset;
if (theOffset >= 0) currentSite = currentSite.substr(0, theOffset );
}
debug("Related Links: Current top-level: " + currentSite + " new top-level: " + newSite + "\n");
// only request new related links data if we've got a new web site (hostname change)
if (currentSite != newSite)
{
// privacy: don't send anything after a '?'
var theSite = "" + data;
var questionOffset = theSite.indexOf("?");
if (questionOffset > 0)
{
theSite = theSite.substr(0, questionOffset);
}
if (skipRelatedLinksDomain(newSite) != true)
{
Handler.URL = theSite;
}
}
}
function Init()
{
// Initialize the Related Links panel
// Create a Related Links handler, and install it in the tree
var Tree = document.getElementById("Tree");
Tree.database.AddDataSource(Handler.QueryInterface(Components.interfaces.nsIRDFDataSource));
// Install our navigation observer so we can track the main client window.
// Install the observer so we'll be notified when new content is loaded.
var ObserverService = Components.classes["component://netscape/observer-service"].getService();
ObserverService = ObserverService.QueryInterface(Components.interfaces.nsIObserverService);
if (ObserverService)
{
ObserverService.AddObserver(Observer, "StartDocumentLoad");
ObserverService.AddObserver(Observer, "EndDocumentLoad");
ObserverService.AddObserver(Observer, "FailDocumentLoad");
debug("added observer\n");
}
else
{
debug("FAILURE to get observer service\n");
}
oContentWindow = window._content;
oFrame = document.getElementById('daFrame');
if (ContentWindow) {
refetchRelatedLinks(Handler, ContentWindow.location);
if (oContentWindow && oFrame) {
window.setTimeout('window._content.resizeBy(0,1);window._content.resizeBy(0,-1);',0);
var oObserverService = Components.classes["component://netscape/observer-service"].getService();
oObserverService = oObserverService.QueryInterface(Components.interfaces.nsIObserverService);
oNavObserver = new NavObserver(oFrame,oContentWindow);
oNavObserver.TrackContext(''+oContentWindow.location);
if (oObserverService && oNavObserver) {
oObserverService.AddObserver(oNavObserver, "StartDocumentLoad");
oObserverService.AddObserver(oNavObserver, "EndDocumentLoad");
oObserverService.AddObserver(oNavObserver, "FailDocumentLoad");
debug("added observer\n");
} else {
oNavObserver = null;
debug("FAILURE to get observer service\n");
}
}
}
function Destruct() {
// Install the observer so we'll be notified when new content is loaded.
var ObserverService = Components.classes["component://netscape/observer-service"].getService();
ObserverService = ObserverService.QueryInterface(Components.interfaces.nsIObserverService);
if (ObserverService)
{
debug("Removing observer\n");
ObserverService.RemoveObserver(Observer, "StartDocumentLoad");
ObserverService.RemoveObserver(Observer, "EndDocumentLoad");
ObserverService.RemoveObserver(Observer, "FailDocumentLoad");
}
else
{
debug("FAILURE to get observer service\n");
}
}
function openURL(event, root)
function Destruct()
{
if (event.type == "click" && event.button != 1) {
return false;
}
var target = event.target.parentNode.parentNode;
if (target.getAttribute('container') == 'true') {
// If single-clicking a folder, open/close it.
if (target.getAttribute('open') == 'true') {
target.removeAttribute('open');
} else {
target.setAttribute('open','true');
}
return true;
}
if (event.detail != 1) {
return false;
}
var treeitem = document.getElementById(root).selectedItems[0];
if (treeitem.getAttribute("type") ==
"http://home.netscape.com/NC-rdf#BookmarkSeparator") {
return(false);
}
var id = treeitem.getAttribute('id');
if (!id) return(false);
// rjc: add support for anonymous resources; if the node has
// a "#URL" property, use it, otherwise default to using the id
try
{
var rootNode = document.getElementById(root);
var ds = null;
if (rootNode)
{
ds = rootNode.database;
}
var rdf = Components.classes["component://netscape/rdf/rdf-service"].getService();
if (rdf) rdf = rdf.QueryInterface(Components.interfaces.nsIRDFService);
if (rdf)
{
if (ds)
{
var src = rdf.GetResource(id, true);
var prop = rdf.GetResource("http://home.netscape.com/NC-rdf#URL", true);
var target = ds.GetTarget(src, prop, true);
if (target) target = target.QueryInterface(Components.interfaces.nsIRDFLiteral);
if (target) target = target.Value;
if (target) id = target;
}
}
}
catch(ex)
{
}
if(appCore)
{
// support session history (if appCore is available)
appCore.loadUrl(id);
}
else
{
// fallback case (if appCore isn't available)
ContentWindow.location = id;
// remove our navigation observer.
var oObserverService = Components.classes["component://netscape/observer-service"].getService();
oObserverService = oObserverService.QueryInterface(Components.interfaces.nsIObserverService);
if (oObserverService && oNavObserver) {
debug("Removing observer\n");
oObserverService.RemoveObserver(oNavObserver, "StartDocumentLoad");
oObserverService.RemoveObserver(oNavObserver, "EndDocumentLoad");
oObserverService.RemoveObserver(oNavObserver, "FailDocumentLoad");
oNavObserver = null;
} else {
debug("FAILURE to get observer service\n");
}
}

View File

@ -11,69 +11,23 @@
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is mozilla.org code.
The Original Code is from Alexa Internet (www.alexa.com).
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998 Netscape Communications Corporation. All
Rights Reserved.
The Initial Developer of the Original Code is Alexa Internet.
Portions created by Alexa Internet are Copyright (C) 2000 Alexa
Internet. All Rights Reserved.
Contributor(s):
-->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://communicator/skin/related/related.css" type="text/css"?>
<!DOCTYPE window SYSTEM "chrome://communicator/locale/related/related-panel.dtd" >
<window
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
orient="vertical">
>
<script src="chrome://communicator/content/related/related-panel.js"></script>
<script src="chrome://communicator/content/related/related-panel.js" />
<!--
Note that the empty "datasources='rdf:null'" will ensure that a composite
datasource is created and a content model builder is installed, even
though there is no datasource from which to build content yet.
-->
<tree id="Tree" ref="NC:RelatedLinks" container="true" flex="1"
datasources="rdf:null" onclick="openURL(event, 'Tree');"
onkeypress="openURL(event, 'Tree');">
<template>
<rule rdf:type="http://home.netscape.com/NC-rdf#BookmarkSeparator">
<treechildren flex="1">
<treeitem uri="..."
type="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type">
<treerow class="relatedseparator">
<treecell>
<separator class="groove" flex="1"/>
</treecell>
</treerow>
</treeitem>
</treechildren>
</rule>
<rule>
<treechildren flex="1">
<treeitem uri="..."
type="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type">
<treerow class="relatedresult">
<treecell class="treecell-indent" value="rdf:http://home.netscape.com/NC-rdf#Name"
src="rdf:http://home.netscape.com/NC-rdf#Icon" />
</treerow>
</treeitem>
</treechildren>
</rule>
</template>
<treecolgroup>
<treecol flex="1" rdf:resource="http://home.netscape.com/NC-rdf#Name" />
</treecolgroup>
</tree>
<iframe id="daFrame" src="about:blank" flex="1" />
</window>