Skip to content

Commit

Permalink
fix style block
Browse files Browse the repository at this point in the history
  • Loading branch information
shahrul committed Oct 18, 2024
1 parent 195685d commit b1f7b0c
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 9 deletions.
6 changes: 3 additions & 3 deletions .rockspec
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package = "luax"
version = "1.0.7-1"
version = "1.0.8-1"

source = {
url = "https://github.com/syarul/luax/archive/refs/tags/v1.0.7.tar.gz",
dir = "luax-1.0.7"
url = "https://github.com/syarul/luax/archive/refs/tags/v1.0.8.tar.gz",
dir = "luax-1.0.8"
}
description = {
summary = "HTML parse in Lua",
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

LuaX is Lua + XML Syntax extension with built-in decent parse. In retrospect it's akin to React JSX.

<a href="https://luarocks.org/modules/syarul/luax" rel="nofollow"><img alt="Luarocks Package" src="https://img.shields.io/badge/Luarocks-1.0.7-blue.svg" style="max-width:100%;"></a>
<a href="https://luarocks.org/modules/syarul/luax" rel="nofollow"><img alt="Luarocks Package" src="https://img.shields.io/badge/Luarocks-1.0.8-blue.svg" style="max-width:100%;"></a>
[![Lua CI](https://github.com/syarul/luax/actions/workflows/lua.yml/badge.svg)](https://github.com/syarul/luax/actions/workflows/lua.yml)

## Decent Parser
Expand Down
32 changes: 27 additions & 5 deletions luax.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ function State:new()
text_node_start = false,
script_node = false,
script_node_init = false,
style_node = false,
style_node_init = false,
}, self)
end

Expand All @@ -48,7 +50,7 @@ function State:xml(level)
if level ~= nil then return self.deep_node > level end
return self.deep_node > 0
end
function State:not_str() return not self.deep_string and not self.deep_string_apos and not self.script_node end
function State:not_str() return not self.deep_string and not self.deep_string_apos and not self.script_node and not self.style_node end
function State:toggle(key, bool)
if bool ~= nil then self[key] = bool else self[key] = not self[key] end
end
Expand Down Expand Up @@ -122,6 +124,7 @@ local function decent_parser_ast(input)
local tag_name_end = tag_range:match("</([%w-]+)>", 0)
local tag_doc_type = tag_range:match("<(%!%w+)", 0)
local tag_script = tag_name and tag_name:match("script", 0) or tag_name_end and tag_name_end:match("script", 0)
local tag_style = tag_name and tag_name:match("style", 0) or tag_name_end and tag_name_end:match("style", 0)
if tag_doc_type then
tag_name = tag_doc_type:sub(2)
s.doc_type = true
Expand All @@ -148,6 +151,9 @@ local function decent_parser_ast(input)
if tag_script then
s.script_node_init = not s.script_node_init
end
if tag_style then
s.style_node_init = not s.style_node_init
end
if s:xml(1) then
-- handle internal return function
local ret = input:sub(s.pos-8, s.pos):gsub("%s\r\n", ""):sub(0, 6) == "return"
Expand Down Expand Up @@ -189,22 +195,27 @@ local function decent_parser_ast(input)
else
s:conc(tok, 1)
end
elseif tok == "<" and not s:not_str() and input:match("</([%w-]+)>", s.pos) == "script" then
elseif tok == "<" and not s.style_node and not s:not_str() and input:match("</([%w-]+)>", s.pos) == "script" then
s:toggle("script_node")
s:conc("]]")
elseif tok == "<" and not s.script_node and not s:not_str() and input:match("</([%w-]+)>", s.pos) == "style" then
s:toggle("style_node")
s:conc("]]")
elseif tok == '"' and s:xml() and not s.script_node then
s:toggle("deep_string")
s:conc(tok, 1)
elseif tok == "'" and s:xml() and not s.script_node then
s:toggle("deep_string_apos")
s:conc(tok, 1)
elseif tok == ">" and s:xml() and s:not_str() then
if not s.script_node_init and not s.text_node and s.is_tag and input:sub(s.pos - 1, s.pos - 1) ~= "/" then
if not s.style_node_init and not s.script_node_init and not s.text_node and s.is_tag and input:sub(s.pos - 1, s.pos - 1) ~= "/" then
s:toggle("is_tag")
s:toggle("text_node")
s:conc("}")
elseif s.script_node_init then
s:toggle("is_tag")
if s.is_tag then
s:toggle("is_tag")
end
s:toggle("script_node_init")
local trail = s.output:sub(#s.output - 10, #s.output):gsub("[%s\r\n]", "")
if trail:sub(#trail) == "{" then
Expand All @@ -213,12 +224,23 @@ local function decent_parser_ast(input)
else
s:conc("}")
end
elseif s.style_node_init and not s.script_node_init then
if s.is_tag then
s:toggle("is_tag")
end
s:toggle("style_node_init")
local trail = s.output:sub(#s.output - 10, #s.output):gsub("[%s\r\n]", "")
if trail:sub(#trail) == "{" then
s:toggle("style_node")
s:conc("}, [[\n")
else
s:conc("}")
end
else
s.is_tag = not s.is_tag
s:dec_deep_node()
s:conc("})")
end

if s.doc_type then
s.doc_type = not s.doc_type
local doc_type_params = s.output:sub(doc_type_start_pos, s.pos - 1)
Expand Down
44 changes: 44 additions & 0 deletions test/24_web_component_style.luax
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
return <!doctype html>
<html>
<head>
<style>
button {
background-color: red;
display: block;
margin-top: 8px;
}

example-component::part(native) {
background-color: pink;
}
</style>
</head>
<body>
<example-component></example-component>
<button>Button in Light DOM</button>
<script>
// Use custom elements API v1 to register a new HTML tag and define its JS behavior
// using an ES6 class. Every instance of <fancy-tab> will have this same prototype.
customElements.define('example-component', class extends HTMLElement {
constructor() {
super(); // always call super() first in the constructor.

// Attach a shadow root to <fancy-tabs>.
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `
<style>
div {
height: 150px;
width: 150px;
border: solid 2px;
}
</style>

<div part="native"></div>
<button>Button in Shadow DOM</button>
`;
}
});
</script>
</body>
</html>
4 changes: 4 additions & 0 deletions test/test_ast.lua
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,8 @@ local st2 = require('test.23_web_component_test')

h(st2)

local st4 = require('test.24_web_component_style')

h(st4)


38 changes: 38 additions & 0 deletions test/test_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -214,4 +214,42 @@ describe("LuaX", function()
</script></body></html>]], h(st2))
end)

it("should return a HTML string when given XML like syntax with script tag", function()
local st3 = require('test.24_web_component_style')
assert.is.equal([[<!doctype html><html><head><style>
button {
background-color: red;
display: block;
margin-top: 8px;
}
example-component::part(native) {
background-color: pink;
}
</style></head><body><example-component></example-component><button>Button in Light DOM</button><script>
// Use custom elements API v1 to register a new HTML tag and define its JS behavior
// using an ES6 class. Every instance of <fancy-tab> will have this same prototype.
customElements.define('example-component', class extends HTMLElement {
constructor() {
super(); // always call super() first in the constructor.
// Attach a shadow root to <fancy-tabs>.
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `
<style>
div {
height: 150px;
width: 150px;
border: solid 2px;
}
</style>
<div part="native"></div>
<button>Button in Shadow DOM</button>
`;
}
});
</script></body></html>]], h(st3))
end)

end)

0 comments on commit b1f7b0c

Please sign in to comment.