Skip to content

Commit

Permalink
fix: clone image on drag and simplify hr and img (#30)
Browse files Browse the repository at this point in the history
* fix: clone image on drag

* feat: image can now be direct descendant

* feat: hr can now be direct descendant as well

* docs: hr and img direct descendant
  • Loading branch information
peterpeterparker authored Feb 10, 2022
1 parent 7d6cbf3 commit 3e09fb2
Show file tree
Hide file tree
Showing 8 changed files with 20 additions and 42 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

- preserve styles when removing links (except Firefox)
- prevent text nodes - i.e. leaves - as direct children of the content editable when user is typing
- `<img/>` and `<hr/>` do not need to be wrapped in a parent `contenteditable=false` anymore

### Fix

- add link on Firefox
- clone image on drag

# 0.0.4-1 (2022-02-08)

Expand Down
7 changes: 7 additions & 0 deletions src/events/input.events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ export class InputEvents {
return;
}

const {data} = $event;

// User is not typing, for example an image is moved
if (data === null) {
return;
}

// User is typing text at the root of the container therefore the browser will create a text node a direct descendant of the contenteditable
// This can happen when user types for example before or after an image

Expand Down
8 changes: 4 additions & 4 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -508,17 +508,17 @@ <h2>Another kind of rich text editor.</h2>
<article contenteditable="true">
<h2><span style="color: rgb(255, 101, 169);">Stylo</span></h2>
<div>Stylo is an open source <a href="https://en.wikipedia.org/wiki/WYSIWYG" rel="noopener noreferrer">WYSIWYG</a> interactive editor for JavaScript. Its goal is to bring great user experience and interactivity to the web, for everyone, with no dependencies. Stylo is a <a href="https://deckdeckgo.com" rel="noopener noreferrer">DeckDeckGo</a> project.</div>
<div contenteditable="false"><hr /></div>
<hr />
<div>This is an <span style="font-weight: bold">&ZeroWidthSpace;alpha</span>&ZeroWidthSpace; version! ⚠️ The project is under active development and contributions on <a href="https://github.com/papyrs/stylo" rel="noopener noreferrer">GitHub</a> are most welcome.</div>
<div contenteditable="false"><hr></div>
<hr />
<h2>Features</h2>
<ul><li>Interactive design 🎯</li><li>Customizable 💪</li><li>Framework agnostic 😎</li><li>Lightweight (30kb gzipped, 0 deps) 🪶</li><li>Future Proof 🚀</li><li>Open Source (MIT license) ⭐️</li></ul>
<div contenteditable="false"><hr></div>
<hr />
<div>Pro tips: trigger <span style="font-weight: bold;">bold</span> mode with "**", <span style="font-style: italic">italic</span> mode with whitespace and "_", and <mark>mark</mark> mode with whitespace and "`". 👾</div>
<div>&ZeroWidthSpace;</div>
<div>Cheers<br/>David</div>
<div>&ZeroWidthSpace;</div>
<div contenteditable="false"><img src="/assets/mogwai.jpg" loading="lazy" style="width: 50%;" /></div>
<img src="/assets/mogwai.jpg" loading="lazy" style="width: 50%;" />
</article>

<stylo-editor> </stylo-editor>
Expand Down
8 changes: 2 additions & 6 deletions src/menus/img.menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,10 @@ const setImageWith = ({
}: {
size: '25%' | '50%' | '75%' | '100%';
paragraph: HTMLElement;
}) => {
const anchorImg: HTMLImageElement = paragraph.firstElementChild as HTMLImageElement;
anchorImg.style.setProperty('width', size);
};
}) => paragraph.style.setProperty('width', size);

export const imgMenu: StyloMenu = {
match: ({paragraph}: {paragraph: HTMLElement}) =>
paragraph.firstElementChild?.nodeName.toLowerCase() === 'img',
match: ({paragraph}: {paragraph: HTMLElement}) => paragraph.nodeName.toLowerCase() === 'img',
actions: [
{
text: 'img_width_original',
Expand Down
7 changes: 2 additions & 5 deletions src/plugins/hr.plugin.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {StyloPlugin, StyloPluginCreateParagraphsParams} from '../types/plugin';
import {createEmptyElement, createUneditableDiv} from '../utils/create-element.utils';
import {createEmptyElement} from '../utils/create-element.utils';
import {transformParagraph} from '../utils/paragraph.utils';

export const hr: StyloPlugin = {
Expand All @@ -8,11 +8,8 @@ export const hr: StyloPlugin = {
createParagraphs: async ({container, paragraph}: StyloPluginCreateParagraphsParams) => {
const hr: HTMLHRElement = document.createElement('hr');

const element: HTMLDivElement = createUneditableDiv();
element.append(hr);

transformParagraph({
elements: [element, createEmptyElement({nodeName: 'div'})],
elements: [hr, createEmptyElement({nodeName: 'div'})],
paragraph,
container,
focus: 'last'
Expand Down
7 changes: 2 additions & 5 deletions src/plugins/img.plugin.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {StyloPlugin, StyloPluginCreateParagraphsParams} from '../types/plugin';
import {createEmptyElement, createUneditableDiv} from '../utils/create-element.utils';
import {createEmptyElement} from '../utils/create-element.utils';
import {transformParagraph} from '../utils/paragraph.utils';

export const img: StyloPlugin = {
Expand All @@ -17,13 +17,10 @@ export const img: StyloPlugin = {
img.src = imgUrl;
img.setAttribute('loading', 'lazy');

const element: HTMLDivElement = createUneditableDiv();
element.append(img);

const emptyDiv: HTMLElement = createEmptyElement({nodeName: 'div'});

transformParagraph({
elements: [element, emptyDiv],
elements: [img, emptyDiv],
paragraph,
container,
focus: 'last'
Expand Down
9 changes: 1 addition & 8 deletions src/utils/create-element.utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {createEmptyElement, createUneditableDiv} from './create-element.utils';
import {createEmptyElement} from './create-element.utils';

describe('create element', () => {
it('should create empty element', () => {
Expand All @@ -7,11 +7,4 @@ describe('create element', () => {
expect(empty.nodeName.toLowerCase()).toEqual('div');
expect(empty.innerHTML).toEqual('\u200B');
});

it('should create a not editable element', () => {
const empty = createUneditableDiv();

expect(empty.nodeName.toLowerCase()).toEqual('div');
expect(empty.getAttribute('contenteditable')).toEqual('false');
});
});
14 changes: 0 additions & 14 deletions src/utils/create-element.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,3 @@ export const createEmptyElement = ({

return element;
};

// We do not want TextNode as direct child of the container.
// If user types next to some HTML elements, such as hr and img, the resulting text is a TextNode with the container as parent.
// <container>
// <img>
// -> after use type
// <container>
// text
// <img>
export const createUneditableDiv = (): HTMLDivElement => {
const div: HTMLDivElement = document.createElement('div');
div.setAttribute('contenteditable', 'false');
return div;
};

0 comments on commit 3e09fb2

Please sign in to comment.