Commit 45670813 authored by Ivan Tyagov's avatar Ivan Tyagov

Add safe-js and examples of sandboxed gadgets which can communicate

sandbox <- -> master and sandbox <- -> sandbox.
Examples and safe-js contributed by Nicolas Petton (to be rafactored).
parent ca08017b
<p id='A_test'>A test gadget</p>
<script type="text/javascript" src="http://localhost/renderjs/A.js"></script>
\ No newline at end of file
$("#A_test").html("hi A");
//$("#test_no").html("hi");
getSelfGadget().whatsyourname = function() {
return 'I am A';
}
communicate('C', 'whatsyourname', function(name) {
console.log(name);
});
\ No newline at end of file
<p id='B_test'>B test gadget</p>
<script type="text/javascript" src="http://localhost/renderjs/B.js"></script>
\ No newline at end of file
$("#B_test").html("hi B");
getSelfGadget.whatsyourname = function() {
return 'I am B';
}
communicate('A', 'whatsyourname', function(name) {
console.log(name);
});
\ No newline at end of file
<p id='C_test'>C test gadget</p>
<script type="text/javascript" src="http://localhost/renderjs/C.js"></script>
\ No newline at end of file
$("#C_test").html("hi C");
var gadget = RenderJs.GadgetIndex.getGadgetById('C');
gadget.whatsyourname = function() {
return "Hey there, I'm C!";
};
\ No newline at end of file
<html>
<head>
<title>Proto 1</title>
<script data-main="./require-renderjs.js"
type="text/javascript"
src="./lib/require/require.js"></script>
</head>
<body>
<div id="test"></div>
<div id="test_no"> No changable</div>
<div id="A"
data-gadget="A.html"
data-gadget-safejs="1"></div>
<div id="B"
data-gadget="B.html"
data-gadget-safejs="1"></div>
<div id="C"
data-gadget="C.html"
data-gadget-safejs="0"></div>
</body>
</html>
#! /bin/bash
node ./node_modules/requirejs/bin/r.js -o name=safe out=build/safe.js baseUrl=./
node ./node_modules/requirejs/bin/r.js -o name=jsdom out=jsdom_min.js baseUrl=lib/jsdom/lib
<html>
<head>
<title>Proto 1</title>
<script type='text/javascript' data-main="safe" src='js/require.js'></script>
<script
type='text/safe-javascript'
src='http://localhost/~nico/protos/safe-js/js/u1.js'
node='#test1'
policy='read-write'>
</script>
<script
type='text/safe-javascript'
src='http://localhost/~nico/protos/safe-js/js/u2.js'
node='#test2'
policy='read-write'>
</script>
<script
type='text/safe-javascript'
src='http://localhost/~nico/protos/safe-js/js/u3.js'
node='#test3'
policy='read-write'>
</script>
</head>
<body>
<div id="test1">1</div>
<div id="test2">2</div>
<div id="test3">3</div>
</body>
</html>
/*
* Boxed replacement for native console object
*/
var console = {};
console.log = function(data) {
postMessage({
command: 'log',
data: data.toString()
})
};
console.warn = function(data) {
postMessage({
command: 'warn',
data: data.toString()
})
};
console.error = function(data) {
postMessage({
command: 'error',
data: data.toString()
})
};
window.console = console
/* Load jsdom first */
importScripts('./require.js');
var jsdom;
var onJSDomReady = function(callback) {
jsDomReady = callback;
}
require({
baseUrl: "./"
},
["require", "../lib/jsdom/lib/jsdom.js"],
function(require, dom) {
jsdom = dom;
jsDomReady(jsdom);
}
);
replicateDOMChanges = function(element) {
postMessage({
command: 'replicateDOMChanges',
data: element
})
};
var safejs;
define(
[
'./jquery-wrapper',
'./policies',
'./sandbox'
],
function(jQuery, policy, sandbox) {
/*
* Create a sandboxed environment for script according to a
* spec literal object with the following attributes:
*
* - policy: the desired policy
* - node: a selector matching a dom element
* - script: the JS script path
*/
function secure(spec) {
/*
* Based on web workers. The sandboxed env. is isolated
* through a separate process + web browser DOM isolation
* in Web Workers.
*/
return sandbox({
policy: policy(spec.policy),
scripts: spec.scripts,
node: spec.node,
dependencies: spec.dependencies || []
});
};
function initialize() {
jQuery('script[type="text/safe-javascript"]').each(function(index, element) {
// Read the DOM node access from the metadata
// If several nodes match, only take the first one
var domElement = jQuery(jQuery(element).attr('node')).get(0);
// TODO: read the policy from the DOM;
secure({
policy: jQuery(element).attr('policy'),
scripts: [jQuery(element).attr('src')],
node: domElement
});
});
};
/*
* Sandbox scripts on initialization
*/
jQuery(document).ready(function() {
initialize();
});
safejs = secure;
}
)
/*
* Runs inside a web worker, loading a jailed script in the
* worker.
*/
var document;
var window;
var global = this;
var jail = function() {
var additionalLibraries = ["jquery-1.9.1.js"];
/*
* Load the dependencies & jailed script
*/
function load(scripts, dependencies, node) {
dependencies = dependencies || [];
scripts = scripts || [];
importScripts('boxed/dom.js');
onJSDomReady(function(jsdom) {
bootstrapDOM(jsdom);
importScripts('boxed/console.js');
importScripts('../lib/jsonml/jsonml-dom.js', '../lib/jsonml/jsonml-html.js');
loadAdditionalLibraries();
dependencies.forEach(function(each) {
importScripts(each);
});
fixReferences();
installNode(node);
importScripts(scripts);
})
};
/*
* Once the dom library is loaded, we need to create a real dom tree for the worker
*/
function bootstrapDOM(dom) {
document = dom.jsdom("<html><body></body></html>", dom.level(3, "core"));
window = document.createWindow();
document.title = 'Worker';
}
/*
* Load the boxing libraries, replacement for native browser
* libs. in our jailed env.
*/
function loadAdditionalLibraries() {
additionalLibraries.forEach(function(each) {
importScripts(each);
});
};
/*
* Once our libs are running, we need to fix some references to
* the global object vs window object
*/
function fixReferences() {
this.$ = this.jQuery = window.jQuery;
}
/*
* Once all the dependencies are laoded and the boostrap done, we
* install the node the worker has access to.
*/
function installNode(node) {
var htmlNode = JsonML.toHTML(node);
jQuery('body').append(htmlNode);
addListeners(htmlNode);
}
/*
* Listen for DOM changes inside our node, to replicate them in
* the host DOM.
*/
function addListeners(node) {
node.addEventListener("DOMNodeInserted", function() {
onDOMModified();
});
node.addEventListener("DOMNodeRemoved", function() {
onDOMModified();
});
node.addEventListener("DOMAttrModified", function() {
onDOMModified();
});
function onDOMModified() {
var jsonmlNode = JsonML.fromHTML(node);
replicateDOMChanges(jsonmlNode);
};
};
/*
* Actual loading on init protocol message. Note that the
* only message sent to the worker is the init message.
* All further communication is the other way only.
*/
this.onmessage = function(event) {
if(event.data.command === 'init') {
load(
event.data.data.scripts,
event.data.data.dependencies,
event.data.data.node);
}
// This addition is the counter part of the extended renderjs.js command pattern
// See renderjs.js begin of file for the other commands triggered from the worker
if(event.data.command === 'commanderResponse') {
handleResponse(event.data.data);
}
if(event.data.command === 'getGadgetById') {
handleGadgetResponse(event.data.data);
}
if(event.data.command === 'methodCall') {
handleMethodCall(event.data.data);
}
};
/* Ask for initialization. See protocol.js for more */
this.postMessage({command: 'start'});
};
jail();
This diff is collapsed.
//jQuery module wrapper
define(["./jquery-1.9.1"], function(){
return jQuery;
});
define(
[],
function() {
var policies = {};
function policyFor(label) {
return policies[label];
};
var policy = function() {
var that = {};
that.validate = function(command) {
throw "Abstract policy";
};
return that;
};
var readWritePolicy = function() {
var that = {};
that.validate = function(command) {};
return that;
};
var readOnlyPolicy = function() {
var that = {};
that.validate = function(command) {
if(command.isWriteCommand()) {
throw "Attempting to perform a write while in a read-only policy";
}
};
return that;
};
// Populate the policiies objects
(function() {
policies['read-only'] = readOnlyPolicy();
policies['read-write'] = readWritePolicy();
}());
return policyFor;
}
)
define(['./protocol'], function(protocol) {
return function() {
var commands = [];
/*
* Log commands. Later on replaced by domain specific
* commands, handled with the right policy (ex: DOM
* command).
*/
commands.push((function() {
var that = protocol.command();
that.label = 'log';
that.handle = function(worker, data) {
console.log(data);
}
return that;
})());
commands.push((function() {
var that = protocol.command();
that.label = 'warn';
that.handle = function(worker, data) {
console.warn(data);
}
return that;
})());
commands.push((function() {
var that = protocol.command();
that.label = 'error';
that.handle = function(worker, data) {
console.error(data);
}
return that;
})());
return commands;
};
})
define(['./protocol', '../../lib/jsonml/jsonml-dom', '../../lib/jsonml/jsonml-html'], function(protocol) {
/*
* DOM commands.
*/
return function() {
var commands = [];
commands.push((function() {
var that = protocol.command();
that.label = 'replicateDOMChanges';
that.handle = function(worker, data) {
var htmlNode = JsonML.toHTML(data);
replaceWith(htmlNode);
};
that.isWriteCommand = function() {
return true;
};
function replaceWith(element) {
jQuery(that.getNode()).replaceWith(element);
that.setNode(element);
};
return that;
})());
return commands;
};
});
define(
function() {
/*
* Defines the communication protocol between the sandbox and
* the outer world.
*/
/* Exception messages */
var protocolException = 'Protocol exception occured.';
var forbidden = 'Access denied by policy';
/*
* Creates and answer a protocol object.
*
* spec properties:
* - worker : Web worker instance (required)
* - scripts : JS files (required)
* - policy : policy object (required)
* - dependencies: JS dependencies collection (optional)
*/
var protocol = function(spec) {
var that = {};
var worker = spec.worker;
var scripts = spec.scripts;
var node = spec.node;
var dependencies = spec.dependencies || [];
that.policy = spec.policy;
/*
* Keep a public reference to the impacted node
*/
that.node = node;
/*
* Each event data should have a command property, matching
* one of the commands defined below. If none, the worker will
* be terminated.
*
* The event data can contain an additional JSON `data'.
* Any other data property is discarded.
*
* Each command is responsible for handling a specific kind of
* event.
*/
that.commands = {};
/* Incoming events */
that.read = function(data) {
//try {
rawRead(data);
//} catch (e) {
// terminate();
// // // }
};
function rawRead(data) {
var command = commandFor(data.command);
that.policy.validate(command);
command.handle(worker, data.data);
};
/* Answer the appropriate command object for string */
function commandFor(string) {
var command = that.commands[string];
if(!command) {throw protocolException};
return command;
};
/* Something wrong happened. Kill the worker process */
function terminate(exception) {
console.log(exception || 'Terminating worker.');
worker.terminate();
};
/* Commands definition */
/*
* The start command is the only command actually sending a
* message back to the worker.
*
* Also, it doesn't read any data.
*/
var startCommand = (function() {
var that = command();
that.label = 'start';
// No data read
that.handle = function(worker) {
var jsonmlNode = JsonML.fromHTML(node);
worker.postMessage({
command: 'init',
data: {
node: jsonmlNode,
scripts: scripts,
dependencies: dependencies
}
});
};
return that;
})();
/*
* Terminate command. The sandbox can this way ask to be
* properly terminated.
*/
var terminateCommand = (function() {
var that = command();
that.label = 'terminate';
that.handle = function(worker) {
worker.terminate('Termination of worker requested.');
}
return that;
})();
that.commands['start'] = startCommand;
that.commands['terminate'] = terminateCommand;
return that;
};
var command = function() {
var that = {};
var protocol;
/* Concrete commands should override this. */
that.label = null;
that.handle = function(worker, data) {};
that.setProtocol = function(p) {
protocol = p;
};
that.setNode = function(n) {
protocol.node = n;
};
that.getNode = function() {
return protocol.node;
};
that.isReadCommand = function() {
return true;
};
that.isWriteCommand = function() {
return false;
};
return that;
};
return {protocol: protocol, command: command};
}
)
define(['./protocol'], function(protocol) {
// we need to register all callbacks in a registry to be able to evaluate them later on
// when handling the response from the worker
var callbackRegistry = {};
return function() {
var commands = [];
var methodCallCommand;
function makeid() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 5; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
};
function registerCallback(callback, id) {
callbackRegistry[id] = callback;
};
commands.push((function() {
var that = protocol.command();
that.label = 'masterAndCommander';
that.handle = function(worker, data) {
performAction(worker, data.id, data.selector, function(result) {
respond(worker, {
result: result,
callback: data.callback
})
})
};
that.isWriteCommand = function() {
return true;
};
function performAction(worker, id, selector, callback) {
var gadget = RenderJs.GadgetIndex.getGadgetById(id);
if(gadget.sandbox) {
methodCallCommand.handle(gadget.sandbox, selector, callback);
}
else {
callback(gadget[selector]());
}
};
function respond(worker, data) {
worker.postMessage({
command: 'commanderResponse',
data: data
});
};
return that;
})());
methodCallCommand = (function() {
var that = protocol.command();
that.label = 'methodCall';
that.handle = function(worker, selector, callback) {
var callId = makeid();
registerCallback(callback, callId);
worker.postMessage({
command: 'methodCall',
data: {
selector: selector,
id: callId
}
});
};
return that;
})();
commands.push(methodCallCommand);
commands.push((function() {
var that = protocol.command();
that.label = 'methodResponse';
that.handle = function(worker, data) {
var callback = callbackRegistry[data.id];
if(callback) {
callback(data.data)
}
};
return that;
})());
commands.push((function() {
var that = protocol.command();
that.label = 'getGadgetById';
that.handle = function(worker, data) {
var gadget = getGadget(data.id);
debugger;
respond(worker, {
gadget: gadget,
callback: data.callback
})
};
that.isWriteCommand = function() {
return false;
};
function getGadget(id) {
var gadget = RenderJs.GadgetIndex.getGadgetById(id);
var selectors = [];
for(var i in gadget) {
if(typeof gadget[i] === 'function') {
selectors.push(i)
}
}
return selectors;
};
function respond(worker, data) {
worker.postMessage({
command: 'commanderResponse',
data: data
});
};
return that;
})());
return commands;
};
});
\ No newline at end of file
This diff is collapsed.
define(
[
'./protocol/protocol',
'./protocol/console',
'./protocol/dom',
'./protocol/renderjs-communication',
'./policies'
],
function(protocol, consoleProtocol, domProtocol, renderjsProtocol, policies) {
// Worker script path.
var jailJS = 'lib/safe-js/js/jail.js';
/*
* A handler is responsible for handling communication with a
* dedicated worker for a sandboxed script. Communication
* happens in one way only. The worker works in a sandboxed
* blind environment.
*/
function handler() {
var that = {};
/*
* Incoming data only. The worker is completely blind.
* Delegate to the sandbox protocol.
*/
that.read = function(data, protocol, callback) {
protocol.read(data);
if(callback) {
callback(data);
}
};
return that;
};
/*
* Creates and answer a sandboxed (jail) environment inside a
* web worker. Attach a protocol object to it. To handle
* incoming events.
*
* Each sandbox has a separate protocol object, holding into
* the policy.
*/
function sandbox(spec) {
var policy = spec.policy;
var scripts = spec.scripts;
var dependencies = spec.dependencies || [];
var node = spec.node;
var my = {};
my.worker = new Worker(jailJS);
my.protocol = protocol.protocol({
worker: my.worker,
policy: policy,
scripts: scripts,
dependencies: dependencies,
node: node
});
/* setup commands */
consoleProtocol().forEach(function(each) {
each.setProtocol(my.protocol);
my.protocol.commands[each.label] = each;
});
domProtocol().forEach(function(each) {
each.setProtocol(my.protocol);
my.protocol.commands[each.label] = each;
});
renderjsProtocol().forEach(function(each) {
each.setProtocol(my.protocol);
my.protocol.commands[each.label] = each;
});
/*
* Creates a dedicated handler for the worker
*/
var workerHandler = handler();
setupWorkerEvents(my.worker);
/*
* Properly initialize worker with event listeners.
*/
function setupWorkerEvents(worker) {
my.worker.onmessage = function(event) {
workerHandler.read(
event.data,
my.protocol,
function() {} //log
);
};
};
/* Testing purposes */
function log(data) {
console.log(data);
};
return my.worker;
};
return sandbox;
}
)
// ___________ .__.__
// \_ _____/__ _|__| |
// | __)_\ \/ / | |
// | \\ /| | |__
// /_______ / \_/ |__|____/
// \/
$('#test1').append('<p>hello 1</p>');
// ___________ .__.__
// \_ _____/__ _|__| |
// | __)_\ \/ / | |
// | \\ /| | |__
// /_______ / \_/ |__|____/
// \/
$('#test2').append('<p>hello 2</p>');
// ___________ .__.__
// \_ _____/__ _|__| |
// | __)_\ \/ / | |
// | \\ /| | |__
// /_______ / \_/ |__|____/
// \/
$('#test3').append('<p>hello 3</p>');
// ___________ .__.__
// \_ _____/__ _|__| |
// | __)_\ \/ / | |
// | \\ /| | |__
// /_______ / \_/ |__|____/
// \/
$('#test').append('<p>hello</p>');
benchmark/
example/
test/
Changelog.md
status.json
Contributing.md
.npmignore
.DS_Store
.svn
.travis.yml
.*.swp
**gmon.out
**v8.log
language: node_js
node_js:
- 0.8
This diff is collapsed.
## Mission
jsdom is, as said in our tagline, “A JavaScript implementation of the W3C DOM.” Anything that helps us be better at that is welcome.
## Status
We're pretty happy with our DOM2 implementation, modulo bugs. DOM3 is nowhere near complete, and DOM4 is almost nonexistant.
## Existing Tests
The DOM, thankfully, has lots of tests already out there. Those already included in the repository are of two types:
* Auto-generated or adapted from existing W3C tests.
* Written by contributors to plug gaps in the W3C tests.
Of these, of course, the first is preferable. When we find gaps, we usually add the tests at the bottom of the relevant auto-generated test suite, e.g. in `test/level2/html.js`.
The current test compliance is tracked [in the README](https://github.com/tmpvar/jsdom#test-compliance).
## Contributing
When contributing, the first question you should ask is:
**Can I exhibit how the browsers differ from what jsdom is doing?**
If you can, then you've almost certainly found a bug in or missing feature of jsdom, and we'd love to have your contribution. In that case, move on to:
**What W3C spec covers this potential contribution?**
Some likely ones include:
* [DOM1](http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/cover.html)
* [DOM2 Core](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/), [DOM2 HTML](http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109/), [DOM2 Events](http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/), [DOM2 Style](http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/)
* [DOM3 Core](http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/), [DOM3 Events](http://www.w3.org/TR/DOM-Level-3-Events/)
* [DOM4](http://www.w3.org/TR/2012/WD-dom-20120405/)
* [DOM Living Standard](http://dom.spec.whatwg.org/)
* [Other W3C Dom Specs](http://www.w3.org/standards/techs/dom)
* [HTML5](http://www.w3.org/TR/html5/)
Once you have those nailed down, you'll want to ask:
**Where can I get a W3C test for this functionality?**
We already have all the DOM1 and DOM2 tests. We even have some DOM3 ones, although sadly they are currently disabled, due to our DOM3 support not being complete. (Maybe you could help break them out into complete vs. work in progress?)
DOM4 has no officially-finished test suite, but many tests are found [on w3c-test.org](http://w3c-test.org/). Check in a few different directories, e.g. [html](http://w3c-test.org/html/tests/) and [webapps](http://w3c-test.org/webapps/), or perhaps browse through the nice [test runner interface](http://w3c-test.org/framework/app/suite). If you really can't find anything, you can always ask [public-webapps-testsuite@w3.org](mailto:public-webapps-testsuite@w3.org), [like I did](http://lists.w3.org/Archives/Public/public-webapps-testsuite/2012Aug/0001.html).
More recently there's been an attempt to consolidate tests for HTML5 in the [w3c/web-platform-tests](https://github.com/w3c/web-platform-tests) repository, so you can try to find things there. Many of the directories are empty, however; it seems that's still largely a work in progress.
If there is no W3C test covering the functionality you're after, then you can write your own, placing it in the appropriate level. But in this case you'll probably want to alert the authors of the relevant test suite that they missed something!
## Issues
Finally, we have [an active and full issue tracker](https://github.com/tmpvar/jsdom/issues) that we'd love you to help with. Go find something broken, and fix it!
Copyright (c) 2010 Elijah Insua
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
This diff is collapsed.
// Taken from: http://ejohn.org/blog/javascript-benchmark-quality/
module.exports = runTest(name, test, next, callback){
var runs = [], r = 0;
setTimeout(function(){
var start = Date.now(), diff = 0;
for ( var n = 0; diff < 1000; n++ ) {
test();
diff = Date.now() - start;
}
runs.push( n );
if ( r++ < 4 )
setTimeout( arguments.callee, 0 );
else {
done(name, runs);
if ( next )
setTimeout( next, 0 );
}
}, 0);
}
var dom = require('../../lib/jsdom/level2/html').dom.level2.html;
var browser = require('../../lib/jsdom/browser/index').windowAugmentation(dom);
var document = browser.document;
var window = browser.window;
var self = browser.self;
var navigator = browser.navigator;
var location = browser.location;
document.title = 'Test Title';
//GLOBAL
var el = document.createElement('div');
el.id = 'foo';
el.innerHTML = '<em>This is a test</em> This <strong class="odd">is another</strong> test ';
document.body.appendChild(el);
//SCOPED
var el2 = browser.document.createElement('div');
el2.id = 'foo2bar';
el2.innerHTML = '<em class="odd">This is a test</em> This <strong>is another</strong> test ';
browser.document.body.appendChild(el2);
console.log('getElementByid(foo2bar): ' + browser.document.getElementById('foo2bar'));
console.log('getElementByid(foo): ' + browser.document.getElementById('foo'));
console.log('getElementByTagName(em): ' + browser.document.getElementsByTagName('em'));
console.log('getElementByClassName(odd): ' + browser.document.getElementsByClassName('odd'));
console.log('');
console.log('document.body.outerHTML: ');
console.log(document.body.outerHTML);
console.log('document.outerHTML: ');
console.log(document.outerHTML);
This diff is collapsed.
var jsdom = require("../../lib/jsdom");
jsdom.env("<html><body></body></html>", ["ender.js"], function(errors, window) {
if (errors) {
console.error(errors);
return;
}
window.$('body').append("<div class='testing'>Hello World, It works!</div>");
console.log(window.$(".testing").text());
});
This diff is collapsed.
var jsdom = require("../../lib/jsdom"),
window = jsdom.jsdom().createWindow();
// this also works:
// jQueryTag.src = "http://code.jquery.com/jquery-1.4.2.js";
jsdom.jQueryify(window, "jquery.js", function() {
window.jQuery('body').append("<div class='testing'>Hello World, It works!</div>");
console.log(window.jQuery(".testing").text());
});
This diff is collapsed.
var dom = require("../../lib/jsdom/level1/core").dom.level1.core;
// git clone git://github.com/robrighter/node-xml.git into ~/.node_libraries
var xml = require("node-xml/lib/node-xml");
var doc = new dom.Document();
var currentElement = doc;
var totalElements = 0;
var parser = new xml.SaxParser(function(cb) {
cb.onStartDocument(function() {
});
cb.onEndDocument(function() {
console.log((doc.getElementsByTagName("*").length === totalElements) ? "success" : "fail");
});
cb.onStartElementNS(function(elem, attrs, prefix, uri, namespaces) {
totalElements++;
var element = doc.createElement(elem);
currentElement.appendChild(element);
currentElement = element;
console.log("=> Started: " + elem + " uri="+uri +" (Attributes: " + JSON.stringify(attrs) + " )");
});
cb.onEndElementNS(function(elem, prefix, uri) {
currentElement = currentElement.parentNode;
console.log("<= End: " + elem + " uri="+uri + "\n");
});
cb.onCharacters(function(chars) {
});
cb.onCdata(function(cdata) {
console.log('<CDATA>'+cdata+"</CDATA>");
});
cb.onComment(function(msg) {
console.log('<COMMENT>'+msg+"</COMMENT>");
});
cb.onWarning(function(msg) {
console.log('<WARNING>'+msg+"</WARNING>");
});
cb.onError(function(msg) {
console.log('<ERROR>'+JSON.stringify(msg)+"</ERROR>");
});
});
//example read from file
parser.parseFile("example.xml");
This diff is collapsed.
This diff is collapsed.
var util = require("util"),
sax = require("./sax");
parser = sax.parser(false);
sax.EVENTS.forEach(function (ev) {
parser["on" + ev] = function() { console.log(util.inspect(arguments)); };
});
parser.write("<span>Welcome,</span> to monkey land").close();
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
define(
["./index", "./documentfeatures", "./domtohtml", "./htmlencoding", "./htmltodom" ],
function(index, documentfeatures, domtohtml, htmlencoding, htmltodom ){
return {
index: index,
documentfeatures: documentfeatures,
domtohtml: domtohtml,
htmlencoding: htmlencoding,
htmltodom: htmltodom
};
})
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
browserified node libs required by jsdom
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment