Skip to content

Commit

Permalink
fix: Add RequestIdleCallback polyfill (#231)
Browse files Browse the repository at this point in the history
  • Loading branch information
tlgimenes authored May 15, 2023
1 parent ab381c0 commit 270e297
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 90 deletions.
181 changes: 91 additions & 90 deletions components/LiveControls.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Head } from "$fresh/runtime.ts";
import { DomInspectorActivators, inspectVSCode } from "../deps.ts";
import type { Site } from "$live/types.ts";
import { context } from "$live/live.ts";
import type { Site } from "$live/types.ts";

const IS_LOCALHOST = context.deploymentId === undefined;

Expand Down Expand Up @@ -35,7 +35,6 @@ type LiveEvent = {
// Only add dom inspector if running in localhost, i.e. deploymentId === undefined
const domInspectorModule = IS_LOCALHOST
? `
window.ACTIVATE_INSPECTOR = true;
const DomInspectorActivators = {
CmdE: {
label: "Cmd+E or Ctrl+E",
Expand All @@ -51,109 +50,112 @@ const DomInspectorActivators = {
${inspectVSCode.DomInspector.toString()}`
: "";

const main = () => {
// deno-lint-ignore no-explicit-any
const isLiveEvent = (data: any): data is LiveEvent =>
["scrollToComponent", "DOMInspector"].includes(data?.type);

const onKeydown = (event: KeyboardEvent) => {
// in case loaded in iframe, avoid redirecting to editor while in editor
if (window !== window.parent) {
return;
}

// Disable going to admin while input it being typed
if (event.target !== document.body) {
return;
}

if (event.defaultPrevented) {
return;
}

if (
(event.ctrlKey && event.shiftKey && event.key === "E") ||
event.key === "."
) {
event.preventDefault();
event.stopPropagation();

const href = new URL(
`/admin/${window.LIVE.site.id}/pages/${window.LIVE.page.id}`,
"https://deco.cx",
);

href.searchParams.set(
"pagePath",
encodeURIComponent(
`${window.location.pathname}${window.location.search}`,
),
);

window.location.href = `${href}`;
}
};
const main = () =>
requestIdleCallback(() => {
// deno-lint-ignore no-explicit-any
const isLiveEvent = (data: any): data is LiveEvent =>
["scrollToComponent", "DOMInspector"].includes(data?.type);

const onMessage = (event: MessageEvent<LiveEvent>) => {
const { data } = event;
const onKeydown = (event: KeyboardEvent) => {
// in case loaded in iframe, avoid redirecting to editor while in editor
if (window !== window.parent) {
return;
}

if (!isLiveEvent(data)) {
return;
}
// Disable going to admin while input it being typed
if (event.target !== document.body) {
return;
}

switch (data.type) {
case "scrollToComponent": {
const findById = document
.getElementById(data.args.id);
if (event.defaultPrevented) {
return;
}

const findByAlternateId = data.args.alternateId
? document
.getElementById(data.args.alternateId)
: undefined;
if (
(event.ctrlKey && event.shiftKey && event.key === "E") ||
event.key === "."
) {
event.preventDefault();
event.stopPropagation();

const href = new URL(
`/admin/${window.LIVE.site.id}/pages/${window.LIVE.page.id}`,
"https://deco.cx",
);

href.searchParams.set(
"pagePath",
encodeURIComponent(
`${window.location.pathname}${window.location.search}`,
),
);

window.location.href = `${href}`;
}
};

(findById ?? findByAlternateId)?.scrollIntoView({ behavior: "smooth" });
const onMessage = (event: MessageEvent<LiveEvent>) => {
const { data } = event;

if (!isLiveEvent(data)) {
return;
}
case "DOMInspector": {
const action = data.args;

if (action === "activate" && !inspector.isActive()) {
inspector.activate();
} else if (action === "deactivate" && inspector.isActive()) {
inspector.deactivate();
switch (data.type) {
case "scrollToComponent": {
const findById = document
.getElementById(data.args.id);

const findByAlternateId = data.args.alternateId
? document
.getElementById(data.args.alternateId)
: undefined;

(findById ?? findByAlternateId)?.scrollIntoView({
behavior: "smooth",
});

return;
}
case "DOMInspector": {
const action = data.args;

return;
if (action === "activate" && !inspector.isActive()) {
inspector.activate();
} else if (action === "deactivate" && inspector.isActive()) {
inspector.deactivate();
}

return;
}
}
}
};
};

//@ts-ignore: "window.ACTIVATE_INSPECTOR not available"
const inspector = window.ACTIVATE_INSPECTOR &&
//@ts-ignore: "DomInspector not available"
new DomInspector(document.body, {
outline: "1px dashed #2fd080",
backgroundColor: "rgba(47, 208, 128, 0.33)",
backgroundBlendMode: "multiply",
activator: DomInspectorActivators.Backquote,
path: "/live/inspect",
});

/** Setup global variables */
window.LIVE = {
...window.LIVE,
...JSON.parse(document.getElementById("__DECO_STATE")!.innerText),
};
const inspector = typeof DomInspector !== "undefined" &&
//@ts-ignore: "DomInspector not available"
new DomInspector(document.body, {
outline: "1px dashed #2fd080",
backgroundColor: "rgba(47, 208, 128, 0.33)",
backgroundBlendMode: "multiply",
activator: DomInspectorActivators.Backquote,
path: "/live/inspect",
});

/** Setup global variables */
window.LIVE = {
...window.LIVE,
...JSON.parse(document.getElementById("__DECO_STATE")!.innerText),
};

/** Setup listeners */
/** Setup listeners */

// navigate to admin when user clicks ctrl+shift+e
document.body.addEventListener("keydown", onKeydown);
// navigate to admin when user clicks ctrl+shift+e
document.body.addEventListener("keydown", onKeydown);

// focus element when inside admin
addEventListener("message", onMessage);
};
// focus element when inside admin
addEventListener("message", onMessage);
});

function LiveControls({ site, page }: Props) {
const partialPage = page && {
Expand All @@ -172,8 +174,7 @@ function LiveControls({ site, page }: Props) {
<script
type="module"
dangerouslySetInnerHTML={{
__html:
`${domInspectorModule}\nrequestIdleCallback(${main.toString()})`,
__html: `${domInspectorModule}\n${main.toString()}`,
}}
/>
</Head>
Expand Down
18 changes: 18 additions & 0 deletions components/LivePolyfills.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Head } from "$fresh/runtime.ts";

// Polyfills required for our inline scripts to work on our targeted browsers
const snippet = () => {
// Required for Safari
window.requestIdleCallback = window.requestIdleCallback ||
((callback: IdleRequestCallback) => setTimeout(callback, 0));
};

function LivePolyfills() {
return (
<Head>
<script dangerouslySetInnerHTML={{ __html: `(${snippet})()` }} />
</Head>
);
}

export default LivePolyfills;
47 changes: 47 additions & 0 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pages/LivePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Head } from "$fresh/runtime.ts";
import { isSection, Section } from "$live/blocks/section.ts";
import LiveAnalytics from "$live/components/LiveAnalytics.tsx";
import LiveControls from "$live/components/LiveControls.tsx";
import LivePolyfills from "$live/components/LivePolyfills.tsx";
import LivePageEditor, {
BlockControls,
} from "$live/components/LivePageEditor.tsx";
Expand Down Expand Up @@ -167,6 +168,7 @@ export default function LivePage(

return (
<>
<LivePolyfills />
<LiveControls
site={{ id: context.siteId, name: context.site }}
page={{
Expand Down
2 changes: 2 additions & 0 deletions routes/live/previews/[...block].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { HandlerContext, PageProps } from "$fresh/server.ts";
import { Page } from "$live/blocks/page.ts";
import LiveAnalytics from "$live/components/LiveAnalytics.tsx";
import LiveControls from "$live/components/LiveControls.tsx";
import LivePolyfills from "$live/components/LivePolyfills.tsx";
import { context } from "$live/live.ts";
import Render from "$live/routes/[...catchall].tsx";
import { LiveConfig, LiveState } from "$live/types.ts";
Expand Down Expand Up @@ -30,6 +31,7 @@ export default function Preview(props: PageProps<Page>) {
};
return (
<>
<LivePolyfills />
<LiveControls
site={{ id: context.siteId, name: context.site }}
page={{
Expand Down

0 comments on commit 270e297

Please sign in to comment.