Skip to content

Commit

Permalink
Merge branch 'Agoric:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
kbennett2000 authored Dec 11, 2023
2 parents e6ce1ba + 296b4ff commit 5e2d286
Show file tree
Hide file tree
Showing 33 changed files with 629 additions and 465 deletions.
55 changes: 50 additions & 5 deletions main/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,57 @@ module.exports = {
}
});
if (location.hash) {
// Re-navigate to the page target once content has loaded.
if (location.hash && location.hash !== '#') {
// Once content has loaded, re-navigate to the page target
// without triggering interfering router/history/scroll logic.
const hash = location.hash;
fixups.set(['main'], _elems => {
const old = location.hash;
location.hash = '';
location.hash = old;
const stopPropagation = evt => {
evt.stopImmediatePropagation();
const props = {};
const proto = Object.getPrototypeOf(evt);
const propSource = proto === Event.prototype ? {} : proto;
for (const name of Object.getOwnPropertyNames(propSource)) {
if (name !== 'constructor') props[name] = evt[name];
}
console.log('suppress', evt.type, { __proto__: evt, ...props });
};
const stopEvents = types => {
const restorers = types.map(type => {
window.addEventListener(type, stopPropagation, true);
return () => window.removeEventListener(type, stopPropagation, true);
});
const passEvents = () => {
// Run and drop references to all restore functions.
while (restorers.length > 0) restorers.pop()();
};
return passEvents;
};
// Navigate to the page itself as a blank slate.
const passStateEvents = stopEvents(['hashchange', 'popstate']);
const passScrollEvents = stopEvents(['scroll']);
location.replace('#');
// Restore state-change events, then navigate back to the target.
passStateEvents();
try {
const target = document.getElementById(decodeURIComponent(hash.slice(1)));
if (target && target.innerHTML.trim() === '') {
document.documentElement.classList.add('scrollingToTarget');
target.scrollIntoView({ behavior: 'instant' });
document.documentElement.classList.remove('scrollingToTarget');
}
} catch (err) {
console.warn(err);
}
location.replace(hash);
// Restore scroll events and create a new history entry to be overridden
// if the initial target lacks a TOC entry to highlight.
passScrollEvents();
history.pushState(null, '', hash);
});
}
Expand Down
114 changes: 80 additions & 34 deletions main/.vuepress/enhanceApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,40 +43,86 @@ function patchRoutesToPreserveFragments(router) {
});
}

// The router assumes everything is site-local, so manually implement external redirection
// to avoid Not Found URLs like 'https://docs.agoric.com/https:/github.com/...'.
// cf. https://github.com/vuejs/vue-router/issues/1280 and
// https://stackoverflow.com/questions/62254666/use-vue-router-for-redirecting-to-absolute-path
const makeExternalRedirect = target => {
const externalRedirect = () => {
location.assign(target);
};
return externalRedirect;
};

const isPathPrefix = (prefix, fullPath) => {
const trimmedPrefix = prefix.replace(/\/+$/, '');
if (!fullPath.startsWith(trimmedPrefix)) {
return false;
}
if (fullPath.length === prefix.length || fullPath[trimmedPrefix.length] === '/') {
return true;
}
// As a special case, allow /path/to/resource to match /path/to/resource.html
return fullPath.slice(prefix.length).toLowerCase() === '.html';
};

export default ({ router }) => {
patchRoutesToPreserveFragments(router);

const redirects = [
{ path: '/wallet-api/', redirect: '/guides/wallet/' },
{ path: '/wallet-api.html', redirect: '/guides/wallet/' },
{ path: '/chainlink-integration/', redirect: '/guides/chainlink-integration/' },
{ path: '/chainlink-integration.html', redirect: '/guides/chainlink-integration/' },
{ path: '/distributed-programming/', redirect: '/guides/js-programming/' },
{ path: '/distributed-programming.html', redirect: '/guides/js-programming/' },
{ path: '/getting-started/agoric-cli-guide/', redirect: '/guides/agoric-cli/' },
{ path: '/getting-started/agoric-cli-guide.html', redirect: '/guides/agoric-cli/' },
{ path: '/guides/js-programming/ses/ses-guide.html', redirect: 'https://github.com/endojs/endo/blob/HEAD/packages/ses/docs/guide.html' },
{ path: '/guides/js-programming/ses/ses-reference.html', redirect: 'https://github.com/endojs/endo/blob/HEAD/packages/ses/docs/reference.html' },
{ path: '/guides/js-programming/ses/lockdown.html', redirect: 'https://github.com/endojs/endo/blob/HEAD/packages/ses/docs/lockdown.html' },
{ path: '/getting-started/before-using-agoric.html', redirect: '/guides/getting-started/' },
{ path: '/getting-started/start-a-project.html', redirect: '/guides/getting-started/start-a-project.html' },
{ path: '/guides/agoric-cli/commands.html', redirect: '/guides/agoric-cli/' },
{ path: '/dapps/', redirect: '/guides/dapps/' },
{ path: '/ertp/guide/', redirect: '/guides/ertp/' },
{ path: '/ertp/guide/amounts.html', redirect: '/guides/ertp/amounts.html' },
{ path: '/platform/', redirect: '/guides/platform/' },
{ path: '/zoe/guide/', redirect: '/guides/zoe/' },
{ path: '/getting-started/intro-zoe.html', redirect: '/guides/zoe/offer-enforcement.html' },
{ path: '/zoe/guide/offer-safety.html', redirect: '/guides/zoe/offer-safety.html' },
{ path: '/zoe/guide/contracts/', redirect: '/guides/zoe/contracts/' },
{ path: '/zoe/guide/contracts/oracle.html', redirect: '/guides/zoe/contracts/oracle.html' },
{ path: '/ertp/api/', redirect: '/reference/ertp-api/' },
{ path: '/ertp/api/issuer.html', redirect: '/reference/ertp-api/issuer.html' },
{ path: '/repl/', redirect: '/reference/repl/' },
{ path: '/repl/timerServices.html', redirect: '/reference/repl/timerServices.html' },
{ path: '/guides/wallet/api.html', redirect: '/reference/wallet-api.html' },
{ path: '/zoe/api/', redirect: '/reference/zoe-api/' },
{ path: '/zoe/api/zoe.html', redirect: '/reference/zoe-api/zoe.html' },
{ path: '/getting-started/beta.html', redirect: '/guides/getting-started/' },
];
redirects.forEach(config => router.addRoute(config));
}
{ path: '/chainlink-integration', redirect: '/guides/chainlink-integration/' },
{ path: '/dapps', redirect: '/guides/dapps/' },
{ path: '/distributed-programming', redirect: '/guides/js-programming/' },
{ path: '/ertp/api', redirect: '/reference/ertp-api/' },
{ path: '/ertp/guide', redirect: '/guides/ertp/' },
{ path: '/getting-started/agoric-cli-guide', redirect: '/guides/agoric-cli/' },
{ path: '/getting-started/before-using-agoric', redirect: '/guides/getting-started/' },
{ path: '/getting-started/beta', redirect: '/guides/getting-started/' },
{ path: '/getting-started/intro-zoe', redirect: '/guides/zoe/offer-enforcement/' },
{ path: '/getting-started/start-a-project', redirect: '/guides/getting-started/start-a-project/' },
{ path: '/guides/agoric-cli/commands', redirect: '/guides/agoric-cli/' },
{ path: '/guides/js-programming/ses/lockdown', redirect: makeExternalRedirect('https://github.com/endojs/endo/blob/master/packages/ses/docs/lockdown.md') },
{ path: '/guides/js-programming/ses/ses-guide', redirect: makeExternalRedirect('https://github.com/endojs/endo/blob/master/packages/ses/docs/guide.md') },
{ path: '/guides/js-programming/ses/ses-reference', redirect: makeExternalRedirect('https://github.com/endojs/endo/blob/master/packages/ses/docs/reference.md') },
{ path: '/guides/wallet/api', redirect: '/reference/wallet-api/' },
{ path: '/platform', redirect: '/guides/platform/' },
{ path: '/repl', redirect: '/reference/repl/' },
{ path: '/wallet-api', redirect: '/guides/wallet/' },
{ path: '/zoe/api', redirect: '/reference/zoe-api/' },
{ path: '/zoe/guide', redirect: '/guides/zoe/' },
].map(redirect => ({ ...redirect, path: redirect.path.replace(/\.html$/i, '') }));

// Define exact-match redirect routes.
redirects.forEach(redirect => {
router.addRoute(redirect);
});

// Also redirect subpaths.
router.beforeEach((to, from, next) => {
const done = (...args) => { next(...args); };
const target = to.path;
const prefixRedirects = redirects.filter(redirect => isPathPrefix(redirect.path, target));
if (prefixRedirects.length === 0) {
// There is no covering redirect.
return done();
} else if (prefixRedirects.some(redirect => redirect.path === target)) {
// There is an exact-match covering redirect.
return done();
}
// Apply the longest-path covering redirect.
prefixRedirects.sort((a, b) => b.path.length - a.path.length);
const match = prefixRedirects[0];
if (!target.startsWith(match.path)) {
console.error('unexpected covering redirect', { to, redirect });
return done();
}
if (typeof match.redirect === 'function') {
return done(match.redirect(to));
}
const trimmedPrefix = match.path.replace(/\/+$/, '');
const trimmedReplacementPrefix = match.redirect.replace(/\/+$/, '');
const targetSuffix = target.slice(trimmedPrefix.length).replace(/\.html$/i, '/');
const newPath = trimmedReplacementPrefix + targetSuffix;
return done({ ...to, path: newPath });
});
}
4 changes: 4 additions & 0 deletions main/.vuepress/styles/index.styl
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@
}
}

:root.scrollingToTarget {
scroll-padding-top: $navbarHeight;
}

.ag-btn
background-color $accentColor
color $white
Expand Down
Loading

0 comments on commit 5e2d286

Please sign in to comment.