Browse Source

Add support for relative paths as issue #9

Shaun 1 year ago
parent
commit
6cd2152ba4
4 changed files with 55 additions and 2 deletions
  1. 1 1
      package.json
  2. 4 1
      src/index.js
  3. 27 0
      src/url.js
  4. 23 0
      tests/url.test.js

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "@shaun/alpinejs-router",
-  "version": "1.2.13",
+  "version": "1.3.0",
   "description": "Easy to use and flexible router for Alpine.js",
   "type": "module",
   "main": "dist/module.cjs.js",

+ 4 - 1
src/index.js

@@ -115,7 +115,10 @@ export default function (Alpine) {
       return inLoadProgress[url]
     }
 
-    const tpl = el.getAttribute('template') ?? el.getAttribute('template.preload')
+    const tpl = RouterURL.resolveTemplatePath(
+      location.pathname,
+      el.getAttribute('template') ?? el.getAttribute('template.preload')
+    )
 
     let loading
     if (el.hasAttribute('template.preload')) {

+ 27 - 0
src/url.js

@@ -37,4 +37,31 @@ export class RouterURL {
     this.url = l + (r ? '?' + r : '')
     return this
   }
+
+  static resolveTemplatePath (pathname, tpl) {
+    if (tpl.startsWith('/')) {
+      return tpl
+    }
+
+    const dir = pathname.slice(0, pathname.lastIndexOf('/'))
+
+    if (tpl.startsWith('./')) {
+      return dir + tpl.slice(1)
+    }
+
+    if (tpl.startsWith('../')) {
+      const re = /\.\.\//g
+      let i = tpl.match(re).length
+      let arr = dir.split('/')
+      while (i--) {
+        arr.pop()
+      }
+      if (arr.length === 0) {
+        arr = ['']
+      }
+      return [...arr, tpl.replace(re, '')].join('/')
+    }
+
+    return tpl
+  }
 }

+ 23 - 0
tests/url.test.js

@@ -81,5 +81,28 @@ describe('URL', () => {
       expect(u.path).toBe('/hello/world')
       expect(u.resolve('/xyz', {a: '123', d: 1}).url).toBe('http://localhost/#/xyz?a=123&b=c&d=1')
     })
+
+    test('resolve template path', () => {
+      let pathname = new URL('http://localhost/hello/world').pathname
+      expect(RouterURL.resolveTemplatePath(pathname, '/a.html')).toStrictEqual('/a.html')
+      expect(RouterURL.resolveTemplatePath(pathname, './a.html')).toStrictEqual('/hello/a.html')
+      expect(RouterURL.resolveTemplatePath(pathname, '../a.html')).toStrictEqual('/a.html')
+      expect(RouterURL.resolveTemplatePath(pathname, '../../a.html')).toStrictEqual('/a.html')
+      expect(RouterURL.resolveTemplatePath(pathname, '../../../a.html')).toStrictEqual('/a.html')
+
+      pathname = new URL('http://localhost/hello/world/').pathname
+      expect(RouterURL.resolveTemplatePath(pathname, '/a.html')).toStrictEqual('/a.html')
+      expect(RouterURL.resolveTemplatePath(pathname, './a.html')).toStrictEqual('/hello/world/a.html')
+      expect(RouterURL.resolveTemplatePath(pathname, '../a.html')).toStrictEqual('/hello/a.html')
+      expect(RouterURL.resolveTemplatePath(pathname, '../../a.html')).toStrictEqual('/a.html')
+      expect(RouterURL.resolveTemplatePath(pathname, '../../../a.html')).toStrictEqual('/a.html')
+
+      pathname = new URL('http://localhost/').pathname
+      expect(RouterURL.resolveTemplatePath(pathname, '/a.html')).toStrictEqual('/a.html')
+      expect(RouterURL.resolveTemplatePath(pathname, './a.html')).toStrictEqual('/a.html')
+      expect(RouterURL.resolveTemplatePath(pathname, '../a.html')).toStrictEqual('/a.html')
+      expect(RouterURL.resolveTemplatePath(pathname, '../../a.html')).toStrictEqual('/a.html')
+      expect(RouterURL.resolveTemplatePath(pathname, '../../../a.html')).toStrictEqual('/a.html')
+    })
   })
 })