16

Exploring Google's +1 Button, I found two things odd about the code they supply:

<script type="text/javascript" src="https://apis.google.com/js/plusone.js">
  {lang: 'en-GB'}
</script>

<g:plusone size="tall" href="http://www.google.com"></g:plusone>

So I have two questions:
First:       How is Google able to use the text between the script tags?
Second:  Is the syntax <g:plusone ... HTML valid? What's this called?

Shaz
  • 15,637
  • 3
  • 41
  • 59

3 Answers3

12

How is Google able to use the text between the script tags?

<script> elements are perfectly visible in the DOM:

<script type="text/javascript">//FIRST SCRIPT BLOCK</script>

<script type="text/javascript">
    var s= document.getElementsByTagName('script')[0];
    alert(s.textContent); // "//FIRST SCRIPT BLOCK"
</script>

Google's sneaky trick is to put content in a <script> that has an external src. In this case the src overrides the content inside the block and executes the external script instead, but the contents of the <script> element are still readable through the DOM even though they do nothing.

Is the syntax <g:plusone ... HTML valid? What's this called?

No. If they made their own doctype for HTML+plusone it could be valid that, but it doesn't satisfy validity for HTML, and it isn't even namespace-well-formed in an XHTML document, unless you add an extra xmlns:g for it too.

bobince
  • 528,062
  • 107
  • 651
  • 834
  • I'm not sure if I would trust `var s= document.getElementsByTagName('script')[0];` What if the script we want access to is not the first `script` element? – Shaz Jul 15 '11 at 21:39
  • 4
    Yeah, that's just an example. In fact what they will be doing is reading the *last* script in the ByTagName list, not the first. Because the page is only partially loaded at run-time, the last ` – bobince Jul 15 '11 at 21:47
2

Is the syntax <g:plusone ... HTML valid?

No

What's this called?

Invalid psuedo-namespaces

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Is XML character ":" not specified? First off ":" is just an ASCII symbol. I'm not sure how Google is using it? Is this a class variable? – Micromega Jul 15 '11 at 21:26
  • @Quentin This certainly helps, as I found w3c documentation on [HTML5 Namespaces](http://www.w3.org/TR/html5/namespaces.html) – Shaz Jul 15 '11 at 21:30
2

The first trick is interesting. It looks like a creative way to pass "global" arguments from the page markup to external scripts. There are ways to find the <script> element that sources the code that's currently running, and I would not be surprised if the inner text of that <script> element was accessible from the DOM even though the browser ignores it.

In your question, this pattern allows each external client-side script to use (at least) its own localization settings, and also allows server-side code to render that parameter as a side effect of rendering the <script> element itself. That's impressive.

The second trick, I'm not so sure about. Basically, I think most browsers would consider the namespaced <g:plusone> element as unknown or even invalid, so they should render its content, but it won't do anything, of course, since that element is empty to begin with.

However, client-side code might still be able to match the namespaced element using DOM navigation, and replace it with its own generated content.

Community
  • 1
  • 1
Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479