Skip to content

Commit

Permalink
Switched back to processing DOMNodeInserted on script tags.
Browse files Browse the repository at this point in the history
  • Loading branch information
assaf committed May 2, 2012
1 parent 4a6fbe8 commit 0a4f8f1
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 28 deletions.
9 changes: 5 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@ zombie.js-changelog(7) -- Changelog
===================================


## Version 0.13.5 2012-05-01
## Version 0.13.5 2012-05-02

Switched default HTML parser back to
Switched default HTML parser back to the more forgiving
[HTML5](https://github.com/aredridel/html5):

- Supports scripts with CDATA
- Supports tag soups
- Preserve order of execution between in-line and loaded JS code
- Support `document.write`

Fix `textContent` of element returning comments.
Fix `textContent` of elements that have comments in them to not exclude the
comment text .

438 tests
9.6 sec to complete
9.7 sec to complete


## Version 0.13.4 2012-05-01
Expand Down
3 changes: 3 additions & 0 deletions lib/zombie/history.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ util = require("util")
JSDOM = require("jsdom")
HTML = JSDOM.dom.level3.html
URL = require("url")
Scripts = require("./scripts")


# History entry. Consists of:
Expand Down Expand Up @@ -100,6 +101,8 @@ class History
document = JSDOM.jsdom(null, HTML, options)
@_window.document = document
document.window = document.parentWindow = @_window
if @_browser.runScripts
Scripts.addInlineScriptSupport document

headers = if headers then JSON.parse(JSON.stringify(headers)) else {}
referer = @_browser.referer || @_stack[@_index-1]?.url?.href
Expand Down
50 changes: 27 additions & 23 deletions lib/zombie/scripts.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,34 @@ HTML.languageProcessors.javascript = (element, code, filename)->
raise element: element, location: filename, from: __filename, error: error


# HTML5 parser doesn't play well with JSDOM and inline scripts.
# HTML5 parser doesn't play well with JSDOM and inline scripts. This methods
# adds proper inline script support.
#
# Basically, DOMNodeInsertedIntoDocument event is captured when the script tag
# is added to the document, at which point it has the src attribute (external
# scripts) but no text content (inline scripts). JSDOM will capture the event
# and try to execute an empty script.
# Basically, JSDOM listens on the script tag, waiting for
# DOMNodeInsertedIntoDocument, at which point the script tag may have a src
# attribute (external) but no text content (internal), so in the later case it
# attempts to execute an empty string.
#
# This code queues the script for processing and also lazily grabs the script's
# text content late enough that it's already set.
#
# Unfortunately, too late for some things to work properly -- basically once the
# HTML page has been processed -- so that needs to be fixed at some point.
HTML.Document.prototype._elementBuilders["script"] = (doc, tag)->
script = new HTML.HTMLScriptElement(doc, tag)
script.addEventListener "DOMNodeInsertedIntoDocument", (event)->
unless @src
src = @sourceLocation || {}
filename = src.file || @_ownerDocument.URL

if src
filename += ":#{src.line}:#{src.col}"
filename += "<script>"
HTML.resourceLoader.enqueue(this, => @_eval(@text, filename))()
return script
# OTOH when we listen to DOMNodeInserted event on the document, the script tag
# includes its full text content and we're able to evaluate it correctly.
addInlineScriptSupport = (document)->
# Basically we're going to listen to new script tags as they are inserted into
# the DOM and then queue them to be processed. JSDOM does the same, but
# listens on the script element itself, and someone the event it captures
# doesn't have any of the script contents.
document.addEventListener "DOMNodeInserted", (event)->
# Get the script tag from the event itself
node = event.relatedNode
return unless node.tagName == "SCRIPT"
# Don't handle scripts with src URL, JSDOM takes care of these
return if node.src
code = node.text
return unless code
# Only process supported languages
language = HTML.languageProcessors[node.language]
return unless language
# Queue so inline scripts execute in order with external scripts
HTML.resourceLoader.enqueue(node, -> language(this, code, document.location.href))()


# -- Utility methods --
Expand Down Expand Up @@ -82,5 +86,5 @@ raise = ({ element, location, from, scope, error })->
window.browser.dispatchEvent window, event


module.exports = { raise }
module.exports = { raise, addInlineScriptSupport }

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"coffee-script": "~1.3.1",
"eventsource": "~0.0.5",
"htmlparser": "~1.7.6",
"jsdom": "~0.2.14",
"html5": "~0.3.5",
"jsdom": "=0.2.14",
"mime": "~1.2.5",
"request": "~2.9.202",
"tough-cookie": "~0.9.12",
Expand Down

0 comments on commit 0a4f8f1

Please sign in to comment.