Alex Rivera | Logout

CSS/JavaScript/hacking: Detect :visited styling on a link *without* checking it directly OR do it faster than me

Asked 2010-03-07T02:01:58.700
22

This is for research purposes on http://cssfingerprint.com

Consider the following code:

<style>
  div.csshistory a { display: none; color: #00ff00;}
  div.csshistory a:visited { display: inline; color: #ff0000;}
</style>

<div id="batch" class="csshistory">
  <a id="1" href="http://foo.com">anything you want here</a>
  <a id="2" href="http://bar.com">anything you want here</a>
  [etc * ~2000]
</div>

My goal is to detect whether foo has been rendered using the :visited styling.

  1. I want to detect whether foo.com is visited without directly looking at $('1').getComputedStyle (or in Internet Explorer, currentStyle), or any other direct method on that element.

    The purpose of this is to get around a potential browser restriction that would prevent direct inspection of the style of visited links.

    For instance, maybe you can put a sub-element in the <a> tag, or check the styling of the text directly; etc. Any method that does not directly or indierctly rely on $('1').anything is acceptable. Doing something clever with the child or parent is probably necessary.

    Note that for the purposes of this point only, the scenario is that the browser will lie to JavaScript about all properties of the <a> element (but not others), and that it will only render color: in :visited. Therefore, methods that rely on e.g. text size or background-image will not meet this requirement.

  2. I want to improve the speed of my current scraping methods.

    The majority of time (at least with the jQuery method in Firefox) is spent on document.body.appendChild(batch), so finding a way to improve that call would probably most effective. <

Edit
Report

1 Answer

0

Since all versions of IE (Yes, even version 8 if you enable quirks) support CSS expressions the color property is still unsafe. You could probably speed up IE testing with this (untested):

a:visited { color: expression( arrVisited.push(this.href) ); }

Also this isn't really covered by your question but you can of course set properties in child nodes very easily to initiate detection and any solution would have to prevent that too:

a.google:visited span { background-image: url(http://example.com/visited/google); }

You need to protect adjacent siblings too, not just descendants:

a.google:visited + span { }

Also untested but you could probably do a heavy speedup using the content property to modify the DOM and then some XPath to find the new nodes.

a.google:visited:before {content: "visited"; visibility: hidden;}

XPath:

visited links = document.evaluate('//a[text()="visited"]')
answered 2010-03-16T07:42:16.437

Your Answer