Skip to content

Commit 596648a

Browse files
fix: Remove trailing slash in edit mode (#921)
1 parent 313d733 commit 596648a

2 files changed

Lines changed: 72 additions & 5 deletions

File tree

blocks/shared/pathDetails.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ export default function getPathDetails(loc) {
117117
if (currhash === hash && currpath === pathname && details) return details;
118118
currhash = hash;
119119

120-
const fullpath = hash.replace('#', '');
120+
let fullpath = hash.replace('#', '');
121121
window.name = fullpath;
122122

123123
// config, edit, sheet
@@ -131,10 +131,21 @@ export default function getPathDetails(loc) {
131131
// Split everything up so it can be later used for both DA & AEM
132132
const pathParts = sanitizePathParts(fullpath);
133133

134-
// Redirect JSON files from edit view to sheet view
135-
if (editor === 'edit' && fullpath.endsWith('.json')) {
136-
window.location.href = `/sheet#${fullpath.slice(0, -5)}`;
137-
return null;
134+
if (editor === 'edit') {
135+
// Redirect JSON files from edit view to sheet view
136+
if (fullpath.endsWith('.json')) {
137+
window.location.href = `/sheet#${fullpath.slice(0, -5)}`;
138+
return null;
139+
}
140+
141+
if (fullpath.endsWith('/')) {
142+
// Remove trailing slash from pathParts and fullpath
143+
pathParts.pop();
144+
fullpath = fullpath.slice(0, -1);
145+
if (!loc) {
146+
history.replaceState(null, '', `${window.location.pathname}${window.location.search}#${fullpath}`);
147+
}
148+
}
138149
}
139150

140151
// Determine if folder (trailing slash split to empty string)

test/unit/blocks/shared/pathDetails.test.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,62 @@ import '../../milo.js';
55
const { default: getPathDetails } = await import('../../../../blocks/shared/pathDetails.js');
66

77
describe('Path details', () => {
8+
describe('Edit with trailing slash', () => {
9+
it('Strips trailing slash from org-only path and treats as HTML', () => {
10+
const loc = { pathname: '/edit', hash: '#/adobe/' };
11+
const details = getPathDetails(loc);
12+
expect(details.fullpath).to.equal('/adobe.html');
13+
expect(details.depth).to.equal(1);
14+
expect(details.view).to.equal('edit');
15+
});
16+
17+
it('Strips trailing slash from org+repo path and treats as HTML', () => {
18+
const loc = { pathname: '/edit', hash: '#/adobe/geometrixx/' };
19+
const details = getPathDetails(loc);
20+
expect(details.fullpath).to.equal('/adobe/geometrixx.html');
21+
expect(details.depth).to.equal(2);
22+
});
23+
24+
it('Strips trailing slash from org+repo+path and treats as HTML', () => {
25+
const loc = { pathname: '/edit', hash: '#/adobe/geometrixx/testing-123/' };
26+
const details = getPathDetails(loc);
27+
expect(details.fullpath).to.equal('/adobe/geometrixx/testing-123.html');
28+
expect(details.depth).to.equal(3);
29+
});
30+
31+
it('Does not strip trailing slash in browse view at org+repo depth', () => {
32+
const loc = { pathname: '/', hash: '#/adobe/geometrixx/' };
33+
const details = getPathDetails(loc);
34+
expect(details.fullpath).to.equal('/adobe/geometrixx/');
35+
});
36+
37+
it('Does not strip trailing slash in browse view at org+repo+path depth', () => {
38+
const loc = { pathname: '/', hash: '#/adobe/geometrixx/testing-123/' };
39+
const details = getPathDetails(loc);
40+
expect(details.fullpath).to.equal('/adobe/geometrixx/testing-123/');
41+
});
42+
43+
it('Calls history.replaceState to remove trailing slash when no loc provided', () => {
44+
const originalUrl = window.location.href;
45+
const replaceStateCalls = [];
46+
const originalReplaceState = history.replaceState;
47+
history.replaceState = (...args) => { replaceStateCalls.push(args); };
48+
49+
// Use pushState to set pathname to /edit with a unique trailing-slash hash
50+
history.pushState(null, '', '/edit#/adobe/geometrixx/replacestate-trail-test/');
51+
52+
try {
53+
getPathDetails();
54+
expect(replaceStateCalls.length).to.equal(1);
55+
expect(replaceStateCalls[0][2]).to.include('#/adobe/geometrixx/replacestate-trail-test');
56+
expect(replaceStateCalls[0][2]).to.not.include('#/adobe/geometrixx/replacestate-trail-test/');
57+
} finally {
58+
history.replaceState = originalReplaceState;
59+
history.pushState(null, '', originalUrl);
60+
}
61+
});
62+
});
63+
864
describe('Org only', () => {
965
describe('Config', () => {
1066
it('Handles folder config (/)', () => {

0 commit comments

Comments
 (0)