///|
/// Algorithms for one Quill embed type. The values are the JSON values under
/// the embed's single type key, not the outer `{ type: value }` object.
pub struct EmbedHandler {
compose_value : (Json, Json, Bool) -> Json raise DeltaError
invert_value : (Json, Json) -> Json raise DeltaError
transform_value : (Json, Json, Bool) -> Json raise DeltaError
}
///|
pub fn EmbedHandler::new(
compose : (Json, Json, Bool) -> Json raise DeltaError,
invert : (Json, Json) -> Json raise DeltaError,
transform : (Json, Json, Bool) -> Json raise DeltaError,
) -> EmbedHandler {
{ compose_value: compose, invert_value: invert, transform_value: transform }
}
///|
/// An explicit registry keeps embed behavior deterministic across independent
/// editors sharing a process. Pass it to the `_with_handlers` methods.
pub struct EmbedHandlers {
handlers : Map[String, EmbedHandler]
}
///|
pub fn EmbedHandlers::new() -> EmbedHandlers {
{ handlers: Map([]) }
}
///|
pub fn EmbedHandlers::register(
self : EmbedHandlers,
embed_type : String,
handler : EmbedHandler,
) -> Unit raise DeltaError {
if embed_type == "" { raise Invalid("embed type cannot be empty") }
self.handlers.set(embed_type, handler)
}
///|
pub fn EmbedHandlers::unregister(self : EmbedHandlers, embed_type : String) -> Unit {
ignore(self.handlers.remove(embed_type))
}
///|
pub fn EmbedHandlers::contains(self : EmbedHandlers, embed_type : String) -> Bool {
self.handlers.get(embed_type) is Some(_)
}
///|
fn EmbedHandlers::require(self : EmbedHandlers, embed_type : String) -> EmbedHandler raise DeltaError {
match self.handlers.get(embed_type) {
Some(handler) => handler
None => raise Invalid("no handler for embed type \"" + embed_type + "\"")
}
}
///|
fn embed_parts(left : Json, right : Json) -> (String, Json, Json) raise DeltaError {
let a = match left {
Object(map) if map.length() == 1 => map
_ => raise Invalid("cannot retain a non-embed value")
}
let b = match right {
Object(map) if map.length() == 1 => map
_ => raise Invalid("retain embed must have one type")
}
for embed_type, data in a {
match b.get(embed_type) {
Some(next) => return (embed_type, data, next)
None => raise Invalid("embed types do not match")
}
}
raise Invalid("embed must have one type")
}
///|
fn wrap_embed(embed_type : String, data : Json) -> Json {
let fields : Map[String, Json] = Map([])
fields.set(embed_type, data)
Json::object(fields)
}
///|
let default_embed_handlers : EmbedHandlers = EmbedHandlers::new()
///|
/// Register the default handler for an embed type, as in Quill Delta's
/// registerEmbed. Explicit registries remain available for isolated editors.
pub fn Delta::register_embed(
embed_type : String,
handler : EmbedHandler,
) -> Unit raise DeltaError {
default_embed_handlers.register(embed_type, handler)
}
///|
pub fn Delta::unregister_embed(embed_type : String) -> Unit {
default_embed_handlers.unregister(embed_type)
}