strict typechecking
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
2d40d7f9a0
commit
3f9a2f0603
16 changed files with 52 additions and 68 deletions
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
export let onClose: () => void;
|
||||
|
||||
function click(event: Event) {
|
||||
function click(this: Element, event: Event) {
|
||||
if (event.target !== this) return;
|
||||
onClose();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<script lang="ts">
|
||||
import type { Readable } from "svelte/store";
|
||||
import { yDocToProsemirrorJSON } from "y-prosemirror";
|
||||
import { Node } from "prosemirror-model";
|
||||
import type { Doc } from "yjs";
|
||||
|
@ -29,7 +28,7 @@
|
|||
}
|
||||
});
|
||||
docs.push({
|
||||
title: titleNode?.textContent,
|
||||
title: titleNode ? (titleNode as Node).textContent : undefined,
|
||||
id: name.replace(/^page\//, ""),
|
||||
name,
|
||||
});
|
||||
|
@ -45,7 +44,7 @@
|
|||
$: entries = deriveEntries(ydoc);
|
||||
$: lastU = lastUpdated(ydoc);
|
||||
$: sortedEntries = $entries
|
||||
.sort((a, b) => +$lastU.get(b.name) - +$lastU.get(a.name))
|
||||
.sort((a, b) => +($lastU.get(b.name) || 0) - +($lastU.get(a.name) || 0))
|
||||
// TODO: FTS
|
||||
.filter((x) => (x.title ?? x.id).includes(filter));
|
||||
// $: console.debug($lastU);
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
getFirstMarkInSelection,
|
||||
} from "./ps-utils";
|
||||
import SimpleMarkItem from "./bubblemenu/SimpleMarkItem.svelte";
|
||||
import { nanoid } from "nanoid";
|
||||
import Button from "./bubblemenu/Button.svelte";
|
||||
import Modal from "../components/Modal.svelte";
|
||||
import PagePicker from "../components/PagePicker.svelte";
|
||||
|
@ -105,7 +104,7 @@
|
|||
/* https://wicg.github.io/visual-viewport/examples/fixed-to-keyboard.html */
|
||||
let barStyle = "";
|
||||
function updateBar() {
|
||||
const viewport = window.visualViewport;
|
||||
const viewport = window.visualViewport!;
|
||||
// Since the bar is position: fixed we need to offset it by the
|
||||
// visual viewport's offset from the layout viewport origin.
|
||||
const offsetY = window.innerHeight - viewport.height - viewport.offsetTop;
|
||||
|
@ -118,12 +117,12 @@ transform: scale(${1 / viewport.scale});
|
|||
}
|
||||
|
||||
onMount(() => {
|
||||
window.visualViewport.addEventListener("resize", updateBar);
|
||||
window.visualViewport.addEventListener("scroll", updateBar);
|
||||
window.visualViewport!.addEventListener("resize", updateBar);
|
||||
window.visualViewport!.addEventListener("scroll", updateBar);
|
||||
});
|
||||
onDestroy(() => {
|
||||
window.visualViewport.removeEventListener("resize", updateBar);
|
||||
window.visualViewport.removeEventListener("scroll", updateBar);
|
||||
window.visualViewport!.removeEventListener("resize", updateBar);
|
||||
window.visualViewport!.removeEventListener("scroll", updateBar);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
import { dropCursor } from "prosemirror-dropcursor";
|
||||
import { gapCursor } from "prosemirror-gapcursor";
|
||||
import type { XmlFragment } from "yjs";
|
||||
import { ySyncPlugin, yCursorPlugin, yUndoPlugin } from "y-prosemirror";
|
||||
import { ySyncPlugin, yUndoPlugin } from "y-prosemirror";
|
||||
|
||||
import "./editor.css";
|
||||
|
||||
import { schema } from "./schema";
|
||||
import BubbleMenu from "./BubbleMenu.svelte";
|
||||
import MenuBar from "./MenuBar.svelte";
|
||||
import { placeholderPlugin } from "./upload";
|
||||
// import { placeholderPlugin } from "./upload";
|
||||
import { baseKeymap } from "./keymap";
|
||||
import type { WorldY } from "../lib/doc";
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
|||
schema,
|
||||
plugins: [
|
||||
new Plugin({
|
||||
view: (editorView) => {
|
||||
view: () => {
|
||||
// editorView.dom.parentElement?.replaceWith(editorView.dom);
|
||||
return {
|
||||
update(view, lastState) {
|
||||
|
@ -50,7 +50,7 @@
|
|||
// yCursorPlugin(doc.webrtcProvider.awareness),
|
||||
yUndoPlugin(),
|
||||
keymap(baseKeymap),
|
||||
placeholderPlugin,
|
||||
// placeholderPlugin,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
$: isActive = nodeIsActiveFn(type, null, true);
|
||||
$: command = wrapIn(type);
|
||||
$: isPossible = command(state, null);
|
||||
$: isPossible = command(state);
|
||||
$: actionListener = commandListener(view, command);
|
||||
</script>
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
const paragraphType = state.schema.nodes.paragraph;
|
||||
const headingType = state.schema.nodes.heading;
|
||||
|
||||
$: isPossible = setBlockType(headingType, { level: 1 })(state, null);
|
||||
$: isPossible = setBlockType(headingType, { level: 1 })(state);
|
||||
$: currentValue =
|
||||
state.selection.to <= state.selection.$from.end() &&
|
||||
(state.selection.$from.parent.type == headingType
|
||||
|
@ -19,10 +19,12 @@
|
|||
? "paragraph"
|
||||
: null);
|
||||
|
||||
const onChange = (event) => {
|
||||
const onChange = (
|
||||
event: Event & { currentTarget: EventTarget & HTMLSelectElement }
|
||||
) => {
|
||||
event.preventDefault();
|
||||
|
||||
const [type, param] = event.target.value.split(":");
|
||||
const [type, param] = event.currentTarget.value.split(":");
|
||||
if (type === "paragraph") {
|
||||
setBlockType(paragraphType, {
|
||||
align: state.selection.$from.parent.attrs.align,
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
? state.schema.nodes.bullet_list
|
||||
: kind === ListKind.Ordered
|
||||
? state.schema.nodes.ordered_list
|
||||
: null;
|
||||
: (null as never);
|
||||
const listItemType = state.schema.nodes.list_item;
|
||||
$: iconComponent =
|
||||
kind === ListKind.Unordered
|
||||
|
@ -32,7 +32,7 @@
|
|||
|
||||
$: isActive = nodeIsActiveFn(type, null, true);
|
||||
$: command = chainCommands(liftListItem(listItemType), wrapInList(type));
|
||||
$: isPossible = command(state, null);
|
||||
$: isPossible = command(state);
|
||||
$: actionListener = commandListener(view, command);
|
||||
</script>
|
||||
|
||||
|
|
|
@ -6,11 +6,9 @@ import type {
|
|||
ResolvedPos,
|
||||
Node as ProsemirrorNode,
|
||||
} from "prosemirror-model";
|
||||
import type { EditorState, Selection } from "prosemirror-state";
|
||||
import type { EditorState } from "prosemirror-state";
|
||||
import type { EditorView } from "prosemirror-view";
|
||||
|
||||
import type { Align } from "./schema";
|
||||
|
||||
export type Command = (
|
||||
state: EditorState,
|
||||
dispatch?: EditorView["dispatch"]
|
||||
|
@ -176,7 +174,7 @@ export function getAttrFn(attrKey: string): (state: EditorState) => any {
|
|||
return (state) => {
|
||||
let { from, to } = state.selection;
|
||||
let value: any = undefined;
|
||||
state.doc.nodesBetween(from, to, (node, pos) => {
|
||||
state.doc.nodesBetween(from, to, (node) => {
|
||||
if (value !== undefined) return false;
|
||||
if (!node.isTextblock) return;
|
||||
if (attrKey in node.attrs) value = node.attrs[attrKey];
|
||||
|
@ -199,10 +197,10 @@ export interface MarkMatch {
|
|||
export function getFirstMarkInSelection(
|
||||
state: EditorState,
|
||||
type: MarkType
|
||||
): MarkMatch {
|
||||
): MarkMatch | null {
|
||||
const { to, from } = state.selection;
|
||||
|
||||
let match: MarkMatch;
|
||||
let match: MarkMatch | null = null;
|
||||
state.selection.$from.doc.nodesBetween(from, to, (node, position) => {
|
||||
if (!match) {
|
||||
const mark = type.isInSet(node.marks);
|
||||
|
@ -213,25 +211,3 @@ export function getFirstMarkInSelection(
|
|||
|
||||
return match;
|
||||
}
|
||||
|
||||
export function setAlign(align: Align): Command {
|
||||
return (state, dispatch) => {
|
||||
let { from, to } = state.selection;
|
||||
let node: ProsemirrorNode | null = null;
|
||||
state.doc.nodesBetween(from, to, (_node, pos) => {
|
||||
if (node) return false;
|
||||
if (!_node.isTextblock) return;
|
||||
if (
|
||||
_node.type == state.schema.nodes.paragraph ||
|
||||
_node.type == state.schema.nodes.heading
|
||||
) {
|
||||
node = _node;
|
||||
}
|
||||
});
|
||||
if (!node) return false;
|
||||
if (dispatch)
|
||||
return setBlockType(node.type, { ...node.attrs, align })(state, dispatch);
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -101,8 +101,9 @@ export const schema = new Schema({
|
|||
tag: "ol",
|
||||
getAttrs(dom) {
|
||||
dom = dom as HTMLElement;
|
||||
const start = dom.getAttribute("start");
|
||||
return {
|
||||
order: dom.hasAttribute("start") ? +dom.getAttribute("start") : 1,
|
||||
order: start ? +start : 1,
|
||||
};
|
||||
},
|
||||
},
|
||||
|
@ -141,11 +142,12 @@ export const schema = new Schema({
|
|||
{
|
||||
tag: "figure",
|
||||
getAttrs(dom) {
|
||||
const child: HTMLElement =
|
||||
const child: HTMLElement | null =
|
||||
(dom as Element).querySelector("img") ||
|
||||
(dom as Element).querySelector("video") ||
|
||||
(dom as Element).querySelector("audio") ||
|
||||
(dom as Element).querySelector("iframe");
|
||||
if (!child) return false;
|
||||
|
||||
if (child instanceof HTMLImageElement) {
|
||||
return { src: child.src, kind: "img" };
|
||||
|
@ -156,6 +158,7 @@ export const schema = new Schema({
|
|||
} else if (child instanceof HTMLIFrameElement) {
|
||||
return { src: child.src, kind: "iframe" };
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -308,9 +311,11 @@ export const schema = new Schema({
|
|||
getAttrs(dom) {
|
||||
dom = dom as HTMLElement;
|
||||
const href = dom.getAttribute("href");
|
||||
if (href.startsWith("/w/")) {
|
||||
if (href?.startsWith("/w/")) {
|
||||
const matches = parse(routes.Page).pattern.exec(href);
|
||||
if (!matches) return false;
|
||||
return {
|
||||
id: parse(routes.Page).pattern.exec(href)[1],
|
||||
id: matches[1],
|
||||
};
|
||||
} else return false;
|
||||
},
|
||||
|
|
|
@ -42,7 +42,7 @@ export const placeholderPlugin = new Plugin({
|
|||
});
|
||||
|
||||
export function findPlaceholder(state: EditorState, id: any): number | null {
|
||||
const decos: DecorationSet = placeholderPlugin.getState(state);
|
||||
const found = decos.find(undefined, undefined, (spec) => spec.id == id);
|
||||
return found.length ? found[0].from : null;
|
||||
const decos = placeholderPlugin.getState(state);
|
||||
const found = decos?.find(undefined, undefined, (spec) => spec.id == id);
|
||||
return found?.length ? found[0].from : null;
|
||||
}
|
|
@ -2,7 +2,12 @@ import type { Readable } from "svelte/store";
|
|||
import type { Doc, Transaction } from "yjs";
|
||||
|
||||
export function makeYdocStore<T>(
|
||||
handler: (update: Uint8Array, origin: any, ydoc: Doc, tr: Transaction) => T,
|
||||
handler: (
|
||||
update: Uint8Array | null,
|
||||
origin: any,
|
||||
ydoc: Doc,
|
||||
tr: Transaction | null
|
||||
) => T,
|
||||
unhandler?: () => void
|
||||
) {
|
||||
return (ydoc: Doc): Readable<T> => {
|
||||
|
@ -10,10 +15,10 @@ export function makeYdocStore<T>(
|
|||
return {
|
||||
subscribe: (run) => {
|
||||
function updateHandler(
|
||||
update: Uint8Array,
|
||||
update: Uint8Array | null,
|
||||
origin: any,
|
||||
ydoc: Doc,
|
||||
tr: Transaction
|
||||
tr: Transaction | null
|
||||
) {
|
||||
run(handler(update, origin, ydoc, tr));
|
||||
}
|
||||
|
|
10
src/main.ts
10
src/main.ts
|
@ -1,8 +1,8 @@
|
|||
import './app.css'
|
||||
import App from './App.svelte'
|
||||
import "./app.css";
|
||||
import App from "./App.svelte";
|
||||
|
||||
const app = new App({
|
||||
target: document.getElementById('app'),
|
||||
})
|
||||
target: document.getElementById("app")!,
|
||||
});
|
||||
|
||||
export default app
|
||||
export default app;
|
||||
|
|
|
@ -4,11 +4,7 @@
|
|||
import { router } from "../lib/router";
|
||||
import { writeWorlds } from "../lib/worldStorage";
|
||||
|
||||
function crear(
|
||||
event: Event & { readonly submitter: HTMLElement } & {
|
||||
currentTarget: EventTarget & HTMLFormElement;
|
||||
}
|
||||
) {
|
||||
function crear(event: Event) {
|
||||
event.preventDefault();
|
||||
writeWorlds((worlds) => [...worlds, generateNewWorld()]);
|
||||
router.run(routes.ChooseWorld);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
async function joinWorldLink() {
|
||||
const worlds = await loadWorlds();
|
||||
const worldIdentifier = worlds.find((w) => w.room === worldId);
|
||||
if (!worldIdentifier) throw new Error("No tenés ese mundo para compartir.");
|
||||
return `${location.origin}${inject(routes.JoinWorld, {
|
||||
worldId: worldIdentifier.room,
|
||||
})}#${worldIdentifier.password}`;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
*/
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"strict": true,
|
||||
"isolatedModules": true
|
||||
},
|
||||
"include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
|
||||
|
|
Loading…
Reference in a new issue