browser_engine 0.1.0

A modular, GPU-accelerated, security-first web browser engine built from scratch in Rust.
Documentation
#![allow(dead_code)]

pub mod ast;
pub mod bytecode;
pub mod dom_bindings;
pub mod gc;
pub mod lexer;
pub mod parser;
pub mod runtime;
pub mod vm;
pub mod worker;

pub use bytecode::{Compiler, Value};
pub use dom_bindings::execute_js_on_dom;
pub use lexer::JsLexer;
pub use parser::JsParser;
pub use runtime::JsRuntime;
pub use vm::VM;
pub use worker::WebWorker;

#[cfg(test)]
mod tests {
    use super::*;
    use crate::dom::{build_dom, NodeType};
    use crate::html::Tokenizer;

    #[test]
    fn test_lexer_and_parser() {
        let code = "var x = 10 + 20; if (x > 15) { x = 100; }";
        let tokens = JsLexer::new(code).tokenize();
        let program = JsParser::new(tokens).parse();
        assert_eq!(program.body.len(), 2);
    }

    #[test]
    fn test_vm_execution() {
        let code = "var a = 5; var b = 10; var c = a + b;";
        let tokens = JsLexer::new(code).tokenize();
        let program = JsParser::new(tokens).parse();
        let chunk = Compiler::new().compile(&program);
        let mut vm = VM::new();
        vm.run(&chunk);
        assert_eq!(vm.globals.get("c"), Some(&Value::Number(15.0)));
    }

    #[test]
    fn test_dom_mutation_from_js() {
        let html = r#"<html><body><h1 id="header">Old Title</h1></body></html>"#;
        let tokens = Tokenizer::new(html).tokenize();
        let mut dom = build_dom(tokens);

        let script = r#"setElementText("header", "New Updated Title");"#;
        execute_js_on_dom(script, &mut dom);

        let mut found_updated_text = false;
        for node in &dom.nodes {
            if let NodeType::Text(t) = &node.node_type {
                if t == "New Updated Title" {
                    found_updated_text = true;
                    break;
                }
            }
        }
        assert!(found_updated_text);
    }

    #[test]
    fn test_web_apis_timers_events_fetch() {
        let html = r#"<html><body><h1 id="header">Title</h1></body></html>"#;
        let mut dom = build_dom(Tokenizer::new(html).tokenize());

        let script = r#"
            addEventListener("click", 1);
            setTimeout(1, 100);
        "#;
        execute_js_on_dom(script, &mut dom);
    }

    #[test]
    fn test_canvas_2d_api() {
        let html = r#"<html><body><canvas id="myCanvas" width="200" height="100"></canvas></body></html>"#;
        let mut dom = build_dom(Tokenizer::new(html).tokenize());

        let script = r#"
            getContext("2d");
            fillRect(10, 20, 100, 50);
        "#;
        execute_js_on_dom(script, &mut dom);
    }

    #[test]
    fn test_web_worker_multithreading() {
        let worker = WebWorker::new("worker.js");
        assert!(worker.post_message("task_data").is_ok());
        std::thread::sleep(std::time::Duration::from_millis(50));
        let response = worker.try_recv();
        assert_eq!(response, Some("processed: task_data".to_string()));
    }

    #[test]
    fn test_js_runtime_execution() {
        let html = r#"<html><body><h1 id="title">Initial</h1><script>setElementText("title", "Updated by JsRuntime");</script></body></html>"#;
        let mut dom = build_dom(Tokenizer::new(html).tokenize());

        let scripts = JsRuntime::extract_scripts(&dom);
        assert_eq!(scripts.len(), 1);

        let mut runtime = JsRuntime::new();
        assert!(runtime.execute(&scripts[0], &mut dom).is_ok());

        let mut found = false;
        for node in &dom.nodes {
            if let NodeType::Text(t) = &node.node_type {
                if t == "Updated by JsRuntime" {
                    found = true;
                    break;
                }
            }
        }
        assert!(found);
    }
}