use crate::sys::{Environment, GetWorkerFn};
use js_sys::Array;
use std::iter;
use wasm_bindgen::{closure::Closure, JsCast, JsValue};
use web_sys::{Blob, Url, Worker};
#[cfg(debug_assertions)]
macro_rules! include_worker {
($name: literal) => {
include_str!(concat!("../../js/debug/", $name))
};
}
#[cfg(not(debug_assertions))]
macro_rules! include_worker {
($name: literal) => {
include_str!(concat!("../../js/release/", $name))
};
}
const EDITOR_WORKER: &str = include_worker!("editor.worker.js");
const CSS_WORKER: &str = include_worker!("css.worker.js");
const HTML_WORKER: &str = include_worker!("html.worker.js");
const JSON_WORKER: &str = include_worker!("json.worker.js");
const TS_WORKER: &str = include_worker!("ts.worker.js");
fn create_worker(source: &str) -> Result<Worker, JsValue> {
let array: Array = iter::once(JsValue::from_str(source)).collect();
let blob = Blob::new_with_str_sequence(&array)?;
let url = Url::create_object_url_with_blob(&blob)?;
Worker::new(&url)
}
fn get_worker(_id: String, label: String) -> Worker {
let worker = match label.as_str() {
"css" => CSS_WORKER,
"html" => HTML_WORKER,
"json" => JSON_WORKER,
"typescript" | "javascript" => TS_WORKER,
_ => EDITOR_WORKER,
};
create_worker(worker).expect("failed to create worker")
}
fn build_environment() -> Environment {
let cb = Closure::wrap(Box::new(get_worker) as Box<GetWorkerFn>);
let env = Environment::default();
env.set_get_worker(Some(cb.as_ref().unchecked_ref()));
cb.forget();
env
}
pub fn set_environment() {
let window = web_sys::window().expect("no global window exists");
object_set!(window.MonacoEnvironment = build_environment());
}
pub fn is_environment_set() -> bool {
if let Some(window) = web_sys::window() {
if let Ok(value) = object_get!(try window.MonacoEnvironment) {
return value.is_truthy();
}
}
false
}
pub fn ensure_environment_set() {
if !is_environment_set() {
set_environment();
}
}