Created
December 4, 2011 17:01
-
-
Save Zapotek/1430686 to your computer and use it in GitHub Desktop.
V8 interpreter with basic DOM in Ruby using TheRubyRacer and Taka
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'v8' | |
require 'open-uri' | |
require 'pp' | |
require 'ap' | |
require 'taka' | |
require 'ostruct' | |
# | |
# Monkey patch all elements to include a 'style' attribute | |
# | |
class Nokogiri::XML::Element | |
attr_reader :style | |
class Style < OpenStruct | |
end | |
def initialize( *args ) | |
super | |
@style = Style.new | |
end | |
end | |
# | |
# Taka lacks a few important interfaces | |
# so I've added some rough ones for the test's sake | |
# | |
module Taka::DOM::Document | |
attr_accessor :location | |
end | |
class Window | |
attr_reader :document | |
attr_reader :navigator | |
attr_reader :readyState | |
attr_accessor :location | |
def initialize( html = '' ) | |
@document = Taka::DOM::HTML( html ) | |
@navigator = Navigator.new | |
@location = Location.new( '' ) | |
@document.location = Location.new( '' ) | |
ready! | |
end | |
def open( url ) | |
@document = Taka::DOM::HTML( Kernel::open( url ) ) | |
@document.location = @location = Location.new( url ) | |
ready! | |
self | |
end | |
def alert( msg ) | |
# puts msg | |
pp msg | |
ap '---------' | |
end | |
def debug( obj ) | |
ap obj | |
end | |
def window | |
self | |
end | |
private | |
def ready! | |
@readyState = 'complete' | |
end | |
end | |
class Window::Navigator | |
attr_accessor :userAgent | |
def initialize | |
@userAgent = 'Arachni' | |
end | |
end | |
class Window::Location | |
def initialize( url ) | |
@url = URI( url ) | |
end | |
def host | |
@url.host + ':' + @url.port.to_s | |
end | |
def hostname | |
@url.host | |
end | |
def href | |
@url.to_s | |
end | |
def path | |
@url.path | |
end | |
def port | |
@url.port | |
end | |
# def hash | |
# return 0 if !@url.fragment | |
# '#' + @url.fragment | |
# end | |
def search | |
'?' + @url.query | |
end | |
def protocol | |
@url.scheme + ':' | |
end | |
def to_s | |
@url.to_s | |
end | |
end | |
# | |
# Taken from a Johnson example | |
# | |
html = <<EOHTML | |
<html> | |
<head> | |
<script> | |
function populateDropDown() { | |
var select = document.getElementById('colors'); | |
var options = ['red', 'green', 'blue', 'black']; | |
var i; | |
for( i = 0; i < options.length; i++ ) { | |
var option = document.createElement( 'option' ); | |
option.appendChild( document.createTextNode( options[i] ) ); | |
option.value = options[i]; | |
select.appendChild( option ); | |
} | |
} | |
div = document.createElement( "div" ); | |
div.style.display="none"; | |
div.textContent = 'Test div'; | |
body = document.getElementsByTagName('body')[0]; | |
body.appendChild( div ); | |
</script> | |
</head> | |
<body onload="populateDropDown()"> | |
<h1>Behold the V8</h1> | |
<form> | |
<select id="colors"> | |
</select> | |
</form> | |
</body> | |
</html> | |
EOHTML | |
window = Window.new( html ) | |
document = window.document | |
V8::Context.new( :with => window ) do |cxt| | |
document.xpath( './/script' ).each { | |
|script| | |
if src = script['src'] | |
src = script['src'].to_s | |
code = IO.read( open( src ) ) | |
else | |
code = script.text | |
src = 'EMBEDED' | |
end | |
begin | |
cxt.eval( code ) | |
rescue Exception => e | |
ap src | |
code.split( "\n" ).each_with_index { | |
|line, i| | |
puts "#{i+1} #{line}" | |
} | |
raise e | |
end | |
} | |
# should be 0 | |
p document.getElementsByTagName('option').length | |
# execute body's onload which will create the options | |
p cxt.eval document.getElementsByTagName('body')[0].onload | |
# should be 4 | |
p document.getElementsByTagName('option').length | |
# HTML code with updated DOM | |
# puts window.document.to_html | |
end | |
Glad to hear it, you might want to check this out: https://github.com/Zapotek/dom-js-experiment
Just what I need. +1.
You should make this some sort of gem btw (I might contribute)
I will eventually, it needs a lot more work still.
…On Feb 3, 2012 10:16 PM, "James Strong" < ***@***.***> wrote:
You should make this some sort of gem btw (I might contribute)
---
Reply to this email directly or view it on GitHub:
https://gist.github.com/1430686
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You just made my day sir.