Skip to content

Commit 592f403

Browse files
committed
the CSS reload strategy supports @import directives
1 parent 5e8c104 commit 592f403

File tree

1 file changed

+54
-12
lines changed

1 file changed

+54
-12
lines changed

priv/static/phoenix_live_reload.js

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
let buildFreshUrl = (link) => {
1+
let getFreshUrl = (url) => {
22
let date = Math.round(Date.now() / 1000).toString()
3-
let url = link.href.replace(/(\&|\\?)vsn=\d*/, "")
3+
let cleanUrl = url.replace(/(&|\?)vsn=\d*/, "")
4+
let freshUrl = cleanUrl + (cleanUrl.indexOf("?") >= 0 ? "&" : "?") + "vsn=" + date
5+
return freshUrl;
6+
}
7+
8+
let buildFreshLinkUrl = (link) => {
49
let newLink = document.createElement('link')
510
let onComplete = () => {
611
if(link.parentNode !== null){
@@ -11,16 +16,45 @@ let buildFreshUrl = (link) => {
1116
newLink.onerror = onComplete
1217
newLink.onload = onComplete
1318
link.setAttribute("data-pending-removal", "")
14-
newLink.setAttribute("rel", "stylesheet");
15-
newLink.setAttribute("type", "text/css");
16-
newLink.setAttribute("href", url + (url.indexOf("?") >= 0 ? "&" : "?") + "vsn=" + date)
19+
newLink.setAttribute("rel", "stylesheet")
20+
newLink.setAttribute("type", "text/css")
21+
newLink.setAttribute("href", getFreshUrl(link.href))
1722
link.parentNode.insertBefore(newLink, link.nextSibling)
1823
return newLink
1924
}
2025

26+
let buildFreshImportUrl = (style) => {
27+
let newStyle = document.createElement('style')
28+
let onComplete = () => {
29+
if (style.parentNode !== null) {
30+
style.parentNode.removeChild(style)
31+
}
32+
}
33+
34+
let originalCSS = style.textContent || style.innerHTML
35+
let freshCSS = originalCSS.replace(/@import\s+(?:url\()?['"]?([^'"\)]+)['"]?\)?/g, (match, url) => {
36+
const freshUrl = getFreshUrl(url);
37+
38+
if (match.includes('url(')) {
39+
return `@import url("${freshUrl}")`
40+
} else {
41+
return `@import "${freshUrl}"`
42+
}
43+
})
44+
45+
newStyle.onerror = onComplete
46+
newStyle.onload = onComplete
47+
style.setAttribute("data-pending-removal", "")
48+
newStyle.setAttribute("type", "text/css")
49+
newStyle.textContent = freshCSS
50+
51+
style.parentNode.insertBefore(newStyle, style.nextSibling)
52+
return newStyle
53+
}
54+
2155
let repaint = () => {
2256
let browser = navigator.userAgent.toLowerCase()
23-
if(browser.indexOf("chrome") > -1){
57+
if (browser.indexOf("chrome") > -1) {
2458
setTimeout(() => document.body.offsetHeight, 25)
2559
}
2660
}
@@ -32,7 +66,15 @@ let cssStrategy = () => {
3266

3367
Array.from(reloadableLinkElements)
3468
.filter(link => link.href)
35-
.forEach(link => buildFreshUrl(link))
69+
.forEach(link => buildFreshLinkUrl(link))
70+
71+
let reloadablestyles = window.parent.document.querySelectorAll(
72+
"style:not([data-no-reload]):not([data-pending-removal])"
73+
)
74+
75+
Array.from(reloadablestyles)
76+
.filter(style => style.textContent.includes("@import"))
77+
.forEach(style => buildFreshImportUrl(style))
3678

3779
repaint()
3880
};
@@ -52,7 +94,7 @@ class LiveReloader {
5294
this.socket = socket
5395
this.logsEnabled = false
5496
this.enabledOnce = false
55-
this.editorURL = null
97+
this.editorUrl = null
5698
}
5799
enable(){
58100
this.socket.onOpen(() => {
@@ -72,7 +114,7 @@ class LiveReloader {
72114
})
73115
this.channel.on("log", ({msg, level}) => this.logsEnabled && this.log(level, msg))
74116
this.channel.join().receive("ok", ({editor_url}) => {
75-
this.editorURL = editor_url
117+
this.editorUrl = editor_url
76118
})
77119
this.socket.connect()
78120
}
@@ -86,7 +128,7 @@ class LiveReloader {
86128
disableServerLogs(){ this.logsEnabled = false }
87129

88130
openEditorAtCaller(targetNode){
89-
if(!this.editorURL){
131+
if(!this.editorUrl){
90132
return console.error("phoenix_live_reload cannot openEditorAtCaller without configured PLUG_EDITOR")
91133
}
92134

@@ -97,7 +139,7 @@ class LiveReloader {
97139
}
98140

99141
openEditorAtDef(targetNode){
100-
if(!this.editorURL){
142+
if(!this.editorUrl){
101143
return console.error("phoenix_live_reload cannot openEditorAtDef without configured PLUG_EDITOR")
102144
}
103145

@@ -114,7 +156,7 @@ class LiveReloader {
114156
this.channel.push("full_path", {rel_path: file, app: app})
115157
.receive("ok", ({full_path}) => {
116158
console.log("full path", full_path)
117-
let url = this.editorURL
159+
let url = this.editorUrl
118160
.replace("__RELATIVEFILE__", file)
119161
.replace("__FILE__", full_path)
120162
.replace("__LINE__", line)

0 commit comments

Comments
 (0)