dante2-editor 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
data/docs/dante.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"dante.js","sources":["webpack:///src/components/core/editor.js","webpack:///./src/styles/fonts/dante/dante.eot","webpack:///./src/styles/fonts/dante/fontello.eot","webpack:///src/index.js","webpack:///./src/styles/dante.scss?293d","webpack:///demo/initialize.js","webpack:///src/components/blocks/embed.js","webpack:///src/components/blocks/image.js","webpack:///src/components/blocks/placeholder.js","webpack:///src/components/blocks/video.js","webpack:///src/components/core/dante.js","webpack:///src/components/core/debug.js","webpack:///src/components/decorators/link.js","webpack:///src/components/init.js","webpack:///src/components/popovers/addButton.js","webpack:///src/components/popovers/image.js","webpack:///src/components/popovers/link.js","webpack:///src/components/popovers/toolTip.js","webpack:///src/utils/find_entities.js","webpack:///src/utils/html2content.js","webpack:///src/utils/save_content.js","webpack:///src/model/index.js","webpack:///./src/styles/fonts/dante/dante.svg","webpack:///./src/styles/fonts/dante/dante.ttf","webpack:///./src/styles/fonts/dante/dante.woff","webpack:///./src/styles/fonts/dante/fontello.svg","webpack:///./src/styles/fonts/dante/fontello.ttf","webpack:///./src/styles/fonts/dante/fontello.woff","webpack:///src/utils/selection.js"],"sourcesContent":["\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport Immutable from 'immutable'\nimport { Map, fromJS } from 'immutable'\nimport { \n convertToRaw, \n convertFromRaw, \n CompositeDecorator, \n getDefaultKeyBinding,\n ContentState, \n Editor, \n EditorState, \n Entity, \n RichUtils, \n DefaultDraftBlockRenderMap, \n SelectionState, \n Modifier\n} from 'draft-js'\n\nimport { \n convertToHTML,\n //, convertFromHTML \n} from 'draft-convert'\n\nimport { \n addNewBlock, \n resetBlockWithType, \n updateDataOfBlock, \n //updateTextOfBlock, \n getCurrentBlock, \n addNewBlockAt \n} from '../../model/index.js'\n\nimport Link from '../decorators/link'\nimport Debug from './debug'\nimport findEntities from '../../utils/find_entities'\nimport SaveBehavior from '../../utils/save_content'\nimport customHTML2Content from '../../utils/html2content'\nimport createStyles from 'draft-js-custom-styles';\n\n\nclass DanteEditor extends React.Component {\n constructor(props) {\n super(props)\n\n this.initializeState = this.initializeState.bind(this)\n this.refreshSelection = this.refreshSelection.bind(this)\n this.forceRender = this.forceRender.bind(this)\n this.onChange = this.onChange.bind(this)\n this.dispatchChangesToSave = this.dispatchChangesToSave.bind(this)\n this.setPreContent = this.setPreContent.bind(this)\n this.focus = this.focus.bind(this)\n this.getEditorState = this.getEditorState.bind(this)\n this.emitSerializedOutput = this.emitSerializedOutput.bind(this)\n this.decodeEditorContent = this.decodeEditorContent.bind(this)\n this.getTextFromEditor = this.getTextFromEditor.bind(this)\n this.getLocks = this.getLocks.bind(this)\n this.addLock = this.addLock.bind(this)\n this.removeLock = this.removeLock.bind(this)\n this.renderableBlocks = this.renderableBlocks.bind(this)\n this.defaultWrappers = this.defaultWrappers.bind(this)\n this.blockRenderer = this.blockRenderer.bind(this)\n this.handleBlockRenderer = this.handleBlockRenderer.bind(this)\n this.blockStyleFn = this.blockStyleFn.bind(this)\n this.getDataBlock = this.getDataBlock.bind(this)\n this.styleForBlock = this.styleForBlock.bind(this)\n this.handlePasteText = this.handlePasteText.bind(this)\n this.handleTXTPaste = this.handleTXTPaste.bind(this)\n this.handleHTMLPaste = this.handleHTMLPaste.bind(this)\n this.handlePasteImage = this.handlePasteImage.bind(this)\n this.handleDroppedFiles = this.handleDroppedFiles.bind(this)\n this.handleUpArrow = this.handleUpArrow.bind(this)\n this.handleDownArrow = this.handleDownArrow.bind(this)\n this.handleReturn = this.handleReturn.bind(this)\n this.handleBeforeInput = this.handleBeforeInput.bind(this)\n this.handleKeyCommand = this.handleKeyCommand.bind(this)\n this.findCommandKey = this.findCommandKey.bind(this)\n this.KeyBindingFn = this.KeyBindingFn.bind(this)\n this.updateBlockData = this.updateBlockData.bind(this)\n this.setDirection = this.setDirection.bind(this)\n this.toggleEditable = this.toggleEditable.bind(this)\n this.disableEditable = this.disableEditable.bind(this)\n this.enableEditable = this.enableEditable.bind(this)\n this.closePopOvers = this.closePopOvers.bind(this)\n this.relocateTooltips = this.relocateTooltips.bind(this)\n this.tooltipsWithProp = this.tooltipsWithProp.bind(this)\n this.tooltipHasSelectionElement = this.tooltipHasSelectionElement.bind(this)\n this.handleShowPopLinkOver = this.handleShowPopLinkOver.bind(this)\n this.handleHidePopLinkOver = this.handleHidePopLinkOver.bind(this)\n this.showPopLinkOver = this.showPopLinkOver.bind(this)\n this.hidePopLinkOver = this.hidePopLinkOver.bind(this)\n this.render = this.render.bind(this)\n\n this.decorator = new CompositeDecorator([{\n strategy: findEntities.bind(null, 'LINK', this),\n component: Link\n }])\n\n this.blockRenderMap = Map({\n \"image\": {\n element: 'figure'\n },\n \"video\": {\n element: 'figure'\n },\n \"embed\": {\n element: 'div'\n },\n 'unstyled': {\n wrapper: null,\n element: 'div'\n },\n 'paragraph': {\n wrapper: null,\n element: 'div'\n },\n 'placeholder': {\n wrapper: null,\n element: 'div'\n }\n\n })\n\n this.extendedBlockRenderMap = DefaultDraftBlockRenderMap.merge(this.blockRenderMap)\n\n this.state = {\n editorState: EditorState.createEmpty(),\n read_only: this.props.config.read_only,\n blockRenderMap: this.extendedBlockRenderMap,\n locks: 0,\n debug: this.props.config.debug\n }\n\n this.widgets = this.props.config.widgets\n this.tooltips = this.props.config.tooltips\n\n this.key_commands = this.props.config.key_commands\n\n this.continuousBlocks = this.props.config.continuousBlocks\n\n this.block_types = this.props.config.block_types\n\n this.default_wrappers = this.props.config.default_wrappers\n\n this.character_convert_mapping = this.props.config.character_convert_mapping\n\n this.save = new SaveBehavior({\n getLocks: this.getLocks,\n config: {\n xhr: this.props.config.xhr,\n data_storage: this.props.config.data_storage\n },\n editorState: this.state.editorState,\n editorContent: this.emitSerializedOutput()\n })\n\n const { styles, customStyleFn, exporter } = createStyles(['font-size', 'color', 'font-family']); //, 'PREFIX', customStyleMap);\n this.styles = styles\n this.customStyleFn = customStyleFn\n }\n\n componentDidMount(){\n this.initializeState()\n }\n\n initializeState() {\n let newEditorState = EditorState.createEmpty(this.decorator)\n if (this.props.content) {\n newEditorState = EditorState.set(this.decodeEditorContent(this.props.content), {decorator: this.decorator});\n }\n this.onChange(newEditorState) \n }\n\n decodeEditorContent(raw_as_json) {\n const new_content = convertFromRaw(raw_as_json)\n let editorState\n return editorState = EditorState.createWithContent(new_content, this.decorator)\n }\n\n refreshSelection(newEditorState) {\n const { editorState } = this.state\n // Setting cursor position after inserting to content\n const s = this.state.editorState.getSelection()\n const c = editorState.getCurrentContent()\n const focusOffset = s.getFocusOffset()\n const anchorKey = s.getAnchorKey()\n\n let selectionState = SelectionState.createEmpty(s.getAnchorKey())\n\n // console.log anchorKey, focusOffset\n selectionState = selectionState.merge({\n anchorOffset: focusOffset,\n focusKey: anchorKey,\n focusOffset\n })\n\n let newState = EditorState.forceSelection(newEditorState, selectionState)\n\n return this.onChange(newState)\n }\n\n forceRender(editorState) {\n const selection = this.state.editorState.getSelection()\n const content = editorState.getCurrentContent()\n const newEditorState = EditorState.createWithContent(content, this.decorator)\n\n return this.refreshSelection(newEditorState)\n }\n\n onChange(editorState) {\n this.setPreContent()\n this.setState({ editorState })\n\n const currentBlock = getCurrentBlock(this.state.editorState)\n const blockType = currentBlock.getType()\n\n if (!editorState.getSelection().isCollapsed()) {\n\n const tooltip = this.tooltipsWithProp('displayOnSelection')[0]\n if (!this.tooltipHasSelectionElement(tooltip, blockType)) {\n return\n }\n this.handleTooltipDisplayOn('displayOnSelection')\n } else {\n this.handleTooltipDisplayOn('displayOnSelection', false)\n }\n\n setTimeout(() => {\n return this.relocateTooltips()\n }, 0)\n\n return this.dispatchChangesToSave()\n }\n\n dispatchChangesToSave() {\n clearTimeout(this.saveTimeout)\n return this.saveTimeout = setTimeout(() => {\n return this.save.store(this.emitSerializedOutput())\n }, 100)\n }\n\n setPreContent() {\n const content = this.emitSerializedOutput()\n return this.save.editorContent = content\n }\n\n focus() {\n //debugger\n }\n //@props.refs.richEditor.focus()\n\n getEditorState() {\n return this.state.editorState\n }\n\n emitSerializedOutput() {\n const raw = convertToRaw(this.state.editorState.getCurrentContent())\n\n return raw\n }\n\n //# title utils\n getTextFromEditor() {\n const c = this.state.editorState.getCurrentContent()\n const out = c.getBlocksAsArray().map(o => {\n return o.getText()\n }).join(\"\\n\")\n\n return out\n }\n\n emitHTML2() {\n let html\n\n return html = convertToHTML({\n entityToHTML: (entity, originalText) => {\n if (entity.type === 'LINK') {\n return `<a href=\\\"${ entity.data.url }\\\">${ originalText }</a>`\n } else {\n return originalText\n }\n }\n\n })(this.state.editorState.getCurrentContent())\n }\n\n getLocks() {\n return this.state.locks\n }\n\n addLock() {\n return this.setState({\n locks: this.state.locks += 1 })\n }\n\n removeLock() {\n return this.setState({\n locks: this.state.locks -= 1 })\n }\n\n renderableBlocks() {\n return this.widgets.filter(o => o.renderable).map(o => o.type)\n }\n\n defaultWrappers(blockType) {\n return this.default_wrappers.filter(o => {\n return o.block === blockType\n }).map(o => o.className)\n }\n\n blockRenderer(block) {\n\n switch (block.getType()) {\n\n case \"atomic\":\n\n const entity = block.getEntityAt(0)\n const entity_type = Entity.get(entity).getType()\n\n break\n }\n\n if (this.renderableBlocks().includes(block.getType())) {\n return this.handleBlockRenderer(block)\n }\n\n return null\n }\n\n handleBlockRenderer(block) {\n const dataBlock = this.getDataBlock(block)\n if (!dataBlock) {\n return null\n }\n\n const read_only = this.state.read_only ? false : null\n const editable = read_only !== null ? read_only : dataBlock.editable\n return {\n component: eval(dataBlock.block),\n editable,\n props: {\n data: block.getData(),\n getEditorState: this.getEditorState,\n setEditorState: this.onChange,\n addLock: this.addLock,\n toggleEditable: this.toggleEditable,\n disableEditable: this.disableEditable,\n enableEditable: this.enableEditable,\n removeLock: this.removeLock,\n getLocks: this.getLocks,\n config: dataBlock.options\n }\n }\n\n return null\n }\n\n blockStyleFn(block) {\n const currentBlock = getCurrentBlock(this.state.editorState)\n const is_selected = currentBlock.getKey() === block.getKey() ? \"is-selected\" : \"\"\n\n if (this.renderableBlocks().includes(block.getType())) {\n return this.styleForBlock(block, currentBlock, is_selected)\n }\n\n const defaultBlockClass = this.defaultWrappers(block.getType())\n if (defaultBlockClass.length > 0) {\n return `graf ${ defaultBlockClass[0] } ${ is_selected }`\n } else {\n return `graf nana ${ is_selected }`\n }\n }\n\n getDataBlock(block) {\n return this.widgets.find(o => {\n return o.type === block.getType()\n })\n }\n\n styleForBlock(block, currentBlock, is_selected) {\n const dataBlock = this.getDataBlock(block)\n\n if (!dataBlock) {\n return null\n }\n\n const selectedFn = dataBlock.selectedFn ? dataBlock.selectedFn(block) : null\n const selected_class = is_selected ? dataBlock.selected_class : ''\n\n return `${ dataBlock.wrapper_class } ${ selected_class } ${ selectedFn }`\n }\n\n handleTooltipDisplayOn(prop, display) {\n\n // for button click on after inline style set, \n // avoids inline popver to reappear on previous selection\n if(this.state.read_only){\n return \n }\n\n if (display == null) {\n display = true\n }\n \n return setTimeout(() => {\n const items = this.tooltipsWithProp(prop)\n console.log(items)\n return items.map(o => {\n this.refs[o.ref].display(display)\n return this.refs[o.ref].relocate()\n })\n }, 20)\n }\n\n handlePasteText(text, html) {\n\n // https://github.com/facebook/draft-js/issues/685\n /*\n html = \"<p>chao</p>\n <avv>aaa</avv>\n <p>oli</p>\n <img src='x'/>\"\n */\n\n // if not html then fallback to default handler\n\n if (!html) {\n return this.handleTXTPaste(text, html)\n }\n if (html) {\n return this.handleHTMLPaste(text, html)\n }\n }\n\n handleTXTPaste(text, html) {\n const currentBlock = getCurrentBlock(this.state.editorState)\n\n let { editorState } = this.state\n\n switch (currentBlock.getType()) {\n case \"image\":case \"video\":case \"placeholder\":\n const newContent = Modifier.replaceText(editorState.getCurrentContent(), new SelectionState({\n anchorKey: currentBlock.getKey(),\n anchorOffset: 0,\n focusKey: currentBlock.getKey(),\n focusOffset: 2\n }), text)\n\n editorState = EditorState.push(editorState, newContent, 'replace-text')\n\n this.onChange(editorState)\n\n return true\n default:\n return false\n }\n }\n\n handleHTMLPaste(text, html) {\n\n const currentBlock = getCurrentBlock(this.state.editorState)\n\n // TODO: make this configurable\n switch (currentBlock.getType()) {\n case \"image\":case \"video\":case \"placeholder\":\n return this.handleTXTPaste(text, html)\n break\n }\n\n const newContentState = customHTML2Content(html, this.extendedBlockRenderMap)\n\n const selection = this.state.editorState.getSelection()\n const endKey = selection.getEndKey()\n\n const content = this.state.editorState.getCurrentContent()\n const blocksBefore = content.blockMap.toSeq().takeUntil(v => v.key === endKey)\n const blocksAfter = content.blockMap.toSeq().skipUntil(v => v.key === endKey).rest()\n\n const newBlockKey = newContentState.blockMap.first().getKey()\n\n const newBlockMap = blocksBefore.concat(newContentState.blockMap, blocksAfter).toOrderedMap()\n\n const newContent = content.merge({\n blockMap: newBlockMap,\n selectionBefore: selection,\n selectionAfter: selection.merge({\n anchorKey: newBlockKey,\n anchorOffset: 0,\n focusKey: newBlockKey,\n focusOffset: 0,\n isBackward: false\n })\n })\n\n const pushedContentState = EditorState.push(this.state.editorState, newContent, 'insert-fragment')\n\n this.onChange(pushedContentState)\n\n return true\n }\n\n handlePasteImage(files) {\n //TODO: check file types\n return files.map(file => {\n let opts = {\n url: URL.createObjectURL(file),\n file\n }\n\n return this.onChange(addNewBlock(this.state.editorState, 'image', opts))\n })\n }\n\n handleDroppedFiles(state, files) {\n return files.map(file => {\n let opts = {\n url: URL.createObjectURL(file),\n file\n }\n\n return this.onChange(addNewBlock(this.state.editorState, 'image', opts))\n })\n }\n\n handleUpArrow(e) {\n return setTimeout(() => {\n return this.forceRender(this.state.editorState)\n }, 10)\n }\n\n handleDownArrow(e) {\n return setTimeout(() => {\n return this.forceRender(this.state.editorState)\n }, 10)\n }\n\n handleReturn(e) {\n if (this.props.handleReturn) {\n if (this.props.handleReturn()) {\n return true\n }\n }\n\n let { editorState } = this.state\n\n if (e.shiftKey) {\n this.setState({ editorState: RichUtils.insertSoftNewline(editorState) });\n return true;\n }\n\n\n if (!e.altKey && !e.metaKey && !e.ctrlKey) {\n const currentBlock = getCurrentBlock(editorState)\n const blockType = currentBlock.getType()\n const selection = editorState.getSelection()\n\n const config_block = this.getDataBlock(currentBlock)\n\n if (currentBlock.getText().length === 0) {\n\n if (config_block && config_block.handleEnterWithoutText) {\n config_block.handleEnterWithText(this, currentBlock)\n this.closePopOvers()\n return true\n }\n\n //TODO turn this in configurable\n switch (blockType) {\n case \"header-one\":\n this.onChange(resetBlockWithType(editorState, \"unstyled\"))\n return true\n break\n default:\n return false\n }\n }\n\n if (currentBlock.getText().length > 0) {\n\n if (config_block && config_block.handleEnterWithText) {\n config_block.handleEnterWithText(this, currentBlock)\n this.closePopOvers()\n return true\n }\n\n if (currentBlock.getLength() === selection.getStartOffset()) {\n if (this.continuousBlocks.indexOf(blockType) < 0) {\n this.onChange(addNewBlockAt(editorState, currentBlock.getKey()))\n return true\n }\n }\n\n return false\n }\n\n // selection.isCollapsed() and # should we check collapsed here?\n if (currentBlock.getLength() === selection.getStartOffset()) {\n //or (config_block && config_block.breakOnContinuous))\n // it will match the unstyled for custom blocks\n if (this.continuousBlocks.indexOf(blockType) < 0) {\n this.onChange(addNewBlockAt(editorState, currentBlock.getKey()))\n return true\n }\n return false\n }\n\n return false\n }\n }\n\n //return false\n\n // TODO: make this configurable\n handleBeforeInput(chars) {\n const currentBlock = getCurrentBlock(this.state.editorState)\n const blockType = currentBlock.getType()\n const selection = this.state.editorState.getSelection()\n\n let { editorState } = this.state\n\n // close popovers\n if (currentBlock.getText().length !== 0) {\n //@closeInlineButton()\n this.closePopOvers()\n }\n\n // handle space on link\n const endOffset = selection.getEndOffset()\n const endKey = currentBlock.getEntityAt(endOffset - 1)\n const endEntityType = endKey && Entity.get(endKey).getType()\n const afterEndKey = currentBlock.getEntityAt(endOffset)\n const afterEndEntityType = afterEndKey && Entity.get(afterEndKey).getType()\n\n // will insert blank space when link found\n if (chars === ' ' && endEntityType === 'LINK' && afterEndEntityType !== 'LINK') {\n const newContentState = Modifier.insertText(editorState.getCurrentContent(), selection, ' ')\n const newEditorState = EditorState.push(editorState, newContentState, 'insert-characters')\n this.onChange(newEditorState)\n return true\n }\n\n // block transform\n if (blockType.indexOf('atomic') === 0) {\n return false\n }\n\n const blockLength = currentBlock.getLength()\n if (selection.getAnchorOffset() > 1 || blockLength > 1) {\n return false\n }\n\n const blockTo = this.character_convert_mapping[currentBlock.getText() + chars]\n\n console.log(`BLOCK TO SHOW: ${ blockTo }`)\n\n if (!blockTo) {\n return false\n }\n\n this.onChange(resetBlockWithType(editorState, blockTo))\n\n return true\n }\n\n // TODO: make this configurable\n handleKeyCommand(command) {\n const { editorState } = this.state\n let currentBlockType, newBlockType\n\n if (this.props.handleKeyCommand && this.props.handleKeyCommand(command)) {\n return true\n }\n\n if (command === 'add-new-block') {\n this.onChange(addNewBlock(editorState, 'blockquote'))\n return true\n }\n\n const block = getCurrentBlock(editorState)\n\n if (command.indexOf('toggle_inline:') === 0) {\n newBlockType = command.split(':')[1]\n currentBlockType = block.getType()\n this.onChange(RichUtils.toggleInlineStyle(editorState, newBlockType))\n return true\n }\n\n if (command.indexOf('toggle_block:') === 0) {\n newBlockType = command.split(':')[1]\n currentBlockType = block.getType()\n\n this.onChange(RichUtils.toggleBlockType(editorState, newBlockType))\n return true\n }\n\n const newState = RichUtils.handleKeyCommand(this.state.editorState, command)\n if (newState) {\n this.onChange(newState)\n return true\n }\n\n return false\n }\n\n findCommandKey(opt, command) {\n // console.log \"COMMAND find: #{opt} #{command}\"\n return this.key_commands[opt].find(o => o.key === command)\n }\n\n KeyBindingFn(e) {\n\n //⌘ + B / Ctrl + B Bold\n //⌘ + I / Ctrl + I Italic\n //⌘ + K / Ctrl + K Turn into link\n //⌘ + Alt + 1 / Ctrl + Alt + 1 Header\n //⌘ + Alt + 2 / Ctrl + Alt + 2 Sub-Header\n //⌘ + Alt + 5 / Ctrl + Alt + 5 Quote (Press once for a block quote, again for a pull quote and a third time to turn off quote)\n\n let cmd\n if (e.altKey) {\n if (e.shiftKey) {\n cmd = this.findCommandKey(\"alt-shift\", e.which)\n if (cmd) {\n return cmd.cmd\n }\n\n return getDefaultKeyBinding(e)\n }\n\n if (e.ctrlKey || e.metaKey) {\n cmd = this.findCommandKey(\"alt-cmd\", e.which)\n if (cmd) {\n return cmd.cmd\n }\n return getDefaultKeyBinding(e)\n }\n } else if (e.ctrlKey || e.metaKey) {\n cmd = this.findCommandKey(\"cmd\", e.which)\n if (cmd) {\n return cmd.cmd\n }\n return getDefaultKeyBinding(e)\n }\n\n return getDefaultKeyBinding(e)\n }\n\n // will update block state todo: movo to utils\n updateBlockData(block, options) {\n const data = block.getData()\n const newData = data.merge(options)\n const newState = updateDataOfBlock(this.state.editorState, block, newData)\n // this fixes enter from image caption\n return this.forceRender(newState)\n }\n\n setDirection(direction_type) {\n const contentState = this.state.editorState.getCurrentContent()\n const selectionState = this.state.editorState.getSelection()\n const block = contentState.getBlockForKey(selectionState.anchorKey)\n\n return this.updateBlockData(block, { direction: direction_type })\n }\n\n //# read only utils\n toggleEditable() {\n this.closePopOvers()\n return this.setState({ read_only: !this.state.read_only }, this.testEmitAndDecode)\n }\n\n disableEditable() {\n console.log(\"in !!\")\n this.closePopOvers()\n return this.setState({ read_only: true }, this.testEmitAndDecode)\n }\n\n enableEditable() {\n this.closePopOvers()\n console.log(\"out !!\")\n return this.setState({ read_only: false }, this.testEmitAndDecode)\n }\n\n closePopOvers() {\n return this.tooltips.map(o => {\n return this.refs[o.ref].hide()\n })\n }\n\n relocateTooltips() {\n if (this.state.read_only)\n return \n\n return this.tooltips.map(o => {\n return this.refs[o.ref].relocate()\n })\n }\n\n tooltipsWithProp(prop) {\n return this.tooltips.filter(o => {\n return o[prop]\n })\n }\n\n tooltipHasSelectionElement(tooltip, element) {\n return tooltip.selectionElements.includes(element)\n }\n\n //################################\n // TODO: this methods belongs to popovers/link\n //################################\n\n handleShowPopLinkOver(e) {\n return this.showPopLinkOver()\n }\n\n handleHidePopLinkOver(e) {\n return this.hidePopLinkOver()\n }\n\n showPopLinkOver(el) {\n // handles popover display\n // using anchor or from popover\n\n const parent_el = ReactDOM.findDOMNode(this)\n\n // set url first in order to calculate popover width\n let coords\n this.refs.anchor_popover.setState({ url: el ? el.href : this.refs.anchor_popover.state.url })\n\n if (el) {\n coords = this.refs.anchor_popover.relocate(el)\n }\n\n if (coords) {\n this.refs.anchor_popover.setPosition(coords)\n }\n\n this.refs.anchor_popover.setState({ show: true })\n\n this.isHover = true\n return this.cancelHide()\n }\n\n hidePopLinkOver() {\n return this.hideTimeout = setTimeout(() => {\n return this.refs.anchor_popover.hide()\n }, 300)\n }\n\n cancelHide() {\n // console.log \"Cancel Hide\"\n return clearTimeout(this.hideTimeout)\n }\n\n //##############################\n\n render() {\n return (\n <div id=\"content\" suppressContentEditableWarning={ true }>\n <article className=\"postArticle\">\n <div className=\"postContent\">\n <div className=\"notesSource\">\n <div id=\"editor\" className=\"postField postField--body\">\n <section className=\"section--first section--last\">\n <div className=\"section-divider layoutSingleColumn\">\n <hr className=\"section-divider\" />\n </div>\n <div className=\"section-content\">\n <div ref=\"richEditor\" \n className=\"section-inner layoutSingleColumn\"\n onClick={ this.focus }>\n <Editor\n blockRendererFn={ this.blockRenderer }\n editorState={ this.state.editorState }\n onChange={ this.onChange }\n onUpArrow={ this.handleUpArrow }\n onDownArrow={ this.handleDownArrow }\n handleReturn={ this.handleReturn }\n blockRenderMap={ this.state.blockRenderMap }\n blockStyleFn={ this.blockStyleFn }\n customStyleFn={this.customStyleFn }\n handlePastedText={ this.handlePasteText }\n handlePastedFiles={ this.handlePasteImage }\n handleDroppedFiles={ this.handleDroppedFiles }\n handleKeyCommand={ this.handleKeyCommand }\n keyBindingFn={ this.KeyBindingFn }\n handleBeforeInput={ this.handleBeforeInput }\n readOnly={ this.state.read_only }\n placeholder={ this.props.config.body_placeholder }\n ref=\"editor\"\n />\n </div>\n </div>\n </section>\n </div>\n </div>\n </div>\n </article>\n {\n this.tooltips.map( (o, i) => {\n return (\n <o.component\n ref={ o.ref }\n key={ i }\n editor={ this }\n editorState={ this.state.editorState }\n onChange={ this.onChange }\n styles={this.styles}\n configTooltip={ o }\n widget_options={ o.widget_options }\n showPopLinkOver={ this.showPopLinkOver }\n hidePopLinkOver={ this.hidePopLinkOver }\n handleOnMouseOver={ this.handleShowPopLinkOver }\n handleOnMouseOut={ this.handleHidePopLinkOver }\n />\n )\n })\n }\n {\n this.state.debug\n ? <Debug locks={ this.state.locks } editor={ this } />\n : undefined\n }\n </div>\n\n )\n }\n}\n\nexport default DanteEditor\n\n\n\n// WEBPACK FOOTER //\n// src/components/core/editor.js","module.exports = __webpack_public_path__ + \"fonts/dante.eot\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/fonts/dante/dante.eot\n// module id = 184\n// module chunks = 0","module.exports = __webpack_public_path__ + \"fonts/fontello.eot\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/fonts/dante/fontello.eot\n// module id = 185\n// module chunks = 0","\nimport {DanteEditor, Dante} from './components/init.js'\n\nwindow.Dante = Dante\nwindow.DanteEditor = DanteEditor\n\nexport {\n Dante, \n DanteEditor\n}\n\n\n// WEBPACK FOOTER //\n// src/index.js","// removed by extract-text-webpack-plugin\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/dante.scss\n// module id = 192\n// module chunks = 0","import 'styles/dante'\nimport { Dante, DanteEditor } from '../src/index'\n/*\nmodule.exports = {\n Dante, \n DanteEditor\n}*/\n\n\n// WEBPACK FOOTER //\n// demo/initialize.js","\nimport React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport { Entity, RichUtils, AtomicBlockUtils, EditorBlock } from 'draft-js'\n\nimport axios from \"axios\"\n\nimport { updateDataOfBlock } from '../../model/index.js'\n\nexport default class EmbedBlock extends React.Component {\n constructor(props) {\n super(props)\n //api_key = \"86c28a410a104c8bb58848733c82f840\"\n\n this.updateData = this.updateData.bind(this)\n this.dataForUpdate = this.dataForUpdate.bind(this)\n this.componentDidMount = this.componentDidMount.bind(this)\n this.state = {\n embed_data: this.defaultData(),\n error: \"\"\n }\n }\n\n defaultData() {\n const existing_data = this.props.block.getData().toJS()\n return existing_data.embed_data || {}\n }\n\n // will update block state\n updateData() {\n const { block, blockProps } = this.props\n const { getEditorState, setEditorState } = this.props.blockProps\n const data = block.getData()\n const newData = data.merge(this.state)\n return setEditorState(updateDataOfBlock(getEditorState(), block, newData))\n }\n\n dataForUpdate() {\n\n return this.props.blockProps.data.toJS()\n }\n\n componentDidMount() {\n\n if (!this.props.blockProps.data) {\n return\n }\n\n // ensure data isnt already loaded\n // unless @dataForUpdate().endpoint or @dataForUpdate().provisory_text\n\n if (!this.dataForUpdate().endpoint && !this.dataForUpdate().provisory_text) {\n //debugger\n return\n }\n\n return axios({\n method: 'get',\n url: `${ this.dataForUpdate().endpoint }${ this.dataForUpdate().provisory_text }&scheme=https`\n }).then(result => {\n\n return this.setState({ embed_data: result.data } //JSON.parse(data.responseText)\n , this.updateData)\n }).catch(error => {\n\n this.setState({\n error: error.response.data.error_message })\n return console.log(\"TODO: error\")\n })\n }\n\n classForImage() {\n if (this.state.embed_data.images) {\n return \"\"\n } else {\n return \"mixtapeImage--empty u-ignoreBlock\"\n }\n }\n //if @state.embed_data.thumbnail_url then \"\" else \"mixtapeImage--empty u-ignoreBlock\"\n\n picture() {\n if (this.state.embed_data.images && this.state.embed_data.images.length > 0) {\n return this.state.embed_data.images[0].url\n } else {\n return \"\"\n }\n }\n\n render() {\n //block = @.props\n //foo = @.props.blockProps\n //data = Entity.get(block.block.getEntityAt(0)).getData()\n console.log(\"ERROR\", this.state.error)\n return (\n <span>\n { this.picture()\n ? <a\n target='_blank'\n className={ `js-mixtapeImage mixtapeImage ${ this.classForImage() }` }\n href={ this.state.embed_data.url }\n style={ { backgroundImage: `url('${ this.picture() }')` } }\n />\n : undefined\n }\n { this.state.error ? \n <h2>{ this.state.error }</h2>\n : undefined\n }\n <a\n className='markup--anchor markup--mixtapeEmbed-anchor'\n target='_blank'\n href={ this.state.embed_data.url }\n >\n <strong className='markup--strong markup--mixtapeEmbed-strong'>\n { this.state.embed_data.title }\n </strong>\n <em className='markup--em markup--mixtapeEmbed-em'>\n { this.state.embed_data.description }\n </em>\n </a>{ this.state.embed_data.provider_url }\n </span>\n )\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/blocks/embed.js","import React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport {\n Entity, \n RichUtils, \n AtomicBlockUtils, \n EditorBlock, \n EditorState } from 'draft-js'\n\nimport axios from \"axios\"\n\nimport { updateDataOfBlock } from '../../model/index.js'\n\nexport default class ImageBlock extends React.Component {\n\n constructor(props) {\n super(props)\n\n this.blockPropsSrc = this.blockPropsSrc.bind(this)\n this.defaultUrl = this.defaultUrl.bind(this)\n this.defaultAspectRatio = this.defaultAspectRatio.bind(this)\n this.updateData = this.updateData.bind(this)\n this.replaceImg = this.replaceImg.bind(this)\n this.startLoader = this.startLoader.bind(this)\n this.stopLoader = this.stopLoader.bind(this)\n this.handleUpload = this.handleUpload.bind(this)\n this.aspectRatio = this.aspectRatio.bind(this)\n this.updateDataSelection = this.updateDataSelection.bind(this)\n this.handleGrafFigureSelectImg = this.handleGrafFigureSelectImg.bind(this)\n this.getUploadUrl = this.getUploadUrl.bind(this)\n this.uploadFile = this.uploadFile.bind(this)\n this.uploadFailed = this.uploadFailed.bind(this)\n this.uploadCompleted = this.uploadCompleted.bind(this)\n this.updateProgressBar = this.updateProgressBar.bind(this)\n this.placeHolderEnabled = this.placeHolderEnabled.bind(this)\n this.placeholderText = this.placeholderText.bind(this)\n this.handleFocus = this.handleFocus.bind(this)\n this.render = this.render.bind(this)\n let existing_data = this.props.block.getData().toJS()\n\n this.config = this.props.blockProps.config\n this.file = this.props.blockProps.data.get('file')\n this.state = {\n loading: false,\n selected: false,\n loading_progress: 0,\n caption: this.defaultPlaceholder(),\n direction: existing_data.direction || \"center\",\n width: 0,\n height: 0,\n file: null,\n url: this.blockPropsSrc() || this.defaultUrl(existing_data),\n aspect_ratio: this.defaultAspectRatio(existing_data)\n }\n }\n\n blockPropsSrc() {\n // console.log @.props.blockProps.data.src\n return this.props.blockProps.data.src\n }\n /*\n debugger\n block = @.props\n entity = block.block.getEntityAt(0)\n if entity\n data = Entity.get(entity).getData().src\n else\n null\n */\n\n defaultUrl(data) {\n if (data.url) {\n return data.url\n }\n\n if (data.url) {\n if (data.file) {\n return URL.createObjectURL(data.file)\n } else {\n return data.url\n }\n } else {\n return this.props.blockProps.data.src\n }\n }\n\n defaultPlaceholder() {\n return this.props.blockProps.config.image_caption_placeholder\n }\n\n defaultAspectRatio(data) {\n if (data.aspect_ratio) {\n return {\n width: data.aspect_ratio['width'],\n height: data.aspect_ratio['height'],\n ratio: data.aspect_ratio['ratio']\n }\n } else {\n return {\n width: 0,\n height: 0,\n ratio: 100\n }\n }\n }\n\n getAspectRatio(w, h) {\n let maxWidth = 1000\n let maxHeight = 1000\n let ratio = 0\n let width = w // Current image width\n let height = h // Current image height\n\n // Check if the current width is larger than the max\n if (width > maxWidth) {\n ratio = maxWidth / width // get ratio for scaling image\n height = height * ratio // Reset height to match scaled image\n width = width * ratio // Reset width to match scaled image\n\n // Check if current height is larger than max\n } else if (height > maxHeight) {\n ratio = maxHeight / height // get ratio for scaling image\n width = width * ratio // Reset width to match scaled image\n height = height * ratio // Reset height to match scaled image\n }\n\n let fill_ratio = height / width * 100\n let result = { width, height, ratio: fill_ratio }\n // console.log result\n return result\n }\n\n // will update block state\n updateData() {\n let { blockProps } = this.props\n let { block } = this.props\n let { getEditorState } = this.props.blockProps\n let { setEditorState } = this.props.blockProps\n let data = block.getData()\n let newData = data.merge(this.state).merge({ forceUpload: false })\n return setEditorState(updateDataOfBlock(getEditorState(), block, newData))\n }\n\n replaceImg() {\n this.img = new Image()\n this.img.src = this.refs.image_tag.src\n this.setState({\n url: this.img.src })\n let self = this\n // exit only when not blob and not forceUload\n if (!this.img.src.includes(\"blob:\") && !this.props.block.data.get(\"forceUpload\")) {\n return\n }\n return this.img.onload = () => {\n this.setState({\n width: this.img.width,\n height: this.img.height,\n aspect_ratio: self.getAspectRatio(this.img.width, this.img.height)\n })\n\n return this.handleUpload()\n }\n }\n\n startLoader() {\n return this.setState({\n loading: true })\n }\n\n stopLoader() {\n return this.setState({\n loading: false })\n }\n\n handleUpload() {\n this.startLoader()\n this.props.blockProps.addLock()\n this.updateData()\n return this.uploadFile()\n }\n\n componentDidMount() {\n return this.replaceImg()\n }\n\n aspectRatio() {\n return {\n maxWidth: `${ this.state.aspect_ratio.width }`,\n maxHeight: `${ this.state.aspect_ratio.height }`,\n ratio: `${ this.state.aspect_ratio.height }`\n }\n }\n\n updateDataSelection() {\n const { getEditorState, setEditorState } = this.props.blockProps\n const newselection = getEditorState().getSelection().merge({\n anchorKey: this.props.block.getKey(),\n focusKey: this.props.block.getKey()\n })\n\n return setEditorState(EditorState.forceSelection(getEditorState(), newselection))\n }\n\n handleGrafFigureSelectImg(e) {\n e.preventDefault()\n return this.setState({ selected: true }, this.updateDataSelection)\n }\n\n //main_editor.onChange(main_editor.state.editorState)\n\n coords() {\n return {\n maxWidth: `${ this.state.aspect_ratio.width }px`,\n maxHeight: `${ this.state.aspect_ratio.height }px`\n }\n }\n\n getBase64Image(img) {\n let canvas = document.createElement(\"canvas\")\n canvas.width = img.width\n canvas.height = img.height\n let ctx = canvas.getContext(\"2d\")\n ctx.drawImage(img, 0, 0)\n let dataURL = canvas.toDataURL(\"image/png\")\n\n return dataURL\n }\n\n formatData() {\n let formData = new FormData()\n if (this.file) {\n let formName = this.config.upload_formName || 'file'\n\n formData.append(formName, this.file)\n return formData\n } else {\n formData.append('url', this.props.blockProps.data.get(\"url\"))\n return formData\n }\n }\n\n getUploadUrl() {\n let url = this.config.upload_url\n if (typeof url === \"function\") {\n return url()\n } else {\n return url\n }\n }\n\n getUploadHeaders() {\n return this.config.upload_headers || {}\n }\n\n uploadFile() {\n\n let handleUp\n // custom upload handler\n if (this.config.upload_handler) {\n return this.config.upload_handler(this.formatData().get('file'), this)\n }\n \n if (!this.config.upload_url){\n this.stopLoader()\n return\n }\n \n axios({\n method: 'post',\n url: this.getUploadUrl(),\n headers: this.getUploadHeaders(),\n data: this.formatData(),\n onUploadProgress: e => {\n return this.updateProgressBar(e)\n }\n }).then(result => {\n this.uploadCompleted(result.data.url)\n\n if (this.config.upload_callback) {\n return this.config.upload_callback(result, this)\n }\n }).catch(error => {\n this.uploadFailed()\n\n console.log(`ERROR: got error uploading file ${ error }`)\n if (this.config.upload_error_callback) {\n return this.config.upload_error_callback(error, this)\n }\n })\n\n return handleUp = json_response => {\n return this.uploadCompleted(json_response.url, n)\n }\n }\n\n uploadFailed() {\n this.props.blockProps.removeLock()\n this.stopLoader()\n }\n\n uploadCompleted(url) {\n this.setState({ url }, this.updateData)\n this.props.blockProps.removeLock()\n this.stopLoader()\n this.file = null\n }\n\n updateProgressBar(e) {\n let complete = this.state.loading_progress\n if (e.lengthComputable) {\n complete = e.loaded / e.total * 100\n complete = complete != null ? complete : { complete: 0 }\n this.setState({\n loading_progress: complete })\n return console.log(`complete: ${ complete }`)\n }\n }\n\n placeHolderEnabled() {\n return this.state.enabled || this.props.block.getText()\n }\n\n placeholderText() {\n return this.config.image_caption_placeholder\n }\n\n handleFocus(e) {\n\n }\n\n render() {\n\n return (\n <div ref=\"image_tag2\" suppressContentEditableWarning={true}>\n <div className=\"aspectRatioPlaceholder is-locked\" \n style={this.coords()} \n onClick={this.handleGrafFigureSelectImg}>\n <div style={{ paddingBottom: `${ this.state.aspect_ratio.ratio }%` }} \n className='aspect-ratio-fill' />\n <img src={this.state.url} \n ref=\"image_tag\" \n height={this.state.aspect_ratio.height} \n width={this.state.aspect_ratio.width} \n className='graf-image' />\n <Loader toggle={this.state.loading} \n progress={this.state.loading_progress} />\n </div>\n <figcaption className='imageCaption' onMouseDown={this.handleFocus}>\n { this.props.block.getText().length === 0 ? \n <span className=\"danteDefaultPlaceholder\">\n {this.placeholderText()}\n </span> : undefined}\n <EditorBlock {...Object.assign({}, this.props, { \n \"editable\": true, \"className\": \"imageCaption\" })\n } />\n </figcaption>\n </div>\n )\n }\n}\n\nclass Loader extends React.Component {\n\n render() {\n return (\n <div>\n { this.props.toggle\n ? <div className=\"image-upoader-loader\">\n <p>\n { this.props.progress === 100\n ? \"processing image...\"\n : <span>\n <span>loading</span> { Math.round( this.props.progress ) }\n </span>\n }\n </p>\n </div>\n : undefined\n }\n </div>\n )\n }\n}\n\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/blocks/image.js","\nimport React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport { Entity, RichUtils, AtomicBlockUtils, EditorBlock } from 'draft-js'\n\nexport default class PlaceholderBlock extends React.Component {\n constructor(props) {\n super(props)\n this.placeholderText = this.placeholderText.bind(this)\n this.placeholderFromProps = this.placeholderFromProps.bind(this)\n this.defaultText = this.defaultText.bind(this)\n this.placeholderRender = this.placeholderRender.bind(this)\n this.state = {\n enabled: false,\n data: this.props.blockProps.data.toJS()\n }\n }\n\n placeholderText() {\n //if (this.state.enabled) {\n // return \"\"\n //}\n return this.props.blockProps.data.toJS().placeholder || this.placeholderFromProps() || this.defaultText()\n }\n //if @.props.blockProps.data then @.props.blockProps.data.placeholder else @defaultText()\n\n\n placeholderFromProps() {\n return this.props.block.toJS().placeholder\n }\n\n defaultText() {\n return \"write something \"\n }\n\n placeholderRender(){\n if (this.props.block.text.length === 0 ) {\n return (\n <div className=\"public-DraftEditorPlaceholder-root\">\n <div className=\"public-DraftEditorPlaceholder-inner\">\n {this.placeholderText() }\n </div>\n </div>\n )\n\n }\n }\n\n render() {\n return (\n <span onMouseDown={this.handleFocus}>\n \n {this.placeholderRender()}\n \n <EditorBlock {...Object.assign({}, this.props, {\n \"className\": \"imageCaption\",\n \"placeholder\": \"escrive alalal\"\n })} />\n </span>\n )\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/blocks/placeholder.js","\nimport React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport { Entity, RichUtils, AtomicBlockUtils, EditorBlock } from 'draft-js'\n\nimport { updateDataOfBlock } from '../../model/index.js'\n\nimport axios from \"axios\"\n\nexport default class VideoBlock extends React.Component {\n constructor(props) {\n super(props)\n //api_key = \"86c28a410a104c8bb58848733c82f840\"\n\n this.updateData = this.updateData.bind(this)\n this.dataForUpdate = this.dataForUpdate.bind(this)\n this.state = { embed_data: this.defaultData() }\n }\n\n defaultData() {\n let existing_data = this.props.block.getData().toJS()\n return existing_data.embed_data || {}\n }\n\n // will update block state\n updateData() {\n const { block, blockProps } = this.props\n const { getEditorState, setEditorState } = this.props.blockProps\n const data = block.getData()\n const newData = data.merge(this.state)\n return setEditorState(updateDataOfBlock(getEditorState(), block, newData))\n }\n\n dataForUpdate() {\n return this.props.blockProps.data.toJS()\n }\n\n componentDidMount() {\n\n if (!this.props.blockProps.data) {\n return\n }\n // ensure data isnt already loaded\n if (!this.dataForUpdate().endpoint && !this.dataForUpdate().provisory_text) {\n return\n }\n\n return axios({\n method: 'get',\n url: `${ this.dataForUpdate().endpoint }${ this.dataForUpdate().provisory_text }&scheme=https`\n }).then(result => {\n return this.setState({ embed_data: result.data } //JSON.parse(data.responseText)\n , this.updateData)\n }).catch(error => {\n return console.log(\"TODO: error\")\n })\n }\n\n classForImage() {\n if (this.state.embed_data.thumbnail_url) {\n return \"\"\n } else {\n return \"mixtapeImage--empty u-ignoreBlock\"\n }\n }\n\n render() {\n return (\n <figure className='graf--figure graf--iframe graf--first' tabIndex='0'>\n <div className='iframeContainer' \n dangerouslySetInnerHTML={ { __html: this.state.embed_data.html } } />\n <figcaption className='imageCaption'>\n <EditorBlock {...Object.assign({}, this.props, { \"className\": \"imageCaption\" })} />\n </figcaption>\n </figure>\n )\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/blocks/video.js","import React from 'react'\nimport ReactDOM from 'react-dom'\nimport { Map, fromJS } from 'immutable'\nimport DanteEditor from './editor.js'\nimport DanteImagePopover from '../popovers/image'\nimport DanteAnchorPopover from '../popovers/link'\nimport DanteInlineTooltip from '../popovers/addButton'\nimport DanteTooltip from '../popovers/toolTip'\n\nimport ImageBlock from '../blocks/image'\nimport EmbedBlock from '../blocks/embed'\nimport VideoBlock from '../blocks/video'\nimport PlaceholderBlock from '../blocks/placeholder'\n\nimport { \n resetBlockWithType, \n addNewBlockAt \n} from '../../model/index.js'\n\nclass Dante {\n constructor(options) {\n if (options == null) {\n options = {}\n }\n console.log(\"init editor Dante!\")\n\n // deep merge on config\n let config = Map(fromJS(this.defaultOptions(options)))\n\n this.options = config.mergeDeep(options).toJS()\n console.log(this.options)\n }\n\n defaultOptions(options) {\n // default options\n if (options == null) {\n options = {}\n }\n let defaultOptions = {}\n defaultOptions.el = 'app'\n defaultOptions.content = \"\"\n defaultOptions.read_only = false\n defaultOptions.spellcheck = false\n defaultOptions.title_placeholder = \"Title\"\n defaultOptions.body_placeholder = \"Write your story\"\n\n defaultOptions.widgets = [{\n title: 'add an image',\n icon: 'image',\n type: 'image',\n block: ImageBlock,\n editable: true,\n renderable: true,\n breakOnContinuous: true,\n wrapper_class: \"graf graf--figure\",\n selected_class: \"is-selected is-mediaFocused\",\n selectedFn: block => {\n const { direction } = block.getData().toJS()\n switch (direction) {\n case \"left\":\n return \"graf--layoutOutsetLeft\"\n case \"center\":\n return \"\"\n case \"wide\":\n return \"sectionLayout--fullWidth\"\n case \"fill\":\n return \"graf--layoutFillWidth\"\n }\n },\n handleEnterWithoutText(ctx, block) {\n const { editorState } = ctx.state\n return ctx.onChange(addNewBlockAt(editorState, block.getKey()))\n },\n handleEnterWithText(ctx, block) {\n const { editorState } = ctx.state\n return ctx.onChange(addNewBlockAt(editorState, block.getKey()))\n },\n widget_options: {\n displayOnInlineTooltip: true,\n insertion: \"upload\",\n insert_block: \"image\"\n },\n options: {\n upload_url: options.upload_url,\n upload_headers: options.upload_headers,\n upload_formName: options.upload_formName,\n upload_handler: options.image_upload_handler,\n upload_callback: options.image_upload_callback,\n image_delete_callback: options.image_delete_callback,\n image_caption_placeholder: options.image_caption_placeholder || \"Write caption for image (optional)\"\n }\n }, {\n icon: 'embed',\n title: 'insert embed',\n type: 'embed',\n block: EmbedBlock,\n editable: true,\n renderable: true,\n breakOnContinuous: true,\n wrapper_class: \"graf graf--mixtapeEmbed\",\n selected_class: \"is-selected is-mediaFocused\",\n widget_options: {\n displayOnInlineTooltip: true,\n insertion: \"placeholder\",\n insert_block: \"embed\"\n },\n options: {\n endpoint: `//api.embed.ly/1/extract?key=${ options.api_key }&url=`,\n placeholder: 'Paste a link to embed content from another site (e.g. Twitter) and press Enter'\n },\n handleEnterWithoutText(ctx, block) {\n const { editorState } = ctx.state\n return ctx.onChange(addNewBlockAt(editorState, block.getKey()))\n },\n handleEnterWithText(ctx, block) {\n const { editorState } = ctx.state\n return ctx.onChange(addNewBlockAt(editorState, block.getKey()))\n }\n }, {\n icon: 'video',\n title: 'insert video',\n editable: true,\n type: 'video',\n block: VideoBlock,\n renderable: true,\n breakOnContinuous: true,\n wrapper_class: \"graf--figure graf--iframe\",\n selected_class: \" is-selected is-mediaFocused\",\n widget_options: {\n displayOnInlineTooltip: true,\n insertion: \"placeholder\",\n insert_block: \"video\"\n },\n options: {\n endpoint: `//api.embed.ly/1/oembed?key=${ options.api_key }&url=`,\n placeholder: 'Paste a YouTube, Vine, Vimeo, or other video link, and press Enter',\n caption: 'Type caption for embed (optional)'\n },\n\n handleEnterWithoutText(ctx, block) {\n const { editorState } = ctx.state\n return ctx.onChange(addNewBlockAt(editorState, block.getKey()))\n },\n\n handleEnterWithText(ctx, block) {\n const { editorState } = ctx.state\n return ctx.onChange(addNewBlockAt(editorState, block.getKey()))\n }\n }, {\n renderable: true,\n editable: true,\n block: PlaceholderBlock,\n type: 'placeholder',\n wrapper_class: \"is-embedable\",\n selected_class: \" is-selected is-mediaFocused\",\n widget_options: {\n displayOnInlineTooltip: false\n },\n handleEnterWithText(ctx, block) {\n const { editorState } = ctx.state\n const data = {\n provisory_text: block.getText(),\n endpoint: block.getData().get('endpoint'),\n type: block.getData().get('type')\n }\n if(block.getText().length > 0){\n return ctx.onChange(resetBlockWithType(editorState, data.type, data))\n }else{\n return ctx.onChange(resetBlockWithType(editorState, \"unstyled\", {}))\n }\n },\n\n handleEnterWithoutText(ctx, block) {\n const { editorState } = ctx.state\n return ctx.onChange(resetBlockWithType(editorState, data.type, data))\n\n //return ctx.onChange(resetBlockWithType(editorState, \"unstyled\", {}))\n //return ctx.onChange(addNewBlockAt(editorState, block.getKey()))\n },\n\n }]\n\n defaultOptions.tooltips = [{\n ref: 'insert_tooltip',\n component: DanteTooltip,\n displayOnSelection: true,\n selectionElements: [\"unstyled\", \n \"blockquote\", \n \"ordered-list\", \n \"unordered-list\", \n \"unordered-list-item\", \n \"ordered-list-item\", \n \"code-block\", \n 'header-one', \n 'header-two', \n 'header-three', \n 'header-four'],\n widget_options: {\n placeholder: \"Paste or type a link\",\n block_types: [\n // {label: 'p', style: 'unstyled'},\n { label: 'h2', style: 'header-one', type: \"block\" }, \n { label: 'h3', style: 'header-two', type: \"block\" }, \n { label: 'h4', style: 'header-three', type: \"block\" }, \n { label: 'blockquote', style: 'blockquote', type: \"block\" },\n { label: 'insertunorderedlist', style: 'unordered-list-item', type: \"block\" }, \n { label: 'insertorderedlist', style: 'ordered-list-item', type: \"block\" }, \n { label: 'code', style: 'code-block', type: \"block\" }, \n { label: 'bold', style: 'BOLD', type: \"inline\" }, \n { label: 'italic', style: 'ITALIC', type: \"inline\" }\n ]\n }\n }, {\n ref: 'add_tooltip',\n component: DanteInlineTooltip\n }, {\n ref: 'anchor_popover',\n component: DanteAnchorPopover\n }, {\n ref: 'image_popover',\n component: DanteImagePopover\n }]\n\n defaultOptions.xhr = {\n before_handler: null,\n success_handler: null,\n error_handler: null\n }\n\n defaultOptions.data_storage = {\n url: null,\n method: \"POST\",\n success_handler: null,\n failure_handler: null,\n interval: 1500,\n withCredentials: false,\n crossDomain: false,\n headers: {},\n }\n\n defaultOptions.default_wrappers = [\n { className: 'graf--p', block: 'unstyled' }, \n { className: 'graf--h2', block: 'header-one' },\n { className: 'graf--h3', block: 'header-two' }, \n { className: 'graf--h4', block: 'header-three' }, \n { className: 'graf--blockquote', block: 'blockquote' }, \n { className: 'graf--insertunorderedlist', block: 'unordered-list-item' }, \n { className: 'graf--insertorderedlist', block: 'ordered-list-item' }, \n { className: 'graf--code', block: 'code-block' }, \n { className: 'graf--bold', block: 'BOLD' }, \n { className: 'graf--italic', block: 'ITALIC' }]\n\n defaultOptions.continuousBlocks = [\n \"unstyled\", \n \"blockquote\", \n \"ordered-list\", \n \"unordered-list\", \n \"unordered-list-item\", \n \"ordered-list-item\", \n \"code-block\"\n ]\n\n defaultOptions.key_commands = {\n \"alt-shift\": [{ key: 65, cmd: 'add-new-block' }],\n \"alt-cmd\": [{ key: 49, cmd: 'toggle_block:header-one' }, \n { key: 50, cmd: 'toggle_block:header-two' }, \n { key: 53, cmd: 'toggle_block:blockquote' }],\n \"cmd\": [{ key: 66, cmd: 'toggle_inline:BOLD' }, \n { key: 73, cmd: 'toggle_inline:ITALIC' }, \n { key: 75, cmd: 'insert:link' }]\n }\n\n defaultOptions.character_convert_mapping = {\n '> ': \"blockquote\",\n '*.': \"unordered-list-item\",\n '* ': \"unordered-list-item\",\n '- ': \"unordered-list-item\",\n '1.': \"ordered-list-item\",\n '# ': 'header-one',\n '##': 'header-two',\n '==': \"unstyled\",\n '` ': \"code-block\"\n }\n\n return defaultOptions\n }\n\n getContent() {\n return this.options.content\n }\n\n render() {\n return this.editor = ReactDOM.render(\n <DanteEditor content={this.getContent()} config={this.options} />,\n document.getElementById(this.options.el)\n )\n }\n}\n\nexport default Dante\n\n\n// WEBPACK FOOTER //\n// src/components/core/dante.js","import React from 'react'\n\nclass Debug extends React.Component {\n\n constructor() {\n super()\n\n this.handleToggleReadOnly = this.handleToggleReadOnly.bind(this)\n this.handleTestEmitAndDecode = this.handleTestEmitAndDecode.bind(this)\n this.handleTestEmitTEXT = this.handleTestEmitTEXT.bind(this)\n this.testEmitAndDecode = this.testEmitAndDecode.bind(this)\n this.testEmitTEXT = this.testEmitTEXT.bind(this)\n this.logState = this.logState.bind(this)\n this.toggleDisplay = this.toggleDisplay.bind(this)\n this.open = this.open.bind(this)\n this.render = this.render.bind(this)\n this.state = {\n output: \"\",\n display: \"none\"\n }\n }\n\n handleToggleReadOnly(e) {\n e.preventDefault()\n this.props.editor.toggleEditable()\n return false\n }\n\n handleTestEmitAndDecode(e) {\n e.preventDefault()\n return this.testEmitAndDecode()\n }\n\n handleTestEmitTEXT(e) {\n e.preventDefault()\n return this.testEmitTEXT()\n }\n\n testEmitAndDecode(e) {\n const raw_as_json = this.props.editor.emitSerializedOutput()\n this.props.editor.setState({ \n editorState: this.props.editor.decodeEditorContent(raw_as_json) }, \n this.logState(JSON.stringify(raw_as_json)))\n return false\n }\n\n testEmitTEXT() {\n const text = this.props.editor.getTextFromEditor()\n return this.logState(text)\n }\n\n logState(raw) {\n return this.setState({ output: raw }, this.open)\n }\n\n toggleDisplay(e) {\n e.preventDefault()\n const d = this.state.display === \"block\" ? \"none\" : this.state.display\n return this.setState({\n display: d })\n }\n\n open() {\n return this.setState({\n display: \"block\" })\n }\n\n render() {\n return (\n <div>\n <div className=\"debugControls\">\n <ul>\n <li> LOCKS: { this.props.editor.state.locks } </li>\n <li>\n <a href=\"#\" onClick={ this.handleToggleReadOnly }>\n EDITABLE: { this.props.editor.state.read_only ? 'NO' : 'YES' }\n </a>\n </li>\n <li>\n <a href=\"#\" onClick={ this.handleTestEmitTEXT }>EDITOR TEXT</a>\n </li>\n <li>\n <a href=\"#\" onClick={ this.handleTestEmitAndDecode }>EDITOR STATE</a>\n </li>\n </ul>\n </div>\n <div className=\"debugZone\" style={ { display: this.state.display } }>\n <a href=\"#\" className=\"dante-debug-close close\" onClick={ this.toggleDisplay } />\n <div className=\"debugOutput\">\n <h2>EDITOR OUTPUT</h2>\n {\n this.state.output.length > 0\n ? <pre>{ this.state.output }</pre>\n : undefined\n }\n </div>\n </div>\n </div>\n )\n }\n}\n\nexport default Debug\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/core/debug.js","import React from 'react'\nimport { Entity } from 'draft-js'\n\nexport default class Link extends React.Component {\n\n constructor(props) {\n super(props)\n this._validateLink = this._validateLink.bind(this)\n this._checkProtocol = this._checkProtocol.bind(this)\n this._showPopLinkOver = this._showPopLinkOver.bind(this)\n this._hidePopLinkOver = this._hidePopLinkOver.bind(this)\n this.isHover = false\n }\n\n _validateLink() {\n const pattern = new RegExp('^(https?:\\/\\/)?' + // protocol\n '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name\n '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address\n '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path\n '(\\?[&a-z\\d%_.~+=-]*)?' + // query string\n '(\\#[-a-z\\d_]*)?$', 'i') // fragment locater\n if (!pattern.test(str)) {\n alert(\"Please enter a valid URL.\")\n return false\n } else {\n return true\n }\n }\n\n _checkProtocol() {\n return console.log(\"xcvd\")\n }\n\n _showPopLinkOver(e) {\n if (!this.data.showPopLinkOver) {\n return\n }\n return this.data.showPopLinkOver(this.refs.link)\n }\n\n _hidePopLinkOver(e) {\n if (!this.data.hidePopLinkOver) {\n return\n }\n return this.data.hidePopLinkOver()\n }\n\n render() {\n this.data = this.props.contentState.getEntity(this.props.entityKey).getData()\n //Entity.get(this.props.entityKey).getData()\n\n return (\n <a\n ref=\"link\"\n href={ this.data.url }\n className=\"markup--anchor\"\n onMouseOver={ this._showPopLinkOver }\n onMouseOut={ this._hidePopLinkOver }\n >\n { this.props.children }\n </a>\n )\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/decorators/link.js","\nimport Dante from './core/dante'\nimport DanteEditor from './core/editor'\n\nexport {\n Dante, \n DanteEditor\n}\n\n\n// WEBPACK FOOTER //\n// src/components/init.js","import React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport { \n Entity, \n RichUtils, \n AtomicBlockUtils, \n EditorState \n } from 'draft-js'\n\nimport { \n addNewBlock, \n resetBlockWithType, \n updateDataOfBlock, \n getCurrentBlock, \n getNode } from '../../model/index.js'\n\nimport { getSelectionRect, getSelection } from \"../../utils/selection.js\"\n\nclass DanteInlineTooltip extends React.Component {\n\n constructor(props) {\n super(props)\n\n this.display = this.display.bind(this)\n this.show = this.show.bind(this)\n this.hide = this.hide.bind(this)\n this._toggleScaled = this._toggleScaled.bind(this)\n this.scale = this.scale.bind(this)\n this.collapse = this.collapse.bind(this)\n this.componentWillReceiveProps = this.componentWillReceiveProps.bind(this)\n this.clickOnFileUpload = this.clickOnFileUpload.bind(this)\n this.handlePlaceholder = this.handlePlaceholder.bind(this)\n this.insertImage = this.insertImage.bind(this)\n this.handleFileInput = this.handleFileInput.bind(this)\n this.widgets = this.widgets.bind(this)\n this.clickHandler = this.clickHandler.bind(this)\n this.relocate = this.relocate.bind(this)\n this.state = {\n position: { top: 0, left: 0 },\n show: false,\n scaled: false\n }\n }\n\n display(b) {\n if (b) {\n return this.show()\n } else {\n return this.hide()\n }\n }\n\n show() {\n return this.setState({\n show: true })\n }\n\n hide() {\n return this.setState({\n show: false })\n }\n\n setPosition(coords) {\n return this.setState({\n position: coords })\n }\n\n _toggleScaled(ev) {\n if (this.state.scaled) {\n return this.collapse()\n } else {\n return this.scale()\n }\n }\n\n scale() {\n return this.setState({\n scaled: true })\n }\n\n collapse() {\n return this.setState({\n scaled: false })\n }\n\n componentWillReceiveProps(newProps) {\n return this.collapse()\n }\n\n activeClass() {\n //if @props.show then \"is-active\" else \"\"\n if (this.isActive()) {\n return \"is-active\"\n } else {\n return \"\"\n }\n }\n\n isActive() {\n return this.state.show\n }\n\n scaledClass() {\n if (this.state.scaled) {\n return \"is-scaled\"\n } else {\n return \"\"\n }\n }\n\n scaledWidth() {\n if (this.state.scaled) {\n return \"124\"\n } else {\n return \"0\"\n }\n }\n\n clickOnFileUpload() {\n this.refs.fileInput.click()\n this.collapse()\n return this.hide()\n }\n\n handlePlaceholder(input) {\n let opts = {\n type: input.widget_options.insert_block,\n placeholder: input.options.placeholder,\n endpoint: input.options.endpoint\n }\n\n return this.props.onChange(resetBlockWithType(this.props.editorState, 'placeholder', opts))\n }\n\n insertImage(file) {\n let opts = {\n url: URL.createObjectURL(file),\n file\n }\n\n return this.props.onChange(addNewBlock(this.props.editorState, 'image', opts))\n }\n\n handleFileInput(e) {\n let fileList = e.target.files\n // TODO: support multiple file uploads\n /*\n Object.keys(fileList).forEach (o)=>\n @.insertImage(fileList[0])\n */\n return this.insertImage(fileList[0])\n }\n\n handleInsertion(e){\n this.hide()\n return this.props.onChange(addNewBlock(this.props.editorState, e.type, {}))\n }\n\n widgets() {\n return this.props.editor.widgets\n }\n\n clickHandler(e, type) {\n let request_block = this.widgets().find(o => o.icon === type)\n\n switch (request_block.widget_options.insertion) {\n case \"upload\":\n return this.clickOnFileUpload(e, request_block)\n case \"placeholder\":\n return this.handlePlaceholder(request_block)\n case \"insertion\":\n return this.handleInsertion(request_block)\n default:\n return console.log(`WRONG TYPE FOR ${ request_block.widget_options.insertion }`)\n }\n }\n\n getItems() {\n return this.widgets().filter(o => {\n return o.widget_options.displayOnInlineTooltip\n })\n }\n\n isDescendant(parent, child) {\n let node = child.parentNode\n while (node !== null) {\n if (node === parent) {\n return true\n }\n node = node.parentNode\n }\n return false\n }\n\n relocate() {\n let { editorState } = this.props\n\n if (editorState.getSelection().isCollapsed()) {\n\n let currentBlock = getCurrentBlock(editorState)\n let blockType = currentBlock.getType()\n\n let contentState = editorState.getCurrentContent()\n let selectionState = editorState.getSelection()\n\n let block = contentState.getBlockForKey(selectionState.anchorKey)\n\n let nativeSelection = getSelection(window)\n if (!nativeSelection.rangeCount) {\n return\n }\n\n let node = getNode()\n\n let selectionBoundary = getSelectionRect(nativeSelection)\n let coords = selectionBoundary //utils.getSelectionDimensions(node)\n\n let parent = ReactDOM.findDOMNode(this.props.editor)\n let parentBoundary = parent.getBoundingClientRect()\n\n // hide if selected node is not in editor\n // debugger\n //console.log @isDescendant(parent, nativeSelection.anchorNode)\n\n if (!this.isDescendant(parent, nativeSelection.anchorNode)) {\n this.hide()\n return\n }\n\n if (!coords)\n return \n\n // checkeamos si esta vacio\n this.display(block.getText().length === 0 && blockType === \"unstyled\")\n return this.setPosition({\n top: coords.top + window.pageYOffset,\n left: coords.left + window.pageXOffset - 60\n })\n\n /*\n @refs.image_popover.display(blockType is \"image\")\n if blockType is \"image\"\n selectionBoundary = node.anchorNode.parentNode.parentNode.parentNode.getBoundingClientRect()\n *el = document.querySelector(\"#dante_image_popover\")\n el = @refs.image_popover.refs.image_popover\n padd = el.offsetWidth / 2\n @refs.image_popover.setPosition\n top: selectionBoundary.top - parentBoundary.top + 60\n left: selectionBoundary.left + (selectionBoundary.width / 2) - padd\n\n *@setState\n * image_popover_position:\n * top: selectionBoundary.top - parentBoundary.top + 60\n * left: selectionBoundary.left + (selectionBoundary.width / 2) - padd\n *\n */\n } else {\n return this.hide()\n }\n }\n\n render() {\n return (\n <div\n className={ `inlineTooltip ${ this.activeClass() } ${ this.scaledClass() }` }\n style={ this.state.position }\n >\n <button\n className=\"inlineTooltip-button control\"\n title=\"Close Menu\"\n data-action=\"inline-menu\"\n onClick={ this._toggleScaled }\n >\n <span className=\"tooltip-icon dante-icon-plus\" />\n </button>\n <div\n className=\"inlineTooltip-menu\"\n style={ { width: `${ this.scaledWidth() }px` } }\n >\n { this.getItems().map( (item, i) => {\n return <InlineTooltipItem\n item={ item }\n key={ i }\n clickHandler={ this.clickHandler }\n />\n })\n }\n <input\n type=\"file\"\n style={ { display: 'none' } }\n ref=\"fileInput\"\n multiple=\"multiple\"\n onChange={ this.handleFileInput }\n />\n </div>\n </div>\n )\n }\n}\n\nclass InlineTooltipItem extends React.Component {\n\n constructor(...args) {\n super(...args)\n this.clickHandler = this.clickHandler.bind(this)\n }\n\n clickHandler(e) {\n e.preventDefault()\n return this.props.clickHandler(e, this.props.item.icon)\n }\n\n render() {\n return (\n <button\n className=\"inlineTooltip-button scale\"\n title={ this.props.title }\n onMouseDown={ this.clickHandler }\n >\n <span className={ `tooltip-icon dante-icon-${ this.props.item.icon }` } />\n </button>\n )\n }\n}\n\nexport default DanteInlineTooltip\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/popovers/addButton.js","\nimport React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport { Entity, RichUtils, AtomicBlockUtils, EditorState } from 'draft-js'\n\nimport { getSelectionRect, getSelection } from \"../../utils/selection.js\"\n\nimport { getCurrentBlock, getNode } from '../../model/index.js'\n\nclass DanteImagePopover extends React.Component {\n\n constructor(props) {\n super(props)\n\n this.display = this.display.bind(this)\n this.show = this.show.bind(this)\n this.hide = this.hide.bind(this)\n this._toggleScaled = this._toggleScaled.bind(this)\n this.scale = this.scale.bind(this)\n this.collapse = this.collapse.bind(this)\n this.relocate = this.relocate.bind(this)\n this.componentWillReceiveProps = this.componentWillReceiveProps.bind(this)\n this.handleClick = this.handleClick.bind(this)\n this.state = {\n position: {\n top: 0,\n left: 0\n },\n show: false,\n scaled: false,\n buttons: [{ type: \"left\" }, \n { type: \"center\"}, \n { type: \"fill\" }, \n { type: \"wide\" }]\n }\n }\n\n display(b) {\n if (b) {\n return this.show()\n } else {\n return this.hide()\n }\n }\n\n show() {\n return this.setState({\n show: true })\n }\n\n hide() {\n return this.setState({\n show: false })\n }\n\n setPosition(coords) {\n return this.setState({\n position: coords })\n }\n\n _toggleScaled(ev) {\n if (this.state.scaled) {\n return this.collapse()\n } else {\n return this.scale()\n }\n }\n\n scale() {\n return this.setState({\n scaled: true })\n }\n\n collapse() {\n return this.setState({\n scaled: false })\n }\n\n relocate() {\n let { editorState } = this.props\n\n if (editorState.getSelection().isCollapsed()) {\n\n let currentBlock = getCurrentBlock(editorState)\n let blockType = currentBlock.getType()\n\n let contentState = editorState.getCurrentContent()\n let selectionState = editorState.getSelection()\n\n let block = contentState.getBlockForKey(selectionState.anchorKey)\n\n let nativeSelection = getSelection(window)\n if (!nativeSelection.rangeCount) {\n return\n }\n\n let node = getNode()\n\n let selectionBoundary = getSelectionRect(nativeSelection)\n let coords = selectionBoundary\n\n let parent = ReactDOM.findDOMNode(this.props.editor)\n let parentBoundary = parent.getBoundingClientRect()\n\n this.display(blockType === \"image\")\n\n if (blockType === \"image\") {\n selectionBoundary = node.anchorNode.parentNode.parentNode\n .parentNode.getBoundingClientRect()\n let el = this.refs.image_popover\n let padd = el.offsetWidth / 2\n return this.setPosition({\n top: selectionBoundary.top - parentBoundary.top + 60,\n left: selectionBoundary.left + selectionBoundary.width / 2 - padd\n })\n }\n } else {\n return this.hide()\n }\n }\n\n componentWillReceiveProps(newProps) {\n return this.collapse()\n }\n\n getStyle() {\n if (!this.state.position) {\n return {}\n }\n }\n\n handleClick(item) {\n return this.props.editor.setDirection(item.type)\n }\n\n render() {\n return (\n <div\n ref=\"image_popover\"\n className={ `dante-popover popover--Aligntooltip popover--top popover--animated ${ this.state.show ? 'is-active' : undefined }` }\n style={ \n { top: this.state.position.top,\n left: this.state.position.left }\n }\n >\n <div className='popover-inner'>\n <ul className='dante-menu-buttons'>\n { this.state.buttons.map( (item, i) => {\n return <DanteImagePopoverItem\n item={ item }\n handleClick={ this.handleClick }\n key={ i }\n />\n })\n }\n </ul>\n </div>\n <div className='popover-arrow' />\n </div>\n )\n }\n}\n\nclass DanteImagePopoverItem extends React.Component {\n\n constructor(...args) {\n super(...args)\n this.handleClick = this.handleClick.bind(this)\n this.render = this.render.bind(this)\n }\n\n handleClick(e) {\n e.preventDefault()\n return this.props.handleClick(this.props.item)\n }\n\n render() {\n return <li \n className={`dante-menu-button align-${ this.props.item.type }`} \n onMouseDown={this.handleClick}>\n <span className={`tooltip-icon dante-icon-image-${ this.props.item.type }`} />\n </li>\n }\n}\n\nexport default DanteImagePopover\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/popovers/image.js","\nimport React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport { getCurrentBlock } from '../../model/index.js'\n\nclass DanteAnchorPopover extends React.Component {\n\n constructor(props) {\n\n super(props)\n this.display = this.display.bind(this)\n this.show = this.show.bind(this)\n this.hide = this.hide.bind(this)\n this.relocate = this.relocate.bind(this)\n this.render = this.render.bind(this)\n this.state = {\n position: {\n top: 0,\n left: 0\n },\n show: false,\n url: \"\"\n }\n }\n\n display(b) {\n if (b) {\n return this.show()\n } else {\n return this.hide()\n }\n }\n\n show() {\n return this.setState({\n show: true })\n }\n\n hide() {\n return this.setState({\n show: false })\n }\n\n setPosition(coords) {\n return this.setState({\n position: coords })\n }\n\n relocate(node) {\n if (node == null) {\n node = null\n }\n if (!node) {\n return\n }\n\n let { editorState } = this.props\n let currentBlock = getCurrentBlock(editorState)\n let blockType = currentBlock.getType()\n\n let contentState = editorState.getCurrentContent()\n let selectionState = editorState.getSelection()\n\n let selectionBoundary = node.getBoundingClientRect()\n let coords = selectionBoundary\n\n let el = this.refs.dante_popover\n let padd = el.offsetWidth / 2\n\n let parent = ReactDOM.findDOMNode(this.props.editor)\n let parentBoundary = parent.getBoundingClientRect()\n\n return {\n top: selectionBoundary.top - parentBoundary.top + 160,\n left: selectionBoundary.left + selectionBoundary.width / 2 - padd\n }\n }\n\n render() {\n let { position } = this.state\n let style = {\n left: position.left,\n top: position.top,\n visibility: `${ this.state.show ? 'visible' : 'hidden' }`\n }\n return (\n <div\n ref=\"dante_popover\"\n className='dante-popover popover--tooltip popover--Linktooltip popover--bottom is-active'\n style={ style }\n onMouseOver={ this.props.handleOnMouseOver }\n onMouseOut={ this.props.handleOnMouseOut }\n >\n <div className='popover-inner'>\n <a href={ this.props.url } target='_blank'>\n { this.state.url }\n </a>\n </div>\n <div className='popover-arrow' />\n </div>\n )\n }\n}\n\nexport default DanteAnchorPopover\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/popovers/link.js","import React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport { \n convertToRaw, \n CompositeDecorator, \n getVisibleSelectionRect, \n getDefaultKeyBinding, \n getSelectionOffsetKeyForNode, \n KeyBindingUtil, \n ContentState, \n Editor, \n EditorState, \n Entity, \n RichUtils } from 'draft-js'\n\nimport { getSelectionRect, getSelection } from \"../../utils/selection.js\"\n\nimport { getCurrentBlock } from '../../model/index.js'\n\nclass DanteTooltip extends React.Component {\n\n constructor(props) {\n super(props)\n this._clickInlineHandler = this._clickInlineHandler.bind(this)\n this.display = this.display.bind(this)\n this.show = this.show.bind(this)\n this.hide = this.hide.bind(this)\n this.relocate = this.relocate.bind(this)\n this._clickBlockHandler = this._clickBlockHandler.bind(this)\n this.displayLinkMode = this.displayLinkMode.bind(this)\n this.displayActiveMenu = this.displayActiveMenu.bind(this)\n this._enableLinkMode = this._enableLinkMode.bind(this)\n this._disableLinkMode = this._disableLinkMode.bind(this)\n this.handleInputEnter = this.handleInputEnter.bind(this)\n this.confirmLink = this.confirmLink.bind(this)\n this.inlineItems = this.inlineItems.bind(this)\n this.blockItems = this.blockItems.bind(this)\n this.getDefaultValue = this.getDefaultValue.bind(this)\n this.getVisibleSelectionRect = getVisibleSelectionRect\n this.state = {\n link_mode: false,\n show: false,\n position: {}\n }\n }\n\n _clickInlineHandler(ev, style) {\n ev.preventDefault()\n\n this.props.onChange(RichUtils.toggleInlineStyle(this.props.editorState, style))\n\n return setTimeout(() => {\n return this.relocate()\n }, 0)\n }\n\n display(b) {\n if (b) {\n return this.show()\n } else {\n return this.hide()\n }\n }\n\n show() {\n return this.setState({\n show: true })\n }\n\n hide() {\n return this.setState({\n link_mode: false,\n show: false\n })\n }\n\n setPosition(coords) {\n return this.setState({\n position: coords })\n }\n\n isDescendant(parent, child) {\n let node = child.parentNode\n while (node !== null) {\n if (node === parent) {\n return true\n }\n node = node.parentNode\n }\n return false\n }\n\n relocate() {\n\n let currentBlock = getCurrentBlock(this.props.editorState)\n let blockType = currentBlock.getType()\n // display tooltip only for unstyled\n\n if (this.props.configTooltip.selectionElements.indexOf(blockType) < 0) {\n this.hide()\n return\n }\n\n if (this.state.link_mode) {\n return\n }\n if (!this.state.show) {\n return\n }\n\n let el = this.refs.dante_menu\n let padd = el.offsetWidth / 2\n\n let nativeSelection = getSelection(window)\n if (!nativeSelection.rangeCount) {\n return\n }\n\n let selectionBoundary = getSelectionRect(nativeSelection)\n\n let parent = ReactDOM.findDOMNode(this.props.editor)\n let parentBoundary = parent.getBoundingClientRect()\n\n // hide if selected node is not in editor\n if (!this.isDescendant(parent, nativeSelection.anchorNode)) {\n this.hide()\n return\n }\n\n let top = selectionBoundary.top - parentBoundary.top - -90 - 5\n let left = selectionBoundary.left + selectionBoundary.width / 2 - padd\n\n if (!top || !left) {\n return\n }\n\n // console.log \"SET SHOW FOR TOOLTIP INSERT MENU\"\n return this.setState({\n show: true,\n position: {\n left,\n top\n }\n })\n }\n\n _clickBlockHandler(ev, style) {\n ev.preventDefault()\n\n this.props.onChange(RichUtils.toggleBlockType(this.props.editorState, style))\n\n return setTimeout(() => {\n return this.relocate()\n }, 0)\n }\n\n displayLinkMode() {\n if (this.state.link_mode) {\n return \"dante-menu--linkmode\"\n } else {\n return \"\"\n }\n }\n\n displayActiveMenu() {\n if (this.state.show) {\n return \"dante-menu--active\"\n } else {\n return \"\"\n }\n }\n\n _enableLinkMode(ev) {\n ev.preventDefault()\n return this.setState({\n link_mode: true })\n }\n\n _disableLinkMode(ev) {\n ev.preventDefault()\n return this.setState({\n link_mode: false,\n url: \"\"\n })\n }\n\n hideMenu() {\n return this.hide()\n }\n\n handleInputEnter(e) {\n if (e.which === 13) {\n return this.confirmLink(e)\n }\n }\n\n confirmLink(e) {\n e.preventDefault()\n let { editorState } = this.props\n let urlValue = e.currentTarget.value\n let contentState = editorState.getCurrentContent()\n let selection = editorState.getSelection()\n\n let opts = {\n url: urlValue,\n showPopLinkOver: this.props.showPopLinkOver,\n hidePopLinkOver: this.props.hidePopLinkOver\n }\n \n let entityKey = Entity.create('LINK', 'MUTABLE', opts)\n //contentState.createEntity('LINK', 'MUTABLE', opts)\n\n if (selection.isCollapsed()) {\n console.log(\"COLLAPSED SKIPPING LINK\")\n return\n }\n\n this.props.onChange(RichUtils.toggleLink(editorState, selection, entityKey))\n\n return this._disableLinkMode(e)\n }\n\n getPosition() {\n let pos = this.state.position\n return pos\n }\n\n inlineItems() {\n return this.props.widget_options.block_types.filter(o => {\n return o.type === \"inline\"\n })\n }\n\n blockItems() {\n return this.props.widget_options.block_types.filter(o => {\n return o.type === \"block\"\n })\n }\n\n getDefaultValue() {\n if (this.refs.dante_menu_input) {\n this.refs.dante_menu_input.value = \"\"\n }\n \n let currentBlock = getCurrentBlock(this.props.editorState)\n let blockType = currentBlock.getType()\n let selection = this.props.editor.state.editorState.getSelection()\n let contentState = this.props.editorState.getCurrentContent()\n let selectedEntity = null\n let defaultUrl = null\n return currentBlock.findEntityRanges(character => {\n let entityKey = character.getEntity()\n selectedEntity = entityKey\n return entityKey !== null && contentState.getEntity(entityKey).getType() === 'LINK'\n }, (start, end) => {\n let selStart = selection.getAnchorOffset()\n let selEnd = selection.getFocusOffset()\n if (selection.getIsBackward()) {\n selStart = selection.getFocusOffset()\n selEnd = selection.getAnchorOffset()\n }\n\n if (start === selStart && end === selEnd) {\n defaultUrl = contentState.getEntity(selectedEntity).getData().url\n return this.refs.dante_menu_input.value = defaultUrl\n }\n })\n }\n\n render() {\n return (\n <div\n id=\"dante-menu\"\n ref=\"dante_menu\"\n className={ `dante-menu ${ this.displayActiveMenu() } ${ this.displayLinkMode() }` }\n style={ this.getPosition() }\n >\n <div className=\"dante-menu-linkinput\">\n <input\n className=\"dante-menu-input\"\n ref=\"dante_menu_input\"\n placeholder={this.props.widget_options.placeholder}\n onKeyPress={ this.handleInputEnter }\n defaultValue={ this.getDefaultValue() }\n />\n <div className=\"dante-menu-button\" onMouseDown={ this._disableLinkMode } />\n </div>\n <ul className=\"dante-menu-buttons\">\n { this.blockItems().map( (item, i) => {\n return <DanteTooltipItem\n key={ i }\n item={ item }\n handleClick={ this._clickBlockHandler }\n editorState={ this.props.editorState }\n type=\"block\"\n currentStyle={ this.props.editorState.getCurrentInlineStyle }\n />\n })\n }\n\n <DanteTooltipLink\n editorState={ this.props.editorState }\n enableLinkMode={ this._enableLinkMode }\n />\n\n\n { this.inlineItems().map( (item, i) => {\n return <DanteTooltipItem\n key={ i }\n item={ item }\n type=\"inline\"\n editorState={ this.props.editorState }\n handleClick={ this._clickInlineHandler }\n />\n })\n }\n </ul>\n </div>\n )\n }\n}\n\nclass DanteTooltipItem extends React.Component {\n\n constructor(...args) {\n super(...args)\n this.handleClick = this.handleClick.bind(this)\n this.activeClass = this.activeClass.bind(this)\n this.isActive = this.isActive.bind(this)\n this.activeClassInline = this.activeClassInline.bind(this)\n this.activeClassBlock = this.activeClassBlock.bind(this)\n this.render = this.render.bind(this)\n }\n\n handleClick(ev) {\n return this.props.handleClick(ev, this.props.item.style)\n }\n\n activeClass() {\n if (this.isActive()) {\n return \"active\"\n } else {\n return \"\"\n }\n }\n\n isActive() {\n if (this.props.type === \"block\") {\n return this.activeClassBlock()\n } else {\n return this.activeClassInline()\n }\n }\n\n activeClassInline() {\n if (!this.props.editorState) {\n return\n }\n //console.log @props.item\n return this.props.editorState.getCurrentInlineStyle().has(this.props.item.style)\n }\n\n activeClassBlock() {\n //console.log \"EDITOR STATE\", @props.editorState\n if (!this.props.editorState) {\n return\n }\n let selection = this.props.editorState.getSelection()\n let blockType = this.props.editorState.getCurrentContent().getBlockForKey(selection.getStartKey()).getType()\n return this.props.item.style === blockType\n }\n\n render() {\n return (\n <li className={ `dante-menu-button ${ this.activeClass() }` } onMouseDown={ this.handleClick }>\n <i className={ `dante-icon dante-icon-${ this.props.item.label }` } data-action=\"bold\" />\n </li>\n )\n }\n}\n\nclass DanteTooltipLink extends React.Component {\n\n constructor(...args) {\n super(...args)\n this.promptForLink = this.promptForLink.bind(this)\n }\n\n promptForLink(ev) {\n let selection = this.props.editorState.getSelection()\n if (!selection.isCollapsed()) {\n return this.props.enableLinkMode(ev)\n }\n }\n\n render() {\n return (\n <li className=\"dante-menu-button\" onMouseDown={ this.promptForLink }>\n <i className=\"dante-icon icon-createlink\" data-action=\"createlink\">link</i>\n </li>\n )\n }\n}\n\n\n\n\n\n\nexport default DanteTooltip\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/popovers/toolTip.js","import { Entity } from 'draft-js'\n\n//TODO: what the f*ck is happening here? ;-;\nconst findEntities = (entityType, instance, contentBlock, callback) => {\n return contentBlock.findEntityRanges((function(_this) {\n return function(character) {\n var entityKey, opts, res\n let contentState = instance.state.editorState.getCurrentContent()\n entityKey = character.getEntity()\n return (res = entityKey !== null && contentState.getEntity(entityKey).getType() === entityType, res ? (opts = {\n showPopLinkOver: instance.showPopLinkOver,\n hidePopLinkOver: instance.hidePopLinkOver\n }, contentState.mergeEntityData(entityKey, opts)) : void 0, res)\n }\n })(this), callback)\n}\n\nexport default findEntities\n\n\n// WEBPACK FOOTER //\n// src/utils/find_entities.js","import { ContentState, genKey, Entity, CharacterMetadata, ContentBlock, convertFromHTML, getSafeBodyFromHTML } from 'draft-js'\n\nimport { List, OrderedSet, Repeat, fromJS } from 'immutable'\n\n\n// { compose\n// } = require('underscore')\n\n// underscore compose function\nlet compose = function() {\n let args = arguments\n let start = args.length - 1\n return function() {\n let i = start\n let result = args[start].apply(this, arguments)\n while (i--) {\n result = args[i].call(this, result)\n }\n return result\n }\n}\n\n// from https://gist.github.com/N1kto/6702e1c2d89a33a15a032c234fc4c34e\n\n/*\n * Helpers\n */\n\n// Prepares img meta data object based on img attributes\nlet getBlockSpecForElement = imgElement=> {\n return {\n contentType: 'image',\n imgSrc: imgElement.getAttribute('src')\n }\n}\n\n// Wraps meta data in HTML element which is 'understandable' by Draft, I used <blockquote />.\nlet wrapBlockSpec = blockSpec=> {\n if (blockSpec === null) {\n return null\n }\n\n let tempEl = document.createElement('blockquote')\n // stringify meta data and insert it as text content of temp HTML element. We will later extract\n // and parse it.\n tempEl.innerText = JSON.stringify(blockSpec)\n return tempEl\n}\n\n// Replaces <img> element with our temp element\nlet replaceElement = (oldEl, newEl)=> {\n if (!(newEl instanceof HTMLElement)) {\n return\n }\n\n let upEl = getUpEl(oldEl)\n //parentNode = oldEl.parentNode\n //return parentNode.replaceChild(newEl, oldEl)\n return upEl.parentNode.insertBefore(newEl, upEl)\n}\n\nvar getUpEl = el=> {\n let original_el = el\n while (el.parentNode) {\n if (el.parentNode.tagName !== 'BODY') {\n el = el.parentNode\n }\n if (el.parentNode.tagName === 'BODY') { return el }\n }\n}\n\nlet elementToBlockSpecElement = compose(wrapBlockSpec, getBlockSpecForElement)\n\nlet imgReplacer = imgElement=> {\n return replaceElement(imgElement, elementToBlockSpecElement(imgElement))\n}\n\n/*\n * Main function\n */\n\n// takes HTML string and returns DraftJS ContentState\nlet customHTML2Content = function(HTML, blockRn){\n let tempDoc = new DOMParser().parseFromString(HTML, 'text/html')\n // replace all <img /> with <blockquote /> elements\n\n let a = tempDoc.querySelectorAll('img').forEach( item=> imgReplacer(item))\n\n // use DraftJS converter to do initial conversion. I don't provide DOMBuilder and\n // blockRenderMap arguments here since it should fall back to its default ones, which are fine\n console.log(tempDoc.body.innerHTML)\n let content = convertFromHTML(tempDoc.body.innerHTML,\n getSafeBodyFromHTML,\n blockRn\n )\n\n let contentBlocks = content.contentBlocks\n\n // now replace <blockquote /> ContentBlocks with 'atomic' ones\n contentBlocks = contentBlocks.map(function(block){\n let newBlock\n console.log(\"CHECK BLOCK\", block.getType())\n if (block.getType() !== 'blockquote') {\n return block\n }\n\n let json = \"\"\n try {\n json = JSON.parse(block.getText())\n } catch (error) {\n return block\n }\n\n return newBlock = block.merge({\n type: \"image\",\n text: \"\",\n data: {\n url: json.imgSrc,\n forceUpload: true\n }\n })\n })\n\n tempDoc = null\n return ContentState.createFromBlockArray(contentBlocks)\n}\n\n\nexport default customHTML2Content\n\n\n// WEBPACK FOOTER //\n// src/utils/html2content.js","import axios from \"axios\"\nimport Immutable from 'immutable'\n\nclass SaveBehavior {\n constructor(options) {\n this.getLocks = options.getLocks\n this.config = options.config\n this.editorContent = options.editorContent\n this.editorState = options.editorState\n }\n\n handleStore(ev){\n return this.store()\n }\n\n store(content){\n if (!this.config.data_storage.url) { return }\n if (this.getLocks() > 0) { return }\n\n clearTimeout(this.timeout)\n\n return this.timeout = setTimeout(() => {\n return this.checkforStore(content)\n }\n , this.config.data_storage.interval)\n }\n\n getTextFromEditor(content){\n return content.blocks.map(o=> {\n return o.text\n }\n )\n .join(\"\\n\")\n }\n\n getUrl() {\n let { url } = this.config.data_storage\n if (typeof(url) === \"function\") { \n return url() \n } else { \n return url \n }\n }\n\n getMethod() {\n let { method } = this.config.data_storage\n if (typeof(method) === \"function\") { \n return method() \n } else { \n return method \n }\n }\n\n getWithCredentials(){\n let { withCredentials } = this.config.data_storage\n if (typeof(withCredentials) === \"function\") { \n return withCredentials() \n } else { \n return withCredentials \n }\n }\n\n getCrossDomain(){\n let { crossDomain } = this.config.data_storage\n if (typeof(crossDomain) === \"function\") { \n return crossDomain()\n } else { \n return crossDomain \n }\n }\n\n getHeaders(){\n let { headers } = this.config.data_storage\n if (typeof(headers) === \"function\") { \n return headers() \n } else { \n return headers \n }\n }\n\n checkforStore(content){\n // ENTER DATA STORE\n let isChanged = !Immutable.is(Immutable.fromJS(this.editorContent), Immutable.fromJS(content))\n // console.log(\"CONTENT CHANGED:\", isChanged)\n\n if (!isChanged) { return }\n\n this.save(content)\n }\n\n save(content){\n\n // use save handler from config if exists\n if (this.config.data_storage.save_handler){\n this.config.data_storage.save_handler(this, content)\n return \n }\n\n if (this.config.xhr.before_handler) { this.config.xhr.before_handler() }\n // console.log \"SAVING TO: #{@getMethod()} #{@getUrl()}\"\n\n return axios({\n method: this.getMethod(),\n url: this.getUrl(),\n data: {\n editor_content: JSON.stringify(content),\n text_content: this.getTextFromEditor(content)\n },\n withCredentials: this.getWithCredentials(),\n crossDomain: this.getCrossDomain(),\n headers: this.getHeaders(),\n })\n .then(result=> {\n // console.log \"STORING CONTENT\", result\n if (this.config.data_storage.success_handler) { this.config.data_storage.success_handler(result) }\n if (this.config.xhr.success_handler) { return this.config.xhr.success_handler(result) }\n }\n )\n .catch(error=> {\n // console.log(\"ERROR: got error saving content at #{@config.data_storage.url} - #{error}\")\n if (this.config.xhr.failure_handler) { return this.config.xhr.failure_handler(error) }\n }\n )\n }\n}\n\n\nexport default SaveBehavior\n\n\n\n// WEBPACK FOOTER //\n// src/utils/save_content.js","import { Map } from 'immutable';\n\n\n\nimport { EditorState, ContentBlock, genKey } from 'draft-js';\n\n\n/*\nUsed from [react-rte](https://github.com/brijeshb42/medium-draft)\nby [brijeshb42](https://github.com/brijeshb42/medium-draft)\n*/\n\n/*\nReturns default block-level metadata for various block type. Empty object otherwise.\n*/\nexport const getDefaultBlockData = (blockType, initialData = {}) => {\n switch (blockType) {\n //case Block.TODO: return { checked: false };\n default: return initialData;\n }\n};\n\nexport const getNode = (root=window) => {\n let t = null\n if (root.getSelection){\n t = root.getSelection()\n } else if (root.document.getSelection){\n t = root.document.getSelection()\n } else if (root.document.selection){\n t = root.document.selection.createRange().text\n }\n return t\n}\n\n/*\nGet currentBlock in the editorState.\n*/\nexport const getCurrentBlock = (editorState) => {\n const selectionState = editorState.getSelection();\n const contentState = editorState.getCurrentContent();\n const block = contentState.getBlockForKey(selectionState.getStartKey());\n return block;\n};\n\n/*\nAdds a new block (currently replaces an empty block) at the current cursor position\nof the given `newType`.\n*/\nexport const addNewBlock = (editorState, newType = \"unstyled\", initialData = {}) => {\n const selectionState = editorState.getSelection();\n if (!selectionState.isCollapsed()) {\n return editorState;\n }\n const contentState = editorState.getCurrentContent();\n const key = selectionState.getStartKey();\n const blockMap = contentState.getBlockMap();\n const currentBlock = getCurrentBlock(editorState);\n if (!currentBlock) {\n return editorState;\n }\n if (currentBlock.getLength() === 0) {\n if (currentBlock.getType() === newType) {\n return editorState;\n }\n const newBlock = currentBlock.merge({\n type: newType,\n data: getDefaultBlockData(newType, initialData),\n });\n const newContentState = contentState.merge({\n blockMap: blockMap.set(key, newBlock),\n selectionAfter: selectionState,\n });\n return EditorState.push(editorState, newContentState, 'change-block-type');\n }\n return editorState;\n};\n\n\n/*\nChanges the block type of the current block.\n*/\nexport const resetBlockWithType = (editorState, newType = \"unstyled\", data={}) => {\n const contentState = editorState.getCurrentContent();\n const selectionState = editorState.getSelection();\n const key = selectionState.getStartKey();\n const blockMap = contentState.getBlockMap();\n const block = blockMap.get(key);\n\n const text = block.getText();\n\n const newBlock = block.merge({\n text: text,\n type: newType,\n data: getDefaultBlockData(newType, data),\n });\n const newContentState = contentState.merge({\n blockMap: blockMap.set(key, newBlock),\n selectionAfter: selectionState.merge({\n anchorOffset: 0,\n focusOffset: 0,\n }),\n });\n return EditorState.push(editorState, newContentState, 'change-block-type');\n};\n\n\n/*\nUpdate block-level metadata of the given `block` to the `newData`/\n*/\nexport const updateDataOfBlock = (editorState, block, newData) => {\n const contentState = editorState.getCurrentContent();\n const newBlock = block.merge({\n data: newData,\n });\n const newContentState = contentState.merge({\n blockMap: contentState.getBlockMap().set(block.getKey(), newBlock),\n });\n return EditorState.push(editorState, newContentState, 'change-block-type');\n // return editorState;\n};\n\nexport const updateTextOfBlock = (editorState, block, text) => {\n const contentState = editorState.getCurrentContent();\n const newBlock = block.merge({\n text: text,\n });\n const newContentState = contentState.merge({\n blockMap: contentState.getBlockMap().set(block.getKey(), newBlock),\n });\n\n return EditorState.push(editorState, newContentState, 'change-block-type');\n // return editorState;\n};\n\n// const BEFORE = -1;\n// const AFTER = 1;\n\n/*\nUsed from [react-rte](https://github.com/sstur/react-rte/blob/master/src/lib/insertBlockAfter.js)\nby [sstur](https://github.com/sstur)\n*/\nexport const addNewBlockAt = (\n editorState,\n pivotBlockKey,\n newBlockType = \"unstyled\",\n initialData = {}\n ) => {\n const content = editorState.getCurrentContent();\n const blockMap = content.getBlockMap();\n const block = blockMap.get(pivotBlockKey);\n const blocksBefore = blockMap.toSeq().takeUntil((v) => (v === block));\n const blocksAfter = blockMap.toSeq().skipUntil((v) => (v === block)).rest();\n const newBlockKey = genKey();\n\n const newBlock = new ContentBlock({\n key: newBlockKey,\n type: newBlockType,\n text: '',\n characterList: block.getCharacterList().slice(0, 0),\n depth: 0,\n data: Map(getDefaultBlockData(newBlockType, initialData)),\n });\n\n const newBlockMap = blocksBefore.concat(\n [[pivotBlockKey, block], [newBlockKey, newBlock]],\n blocksAfter\n ).toOrderedMap();\n\n const selection = editorState.getSelection();\n\n const newContent = content.merge({\n blockMap: newBlockMap,\n selectionBefore: selection,\n selectionAfter: selection.merge({\n anchorKey: newBlockKey,\n anchorOffset: 0,\n focusKey: newBlockKey,\n focusOffset: 0,\n isBackward: false,\n }),\n });\n return EditorState.push(editorState, newContent, 'split-block');\n};\n\n\n\n// WEBPACK FOOTER //\n// src/model/index.js","module.exports = __webpack_public_path__ + \"fonts/dante.svg\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/fonts/dante/dante.svg\n// module id = 429\n// module chunks = 0","module.exports = __webpack_public_path__ + \"fonts/dante.ttf\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/fonts/dante/dante.ttf\n// module id = 430\n// module chunks = 0","module.exports = __webpack_public_path__ + \"fonts/dante.woff\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/fonts/dante/dante.woff\n// module id = 431\n// module chunks = 0","module.exports = __webpack_public_path__ + \"fonts/fontello.svg\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/fonts/dante/fontello.svg\n// module id = 432\n// module chunks = 0","module.exports = __webpack_public_path__ + \"fonts/fontello.ttf\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/fonts/dante/fontello.ttf\n// module id = 433\n// module chunks = 0","module.exports = __webpack_public_path__ + \"fonts/fontello.woff\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/fonts/dante/fontello.woff\n// module id = 434\n// module chunks = 0","/*\nReturns the `boundingClientRect` of the passed selection.\n*/\nexport const getSelectionRect = (selected) => {\n const _rect = selected.getRangeAt(0).getBoundingClientRect();\n // selected.getRangeAt(0).getBoundingClientRect()\n let rect = _rect && _rect.top ? _rect : selected.getRangeAt(0).getClientRects()[0];\n if (!rect) {\n if (selected.anchorNode && selected.anchorNode.getBoundingClientRect) {\n rect = selected.anchorNode.getBoundingClientRect();\n rect.isEmptyline = true;\n } else {\n return null;\n }\n }\n return rect;\n};\n\n/*\nReturns the native selection node.\n*/\nexport const getSelection = (root) => {\n let t = null;\n if (root.getSelection) {\n t = root.getSelection();\n } else if (root.document.getSelection) {\n t = root.document.getSelection();\n } else if (root.document.selection) {\n t = root.document.selection.createRange().text;\n }\n return t;\n};\n\n/*\nRecursively finds the DOM Element of the block where the cursor is currently present.\nIf not found, returns null.\n*/\nexport const getSelectedBlockNode = (root) => {\n const selection = root.getSelection();\n if (selection.rangeCount === 0) {\n return null;\n }\n let node = selection.getRangeAt(0).startContainer;\n // console.log(node);\n do {\n if (node.getAttribute && node.getAttribute('data-block') === 'true') {\n return node;\n }\n node = node.parentNode;\n // console.log(node);\n } while (node !== null);\n return null;\n};\n\n\n\n// WEBPACK FOOTER //\n// src/utils/selection.js"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AACA;AACA;AAcA;AACA;AAIA;AACA;AAQA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;;;AAEA;;;AACA;AAAA;AACA;AADA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AACA;AAIA;AACA;AACA;AADA;AAGA;AACA;AADA;AAGA;AACA;AADA;AAGA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AACA;AAnBA;AACA;AAwBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AALA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AAPA;AACA;AAzGA;AAAA;AAAA;AAAA;AACA;AACA;AAiHA;AACA;AApHA;AAqHA;AACA;;;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AARA;AAUA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;;;AAEA;AACA;AACA;AACA;AAAA;AAAA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAVA;AAHA;AACA;AAgBA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AAFA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAfA;AAiBA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AALA;AAHA;AACA;AAWA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAFA;AACA;AAIA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAFA;AACA;AAIA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AACA;AACA;AACA;AACA;AAJA;AACA;AAMA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AAAA;AAAA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AADA;AAGA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAlBA;AAHA;AADA;AAJA;AADA;AADA;AADA;AADA;AAwCA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAZA;AAeA;AAGA;AA7DA;AAoEA;;;AAr3BA;AACA;AAu3BA;;;;;;;ACl6BA;;;;;;;ACAA;;;;;;;;;;;;;;;ACCA;AACA;AACA;AACA;AACA;AAEA;AACA;;;;;;;ACRA;;;;;;;;;;ACAA;AACA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACAA;AACA;;;AAAA;AACA;;;AACA;AACA;AACA;AACA;;;AACA;AACA;;;AACA;;;AACA;AAAA;AACA;AACA;AACA;AAHA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAFA;AAPA;AAWA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AACA;AAIA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAJA;AAQA;AACA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AACA;AACA;AACA;AAHA;AAKA;AAAA;AAAA;AACA;AADA;AAGA;AAAA;AAAA;AACA;AADA;AARA;AAWA;AAzBA;AA4BA;;;AAjHA;AACA;AADA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACVA;AACA;;;AAAA;AACA;;;AACA;AACA;AAMA;AACA;;;AACA;AACA;;;AACA;;;AAEA;AAAA;AACA;AADA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAVA;AA3BA;AAuCA;AACA;;;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AACA;AACA;AACA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAIA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AAHA;AAKA;;;AAEA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAFA;AACA;AAIA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA;AACA;AACA;AACA;AAFA;AAIA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;;;AAIA;AACA;AACA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAXA;AAaA;AAAA;AAAA;AACA;AACA;AAAA;AACA;AADA;AAGA;AACA;AANA;AAdA;AAyBA;;;AAzVA;AACA;AADA;AACA;AA2VA;;;;;;;;;;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAEA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AADA;AACA;AADA;AAHA;AADA;AAFA;AAgBA;;;AApBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzWA;AACA;;;AAAA;AACA;;;AACA;AACA;;;AACA;;;AACA;AAAA;AACA;AADA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AANA;AAUA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AADA;AADA;AAOA;AACA;;;AAEA;AACA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AAFA;AAJA;AAUA;;;AAvDA;AACA;AADA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACLA;AACA;;;AAAA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AACA;;;AACA;AAAA;AACA;AACA;AACA;AAHA;AACA;AAGA;AACA;AACA;AANA;AAOA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAAA;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAAA;AACA;AADA;AAHA;AAQA;;;AAnEA;AACA;AADA;;;;;;;;;;;;;;;;;;;;;;ACVA;AACA;;;AAAA;AACA;;;AAAA;AACA;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AACA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AACA;AACA;;;AAIA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AARA;AAUA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AApCA;AA8CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AAFA;AAIA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AA1BA;AA4BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AAHA;AACA;AAKA;AAAA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AA7BA;AA+BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AA9BA;AACA;AAiCA;AACA;AACA;AACA;AACA;AAWA;AACA;AACA;AACA;AACA;AAJA;AAfA;AA+BA;AACA;AAFA;AAIA;AACA;AAFA;AAIA;AACA;AAFA;AACA;AAIA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AARA;AACA;AAUA;AACA;AAWA;AACA;AASA;AACA;AACA;AAGA;AALA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AATA;AACA;AAWA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AAIA;;;;;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3SA;AACA;;;;;AACA;;;AAEA;AAAA;AACA;AADA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAZA;AAgBA;AACA;;;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AADA;AADA;AAKA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AADA;AAGA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AADA;AAVA;AADA;AAgBA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAEA;AACA;AAAA;AAAA;AAAA;AAJA;AAFA;AAjBA;AA8BA;;;AAjGA;AACA;AAmGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtGA;AACA;;;AAAA;AACA;;;AACA;;;AAEA;AAAA;AACA;AADA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AAOA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AALA;AAOA;AAPA;AAUA;;;AA3DA;AACA;AADA;;;;;;;;;;;;;;;ACFA;AACA;;;AAAA;AACA;;;;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACNA;AACA;;;AAAA;AACA;;;AACA;AACA;AAMA;AACA;AAMA;AACA;;;AACA;;;AAEA;AAAA;AACA;AADA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAjBA;AAsBA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;;;AAEA;AACA;AACA;AACA;AAFA;AACA;AAIA;AACA;;;AAEA;AACA;AACA;AACA;;;;AAIA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AARA;AAUA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAFA;AACA;AAIA;;;;;;;;;;;;;;;;AAiBA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAFA;AAIA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAJA;AAMA;AANA;AAQA;AAAA;AAAA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AACA;AAHA;AAKA;AAEA;AACA;AACA;AACA;AACA;AACA;AALA;AAZA;AAZA;AAkCA;;;AAvRA;AACA;AAyRA;;;AAEA;AAAA;AACA;AADA;AACA;AADA;AAAA;AAAA;AACA;AADA;AACA;AACA;AAFA;AAGA;AACA;;;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAHA;AAKA;AALA;AAQA;;;AAtBA;AACA;AAwBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrUA;AACA;;;AAAA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA;;;AAEA;AAAA;AACA;AADA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAPA;AAZA;AAwBA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAEA;AALA;AAQA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AAPA;AADA;AAYA;AApBA;AAuBA;;;AAvJA;AACA;AAyJA;;;AAEA;AAAA;AACA;AADA;AACA;AADA;AAAA;AAAA;AACA;AADA;AACA;AACA;AACA;AAHA;AAIA;AACA;;;AACA;AACA;AACA;AACA;;;AAEA;AACA;AAAA;AAAA;AACA;AACA;AACA;AAHA;AAKA;;;AAnBA;AACA;AAqBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzLA;AACA;;;AAAA;AACA;;;AACA;AACA;;;AACA;;;AAEA;AAAA;AACA;AADA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AANA;AARA;AAgBA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AALA;AAOA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AADA;AADA;AAKA;AAZA;AAeA;;;AAhGA;AACA;AAkGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzGA;AACA;;;AAAA;AACA;;;AACA;AACA;AAYA;AACA;AACA;AACA;;;AACA;;;AAEA;AAAA;AACA;AADA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAlBA;AAuBA;AACA;;;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AAFA;AAIA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAFA;AAOA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AADA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAJA;AAMA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AALA;AAOA;AARA;AAUA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AAQA;AAGA;AACA;AACA;AAFA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AALA;AAOA;AA3BA;AAhBA;AAgDA;;;AA5SA;AACA;AA8SA;;;AAEA;AAAA;AACA;AADA;AACA;AADA;AAAA;AAAA;AACA;AADA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AAQA;AACA;;;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AAAA;AACA;AADA;AAIA;;;AAxDA;AACA;AA0DA;;;AAEA;AAAA;AACA;AADA;AACA;AADA;AAAA;AAAA;AACA;AADA;AACA;AACA;AAFA;AAGA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AADA;AAIA;;;AApBA;AACA;AA2BA;;;;;;;;;;;;;;AC1ZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAHA;AAQA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;AChIA;AACA;;;AAAA;AACA;;;;;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;;;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;AAEA;AACA;AACA;AACA;AAGA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AATA;AAYA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAGA;AACA;AAAA;AAAA;AACA;AAEA;;;;;AAIA;;;;;;;;;;;;;;;AC/HA;AACA;AAGA;AACA;AAEA;;;;;AAKA;;;AAGA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AAFA;AAIA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AAFA;AAFA;AAOA;AACA;AACA;AAEA;;;AAGA;AACA;AACA;AACA;AADA;AAGA;AACA;AADA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AACA;AADA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AAKA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AACA;AAQA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AALA;AAHA;AAWA;AACA;;;;;;;ACtLA;;;;;;;ACAA;;;;;;;ACAA;;;;;;;ACAA;;;;;;;ACAA;;;;;;;ACAA;;;;;;;;;;;;;ACAA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;A","sourceRoot":""}
1
+ {"version":3,"file":"dante.js","sources":["webpack:///src/components/core/editor.js","webpack:///./src/styles/fonts/dante/dante.eot","webpack:///./src/styles/fonts/dante/fontello.eot","webpack:///src/index.js","webpack:///./src/styles/dante.scss?293d","webpack:///demo/initialize.js","webpack:///src/components/blocks/embed.js","webpack:///src/components/blocks/image.js","webpack:///src/components/blocks/placeholder.js","webpack:///src/components/blocks/video.js","webpack:///src/components/core/dante.js","webpack:///src/components/core/debug.js","webpack:///src/components/decorators/link.js","webpack:///src/components/init.js","webpack:///src/components/popovers/addButton.js","webpack:///src/components/popovers/image.js","webpack:///src/components/popovers/link.js","webpack:///src/components/popovers/toolTip.js","webpack:///src/utils/find_entities.js","webpack:///src/utils/html2content.js","webpack:///src/utils/save_content.js","webpack:///src/model/index.js","webpack:///./src/styles/fonts/dante/dante.svg","webpack:///./src/styles/fonts/dante/dante.ttf","webpack:///./src/styles/fonts/dante/dante.woff","webpack:///./src/styles/fonts/dante/fontello.svg","webpack:///./src/styles/fonts/dante/fontello.ttf","webpack:///./src/styles/fonts/dante/fontello.woff","webpack:///src/utils/selection.js"],"sourcesContent":["\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport Immutable from 'immutable'\nimport { Map, fromJS } from 'immutable'\nimport { \n convertToRaw, \n convertFromRaw, \n CompositeDecorator, \n getDefaultKeyBinding,\n ContentState, \n Editor, \n EditorState, \n Entity, \n RichUtils, \n DefaultDraftBlockRenderMap, \n SelectionState, \n Modifier\n} from 'draft-js'\n\nimport { \n convertToHTML,\n //, convertFromHTML \n} from 'draft-convert'\n\nimport { \n addNewBlock, \n resetBlockWithType, \n updateDataOfBlock, \n //updateTextOfBlock, \n getCurrentBlock, \n addNewBlockAt \n} from '../../model/index.js'\n\nimport Link from '../decorators/link'\nimport Debug from '../core/debug'\nimport findEntities from '../../utils/find_entities'\nimport SaveBehavior from '../../utils/save_content'\nimport customHTML2Content from '../../utils/html2content'\nimport createStyles from 'draft-js-custom-styles'\n\n\nclass DanteEditor extends React.Component {\n constructor(props) {\n super(props)\n\n this.initializeState = this.initializeState.bind(this)\n this.refreshSelection = this.refreshSelection.bind(this)\n this.forceRender = this.forceRender.bind(this)\n this.onChange = this.onChange.bind(this)\n this.dispatchChangesToSave = this.dispatchChangesToSave.bind(this)\n this.setPreContent = this.setPreContent.bind(this)\n this.focus = this.focus.bind(this)\n this.getEditorState = this.getEditorState.bind(this)\n this.emitSerializedOutput = this.emitSerializedOutput.bind(this)\n this.decodeEditorContent = this.decodeEditorContent.bind(this)\n this.getTextFromEditor = this.getTextFromEditor.bind(this)\n this.getLocks = this.getLocks.bind(this)\n this.addLock = this.addLock.bind(this)\n this.removeLock = this.removeLock.bind(this)\n this.renderableBlocks = this.renderableBlocks.bind(this)\n this.defaultWrappers = this.defaultWrappers.bind(this)\n this.blockRenderer = this.blockRenderer.bind(this)\n this.handleBlockRenderer = this.handleBlockRenderer.bind(this)\n this.blockStyleFn = this.blockStyleFn.bind(this)\n this.getDataBlock = this.getDataBlock.bind(this)\n this.styleForBlock = this.styleForBlock.bind(this)\n this.handlePasteText = this.handlePasteText.bind(this)\n this.handleTXTPaste = this.handleTXTPaste.bind(this)\n this.handleHTMLPaste = this.handleHTMLPaste.bind(this)\n this.handlePasteImage = this.handlePasteImage.bind(this)\n this.handleDroppedFiles = this.handleDroppedFiles.bind(this)\n this.handleDrop = this.handleDrop.bind(this)\n this.handleUpArrow = this.handleUpArrow.bind(this)\n this.handleDownArrow = this.handleDownArrow.bind(this)\n this.handleReturn = this.handleReturn.bind(this)\n this.handleBeforeInput = this.handleBeforeInput.bind(this)\n this.handleKeyCommand = this.handleKeyCommand.bind(this)\n this.findCommandKey = this.findCommandKey.bind(this)\n this.KeyBindingFn = this.KeyBindingFn.bind(this)\n this.updateBlockData = this.updateBlockData.bind(this)\n this.setDirection = this.setDirection.bind(this)\n this.toggleEditable = this.toggleEditable.bind(this)\n this.disableEditable = this.disableEditable.bind(this)\n this.enableEditable = this.enableEditable.bind(this)\n this.closePopOvers = this.closePopOvers.bind(this)\n this.relocateTooltips = this.relocateTooltips.bind(this)\n this.tooltipsWithProp = this.tooltipsWithProp.bind(this)\n this.tooltipHasSelectionElement = this.tooltipHasSelectionElement.bind(this)\n this.handleShowPopLinkOver = this.handleShowPopLinkOver.bind(this)\n this.handleHidePopLinkOver = this.handleHidePopLinkOver.bind(this)\n this.showPopLinkOver = this.showPopLinkOver.bind(this)\n this.hidePopLinkOver = this.hidePopLinkOver.bind(this)\n this.render = this.render.bind(this)\n\n this.decorator = new CompositeDecorator([{\n strategy: findEntities.bind(null, 'LINK', this),\n component: Link\n }])\n\n this.blockRenderMap = Map({\n \"image\": {\n element: 'figure'\n },\n \"video\": {\n element: 'figure'\n },\n \"embed\": {\n element: 'div'\n },\n 'unstyled': {\n wrapper: null,\n element: 'div'\n },\n 'paragraph': {\n wrapper: null,\n element: 'div'\n },\n 'placeholder': {\n wrapper: null,\n element: 'div'\n }\n\n })\n\n this.extendedBlockRenderMap = DefaultDraftBlockRenderMap.merge(this.blockRenderMap)\n\n this.state = {\n editorState: EditorState.createEmpty(),\n read_only: this.props.config.read_only,\n blockRenderMap: this.extendedBlockRenderMap,\n locks: 0,\n debug: this.props.config.debug\n }\n\n this.widgets = this.props.config.widgets\n this.tooltips = this.props.config.tooltips\n\n this.key_commands = this.props.config.key_commands\n\n this.continuousBlocks = this.props.config.continuousBlocks\n\n this.block_types = this.props.config.block_types\n\n this.default_wrappers = this.props.config.default_wrappers\n\n this.character_convert_mapping = this.props.config.character_convert_mapping\n\n this.save = new SaveBehavior({\n getLocks: this.getLocks,\n config: {\n xhr: this.props.config.xhr,\n data_storage: this.props.config.data_storage\n },\n editor: this,\n editorState: this.getEditorState,\n editorContent: this.emitSerializedOutput()\n })\n\n const { styles, customStyleFn, exporter } = createStyles(['font-size', 'color', 'font-family']); //, 'PREFIX', customStyleMap);\n this.styles = styles\n this.customStyleFn = customStyleFn\n }\n\n componentDidMount(){\n this.initializeState()\n window.addEventListener('resize', ()=> {\n if(this.relocateTooltips)\n setTimeout(() => {\n return this.relocateTooltips()\n })\n })\n }\n\n initializeState() {\n let newEditorState = EditorState.createEmpty(this.decorator)\n if (this.props.content) {\n newEditorState = EditorState.set(this.decodeEditorContent(this.props.content), {decorator: this.decorator});\n }\n this.onChange(newEditorState) \n }\n\n decodeEditorContent(raw_as_json) {\n const new_content = convertFromRaw(raw_as_json)\n let editorState\n return editorState = EditorState.createWithContent(new_content, this.decorator)\n }\n\n refreshSelection(newEditorState) {\n const { editorState } = this.state\n // Setting cursor position after inserting to content\n const s = this.state.editorState.getSelection()\n const c = editorState.getCurrentContent()\n const focusOffset = s.getFocusOffset()\n const anchorKey = s.getAnchorKey()\n\n let selectionState = SelectionState.createEmpty(s.getAnchorKey())\n\n // console.log anchorKey, focusOffset\n selectionState = selectionState.merge({\n anchorOffset: focusOffset,\n focusKey: anchorKey,\n focusOffset\n })\n\n let newState = EditorState.forceSelection(newEditorState, selectionState)\n\n return this.onChange(newState)\n }\n\n forceRender(editorState) {\n const selection = this.state.editorState.getSelection()\n const content = editorState.getCurrentContent()\n const newEditorState = EditorState.createWithContent(content, this.decorator)\n\n return this.refreshSelection(newEditorState)\n }\n\n onChange(editorState) {\n\n editorState = this.handleUndeletables(editorState)\n\n this.setPreContent()\n this.setState({ editorState })\n\n const currentBlock = getCurrentBlock(this.state.editorState)\n const blockType = currentBlock.getType()\n\n\n if (!editorState.getSelection().isCollapsed()) {\n const tooltip = this.tooltipsWithProp('displayOnSelection')[0]\n if (!this.tooltipHasSelectionElement(tooltip, blockType)) {\n return\n }\n this.handleTooltipDisplayOn('displayOnSelection')\n } else {\n this.handleTooltipDisplayOn('displayOnSelection', false)\n }\n\n setTimeout(() => {\n return this.relocateTooltips()\n })\n\n return this.dispatchChangesToSave()\n }\n\n handleUndeletables(editorState){\n // undeletable behavior, will keep previous blockMap \n // if undeletables are deleted\n const undeletable_types = this.widgets.filter(\n function(o){ return o.undeletable })\n .map(function(o){ return o.type })\n \n const currentblockMap = this.state.editorState.getCurrentContent().get(\"blockMap\")\n const blockMap = editorState.getCurrentContent().get(\"blockMap\")\n\n const undeletablesMap = blockMap\n .filter(function(o){ \n return undeletable_types.indexOf(o.get(\"type\")) > 0 \n })\n\n if (undeletable_types.length > 0 && undeletablesMap.size === 0) {\n\n const contentState = editorState.getCurrentContent();\n const blockMap = contentState.getBlockMap();\n const newContentState = contentState.merge({\n blockMap: this.state.editorState.getCurrentContent().blockMap,\n selectionBefore: contentState.getSelectionAfter()\n });\n\n return editorState = EditorState.push(editorState, newContentState, 'change-block')\n }\n\n return editorState\n }\n\n dispatchChangesToSave() {\n clearTimeout(this.saveTimeout)\n return this.saveTimeout = setTimeout(() => {\n return this.save.store(this.emitSerializedOutput())\n }, 100)\n }\n\n setPreContent() {\n const content = this.emitSerializedOutput()\n return this.save.editorContent = content\n }\n\n focus() {\n //debugger\n }\n //@props.refs.richEditor.focus()\n\n getEditorState() {\n return this.state.editorState\n }\n\n emitSerializedOutput() {\n const raw = convertToRaw(this.state.editorState.getCurrentContent())\n\n return raw\n }\n\n //# title utils\n getTextFromEditor() {\n const c = this.state.editorState.getCurrentContent()\n const out = c.getBlocksAsArray().map(o => {\n return o.getText()\n }).join(\"\\n\")\n\n return out\n }\n\n emitHTML2() {\n let html\n\n return html = convertToHTML({\n entityToHTML: (entity, originalText) => {\n if (entity.type === 'LINK') {\n return `<a href=\\\"${ entity.data.url }\\\">${ originalText }</a>`\n } else {\n return originalText\n }\n }\n\n })(this.state.editorState.getCurrentContent())\n }\n\n getLocks() {\n return this.state.locks\n }\n\n addLock() {\n return this.setState({\n locks: this.state.locks += 1 })\n }\n\n removeLock() {\n return this.setState({\n locks: this.state.locks -= 1 })\n }\n\n renderableBlocks() {\n return this.widgets.filter(o => o.renderable).map(o => o.type)\n }\n\n defaultWrappers(blockType) {\n return this.default_wrappers.filter(o => {\n return o.block === blockType\n }).map(o => o.className)\n }\n\n blockRenderer(block) {\n\n switch (block.getType()) {\n\n case \"atomic\":\n\n const entity = block.getEntityAt(0)\n const entity_type = Entity.get(entity).getType()\n\n break\n }\n\n if (this.renderableBlocks().includes(block.getType())) {\n return this.handleBlockRenderer(block)\n }\n\n return null\n }\n\n handleBlockRenderer(block) {\n const dataBlock = this.getDataBlock(block)\n if (!dataBlock) {\n return null\n }\n\n const read_only = this.state.read_only ? false : null\n const editable = read_only !== null ? read_only : dataBlock.editable\n return {\n component: eval(dataBlock.block),\n editable,\n props: {\n data: block.getData(),\n getEditorState: this.getEditorState,\n setEditorState: this.onChange,\n addLock: this.addLock,\n toggleEditable: this.toggleEditable,\n disableEditable: this.disableEditable,\n enableEditable: this.enableEditable,\n removeLock: this.removeLock,\n getLocks: this.getLocks,\n config: dataBlock.options\n }\n }\n\n return null\n }\n\n blockStyleFn(block) {\n const currentBlock = getCurrentBlock(this.state.editorState)\n const is_selected = currentBlock.getKey() === block.getKey() ? \"is-selected\" : \"\"\n\n if (this.renderableBlocks().includes(block.getType())) {\n return this.styleForBlock(block, currentBlock, is_selected)\n }\n\n const defaultBlockClass = this.defaultWrappers(block.getType())\n if (defaultBlockClass.length > 0) {\n return `graf ${ defaultBlockClass[0] } ${ is_selected }`\n } else {\n return `graf ${ is_selected }`\n }\n }\n\n getDataBlock(block) {\n return this.widgets.find(o => {\n return o.type === block.getType()\n })\n }\n\n styleForBlock(block, currentBlock, is_selected) {\n const dataBlock = this.getDataBlock(block)\n\n if (!dataBlock) {\n return null\n }\n\n const selectedFn = dataBlock.selectedFn ? dataBlock.selectedFn(block) : ''\n const selected_class = (dataBlock.selected_class ? dataBlock.selected_class : '' )\n const selected_class_out = is_selected ? selected_class : ''\n\n return `${ dataBlock.wrapper_class } ${ selected_class_out } ${ selectedFn }`\n }\n\n handleTooltipDisplayOn(prop, display) {\n\n // for button click on after inline style set, \n // avoids inline popver to reappear on previous selection\n if(this.state.read_only){\n return \n }\n\n if (display == null) {\n display = true\n }\n \n return setTimeout(() => {\n const items = this.tooltipsWithProp(prop)\n console.log(items)\n return items.map(o => {\n this.refs[o.ref].display(display)\n return this.refs[o.ref].relocate()\n })\n }, 20)\n }\n\n handlePasteText(text, html) {\n\n // https://github.com/facebook/draft-js/issues/685\n /*\n html = \"<p>chao</p>\n <avv>aaa</avv>\n <p>oli</p>\n <img src='x'/>\"\n */\n\n // if not html then fallback to default handler\n\n if (!html) {\n return this.handleTXTPaste(text, html)\n }\n if (html) {\n return this.handleHTMLPaste(text, html)\n }\n }\n\n handleTXTPaste(text, html) {\n const currentBlock = getCurrentBlock(this.state.editorState)\n\n let { editorState } = this.state\n\n switch (currentBlock.getType()) {\n case \"image\":case \"video\":case \"placeholder\":\n const newContent = Modifier.replaceText(editorState.getCurrentContent(), new SelectionState({\n anchorKey: currentBlock.getKey(),\n anchorOffset: 0,\n focusKey: currentBlock.getKey(),\n focusOffset: 2\n }), text)\n\n editorState = EditorState.push(editorState, newContent, 'replace-text')\n\n this.onChange(editorState)\n\n return true\n default:\n return false\n }\n }\n\n handleHTMLPaste(text, html) {\n\n const currentBlock = getCurrentBlock(this.state.editorState)\n\n // TODO: make this configurable\n switch (currentBlock.getType()) {\n case \"image\":case \"video\":case \"placeholder\":\n return this.handleTXTPaste(text, html)\n break\n }\n\n const newContentState = customHTML2Content(html, this.extendedBlockRenderMap)\n\n const selection = this.state.editorState.getSelection()\n const endKey = selection.getEndKey()\n\n const content = this.state.editorState.getCurrentContent()\n const blocksBefore = content.blockMap.toSeq().takeUntil(v => v.key === endKey)\n const blocksAfter = content.blockMap.toSeq().skipUntil(v => v.key === endKey).rest()\n\n const newBlockKey = newContentState.blockMap.first().getKey()\n\n const newBlockMap = blocksBefore.concat(newContentState.blockMap, blocksAfter).toOrderedMap()\n\n const newContent = content.merge({\n blockMap: newBlockMap,\n selectionBefore: selection,\n selectionAfter: selection.merge({\n anchorKey: newBlockKey,\n anchorOffset: 0,\n focusKey: newBlockKey,\n focusOffset: 0,\n isBackward: false\n })\n })\n\n const pushedContentState = EditorState.push(this.state.editorState, newContent, 'insert-fragment')\n\n this.onChange(pushedContentState)\n\n return true\n }\n\n handlePasteImage(files) {\n //TODO: check file types\n return files.map(file => {\n let opts = {\n url: URL.createObjectURL(file),\n file\n }\n\n return this.onChange(addNewBlock(this.state.editorState, 'image', opts))\n })\n }\n\n handleDroppedFiles(state, files) {\n return files.map(file => {\n let opts = {\n url: URL.createObjectURL(file),\n file\n }\n\n return this.onChange(addNewBlock(this.state.editorState, 'image', opts))\n })\n }\n\n handleDrop(selection, dataTransfer, isInternal){\n\n const editorState = this.getEditorState();\n\n const raw = dataTransfer.data.getData('text');\n\n const data = JSON.parse(raw);\n\n this.onChange(addNewBlock(editorState, data.type, data.data))\n\n return 'handled';\n }\n\n handleUpArrow(e) {\n return setTimeout(() => {\n return this.forceRender(this.state.editorState)\n }, 10)\n }\n\n handleDownArrow(e) {\n return setTimeout(() => {\n return this.forceRender(this.state.editorState)\n }, 10)\n }\n\n handleReturn(e) {\n if (this.props.handleReturn) {\n if (this.props.handleReturn()) {\n return true\n }\n }\n\n let { editorState } = this.state\n\n if (e.shiftKey) {\n this.setState({ editorState: RichUtils.insertSoftNewline(editorState) });\n return true;\n }\n\n\n if (!e.altKey && !e.metaKey && !e.ctrlKey) {\n const currentBlock = getCurrentBlock(editorState)\n const blockType = currentBlock.getType()\n const selection = editorState.getSelection()\n\n const config_block = this.getDataBlock(currentBlock)\n\n if (currentBlock.getText().length === 0) {\n\n if (config_block && config_block.handleEnterWithoutText) {\n config_block.handleEnterWithoutText(this, currentBlock)\n this.closePopOvers()\n return true\n }\n\n //TODO turn this in configurable\n switch (blockType) {\n case \"header-one\":\n this.onChange(resetBlockWithType(editorState, \"unstyled\"))\n return true\n break\n default:\n return false\n }\n }\n\n if (currentBlock.getText().length > 0) {\n\n if (config_block && config_block.handleEnterWithText) {\n config_block.handleEnterWithText(this, currentBlock)\n this.closePopOvers()\n return true\n }\n\n if (currentBlock.getLength() === selection.getStartOffset()) {\n if (this.continuousBlocks.indexOf(blockType) < 0) {\n this.onChange(addNewBlockAt(editorState, currentBlock.getKey()))\n return true\n }\n }\n\n return false\n }\n\n // selection.isCollapsed() and # should we check collapsed here?\n if (currentBlock.getLength() === selection.getStartOffset()) {\n //or (config_block && config_block.breakOnContinuous))\n // it will match the unstyled for custom blocks\n if (this.continuousBlocks.indexOf(blockType) < 0) {\n this.onChange(addNewBlockAt(editorState, currentBlock.getKey()))\n return true\n }\n return false\n }\n\n return false\n }\n }\n\n //return false\n\n // TODO: make this configurable\n handleBeforeInput(chars) {\n const currentBlock = getCurrentBlock(this.state.editorState)\n const blockType = currentBlock.getType()\n const selection = this.state.editorState.getSelection()\n\n let { editorState } = this.state\n\n // close popovers\n if (currentBlock.getText().length !== 0) {\n //@closeInlineButton()\n this.closePopOvers()\n }\n\n // handle space on link\n const endOffset = selection.getEndOffset()\n const endKey = currentBlock.getEntityAt(endOffset - 1)\n const endEntityType = endKey && Entity.get(endKey).getType()\n const afterEndKey = currentBlock.getEntityAt(endOffset)\n const afterEndEntityType = afterEndKey && Entity.get(afterEndKey).getType()\n\n // will insert blank space when link found\n if (chars === ' ' && endEntityType === 'LINK' && afterEndEntityType !== 'LINK') {\n const newContentState = Modifier.insertText(editorState.getCurrentContent(), selection, ' ')\n const newEditorState = EditorState.push(editorState, newContentState, 'insert-characters')\n this.onChange(newEditorState)\n return true\n }\n\n // block transform\n if (blockType.indexOf('atomic') === 0) {\n return false\n }\n\n const blockLength = currentBlock.getLength()\n if (selection.getAnchorOffset() > 1 || blockLength > 1) {\n return false\n }\n\n const blockTo = this.character_convert_mapping[currentBlock.getText() + chars]\n\n console.log(`BLOCK TO SHOW: ${ blockTo }`)\n\n if (!blockTo) {\n return false\n }\n\n this.onChange(resetBlockWithType(editorState, blockTo))\n\n return true\n }\n\n // TODO: make this configurable\n handleKeyCommand(command) {\n const { editorState } = this.state\n let currentBlockType, newBlockType\n\n if (this.props.handleKeyCommand && this.props.handleKeyCommand(command)) {\n return true\n }\n\n if (command === 'add-new-block') {\n this.onChange(addNewBlock(editorState, 'blockquote'))\n return true\n }\n\n const block = getCurrentBlock(editorState)\n\n if (command.indexOf('toggle_inline:') === 0) {\n newBlockType = command.split(':')[1]\n currentBlockType = block.getType()\n this.onChange(RichUtils.toggleInlineStyle(editorState, newBlockType))\n return true\n }\n\n if (command.indexOf('toggle_block:') === 0) {\n newBlockType = command.split(':')[1]\n currentBlockType = block.getType()\n\n this.onChange(RichUtils.toggleBlockType(editorState, newBlockType))\n return true\n }\n\n const newState = RichUtils.handleKeyCommand(this.state.editorState, command)\n if (newState) {\n this.onChange(newState)\n return true\n }\n\n return false\n }\n\n findCommandKey(opt, command) {\n // console.log \"COMMAND find: #{opt} #{command}\"\n return this.key_commands[opt].find(o => o.key === command)\n }\n\n KeyBindingFn(e) {\n\n //⌘ + B / Ctrl + B Bold\n //⌘ + I / Ctrl + I Italic\n //⌘ + K / Ctrl + K Turn into link\n //⌘ + Alt + 1 / Ctrl + Alt + 1 Header\n //⌘ + Alt + 2 / Ctrl + Alt + 2 Sub-Header\n //⌘ + Alt + 5 / Ctrl + Alt + 5 Quote (Press once for a block quote, again for a pull quote and a third time to turn off quote)\n\n let cmd\n if (e.altKey) {\n if (e.shiftKey) {\n cmd = this.findCommandKey(\"alt-shift\", e.which)\n if (cmd) {\n return cmd.cmd\n }\n\n return getDefaultKeyBinding(e)\n }\n\n if (e.ctrlKey || e.metaKey) {\n cmd = this.findCommandKey(\"alt-cmd\", e.which)\n if (cmd) {\n return cmd.cmd\n }\n return getDefaultKeyBinding(e)\n }\n } else if (e.ctrlKey || e.metaKey) {\n cmd = this.findCommandKey(\"cmd\", e.which)\n if (cmd) {\n return cmd.cmd\n }\n return getDefaultKeyBinding(e)\n }\n\n return getDefaultKeyBinding(e)\n }\n\n // will update block state todo: movo to utils\n updateBlockData(block, options) {\n const data = block.getData()\n const newData = data.merge(options)\n const newState = updateDataOfBlock(this.state.editorState, block, newData)\n // this fixes enter from image caption\n return this.forceRender(newState)\n }\n\n setDirection(direction_type) {\n const contentState = this.state.editorState.getCurrentContent()\n const selectionState = this.state.editorState.getSelection()\n const block = contentState.getBlockForKey(selectionState.anchorKey)\n\n return this.updateBlockData(block, { direction: direction_type })\n }\n\n //# read only utils\n toggleEditable() {\n this.closePopOvers()\n return this.setState({ read_only: !this.state.read_only }, this.testEmitAndDecode)\n }\n\n disableEditable() {\n console.log(\"in !!\")\n this.closePopOvers()\n return this.setState({ read_only: true }, this.testEmitAndDecode)\n }\n\n enableEditable() {\n this.closePopOvers()\n console.log(\"out !!\")\n return this.setState({ read_only: false }, this.testEmitAndDecode)\n }\n\n closePopOvers() {\n return this.tooltips.map(o => {\n return this.refs[o.ref].hide()\n })\n }\n\n relocateTooltips() {\n if (this.state.read_only)\n return \n\n return this.tooltips.map(o => {\n return this.refs[o.ref].relocate()\n })\n }\n\n tooltipsWithProp(prop) {\n return this.tooltips.filter(o => {\n return o[prop]\n })\n }\n\n tooltipHasSelectionElement(tooltip, element) {\n return tooltip.selectionElements.includes(element)\n }\n\n //################################\n // TODO: this methods belongs to popovers/link\n //################################\n\n handleShowPopLinkOver(e) {\n return this.showPopLinkOver()\n }\n\n handleHidePopLinkOver(e) {\n return this.hidePopLinkOver()\n }\n\n showPopLinkOver(el) {\n // handles popover display\n // using anchor or from popover\n\n const parent_el = ReactDOM.findDOMNode(this)\n\n // set url first in order to calculate popover width\n let coords\n this.refs.anchor_popover.setState({ url: el ? el.href : this.refs.anchor_popover.state.url })\n\n if (el) {\n coords = this.refs.anchor_popover.relocate(el)\n }\n\n if (coords) {\n this.refs.anchor_popover.setPosition(coords)\n }\n\n this.refs.anchor_popover.setState({ show: true })\n\n this.isHover = true\n return this.cancelHide()\n }\n\n hidePopLinkOver() {\n return this.hideTimeout = setTimeout(() => {\n return this.refs.anchor_popover.hide()\n }, 300)\n }\n\n cancelHide() {\n // console.log \"Cancel Hide\"\n return clearTimeout(this.hideTimeout)\n }\n\n //##############################\n\n render() {\n return (\n <div id=\"content\" suppressContentEditableWarning={ true }>\n <article className=\"postArticle\">\n <div className=\"postContent\">\n <div className=\"notesSource\">\n <div id=\"editor\" className=\"postField postField--body\">\n <section className=\"section--first section--last\">\n <div className=\"section-divider layoutSingleColumn\">\n <hr className=\"section-divider\" />\n </div>\n <div className=\"section-content container\">\n <div ref=\"richEditor\" \n className=\"section-inner layoutSingleColumn\"\n onClick={ this.focus }>\n <Editor\n blockRendererFn={ this.blockRenderer }\n editorState={ this.state.editorState }\n onChange={ this.onChange }\n handleDrop={this.handleDrop}\n onUpArrow={ this.handleUpArrow }\n onDownArrow={ this.handleDownArrow }\n handleReturn={ this.handleReturn }\n blockRenderMap={ this.state.blockRenderMap }\n blockStyleFn={ this.blockStyleFn }\n customStyleFn={this.customStyleFn }\n handlePastedText={ this.handlePasteText }\n handlePastedFiles={ this.handlePasteImage }\n handleDroppedFiles={ this.handleDroppedFiles }\n handleKeyCommand={ this.handleKeyCommand }\n keyBindingFn={ this.KeyBindingFn }\n handleBeforeInput={ this.handleBeforeInput }\n readOnly={ this.state.read_only }\n placeholder={ this.props.config.body_placeholder }\n ref=\"editor\"\n />\n </div>\n </div>\n </section>\n </div>\n </div>\n </div>\n </article>\n {\n this.tooltips.map( (o, i) => {\n return (\n <o.component\n ref={ o.ref }\n key={ i }\n editor={ this }\n editorState={ this.state.editorState }\n onChange={ this.onChange }\n styles={this.styles}\n configTooltip={ o }\n widget_options={ o.widget_options }\n showPopLinkOver={ this.showPopLinkOver }\n hidePopLinkOver={ this.hidePopLinkOver }\n handleOnMouseOver={ this.handleShowPopLinkOver }\n handleOnMouseOut={ this.handleHidePopLinkOver }\n />\n )\n })\n }\n {\n this.state.debug\n ? <Debug locks={ this.state.locks } editor={ this } />\n : undefined\n }\n\n </div>\n\n )\n }\n}\n\nexport default DanteEditor\n\n\n\n// WEBPACK FOOTER //\n// src/components/core/editor.js","module.exports = __webpack_public_path__ + \"fonts/dante.eot\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/fonts/dante/dante.eot\n// module id = 187\n// module chunks = 0","module.exports = __webpack_public_path__ + \"fonts/fontello.eot\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/fonts/dante/fontello.eot\n// module id = 188\n// module chunks = 0","\nimport {DanteEditor, Dante} from './components/init.js'\n\nwindow.Dante = Dante\nwindow.DanteEditor = DanteEditor\n\nexport {\n Dante, \n DanteEditor\n}\n\n\n// WEBPACK FOOTER //\n// src/index.js","// removed by extract-text-webpack-plugin\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/dante.scss\n// module id = 195\n// module chunks = 0","import 'styles/dante'\nimport { Dante, DanteEditor } from '../src/index'\n/*\nmodule.exports = {\n Dante, \n DanteEditor\n}*/\n\n\n// WEBPACK FOOTER //\n// demo/initialize.js","\nimport React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport { Entity, RichUtils, AtomicBlockUtils, EditorBlock } from 'draft-js'\n\nimport axios from \"axios\"\n\nimport { updateDataOfBlock } from '../../model/index.js'\n\nexport default class EmbedBlock extends React.Component {\n constructor(props) {\n super(props)\n //api_key = \"86c28a410a104c8bb58848733c82f840\"\n\n this.updateData = this.updateData.bind(this)\n this.dataForUpdate = this.dataForUpdate.bind(this)\n this.componentDidMount = this.componentDidMount.bind(this)\n this.state = {\n embed_data: this.defaultData(),\n error: \"\"\n }\n }\n\n defaultData() {\n const existing_data = this.props.block.getData().toJS()\n return existing_data.embed_data || {}\n }\n\n // will update block state\n updateData() {\n const { block, blockProps } = this.props\n const { getEditorState, setEditorState } = this.props.blockProps\n const data = block.getData()\n const newData = data.merge(this.state)\n return setEditorState(updateDataOfBlock(getEditorState(), block, newData))\n }\n\n dataForUpdate() {\n\n return this.props.blockProps.data.toJS()\n }\n\n componentDidMount() {\n\n if (!this.props.blockProps.data) {\n return\n }\n\n // ensure data isnt already loaded\n // unless @dataForUpdate().endpoint or @dataForUpdate().provisory_text\n\n if (!this.dataForUpdate().endpoint && !this.dataForUpdate().provisory_text) {\n //debugger\n return\n }\n\n return axios({\n method: 'get',\n url: `${ this.dataForUpdate().endpoint }${ this.dataForUpdate().provisory_text }&scheme=https`\n }).then(result => {\n\n return this.setState({ embed_data: result.data } //JSON.parse(data.responseText)\n , this.updateData)\n }).catch(error => {\n\n this.setState({\n error: error.response.data.error_message })\n return console.log(\"TODO: error\")\n })\n }\n\n classForImage() {\n if (this.state.embed_data.images) {\n return \"\"\n } else {\n return \"mixtapeImage--empty u-ignoreBlock\"\n }\n }\n //if @state.embed_data.thumbnail_url then \"\" else \"mixtapeImage--empty u-ignoreBlock\"\n\n picture() {\n if (this.state.embed_data.images && this.state.embed_data.images.length > 0) {\n return this.state.embed_data.images[0].url\n } else {\n return \"\"\n }\n }\n\n render() {\n //block = @.props\n //foo = @.props.blockProps\n //data = Entity.get(block.block.getEntityAt(0)).getData()\n console.log(\"ERROR\", this.state.error)\n return (\n <span>\n { this.picture()\n ? <a\n target='_blank'\n className={ `js-mixtapeImage mixtapeImage ${ this.classForImage() }` }\n href={ this.state.embed_data.url }\n style={ { backgroundImage: `url('${ this.picture() }')` } }\n />\n : undefined\n }\n { this.state.error ? \n <h2>{ this.state.error }</h2>\n : undefined\n }\n <a\n className='markup--anchor markup--mixtapeEmbed-anchor'\n target='_blank'\n href={ this.state.embed_data.url }\n >\n <strong className='markup--strong markup--mixtapeEmbed-strong'>\n { this.state.embed_data.title }\n </strong>\n <em className='markup--em markup--mixtapeEmbed-em'>\n { this.state.embed_data.description }\n </em>\n </a>{ this.state.embed_data.provider_url }\n </span>\n )\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/blocks/embed.js","import React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport {\n Entity, \n RichUtils, \n AtomicBlockUtils, \n EditorBlock, \n EditorState } from 'draft-js'\n\nimport axios from \"axios\"\n\nimport { updateDataOfBlock } from '../../model/index.js'\n\nexport default class ImageBlock extends React.Component {\n\n constructor(props) {\n super(props)\n\n this.blockPropsSrc = this.blockPropsSrc.bind(this)\n this.defaultUrl = this.defaultUrl.bind(this)\n this.defaultAspectRatio = this.defaultAspectRatio.bind(this)\n this.updateData = this.updateData.bind(this)\n this.replaceImg = this.replaceImg.bind(this)\n this.startLoader = this.startLoader.bind(this)\n this.stopLoader = this.stopLoader.bind(this)\n this.handleUpload = this.handleUpload.bind(this)\n this.aspectRatio = this.aspectRatio.bind(this)\n this.updateDataSelection = this.updateDataSelection.bind(this)\n this.handleGrafFigureSelectImg = this.handleGrafFigureSelectImg.bind(this)\n this.getUploadUrl = this.getUploadUrl.bind(this)\n this.uploadFile = this.uploadFile.bind(this)\n this.uploadFailed = this.uploadFailed.bind(this)\n this.uploadCompleted = this.uploadCompleted.bind(this)\n this.updateProgressBar = this.updateProgressBar.bind(this)\n this.placeHolderEnabled = this.placeHolderEnabled.bind(this)\n this.placeholderText = this.placeholderText.bind(this)\n this.handleFocus = this.handleFocus.bind(this)\n this.render = this.render.bind(this)\n let existing_data = this.props.block.getData().toJS()\n\n this.config = this.props.blockProps.config\n this.file = this.props.blockProps.data.get('file')\n this.state = {\n loading: false,\n selected: false,\n loading_progress: 0,\n caption: this.defaultPlaceholder(),\n direction: existing_data.direction || \"center\",\n width: 0,\n height: 0,\n file: null,\n url: this.blockPropsSrc() || this.defaultUrl(existing_data),\n aspect_ratio: this.defaultAspectRatio(existing_data)\n }\n }\n\n blockPropsSrc() {\n // console.log @.props.blockProps.data.src\n return this.props.blockProps.data.src\n }\n /*\n debugger\n block = @.props\n entity = block.block.getEntityAt(0)\n if entity\n data = Entity.get(entity).getData().src\n else\n null\n */\n\n defaultUrl(data) {\n if (data.url) {\n return data.url\n }\n\n if (data.url) {\n if (data.file) {\n return URL.createObjectURL(data.file)\n } else {\n return data.url\n }\n } else {\n return this.props.blockProps.data.src\n }\n }\n\n defaultPlaceholder() {\n return this.props.blockProps.config.image_caption_placeholder\n }\n\n defaultAspectRatio(data) {\n if (data.aspect_ratio) {\n return {\n width: data.aspect_ratio['width'],\n height: data.aspect_ratio['height'],\n ratio: data.aspect_ratio['ratio']\n }\n } else {\n return {\n width: 0,\n height: 0,\n ratio: 100\n }\n }\n }\n\n getAspectRatio(w, h) {\n let maxWidth = 1000\n let maxHeight = 1000\n let ratio = 0\n let width = w // Current image width\n let height = h // Current image height\n\n // Check if the current width is larger than the max\n if (width > maxWidth) {\n ratio = maxWidth / width // get ratio for scaling image\n height = height * ratio // Reset height to match scaled image\n width = width * ratio // Reset width to match scaled image\n\n // Check if current height is larger than max\n } else if (height > maxHeight) {\n ratio = maxHeight / height // get ratio for scaling image\n width = width * ratio // Reset width to match scaled image\n height = height * ratio // Reset height to match scaled image\n }\n\n let fill_ratio = height / width * 100\n let result = { width, height, ratio: fill_ratio }\n // console.log result\n return result\n }\n\n // will update block state\n updateData() {\n let { blockProps } = this.props\n let { block } = this.props\n let { getEditorState } = this.props.blockProps\n let { setEditorState } = this.props.blockProps\n let data = block.getData()\n let newData = data.merge(this.state).merge({ forceUpload: false })\n return setEditorState(updateDataOfBlock(getEditorState(), block, newData))\n }\n\n replaceImg() {\n this.img = new Image()\n this.img.src = this.refs.image_tag.src\n this.setState({\n url: this.img.src })\n let self = this\n // exit only when not blob and not forceUload\n if (!this.img.src.includes(\"blob:\") && !this.props.block.data.get(\"forceUpload\")) {\n return\n }\n return this.img.onload = () => {\n this.setState({\n width: this.img.width,\n height: this.img.height,\n aspect_ratio: self.getAspectRatio(this.img.width, this.img.height)\n })\n\n return this.handleUpload()\n }\n }\n\n startLoader() {\n return this.setState({\n loading: true })\n }\n\n stopLoader() {\n return this.setState({\n loading: false })\n }\n\n handleUpload() {\n this.startLoader()\n this.props.blockProps.addLock()\n this.updateData()\n return this.uploadFile()\n }\n\n componentDidMount() {\n return this.replaceImg()\n }\n\n aspectRatio() {\n return {\n maxWidth: `${ this.state.aspect_ratio.width }`,\n maxHeight: `${ this.state.aspect_ratio.height }`,\n ratio: `${ this.state.aspect_ratio.height }`\n }\n }\n\n updateDataSelection() {\n const { getEditorState, setEditorState } = this.props.blockProps\n const newselection = getEditorState().getSelection().merge({\n anchorKey: this.props.block.getKey(),\n focusKey: this.props.block.getKey()\n })\n\n return setEditorState(EditorState.forceSelection(getEditorState(), newselection))\n }\n\n handleGrafFigureSelectImg(e) {\n e.preventDefault()\n return this.setState({ selected: true }, this.updateDataSelection)\n }\n\n //main_editor.onChange(main_editor.state.editorState)\n\n coords() {\n return {\n maxWidth: `${ this.state.aspect_ratio.width }px`,\n maxHeight: `${ this.state.aspect_ratio.height }px`\n }\n }\n\n getBase64Image(img) {\n let canvas = document.createElement(\"canvas\")\n canvas.width = img.width\n canvas.height = img.height\n let ctx = canvas.getContext(\"2d\")\n ctx.drawImage(img, 0, 0)\n let dataURL = canvas.toDataURL(\"image/png\")\n\n return dataURL\n }\n\n formatData() {\n let formData = new FormData()\n if (this.file) {\n let formName = this.config.upload_formName || 'file'\n\n formData.append(formName, this.file)\n return formData\n } else {\n formData.append('url', this.props.blockProps.data.get(\"url\"))\n return formData\n }\n }\n\n getUploadUrl() {\n let url = this.config.upload_url\n if (typeof url === \"function\") {\n return url()\n } else {\n return url\n }\n }\n\n getUploadHeaders() {\n return this.config.upload_headers || {}\n }\n\n uploadFile() {\n\n let handleUp\n // custom upload handler\n if (this.config.upload_handler) {\n return this.config.upload_handler(this.formatData().get('file'), this)\n }\n \n if (!this.config.upload_url){\n this.stopLoader()\n return\n }\n \n axios({\n method: 'post',\n url: this.getUploadUrl(),\n headers: this.getUploadHeaders(),\n data: this.formatData(),\n onUploadProgress: e => {\n return this.updateProgressBar(e)\n }\n }).then(result => {\n this.uploadCompleted(result.data.url)\n\n if (this.config.upload_callback) {\n return this.config.upload_callback(result, this)\n }\n }).catch(error => {\n this.uploadFailed()\n\n console.log(`ERROR: got error uploading file ${ error }`)\n if (this.config.upload_error_callback) {\n return this.config.upload_error_callback(error, this)\n }\n })\n\n return handleUp = json_response => {\n return this.uploadCompleted(json_response.url, n)\n }\n }\n\n uploadFailed() {\n this.props.blockProps.removeLock()\n this.stopLoader()\n }\n\n uploadCompleted(url) {\n this.setState({ url }, this.updateData)\n this.props.blockProps.removeLock()\n this.stopLoader()\n this.file = null\n }\n\n updateProgressBar(e) {\n let complete = this.state.loading_progress\n if (e.lengthComputable) {\n complete = e.loaded / e.total * 100\n complete = complete != null ? complete : { complete: 0 }\n this.setState({\n loading_progress: complete })\n return console.log(`complete: ${ complete }`)\n }\n }\n\n placeHolderEnabled() {\n return this.state.enabled || this.props.block.getText()\n }\n\n placeholderText() {\n return this.config.image_caption_placeholder\n }\n\n handleFocus(e) {\n\n }\n\n render() {\n\n return (\n <div ref=\"image_tag2\" suppressContentEditableWarning={true}>\n <div className=\"aspectRatioPlaceholder is-locked\" \n style={this.coords()} \n onClick={this.handleGrafFigureSelectImg}>\n <div style={{ paddingBottom: `${ this.state.aspect_ratio.ratio }%` }} \n className='aspect-ratio-fill' />\n <img src={this.state.url} \n ref=\"image_tag\" \n height={this.state.aspect_ratio.height} \n width={this.state.aspect_ratio.width} \n className='graf-image'\n contentEditable={false}\n />\n <Loader toggle={this.state.loading} \n progress={this.state.loading_progress} />\n </div>\n <figcaption className='imageCaption' onMouseDown={this.handleFocus}>\n { this.props.block.getText().length === 0 ? \n <span className=\"danteDefaultPlaceholder\">\n {this.placeholderText()}\n </span> : undefined}\n <EditorBlock {...Object.assign({}, this.props, { \n \"editable\": true, \"className\": \"imageCaption\" })\n } />\n </figcaption>\n </div>\n )\n }\n}\n\nclass Loader extends React.Component {\n\n render() {\n return (\n <div>\n { this.props.toggle\n ? <div className=\"image-upoader-loader\">\n <p>\n { this.props.progress === 100\n ? \"processing image...\"\n : <span>\n <span>loading</span> { Math.round( this.props.progress ) }\n </span>\n }\n </p>\n </div>\n : undefined\n }\n </div>\n )\n }\n}\n\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/blocks/image.js","\nimport React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport { Entity, RichUtils, AtomicBlockUtils, EditorBlock } from 'draft-js'\n\nexport default class PlaceholderBlock extends React.Component {\n constructor(props) {\n super(props)\n this.placeholderText = this.placeholderText.bind(this)\n this.placeholderFromProps = this.placeholderFromProps.bind(this)\n this.defaultText = this.defaultText.bind(this)\n this.placeholderRender = this.placeholderRender.bind(this)\n this.state = {\n enabled: false,\n data: this.props.blockProps.data.toJS()\n }\n }\n\n placeholderText() {\n //if (this.state.enabled) {\n // return \"\"\n //}\n return this.props.blockProps.data.toJS().placeholder || this.placeholderFromProps() || this.defaultText()\n }\n //if @.props.blockProps.data then @.props.blockProps.data.placeholder else @defaultText()\n\n\n placeholderFromProps() {\n return this.props.block.toJS().placeholder\n }\n\n defaultText() {\n return \"write something \"\n }\n\n placeholderRender(){\n if (this.props.block.text.length === 0 ) {\n return (\n <div className=\"public-DraftEditorPlaceholder-root\">\n <div className=\"public-DraftEditorPlaceholder-inner\">\n {this.placeholderText() }\n </div>\n </div>\n )\n\n }\n }\n\n render() {\n return (\n <span onMouseDown={this.handleFocus}>\n \n {this.placeholderRender()}\n \n <EditorBlock {...Object.assign({}, this.props, {\n \"className\": \"imageCaption\",\n \"placeholder\": \"escrive alalal\"\n })} />\n </span>\n )\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/blocks/placeholder.js","\nimport React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport { Entity, RichUtils, AtomicBlockUtils, EditorBlock } from 'draft-js'\n\nimport { updateDataOfBlock } from '../../model/index.js'\n\nimport axios from \"axios\"\n\nexport default class VideoBlock extends React.Component {\n constructor(props) {\n super(props)\n //api_key = \"86c28a410a104c8bb58848733c82f840\"\n\n this.updateData = this.updateData.bind(this)\n this.dataForUpdate = this.dataForUpdate.bind(this)\n this.state = { embed_data: this.defaultData() }\n }\n\n defaultData() {\n let existing_data = this.props.block.getData().toJS()\n return existing_data.embed_data || {}\n }\n\n // will update block state\n updateData() {\n const { block, blockProps } = this.props\n const { getEditorState, setEditorState } = this.props.blockProps\n const data = block.getData()\n const newData = data.merge(this.state)\n return setEditorState(updateDataOfBlock(getEditorState(), block, newData))\n }\n\n dataForUpdate() {\n return this.props.blockProps.data.toJS()\n }\n\n componentDidMount() {\n\n if (!this.props.blockProps.data) {\n return\n }\n // ensure data isnt already loaded\n if (!this.dataForUpdate().endpoint && !this.dataForUpdate().provisory_text) {\n return\n }\n\n return axios({\n method: 'get',\n url: `${ this.dataForUpdate().endpoint }${ this.dataForUpdate().provisory_text }&scheme=https`\n }).then(result => {\n return this.setState({ embed_data: result.data } //JSON.parse(data.responseText)\n , this.updateData)\n }).catch(error => {\n return console.log(\"TODO: error\")\n })\n }\n\n classForImage() {\n if (this.state.embed_data.thumbnail_url) {\n return \"\"\n } else {\n return \"mixtapeImage--empty u-ignoreBlock\"\n }\n }\n\n render() {\n return (\n <figure className='graf--figure graf--iframe graf--first' tabIndex='0'>\n <div className='iframeContainer' \n dangerouslySetInnerHTML={ { __html: this.state.embed_data.html } } />\n <figcaption className='imageCaption'>\n <EditorBlock {...Object.assign({}, this.props, { \"className\": \"imageCaption\" })} />\n </figcaption>\n </figure>\n )\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/blocks/video.js","import React from 'react'\nimport ReactDOM from 'react-dom'\nimport { Map, fromJS } from 'immutable'\nimport DanteEditor from './editor.js'\nimport DanteImagePopover from '../popovers/image'\nimport DanteAnchorPopover from '../popovers/link'\nimport DanteInlineTooltip from '../popovers/addButton'\nimport DanteTooltip from '../popovers/toolTip'\n\nimport ImageBlock from '../blocks/image'\nimport EmbedBlock from '../blocks/embed'\nimport VideoBlock from '../blocks/video'\nimport PlaceholderBlock from '../blocks/placeholder'\n\nimport { \n resetBlockWithType, \n addNewBlockAt \n} from '../../model/index.js'\n\nclass Dante {\n constructor(options) {\n if (options == null) {\n options = {}\n }\n console.log(\"init editor Dante!\")\n\n // deep merge on config\n let config = Map(fromJS(this.defaultOptions(options)))\n\n this.options = config.mergeDeep(options).toJS()\n console.log(this.options)\n }\n\n defaultOptions(options) {\n // default options\n if (options == null) {\n options = {}\n }\n let defaultOptions = {}\n defaultOptions.el = 'app'\n defaultOptions.content = \"\"\n defaultOptions.read_only = false\n defaultOptions.spellcheck = false\n defaultOptions.title_placeholder = \"Title\"\n defaultOptions.body_placeholder = \"Write your story\"\n\n defaultOptions.widgets = [{\n title: 'add an image',\n icon: 'image',\n type: 'image',\n block: ImageBlock,\n editable: true,\n renderable: true,\n breakOnContinuous: true,\n wrapper_class: \"graf graf--figure\",\n selected_class: \"is-selected is-mediaFocused\",\n selectedFn: block => {\n const { direction } = block.getData().toJS()\n switch (direction) {\n case \"left\":\n return \"graf--layoutOutsetLeft\"\n case \"center\":\n return \"\"\n case \"wide\":\n return \"sectionLayout--fullWidth\"\n case \"fill\":\n return \"graf--layoutFillWidth\"\n }\n },\n handleEnterWithoutText(ctx, block) {\n const { editorState } = ctx.state\n return ctx.onChange(addNewBlockAt(editorState, block.getKey()))\n },\n handleEnterWithText(ctx, block) {\n const { editorState } = ctx.state\n return ctx.onChange(addNewBlockAt(editorState, block.getKey()))\n },\n widget_options: {\n displayOnInlineTooltip: true,\n insertion: \"upload\",\n insert_block: \"image\"\n },\n options: {\n upload_url: options.upload_url,\n upload_headers: options.upload_headers,\n upload_formName: options.upload_formName,\n upload_handler: options.image_upload_handler,\n upload_callback: options.image_upload_callback,\n image_delete_callback: options.image_delete_callback,\n image_caption_placeholder: options.image_caption_placeholder || \"Write caption for image (optional)\"\n }\n }, {\n icon: 'embed',\n title: 'insert embed',\n type: 'embed',\n block: EmbedBlock,\n editable: true,\n renderable: true,\n breakOnContinuous: true,\n wrapper_class: \"graf graf--mixtapeEmbed\",\n selected_class: \"is-selected is-mediaFocused\",\n widget_options: {\n displayOnInlineTooltip: true,\n insertion: \"placeholder\",\n insert_block: \"embed\"\n },\n options: {\n endpoint: `//api.embed.ly/1/extract?key=${ options.api_key }&url=`,\n placeholder: 'Paste a link to embed content from another site (e.g. Twitter) and press Enter'\n },\n handleEnterWithoutText(ctx, block) {\n const { editorState } = ctx.state\n return ctx.onChange(addNewBlockAt(editorState, block.getKey()))\n },\n handleEnterWithText(ctx, block) {\n const { editorState } = ctx.state\n return ctx.onChange(addNewBlockAt(editorState, block.getKey()))\n }\n }, {\n icon: 'video',\n title: 'insert video',\n editable: true,\n type: 'video',\n block: VideoBlock,\n renderable: true,\n breakOnContinuous: true,\n wrapper_class: \"graf--figure graf--iframe\",\n selected_class: \" is-selected is-mediaFocused\",\n widget_options: {\n displayOnInlineTooltip: true,\n insertion: \"placeholder\",\n insert_block: \"video\"\n },\n options: {\n endpoint: `//api.embed.ly/1/oembed?key=${ options.api_key }&url=`,\n placeholder: 'Paste a YouTube, Vine, Vimeo, or other video link, and press Enter',\n caption: 'Type caption for embed (optional)'\n },\n\n handleEnterWithoutText(ctx, block) {\n const { editorState } = ctx.state\n return ctx.onChange(addNewBlockAt(editorState, block.getKey()))\n },\n\n handleEnterWithText(ctx, block) {\n const { editorState } = ctx.state\n return ctx.onChange(addNewBlockAt(editorState, block.getKey()))\n }\n }, {\n renderable: true,\n editable: true,\n block: PlaceholderBlock,\n type: 'placeholder',\n wrapper_class: \"is-embedable\",\n selected_class: \" is-selected is-mediaFocused\",\n widget_options: {\n displayOnInlineTooltip: false\n },\n handleEnterWithText(ctx, block) {\n const { editorState } = ctx.state\n const data = {\n provisory_text: block.getText(),\n endpoint: block.getData().get('endpoint'),\n type: block.getData().get('type')\n }\n if(block.getText().length > 0){\n return ctx.onChange(resetBlockWithType(editorState, data.type, data))\n }else{\n return ctx.onChange(resetBlockWithType(editorState, \"unstyled\", {}))\n }\n },\n\n handleEnterWithoutText(ctx, block) {\n const { editorState } = ctx.state\n return ctx.onChange(resetBlockWithType(editorState, data.type, data))\n\n //return ctx.onChange(resetBlockWithType(editorState, \"unstyled\", {}))\n //return ctx.onChange(addNewBlockAt(editorState, block.getKey()))\n },\n\n }]\n\n defaultOptions.tooltips = [{\n ref: 'insert_tooltip',\n component: DanteTooltip,\n displayOnSelection: true,\n selectionElements: [\"unstyled\", \n \"blockquote\", \n \"ordered-list\", \n \"unordered-list\", \n \"unordered-list-item\", \n \"ordered-list-item\", \n \"code-block\", \n 'header-one', \n 'header-two', \n 'header-three', \n 'header-four'],\n widget_options: {\n placeholder: \"Paste or type a link\",\n block_types: [\n // {label: 'p', style: 'unstyled'},\n { label: 'h2', style: 'header-one', type: \"block\" }, \n { label: 'h3', style: 'header-two', type: \"block\" }, \n { label: 'h4', style: 'header-three', type: \"block\" }, \n { label: 'blockquote', style: 'blockquote', type: \"block\" },\n { label: 'insertunorderedlist', style: 'unordered-list-item', type: \"block\" }, \n { label: 'insertorderedlist', style: 'ordered-list-item', type: \"block\" }, \n { label: 'code', style: 'code-block', type: \"block\" }, \n { label: 'bold', style: 'BOLD', type: \"inline\" }, \n { label: 'italic', style: 'ITALIC', type: \"inline\" }\n ]\n }\n }, {\n ref: 'add_tooltip',\n component: DanteInlineTooltip\n }, {\n ref: 'anchor_popover',\n component: DanteAnchorPopover\n }, {\n ref: 'image_popover',\n component: DanteImagePopover\n }]\n\n defaultOptions.xhr = {\n before_handler: null,\n success_handler: null,\n error_handler: null\n }\n\n defaultOptions.data_storage = {\n url: null,\n method: \"POST\",\n success_handler: null,\n failure_handler: null,\n interval: 1500,\n withCredentials: false,\n crossDomain: false,\n headers: {},\n }\n\n defaultOptions.default_wrappers = [\n { className: 'graf--p', block: 'unstyled' }, \n { className: 'graf--h2', block: 'header-one' },\n { className: 'graf--h3', block: 'header-two' }, \n { className: 'graf--h4', block: 'header-three' }, \n { className: 'graf--blockquote', block: 'blockquote' }, \n { className: 'graf--insertunorderedlist', block: 'unordered-list-item' }, \n { className: 'graf--insertorderedlist', block: 'ordered-list-item' }, \n { className: 'graf--code', block: 'code-block' }, \n { className: 'graf--bold', block: 'BOLD' }, \n { className: 'graf--italic', block: 'ITALIC' }]\n\n defaultOptions.continuousBlocks = [\n \"unstyled\", \n \"blockquote\", \n \"ordered-list\", \n \"unordered-list\", \n \"unordered-list-item\", \n \"ordered-list-item\", \n \"code-block\"\n ]\n\n defaultOptions.key_commands = {\n \"alt-shift\": [{ key: 65, cmd: 'add-new-block' }],\n \"alt-cmd\": [{ key: 49, cmd: 'toggle_block:header-one' }, \n { key: 50, cmd: 'toggle_block:header-two' }, \n { key: 53, cmd: 'toggle_block:blockquote' }],\n \"cmd\": [{ key: 66, cmd: 'toggle_inline:BOLD' }, \n { key: 73, cmd: 'toggle_inline:ITALIC' }, \n { key: 75, cmd: 'insert:link' }]\n }\n\n defaultOptions.character_convert_mapping = {\n '> ': \"blockquote\",\n '*.': \"unordered-list-item\",\n '* ': \"unordered-list-item\",\n '- ': \"unordered-list-item\",\n '1.': \"ordered-list-item\",\n '# ': 'header-one',\n '##': 'header-two',\n '==': \"unstyled\",\n '` ': \"code-block\"\n }\n\n return defaultOptions\n }\n\n getContent() {\n return this.options.content\n }\n\n render() {\n return this.editor = ReactDOM.render(\n <DanteEditor content={this.getContent()} config={this.options} />,\n document.getElementById(this.options.el)\n )\n }\n}\n\nexport default Dante\n\n\n// WEBPACK FOOTER //\n// src/components/core/dante.js","import React from 'react'\n\nclass Debug extends React.Component {\n\n constructor() {\n super()\n\n this.handleToggleReadOnly = this.handleToggleReadOnly.bind(this)\n this.handleTestEmitAndDecode = this.handleTestEmitAndDecode.bind(this)\n this.handleTestEmitTEXT = this.handleTestEmitTEXT.bind(this)\n this.testEmitAndDecode = this.testEmitAndDecode.bind(this)\n this.testEmitTEXT = this.testEmitTEXT.bind(this)\n this.logState = this.logState.bind(this)\n this.toggleDisplay = this.toggleDisplay.bind(this)\n this.open = this.open.bind(this)\n this.render = this.render.bind(this)\n this.state = {\n output: \"\",\n display: \"none\"\n }\n }\n\n handleToggleReadOnly(e) {\n e.preventDefault()\n this.props.editor.toggleEditable()\n return false\n }\n\n handleTestEmitAndDecode(e) {\n e.preventDefault()\n return this.testEmitAndDecode()\n }\n\n handleTestEmitTEXT(e) {\n e.preventDefault()\n return this.testEmitTEXT()\n }\n\n testEmitAndDecode(e) {\n const raw_as_json = this.props.editor.emitSerializedOutput()\n this.props.editor.setState({ \n editorState: this.props.editor.decodeEditorContent(raw_as_json) }, \n this.logState(JSON.stringify(raw_as_json)))\n return false\n }\n\n testEmitTEXT() {\n const text = this.props.editor.getTextFromEditor()\n return this.logState(text)\n }\n\n logState(raw) {\n return this.setState({ output: raw }, this.open)\n }\n\n toggleDisplay(e) {\n e.preventDefault()\n const d = this.state.display === \"block\" ? \"none\" : this.state.display\n return this.setState({\n display: d })\n }\n\n open() {\n return this.setState({\n display: \"block\" })\n }\n\n render() {\n return (\n <div>\n <div className=\"debugControls\">\n <ul>\n <li> LOCKS: { this.props.editor.state.locks } </li>\n <li>\n <a href=\"#\" onClick={ this.handleToggleReadOnly }>\n EDITABLE: { this.props.editor.state.read_only ? 'NO' : 'YES' }\n </a>\n </li>\n <li>\n <a href=\"#\" onClick={ this.handleTestEmitTEXT }>EDITOR TEXT</a>\n </li>\n <li>\n <a href=\"#\" onClick={ this.handleTestEmitAndDecode }>EDITOR STATE</a>\n </li>\n </ul>\n </div>\n <div className=\"debugZone\" style={ { display: this.state.display } }>\n <a href=\"#\" className=\"dante-debug-close close\" onClick={ this.toggleDisplay } />\n <div className=\"debugOutput\">\n <h2>EDITOR OUTPUT</h2>\n {\n this.state.output.length > 0\n ? <pre>{ this.state.output }</pre>\n : undefined\n }\n </div>\n </div>\n </div>\n )\n }\n}\n\nexport default Debug\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/core/debug.js","import React from 'react'\nimport { Entity } from 'draft-js'\n\nexport default class Link extends React.Component {\n\n constructor(props) {\n super(props)\n this._validateLink = this._validateLink.bind(this)\n this._checkProtocol = this._checkProtocol.bind(this)\n this._showPopLinkOver = this._showPopLinkOver.bind(this)\n this._hidePopLinkOver = this._hidePopLinkOver.bind(this)\n this.isHover = false\n }\n\n _validateLink() {\n const pattern = new RegExp('^(https?:\\/\\/)?' + // protocol\n '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name\n '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address\n '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path\n '(\\?[&a-z\\d%_.~+=-]*)?' + // query string\n '(\\#[-a-z\\d_]*)?$', 'i') // fragment locater\n if (!pattern.test(str)) {\n alert(\"Please enter a valid URL.\")\n return false\n } else {\n return true\n }\n }\n\n _checkProtocol() {\n return console.log(\"xcvd\")\n }\n\n _showPopLinkOver(e) {\n if (!this.data.showPopLinkOver) {\n return\n }\n return this.data.showPopLinkOver(this.refs.link)\n }\n\n _hidePopLinkOver(e) {\n if (!this.data.hidePopLinkOver) {\n return\n }\n return this.data.hidePopLinkOver()\n }\n\n render() {\n this.data = this.props.contentState.getEntity(this.props.entityKey).getData()\n //Entity.get(this.props.entityKey).getData()\n\n return (\n <a\n ref=\"link\"\n href={ this.data.url }\n className=\"markup--anchor\"\n onMouseOver={ this._showPopLinkOver }\n onMouseOut={ this._hidePopLinkOver }\n >\n { this.props.children }\n </a>\n )\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/decorators/link.js","\nimport Dante from './core/dante'\nimport DanteEditor from './core/editor'\n\nexport {\n Dante, \n DanteEditor\n}\n\n\n// WEBPACK FOOTER //\n// src/components/init.js","import React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport { \n Entity, \n RichUtils, \n AtomicBlockUtils, \n EditorState \n } from 'draft-js'\n\nimport { \n addNewBlock, \n resetBlockWithType, \n updateDataOfBlock, \n getCurrentBlock, \n getNode } from '../../model/index.js'\n\nimport { getSelectionRect, getSelection, getRelativeParent } from \"../../utils/selection.js\"\n\nclass DanteInlineTooltip extends React.Component {\n\n constructor(props) {\n super(props)\n\n this.display = this.display.bind(this)\n this.show = this.show.bind(this)\n this.hide = this.hide.bind(this)\n this._toggleScaled = this._toggleScaled.bind(this)\n this.scale = this.scale.bind(this)\n this.collapse = this.collapse.bind(this)\n this.componentWillReceiveProps = this.componentWillReceiveProps.bind(this)\n this.clickOnFileUpload = this.clickOnFileUpload.bind(this)\n this.handlePlaceholder = this.handlePlaceholder.bind(this)\n this.insertImage = this.insertImage.bind(this)\n this.handleFileInput = this.handleFileInput.bind(this)\n this.widgets = this.widgets.bind(this)\n this.clickHandler = this.clickHandler.bind(this)\n this.relocate = this.relocate.bind(this)\n this.state = {\n position: { top: 0, left: 0 },\n show: false,\n scaled: false\n }\n }\n\n display(b) {\n if (b) {\n return this.show()\n } else {\n return this.hide()\n }\n }\n\n show() {\n return this.setState({\n show: true })\n }\n\n hide() {\n return this.setState({\n show: false })\n }\n\n setPosition(coords) {\n return this.setState({\n position: coords })\n }\n\n _toggleScaled(ev) {\n if (this.state.scaled) {\n return this.collapse()\n } else {\n return this.scale()\n }\n }\n\n scale() {\n return this.setState({\n scaled: true })\n }\n\n collapse() {\n return this.setState({\n scaled: false })\n }\n\n componentWillReceiveProps(newProps) {\n return this.collapse()\n }\n\n activeClass() {\n //if @props.show then \"is-active\" else \"\"\n if (this.isActive()) {\n return \"is-active\"\n } else {\n return \"\"\n }\n }\n\n isActive() {\n return this.state.show\n }\n\n scaledClass() {\n if (this.state.scaled) {\n return \"is-scaled\"\n } else {\n return \"\"\n }\n }\n\n scaledWidth() {\n if (this.state.scaled) {\n return \"124\"\n } else {\n return \"0\"\n }\n }\n\n clickOnFileUpload() {\n this.refs.fileInput.click()\n this.collapse()\n return this.hide()\n }\n\n handlePlaceholder(input) {\n let opts = {\n type: input.widget_options.insert_block,\n placeholder: input.options.placeholder,\n endpoint: input.options.endpoint\n }\n\n return this.props.onChange(resetBlockWithType(this.props.editorState, 'placeholder', opts))\n }\n\n insertImage(file) {\n let opts = {\n url: URL.createObjectURL(file),\n file\n }\n\n return this.props.onChange(addNewBlock(this.props.editorState, 'image', opts))\n }\n\n handleFileInput(e) {\n let fileList = e.target.files\n // TODO: support multiple file uploads\n /*\n Object.keys(fileList).forEach (o)=>\n @.insertImage(fileList[0])\n */\n return this.insertImage(fileList[0])\n }\n\n handleInsertion(e){\n this.hide()\n return this.props.onChange(addNewBlock(this.props.editorState, e.type, {}))\n }\n\n widgets() {\n return this.props.editor.widgets\n }\n\n clickHandler(e, type) {\n let request_block = this.widgets().find(o => o.icon === type)\n\n switch (request_block.widget_options.insertion) {\n case \"upload\":\n return this.clickOnFileUpload(e, request_block)\n case \"placeholder\":\n return this.handlePlaceholder(request_block)\n case \"insertion\":\n return this.handleInsertion(request_block)\n default:\n return console.log(`WRONG TYPE FOR ${ request_block.widget_options.insertion }`)\n }\n }\n\n getItems() {\n return this.widgets().filter(o => {\n return o.widget_options.displayOnInlineTooltip\n })\n }\n\n isDescendant(parent, child) {\n let node = child.parentNode\n while (node !== null) {\n if (node === parent) {\n return true\n }\n node = node.parentNode\n }\n return false\n }\n\n relocate() {\n let { editorState } = this.props\n\n if (editorState.getSelection().isCollapsed()) {\n\n let currentBlock = getCurrentBlock(editorState)\n let blockType = currentBlock.getType()\n\n let contentState = editorState.getCurrentContent()\n let selectionState = editorState.getSelection()\n\n let block = contentState.getBlockForKey(selectionState.anchorKey)\n\n let nativeSelection = getSelection(window)\n if (!nativeSelection.rangeCount) {\n return\n }\n\n let node = getNode()\n\n let selectionBoundary = getSelectionRect(nativeSelection)\n let coords = selectionBoundary //utils.getSelectionDimensions(node)\n\n let parent = ReactDOM.findDOMNode(this.props.editor)\n let parentBoundary = parent.getBoundingClientRect()\n\n if (!this.isDescendant(parent, nativeSelection.anchorNode)) {\n this.hide()\n return\n }\n\n // checkeamos si esta vacio\n this.display(block.getText().length === 0 && blockType === \"unstyled\")\n return this.setPosition({\n top: coords.top + window.scrollY,\n left: coords.left + window.scrollX - 60\n })\n\n } else {\n return this.hide()\n }\n }\n\n render() {\n return (\n <div\n className={ `inlineTooltip ${ this.activeClass() } ${ this.scaledClass() }` }\n style={ this.state.position }\n >\n <button\n className=\"inlineTooltip-button control\"\n title=\"Close Menu\"\n data-action=\"inline-menu\"\n onClick={ this._toggleScaled }\n >\n <span className=\"tooltip-icon dante-icon-plus\" />\n </button>\n <div\n className=\"inlineTooltip-menu\"\n style={ { width: `${ this.scaledWidth() }px` } }\n >\n { this.getItems().map( (item, i) => {\n return <InlineTooltipItem\n item={ item }\n key={ i }\n clickHandler={ this.clickHandler }\n />\n })\n }\n <input\n type=\"file\"\n style={ { display: 'none' } }\n ref=\"fileInput\"\n multiple=\"multiple\"\n onChange={ this.handleFileInput }\n />\n </div>\n </div>\n )\n }\n}\n\nclass InlineTooltipItem extends React.Component {\n\n constructor(...args) {\n super(...args)\n this.clickHandler = this.clickHandler.bind(this)\n }\n\n clickHandler(e) {\n e.preventDefault()\n return this.props.clickHandler(e, this.props.item.icon)\n }\n\n render() {\n return (\n <button\n className=\"inlineTooltip-button scale\"\n title={ this.props.title }\n onMouseDown={ this.clickHandler }\n >\n <span className={ `tooltip-icon dante-icon-${ this.props.item.icon }` } />\n </button>\n )\n }\n}\n\nexport default DanteInlineTooltip\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/popovers/addButton.js","\nimport React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport { Entity, RichUtils, AtomicBlockUtils, EditorState } from 'draft-js'\n\nimport { getSelectionRect, getSelection, getRelativeParent } from \"../../utils/selection.js\"\n\nimport { getCurrentBlock, getNode } from '../../model/index.js'\n\nclass DanteImagePopover extends React.Component {\n\n constructor(props) {\n super(props)\n\n this.display = this.display.bind(this)\n this.show = this.show.bind(this)\n this.hide = this.hide.bind(this)\n this._toggleScaled = this._toggleScaled.bind(this)\n this.scale = this.scale.bind(this)\n this.collapse = this.collapse.bind(this)\n this.relocate = this.relocate.bind(this)\n this.componentWillReceiveProps = this.componentWillReceiveProps.bind(this)\n this.handleClick = this.handleClick.bind(this)\n this.state = {\n position: {\n top: 0,\n left: 0\n },\n show: false,\n scaled: false,\n buttons: [{ type: \"left\" },\n { type: \"center\"},\n { type: \"fill\" },\n { type: \"wide\" }]\n }\n }\n\n display(b) {\n if (b) {\n return this.show()\n } else {\n return this.hide()\n }\n }\n\n show() {\n return this.setState({\n show: true })\n }\n\n hide() {\n return this.setState({\n show: false })\n }\n\n setPosition(coords) {\n return this.setState({\n position: coords })\n }\n\n _toggleScaled(ev) {\n if (this.state.scaled) {\n return this.collapse()\n } else {\n return this.scale()\n }\n }\n\n scale() {\n return this.setState({\n scaled: true })\n }\n\n collapse() {\n return this.setState({\n scaled: false })\n }\n\n relocate() {\n let { editorState } = this.props\n\n if (editorState.getSelection().isCollapsed()) {\n\n let currentBlock = getCurrentBlock(editorState)\n let blockType = currentBlock.getType()\n\n let contentState = editorState.getCurrentContent()\n let selectionState = editorState.getSelection()\n\n let block = contentState.getBlockForKey(selectionState.anchorKey)\n\n let nativeSelection = getSelection(window)\n if (!nativeSelection.rangeCount) {\n return\n }\n\n let node = getNode()\n\n this.display(blockType === \"image\")\n\n if (blockType === \"image\") {\n let selectionBoundary = node.anchorNode.parentNode.parentNode\n .parentNode.getBoundingClientRect()\n \n let coords = selectionBoundary\n\n let el = this.refs.image_popover\n let padd = el.offsetWidth / 2\n\n let parent = ReactDOM.findDOMNode(this.props.editor)\n let parentBoundary = parent.getBoundingClientRect()\n\n const toolbarHeight = el.offsetHeight;\n\n let left = selectionBoundary.left + selectionBoundary.width / 2 - padd\n \n let diff = window.pageYOffset + parent.getBoundingClientRect().top\n \n let top = selectionBoundary.top - parentBoundary.top + toolbarHeight //+ diff\n\n return this.setPosition({ top: top, left: left })\n\n }\n } else {\n return this.hide()\n }\n }\n\n componentWillReceiveProps(newProps) {\n return this.collapse()\n }\n\n getStyle() {\n if (!this.state.position) {\n return {}\n }\n }\n\n handleClick(item) {\n return this.props.editor.setDirection(item.type)\n }\n\n render() {\n return (\n <div\n ref=\"image_popover\"\n className={ `dante-popover popover--Aligntooltip popover--top popover--animated ${ this.state.show ? 'is-active' : undefined }` }\n style={\n { top: this.state.position.top,\n left: this.state.position.left }\n }\n >\n <div className='popover-inner'>\n <ul className='dante-menu-buttons'>\n { this.state.buttons.map( (item, i) => {\n return <DanteImagePopoverItem\n item={ item }\n handleClick={ this.handleClick }\n key={ i }\n />\n })\n }\n </ul>\n </div>\n <div className='popover-arrow' />\n </div>\n )\n }\n}\n\nclass DanteImagePopoverItem extends React.Component {\n\n constructor(...args) {\n super(...args)\n this.handleClick = this.handleClick.bind(this)\n this.render = this.render.bind(this)\n }\n\n handleClick(e) {\n e.preventDefault()\n return this.props.handleClick(this.props.item)\n }\n\n render() {\n return <li\n className={`dante-menu-button align-${ this.props.item.type }`}\n onMouseDown={this.handleClick}>\n <span className={`tooltip-icon dante-icon dante-icon-image-${ this.props.item.type }`} />\n </li>\n }\n}\n\nexport default DanteImagePopover\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/popovers/image.js","\nimport React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport { getCurrentBlock } from '../../model/index.js'\n\nimport { getRelativeParent } from \"../../utils/selection.js\"\n\nclass DanteAnchorPopover extends React.Component {\n\n constructor(props) {\n\n super(props)\n this.display = this.display.bind(this)\n this.show = this.show.bind(this)\n this.hide = this.hide.bind(this)\n this.relocate = this.relocate.bind(this)\n this.render = this.render.bind(this)\n this.state = {\n position: {\n top: 0,\n left: 0\n },\n show: false,\n url: \"\"\n }\n }\n\n display(b) {\n if (b) {\n return this.show()\n } else {\n return this.hide()\n }\n }\n\n show() {\n return this.setState({\n show: true })\n }\n\n hide() {\n return this.setState({\n show: false })\n }\n\n setPosition(coords) {\n return this.setState({\n position: coords })\n }\n\n relocate(node) {\n if (node == null) {\n node = null\n }\n if (!node) {\n return\n }\n\n let { editorState } = this.props\n let currentBlock = getCurrentBlock(editorState)\n let blockType = currentBlock.getType()\n\n let contentState = editorState.getCurrentContent()\n let selectionState = editorState.getSelection()\n\n let selectionBoundary = node.getBoundingClientRect()\n let coords = selectionBoundary\n\n let el = this.refs.dante_popover\n let padd = el.offsetWidth / 2\n\n let parent = ReactDOM.findDOMNode(this.props.editor)\n let parentBoundary = parent.getBoundingClientRect()\n\n const toolbarHeight = el.offsetHeight;\n const relativeRect = node.getBoundingClientRect();\n let left = selectionBoundary.left + selectionBoundary.width / 2 - padd\n \n let diff = window.pageYOffset + parent.getBoundingClientRect().top\n let top = relativeRect.top - parentBoundary.top + (toolbarHeight * 0.3) + diff\n\n return {\n top: top,\n left: left\n }\n }\n\n render() {\n let { position } = this.state\n let style = {\n left: position.left,\n top: position.top,\n visibility: `${ this.state.show ? 'visible' : 'hidden' }`\n }\n return (\n <div\n ref=\"dante_popover\"\n className='dante-popover popover--tooltip popover--Linktooltip popover--bottom is-active'\n style={ style }\n onMouseOver={ this.props.handleOnMouseOver }\n onMouseOut={ this.props.handleOnMouseOut }\n >\n <div className='popover-inner'>\n <a href={ this.state.url } target='_blank'>\n { this.state.url }\n </a>\n </div>\n <div className='popover-arrow' />\n </div>\n )\n }\n}\n\nexport default DanteAnchorPopover\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/popovers/link.js","import React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport { \n convertToRaw, \n CompositeDecorator, \n getVisibleSelectionRect, \n getDefaultKeyBinding, \n getSelectionOffsetKeyForNode, \n KeyBindingUtil, \n ContentState, \n Editor, \n EditorState, \n Entity, \n RichUtils } from 'draft-js'\n\nimport { getSelectionRect, getSelection, getRelativeParent } from \"../../utils/selection.js\"\n\nimport { getCurrentBlock } from '../../model/index.js'\n\nclass DanteTooltip extends React.Component {\n\n constructor(props) {\n super(props)\n this._clickInlineHandler = this._clickInlineHandler.bind(this)\n this.display = this.display.bind(this)\n this.show = this.show.bind(this)\n this.hide = this.hide.bind(this)\n this.relocate = this.relocate.bind(this)\n this._clickBlockHandler = this._clickBlockHandler.bind(this)\n this.displayLinkMode = this.displayLinkMode.bind(this)\n this.displayActiveMenu = this.displayActiveMenu.bind(this)\n this._enableLinkMode = this._enableLinkMode.bind(this)\n this._disableLinkMode = this._disableLinkMode.bind(this)\n this.handleInputEnter = this.handleInputEnter.bind(this)\n this.confirmLink = this.confirmLink.bind(this)\n this.inlineItems = this.inlineItems.bind(this)\n this.blockItems = this.blockItems.bind(this)\n this.getDefaultValue = this.getDefaultValue.bind(this)\n this.getVisibleSelectionRect = getVisibleSelectionRect\n this.state = {\n link_mode: false,\n show: false,\n position: {}\n }\n }\n\n _clickInlineHandler(ev, style) {\n ev.preventDefault()\n\n this.props.onChange(RichUtils.toggleInlineStyle(this.props.editorState, style))\n\n return setTimeout(() => {\n return this.relocate()\n }, 0)\n }\n\n display(b) {\n if (b) {\n return this.show()\n } else {\n return this.hide()\n }\n }\n\n show() {\n return this.setState({\n show: true })\n }\n\n hide() {\n return this.setState({\n link_mode: false,\n show: false\n })\n }\n\n setPosition(coords) {\n return this.setState({\n position: coords })\n }\n\n isDescendant(parent, child) {\n let node = child.parentNode\n while (node !== null) {\n if (node === parent) {\n return true\n }\n node = node.parentNode\n }\n return false\n }\n\n relocate() {\n\n let currentBlock = getCurrentBlock(this.props.editorState)\n let blockType = currentBlock.getType()\n // display tooltip only for unstyled\n\n if (this.props.configTooltip.selectionElements.indexOf(blockType) < 0) {\n this.hide()\n return\n }\n\n if (this.state.link_mode) {\n return\n }\n if (!this.state.show) {\n return\n }\n\n let el = this.refs.dante_menu\n let padd = el.offsetWidth / 2\n\n let nativeSelection = getSelection(window)\n if (!nativeSelection.rangeCount) {\n return\n }\n\n let selectionBoundary = getSelectionRect(nativeSelection)\n\n let parent = ReactDOM.findDOMNode(this.props.editor)\n let parentBoundary = parent.getBoundingClientRect()\n\n // hide if selected node is not in editor\n if (!this.isDescendant(parent, nativeSelection.anchorNode)) {\n this.hide()\n return\n }\n\n //let top = selectionBoundary.top - parentBoundary.top - -90 - 5\n\n const relativeParent = getRelativeParent(this.refs.dante_menu.parentElement);\n const toolbarHeight = this.refs.dante_menu.clientHeight;\n const relativeRect = (relativeParent || document.body).getBoundingClientRect();\n const selectionRect = getVisibleSelectionRect(window);\n\n if(!selectionRect || !relativeRect || !selectionBoundary)\n return\n\n\n let diff = window.pageYOffset + parent.getBoundingClientRect().top\n let top = (selectionRect.top - relativeRect.top) - toolbarHeight + diff\n let left = selectionBoundary.left + selectionBoundary.width / 2 - padd\n\n //let left = (selectionRect.left - relativeRect.left) + (selectionRect.width / 2)\n\n if (!top || !left) {\n return\n }\n\n // console.log \"SET SHOW FOR TOOLTIP INSERT MENU\"\n return this.setState({\n show: true,\n position: {\n left,\n top\n }\n })\n }\n\n _clickBlockHandler(ev, style) {\n ev.preventDefault()\n\n this.props.onChange(RichUtils.toggleBlockType(this.props.editorState, style))\n\n return setTimeout(() => {\n return this.relocate()\n }, 0)\n }\n\n displayLinkMode() {\n if (this.state.link_mode) {\n return \"dante-menu--linkmode\"\n } else {\n return \"\"\n }\n }\n\n displayActiveMenu() {\n if (this.state.show) {\n return \"dante-menu--active\"\n } else {\n return \"\"\n }\n }\n\n _enableLinkMode(ev) {\n ev.preventDefault()\n return this.setState({\n link_mode: true })\n }\n\n _disableLinkMode(ev) {\n ev.preventDefault()\n return this.setState({\n link_mode: false,\n url: \"\"\n })\n }\n\n hideMenu() {\n return this.hide()\n }\n\n handleInputEnter(e) {\n if (e.which === 13) {\n return this.confirmLink(e)\n }\n }\n\n confirmLink(e) {\n e.preventDefault()\n let { editorState } = this.props\n let urlValue = e.currentTarget.value\n let contentState = editorState.getCurrentContent()\n let selection = editorState.getSelection()\n\n let opts = {\n url: urlValue,\n showPopLinkOver: this.props.showPopLinkOver,\n hidePopLinkOver: this.props.hidePopLinkOver\n }\n \n let entityKey = Entity.create('LINK', 'MUTABLE', opts)\n //contentState.createEntity('LINK', 'MUTABLE', opts)\n\n if (selection.isCollapsed()) {\n console.log(\"COLLAPSED SKIPPING LINK\")\n return\n }\n\n this.props.onChange(RichUtils.toggleLink(editorState, selection, entityKey))\n\n return this._disableLinkMode(e)\n }\n\n getPosition() {\n let pos = this.state.position\n return pos\n }\n\n inlineItems() {\n return this.props.widget_options.block_types.filter(o => {\n return o.type === \"inline\"\n })\n }\n\n blockItems() {\n return this.props.widget_options.block_types.filter(o => {\n return o.type === \"block\"\n })\n }\n\n getDefaultValue() {\n if (this.refs.dante_menu_input) {\n this.refs.dante_menu_input.value = \"\"\n }\n \n let currentBlock = getCurrentBlock(this.props.editorState)\n let blockType = currentBlock.getType()\n let selection = this.props.editor.state.editorState.getSelection()\n let contentState = this.props.editorState.getCurrentContent()\n let selectedEntity = null\n let defaultUrl = null\n return currentBlock.findEntityRanges(character => {\n let entityKey = character.getEntity()\n selectedEntity = entityKey\n return entityKey !== null && contentState.getEntity(entityKey).getType() === 'LINK'\n }, (start, end) => {\n let selStart = selection.getAnchorOffset()\n let selEnd = selection.getFocusOffset()\n if (selection.getIsBackward()) {\n selStart = selection.getFocusOffset()\n selEnd = selection.getAnchorOffset()\n }\n\n if (start === selStart && end === selEnd) {\n defaultUrl = contentState.getEntity(selectedEntity).getData().url\n return this.refs.dante_menu_input.value = defaultUrl\n }\n })\n }\n\n render() {\n return (\n <div\n id=\"dante-menu\"\n ref=\"dante_menu\"\n className={ `dante-menu ${ this.displayActiveMenu() } ${ this.displayLinkMode() }` }\n style={ this.getPosition() }\n >\n <div className=\"dante-menu-linkinput\">\n <input\n className=\"dante-menu-input\"\n ref=\"dante_menu_input\"\n placeholder={this.props.widget_options.placeholder}\n onKeyPress={ this.handleInputEnter }\n defaultValue={ this.getDefaultValue() }\n />\n <div className=\"dante-menu-button\" onMouseDown={ this._disableLinkMode } />\n </div>\n <ul className=\"dante-menu-buttons\">\n { this.blockItems().map( (item, i) => {\n return <DanteTooltipItem\n key={ i }\n item={ item }\n handleClick={ this._clickBlockHandler }\n editorState={ this.props.editorState }\n type=\"block\"\n currentStyle={ this.props.editorState.getCurrentInlineStyle }\n />\n })\n }\n\n <DanteTooltipLink\n editorState={ this.props.editorState }\n enableLinkMode={ this._enableLinkMode }\n />\n\n\n { this.inlineItems().map( (item, i) => {\n return <DanteTooltipItem\n key={ i }\n item={ item }\n type=\"inline\"\n editorState={ this.props.editorState }\n handleClick={ this._clickInlineHandler }\n />\n })\n }\n </ul>\n </div>\n )\n }\n}\n\nclass DanteTooltipItem extends React.Component {\n\n constructor(...args) {\n super(...args)\n this.handleClick = this.handleClick.bind(this)\n this.activeClass = this.activeClass.bind(this)\n this.isActive = this.isActive.bind(this)\n this.activeClassInline = this.activeClassInline.bind(this)\n this.activeClassBlock = this.activeClassBlock.bind(this)\n this.render = this.render.bind(this)\n }\n\n handleClick(ev) {\n return this.props.handleClick(ev, this.props.item.style)\n }\n\n activeClass() {\n if (this.isActive()) {\n return \"active\"\n } else {\n return \"\"\n }\n }\n\n isActive() {\n if (this.props.type === \"block\") {\n return this.activeClassBlock()\n } else {\n return this.activeClassInline()\n }\n }\n\n activeClassInline() {\n if (!this.props.editorState) {\n return\n }\n //console.log @props.item\n return this.props.editorState.getCurrentInlineStyle().has(this.props.item.style)\n }\n\n activeClassBlock() {\n //console.log \"EDITOR STATE\", @props.editorState\n if (!this.props.editorState) {\n return\n }\n let selection = this.props.editorState.getSelection()\n let blockType = this.props.editorState.getCurrentContent().getBlockForKey(selection.getStartKey()).getType()\n return this.props.item.style === blockType\n }\n\n render() {\n return (\n <li className={ `dante-menu-button ${ this.activeClass() }` } onMouseDown={ this.handleClick }>\n <i className={ `dante-icon dante-icon-${ this.props.item.label }` } data-action=\"bold\" />\n </li>\n )\n }\n}\n\nclass DanteTooltipLink extends React.Component {\n\n constructor(...args) {\n super(...args)\n this.promptForLink = this.promptForLink.bind(this)\n }\n\n promptForLink(ev) {\n let selection = this.props.editorState.getSelection()\n if (!selection.isCollapsed()) {\n return this.props.enableLinkMode(ev)\n }\n }\n\n render() {\n return (\n <li className=\"dante-menu-button\" onMouseDown={ this.promptForLink }>\n <i className=\"dante-icon icon-createlink\" data-action=\"createlink\">link</i>\n </li>\n )\n }\n}\n\n\n\n\n\n\nexport default DanteTooltip\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/popovers/toolTip.js","import { Entity } from 'draft-js'\n\n//TODO: what the f*ck is happening here? ;-;\nconst findEntities = (entityType, instance, contentBlock, callback) => {\n return contentBlock.findEntityRanges((function(_this) {\n return function(character) {\n var entityKey, opts, res\n let contentState = instance.state.editorState.getCurrentContent()\n entityKey = character.getEntity()\n return (res = entityKey !== null && contentState.getEntity(entityKey).getType() === entityType, res ? (opts = {\n showPopLinkOver: instance.showPopLinkOver,\n hidePopLinkOver: instance.hidePopLinkOver\n }, contentState.mergeEntityData(entityKey, opts)) : void 0, res)\n }\n })(this), callback)\n}\n\nexport default findEntities\n\n\n// WEBPACK FOOTER //\n// src/utils/find_entities.js","import { ContentState, genKey, Entity, CharacterMetadata, ContentBlock, convertFromHTML, getSafeBodyFromHTML } from 'draft-js'\n\nimport { List, OrderedSet, Repeat, fromJS } from 'immutable'\n\n\n// { compose\n// } = require('underscore')\n\n// underscore compose function\nlet compose = function() {\n let args = arguments\n let start = args.length - 1\n return function() {\n let i = start\n let result = args[start].apply(this, arguments)\n while (i--) {\n result = args[i].call(this, result)\n }\n return result\n }\n}\n\n// from https://gist.github.com/N1kto/6702e1c2d89a33a15a032c234fc4c34e\n\n/*\n * Helpers\n */\n\n// Prepares img meta data object based on img attributes\nlet getBlockSpecForElement = imgElement=> {\n return {\n contentType: 'image',\n imgSrc: imgElement.getAttribute('src')\n }\n}\n\n// Wraps meta data in HTML element which is 'understandable' by Draft, I used <blockquote />.\nlet wrapBlockSpec = blockSpec=> {\n if (blockSpec === null) {\n return null\n }\n\n let tempEl = document.createElement('blockquote')\n // stringify meta data and insert it as text content of temp HTML element. We will later extract\n // and parse it.\n tempEl.innerText = JSON.stringify(blockSpec)\n return tempEl\n}\n\n// Replaces <img> element with our temp element\nlet replaceElement = (oldEl, newEl)=> {\n if (!(newEl instanceof HTMLElement)) {\n return\n }\n\n let upEl = getUpEl(oldEl)\n //parentNode = oldEl.parentNode\n //return parentNode.replaceChild(newEl, oldEl)\n return upEl.parentNode.insertBefore(newEl, upEl)\n}\n\nvar getUpEl = el=> {\n let original_el = el\n while (el.parentNode) {\n if (el.parentNode.tagName !== 'BODY') {\n el = el.parentNode\n }\n if (el.parentNode.tagName === 'BODY') { return el }\n }\n}\n\nlet elementToBlockSpecElement = compose(wrapBlockSpec, getBlockSpecForElement)\n\nlet imgReplacer = imgElement=> {\n return replaceElement(imgElement, elementToBlockSpecElement(imgElement))\n}\n\n/*\n * Main function\n */\n\n// takes HTML string and returns DraftJS ContentState\nlet customHTML2Content = function(HTML, blockRn){\n let tempDoc = new DOMParser().parseFromString(HTML, 'text/html')\n // replace all <img /> with <blockquote /> elements\n\n let a = tempDoc.querySelectorAll('img').forEach( item=> imgReplacer(item))\n\n // use DraftJS converter to do initial conversion. I don't provide DOMBuilder and\n // blockRenderMap arguments here since it should fall back to its default ones, which are fine\n console.log(tempDoc.body.innerHTML)\n let content = convertFromHTML(tempDoc.body.innerHTML,\n getSafeBodyFromHTML,\n blockRn\n )\n\n let contentBlocks = content.contentBlocks\n\n // now replace <blockquote /> ContentBlocks with 'atomic' ones\n contentBlocks = contentBlocks.map(function(block){\n let newBlock\n console.log(\"CHECK BLOCK\", block.getType())\n if (block.getType() !== 'blockquote') {\n return block\n }\n\n let json = \"\"\n try {\n json = JSON.parse(block.getText())\n } catch (error) {\n return block\n }\n\n return newBlock = block.merge({\n type: \"image\",\n text: \"\",\n data: {\n url: json.imgSrc,\n forceUpload: true\n }\n })\n })\n\n tempDoc = null\n return ContentState.createFromBlockArray(contentBlocks)\n}\n\n\nexport default customHTML2Content\n\n\n// WEBPACK FOOTER //\n// src/utils/html2content.js","import axios from \"axios\"\nimport Immutable from 'immutable'\n\nclass SaveBehavior {\n constructor(options) {\n this.getLocks = options.getLocks\n this.config = options.config\n this.editor = options.editor\n this.editorContent = options.editorContent\n this.editorState = options.editorState\n }\n\n handleStore(ev){\n return this.store()\n }\n\n store(content){\n if (!this.config.data_storage.url) { return }\n if (this.getLocks() > 0) { return }\n\n clearTimeout(this.timeout)\n\n return this.timeout = setTimeout(() => {\n return this.checkforStore(content)\n }\n , this.config.data_storage.interval)\n }\n\n getTextFromEditor(content){\n return content.blocks.map(o=> {\n return o.text\n }\n )\n .join(\"\\n\")\n }\n\n getUrl() {\n let { url } = this.config.data_storage\n if (typeof(url) === \"function\") { \n return url() \n } else { \n return url \n }\n }\n\n getMethod() {\n let { method } = this.config.data_storage\n if (typeof(method) === \"function\") { \n return method() \n } else { \n return method \n }\n }\n\n getWithCredentials(){\n let { withCredentials } = this.config.data_storage\n if (typeof(withCredentials) === \"function\") { \n return withCredentials() \n } else { \n return withCredentials \n }\n }\n\n getCrossDomain(){\n let { crossDomain } = this.config.data_storage\n if (typeof(crossDomain) === \"function\") { \n return crossDomain()\n } else { \n return crossDomain \n }\n }\n\n getHeaders(){\n let { headers } = this.config.data_storage\n if (typeof(headers) === \"function\") { \n return headers() \n } else { \n return headers \n }\n }\n\n checkforStore(content){\n // ENTER DATA STORE\n let isChanged = !Immutable.is(Immutable.fromJS(this.editorContent), Immutable.fromJS(content))\n // console.log(\"CONTENT CHANGED:\", isChanged)\n\n if (!isChanged) { return }\n\n this.save(content)\n }\n\n save(content){\n // use save handler from config if exists\n if (this.config.data_storage.save_handler){\n this.config.data_storage.save_handler(this, content)\n return \n }\n\n if (this.config.xhr.before_handler) { this.config.xhr.before_handler() }\n // console.log \"SAVING TO: #{@getMethod()} #{@getUrl()}\"\n\n return axios({\n method: this.getMethod(),\n url: this.getUrl(),\n data: {\n editor_content: JSON.stringify(content),\n text_content: this.getTextFromEditor(content)\n },\n withCredentials: this.getWithCredentials(),\n crossDomain: this.getCrossDomain(),\n headers: this.getHeaders(),\n })\n .then(result=> {\n // console.log \"STORING CONTENT\", result\n if (this.config.data_storage.success_handler) { this.config.data_storage.success_handler(result) }\n if (this.config.xhr.success_handler) { return this.config.xhr.success_handler(result) }\n }\n )\n .catch(error=> {\n // console.log(\"ERROR: got error saving content at #{@config.data_storage.url} - #{error}\")\n if (this.config.xhr.failure_handler) { return this.config.xhr.failure_handler(error) }\n }\n )\n }\n}\n\n\nexport default SaveBehavior\n\n\n\n// WEBPACK FOOTER //\n// src/utils/save_content.js","import { Map } from 'immutable';\n\n\n\nimport { EditorState, ContentBlock, genKey } from 'draft-js';\n\n\n/*\nUsed from [react-rte](https://github.com/brijeshb42/medium-draft)\nby [brijeshb42](https://github.com/brijeshb42/medium-draft)\n*/\n\n/*\nReturns default block-level metadata for various block type. Empty object otherwise.\n*/\nexport const getDefaultBlockData = (blockType, initialData = {}) => {\n switch (blockType) {\n //case Block.TODO: return { checked: false };\n default: return initialData;\n }\n};\n\nexport const getNode = (root=window) => {\n let t = null\n if (root.getSelection){\n t = root.getSelection()\n } else if (root.document.getSelection){\n t = root.document.getSelection()\n } else if (root.document.selection){\n t = root.document.selection.createRange().text\n }\n return t\n}\n\n/*\nGet currentBlock in the editorState.\n*/\nexport const getCurrentBlock = (editorState) => {\n const selectionState = editorState.getSelection();\n const contentState = editorState.getCurrentContent();\n const block = contentState.getBlockForKey(selectionState.getStartKey());\n return block;\n};\n\n/*\nAdds a new block (currently replaces an empty block) at the current cursor position\nof the given `newType`.\n*/\nexport const addNewBlock = (editorState, newType = \"unstyled\", initialData = {}) => {\n const selectionState = editorState.getSelection();\n if (!selectionState.isCollapsed()) {\n return editorState;\n }\n const contentState = editorState.getCurrentContent();\n const key = selectionState.getStartKey();\n const blockMap = contentState.getBlockMap();\n const currentBlock = getCurrentBlock(editorState);\n if (!currentBlock) {\n return editorState;\n }\n if (currentBlock.getLength() === 0) {\n if (currentBlock.getType() === newType) {\n return editorState;\n }\n const newBlock = currentBlock.merge({\n type: newType,\n data: getDefaultBlockData(newType, initialData),\n });\n const newContentState = contentState.merge({\n blockMap: blockMap.set(key, newBlock),\n selectionAfter: selectionState,\n });\n return EditorState.push(editorState, newContentState, 'change-block-type');\n }\n return editorState;\n};\n\n\n/*\nChanges the block type of the current block.\n*/\nexport const resetBlockWithType = (editorState, newType = \"unstyled\", data={}) => {\n const contentState = editorState.getCurrentContent();\n const selectionState = editorState.getSelection();\n const key = selectionState.getStartKey();\n const blockMap = contentState.getBlockMap();\n const block = blockMap.get(key);\n\n const text = block.getText();\n\n const newBlock = block.merge({\n text: text,\n type: newType,\n data: getDefaultBlockData(newType, data),\n });\n const newContentState = contentState.merge({\n blockMap: blockMap.set(key, newBlock),\n selectionAfter: selectionState.merge({\n anchorOffset: 0,\n focusOffset: 0,\n }),\n });\n return EditorState.push(editorState, newContentState, 'change-block-type');\n};\n\n\n/*\nUpdate block-level metadata of the given `block` to the `newData`/\n*/\nexport const updateDataOfBlock = (editorState, block, newData) => {\n const contentState = editorState.getCurrentContent();\n const newBlock = block.merge({\n data: newData,\n });\n const newContentState = contentState.merge({\n blockMap: contentState.getBlockMap().set(block.getKey(), newBlock),\n });\n return EditorState.push(editorState, newContentState, 'change-block-type');\n // return editorState;\n};\n\nexport const updateTextOfBlock = (editorState, block, text) => {\n const contentState = editorState.getCurrentContent();\n const newBlock = block.merge({\n text: text,\n });\n const newContentState = contentState.merge({\n blockMap: contentState.getBlockMap().set(block.getKey(), newBlock),\n });\n\n return EditorState.push(editorState, newContentState, 'replace-text');\n // return editorState;\n};\n\n// const BEFORE = -1;\n// const AFTER = 1;\n\n/*\nUsed from [react-rte](https://github.com/sstur/react-rte/blob/master/src/lib/insertBlockAfter.js)\nby [sstur](https://github.com/sstur)\n*/\nexport const addNewBlockAt = (\n editorState,\n pivotBlockKey,\n newBlockType = \"unstyled\",\n initialData = {}\n ) => {\n const content = editorState.getCurrentContent();\n const blockMap = content.getBlockMap();\n const block = blockMap.get(pivotBlockKey);\n const blocksBefore = blockMap.toSeq().takeUntil((v) => (v === block));\n const blocksAfter = blockMap.toSeq().skipUntil((v) => (v === block)).rest();\n const newBlockKey = genKey();\n\n const newBlock = new ContentBlock({\n key: newBlockKey,\n type: newBlockType,\n text: '',\n characterList: block.getCharacterList().slice(0, 0),\n depth: 0,\n data: Map(getDefaultBlockData(newBlockType, initialData)),\n });\n\n const newBlockMap = blocksBefore.concat(\n [[pivotBlockKey, block], [newBlockKey, newBlock]],\n blocksAfter\n ).toOrderedMap();\n\n const selection = editorState.getSelection();\n\n const newContent = content.merge({\n blockMap: newBlockMap,\n selectionBefore: selection,\n selectionAfter: selection.merge({\n anchorKey: newBlockKey,\n anchorOffset: 0,\n focusKey: newBlockKey,\n focusOffset: 0,\n isBackward: false,\n }),\n });\n return EditorState.push(editorState, newContent, 'split-block');\n};\n\n\n\n// WEBPACK FOOTER //\n// src/model/index.js","module.exports = __webpack_public_path__ + \"fonts/dante.svg\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/fonts/dante/dante.svg\n// module id = 434\n// module chunks = 0","module.exports = __webpack_public_path__ + \"fonts/dante.ttf\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/fonts/dante/dante.ttf\n// module id = 435\n// module chunks = 0","module.exports = __webpack_public_path__ + \"fonts/dante.woff\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/fonts/dante/dante.woff\n// module id = 436\n// module chunks = 0","module.exports = __webpack_public_path__ + \"fonts/fontello.svg\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/fonts/dante/fontello.svg\n// module id = 437\n// module chunks = 0","module.exports = __webpack_public_path__ + \"fonts/fontello.ttf\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/fonts/dante/fontello.ttf\n// module id = 438\n// module chunks = 0","module.exports = __webpack_public_path__ + \"fonts/fontello.woff\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/styles/fonts/dante/fontello.woff\n// module id = 439\n// module chunks = 0","export const getRelativeParent = (element) => {\n if (!element) {\n return null;\n }\n\n const position = window.getComputedStyle(element).getPropertyValue('position');\n if (position !== 'static') {\n return element;\n }\n\n return getRelativeParent(element.parentElement);\n};\n\n/*\nReturns the `boundingClientRect` of the passed selection.\n*/\nexport const getSelectionRect = (selected) => {\n const _rect = selected.getRangeAt(0).getBoundingClientRect();\n // selected.getRangeAt(0).getBoundingClientRect()\n let rect = _rect && _rect.top ? _rect : selected.getRangeAt(0).getClientRects()[0];\n if (!rect) {\n if (selected.anchorNode && selected.anchorNode.getBoundingClientRect) {\n rect = selected.anchorNode.getBoundingClientRect();\n rect.isEmptyline = true;\n } else {\n return null;\n }\n }\n return rect;\n};\n\n/*\nReturns the native selection node.\n*/\nexport const getSelection = (root) => {\n let t = null;\n if (root.getSelection) {\n t = root.getSelection();\n } else if (root.document.getSelection) {\n t = root.document.getSelection();\n } else if (root.document.selection) {\n t = root.document.selection.createRange().text;\n }\n return t;\n};\n\n/*\nRecursively finds the DOM Element of the block where the cursor is currently present.\nIf not found, returns null.\n*/\nexport const getSelectedBlockNode = (root) => {\n const selection = root.getSelection();\n if (selection.rangeCount === 0) {\n return null;\n }\n let node = selection.getRangeAt(0).startContainer;\n // console.log(node);\n do {\n if (node.getAttribute && node.getAttribute('data-block') === 'true') {\n return node;\n }\n node = node.parentNode;\n // console.log(node);\n } while (node !== null);\n return null;\n};\n\n\n\n// WEBPACK FOOTER //\n// src/utils/selection.js"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AACA;AACA;AAcA;AACA;AAIA;AACA;AAQA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;;;AAEA;;;AACA;AAAA;AACA;AADA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AACA;AAIA;AACA;AACA;AADA;AAGA;AACA;AADA;AAGA;AACA;AADA;AAGA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AACA;AAnBA;AACA;AAwBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AALA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AARA;AACA;AA1GA;AAAA;AAAA;AAAA;AACA;AACA;AAmHA;AACA;AAtHA;AAuHA;AACA;;;AACA;AAAA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AACA;AAIA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AARA;AAUA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;;;AAEA;AACA;AACA;AACA;AAAA;AAAA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAVA;AAHA;AACA;AAgBA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AAFA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAfA;AAiBA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AALA;AAHA;AACA;AAWA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAFA;AACA;AAIA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAFA;AACA;AAIA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AACA;AACA;AACA;AACA;AAJA;AACA;AAMA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AAAA;AAAA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AADA;AAGA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAnBA;AAHA;AADA;AAJA;AADA;AADA;AADA;AADA;AAyCA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAZA;AAeA;AAGA;AA9DA;AAsEA;;;AA96BA;AACA;AAg7BA;;;;;;;AC39BA;;;;;;;ACAA;;;;;;;;;;;;;;;ACCA;AACA;AACA;AACA;AACA;AAEA;AACA;;;;;;;ACRA;;;;;;;;;;ACAA;AACA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACAA;AACA;;;AAAA;AACA;;;AACA;AACA;AACA;AACA;;;AACA;AACA;;;AACA;;;AACA;AAAA;AACA;AACA;AACA;AAHA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAFA;AAPA;AAWA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AACA;AAIA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAJA;AAQA;AACA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AACA;AACA;AACA;AAHA;AAKA;AAAA;AAAA;AACA;AADA;AAGA;AAAA;AAAA;AACA;AADA;AARA;AAWA;AAzBA;AA4BA;;;AAjHA;AACA;AADA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACVA;AACA;;;AAAA;AACA;;;AACA;AACA;AAMA;AACA;;;AACA;AACA;;;AACA;;;AAEA;AAAA;AACA;AADA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAVA;AA3BA;AAuCA;AACA;;;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AACA;AACA;AACA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAIA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AAHA;AAKA;;;AAEA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAFA;AACA;AAIA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA;AACA;AACA;AACA;AAFA;AAIA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;;;AAIA;AACA;AACA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AALA;AAOA;AACA;AAbA;AAeA;AAAA;AAAA;AACA;AACA;AAAA;AACA;AADA;AAGA;AACA;AANA;AAhBA;AA2BA;;;AA3VA;AACA;AADA;AACA;AA6VA;;;;;;;;;;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAEA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AADA;AACA;AADA;AAHA;AADA;AAFA;AAgBA;;;AApBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3WA;AACA;;;AAAA;AACA;;;AACA;AACA;;;AACA;;;AACA;AAAA;AACA;AADA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AANA;AAUA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AADA;AADA;AAOA;AACA;;;AAEA;AACA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AAFA;AAJA;AAUA;;;AAvDA;AACA;AADA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACLA;AACA;;;AAAA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AACA;;;AACA;AAAA;AACA;AACA;AACA;AAHA;AACA;AAGA;AACA;AACA;AANA;AAOA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAAA;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAAA;AACA;AADA;AAHA;AAQA;;;AAnEA;AACA;AADA;;;;;;;;;;;;;;;;;;;;;;ACVA;AACA;;;AAAA;AACA;;;AAAA;AACA;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AACA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AACA;AACA;;;AAIA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AARA;AAUA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AApCA;AA8CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AAFA;AAIA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AA1BA;AA4BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AAHA;AACA;AAKA;AAAA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AA7BA;AA+BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AA9BA;AACA;AAiCA;AACA;AACA;AACA;AACA;AAWA;AACA;AACA;AACA;AACA;AAJA;AAfA;AA+BA;AACA;AAFA;AAIA;AACA;AAFA;AAIA;AACA;AAFA;AACA;AAIA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AARA;AACA;AAUA;AACA;AAWA;AACA;AASA;AACA;AACA;AAGA;AALA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AATA;AACA;AAWA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AAIA;;;;;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3SA;AACA;;;;;AACA;;;AAEA;AAAA;AACA;AADA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAZA;AAgBA;AACA;;;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AADA;AADA;AAKA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AADA;AAGA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AADA;AAVA;AADA;AAgBA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAEA;AACA;AAAA;AAAA;AAAA;AAJA;AAFA;AAjBA;AA8BA;;;AAjGA;AACA;AAmGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtGA;AACA;;;AAAA;AACA;;;AACA;;;AAEA;AAAA;AACA;AADA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AAOA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AALA;AAOA;AAPA;AAUA;;;AA3DA;AACA;AADA;;;;;;;;;;;;;;;ACFA;AACA;;;AAAA;AACA;;;;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACNA;AACA;;;AAAA;AACA;;;AACA;AACA;AAMA;AACA;AAMA;AACA;;;AACA;;;AAEA;AAAA;AACA;AADA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAjBA;AAsBA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;;;AAEA;AACA;AACA;AACA;AAFA;AACA;AAIA;AACA;;;AAEA;AACA;AACA;AACA;;;;AAIA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AARA;AAUA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAKA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAFA;AAIA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAJA;AAMA;AANA;AAQA;AAAA;AAAA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AACA;AAHA;AAKA;AAEA;AACA;AACA;AACA;AACA;AACA;AALA;AAZA;AAZA;AAkCA;;;AA/PA;AACA;AAiQA;;;AAEA;AAAA;AACA;AADA;AACA;AADA;AAAA;AAAA;AACA;AADA;AACA;AACA;AAFA;AAGA;AACA;;;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAHA;AAKA;AALA;AAQA;;;AAtBA;AACA;AAwBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7SA;AACA;;;AAAA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA;;;AAEA;AAAA;AACA;AADA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAPA;AAZA;AAwBA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAEA;AALA;AAQA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AAPA;AADA;AAYA;AApBA;AAuBA;;;AA9JA;AACA;AAgKA;;;AAEA;AAAA;AACA;AADA;AACA;AADA;AAAA;AAAA;AACA;AADA;AACA;AACA;AACA;AAHA;AAIA;AACA;;;AACA;AACA;AACA;AACA;;;AAEA;AACA;AAAA;AAAA;AACA;AACA;AACA;AAHA;AAKA;;;AAnBA;AACA;AAqBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChMA;AACA;;;AAAA;AACA;;;AACA;AACA;AACA;AACA;;;AACA;;;AAEA;AAAA;AACA;AADA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AANA;AARA;AAgBA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AALA;AAOA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AADA;AADA;AAKA;AAZA;AAeA;;;AAvGA;AACA;AAyGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClHA;AACA;;;AAAA;AACA;;;AACA;AACA;AAYA;AACA;AACA;AACA;;;AACA;;;AAEA;AAAA;AACA;AADA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAlBA;AAuBA;AACA;;;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AAFA;AAIA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAFA;AAOA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AAFA;AAIA;;;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AADA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAJA;AAMA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AALA;AAOA;AARA;AAUA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AAQA;AAGA;AACA;AACA;AAFA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AALA;AAOA;AA3BA;AAhBA;AAgDA;;;AA1TA;AACA;AA4TA;;;AAEA;AAAA;AACA;AADA;AACA;AADA;AAAA;AAAA;AACA;AADA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AAQA;AACA;;;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AAAA;AACA;AADA;AAIA;;;AAxDA;AACA;AA0DA;;;AAEA;AAAA;AACA;AADA;AACA;AADA;AAAA;AAAA;AACA;AADA;AACA;AACA;AAFA;AAGA;AACA;;;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AADA;AAIA;;;AApBA;AACA;AA2BA;;;;;;;;;;;;;;ACxaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACjBA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAHA;AAQA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;AChIA;AACA;;;AAAA;AACA;;;;;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;AAEA;AACA;AACA;AACA;AAGA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;;;AAEA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AATA;AAYA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAGA;AACA;AAAA;AAAA;AACA;AAEA;;;;;AAIA;;;;;;;;;;;;;;;AC/HA;AACA;AAGA;AACA;AAEA;;;;;AAKA;;;AAGA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AAFA;AAIA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AACA;AAEA;;;AAGA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AAFA;AAFA;AAOA;AACA;AACA;AAEA;;;AAGA;AACA;AACA;AACA;AADA;AAGA;AACA;AADA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AACA;AADA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AAKA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AACA;AAQA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AALA;AAHA;AAWA;AACA;;;;;;;ACtLA;;;;;;;ACAA;;;;;;;ACAA;;;;;;;ACAA;;;;;;;ACAA;;;;;;;ACAA;;;;;;;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;A","sourceRoot":""}
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Dante2",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "Dante wysiwyg rewritten in draft-js",
5
5
  "author": "Miguel Michelson",
6
6
  "license": "GPL-3.0",
@@ -26,9 +26,9 @@
26
26
  "dependencies": {
27
27
  "axios": "^0.15.2",
28
28
  "babel-runtime": "^6.11.6",
29
- "draft-convert": "^1.2.3",
30
- "draft-js": "0.10.3",
31
- "draft-js-custom-styles": "^2.0.1",
29
+ "draft-convert": "^2.1.2",
30
+ "draft-js": "0.10.4",
31
+ "draft-js-custom-styles": "^2.0.4",
32
32
  "immutable": "^3.8.2"
33
33
  },
34
34
  "devDependencies": {
@@ -52,8 +52,6 @@
52
52
  "colors": "^1.1.2",
53
53
  "cross-env": "^3.1.4",
54
54
  "css-loader": "^0.25.0",
55
- "draft-convert": "^1.2.3",
56
- "draft-js": "0.10.3",
57
55
  "eslint": "1.7.2",
58
56
  "eslint-loader": "1.1.0",
59
57
  "expose-loader": "^0.7.1",
@@ -1,5 +1,5 @@
1
1
  require "dante2-editor/version"
2
2
 
3
3
  module Dante2Editor
4
- VERSION = "0.4.3"
4
+ VERSION = "0.4.4"
5
5
  end
@@ -342,7 +342,9 @@ export default class ImageBlock extends React.Component {
342
342
  ref="image_tag"
343
343
  height={this.state.aspect_ratio.height}
344
344
  width={this.state.aspect_ratio.width}
345
- className='graf-image' />
345
+ className='graf-image'
346
+ contentEditable={false}
347
+ />
346
348
  <Loader toggle={this.state.loading}
347
349
  progress={this.state.loading_progress} />
348
350
  </div>
@@ -33,11 +33,11 @@ import {
33
33
  } from '../../model/index.js'
34
34
 
35
35
  import Link from '../decorators/link'
36
- import Debug from './debug'
36
+ import Debug from '../core/debug'
37
37
  import findEntities from '../../utils/find_entities'
38
38
  import SaveBehavior from '../../utils/save_content'
39
39
  import customHTML2Content from '../../utils/html2content'
40
- import createStyles from 'draft-js-custom-styles';
40
+ import createStyles from 'draft-js-custom-styles'
41
41
 
42
42
 
43
43
  class DanteEditor extends React.Component {
@@ -70,6 +70,7 @@ class DanteEditor extends React.Component {
70
70
  this.handleHTMLPaste = this.handleHTMLPaste.bind(this)
71
71
  this.handlePasteImage = this.handlePasteImage.bind(this)
72
72
  this.handleDroppedFiles = this.handleDroppedFiles.bind(this)
73
+ this.handleDrop = this.handleDrop.bind(this)
73
74
  this.handleUpArrow = this.handleUpArrow.bind(this)
74
75
  this.handleDownArrow = this.handleDownArrow.bind(this)
75
76
  this.handleReturn = this.handleReturn.bind(this)
@@ -151,7 +152,8 @@ class DanteEditor extends React.Component {
151
152
  xhr: this.props.config.xhr,
152
153
  data_storage: this.props.config.data_storage
153
154
  },
154
- editorState: this.state.editorState,
155
+ editor: this,
156
+ editorState: this.getEditorState,
155
157
  editorContent: this.emitSerializedOutput()
156
158
  })
157
159
 
@@ -162,6 +164,12 @@ class DanteEditor extends React.Component {
162
164
 
163
165
  componentDidMount(){
164
166
  this.initializeState()
167
+ window.addEventListener('resize', ()=> {
168
+ if(this.relocateTooltips)
169
+ setTimeout(() => {
170
+ return this.relocateTooltips()
171
+ })
172
+ })
165
173
  }
166
174
 
167
175
  initializeState() {
@@ -209,14 +217,17 @@ class DanteEditor extends React.Component {
209
217
  }
210
218
 
211
219
  onChange(editorState) {
220
+
221
+ editorState = this.handleUndeletables(editorState)
222
+
212
223
  this.setPreContent()
213
224
  this.setState({ editorState })
214
225
 
215
226
  const currentBlock = getCurrentBlock(this.state.editorState)
216
227
  const blockType = currentBlock.getType()
217
228
 
218
- if (!editorState.getSelection().isCollapsed()) {
219
229
 
230
+ if (!editorState.getSelection().isCollapsed()) {
220
231
  const tooltip = this.tooltipsWithProp('displayOnSelection')[0]
221
232
  if (!this.tooltipHasSelectionElement(tooltip, blockType)) {
222
233
  return
@@ -228,11 +239,41 @@ class DanteEditor extends React.Component {
228
239
 
229
240
  setTimeout(() => {
230
241
  return this.relocateTooltips()
231
- }, 0)
242
+ })
232
243
 
233
244
  return this.dispatchChangesToSave()
234
245
  }
235
246
 
247
+ handleUndeletables(editorState){
248
+ // undeletable behavior, will keep previous blockMap
249
+ // if undeletables are deleted
250
+ const undeletable_types = this.widgets.filter(
251
+ function(o){ return o.undeletable })
252
+ .map(function(o){ return o.type })
253
+
254
+ const currentblockMap = this.state.editorState.getCurrentContent().get("blockMap")
255
+ const blockMap = editorState.getCurrentContent().get("blockMap")
256
+
257
+ const undeletablesMap = blockMap
258
+ .filter(function(o){
259
+ return undeletable_types.indexOf(o.get("type")) > 0
260
+ })
261
+
262
+ if (undeletable_types.length > 0 && undeletablesMap.size === 0) {
263
+
264
+ const contentState = editorState.getCurrentContent();
265
+ const blockMap = contentState.getBlockMap();
266
+ const newContentState = contentState.merge({
267
+ blockMap: this.state.editorState.getCurrentContent().blockMap,
268
+ selectionBefore: contentState.getSelectionAfter()
269
+ });
270
+
271
+ return editorState = EditorState.push(editorState, newContentState, 'change-block')
272
+ }
273
+
274
+ return editorState
275
+ }
276
+
236
277
  dispatchChangesToSave() {
237
278
  clearTimeout(this.saveTimeout)
238
279
  return this.saveTimeout = setTimeout(() => {
@@ -368,7 +409,7 @@ class DanteEditor extends React.Component {
368
409
  if (defaultBlockClass.length > 0) {
369
410
  return `graf ${ defaultBlockClass[0] } ${ is_selected }`
370
411
  } else {
371
- return `graf nana ${ is_selected }`
412
+ return `graf ${ is_selected }`
372
413
  }
373
414
  }
374
415
 
@@ -385,10 +426,11 @@ class DanteEditor extends React.Component {
385
426
  return null
386
427
  }
387
428
 
388
- const selectedFn = dataBlock.selectedFn ? dataBlock.selectedFn(block) : null
389
- const selected_class = is_selected ? dataBlock.selected_class : ''
429
+ const selectedFn = dataBlock.selectedFn ? dataBlock.selectedFn(block) : ''
430
+ const selected_class = (dataBlock.selected_class ? dataBlock.selected_class : '' )
431
+ const selected_class_out = is_selected ? selected_class : ''
390
432
 
391
- return `${ dataBlock.wrapper_class } ${ selected_class } ${ selectedFn }`
433
+ return `${ dataBlock.wrapper_class } ${ selected_class_out } ${ selectedFn }`
392
434
  }
393
435
 
394
436
  handleTooltipDisplayOn(prop, display) {
@@ -523,6 +565,19 @@ class DanteEditor extends React.Component {
523
565
  })
524
566
  }
525
567
 
568
+ handleDrop(selection, dataTransfer, isInternal){
569
+
570
+ const editorState = this.getEditorState();
571
+
572
+ const raw = dataTransfer.data.getData('text');
573
+
574
+ const data = JSON.parse(raw);
575
+
576
+ this.onChange(addNewBlock(editorState, data.type, data.data))
577
+
578
+ return 'handled';
579
+ }
580
+
526
581
  handleUpArrow(e) {
527
582
  return setTimeout(() => {
528
583
  return this.forceRender(this.state.editorState)
@@ -560,7 +615,7 @@ class DanteEditor extends React.Component {
560
615
  if (currentBlock.getText().length === 0) {
561
616
 
562
617
  if (config_block && config_block.handleEnterWithoutText) {
563
- config_block.handleEnterWithText(this, currentBlock)
618
+ config_block.handleEnterWithoutText(this, currentBlock)
564
619
  this.closePopOvers()
565
620
  return true
566
621
  }
@@ -866,7 +921,7 @@ class DanteEditor extends React.Component {
866
921
  <div className="section-divider layoutSingleColumn">
867
922
  <hr className="section-divider" />
868
923
  </div>
869
- <div className="section-content">
924
+ <div className="section-content container">
870
925
  <div ref="richEditor"
871
926
  className="section-inner layoutSingleColumn"
872
927
  onClick={ this.focus }>
@@ -874,6 +929,7 @@ class DanteEditor extends React.Component {
874
929
  blockRendererFn={ this.blockRenderer }
875
930
  editorState={ this.state.editorState }
876
931
  onChange={ this.onChange }
932
+ handleDrop={this.handleDrop}
877
933
  onUpArrow={ this.handleUpArrow }
878
934
  onDownArrow={ this.handleDownArrow }
879
935
  handleReturn={ this.handleReturn }
@@ -922,6 +978,7 @@ class DanteEditor extends React.Component {
922
978
  ? <Debug locks={ this.state.locks } editor={ this } />
923
979
  : undefined
924
980
  }
981
+
925
982
  </div>
926
983
 
927
984
  )
@@ -15,7 +15,7 @@ import {
15
15
  getCurrentBlock,
16
16
  getNode } from '../../model/index.js'
17
17
 
18
- import { getSelectionRect, getSelection } from "../../utils/selection.js"
18
+ import { getSelectionRect, getSelection, getRelativeParent } from "../../utils/selection.js"
19
19
 
20
20
  class DanteInlineTooltip extends React.Component {
21
21
 
@@ -219,42 +219,18 @@ class DanteInlineTooltip extends React.Component {
219
219
  let parent = ReactDOM.findDOMNode(this.props.editor)
220
220
  let parentBoundary = parent.getBoundingClientRect()
221
221
 
222
- // hide if selected node is not in editor
223
- // debugger
224
- //console.log @isDescendant(parent, nativeSelection.anchorNode)
225
-
226
222
  if (!this.isDescendant(parent, nativeSelection.anchorNode)) {
227
223
  this.hide()
228
224
  return
229
225
  }
230
226
 
231
- if (!coords)
232
- return
233
-
234
227
  // checkeamos si esta vacio
235
228
  this.display(block.getText().length === 0 && blockType === "unstyled")
236
229
  return this.setPosition({
237
- top: coords.top + window.pageYOffset,
238
- left: coords.left + window.pageXOffset - 60
230
+ top: coords.top + window.scrollY,
231
+ left: coords.left + window.scrollX - 60
239
232
  })
240
233
 
241
- /*
242
- @refs.image_popover.display(blockType is "image")
243
- if blockType is "image"
244
- selectionBoundary = node.anchorNode.parentNode.parentNode.parentNode.getBoundingClientRect()
245
- *el = document.querySelector("#dante_image_popover")
246
- el = @refs.image_popover.refs.image_popover
247
- padd = el.offsetWidth / 2
248
- @refs.image_popover.setPosition
249
- top: selectionBoundary.top - parentBoundary.top + 60
250
- left: selectionBoundary.left + (selectionBoundary.width / 2) - padd
251
-
252
- *@setState
253
- * image_popover_position:
254
- * top: selectionBoundary.top - parentBoundary.top + 60
255
- * left: selectionBoundary.left + (selectionBoundary.width / 2) - padd
256
- *
257
- */
258
234
  } else {
259
235
  return this.hide()
260
236
  }
@@ -4,7 +4,7 @@ import ReactDOM from 'react-dom'
4
4
 
5
5
  import { Entity, RichUtils, AtomicBlockUtils, EditorState } from 'draft-js'
6
6
 
7
- import { getSelectionRect, getSelection } from "../../utils/selection.js"
7
+ import { getSelectionRect, getSelection, getRelativeParent } from "../../utils/selection.js"
8
8
 
9
9
  import { getCurrentBlock, getNode } from '../../model/index.js'
10
10
 
@@ -29,9 +29,9 @@ class DanteImagePopover extends React.Component {
29
29
  },
30
30
  show: false,
31
31
  scaled: false,
32
- buttons: [{ type: "left" },
33
- { type: "center"},
34
- { type: "fill" },
32
+ buttons: [{ type: "left" },
33
+ { type: "center"},
34
+ { type: "fill" },
35
35
  { type: "wide" }]
36
36
  }
37
37
  }
@@ -97,23 +97,30 @@ class DanteImagePopover extends React.Component {
97
97
 
98
98
  let node = getNode()
99
99
 
100
- let selectionBoundary = getSelectionRect(nativeSelection)
101
- let coords = selectionBoundary
102
-
103
- let parent = ReactDOM.findDOMNode(this.props.editor)
104
- let parentBoundary = parent.getBoundingClientRect()
105
-
106
100
  this.display(blockType === "image")
107
101
 
108
102
  if (blockType === "image") {
109
- selectionBoundary = node.anchorNode.parentNode.parentNode
103
+ let selectionBoundary = node.anchorNode.parentNode.parentNode
110
104
  .parentNode.getBoundingClientRect()
105
+
106
+ let coords = selectionBoundary
107
+
111
108
  let el = this.refs.image_popover
112
109
  let padd = el.offsetWidth / 2
113
- return this.setPosition({
114
- top: selectionBoundary.top - parentBoundary.top + 60,
115
- left: selectionBoundary.left + selectionBoundary.width / 2 - padd
116
- })
110
+
111
+ let parent = ReactDOM.findDOMNode(this.props.editor)
112
+ let parentBoundary = parent.getBoundingClientRect()
113
+
114
+ const toolbarHeight = el.offsetHeight;
115
+
116
+ let left = selectionBoundary.left + selectionBoundary.width / 2 - padd
117
+
118
+ let diff = window.pageYOffset + parent.getBoundingClientRect().top
119
+
120
+ let top = selectionBoundary.top - parentBoundary.top + toolbarHeight //+ diff
121
+
122
+ return this.setPosition({ top: top, left: left })
123
+
117
124
  }
118
125
  } else {
119
126
  return this.hide()
@@ -139,7 +146,7 @@ class DanteImagePopover extends React.Component {
139
146
  <div
140
147
  ref="image_popover"
141
148
  className={ `dante-popover popover--Aligntooltip popover--top popover--animated ${ this.state.show ? 'is-active' : undefined }` }
142
- style={
149
+ style={
143
150
  { top: this.state.position.top,
144
151
  left: this.state.position.left }
145
152
  }
@@ -176,10 +183,10 @@ class DanteImagePopoverItem extends React.Component {
176
183
  }
177
184
 
178
185
  render() {
179
- return <li
180
- className={`dante-menu-button align-${ this.props.item.type }`}
186
+ return <li
187
+ className={`dante-menu-button align-${ this.props.item.type }`}
181
188
  onMouseDown={this.handleClick}>
182
- <span className={`tooltip-icon dante-icon-image-${ this.props.item.type }`} />
189
+ <span className={`tooltip-icon dante-icon dante-icon-image-${ this.props.item.type }`} />
183
190
  </li>
184
191
  }
185
192
  }
@@ -4,6 +4,8 @@ import ReactDOM from 'react-dom'
4
4
 
5
5
  import { getCurrentBlock } from '../../model/index.js'
6
6
 
7
+ import { getRelativeParent } from "../../utils/selection.js"
8
+
7
9
  class DanteAnchorPopover extends React.Component {
8
10
 
9
11
  constructor(props) {
@@ -71,9 +73,16 @@ class DanteAnchorPopover extends React.Component {
71
73
  let parent = ReactDOM.findDOMNode(this.props.editor)
72
74
  let parentBoundary = parent.getBoundingClientRect()
73
75
 
76
+ const toolbarHeight = el.offsetHeight;
77
+ const relativeRect = node.getBoundingClientRect();
78
+ let left = selectionBoundary.left + selectionBoundary.width / 2 - padd
79
+
80
+ let diff = window.pageYOffset + parent.getBoundingClientRect().top
81
+ let top = relativeRect.top - parentBoundary.top + (toolbarHeight * 0.3) + diff
82
+
74
83
  return {
75
- top: selectionBoundary.top - parentBoundary.top + 160,
76
- left: selectionBoundary.left + selectionBoundary.width / 2 - padd
84
+ top: top,
85
+ left: left
77
86
  }
78
87
  }
79
88
 
@@ -93,7 +102,7 @@ class DanteAnchorPopover extends React.Component {
93
102
  onMouseOut={ this.props.handleOnMouseOut }
94
103
  >
95
104
  <div className='popover-inner'>
96
- <a href={ this.props.url } target='_blank'>
105
+ <a href={ this.state.url } target='_blank'>
97
106
  { this.state.url }
98
107
  </a>
99
108
  </div>
@@ -14,7 +14,7 @@ import {
14
14
  Entity,
15
15
  RichUtils } from 'draft-js'
16
16
 
17
- import { getSelectionRect, getSelection } from "../../utils/selection.js"
17
+ import { getSelectionRect, getSelection, getRelativeParent } from "../../utils/selection.js"
18
18
 
19
19
  import { getCurrentBlock } from '../../model/index.js'
20
20
 
@@ -128,9 +128,23 @@ class DanteTooltip extends React.Component {
128
128
  return
129
129
  }
130
130
 
131
- let top = selectionBoundary.top - parentBoundary.top - -90 - 5
131
+ //let top = selectionBoundary.top - parentBoundary.top - -90 - 5
132
+
133
+ const relativeParent = getRelativeParent(this.refs.dante_menu.parentElement);
134
+ const toolbarHeight = this.refs.dante_menu.clientHeight;
135
+ const relativeRect = (relativeParent || document.body).getBoundingClientRect();
136
+ const selectionRect = getVisibleSelectionRect(window);
137
+
138
+ if(!selectionRect || !relativeRect || !selectionBoundary)
139
+ return
140
+
141
+
142
+ let diff = window.pageYOffset + parent.getBoundingClientRect().top
143
+ let top = (selectionRect.top - relativeRect.top) - toolbarHeight + diff
132
144
  let left = selectionBoundary.left + selectionBoundary.width / 2 - padd
133
145
 
146
+ //let left = (selectionRect.left - relativeRect.left) + (selectionRect.width / 2)
147
+
134
148
  if (!top || !left) {
135
149
  return
136
150
  }
data/src/model/index.js CHANGED
@@ -128,7 +128,7 @@ export const updateTextOfBlock = (editorState, block, text) => {
128
128
  blockMap: contentState.getBlockMap().set(block.getKey(), newBlock),
129
129
  });
130
130
 
131
- return EditorState.push(editorState, newContentState, 'change-block-type');
131
+ return EditorState.push(editorState, newContentState, 'replace-text');
132
132
  // return editorState;
133
133
  };
134
134