- [~] Remove/segment tiptap styles.
- i18n
- We often don't need to be checkingthe to type in commands.
- Cleanup fallbacks and nodetypes. Fallback => createAndFill if possible.
- Move pinToItemDistance to menu options?
- Fix link menu condition.
- Fix table should not be able to press enter.
- [>] List of valid commands.
- Comments
- [^] Modal mode.
- [^] Change selection => apply command => return selection. For vim like selections.
- Up arrow at last node that doesn't support gap cursor adds a new paragraph.
- Allow configuring popup options in mark menus.
- Prevent link menu from being opened when it wasn't a user focus event (manually through some meta on the tr).
- Normalize renderHTML with nodes to get same look.
- Shift select is broken around embeds and tables.
- Figure out way to disallow undoing of file loader nodes.
- [?] Enter at end of embed redirects to parent?
- Dragging across document embed boundaries.
- Injectable bubble menus?
- If in the embedded block of an embedded document, indent the embedded block in the parent.
- Async Oembed
- Rewrite the table node.
- Dragging multiple block selections into a table is completely fucked. Figure out a way to turn them into multiple lines/rows?
- Don't show the list expander when it's just a single very nested item.
- [?] Use/implement BlockSelection https://github.com/ccorcos/prosemirror-examples/blob/b961b7545c527655eb67717a181860beefd4dcf8/src/components/BlockSelectionPlugin.tsx
- At last line / at first line helpers.
- Link Menu tests.
- Redirected commands tests.
- Complex parsing tests.
- Enter key tests.
-
Backspace in blockquotes is not working.
-
Internal links are not working.
-
[~~] Add block button on hover over the end of the editor.
- Ensured last is paragraph instead.
-
Enter in table should start new paragraph block. ...sortof
-
Check all keys have state plugin if needed.
-
Convert options to interfaces.
-
Avoid interface merging of unused if possible.
-
Highlight parsing tests.
-
Images/Videos/Attachments
- Custom image node. Tiptap one adds margins.
- Image Preview Node
- Drop
-
Command menu.
-
Highlights
-
Table commands bubble menu.
-
Command bar styles.
-
[~~] Check if we can replace on* in components by computed refs depending on props.editor.state
- Nope, causes weird issues with mark menu at least.
-
Fix gap cursor.
-
Gap cursor on the list works properly but looks wrong (is at the top of the list???).
-
Include/create gap cursor styles.
-
Fix usage of dispatch.
-
Replace ChainedCommands with SingleCommands.
-
Weird bug where both command bar menus show (embed and editor)
-
update unfocused selection css docs
-
Swap any mousedowns for pointerdowns.
-
Down/up arrows in embeds. Already works.
-
Content Embed
- iFrame/YouTube
- Per provider params?
- iFrame/YouTube
-
Fix html attributes handling.
-
Handle enter at the end of special blocks. Prevent at command level if editor is embedded.
- Partial Embeds shouldn't allow enter at all.
- Other should start new block.
-
Change parsehtml to return false if rule shoundn't match.
-
Tests for file loader.
- Auto delete last.
- Auto delete nested.
- Auto delete sibling but not wrapping list.
-
Editor block embed?
- Block/link picker.
- Check undo state isn't getting accidentally shared.
- Undo
- Block/link picker.
-
Keyboard shortcuts not working in embedded editor.
-
Properly override some commands.
-
See what selectingIndicator did.
-
Change commands to take a position or selection if possible.
-
Fix items with tables not being able to get their state types changed.
-
Language suggestions causing overflow :(
-
Set selection to embed range when selecting block.
-
Prevent dragging across document boundaries.
-
Document drag scroll.
-
Add configuration for scroll margins and styling.
-
[~~] Refactor dropindicator to be relative to editor.
- Did not work well. Absolutely posiitoned element does not get overflow hidden?
-
uuid validation on load
-
Prevent duplicate block ids.
-
Add doc loading state.
-
Fix contentless drags.
-
Prevent recursive embedding of the same document.
-
Rework shift option for nodesBetween.Reworked dependant commands instead. -
Double check root extension state can be shared.Added instancePerEditor option. -
It thinks there's no history. Again
-
link menu and related trs add to history false
-
Deduping of parent plugins
-
Regular hard break with shift + enter not working.
-
Implemented indent/unindent in code block.
- This is not meant to be used with tab set to indenting item blocks.
-
Links
- External
- Possible to have an allowed protocols list?
- This can just be implemented in the openInternal function.
- Possible to have an allowed protocols list?
- Internal
- Autocomplete
- External
-
Setting code block twice unindents block!
-
Hitting enter on a list item is unindenting it if it's blank. Write own splitlistItem command.
-
Tab indents a list item.
-
[~~] Override splitListItem to make it usable.
- Using custom instead.
-
Remove selectionAdjust selection after dropping a single item, when the selection goes outside the item. -
Move item up/down.
- Make children move with it.
- Expand selection when start.depth is deeper than end.depth, otherwise it get's very complicated.
-
Backspace is doing weird things.
-
Hard break code block.
-
Split code block.
-
Triple escape code block + list split.
-
Recheck block types
--- Scratchpad ---
export const focusCodeBlockLanguage = ( codeBlockType: string, langPickerClass: string = "lang-picker" ) => (dir: "up" | "down"): Command => ({ state, tr, view }) => { const { from, to, empty, $from } = state.selection.map(tr.doc, tr.mapping) if (!empty) { return false } const $node = tr.doc.resolve(from) debugNode($node.node()) const isCodeBlock = $node.node()?.type.name === codeBlockType console.log(dir) if (dir === "up" && isCodeBlock) { const firstLineIndex = $from.parent.textContent.indexOf("\n") const firstLine = firstLineIndex > 0 ? $from.parent.textContent.slice(0, firstLineIndex) : false as const const nodePos = from - $node.start() if (!firstLine || (nodePos >= 0 && nodePos <= firstLine.length)) { const domNode = view.domAtPos(from - 1).node focusInput(domNode, langPickerClass) } } else if (dir === "down" && !isCodeBlock) { const lastLineIndex = $from.parent.textContent.lastIndexOf("\n") const lastLine = lastLineIndex > 0 ? $from.parent.textContent.slice(lastLineIndex + 1) : false as const const nodePos = from - $node.start() if (!lastLine || (nodePos >= 0 && nodePos <= lastLine.length)) { console.log("at last") const endOfLinePlusOne = nodePos + (lastLine ? lastLine.length - nodePos + 1 : 1) const nextSel = TextSelection.findFrom(tr.doc.resolve(tr.doc.resolve(endOfLinePlusOne).pos), 1, true)
console.log(nextSel)
// const nextNode = tr.doc.nodesBetween(from, tr.doc.resolve(0).end(), (node,pos) => {
// if (node.type?.name === codeBlockType) {
// return true
// }
// })
// const domNode = view.domAtPos(from).node
// focusInput(domNode, langPickerClass)
}
}
return false
}
// [<iframe width="560" height="315" src="https://www.youtube.com/embed/0GoU-A996Bc?si=rXgwW-Xfb19ZMq2u" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>],
// [<iframe src="https://www.google.com/search?q=reddit+js+library+detecting+embed+urls&oq=reddit+js+library+detecting+embed+urls&gs_lcrp=EgZjaHJvbWUyBggAEEUYOdIBCDUzMTJqMGo3qAIAsAIA&sourceid=chrome&ie=UTF-8"></iframe>],
// [<iframe src="https://player.vimeo.com/video/215976284?h=66cf6fc4bb" width="640" height="360" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe>],
// ["https://player.vimeo.com/video/215976284?h=66cf6fc4bb"],
B 1
B 1
- Embedded
C 1
D 1
E 1D 2
D 3
import assert from "node:assert" import { chromium, devices } from "playwright";
(async () => { // Setup const browser = await chromium.launch({ headless: false, executablePath: process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH, }) const context = await browser.newContext(devices["iPhone 11"]) const page = await context.newPage()
// The actual interesting bit
await context.route("**.jpg", route => route.abort())
console.log(1)
await page.goto("https://example.com/")
console.log(2)
const pt = await page.title()
console.log("page title")
console.log(JSON.stringify(pt))
assert(pt === "Example Domain") // 👎 not a Web First assertion
const sleep = ms => new Promise(r => setTimeout(r, ms))
await sleep(5000)
// Teardown
await context.close()
await browser.close()
const $deepest = convertTo.resolve(Math.floor(convertTo.nodeSize / 2)) if (keepsContent && ($deepest.node().type.name === "text" || $deepest?.parent)) { const selPos = posByNode(editor.state.doc, { textContent: "ABC", type: $deepest.node().type.name === "text" ? $deepest.parent.type : $deepest.node().type, }) const closest = TextSelection.near(editor.state.doc.resolve(selPos), -1) console.log(closest.from, editor.state.selection.from, editor.state.doc.resolve(selPos).node().type.name) }
const commands: { key: keyof ChainedCommands, buttons: any[][] }[] = [ { key: "indentListItem" , buttons: [[]]}, { key: "unindentListItem" , buttons: [[]]}, { key: "toggleHeading", buttons: [1, 2, 3, 4, 5, 6, undefined].map(level => [{ level }]) }, { key: "toggleBold", buttons: [[]]}, { key: "toggleItalic", buttons: [[]]}, { key: "toggleCode", buttons: [[]]}, { key: "toggleCodeBlock", buttons: [[]]}, { key: "setCodeBlock", buttons: [ [{ language: "javascript" , loading: true }], [{ language: "css", loading: true }], ]}, { key: "focusCodeBlockLanguage", buttons: [[]]}, { key: "setHardBreak", buttons: [[]]}, { key: "undo", buttons: [[]]}, { key: "redo", buttons: [[]]}, { key: "moveListItem", buttons: [["down"], ["up"]]}, { key: "changeListItemType", buttons: [ [{ type: "none" }], [{ type: "stateful-task", state: "unchecked" }], [{ type: "stateful-task", state: "partial" }], [{ type: "stateful-task", state: "cancelled" }], [{ type: "stateful-task", state: "checked" }], [{ type: "ordered" }], // todo list all list-style-types [{ type: "unordered" }], [{ type: "ordered-upper-roman" }], [{ type: "ordered-lower-roman" }], // "unordered-square", ]}, ]