Skip to content

Commit

Permalink
fix: svg
Browse files Browse the repository at this point in the history
  • Loading branch information
shuta13 committed Aug 31, 2022
1 parent a4c848b commit 1382a91
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 13 deletions.
41 changes: 30 additions & 11 deletions packages/core/__tests__/smoke/dev-server/src/plugins.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import EditorJS, {
import { h, useState, useEffect, createPlugin } from '../../../../src';
import type { PDJSX } from '../../../../src/';

const SampleWithHooks = () => {
const WithHooks = () => {
console.log('render or re-render');

const [show, setShow] = useState(false);
Expand Down Expand Up @@ -111,7 +111,7 @@ const SampleWithHooks = () => {
);
};

const SampleWithContentEdiable = () => {
const WithContentEdiable = () => {
const [data, setData] = useState<BlockToolData | null>(null);
const initializer = ({ data }: BlockToolConstructorOptions) => {
setData(data);
Expand All @@ -130,6 +130,24 @@ const SampleWithContentEdiable = () => {
);
};

const WithSvg = () => {
const surround = (range: Range) => {};
const checkState = () => {};
return (
<inlineTool
static_get_isInline={true}
surround={surround}
checkState={checkState}
>
<button class="ce-inline-tool">
<svg width="20" height="18">
<path d="M10.458 12.04l2.919 1.686-.781 1.417-.984-.03-.974 1.687H8.674l1.49-2.583-.508-.775.802-1.401zm.546-.952l3.624-6.327a1.597 1.597 0 0 1 2.182-.59 1.632 1.632 0 0 1 .615 2.201l-3.519 6.391-2.902-1.675zm-7.73 3.467h3.465a1.123 1.123 0 1 1 0 2.247H3.273a1.123 1.123 0 1 1 0-2.247z" />
</svg>
</button>
</inlineTool>
);
};

const CustomTool = () => {
const handleClick = () => {
console.log('clicked');
Expand Down Expand Up @@ -171,9 +189,7 @@ const CustomInlineTool = () => {
checkState={() => {}}
static_get_isInline={true}
>
<div className="ce-inline-tool">
<span>📝</span>
</div>
<button class="ce-inline-tool">📝</button>
</inlineTool>
);
};
Expand Down Expand Up @@ -204,11 +220,14 @@ if (!outputElm) {
const editor = new EditorJS({
holder: containerElm,
tools: {
sampleWithHooks: {
class: createPlugin(<SampleWithHooks />),
withHooks: {
class: createPlugin(<WithHooks />),
},
withContentEditable: {
class: createPlugin(<WithContentEdiable />),
},
sampleWithContentEditable: {
class: createPlugin(<SampleWithContentEdiable />),
withSvg: {
class: createPlugin(<WithSvg />),
},
customTool: {
class: createPlugin(<CustomTool />),
Expand All @@ -224,13 +243,13 @@ const editor = new EditorJS({
data: {
blocks: [
{
type: 'sampleWithContentEditable',
type: 'withContentEditable',
data: {
value: 'initial paragraph 01',
},
},
{
type: 'sampleWithContentEditable',
type: 'withContentEditable',
data: {
value: 'initial paragraph 02',
},
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ const renderComponent = (component: ComponentType) => {
oldVNode,
commitQueue,
oldDom,
isSvg: parentDom.ownerSVGElement !== undefined,
});
commitRoot(commitQueue, vNode);

Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/create-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const createPlugin = (
oldVNode: null,
commitQueue,
oldDom: null,
isSvg: parentDom.ownerSVGElement !== undefined,
});

if (dom) {
Expand Down Expand Up @@ -63,6 +64,7 @@ export const createPlugin = (
oldVNode: null,
commitQueue: [],
oldDom: null,
isSvg: _parentDom.ownerSVGElement !== undefined,
})?._pluginProps ?? null,
render
);
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/reconciler/childlen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export type ReconcileChildrenParams = {
oldParentVNode: VNode | null;
commitQueue: ComponentType[];
oldDom: PDJSX.Element | null;
isSvg: boolean;
};

export type PlaceChildParams = {
Expand Down Expand Up @@ -114,6 +115,7 @@ export const reconcileChildren = ({
oldParentVNode,
commitQueue,
oldDom,
isSvg,
}: ReconcileChildrenParams) => {
let oldVNode: VNode | null;
let childVNode: VNode | ComponentChild | ComponentChild[];
Expand Down Expand Up @@ -223,6 +225,7 @@ export const reconcileChildren = ({
oldVNode,
commitQueue,
oldDom: filteredOldDom,
isSvg,
});

if (newDom != null) {
Expand Down
14 changes: 14 additions & 0 deletions packages/core/src/reconciler/elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,24 @@ export type ReconcileElementsParams = {
newVNode: VNode;
oldVNode: VNode | null;
commitQueue: ComponentType[];
isSvg: boolean;
};

export const reconcileElements = ({
dom,
newVNode,
oldVNode,
commitQueue,
isSvg,
}: ReconcileElementsParams) => {
const nodeType = newVNode.type;
const newProps = newVNode.props;
const oldProps = oldVNode?.props ?? {};

if (nodeType === 'svg') {
isSvg = true;
}

if (dom === null) {
// NOTE: Not element but text node value
if (newVNode.type === null) {
Expand All @@ -29,6 +36,11 @@ export const reconcileElements = ({
dom = document.createDocumentFragment() as unknown as HTMLElement;
const { children, ...pluginProps } = newProps;
dom._pluginProps = pluginProps as VNode['pluginProps'];
} else if (isSvg) {
dom = document.createElementNS(
'http://www.w3.org/2000/svg',
nodeType as string
) as unknown as HTMLElement;
} else {
dom = document.createElement(newVNode.type as string);
}
Expand All @@ -45,6 +57,7 @@ export const reconcileElements = ({
dom,
newProps,
oldProps,
isSvg,
});

const children = newVNode.props.children;
Expand All @@ -55,6 +68,7 @@ export const reconcileElements = ({
oldParentVNode: oldVNode,
commitQueue,
oldDom: null,
isSvg,
});
}
return dom;
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/reconciler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type ReconcileParams = {
newVNode: VNode;
oldVNode: VNode | null;
commitQueue: ComponentType[];
isSvg: boolean;
};

type RenderParams = {
Expand Down Expand Up @@ -47,6 +48,7 @@ export const reconcile = ({
newVNode,
oldVNode,
commitQueue,
isSvg,
}: ReconcileParams) => {
// NOTE: This mutable variable will include a lot of side effects.
// So, we named it with `dirty` prefix.
Expand Down Expand Up @@ -134,6 +136,7 @@ export const reconcile = ({
oldParentVNode: oldVNode,
commitQueue,
oldDom,
isSvg,
});

if (dirtyComponent.renderCallbacks.length) {
Expand All @@ -145,6 +148,7 @@ export const reconcile = ({
newVNode,
oldVNode,
commitQueue,
isSvg,
}) as PDJSX.Element;

if (options.diffed) {
Expand Down
17 changes: 16 additions & 1 deletion packages/core/src/reconciler/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type ReconcilePropsParams = {
dom: PDJSX.Element;
newProps: VNode['props'];
oldProps: VNode['props'] | { [key: string]: any };
isSvg: boolean;
};

type SetStylePropsParams = {
Expand All @@ -21,6 +22,7 @@ type SetPropsParams = {
key: string;
newValue: { [key: string]: any } | null;
oldValue: string | { [key: string]: any };
isSvg: boolean;
};

export const setStyleProps = ({ dom, key, value }: SetStylePropsParams) => {
Expand All @@ -38,7 +40,13 @@ export const setStyleProps = ({ dom, key, value }: SetStylePropsParams) => {
}
};

export const setProps = ({ dom, key, newValue, oldValue }: SetPropsParams) => {
export const setProps = ({
dom,
key,
newValue,
oldValue,
isSvg,
}: SetPropsParams) => {
if (key === 'style') {
if (typeof newValue === 'string') {
dom.style.cssText = newValue;
Expand Down Expand Up @@ -104,6 +112,10 @@ export const setProps = ({ dom, key, newValue, oldValue }: SetPropsParams) => {
key !== 'dangerouslySetInnerHTML'
) {
dom.setAttribute(key, newValue);
} else if (isSvg && key !== 'dangerouslySetInnerHTML') {
key = key.replace(/xlink(H|:h)/, 'h').replace(/sName$/, 's');
// @ts-expect-error Set readonly props
dom[key] = newValue ?? '';
} else if (key === 'contentEditable') {
dom.setAttribute('contenteditable', newValue as unknown as string);
} else {
Expand All @@ -116,6 +128,7 @@ export const reconcileProps = ({
dom,
newProps,
oldProps,
isSvg,
}: ReconcilePropsParams) => {
for (const [oldKey, oldValue] of Object.entries(oldProps)) {
if (
Expand All @@ -128,6 +141,7 @@ export const reconcileProps = ({
key: oldKey,
newValue: null,
oldValue,
isSvg,
});
}
}
Expand All @@ -145,6 +159,7 @@ export const reconcileProps = ({
key: newKey,
newValue,
oldValue: oldProps[newKey],
isSvg,
});
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ export namespace PDJSX {
| BlockTuneAttributes
| null;
_listeners?: { [key: string]: (e: Event) => void };
ownerSVGElement?: SVGElement | null;
data?: string | number;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/tool-inline-marker/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const Marker = () => {
checkState={checkState}
>
<button
className={`${api?.styles.inlineToolButton ?? ''} ${
class={`${api?.styles.inlineToolButton ?? ''} ${
marked ? api?.styles.inlineToolButtonActive : ''
}`}
>
Expand Down

0 comments on commit 1382a91

Please sign in to comment.