Skip to content

Commit

Permalink
Sync and improve regex (#2959)
Browse files Browse the repository at this point in the history
We also use the regex on the JavaScript side,
so it provides better validation it works as
desired.
  • Loading branch information
josevalim authored Dec 22, 2023
1 parent c0d3acc commit e26693e
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 45 deletions.
67 changes: 24 additions & 43 deletions assets/js/phoenix_live_view/rendered.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,60 +37,41 @@ const VOID_TAGS = new Set([
"track",
"wbr"
])
const endingTagNameChars = new Set([">", "/", " ", "\n", "\t", "\r"])
const quoteChars = new Set(["'", '"'])

export let modifyRoot = (html, attrs, clearInnerHTML) => {
let i = 0
let insideComment = false
let beforeTag, afterTag, tag, tagNameEndsAt, id, newHTML
while(i < html.length){
let char = html.charAt(i)
if(insideComment){
if(char === "-" && html.slice(i, i + 3) === "-->"){
insideComment = false
i += 3
} else {

let lookahead = html.match(/^(\s*(?:<!--.*?-->\s*)*)<([^\s\/>]+)/)
if(lookahead === null) { throw new Error(`malformed html ${html}`) }

i = lookahead[0].length
beforeTag = lookahead[1]
tag = lookahead[2]
tagNameEndsAt = i

// Scan the opening tag for id, if there is any
for(i; i < html.length; i++){
if(html.charAt(i) === ">" ){ break }
if(html.charAt(i) === "="){
let isId = html.slice(i - 3, i) === " id"
i++;
let char = html.charAt(i)
if (quoteChars.has(char)) {
let attrStartsAt = i
i++
}
} else if(char === "<" && html.slice(i, i + 4) === "<!--"){
insideComment = true
i += 4
} else if(char === "<"){
beforeTag = html.slice(0, i)
let iAtOpen = i
i++
for(i; i < html.length; i++){
if(endingTagNameChars.has(html.charAt(i))){ break }
}
tagNameEndsAt = i
tag = html.slice(iAtOpen + 1, tagNameEndsAt)
// Scan the opening tag for id, if there is any
for(i; i < html.length; i++){
if(html.charAt(i) === ">" ){ break }
if(html.charAt(i) === "="){
let isId = html.slice(i - 3, i) === " id"
i++;
let char = html.charAt(i)
if (quoteChars.has(char)) {
let attrStartsAt = i
i++
for(i; i < html.length; i++){
if(html.charAt(i) === char){ break }
}
if (isId) {
id = html.slice(attrStartsAt + 1, i)
break
}
}
for(i; i < html.length; i++){
if(html.charAt(i) === char){ break }
}
if (isId) {
id = html.slice(attrStartsAt + 1, i)
break
}
}
break
} else {
i++
}
}
if(!tag){ throw new Error(`malformed html ${html}`) }

let closeAt = html.length - 1
insideComment = false
Expand Down
4 changes: 2 additions & 2 deletions lib/phoenix_live_view/test/dom.ex
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,9 @@ defmodule Phoenix.LiveViewTest.DOM do
defp add_cid_attr(cid, [head | tail]) do
head_with_cid =
Regex.replace(
~r"^((?:<!--.*-->)?<[^\s\r\n\t/>]+)",
~r/^(\s*(?:<!--.*?-->\s*)*)<([^\s\/>]+)/,
IO.iodata_to_binary(head),
"\\1 #{@phx_component}=\"#{to_string(cid)}\"",
"\\0 #{@phx_component}=\"#{to_string(cid)}\"",
global: false
)

Expand Down

0 comments on commit e26693e

Please sign in to comment.