dante2-editor 0.4.3 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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