Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic dom2 #575

Merged
merged 4 commits into from
Feb 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 56 additions & 29 deletions build.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ function enable_light_mode() {
function enable_system_mode() {
window.enable_system_mode();
}
function is_empty(str) {
return (!str || str.length === 0);
}
function fallbackCopyTextToClipboard(text) {
var textArea = document.createElement("textarea");
textArea.value = text;
Expand Down Expand Up @@ -137,6 +134,7 @@ window.ftd = (function () {
window.ftd.post_init();
}
};
exports.data = ftd_data;
function handle_function(evt, id, action, obj, function_arguments) {
console.log(id, action);
console.log(action.name);
Expand All @@ -152,7 +150,7 @@ window.ftd = (function () {
let obj_checked = null;
try {
obj_value = obj.value;
obj_checked = obj.checked
obj_checked = obj.checked;
}
catch (_a) {
obj_value = null;
Expand All @@ -173,12 +171,15 @@ window.ftd = (function () {
}
}
}
return window[action.name](...function_arguments);
return window[action.name](...function_arguments, function_arguments, ftd_data[id], id);
}
function handle_event(evt, id, action, obj) {
let function_arguments = [];
handle_function(evt, id, action, obj, function_arguments);
change_value(function_arguments, ftd_data[id], id);
// @ts-ignore
if (function_arguments["CHANGE_VALUE"] !== false) {
change_value(function_arguments, ftd_data[id], id);
}
}
exports.handle_event = function (evt, id, event, obj) {
console_log(id, event);
Expand Down Expand Up @@ -243,8 +244,23 @@ window.ftd = (function () {
exports.is_empty = function (str) {
return (!str || str.length === 0);
};
exports.append = function (array, value) {
exports.append = function (array, value, args, data, id) {
array.push(value);
args["CHANGE_VALUE"] = false;
args[0].value = array;
change_value(args, data, id);
if (!!window.append_data_main && !!window.append_data_main[args[0].reference]) {
let [htmls, data_id, start_index] = window.append_data_main[args[0].reference](data);
let html = htmls[htmls.length - 1];
let nodes = stringToHTML(html);
let main = document.querySelector(`[data-id="${data_id}"]`);
for (var j = 0, len = nodes.childElementCount; j < len; ++j) {
{
// @ts-ignore
main.insertBefore(nodes.children[j], main.children[start_index + htmls.length - 1]);
}
}
}
return array;
};
return exports;
Expand Down Expand Up @@ -536,25 +552,12 @@ function console_log(...message) {
function isObject(obj) {
return obj != null && typeof obj === 'object' && obj === Object(obj);
}
function resolve_reference(reference, data, value, checked) {
if (reference === "VALUE") {
return value;
}
if (reference === "CHECKED") {
return checked;
}
if (!!data[reference]) {
return deepCopy(data[reference]);
}
let [var_name, remaining] = get_name_and_remaining(reference);
let initial_value = data[var_name];
while (!!remaining) {
let [p1, p2] = split_once(remaining, ".");
initial_value = initial_value[p1];
remaining = p2;
}
return deepCopy(initial_value);
function stringToHTML(str) {
var parser = new DOMParser();
var doc = parser.parseFromString(str, 'text/html');
return doc.body;
}
;
function get_name_and_remaining(name) {
let part1 = "";
let pattern_to_split_at = name;
Expand Down Expand Up @@ -617,6 +620,21 @@ String.prototype.format = function () {
}
return formatted;
};
String.prototype.replace_format = function () {
var formatted = this;
if (arguments.length > 0) {
// @ts-ignore
for (let [header, value] of Object.entries(arguments[0])) {
var regexp = new RegExp('\\{' + header + '(\\..*)?\\}', 'gi');
let matching = formatted.match(regexp);
for (let i in matching) {
// @ts-ignore
formatted = formatted.replace(matching[i], resolve_reference(matching[i].substring(1, matching[i].length - 1), arguments[0]));
}
}
}
return formatted;
};
function set_data_value(data, name, value) {
if (!!data[name]) {
data[name] = deepCopy(set(data[name], null, value));
Expand All @@ -635,11 +653,17 @@ function set_data_value(data, name, value) {
return initial_value;
}
}
function get_data_value(data, name) {
if (!!data[name]) {
return deepCopy(data[name]);
function resolve_reference(reference, data, value, checked) {
if (reference === "VALUE") {
return value;
}
let [var_name, remaining] = get_name_and_remaining(name);
if (reference === "CHECKED") {
return checked;
}
if (!!data[reference]) {
return deepCopy(data[reference]);
}
let [var_name, remaining] = get_name_and_remaining(reference);
let initial_value = data[var_name];
while (!!remaining) {
let [p1, p2] = split_once(remaining, ".");
Expand All @@ -648,6 +672,9 @@ function get_data_value(data, name) {
}
return deepCopy(initial_value);
}
function get_data_value(data, name) {
resolve_reference(name, data, null, null);
}
function JSONstringify(f) {
if (typeof f === 'object') {
return JSON.stringify(f);
Expand Down
2 changes: 0 additions & 2 deletions src/executor/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,6 @@ impl<'a> ExecuteDoc<'a> {
let component = ftd::executor::utils::create_dummy_instruction_for_loop_element(
instruction,
doc,
iteration.alias.as_str(),
reference_name,
inherited_variables,
local_container.as_slice(),
)?;
Expand Down
2 changes: 1 addition & 1 deletion src/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ mod main;
mod markup;
mod styles;
mod tdoc;
mod utils;
pub(crate) mod utils;
mod value;
mod youtube_id;

Expand Down
8 changes: 3 additions & 5 deletions src/executor/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,19 @@ pub(crate) fn get_string_container(local_container: &[usize]) -> String {
pub(crate) fn create_dummy_instruction_for_loop_element(
instruction: &ftd::interpreter2::Component,
doc: &mut ftd::executor::TDoc,
alias: &str,
reference_name: &str,
inherited_variables: &mut ftd::VecMap<(String, Vec<usize>)>,
local_container: &[usize],
) -> ftd::executor::Result<ftd::interpreter2::Component> {
let mut instruction = instruction.clone();
let reference_replace_pattern = ftd::interpreter2::PropertyValueSource::Loop(alias.to_string())
/*let reference_replace_pattern = ftd::interpreter2::PropertyValueSource::Loop(alias.to_string())
.get_reference_name(alias, &doc.itdoc());
let replace_with = format!("{}.INDEX", reference_name);
let map =
std::iter::IntoIterator::into_iter([(reference_replace_pattern, replace_with)]).collect();
std::iter::IntoIterator::into_iter([(reference_replace_pattern, replace_with)]).collect();*/

update_local_variable_references_in_component(
&mut instruction,
&map,
&Default::default(),
inherited_variables,
&Default::default(),
local_container,
Expand Down
4 changes: 3 additions & 1 deletion src/executor/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,9 @@ pub(crate) fn find_value_by_argument(
}
} else if p.condition.is_none() {
if let Some(v) = p.value.get_reference_or_clone() {
value = Some(ftd::interpreter2::Value::new_string(v));
value = Some(ftd::interpreter2::Value::new_string(
format!("{{{}}}", v).as_str(),
));
line_number = Some(p.line_number);
}
}
Expand Down
171 changes: 171 additions & 0 deletions src/html1/dummy_html.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
pub(crate) struct DummyHtmlGenerator<'a> {
pub id: String,
pub doc: &'a ftd::interpreter2::TDoc<'a>,
}

impl<'a> DummyHtmlGenerator<'a> {
pub fn new(id: &str, doc: &'a ftd::interpreter2::TDoc<'a>) -> DummyHtmlGenerator<'a> {
DummyHtmlGenerator {
id: id.to_string(),
doc,
}
}

pub fn from_dummy_nodes(&self, dummy_nodes: &ftd::Map<ftd::node::DummyNode>) -> String {
let mut dummy_dependency = "".to_string();
for (dependency, dummy_node) in dummy_nodes {
dummy_dependency = format!(
"{}\n{}",
dummy_dependency,
self.from_dummy_node(dummy_node, dependency)
)
}
if dummy_dependency.trim().is_empty() {
"".to_string()
} else {
format!(
"window.append_data_{} = {{}};\n{}",
self.id, dummy_dependency
)
}
}

pub fn from_dummy_node(&self, dummy_node: &ftd::node::DummyNode, dependency: &str) -> String {
let dummy_html = ftd::html1::RawHtmlGenerator::from_node(
self.id.as_str(),
self.doc,
dummy_node.main.to_owned(),
);

if let Some(iteration) = dummy_html.iteration {
format!(
indoc::indoc! {"
window.append_data_{id}[\"{dependency}\"] = function(all_data) {{
let list = resolve_reference(\"{dependency}\", all_data);
let htmls = [];
for (var i = 0; i < list.length; i++) {{
let new_data = {{
\"{alias}\": list[i],
\"LOOP__COUNTER\": i
}};
let data = {{...new_data, ...all_data}};
{arguments}
data = {{...args, ...all_data}};
if (!!\"{node}\".trim() && !!window[\"raw_nodes_{id}\"] && !!window.raw_nodes_{id}[\"{node}\"]) {{
data[\"{node}\"] = window.raw_nodes_{id}[\"{node}\"](data);
}}
let html = \"{html}\".replace_format(data);
htmls.push(html);
}}
return [htmls, \"{data_id}\", {start_index}]
}}"
},
dependency = dependency,
alias = iteration.alias,
arguments = dummy_html.properties_string.unwrap_or_default(),
node = dummy_html.name,
html = dummy_html.html,
id = self.id,
data_id = ftd::html1::utils::full_data_id(
self.id.as_str(),
ftd::executor::utils::get_string_container(
dummy_node.parent_container.as_slice()
)
.as_str()
),
start_index = dummy_node.start_index
)
} else {
format!(
indoc::indoc! {"
window.append_data_{id}[\"{dependency}\"] = function(all_data){{
{arguments}
let data = {{...args, ...all_data}};
if (!!\"{node}\".trim() && !!window[\"raw_nodes_{id}\"] && !!window.raw_nodes_{id}[\"{node}\"]) {{
data[\"{node}\"] = window.raw_nodes_{id}[\"{node}\"](data);
}}
let html = \"{html}\".replace_format(data);
return [html, \"{data_id}\", {start_index}]
}}"
},
dependency = dependency,
arguments = dummy_html.properties_string.unwrap_or_default(),
node = dummy_html.name,
html = dummy_html.html,
id = self.id,
data_id = ftd::html1::utils::full_data_id(
self.id.as_str(),
ftd::executor::utils::get_string_container(
dummy_node.parent_container.as_slice()
)
.as_str()
),
start_index = dummy_node.start_index
)
}
}
}

pub(crate) struct HelperHtmlGenerator<'a> {
pub id: String,
pub doc: &'a ftd::interpreter2::TDoc<'a>,
}

impl<'a> HelperHtmlGenerator<'a> {
pub fn new(id: &str, doc: &'a ftd::interpreter2::TDoc<'a>) -> HelperHtmlGenerator<'a> {
HelperHtmlGenerator {
id: id.to_string(),
doc,
}
}

pub fn from_raw_nodes(&self, raw_nodes: &ftd::Map<ftd::node::RawNode>) -> String {
let mut raw_dependency = "".to_string();
for (dependency, raw_node) in raw_nodes {
raw_dependency = format!(
"{}\n{}",
raw_dependency,
self.from_raw_node(raw_node, dependency)
)
}
if raw_dependency.trim().is_empty() {
"".to_string()
} else {
format!("window.raw_nodes_{} = {{}};\n{}", self.id, raw_dependency)
}
}

pub fn from_raw_node(&self, raw_node: &ftd::node::RawNode, dependency: &str) -> String {
let raw_html = ftd::html1::RawHtmlGenerator::from_node(
self.id.as_str(),
self.doc,
raw_node.node.to_owned(),
);

let argument_string = ftd::html1::utils::to_argument_string(
self.id.as_str(),
raw_node.arguments.as_slice(),
self.doc,
dependency,
);

format!(
indoc::indoc! {"
window.raw_nodes_{id}[\"{dependency}\"] = function(all_data){{
{arguments}
let data = {{...args, ...all_data}};
if (!!\"{node}\".trim() && !!window[\"raw_nodes_{id}\"] && !!window.raw_nodes_{id}[\"{node}\"]) {{
data[\"{node}\"] = window.raw_nodes_{id}[\"{node}\"](data);
}}
let html = \"{html}\".replace_format(data);
return html;
}}"
},
dependency = dependency,
arguments = argument_string.unwrap_or_default(),
node = raw_html.name,
html = raw_html.html.replace("\"", "\\\""),
id = self.id,
)
}
}
Loading