Skip to content
This repository has been archived by the owner on Dec 16, 2023. It is now read-only.

Commit

Permalink
[#37] Cleanup.
Browse files Browse the repository at this point in the history
  • Loading branch information
assaf committed Feb 17, 2011
1 parent e652bb7 commit ef05ce0
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 42 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -7,3 +7,4 @@ man7
node_modules
build
.lock-wscript
tags
5 changes: 5 additions & 0 deletions CHANGELOG.md
Expand Up @@ -3,6 +3,11 @@ zombie.js-changelog(7) -- Changelog

### Version 0.8.14 Pending

New isolated contexts for executing JavaScript.

293 Tests
4.4 sec to complete


### Version 0.8.13 2011-02-11

Expand Down
4 changes: 3 additions & 1 deletion Cakefile
Expand Up @@ -52,7 +52,9 @@ task "install", "Install Zombie in your local repository", ->
build = (callback)->
log "Compiling CoffeeScript to JavaScript ...", green
exec "rm -rf lib && coffee -c -l -b -o lib src", (err, stdout)->
callback err
onerror err
log "Compiling native extension ...", green
exec "node-waf clean build", callback
task "build", "Compile CoffeeScript to JavaScript", -> build onerror

task "watch", "Continously compile CoffeeScript to JavaScript", ->
Expand Down
7 changes: 0 additions & 7 deletions TODO.md
Expand Up @@ -9,13 +9,6 @@ zombie.js-todo(7) -- Wishlist
* Make sure `DOMContentLoaded` event fires after all stylesheets
are loaded

* New script context
* The execution context for all scripts on the page is the `Window`
object itself
* Node's `runInContext` accepts a sandbox, then creates an actual V8
context by copying properties to/from, which breaks asynchronous
scripts (timer, XHR, etc) which run in the contex, not the sandbox

* Navigation: Browser.open/close should work as a pair; look into supporting
window.open; fire unload event when navigating away from page.

Expand Down
38 changes: 4 additions & 34 deletions src/zombie/browser.coffee
Expand Up @@ -5,7 +5,8 @@ require "./jsdom_patches"
require "./forms"
require "./xpath"
History = require("./history").History

require.paths.push "../../build/default"
WindowContext = require("../../build/default/windowcontext").WindowContext


# Use the browser to open up new windows and load documents.
Expand Down Expand Up @@ -78,10 +79,6 @@ class Browser extends require("events").EventEmitter
# Windows
# -------

require.paths.push "build/default"
WindowContext = require("windowcontext").WindowContext


window = null
# ### browser.open() => Window
#
Expand All @@ -94,36 +91,9 @@ class Browser extends require("events").EventEmitter
history = features.history || new History

newWindow = jsdom.createWindow(html)
# Add context for evaluating scripts.
newWindow._evalContext = new WindowContext(newWindow)
global = newWindow._evalContext.global
global.decodeURI = decodeURI
global.decodeURIComponent = decodeURIComponent
global.encodeURI = encodeURI
global.encodeURIComponent = encodeURIComponent
global.escape = escape
global.eval = eval
global.isFinite = isFinite
global.isNaN = isNaN
global.parseFloat = parseFloat
global.parseInt = parseInt
global.unescape = unescape
global.Array = [].constructor
global.Boolean = Boolean
global.Date = Date
global.Error = Error
global.Function = Function
global.Math = Math
global.Number = Number
global.Object = {}.constructor
global.RegExp = //.constructor
global.String = newWindow._evalContext.evaluate("''.constructor")

newWindow._evaluate = (code, filename)->
try
newWindow._evalContext.evaluate(code, filename)
catch ex
console.log ex.message[0..500]
console.log ex.stack
newWindow._evaluate = (code, filename)-> newWindow._evalContext.evaluate(code, filename)

# Switch to the newly created window if it's interactive.
# Examples of non-interactive windows are frames.
Expand Down
23 changes: 23 additions & 0 deletions src/zombie/windowcontext.cc
Expand Up @@ -4,6 +4,8 @@
using namespace node;
using namespace v8;

// Isolated V8 Context/global scope for evaluating JavaScript, with access to
// all window methods/properties.
class WindowContext: ObjectWrap {
private:

Expand Down Expand Up @@ -35,6 +37,27 @@ class WindowContext: ObjectWrap {
this->global = Persistent<Object>::New(global);
tmpl->SetNamedPropertyHandler(GetProperty, SetProperty, NULL, DeleteProperty, EnumerateProperties, this->global);
context = Context::New(NULL, tmpl);

// Define constructor functions for primitives. We need to do this within
// the context, so "foo".constructor == String
context->Enter();
global->Set(String::New("Array"), Script::New(String::New("[].constructor"))->Run());
global->Set(String::New("Boolean"), Script::New(String::New("true.constructor"))->Run());
global->Set(String::New("Function"), Script::New(String::New("(function() {}).constructor"))->Run());
global->Set(String::New("Number"), Script::New(String::New("(1).constructor"))->Run());
global->Set(String::New("Object"), Script::New(String::New("({}).constructor"))->Run());
global->Set(String::New("RegExp"), Script::New(String::New("/./.constructor"))->Run());
global->Set(String::New("String"), Script::New(String::New("''.constructor"))->Run());
context->Exit();
// FIX ME: Define constructors for non-primitive types. We copy the
// constructor from Zombie's context, which is not a good thing.
const char* const list[] = { "Date", "Error", "Math", "decodeURI", "decodeURIComponent", "encodeURI", "encodeURIComponent",
"escape", "eval", "isFinite", "isNaN", "parseFloat", "parseInt", "unescape" };
const size_t len = sizeof(list) / sizeof(list[0]);
for (int i = len ; i-- >0 ; ) {
Handle<String> str = String::New(list[i]);
global->Set(str, Script::New(str)->Run());
}
}

~WindowContext() {
Expand Down

0 comments on commit ef05ce0

Please sign in to comment.