Tel: 01884 860 900
Faux Fur Ruffle Scarves
£ 27.50 inc VAT
So warm and snug, you can wear it all day long, as the style works with both indoor and outdoor wear.
![]() |
The ruffle scarves come tied with satin ribbon so make an excellent gift. |
Available in 4 colourways
Length 84cm
Machine washable at 40 degrees and cool tumble dry.
|
Nebraska |
Snow Leopard |
Lavender |
|
|
Mink Crush |
Zebra |
Alberta |
0) avglsflyover.hide(null, 1); var phishLinks = []; for (var i=0; i < links.length; i++) { var isPhishing = searchshield.avglsCheckandUpdate(links[i], engine); if (!!isPhishing) { phishLinks.push(links[i]); } } if (phishLinks.length > 0) { var prev = ’1’; if ( engine.type == ’inline’ ) prev = ’0’; searchshield.avgCallFunc(doc, ’GetPhishingResults’, prev); } else if (links.length > 0 && engine.type != ’inline’) { searchshield.avgCallFunc(doc, ’FinalScanComplete’); } }, stop: function(){ if (searchshield.avgSearchMonitor.timeoutID) { window.clearTimeout(searchshield.avgSearchMonitor.timeoutID); delete searchshield.avgSearchMonitor.timeoutID; } } }; searchshield.avgProcessSearch = function (doc) { // doc may be about:Tabs or about:Blank if (!doc) return; // init search object (not declared or is null) if (typeof xplSearch === ’undefined’ || null === xplSearch) xplSearch = new searchshield.Search(); xplSearch.doc = doc; xplSearch.href = xplSearch.doc.location.href; xplSearch.uri = searchshield.parseLink(xplSearch.href); if (!searchshield.clockUrl) searchshield.clockUrl = searchshield.avgCallFunc(doc, ’GetIconUrl’, ’0’); xplSearch.clockUrl = searchshield.clockUrl if (!xplSearch.engines) { var aEng = xplSearch.getSearchNames(); var aEngLen = aEng.length; for (var i=0; i < aEngLen; i++) { xplSearch.addEngine(new searchshield[aEng[i]+’SearchEngine’](xplSearch)); } } if (!xplSearch.engine) { var engLen = xplSearch.engines.length; for (var i = 0; i < engLen; i++) { if (xplSearch.engines[i].validSearch()) { xplSearch.engine = xplSearch.engines[i]; break; } } } if (!xplSearch.engine) return; // set verdict display config xplSearch.engine.setRatingsConfig(doc); // init the alert popup searchshield.initPopupAlert(doc); // start search monitor searchshield.avgSearchMonitor.start(doc, xplSearch.engine); // attach click handlers for popup alerts doc.body.detachEvent("onclick", searchshield.blockClick); doc.body.attachEvent("onclick", searchshield.blockClick); doc.body.detachEvent("ondblclick", searchshield.blockClick); doc.body.attachEvent("ondblclick", searchshield.blockClick); }; searchshield.avgGetSearchLinks = function (doc, engine) { if (!engine) { // restart page monitor searchshield.avgPageMonitor.start(doc); return; } var alltags = doc.getElementsByTagName(’*’); for (var i = 0; i < alltags.length; i++) { if (alltags[i].getAttribute(’avglschecked’)) continue; // ignore linked resources if ((alltags[i].tagName) && (alltags[i].tagName == ’LINK’)) continue; // ignore in-page bookmarks and javascript if ((!alltags[i].href) || (alltags[i].href.charAt(0) == ’#’) || // in-page bookmark (alltags[i].href.indexOf("javascript") == 0)) continue; // ignore verdicts if (alltags[i].id && (alltags[i].id.indexOf("XPLSS_") != -1)) continue; // ignore flyover anchors if (alltags[i].href && (alltags[i].href.indexOf("linkscanner:") == 0 || alltags[i].href.indexOf("avgthreatlabs.com") != -1)) continue; var href = engine.includeLink(alltags[i]); if (!href) continue; var newNode = engine.search.addLink(alltags[i], href); engine.addImage(newNode, engine.search.clockUrl, false); } // recursivesly process all frames var docFrames = doc.frames; if (docFrames && engine.processFrames) { for (var j = 0; j < docFrames.length; j++) { var attr; var frameDoc; try { attr = docFrames[j].frameElement.className; frameDoc = docFrames[j].document; } catch(err){} //TODO: make frame processing an engine function or at least make exclusions an engine property // ’editable’ frame it’s probably a gmail reply if (attr && (attr.indexOf("editable") != -1)) continue; if (frameDoc) searchshield.avgGetSearchLinks(frameDoc, engine); } } return engine.search.links; }; searchshield.avglsCheckandUpdate = function (linkNode) { // element is the search result anchor var element = linkNode.element; var href = linkNode.href; if (!xplSearch) return; var result = searchshield.avgCallFunc(xplSearch.doc, ’CheckSite’, href, element.href); if (result == null) return; var resultParse = result.split(’::’); var phishing = resultParse[0]; // if phishing then rest of array does not exist. if (phishing == 1) return true; if (resultParse.length < 8) return; var hash = resultParse[1]; var score = resultParse[2]; var new_image = resultParse[3]; var alt_image = resultParse[4]; var flyover = resultParse[5]; var click_thru= resultParse[6]; var altClick_thru = resultParse[7]; // iterate to get verdict anchor nextElem = element.nextSibling; while (nextElem) { if (nextElem.nodeType == 1 && nextElem.id && (nextElem.id.indexOf("XPLSS_") != -1)) break; nextElem = nextElem.nextSibling; } xplSearch.engine.updateImage(hash, xplSearch.searchHash, score, new_image, alt_image, flyover, click_thru, altClick_thru); }; // click event handler - shows popup for links of caution and warning severity searchshield.blockClick = function(event) { if (!event) event = window.event; // no action needed if click is not the left mouse button if (event.button != 0) return; var anchor = searchshield.getAnchorNode(event.srcElement, function(node) {return ((node.tagName.charAt(0) == "H") || (node.tagName.charAt(0) == "D") || (node.tagName.charAt(0) == "T"))} ); if ((anchor == null) || (anchor.href == null)) return true; // ignore if anchor is on an xpl verdict if (!!anchor.id) { if (anchor.id.indexOf(’LXPLSS_’) == 0) return true; if (anchor.id.indexOf(’XPLSS_INTR’) == 0) { searchshield.allowedSites.push(searchshield.GetDomain(anchor.href)) return true; } } // VeriSign A/B Split reporting - only for VerSign domains var avglschecked = anchor.getAttribute("avglschecked"); if (avglschecked && avglschecked != 1) { var sPos = avglschecked.indexOf("S"); var hash = (sPos > -1) ? avglschecked.substring(0, sPos) : null; var split = (sPos > -1) ? avglschecked.substring(sPos+1) : null; if (hash && split && split != searchshield.VERISIGN_SPLIT_NOTEST) { // check updated verdict anchor for verisign domain var d = event.srcElement.ownerDocument; if (d.getElementById("LXPLSS_" + hash + "U" + searchshield.SCORE_SS_VERISIGN)) { searchshield.avgCallFunc(d, "RecordVSClick", hash, d.location.href); } } } var link = anchor.href; var verdict = searchshield.getAvgImage(anchor); var score = -1; var img_id = ’’; if (verdict != null) { score = verdict.score; img_id = verdict.rawId; } // show popup alert (upper left) if ((score >= searchshield.SCORE_SS_CAUTION) && (score <= searchshield.SCORE_SS_WARNING)) { // prevent this click from going any further var search_hash = searchshield.avgCallFunc(document, ’GetHash’, document.location.href); searchshield.ShowPopupAlert(document, link, img_id, search_hash); // if possible, stop the event from going any further searchshield.cancelEvent(event); return false; } return true; }; // called by native to update phishing links searchshield.updatePhishingLinks = function (results) { if (!results) return; if (!xplSearch) return; var engine = xplSearch.engine; var resultParse = results.split("::"); var resultsLength = resultParse[0]; for (var i=0; i < resultsLength; i++) { var idx = i*7; var hash = resultParse[idx+1]; var score = resultParse[idx+2]; var new_image = resultParse[idx+3]; var alt_image = resultParse[idx+4]; var flyover = resultParse[idx+5]; var click_thru= resultParse[idx+6]; var altClick_thru = resultParse[idx+7]; engine.updateImage(hash, xplSearch.searchHash, score, new_image, alt_image, flyover, click_thru, altClick_thru); } }; searchshield.getAvgImage = function (element) { var obj = {}; obj.img = xplSearch.engine.getImgElement(element); obj.score = -1; //parse the score from the id if (obj.img != null && obj.img.id) { var pos = !!obj.img.id ? obj.img.id.indexOf(’U’) + 1 : -1; obj.score = (pos < 1) ? -1 : obj.img.id.charAt(pos); obj.rawId = obj.img.id.substring(0,pos-1); } return obj; }; searchshield.GetScannedLink = function (link) { if (!xplSearch || !(xplSearch.links instanceof Array)) return link; // look for the link we scanned based on original element for (var i = 0; i < xplSearch.links.length; i++) { if (xplSearch.links[i].element.href == link) return xplSearch.links[i].href; } // else return the incoming link return link; }; searchshield.previouslyScanned = function (links, hash) { for (var i = 0; i < links.length; i++) { if ((links[i] != null) && (links[i].hash != null) && (links[i].hash == hash) && (links[i].checked == true)) return true; } return false; }; searchshield.initPopupAlert = function (doc) { // check if it exists first if (doc.getElementById("XPLSS_PopupAlert")) return; // create a div to use for the popup itself, hide for now var popup_div = doc.createElement("DIV"); popup_div.setAttribute("id", "XPLSS_PopupAlert"); popup_div.style.position = "absolute"; popup_div.style.zIndex = "10000"; doc.body.appendChild(popup_div); }; searchshield.initFlyover = function (doc, engine) { // create in top doc only if (doc !== window.top.document) doc = window.top.document; // check if it exists first if ((doc == null) || (doc.getElementById("XPLSS_Flyover"))) return; // create a div to use for the flyover itself, hide for now var flyover_div = doc.createElement("DIV"); flyover_div.setAttribute("id", "XPLSS_Flyover"); flyover_div.style.position = "absolute"; flyover_div.style.zIndex = "10000"; doc.body.appendChild(flyover_div); // create a layer for the image var trans_div = doc.createElement("DIV"); trans_div.setAttribute("id", "XPLSS_Trans"); trans_div.style.position = "absolute"; trans_div.style.zIndex = "9999"; doc.body.appendChild(trans_div); }; searchshield.ShowPopupAlert = function (doc, link, hash, search) { // build the content var popup_content = searchshield.avgCallFunc(doc, ’BuildPopupAlert’, hash, search); if (popup_content == null || popup_content == "") return; // get the div var div = doc.getElementById("XPLSS_PopupAlert"); div.innerHTML = searchshield.CleanupHTML(popup_content); // set position, account for scrolling var zoom = searchshield.zoomLevel(); var pageOffsetX = Math.round(doc.documentElement.scrollLeft/zoom); var pageOffsetY = Math.round(doc.documentElement.scrollTop/zoom); div.style.left = 10 + pageOffsetX + "px"; div.style.top = 10 + pageOffsetY + "px"; // TODO: the event handler function doesn’t exist so, is this even necessary? //div.attachEvent("onmouseout", HidePopupAlert); // set the link //var data = doc.getElementById("avgalertpopurl"); //if (data) // data.innerHTML = escape(link); // set visibility div.style.visibility = "visible"; //navigate to the link after timed delay // TODO: Bug 31707 - make this open a new tab/window setTimeout(function(){doc.location.assign(link)}, 3000); }; searchshield.avgCallFunc = function (doc, name /*, param1..., paramN*/) { // get the data element var avg_ls_data = (typeof gAvgDataElement !== ’undefined’) ? gAvgDataElement : doc.getElementById("avglsdata"); if ((avg_ls_data == null) || (name == null)) return; // save the data element gAvgDataElement = avg_ls_data; // for some reason you can’t fire and event on an element with no parent node if (avg_ls_data.parentNode == null) return; // set the attributes avg_ls_data.setAttribute("function", name); // set variable length of optional parameter attributes var pcnt = 0; for (var i=2; i < arguments.length; i++) avg_ls_data.setAttribute("param"+(++pcnt), arguments[i]); avg_ls_data.fireEvent("onrowenter"); // get the result return avg_ls_data.getAttribute("result"); }; // general use functions - begin // DOM Functions searchshield.getAnchorNode = function (node, filterFunc) { // filterFunc should return a boolean if (!filterFunc || !filterFunc instanceof Function) return null; // go up the dom tree starting at node and look for anchor // before hitting a header, div or table element while ((node != null) && (node.tagName != null) && (node.tagName != "A")) { if (filterFunc(node)) { node = null; break; } node = node.parentNode; } return node; }; searchshield.getDocuments = function (frame, frameArray) { // recursively get all embedded frames/docs frameArray.push(frame.document); var frames = frame.frames; for (var i = 0; i < frames.length; i++) { // recurse on each frame searchshield.getDocuments(frames[i], frameArray); } return frameArray; }; searchshield.NextSiblingNode = function (element) { var TEXTNODE = 3; var ParentNode = element.parentNode; if (!ParentNode) return; var NextSibling = ParentNode.nextSibling; while (NextSibling) { if (NextSibling.nodeType != TEXTNODE) return NextSibling; NextSibling = NextSibling.nextSibling; } return; }; searchshield.getParentNodeByAttribute = function (attrName, attrValue, node, maxDepth) { if (!node) return null; var maxLoop = maxDepth ? maxDepth : 1; var pNode = node.parentNode; if (!pNode) return null; for(; 0 < maxLoop; maxLoop--) { if ((pNode[attrName]) && (pNode[attrName].toLowerCase() === attrValue.toLowerCase())) { return pNode; } pNode = pNode.parentNode; if (!pNode) return null; } return null; }; searchshield.getParentNodeByClassName = function (className, node, maxDepth) { return searchshield.getParentNodeByAttribute("className", className, node, maxDepth); }; searchshield.getParentNodeById = function (id, node, maxDepth) { return searchshield.getParentNodeByAttribute("id", id, node, maxDepth); }; searchshield.getParentNodeByTagName = function (tagName, node, attrName) { // find parent node by tag name and optional attribute name if (!tagName || !node || !node.parentNode) return null; tagName = tagName.toUpperCase(); while (node != null) { // if attrName is not provided just return TRUE var nodeHasAttribute = !!attrName ? !!node[attrName] : true; if ((node.tagName == tagName) && (nodeHasAttribute)) return node; node = node.parentNode; } // no div return null; }; searchshield.getTopLevelDocument = function (doc) { // return the top level document for the given doc, could be itself // TODO: determine a method of doing this for IE, if necessary // don’t check about:blank if (doc && (doc.location.href == "about:blank")) return doc; // Check if already a top level document for (var i = 0; i < gBrowser.browsers.length; i++) { if (doc == gBrowser.browsers[i].contentDocument) return doc; } // Not a top level, check all frames var documents; for (var j = 0; j < gBrowser.browsers.length; j++) { // get all docs for each browser documents = searchshield.getDocuments(gBrowser.browsers[j].contentWindow, new Array()); for (var k = 0; k < documents.length; k++) { // check if doc is from current browser if (doc == documents[k]) { // it is, return the top level doc for this browser return gBrowser.browsers[j].contentDocument; } } } return doc; }; searchshield.getTopLevelWindow = function () { // TODO: determine a method of doing this for IE, if necessary return mediator.getMostRecentWindow("navigator:browser"); }; //Event functions searchshield.addListener = function (object, evtType, listener, useCapture) { useCapture = !!useCapture; if (object.addEventListener) { object.addEventListener(evtType, listener, useCapture); return true; } else if (object.attachEvent) { object.attachEvent("on"+evtType, listener); return true; } return false; }; searchshield.cancelEvent = function (event) { event.cancelBubble = true; event.returnValue = false; }; searchshield.doEvent = function (evtObj, evtTarget, evtName, evtType, bubbles, cancelable) { bubbles = !!bubbles; cancelable = !!cancelable; if (document.createEvent) { var evt = document.createEvent("Events"); evt.initEvent(evtName, bubbles, cancelable); evtTarget.dispatchEvent(evt); return true; } else if (document.createEventObject) { var evt = document.createEventObject(evtObj); evtTarget.fireEvent("on" + evtType, evt); return true; } return false; }; searchshield.removeListener = function (object, evtType, listener, useCapture) { useCapture = !!useCapture; if (object.removeEventListener) { object.removeEventListener(evtType, listener, useCapture); return true; } else if (object.detachEvent) { object.detachEvent(evtType, listener); return true; } return false; }; // HTML functions searchshield.CleanupHTML = function (data) { if (data == null) return data; // cleanup html data, replace any new lines data = data.replace(/\r/g, ""); data = data.replace(/\n/g, ""); // escape any single quotes data = data.replace(/’/g, "\\’"); return data; }; searchshield.removeHtmlTags = function (str) { var re = new RegExp(’(<[^>]+>)’,’g’); var strStr = new String(str); if (!!strStr) return strStr.replace(re, ’’); else return str; }; // Browser functions searchshield.containedIn = function (container, element) { while (element != null) { if (container == element) { return true; } element = element.parentNode; } return false; }; searchshield.elementSize = function (element) { //returns an array [sizeX, sizeY] var elemX; var elemY; elemX = parseInt(element.offsetWidth); elemY = parseInt(element.offsetHeight) return [elemX, elemY]; }; searchshield.GetFullBoundingRect = function (element) { if (!element) return; // get bounding rect for incoming element var elementRect = element.getBoundingClientRect(); var nextImg = null; var nextImgRect = null; // first check for another non-TextNode element after this one var siblingElement = searchshield.NextSiblingNode(element); if ( siblingElement && siblingElement.firstChild && siblingElement.id && siblingElement.id.indexOf("XPLSS_") != -1) { nextImg = siblingElement.firstChild; nextImgRect = nextImg.getBoundingClientRect(); } else { return elementRect; } if ((nextImgRect.top >= elementRect.bottom) && (nextImgRect.left <= elementRect.left)) { // images appear to be on seperate lines return elementRect; } // else merge the rects together into a new one var newRect = new function() { this.top=0; this.left=0; this.right=0; this.bottom=0; this.mid=0;}; newRect.top = Math.min(elementRect.top, nextImgRect.top); newRect.left= Math.min(elementRect.left, nextImgRect.left); newRect.right=Math.max(elementRect.right, nextImgRect.right); newRect.bottom=Math.max(elementRect.bottom, nextImgRect.bottom); newRect.mid = Math.min(elementRect.right, nextImgRect.left); return newRect; }; searchshield.offsetLeft = function (element) { var offset = 0; while (element) { offset += element.offsetLeft; element = element.offsetParent; } return offset; }; searchshield.offsetTop = function (element) { var offset = 0; while (element) { offset += element.offsetTop; element = element.offsetParent; } return offset; }; searchshield.scrollSize = function (imageElem) { // returns an array [scrollX, scrollY, hasParentFrame] var scrollX; var scrollY; var hasParentFrame; // firefox if (window.pageXOffset && window.pageYOffset) { scrollX = window.pageXOffset; scrollY = window.pageYOffset; } else if (document.documentElement || document.body) { scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; scrollY = document.documentElement.scrollTop || document.body.scrollTop; if (imageElem) { var frames = document.frames; if (frames) { for (var i=0; i < frames.length; i++) { var img; try { img = frames[i].document.getElementById(imageElem.id); } catch(domErr){} if (img != null) { scrollX = frames[i].document.documentElement.scrollLeft; scrollY = frames[i].document.documentElement.scrollTop; hasParentFrame = true; break; } } } } } else { scrollX = 0; scrollY = 0; } return [parseInt(scrollX,10), parseInt(scrollY,10), hasParentFrame]; }; searchshield.viewPortSize = function () { // returns an array [width, height, scrollYWidth], where scrollYWidth is always 0 for IE var scrollXWidth = 19; var scrollYWidth = 0; // 0 for Microsoft IE var scrollBarX = false; var windowX; var windowY; // firefox if (window.innerWidth && window.innerHeight) { //TODO: validate this block if implemented for firefox windowX = window.innerWidth - scrollXWidth; windowY = window.innerHeight; try { scrollYWidth = Math.floor(Math.abs(window.innerHeight - document.documentElement.clientHeight)) + 1; scrollBarX = (document.documentElement.clientWidth < document.documentElement.scrollWidth); } catch(err){} if (scrollBarX && !scrollYWidth) scrollYWidth = 18; //normally 17 (+1 top border) } else if (document.documentElement || document.body) { windowX = (document.documentElement.clientWidth || document.body.clientWidth) - scrollXWidth; windowY = document.documentElement.clientHeight || document.body.clientHeight; } else { windowX = 0; windowY = 0; } return [windowX, windowY, scrollYWidth]; }; searchshield.zoomLevel = function () { var level = 1; if (document.body.getBoundingClientRect) { // rect is only in physical pixel size before IE8 var rect = document.body.getBoundingClientRect(); level = Math.round (((rect.right - rect.left) / (document.body.offsetWidth)) * 100) / 100; } return level; }; // Href functions searchshield.checkUrl = function (url) { // cleanup a url, make sure there is a protocol on the front for scanning try { // trim url = url.replace(/^\s+/, "").replace(/\s+$/, ""); // if no protocol, add http:// to it if (url.indexOf("://") == -1) url = "http://" + url; } catch(err){} return url; }; searchshield.DoesURLContain = function (url, contain) { if ((url == null) || (url.length < 1)) return false; // breakup the url to check var parts = url.split(’/’); if (parts.length < 3) return false; var domain= parts[2].toLowerCase(); if (domain.indexOf(contain) > -1) return true; return false; }; searchshield.FilterUrl = function (url, filter) { if (!url || (url.length < 1)) return false; if (!filter || !(filter instanceof Array)) return false; var parts = url.split(’/’); if ((parts == null) || (parts.length < 3)) return false; var domain = parts[2]; for (var i = 0; i < filter.length; i++) { if (domain.indexOf(filter[i]) != -1) return true; } return false; }; searchshield.GetDomain = function (url) { if (url != null) { // get url domain var parts = url.split(’/’); if ((parts != null) && (parts.length >= 3)) { return parts[2].toLowerCase(); } } return url; }; searchshield.getUrlContents = function (url) { if (url == null) return null; // don’t query if local url if (url.indexOf("linkscanner://") != -1) return null; try { req = new XMLHttpRequest(); req.open("GET", url, false); req.send(null); if (req.status == 200) return req.responseText; else return null; } catch (err) { // nothing to do return null; } }; searchshield.parseLink = function (href, simpleMode) { var uri = {}; var parameter = { complex: { pattern: /^(?:([a-z]+):(?:([a-z]*):)?\/\/)?(?:([^:@]*)(?::([^:@]*))?@)?((?:[a-z0-9_-]+\.)+[a-z]{2,})(?::(\d+))?(?:([^:\?\#]+))?(?:\?([^\#]+))?(?:\#([^\s]+))?$/i, element: [’source’,’scheme’,’subscheme’,’user’,’pass’,’host’,’port’,’path’,’query’,’fragment’] }, simple: { pattern: /^(?:([a-z]+):\/\/)?((?:[a-z0-9_-]+\.)+[a-z]{2,})(?:\/)([^:\?]+)?(?:([\?|\#])([^\?]+))?$/i, element: [’source’,’scheme’,’host’,’path’,’delimiter’,’query’] } }; var mode = simpleMode !== false ? ’simple’ : ’complex’; var pattern = parameter[mode].pattern; var element = parameter[mode].element; if (!href) return uri; var matches = href.match(pattern); if (matches) { // -------------------- // iterate over the matches array and populate uri properties // using the respective element parameter as the name. // NOTE: set raw property type as String to make inArray() // work properly with instanceof. // -------------------- for (var i=0; i < matches.length; i++) uri[element[i]] = new String(matches[i] || ""); // -------------------- // create an array, hostArray, from host, for example, // host="www.google.com" and hostArray=["www","google","com"] // -------------------- uri.hostArray = uri.host.split("."); // -------------------- // create an array, qsArray, from query, for example, // query=’hl=en&q=javascript&btnG=Search&aq=f&aqi=g10&aql=&oq=&gs_rfai=’ // qsArray=[{hl:’en’},{q:javascript}, ... ,(qs_rfai:’’}] // // $0=entire match, $1=capture 1, $2=capture 2 // must include $0 even though it is unused so // the replace works properly // -------------------- uri.qsArray = []; uri.query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function ($0, $1, $2) { if ($1) uri.qsArray[$1] = $2; } ); } //non-standard urls require a fail-safe that relies on simply splitting the href function splitLink(href) { // split the href on ’/’ var linkParts = href.split("/"); // need domain and path if ((linkParts == null) || (linkParts.length < 2)) return false; var uri = { delimiter: (linkParts[3]).substring(0,1), host: linkParts[2], hostArray: (linkParts[2]).split(’.’), path: (linkParts[3]).substring(1), qsArray: {}, query: ’’, scheme: (linkParts[0]).substring(0, linkParts[0].length-1), source: href }; return uri; } if (!uri.host) uri = splitLink(href); return uri; }; // general functions searchshield.arrayKeys = function (array) { var keys = new Array(); for(k in array) keys.push(k); return keys; }; searchshield.inArray = function (key, array, caseSensitive, exactMatch) { if (! array instanceof Array) return false; if (caseSensitive !== true) caseSensitive = false; if (exactMatch !== false) exactMatch = true; if (key instanceof String) { for (var i=0; i < array.length; i++) { var k = caseSensitive ? key.valueOf() : key.valueOf().toLowerCase(); var a = caseSensitive ? array[i] : array[i].toLowerCase(); if(exactMatch && k === a) return true; else if (!exactMatch && (-1 !== k.indexOf(a))) return true; } } else if (key instanceof Array) { for (var i=0; i < array.length; i++) for (var j=0; j < key.length; j++) { var k = caseSensitive ? key[j] : key[j].toLowerCase(); var a = caseSensitive ? array[i] : array[i].toLowerCase(); if (exactMatch && k === a) return true; else if (!exactMatch && (-1 !== k.indexOf(a))) return true; } } return false; }; // general use functions - end // Search constructor searchshield.Search = function() { this.doc = null; this.engine = null; this.engines = null; this.links = null; this.uri = null; this.searchHash = null; this.checkUrl = null; this.useLocalImgs = null; this.clockUrl = null; // create engine list (actually key/value object will be used) this.engineList = {}; }; searchshield.Search.prototype.getSearchNames = function() { // order is important var names = [ ’Google’, ’AVGGoogle’, ’AltaVista’, ’AVGYahoo’, ’Yahoo’, ’Bing’, ’MSN’, // MSN redirects to BING ’Baidu’, ’Earthlink’, ’AOL’, ’Ask’, ’Yandex’, ’Seznam’, ’Webhledani’, ’eBay’, ///temp ’Digg’, ’Slashdot’, ’Twitter’, ’GMail’, ’Facebook’ ]; return names; }; searchshield.Search.prototype.detectEngine = function(href) { if (!href) return; var aEng = searchshield.Search.prototype.getSearchNames(); var aEngLen = aEng.length; for (var i=0; i < aEngLen; i++) { if (searchshield[aEng[i] + ’SearchEngine’].prototype.validSearch(href)) return aEng[i]; } return; }; searchshield.Search.prototype.addEngine = function(engine) { if (!this.engines) this.engines = new Array(); this.engines.push(engine); }; searchshield.Search.prototype.addLink = function(inElement, inHref) { if (!this.links) this.links = new Array(); var hrefHash; try { hrefHash = searchshield.avgCallFunc(this.doc, ’GetHash’, inHref); } catch (e){} var newNode = { element: inElement, href: inHref, hash: hrefHash, search: this.searchHash }; this.links.push(newNode); return newNode; } // process the search result page after all search engines have been added searchshield.Search.prototype.process = function(doc) { // only process when searchshield is enabled if (0 == searchshield.avgCallFunc(doc, ’GetSearchEnabled’)) return; this.doc = doc; this.href = this.doc.location.href; this.uri = searchshield.parseLink(this.href); try { this.searchHash = searchshield.avgCallFunc(this.doc, ’GetHash’, this.href); // get any previously active engine this.engine = this.engineList[this.searchHash.toString()]; } catch (e) {} /* Process Steps: 1. Add all supported search engines 2. Identify the active search engine 3. Get all document links and add AVG images */ // STEP 1 - Add all supported search engines if (!this.engines) { var aEng = xplSearch.getSearchNames(); var aEngLen = aEng.length; for (var i=0; i < aEngLen; i++) { xplSearch.addEngine(new searchshield[aEng[i]+’SearchEngine’](this)); } } // search the engines if we didn’t find one if (!this.engine) { // STEP 2 - Identify the active search engine var engLen = this.engines.length; for (var i = 0; i < engLen; i++) { if (this.engines[i].validSearch()) { this.engine = this.engines[i]; break; } } // create a new engine instance to store this.engineList[this.searchHash.toString()] = this.engine; // init this search, if < 1 either an error or disabled //var sdkInit = 0; //try { // sdkInit = xpl_sdk.SXPL_InitSearch(this.href); //} //catch(e){} //if (sdkInit < 1) // return false; } // return immediately if there is not an active search engine if (!this.engine) return false; try { // base url to check for icons this.checkUrl = searchshield.avgCallFunc(this.doc, ’GetIconUrl’, ’1’); // check if using linked or local icons this.useLocalImgs = !searchshield.getUrlContents(this.checkUrl); // get the clock url this.clockUrl = searchshield.avgCallFunc(this.doc, ’GetIconUrl’, ’0’); } catch(e){} // STEP 3 - Get all document links and add AVG images var alltags = this.doc.getElementsByTagName("*"); // this method works for IE, FF and Chrome for (var i=0; i < alltags.length; i++) { // ignore verdicts if (alltags[i].id && (alltags[i].id.indexOf("LXPLSS_") != -1)) continue; //should the link be included? Make sure includeLink always returns an href else FALSE, var href = this.engine.includeLink(alltags[i]); if (!href) continue; var newNode = this.addLink(alltags[i], href); this.engine.addImage(newNode, this.clockUrl, false); } return (this.links ? this.links.length : false); }; //////////////// SEARCH //////////////// //////////////// SEARCH ENGINE //////////////// // Interface for a SearchEngine object searchshield.SearchEngine = function(search) { this.search = search; this.type = ’standard’; this.processFrames = false; this.new_links = true; this.onlyPrimaries = true; this.inline = { clockImage: "linkscanner://clock12.png", image: [ "linkscanner://safe12.png", "linkscanner://caution12.png", "linkscanner://warning12.png", "linkscanner://blocked12.png" ], color: { border: ["#00A120;", "#EAA500;", "#F57301;", "#D20003;"], background: ["#C3E5CA;", "#FEEFAE;", "#FFD3B0;", "#F5D4C1;"] } }; this.filter_urls = [ "ad.doubleclick.net", "ads1.revenue.net", "aslads.ask.com", "bluestreak.com", "clickbacktrack.net", "clickbank.net", "clickboothlnk.com", "clickmanager.com", "clickserve.cc-dt.com", "clickserve.dartsearch.net", "clicktraxmedia.com", "clk.atdmt.com", "dpi-digialphoto.com", "feedpoint.net", "hypertracker.com", "jdoqocy.com", "kqzyfj.com", "m1428.ic-live.com", "mediaplex.com", "mr.mdmngr.com", "n339.asp-cc.com", "offeredby.net", "offerweb.com", "pinktrax.com", "pinktrax.com", "pixel1523.everesttech.net", "qckjmp.com", "r.rd06.com", "revenuewire.net", "s0b.bluestreak.com", "s2.srtk.net", "servedby.advertising.com", "store.yahoo.com", "tf8.cpcmanager.com", "thetoptracker.com", "track.searchignite.com", "tracking.searchmarketing.com", "www.dpbolvw.net", "www.rkdms.com", "www.yellowbookleads.com" ]; this.shortened_urls = [ "3.ly", "bit.ly", "is.gd", "tr.im", "short.to", "tiny.cc", "tinyurl.com" ]; this.showCleanVerdicts = true; this.showLowRiskVerdicts = true; this.showMedRiskVerdicts = true; this.VeriSignSplit = searchshield.VERISIGN_SPLIT_NOTEST; }; searchshield.SearchEngine.prototype.flyoverExists = function (doc) { return !!doc.getElementById("XPLSS_Flyover"); }; searchshield.SearchEngine.prototype.inlineExists = function (doc) { return !!doc.getElementById("XPLSS_InlineFlyover"); }; searchshield.SearchEngine.prototype.validSearch = function(href) { return false; }; searchshield.SearchEngine.prototype.includeLink = function(link) { return false; }; searchshield.SearchEngine.prototype.insertNodes = function(node, doc) { var element = node.element; var parentNode = node.element.parentNode; if (parentNode == null) { // try and find element again based on the hash element = doc.getElementById("xplid_" + node.hash); parentNode = !!element ? element.parentNode : null; } var insertNode = !!element ? element.nextSibling : null; while ((insertNode != null) && (insertNode.tagName != null) && (insertNode.tagName == "SPAN")) { insertNode = insertNode.nextSibling; } return [insertNode, parentNode]; }; searchshield.SearchEngine.prototype.addImage = function(node, image, hidden) { var element = node.element; var hash = node.hash; var score = node.score; // set verdict display configuration var doc = element.ownerDocument; if (!doc.getElementById(’XPLSS_Flyover’)) searchshield.initFlyover(doc, this); // get the proper insertion point for the image var insertNodes = this.insertNodes(node, doc); var insertNode = insertNodes[0]; var parentNode = insertNodes[1]; if (!parentNode) return; // see if we already have an image if ((insertNode != null) && (insertNode.id != null) && (insertNode.id.indexOf("XPLSS_") > -1)) { return; } // mark search result anchor so it isn’t processed repeatedly if (score == undefined) element.setAttribute("avglschecked", hash + "S" + this.VeriSignSplit); // create a new image var img = doc.createElement(’img’); img.src = image; img.id = "XPLSS_" + hash; img.style.borderStyle = "none"; img.style.margin = "0 3px"; // for IE, specify these style attributes to prevent inadvertent inheritance from parent if (img.width && img.height) { img.style.width = img.width + ’px’; img.style.height = img.height + ’px’; } // apply custom element styles this.updateElementStyle(img, this.addImageStyle); // create the link element var anchor = doc.createElement("A"); anchor.setAttribute("id", "LXPLSS_" + hash); if ((hidden != null) && (hidden == true)) { // hiding the parent will also hide its child nodes anchor.style.display = "none"; } // Default anchor styles //Over-ride possible border style with inline declaration anchor.style.borderStyle = "none"; // apply custom element styles this.updateElementStyle(anchor, this.addAnchorStyle); if (score == searchshield.SCORE_SS_VERISIGN) { anchor.style.textDecoration = "none"; anchor.style.background = "none"; } // append the image to the link anchor.appendChild(img); // insert the node as either a sibling or a child if (insertNode != null) parentNode.insertBefore(anchor, insertNode); else parentNode.appendChild(anchor); return anchor; }; searchshield.SearchEngine.prototype.updateImage = function (hash, search, score, image, alt_image, flyover, click_thru, altClick_thru) { var updated = false; var frameDoc = this.search.doc; var docFrames = frameDoc.frames; var frameElem; if (docFrames && this.processFrames) { for (var i=0; i < docFrames.length; i++) { try { if (docFrames[i].document.getElementById(hash)) { frameElem = docFrames[i].frameElement; frameDoc = docFrames[i].document; break; } } catch(err){} } } while ((element = frameDoc.getElementById(hash)) != null) { // check configuration to determine if verdict display property var showVerdict = true; var nSeverity = Number(score - 1); switch (nSeverity) { case searchshield.XPLCHECK_RESULT_SEV_LOW: showVerdict = this.showLowRiskVerdicts; break; case searchshield.XPLCHECK_RESULT_SEV_MED: showVerdict = this.showMedRiskVerdicts; break; case searchshield.XPLCHECK_RESULT_SEV_NONE: showVerdict = this.showCleanVerdicts; break; default: if (score == searchshield.SCORE_SS_VERISIGN) showVerdict = this.showCleanVerdicts; break; } // remove image if no url specified if ((!showVerdict) || (image == null) || (image.length < 1)) { // hide the parent anchor node element.parentNode.style.display = "none"; // mark the id as being hidden (element is the image) element.id = element.id + "H"; updated = true; // if not a verisign score if (score != searchshield.SCORE_SS_VERISIGN) continue; } // cleanup flyover, replace any new lines or single quotes flyover = searchshield.CleanupHTML(flyover); // mark the id as having been updated element.id = element.id + "U" + score; element.src = image; element.attachEvent("onmouseover", function(e){avglsflyover.popup(e, hash, search, flyover)}); element.attachEvent("onmouseout", function(e){avglsflyover.hide(e)}); // check for attribute updates (elementAttribute is an associative array (i.e., object) if (this.elementAttribute) { for (a in this.elementAttribute) { if(this.elementAttribute[a]) element.setAttribute(a, this.elementAttribute[a]); } } // To dynamically reduce verdict image size if it causes its container to scroll // when not showing alt images determine if the element containing // the verdict image is scrolling and decrease the image size by // the scroll amount (min size is 80% or original) var reduceBy = 0.8; var scrl = 0; if (!alt_image || this.omitAltImage || this.VeriSignSplit == searchshield.VERISIGN_SPLIT_TESTB) { try{ var maxLoop = 5; var cN = element.parentNode.parentNode; //image->anchor->containerNodes... while (cN && maxLoop--) { if (cN.tagName == "DIV" || cN.tagName == "SPAN") { // get object height depending on ie document mode var clientHeight = (cN.clientHeight == 0 || (this.search.doc.documentMode && this.search.doc.documentMode < 8)) ? cN.offsetHeight : cN.clientHeight; scrl = cN.scrollHeight - clientHeight; break; } cN = cN.parentNode; } if (0 < scrl) { var eH = (element.height - scrl)/element.height; if (reduceBy > eH) eH = reduceBy; var newDim = Math.ceil(eH*element.height); element.height = newDim; element.width = newDim; element.style.height = newDim + "px"; element.style.width = newDim + "px"; } } catch(e){} } // set default style attributes element.style.display = ""; // if verisign icon showing move our icon up for better centering of the 2 // except for IE7 browser - it does not like this style try { var ieVersion = parseFloat(navigator.appVersion.split("MSIE")[1]); if (alt_image && (alt_image.length > 0) && ieVersion != 7) element.style.verticalAlign = "10%"; } catch(err){}; // apply custom element styles this.updateElementStyle(element, this.updateImageStyle) // update the click thru var link = this.search.doc.getElementById("L" + hash); if (link) { link.href = click_thru; link.id = link.id + "U" + score; } updated = true; // add the alternate image if supplied BUT not on avg yahoo if ((alt_image) && (alt_image.length > 0) && (!this.omitAltImage) && (this.VeriSignSplit != searchshield.VERISIGN_SPLIT_TESTB)) { var vhash = hash.substring(hash.indexOf("_")+1); // create a temporary link node var tmp_node = { element: element.parentNode, href: altClick_thru, hash: vhash + "VU" + score, search: this.searchHash, score: score }; var altAnchor = this.addImage(tmp_node, alt_image, false); if (altAnchor && altAnchor.firstChild) { altAnchor.firstChild.setAttribute("onmouseover", ""); altAnchor.href = altClick_thru; } } } if (updated != false) { this.resizeFrame(frameElem); return true; } return false; }; searchshield.SearchEngine.prototype.updateElementStyle = function (element, elementStyle) { if (elementStyle) { // a NULL attribte value will unset it for(attr in elementStyle) { try { if (element.style.setAttribute) element.style.setAttribute(attr, elementStyle[attr]); else element.style[attr] = elementStyle[attr]; } catch(err){} } } }; searchshield.SearchEngine.prototype.resizeFrame = function (frameElem) { // resize frame to prevent unwanted scrolling after inserting verdicts // ignore inline and non-frame engines if ((this.type == ’inline’) || (!this.processFrames)) return; // ensure all required elements are available if ((frameElem == null) || (frameElem.style == null) || (frameElem.contentWindow == null)) return; // if frame is scrolling vertically then resize var frameHeight = parseInt(frameElem.style.height, 10); if (!isNaN(frameHeight) && (frameHeight < frameElem.contentWindow.document.body.scrollHeight)) frameElem.style.height = frameElem.contentWindow.document.body.scrollHeight + ’px’; return; }; searchshield.SearchEngine.prototype.getImgElement = function (element) { // return an xpl img element associated with a given element if (element == null) return null; // go up the parent tree looking for a header or div while ( (element.parentNode != null) && (element.tagName.charAt(0) != "H") && (element.tagName.charAt(0) != "D") && (element.tagName.charAt(0) != "T") ) { element = element.parentNode; } // if all the way to the top, nothing if ((element.tagName == "HTML") || (element == null)) return null; // get image tags, if none we are done var imgTags = element.getElementsByTagName("IMG"); if ((imgTags == null) || (imgTags.Length < 1)) return null; for (var i = 0; i < imgTags.length; i++) { if ((imgTags[i].id == null) || (imgTags[i].id.indexOf("XPLSS_") == -1)) continue; return imgTags[i]; } // else didn’t find anything return null; }; searchshield.SearchEngine.prototype.setRatingsConfig = function (doc) { // get verdict configuration, need at least severity var results = searchshield.avgCallFunc(doc, ’GetRatingsConfig’); var parts = !!results ? results.split(’::’) : null; if (parts != null && parts.length >= 5) { //if set to default then get config value if (this.showCleanVerdicts === true) this.showCleanVerdicts = (parseInt(parts[0]) == 1) ? true : false; if (this.showLowRiskVerdicts === true) this.showLowRiskVerdicts = (parseInt(parts[1]) == 1) ? true : false; if (this.showMedRiskVerdicts === true) this.showMedRiskVerdicts = (parseInt(parts[2]) == 1) ? true : false; this.VeriSignSplit = (parseInt(parts[4])); } return true; }; searchshield.SearchEngine.prototype.init_inline_ratings = function (doc) { if ((doc == null) || (doc.getElementById("XPLSS_InlineFlyover"))) return; // create the popup box var box = doc.createElement("DIV"); try { box.setAttribute("id", "XPLSS_InlineFlyover"); box.style.visibility = "hidden"; box.style.left = "-5000px"; box.style.position = "absolute"; box.style.zIndex = "9999"; box.style.padding = "0px 0px"; box.style.marginLeft = "0px"; box.style.marginTop = "0px"; box.style.overflow = "hidden"; box.style.wordWrap = "break-word"; box.style.color = "black"; box.style.fontSize = "10px"; box.style.textAlign = "left"; box.style.lineHeight = "130%"; doc.body.appendChild(box); box = null; } catch(boxErr){} }; searchshield.SearchEngine.prototype.show_inline_ratings = function (doc, node, image) { var href = node.href; var anchor = node.element; if ((href == null) || (href.length < 1)) return; if (avglsinlineflyover.imageExists(anchor)) return; // mark search result anchor so it isn’t processed repeatedly anchor.setAttribute("avglschecked", "1"); // get verdict this.display_inline(doc, anchor, href, node, false); }; searchshield.SearchEngine.prototype.display_inline = function (doc, anchor, href, node, update, min_severity) { // min_severity is the lowest severity to display, so setting it to // 1 would not display safe icons var results = searchshield.avgCallFunc(doc, ’MalsiteCheck’, href); if (results == null) return; var parts = results.split(’::’); // need at least severity if (parts == null) return; var nSeverity = parseInt(parts[0]); if (!update && nSeverity == searchshield.XPLCHECK_RESULT_SEV_NONE) { var shortUrl = searchshield.FilterUrl(href, this.shortened_urls); if (shortUrl) { // shortened url verdicts display later var engine = this; anchor.attachEvent("onmouseover", function(event){avglsinlineflyover.mouseOverHandler(event, doc, engine)}, false); return; } } //blacklist url var blShortUrl = false; if (nSeverity == searchshield.XPLCHECK_RESULT_SEV_BLOCK) { var shortUrl = searchshield.FilterUrl(href, this.shortened_urls); if (shortUrl) blShortUrl = true; } // need xlated cat tag and category if (parts.length < 3) return; // check the minimum to display if ((min_severity != null) && (nSeverity < min_severity)) return; if (nSeverity == searchshield.XPLCHECK_RESULT_SEV_LOW && !this.showLowRiskVerdicts) { if (update) this.avg_ls_inline_hide_verdict(anchor); return; } if (nSeverity == searchshield.XPLCHECK_RESULT_SEV_MED && !this.showMedRiskVerdicts) { if (update) this.avg_ls_inline_hide_verdict(anchor); return; } if (nSeverity == searchshield.XPLCHECK_RESULT_SEV_NONE && !this.showCleanVerdicts) { if (update) this.avg_ls_inline_hide_verdict(anchor); return; } if (update) this.update_inline_image(anchor, nSeverity, parts); else this.add_inline_image(doc, anchor, nSeverity, parts, blShortUrl); }; searchshield.SearchEngine.prototype.avg_ls_inline_hide_verdict = function (anchor) { var image = avglsinlineflyover.getImage(anchor); if (image) { image.style.display = "none"; if (image.parentNode && image.parentNode.id == "avg_ls_anch") image.parentNode.style.display = "none"; } }; searchshield.SearchEngine.prototype.update_inline_image = function (anchor, nSeverity, aRisk) { // update the image already in the page if (anchor && anchor.firstChild) { var html = ’’; var image = ’’; if (aRisk != null && nSeverity != null) { var riskCategory = aRisk[1]; var riskName = aRisk[2]; var bgColor = this.inline.color.background[nSeverity]; var borderColor = this.inline.color.border[nSeverity]; image = this.inline.image[nSeverity]; html = avglsinlineflyover.build(riskCategory, riskName, bgColor, borderColor); } var imageElem = anchor.firstChild; imageElem.src = image; if ( html && html.length > 0 ) { imageElem.setAttribute("title", ""); imageElem.attachEvent("onmouseover", function(e){avglsinlineflyover.popup(e, html)}); imageElem.attachEvent("onmouseout", function(e){avglsinlineflyover.hide(e)}); } } }; // add the image to the page searchshield.SearchEngine.prototype.add_inline_image = function (doc, anchor, nSeverity, aRisk, blShortUrl) { if (anchor == null || anchor.parentNode == null) return null; // get the proper insertion point for the image var insertNode = anchor.nextSibling; while ((insertNode != null) && (insertNode.tagName != null) && (insertNode.tagName == "SPAN")) { insertNode= insertNode.nextSibling; } // see if we already have an image anchor if ((insertNode != null) && (insertNode.id != null) && (insertNode.id == "avg_ls_anch")) { return null; } var html = ’’; var image = this.inline.clockImage; if (aRisk != null && nSeverity != null) { var riskCategory = aRisk[1]; var riskName = aRisk[2]; var bgColor = this.inline.color.background[nSeverity]; var borderColor = this.inline.color.border[nSeverity]; image = this.inline.image[nSeverity]; var blUrl; if (blShortUrl) { var aRiskName = riskName.split(’:’); var sUrl = searchshield.checkUrl(aRiskName[1]); blUrl = {}; blUrl.riskNameLabel = aRiskName[0] + ’: ’; blUrl.riskCategory = riskCategory; blUrl.bgColor = bgColor; blUrl.borderColor = borderColor; blUrl.sUrl = sUrl; } else { html = avglsinlineflyover.build(riskCategory, riskName, bgColor, borderColor); } } doc = anchor.ownerDocument; var img = doc.createElement("img"); img.src = image; img.setAttribute("id","avg_ls_image"); img.style.width = "12px"; img.style.border = "none"; img.style.padding = "0 3px"; img.style.margin = "0"; img.style.display = "inline"; if ((html && html.length > 0) || (blUrl != undefined)) { img.setAttribute("title", ""); img.attachEvent("onmouseover", function(e){avglsinlineflyover.popup(e, html, blUrl)}); img.attachEvent("onmouseout", function(e){avglsinlineflyover.hide(e)}); } // create the link element var newAnchor = doc.createElement("A"); newAnchor.setAttribute("id", "avg_ls_anch"); newAnchor.appendChild(img); img = null; // insert the node as either a sibling or a child if (insertNode != null) anchor.parentNode.insertBefore(newAnchor, insertNode); else anchor.parentNode.appendChild(newAnchor); return newAnchor; }; //////////////// SEARCH ENGINE //////////////// /////////////// GOOGLE SEARCH ENGINE /////////////// searchshield.GoogleSearchEngine = function(search) { searchshield.SearchEngine.call(this, search); this.onlyPrimaries = false; }; searchshield.GoogleSearchEngine.prototype = new searchshield.SearchEngine(); searchshield.GoogleSearchEngine.prototype.constructor = searchshield.GoogleSearchEngine; searchshield.GoogleSearchEngine.prototype.name = "google"; // the name by which the search engine is known (always lowercase) searchshield.GoogleSearchEngine.prototype.validSearch = function(href) { var uri; if (typeof(this.search) === ’undefined’ || null === this.search) uri = searchshield.parseLink(href); else uri = this.search.uri; if(!uri || !uri.host) return false; var hostMatch = false; var domain = uri.host; // re stitch the uri path and query elements to // use existing logic var path = uri.path + uri.delimiter + uri.query; // Domains valid for google searches, must start with ’.’ var valid_domains = new Array(".google.co", ".mozilla.co"); // For Google the host must match: // .google.com OR // .google.co.XX where XX is a country code // .google.XX where XX is a country code // Where any subdomain can come before the top level domain var domLen = valid_domains.length; for (var i = 0; i < domLen; i++) { var domainLen = domain.length; var valid_domain_len = valid_domains[i].length; var tldPos = domain.indexOf(valid_domains[i]); if (tldPos > -1) { if (domain.charAt(tldPos + valid_domain_len) == ’m’) hostMatch = true; else if ((domain.charAt(tldPos + valid_domain_len) == ’.’) && ((domainLen - tldPos) == valid_domain_len+3)) hostMatch = true; } else { // get the form .google. to check the length of var dot_pos = valid_domains[i].indexOf(".",1); var valid_short_name = valid_domains[i].substring(0, dot_pos+1); tldPos = domain.indexOf(valid_short_name); if ((tldPos > -1) && ((domainLen - tldPos) == valid_domain_len)) hostMatch = true; } if (hostMatch) { // replace beginning of domain with www.google since links will refer back to it if ((i > 0) && (tldPos > -1)) { var last_dot = domain.indexOf(".",tldPos+1) if (last_dot > -1) domain = "www.google" + domain.substring(last_dot); } break; } } if (hostMatch) { // using ajax engine if ((path.indexOf("search?") == 0) || (path.indexOf("sponsoredlinks?") == 0) || (path.indexOf("webhp?") == 0) || (path.indexOf("webhp#") == 0) || (path.indexOf("#q=") == 0) || (path.indexOf("#hl=") == 0) || (path.indexOf("#sclient=") == 0)) { return true; } } return false; }; searchshield.GoogleSearchEngine.prototype.includeLink = function(tag) { var href = ""; var outHref = false; var findStr = ""; // check for interstitials if (searchshield.DoesURLContain(tag.href, this.search.uri.host)) { findStr = this.search.uri.host + "/interstitial?"; if (tag.className == "l" && tag.href) { if (tag.href.indexOf(findStr) != -1) { findStr = "?url="; var pos = tag.href.indexOf(findStr); if (pos !== -1) { pos += 5; outHref = tag.href.substring(pos); if (searchshield.FilterUrl(outHref, this.filter_urls)) return false; return outHref; } } } if (tag.className == "sla") { findStr = "/url?q="; urlPos = tag.href.indexOf(findStr); if (urlPos != -1) { urlPos += 7; outHref = tag.href.substring(urlPos); return outHref; } } // if an ad id if ((tag.id.indexOf("pa") == 0) || (tag.id.indexOf("an") == 0) || (tag.className == "resultLink")) { var urlPos = -1; // ads now need unescaping href = unescape(tag.href); findStr= "/url?sa="; if (href.indexOf(findStr) != -1) { // first kind, locate real url findStr= "&q=http"; urlPos = href.indexOf(findStr); if (u









