@rip-lang/server 1.4.3 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browse.rip +9 -6
- package/package.json +1 -1
- package/serving/static.rip +4 -3
package/browse.rip
CHANGED
|
@@ -5,14 +5,15 @@
|
|
|
5
5
|
# Built-in file browser when no index.rip or index.ts exists in the target
|
|
6
6
|
# directory. Activated automatically by `rip server` when no app entry is found.
|
|
7
7
|
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
8
|
+
# Single-click serves files natively (HTML renders, images display, etc.).
|
|
9
|
+
# Double-click (appends ?) shows syntax-highlighted source for text files.
|
|
10
|
+
# Markdown always renders. Directories show a listing with index file detection.
|
|
10
11
|
# ==============================================================================
|
|
11
12
|
|
|
12
13
|
import { use, start, notFound } from '@rip-lang/server'
|
|
13
14
|
import { statSync } from 'node:fs'
|
|
14
15
|
import { join, resolve, basename } from 'node:path'
|
|
15
|
-
import { renderDirectoryListing, renderMarkdown, renderTextFile, isTextFile, serveRipHighlightGrammar, findIndexFile
|
|
16
|
+
import { renderDirectoryListing, renderMarkdown, renderTextFile, isTextFile, serveRipHighlightGrammar, findIndexFile } from './serving/static.rip'
|
|
16
17
|
|
|
17
18
|
root = resolve(process.env.APP_BASE_DIR or process.cwd())
|
|
18
19
|
rootSlash = root + '/'
|
|
@@ -23,8 +24,10 @@ notFound ->
|
|
|
23
24
|
res = serveRipHighlightGrammar()
|
|
24
25
|
return res if res
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
url = new URL(@req.url)
|
|
28
|
+
reqPath = try decodeURIComponent(url.pathname) catch then url.pathname
|
|
27
29
|
path = resolve(root, reqPath.slice(1))
|
|
30
|
+
viewSource = url.search is '?'
|
|
28
31
|
|
|
29
32
|
unless path is root or path.startsWith(rootSlash)
|
|
30
33
|
return new Response 'Not Found', { status: 404 }
|
|
@@ -37,11 +40,11 @@ notFound ->
|
|
|
37
40
|
if stat.isFile()
|
|
38
41
|
accept = @req.header('accept') or ''
|
|
39
42
|
if accept.includes('text/html')
|
|
40
|
-
if path.endsWith('.md')
|
|
43
|
+
if path.endsWith('.md') and not viewSource
|
|
41
44
|
try
|
|
42
45
|
html = renderMarkdown(path)
|
|
43
46
|
return new Response html, { headers: { 'Content-Type': 'text/html; charset=UTF-8' } }
|
|
44
|
-
if
|
|
47
|
+
if viewSource and isTextFile(path)
|
|
45
48
|
try
|
|
46
49
|
html = renderTextFile(path)
|
|
47
50
|
return new Response html, { headers: { 'Content-Type': 'text/html; charset=UTF-8' } }
|
package/package.json
CHANGED
package/serving/static.rip
CHANGED
|
@@ -189,7 +189,7 @@ export renderDirectoryListing = (reqPath, fsPath, rootName) ->
|
|
|
189
189
|
</table>
|
|
190
190
|
</div></div>
|
|
191
191
|
<script>
|
|
192
|
-
!function(){var p,c,ox=14,oy=14;function mk(){if(p)return p;p=document.createElement('div');p.className='pop';p.innerHTML='<div class="pop-b"></div>';document.body.appendChild(p);return p}function show(a,e){var s=a.dataset.src;if(!s)return;var el=mk(),b=el.firstChild;b.innerHTML='';var img=new Image();img.src=s;b.appendChild(img);c=a;el.classList.add('on');place(e.clientX,e.clientY)}function hide(){c=null;if(p)p.classList.remove('on')}function place(x,y){if(!p)return;var r=p.getBoundingClientRect(),m=12,l=x+ox,t=y+oy;if(l+r.width>innerWidth-m)l=x-r.width-ox;if(t+r.height>innerHeight-m)t=innerHeight-r.height-m;if(l<m)l=m;if(t<m)t=m;p.style.left=l+'px';p.style.top=t+'px'}document.addEventListener('mouseover',function(e){var a=e.target.closest('[data-pv]');if(a)show(a,e)});document.addEventListener('mousemove',function(e){if(c)place(e.clientX,e.clientY)});document.addEventListener('mouseout',function(e){var a=e.target.closest('[data-pv]');if(a&&a===c)hide()});document.addEventListener('scroll',hide,{passive:true});document.addEventListener('keydown',function(e){if(e.key==='Escape')hide()});window.addEventListener('blur',hide)}();
|
|
192
|
+
!function(){var p,c,ox=14,oy=14;function mk(){if(p)return p;p=document.createElement('div');p.className='pop';p.innerHTML='<div class="pop-b"></div>';document.body.appendChild(p);return p}function show(a,e){var s=a.dataset.src;if(!s)return;var el=mk(),b=el.firstChild;b.innerHTML='';var img=new Image();img.src=s;b.appendChild(img);c=a;el.classList.add('on');place(e.clientX,e.clientY)}function hide(){c=null;if(p)p.classList.remove('on')}function place(x,y){if(!p)return;var r=p.getBoundingClientRect(),m=12,l=x+ox,t=y+oy;if(l+r.width>innerWidth-m)l=x-r.width-ox;if(t+r.height>innerHeight-m)t=innerHeight-r.height-m;if(l<m)l=m;if(t<m)t=m;p.style.left=l+'px';p.style.top=t+'px'}document.addEventListener('mouseover',function(e){var a=e.target.closest('[data-pv]');if(a)show(a,e)});document.addEventListener('mousemove',function(e){if(c)place(e.clientX,e.clientY)});document.addEventListener('mouseout',function(e){var a=e.target.closest('[data-pv]');if(a&&a===c)hide()});document.addEventListener('scroll',hide,{passive:true});document.addEventListener('keydown',function(e){if(e.key==='Escape')hide()});window.addEventListener('blur',hide);var dt=0;document.addEventListener('click',function(e){var a=e.target.closest('td.nm a');if(!a)return;var h=a.getAttribute('href');if(!h||h.endsWith('/'))return;e.preventDefault();clearTimeout(dt);dt=setTimeout(function(){location.href=h},250)});document.addEventListener('dblclick',function(e){var a=e.target.closest('td.nm a');if(!a)return;var h=a.getAttribute('href');if(!h||h.endsWith('/'))return;e.preventDefault();clearTimeout(dt);location.href=h+'?'})}();
|
|
193
193
|
</script>
|
|
194
194
|
</body>
|
|
195
195
|
</html>
|
|
@@ -376,10 +376,11 @@ export serveStaticRoute = (req, url, route) ->
|
|
|
376
376
|
return new Response(html, { headers: { 'content-type': 'text/html; charset=UTF-8' } })
|
|
377
377
|
if stat.isFile()
|
|
378
378
|
if route.browse and acceptsHtml(req)
|
|
379
|
-
|
|
379
|
+
viewSource = url.search is '?'
|
|
380
|
+
if filePath.endsWith('.md') and not viewSource
|
|
380
381
|
html = renderMarkdown(filePath)
|
|
381
382
|
return new Response(html, { headers: { 'content-type': 'text/html; charset=UTF-8' } })
|
|
382
|
-
if isTextFile(filePath)
|
|
383
|
+
if viewSource and isTextFile(filePath)
|
|
383
384
|
html = renderTextFile(filePath)
|
|
384
385
|
return new Response(html, { headers: { 'content-type': 'text/html; charset=UTF-8' } })
|
|
385
386
|
file = Bun.file(filePath)
|