@uniweb/core 0.2.0 → 0.2.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniweb/core",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Core classes for the Uniweb platform - Uniweb, Website, Page, Block",
5
5
  "type": "module",
6
6
  "exports": {
@@ -30,7 +30,7 @@
30
30
  "jest": "^29.7.0"
31
31
  },
32
32
  "dependencies": {
33
- "@uniweb/semantic-parser": "1.0.12"
33
+ "@uniweb/semantic-parser": "1.0.14"
34
34
  },
35
35
  "scripts": {
36
36
  "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
package/src/block.js CHANGED
@@ -233,7 +233,8 @@ export default class Block {
233
233
  videos: c.videos || [],
234
234
  lists: c.lists || [],
235
235
  buttons: c.buttons || [],
236
- items: c.items || []
236
+ items: c.items || [],
237
+ data: c.data || {}
237
238
  }
238
239
  }
239
240
 
package/src/page.js CHANGED
@@ -20,6 +20,7 @@ export default class Page {
20
20
  this.id = id
21
21
  this.stableId = pageData.id || null // Stable page ID for page: links (from page.yml)
22
22
  this.route = pageData.route
23
+ this.sourcePath = pageData.sourcePath || null // Original folder-based path (for ancestor checking)
23
24
  this.isIndex = pageData.isIndex || false // True if this page is the index for its parent route
24
25
  this.title = pageData.title || ''
25
26
  this.description = pageData.description || ''
@@ -345,22 +346,12 @@ export default class Page {
345
346
 
346
347
  /**
347
348
  * Get the navigation route (canonical route for links)
348
- * For index pages, returns the parent route (e.g., '/' for homepage)
349
- * For regular pages, returns the actual route
349
+ * With the new routing model, route is already the canonical nav route.
350
+ * Index pages have route set to parent route (e.g., '/' for homepage).
350
351
  * @returns {string}
351
352
  */
352
353
  getNavRoute() {
353
- if (!this.isIndex) {
354
- return this.route
355
- }
356
- // Index page - compute parent route
357
- // /home -> /
358
- // /docs/getting-started -> /docs
359
- const segments = this.route.split('/').filter(Boolean)
360
- if (segments.length <= 1) {
361
- return '/'
362
- }
363
- return '/' + segments.slice(0, -1).join('/')
354
+ return this.route
364
355
  }
365
356
 
366
357
  /**
@@ -494,18 +485,27 @@ export default class Page {
494
485
  /**
495
486
  * Check if this page or any descendant matches the given route.
496
487
  * Useful for highlighting parent nav items when a child page is active.
497
- * Delegates to Website.isRouteActiveOrAncestor() for consistent logic.
488
+ *
489
+ * For index pages, uses sourcePath (original folder path) for ancestor checking
490
+ * to avoid false positives. E.g., homepage at '/' shouldn't be ancestor of '/about'.
498
491
  *
499
492
  * @param {string} currentRoute - Current route to compare against
500
493
  * @returns {boolean} True if this page or a descendant is active
501
494
  *
502
495
  * @example
503
- * // Page route: '/docs'
504
- * // Current route: 'docs/getting-started/installation'
505
- * page.isActiveOrAncestor('docs/getting-started/installation') // true
496
+ * // Page route: '/docs' (index page with sourcePath: '/docs/intro')
497
+ * // Current route: '/docs/api'
498
+ * page.isActiveOrAncestor('/docs/api') // false (not under /docs/intro)
506
499
  */
507
500
  isActiveOrAncestor(currentRoute) {
508
- return this.website.isRouteActiveOrAncestor(this.route, currentRoute)
501
+ // Exact match on canonical route
502
+ if (this.website.isRouteActive(this.route, currentRoute)) {
503
+ return true
504
+ }
505
+ // Ancestor check uses sourcePath (folder-based path) to avoid false positives
506
+ // For index pages, sourcePath differs from route
507
+ const pathForAncestorCheck = this.sourcePath || this.route
508
+ return this.website.isRouteActiveOrAncestor(pathForAncestorCheck, currentRoute)
509
509
  }
510
510
 
511
511
  // ─────────────────────────────────────────────────────────────────
package/src/website.js CHANGED
@@ -969,8 +969,18 @@ export default class Website {
969
969
 
970
970
  // Check each versioned scope to see if route falls within it
971
971
  for (const scope of Object.keys(this.versionedScopes)) {
972
- // Route matches scope exactly or is a child of scope
973
- if (normalizedRoute === scope || normalizedRoute.startsWith(scope + '/')) {
972
+ // Route matches scope exactly
973
+ if (normalizedRoute === scope) {
974
+ return scope
975
+ }
976
+
977
+ // Root scope matches all routes starting with /
978
+ if (scope === '/') {
979
+ if (normalizedRoute.startsWith('/') || normalizedRoute === '') {
980
+ return scope
981
+ }
982
+ } else if (normalizedRoute.startsWith(scope + '/')) {
983
+ // Route is a child of this scope
974
984
  return scope
975
985
  }
976
986
  }
@@ -1060,7 +1070,10 @@ export default class Website {
1060
1070
  if (!targetVersionInfo) return null
1061
1071
 
1062
1072
  // Extract the path within the scope (after scope and any version prefix)
1063
- const afterScope = currentRoute.slice(scope.length) // e.g., '/getting-started' or '/v1/getting-started'
1073
+ // For root scope ('/'), keep the full path; otherwise slice off the scope
1074
+ const afterScope = scope === '/'
1075
+ ? currentRoute
1076
+ : currentRoute.slice(scope.length) // e.g., '/getting-started' or '/v1/getting-started'
1064
1077
 
1065
1078
  // Check if current route has a version prefix
1066
1079
  let pathWithinVersion = afterScope
@@ -1076,9 +1089,13 @@ export default class Website {
1076
1089
  // Build target URL
1077
1090
  // Latest version has no prefix, others have /vN prefix
1078
1091
  if (targetVersionInfo.latest) {
1079
- return scope + pathWithinVersion
1092
+ // For root scope, return path directly; otherwise prepend scope
1093
+ return scope === '/' ? pathWithinVersion : scope + pathWithinVersion
1080
1094
  } else {
1081
- return scope + '/' + targetVersion + pathWithinVersion
1095
+ // For root scope: /v1/path; otherwise: scope/v1/path
1096
+ return scope === '/'
1097
+ ? '/' + targetVersion + pathWithinVersion
1098
+ : scope + '/' + targetVersion + pathWithinVersion
1082
1099
  }
1083
1100
  }
1084
1101