Skip to content

Commit

Permalink
Final changes
Browse files Browse the repository at this point in the history
  • Loading branch information
captainbrosset committed Mar 18, 2024
1 parent 5c2d271 commit c0818e3
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 51 deletions.
44 changes: 22 additions & 22 deletions edit-context/html-editor/converter.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,3 @@
// The EditContext object only knows about character offsets. But out editor
// view renders HTML tokens as DOM nodes. This function finds DOM node tokens
// that are in the provided EditContext offset range.
export function fromOffsetsToRenderedTokenNodes(renderedTokens, start, end) {
const tokenNodes = [];

for (let offset = start; offset < end; offset++) {
const token = renderedTokens.find(
(token) => token.pos <= offset && token.pos + token.value.length > offset
);
if (token) {
tokenNodes.push({
node: token.node,
nodeOffset: token.pos,
charOffset: offset,
});
}
}

return tokenNodes;
}

// The EditContext object only knows about a plain text string and about
// character offsets. However, our editor view renders the text by using
// DOM nodes. So we sometimes need to convert between the two.
Expand Down Expand Up @@ -94,3 +72,25 @@ export function fromOffsetsToSelection(start, end, editorEl) {

return { anchorNode, anchorOffset, extentNode, extentOffset };
}

// The EditContext object only knows about character offsets. But out editor
// view renders HTML tokens as DOM nodes. This function finds DOM node tokens
// that are in the provided EditContext offset range.
export function fromOffsetsToRenderedTokenNodes(renderedTokens, start, end) {
const tokenNodes = [];

for (let offset = start; offset < end; offset++) {
const token = renderedTokens.find(
(token) => token.pos <= offset && token.pos + token.value.length > offset
);
if (token) {
tokenNodes.push({
node: token.node,
nodeOffset: token.pos,
charOffset: offset,
});
}
}

return tokenNodes;
}
49 changes: 30 additions & 19 deletions edit-context/html-editor/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,16 @@ if (IS_CUSTOM_HIGHLIGHT_SUPPORTED) {
// Tokenize the text.
currentTokens = tokenizeHTML(text);

// Render each token.
// Render each token as a DOM node.
for (const token of currentTokens) {
const span = document.createElement("span");
span.classList.add(`token-${token.type}`);
span.textContent = token.value;
span.dataset.tokenPos = token.pos;
editorEl.appendChild(span);

// Store the node in the token so we can find it later.
// Store the new DOM node as a property of the token
// in the currentTokens array. We will need it again
// later in fromOffsetsToRenderedTokenNodes.
token.node = span;
}

Expand Down Expand Up @@ -146,25 +147,35 @@ if (IS_CUSTOM_HIGHLIGHT_SUPPORTED) {
const formats = e.getTextFormats();

for (const format of formats) {
const { rangeStart, rangeEnd, underlineStyle, underlineThickness } =
format;

// Find the nodes in the view that are in the range.
const { anchorNode, anchorOffset, extentNode, extentOffset } =
fromOffsetsToSelection(rangeStart, rangeEnd, editorEl);
const highlight =
imeHighlights[
`${format.underlineStyle.toLowerCase()}-${format.underlineThickness.toLowerCase()}`
];
if (highlight) {
const range = document.createRange();
range.setStart(anchorNode, anchorOffset);
range.setEnd(extentNode, extentOffset);
highlight.add(range);
}
// Find the DOM selection that corresponds to the format's range.
const selection = fromOffsetsToSelection(
format.rangeStart,
format.rangeEnd,
editorEl
);

// Highlight the selection with the right style and thickness.
addHighlight(selection, format.underlineStyle, format.underlineThickness);
}
});

function addHighlight(selection, underlineStyle, underlineThickness) {
// Get the right CSS custom Highlight object depending on the
// underline style and thickness.
const highlight =
imeHighlights[
`${underlineStyle.toLowerCase()}-${underlineThickness.toLowerCase()}`
];

if (highlight) {
// Add a range to the Highlight object.
const range = document.createRange();
range.setStart(selection.anchorNode, selection.anchorOffset);
range.setEnd(selection.extentNode, selection.extentOffset);
highlight.add(range);
}
}

// Handle key presses that are not already handled by the EditContext.
editorEl.addEventListener("keydown", (e) => {
const start = Math.min(
Expand Down
3 changes: 3 additions & 0 deletions edit-context/html-editor/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Edit Context API: HTML editor demo</title>

<!-- The demo CSS styles -->
<link rel="stylesheet" href="styles.css">
</head>

<body>
<!-- The editor element -->
<div id="html-editor" spellcheck="false"></div>

<!-- The demo JavaScript code -->
<script type="module" src="editor.js"></script>
</body>

Expand Down
10 changes: 0 additions & 10 deletions edit-context/html-editor/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ body {
box-shadow: 0 0 0 0.25rem red;
}

[data-token-pos] {
margin: 0;
transition: margin 0.2s;
}

.token-openTagStart,
.token-openTagEnd,
.token-closeTagStart,
Expand Down Expand Up @@ -129,8 +124,3 @@ body {
::highlight(ime-squiggle-thick) {
text-decoration: underline wavy 2px;
}

.controls label {
display: flex;
align-items: center;
}

0 comments on commit c0818e3

Please sign in to comment.