use super::{
DomBinding, DomBuilder, DomDependency, DomExpressionFacts, DomUnsupported, PropertyRole,
ValueKind,
};
use crate::decision::dom::{file::DomFileExpression, vue::policy::FileReads};
use vize_l0::id::NodeId;
use vize_l2::{
file::FileResolution,
op::{BindingOp, ModelOp, Op},
};
impl<'owner, 'arena, F: DomExpressionFacts, R: FileReads<'owner, 'arena>>
DomBuilder<'_, 'owner, 'arena, F, R>
{
pub(super) fn model_binding(
&mut self,
node: NodeId,
binding: &'owner BindingOp<'arena>,
model: &'owner ModelOp<'arena>,
) {
let Some(resolution) = self.checked_model(node, binding, model) else {
self.reject(node, model.span, DomUnsupported::FileBinding);
return;
};
let Some((_, frame)) = self.frames.last_mut() else {
self.reject(node, model.span, DomUnsupported::Binding);
return;
};
frame.node.changes.properties = true;
frame.node.dynamic_property_bindings.push(node);
self.facts
.file_expressions
.insert(node, DomFileExpression { resolution });
self.facts.bindings.insert(
node,
DomBinding {
binding,
role: PropertyRole::Model,
value: ValueKind::FileDependent,
},
);
self.demand(DomDependency::TextModel);
self.demand(DomDependency::DirectiveApplication);
}
fn checked_model(
&self,
node: NodeId,
binding: &'owner BindingOp<'arena>,
model: &'owner ModelOp<'arena>,
) -> Option<FileResolution<'owner, 'arena>> {
if !R::NATIVE_SETUP || self.root_count != 1 {
return None;
}
let [(element_node, frame)] = self.frames.as_slice() else {
return None;
};
let Op::Element(element) = frame.node.op else {
return None;
};
if !frame.binding_names.is_empty() {
return None;
}
crate::decision::model::checked(self.file?, *element_node, element, node, binding, model)
}
}