import React, { useEffect, useState } from 'react';
import cn from 'classnames';
import useToggle from 'App/hooks/useToggle';
import useForceUpdate from 'App/hooks/useForceUpdate';
import { Icon } from 'UI';
import stl from './inspector.module.css';
import AttrView from './AttrView';
import TextView from './TextView';
import InlineInput from './InlineInput';
//TODO: add attribute, add child, add text (when there was no text before), Ctrl+Z
interface Window {
Element: typeof Element;
Text: typeof Text;
document: typeof document;
}
interface Props {
element: Element;
level: number;
context?: Window;
openChain: Element[];
forceUpdateParent: () => void;
selectedElement?: Element; // for deletion and other things
setSelectedElement?: (Element) => void;
onHover?: (Element) => void;
className?: String
}
interface TagEditorProps {
element: Element;
forceUpdateParent: () => void;
context: Window;
}
// TODO: to common space
function stopPropagation(cb: Function): React.MouseEventHandler {
return function(e) {
e.stopPropagation();
cb();
}
}
const RESTRICTED_TAGS = ['html', 'body', 'head'];
function TagEditor({ element, forceUpdateParent, context }: TagEditorProps) {
const [ editing, setEditing ] = useState(false);
const commitTag = (newTag: string) => {
if (newTag !== '' &&
!RESTRICTED_TAGS.includes(newTag) &&
element.parentNode &&
/^[a-zA-Z]+$/.test(newTag) // TODO: sync with spec
) {
const rElem = context.document.createElement(newTag);
rElem.innerHTML = element.innerHTML;
Array.from(element.attributes).forEach(attr => {
rElem.setAttribute(attr.name, attr.value);
})
element.parentNode.replaceChild(rElem, element);
}
setEditing(false);
forceUpdateParent();
}
const tag = element.tagName.toLowerCase();
return editing && !RESTRICTED_TAGS.includes(tag)
?