Skip to content

Instantly share code, notes, and snippets.

@howyay
Forked from tobiaslins/worker.js
Last active April 6, 2020 15:16
Show Gist options
  • Save howyay/efda51d561fc57e395bd28539182dad1 to your computer and use it in GitHub Desktop.
Save howyay/efda51d561fc57e395bd28539182dad1 to your computer and use it in GitHub Desktop.
Notion.so Custom Domain + Inline LaTeX Rendering
const MY_DOMAIN = "YOUR_DOMAIN"
const START_PAGE = "URL_TO_NOTION_LANDING_PAGE"
addEventListener('fetch', event => {
event.respondWith(fetchAndApply(event.request))
})
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, HEAD, POST,PUT, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
}
function handleOptions(request) {
if (request.headers.get("Origin") !== null &&
request.headers.get("Access-Control-Request-Method") !== null &&
request.headers.get("Access-Control-Request-Headers") !== null) {
// Handle CORS pre-flight request.
return new Response(null, {
headers: corsHeaders
})
} else {
// Handle standard OPTIONS request.
return new Response(null, {
headers: {
"Allow": "GET, HEAD, POST, PUT, OPTIONS",
}
})
}
}
async function fetchAndApply(request) {
if (request.method === "OPTIONS") {
return handleOptions(request)
}
let url = new URL(request.url)
let response
if (url.pathname.startsWith("/app") && url.pathname.endsWith("js")) {
// skip validation in app.js
response = await fetch(`https://www.notion.so${url.pathname}`)
let body = await response.text()
try {
response = new Response(body.replace(/www.notion.so/g, MY_DOMAIN).replace(/notion.so/g, MY_DOMAIN), response)
response.headers.set('Content-Type', "application/x-javascript")
console.log("get rewrite app.js")
} catch (err) {
console.log(err)
}
} else if ((url.pathname.startsWith("/api"))) {
// Forward API
response = await fetch(`https://www.notion.so${url.pathname}`, {
body: request.body, // must match 'Content-Type' header
headers: {
'content-type': 'application/json;charset=UTF-8',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
},
method: "POST", // *GET, POST, PUT, DELETE, etc.
})
response = new Response(response.body, response)
response.headers.set('Access-Control-Allow-Origin', "*")
} else if (url.pathname === `/`) {
// 301 redrict
let pageUrlList = START_PAGE.split("/")
let redrictUrl = `https://${MY_DOMAIN}/${pageUrlList[pageUrlList.length - 1]}`
return Response.redirect(redrictUrl, 301)
} else {
response = await fetch(`https://www.notion.so${url.pathname}`, {
body: request.body, // must match 'Content-Type' header
headers: request.headers,
method: request.method, // *GET, POST, PUT, DELETE, etc.
})
response = new Response(response.body, response)
}
response.headers.delete("Content-Security-Policy")
return new HTMLRewriter().on('body', new ElementHandler()).transform(response)
return response
}
class ElementHandler {
element(element) {
element.append(`
<script src=https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js></script>
<script src=https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js></script>
<script type="text/javascript">
// right-padding for inline math mode
var style = document.createElement('style');
style.innerHTML = '.katex{padding-right:0!important;}';
document.head.appendChild(style);
// declare/init vars
let timer; // timer identifier
let startUpWaitTime = 3000; // ms after startup (adjust as needed)
let pageChangeWaitTime = 1500; // ms after page changed (adjust as needed)
let backupRender;
let backupRenderWaitTime = 6000;
// render inline LaTeX
function renderInlineLaTeX() {
renderMathInElement(document.body, {
delimiters: [
// LaTeX delimiters (uncomment/add as needed)
{ left: "$$", right: "$$", display: true },
// { left: "\\[", right: "\\]", display: true },
// { left: "\\(", right: "\\)", display: false },
{ left: "$", right: "$", display: false }
]
});
console.log("Inline LaTeX is rendered.");
}
let url = window.location.href;
['click','popstate'].forEach( evt =>
window.addEventListener(evt, function () {
requestAnimationFrame(()=>{
if (url !== location.href) {
renderOnPageChange();
}
url = location.href;
});
}, true)
);
function renderOnLoad() {
console.log("Rendering inline LaTeX on startup...");
clearTimeout(timer);
timer = setTimeout(renderInlineLaTeX, startUpWaitTime);
backupRendering();
}
function renderOnPageChange() {
console.log("Rendering inline LaTeX on navigation...");
clearTimeout(timer);
timer = setTimeout(renderInlineLaTeX, pageChangeWaitTime);
backupRendering();
}
function backupRendering() {
clearTimeout(backupRender);
backupRender = setTimeout(function() {
console.log("Rerendering just in case...");
renderInlineLaTeX();
}, backupRenderWaitTime);
}
// on startup...
window.addEventListener("DOMContentLoaded", renderOnLoad);
</script>
`, {
html: true
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment