Skip to content

Commit

Permalink
fix handling textNode
Browse files Browse the repository at this point in the history
  • Loading branch information
shahrul committed Oct 11, 2024
1 parent 6627906 commit 34ab348
Show file tree
Hide file tree
Showing 15 changed files with 96 additions and 65 deletions.
6 changes: 3 additions & 3 deletions h.lua
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ local voidTags = {

local function isVoidTag(tag)
for _, voidTag in ipairs(voidTags) do
if voidTag == tag then
return true
end
if voidTag == tag then
return true
end
end
return false
end
Expand Down
37 changes: 20 additions & 17 deletions luax.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ local function decentParserAST(input)
-- escape " ' encapsulation
-- opening tag
if tok == "<" and not deepString and not deepStringApos then
local nextSpacingPos = input:find('%s',pos)
local nextSpacingPos = input:find("%s", pos)
local tagRange = input:sub(pos, nextSpacingPos)
local tagName = tagRange:match("<(%w+)", 0)
local tagNameEnd = tagRange:match("</(%w+)>", 0)
if tagName then deepNode = deepNode + 1 end
if tagNameEnd then deepNode = deepNode - 1 end
pos = pos + 1

if tagName and not deepString then
isTag = true
textNode = false
Expand All @@ -37,13 +37,13 @@ local function decentParserAST(input)
end
local step = 1
-- enclose attributes if it empty
if tagRange:sub(#tagRange-1, #tagRange):gsub("[\r\n]", ""):match("^%s*(.-)$") == '>' then step = 0 end
if tagRange:sub(#tagRange - 1, #tagRange):gsub("[\r\n]", ""):match("^%s*(.-)$") == ">" then step = 0 end
pos = pos + #tagName + step
elseif tagNameEnd then
if isTag and not textNode then
isTag = not isTag
local trail = input:sub(0, pos-2):gsub("[%s\r\n]", "")
if trail:sub(#trail-1, #trail-1) == '/' then
local trail = input:sub(0, pos - 2):gsub("[%s\r\n]", "")
if trail:sub(#trail - 1, #trail - 1) == '/' then
output = output .. ")"
else
output = output .. "})"
Expand Down Expand Up @@ -72,33 +72,33 @@ local function decentParserAST(input)
output = output .. tok
pos = pos + 1
elseif tok == ">" and deepNode > 0 and not deepString and not deepStringApos then
if not textNode and isTag and input:sub(pos-1, pos-1) ~= "/" then
if not textNode and isTag and input:sub(pos - 1, pos - 1) ~= "/" then
isTag = not isTag
textNode = not textNode
output = output .. '}'
output = output .. "}"
else
isTag = not isTag
-- textNode = not textNode
output = output .. '})'
deepNode = deepNode - 1
output = output .. "})"
end
pos = pos + 1
elseif tok == "/" and input:sub(pos+1, pos+1) == '>' and not deepString and not deepStringApos then
elseif tok == "/" and input:sub(pos + 1, pos + 1) == ">" and not deepString and not deepStringApos then
deepNode = deepNode - 1
output = output .. '})'
output = output .. "})"
pos = pos + 2
elseif tok == '{' and deepNode > 0 and not deepString and not deepStringApos then
elseif tok == "{" and deepNode > 0 and not deepString and not deepStringApos then
var = not var
if not isTag then
output = output .. ','
output = output .. ","
end
pos = pos + 1
elseif tok == '}' and deepNode > 0 and not deepString and not deepStringApos then
elseif tok == "}" and deepNode > 0 and not deepString and not deepStringApos then
var = not var
pos = pos + 1
elseif deepNode > 0 and not deepString and not deepStringApos then
if tok:match("%s") then
if isTag and output:sub(-1) ~= "{" and output:sub(-1) == "\"" or
isTag and input:sub(pos -1, pos -1) == "}" then
if not var and isTag and output:sub(-1) ~= "{" and output:sub(-1) == "\"" or
isTag and input:sub(pos - 1, pos - 1) == "}" then
output = output .. ","
end
end
Expand All @@ -118,8 +118,11 @@ local function decentParserAST(input)
textNode = not textNode
if textNode then
local subNode = input:match("%s*<(%w+)", pos)
local trail = input:sub(pos - 10, pos):gsub("[%s\r\n]", "")
if isTag and not subNode then
output = output .. "}, [["
if trail:sub(#trail, #trail) ~= ">" then
output = output .. "}, [["
end
elseif deepNode > 0 and not subNode then
output = output .. "[["
end
Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion test/test.luax → test/12_test.luax
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ return <li id={id} class={class} _="on destroy my.querySelector('button').click(
/>
</div>
{val3}
</li>
</li>
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
7 changes: 7 additions & 0 deletions test/8_input.luax
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
local module = {}

function module.EditTodo(todo)
return <input class="edit" name="title" value={todo.editing and todo.title or nil} todo-id={todo.id} _="install TodoEdit"/>
end

return module
11 changes: 11 additions & 0 deletions test/9_input2.luax
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
local todo = { id="1", done = false }

return <input
class="toggle"
type="checkbox"
checked={'' or nil}
hx-patch="/toggle-todo?id="..{todo.id}.."&done="..{tostring(todo.done)}
hx-target="closest <li/>"
hx-swap="outerHTML"
_="install TodoCheck"
/>
2 changes: 0 additions & 2 deletions test/input.luax

This file was deleted.

38 changes: 21 additions & 17 deletions test/test_ast.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,40 +28,44 @@ local node_value = require('test.2_node_value')

h(node_value)

local element = require('test.element')
local content = require('test.4_content')

h(element)
h(content)

local varin = require('test.varin')
local element = require('test.5_element')

h(varin)
h(element)

local foo = require('test.foo')
local foo = require('test.6_foo')

h(foo)

local content = require('test.content')
local input_with_con = require('test.7_input_with_con')

h(content)
h(input_with_con)

local input = require('test.input')
local module = require('test.8_input')

h(input)
h(module.EditTodo({ editing = true, title = "task", id = "1" }))

local input_with_con = require('test.input_with_con')
local input2 = require('test.9_input2')

h(input_with_con)
h(input2)

local props = require('test.props')
local linebreak = require('test.10_line_break')

h(props)
h(linebreak)

local linebreak = require('test.line_break')
local props = require('test.11_props')

h(linebreak)
print("========================")
h(props)

local test = require('test.test')
local test = require('test.12_test')

h(test)

local varin = require('test.13_varin')

h(varin)


58 changes: 33 additions & 25 deletions test/test_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,59 +45,67 @@ describe("LuaX", function()
assert.is.equal('<div>xxxx</div>', h(el))
end)

it("should return a HTML string when given JSX like syntax", function()
local el = require("test.element")
assert.is.equal('<div bar="bar" class="container" d="1" id="foo" val="value">Hello, world!</div>', h(el))
it("should return a HTML string when given attributes with special characters", function()
local el = require("test.4_content")
assert.is.equal(
'<footer _="install Footer" class="footer"><span _="install TodoCount" class="todo-count" hx-trigger="load"></span>foobar</footer>',
h(el))
end)

it("should return a HTML string when given JSX like syntax with nested node", function()
local el = require("test.varin")
assert.is.equal('<div class="container" id="div_1"><p class="title" id="p_2" style="border: 1px solid red;">Hello, world!</p></div>', h(el))
it("should return a HTML string when given JSX like syntax", function()
local el = require("test.5_element")
assert.is.equal('<div bar="bar" class="container" d="1" id="foo" val="value">Hello, world!</div>', h(el))
end)

it("should return a HTML string when given children prop", function()
local el = require("test.foo")
local el = require("test.6_foo")
assert.is.equal('<div>foobar</div>', h(el))
end)

it("should return a HTML string when given attributes with special characters", function()
local el = require("test.content")
it("should return a HTML string when have conditional statement", function()
local el = require("test.7_input_with_con")
assert.is.equal(
'<footer _="install Footer" class="footer"><span _="install TodoCount" class="todo-count" hx-trigger="load"></span>foobar</footer>',
'<input _="install TodoEdit" class="edit" name="title" todo-id="0">',
h(el))
end)

it("should return a HTML string when given input node", function()
local el = require("test.input")
local module = require("test.8_input")
assert.is.equal(
'<input _="install TodoEdit" class="edit" name="title" todo-id="0" value="foo">',
h(el))
'<input _="install TodoEdit" class="edit" name="title" todo-id="1" value="task">',
h(module.EditTodo({ editing = true, title = "task", id = "1" })))
end)

it("should return a HTML string when have conditional statement", function()
local el = require("test.input_with_con")
it("should return a HTML string when given input node", function()
local el = require("test.9_input2")
assert.is.equal(
'<input _="install TodoEdit" class="edit" name="title" todo-id="0">',
'<input _="install TodoCheck" checked="" class="toggle" hx-patch="/toggle-todo?id=1&done=false" hx-swap="outerHTML" hx-target="closest <li/>" type="checkbox">',
h(el))
end)

it("should return a HTML string when given JSX like syntax", function()
local el = require("test.props")
assert.is.equal([[<div id="foo" style="color;red"> test
</div>]], h(el))
end)

it("should return a HTML string with multi breakline", function()
local el = require("test.line_break")
local el = require("test.10_line_break")
assert.is.equal(
'<div><p color="red">foobar!</p> </div>',
h(el))
end)

it("should return a HTML string when given JSX like syntax", function()
local el = require("test.11_props")
assert.is.equal([[<div id="foo" style="color;red"> test
</div>]], h(el))
end)

it("should return a HTML string with deep node tree", function()
local el = require("test.test")
local el = require("test.12_test")
assert.is.equal(
'<li _="on destroy my.querySelector(\'button\').click()" class="test" id="1"><div class="view">todo A<label _="install TodoDblclick" hx-patch="/edit-todo?id=1&foo=test" hx-swap="outerHTML" hx-target="next input" hx-trigger="dblclick">todo A Label</label><button _="install Destroy" class="destroy" hx-delete="/remove-todo?id=1" hx-swap="outerHTML" hx-target="closest <li/>" hx-trigger="click"></button></div>todo A Value</li>',
h(el))
end)

it("should return a HTML string when given JSX like syntax with nested node", function()
local el = require("test.13_varin")
assert.is.equal('<div class="container" id="div_1"><p class="title" id="p_2" style="border: 1px solid red;">Hello, world!</p></div>', h(el))
end)

end)

0 comments on commit 34ab348

Please sign in to comment.