mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) Fix browser history bug with tutorials
Summary: History wasn't being replaced in some cases, which was causing a bug where trying to leave a tutorial fork via the browser's back button would navigate back to the trunk, and trigger forking again. This effectively made it impossible to leave a tutorial. Also adds support for specifying custom CSS classes for tutorial Markdown images. Test Plan: Browser test. Reviewers: JakubSerafin Reviewed By: JakubSerafin Differential Revision: https://phab.getgrist.com/D3866
This commit is contained in:
parent
69fea132de
commit
b15ae98349
@ -240,9 +240,9 @@ export class DocPageModelImpl extends Disposable implements DocPageModel {
|
|||||||
public updateUrlNoReload(
|
public updateUrlNoReload(
|
||||||
urlId: string,
|
urlId: string,
|
||||||
urlOpenMode: OpenDocMode,
|
urlOpenMode: OpenDocMode,
|
||||||
options: {removeSlug?: boolean, replaceUrl?: boolean} = {removeSlug: false, replaceUrl: true}
|
options: {removeSlug?: boolean, replaceUrl?: boolean} = {}
|
||||||
) {
|
) {
|
||||||
const {removeSlug, replaceUrl} = options;
|
const {removeSlug = false, replaceUrl = true} = options;
|
||||||
const state = urlState().state.get();
|
const state = urlState().state.get();
|
||||||
const nextState = {
|
const nextState = {
|
||||||
...state,
|
...state,
|
||||||
|
@ -69,6 +69,12 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.doc-tutorial-popup-thumbnail-half-screenshot {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
.doc-tutorial-popup-thumbnail img {
|
.doc-tutorial-popup-thumbnail img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: 1px solid var(--grist-theme-tutorials-popup-border, #D9D9D9);
|
border: 1px solid var(--grist-theme-tutorials-popup-border, #D9D9D9);
|
||||||
|
@ -2,15 +2,21 @@ import {marked} from 'marked';
|
|||||||
|
|
||||||
export const renderer = new marked.Renderer();
|
export const renderer = new marked.Renderer();
|
||||||
|
|
||||||
renderer.image = (href: string, text: string) => {
|
renderer.image = (href: string | null, title: string | null, _text: string) => {
|
||||||
return `<div class="doc-tutorial-popup-thumbnail">
|
let classes = 'doc-tutorial-popup-thumbnail';
|
||||||
<img src="${href}" title="${text ?? ''}" />
|
const hash = href?.split('#')?.[1];
|
||||||
|
if (hash) {
|
||||||
|
const extraClass = `doc-tutorial-popup-thumbnail-${hash}`;
|
||||||
|
classes += ` ${extraClass}`;
|
||||||
|
}
|
||||||
|
return `<div class="${classes}">
|
||||||
|
<img src="${href}" title="${title ?? ''}" />
|
||||||
<div class="doc-tutorial-popup-thumbnail-icon-wrapper">
|
<div class="doc-tutorial-popup-thumbnail-icon-wrapper">
|
||||||
<div class="doc-tutorial-popup-thumbnail-icon"></div>
|
<div class="doc-tutorial-popup-thumbnail-icon"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
};
|
};
|
||||||
|
|
||||||
renderer.link = (href: string, _title: string, text: string) => {
|
renderer.link = (href: string | null, _title: string | null, text: string) => {
|
||||||
return `<a href="${href}" target="_blank">${text}</a>`;
|
return `<a href="${href}" target="_blank">${text}</a>`;
|
||||||
};
|
};
|
||||||
|
@ -115,6 +115,25 @@ describe('DocTutorial', function () {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not break navigation via browser history', async function() {
|
||||||
|
// Navigating via browser history was partially broken at one point; if you
|
||||||
|
// started a tutorial, and wanted to leave via the browser's back button, you
|
||||||
|
// couldn't.
|
||||||
|
for (const page of ['code', 'data', 'acl']) {
|
||||||
|
await driver.navigate().back();
|
||||||
|
const currentUrl = await driver.getCurrentUrl();
|
||||||
|
assert.match(currentUrl, new RegExp(`/p/${page}$`));
|
||||||
|
}
|
||||||
|
|
||||||
|
await driver.navigate().back();
|
||||||
|
await driver.navigate().back();
|
||||||
|
await driver.findWait('.test-dm-doclist', 2000);
|
||||||
|
|
||||||
|
await driver.navigate().forward();
|
||||||
|
await gu.waitForDocToLoad();
|
||||||
|
assert.isTrue(await driver.findWait('.test-doc-tutorial-popup', 2000).isDisplayed());
|
||||||
|
});
|
||||||
|
|
||||||
it('does not show the GristDocTutorial page or table', async function() {
|
it('does not show the GristDocTutorial page or table', async function() {
|
||||||
assert.deepEqual(await gu.getPageNames(), ['Page 1', 'Page 2']);
|
assert.deepEqual(await gu.getPageNames(), ['Page 1', 'Page 2']);
|
||||||
await driver.find('.test-tools-raw').click();
|
await driver.find('.test-tools-raw').click();
|
||||||
@ -290,7 +309,7 @@ describe('DocTutorial', function () {
|
|||||||
await api.updateDoc(doc.id, {name: 'DocTutorial V2'});
|
await api.updateDoc(doc.id, {name: 'DocTutorial V2'});
|
||||||
await api.applyUserActions(doc.id, [['AddTable', 'NewTable', [{id: 'A'}]]]);
|
await api.applyUserActions(doc.id, [['AddTable', 'NewTable', [{id: 'A'}]]]);
|
||||||
|
|
||||||
// Load the current fork of the tutorial.
|
// Load the fork of the tutorial.
|
||||||
await driver.navigate().to(forkUrl);
|
await driver.navigate().to(forkUrl);
|
||||||
await gu.waitForDocToLoad();
|
await gu.waitForDocToLoad();
|
||||||
await driver.findWait('.test-doc-tutorial-popup', 2000);
|
await driver.findWait('.test-doc-tutorial-popup', 2000);
|
||||||
@ -299,7 +318,7 @@ describe('DocTutorial', function () {
|
|||||||
assert.deepEqual(await gu.getPageNames(), ['Page 1', 'Page 2']);
|
assert.deepEqual(await gu.getPageNames(), ['Page 1', 'Page 2']);
|
||||||
assert.deepEqual(await gu.getVisibleGridCells({cols: [0], rowNums: [1]}), ['Redacted']);
|
assert.deepEqual(await gu.getVisibleGridCells({cols: [0], rowNums: [1]}), ['Redacted']);
|
||||||
|
|
||||||
// Restart the tutorial and wait for a new fork to be created.
|
// Restart the tutorial.
|
||||||
await driver.find('.test-doc-tutorial-popup-restart').click();
|
await driver.find('.test-doc-tutorial-popup-restart').click();
|
||||||
await driver.find('.test-modal-confirm').click();
|
await driver.find('.test-modal-confirm').click();
|
||||||
await gu.waitForServer();
|
await gu.waitForServer();
|
||||||
@ -319,7 +338,7 @@ describe('DocTutorial', function () {
|
|||||||
// Check that edits were reset.
|
// Check that edits were reset.
|
||||||
assert.deepEqual(await gu.getVisibleGridCells({cols: [0], rowNums: [1]}), ['Zane Rails']);
|
assert.deepEqual(await gu.getVisibleGridCells({cols: [0], rowNums: [1]}), ['Zane Rails']);
|
||||||
|
|
||||||
// Check that changes made to the tutorial since the last fork are included.
|
// Check that changes made to the tutorial since it was last started are included.
|
||||||
assert.equal(await driver.find('.test-doc-tutorial-popup-header').getText(),
|
assert.equal(await driver.find('.test-doc-tutorial-popup-header').getText(),
|
||||||
'DocTutorial V2');
|
'DocTutorial V2');
|
||||||
assert.deepEqual(await gu.getPageNames(), ['Page 1', 'Page 2', 'NewTable']);
|
assert.deepEqual(await gu.getPageNames(), ['Page 1', 'Page 2', 'NewTable']);
|
||||||
|
Loading…
Reference in New Issue
Block a user